diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000000..7530d955fd --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,283 @@ +version: 2 +jobs: + test-node10-0: + working_directory: ~/ark-core + docker: + - image: 'circleci/node:10-browsers' + - image: 'postgres:alpine' + environment: + POSTGRES_PASSWORD: password + POSTGRES_DB: ark_development + POSTGRES_USER: ark + steps: + - checkout + - run: + name: Apt update + command: >- + sudo sh -c 'echo "deb http://ftp.debian.org/debian stable main + contrib non-free" >> /etc/apt/sources.list' && sudo apt-get update + - run: + name: Install xsel + command: sudo apt-get install -q xsel + - run: + name: Generate cache key + command: >- + find ./packages/ -name package.json -print0 | sort -z | xargs -r0 + echo ./package.json | xargs md5sum | md5sum - > checksum.txt + - restore_cache: + key: 'core-node10-{{ checksum "checksum.txt" }}-1' + - run: + name: Install packages + command: yarn + - save_cache: + key: 'core-node10-{{ checksum "checksum.txt" }}-1' + paths: + - ./packages/core/node_modules + - ./packages/core-api/node_modules + - ./packages/core-blockchain/node_modules + - ./packages/core-config/node_modules + - ./packages/core-container/node_modules + - ./packages/core-database/node_modules + - ./packages/core-database-postgres/node_modules + - ./packages/core-debugger-cli/node_modules + - ./packages/core-deployer/node_modules + - ./packages/core-elasticsearch/node_modules + - ./packages/core-error-tracker-bugsnag/node_modules + - ./packages/core-error-tracker-sentry/node_modules + - ./packages/core-event-emitter/node_modules + - ./packages/core-forger/node_modules + - ./packages/core-graphql/node_modules + - ./packages/core-http-utils/node_modules + - ./packages/core-json-rpc/node_modules + - ./packages/core-logger/node_modules + - ./packages/core-logger-winston/node_modules + - ./packages/core-p2p/node_modules + - ./packages/core-snapshots/node_modules + - ./packages/core-snapshots-cli/node_modules + - ./packages/core-test-utils/node_modules + - ./packages/core-tester-cli/node_modules + - ./packages/core-transaction-pool/node_modules + - ./packages/core-transaction-pool-mem/node_modules + - ./packages/core-utils/node_modules + - ./packages/core-vote-report/node_modules + - ./packages/core-webhooks/node_modules + - ./packages/crypto/node_modules + - ./node_modules + - run: + name: Create .ark/database directory + command: mkdir -p $HOME/.ark/database + - run: + name: Test + command: > + ./node_modules/.bin/cross-env ARK_ENV=test ./node_modules/.bin/jest + ./packages/core-vote-report/ ./packages/core-transaction-pool/ + ./packages/core-snapshots-cli/ ./packages/core-logger-winston/ + ./packages/core-api/ ./packages/core-event-emitter/ + ./packages/core-elasticsearch/ ./packages/core-database-postgres/ + ./packages/core-config/ ./packages/core-http-utils/ + --detectOpenHandles --runInBand --forceExit --ci --coverage | tee + test_output.txt + - run: + name: Last 1000 lines of test output + when: on_fail + command: tail -n 1000 test_output.txt + - run: + name: Codecov + command: ./node_modules/.bin/codecov + depcheck-lint: + working_directory: ~/ark-core + docker: + - image: 'circleci/node:10' + steps: + - checkout + - run: + name: Generate cache key + command: >- + find ./packages/ -name package.json -print0 | sort -z | xargs -r0 + echo ./package.json | xargs md5sum | md5sum - > checksum.txt + - restore_cache: + key: 'core-node10-{{ checksum "checksum.txt" }}-1' + - run: + name: Install packages + command: yarn + - run: + name: Lint + command: yarn lint + - run: + name: Depcheck + command: yarn depcheck + test-node10-1: + working_directory: ~/ark-core + docker: + - image: 'circleci/node:10-browsers' + - image: 'postgres:alpine' + environment: + POSTGRES_PASSWORD: password + POSTGRES_DB: ark_development + POSTGRES_USER: ark + steps: + - checkout + - run: + name: Apt update + command: >- + sudo sh -c 'echo "deb http://ftp.debian.org/debian stable main + contrib non-free" >> /etc/apt/sources.list' && sudo apt-get update + - run: + name: Install xsel + command: sudo apt-get install -q xsel + - run: + name: Generate cache key + command: >- + find ./packages/ -name package.json -print0 | sort -z | xargs -r0 + echo ./package.json | xargs md5sum | md5sum - > checksum.txt + - restore_cache: + key: 'core-node10-{{ checksum "checksum.txt" }}-1' + - run: + name: Install packages + command: yarn + - save_cache: + key: 'core-node10-{{ checksum "checksum.txt" }}-1' + paths: + - ./packages/core/node_modules + - ./packages/core-api/node_modules + - ./packages/core-blockchain/node_modules + - ./packages/core-config/node_modules + - ./packages/core-container/node_modules + - ./packages/core-database/node_modules + - ./packages/core-database-postgres/node_modules + - ./packages/core-debugger-cli/node_modules + - ./packages/core-deployer/node_modules + - ./packages/core-elasticsearch/node_modules + - ./packages/core-error-tracker-bugsnag/node_modules + - ./packages/core-error-tracker-sentry/node_modules + - ./packages/core-event-emitter/node_modules + - ./packages/core-forger/node_modules + - ./packages/core-graphql/node_modules + - ./packages/core-http-utils/node_modules + - ./packages/core-json-rpc/node_modules + - ./packages/core-logger/node_modules + - ./packages/core-logger-winston/node_modules + - ./packages/core-p2p/node_modules + - ./packages/core-snapshots/node_modules + - ./packages/core-snapshots-cli/node_modules + - ./packages/core-test-utils/node_modules + - ./packages/core-tester-cli/node_modules + - ./packages/core-transaction-pool/node_modules + - ./packages/core-transaction-pool-mem/node_modules + - ./packages/core-utils/node_modules + - ./packages/core-vote-report/node_modules + - ./packages/core-webhooks/node_modules + - ./packages/crypto/node_modules + - ./node_modules + - run: + name: Create .ark/database directory + command: mkdir -p $HOME/.ark/database + - run: + name: Test + command: > + ./node_modules/.bin/cross-env ARK_ENV=test ./node_modules/.bin/jest + ./packages/core-webhooks/ ./packages/core-transaction-pool-mem/ + ./packages/core-test-utils/ ./packages/core-p2p/ + ./packages/core-json-rpc/ ./packages/core-forger/ + ./packages/core-error-tracker-bugsnag/ ./packages/core-debugger-cli/ + ./packages/core-container/ ./packages/core/ --detectOpenHandles + --runInBand --forceExit --ci --coverage | tee test_output.txt + - run: + name: Last 1000 lines of test output + when: on_fail + command: tail -n 1000 test_output.txt + - run: + name: Codecov + command: ./node_modules/.bin/codecov + test-node10-2: + working_directory: ~/ark-core + docker: + - image: 'circleci/node:10-browsers' + - image: 'postgres:alpine' + environment: + POSTGRES_PASSWORD: password + POSTGRES_DB: ark_development + POSTGRES_USER: ark + steps: + - checkout + - run: + name: Apt update + command: >- + sudo sh -c 'echo "deb http://ftp.debian.org/debian stable main + contrib non-free" >> /etc/apt/sources.list' && sudo apt-get update + - run: + name: Install xsel + command: sudo apt-get install -q xsel + - run: + name: Generate cache key + command: >- + find ./packages/ -name package.json -print0 | sort -z | xargs -r0 + echo ./package.json | xargs md5sum | md5sum - > checksum.txt + - restore_cache: + key: 'core-node10-{{ checksum "checksum.txt" }}-1' + - run: + name: Install packages + command: yarn + - save_cache: + key: 'core-node10-{{ checksum "checksum.txt" }}-1' + paths: + - ./packages/core/node_modules + - ./packages/core-api/node_modules + - ./packages/core-blockchain/node_modules + - ./packages/core-config/node_modules + - ./packages/core-container/node_modules + - ./packages/core-database/node_modules + - ./packages/core-database-postgres/node_modules + - ./packages/core-debugger-cli/node_modules + - ./packages/core-deployer/node_modules + - ./packages/core-elasticsearch/node_modules + - ./packages/core-error-tracker-bugsnag/node_modules + - ./packages/core-error-tracker-sentry/node_modules + - ./packages/core-event-emitter/node_modules + - ./packages/core-forger/node_modules + - ./packages/core-graphql/node_modules + - ./packages/core-http-utils/node_modules + - ./packages/core-json-rpc/node_modules + - ./packages/core-logger/node_modules + - ./packages/core-logger-winston/node_modules + - ./packages/core-p2p/node_modules + - ./packages/core-snapshots/node_modules + - ./packages/core-snapshots-cli/node_modules + - ./packages/core-test-utils/node_modules + - ./packages/core-tester-cli/node_modules + - ./packages/core-transaction-pool/node_modules + - ./packages/core-transaction-pool-mem/node_modules + - ./packages/core-utils/node_modules + - ./packages/core-vote-report/node_modules + - ./packages/core-webhooks/node_modules + - ./packages/crypto/node_modules + - ./node_modules + - run: + name: Create .ark/database directory + command: mkdir -p $HOME/.ark/database + - run: + name: Test + command: > + ./node_modules/.bin/cross-env ARK_ENV=test ./node_modules/.bin/jest + ./packages/crypto/ ./packages/core-utils/ + ./packages/core-tester-cli/ ./packages/core-snapshots/ + ./packages/core-logger/ ./packages/core-graphql/ + ./packages/core-error-tracker-sentry/ ./packages/core-deployer/ + ./packages/core-database/ ./packages/core-blockchain/ + --detectOpenHandles --runInBand --forceExit --ci --coverage | tee + test_output.txt + - run: + name: Last 1000 lines of test output + when: on_fail + command: tail -n 1000 test_output.txt + - run: + name: Codecov + command: ./node_modules/.bin/codecov +workflows: + version: 2 + test_depcheck_lint: + jobs: + - depcheck-lint + - test-node10-0 + - test-node10-1 + - test-node10-2 diff --git a/.circleci/configTemplate.json b/.circleci/configTemplate.json new file mode 100644 index 0000000000..cebbd4de0c --- /dev/null +++ b/.circleci/configTemplate.json @@ -0,0 +1,130 @@ +{ + "version": 2, + "jobs": { + "test-node10-0": { + "working_directory": "~/ark-core", + "docker": [ + { + "image": "circleci/node:10-browsers" + }, + { + "image": "postgres:alpine", + "environment": { + "POSTGRES_PASSWORD": "password", + "POSTGRES_DB": "ark_development", + "POSTGRES_USER": "ark" + } + } + ], + "steps": [ + "checkout", + { + "run": { + "name": "Apt update", + "command": "sudo sh -c 'echo \"deb http://ftp.debian.org/debian stable main contrib non-free\" >> /etc/apt/sources.list' && sudo apt-get update" + } + }, + { + "run": { + "name": "Install xsel", + "command": "sudo apt-get install -q xsel" + } + }, + { + "run": { + "name": "Generate cache key", + "command": "find ./packages/ -name package.json -print0 | sort -z | xargs -r0 echo ./package.json | xargs md5sum | md5sum - > checksum.txt" + } + }, + { + "restore_cache": { + "key": "core-node10-{{ checksum \"checksum.txt\" }}-1" + } + }, + { + "run": { + "name": "Install packages", + "command": "yarn" + } + }, + { + "save_cache": { + "key": "core-node10-{{ checksum \"checksum.txt\" }}-1", + "paths": [] + } + }, + { + "run": { + "name": "Create .ark/database directory", + "command": "mkdir -p $HOME/.ark/database" + } + }, + { + "run": { + "name": "Test", + "command": "./node_modules/.bin/cross-env ARK_ENV=test ./node_modules/.bin/jest {{TESTPATHS}} --detectOpenHandles --runInBand --forceExit --ci --coverage | tee test_output.txt\n" + } + }, + { + "run": { + "name": "Last 1000 lines of test output", + "when": "on_fail", + "command": "tail -n 1000 test_output.txt" + } + }, + { + "run": { + "name": "Codecov", + "command": "./node_modules/.bin/codecov" + } + } + ] + }, + "depcheck-lint": { + "working_directory": "~/ark-core", + "docker": [ + { + "image": "circleci/node:10" + } + ], + "steps": [ + "checkout", + { + "run": { + "name": "Generate cache key", + "command": "find ./packages/ -name package.json -print0 | sort -z | xargs -r0 echo ./package.json | xargs md5sum | md5sum - > checksum.txt" + } + }, + { + "restore_cache": { + "key": "core-node10-{{ checksum \"checksum.txt\" }}-1" + } + }, + { + "run": { + "name": "Install packages", + "command": "yarn" + } + }, + { + "run": { + "name": "Lint", + "command": "yarn lint" + } + }, + { + "run": { + "name": "Depcheck", + "command": "yarn depcheck" + } + } + ] + } + }, + "workflows": { + "version": 2, + "test_depcheck_lint": { + "jobs": ["depcheck-lint"] + } + } +} diff --git a/.circleci/generateConfig.js b/.circleci/generateConfig.js new file mode 100644 index 0000000000..ec699e53c3 --- /dev/null +++ b/.circleci/generateConfig.js @@ -0,0 +1,90 @@ +const yaml = require('js-yaml') +const fs = require('fs') +const path = require('path') + +const config = require('./configTemplate.json') + +generateConfig() + +function generateConfig() { + fs.readdir('./packages', (err, packages) => genYaml({ packages })) +} + +function genYaml(options) { + // save cache + const saveCacheStep = config.jobs['test-node10-0'].steps.find( + step => typeof step === 'object' && step.save_cache, + ) + saveCacheStep.save_cache.paths = options.packages + .map(package => `./packages/${package}/node_modules`) + .concat('./node_modules') + + // test split + const packagesSplit = splitPackagesByTestFiles(options.packages, 3) + + const jobs = [ + config.jobs['test-node10-0'], + JSON.parse(JSON.stringify(config.jobs['test-node10-0'])), + JSON.parse(JSON.stringify(config.jobs['test-node10-0'])), + ] + + jobs.forEach((job, index) => { + const testStep = job.steps.find( + step => typeof step === 'object' && step.run && step.run.name === 'Test', + ) + testStep.run.command = testStep.run.command.replace( + '{{TESTPATHS}}', + packagesSplit[index].map(package => `./packages/${package}/`).join(' '), + ) + + config.jobs[`test-node10-${index}`] = job + config.workflows.test_depcheck_lint.jobs.push(`test-node10-${index}`) + }) + + fs.writeFile('.circleci/config.yml', yaml.safeDump(config), 'utf8', err => { + if (err) console.error(err) + }) +} + +function splitPackagesByTestFiles(packages, splitNumber) { + /* distribute test packages by test files count : start by most files package, + and distribute package by package in each _packagesSplit_ (not the most effective + distribution but simple and enough for now) */ + const packagesWithCount = packages.map(package => ({ + package, + count: countFiles(`packages/${package}/__tests__`, '.test.js'), + })) + const packagesSortedByCount = packagesWithCount.sort( + (pkgA, pkgB) => pkgA.count > pkgB.count, + ) + + const packagesSplit = new Array(splitNumber) + packagesSortedByCount.forEach( + (pkg, index) => + (packagesSplit[index % splitNumber] = [pkg.package].concat( + packagesSplit[index % splitNumber] || [], + )), + ) + + return packagesSplit +} + +function countFiles(startPath, filter) { + let count = 0 + if (!fs.existsSync(startPath)) { + return + } + + var files = fs.readdirSync(startPath) + for (let i = 0; i < files.length; i++) { + const filename = path.join(startPath, files[i]) + const stat = fs.lstatSync(filename) + if (stat.isDirectory()) { + count += countFiles(filename, filter) + } else if (filename.indexOf(filter) >= 0) { + count++ + } + } + + return count +} diff --git a/.codecov.yml b/.codecov.yml new file mode 100644 index 0000000000..f0d614a77b --- /dev/null +++ b/.codecov.yml @@ -0,0 +1,3 @@ +ignore: + - "packages/core-tester-cli/**/*" + - "packages/**/lib/index" diff --git a/.eslintignore b/.eslintignore index 89c1650228..a04bc1cdb1 100644 --- a/.eslintignore +++ b/.eslintignore @@ -4,4 +4,6 @@ /.coverage/** /docs/** /tmp/** +/fixtures/** +/__fixtures__/** !.eslintrc.js diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index cbe0fab64a..0000000000 --- a/.eslintrc +++ /dev/null @@ -1,20 +0,0 @@ -{ - "env": { - "commonjs": true, - "node": true, - "jest": true - }, - "extends": [ - "standard" - ], - "parserOptions": { - "sourceType": "module" - }, - "rules": { - "no-console": "off", - "indent": ["off", 2], - "linebreak-style": 0, - "quotes": ["error", "single"], - "semi": ["off", "always"] - } -} diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000000..ab219a187a --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,38 @@ +{ + "env": { + "commonjs": true, + "node": true, + "jest": true + }, + "extends": ["@arkecosystem/eslint-config-base", "prettier"], + "rules": { + "class-methods-use-this": "off", + "complexity": "off", + "global-require": "off", + "import/no-dynamic-require": "off", + "no-restricted-syntax": "off", + "no-console": [ + "error", + { "allow": ["error", "info", "warn", "time", "timeEnd"] } + ], + "no-plusplus": "off", + "no-continue": "off", + "no-param-reassign": "off", + "max-len": [ + "warn", + { + "code": 120, + "ignoreTemplateLiterals": true, + "ignoreRegExpLiterals": true + } + ], + "import/no-extraneous-dependencies": "off", + // TODO: fix later as they require a lot of changes + "consistent-return": "off", + "no-unused-expressions": "off", + "no-underscore-dangle": "off", + "no-unused-vars": "off", + "prefer-destructuring": "off", + "radix": "off" + } +} diff --git a/.gitignore b/.gitignore index 42fbaf4f34..da756344b3 100644 --- a/.gitignore +++ b/.gitignore @@ -53,8 +53,11 @@ bundle.min.js dist packages/**/dist/ -# Lockfile -yarn.lock - # Microsoft Visual Studio settings .vs + +# Databases +*.sqlite + +# Random +peers_backup.json diff --git a/.lintstagedrc.json b/.lintstagedrc.json new file mode 100644 index 0000000000..a8cd9eebff --- /dev/null +++ b/.lintstagedrc.json @@ -0,0 +1,4 @@ +{ + "*.js": ["eslint --fix", "prettier --write", "git add"], + "*.{json,md}": ["prettier --write", "git add"] +} diff --git a/.nvmrc b/.nvmrc index 0a7b8bccfc..51fe2f11d6 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v9.11.1 +v10.12.0 diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000000..6350e98682 --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +.coverage diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000000..89a0a2b7f0 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,5 @@ +{ + "singleQuote": true, + "trailingComma": "all", + "semi": false +} diff --git a/.snyk b/.snyk new file mode 100644 index 0000000000..384ff6609d --- /dev/null +++ b/.snyk @@ -0,0 +1,269 @@ +# Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities. +version: v1.13.1 +# ignores vulnerabilities until expiry date; change duration by modifying expiry date +ignore: + SNYK-JS-MERGE-72553: + - jest-mock-process > jest > jest-cli > jest-haste-map > sane > exec-sh > merge: + reason: None given + expires: '2018-12-11T05:03:38.309Z' + - jest-mock-process > jest > jest-cli > jest-haste-map > sane > watch > exec-sh > merge: + reason: None given + expires: '2018-12-11T05:03:38.309Z' + - jest-mock-process > jest > jest-cli > jest-runtime > jest-haste-map > sane > exec-sh > merge: + reason: None given + expires: '2018-12-11T05:03:38.309Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-haste-map > sane > exec-sh > merge: + reason: None given + expires: '2018-12-11T05:03:38.309Z' + - jest-mock-process > jest > jest-cli > jest-runtime > jest-haste-map > sane > watch > exec-sh > merge: + reason: None given + expires: '2018-12-11T05:03:38.310Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-haste-map > sane > watch > exec-sh > merge: + reason: None given + expires: '2018-12-11T05:03:38.310Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-runtime > jest-haste-map > sane > exec-sh > merge: + reason: None given + expires: '2018-12-11T05:03:38.310Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-runtime > jest-haste-map > sane > watch > exec-sh > merge: + reason: None given + expires: '2018-12-11T05:03:38.310Z' + 'npm:braces:20180219': + - jest-mock-process > jest > jest-cli > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.310Z' + - jest-mock-process > jest > jest-cli > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.310Z' + - jest-mock-process > jest > jest-cli > jest-runtime > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.310Z' + - jest-mock-process > jest > jest-cli > jest-config > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.310Z' + - jest-mock-process > jest > jest-cli > jest-haste-map > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.310Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-haste-map > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.310Z' + - jest-mock-process > jest > jest-cli > jest-snapshot > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.310Z' + - jest-mock-process > jest > jest-cli > jest-runtime > jest-haste-map > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.310Z' + - jest-mock-process > jest > jest-cli > jest-runtime > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.310Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-runtime > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.310Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-config > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.311Z' + - jest-mock-process > jest > jest-cli > jest-runtime > jest-config > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.311Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.311Z' + - jest-mock-process > jest > jest-cli > jest-util > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.311Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-runtime > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.311Z' + - jest-mock-process > jest > jest-cli > jest-config > jest-util > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.311Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-util > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.311Z' + - jest-mock-process > jest > jest-cli > jest-runtime > babel-plugin-istanbul > test-exclude > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.311Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-runtime > jest-config > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.311Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-runtime > jest-haste-map > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.311Z' + - jest-mock-process > jest > jest-cli > jest-environment-jsdom > jest-util > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.311Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-jasmine2 > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.311Z' + - jest-mock-process > jest > jest-cli > jest-config > jest-jasmine2 > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.311Z' + - jest-mock-process > jest > jest-cli > jest-resolve-dependencies > jest-snapshot > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.311Z' + - jest-mock-process > jest > jest-cli > jest-runtime > jest-snapshot > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.312Z' + - jest-mock-process > jest > jest-cli > jest-runtime > jest-util > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.312Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-runtime > babel-plugin-istanbul > test-exclude > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.312Z' + - jest-mock-process > jest > jest-cli > jest-config > jest-jasmine2 > expect > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.312Z' + - jest-mock-process > jest > jest-cli > jest-config > jest-jasmine2 > jest-util > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.312Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-jasmine2 > jest-util > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.312Z' + - jest-mock-process > jest > jest-cli > jest-config > jest-environment-jsdom > jest-util > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.312Z' + - jest-mock-process > jest > jest-cli > jest-runtime > jest-config > jest-util > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.312Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-jasmine2 > expect > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.312Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-config > jest-util > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.312Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-config > jest-jasmine2 > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.312Z' + - jest-mock-process > jest > jest-cli > jest-runtime > jest-config > jest-jasmine2 > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.312Z' + - jest-mock-process > jest > jest-cli > jest-config > jest-jasmine2 > jest-snapshot > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.312Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-jasmine2 > jest-snapshot > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.312Z' + - jest-mock-process > jest > jest-cli > jest-config > jest-environment-node > jest-util > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.312Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-runtime > jest-snapshot > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.312Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-runtime > jest-util > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.312Z' + - jest-mock-process > jest > jest-cli > jest-config > babel-jest > babel-plugin-istanbul > test-exclude > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.312Z' + - jest-mock-process > jest > jest-cli > jest-runtime > jest-config > jest-jasmine2 > jest-util > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.312Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-runtime > jest-config > jest-jasmine2 > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.313Z' + - jest-mock-process > jest > jest-cli > jest-runtime > jest-config > jest-jasmine2 > jest-snapshot > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.313Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-config > babel-jest > babel-plugin-istanbul > test-exclude > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.313Z' + - jest-mock-process > jest > jest-cli > jest-runtime > jest-config > babel-jest > babel-plugin-istanbul > test-exclude > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.313Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-config > jest-jasmine2 > expect > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.313Z' + - jest-mock-process > jest > jest-cli > jest-runtime > jest-config > jest-jasmine2 > expect > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.313Z' + - jest-mock-process > jest > jest-cli > jest-runtime > jest-config > jest-environment-jsdom > jest-util > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.313Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-runtime > jest-config > jest-util > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.313Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-config > jest-jasmine2 > jest-util > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.313Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-config > jest-jasmine2 > jest-snapshot > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.313Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-config > jest-environment-jsdom > jest-util > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.313Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-config > jest-environment-node > jest-util > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.313Z' + - jest-mock-process > jest > jest-cli > jest-runtime > jest-config > jest-environment-node > jest-util > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.313Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-runtime > jest-config > jest-environment-node > jest-util > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.313Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-runtime > jest-config > jest-jasmine2 > jest-util > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.313Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-runtime > jest-config > jest-jasmine2 > expect > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.313Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-runtime > jest-config > jest-environment-jsdom > jest-util > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.313Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-runtime > jest-config > jest-jasmine2 > jest-snapshot > jest-message-util > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.313Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-runtime > jest-config > babel-jest > babel-plugin-istanbul > test-exclude > micromatch > braces: + reason: None given + expires: '2018-12-11T05:03:38.314Z' + 'npm:chownr:20180731': + - '@arkecosystem/core > @arkecosystem/core-transaction-pool-mem > better-sqlite3 > tar > chownr': + reason: None given + expires: '2018-12-11T05:03:38.314Z' + - '@arkecosystem/core > @arkecosystem/core-webhooks > sqlite3 > node-pre-gyp > tar > chownr': + reason: None given + expires: '2018-12-11T05:03:38.314Z' + - '@arkecosystem/core > @arkecosystem/core-json-rpc > @keyv/sqlite > sqlite3 > node-pre-gyp > tar > chownr': + reason: None given + expires: '2018-12-11T05:03:38.314Z' + - jest-mock-process > jest > jest-cli > jest-haste-map > sane > fsevents > node-pre-gyp > tar > chownr: + reason: None given + expires: '2018-12-11T05:03:38.314Z' + - jest-mock-process > jest > jest-cli > jest-runtime > jest-haste-map > sane > fsevents > node-pre-gyp > tar > chownr: + reason: None given + expires: '2018-12-11T05:03:38.314Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-haste-map > sane > fsevents > node-pre-gyp > tar > chownr: + reason: None given + expires: '2018-12-11T05:03:38.314Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-runtime > jest-haste-map > sane > fsevents > node-pre-gyp > tar > chownr: + reason: None given + expires: '2018-12-11T05:03:38.314Z' + 'npm:lodash:20180130': + - '@arkecosystem/core > @arkecosystem/core-database-postgres > sql > lodash': + reason: None given + expires: '2018-12-11T05:03:38.314Z' + - '@arkecosystem/core-snapshots > @arkecosystem/core-database-postgres > sql > lodash': + reason: None given + expires: '2018-12-11T05:03:38.314Z' + - '@arkecosystem/core > @arkecosystem/core-json-rpc > @keyv/sqlite > @keyv/sql > sql > lodash': + reason: None given + expires: '2018-12-11T05:03:38.314Z' + 'npm:mem:20180117': + - jest-mock-process > jest > jest-cli > yargs > os-locale > mem: + reason: None given + expires: '2018-12-11T05:03:38.315Z' + - jest-mock-process > jest > jest-cli > jest-runtime > yargs > os-locale > mem: + reason: None given + expires: '2018-12-11T05:03:38.315Z' + - jest-mock-process > jest > jest-cli > jest-runner > jest-runtime > yargs > os-locale > mem: + reason: None given + expires: '2018-12-11T05:03:38.315Z' + 'npm:sql:20180512': + - '@arkecosystem/core > @arkecosystem/core-database-postgres > sql': + reason: None given + expires: '2018-12-11T05:03:38.315Z' + - '@arkecosystem/core-snapshots > @arkecosystem/core-database-postgres > sql': + reason: None given + expires: '2018-12-11T05:03:38.315Z' + - '@arkecosystem/core > @arkecosystem/core-json-rpc > @keyv/sqlite > @keyv/sql > sql': + reason: None given + expires: '2018-12-11T05:03:38.315Z' +patch: {} diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index b970a01956..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,78 +0,0 @@ -language: node_js - -node_js: - - node - - 9 - -addons: - apt: - packages: - - xsel - -services: - - redis-server - -env: - ARK_CI_TEST: true - -before_install: - # - npm install yarn - - curl -o- -L https://yarnpkg.com/install.sh | bash - - export PATH="$HOME/.yarn/bin:$PATH" - - yarn config set cache-folder $HOME/.cache/yarn - -install: yarn -# - yarn bootstrap - -stages: - - lint - - depcheck - - test - # TODO - # - browser_test - -before_script: - - 'if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export DISPLAY=:99.0; fi' - - 'if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sh -e /etc/init.d/xvfb start; sleep 3; fi' - # To avoid a problem when starting the Redis service - - sudo redis-server /etc/redis/redis.conf --port 6379 - -script: - # See https://jestjs.io/docs/en/troubleshooting.html#tests-are-extremely-slow-on-docker-and-or-continuous-integration-ci-server - - yarn test:force-exit --ci --coverage - - codecov - -jobs: - include: - - stage: lint - script: yarn lint - # To lint the version 9 too - - stage: lint - node_js: 9 - script: yarn lint - - - stage: depcheck - script: yarn depcheck - # To lint the version 9 too - - stage: depcheck - node_js: 9 - script: yarn depcheck - - # TODO - # - stage: browser_test - # script: yarn test:coverage - # - stage: browser_test - # node_js: 9 - # script: yarn test:coverage - -cache: - yarn: true # This wouldn't do anything because it needs a yarn.lock - directories: - - $HOME/.nvm/.cache - - $HOME/.cache/yarn - - node_modules - - packages/**/node_modules - -git: - # It's not necessary to get more than the last commit (and this branch alone) - depth: 1 diff --git a/README.md b/README.md index 1f9fc7fe9d..801373436b 100644 --- a/README.md +++ b/README.md @@ -1,54 +1,54 @@ -![ARK Core](https://i.imgur.com/1aP6F2o.png) +# Ark Core -# ARK Core +

+ +

+ +[![Build Status](https://badgen.now.sh/circleci/github/ArkEcosystem/core)](https://circleci.com/gh/ArkEcosystem/core) +[![Codecov](https://badgen.now.sh/codecov/c/github/arkecosystem/core)](https://codecov.io/gh/arkecosystem/core) +[![License: MIT](https://badgen.now.sh/badge/license/MIT/green)](https://opensource.org/licenses/MIT) ## Introduction -This repository contains all plugins that make up the ARK Core. +This repository contains all plugins that make up the Ark Core. ## Documentation -- Development : https://docs.ark.io/core/development.html -- Docker : https://docs.ark.io/core/docker.html +- Development : https://docs.ark.io/guidebook/core/development.html +- Docker : https://docs.ark.io/guidebook/core/docker.html ## API Documentation -- API v1 : https://docs.ark.io/developers/api/public/v1/ -- API v2 : https://docs.ark.io/developers/api/public/v2/ +- API v1 : https://docs.ark.io/api/public/v1/ +- API v2 : https://docs.ark.io/api/public/v2/ ## GitHub Development Bounty -- Get involved with ARK development and earn ARK coins : https://bounty.ark.io +- Get involved with Ark development and start earning ARK : https://bounty.ark.io ## Core Packages -[![Build Status](https://travis-ci.org/ArkEcosystem/core.svg?branch=master)](https://travis-ci.org/ArkEcosystem/core) - -| Package | Version | Description -|---|---|---| -| **[core](/packages/core)** | [![npm](https://img.shields.io/npm/v/@arkecosystem/core.svg)](https://www.npmjs.com/package/@arkecosystem/core) | **Includes all packages** | -| [client](/packages/client) | [![npm](https://img.shields.io/npm/v/@arkecosystem/client.svg)](https://www.npmjs.com/package/@arkecosystem/client) | A JavaScript library to interact with the ARK Blockchain | -| [core-api](/packages/core-api) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-api.svg)](https://www.npmjs.com/package/@arkecosystem/core-api) | Public API | -| [core-blockchain](/packages/core-blockchain) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-blockchain.svg)](https://www.npmjs.com/package/@arkecosystem/core-blockchain) | Blockchain Management | -| [core-config](/packages/core-config) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-config.svg)](https://www.npmjs.com/package/@arkecosystem/core-config) | Configuration Loader | -| [core-container](/packages/core-container) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-container.svg)](https://www.npmjs.com/package/@arkecosystem/core-container) | Container Management | -| [core-database](/packages/core-database) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-database.svg)](https://www.npmjs.com/package/@arkecosystem/core-database) | Database Interface | -| [core-database-sequelize](/packages/core-database-sequelize) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-database-sequelize.svg)](https://www.npmjs.com/package/@arkecosystem/core-database-sequelize) | Sequelize Database Provider | -| [core-deployer](/packages/core-deployer) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-deployer.svg)](https://www.npmjs.com/package/@arkecosystem/core-deployer) | Deployer CLI | -| [core-event-emitter](/packages/core-event-emitter) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-event-emitter.svg)](https://www.npmjs.com/package/@arkecosystem/core-event-emitter) | Event Manager | -| [core-forger](/packages/core-forger) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-forger.svg)](https://www.npmjs.com/package/@arkecosystem/core-forger) | Forger Manager | -| [core-graphql](/packages/core-graphql) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-graphql.svg)](https://www.npmjs.com/package/@arkecosystem/core-graphql) | GraphQL Provider | -| [core-json-rpc](/packages/core-json-rpc) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-json-rpc.svg)](https://www.npmjs.com/package/@arkecosystem/core-json-rpc) | JSON-RPC Server | -| [core-logger](/packages/core-logger) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-logger.svg)](https://www.npmjs.com/package/@arkecosystem/core-logger) | Logger Manager | -| [core-logger-winston](/packages/core-logger-winston) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-logger-winston.svg)](https://www.npmjs.com/package/@arkecosystem/core-logger-winston) | Winston Logger Provider | -| [core-p2p](/packages/core-p2p) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-p2p.svg)](https://www.npmjs.com/package/@arkecosystem/core-p2p) | P2P API | -| [test-utils](/packages/core-test-utils) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-test-utils.svg)](https://www.npmjs.com/package/@arkecosystem/core-test-utils) | Test Utilities | -| [tester-cli](/packages/core-tester-cli) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-tester-cli.svg)](https://www.npmjs.com/package/@arkecosystem/core-tester-cli) | Tester CLI | +| Package | Version | Description | +| -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | +| **[core](/packages/core)** | [![npm](https://img.shields.io/npm/v/@arkecosystem/core.svg)](https://www.npmjs.com/package/@arkecosystem/core) | **Includes all packages** | +| [core-api](/packages/core-api) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-api.svg)](https://www.npmjs.com/package/@arkecosystem/core-api) | Public API | +| [core-blockchain](/packages/core-blockchain) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-blockchain.svg)](https://www.npmjs.com/package/@arkecosystem/core-blockchain) | Blockchain Management | +| [core-config](/packages/core-config) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-config.svg)](https://www.npmjs.com/package/@arkecosystem/core-config) | Configuration Loader | +| [core-container](/packages/core-container) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-container.svg)](https://www.npmjs.com/package/@arkecosystem/core-container) | Container Management | +| [core-database](/packages/core-database) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-database.svg)](https://www.npmjs.com/package/@arkecosystem/core-database) | Database Interface | +| [core-deployer](/packages/core-deployer) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-deployer.svg)](https://www.npmjs.com/package/@arkecosystem/core-deployer) | Deployer CLI | +| [core-event-emitter](/packages/core-event-emitter) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-event-emitter.svg)](https://www.npmjs.com/package/@arkecosystem/core-event-emitter) | Event Manager | +| [core-forger](/packages/core-forger) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-forger.svg)](https://www.npmjs.com/package/@arkecosystem/core-forger) | Forger Manager | +| [core-graphql](/packages/core-graphql) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-graphql.svg)](https://www.npmjs.com/package/@arkecosystem/core-graphql) | GraphQL Provider | +| [core-json-rpc](/packages/core-json-rpc) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-json-rpc.svg)](https://www.npmjs.com/package/@arkecosystem/core-json-rpc) | JSON-RPC Server | +| [core-logger](/packages/core-logger) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-logger.svg)](https://www.npmjs.com/package/@arkecosystem/core-logger) | Logger Manager | +| [core-logger-winston](/packages/core-logger-winston) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-logger-winston.svg)](https://www.npmjs.com/package/@arkecosystem/core-logger-winston) | Winston Logger Provider | +| [core-p2p](/packages/core-p2p) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-p2p.svg)](https://www.npmjs.com/package/@arkecosystem/core-p2p) | P2P API | +| [test-utils](/packages/core-test-utils) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-test-utils.svg)](https://www.npmjs.com/package/@arkecosystem/core-test-utils) | Test Utilities | +| [tester-cli](/packages/core-tester-cli) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-tester-cli.svg)](https://www.npmjs.com/package/@arkecosystem/core-tester-cli) | Tester CLI | | [core-transaction-pool](/packages/core-transaction-pool) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-transaction-pool.svg)](https://www.npmjs.com/package/@arkecosystem/core-transaction-pool) | Transaction Pool Interface | -| [core-transaction-pool-redis](/packages/core-transaction-pool-redis) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-transaction-pool-redis.svg)](https://www.npmjs.com/package/@arkecosystem/core-transaction-pool-redis) | Transaction Pool - Redis Implementation | -| [core-webhooks](/packages/core-webhooks) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-webhooks.svg)](https://www.npmjs.com/package/@arkecosystem/core-webhooks) | Webhooks Manager | -| [crypto](/packages/crypto) | [![npm](https://img.shields.io/npm/v/@arkecosystem/crypto.svg)](https://www.npmjs.com/package/@arkecosystem/crypto) | Crypto Utilities | -| [validation](/packages/validation) | [![npm](https://img.shields.io/npm/v/@arkecosystem/validation.svg)](https://www.npmjs.com/package/@arkecosystem/validation) | Validation Manager | +| [core-webhooks](/packages/core-webhooks) | [![npm](https://img.shields.io/npm/v/@arkecosystem/core-webhooks.svg)](https://www.npmjs.com/package/@arkecosystem/core-webhooks) | Webhooks Manager | +| [crypto](/packages/crypto) | [![npm](https://img.shields.io/npm/v/@arkecosystem/crypto.svg)](https://www.npmjs.com/package/@arkecosystem/crypto) | Crypto Utilities | ## Security diff --git a/banner.png b/banner.png new file mode 100644 index 0000000000..b73a8bf34c Binary files /dev/null and b/banner.png differ diff --git a/docker/development/docker-compose.yml b/docker/development/docker-compose.yml index 5963dfeba4..de8fa8f6e6 100644 --- a/docker/development/docker-compose.yml +++ b/docker/development/docker-compose.yml @@ -4,14 +4,6 @@ version: '2' services: - redis: - image: "redis:alpine" - container_name: ark-development-redis - ports: - - '127.0.0.1:6379:6379' - volumes: - - 'redis:/data' - postgres: image: "postgres:alpine" container_name: ark-development-postgres @@ -20,10 +12,9 @@ services: volumes: - 'postgres:/var/lib/postgresql/data' environment: - POSTGRES_PASSWORD: ark_development_not_random_password + POSTGRES_PASSWORD: password POSTGRES_DB: ark_development - POSTGRES_USER: ark_development + POSTGRES_USER: ark volumes: - redis: postgres: diff --git a/docker/development/purge.sh b/docker/development/purge.sh new file mode 100755 index 0000000000..9849a43d90 --- /dev/null +++ b/docker/development/purge.sh @@ -0,0 +1,6 @@ +#!/usr/bin/env sh + +docker stop ark-development-postgres +docker rm -v ark-development-postgres +docker volume rm development_postgres +docker network rm development_default diff --git a/docker/devnet/Dockerfile b/docker/devnet/Dockerfile index a65e5a046b..46d929718d 100644 --- a/docker/devnet/Dockerfile +++ b/docker/devnet/Dockerfile @@ -1,4 +1,4 @@ -FROM node:9 +FROM node:10 WORKDIR /ark-core @@ -14,4 +14,3 @@ RUN apt-get update && \ rm -rf /var/lib/apt/lists/* EXPOSE 4002 4003 - diff --git a/docker/devnet/docker-compose.yml b/docker/devnet/docker-compose.yml index 83dae65bac..fdc00da3bf 100644 --- a/docker/devnet/docker-compose.yml +++ b/docker/devnet/docker-compose.yml @@ -1,17 +1,9 @@ version: '2' services: - redis: - image: "redis:alpine" - container_name: ark-redis - ports: - - '127.0.0.1:6379:6379' - volumes: - - 'redis:/data' - postgres: image: "postgres:alpine" - container_name: ark-postgres + container_name: ark-devnet-postgres ports: - '127.0.0.1:5432:5432' volumes: @@ -24,7 +16,7 @@ services: ark-core: build: . image: ark-core - container_name: ark-core + container_name: ark-devnet-core ports: - "4002:4002" - "4003:4003" @@ -34,10 +26,8 @@ services: privileged: true links: - postgres - - redis depends_on: - postgres - - redis command: - /bin/sh - -c @@ -45,7 +35,6 @@ services: /entrypoint.sh volumes: - redis: postgres: ark-core: driver_opts: diff --git a/docker/devnet/entrypoint.sh b/docker/devnet/entrypoint.sh index 8c5cd35f25..f67d2d61e4 100755 --- a/docker/devnet/entrypoint.sh +++ b/docker/devnet/entrypoint.sh @@ -2,14 +2,11 @@ sysctl -w net.ipv4.conf.all.route_localnet=1 -POSTGRES=$(ping -c 1 ark-postgres | awk -F'[()]' '/PING/{print $2}') -REDIS=$(ping -c 1 ark-redis | awk -F'[()]' '/PING/{print $2}') -CORE=$(ping -c 1 ark-core | awk -F'[()]' '/PING/{print $2}') +POSTGRES=$(ping -c 1 ark-devnet-postgres | awk -F'[()]' '/PING/{print $2}') +CORE=$(ping -c 1 ark-devnet-core | awk -F'[()]' '/PING/{print $2}') iptables -I OUTPUT -t nat -o lo -d localhost -p tcp --dport 5432 -j DNAT --to-destination ${POSTGRES}:5432 iptables -I POSTROUTING -t nat -p tcp --dport 5432 -d ${POSTGRES} -j SNAT --to ${CORE} -iptables -I OUTPUT -t nat -o lo -d localhost -p tcp --dport 6379 -j DNAT --to-destination ${REDIS}:6379 -iptables -I POSTROUTING -t nat -p tcp --dport 6379 -d ${REDIS} -j SNAT --to ${CORE} cd /ark-core rm -rf node_modules package-lock.json > /dev/null 2>&1 diff --git a/docker/devnet/purge_all.sh b/docker/devnet/purge_all.sh index bf255642ac..7be429bc03 100755 --- a/docker/devnet/purge_all.sh +++ b/docker/devnet/purge_all.sh @@ -2,6 +2,6 @@ docker stop $(docker ps -aq) docker rm $(docker ps -aq) -#docker rmi $(docker images -q) -docker volume prune -f +docker rmi $(docker images -q) +docker volume prune -f docker network prune -f diff --git a/docker/mainnet/docker-compose.yml b/docker/mainnet/docker-compose.yml new file mode 100644 index 0000000000..213e11d607 --- /dev/null +++ b/docker/mainnet/docker-compose.yml @@ -0,0 +1,20 @@ +# +# For running some services on development without tainting your system +# +version: '2' +services: + + postgres: + image: "postgres:alpine" + container_name: ark-mainnet-postgres + ports: + - '127.0.0.1:5432:5432' + volumes: + - 'postgres:/var/lib/postgresql/data' + environment: + POSTGRES_PASSWORD: password + POSTGRES_DB: ark_mainnet + POSTGRES_USER: ark + +volumes: + postgres: diff --git a/docker/testnet/Dockerfile b/docker/testnet/Dockerfile index de8c3948cd..e47f4a08ea 100644 --- a/docker/testnet/Dockerfile +++ b/docker/testnet/Dockerfile @@ -1,4 +1,4 @@ -FROM node:9 +FROM node:10 WORKDIR /ark-core @@ -13,5 +13,5 @@ RUN apt-get update && \ vim && \ rm -rf /var/lib/apt/lists/* -EXPOSE 4000 4003 +EXPOSE 4000 4003 diff --git a/docker/testnet/docker-compose.yml b/docker/testnet/docker-compose.yml index ebd7e19c7b..9d42e85a7c 100644 --- a/docker/testnet/docker-compose.yml +++ b/docker/testnet/docker-compose.yml @@ -1,17 +1,9 @@ version: '2' services: - redis: - image: "redis:alpine" - container_name: ark-redis - ports: - - '127.0.0.1:6379:6379' - volumes: - - 'redis:/data' - postgres: image: "postgres:alpine" - container_name: ark-postgres + container_name: ark-testnet-postgres ports: - '127.0.0.1:5432:5432' volumes: @@ -24,7 +16,7 @@ services: ark-core: build: . image: ark-core - container_name: ark-core + container_name: ark-testnet-core ports: - "4000:4000" - "4003:4003" @@ -34,10 +26,8 @@ services: privileged: true links: - postgres - - redis depends_on: - postgres - - redis command: - /bin/sh - -c @@ -45,7 +35,6 @@ services: /entrypoint.sh volumes: - redis: postgres: ark-core: driver_opts: diff --git a/docker/testnet/entrypoint.sh b/docker/testnet/entrypoint.sh index 8c5cd35f25..0fcd93ea11 100755 --- a/docker/testnet/entrypoint.sh +++ b/docker/testnet/entrypoint.sh @@ -2,14 +2,11 @@ sysctl -w net.ipv4.conf.all.route_localnet=1 -POSTGRES=$(ping -c 1 ark-postgres | awk -F'[()]' '/PING/{print $2}') -REDIS=$(ping -c 1 ark-redis | awk -F'[()]' '/PING/{print $2}') -CORE=$(ping -c 1 ark-core | awk -F'[()]' '/PING/{print $2}') +POSTGRES=$(ping -c 1 ark-testnet-postgres | awk -F'[()]' '/PING/{print $2}') +CORE=$(ping -c 1 ark-testnet-core | awk -F'[()]' '/PING/{print $2}') iptables -I OUTPUT -t nat -o lo -d localhost -p tcp --dport 5432 -j DNAT --to-destination ${POSTGRES}:5432 iptables -I POSTROUTING -t nat -p tcp --dport 5432 -d ${POSTGRES} -j SNAT --to ${CORE} -iptables -I OUTPUT -t nat -o lo -d localhost -p tcp --dport 6379 -j DNAT --to-destination ${REDIS}:6379 -iptables -I POSTROUTING -t nat -p tcp --dport 6379 -d ${REDIS} -j SNAT --to ${CORE} cd /ark-core rm -rf node_modules package-lock.json > /dev/null 2>&1 diff --git a/jest.config.js b/jest.config.js index b0e8265348..febc94cc95 100644 --- a/jest.config.js +++ b/jest.config.js @@ -2,53 +2,10 @@ module.exports = { bail: false, verbose: true, testEnvironment: 'node', - testMatch: [ - // '**/packages/**/__tests__/**/*.test.js' - - '**/packages/client/**/__tests__/**/*.test.js', - '**/packages/core-config/**/__tests__/**/*.test.js', - '**/packages/core-container/**/__tests__/**/*.test.js', - '**/packages/core-deployer/**/__tests__/**/*.test.js', - '**/packages/core-event-emitter/**/__tests__/**/*.test.js', - '**/packages/core-logger-winston/**/__tests__/**/*.test.js', - '**/packages/core-logger/**/__tests__/**/*.test.js', - '**/packages/core-test-utils/**/__tests__/**/*.test.js', - '**/packages/core-tester-cli/**/__tests__/**/*.test.js', - '**/packages/core-transaction-pool-redis/**/__tests__/**/*.test.js', - '**/packages/core-webhooks/**/__tests__/**/*.test.js', - '**/packages/validation/**/__tests__/**/*.test.js', - '**/packages/core-database-sequelize/**/__tests__/**/*.test.js' - - /* These packages have failing tests */ - - /* These packages don't have any test yet */ - - // '**/packages/core-graphql/**/__tests__/**/*.test.js', - // '**/packages/core/**/__tests__/**/*.test.js', - - /* These packages `runInBand` */ - - // '**/packages/core-api/**/__tests__/**/*.test.js', - - /* These packages have very long timeouts or don't end properly */ - - // '**/packages/core-blockchain/**/__tests__/**/*.test.js', - // '**/packages/core-database/**/__tests__/**/*.test.js', - // '**/packages/core-forger/**/__tests__/**/*.test.js', - // '**/packages/core-json-rpc/**/__tests__/**/*.test.js', - // '**/packages/core-p2p/**/__tests__/**/*.test.js', - // '**/packages/core-transaction-pool/**/__tests__/**/*.test.js', - // '**/packages/crypto/**/__tests__/**/*.test.js' - ], - moduleFileExtensions: [ - 'js', - 'json' - ], + testMatch: ['**/packages/**/__tests__/**/*.test.js'], + moduleFileExtensions: ['js', 'json'], coverageDirectory: '/.coverage', - collectCoverageFrom: [ - 'packages/**/lib/**/*.js', - '!**/node_modules/**' - ], + collectCoverageFrom: ['packages/**/lib/**/*.js', '!**/node_modules/**'], watchman: false, - setupTestFrameworkScriptFile: 'jest-extended' + setupTestFrameworkScriptFile: 'jest-extended', } diff --git a/lerna.json b/lerna.json index 5f622ca369..6fa44c3962 100644 --- a/lerna.json +++ b/lerna.json @@ -1,9 +1,6 @@ { "lerna": "2.10.0", - "packages": [ - "packages/*", - "plugins/*" - ], + "packages": ["packages/*", "plugins/*"], "npmClient": "yarn", "useWorkspaces": true, "version": "independent" diff --git a/package.json b/package.json index a7ff4d9f25..4a8843df7c 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,6 @@ "private": true, "scripts": { "bootstrap": "lerna bootstrap", - "build:docs": "lerna run build:docs", "clean": "lerna clean", "commit": "git-cz", "lint": "lerna run lint", @@ -10,39 +9,45 @@ "prepare": "lerna run prepare", "test": "cross-env ARK_ENV=test jest --runInBand --detectOpenHandles", "test:force-exit": "cross-env ARK_ENV=test jest --runInBand --forceExit", - "test:coverage": "cross-env ARK_ENV=test jest --coverage --runInBand --detectOpenHandles" + "test:coverage": "cross-env ARK_ENV=test jest --coverage --coveragePathIgnorePatterns='/(defaults.js|index.js)$' --runInBand --detectOpenHandles", + "format": "prettier --write \"./*.{js,json,md}\" \"./packages/**/*.{js,json,md}\"", + "snyk": "./node_modules/.bin/snyk protect" }, "devDependencies": { - "@babel/core": "^7.0.0-beta.51", - "@babel/preset-env": "^7.0.0-beta.51", + "@arkecosystem/eslint-config-base": "^0.1.0", + "@babel/core": "^7.1.6", + "@babel/preset-env": "^7.1.6", "axios": "^0.18.0", - "babel-loader": "^8.0.0-beta", + "babel-loader": "^8.0.4", "body-parser": "^1.18.3", - "codecov": "^3.0.4", + "codecov": "^3.1.0", "cross-env": "^5.2.0", - "depcheck": "^0.6.9", - "docdash": "^0.4.0", - "eslint": "^4.19.1", - "eslint-config-standard": "^11.0.0", - "eslint-plugin-import": "^2.12.0", - "eslint-plugin-node": "^6.0.1", - "eslint-plugin-promise": "^3.7.0", - "eslint-plugin-standard": "^3.1.0", - "express": "^4.16.3", - "husky": "^1.0.0-rc.2", - "jest": "^23.3.0", - "jest-extended": "^0.7.2", - "jsdoc": "^3.5.5", - "lerna": "^2.11.0", - "lint-staged": "^7.1.2", - "regenerator-runtime": "^0.11.1", + "depcheck": "^0.6.11", + "docdash": "^1.0.0", + "eslint": "^5.9.0", + "eslint-config-airbnb-base": "^13.1.0", + "eslint-config-prettier": "^3.3.0", + "eslint-plugin-import": "^2.14.0", + "eslint-plugin-jest": "^22.1.0", + "eslint-plugin-node": "^8.0.0", + "eslint-plugin-promise": "^4.0.1", + "express": "^4.16.4", + "husky": "^1.2.0", + "jest": "^23.6.0", + "jest-extended": "^0.11.0", + "js-yaml": "^3.12.0", + "lerna": "^3.5.0", + "lint-staged": "^8.1.0", + "npm-check-updates": "^2.15.0", + "prettier": "^1.15.2", + "regenerator-runtime": "^0.13.1", "request-promise": "^4.2.2", "rimraf": "^2.6.2", - "standard": "^11.0.1", - "uuid": "^3.2.1", - "webpack": "^4.8.3", - "webpack-cli": "^2.1.3", - "webpack-merge": "^4.1.2", + "snyk": "^1.111.1", + "uuid": "^3.3.2", + "webpack": "^4.26.1", + "webpack-cli": "^3.1.2", + "webpack-merge": "^4.1.4", "webpack-node-externals": "^1.7.2" }, "workspaces": [ @@ -51,12 +56,7 @@ ], "husky": { "hooks": { - "pre-commit": "lint-staged" + "pre-commit": "lint-staged && ./scripts/pre-commit.sh" } - }, - "lint-staged": { - "*.js": [ - "eslint --fix" - ] } } diff --git a/packages/client/README.md b/packages/client/README.md deleted file mode 100644 index 2ced04688c..0000000000 --- a/packages/client/README.md +++ /dev/null @@ -1,54 +0,0 @@ -![ARK Core](banner.png) - -# ARK - Client - -## Installation - -### Node.js - -```bash -yarn add @arkecosystem/client -``` - -If you want to use the CDN version: - -```html - -``` - -## Usage - -Import the library in Node.js: - -``` -import ArkEcosystemClient from @arkecosystem/client -``` -or -``` -const ArkEcosystemClient require('@arkecosystem/client') -``` - -Use the library: - -``` -const client = new ArkEcosystemClient('') -``` - -### Examples -There are more examples in the `examples` folder. - -## Security - -If you discover a security vulnerability within this package, please send an e-mail to security@ark.io. All security vulnerabilities will be promptly addressed. - -## Credits - -- [Brian Faust](https://github.com/faustbrian) -- [Lúcio Rubens](https://github.com/luciorubeens) -- [Alex Barnsley](https://github.com/alexbarnsley) -- [Juan A. Martín](https://github.com/j-a-m-l) -- [All Contributors](../../../../contributors) - -## License - -[MIT](LICENSE) © [ArkEcosystem](https://ark.io) diff --git a/packages/client/__tests__/client.test.js b/packages/client/__tests__/client.test.js deleted file mode 100644 index 4c106cecb5..0000000000 --- a/packages/client/__tests__/client.test.js +++ /dev/null @@ -1,189 +0,0 @@ -const axios = require('axios') -const MockAdapter = require('axios-mock-adapter') -const httpMock = new MockAdapter(axios) -const { arrayContaining } = expect - -const Client = require('../lib') -const HttpClient = require('../lib/http') -const ApiResource = require('../lib/resources/v1/transactions') -const initialPeers = require('../lib/peers') - -// https://github.com/facebook/jest/issues/3601 -const errorCapturer = fn => fn.then(res => () => res).catch(err => () => { throw err }) - -const host = 'https://example.net:4003' -const { peers } = require('./fixtures/peers') - -let client - -beforeEach(() => { - client = (new Client(host)) -}) - -describe('API - Client', () => { - describe('constructor', () => { - it('should be instantiated', () => { - expect(client).toBeInstanceOf(Client) - }) - - it('should set connection', () => { - expect(client.http).toBeInstanceOf(HttpClient) - }) - - it('should return an API resource', () => { - expect(client.resource('transactions')).toBeInstanceOf(ApiResource) - }) - - it('should use 1 as the default API version', () => { - expect(client.version).toBe(1) - }) - - it('should set the API version', () => { - client = (new Client('https://localhost:4003', 3)) - expect(client.version).toBe(3) - }) - - it('should set the HTTP client API version', () => { - client = (new Client('https://localhost:4003', 3)) - expect(client.getConnection().version).toBe(3) - }) - }) - - describe('setVersion', () => { - it('should set the API version', () => { - client.setVersion(2) - - expect(client.version).toBe(2) - }) - - it('should set the API version of the HTTP client too', () => { - client.setVersion(2) - - expect(client.http.version).toBe(2) - }) - - it('should throw an Error if the API version is falsy', async () => { - expect(client.setVersion).toThrowError(/api.*version/i) - }) - }) - - describe('static findPeers', () => { - it('should throw an Error if the network does not have initial peers', async () => { - expect(await errorCapturer(Client.findPeers('wrong'))).toThrowError(/network.*wrong/i) - }) - - xit('should connect randomly to the initial peers', () => { - }) - - it('should return a sorted list of peers', async () => { - const data = { - success: true, - peers - } - - peers.forEach(peer => { - httpMock.onGet(/http.*\/api\/peers/).reply(200, { data }) - }) - - const foundPeers = await Client.findPeers('devnet') - expect(foundPeers).toEqual([ - peers[1], - peers[3], - peers[0], - peers[2] - ]) - }) - - it('should ignore local peers', async () => { - const ips = ['127.0.0.1', '::ffff:127.0.0.1', '::1'] - - expect.assertions(ips.length * 2) - - for (const ip of ips) { - const localPeer = { - ip, - height: 3663605, - status: 'OK', - delay: 17 - } - const data = { - success: true, - peers: peers.concat([localPeer]) - } - - peers.forEach(peer => { - httpMock.onGet(/http.*\/api\/peers/).reply(200, { data }) - }) - - const foundPeers = await Client.findPeers('devnet') - expect(foundPeers).toEqual(arrayContaining(peers)) - expect(foundPeers).not.toContainEqual(localPeer) - } - }) - - it('should ignore not-OK peers', async () => { - const notOkPeer = { - ip: '7.7.7.7', - port: 3333, - height: 3663605, - status: 'not OK', - delay: 17 - } - const data = { - success: true, - peers: peers.concat([notOkPeer]) - } - - peers.forEach(peer => { - httpMock.onGet(/http.*\/api\/peers/).reply(200, { data }) - }) - - const foundPeers = await Client.findPeers('devnet') - expect(foundPeers).toEqual(arrayContaining(peers)) - expect(foundPeers).not.toContainEqual(notOkPeer) - }) - - xdescribe('when a peer is not valid', () => { - it('tries others', () => { - }) - }) - - describe('when the request to find peers fails', () => { - beforeEach(() => { - peers.forEach(peer => { - httpMock.onGet(/http.*\/api\/peers/).reply(500) - }) - }) - - it('returns the list of initial (hardcoded) peers', async () => { - const foundPeers = await Client.findPeers('devnet') - expect(foundPeers).not.toEqual(arrayContaining(peers)) - expect(foundPeers).toEqual(arrayContaining(initialPeers.devnet)) - }) - }) - }) - - describe('static connect', () => { - it('should throw an Error if the network does not have initial peers', async () => { - try { - expect(async () => Client.connect('wrong')).toThrow() - expect().fail('Should fail on the previous line') - } catch (error) { - expect(error).toBeInstanceOf(Error) - } - }) - - it('should find peers and connect to the most updated and less delayed', async () => { - const data = { - success: true, - peers - } - peers.forEach(peer => { - httpMock.onGet(/http.*\/api\/peers/).reply(200, { data }) - }) - - const client = await Client.connect('devnet') - expect(client.getConnection().host).toEqual(`http://${peers[1].ip}:${peers[1].port}`) - }) - }) -}) diff --git a/packages/client/__tests__/fixtures/peers.js b/packages/client/__tests__/fixtures/peers.js deleted file mode 100644 index 30e93c32a3..0000000000 --- a/packages/client/__tests__/fixtures/peers.js +++ /dev/null @@ -1,47 +0,0 @@ -const peer1 = { - ip: '1.1.1.1', - port: 4002, - version: '1.1.1', - errors: 0, - os: 'linux', - height: 3663605, - status: 'OK', - delay: 217 -} -const peer2 = { - ip: '2.2.2.2', - port: 4002, - version: '1.1.1', - errors: 0, - os: 'linux', - height: 3663608, - status: 'OK', - delay: 21 -} -const peer3 = { - ip: '3.3.3.3', - port: 4002, - version: '1.1.1', - errors: 0, - os: 'linux', - height: 3663600, - status: 'OK', - delay: 19 -} -const peer4 = { - ip: '4.4.4.4', - port: 4002, - version: '1.1.1', - errors: 0, - os: 'linux', - height: 3663605, - status: 'OK', - delay: 17 -} - -exports.peers = [peer1, peer2, peer3, peer4] - -exports.peer1 = peer1 -exports.peer2 = peer2 -exports.peer3 = peer3 -exports.peer4 = peer4 diff --git a/packages/client/__tests__/http.test.js b/packages/client/__tests__/http.test.js deleted file mode 100644 index 3de561e273..0000000000 --- a/packages/client/__tests__/http.test.js +++ /dev/null @@ -1,169 +0,0 @@ -const axios = require('axios') -const MockAdapter = require('axios-mock-adapter') -const mock = new MockAdapter(axios) - -const toHaveAtLeastHeaders = require('./matchers/http/headers') -expect.extend({ toHaveAtLeastHeaders }) - -const HttpClient = require('../lib/http') - -const host = 'http://example.net' -let client - -beforeEach(() => { - client = new HttpClient(host, 2) -}) - -describe('API - HTTP Client', () => { - let headers - - beforeEach(() => { - headers = { - 'API-Version': client.version - } - }) - - describe('constructor', () => { - it('should be instantiated', () => { - expect(client).toBeInstanceOf(HttpClient) - }) - - describe('host', () => { - it('should set the host', () => { - client = new HttpClient(host) - expect(client.host).toBe(host) - }) - - it('should remove the final slash of the host when necessary', () => { - client = new HttpClient('http://example.net/') - expect(client.host).toBe('http://example.net') - }) - - it('should check that the host is not empty', () => { - expect(() => new HttpClient('')).toThrow() - }) - }) - - describe('API version parameter', () => { - it('should set the API version', () => { - client = new HttpClient(host, 3) - expect(client.version).toBe(3) - }) - - it('should use 1 when is not present', () => { - client = new HttpClient(host) - expect(client.version).toBe(1) - }) - }) - }) - - describe('setTimeout', () => { - it('should set the timeout', () => { - expect(client.timeout).toBe(60000) - client.setTimeout(5000) - expect(client.timeout).toBe(5000) - }) - }) - - describe('setHeaders', () => { - it('should set the headers', () => { - const newHeaders = { - 'API-Version': 30, - other: 'value' - } - client.setHeaders(newHeaders) - - expect(client.headers).toEqual(newHeaders) - }) - }) - - describe('get', () => { - beforeEach(() => { - mock.onGet(`${host}/api/ENDPOINT`).reply(200, { data: [] }) - }) - - it('should send GET requests to the API', async () => { - const response = await client.get('ENDPOINT') - - expect(response.status).toBe(200) - }) - - it('should use the necessary request headers', async () => { - const response = await client.get('ENDPOINT') - - expect(response.config).toHaveAtLeastHeaders(headers) - }) - }) - - describe('post', () => { - beforeEach(() => { - mock.onPost(`${host}/api/ENDPOINT`).reply(200, { data: [] }) - }) - - it('should send POST requests to the API', async () => { - const response = await client.post('ENDPOINT') - - expect(response.status).toBe(200) - }) - - it('should use the necessary request headers', async () => { - const response = await client.post('ENDPOINT') - - expect(response.config).toHaveAtLeastHeaders(headers) - }) - }) - - describe('put', () => { - beforeEach(() => { - mock.onPut(`${host}/api/ENDPOINT`).reply(200, { data: [] }) - }) - - it('should send PUT requests to the API', async () => { - const response = await client.put('ENDPOINT') - - expect(response.status).toBe(200) - }) - - it('should use the necessary request headers', async () => { - const response = await client.put('ENDPOINT') - - expect(response.config).toHaveAtLeastHeaders(headers) - }) - }) - - describe('patch', () => { - beforeEach(() => { - mock.onPatch(`${host}/api/ENDPOINT`).reply(200, { data: [] }) - }) - - it('should send PATCH requests to the API', async () => { - const response = await client.patch('ENDPOINT') - - expect(response.status).toBe(200) - }) - - it('should use the necessary request headers', async () => { - const response = await client.patch('ENDPOINT') - - expect(response.config).toHaveAtLeastHeaders(headers) - }) - }) - - describe('delete', () => { - beforeEach(() => { - mock.onDelete(`${host}/api/ENDPOINT`).reply(200, { data: [] }) - }) - - it('should send DELETE requests to the API', async () => { - const response = await client.delete('ENDPOINT') - - expect(response.status).toBe(200) - }) - - it('should use the necessary request headers', async () => { - const response = await client.delete('ENDPOINT') - - expect(response.config).toHaveAtLeastHeaders(headers) - }) - }) -}) diff --git a/packages/client/__tests__/matchers/http/headers.js b/packages/client/__tests__/matchers/http/headers.js deleted file mode 100644 index 10452b6a07..0000000000 --- a/packages/client/__tests__/matchers/http/headers.js +++ /dev/null @@ -1,29 +0,0 @@ -'use strict' - -/** - * Check that the request configuration includes some headers with the expected - * values. The assertion is case insensitive. - */ -module.exports = (actual, expected) => { - const requestNormalizedHeaders = Object.keys(actual.headers).map(header => header.toLowerCase()) - - let found = 0 - for (const header in expected) { - const normalizedHeader = header.toLowerCase() - - if (requestNormalizedHeaders.indexOf(normalizedHeader) !== -1) { - const expectedValue = expected[header] - - if (expectedValue === actual.headers[header]) { - found++ - } else { - break - } - } - } - - return { - message: () => `Expected actual headers to include and match expected: ${JSON.stringify(actual)} vs. ${JSON.stringify(expected)}`, - pass: found === Object.keys(expected).length - } -} diff --git a/packages/client/__tests__/mocks/v1/accounts.js b/packages/client/__tests__/mocks/v1/accounts.js deleted file mode 100644 index d90bea488f..0000000000 --- a/packages/client/__tests__/mocks/v1/accounts.js +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = (mock, host) => { - mock.onGet(`${host}/api/accounts`).reply(200, { data: [] }) - mock.onGet(`${host}/api/accounts/count`).reply(200, { data: [] }) - mock.onGet(`${host}/api/accounts/delegates`).reply(200, { data: [] }) - mock.onGet(`${host}/api/accounts/delegates/fee`).reply(200, { data: [] }) - mock.onGet(`${host}/api/accounts/getAllAccounts`).reply(200, { data: [] }) - mock.onGet(`${host}/api/accounts/getBalance`).reply(200, { data: [] }) - mock.onGet(`${host}/api/accounts/getPublicKey`).reply(200, { data: [] }) - mock.onGet(`${host}/api/accounts/top`).reply(200, { data: [] }) -} diff --git a/packages/client/__tests__/mocks/v1/blocks.js b/packages/client/__tests__/mocks/v1/blocks.js deleted file mode 100644 index 7dd776200e..0000000000 --- a/packages/client/__tests__/mocks/v1/blocks.js +++ /dev/null @@ -1,13 +0,0 @@ -module.exports = (mock, host) => { - mock.onGet(`${host}/api/blocks`).reply(200, { data: [] }) - mock.onGet(`${host}/api/blocks/get`).reply(200, { data: [] }) - mock.onGet(`${host}/api/blocks/getEpoch`).reply(200, { data: [] }) - mock.onGet(`${host}/api/blocks/getFee`).reply(200, { data: [] }) - mock.onGet(`${host}/api/blocks/getFees`).reply(200, { data: [] }) - mock.onGet(`${host}/api/blocks/getHeight`).reply(200, { data: [] }) - mock.onGet(`${host}/api/blocks/getMilestone`).reply(200, { data: [] }) - mock.onGet(`${host}/api/blocks/getNethash`).reply(200, { data: [] }) - mock.onGet(`${host}/api/blocks/getReward`).reply(200, { data: [] }) - mock.onGet(`${host}/api/blocks/getStatus`).reply(200, { data: [] }) - mock.onGet(`${host}/api/blocks/getSupply`).reply(200, { data: [] }) -} diff --git a/packages/client/__tests__/mocks/v1/delegates.js b/packages/client/__tests__/mocks/v1/delegates.js deleted file mode 100644 index e23e4e13f1..0000000000 --- a/packages/client/__tests__/mocks/v1/delegates.js +++ /dev/null @@ -1,9 +0,0 @@ -module.exports = (mock, host) => { - mock.onGet(`${host}/api/delegates`).reply(200, { data: [] }) - mock.onGet(`${host}/api/delegates/count`).reply(200, { data: [] }) - mock.onGet(`${host}/api/delegates/fee`).reply(200, { data: [] }) - mock.onGet(`${host}/api/delegates/forging/getForgedByAccount`).reply(200, { data: [] }) - mock.onGet(`${host}/api/delegates/get`).reply(200, { data: [] }) - mock.onGet(`${host}/api/delegates/search`).reply(200, { data: [] }) - mock.onGet(`${host}/api/delegates/voters`).reply(200, { data: [] }) -} diff --git a/packages/client/__tests__/mocks/v1/index.js b/packages/client/__tests__/mocks/v1/index.js deleted file mode 100644 index 8a99bf0ee5..0000000000 --- a/packages/client/__tests__/mocks/v1/index.js +++ /dev/null @@ -1,25 +0,0 @@ -const axios = require('axios') -const MockAdapter = require('axios-mock-adapter') - -const Accounts = require('./accounts') -const Blocks = require('./blocks') -const Delegates = require('./delegates') -const Loader = require('./loader') -const Peers = require('./peers') -const Signatures = require('./signatures') -const Transactions = require('./transactions') - -module.exports = config => { - const mock = new MockAdapter(axios) - const { host } = config - - Accounts(mock, host) - Blocks(mock, host) - Delegates(mock, host) - Loader(mock, host) - Peers(mock, host) - Signatures(mock, host) - Transactions(mock, host) - - return mock -} diff --git a/packages/client/__tests__/mocks/v1/loader.js b/packages/client/__tests__/mocks/v1/loader.js deleted file mode 100644 index 371072fb60..0000000000 --- a/packages/client/__tests__/mocks/v1/loader.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = (mock, host) => { - mock.onGet(`${host}/api/loader/autoconfigure`).reply(200, { data: [] }) - mock.onGet(`${host}/api/loader/status`).reply(200, { data: [] }) - mock.onGet(`${host}/api/loader/status/sync`).reply(200, { data: [] }) -} diff --git a/packages/client/__tests__/mocks/v1/peers.js b/packages/client/__tests__/mocks/v1/peers.js deleted file mode 100644 index 5674bf0aa2..0000000000 --- a/packages/client/__tests__/mocks/v1/peers.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = (mock, host) => { - mock.onGet(`${host}/api/peers`).reply(200, { data: [] }) - mock.onGet(`${host}/api/peers/get`).reply(200, { data: [] }) - mock.onGet(`${host}/api/peers/version`).reply(200, { data: [] }) -} diff --git a/packages/client/__tests__/mocks/v1/signatures.js b/packages/client/__tests__/mocks/v1/signatures.js deleted file mode 100644 index 53b2f9e570..0000000000 --- a/packages/client/__tests__/mocks/v1/signatures.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = (mock, host) => { - mock.onGet(`${host}/api/signatures/fee`).reply(200, { data: [] }) -} diff --git a/packages/client/__tests__/mocks/v1/transactions.js b/packages/client/__tests__/mocks/v1/transactions.js deleted file mode 100644 index 2f87490dff..0000000000 --- a/packages/client/__tests__/mocks/v1/transactions.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = (mock, host) => { - mock.onGet(`${host}/api/transactions`).reply(200, { data: [] }) - mock.onGet(`${host}/api/transactions/get`).reply(200, { data: [] }) - mock.onGet(`${host}/api/transactions/unconfirmed`).reply(200, { data: [] }) - mock.onGet(`${host}/api/transactions/unconfirmed/get`).reply(200, { data: [] }) -} diff --git a/packages/client/__tests__/mocks/v2/blocks.js b/packages/client/__tests__/mocks/v2/blocks.js deleted file mode 100644 index 1d70110233..0000000000 --- a/packages/client/__tests__/mocks/v2/blocks.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = (mock, host) => { - mock.onGet(`${host}/api/blocks`).reply(200, { data: [] }) - mock.onGet(`${host}/api/blocks/123`).reply(200, { data: [] }) - mock.onGet(`${host}/api/blocks/123/transactions`).reply(200, { data: [] }) - mock.onPost(`${host}/api/blocks/search`).reply(200, { data: [] }) -} diff --git a/packages/client/__tests__/mocks/v2/delegates.js b/packages/client/__tests__/mocks/v2/delegates.js deleted file mode 100644 index 15bc7c2087..0000000000 --- a/packages/client/__tests__/mocks/v2/delegates.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = (mock, host) => { - mock.onGet(`${host}/api/delegates`).reply(200, { data: [] }) - mock.onGet(`${host}/api/delegates/123`).reply(200, { data: [] }) - mock.onGet(`${host}/api/delegates/123/blocks`).reply(200, { data: [] }) - mock.onGet(`${host}/api/delegates/123/voters`).reply(200, { data: [] }) -} diff --git a/packages/client/__tests__/mocks/v2/index.js b/packages/client/__tests__/mocks/v2/index.js deleted file mode 100644 index 0c29c511e1..0000000000 --- a/packages/client/__tests__/mocks/v2/index.js +++ /dev/null @@ -1,29 +0,0 @@ -const axios = require('axios') -const MockAdapter = require('axios-mock-adapter') - -const Blocks = require('./blocks') -const Delegates = require('./delegates') -const Node = require('./node') -const Peers = require('./peers') -const Statistics = require('./statistics') -const Transactions = require('./transactions') -const Votes = require('./votes') -const Wallets = require('./wallets') -const Webhooks = require('./webhooks') - -module.exports = config => { - const mock = new MockAdapter(axios) - const { host } = config - - Blocks(mock, host) - Delegates(mock, host) - Node(mock, host) - Peers(mock, host) - Statistics(mock, host) - Transactions(mock, host) - Votes(mock, host) - Wallets(mock, host) - Webhooks(mock, host) - - return mock -} diff --git a/packages/client/__tests__/mocks/v2/multisignatures.js b/packages/client/__tests__/mocks/v2/multisignatures.js deleted file mode 100644 index 4b14a66106..0000000000 --- a/packages/client/__tests__/mocks/v2/multisignatures.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = (mock, host) => { - mock.onGet(`${host}/api/multisignatures`).reply(200, { data: [] }) - mock.onGet(`${host}/api/multisignatures/pending`).reply(200, { data: [] }) - mock.onGet(`${host}/api/multisignatures/wallets`).reply(200, { data: [] }) -} diff --git a/packages/client/__tests__/mocks/v2/node.js b/packages/client/__tests__/mocks/v2/node.js deleted file mode 100644 index 1e54ee0193..0000000000 --- a/packages/client/__tests__/mocks/v2/node.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = (mock, host) => { - mock.onGet(`${host}/api/node/status`).reply(200, { data: [] }) - mock.onGet(`${host}/api/node/syncing`).reply(200, { data: [] }) - mock.onGet(`${host}/api/node/configuration`).reply(200, { data: [] }) -} diff --git a/packages/client/__tests__/mocks/v2/peers.js b/packages/client/__tests__/mocks/v2/peers.js deleted file mode 100644 index 75a52f16e1..0000000000 --- a/packages/client/__tests__/mocks/v2/peers.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = (mock, host) => { - mock.onGet(`${host}/api/peers`).reply(200, { data: [] }) - mock.onGet(`${host}/api/peers/123`).reply(200, { data: [] }) -} diff --git a/packages/client/__tests__/mocks/v2/signatures.js b/packages/client/__tests__/mocks/v2/signatures.js deleted file mode 100644 index 6ac7cf9673..0000000000 --- a/packages/client/__tests__/mocks/v2/signatures.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = (mock, host) => { - mock.onGet(`${host}/api/signatures`).reply(200, { data: [] }) -} diff --git a/packages/client/__tests__/mocks/v2/statistics.js b/packages/client/__tests__/mocks/v2/statistics.js deleted file mode 100644 index 0b352cb5f3..0000000000 --- a/packages/client/__tests__/mocks/v2/statistics.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = (mock, host) => { - mock.onGet(`${host}/api/statistics/blockchain`).reply(200, { data: [] }) - mock.onGet(`${host}/api/statistics/transactions`).reply(200, { data: [] }) - mock.onGet(`${host}/api/statistics/blocks`).reply(200, { data: [] }) - mock.onGet(`${host}/api/statistics/votes`).reply(200, { data: [] }) - mock.onGet(`${host}/api/statistics/unvotes`).reply(200, { data: [] }) -} diff --git a/packages/client/__tests__/mocks/v2/transactions.js b/packages/client/__tests__/mocks/v2/transactions.js deleted file mode 100644 index 31ef169309..0000000000 --- a/packages/client/__tests__/mocks/v2/transactions.js +++ /dev/null @@ -1,9 +0,0 @@ -module.exports = (mock, host) => { - mock.onGet(`${host}/api/transactions`).reply(200, { data: [] }) - mock.onPost(`${host}/api/transactions`).reply(200, { data: [] }) - mock.onGet(`${host}/api/transactions/123`).reply(200, { data: [] }) - mock.onGet(`${host}/api/transactions/unconfirmed`).reply(200, { data: [] }) - mock.onGet(`${host}/api/transactions/unconfirmed/123`).reply(200, { data: [] }) - mock.onPost(`${host}/api/transactions/search`).reply(200, { data: [] }) - mock.onGet(`${host}/api/transactions/types`).reply(200, { data: [] }) -} diff --git a/packages/client/__tests__/mocks/v2/votes.js b/packages/client/__tests__/mocks/v2/votes.js deleted file mode 100644 index 8a4b99d681..0000000000 --- a/packages/client/__tests__/mocks/v2/votes.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = (mock, host) => { - mock.onGet(`${host}/api/votes`).reply(200, { data: [] }) - mock.onGet(`${host}/api/votes/123`).reply(200, { data: [] }) -} diff --git a/packages/client/__tests__/mocks/v2/wallets.js b/packages/client/__tests__/mocks/v2/wallets.js deleted file mode 100644 index 19024b8575..0000000000 --- a/packages/client/__tests__/mocks/v2/wallets.js +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = (mock, host) => { - mock.onGet(`${host}/api/wallets`).reply(200, { data: [] }) - mock.onGet(`${host}/api/wallets/top`).reply(200, { data: [] }) - mock.onGet(`${host}/api/wallets/123`).reply(200, { data: [] }) - mock.onGet(`${host}/api/wallets/123/transactions`).reply(200, { data: [] }) - mock.onGet(`${host}/api/wallets/123/transactions/sent`).reply(200, { data: [] }) - mock.onGet(`${host}/api/wallets/123/transactions/received`).reply(200, { data: [] }) - mock.onGet(`${host}/api/wallets/123/votes`).reply(200, { data: [] }) - mock.onPost(`${host}/api/wallets/search`).reply(200, { data: [] }) -} diff --git a/packages/client/__tests__/mocks/v2/webhooks.js b/packages/client/__tests__/mocks/v2/webhooks.js deleted file mode 100644 index a64cea3b22..0000000000 --- a/packages/client/__tests__/mocks/v2/webhooks.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = (mock, host) => { - mock.onGet(`${host}/api/webhooks`).reply(200, { data: [] }) - mock.onPost(`${host}/api/webhooks`).reply(200, { data: [] }) - mock.onGet(`${host}/api/webhooks/123`).reply(200, { data: [] }) - mock.onPut(`${host}/api/webhooks/123`).reply(200, { data: [] }) - mock.onDelete(`${host}/api/webhooks/123`).reply(200, { data: [] }) - mock.onGet(`${host}/api/webhooks/events`).reply(200, { data: [] }) -} diff --git a/packages/client/__tests__/resources/v1/accounts.test.js b/packages/client/__tests__/resources/v1/accounts.test.js deleted file mode 100644 index f5fde3319a..0000000000 --- a/packages/client/__tests__/resources/v1/accounts.test.js +++ /dev/null @@ -1,66 +0,0 @@ -const Client = require('../../../lib') -const ApiResource = require('../../../lib/resources/v1/accounts') - -const configureMocks = require('../../mocks/v1') -const host = 'https://example.net:4003' -configureMocks({ host }) - -let resource - -beforeEach(() => { - resource = (new Client(host)).setVersion(1).resource('accounts') -}) - -describe('API - 1.0 - Resources - Accounts', () => { - it('should be instantiated', () => { - expect(resource).toBeInstanceOf(ApiResource) - }) - - it('should call "all" method', async () => { - const response = await resource.all({}) - - expect(response.status).toBe(200) - }) - - it('should call "get" method', async () => { - const response = await resource.get('123') - - expect(response.status).toBe(200) - }) - - it('should call "count" method', async () => { - const response = await resource.count() - - expect(response.status).toBe(200) - }) - - it('should call "delegates" method', async () => { - const response = await resource.delegates('123') - - expect(response.status).toBe(200) - }) - - it('should call "fee" method', async () => { - const response = await resource.fee() - - expect(response.status).toBe(200) - }) - - it('should call "balance" method', async () => { - const response = await resource.balance('123') - - expect(response.status).toBe(200) - }) - - it('should call "publicKey" method', async () => { - const response = await resource.publicKey('123') - - expect(response.status).toBe(200) - }) - - it('should call "top" method', async () => { - const response = await resource.top({}) - - expect(response.status).toBe(200) - }) -}) diff --git a/packages/client/__tests__/resources/v1/blocks.test.js b/packages/client/__tests__/resources/v1/blocks.test.js deleted file mode 100644 index a90e50a35d..0000000000 --- a/packages/client/__tests__/resources/v1/blocks.test.js +++ /dev/null @@ -1,84 +0,0 @@ -const Client = require('../../../lib') -const ApiResource = require('../../../lib/resources/v1/blocks') - -const configureMocks = require('../../mocks/v1') -const host = 'https://example.net:4003' -configureMocks({ host }) - -let resource - -beforeEach(() => { - resource = (new Client(host)).setVersion(1).resource('blocks') -}) - -describe('API - 1.0 - Resources - Blocks', () => { - it('should be instantiated', () => { - expect(resource).toBeInstanceOf(ApiResource) - }) - - it('should call "all" method', async () => { - const response = await resource.all({}) - - expect(response.status).toBe(200) - }) - - it('should call "get" method', async () => { - const response = await resource.get(123) - - expect(response.status).toBe(200) - }) - - it('should call "epoch" method', async () => { - const response = await resource.epoch() - - expect(response.status).toBe(200) - }) - - it('should call "fee" method', async () => { - const response = await resource.fee() - - expect(response.status).toBe(200) - }) - - it('should call "fees" method', async () => { - const response = await resource.fees() - - expect(response.status).toBe(200) - }) - - it('should call "height" method', async () => { - const response = await resource.height() - - expect(response.status).toBe(200) - }) - - it('should call "milestone" method', async () => { - const response = await resource.milestone() - - expect(response.status).toBe(200) - }) - - it('should call "nethash" method', async () => { - const response = await resource.nethash() - - expect(response.status).toBe(200) - }) - - it('should call "reward" method', async () => { - const response = await resource.reward() - - expect(response.status).toBe(200) - }) - - it('should call "status" method', async () => { - const response = await resource.status() - - expect(response.status).toBe(200) - }) - - it('should call "supply" method', async () => { - const response = await resource.supply() - - expect(response.status).toBe(200) - }) -}) diff --git a/packages/client/__tests__/resources/v1/delegates.test.js b/packages/client/__tests__/resources/v1/delegates.test.js deleted file mode 100644 index 8e8fe6c62d..0000000000 --- a/packages/client/__tests__/resources/v1/delegates.test.js +++ /dev/null @@ -1,60 +0,0 @@ -const Client = require('../../../lib') -const ApiResource = require('../../../lib/resources/v1/delegates') - -const configureMocks = require('../../mocks/v1') -const host = 'https://example.net:4003' -configureMocks({ host }) - -let resource - -beforeEach(() => { - resource = (new Client(host)).setVersion(1).resource('delegates') -}) - -describe('API - 1.0 - Resources - Delegates', () => { - it('should be instantiated', () => { - expect(resource).toBeInstanceOf(ApiResource) - }) - - it('should call "all" method', async () => { - const response = await resource.all({}) - - expect(response.status).toBe(200) - }) - - it('should call "get" method', async () => { - const response = await resource.get('123') - - expect(response.status).toBe(200) - }) - - it('should call "count" method', async () => { - const response = await resource.count() - - expect(response.status).toBe(200) - }) - - it('should call "fee" method', async () => { - const response = await resource.fee() - - expect(response.status).toBe(200) - }) - - it('should call "forged" method', async () => { - const response = await resource.forged('123') - - expect(response.status).toBe(200) - }) - - it('should call "search" method', async () => { - const response = await resource.search({}) - - expect(response.status).toBe(200) - }) - - it('should call "voters" method', async () => { - const response = await resource.voters('123') - - expect(response.status).toBe(200) - }) -}) diff --git a/packages/client/__tests__/resources/v1/loader.test.js b/packages/client/__tests__/resources/v1/loader.test.js deleted file mode 100644 index 4902f5afad..0000000000 --- a/packages/client/__tests__/resources/v1/loader.test.js +++ /dev/null @@ -1,36 +0,0 @@ -const Client = require('../../../lib') -const ApiResource = require('../../../lib/resources/v1/loader') - -const configureMocks = require('../../mocks/v1') -const host = 'https://example.net:4003' -configureMocks({ host }) - -let resource - -beforeEach(() => { - resource = (new Client(host)).setVersion(1).resource('loader') -}) - -describe('API - 1.0 - Resources - Loader', () => { - it('should be instantiated', () => { - expect(resource).toBeInstanceOf(ApiResource) - }) - - it('should call "status" method', async () => { - const response = await resource.status() - - expect(response.status).toBe(200) - }) - - it('should call "syncing" method', async () => { - const response = await resource.syncing() - - expect(response.status).toBe(200) - }) - - it('should call "configuration" method', async () => { - const response = await resource.configuration() - - expect(response.status).toBe(200) - }) -}) diff --git a/packages/client/__tests__/resources/v1/peers.test.js b/packages/client/__tests__/resources/v1/peers.test.js deleted file mode 100644 index db36fe637b..0000000000 --- a/packages/client/__tests__/resources/v1/peers.test.js +++ /dev/null @@ -1,36 +0,0 @@ -const Client = require('../../../lib') -const ApiResource = require('../../../lib/resources/v1/peers') - -const configureMocks = require('../../mocks/v1') -const host = 'https://example.net:4003' -configureMocks({ host }) - -let resource - -beforeEach(() => { - resource = (new Client(host)).setVersion(1).resource('peers') -}) - -describe('API - 1.0 - Resources - Peers', () => { - it('should be instantiated', () => { - expect(resource).toBeInstanceOf(ApiResource) - }) - - it('should call "all" method', async () => { - const response = await resource.all({}) - - expect(response.status).toBe(200) - }) - - it('should call "get" method', async () => { - const response = await resource.get('127.0.0.1', 4001) - - expect(response.status).toBe(200) - }) - - it('should call "version" method', async () => { - const response = await resource.version() - - expect(response.status).toBe(200) - }) -}) diff --git a/packages/client/__tests__/resources/v1/signatures.test.js b/packages/client/__tests__/resources/v1/signatures.test.js deleted file mode 100644 index 5e358bbcf1..0000000000 --- a/packages/client/__tests__/resources/v1/signatures.test.js +++ /dev/null @@ -1,24 +0,0 @@ -const Client = require('../../../lib') -const ApiResource = require('../../../lib/resources/v1/signatures') - -const configureMocks = require('../../mocks/v1') -const host = 'https://example.net:4003' -configureMocks({ host }) - -let resource - -beforeEach(() => { - resource = (new Client(host)).setVersion(1).resource('signatures') -}) - -describe('API - 1.0 - Resources - Signatures', () => { - it('should be instantiated', () => { - expect(resource).toBeInstanceOf(ApiResource) - }) - - it('should call "fee" method', async () => { - const response = await resource.fee() - - expect(response.status).toBe(200) - }) -}) diff --git a/packages/client/__tests__/resources/v1/transactions.test.js b/packages/client/__tests__/resources/v1/transactions.test.js deleted file mode 100644 index 0913912b83..0000000000 --- a/packages/client/__tests__/resources/v1/transactions.test.js +++ /dev/null @@ -1,42 +0,0 @@ -const Client = require('../../../lib') -const ApiResource = require('../../../lib/resources/v1/transactions') - -const configureMocks = require('../../mocks/v1') -const host = 'https://example.net:4003' -configureMocks({ host }) - -let resource - -beforeEach(() => { - resource = (new Client(host)).setVersion(1).resource('transactions') -}) - -describe('API - 1.0 - Resources - Transactions', () => { - it('should be instantiated', () => { - expect(resource).toBeInstanceOf(ApiResource) - }) - - it('should call "all" method', async () => { - const response = await resource.all({}) - - expect(response.status).toBe(200) - }) - - it('should call "get" method', async () => { - const response = await resource.get('123') - - expect(response.status).toBe(200) - }) - - it('should call "allUnconfirmed" method', async () => { - const response = await resource.allUnconfirmed({}) - - expect(response.status).toBe(200) - }) - - it('should call "getUnconfirmed" method', async () => { - const response = await resource.getUnconfirmed('123') - - expect(response.status).toBe(200) - }) -}) diff --git a/packages/client/__tests__/resources/v2/blocks.test.js b/packages/client/__tests__/resources/v2/blocks.test.js deleted file mode 100644 index 1955878c86..0000000000 --- a/packages/client/__tests__/resources/v2/blocks.test.js +++ /dev/null @@ -1,42 +0,0 @@ -const Client = require('../../../lib') -const ApiResource = require('../../../lib/resources/v2/blocks') - -const configureMocks = require('../../mocks/v2') -const host = 'https://example.net:4003' -configureMocks({ host }) - -let resource - -beforeEach(() => { - resource = (new Client(host)).setVersion(2).resource('blocks') -}) - -describe('API - 2.0 - Resources - Blocks', () => { - it('should be instantiated', () => { - expect(resource).toBeInstanceOf(ApiResource) - }) - - it('should call "all" method', async () => { - const response = await resource.all() - - expect(response.status).toBe(200) - }) - - it('should call "get" method', async () => { - const response = await resource.get('123') - - expect(response.status).toBe(200) - }) - - it('should call "transactions" method', async () => { - const response = await resource.transactions('123') - - expect(response.status).toBe(200) - }) - - it('should call "search" method', async () => { - const response = await resource.search({}) - - expect(response.status).toBe(200) - }) -}) diff --git a/packages/client/__tests__/resources/v2/delegates.test.js b/packages/client/__tests__/resources/v2/delegates.test.js deleted file mode 100644 index 62a874cacb..0000000000 --- a/packages/client/__tests__/resources/v2/delegates.test.js +++ /dev/null @@ -1,42 +0,0 @@ -const Client = require('../../../lib') -const ApiResource = require('../../../lib/resources/v2/delegates') - -const configureMocks = require('../../mocks/v2') -const host = 'https://example.net:4003' -configureMocks({ host }) - -let resource - -beforeEach(() => { - resource = (new Client(host)).setVersion(2).resource('delegates') -}) - -describe('API - 2.0 - Resources - Delegates', () => { - it('should be instantiated', () => { - expect(resource).toBeInstanceOf(ApiResource) - }) - - it('should call "all" method', async () => { - const response = await resource.all() - - expect(response.status).toBe(200) - }) - - it('should call "get" method', async () => { - const response = await resource.get('123') - - expect(response.status).toBe(200) - }) - - it('should call "blocks" method', async () => { - const response = await resource.blocks('123') - - expect(response.status).toBe(200) - }) - - it('should call "voters" method', async () => { - const response = await resource.voters('123') - - expect(response.status).toBe(200) - }) -}) diff --git a/packages/client/__tests__/resources/v2/node.test.js b/packages/client/__tests__/resources/v2/node.test.js deleted file mode 100644 index e680e4ffff..0000000000 --- a/packages/client/__tests__/resources/v2/node.test.js +++ /dev/null @@ -1,36 +0,0 @@ -const Client = require('../../../lib') -const ApiResource = require('../../../lib/resources/v2/node') - -const configureMocks = require('../../mocks/v2') -const host = 'https://example.net:4003' -configureMocks({ host }) - -let resource - -beforeEach(() => { - resource = (new Client(host)).setVersion(2).resource('node') -}) - -describe('API - 2.0 - Resources - Loader', () => { - it('should be instantiated', () => { - expect(resource).toBeInstanceOf(ApiResource) - }) - - it('should call "status" method', async () => { - const response = await resource.status() - - expect(response.status).toBe(200) - }) - - it('should call "syncing" method', async () => { - const response = await resource.syncing() - - expect(response.status).toBe(200) - }) - - it('should call "configuration" method', async () => { - const response = await resource.configuration() - - expect(response.status).toBe(200) - }) -}) diff --git a/packages/client/__tests__/resources/v2/peers.test.js b/packages/client/__tests__/resources/v2/peers.test.js deleted file mode 100644 index e9211f5015..0000000000 --- a/packages/client/__tests__/resources/v2/peers.test.js +++ /dev/null @@ -1,30 +0,0 @@ -const Client = require('../../../lib') -const ApiResource = require('../../../lib/resources/v2/peers') - -const configureMocks = require('../../mocks/v2') -const host = 'https://example.net:4003' -configureMocks({ host }) - -let resource - -beforeEach(() => { - resource = (new Client(host)).setVersion(2).resource('peers') -}) - -describe('API - 2.0 - Resources - Peers', () => { - it('should be instantiated', () => { - expect(resource).toBeInstanceOf(ApiResource) - }) - - it('should call "all" method', async () => { - const response = await resource.all() - - expect(response.status).toBe(200) - }) - - it('should call "get" method', async () => { - const response = await resource.get('123') - - expect(response.status).toBe(200) - }) -}) diff --git a/packages/client/__tests__/resources/v2/statistics.test.js b/packages/client/__tests__/resources/v2/statistics.test.js deleted file mode 100644 index bb86b815f3..0000000000 --- a/packages/client/__tests__/resources/v2/statistics.test.js +++ /dev/null @@ -1,48 +0,0 @@ -const Client = require('../../../lib') -const ApiResource = require('../../../lib/resources/v2/statistics') - -const configureMocks = require('../../mocks/v2') -const host = 'https://example.net:4003' -configureMocks({ host }) - -let resource - -beforeEach(() => { - resource = (new Client(host)).setVersion(2).resource('statistics') -}) - -describe('API - 2.0 - Resources - Statistics', () => { - it('should be instantiated', () => { - expect(resource).toBeInstanceOf(ApiResource) - }) - - it('should call "blockchain" method', async () => { - const response = await resource.blockchain() - - expect(response.status).toBe(200) - }) - - it('should call "transactions" method', async () => { - const response = await resource.transactions() - - expect(response.status).toBe(200) - }) - - it('should call "blocks" method', async () => { - const response = await resource.blocks() - - expect(response.status).toBe(200) - }) - - it('should call "votes" method', async () => { - const response = await resource.votes() - - expect(response.status).toBe(200) - }) - - it('should call "unvotes" method', async () => { - const response = await resource.unvotes() - - expect(response.status).toBe(200) - }) -}) diff --git a/packages/client/__tests__/resources/v2/transactions.test.js b/packages/client/__tests__/resources/v2/transactions.test.js deleted file mode 100644 index 49fdb3d600..0000000000 --- a/packages/client/__tests__/resources/v2/transactions.test.js +++ /dev/null @@ -1,60 +0,0 @@ -const Client = require('../../../lib') -const ApiResource = require('../../../lib/resources/v2/transactions') - -const configureMocks = require('../../mocks/v2') -const host = 'https://example.net:4003' -configureMocks({ host }) - -let resource - -beforeEach(() => { - resource = (new Client(host)).setVersion(2).resource('transactions') -}) - -describe('API - 2.0 - Resources - Transactions', () => { - it('should be instantiated', () => { - expect(resource).toBeInstanceOf(ApiResource) - }) - - it('should call "all" method', async () => { - const response = await resource.all() - - expect(response.status).toBe(200) - }) - - it('should call "create" method', async () => { - const response = await resource.create() - - expect(response.status).toBe(200) - }) - - it('should call "get" method', async () => { - const response = await resource.get('123') - - expect(response.status).toBe(200) - }) - - it('should call "allUnconfirmed" method', async () => { - const response = await resource.allUnconfirmed() - - expect(response.status).toBe(200) - }) - - it('should call "getUnconfirmed" method', async () => { - const response = await resource.getUnconfirmed('123') - - expect(response.status).toBe(200) - }) - - it('should call "search" method', async () => { - const response = await resource.search({}) - - expect(response.status).toBe(200) - }) - - it('should call "types" method', async () => { - const response = await resource.types() - - expect(response.status).toBe(200) - }) -}) diff --git a/packages/client/__tests__/resources/v2/votes.test.js b/packages/client/__tests__/resources/v2/votes.test.js deleted file mode 100644 index d42005e685..0000000000 --- a/packages/client/__tests__/resources/v2/votes.test.js +++ /dev/null @@ -1,28 +0,0 @@ -const Client = require('../../../lib') -const ApiResource = require('../../../lib/resources/v2/votes') - -const configureMocks = require('../../mocks/v2') -const host = 'https://example.net:4003' -configureMocks({ host }) - -let resource - -beforeEach(() => { - resource = (new Client(host)).setVersion(2).resource('votes') -}) - -describe('API - 2.0 - Resources - Voters', () => { - it('should be instantiated', () => { - expect(resource).toBeInstanceOf(ApiResource) - }) - - it('should call "all" method', async () => { - const response = await resource.all() - expect(response.status).toBe(200) - }) - - it('should call "get" method', async () => { - const response = await resource.get('123') - expect(response.status).toBe(200) - }) -}) diff --git a/packages/client/__tests__/resources/v2/wallets.test.js b/packages/client/__tests__/resources/v2/wallets.test.js deleted file mode 100644 index f8c0b1ac20..0000000000 --- a/packages/client/__tests__/resources/v2/wallets.test.js +++ /dev/null @@ -1,66 +0,0 @@ -const Client = require('../../../lib') -const ApiResource = require('../../../lib/resources/v2/wallets') - -const configureMocks = require('../../mocks/v2') -const host = 'https://example.net:4003' -configureMocks({ host }) - -let resource - -beforeEach(() => { - resource = (new Client(host)).setVersion(2).resource('wallets') -}) - -describe('API - 2.0 - Resources - Webhooks', () => { - it('should be instantiated', () => { - expect(resource).toBeInstanceOf(ApiResource) - }) - - it('should call "all" method', async () => { - const response = await resource.all() - - expect(response.status).toBe(200) - }) - - it('should call "top" method', async () => { - const response = await resource.top() - - expect(response.status).toBe(200) - }) - - it('should call "get" method', async () => { - const response = await resource.get('123') - - expect(response.status).toBe(200) - }) - - it('should call "transactions" method', async () => { - const response = await resource.transactions('123') - - expect(response.status).toBe(200) - }) - - it('should call "transactionsSent" method', async () => { - const response = await resource.transactionsSent('123') - - expect(response.status).toBe(200) - }) - - it('should call "transactionsReceived" method', async () => { - const response = await resource.transactionsReceived('123') - - expect(response.status).toBe(200) - }) - - it('should call "votes" method', async () => { - const response = await resource.votes('123') - - expect(response.status).toBe(200) - }) - - it('should call "search" method', async () => { - const response = await resource.search({}) - - expect(response.status).toBe(200) - }) -}) diff --git a/packages/client/__tests__/resources/v2/webhooks.test.js b/packages/client/__tests__/resources/v2/webhooks.test.js deleted file mode 100644 index c971d08503..0000000000 --- a/packages/client/__tests__/resources/v2/webhooks.test.js +++ /dev/null @@ -1,54 +0,0 @@ -const Client = require('../../../lib') -const ApiResource = require('../../../lib/resources/v2/webhooks') - -const configureMocks = require('../../mocks/v2') -const host = 'https://example.net:4003' -configureMocks({ host }) - -let resource - -beforeEach(() => { - resource = (new Client(host)).setVersion(2).resource('webhooks') -}) - -describe('API - 2.0 - Resources - Blocks', () => { - it('should be instantiated', () => { - expect(resource).toBeInstanceOf(ApiResource) - }) - - it('should call "all" method', async () => { - const response = await resource.all() - - expect(response.status).toBe(200) - }) - - it('should call "create" method', async () => { - const response = await resource.create() - - expect(response.status).toBe(200) - }) - - it('should call "get" method', async () => { - const response = await resource.get('123') - - expect(response.status).toBe(200) - }) - - it('should call "update" method', async () => { - const response = await resource.update('123') - - expect(response.status).toBe(200) - }) - - it('should call "delete" method', async () => { - const response = await resource.delete('123') - - expect(response.status).toBe(200) - }) - - it('should call "events" method', async () => { - const response = await resource.events() - - expect(response.status).toBe(200) - }) -}) diff --git a/packages/client/__tests__/utils/sort-peers.test.js b/packages/client/__tests__/utils/sort-peers.test.js deleted file mode 100644 index 815c12bb66..0000000000 --- a/packages/client/__tests__/utils/sort-peers.test.js +++ /dev/null @@ -1,41 +0,0 @@ -const sortPeers = require('../../lib/utils/sort-peers') - -describe('API - Utils - sortPeers', () => { - const peers = [ - { height: 190, delay: 10 }, - { height: 180, delay: 10 }, - { height: 170, delay: 10 }, - { height: 160, delay: 10 }, - - { height: 100, delay: 10 }, - { height: 100, delay: 12 }, - { height: 100, delay: 14 }, - { height: 100, delay: 19 }, - - { height: 180, delay: 8 }, - { height: 130, delay: 9 }, - { height: 150, delay: 13 } - ] - - describe('when the `delay` is the same', () => { - it('sorts the peers by `height`', () => { - const sample = [peers[2], peers[1], peers[3], peers[0]] - const expected = peers.slice(0, 4) - expect(sortPeers(sample)).toEqual(expected) - }) - }) - - describe('when the `height` is the same', () => { - it('sorts the peers by `delay`', () => { - const sample = [peers[7], peers[5], peers[6], peers[4]] - const expected = peers.slice(4, 8) - expect(sortPeers(sample)).toEqual(expected) - }) - }) - - it('sorts the peers by `height` and then `delay`', () => { - const sample = [peers[3], peers[5], peers[8], peers[9], peers[10]] - const expected = [peers[8], peers[3], peers[10], peers[9], peers[5]] - expect(sortPeers(sample)).toEqual(expected) - }) -}) diff --git a/packages/client/banner.png b/packages/client/banner.png deleted file mode 100644 index d70190ffa7..0000000000 Binary files a/packages/client/banner.png and /dev/null differ diff --git a/packages/client/build/webpack.base.js b/packages/client/build/webpack.base.js deleted file mode 100644 index cca9dfc4d0..0000000000 --- a/packages/client/build/webpack.base.js +++ /dev/null @@ -1,24 +0,0 @@ -module.exports = (babelOptions = {}) => ({ - mode: 'production', - - context: __dirname, - - module: { - rules: [{ - test: /\.js$/, - exclude: /node_modules/, - use: { - loader: 'babel-loader', - options: { - presets: [ - ['@babel/preset-env', babelOptions] - ] - } - } - }] - }, - - resolve: { - extensions: ['.js', '.json'] - } -}) diff --git a/packages/client/build/webpack.config.js b/packages/client/build/webpack.config.js deleted file mode 100644 index 071a5b52f1..0000000000 --- a/packages/client/build/webpack.config.js +++ /dev/null @@ -1,56 +0,0 @@ -const path = require('path') -const merge = require('webpack-merge') -const pkg = require('../package.json') -const base = require('./webpack.base') -const nodeExternals = require('webpack-node-externals') - -const resolve = (dir) => path.resolve(__dirname, '..', dir) - -const format = (dist) => ({ - path: resolve(path.dirname(dist)), - filename: path.basename(dist) -}) - -// bundle without crypto package -const browserConfig = { - entry: resolve(pkg.main), - target: 'web', - babel: { - modules: 'umd', - useBuiltIns: 'usage', - targets: { - browsers: 'defaults' - } - }, - output: { - ...format(pkg.browser), - library: 'ArkEcosystemClient', - libraryTarget: 'umd', - umdNamedDefine: true, - globalObject: 'this' - } -} - -const moduleConfig = { - target: 'node', - babel: { - modules: 'commonjs', - targets: { - node: 'current' - } - }, - externals: [nodeExternals({ - modulesFromFile: true, - modulesDir: resolve('node_modules') - })], - entry: resolve(pkg.main), - output: { - ...format(pkg.module), - libraryTarget: 'commonjs2' - }, - optimization: { - minimize: false - } -} - -module.exports = [browserConfig, moduleConfig].map(({ babel, ...entry }) => merge(base(babel), entry)); diff --git a/packages/client/examples/README.md b/packages/client/examples/README.md deleted file mode 100644 index 685ba4a8a0..0000000000 --- a/packages/client/examples/README.md +++ /dev/null @@ -1,12 +0,0 @@ -## ArkEcosystem Javascript API Client Examples - -### `send-to-random-wallet` -This example sends 1 DARK to a random wallet if you've enough balance. - - * To use this example, it's necessary having a devnet wallet with at least 1.1 DARK. - -To run it: -``` -cd packages/client/examples -ARK_CLIENT_EXAMPLE_SENDER="devnet wallet address" ARK_CLIENT_EXAMPLE_PASS="the twelve words that forms the password of the wallet" ./post-transaction.js -``` diff --git a/packages/client/examples/send-to-random-wallet.js b/packages/client/examples/send-to-random-wallet.js deleted file mode 100755 index 8df7b5b59e..0000000000 --- a/packages/client/examples/send-to-random-wallet.js +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/env node - -const Client = require('../lib/index') -const crypto = require('../../crypto/lib/index') - -const sendGift = async () => { - const version = 2 - const amount = 1 * Math.pow(10, 8) // 1 DARK - - let client - - /** - * Return a random member of an Array - * @param {Array} - array - * @return 1 item of the array - */ - const getRandom = array => { - const index = Math.floor(Math.random() * array.length) - return array[index] - } - - /** - * Print an error and exit the app - * @param {String} - message - * @param {(Object|Error)} - error - */ - const fail = (message, error = {}) => { - // API error message or Error instance message - const originalError = error.error ? error.error : error.message - console.error(message, originalError) - process.exit(1) - } - - /** - * Get all the information of a wallet by its address - * @param {String} address - * @return {Object} wallet with all the available properties - */ - const getWallet = async address => { - try { - const { data } = await client.resource('wallets').get(address) - return data.data - } catch (error) { - fail(`An error has occured while retrieving the wallet with address ${address}:`, error) - } - } - - /** - * Get a random wallet - * @return {Object} wallet, but only with some properties - */ - const getRandomWallet = async () => { - try { - const { data } = await client.resource('wallets').all() - const wallets = data.data - return getRandom(wallets) - } catch (error) { - fail('An error has occured while retrieving the wallets:', error) - } - } - - /** - * Build a transaction using the crypto library and send it with the client - * @param {String} recipient - the address of the recipient - * @param {String} senderPublicKey - * @param {String} passphrase - the sender passphrase - * @param {Object} the transaction that has been posted - */ - const postTransaction = async ({ recipient, senderPublicKey, passphrase }) => { - try { - const transaction = crypto.transactionBuilder.transfer() - .amount(amount) - .vendorField('This is a lovely gift!') - .recipientId(recipient) - .senderPublicKey(senderPublicKey) - .sign(passphrase) - .getStruct() - - client.resource('transactions').create({ transactions: [transaction] }) - - return transaction - } catch (error) { - fail('An error has occured while posting the transaction:', error) - } - } - - try { - client = await Client.connect('devnet', version) - } catch (error) { - fail('An error has occured while trying to connect to the network:', error.message) - } - - const sender = process.env.ARK_CLIENT_EXAMPLE_SENDER - if (!sender) { - fail('It is necessary to establish the value of the environment variable "ARK_CLIENT_EXAMPLE_SENDER" to an address') - } - - const passphrase = process.env.ARK_CLIENT_EXAMPLE_PASS - if (!sender) { - fail('It is necessary to establish the value of the environment variable "ARK_CLIENT_EXAMPLE_PASS" to the passphrase of the "ARK_CLIENT_EXAMPLE_SENDER" address') - } - - const senderWallet = await getWallet(sender) - - if (senderWallet.balance < amount) { - fail(`The sender wallet (${senderWallet.address}) does not have enough balance (${senderWallet.balance} DARK)`) - } - - const recipientWallet = await getRandomWallet() - const recipient = recipientWallet.address - - const transaction = await postTransaction({ recipient, senderPublicKey: senderWallet.address, passphrase }) - const explorerUrl = 'https://dexplorer.ark.io/transaction/' - console.log(`\n\tThe gift has been sent to ${recipient} (${explorerUrl}${transaction.id})\n`) -} - -sendGift() diff --git a/packages/client/jest.config.js b/packages/client/jest.config.js deleted file mode 100644 index 9095ebb43f..0000000000 --- a/packages/client/jest.config.js +++ /dev/null @@ -1,19 +0,0 @@ -module.exports = { - testEnvironment: 'node', - bail: false, - verbose: true, - testMatch: [ - '**/__tests__/**/*.test.js' - ], - moduleFileExtensions: [ - 'js', - 'json' - ], - coverageDirectory: '/.coverage', - collectCoverageFrom: [ - 'lib/**/*.js', - '!**/node_modules/**' - ], - watchman: false, - setupTestFrameworkScriptFile: 'jest-extended' -} diff --git a/packages/client/lib/base.js b/packages/client/lib/base.js deleted file mode 100644 index 6cc9dac978..0000000000 --- a/packages/client/lib/base.js +++ /dev/null @@ -1,9 +0,0 @@ -module.exports = class Base { - /** - * @constructor - * @param {Object} http - */ - constructor (http) { - this.http = http - } -} diff --git a/packages/client/lib/http.js b/packages/client/lib/http.js deleted file mode 100644 index 30c3c293c3..0000000000 --- a/packages/client/lib/http.js +++ /dev/null @@ -1,116 +0,0 @@ -const axios = require('axios') - -module.exports = class HttpClient { - /** - * @constructor - * @param {String} host - * @param {Number = 1} [apiVersion] - */ - constructor (host, apiVersion = 1) { - this.host = host.endsWith('/') ? host.slice(0, -1) : host - - if (host.length === 0) { - throw new Error('An empty host is not permitted') - } - - this.version = apiVersion - this.timeout = 60000 - this.headers = {} - } - - /** - * Used to specify the API Version. - * @param {Number} version - */ - setVersion (version) { - this.version = version - } - - /** - * Establish the headers of the requests. - * @param {Object} headers - */ - setHeaders (headers = {}) { - this.headers = headers - } - - /** - * Establish the timeout of the requests. - * @param {Number} timeout - */ - setTimeout (timeout) { - this.timeout = timeout - } - - /** - * Perform a HTTP GET request. - * @param {String} path - * @param {Object} params - * @return {Promise} - */ - get (path, params = {}) { - return this.sendRequest('get', path, params) - } - - /** - * Perform a HTTP POST request. - * @param {String} path - * @param {Object} data - * @return {Promise} - */ - post (path, data = {}) { - return this.sendRequest('post', path, data) - } - - /** - * Perform a HTTP PUT request. - * @param {String} path - * @param {Object} data - * @return {Promise} - */ - put (path, data = {}) { - return this.sendRequest('put', path, data) - } - - /** - * Perform a HTTP PATCH request. - * @param {String} path - * @param {Object} data - * @return {Promise} - */ - patch (path, data = {}) { - return this.sendRequest('patch', path, data) - } - - /** - * Perform a HTTP DELETE request. - * @param {String} path - * @param {Object} params - * @return {Promise} - */ - delete (path, params = {}) { - return this.sendRequest('delete', path, params) - } - - /** - * Performs a request using the headers that are expected by the network. - * @param {String} method - * @param {String} path - * @param {Object} payload - * @return {Promise} - * @throws Will throw an error if the HTTP request fails. - */ - sendRequest (method, path, payload) { - if (!this.headers['API-Version']) { - this.headers['API-Version'] = this.version - } - - const client = axios.create({ - baseURL: `${this.host}/api/`, - headers: this.headers, - timeout: this.timeout - }) - - return client[method](path, payload) - } -} diff --git a/packages/client/lib/index.js b/packages/client/lib/index.js deleted file mode 100644 index cede004cbb..0000000000 --- a/packages/client/lib/index.js +++ /dev/null @@ -1,117 +0,0 @@ -const shuffle = require('lodash.shuffle') -const HttpClient = require('./http') -const resources = require('./resources') -const initialPeers = require('./peers') -const sortPeers = require('./utils/sort-peers') - -module.exports = class ApiClient { - /** - * Finds all the available peers, sorted by block heigh and delay - * - * @param {String} network - Network name ('devnet' or 'mainnet') - * @param {Number} version - API version - */ - static async findPeers (network, version) { - if (!initialPeers.hasOwnProperty(network)) { - throw new Error(`Network "${network}" is not supported`) - } - - const networkPeers = initialPeers[network] - - // Shuffle the peers to avoid connecting always to the first ones - shuffle(networkPeers) - - const selfIps = ['127.0.0.1', '::ffff:127.0.0.1', '::1'] - let peers = null - - // Connect to each peer to get an updated list of peers until a success response - for (const peer of networkPeers) { - const peerUrl = `http://${peer.ip}:${peer.port}` - - // This method should not crash when a peer fails - try { - const client = new ApiClient(peerUrl, version) - const response = await client.resource('peers').all() - const { data } = response.data - - if (data.success && data.peers) { - // Ignore local and unavailable peers - peers = data.peers.filter(peer => { - return selfIps.indexOf(peer.ip) === -1 && peer.status === 'OK' - }) - - if (peers.length) { - break - } - } - } catch (error) { - // TODO only if a new feature to enable logging is added - // console.log(`Cannot find find peers of \`${peerUrl}\``) - } - } - - // Return at least the initial (hardcoded) peers - return sortPeers(peers && peers.length ? peers : networkPeers) - } - - /** - * Connects to a random peer of the network - * - * @param {String} network - Network name - * @param {Number} version - API version - */ - static async connect (network, version) { - const peers = await ApiClient.findPeers(network, version) - return new ApiClient(`http://${peers[0].ip}:${peers[0].port}`, version) - } - - /** - * @constructor - * @param {String} host - * @param {Number} version - API version - */ - constructor (host, version) { - this.setConnection(host) - this.setVersion(version || 1) - } - - /** - * Create a HTTP connection to the API. - * @param {String} host - */ - setConnection (host) { - this.http = new HttpClient(host, this.version) - } - - /** - * Get the HTTP connection to the API. - * @return {Object} - */ - getConnection () { - return this.http - } - - /** - * Set the API Version. - * @param {Number} version - */ - setVersion (version) { - if (!version) { - throw new Error('A valid API version is required') - } - - this.version = version - this.http.setVersion(version) - - return this - } - - /** - * Create an instance of a version specific resource. - * @param {String} name - * @return {Resource} - */ - resource (name) { - return new resources[`v${this.version}`][name](this.http) - } -} diff --git a/packages/client/lib/peers.js b/packages/client/lib/peers.js deleted file mode 100644 index 177d249b74..0000000000 --- a/packages/client/lib/peers.js +++ /dev/null @@ -1,122 +0,0 @@ -/* - * List from https://github.com/ArkEcosystem/peers - */ -module.exports = { - devnet: [ - { - ip: '167.114.29.51', - port: 4003 - }, { - ip: '167.114.29.52', - port: 4003 - }, { - ip: '167.114.29.53', - port: 4003 - }, { - ip: '167.114.29.54', - port: 4003 - }, { - ip: '167.114.29.55', - port: 4003 - } - ], - mainnet: [ - { - ip: '5.39.9.240', - port: 4001 - }, { - ip: '5.39.9.241', - port: 4001 - }, { - ip: '5.39.9.242', - port: 4001 - }, { - ip: '5.39.9.243', - port: 4001 - }, { - ip: '5.39.9.244', - port: 4001 - }, { - ip: '5.39.9.245', - port: 4001 - }, { - ip: '5.39.9.246', - port: 4001 - }, { - ip: '5.39.9.247', - port: 4001 - }, { - ip: '5.39.9.248', - port: 4001 - }, { - ip: '5.39.9.249', - port: 4001 - }, { - ip: '5.39.9.250', - port: 4001 - }, { - ip: '5.39.9.251', - port: 4001 - }, { - ip: '5.39.9.252', - port: 4001 - }, { - ip: '5.39.9.253', - port: 4001 - }, { - ip: '5.39.9.254', - port: 4001 - }, { - ip: '5.39.9.255', - port: 4001 - }, { - ip: '54.38.48.160', - port: 4001 - }, { - ip: '54.38.48.161', - port: 4001 - }, { - ip: '54.38.48.162', - port: 4001 - }, { - ip: '54.38.48.163', - port: 4001 - }, { - ip: '54.38.48.164', - port: 4001 - }, { - ip: '54.38.48.165', - port: 4001 - }, { - ip: '54.38.48.166', - port: 4001 - }, { - ip: '54.38.48.167', - port: 4001 - }, { - ip: '54.38.48.168', - port: 4001 - }, { - ip: '54.38.48.169', - port: 4001 - }, { - ip: '54.38.48.170', - port: 4001 - }, { - ip: '54.38.48.171', - port: 4001 - }, { - ip: '54.38.48.172', - port: 4001 - }, { - ip: '54.38.48.173', - port: 4001 - }, { - ip: '54.38.48.174', - port: 4001 - }, { - ip: '54.38.48.175', - port: 4001 - } - ] -} diff --git a/packages/client/lib/resources/index.js b/packages/client/lib/resources/index.js deleted file mode 100644 index bab32e2626..0000000000 --- a/packages/client/lib/resources/index.js +++ /dev/null @@ -1,7 +0,0 @@ -const v1 = require('./v1') -const v2 = require('./v2') - -module.exports = { - v1, - v2 -} diff --git a/packages/client/lib/resources/v1/accounts.js b/packages/client/lib/resources/v1/accounts.js deleted file mode 100644 index 2325c21f55..0000000000 --- a/packages/client/lib/resources/v1/accounts.js +++ /dev/null @@ -1,73 +0,0 @@ -const Base = require('../../base') - -module.exports = class Wallets extends Base { - /** - * Get all wallets. - * @param {Object} query - * @return {Promise} - */ - all (query) { - return this.http.get('accounts/getAllAccounts', query) - } - - /** - * Get a wallet by address. - * @param {String} address - * @return {Promise} - */ - get (address) { - return this.http.get('accounts', {address}) - } - - /** - * Count how many wallets there are. - * @return {Promise} - */ - count () { - return this.http.get('accounts/count') - } - - /** - * Get deletate by address. - * @param {String} address - * @return {Promise} - */ - delegates (address) { - return this.http.get('accounts/delegates', {address}) - } - - /** - * Get delegate fees. - * @return {Promise} - */ - fee () { - return this.http.get('accounts/delegates/fee') - } - - /** - * Get wallet balance by Address. - * @param {String} address - * @return {Promise} - */ - balance (address) { - return this.http.get('accounts/getBalance', {address}) - } - - /** - * Get wallet public key by Address. - * @param {String} address - * @return {Promise} - */ - publicKey (address) { - return this.http.get('accounts/getPublicKey', {address}) - } - - /** - * Get the top wallets. - * @param {Object} query - * @return {Promise} - */ - top (query) { - return this.http.get('accounts/top', query) - } -} diff --git a/packages/client/lib/resources/v1/blocks.js b/packages/client/lib/resources/v1/blocks.js deleted file mode 100644 index 8655f10cb6..0000000000 --- a/packages/client/lib/resources/v1/blocks.js +++ /dev/null @@ -1,93 +0,0 @@ -const Base = require('../../base') - -module.exports = class Blocks extends Base { - /** - * Get all blocks. - * @param {Object} query - * @return {Promise} - */ - all (query) { - return this.http.get('blocks', query) - } - - /** - * Get block by id. - * @param {String} id - * @return {Promise} - */ - get (id) { - return this.http.get('blocks/get', { id }) - } - - /** - * Get epoch time from config. - * @return {Promise} - */ - epoch () { - return this.http.get('blocks/getEpoch') - } - - /** - * Get the transfer fee from config. - * @return {Promise} - */ - fee () { - return this.http.get('blocks/getFee') - } - - /** - * Get all fees from config. - * @return {Promise} - */ - fees () { - return this.http.get('blocks/getFees') - } - - /** - * Get current height. - * @return {Promise} - */ - height () { - return this.http.get('blocks/getHeight') - } - - /** - * Get current milestone. - * @return {Promise} - */ - milestone () { - return this.http.get('blocks/getMilestone') - } - - /** - * Get nethash from config. - * @return {Promise} - */ - nethash () { - return this.http.get('blocks/getNethash') - } - - /** - * Get reward from config. - * @return {Promise} - */ - reward () { - return this.http.get('blocks/getReward') - } - - /** - * Get config/status for the network. - * @return {Promise} - */ - status () { - return this.http.get('blocks/getStatus') - } - - /** - * Calculate network supply. - * @return {Promise} - */ - supply () { - return this.http.get('blocks/getSupply') - } -} diff --git a/packages/client/lib/resources/v1/delegates.js b/packages/client/lib/resources/v1/delegates.js deleted file mode 100644 index 4954e7bc0e..0000000000 --- a/packages/client/lib/resources/v1/delegates.js +++ /dev/null @@ -1,66 +0,0 @@ -const Base = require('../../base') - -module.exports = class Delegates extends Base { - /** - * Get all delegates. - * @param {Object} query - * @return {Promise} - */ - all (query) { - return this.http.get('delegates', query) - } - - /** - * Get delegate by id. - * @param {String} id - * @return {Promise} - */ - get (id) { - return this.http.get('delegates/get', {id}) - } - - /** - * Get quantity of delegates. - * @return {Promise} - */ - count () { - return this.http.get('delegates/count') - } - - /** - * Get delegate fee. - * @return {Promise} - */ - fee () { - return this.http.get('delegates/fee') - } - - /** - * Get delegate forged data by public key. - * @param {String} generatorPublicKey - * @return {Promise} - */ - forged (generatorPublicKey) { - return this.http.get('delegates/forging/getForgedByAccount', {generatorPublicKey}) - } - - /** - * Search for delegates. - * @param {Object} query - * @param {String} query.q - * @param {Number} query.limit - * @return {Promise} - */ - search (query) { - return this.http.get('delegates/search', query) - } - - /** - * Get voters for delegate. - * @param {String} publicKey - * @return {Promise} - */ - voters (publicKey) { - return this.http.get('delegates/voters', {publicKey}) - } -} diff --git a/packages/client/lib/resources/v1/index.js b/packages/client/lib/resources/v1/index.js deleted file mode 100644 index 9d0b211a88..0000000000 --- a/packages/client/lib/resources/v1/index.js +++ /dev/null @@ -1,17 +0,0 @@ -const accounts = require('./accounts') -const blocks = require('./blocks') -const delegates = require('./delegates') -const loader = require('./loader') -const peers = require('./peers') -const signatures = require('./signatures') -const transactions = require('./transactions') - -module.exports = { - accounts, - blocks, - delegates, - loader, - peers, - signatures, - transactions -} diff --git a/packages/client/lib/resources/v1/loader.js b/packages/client/lib/resources/v1/loader.js deleted file mode 100644 index 9a5f5837af..0000000000 --- a/packages/client/lib/resources/v1/loader.js +++ /dev/null @@ -1,27 +0,0 @@ -const Base = require('../../base') - -module.exports = class Loader extends Base { - /** - * Get network configuration. - * @return {Promise} - */ - status () { - return this.http.get('loader/autoconfigure') - } - - /** - * Get node status. - * @return {Promise} - */ - syncing () { - return this.http.get('loader/status') - } - - /** - * Get node syncing status. - * @return {Promise} - */ - configuration () { - return this.http.get('loader/status/sync') - } -} diff --git a/packages/client/lib/resources/v1/peers.js b/packages/client/lib/resources/v1/peers.js deleted file mode 100644 index 4860c40862..0000000000 --- a/packages/client/lib/resources/v1/peers.js +++ /dev/null @@ -1,30 +0,0 @@ -const Base = require('../../base') - -module.exports = class Peers extends Base { - /** - * Get all peers. - * @param {Object} query - * @return {Promise} - */ - all (query) { - return this.http.get('peers', query) - } - - /** - * Get peer by IP and Port. - * @param {String} ip - * @param {Number} port - * @return {Promise} - */ - get (ip, port) { - return this.http.get('peers/get', {ip, port}) - } - - /** - * Get peer version. - * @return {Promise} - */ - version () { - return this.http.get('peers/version') - } -} diff --git a/packages/client/lib/resources/v1/signatures.js b/packages/client/lib/resources/v1/signatures.js deleted file mode 100644 index dfe2263f33..0000000000 --- a/packages/client/lib/resources/v1/signatures.js +++ /dev/null @@ -1,11 +0,0 @@ -const Base = require('../../base') - -module.exports = class Signatures extends Base { - /** - * Get signature fee. - * @return {Promise} - */ - fee () { - return this.http.get('signatures/fee') - } -} diff --git a/packages/client/lib/resources/v1/transactions.js b/packages/client/lib/resources/v1/transactions.js deleted file mode 100644 index e572c60ba7..0000000000 --- a/packages/client/lib/resources/v1/transactions.js +++ /dev/null @@ -1,39 +0,0 @@ -const Base = require('../../base') - -module.exports = class Transactions extends Base { - /** - * Get all transactions. - * @param {Object} query - * @return {Promise} - */ - all (query) { - return this.http.get('transactions', query) - } - - /** - * Get transaction by id. - * @param {String} id - * @return {Promise} - */ - get (id) { - return this.http.get('transactions/get', {id}) - } - - /** - * Get all unconfirmed transactions. - * @param {Object} query - * @return {Promise} - */ - allUnconfirmed (query) { - return this.http.get('transactions/unconfirmed', query) - } - - /** - * Get unconfirmed transaction by id. - * @param {String} id - * @return {Promise} - */ - getUnconfirmed (id) { - return this.http.get('transactions/unconfirmed/get', {id}) - } -} diff --git a/packages/client/lib/resources/v2/blocks.js b/packages/client/lib/resources/v2/blocks.js deleted file mode 100644 index ea59f61520..0000000000 --- a/packages/client/lib/resources/v2/blocks.js +++ /dev/null @@ -1,38 +0,0 @@ -const Base = require('../../base') - -module.exports = class Blocks extends Base { - /** - * Get all blocks. - * @return {Promise} - */ - all () { - return this.http.get('blocks') - } - - /** - * Get block by id. - * @param {String} id - * @return {Promise} - */ - get (id) { - return this.http.get(`blocks/${id}`) - } - - /** - * Get transactions by block id. - * @param {String} id - * @return {Promise} - */ - transactions (id) { - return this.http.get(`blocks/${id}/transactions`) - } - - /** - * Search for blocks. - * @param {Object} payload - * @return {Promise} - */ - search (payload) { - return this.http.post('blocks/search', payload) - } -} diff --git a/packages/client/lib/resources/v2/delegates.js b/packages/client/lib/resources/v2/delegates.js deleted file mode 100644 index 39e11c4c1e..0000000000 --- a/packages/client/lib/resources/v2/delegates.js +++ /dev/null @@ -1,38 +0,0 @@ -const Base = require('../../base') - -module.exports = class Delegates extends Base { - /** - * Get all delegates. - * @return {Promise} - */ - all () { - return this.http.get('delegates') - } - - /** - * Get delegate by id. - * @param {String} id - * @return {Promise} - */ - get (id) { - return this.http.get(`delegates/${id}`) - } - - /** - * Get blocks forged by delegate id. - * @param {String} id - * @return {Promise} - */ - blocks (id) { - return this.http.get(`delegates/${id}/blocks`) - } - - /** - * Get voters by delegate id. - * @param {String} id - * @return {Promise} - */ - voters (id) { - return this.http.get(`delegates/${id}/voters`) - } -} diff --git a/packages/client/lib/resources/v2/index.js b/packages/client/lib/resources/v2/index.js deleted file mode 100644 index b7d9b1d85d..0000000000 --- a/packages/client/lib/resources/v2/index.js +++ /dev/null @@ -1,21 +0,0 @@ -const blocks = require('./blocks') -const delegates = require('./delegates') -const node = require('./node') -const peers = require('./peers') -const statistics = require('./statistics') -const transactions = require('./transactions') -const votes = require('./votes') -const wallets = require('./wallets') -const webhooks = require('./webhooks') - -module.exports = { - blocks, - delegates, - node, - peers, - statistics, - transactions, - votes, - wallets, - webhooks -} diff --git a/packages/client/lib/resources/v2/node.js b/packages/client/lib/resources/v2/node.js deleted file mode 100644 index 20e3e45adb..0000000000 --- a/packages/client/lib/resources/v2/node.js +++ /dev/null @@ -1,27 +0,0 @@ -const Base = require('../../base') - -module.exports = class Node extends Base { - /** - * Get node status. - * @return {Promise} - */ - status () { - return this.http.get('node/status') - } - - /** - * Get node syncing status. - * @return {Promise} - */ - syncing () { - return this.http.get('node/syncing') - } - - /** - * Get node configuration. - * @return {Promise} - */ - configuration () { - return this.http.get('node/configuration') - } -} diff --git a/packages/client/lib/resources/v2/peers.js b/packages/client/lib/resources/v2/peers.js deleted file mode 100644 index 10e21e53a5..0000000000 --- a/packages/client/lib/resources/v2/peers.js +++ /dev/null @@ -1,20 +0,0 @@ -const Base = require('../../base') - -module.exports = class Peers extends Base { - /** - * Get all peers. - * @return {Promise} - */ - all () { - return this.http.get('peers') - } - - /** - * Get peer by ip. - * @param {String} ip - * @return {Promise} - */ - get (ip) { - return this.http.get(`peers/${ip}`) - } -} diff --git a/packages/client/lib/resources/v2/statistics.js b/packages/client/lib/resources/v2/statistics.js deleted file mode 100644 index c60e5a5a99..0000000000 --- a/packages/client/lib/resources/v2/statistics.js +++ /dev/null @@ -1,43 +0,0 @@ -const Base = require('../../base') - -module.exports = class Statistics extends Base { - /** - * Get network statistics. - * @return {Promise} - */ - blockchain () { - return this.http.get('statistics/blockchain') - } - - /** - * Get transaction statistics. - * @return {Promise} - */ - transactions () { - return this.http.get('statistics/transactions') - } - - /** - * Get block statistics. - * @return {Promise} - */ - blocks () { - return this.http.get('statistics/blocks') - } - - /** - * Get vote statistics. - * @return {Promise} - */ - votes () { - return this.http.get('statistics/votes') - } - - /** - * Get unvote statistics. - * @return {Promise} - */ - unvotes () { - return this.http.get('statistics/unvotes') - } -} diff --git a/packages/client/lib/resources/v2/transactions.js b/packages/client/lib/resources/v2/transactions.js deleted file mode 100644 index 71752dbd0b..0000000000 --- a/packages/client/lib/resources/v2/transactions.js +++ /dev/null @@ -1,63 +0,0 @@ -const Base = require('../../base') - -module.exports = class Transactions extends Base { - /** - * Get all transactions. - * @return {Promise} - */ - all () { - return this.http.get('transactions') - } - - /** - * Push transactions to the blockchain. - * @param {Object} payload - * @return {Promise} - */ - create (payload) { - return this.http.post('transactions', payload) - } - - /** - * Get transaction by id. - * @param {String} id - * @return {Promise} - */ - get (id) { - return this.http.get(`transactions/${id}`) - } - - /** - * Get all unconfirmed transactions. - * @return {Promise} - */ - allUnconfirmed () { - return this.http.get('transactions/unconfirmed') - } - - /** - * Get unconfirmed transaction by id. - * @param {String} id - * @return {Promise} - */ - getUnconfirmed (id) { - return this.http.get(`transactions/unconfirmed/${id}`) - } - - /** - * Search for transactions. - * @param {Object} payload - * @return {Promise} - */ - search (payload) { - return this.http.post('transactions/search', payload) - } - - /** - * Get transaction types. - * @return {Promise} - */ - types () { - return this.http.get('transactions/types') - } -} diff --git a/packages/client/lib/resources/v2/votes.js b/packages/client/lib/resources/v2/votes.js deleted file mode 100644 index 37eaefac2e..0000000000 --- a/packages/client/lib/resources/v2/votes.js +++ /dev/null @@ -1,20 +0,0 @@ -const Base = require('../../base') - -module.exports = class Votes extends Base { - /** - * Get all votes. - * @return {Promise} - */ - all () { - return this.http.get('votes') - } - - /** - * Get vote by id. - * @param {String} id - * @return {Promise} - */ - get (id) { - return this.http.get(`votes/${id}`) - } -} diff --git a/packages/client/lib/resources/v2/wallets.js b/packages/client/lib/resources/v2/wallets.js deleted file mode 100644 index c1ad713353..0000000000 --- a/packages/client/lib/resources/v2/wallets.js +++ /dev/null @@ -1,73 +0,0 @@ -const Base = require('../../base') - -module.exports = class Wallets extends Base { - /** - * Get all wallets. - * @return {Promise} - */ - all () { - return this.http.get('wallets') - } - - /** - * Get top wallets. - * @return {Promise} - */ - top () { - return this.http.get('wallets/top') - } - - /** - * Get wallet by id. - * @param {String} id - * @return {Promise} - */ - get (id) { - return this.http.get(`wallets/${id}`) - } - - /** - * Get transactions by wallet id. - * @param {String} id - * @return {Promise} - */ - transactions (id) { - return this.http.get(`wallets/${id}/transactions`) - } - - /** - * Get sent transactions by wallet id. - * @param {String} id - * @return {Promise} - */ - transactionsSent (id) { - return this.http.get(`wallets/${id}/transactions/sent`) - } - - /** - * Get received transactions by wallet id. - * @param {String} id - * @return {Promise} - */ - transactionsReceived (id) { - return this.http.get(`wallets/${id}/transactions/received`) - } - - /** - * Get votes by wallet id. - * @param {String} id - * @return {Promise} - */ - votes (id) { - return this.http.get(`wallets/${id}/votes`) - } - - /** - * Search for wallets. - * @param {Object} payload - * @return {Promise} - */ - search (payload) { - return this.http.post('wallets/search', payload) - } -} diff --git a/packages/client/lib/resources/v2/webhooks.js b/packages/client/lib/resources/v2/webhooks.js deleted file mode 100644 index 43c5be94ac..0000000000 --- a/packages/client/lib/resources/v2/webhooks.js +++ /dev/null @@ -1,55 +0,0 @@ -const Base = require('../../base') - -module.exports = class Webhooks extends Base { - /** - * Get all webhooks. - * @return {Promise} - */ - all () { - return this.http.get('webhooks') - } - - /** - * Create webhooks. - * @param {Object} payload - * @return {Promise} - */ - create (payload) { - return this.http.post('webhooks', payload) - } - - /** - * Get webhook by id. - * @param {String} id - * @return {Promise} - */ - get (id) { - return this.http.get(`webhooks/${id}`) - } - - /** - * Update webhook by id. - * @param {String} id - * @return {Promise} - */ - update (id) { - return this.http.put(`webhooks/${id}`) - } - - /** - * Delete webhook by id. - * @param {String} id - * @return {Promise} - */ - delete (id) { - return this.http.delete(`webhooks/${id}`) - } - - /** - * Get webhook events. - * @return {Promise} - */ - events () { - return this.http.get('webhooks/events') - } -} diff --git a/packages/client/lib/utils/sort-peers.js b/packages/client/lib/utils/sort-peers.js deleted file mode 100644 index af4ddf0dd6..0000000000 --- a/packages/client/lib/utils/sort-peers.js +++ /dev/null @@ -1,8 +0,0 @@ -const orderBy = require('lodash.orderby') - -/** - * Sorts the peers, in place, by block height and delay - */ -module.exports = peers => { - return orderBy(peers, ['height', 'delay'], ['desc', 'asc']) -} diff --git a/packages/client/package.json b/packages/client/package.json deleted file mode 100644 index ed8c854242..0000000000 --- a/packages/client/package.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "name": "@arkecosystem/client", - "description": "A JavaScript library to interact with the ARK Blockchain", - "version": "0.1.2", - "contributors": [ - "Brian Faust ", - "Alex Barnsley ", - "Lúcio Rubens ", - "Juan A. Martín " - ], - "license": "MIT", - "main": "lib/index.js", - "browser": "dist/index.umd.js", - "module": "dist/index.cjs.js", - "files": [ - "dist", - "lib" - ], - "scripts": { - "prepublish": "yarn run lint && yarn run test && yarn run build", - "build": "rimraf dist && cross-env NODE_ENV=production webpack --config build/webpack.config.js", - "build:docs": "../../node_modules/.bin/jsdoc -c jsdoc.json", - "test": "cross-env ARK_ENV=test jest --runInBand --detectOpenHandles", - "test:coverage": "cross-env ARK_ENV=test jest --coverage --runInBand --detectOpenHandles", - "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand --watch", - "test:watch": "cross-env ARK_ENV=test jest --runInBand --watch", - "test:watch:all": "cross-env ARK_ENV=test jest --runInBand --watchAll", - "lint": "eslint -c ../../.eslintrc --ignore-pattern dist ./ --fix", - "depcheck": "depcheck ./" - }, - "dependencies": { - "axios": "^0.18.0", - "lodash.orderby": "^4.6.0", - "lodash.shuffle": "^4.2.0" - }, - "devDependencies": { - "axios-mock-adapter": "^1.15.0", - "webpack-merge": "^4.1.3", - "webpack-node-externals": "^1.7.2" - }, - "publishConfig": { - "access": "public" - } -} diff --git a/packages/core-api/CHANGELOG.md b/packages/core-api/CHANGELOG.md index 127cc35e42..dbda7c7eae 100644 --- a/packages/core-api/CHANGELOG.md +++ b/packages/core-api/CHANGELOG.md @@ -7,6 +7,65 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Unreleased -## 0.0.1 - 2018-05-31 +## 0.2.0 - 2018-12-03 + +### Added + +- Return forged rewards and fees via v2 API +- Return error feedback for transaction posting via v2 API +- Cache block heights to reduce database load +- Implement database repositories +- Limit the number of transactions per request if posting +- `ownerId` property for transaction searches +- Blockchains endpoint to provide information like supply +- Allow registration of additional plugins +- Run HTTP & HTTPS server at the same time +- Validate transaction payloads +- Implement server side caching via server methods + +### Fixed + +- Ensure order parameters are treated as lower-case and properly formatted +- Handle trailing slashes to avoid v1 issues + +### Changed + +- Use the IANA format for the API vendor in the `Accept` header +- Use the official `hapi-api-version` dependency +- Return ports as integers +- Improved some error messages +- Return broadcast IDs for improved feedback +- Sort peers by latency +- Stricter validation of parameters +- Dropped node.js 9 as minimum requirement in favour of node.js 10 +- Return a `type` and `message` property for transaction errors +- Only allow JSON requests to the API + +### Removed + +- All `redis` integrations and dependencies + +### Fixed + +- Return the delegate list in the v1 format with correct limits +- Add the missing `vendorField` property to transactions +- Broken search in the v2 API for blocks and transactions +- Various search, sort and pagination issues +- Failing search because of unknown parameters +- Properly handle CORS headers +- Race condition that would result in duplicate transactions in the transaction pool +- Fixed the value returned by `unconfirmedBalance` +- Various inconsistencies of string/integer values in the v1 API +- Various inconsistencies of property names in the v1 API +- Various validation schemas +- Added missing `orderBy` property for block transaction sorting +- Crashes caused by bad sorting handling +- Properly return the total forged and total amount of transactions that was forged +- Allow an offset of 0 as default +- Sorting of transactions & wallets + +## 0.1.1 - 2018-06-14 + ### Added + - initial release diff --git a/packages/core-api/README.md b/packages/core-api/README.md index 82c8d11a4a..4f63fccdf8 100644 --- a/packages/core-api/README.md +++ b/packages/core-api/README.md @@ -1,70 +1,12 @@ -![ARK Core](https://i.imgur.com/1aP6F2o.png) +# Ark Core - Public API -# ARK Core - API +

+ +

-## Installation +## Documentation -```bash -yarn add @arkecosystem/core-api -``` - -## Configuration - -### Defaults - -```js -module.exports = { - enabled: true, - port: process.env.ARK_API_PORT || 4003, - versions: { - default: 1, - valid: [1, 2] - }, - cache: { - enabled: false, - options: { - name: 'redisCache', - engine: 'catbox-redis', - host: process.env.ARK_REDIS_HOST || 'localhost', - port: process.env.ARK_REDIS_PORT || 6379, - partition: 'cache', - expiresIn: 60000 - } - }, - rateLimit: { - enabled: false, - limit: 300, - expires: 60000 - }, - pagination: { - limit: 100, - include: [ - '/api/v2/blocks', - '/api/v2/blocks/{id}/transactions', - '/api/v2/blocks/search', - '/api/v2/delegates', - '/api/v2/delegates/{id}/blocks', - '/api/v2/delegates/{id}/voters', - '/api/v2/multisignatures', - '/api/v2/peers', - '/api/v2/signatures', - '/api/v2/transactions', - '/api/v2/transactions/search', - '/api/v2/votes', - '/api/v2/wallets', - '/api/v2/wallets/top', - '/api/v2/wallets/{id}/transactions', - '/api/v2/wallets/{id}/transactions/received', - '/api/v2/wallets/{id}/transactions/sent', - '/api/v2/wallets/{id}/votes', - '/api/v2/wallets/search' - ] - }, - statistics: { - enabled: false - } -} -``` +You can find installation instructions and detailed instructions on how to use this package at the [dedicated documentation site](https://docs.ark.io/guidebook/core/plugins/core-api.html). ## Security diff --git a/packages/core-api/__tests__/__fixtures__/delegates.json b/packages/core-api/__tests__/__fixtures__/delegates.json deleted file mode 100644 index 925645bd62..0000000000 --- a/packages/core-api/__tests__/__fixtures__/delegates.json +++ /dev/null @@ -1,53 +0,0 @@ -[ - "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f", - "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a", - "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983", - "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689", - "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c", - "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0", - "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294", - "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883", - "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d", - "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565", - "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e", - "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb", - "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a", - "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b", - "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964", - "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751", - "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca", - "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9", - "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d", - "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd", - "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055", - "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252", - "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1", - "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4", - "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80", - "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d", - "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37", - "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e", - "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374", - "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f", - "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904", - "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c", - "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e", - "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a", - "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc", - "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564", - "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd", - "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28", - "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647", - "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2", - "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17", - "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5", - "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93", - "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a", - "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95", - "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a", - "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe", - "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12", - "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24", - "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357", - "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b" -] diff --git a/packages/core-api/__tests__/__fixtures__/genesisBlock.js b/packages/core-api/__tests__/__fixtures__/genesisBlock.js deleted file mode 100644 index 821ca9f0f8..0000000000 --- a/packages/core-api/__tests__/__fixtures__/genesisBlock.js +++ /dev/null @@ -1,2160 +0,0 @@ -const { Block } = require('@arkecosystem/crypto').models - -module.exports = new Block({ - 'version': 0, - 'totalAmount': 12500000000000000, - 'totalFee': 0, - 'reward': 0, - 'payloadHash': 'd9acd04bde4234a81addb8482333b4ac906bed7be5a9970ce8ada428bd083192', - 'timestamp': 0, - 'numberOfTransactions': 153, - 'payloadLength': 35960, - 'previousBlock': null, - 'generatorPublicKey': '03b47f6b6719c76bad46a302d9cff7be9b1c2b2a20602a0d880f139b5b8901f068', - 'transactions': [{ - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402205fcb0677e06bde7aac3dc776665615f4b93ef8c3ed0fddecef9900e74fcb00f302206958a0c9868ea1b1f3d151bdfa92da1ce24de0b1fcd91933e64fb7971e92f48d', - 'id': 'db1aa687737858cc9199bfa336f9b1c035915c30aaee60b1e0f8afadfdb946bd', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100ffff4e9ba62e5e3beb37deee052824da83c4030925bce09f190151652d0669b8022056a432e56a2e1b026d4b54f6c34ce88a0c9cebdccc730659c03449fe878c66f8', - 'id': '0762007f825f02979a883396839d6f7425d5ab18f4b8c266bebe60212c793c6d', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3044022001a6326e5d1eb06d0ba1fa39446bd6d56ea45f0c269ebbce5dfc6a649277cfcc02203b252d3a6ef2b22349d9d0a9110ce28a199c39dc8b911edfa82c297a02009d07', - 'id': '3c39aca95ad807ce19c0325e3059d7b1cf967751c6929035214a4ef320fb8154', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304502210084d855eddfe616cf1dc238b19226c7959c2fc4027ae2e8aea6fd8e9eb8928e6b0220440f980e40c1c56348782fd69d49a96944df7ee5b68d18028600e0e7501d4000', - 'id': '9fdf6ae86f7c005b3b7dc1b9fb6411219407ecaa93adff85fdb61710f5121638', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402205438b8b9058bbde5d30794e7681e400e52b5fbd22324c5b6b521f97bc8b8aabc022000fe04d7afbd2e668b1d4576988ed596dc92251e33efebc081e2cba14ad5a898', - 'id': '1d7c68087c875d7ce555b2c3e71e1d91a1ad62d0c2497efe3cab91415e634041', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'APRiwbs17FdbaF8DYU9js2jChRehQc2e6P', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100b2e634a95b011a68489870f003e4bac4a4f0578bfdc6b9f645c934016c2c0463022022cd4ebf276dd627d98be4b697bae2df10b86d94e984da2eb7e011b08d6dffd2', - 'id': '0c993e115ba26981b0be9d22e7c4a13b0f106e0cb472f9d34eabfc8e414dd528', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100f965e5c280acb22d1cde405223fe9a6fcb765844adbc5321b17a268924e1f597022043d31b1edc5fe0cf60a960d84e3528472cdf34560c9463979043a409f37e7f29', - 'id': 'c279f2eb1f9e6e7d4b0ba7a98233a0f1a2536231976c99f56f64b248eb06a0c1', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '30440220715463c316a75959dbfb6a59a013fbf914bef1ff739ac8000d49dabbf5118df9022019345ae1c34173dc214bae82f3cfbf438092f0fd2d277acafe3e9deb644b1a3b', - 'id': '7e2fc9ecf23e909a3d0fbecd615445a0eed8c2cef18e01b1492d63f616f5d87d', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100fdd8aff26dceeb5abb6e5e8a8f468c8ac1997a587225298e3d8135d57dadf4dc022072ab80a81b301a162ed5cfa67d213d5a3980185088632f5f592351aff8aa0e9c', - 'id': '511c0e1076104743f98932f8e7720bdb3f1539134edadd331914fd9ece1ebede', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '30440220635e04ce278870f17fcd1883aa26c568e63dfbdd302add39aa30fd3637c79c2c02206fdd9e7b1f4d238a97d26ef1758927e2d39f121687490f2bd79831e36afdd43b', - 'id': '0768d5016c53d884e3d68a09d1bab0d730b7067c71ef4ca1c4d61b3815f5ff66', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402200b1dac57ca6565ac31afb99686f2e0f0e8dc219b9860b295ca5444a1663cecfb02205787393561fe407449af4aaf2f621db9e4d3f11c7438666cd694d495c0a0c41f', - 'id': '1aeb50080ea118165e5041f7a897974c2ed1ebde08add85dc78cc7cf73566a91', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304502210098dea25eccf31ce6f874a9528578805aaf07be8b41f1571865793f9e3e6e3c97022033ae9c73dad44c01fe6362665fccf63bb1a0ae8e26f77a1cf60b67dc96b05343', - 'id': '254f0f4fa277cc651a746d6ac371eb27afc3ea155ba060552dd26b8e83d17b72', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402207f4bf346aac501e766156818089fb16905a9bdca69ff6d5a55ba918a08afc7ab02200ec2c25cc4bb30e2c176d55630d8e2679b899c14ab4ba43c3d62955dd940425b', - 'id': 'e5ebb02e8e8a6708e22ee5ef99fe1dd8b6eea1095be6b772aa21bf63cf7ade5a', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100a0bbc15bdad648bb9b439f1d34b12b853442d1cfd4ce7f569905082801fa58e8022036b4e73edf7ab7226f8007233f77b1d497cb6b4736f02721bf1b399312ebe114', - 'id': '8a686b21477b64dfd85f08f8598a0f121ca1c7d65ccaca9e42326c75fb5f3abb', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402205d77dfcde527dcc6669bcb01c27b92c1a6399e35ebac9e69415645f596ab1d2802204179497bfd952f44d5f9e295b2a3219a290a4a82841c084a18553b7712e26415', - 'id': '21175347e2acfabc09a7593aae0682e39fe7152199a90561c11125f525211243', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100cf77c16df9185727ff717b71a94f8b29ceeae1e5bb3a28da8cef9df5bc63b7c202207bca394ce9ebd344a548e5a5697f672dedbef640dc1f9105f7c063287bcd1840', - 'id': 'ce1d9b7377551f36568127f5b635b5443f5a58abba6566b50a8d4d7b53c8a874', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100eb8daebb5484f3b0a738c9344fb28298c596f9486963f8fe36e2501ee6876f2a0220559df66986dc9a9a8e76982ef85f907c62745757990c69f0b17b6ae5a7ca4719', - 'id': 'b56702f5eddad0d8dbbb33b6b1ca3e07e4740def9c5dd2aaed9a70b90a4e31b7', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100d088e9bcd78978f2d67e7c7bccecfb73ddd0d1a2dad5b039390812320355722d02207affe83d815f04f6b11abf98eebe0488bfb87f8cd6513d44b829008ed1c15ceb', - 'id': 'a73c053c42e83a83498cf58e5b077b31443e265ddf8228081cb17a36bba366ae', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100db16a8e9682f07efb607bc7c75b654646ff449761ed146ab9358e69d29fadd7f0220436554ad78db0e04ae5b573258e2c8067848e89b55a6e8e1e25011a43882a643', - 'id': '2dccb8b44ad2e598673628fd9d74e336b467a0c941d5e257dceb85c8e0a0000c', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100b03738eccce8ad0b8ac0a656119c2cdd202089c5650d8e1486bd13eb9c3158980220059079900c7fdc16e799c50dccc074726fbf0068044462faabdf1e73f9f9bc38', - 'id': 'b2cce30021d139f97925807da796722bf4d5459442523823388c259ca5ad73db', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100becb49fe5edd6806d5ba6eddbbb34ca8eaf3a12dba123d1610b2b120ca8bd017022072972992ee0ca0f319ae754a2a5a10d715a08b23f8239f9d6d59774f790543ea', - 'id': '9e4841f43ab355be7a4f93b09f3d82c17065fbe25387dd6c5eb4e2692ea05b0b', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402207f1a3fe8c5aa7a77a58ed35c34f128b5df6fba89aa918af35eff432be7d1f8e00220460d4f2a457e1a477974157e33bf2974de6588d56e59729ae980720e9794827a', - 'id': '2c7ca823be21724a4876de632dded3b9afca45df357819ed028488128d85d29e', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3044022067266dfe9d8f2550b590e1eae2f73d28c6b80fecb24c3eb1b4539bc864b3b4f4022031e5122145c35874c0c48673d088e76fb3e11c308ffe9d5dee6431d3441d627e', - 'id': 'a91119f04e2201184761f7fdcb26e4aa81c7e1076cb11a58a422d351241d4e4a', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100b970ec89927de0cb7805e614a742d42c2967db5a9c68d0892956dc89d68ca7d1022067fa30265dd2e1a2985980be2bf876748a7a8c7f3cde0382265b601fa658dc17', - 'id': '94955e6bac6269fbd19e92d2292ac947225fc6f68c6216001b528596a961040c', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402203671b82ddf8a824b8e5aac8bc28be4aef1c00aca1097d14ec1a55003d7a3f28d02203aacb6e7517e916478432b81399828ba7425183ce0fc43feb361bcf345fb0519', - 'id': 'df563ee9822bd3d7aada600d4800952743ec64fafdc7697428d7a19a60745885', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100b77653317c93eb20ee19c71e64a7f9ecb985351bfb1fe351ac65a5738cb37ae202203d540395e1d55f87caaaa867afbfbaf98c553be0b4c7d1748418a76b0c258c89', - 'id': 'd21b6341e2b4be5ffdc3dd8fbcdf2c576ba02e2ef4ab5eab0e4bfc9da4e9e442', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3044022046239e39062a58925099b005888355b8cd6700af66972bf509a10123f9abdec60220202321ea74e56177606fc079d19c29851d832e6d00c93985ffbec3dba6f0d675', - 'id': 'df6bc7a17ad34f8e9faaa2646e8e5dd8bca35affba352537184f690e200e17b6', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402204eeab87f7ecc2097b85606b986177964f3ae777535f6fc0cf08a55fec587d87602203779d59903b8de63511e4ed0a7967bd85e9cb1fc9d84bbc5091e3caa87d8bd52', - 'id': '5f0d5f0dff464d0ad587da5bc93e600a8e2657d359d0a1224bdd4ccc3b6f376a', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402200a2b9d0f61066fa00a2a2882379aa8ee60e949bdc2a85103bbbb69ce3eafccd9022057364f349faceb3047fa95ada210c64fc4a81978d66925b37d3dbc21ede885af', - 'id': '1b39e3702576e6ad7775e34d53e43210549d52a56b3f246031e6ba4121a66bf0', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304502210099e568d3d0c1b48410e0b85c74d04234dacfb2fdf2b1d4b51fca1cfb3445347a02207a2509645aae54560762a37422b66ba4b3ee1c42de35d58c36d2f9d8fdea11b4', - 'id': '0f21e53dbb1edb1cfb4c31bb675aa4672b452a03ec363a2b3300a9dda49e3be3', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3044022026cc5f2b588a86241badca73cd9c1686916d516b8c6c397c66a9d5bb6b5d4cd402204ab5a8c8589ee954bda4a116999d2a0e4ab0e3e96f0c7fe131d7c57b9a1ede43', - 'id': '410826c255a23a78ac5c3aa10dd48132693bc955845af16c20d9c6f69b05dfe9', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402205fedd8d3b5c8d69cdd7db5ca8e9e7c5004f6ba751e45eb1b85b26d9e89800a2402202be56bb2cd824bccf325b6b11432bf6d0ddb5ec97fcc121839ac2ebf884c7173', - 'id': 'ddb57d8270b2b6c876191c1e1c5974388b9fb3ae0980cb2245d8a7c426237f47', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3044022053cd42ad147eea33801b2b57388b33f633b4bfe2ad902190e12480522250d07802203066dc0d0c2ffacc4c74cca1e0187fbea1cef7e78a78666d2ec7e4e87ef546eb', - 'id': '29e1aedf98935c369946c8dadb2d6784f9ab5ce8d73b9b4de2466c7757e2557b', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100c10448b87e7176735c8ddfc8fb3c4d5d55c2d71d18b7ce3ab321209ec299fd41022013517a09e4b366ab386698286ec7bb20410bdfb7f6674fab25a739259083b297', - 'id': '4cf04852529b5525f22cc540790e36e61ed36045ad1b5b788f61ebe42637391e', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402204cc1588b204ebc0c20f44a31ce53d15ab5e4d1f9c103c02dd4e4eaa1c33630b40220194b6e427b6def0783461cd8d765f97b105d048942be468be2ee9b0a2785d2ac', - 'id': '35c6bc3f0799d9c79efc6515f232c58be0d03a3a797d066cba879eef4afaae2c', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100be44f7ea12e2ee89245fb474643ec6c2c75afa00276826a4ecd6fca4cad5ff30022071a2c083b353a821345e4bbf74d98db0760b8721856572572cc3436ebdb8f08c', - 'id': '45f75a349f3b4d73434c0f2ac9c291d5d07278b79e6eaa0d38d6e005f66c4783', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402202090f506e8f18fde70b87a3fd6c470a23e9e262f20ec6268dd59b6362e51a29202202b838c598b33c6317c998dc179fad2b660b8a72bfaf8223d7cc82414ab4c6af4', - 'id': 'a8d9034d1091a4dbe595647ad5f64ca8b243e7842301aee48f7eaf8b8ae98119', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100be59b689a48e198267305f1ae7e116f69f7c360857ea0b1fa81db122278cad69022033436d24ec0103674522f0c559e2357f8696bd498deccad2e0f66b2cf7469538', - 'id': '061cb438ba1216cfd5a0f268ce18e6f280557bc944d9aed3655e2bc5f08bdf51', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402203b5d2aa7c4554d6d2dd6723043350df0199e6e7bbd9f21a1a20dbba8c63918cc022014a78064c5f9c5e2f43d3be36de2b5e2f17e9af557bb6c75e8d82d9f725d0188', - 'id': '239f0640ddc3170a737ef349c07cb82b2493d207421b6f71b6b3dab856f16088', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3044022005eb29ad4cf79fd4f6898de19459e15cc816acb0975e53530a202e69c29d0d4a0220686cf6e0c14779d6d68dcb9d16358c0e859094d2eec8083598b7bb5869478bf2', - 'id': '25d8eef755cfee7cab0d7f9fbbea0fad6d5f906c432d997ae8ef1c49d23735f5', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100b93096a287d59545fa3a08593dfc740d9d47f3cfa3c4bd3c8ff8ef53d3a2e957022027eda62e47220774cf799f46916195e5a8b30015c56ceff4f4a1c10a918e3675', - 'id': 'aac25996e3be809ee88996b6b4063e2097d6306e77a067de8ebc8d7076a28d43', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3044022017282aa4fac7b18e834abc3ca37b2f60cf989c26b12e2f2398a66cb907015a760220428218d39db812a22cc138acc7d5d4d2d5713f0546751c02d2c3fabecca0e724', - 'id': 'b040f86b75750b49c83ca7eb8f2a458f16b44789796ff306c5f942ca5f19164d', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402205970d53cb0921a62bbef540dc33189b2313f3574e44f046097067e6991d63b1102200a356c87642cc781df661a1fee21cce354a144463d37053280e000e1b75da7a5', - 'id': '25ce96f951d7b7d886ef487331125b3413f655f9c5ee7fb4691a728c3cbce18f', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100aab0201c9d9a9641c11605d32353685cbaa051ecc276da1e6a3b309be9f20cf7022067aecbc7329bdf1770974e317a1243815511efa8c7af7801217a83c96d86eb0e', - 'id': '285143b8b19cbde7c680b0f62ef51293e8f315c823ffbd97608c38c02045d831', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100dc7752f6f8acaa3a1ee2ed1bed306ee04556b3866db92a1e770c4b970c7a932e02202d137b312342f9d0708704833b26b6611d0464c87df97049ad8b616483e9d1f8', - 'id': '87b06fccbb63809e976b3405cccec2eeaa3694d5510203f04c0e60bb6c2c0020', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402205ccad5c77ea339f5e3f2b7900b4b1c409d3c8204273e89b6401314fb61f0d224022026a63fef86356de64fe571ff8488a951dcacab56e980fc044ef9f43b9d37439c', - 'id': '5597ed52e4123756bea9307c09c916ff9d0f9fbce8d2e9a3a2ff719a87ad0966', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402207c91153f820f34228bec62772e0d78876bd3277912eacd866fe35b5c86a316c80220104529c6f786cb387ec1e3d5826271c837f0d0a6d0fa5731b9a5c6663cce7108', - 'id': 'd46fde78608fcc668246cc35336210b3c167ba55c82e91b0fd99df7e36872130', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100acc0cf119c18861d3683bb3b0f6e209f2d62acfdd958f86dfbd35137ada814320220448f6f8adcd46204629b45a4a06f5dc7ccb4dbc2a1d702e107d91053847adf2f', - 'id': 'aa92faf5d80459b4e058dc8a8212608b589925052e22148384835ab687a4e875', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3044022055b6bbde5fa886db3cf1224a59f1fb43e850e2d9237db593368e1043698fe2c30220067dd20195e794af4152f1ff9e3ae4261698a86c54803ba1890bf176d97844d4', - 'id': '432e67db0d5fc8c66376aa96c7324e5a1e6d00a415a9c8898b5e3bf25d8b083d', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '30450221009d6f38067264df8497d6888e4a8c316ec58ceba8a54c39ccb0ce261d114fbbab02200fae3f2f950f5c5e3387679f8ca341ec70cd90d0e32a30112f03cfb12cd9fc23', - 'id': '9321e1b08faa544f592ad8dc7b60ff1cf845efcd28fedf8b445be3bda60434cb', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245100000000000, - 'fee': 0, - 'recipientId': 'ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402200aed5a4102bdafda00fda575294f149b393a798c510af8ba877b8c2d7ec8051e022004f7487c4f728c633aee5baa62ab0017f4b91cf2f494eb1c4cc9addc3e9155da', - 'id': '0bbc9340798a18a81109bdfdbee9c9003f20a586dd9f80a39507c84588c1b4b1', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_9', - 'publicKey': '0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647' - } - }, - 'signature': '30440220072124721ba7c997f7c29ad3d4819515fae7a67be2bc395cb73f114eb8d4abe60220523ac295e114de30ce8a4300f4670db91ad2abe1268460e6ad3463fbe9834b84', - 'id': 'd2e70f9d2de57240571905aa81db0b6883e27a83be2422530722d76b56e63ecd', - 'senderId': 'AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_18', - 'publicKey': '02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a' - } - }, - 'signature': '304402204b93b06e08e71e3317f9426a1d3d450d6293fdbf5a6b3043fce27b3ce65431e20220683609720ea1d7d921238ca8b5098d3d9c0caab7b1e26efe42a6aebbc095471a', - 'id': '8695bcb906f5fd81d858794f7d90447aadaa38418d312e33115a81e856b34d12', - 'senderId': 'AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_47', - 'publicKey': '036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd' - } - }, - 'signature': '30450221009711559a43005c808113a1e9a01b1665495ff4bf30d635f7d98c752ead4cc3fc02207879e2a939914effe2b5c80cd515c4b3ff77a071b707c85c4444481878803db9', - 'id': '55853d2d2a98def00c5ab842866a44d1db91678a07b6dd63d062508db28a00a5', - 'senderId': 'AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_5', - 'publicKey': '026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565' - } - }, - 'signature': '3044022025ba51a588253524557547ec492d71bd485fe5b291e60eef681c39eaf8ee781702202bf24c3d295c7a2c9aed97a79fb835506797dcfe7e7a2853e2578e7773c7e134', - 'id': '553298aadf692c9c5d0334c307dd4ac0e277a49ed165c97ce1362f8ec639ee3f', - 'senderId': 'AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_19', - 'publicKey': '0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb' - } - }, - 'signature': '3044022041291ba10ad30fb9ebcb0e13902e92d85e2c3e98493b6d369d7d1e70e8474e31022009083444460c415eab6b4beed9e0206eb0733bad5d2a476af4db4f5b5e74b835', - 'id': '90af927db7b258538c8e21116b5a31418c88ecc163628b2b65fac92a5a949b14', - 'senderId': 'ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_42', - 'publicKey': '0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d' - } - }, - 'signature': '304402205d4111c87874e696b8f4b8897d0dfe68fabe4ad5c5769026c6ecdd04f09a1e2f02207b9c8a2a16b50164215eb1efea6d5d9f4e693cbb7eec8535e526cf8ba68bb796', - 'id': '8a920ebf5255a102d0c9c5fd720e0d36a6a3539991a2267442facf1fea2d0b86', - 'senderId': 'AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_10', - 'publicKey': '02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd' - } - }, - 'signature': '3045022100f15ff048872020d9efc561b8c837f542d54d43b9b071f7a6cc09643c6d4180f002207d0e82153a30b66f43fc4cb4b9b3093bb3d5dfd70f96928c8780c838b1448c19', - 'id': '30738f376aa40fb3c8d8849a5dc698786aeb1409fa801c18729f8da624631391', - 'senderId': 'AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_20', - 'publicKey': '02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751' - } - }, - 'signature': '3045022100babb7410d09215def98078bbab6b5e5690c2ebf54960d94527226ed3925877320220342576d1d8fd2d2fe3b6974cab48a2e16b4813f022b341b32f88e13f572bf060', - 'id': 'ccbe1c27eadc1b3b33f3f87f645be4f756021ee3d4c96f4f094e1f82d5728a3a', - 'senderId': 'ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_49', - 'publicKey': '032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374' - } - }, - 'signature': '3044022032f2c350cc1319f5838d6880e91b49ae0438fb3a626ed9ab5e27ce8788e3347c02202cca18567c8491e0feea8a5f078e28605029346c509fac0c0a192e934f8c5326', - 'id': 'f99af0fbb4d65c2c3f2c1c558f0c0c0eac2724942802fcde02fa6da1d3a9000c', - 'senderId': 'AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_3', - 'publicKey': '038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17' - } - }, - 'signature': '3045022100f0cb5d885ddf3bd4a58837f9b86486da4171652a5eb39228dfd0ff9d34d9c7c602202dc6e3d268d745a7e8633311a337ec097382342049672880c7c2215cf58e5da2', - 'id': '2dca03aed08533585d8bc609da5deb9f17ac9be5a8352769d7ae63d0db16ff59', - 'senderId': 'ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_21', - 'publicKey': '0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a' - } - }, - 'signature': '3045022100999f19fbdc9a12eebbb8c748a4cfc6c91b2233f333a09cddfd49dfeab6aaf38602203d8dc9d1551d400572a88ee812f51f897f8b35508713b789b2c1bf6dd0e88945', - 'id': '5d7e51d57b5914ec201ab65a019ecdf651c4f267cbffe403fd2170bb95145f9d', - 'senderId': 'Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_41', - 'publicKey': '03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f' - } - }, - 'signature': '3045022100e86e648add940a1e637e32ea9187497c281b843da09597e62d0c927d7f43235102200479f64ae63abb55e338f9ce1073a5c46907f7a2a82ea6f9bd9bc29811683515', - 'id': 'eaeed4133da26612c53550b6572722d8c3380d0a2344da1bd270eed1ea91fdf3', - 'senderId': 'AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_11', - 'publicKey': '0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904' - } - }, - 'signature': '3045022100bc3b2ebc58a92bf38672206e8311e7ef0e54912abce7338155b11e7d191b0b5d0220765a568c1fa4665c0ace6b4bd3b7ba0f8329e2f25af7a3cc0d78b2ea398084c3', - 'id': 'bb91e78e43c59a19ac06c015d8a7ef09d7c5b274c9f98505e5a978027354b71c', - 'senderId': 'AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_22', - 'publicKey': '03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a' - } - }, - 'signature': '3045022100aae4868ab75a33e4e77f9bf6c53b920c5e7c523a7cfe271d1afc472655f3d6a60220499f1bcb79bc0fa830dfa939898db5c9fa8571a2788c8de0da7e550bfc818bcc', - 'id': 'a6e687647dde9c1db68690090afc4fcf11833dd35fff3186b6b709a1e7d24260', - 'senderId': 'AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_46', - 'publicKey': '034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c' - } - }, - 'signature': '3045022100c0cf1fc54705c13f70fde39c55a1703a4c612b8a919379cd5b1ada464c7cc8de022074ee62490a184010ad2418d3177ff2ab03d02d2589000176312b90422b1bd64b', - 'id': '70262b0eec3ab5a60a736eb8a628cb600eae7522464a49791c0bf26e82318ec6', - 'senderId': 'AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_6', - 'publicKey': '0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc' - } - }, - 'signature': '3044022045db446b109215c6d3dfb0ee5869154a8a7624376c3760eec4fadc75a29033cf022003e524d64f3ccd0c6de4ca80a7327e2c47ffd16b3ad042bd25a02f5f64500ab7', - 'id': '56048c449694964bee3d367609a7bc46c8da20f66878c09c01dcc53c3abd932e', - 'senderId': 'Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_23', - 'publicKey': '034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a' - } - }, - 'signature': '3045022100f8f69f2957781ed02d64983744c8e51fae613ebe5bbb330d4f509bdcf4fc6b6602205568ad1fd840e01ec26a24ac9a0ff093e978172da55d494138d018a45eb67893', - 'id': 'e15dfc4e18106480083b3c6211349fd9c803e334e9ba5eb62cca19ae3f57d8e7', - 'senderId': 'AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_40', - 'publicKey': '022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689' - } - }, - 'signature': '3044022021eeb9e1db8915a9adb99db72972cd17fc7b5b377fc532ac2c9deffcb2707edf022068b9e08f45bbebad89295f520ad40d7786fe64059d45df95551576e3acb736d1', - 'id': '2bd0f888ccdeeca24a0134e3c1bf729582d284f32ee000d97f1417f1349a6594', - 'senderId': 'AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_12', - 'publicKey': '03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12' - } - }, - 'signature': '3044022040a9d0975f747df19792211546410d7c735aff2d26f367d1bf9233ffd1d993d702206890c66d4d0eb5de37df088c082d8fbd8da043817b48a76bd5d70f1e3f6b6529', - 'id': 'f75ac5ccd243e09fc9da2b3842a0654ca860d2dba5bb73866693a8a918937994', - 'senderId': 'AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_24', - 'publicKey': '039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95' - } - }, - 'signature': '30440220550c0ab565ab2de649ca7a2aaf2975453a1e4ab8b0d392d69663c0c9b6b80b7b022039047d4d1bf4e9b167a95adcde0a5a8631aeca060dfd426da28a10d968fb3a64', - 'id': 'aa2ed932faf4832848356beaf87e5381ee56a1a84fb485ba975acb28f8fcf5df', - 'senderId': 'AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_50', - 'publicKey': '030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1' - } - }, - 'signature': '3044022038df37ef25928d1a04516e982c99f49cbdc193603f814b48ab3802153bdd352002204c918915a3cbfa305c5f898ae4bcdd75394b57460f85c80daa0999751d466c08', - 'id': 'd30a726e1bb8d199d8f44700bc999c9a0a1a8be86e4be6a15764ecd424f9db1b', - 'senderId': 'APRiwbs17FdbaF8DYU9js2jChRehQc2e6P' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_2', - 'publicKey': '02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d' - } - }, - 'signature': '3044022028dd44b9609b0b599c15a257757fd068f9014e33947c77776a6fcbe71879271b02200b46fd8eb0827da6de13f5efd63b17f29e8ba4600e4a690ec31eb08bf2d9af33', - 'id': '1410b8b5f15c05528013378251bf5da30e04c8a6b7ac0f729b527664cfbdfbc4', - 'senderId': 'AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_25', - 'publicKey': '02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964' - } - }, - 'signature': '3044022038edfe34f7b89b4e69ea8b94e3335063b60deaee28246932147f53b2525924a402205b89f5e3d956aa49f24f81e2ba3447c19bd5c026568b3bef73a7a7d5160ad661', - 'id': '58d14b74b71586e18f0499a50004ec2e0cc2e5b56aa53f4cf57084030ff90fa3', - 'senderId': 'AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_39', - 'publicKey': '03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5' - } - }, - 'signature': '3045022100bc1e477994bf4cbcdb5cbe2bd92c7d955a03adfe562f8e3bf04d2f62965e9f78022045512772d8453314361161b2bd2a39aa0a7fbb897a5a83f4c7ab54ced615b42c', - 'id': '3ee53b3f1455ef0ddb52afe08854c9d87f42c7313babd3e05bb3ca4f94c495ef', - 'senderId': 'AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_13', - 'publicKey': '021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f' - } - }, - 'signature': '3044022052fe00e8e9f05b1d890f6910beab0627c823eb2d5875b4b9813a33aed11edfb6022034a723b827ce0e73bfdc0f535b244ffc983f8d549ee72b4d432de90d658db72e', - 'id': '4a3d204c2916c93360d7bb11390e355bc1a930e3cf503965a45253d65bfe928b', - 'senderId': 'ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_1', - 'publicKey': '03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37' - } - }, - 'signature': '3044022013b2798a4ab4d741850abac10d962360cd4ab6a47dfac7c1c806d6f9c3d810cc02202742414ad8a04ce679b445fcd040fb877bbfed3d2692b873dec8cb46c01c8c4c', - 'id': '7d0c5a44a7517f6ad7a1253db45d58e85aa1c735a282a32f45d28efdb7869d7e', - 'senderId': 'ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_45', - 'publicKey': '02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b' - } - }, - 'signature': '304402202c372b7b9679a8fe66f952a1d47d4327968d6e98770b215ada2fed6a8d87ed5502205a797fb511cfba557255dd37e028fb40981b7b65ad2ce8fe0e559a46eb274bf8', - 'id': '70bfe97ae7452dc752ab4de0e2a0e81bd18bef07392c56e7a101257683d4d932', - 'senderId': 'ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_7', - 'publicKey': '022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0' - } - }, - 'signature': '3044022058851712200f7386d6b3c188444f9c8f05788667649ec17c71b9e514206eb105022061e6a4bc4cd11599792e03298f95509893d56af54d51e9f639981045e754b974', - 'id': 'f6f90ff09dee5be7d8f3d58d217772df7a95865bf8609d7d5b0b673e9a5bc953', - 'senderId': 'AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_27', - 'publicKey': '02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d' - } - }, - 'signature': '304402204878d69a166e60e0a779c31fbc48c67b70d2e4aed1d63c60beb9f070963e2894022078c46b6687f23493a4c2ed39709a183a0f7352568cc9cc2c1f0d7bf0d809a4a4', - 'id': 'f68809e407d20a50029fe460d411c866b79c7e09c076dada768a38d81f184aa3', - 'senderId': 'ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_38', - 'publicKey': '0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294' - } - }, - 'signature': '3045022100d5576393a1dea704cf79a5d0bc2757a3a5e66e1055103b52157fca05fc5693ec0220522832ce0e31b779decef83ac8ce764930de927df9ae1d6f6f99a3312d99c90c', - 'id': '2ec6c6f33f00431ef063fbb8a79fb90eadb13a79bf46e6e1df36dd9434314df0', - 'senderId': 'ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_14', - 'publicKey': '03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24' - } - }, - 'signature': '3044022008a7d0bfe9c4c150566ddf701d08e84b4a5f84b07e3b1c91dde1cefa16d2a3c202200b787e898c0b2c68f4343e74f18ae7363f62b5f4ef2962386932aee09a9fa0d4', - 'id': 'e37b3efbf034bea4c852be7d7013978f8999eacc39549ceea775de197e14e8da', - 'senderId': 'AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_28', - 'publicKey': '03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28' - } - }, - 'signature': '3044022023b6fbfa5f4482a4dcc34411846696052b1592786ca87243b7d3344fc9fe9954022035402fbca22691de2497552c743f0f68c7591edd1bd7954ab7639548fcd558a3', - 'id': '08268f5e6c15cf146523ca928f24aca65b162f363593d927c66144ee5df297cc', - 'senderId': 'AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_48', - 'publicKey': '03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b' - } - }, - 'signature': '3045022100b3cad169f29a3a95995b87e1b50b35583c1bff91d69cfa236f58ce452491c579022026775f4ef50b50ecf6d78b530b4633711394983456e6a45ec227b652c86e3014', - 'id': 'ad94ee2ae94813a638b93909930c7cc631c364b6c8528b2dcd6fa8f69260cc2d', - 'senderId': 'AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_4', - 'publicKey': '03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93' - } - }, - 'signature': '3044022007ac9ff2f272f3fda4947393b8688586cc8b2958ff5dc7931ac8f82c697bb76802202a66c28852bbff86ef17ac7f51e7eee52e611e825d91a9846f531ab3c3115c81', - 'id': '76fb1984da9ef90fd7d588756163c97e00d3e4d6e9dfe78d9e3d3cb6d71ddd38', - 'senderId': 'ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_29', - 'publicKey': '0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252' - } - }, - 'signature': '304402204416e428688ad29928303fb2b00a26996cf79753fe70fb91c1f4635c644ba859022068ac5eab7d05f87c40ba36bd9dc149607c196778120c061698d7ab64aaade7ac', - 'id': '0f442a91857061e87dd193b0b9f17a71719ca7e3da62841a63568713fc12b5e7', - 'senderId': 'Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_37', - 'publicKey': '030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4' - } - }, - 'signature': '304402206a248caa5949024202f297c38cee18845e344c5f140be74349787097d3b0a33c02207ac84336e02592bb5e00dcd0c490d30eb856b34177ab9ac03410d82a355a7b0d', - 'id': 'eed30a45c350fdffc5877458f7fe29f28dc4bf81aa1a197d003c9433148b71aa', - 'senderId': 'AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_15', - 'publicKey': '02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca' - } - }, - 'signature': '3045022100c99336ce666cb4a6db3727a61c04c14d8746365f72280d9984441b7d2b568b5402201759e4f417f683743e1d4a14f8a7a215009321cdfa29834b2dbdbe54ee22c1d9', - 'id': 'ecfba14a58f9d79782c4f905646df28bf566e3e7d1f17b39df6fe6b52c11de59', - 'senderId': 'AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_30', - 'publicKey': '02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883' - } - }, - 'signature': '3044022070de7b4d4ce64bd605c9d008142544c2b113cc84df07ed1982e0adf3cf69f4520220211b01710a6533a270dc2814c7f968adf27eb6dbf437e7a72960b013b9651a0c', - 'id': '36ce5323859a92f302f77f27bd08ee3485d720f55842ccba353a47ea96a964c2', - 'senderId': 'AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_44', - 'publicKey': '022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c' - } - }, - 'signature': '3045022100a7c271633ecbf3c6641c7db36913b5fa0ea521f400a4848edf024648f3d7128002206a271f8a88644062b64d856407af9567c0b2937d4a3d89a3b3d07edbd3a0f177', - 'id': 'e120452e7c56a9327b2be7dfd3dcecae193f2e2e772903008b03cdf00146ebd1', - 'senderId': 'AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_8', - 'publicKey': '03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564' - } - }, - 'signature': '304402200394b6545015bcf2d0f291de57a4197cb6ef57b2ad5fa37f05e8a220913ba83502204d0d2f2206edba54ada5b8e5afd194ba83dd1bf15f744258409595251dbe3ff0', - 'id': '7d15eee8e4e3be3d2c44acd51b87a816bdb593565d4ac358dab24ae9c8a5bae2', - 'senderId': 'AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_31', - 'publicKey': '03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2' - } - }, - 'signature': '3045022100989eb331951a13152aa03583efc765499e836c6fbafcafec4302b243ada8de5002203876fc4cf7fdeee4a095667e55a2fef84e5a7053e807b4d8e029883f0d578019', - 'id': 'baa686d521f95d265e7099cfd9ef14e0a9a92254dd94c16ce50c460bd013c588', - 'senderId': 'ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_36', - 'publicKey': '0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e' - } - }, - 'signature': '304402202be177dddfad323302565a866d38a3e7939e0234b16e7dc02075cf258502eba302200928a139ec1a82b4609fcc1bd6d1d027ad050e93fcd2eff94181936d2d43e39c', - 'id': '9fcf7ec6fe98ed94710e212226d8b90df7e7467d66dd4c5c9d48474388be3099', - 'senderId': 'ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_16', - 'publicKey': '02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9' - } - }, - 'signature': '304402207b4f8c09a728acedf3b6ba0632e12d01670c683215053e49dde8598954d85a9a02202a7d7930baa17c2134b314e47dd6c334c828f78e573a2bf92fcbc1146d630541', - 'id': 'c35e4b1e7a2435664fc0939251c2052633ebf4b51fb22d15e71bfcab85b26de9', - 'senderId': 'AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_32', - 'publicKey': '0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055' - } - }, - 'signature': '30440220127d27312345e015c681adb799c1a87d16fb0caaabd5020b39257d567816b91c022018b2388f6d2d9afb3714d84ed102b3ea61159772786033c855947613c7ce7b5b', - 'id': '0d682a3a9c252a674043bee5240e456dae2685d76fbd3bdeda6ff50f0c442fff', - 'senderId': 'AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_51', - 'publicKey': '02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a' - } - }, - 'signature': '304402203d0ee691830e4d001553bf4e49b6d9669b3c959376f391410551c8adc679dac902203ba6e275bf6d543efd19d20428649f802d9396bb0967114a1f09c24827be1da7', - 'id': 'ec2373b0d609ae72fb400ffdfbffc59670ebbf1c15f59c0ac22a4030dae700e3', - 'senderId': 'AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_26', - 'publicKey': '02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983' - } - }, - 'signature': '3045022100f2cf77b0510f589b5aaaf2b0027ffbce6ce8d4873cdc67dc8900865d156de3be02203c22e30945618683182f3d3873e6b3657e0900b062f866bab2705cd593669e79', - 'id': '3cb2f0f7d05a515d4c5c873cbe96e33b1dfba1b7718e4548de7f9da54933b652', - 'senderId': 'AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_33', - 'publicKey': '03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe' - } - }, - 'signature': '304402201e328159172d543d2225c247c6b728800c52eb724f67c0e919f6b7215e6bd7f2022075fc02fe0b14a1499c5602d87ca2c99d6e789beaceed2b9702060dece872d14a', - 'id': '2fd77e744399c9632cc8f106c39237f201dafda976f1040235359f99eea3b832', - 'senderId': 'AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_35', - 'publicKey': '032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e' - } - }, - 'signature': '3044022063903d82e8bd15a6741a298b9a6007d0dc3626acfe2f072c3b624ccbf91ce3360220486ba4cc5591d8aa31b77dfde025b61691dbaad0feabe13e840d26e40010c5df', - 'id': '5baf9e318c9e4cb0513a21eaea27e51c849f95fddc963207fb07aa2fd2b9f9d4', - 'senderId': 'AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_17', - 'publicKey': '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357' - } - }, - 'signature': '3045022100efc1bc16e0b646da48f84822543b62ef5253bfa98bed6613f2d6d4634076e61802200ef243f9dbac7633a8819ce45e2a85d0eacfdc9a33a92bd3a03e90cbd312b823', - 'id': 'b4a959ad75f81b7fdbb957c90a3a63a6c5589e7819e2c455733a3a2b4b034634', - 'senderId': 'AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_34', - 'publicKey': '030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80' - } - }, - 'signature': '3044022012e52a479648990bfc1ed12bf901cad865708ff45962c3724ea67967be4f9d0102201901525ed8dd090af6a2637c123afb304e9fd178794addcb88d916227e66887d', - 'id': '6439f2308efe31ac52ad06ef1caa45b9abf6c589118b7997da6a287325ca36e7', - 'senderId': 'AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_43', - 'publicKey': '034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e' - } - }, - 'signature': '3045022100a0874d1582ce210081f7ab30e7f951dfb9ce8f512d237f8a8cbd5d85569ef3b902200f0053c05de3d6e5ada4e4cf1403a836779d653573c2f374055645cc954c4c4a', - 'id': 'b0733072e98d3d6afe977e32f3dd118c15e79212232417743ffb551dc2a2ba55', - 'senderId': 'AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW', - 'senderPublicKey': '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357' - ] - }, - 'signature': '30440220158ed59156e0eef2d2b94a296451dffe079be701b3d74f0443ef43bc266b334202205a2c39f57abfcd279d568608b90884b3ebe107316aa7552eca35c743b318a47c', - 'id': 'ea294b610e51efb3ceb4229f27bf773e87f41d21b6bb1f3bf68629ffd652c2d3', - 'senderId': 'AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7', - 'senderPublicKey': '030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80' - ] - }, - 'signature': '3045022100898da9f693a458a6875344c6c4cb73069c4075904c75595ffbc665967d84b07002200f168aaf3ab1b52dfa74599394387dc4cf627a447fbc5a91000e9d251cdb20c0', - 'id': '3639b5dc6d19d46d8254d941bf7ace0f3da8a7cf8a56361921b260820c7239cd', - 'senderId': 'AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1', - 'senderPublicKey': '032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e' - ] - }, - 'signature': '3044022055ed9a8b55ccb3bd0945a710269b6f243f1dbfaa28467d3218a17565eb0c962d02207d31561478f16d93a20f5454ad565dea24e8dda4ddc464cb011f4b6b360c4e81', - 'id': 'fe24509580cde0c2e2f49defedd3a0f7572d2f78f90b51a253b0d8cebd74c20d', - 'senderId': 'AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof', - 'senderPublicKey': '0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055' - ] - }, - 'signature': '30440220092f367f833d677e8d0609ad1df65f389c2c35d1501c71c245c2982e6a832268022018e67445f525613d6cb6ac0c9683bd0f55bd40d9c929165649414f083c9041f9', - 'id': '6a76553db794ebf4d5f60a7d7d71cfe29f4dbcaad9610106fbc578cdc7167cd4', - 'senderId': 'AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy', - 'senderPublicKey': '03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2' - ] - }, - 'signature': '304402203dc028b5013c36b03f97b111a8d7c05d0cd8e505b0b0d18747c0656c9b5cfe8102205e9ce8a78d1183b3e9880c69635d04218d94d17808bcc3f92e7af53195c23daf', - 'id': '0f9d7e7708918b77afbdfffb63eef8fe87ba36e0131c88b44c1a7f81750cc025', - 'senderId': 'ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9', - 'senderPublicKey': '0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e' - ] - }, - 'signature': '3045022100a80ddd7c3adaf0e97ab938773fc78a716f3054d7e03afc1ddfcb5005badbd2810220231c0dabe2262149f994c939f9dc90d46b9bd7ca96b19aad6788cd3571e4f71a', - 'id': '0ac77b2637fb25be42b3b60d1651bbbd788aeaba933a08ec4a417c7b4c54e087', - 'senderId': 'ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT', - 'senderPublicKey': '02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883' - ] - }, - 'signature': '30440220772c9cd8b96f74fcddc429d57d466eca6fc40fc211845f59eeb78cb027e116c5022004cda291587eb118d622de21333d2a5783969794b5b0101ad8b1044c7d8058af', - 'id': '4b0dda465564d53981c0e36d73caec888e3523633eaa80dfb99a9c81b2604c7d', - 'senderId': 'AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU', - 'senderPublicKey': '0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252' - ] - }, - 'signature': '30440220406d54714b6425ae4553ea8bec75f31fe52e9b1a9b6f6897151253ab7f637d3b022040a2df4b69840f4d9b0b67658c75efdae8d8269780d4cc50d055fa63922dbb9a', - 'id': 'c7db9d36d97ff0168d0d670ec695e1dc786dfb93f4081586870c8793b50e5f17', - 'senderId': 'Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK', - 'senderPublicKey': '030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4' - ] - }, - 'signature': '3044022018b7e51118ec83c985fa4eb3d7f0cf0655753bcbde7e82bac521665fb1c0ffaf02204e2ace460b2542db8c77e41d05d5e02fa5514b746a0a1e947256925846ed19f1', - 'id': 'c41f4cffcdd523f1718154d5bd5f4f0bec0376076b5f8dd340337e9edb4821ae', - 'senderId': 'AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW', - 'senderPublicKey': '03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28' - ] - }, - 'signature': '304502210088dbe249503da43c157485bfd4f2c95babfe4d0b8bbefe44afa52529b824a79e022045239b6a374fd9aca52c27171ee66b4863c956ae4085c9760d863b1902596c1a', - 'id': 'b1736ec6a1ea4c6d4eb278430a8ee214c88daefe296ba98530e692f8b7a7434c', - 'senderId': 'AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej', - 'senderPublicKey': '02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d' - ] - }, - 'signature': '3045022100fcdf750a775e728a31691a1b38908a7f990b579da510959cc2c63442f5ffde760220316ebb051d9fecb2486771dd39921fb12675b6d46b2441dd1db3c42fad0a59b0', - 'id': '069271456015c2ff842771775993b8afc3404bc070572eeeb0f2fd72d58e18dc', - 'senderId': 'ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U', - 'senderPublicKey': '0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294' - ] - }, - 'signature': '3044022034ce8f77ea9d0f5cf3a9135d7b72d0ba3b96ac6d7eaa3670e9956aef2c9a83cb0220626d1f269128f673a23f9993ce00ba78a08103e697298be29a4c8ee94f204e3a', - 'id': '9a99bba8340e7ad4e05d8424a0977ebbde428d31ee066c9828bd06b42bb42a72', - 'senderId': 'ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2', - 'senderPublicKey': '02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983' - ] - }, - 'signature': '3044022039ae1155f8b87a61c38b25cbbf30da6ecf6cfcc12b25c2e7fe576373754a41eb0220061a66a893129fbad5d48cdd19cf48b1a0d133dd2f3ecdc60ee7b87277e1f81d', - 'id': '6c2c8926420ac269b50fa30127e0e791afb2131aff5821ca7aa80d38a0182048', - 'senderId': 'AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf', - 'senderPublicKey': '02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964' - ] - }, - 'signature': '3045022100d0dac2b7691aa059b1048d7925a0c5d5099f6e9b0f2e321e6d4f128ab1b3272b02207e8c4f643f8f9d1c3f81f0cce6a698df2da2ab71d5b01042766bbe0f46f4a775', - 'id': '9259193c5de72276ed7a99f9d507dd6ea9856411fda521074fb41a556294fdf7', - 'senderId': 'AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9', - 'senderPublicKey': '03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5' - ] - }, - 'signature': '3045022100d5496fec447367ab6b53956a8c40cd8566e050ebb3b92d2c0b2a9d09bef36c7402205e32367605372375801f7b9db39aaafb46ee763b1494f0aca144fb91f3415752', - 'id': '2a41e5946ab0773ca2334bba9d3510184bdd258f1c651ff8ec95b7b64a01dc2e', - 'senderId': 'AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW', - 'senderPublicKey': '039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95' - ] - }, - 'signature': '304502210099249695dc38826e04c8fcffd2570b98c43dec4788cc6a19737ed0872f17ec3302205301f645d803ad5df4ab1a700446e28c7cd76153607f6a2d68ae9168d46f3fe9', - 'id': 'e5c09b0fb2c24c57a4dcef0078953093800329ab4dc8e16a9d9f68215b5acd3d', - 'senderId': 'AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU', - 'senderPublicKey': '034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a' - ] - }, - 'signature': '3045022100f983b03e319aaa6c6ab6381e3ef8c0c035d6e3cc2139cedf70fd4e385393e38a0220286f73577765eb3e89e362785ad8a6de572bebf41bbc1f515b0ea93e41801eb3', - 'id': '00b2c0455ef6f508d65f11bb49e3cfe1e6062d5fd153cafdfdfd2ccbf9c646e5', - 'senderId': 'AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr', - 'senderPublicKey': '022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689' - ] - }, - 'signature': '30440220103862ec51621ca27a0ec6b2817848e8824d2d09dbf7e6aac2f45aeea5d2dc9102205e8cce78b5cd7148aa4d406dc7b491dd7758047200e10cfe1e5fde5c56107ac5', - 'id': 'e25439ad11cb8db3d49ccb3b8b608c1bcb24cb29b2e5ea15101cce3e475224eb', - 'senderId': 'AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ', - 'senderPublicKey': '03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a' - ] - }, - 'signature': '304502210099241ced4a0fd1eb02f5cdcc880ae5f48eb3c7e490d4520c20124ecbf403893602204729dc6cacf3e87c97ca57c1be54d1e80791bf31ef022135e68fc06c950f6994', - 'id': '1474f50815c6c7df41ab652414806d61abe15bee0d41f32d772f4e2793badce4', - 'senderId': 'AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX', - 'senderPublicKey': '0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a' - ] - }, - 'signature': '3045022100eccf81d44992c49a5ee37c6fc2ccc4b6bee9aa44888513b3e18e79452ede3156022056b0ddf079d2918d72e8781d3af009c87e6058563591dfd6ee0117b7df5534b2', - 'id': 'b394e2a8b5c2d20a72ed288408b8f0d48aed922edbee6e16c1c5b0e67517214c', - 'senderId': 'Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf', - 'senderPublicKey': '03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f' - ] - }, - 'signature': '3045022100bdb87894846eccc5a5473edaee1e6dca5f3469963e22f06123b6bde195aede0e02203d0c6833e87c5e60f4597ce624d4c2502a0562b4e54d943f82a4889e3cd69532', - 'id': '6a399099bac6c74fa5e956512ef8b3a39f6f946d5d6996f192c2f1dd5ba172dc', - 'senderId': 'AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv', - 'senderPublicKey': '02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751' - ] - }, - 'signature': '304402200785771ccf1a6a40b51183a190d4cb4ce76b9ffd4c2c736d7724e6c667113d020220649ecfe73017d8dda96a7914793470ee7e582693e4866df123b1032194c163b1', - 'id': 'f20a831a6bae0a85470e308fb66517e70db479657459f6bb39f2cd1783c565e6', - 'senderId': 'ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv', - 'senderPublicKey': '0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb' - ] - }, - 'signature': '3044022020b79e1f07bcb17cae9485b9f44e9f583ca235da4ddd363b905fafb884347f71022015a20481b43720ddb3b1e3ca64b1f47e59b5cc2016a62f43327ca14533384dd4', - 'id': '7a1285be87dca9718bece5b84266c1bf6801a39cc111d534e660aef9e6d26929', - 'senderId': 'ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg', - 'senderPublicKey': '0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d' - ] - }, - 'signature': '3045022100b1615d16763c46d42ca2aae967f04c1c07c119b5af7a378c262ba85515a8d35002202cf7df91676cd137943720e93f06c11907412a6bdc5ef2157cf536a203cf83a3', - 'id': '76fb5a1de90f245b1eeb79cb11c7bea7c8b738add0fb8cd95191186a944b0229', - 'senderId': 'AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri', - 'senderPublicKey': '02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a' - ] - }, - 'signature': '3045022100e3c7b5d6a72acde4d22e8c1c6cd864c549deba89683f4b84320407d6c380827c02202da57df0ab7cd381b776bdf85802aed371e7cea7269a84f911b1d8e9956badee', - 'id': '8da75c8100e6248ab37cc92f72ed9facec3067f4f82f03db8bb8063791463fb3', - 'senderId': 'AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t', - 'senderPublicKey': '03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe' - ] - }, - 'signature': '304402205779b5d8acbfedfc105fedb6fcbd4636713ed27605faa9bd988598072640a958022042d8a8b3d7910c7c385f3707a317c5d445d56da250f8d127c71df2d9d4c5d86e', - 'id': 'fd26e265be88289828d0ce7ffc5faeb9849e1f4cb37a8f1dd5d6fcc436d910b7', - 'senderId': 'AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf', - 'senderPublicKey': '034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e' - ] - }, - 'signature': '3045022100e18a89fe1fe0a8acaca2b6461314e784ffebbe7374f6aafdb06934e83985ccbf022027314b21a4a25b477bd7cc070b4e00ef8f3d69f3f1af028b96571dc245924c00', - 'id': '41d92e128e6b8367cbf8fd111e5263d52e1abad553653f975dd60d7f7c5b637b', - 'senderId': 'AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9', - 'senderPublicKey': '02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9' - ] - }, - 'signature': '304402201c614c84dbae26f87973c9e2b38df883fe0c8c469080e31fe32a4c4946d50b67022075b8fb498fb1384aa6be785845da02813185ccf095597b5782618033828af4d5', - 'id': '1e4a1f8aab6fbf8682c2b35e0d04e9e007ae717ce3f4a82894747e5807e3c759', - 'senderId': 'AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV', - 'senderPublicKey': '02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca' - ] - }, - 'signature': '3045022100b1ee6becc59d594776a40e5b3caec82390d273b703ecb0d7caece44953141449022016543cc29a28882845118afab6e51296cd216bc662260c28e5efd9597b6025b1', - 'id': '2ce068bfccb3f967f4004e9a1e81614a738e55e45c80114c0af30a085f71a2e9', - 'senderId': 'AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ', - 'senderPublicKey': '022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c' - ] - }, - 'signature': '3044022036698a329d7f5f751f91ce02bc188a7527a377d01583b70427cfce64def945ec022079afafea10aa32394a1e42a80577de3869856656221d5f259e05fb44f01668b8', - 'id': '3478d1ad3655e10fcc864f191972322c866616866bb1dbf66d7b66b31cd95de6', - 'senderId': 'AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA', - 'senderPublicKey': '03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24' - ] - }, - 'signature': '3044022035fa7be80cf881eefefc12b11de04ffb2e2e92815cf05074afef54a3c5b2eccb022041f3347f59db0b3caadefcbfbc5ae275d3fe3e2a52fe1504b23628d4b79a43bf', - 'id': '8adfd8e73e96188ed9fdec459d88db1fb041a2b25b3f64830476aec661ae5010', - 'senderId': 'AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm', - 'senderPublicKey': '021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f' - ] - }, - 'signature': '30440220630da8a73979bd3988b7f84fe9e83a429cf3239f54c140c3dbcc407140513fc002203664ad54ed9f199f2683479b988bd97ad8fffb2c2d5dfdbdb10858aca4abfaca', - 'id': 'e306328ffefcd9e3809e7390a358199a62cf8ef037d57af1f5c7b54d728d427e', - 'senderId': 'ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1', - 'senderPublicKey': '02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b' - ] - }, - 'signature': '304402206f1df93f299ffedacc25aa201807df47d32c43369315cf9db280963c357be56302206a66acd553710f49bbb7b803a2bcb71128c8e617ffce66b37b7c968817349247', - 'id': 'dc69bc8f78502ba34655ed062987788939189709a4112760cd8807245d7461f5', - 'senderId': 'ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8', - 'senderPublicKey': '03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12' - ] - }, - 'signature': '30440220629e696a10e04d4fbc10a5ac443bf9bd40dd5d89d4b214224abe47d7ab5600340220643f361a24d9916e2c5aaec7bd7d8a6a0d3ffc5fc0b62c3ac4906eb799a862fa', - 'id': 'c3f49fb80c40f7779b32ba23616f5573a6ba58fc60c4629c2252933038dd89f0', - 'senderId': 'AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2', - 'senderPublicKey': '0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904' - ] - }, - 'signature': '30440220660f9604896dad2a97820b0d7524f0bce5a8b5766f150517d5061fd02bddf768022055e87c25891d4480e66e5d1a71e42cd5a4bef3ab2b2651cd72d44f30a4b32309', - 'id': '8e8ac1b1a586e86867abbf25d63387bb6dfb793c691f0b06333c1581a9a568b3', - 'senderId': 'AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT', - 'senderPublicKey': '034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c' - ] - }, - 'signature': '304402202e2ad64129f61ef1156c4c7e80ab862d4823d62dac502685f53028536ddfb41a02201a3ec777fdfe8fae9f7cd5251fac322c1b6a2a4d41b3ec456daed474986d4872', - 'id': 'ff73565c373f2cefebf86c72dda3a6a6205750eb03b69178cb83378620715e1d', - 'senderId': 'AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q', - 'senderPublicKey': '02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd' - ] - }, - 'signature': '304402202e5c78cf21a088db10e1e1f64d98d84c8d3294fde7bc322d4af06bfe99d4c2e302207e7912a16a37b641a9f8c7c722f2b0d699917ca73e4d0f21584b717fb7f02f13', - 'id': '3822273b496f2e253081cedf382e4f9937713fabb83449e1f892377cf536e68a', - 'senderId': 'AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo', - 'senderPublicKey': '0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647' - ] - }, - 'signature': '3045022100a65ce45164c9bc3e018e26703370c9deb2933ee3b4e814619043cc37c4a39c4802205ae4931ac9e8dffd714c3b601fe248a49c0185c8367887205f497d951c52eb54', - 'id': '430d6db0b87c25dce4ce14ac907c13bcc6efa5d95135f05aa4ba7596ea9d400c', - 'senderId': 'AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN', - 'senderPublicKey': '036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd' - ] - }, - 'signature': '3045022100f3cdd7f688ad2d7b6a5b9cc7e793cb8a6e6e07d3327bc67add64691a53fd2911022026ae1adc8f4fcfc01bcca3efc83019026755b443a504265ad1f46f69d1f5951c', - 'id': 'dda86ecc0332e6c4eed1c0a5af7424374089b85dd274a300fed51b86e2655587', - 'senderId': 'AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj', - 'senderPublicKey': '03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564' - ] - }, - 'signature': '3045022100d419072a752acd55792257c96099fb14c56c29112a00535d39bca96fbd7951c902201abdf4db247dc956d79f4543c389823fbd1a9337f95d30df39603a3b52486bfb', - 'id': '0998e9a055c53bf6697ee76af94c7a830c1364016d78fce889a21bc38ed70cd5', - 'senderId': 'AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN', - 'senderPublicKey': '022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0' - ] - }, - 'signature': '3045022100ba1e0ab761326d2a53cbda2a4a5135033c94d8166864d2ad3ceb963b4a0c046402207d755ecf4ada9fa2a598fd75e73a59d30cb83e01f510020b48b6bf162dc60b27', - 'id': 'be13743deb8486a575d1fb564d2b07d797ac77148d35793c9aca43c0d47aad61', - 'senderId': 'AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA', - 'senderPublicKey': '03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b' - ] - }, - 'signature': '3044022038a491e2e13ac32025209d00aec1af31b73a8b6ee77ad9b8bb80a34f5df59dfc02200ce82c89fe9f88bd5af236ceeaa80f9954e3fb4af7bc884c447505751d49c134', - 'id': 'f1d3d44cc289837de9623cba8891a1ed1cde8918473a91e2daead29975afad22', - 'senderId': 'AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx', - 'senderPublicKey': '0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc' - ] - }, - 'signature': '304402202ae599ce389cd030b8ab48ef53113458b9ba8bf9c9ed09c662eba2849bf540f802202ed63f8af492dd0b67d1b451170a989418a42466a3a7ffe89c4c5a18337e8fb9', - 'id': '65ab302a44ea7550891eabc3b4a8d5ecbcb80784c4666195d5d0b7e33394300d', - 'senderId': 'Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK', - 'senderPublicKey': '026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565' - ] - }, - 'signature': '304502210088a3a4e82d307c238e01ce154b57631d4429e0b591e828ec36839a783736e842022042c6e1d719781e2edca3dbfe84ad13b9e490821a47ccadfcff379decb9c873c0', - 'id': 'd26a7ea56f398634a81086bb15c2f0c863c71b8bd728304d324d8245a8fb6c73', - 'senderId': 'AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz', - 'senderPublicKey': '032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374' - ] - }, - 'signature': '3045022100ae5805541f085a50076835422b2581d3b7a128a05b4f068ad7e3c14cd02799b802205f4bb40e06f90e02282ae74c0aba97923e601fd78234b9585468c4fb73f47893', - 'id': '02504eae7ff4963c081219523bc48d7a07de4c29fdc1622224547f9a7c133abf', - 'senderId': 'AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp', - 'senderPublicKey': '03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93' - ] - }, - 'signature': '3044022078d38cabd8f427ef381d0aa6a0b98c6a590cb18f47acc1d80b429a1c1959b0ab022022a70d4d93d650ca3121dde6065e80cd90d1e2e91cb90f0d0b2eadde609e0d75', - 'id': 'addb8c1baa833baa52a5b51d8a86f8524bde826b5c9f0a99e57070e6323e1dfc', - 'senderId': 'ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv', - 'senderPublicKey': '038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17' - ] - }, - 'signature': '3044022076dd065e3fba825b77884a179d0231d7fc9e7d3a02e34bc6565fab81a84e559e02200a880c028e690a9d6f2c4c6576b1bf3e913817c834da8ec6afdbadfae78d341d', - 'id': '72f31f9a829b93045ef2e860b24c33b9be6a2621c26914acd42121215c1d517e', - 'senderId': 'ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'APRiwbs17FdbaF8DYU9js2jChRehQc2e6P', - 'senderPublicKey': '030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1' - ] - }, - 'signature': '304402205261d9d8ded6364fda8b10bd477982be84990cb010f9214d52c492676814e1f40220489f441ffe2478d361a12ab96caa59da495fe62d61d0e2255aa5ec4ed789afb8', - 'id': '1f17b4ba072d205761ed3f786491eaf684ed3601b69082e487e568aa74a319e8', - 'senderId': 'APRiwbs17FdbaF8DYU9js2jChRehQc2e6P' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd', - 'senderPublicKey': '02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d' - ] - }, - 'signature': '3044022040219da41054a3eebd3122df7f09a62a4e8b4fdc287ae77221f2217b42f291ad02202b9a70c54bb546a604eafadcc086ef6b6570f57542374d87de02ad7f61fe51a4', - 'id': '5fa837023159d6a3d6cf7c5b2ed6fe05ff7df19300226b2f0be5a48a06993780', - 'senderId': 'AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo', - 'senderPublicKey': '03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37' - ] - }, - 'signature': '3045022100ded426768f114f459485ba6ae293c9649b340cf2dcb15e8e887fbb5fed6f7e0b0220752297022de6e93ff64bb9e07b4efef8e946cd2872f84d9e1cb3165ff5c342cb', - 'id': '0a16dc31514629a36d7237968ada6a95d6cbec027b7d26e1e0f0d7d4febe9494', - 'senderId': 'ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD', - 'senderPublicKey': '02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a' - ] - }, - 'signature': '304402203aa292e7aedcd62bb5a79c2521b666b8e1886b57923d98f51911b0461cfdb5db0220539657d5c1dcb78c2c86376da87cc0db428e03c53da3f4f64ebe7115998f00b6', - 'id': '8816f8d8c257ea0c951deba911266394b0f2614df023f8b4ffd9da43d36efd9d', - 'senderId': 'AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD' - }], - 'height': 1, - 'id': '17184958558311101492', - 'blockSignature': '304402202fe5de5697fa25d3d3c0cb24617ac02ddfb1c915ee9194a89f8392f948c6076402200d07c5244642fe36afa53fb2d048735f1adfa623e8fa4760487e5f72e17d253b' -}) diff --git a/packages/core-api/__tests__/__support__/config/genesisBlock.json b/packages/core-api/__tests__/__support__/config/genesisBlock.json deleted file mode 100644 index 9857a98e27..0000000000 --- a/packages/core-api/__tests__/__support__/config/genesisBlock.json +++ /dev/null @@ -1,2158 +0,0 @@ -{ - "version": 0, - "totalAmount": 12500000000000000, - "totalFee": 1, - "reward": 1, - "payloadHash": "d9acd04bde4234a81addb8482333b4ac906bed7be5a9970ce8ada428bd083192", - "timestamp": 0, - "numberOfTransactions": 153, - "payloadLength": 35960, - "previousBlock": "7184958558311101492", - "generatorPublicKey": "03b47f6b6719c76bad46a302d9cff7be9b1c2b2a20602a0d880f139b5b8901f068", - "transactions": [{ - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402205fcb0677e06bde7aac3dc776665615f4b93ef8c3ed0fddecef9900e74fcb00f302206958a0c9868ea1b1f3d151bdfa92da1ce24de0b1fcd91933e64fb7971e92f48d", - "id": "db1aa687737858cc9199bfa336f9b1c035915c30aaee60b1e0f8afadfdb946bd", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100ffff4e9ba62e5e3beb37deee052824da83c4030925bce09f190151652d0669b8022056a432e56a2e1b026d4b54f6c34ce88a0c9cebdccc730659c03449fe878c66f8", - "id": "0762007f825f02979a883396839d6f7425d5ab18f4b8c266bebe60212c793c6d", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022001a6326e5d1eb06d0ba1fa39446bd6d56ea45f0c269ebbce5dfc6a649277cfcc02203b252d3a6ef2b22349d9d0a9110ce28a199c39dc8b911edfa82c297a02009d07", - "id": "3c39aca95ad807ce19c0325e3059d7b1cf967751c6929035214a4ef320fb8154", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304502210084d855eddfe616cf1dc238b19226c7959c2fc4027ae2e8aea6fd8e9eb8928e6b0220440f980e40c1c56348782fd69d49a96944df7ee5b68d18028600e0e7501d4000", - "id": "9fdf6ae86f7c005b3b7dc1b9fb6411219407ecaa93adff85fdb61710f5121638", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402205438b8b9058bbde5d30794e7681e400e52b5fbd22324c5b6b521f97bc8b8aabc022000fe04d7afbd2e668b1d4576988ed596dc92251e33efebc081e2cba14ad5a898", - "id": "1d7c68087c875d7ce555b2c3e71e1d91a1ad62d0c2497efe3cab91415e634041", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100b2e634a95b011a68489870f003e4bac4a4f0578bfdc6b9f645c934016c2c0463022022cd4ebf276dd627d98be4b697bae2df10b86d94e984da2eb7e011b08d6dffd2", - "id": "0c993e115ba26981b0be9d22e7c4a13b0f106e0cb472f9d34eabfc8e414dd528", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100f965e5c280acb22d1cde405223fe9a6fcb765844adbc5321b17a268924e1f597022043d31b1edc5fe0cf60a960d84e3528472cdf34560c9463979043a409f37e7f29", - "id": "c279f2eb1f9e6e7d4b0ba7a98233a0f1a2536231976c99f56f64b248eb06a0c1", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "30440220715463c316a75959dbfb6a59a013fbf914bef1ff739ac8000d49dabbf5118df9022019345ae1c34173dc214bae82f3cfbf438092f0fd2d277acafe3e9deb644b1a3b", - "id": "7e2fc9ecf23e909a3d0fbecd615445a0eed8c2cef18e01b1492d63f616f5d87d", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100fdd8aff26dceeb5abb6e5e8a8f468c8ac1997a587225298e3d8135d57dadf4dc022072ab80a81b301a162ed5cfa67d213d5a3980185088632f5f592351aff8aa0e9c", - "id": "511c0e1076104743f98932f8e7720bdb3f1539134edadd331914fd9ece1ebede", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "30440220635e04ce278870f17fcd1883aa26c568e63dfbdd302add39aa30fd3637c79c2c02206fdd9e7b1f4d238a97d26ef1758927e2d39f121687490f2bd79831e36afdd43b", - "id": "0768d5016c53d884e3d68a09d1bab0d730b7067c71ef4ca1c4d61b3815f5ff66", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402200b1dac57ca6565ac31afb99686f2e0f0e8dc219b9860b295ca5444a1663cecfb02205787393561fe407449af4aaf2f621db9e4d3f11c7438666cd694d495c0a0c41f", - "id": "1aeb50080ea118165e5041f7a897974c2ed1ebde08add85dc78cc7cf73566a91", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304502210098dea25eccf31ce6f874a9528578805aaf07be8b41f1571865793f9e3e6e3c97022033ae9c73dad44c01fe6362665fccf63bb1a0ae8e26f77a1cf60b67dc96b05343", - "id": "254f0f4fa277cc651a746d6ac371eb27afc3ea155ba060552dd26b8e83d17b72", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402207f4bf346aac501e766156818089fb16905a9bdca69ff6d5a55ba918a08afc7ab02200ec2c25cc4bb30e2c176d55630d8e2679b899c14ab4ba43c3d62955dd940425b", - "id": "e5ebb02e8e8a6708e22ee5ef99fe1dd8b6eea1095be6b772aa21bf63cf7ade5a", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100a0bbc15bdad648bb9b439f1d34b12b853442d1cfd4ce7f569905082801fa58e8022036b4e73edf7ab7226f8007233f77b1d497cb6b4736f02721bf1b399312ebe114", - "id": "8a686b21477b64dfd85f08f8598a0f121ca1c7d65ccaca9e42326c75fb5f3abb", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402205d77dfcde527dcc6669bcb01c27b92c1a6399e35ebac9e69415645f596ab1d2802204179497bfd952f44d5f9e295b2a3219a290a4a82841c084a18553b7712e26415", - "id": "21175347e2acfabc09a7593aae0682e39fe7152199a90561c11125f525211243", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100cf77c16df9185727ff717b71a94f8b29ceeae1e5bb3a28da8cef9df5bc63b7c202207bca394ce9ebd344a548e5a5697f672dedbef640dc1f9105f7c063287bcd1840", - "id": "ce1d9b7377551f36568127f5b635b5443f5a58abba6566b50a8d4d7b53c8a874", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100eb8daebb5484f3b0a738c9344fb28298c596f9486963f8fe36e2501ee6876f2a0220559df66986dc9a9a8e76982ef85f907c62745757990c69f0b17b6ae5a7ca4719", - "id": "b56702f5eddad0d8dbbb33b6b1ca3e07e4740def9c5dd2aaed9a70b90a4e31b7", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100d088e9bcd78978f2d67e7c7bccecfb73ddd0d1a2dad5b039390812320355722d02207affe83d815f04f6b11abf98eebe0488bfb87f8cd6513d44b829008ed1c15ceb", - "id": "a73c053c42e83a83498cf58e5b077b31443e265ddf8228081cb17a36bba366ae", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100db16a8e9682f07efb607bc7c75b654646ff449761ed146ab9358e69d29fadd7f0220436554ad78db0e04ae5b573258e2c8067848e89b55a6e8e1e25011a43882a643", - "id": "2dccb8b44ad2e598673628fd9d74e336b467a0c941d5e257dceb85c8e0a0000c", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100b03738eccce8ad0b8ac0a656119c2cdd202089c5650d8e1486bd13eb9c3158980220059079900c7fdc16e799c50dccc074726fbf0068044462faabdf1e73f9f9bc38", - "id": "b2cce30021d139f97925807da796722bf4d5459442523823388c259ca5ad73db", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100becb49fe5edd6806d5ba6eddbbb34ca8eaf3a12dba123d1610b2b120ca8bd017022072972992ee0ca0f319ae754a2a5a10d715a08b23f8239f9d6d59774f790543ea", - "id": "9e4841f43ab355be7a4f93b09f3d82c17065fbe25387dd6c5eb4e2692ea05b0b", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402207f1a3fe8c5aa7a77a58ed35c34f128b5df6fba89aa918af35eff432be7d1f8e00220460d4f2a457e1a477974157e33bf2974de6588d56e59729ae980720e9794827a", - "id": "2c7ca823be21724a4876de632dded3b9afca45df357819ed028488128d85d29e", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022067266dfe9d8f2550b590e1eae2f73d28c6b80fecb24c3eb1b4539bc864b3b4f4022031e5122145c35874c0c48673d088e76fb3e11c308ffe9d5dee6431d3441d627e", - "id": "a91119f04e2201184761f7fdcb26e4aa81c7e1076cb11a58a422d351241d4e4a", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100b970ec89927de0cb7805e614a742d42c2967db5a9c68d0892956dc89d68ca7d1022067fa30265dd2e1a2985980be2bf876748a7a8c7f3cde0382265b601fa658dc17", - "id": "94955e6bac6269fbd19e92d2292ac947225fc6f68c6216001b528596a961040c", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402203671b82ddf8a824b8e5aac8bc28be4aef1c00aca1097d14ec1a55003d7a3f28d02203aacb6e7517e916478432b81399828ba7425183ce0fc43feb361bcf345fb0519", - "id": "df563ee9822bd3d7aada600d4800952743ec64fafdc7697428d7a19a60745885", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100b77653317c93eb20ee19c71e64a7f9ecb985351bfb1fe351ac65a5738cb37ae202203d540395e1d55f87caaaa867afbfbaf98c553be0b4c7d1748418a76b0c258c89", - "id": "d21b6341e2b4be5ffdc3dd8fbcdf2c576ba02e2ef4ab5eab0e4bfc9da4e9e442", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022046239e39062a58925099b005888355b8cd6700af66972bf509a10123f9abdec60220202321ea74e56177606fc079d19c29851d832e6d00c93985ffbec3dba6f0d675", - "id": "df6bc7a17ad34f8e9faaa2646e8e5dd8bca35affba352537184f690e200e17b6", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402204eeab87f7ecc2097b85606b986177964f3ae777535f6fc0cf08a55fec587d87602203779d59903b8de63511e4ed0a7967bd85e9cb1fc9d84bbc5091e3caa87d8bd52", - "id": "5f0d5f0dff464d0ad587da5bc93e600a8e2657d359d0a1224bdd4ccc3b6f376a", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402200a2b9d0f61066fa00a2a2882379aa8ee60e949bdc2a85103bbbb69ce3eafccd9022057364f349faceb3047fa95ada210c64fc4a81978d66925b37d3dbc21ede885af", - "id": "1b39e3702576e6ad7775e34d53e43210549d52a56b3f246031e6ba4121a66bf0", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304502210099e568d3d0c1b48410e0b85c74d04234dacfb2fdf2b1d4b51fca1cfb3445347a02207a2509645aae54560762a37422b66ba4b3ee1c42de35d58c36d2f9d8fdea11b4", - "id": "0f21e53dbb1edb1cfb4c31bb675aa4672b452a03ec363a2b3300a9dda49e3be3", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022026cc5f2b588a86241badca73cd9c1686916d516b8c6c397c66a9d5bb6b5d4cd402204ab5a8c8589ee954bda4a116999d2a0e4ab0e3e96f0c7fe131d7c57b9a1ede43", - "id": "410826c255a23a78ac5c3aa10dd48132693bc955845af16c20d9c6f69b05dfe9", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402205fedd8d3b5c8d69cdd7db5ca8e9e7c5004f6ba751e45eb1b85b26d9e89800a2402202be56bb2cd824bccf325b6b11432bf6d0ddb5ec97fcc121839ac2ebf884c7173", - "id": "ddb57d8270b2b6c876191c1e1c5974388b9fb3ae0980cb2245d8a7c426237f47", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022053cd42ad147eea33801b2b57388b33f633b4bfe2ad902190e12480522250d07802203066dc0d0c2ffacc4c74cca1e0187fbea1cef7e78a78666d2ec7e4e87ef546eb", - "id": "29e1aedf98935c369946c8dadb2d6784f9ab5ce8d73b9b4de2466c7757e2557b", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100c10448b87e7176735c8ddfc8fb3c4d5d55c2d71d18b7ce3ab321209ec299fd41022013517a09e4b366ab386698286ec7bb20410bdfb7f6674fab25a739259083b297", - "id": "4cf04852529b5525f22cc540790e36e61ed36045ad1b5b788f61ebe42637391e", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402204cc1588b204ebc0c20f44a31ce53d15ab5e4d1f9c103c02dd4e4eaa1c33630b40220194b6e427b6def0783461cd8d765f97b105d048942be468be2ee9b0a2785d2ac", - "id": "35c6bc3f0799d9c79efc6515f232c58be0d03a3a797d066cba879eef4afaae2c", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100be44f7ea12e2ee89245fb474643ec6c2c75afa00276826a4ecd6fca4cad5ff30022071a2c083b353a821345e4bbf74d98db0760b8721856572572cc3436ebdb8f08c", - "id": "45f75a349f3b4d73434c0f2ac9c291d5d07278b79e6eaa0d38d6e005f66c4783", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402202090f506e8f18fde70b87a3fd6c470a23e9e262f20ec6268dd59b6362e51a29202202b838c598b33c6317c998dc179fad2b660b8a72bfaf8223d7cc82414ab4c6af4", - "id": "a8d9034d1091a4dbe595647ad5f64ca8b243e7842301aee48f7eaf8b8ae98119", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100be59b689a48e198267305f1ae7e116f69f7c360857ea0b1fa81db122278cad69022033436d24ec0103674522f0c559e2357f8696bd498deccad2e0f66b2cf7469538", - "id": "061cb438ba1216cfd5a0f268ce18e6f280557bc944d9aed3655e2bc5f08bdf51", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402203b5d2aa7c4554d6d2dd6723043350df0199e6e7bbd9f21a1a20dbba8c63918cc022014a78064c5f9c5e2f43d3be36de2b5e2f17e9af557bb6c75e8d82d9f725d0188", - "id": "239f0640ddc3170a737ef349c07cb82b2493d207421b6f71b6b3dab856f16088", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022005eb29ad4cf79fd4f6898de19459e15cc816acb0975e53530a202e69c29d0d4a0220686cf6e0c14779d6d68dcb9d16358c0e859094d2eec8083598b7bb5869478bf2", - "id": "25d8eef755cfee7cab0d7f9fbbea0fad6d5f906c432d997ae8ef1c49d23735f5", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100b93096a287d59545fa3a08593dfc740d9d47f3cfa3c4bd3c8ff8ef53d3a2e957022027eda62e47220774cf799f46916195e5a8b30015c56ceff4f4a1c10a918e3675", - "id": "aac25996e3be809ee88996b6b4063e2097d6306e77a067de8ebc8d7076a28d43", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022017282aa4fac7b18e834abc3ca37b2f60cf989c26b12e2f2398a66cb907015a760220428218d39db812a22cc138acc7d5d4d2d5713f0546751c02d2c3fabecca0e724", - "id": "b040f86b75750b49c83ca7eb8f2a458f16b44789796ff306c5f942ca5f19164d", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402205970d53cb0921a62bbef540dc33189b2313f3574e44f046097067e6991d63b1102200a356c87642cc781df661a1fee21cce354a144463d37053280e000e1b75da7a5", - "id": "25ce96f951d7b7d886ef487331125b3413f655f9c5ee7fb4691a728c3cbce18f", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100aab0201c9d9a9641c11605d32353685cbaa051ecc276da1e6a3b309be9f20cf7022067aecbc7329bdf1770974e317a1243815511efa8c7af7801217a83c96d86eb0e", - "id": "285143b8b19cbde7c680b0f62ef51293e8f315c823ffbd97608c38c02045d831", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100dc7752f6f8acaa3a1ee2ed1bed306ee04556b3866db92a1e770c4b970c7a932e02202d137b312342f9d0708704833b26b6611d0464c87df97049ad8b616483e9d1f8", - "id": "87b06fccbb63809e976b3405cccec2eeaa3694d5510203f04c0e60bb6c2c0020", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402205ccad5c77ea339f5e3f2b7900b4b1c409d3c8204273e89b6401314fb61f0d224022026a63fef86356de64fe571ff8488a951dcacab56e980fc044ef9f43b9d37439c", - "id": "5597ed52e4123756bea9307c09c916ff9d0f9fbce8d2e9a3a2ff719a87ad0966", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402207c91153f820f34228bec62772e0d78876bd3277912eacd866fe35b5c86a316c80220104529c6f786cb387ec1e3d5826271c837f0d0a6d0fa5731b9a5c6663cce7108", - "id": "d46fde78608fcc668246cc35336210b3c167ba55c82e91b0fd99df7e36872130", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100acc0cf119c18861d3683bb3b0f6e209f2d62acfdd958f86dfbd35137ada814320220448f6f8adcd46204629b45a4a06f5dc7ccb4dbc2a1d702e107d91053847adf2f", - "id": "aa92faf5d80459b4e058dc8a8212608b589925052e22148384835ab687a4e875", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022055b6bbde5fa886db3cf1224a59f1fb43e850e2d9237db593368e1043698fe2c30220067dd20195e794af4152f1ff9e3ae4261698a86c54803ba1890bf176d97844d4", - "id": "432e67db0d5fc8c66376aa96c7324e5a1e6d00a415a9c8898b5e3bf25d8b083d", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "30450221009d6f38067264df8497d6888e4a8c316ec58ceba8a54c39ccb0ce261d114fbbab02200fae3f2f950f5c5e3387679f8ca341ec70cd90d0e32a30112f03cfb12cd9fc23", - "id": "9321e1b08faa544f592ad8dc7b60ff1cf845efcd28fedf8b445be3bda60434cb", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245100000000000, - "fee": 0, - "recipientId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402200aed5a4102bdafda00fda575294f149b393a798c510af8ba877b8c2d7ec8051e022004f7487c4f728c633aee5baa62ab0017f4b91cf2f494eb1c4cc9addc3e9155da", - "id": "0bbc9340798a18a81109bdfdbee9c9003f20a586dd9f80a39507c84588c1b4b1", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_9", - "publicKey": "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647" - } - }, - "signature": "30440220072124721ba7c997f7c29ad3d4819515fae7a67be2bc395cb73f114eb8d4abe60220523ac295e114de30ce8a4300f4670db91ad2abe1268460e6ad3463fbe9834b84", - "id": "d2e70f9d2de57240571905aa81db0b6883e27a83be2422530722d76b56e63ecd", - "senderId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_18", - "publicKey": "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a" - } - }, - "signature": "304402204b93b06e08e71e3317f9426a1d3d450d6293fdbf5a6b3043fce27b3ce65431e20220683609720ea1d7d921238ca8b5098d3d9c0caab7b1e26efe42a6aebbc095471a", - "id": "8695bcb906f5fd81d858794f7d90447aadaa38418d312e33115a81e856b34d12", - "senderId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_47", - "publicKey": "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd" - } - }, - "signature": "30450221009711559a43005c808113a1e9a01b1665495ff4bf30d635f7d98c752ead4cc3fc02207879e2a939914effe2b5c80cd515c4b3ff77a071b707c85c4444481878803db9", - "id": "55853d2d2a98def00c5ab842866a44d1db91678a07b6dd63d062508db28a00a5", - "senderId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_5", - "publicKey": "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565" - } - }, - "signature": "3044022025ba51a588253524557547ec492d71bd485fe5b291e60eef681c39eaf8ee781702202bf24c3d295c7a2c9aed97a79fb835506797dcfe7e7a2853e2578e7773c7e134", - "id": "553298aadf692c9c5d0334c307dd4ac0e277a49ed165c97ce1362f8ec639ee3f", - "senderId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_19", - "publicKey": "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb" - } - }, - "signature": "3044022041291ba10ad30fb9ebcb0e13902e92d85e2c3e98493b6d369d7d1e70e8474e31022009083444460c415eab6b4beed9e0206eb0733bad5d2a476af4db4f5b5e74b835", - "id": "90af927db7b258538c8e21116b5a31418c88ecc163628b2b65fac92a5a949b14", - "senderId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_42", - "publicKey": "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d" - } - }, - "signature": "304402205d4111c87874e696b8f4b8897d0dfe68fabe4ad5c5769026c6ecdd04f09a1e2f02207b9c8a2a16b50164215eb1efea6d5d9f4e693cbb7eec8535e526cf8ba68bb796", - "id": "8a920ebf5255a102d0c9c5fd720e0d36a6a3539991a2267442facf1fea2d0b86", - "senderId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_10", - "publicKey": "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd" - } - }, - "signature": "3045022100f15ff048872020d9efc561b8c837f542d54d43b9b071f7a6cc09643c6d4180f002207d0e82153a30b66f43fc4cb4b9b3093bb3d5dfd70f96928c8780c838b1448c19", - "id": "30738f376aa40fb3c8d8849a5dc698786aeb1409fa801c18729f8da624631391", - "senderId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_20", - "publicKey": "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751" - } - }, - "signature": "3045022100babb7410d09215def98078bbab6b5e5690c2ebf54960d94527226ed3925877320220342576d1d8fd2d2fe3b6974cab48a2e16b4813f022b341b32f88e13f572bf060", - "id": "ccbe1c27eadc1b3b33f3f87f645be4f756021ee3d4c96f4f094e1f82d5728a3a", - "senderId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_49", - "publicKey": "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374" - } - }, - "signature": "3044022032f2c350cc1319f5838d6880e91b49ae0438fb3a626ed9ab5e27ce8788e3347c02202cca18567c8491e0feea8a5f078e28605029346c509fac0c0a192e934f8c5326", - "id": "f99af0fbb4d65c2c3f2c1c558f0c0c0eac2724942802fcde02fa6da1d3a9000c", - "senderId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_3", - "publicKey": "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17" - } - }, - "signature": "3045022100f0cb5d885ddf3bd4a58837f9b86486da4171652a5eb39228dfd0ff9d34d9c7c602202dc6e3d268d745a7e8633311a337ec097382342049672880c7c2215cf58e5da2", - "id": "2dca03aed08533585d8bc609da5deb9f17ac9be5a8352769d7ae63d0db16ff59", - "senderId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_21", - "publicKey": "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a" - } - }, - "signature": "3045022100999f19fbdc9a12eebbb8c748a4cfc6c91b2233f333a09cddfd49dfeab6aaf38602203d8dc9d1551d400572a88ee812f51f897f8b35508713b789b2c1bf6dd0e88945", - "id": "5d7e51d57b5914ec201ab65a019ecdf651c4f267cbffe403fd2170bb95145f9d", - "senderId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_41", - "publicKey": "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f" - } - }, - "signature": "3045022100e86e648add940a1e637e32ea9187497c281b843da09597e62d0c927d7f43235102200479f64ae63abb55e338f9ce1073a5c46907f7a2a82ea6f9bd9bc29811683515", - "id": "eaeed4133da26612c53550b6572722d8c3380d0a2344da1bd270eed1ea91fdf3", - "senderId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_11", - "publicKey": "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904" - } - }, - "signature": "3045022100bc3b2ebc58a92bf38672206e8311e7ef0e54912abce7338155b11e7d191b0b5d0220765a568c1fa4665c0ace6b4bd3b7ba0f8329e2f25af7a3cc0d78b2ea398084c3", - "id": "bb91e78e43c59a19ac06c015d8a7ef09d7c5b274c9f98505e5a978027354b71c", - "senderId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_22", - "publicKey": "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a" - } - }, - "signature": "3045022100aae4868ab75a33e4e77f9bf6c53b920c5e7c523a7cfe271d1afc472655f3d6a60220499f1bcb79bc0fa830dfa939898db5c9fa8571a2788c8de0da7e550bfc818bcc", - "id": "a6e687647dde9c1db68690090afc4fcf11833dd35fff3186b6b709a1e7d24260", - "senderId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_46", - "publicKey": "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c" - } - }, - "signature": "3045022100c0cf1fc54705c13f70fde39c55a1703a4c612b8a919379cd5b1ada464c7cc8de022074ee62490a184010ad2418d3177ff2ab03d02d2589000176312b90422b1bd64b", - "id": "70262b0eec3ab5a60a736eb8a628cb600eae7522464a49791c0bf26e82318ec6", - "senderId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_6", - "publicKey": "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc" - } - }, - "signature": "3044022045db446b109215c6d3dfb0ee5869154a8a7624376c3760eec4fadc75a29033cf022003e524d64f3ccd0c6de4ca80a7327e2c47ffd16b3ad042bd25a02f5f64500ab7", - "id": "56048c449694964bee3d367609a7bc46c8da20f66878c09c01dcc53c3abd932e", - "senderId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_23", - "publicKey": "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a" - } - }, - "signature": "3045022100f8f69f2957781ed02d64983744c8e51fae613ebe5bbb330d4f509bdcf4fc6b6602205568ad1fd840e01ec26a24ac9a0ff093e978172da55d494138d018a45eb67893", - "id": "e15dfc4e18106480083b3c6211349fd9c803e334e9ba5eb62cca19ae3f57d8e7", - "senderId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_40", - "publicKey": "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689" - } - }, - "signature": "3044022021eeb9e1db8915a9adb99db72972cd17fc7b5b377fc532ac2c9deffcb2707edf022068b9e08f45bbebad89295f520ad40d7786fe64059d45df95551576e3acb736d1", - "id": "2bd0f888ccdeeca24a0134e3c1bf729582d284f32ee000d97f1417f1349a6594", - "senderId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_12", - "publicKey": "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12" - } - }, - "signature": "3044022040a9d0975f747df19792211546410d7c735aff2d26f367d1bf9233ffd1d993d702206890c66d4d0eb5de37df088c082d8fbd8da043817b48a76bd5d70f1e3f6b6529", - "id": "f75ac5ccd243e09fc9da2b3842a0654ca860d2dba5bb73866693a8a918937994", - "senderId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_24", - "publicKey": "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95" - } - }, - "signature": "30440220550c0ab565ab2de649ca7a2aaf2975453a1e4ab8b0d392d69663c0c9b6b80b7b022039047d4d1bf4e9b167a95adcde0a5a8631aeca060dfd426da28a10d968fb3a64", - "id": "aa2ed932faf4832848356beaf87e5381ee56a1a84fb485ba975acb28f8fcf5df", - "senderId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_50", - "publicKey": "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1" - } - }, - "signature": "3044022038df37ef25928d1a04516e982c99f49cbdc193603f814b48ab3802153bdd352002204c918915a3cbfa305c5f898ae4bcdd75394b57460f85c80daa0999751d466c08", - "id": "d30a726e1bb8d199d8f44700bc999c9a0a1a8be86e4be6a15764ecd424f9db1b", - "senderId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_2", - "publicKey": "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d" - } - }, - "signature": "3044022028dd44b9609b0b599c15a257757fd068f9014e33947c77776a6fcbe71879271b02200b46fd8eb0827da6de13f5efd63b17f29e8ba4600e4a690ec31eb08bf2d9af33", - "id": "1410b8b5f15c05528013378251bf5da30e04c8a6b7ac0f729b527664cfbdfbc4", - "senderId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_25", - "publicKey": "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964" - } - }, - "signature": "3044022038edfe34f7b89b4e69ea8b94e3335063b60deaee28246932147f53b2525924a402205b89f5e3d956aa49f24f81e2ba3447c19bd5c026568b3bef73a7a7d5160ad661", - "id": "58d14b74b71586e18f0499a50004ec2e0cc2e5b56aa53f4cf57084030ff90fa3", - "senderId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_39", - "publicKey": "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5" - } - }, - "signature": "3045022100bc1e477994bf4cbcdb5cbe2bd92c7d955a03adfe562f8e3bf04d2f62965e9f78022045512772d8453314361161b2bd2a39aa0a7fbb897a5a83f4c7ab54ced615b42c", - "id": "3ee53b3f1455ef0ddb52afe08854c9d87f42c7313babd3e05bb3ca4f94c495ef", - "senderId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_13", - "publicKey": "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f" - } - }, - "signature": "3044022052fe00e8e9f05b1d890f6910beab0627c823eb2d5875b4b9813a33aed11edfb6022034a723b827ce0e73bfdc0f535b244ffc983f8d549ee72b4d432de90d658db72e", - "id": "4a3d204c2916c93360d7bb11390e355bc1a930e3cf503965a45253d65bfe928b", - "senderId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_1", - "publicKey": "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37" - } - }, - "signature": "3044022013b2798a4ab4d741850abac10d962360cd4ab6a47dfac7c1c806d6f9c3d810cc02202742414ad8a04ce679b445fcd040fb877bbfed3d2692b873dec8cb46c01c8c4c", - "id": "7d0c5a44a7517f6ad7a1253db45d58e85aa1c735a282a32f45d28efdb7869d7e", - "senderId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_45", - "publicKey": "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b" - } - }, - "signature": "304402202c372b7b9679a8fe66f952a1d47d4327968d6e98770b215ada2fed6a8d87ed5502205a797fb511cfba557255dd37e028fb40981b7b65ad2ce8fe0e559a46eb274bf8", - "id": "70bfe97ae7452dc752ab4de0e2a0e81bd18bef07392c56e7a101257683d4d932", - "senderId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_7", - "publicKey": "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0" - } - }, - "signature": "3044022058851712200f7386d6b3c188444f9c8f05788667649ec17c71b9e514206eb105022061e6a4bc4cd11599792e03298f95509893d56af54d51e9f639981045e754b974", - "id": "f6f90ff09dee5be7d8f3d58d217772df7a95865bf8609d7d5b0b673e9a5bc953", - "senderId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_27", - "publicKey": "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d" - } - }, - "signature": "304402204878d69a166e60e0a779c31fbc48c67b70d2e4aed1d63c60beb9f070963e2894022078c46b6687f23493a4c2ed39709a183a0f7352568cc9cc2c1f0d7bf0d809a4a4", - "id": "f68809e407d20a50029fe460d411c866b79c7e09c076dada768a38d81f184aa3", - "senderId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_38", - "publicKey": "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294" - } - }, - "signature": "3045022100d5576393a1dea704cf79a5d0bc2757a3a5e66e1055103b52157fca05fc5693ec0220522832ce0e31b779decef83ac8ce764930de927df9ae1d6f6f99a3312d99c90c", - "id": "2ec6c6f33f00431ef063fbb8a79fb90eadb13a79bf46e6e1df36dd9434314df0", - "senderId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_14", - "publicKey": "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24" - } - }, - "signature": "3044022008a7d0bfe9c4c150566ddf701d08e84b4a5f84b07e3b1c91dde1cefa16d2a3c202200b787e898c0b2c68f4343e74f18ae7363f62b5f4ef2962386932aee09a9fa0d4", - "id": "e37b3efbf034bea4c852be7d7013978f8999eacc39549ceea775de197e14e8da", - "senderId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_28", - "publicKey": "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28" - } - }, - "signature": "3044022023b6fbfa5f4482a4dcc34411846696052b1592786ca87243b7d3344fc9fe9954022035402fbca22691de2497552c743f0f68c7591edd1bd7954ab7639548fcd558a3", - "id": "08268f5e6c15cf146523ca928f24aca65b162f363593d927c66144ee5df297cc", - "senderId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_48", - "publicKey": "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b" - } - }, - "signature": "3045022100b3cad169f29a3a95995b87e1b50b35583c1bff91d69cfa236f58ce452491c579022026775f4ef50b50ecf6d78b530b4633711394983456e6a45ec227b652c86e3014", - "id": "ad94ee2ae94813a638b93909930c7cc631c364b6c8528b2dcd6fa8f69260cc2d", - "senderId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_4", - "publicKey": "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93" - } - }, - "signature": "3044022007ac9ff2f272f3fda4947393b8688586cc8b2958ff5dc7931ac8f82c697bb76802202a66c28852bbff86ef17ac7f51e7eee52e611e825d91a9846f531ab3c3115c81", - "id": "76fb1984da9ef90fd7d588756163c97e00d3e4d6e9dfe78d9e3d3cb6d71ddd38", - "senderId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_29", - "publicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252" - } - }, - "signature": "304402204416e428688ad29928303fb2b00a26996cf79753fe70fb91c1f4635c644ba859022068ac5eab7d05f87c40ba36bd9dc149607c196778120c061698d7ab64aaade7ac", - "id": "0f442a91857061e87dd193b0b9f17a71719ca7e3da62841a63568713fc12b5e7", - "senderId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_37", - "publicKey": "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4" - } - }, - "signature": "304402206a248caa5949024202f297c38cee18845e344c5f140be74349787097d3b0a33c02207ac84336e02592bb5e00dcd0c490d30eb856b34177ab9ac03410d82a355a7b0d", - "id": "eed30a45c350fdffc5877458f7fe29f28dc4bf81aa1a197d003c9433148b71aa", - "senderId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_15", - "publicKey": "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca" - } - }, - "signature": "3045022100c99336ce666cb4a6db3727a61c04c14d8746365f72280d9984441b7d2b568b5402201759e4f417f683743e1d4a14f8a7a215009321cdfa29834b2dbdbe54ee22c1d9", - "id": "ecfba14a58f9d79782c4f905646df28bf566e3e7d1f17b39df6fe6b52c11de59", - "senderId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_30", - "publicKey": "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883" - } - }, - "signature": "3044022070de7b4d4ce64bd605c9d008142544c2b113cc84df07ed1982e0adf3cf69f4520220211b01710a6533a270dc2814c7f968adf27eb6dbf437e7a72960b013b9651a0c", - "id": "36ce5323859a92f302f77f27bd08ee3485d720f55842ccba353a47ea96a964c2", - "senderId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_44", - "publicKey": "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c" - } - }, - "signature": "3045022100a7c271633ecbf3c6641c7db36913b5fa0ea521f400a4848edf024648f3d7128002206a271f8a88644062b64d856407af9567c0b2937d4a3d89a3b3d07edbd3a0f177", - "id": "e120452e7c56a9327b2be7dfd3dcecae193f2e2e772903008b03cdf00146ebd1", - "senderId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_8", - "publicKey": "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564" - } - }, - "signature": "304402200394b6545015bcf2d0f291de57a4197cb6ef57b2ad5fa37f05e8a220913ba83502204d0d2f2206edba54ada5b8e5afd194ba83dd1bf15f744258409595251dbe3ff0", - "id": "7d15eee8e4e3be3d2c44acd51b87a816bdb593565d4ac358dab24ae9c8a5bae2", - "senderId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_31", - "publicKey": "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2" - } - }, - "signature": "3045022100989eb331951a13152aa03583efc765499e836c6fbafcafec4302b243ada8de5002203876fc4cf7fdeee4a095667e55a2fef84e5a7053e807b4d8e029883f0d578019", - "id": "baa686d521f95d265e7099cfd9ef14e0a9a92254dd94c16ce50c460bd013c588", - "senderId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_36", - "publicKey": "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e" - } - }, - "signature": "304402202be177dddfad323302565a866d38a3e7939e0234b16e7dc02075cf258502eba302200928a139ec1a82b4609fcc1bd6d1d027ad050e93fcd2eff94181936d2d43e39c", - "id": "9fcf7ec6fe98ed94710e212226d8b90df7e7467d66dd4c5c9d48474388be3099", - "senderId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_16", - "publicKey": "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9" - } - }, - "signature": "304402207b4f8c09a728acedf3b6ba0632e12d01670c683215053e49dde8598954d85a9a02202a7d7930baa17c2134b314e47dd6c334c828f78e573a2bf92fcbc1146d630541", - "id": "c35e4b1e7a2435664fc0939251c2052633ebf4b51fb22d15e71bfcab85b26de9", - "senderId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_32", - "publicKey": "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055" - } - }, - "signature": "30440220127d27312345e015c681adb799c1a87d16fb0caaabd5020b39257d567816b91c022018b2388f6d2d9afb3714d84ed102b3ea61159772786033c855947613c7ce7b5b", - "id": "0d682a3a9c252a674043bee5240e456dae2685d76fbd3bdeda6ff50f0c442fff", - "senderId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_51", - "publicKey": "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a" - } - }, - "signature": "304402203d0ee691830e4d001553bf4e49b6d9669b3c959376f391410551c8adc679dac902203ba6e275bf6d543efd19d20428649f802d9396bb0967114a1f09c24827be1da7", - "id": "ec2373b0d609ae72fb400ffdfbffc59670ebbf1c15f59c0ac22a4030dae700e3", - "senderId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_26", - "publicKey": "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983" - } - }, - "signature": "3045022100f2cf77b0510f589b5aaaf2b0027ffbce6ce8d4873cdc67dc8900865d156de3be02203c22e30945618683182f3d3873e6b3657e0900b062f866bab2705cd593669e79", - "id": "3cb2f0f7d05a515d4c5c873cbe96e33b1dfba1b7718e4548de7f9da54933b652", - "senderId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_33", - "publicKey": "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe" - } - }, - "signature": "304402201e328159172d543d2225c247c6b728800c52eb724f67c0e919f6b7215e6bd7f2022075fc02fe0b14a1499c5602d87ca2c99d6e789beaceed2b9702060dece872d14a", - "id": "2fd77e744399c9632cc8f106c39237f201dafda976f1040235359f99eea3b832", - "senderId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_35", - "publicKey": "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e" - } - }, - "signature": "3044022063903d82e8bd15a6741a298b9a6007d0dc3626acfe2f072c3b624ccbf91ce3360220486ba4cc5591d8aa31b77dfde025b61691dbaad0feabe13e840d26e40010c5df", - "id": "5baf9e318c9e4cb0513a21eaea27e51c849f95fddc963207fb07aa2fd2b9f9d4", - "senderId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_17", - "publicKey": "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357" - } - }, - "signature": "3045022100efc1bc16e0b646da48f84822543b62ef5253bfa98bed6613f2d6d4634076e61802200ef243f9dbac7633a8819ce45e2a85d0eacfdc9a33a92bd3a03e90cbd312b823", - "id": "b4a959ad75f81b7fdbb957c90a3a63a6c5589e7819e2c455733a3a2b4b034634", - "senderId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_34", - "publicKey": "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80" - } - }, - "signature": "3044022012e52a479648990bfc1ed12bf901cad865708ff45962c3724ea67967be4f9d0102201901525ed8dd090af6a2637c123afb304e9fd178794addcb88d916227e66887d", - "id": "6439f2308efe31ac52ad06ef1caa45b9abf6c589118b7997da6a287325ca36e7", - "senderId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_43", - "publicKey": "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e" - } - }, - "signature": "3045022100a0874d1582ce210081f7ab30e7f951dfb9ce8f512d237f8a8cbd5d85569ef3b902200f0053c05de3d6e5ada4e4cf1403a836779d653573c2f374055645cc954c4c4a", - "id": "b0733072e98d3d6afe977e32f3dd118c15e79212232417743ffb551dc2a2ba55", - "senderId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW", - "senderPublicKey": "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357", - "timestamp": 0, - "asset": { - "votes": [ - "+03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357" - ] - }, - "signature": "30440220158ed59156e0eef2d2b94a296451dffe079be701b3d74f0443ef43bc266b334202205a2c39f57abfcd279d568608b90884b3ebe107316aa7552eca35c743b318a47c", - "id": "ea294b610e51efb3ceb4229f27bf773e87f41d21b6bb1f3bf68629ffd652c2d3", - "senderId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7", - "senderPublicKey": "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80", - "timestamp": 0, - "asset": { - "votes": [ - "+030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80" - ] - }, - "signature": "3045022100898da9f693a458a6875344c6c4cb73069c4075904c75595ffbc665967d84b07002200f168aaf3ab1b52dfa74599394387dc4cf627a447fbc5a91000e9d251cdb20c0", - "id": "3639b5dc6d19d46d8254d941bf7ace0f3da8a7cf8a56361921b260820c7239cd", - "senderId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1", - "senderPublicKey": "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e", - "timestamp": 0, - "asset": { - "votes": [ - "+032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e" - ] - }, - "signature": "3044022055ed9a8b55ccb3bd0945a710269b6f243f1dbfaa28467d3218a17565eb0c962d02207d31561478f16d93a20f5454ad565dea24e8dda4ddc464cb011f4b6b360c4e81", - "id": "fe24509580cde0c2e2f49defedd3a0f7572d2f78f90b51a253b0d8cebd74c20d", - "senderId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof", - "senderPublicKey": "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055", - "timestamp": 0, - "asset": { - "votes": [ - "+0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055" - ] - }, - "signature": "30440220092f367f833d677e8d0609ad1df65f389c2c35d1501c71c245c2982e6a832268022018e67445f525613d6cb6ac0c9683bd0f55bd40d9c929165649414f083c9041f9", - "id": "6a76553db794ebf4d5f60a7d7d71cfe29f4dbcaad9610106fbc578cdc7167cd4", - "senderId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy", - "senderPublicKey": "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2", - "timestamp": 0, - "asset": { - "votes": [ - "+03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2" - ] - }, - "signature": "304402203dc028b5013c36b03f97b111a8d7c05d0cd8e505b0b0d18747c0656c9b5cfe8102205e9ce8a78d1183b3e9880c69635d04218d94d17808bcc3f92e7af53195c23daf", - "id": "0f9d7e7708918b77afbdfffb63eef8fe87ba36e0131c88b44c1a7f81750cc025", - "senderId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9", - "senderPublicKey": "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e", - "timestamp": 0, - "asset": { - "votes": [ - "+0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e" - ] - }, - "signature": "3045022100a80ddd7c3adaf0e97ab938773fc78a716f3054d7e03afc1ddfcb5005badbd2810220231c0dabe2262149f994c939f9dc90d46b9bd7ca96b19aad6788cd3571e4f71a", - "id": "0ac77b2637fb25be42b3b60d1651bbbd788aeaba933a08ec4a417c7b4c54e087", - "senderId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT", - "senderPublicKey": "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883", - "timestamp": 0, - "asset": { - "votes": [ - "+02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883" - ] - }, - "signature": "30440220772c9cd8b96f74fcddc429d57d466eca6fc40fc211845f59eeb78cb027e116c5022004cda291587eb118d622de21333d2a5783969794b5b0101ad8b1044c7d8058af", - "id": "4b0dda465564d53981c0e36d73caec888e3523633eaa80dfb99a9c81b2604c7d", - "senderId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU", - "senderPublicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252", - "timestamp": 0, - "asset": { - "votes": [ - "+0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252" - ] - }, - "signature": "30440220406d54714b6425ae4553ea8bec75f31fe52e9b1a9b6f6897151253ab7f637d3b022040a2df4b69840f4d9b0b67658c75efdae8d8269780d4cc50d055fa63922dbb9a", - "id": "c7db9d36d97ff0168d0d670ec695e1dc786dfb93f4081586870c8793b50e5f17", - "senderId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK", - "senderPublicKey": "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4", - "timestamp": 0, - "asset": { - "votes": [ - "+030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4" - ] - }, - "signature": "3044022018b7e51118ec83c985fa4eb3d7f0cf0655753bcbde7e82bac521665fb1c0ffaf02204e2ace460b2542db8c77e41d05d5e02fa5514b746a0a1e947256925846ed19f1", - "id": "c41f4cffcdd523f1718154d5bd5f4f0bec0376076b5f8dd340337e9edb4821ae", - "senderId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW", - "senderPublicKey": "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28", - "timestamp": 0, - "asset": { - "votes": [ - "+03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28" - ] - }, - "signature": "304502210088dbe249503da43c157485bfd4f2c95babfe4d0b8bbefe44afa52529b824a79e022045239b6a374fd9aca52c27171ee66b4863c956ae4085c9760d863b1902596c1a", - "id": "b1736ec6a1ea4c6d4eb278430a8ee214c88daefe296ba98530e692f8b7a7434c", - "senderId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej", - "senderPublicKey": "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d", - "timestamp": 0, - "asset": { - "votes": [ - "+02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d" - ] - }, - "signature": "3045022100fcdf750a775e728a31691a1b38908a7f990b579da510959cc2c63442f5ffde760220316ebb051d9fecb2486771dd39921fb12675b6d46b2441dd1db3c42fad0a59b0", - "id": "069271456015c2ff842771775993b8afc3404bc070572eeeb0f2fd72d58e18dc", - "senderId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U", - "senderPublicKey": "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294", - "timestamp": 0, - "asset": { - "votes": [ - "+0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294" - ] - }, - "signature": "3044022034ce8f77ea9d0f5cf3a9135d7b72d0ba3b96ac6d7eaa3670e9956aef2c9a83cb0220626d1f269128f673a23f9993ce00ba78a08103e697298be29a4c8ee94f204e3a", - "id": "9a99bba8340e7ad4e05d8424a0977ebbde428d31ee066c9828bd06b42bb42a72", - "senderId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2", - "senderPublicKey": "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983", - "timestamp": 0, - "asset": { - "votes": [ - "+02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983" - ] - }, - "signature": "3044022039ae1155f8b87a61c38b25cbbf30da6ecf6cfcc12b25c2e7fe576373754a41eb0220061a66a893129fbad5d48cdd19cf48b1a0d133dd2f3ecdc60ee7b87277e1f81d", - "id": "6c2c8926420ac269b50fa30127e0e791afb2131aff5821ca7aa80d38a0182048", - "senderId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf", - "senderPublicKey": "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964", - "timestamp": 0, - "asset": { - "votes": [ - "+02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964" - ] - }, - "signature": "3045022100d0dac2b7691aa059b1048d7925a0c5d5099f6e9b0f2e321e6d4f128ab1b3272b02207e8c4f643f8f9d1c3f81f0cce6a698df2da2ab71d5b01042766bbe0f46f4a775", - "id": "9259193c5de72276ed7a99f9d507dd6ea9856411fda521074fb41a556294fdf7", - "senderId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9", - "senderPublicKey": "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5", - "timestamp": 0, - "asset": { - "votes": [ - "+03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5" - ] - }, - "signature": "3045022100d5496fec447367ab6b53956a8c40cd8566e050ebb3b92d2c0b2a9d09bef36c7402205e32367605372375801f7b9db39aaafb46ee763b1494f0aca144fb91f3415752", - "id": "2a41e5946ab0773ca2334bba9d3510184bdd258f1c651ff8ec95b7b64a01dc2e", - "senderId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW", - "senderPublicKey": "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95", - "timestamp": 0, - "asset": { - "votes": [ - "+039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95" - ] - }, - "signature": "304502210099249695dc38826e04c8fcffd2570b98c43dec4788cc6a19737ed0872f17ec3302205301f645d803ad5df4ab1a700446e28c7cd76153607f6a2d68ae9168d46f3fe9", - "id": "e5c09b0fb2c24c57a4dcef0078953093800329ab4dc8e16a9d9f68215b5acd3d", - "senderId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU", - "senderPublicKey": "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a", - "timestamp": 0, - "asset": { - "votes": [ - "+034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a" - ] - }, - "signature": "3045022100f983b03e319aaa6c6ab6381e3ef8c0c035d6e3cc2139cedf70fd4e385393e38a0220286f73577765eb3e89e362785ad8a6de572bebf41bbc1f515b0ea93e41801eb3", - "id": "00b2c0455ef6f508d65f11bb49e3cfe1e6062d5fd153cafdfdfd2ccbf9c646e5", - "senderId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr", - "senderPublicKey": "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689", - "timestamp": 0, - "asset": { - "votes": [ - "+022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689" - ] - }, - "signature": "30440220103862ec51621ca27a0ec6b2817848e8824d2d09dbf7e6aac2f45aeea5d2dc9102205e8cce78b5cd7148aa4d406dc7b491dd7758047200e10cfe1e5fde5c56107ac5", - "id": "e25439ad11cb8db3d49ccb3b8b608c1bcb24cb29b2e5ea15101cce3e475224eb", - "senderId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ", - "senderPublicKey": "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a", - "timestamp": 0, - "asset": { - "votes": [ - "+03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a" - ] - }, - "signature": "304502210099241ced4a0fd1eb02f5cdcc880ae5f48eb3c7e490d4520c20124ecbf403893602204729dc6cacf3e87c97ca57c1be54d1e80791bf31ef022135e68fc06c950f6994", - "id": "1474f50815c6c7df41ab652414806d61abe15bee0d41f32d772f4e2793badce4", - "senderId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX", - "senderPublicKey": "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a", - "timestamp": 0, - "asset": { - "votes": [ - "+0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a" - ] - }, - "signature": "3045022100eccf81d44992c49a5ee37c6fc2ccc4b6bee9aa44888513b3e18e79452ede3156022056b0ddf079d2918d72e8781d3af009c87e6058563591dfd6ee0117b7df5534b2", - "id": "b394e2a8b5c2d20a72ed288408b8f0d48aed922edbee6e16c1c5b0e67517214c", - "senderId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf", - "senderPublicKey": "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f", - "timestamp": 0, - "asset": { - "votes": [ - "+03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f" - ] - }, - "signature": "3045022100bdb87894846eccc5a5473edaee1e6dca5f3469963e22f06123b6bde195aede0e02203d0c6833e87c5e60f4597ce624d4c2502a0562b4e54d943f82a4889e3cd69532", - "id": "6a399099bac6c74fa5e956512ef8b3a39f6f946d5d6996f192c2f1dd5ba172dc", - "senderId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv", - "senderPublicKey": "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751", - "timestamp": 0, - "asset": { - "votes": [ - "+02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751" - ] - }, - "signature": "304402200785771ccf1a6a40b51183a190d4cb4ce76b9ffd4c2c736d7724e6c667113d020220649ecfe73017d8dda96a7914793470ee7e582693e4866df123b1032194c163b1", - "id": "f20a831a6bae0a85470e308fb66517e70db479657459f6bb39f2cd1783c565e6", - "senderId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv", - "senderPublicKey": "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb", - "timestamp": 0, - "asset": { - "votes": [ - "+0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb" - ] - }, - "signature": "3044022020b79e1f07bcb17cae9485b9f44e9f583ca235da4ddd363b905fafb884347f71022015a20481b43720ddb3b1e3ca64b1f47e59b5cc2016a62f43327ca14533384dd4", - "id": "7a1285be87dca9718bece5b84266c1bf6801a39cc111d534e660aef9e6d26929", - "senderId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg", - "senderPublicKey": "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d", - "timestamp": 0, - "asset": { - "votes": [ - "+0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d" - ] - }, - "signature": "3045022100b1615d16763c46d42ca2aae967f04c1c07c119b5af7a378c262ba85515a8d35002202cf7df91676cd137943720e93f06c11907412a6bdc5ef2157cf536a203cf83a3", - "id": "76fb5a1de90f245b1eeb79cb11c7bea7c8b738add0fb8cd95191186a944b0229", - "senderId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri", - "senderPublicKey": "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a", - "timestamp": 0, - "asset": { - "votes": [ - "+02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a" - ] - }, - "signature": "3045022100e3c7b5d6a72acde4d22e8c1c6cd864c549deba89683f4b84320407d6c380827c02202da57df0ab7cd381b776bdf85802aed371e7cea7269a84f911b1d8e9956badee", - "id": "8da75c8100e6248ab37cc92f72ed9facec3067f4f82f03db8bb8063791463fb3", - "senderId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t", - "senderPublicKey": "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe", - "timestamp": 0, - "asset": { - "votes": [ - "+03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe" - ] - }, - "signature": "304402205779b5d8acbfedfc105fedb6fcbd4636713ed27605faa9bd988598072640a958022042d8a8b3d7910c7c385f3707a317c5d445d56da250f8d127c71df2d9d4c5d86e", - "id": "fd26e265be88289828d0ce7ffc5faeb9849e1f4cb37a8f1dd5d6fcc436d910b7", - "senderId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf", - "senderPublicKey": "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e", - "timestamp": 0, - "asset": { - "votes": [ - "+034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e" - ] - }, - "signature": "3045022100e18a89fe1fe0a8acaca2b6461314e784ffebbe7374f6aafdb06934e83985ccbf022027314b21a4a25b477bd7cc070b4e00ef8f3d69f3f1af028b96571dc245924c00", - "id": "41d92e128e6b8367cbf8fd111e5263d52e1abad553653f975dd60d7f7c5b637b", - "senderId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9", - "senderPublicKey": "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9", - "timestamp": 0, - "asset": { - "votes": [ - "+02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9" - ] - }, - "signature": "304402201c614c84dbae26f87973c9e2b38df883fe0c8c469080e31fe32a4c4946d50b67022075b8fb498fb1384aa6be785845da02813185ccf095597b5782618033828af4d5", - "id": "1e4a1f8aab6fbf8682c2b35e0d04e9e007ae717ce3f4a82894747e5807e3c759", - "senderId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV", - "senderPublicKey": "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca", - "timestamp": 0, - "asset": { - "votes": [ - "+02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca" - ] - }, - "signature": "3045022100b1ee6becc59d594776a40e5b3caec82390d273b703ecb0d7caece44953141449022016543cc29a28882845118afab6e51296cd216bc662260c28e5efd9597b6025b1", - "id": "2ce068bfccb3f967f4004e9a1e81614a738e55e45c80114c0af30a085f71a2e9", - "senderId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ", - "senderPublicKey": "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c", - "timestamp": 0, - "asset": { - "votes": [ - "+022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c" - ] - }, - "signature": "3044022036698a329d7f5f751f91ce02bc188a7527a377d01583b70427cfce64def945ec022079afafea10aa32394a1e42a80577de3869856656221d5f259e05fb44f01668b8", - "id": "3478d1ad3655e10fcc864f191972322c866616866bb1dbf66d7b66b31cd95de6", - "senderId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA", - "senderPublicKey": "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24", - "timestamp": 0, - "asset": { - "votes": [ - "+03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24" - ] - }, - "signature": "3044022035fa7be80cf881eefefc12b11de04ffb2e2e92815cf05074afef54a3c5b2eccb022041f3347f59db0b3caadefcbfbc5ae275d3fe3e2a52fe1504b23628d4b79a43bf", - "id": "8adfd8e73e96188ed9fdec459d88db1fb041a2b25b3f64830476aec661ae5010", - "senderId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm", - "senderPublicKey": "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f", - "timestamp": 0, - "asset": { - "votes": [ - "+021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f" - ] - }, - "signature": "30440220630da8a73979bd3988b7f84fe9e83a429cf3239f54c140c3dbcc407140513fc002203664ad54ed9f199f2683479b988bd97ad8fffb2c2d5dfdbdb10858aca4abfaca", - "id": "e306328ffefcd9e3809e7390a358199a62cf8ef037d57af1f5c7b54d728d427e", - "senderId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1", - "senderPublicKey": "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b", - "timestamp": 0, - "asset": { - "votes": [ - "+02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b" - ] - }, - "signature": "304402206f1df93f299ffedacc25aa201807df47d32c43369315cf9db280963c357be56302206a66acd553710f49bbb7b803a2bcb71128c8e617ffce66b37b7c968817349247", - "id": "dc69bc8f78502ba34655ed062987788939189709a4112760cd8807245d7461f5", - "senderId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8", - "senderPublicKey": "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12", - "timestamp": 0, - "asset": { - "votes": [ - "+03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12" - ] - }, - "signature": "30440220629e696a10e04d4fbc10a5ac443bf9bd40dd5d89d4b214224abe47d7ab5600340220643f361a24d9916e2c5aaec7bd7d8a6a0d3ffc5fc0b62c3ac4906eb799a862fa", - "id": "c3f49fb80c40f7779b32ba23616f5573a6ba58fc60c4629c2252933038dd89f0", - "senderId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2", - "senderPublicKey": "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904", - "timestamp": 0, - "asset": { - "votes": [ - "+0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904" - ] - }, - "signature": "30440220660f9604896dad2a97820b0d7524f0bce5a8b5766f150517d5061fd02bddf768022055e87c25891d4480e66e5d1a71e42cd5a4bef3ab2b2651cd72d44f30a4b32309", - "id": "8e8ac1b1a586e86867abbf25d63387bb6dfb793c691f0b06333c1581a9a568b3", - "senderId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT", - "senderPublicKey": "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c", - "timestamp": 0, - "asset": { - "votes": [ - "+034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c" - ] - }, - "signature": "304402202e2ad64129f61ef1156c4c7e80ab862d4823d62dac502685f53028536ddfb41a02201a3ec777fdfe8fae9f7cd5251fac322c1b6a2a4d41b3ec456daed474986d4872", - "id": "ff73565c373f2cefebf86c72dda3a6a6205750eb03b69178cb83378620715e1d", - "senderId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q", - "senderPublicKey": "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd", - "timestamp": 0, - "asset": { - "votes": [ - "+02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd" - ] - }, - "signature": "304402202e5c78cf21a088db10e1e1f64d98d84c8d3294fde7bc322d4af06bfe99d4c2e302207e7912a16a37b641a9f8c7c722f2b0d699917ca73e4d0f21584b717fb7f02f13", - "id": "3822273b496f2e253081cedf382e4f9937713fabb83449e1f892377cf536e68a", - "senderId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo", - "senderPublicKey": "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647", - "timestamp": 0, - "asset": { - "votes": [ - "+0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647" - ] - }, - "signature": "3045022100a65ce45164c9bc3e018e26703370c9deb2933ee3b4e814619043cc37c4a39c4802205ae4931ac9e8dffd714c3b601fe248a49c0185c8367887205f497d951c52eb54", - "id": "430d6db0b87c25dce4ce14ac907c13bcc6efa5d95135f05aa4ba7596ea9d400c", - "senderId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN", - "senderPublicKey": "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd", - "timestamp": 0, - "asset": { - "votes": [ - "+036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd" - ] - }, - "signature": "3045022100f3cdd7f688ad2d7b6a5b9cc7e793cb8a6e6e07d3327bc67add64691a53fd2911022026ae1adc8f4fcfc01bcca3efc83019026755b443a504265ad1f46f69d1f5951c", - "id": "dda86ecc0332e6c4eed1c0a5af7424374089b85dd274a300fed51b86e2655587", - "senderId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj", - "senderPublicKey": "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564", - "timestamp": 0, - "asset": { - "votes": [ - "+03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564" - ] - }, - "signature": "3045022100d419072a752acd55792257c96099fb14c56c29112a00535d39bca96fbd7951c902201abdf4db247dc956d79f4543c389823fbd1a9337f95d30df39603a3b52486bfb", - "id": "0998e9a055c53bf6697ee76af94c7a830c1364016d78fce889a21bc38ed70cd5", - "senderId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN", - "senderPublicKey": "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0", - "timestamp": 0, - "asset": { - "votes": [ - "+022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0" - ] - }, - "signature": "3045022100ba1e0ab761326d2a53cbda2a4a5135033c94d8166864d2ad3ceb963b4a0c046402207d755ecf4ada9fa2a598fd75e73a59d30cb83e01f510020b48b6bf162dc60b27", - "id": "be13743deb8486a575d1fb564d2b07d797ac77148d35793c9aca43c0d47aad61", - "senderId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA", - "senderPublicKey": "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b", - "timestamp": 0, - "asset": { - "votes": [ - "+03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b" - ] - }, - "signature": "3044022038a491e2e13ac32025209d00aec1af31b73a8b6ee77ad9b8bb80a34f5df59dfc02200ce82c89fe9f88bd5af236ceeaa80f9954e3fb4af7bc884c447505751d49c134", - "id": "f1d3d44cc289837de9623cba8891a1ed1cde8918473a91e2daead29975afad22", - "senderId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx", - "senderPublicKey": "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc", - "timestamp": 0, - "asset": { - "votes": [ - "+0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc" - ] - }, - "signature": "304402202ae599ce389cd030b8ab48ef53113458b9ba8bf9c9ed09c662eba2849bf540f802202ed63f8af492dd0b67d1b451170a989418a42466a3a7ffe89c4c5a18337e8fb9", - "id": "65ab302a44ea7550891eabc3b4a8d5ecbcb80784c4666195d5d0b7e33394300d", - "senderId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK", - "senderPublicKey": "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565", - "timestamp": 0, - "asset": { - "votes": [ - "+026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565" - ] - }, - "signature": "304502210088a3a4e82d307c238e01ce154b57631d4429e0b591e828ec36839a783736e842022042c6e1d719781e2edca3dbfe84ad13b9e490821a47ccadfcff379decb9c873c0", - "id": "d26a7ea56f398634a81086bb15c2f0c863c71b8bd728304d324d8245a8fb6c73", - "senderId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz", - "senderPublicKey": "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374", - "timestamp": 0, - "asset": { - "votes": [ - "+032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374" - ] - }, - "signature": "3045022100ae5805541f085a50076835422b2581d3b7a128a05b4f068ad7e3c14cd02799b802205f4bb40e06f90e02282ae74c0aba97923e601fd78234b9585468c4fb73f47893", - "id": "02504eae7ff4963c081219523bc48d7a07de4c29fdc1622224547f9a7c133abf", - "senderId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp", - "senderPublicKey": "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93", - "timestamp": 0, - "asset": { - "votes": [ - "+03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93" - ] - }, - "signature": "3044022078d38cabd8f427ef381d0aa6a0b98c6a590cb18f47acc1d80b429a1c1959b0ab022022a70d4d93d650ca3121dde6065e80cd90d1e2e91cb90f0d0b2eadde609e0d75", - "id": "addb8c1baa833baa52a5b51d8a86f8524bde826b5c9f0a99e57070e6323e1dfc", - "senderId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv", - "senderPublicKey": "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17", - "timestamp": 0, - "asset": { - "votes": [ - "+038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17" - ] - }, - "signature": "3044022076dd065e3fba825b77884a179d0231d7fc9e7d3a02e34bc6565fab81a84e559e02200a880c028e690a9d6f2c4c6576b1bf3e913817c834da8ec6afdbadfae78d341d", - "id": "72f31f9a829b93045ef2e860b24c33b9be6a2621c26914acd42121215c1d517e", - "senderId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P", - "senderPublicKey": "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1", - "timestamp": 0, - "asset": { - "votes": [ - "+030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1" - ] - }, - "signature": "304402205261d9d8ded6364fda8b10bd477982be84990cb010f9214d52c492676814e1f40220489f441ffe2478d361a12ab96caa59da495fe62d61d0e2255aa5ec4ed789afb8", - "id": "1f17b4ba072d205761ed3f786491eaf684ed3601b69082e487e568aa74a319e8", - "senderId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd", - "senderPublicKey": "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d", - "timestamp": 0, - "asset": { - "votes": [ - "+02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d" - ] - }, - "signature": "3044022040219da41054a3eebd3122df7f09a62a4e8b4fdc287ae77221f2217b42f291ad02202b9a70c54bb546a604eafadcc086ef6b6570f57542374d87de02ad7f61fe51a4", - "id": "5fa837023159d6a3d6cf7c5b2ed6fe05ff7df19300226b2f0be5a48a06993780", - "senderId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo", - "senderPublicKey": "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37", - "timestamp": 0, - "asset": { - "votes": [ - "+03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37" - ] - }, - "signature": "3045022100ded426768f114f459485ba6ae293c9649b340cf2dcb15e8e887fbb5fed6f7e0b0220752297022de6e93ff64bb9e07b4efef8e946cd2872f84d9e1cb3165ff5c342cb", - "id": "0a16dc31514629a36d7237968ada6a95d6cbec027b7d26e1e0f0d7d4febe9494", - "senderId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD", - "senderPublicKey": "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a", - "timestamp": 0, - "asset": { - "votes": [ - "+02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a" - ] - }, - "signature": "304402203aa292e7aedcd62bb5a79c2521b666b8e1886b57923d98f51911b0461cfdb5db0220539657d5c1dcb78c2c86376da87cc0db428e03c53da3f4f64ebe7115998f00b6", - "id": "8816f8d8c257ea0c951deba911266394b0f2614df023f8b4ffd9da43d36efd9d", - "senderId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD" - }], - "height": 1, - "id": "17184958558311101492", - "blockSignature": "304402202fe5de5697fa25d3d3c0cb24617ac02ddfb1c915ee9194a89f8392f948c6076402200d07c5244642fe36afa53fb2d048735f1adfa623e8fa4760487e5f72e17d253b" -} diff --git a/packages/core-api/__tests__/__support__/config/network.json b/packages/core-api/__tests__/__support__/config/network.json deleted file mode 100644 index b3cadc36f1..0000000000 --- a/packages/core-api/__tests__/__support__/config/network.json +++ /dev/null @@ -1,63 +0,0 @@ -{ - "name": "testnet", - "messagePrefix": "TEST message:\n", - "bip32": { - "public": 70617039, - "private": 70615956 - }, - "pubKeyHash": 23, - "nethash": "d9acd04bde4234a81addb8482333b4ac906bed7be5a9970ce8ada428bd083192", - "wif": 186, - "client": { - "token": "TARK", - "symbol": "TѦ", - "explorer": "http://texplorer.ark.io" - }, - "constants": [{ - "height": 1, - "reward": 0, - "activeDelegates": 51, - "blocktime": 8, - "block": { - "version": 0, - "maxTransactions": 50, - "maxPayload": 2097152 - }, - "epoch": "2017-03-21T13:00:00.000Z", - "fees": { - "dynamic" : false, - "transfer": 10000000, - "secondSignature": 500000000, - "delegateRegistration": 2500000000, - "vote": 100000000, - "multiSignature": 500000000, - "ipfs": 0, - "timelockTransfer": 0, - "multiPayment": 0, - "delegateResignation": 0 - }, - "dynamicOffsets": { - "transfer": 100, - "secondSignature": 250, - "delegateRegistration": 500, - "vote": 100, - "multiSignature": 500, - "ipfs": 250, - "timelockTransfer": 500, - "multiPayment": 500, - "delegateResignation": 500 - } - }, - { - "height": 10, - "fees":{ - "dynamic" : true - } - }, - { - "height": 75600, - "reward": 200000000 - } -], - "exceptions": {} -} diff --git a/packages/core-api/__tests__/__support__/config/peers.json b/packages/core-api/__tests__/__support__/config/peers.json deleted file mode 100644 index 39032336cb..0000000000 --- a/packages/core-api/__tests__/__support__/config/peers.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "blackList": [], - "list": [{ - "ip": "167.114.29.32", - "port": 4002 - }, { - "ip": "167.114.29.33", - "port": 4002 - }, { - "ip": "167.114.29.34", - "port": 4002 - }, { - "ip": "167.114.29.35", - "port": 4002 - }, { - "ip": "167.114.29.36", - "port": 4002 - }] -} diff --git a/packages/core-api/__tests__/__support__/config/plugins.js b/packages/core-api/__tests__/__support__/config/plugins.js deleted file mode 100644 index 3ab6efcef0..0000000000 --- a/packages/core-api/__tests__/__support__/config/plugins.js +++ /dev/null @@ -1,24 +0,0 @@ -module.exports = { - '@arkecosystem/core-event-emitter': {}, - '@arkecosystem/core-config': {}, - '@arkecosystem/core-logger': {}, - '@arkecosystem/core-logger-winston': {}, - '@arkecosystem/core-database': {}, - '@arkecosystem/core-database-sequelize': { - dialect: 'sqlite', - storage: ':memory:' - }, - '@arkecosystem/core-transaction-pool': {}, - '@arkecosystem/core-transaction-pool-redis': {}, - '@arkecosystem/core-p2p': {}, - '@arkecosystem/core-blockchain': {}, - '@arkecosystem/core-api': { - enabled: true, - whitelist: [ - '127.0.0.1', - '::ffff:127.0.0.1' - ] - }, - '@arkecosystem/core-webhooks': {}, - '@arkecosystem/core-forger': {} -} diff --git a/packages/core-api/__tests__/__support__/config/server.json b/packages/core-api/__tests__/__support__/config/server.json deleted file mode 100644 index fb863dc1a5..0000000000 --- a/packages/core-api/__tests__/__support__/config/server.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "port": 4002, - "version": "2.0.0" -} diff --git a/packages/core-api/__tests__/__support__/setup.js b/packages/core-api/__tests__/__support__/setup.js index 8413c29638..fd3bad69ac 100644 --- a/packages/core-api/__tests__/__support__/setup.js +++ b/packages/core-api/__tests__/__support__/setup.js @@ -1,31 +1,26 @@ -'use strict' - -const path = require('path') -const container = require('@arkecosystem/core-container') +const app = require('@arkecosystem/core-container') +const appHelper = require('@arkecosystem/core-test-utils/lib/helpers/container') +const activeDelegates = require('@arkecosystem/core-test-utils/fixtures/testnet/delegates') const generateRound = require('./utils/generate-round') -const activeDelegates = require('../__fixtures__/delegates.json') -const round = generateRound(activeDelegates, 1) + +const round = generateRound( + activeDelegates.map(delegate => delegate.publicKey), + 1, +) exports.setUp = async () => { jest.setTimeout(60000) - process.env.ARK_SKIP_BLOCKCHAIN_STARTED_CHECK = true - - await container.setUp({ - data: '~/.ark', - config: path.resolve(__dirname, './config') - }, { - exit: '@arkecosystem/core-api' - }) + await appHelper.setUp({}) - // seed - const connection = container.resolvePlugin('database') + const connection = app.resolvePlugin('database') + await connection.db.rounds.truncate() await connection.buildWallets(1) await connection.saveWallets(true) await connection.saveRound(round) } exports.tearDown = async () => { - await container.tearDown() + await app.tearDown() } diff --git a/packages/core-api/__tests__/__support__/utils/generate-round.js b/packages/core-api/__tests__/__support__/utils/generate-round.js index 379d1eb977..69eb78bb8b 100644 --- a/packages/core-api/__tests__/__support__/utils/generate-round.js +++ b/packages/core-api/__tests__/__support__/utils/generate-round.js @@ -1,7 +1,7 @@ -module.exports = (delegates, round) => { - return delegates.map(delegate => ({ - round, - publicKey: delegate, - balance: '245098000000000' - })) -} +const { bignumify } = require('@arkecosystem/core-utils') + +module.exports = (delegates, round) => delegates.map(delegate => ({ + round, + publicKey: delegate, + voteBalance: bignumify('245098000000000'), +})) diff --git a/packages/core-api/__tests__/repositories/transactions.test.js b/packages/core-api/__tests__/repositories/transactions.test.js new file mode 100644 index 0000000000..f4ee83fc5d --- /dev/null +++ b/packages/core-api/__tests__/repositories/transactions.test.js @@ -0,0 +1,160 @@ +require('@arkecosystem/core-test-utils/lib/matchers') +const { crypto } = require('@arkecosystem/crypto') +const app = require('../__support__/setup') + +let genesisBlock +let genesisTransaction +let repository + +beforeAll(async () => { + await app.setUp() + + // Create the genesis block after the setup has finished or else it uses a potentially + // wrong network config. + genesisBlock = require('@arkecosystem/core-test-utils/config/testnet/genesisBlock.json') + genesisTransaction = genesisBlock.transactions[0] +}) + +afterAll(async () => { + await app.tearDown() +}) + +beforeEach(async () => { + repository = require('../../lib/repositories/transactions') +}) + +describe('Transaction Repository', () => { + describe('search', () => { + const expectSearch = async (params, expected) => { + // await connection.saveBlock(genesisBlock) + + const transactions = await repository.search(params) + expect(transactions).toBeObject() + + expect(transactions.count).toBeNumber() + + expect(transactions.rows).toBeArray() + expect(transactions.rows).not.toBeEmpty() + transactions.rows.forEach(transaction => { + expect(transaction).toContainKeys([ + 'id', + 'version', + 'sequence', + 'timestamp', + 'type', + 'amount', + 'fee', + 'serialized', + 'blockId', + 'senderPublicKey', + 'vendorFieldHex', + 'block', + ]) + }) + + expect(transactions.count).toBe(expected) + } + + it('should be a function', () => { + expect(repository.search).toBeFunction() + }) + + it('should search transactions by the specified `id`', async () => { + await expectSearch({ id: genesisTransaction.id }, 1) + }) + + it('should search transactions by the specified `blockId`', async () => { + await expectSearch({ blockId: genesisTransaction.blockId }, 153) + }) + + it('should search transactions by the specified `type`', async () => { + await expectSearch({ type: genesisTransaction.type }, 51) + }) + + it('should search transactions by the specified `version`', async () => { + await expectSearch({ version: genesisTransaction.version }, 153) + }) + + it('should search transactions by the specified `senderPublicKey`', async () => { + await expectSearch( + { senderPublicKey: genesisTransaction.senderPublicKey }, + 51, + ) + }) + + it('should search transactions by the specified `senderId`', async () => { + const senderId = crypto.getAddress(genesisTransaction.senderPublicKey, 23) + await expectSearch({ senderId }, 51) + }) + + it('should search transactions by the specified `recipientId`', async () => { + await expectSearch({ recipientId: genesisTransaction.recipientId }, 2) + }) + + it('should search transactions by the specified `timestamp`', async () => { + await expectSearch( + { + timestamp: { + from: genesisTransaction.timestamp, + to: genesisTransaction.timestamp, + }, + }, + 153, + ) + }) + + it('should search transactions by the specified `amount`', async () => { + await expectSearch( + { + amount: { + from: genesisTransaction.amount, + to: genesisTransaction.amount, + }, + }, + 50, + ) + }) + + it('should search transactions by the specified `fee`', async () => { + await expectSearch( + { + fee: { + from: genesisTransaction.fee, + to: genesisTransaction.fee, + }, + }, + 153, + ) + }) + + it('should search transactions by the specified `vendorFieldHex`', async () => { + await expectSearch( + { vendorFieldHex: genesisTransaction.vendorFieldHex }, + 153, + ) + }) + + describe('when there are more than 1 condition', () => { + it('should search transactions that includes all of them (AND)', async () => { + await expectSearch( + { recipientId: genesisTransaction.recipientId, type: 3 }, + 1, + ) + }) + }) + + describe('when no results', () => { + it('should not return them', async () => { + // await connection.saveBlock(genesisBlock) + + const transactions = await repository.search({ recipientId: 'dummy' }) + expect(transactions).toBeObject() + + expect(transactions).toHaveProperty('count', 0) + + expect(transactions.rows).toBeArray() + expect(transactions.rows).toBeEmpty() + }) + }) + }) +}) diff --git a/packages/core-api/__tests__/utils/delegate-calculator.test.js b/packages/core-api/__tests__/utils/delegate-calculator.test.js deleted file mode 100644 index d08c2239d9..0000000000 --- a/packages/core-api/__tests__/utils/delegate-calculator.test.js +++ /dev/null @@ -1,69 +0,0 @@ -'use strict' - -const { Wallet } = require('@arkecosystem/crypto').models -const container = require('@arkecosystem/core-container') -const delegateCalculator = require('../../lib/utils/delegate-calculator') - -let delegate - -beforeEach(() => { - delegate = new Wallet('D61xc3yoBQDitwjqUspMPx1ooET6r1XLt7') - Object.entries({ - balance: 109390000000, - votebalance: 0, - producedBlocks: 0, - missedBlocks: 0 - }).forEach((key, value) => (delegate[key] = value)) -}) - -describe('Delegate Calculator', () => { - describe('calculateApproval', () => { - it('should be a function', () => { - expect(delegateCalculator.calculateApproval).toBeFunction() - }) - - it.skip('should calculate correctly', () => { - delegate.votebalance = 100000 * Math.pow(10, 8) - container.resolvePlugin = jest.fn(plugin => { - if (plugin === 'blockchain') { - return { - getLastBlock: () => { - return { - data: { - height: 1 - } - } - } - } - } else if (plugin === 'config') { - return { - getConstants: () => { - return { - height: 1, - reward: 1 * Math.pow(10, 8) - } - }, - genesisBlock: { - totalAmount: 1000000 * Math.pow(10, 8) - } - } - } - }) - - expect(delegateCalculator.calculateApproval(delegate)).toBe(0.5) - }) - }) - - describe('calculateProductivity', () => { - it('should be a function', () => { - expect(delegateCalculator.calculateProductivity).toBeFunction() - }) - - it('should calculate correctly', () => { - delegate.missedBlocks = 10 - delegate.producedBlocks = 100 - - expect(delegateCalculator.calculateProductivity(delegate)).toBe(90.91) - }) - }) -}) diff --git a/packages/core-api/__tests__/v1/handlers/accounts.test.js b/packages/core-api/__tests__/v1/handlers/accounts.test.js index d0d4675ebb..50c2cbc89e 100644 --- a/packages/core-api/__tests__/v1/handlers/accounts.test.js +++ b/packages/core-api/__tests__/v1/handlers/accounts.test.js @@ -1,5 +1,4 @@ -'use strict' - +require('@arkecosystem/core-test-utils/lib/matchers') const app = require('../../__support__/setup') const utils = require('../utils') @@ -17,7 +16,7 @@ describe('API 1.0 - Wallets', () => { describe('GET api/accounts/getAllAccounts', () => { it('should return all the wallets', async () => { const response = await utils.request('GET', 'accounts/getAllAccounts') - utils.expectSuccessful(response) + expect(response).toBeSuccessfulResponse() expect(response.data.accounts).toBeArray() }) @@ -26,7 +25,7 @@ describe('API 1.0 - Wallets', () => { describe('GET api/accounts/?address', () => { it('should return account information', async () => { const response = await utils.request('GET', 'accounts', { address }) - utils.expectSuccessful(response) + expect(response).toBeSuccessfulResponse() utils.expectWallet(response.data.account) }) @@ -34,8 +33,10 @@ describe('API 1.0 - Wallets', () => { describe('GET api/accounts/getBalance?address', () => { it('should return balance', async () => { - const response = await utils.request('GET', 'accounts/getBalance', { address }) - utils.expectSuccessful(response) + const response = await utils.request('GET', 'accounts/getBalance', { + address, + }) + expect(response).toBeSuccessfulResponse() expect(response.data.balance).toBeString() expect(response.data.unconfirmedBalance).toBeString() @@ -44,8 +45,10 @@ describe('API 1.0 - Wallets', () => { describe('GET /accounts/getPublicKey?address', () => { it('should return public key for address', async () => { - const response = await utils.request('GET', 'accounts/getPublicKey', { address }) - utils.expectSuccessful(response) + const response = await utils.request('GET', 'accounts/getPublicKey', { + address, + }) + expect(response).toBeSuccessfulResponse() expect(response.data.publicKey).toBeString() }) @@ -54,7 +57,7 @@ describe('API 1.0 - Wallets', () => { describe('GET api/accounts/delegates/fee', () => { it('should return delegate fee of an account', async () => { const response = await utils.request('GET', 'accounts/delegates/fee') - utils.expectSuccessful(response) + expect(response).toBeSuccessfulResponse() expect(response.data.fee).toBeNumber() }) @@ -62,8 +65,10 @@ describe('API 1.0 - Wallets', () => { describe('GET /accounts/delegates?address', () => { it('should return delegate info the address has voted for', async () => { - const response = await utils.request('GET', 'accounts/delegates', { address }) - utils.expectSuccessful(response) + const response = await utils.request('GET', 'accounts/delegates', { + address, + }) + expect(response).toBeSuccessfulResponse() expect(response.data.delegates).toBeArray() expect(response.data.delegates[0].producedblocks).toBeNumber() @@ -73,7 +78,7 @@ describe('API 1.0 - Wallets', () => { describe('GET api/accounts/top', () => { it('should return the top wallets', async () => { const response = await utils.request('GET', 'accounts/top') - utils.expectSuccessful(response) + expect(response).toBeSuccessfulResponse() expect(response.data.accounts).toBeArray() }) @@ -82,7 +87,7 @@ describe('API 1.0 - Wallets', () => { describe('GET api/accounts/count', () => { it('should return the total number of wallets', async () => { const response = await utils.request('GET', 'accounts/count') - utils.expectSuccessful(response) + expect(response).toBeSuccessfulResponse() expect(response.data.count).toBeNumber() }) diff --git a/packages/core-api/__tests__/v1/handlers/blocks.test.js b/packages/core-api/__tests__/v1/handlers/blocks.test.js index 2b0527178d..2ddb2c8c14 100644 --- a/packages/core-api/__tests__/v1/handlers/blocks.test.js +++ b/packages/core-api/__tests__/v1/handlers/blocks.test.js @@ -1,5 +1,4 @@ -'use strict' - +require('@arkecosystem/core-test-utils/lib/matchers') const app = require('../../__support__/setup') const utils = require('../utils') @@ -10,7 +9,7 @@ beforeAll(async () => { // Create the genesis block after the setup has finished or else it uses a potentially // wrong network config. - genesisBlock = require('../../__support__/config/genesisBlock.json') + genesisBlock = require('@arkecosystem/core-test-utils/config/testnet/genesisBlock.json') }) afterAll(async () => { @@ -20,8 +19,10 @@ afterAll(async () => { describe('API 1.0 - Blocks', () => { describe('GET /blocks/get?id', () => { it('should return blocks based on id', async () => { - const response = await utils.request('GET', 'blocks/get', { id: genesisBlock.id }) - utils.expectSuccessful(response) + const response = await utils.request('GET', 'blocks/get', { + id: genesisBlock.id, + }) + expect(response).toBeSuccessfulResponse() expect(response.data.block).toBeObject() expect(response.data.block.id).toBeString() @@ -29,7 +30,9 @@ describe('API 1.0 - Blocks', () => { }) it('should return block not found', async () => { - const response = await utils.request('GET', 'blocks/get', { id: '18777we16674628308671' }) + const response = await utils.request('GET', 'blocks/get', { + id: '18777we16674628308671', + }) utils.expectError(response) expect(response.data.error).toContain('not found') @@ -39,7 +42,7 @@ describe('API 1.0 - Blocks', () => { describe('GET /blocks?limit=XX', () => { it('should return 1 blocks', async () => { const response = await utils.request('GET', 'blocks', { limit: 1 }) - utils.expectSuccessful(response) + expect(response).toBeSuccessfulResponse() expect(response.data.blocks).toHaveLength(1) }) @@ -48,7 +51,7 @@ describe('API 1.0 - Blocks', () => { const response = await utils.request('GET', 'blocks', { limit: 500 }) utils.expectError(response) - expect(response.data.success).toBeFalsy() + expect(response.data.success).toBeFalse() expect(response.data.error).toContain('should be <= 100') }) }) @@ -56,7 +59,7 @@ describe('API 1.0 - Blocks', () => { describe('GET /blocks/getfees', () => { it('should return matching fees with the config', async () => { const response = await utils.request('GET', 'blocks/getFees') - utils.expectSuccessful(response) + expect(response).toBeSuccessfulResponse() expect(response.data.fees).toBeObject() @@ -65,7 +68,7 @@ describe('API 1.0 - Blocks', () => { 'secondsignature', 'delegate', 'vote', - 'multisignature' + 'multisignature', ]) }) }) @@ -73,7 +76,7 @@ describe('API 1.0 - Blocks', () => { describe('GET /blocks/getNethash', () => { it('should be ok', async () => { const response = await utils.request('GET', 'blocks/getNethash') - utils.expectSuccessful(response) + expect(response).toBeSuccessfulResponse() expect(response.data.nethash).toBeString() @@ -87,7 +90,7 @@ describe('API 1.0 - Blocks', () => { describe('GET /blocks/getMilestone', () => { it('should be ok', async () => { const response = await utils.request('GET', 'blocks/getMilestone') - utils.expectSuccessful(response) + expect(response).toBeSuccessfulResponse() expect(response.data.milestone).toBeNumber() }) @@ -96,7 +99,7 @@ describe('API 1.0 - Blocks', () => { describe('GET /blocks/getReward', () => { it('should be ok', async () => { const response = await utils.request('GET', 'blocks/getReward') - utils.expectSuccessful(response) + expect(response).toBeSuccessfulResponse() expect(response.data.reward).toBeNumber() }) @@ -105,7 +108,7 @@ describe('API 1.0 - Blocks', () => { describe('GET /blocks/getSupply', () => { it('should be ok', async () => { const response = await utils.request('GET', 'blocks/getSupply') - utils.expectSuccessful(response) + expect(response).toBeSuccessfulResponse() expect(response.data.supply).toBeNumber() }) @@ -114,7 +117,7 @@ describe('API 1.0 - Blocks', () => { describe('GET /blocks/getStatus', () => { it('should be ok', async () => { const response = await utils.request('GET', 'blocks/getStatus') - utils.expectSuccessful(response) + expect(response).toBeSuccessfulResponse() expect(response.data.epoch).toBeString() expect(response.data.height).toBeNumber() diff --git a/packages/core-api/__tests__/v1/handlers/delegates.test.js b/packages/core-api/__tests__/v1/handlers/delegates.test.js index 486888bc20..fbad0b5817 100644 --- a/packages/core-api/__tests__/v1/handlers/delegates.test.js +++ b/packages/core-api/__tests__/v1/handlers/delegates.test.js @@ -1,11 +1,11 @@ -'use strict' - +require('@arkecosystem/core-test-utils/lib/matchers') const app = require('../../__support__/setup') const utils = require('../utils') const delegate = { username: 'genesis_9', - publicKey: '0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647' + publicKey: + '0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647', } beforeAll(async () => { @@ -20,7 +20,7 @@ describe('API 1.0 - Delegates', () => { describe('GET /delegates', () => { it('should be ok', async () => { const response = await utils.request('GET', 'delegates') - utils.expectSuccessful(response) + expect(response).toBeSuccessfulResponse() expect(response.data).toBeObject() utils.expectDelegate(response.data.delegates[0]) @@ -29,16 +29,20 @@ describe('API 1.0 - Delegates', () => { describe('GET /delegates/get', () => { it('should be ok using a username', async () => { - const response = await utils.request('GET', 'delegates/get', { username: delegate.username }) - utils.expectSuccessful(response) + const response = await utils.request('GET', 'delegates/get', { + username: delegate.username, + }) + expect(response).toBeSuccessfulResponse() expect(response.data).toBeObject() utils.expectDelegate(response.data.delegate, delegate) }) it('should be ok using a publicKey', async () => { - const response = await utils.request('GET', 'delegates/get', { publicKey: delegate.publicKey }) - utils.expectSuccessful(response) + const response = await utils.request('GET', 'delegates/get', { + publicKey: delegate.publicKey, + }) + expect(response).toBeSuccessfulResponse() expect(response.data).toBeObject() utils.expectDelegate(response.data.delegate, delegate) @@ -48,7 +52,7 @@ describe('API 1.0 - Delegates', () => { describe('GET /delegates/count', () => { it('should be ok', async () => { const response = await utils.request('GET', 'delegates/count') - utils.expectSuccessful(response) + expect(response).toBeSuccessfulResponse() expect(response.data).toBeObject() expect(response.data).toHaveProperty('count') @@ -58,22 +62,22 @@ describe('API 1.0 - Delegates', () => { describe('GET /delegates/search', () => { it('should be ok searching a username', async () => { - const response = await utils.request('GET', 'delegates/search', { q: delegate.username }) - utils.expectSuccessful(response) + const response = await utils.request('GET', 'delegates/search', { + q: delegate.username, + }) + expect(response).toBeSuccessfulResponse() expect(response.data).toBeObject() utils.expectDelegate(response.data.delegates[0], delegate) }) - - // TODO when the DelegatesRepository#search method admits more parameters - xit('should not search using other parameters (V2)', () => { - }) }) describe('GET /delegates/voters', () => { it('should be ok', async () => { - const response = await utils.request('GET', 'delegates/voters', { publicKey: delegate.publicKey }) - utils.expectSuccessful(response) + const response = await utils.request('GET', 'delegates/voters', { + publicKey: delegate.publicKey, + }) + expect(response).toBeSuccessfulResponse() expect(response.data).toBeObject() utils.expectWallet(response.data.accounts[0]) @@ -83,25 +87,11 @@ describe('API 1.0 - Delegates', () => { describe('GET /delegates/fee', () => { it('should be ok', async () => { const response = await utils.request('GET', 'delegates/fee') - utils.expectSuccessful(response) + expect(response).toBeSuccessfulResponse() expect(response.data).toBeObject() expect(response.data).toHaveProperty('fee') expect(response.data.fee).toBeNumber() }) }) - - describe.skip('GET /delegates/forging/getForgedByAccount', () => { - it('should be ok', async () => { - const response = await utils.request('GET', 'delegates/forging/getForgedByAccount', { - generatorPublicKey: delegate.publicKey - }) - utils.expectSuccessful(response) - - expect(response.data).toBeObject() - expect(response.data).toHaveProperty('fees') - expect(response.data).toHaveProperty('rewards') - expect(response.data).toHaveProperty('forged') - }) - }) }) diff --git a/packages/core-api/__tests__/v1/handlers/loader.test.js b/packages/core-api/__tests__/v1/handlers/loader.test.js index a6216aaf96..f7f9f36bfc 100644 --- a/packages/core-api/__tests__/v1/handlers/loader.test.js +++ b/packages/core-api/__tests__/v1/handlers/loader.test.js @@ -1,5 +1,4 @@ -'use strict' - +require('@arkecosystem/core-test-utils/lib/matchers') const app = require('../../__support__/setup') const utils = require('../utils') @@ -15,7 +14,7 @@ describe('API 1.0 - Loader', () => { describe('GET /loader/status', () => { it('should be ok', async () => { const response = await utils.request('GET', 'loader/status') - utils.expectSuccessful(response) + expect(response).toBeSuccessfulResponse() expect(response.data).toBeObject() expect(response.data).toHaveProperty('loaded') @@ -27,7 +26,7 @@ describe('API 1.0 - Loader', () => { describe('GET /loader/status/sync', () => { it('should be ok', async () => { const response = await utils.request('GET', 'loader/status/sync') - utils.expectSuccessful(response) + expect(response).toBeSuccessfulResponse() expect(response.data).toBeObject() expect(response.data).toHaveProperty('syncing') @@ -40,7 +39,7 @@ describe('API 1.0 - Loader', () => { describe('GET /loader/autoconfigure', () => { it('should be ok', async () => { const response = await utils.request('GET', 'loader/autoconfigure') - utils.expectSuccessful(response) + expect(response).toBeSuccessfulResponse() expect(response.data).toBeObject() expect(response.data.network).toBeObject() diff --git a/packages/core-api/__tests__/v1/handlers/peers.test.js b/packages/core-api/__tests__/v1/handlers/peers.test.js index 66420c9287..45e8a8d4ef 100644 --- a/packages/core-api/__tests__/v1/handlers/peers.test.js +++ b/packages/core-api/__tests__/v1/handlers/peers.test.js @@ -1,5 +1,4 @@ -'use strict' - +require('@arkecosystem/core-test-utils/lib/matchers') const app = require('../../__support__/setup') const utils = require('../utils') @@ -18,7 +17,7 @@ describe('API 1.0 - Peers', () => { describe('GET /peers/version', () => { it('should be ok', async () => { const response = await utils.request('GET', 'peers/version') - utils.expectSuccessful(response) + expect(response).toBeSuccessfulResponse() expect(response.data.version).toBeString() }) @@ -45,8 +44,6 @@ describe('API 1.0 - Peers', () => { it('should fail using limit > 100', async () => { const response = await utils.request('GET', 'peers', { limit: 101 }) utils.expectError(response) - - expect(response.data.error) }) it('should fail using invalid parameters', async () => { @@ -57,7 +54,7 @@ describe('API 1.0 - Peers', () => { version: 'invalid', limit: 'invalid', offset: 'invalid', - orderBy: 'invalid' + orderBy: 'invalid', }) utils.expectError(response) @@ -67,28 +64,26 @@ describe('API 1.0 - Peers', () => { describe('GET /peers/get', () => { it('should fail using known ip address with no port', async () => { - const response = await utils.request('GET', 'peers/get?ip=127.0.0.1') + const response = await utils.request('GET', 'peers/get', { + ip: '127.0.0.1', + }) utils.expectError(response) - expect(response.data.error).toBe('should have required property \'port\'') + expect(response.data.error).toBe("should have required property 'port'") }) it('should fail using valid port with no ip address', async () => { const response = await utils.request('GET', 'peers/get', { port: 4002 }) utils.expectError(response) - expect(response.data.error).toBe('should have required property \'ip\'') - }) - - it.skip('should be ok using known ip address and port', async () => { - const response = await utils.request('GET', 'peers/get', { ip: peerIp, port: peerPort }) - utils.expectSuccessful(response) - - expect(response.data.peer).toBeObject() + expect(response.data.error).toBe("should have required property 'ip'") }) it('should fail using unknown ip address and port', async () => { - const response = await utils.request('GET', 'peers/get', { ip: '99.99.99.99', port: peerPort }) + const response = await utils.request('GET', 'peers/get', { + ip: '99.99.99.99', + port: peerPort, + }) utils.expectError(response) expect(response.data.error).toBe(`Peer 99.99.99.99:${peerPort} not found`) diff --git a/packages/core-api/__tests__/v1/handlers/signatures.test.js b/packages/core-api/__tests__/v1/handlers/signatures.test.js index d341b93cb6..30fe41c2b9 100644 --- a/packages/core-api/__tests__/v1/handlers/signatures.test.js +++ b/packages/core-api/__tests__/v1/handlers/signatures.test.js @@ -1,5 +1,4 @@ -'use strict' - +require('@arkecosystem/core-test-utils/lib/matchers') const app = require('../../__support__/setup') const utils = require('../utils') @@ -15,7 +14,7 @@ describe('API 1.0 - Signatures', () => { describe('GET /signatures/fee', () => { it('should return second signature value from config', async () => { const response = await utils.request('GET', 'signatures/fee') - utils.expectSuccessful(response) + expect(response).toBeSuccessfulResponse() expect(response.data.fee).toBeNumber() }) diff --git a/packages/core-api/__tests__/v1/handlers/transactions.test.js b/packages/core-api/__tests__/v1/handlers/transactions.test.js index eb64ce394e..c4486e6040 100644 --- a/packages/core-api/__tests__/v1/handlers/transactions.test.js +++ b/packages/core-api/__tests__/v1/handlers/transactions.test.js @@ -1,6 +1,6 @@ -'use strict' +/* eslint max-len: "off" */ -require('@arkecosystem/core-test-utils') +require('@arkecosystem/core-test-utils/lib/matchers') const app = require('../../__support__/setup') const utils = require('../utils') @@ -16,7 +16,7 @@ beforeAll(async () => { // Create the genesis block after the setup has finished or else it uses a potentially // wrong network config. - genesisBlock = require('../../__support__/config/genesisBlock.json') + genesisBlock = require('@arkecosystem/core-test-utils/config/testnet/genesisBlock.json') transactionList = genesisBlock.transactions }) @@ -33,11 +33,11 @@ describe('API 1.0 - Transactions', () => { recipientId: address2, limit: 10, offset: 0, - orderBy: 'amount:asc' + orderBy: 'amount:asc', } const response = await utils.request('GET', 'transactions', data) - utils.expectSuccessful(response) + expect(response).toBeSuccessfulResponse() expect(response.data.transactions).toBeArray() expect(response.data.transactions).not.toBeEmpty() @@ -50,11 +50,11 @@ describe('API 1.0 - Transactions', () => { it('should reply with transactions that have any of the values (OR)', async () => { const data = { senderId: address1, - recipientId: address2 + recipientId: address2, } const response = await utils.request('GET', 'transactions', data) - utils.expectSuccessful(response) + expect(response).toBeSuccessfulResponse() expect(response.data.transactions).toBeArray() expect(response.data.transactions).not.toBeEmpty() @@ -73,7 +73,7 @@ describe('API 1.0 - Transactions', () => { const type = 3 const response = await utils.request('GET', 'transactions', { type }) - utils.expectSuccessful(response) + expect(response).toBeSuccessfulResponse() expect(response.data.transactions).toBeArray() expect(response.data.transactions).not.toBeEmpty() @@ -86,7 +86,7 @@ describe('API 1.0 - Transactions', () => { it('should be ok using no params', async () => { const response = await utils.request('GET', 'transactions') - utils.expectSuccessful(response) + expect(response).toBeSuccessfulResponse() expect(response.data.transactions).toBeArray() expect(response.data.transactions).not.toBeEmpty() @@ -109,8 +109,10 @@ describe('API 1.0 - Transactions', () => { }) it('should be ok ordered by ascending timestamp', async () => { - const response = await utils.request('GET', 'transactions', { orderBy: 'timestamp:asc' }) - utils.expectSuccessful(response) + const response = await utils.request('GET', 'transactions', { + orderBy: 'timestamp:asc', + }) + expect(response).toBeSuccessfulResponse() expect(response.data.transactions).toBeArray() expect(response.data.transactions).not.toBeEmpty() @@ -119,7 +121,7 @@ describe('API 1.0 - Transactions', () => { expect(transaction).toBeApiTransaction() }) - let flag = 0; + let flag = 0 for (let i = 0; i < response.data.transactions.length; i++) { if (response.data.transactions[i + 1]) { // await response.data.transactions[i].toHaveProperty('timestamp').which.is.at.most(response.data.transactions[i + 1].timestamp) @@ -135,7 +137,7 @@ describe('API 1.0 - Transactions', () => { it('should be ok using offset == 1', async () => { const response = await utils.request('GET', 'transactions', { offset: 1 }) - utils.expectSuccessful(response) + expect(response).toBeSuccessfulResponse() expect(response.data.transactions).toBeArray() expect(response.data.transactions).not.toBeEmpty() @@ -146,7 +148,9 @@ describe('API 1.0 - Transactions', () => { }) it('should fail using offset == "one"', async () => { - const response = await utils.request('GET', 'transactions', { offset: 'one' }) + const response = await utils.request('GET', 'transactions', { + offset: 'one', + }) utils.expectError(response) expect(response.data.error).toBeString() @@ -159,7 +163,7 @@ describe('API 1.0 - Transactions', () => { recipientId: 'invalid', limit: 'invalid', offset: 'invalid', - orderBy: 'invalid' + orderBy: 'invalid', }) utils.expectError(response) @@ -173,7 +177,7 @@ describe('API 1.0 - Transactions', () => { recipientId: address1, limit: 'invalid', offset: 'invalid', - orderBy: 'invalid' + orderBy: 'invalid', }) utils.expectError(response) @@ -181,27 +185,47 @@ describe('API 1.0 - Transactions', () => { }) }) - describe('GET /transactions/get?id=3fd7fa4fda1ae97055996040b482efa81f420516fadf50cff508da2025e9b8b9', () => { + describe('GET /transactions/get?id=', () => { it('should be ok using valid id', async () => { const transactionInCheck = transactionList[0] - const params = `id=${transactionInCheck.id}` - const response = await utils.request('GET', `transactions/get?${params}`) + const response = await utils.request('GET', 'transactions/get', { + id: transactionInCheck.id, + }) - utils.expectSuccessful(response) + expect(response).toBeSuccessfulResponse() expect(response.data.transaction).toBeApiTransaction() - expect(response.data.transaction).toHaveProperty('id', transactionInCheck.id) - expect(response.data.transaction).toHaveProperty('amount', transactionInCheck.amount) - expect(response.data.transaction).toHaveProperty('fee', transactionInCheck.fee) - expect(response.data.transaction).toHaveProperty('recipientId', transactionInCheck.recipientId) - expect(response.data.transaction).toHaveProperty('senderId', transactionInCheck.senderId) - expect(response.data.transaction).toHaveProperty('type', transactionInCheck.type) + expect(response.data.transaction).toHaveProperty( + 'id', + transactionInCheck.id, + ) + expect(response.data.transaction).toHaveProperty( + 'amount', + transactionInCheck.amount, + ) + expect(response.data.transaction).toHaveProperty( + 'fee', + transactionInCheck.fee, + ) + expect(response.data.transaction).toHaveProperty( + 'recipientId', + transactionInCheck.recipientId, + ) + expect(response.data.transaction).toHaveProperty( + 'senderId', + transactionInCheck.senderId, + ) + expect(response.data.transaction).toHaveProperty( + 'type', + transactionInCheck.type, + ) }) it('should fail using invalid id', async () => { - const params = 'id=invalid' - const response = await utils.request('GET', `transactions/get?${params}`) + const response = await utils.request('GET', 'transactions/get', { + id: 'invalid', + }) utils.expectError(response) @@ -213,12 +237,45 @@ describe('API 1.0 - Transactions', () => { it('should be ok using valid id', async () => { const transaction = await utils.createTransaction() - const response = await utils.request('GET', `transactions/unconfirmed/get?id=${transaction.id}`) - utils.expectSuccessful(response) + const response = await utils.request( + 'GET', + 'transactions/unconfirmed/get', + { id: transaction.id }, + ) + expect(response).toBeSuccessfulResponse() - if (response.data.success && response.data.transaction != null) { + if (response.data.success && response.data.transaction !== null) { expect(response.data.transaction).toBeObject() expect(response.data.transaction).toHaveProperty('id', transaction.id) + expect(response.data.transaction).toHaveProperty( + 'type', + transaction.type, + ) + expect(response.data.transaction).toHaveProperty( + 'amount', + transaction.amount, + ) + expect(response.data.transaction).toHaveProperty('fee', transaction.fee) + expect(response.data.transaction).toHaveProperty( + 'recipientId', + transaction.recipientId, + ) + expect(response.data.transaction).toHaveProperty( + 'senderPublicKey', + transaction.senderPublicKey, + ) + expect(response.data.transaction).toHaveProperty( + 'signature', + transaction.signature, + ) + expect(response.data.transaction).toHaveProperty( + 'timestamp', + transaction.timestamp, + ) + expect(response.data.transaction).toHaveProperty( + 'vendorField', + transaction.vendorField, + ) } else { expect(response.data.error).toBeString() } @@ -228,7 +285,7 @@ describe('API 1.0 - Transactions', () => { describe('GET /transactions/unconfirmed', () => { it('should be ok', async () => { const response = await utils.request('GET', 'transactions/unconfirmed') - utils.expectSuccessful(response) + expect(response).toBeSuccessfulResponse() expect(response.data.transactions).toBeArray() }) diff --git a/packages/core-api/__tests__/v1/utils.js b/packages/core-api/__tests__/v1/utils.js index 1d02b41c93..d27edb7d6f 100644 --- a/packages/core-api/__tests__/v1/utils.js +++ b/packages/core-api/__tests__/v1/utils.js @@ -1,88 +1,101 @@ -'use strict' - const axios = require('axios') -const { client, transactionBuilder, NetworkManager } = require('@arkecosystem/crypto') +const { + client, + transactionBuilder, + NetworkManager, +} = require('@arkecosystem/crypto') +const apiHelpers = require('@arkecosystem/core-test-utils/lib/helpers/api') class Helpers { - request (method, path, params = {}) { + async request(method, path, params = {}) { const url = `http://localhost:4003/api/${path}` - const headers = { 'API-Version': 1 } - const request = axios[method.toLowerCase()] + const headers = { + 'API-Version': 1, + 'Content-Type': 'application/json', + } + + const server = require('@arkecosystem/core-container').resolvePlugin('api') - return ['GET', 'DELETE'].includes(method) - ? request(url, { params, headers }) - : request(url, params, { headers }) + return apiHelpers.request(server.http, method, url, headers, params) } - expectJson (response) { + expectJson(response) { expect(response.data).toBeObject() } - expectStatus (response, code) { + expectStatus(response, code) { expect(response.status).toBe(code) } - assertVersion (response, version) { + assertVersion(response, version) { expect(response.headers).toBeObject() expect(response.headers).toHaveProperty('api-version', version) } - expectState (response, state) { + expectState(response, state) { expect(response.data).toHaveProperty('success', state) } - expectSuccessful (response) { + expectSuccessful(response) { this.expectStatus(response, 200) this.expectJson(response) this.expectState(response, true) - this.assertVersion(response, '1') + this.assertVersion(response, 1) } - expectError (response) { + expectError(response) { this.expectStatus(response, 200) this.expectJson(response) this.expectState(response, false) - this.assertVersion(response, '1') + this.assertVersion(response, 1) } - expectDelegate (delegate, expected) { + expectDelegate(delegate, expected) { expect(delegate).toBeObject() expect(delegate.username).toBeString() expect(delegate.address).toBeString() expect(delegate.publicKey).toBeString() - expect(delegate.votes).toBeNumber() + expect(delegate.vote).toBeString() expect(delegate.rate).toBeNumber() expect(delegate.missedblocks).toBeNumber() expect(delegate.producedblocks).toBeNumber() - expect(delegate.approval).toBeString() - expect(delegate.productivity).toBeString() + expect(delegate.approval).toBeNumber() + expect(delegate.productivity).toBeNumber() Object.keys(expected || {}).forEach(attr => { expect(delegate[attr]).toBe(expected[attr]) }) } - expectWallet (response) { + expectWallet(response) { expect(response).toHaveProperty('username') expect(response).toHaveProperty('address') expect(response).toHaveProperty('publicKey') expect(response).toHaveProperty('balance') } - async createTransaction () { + async createTransaction() { client.setConfig(NetworkManager.findByName('testnet')) - let transaction = transactionBuilder + const transaction = transactionBuilder .transfer() - .amount(1 * Math.pow(10, 8)) + .amount(1 * 1e8) .recipientId('AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1') .vendorField('test') - .sign('prison tobacco acquire stone dignity palace note decade they current lesson robot') + .sign( + 'prison tobacco acquire stone dignity palace note decade they current lesson robot', + ) .getStruct() - await axios.post('http://127.0.0.1:4003/api/v2/transactions', { - transactions: [transaction] - }) + await axios.post( + 'http://127.0.0.1:4003/api/v2/transactions', + { + transactions: [transaction], + }, + { + headers: { 'Content-Type': 'application/json' }, + }, + ) return transaction } diff --git a/packages/core-api/__tests__/v2/handlers/blocks.test.js b/packages/core-api/__tests__/v2/handlers/blocks.test.js index bd2bdc1fed..569a708527 100644 --- a/packages/core-api/__tests__/v2/handlers/blocks.test.js +++ b/packages/core-api/__tests__/v2/handlers/blocks.test.js @@ -1,16 +1,21 @@ -'use strict' - +require('@arkecosystem/core-test-utils/lib/matchers') +const blockchainHelper = require('@arkecosystem/core-test-utils/lib/helpers/blockchain') +const { Block } = require('@arkecosystem/crypto').models +const blocks2to100 = require('@arkecosystem/core-test-utils/fixtures/testnet/blocks.2-100') const app = require('../../__support__/setup') const utils = require('../utils') let genesisBlock +let container beforeAll(async () => { await app.setUp() + await blockchainHelper.resetBlockchain() + container = require('@arkecosystem/core-container') // Create the genesis block after the setup has finished or else it uses a potentially // wrong network config. - genesisBlock = require('../../__support__/config/genesisBlock.json') + genesisBlock = require('@arkecosystem/core-test-utils/config/testnet/genesisBlock.json') }) afterAll(async () => { @@ -19,392 +24,556 @@ afterAll(async () => { describe('API 2.0 - Blocks', () => { describe('GET /blocks', () => { - it('should GET all the blocks', async () => { - const response = await utils.request('GET', 'blocks') - utils.expectSuccessful(response) - utils.expectCollection(response) - utils.expectPaginator(response) - - const block = response.data.data[0] - utils.expectBlock(block) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the "%s" header', (header, request) => { + it('should GET all the blocks', async () => { + const response = await utils[request]('GET', 'blocks') + + expect(response).toBeSuccessfulResponse() + expect(response).toBePaginated() + expect(response.data.data).toBeArray() + + const block = response.data.data[0] + utils.expectBlock(block, { + id: genesisBlock.id, + transactions: genesisBlock.numberOfTransactions, + }) + }) + }) + }) + + describe('GET /blocks?orderBy=height:', () => { + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the "%s" header', (header, request) => { + it('should GET all the blocks in descending order', async () => { + const response = await utils[request]('GET', 'blocks?orderBy=height:') + + expect(response).toBeSuccessfulResponse() + expect(response).toBePaginated() + expect(response.data.data).toBeArray() + + const block = response.data.data[0] + utils.expectBlock(block) + }) }) }) describe('GET /blocks/:id', () => { - it('should GET a block by the given identifier', async () => { - const response = await utils.request('GET', `blocks/${genesisBlock.id}`) - utils.expectSuccessful(response) - utils.expectResource(response) - - const block = response.data.data; - utils.expectBlock(block) - expect(block.id).toBe(genesisBlock.id) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should GET a block by the given identifier', async () => { + const response = await utils[request]( + 'GET', + `blocks/${genesisBlock.id}`, + ) + + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeObject() + + const block = response.data.data + utils.expectBlock(block, { + id: genesisBlock.id, + transactions: genesisBlock.numberOfTransactions, + }) + }) }) }) describe('GET /blocks/:id/transactions', () => { - it('should GET all the transactions for the given block by id', async () => { - const response = await utils.request('GET', `blocks/${genesisBlock.id}/transactions`) - utils.expectSuccessful(response) - utils.expectCollection(response) - - const transaction = response.data.data[0] - utils.expectTransaction(transaction) - expect(transaction.blockId).toBe(genesisBlock.id) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the "%s" header', (header, request) => { + it('should GET all the transactions for the given block by id', async () => { + const response = await utils[request]( + 'GET', + `blocks/${genesisBlock.id}/transactions`, + ) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + const transaction = response.data.data[0] + utils.expectTransaction(transaction) + expect(transaction.blockId).toBe(genesisBlock.id) + }) }) }) describe('POST /blocks/search', () => { - it('should POST a search for blocks with the exact specified blockId', async () => { - const response = await utils.request('POST', 'blocks/search', { - id: genesisBlock.id + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for blocks with the exact specified blockId', async () => { + const response = await utils[request]('POST', 'blocks/search', { + id: genesisBlock.id, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(1) + + const block = response.data.data[0] + utils.expectBlock(block) + expect(block.id).toBe(genesisBlock.id) }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const block = response.data.data[0] - utils.expectBlock(block) - expect(block.id).toBe(genesisBlock.id) }) - it('should POST a search for blocks with the exact specified version', async () => { - const response = await utils.request('POST', 'blocks/search', { - id: genesisBlock.id, version: genesisBlock.version + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for blocks with the exact specified version', async () => { + const response = await utils[request]('POST', 'blocks/search', { + id: genesisBlock.id, + version: genesisBlock.version, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(1) + + const block = response.data.data[0] + utils.expectBlock(block) + expect(block.id).toBe(genesisBlock.id) + expect(block.version).toBe(genesisBlock.version) }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const block = response.data.data[0] - utils.expectBlock(block) - expect(block.id).toBe(genesisBlock.id) - expect(block.version).toBe(genesisBlock.version) }) - it.skip('should POST a search for blocks with the exact specified previousBlock', async () => { - const response = await utils.request('POST', 'blocks/search', { - id: genesisBlock.id, previousBlock: genesisBlock.previousBlock + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for blocks with the exact specified previousBlock', async () => { + // save a new block so that we can make the request with previousBlock + const block2 = new Block(blocks2to100[0]) + const database = container.resolvePlugin('database') + await database.saveBlock(block2) + + const response = await utils[request]('POST', 'blocks/search', { + id: blocks2to100[0].id, + previousBlock: blocks2to100[0].previousBlock, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(1) + + const block = response.data.data[0] + utils.expectBlock(block) + expect(block.id).toBe(blocks2to100[0].id) + expect(block.previous).toBe(blocks2to100[0].previousBlock) + + await database.deleteBlock(block2) // reset to genesis block }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const block = response.data.data[0] - utils.expectBlock(block) - expect(block.id).toBe(genesisBlock.id) - expect(block.previous).toBe(genesisBlock.previousBlock) }) - it('should POST a search for blocks with the exact specified payloadHash', async () => { - const response = await utils.request('POST', 'blocks/search', { - id: genesisBlock.id, payloadHash: genesisBlock.payloadHash + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for blocks with the exact specified payloadHash', async () => { + const response = await utils[request]('POST', 'blocks/search', { + id: genesisBlock.id, + payloadHash: genesisBlock.payloadHash, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(1) + + const block = response.data.data[0] + utils.expectBlock(block) + expect(block.id).toBe(genesisBlock.id) + expect(block.payload.length).toBe(genesisBlock.payloadLength) + expect(block.payload.hash).toBe(genesisBlock.payloadHash) }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const block = response.data.data[0] - utils.expectBlock(block) - expect(block.id).toBe(genesisBlock.id) - expect(block.payload.length).toBe(genesisBlock.payloadLength) - expect(block.payload.hash).toBe(genesisBlock.payloadHash) }) - it('should POST a search for blocks with the exact specified generatorPublicKey', async () => { - const response = await utils.request('POST', 'blocks/search', { - id: genesisBlock.id, generatorPublicKey: genesisBlock.generatorPublicKey + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for blocks with the exact specified generatorPublicKey', async () => { + const response = await utils[request]('POST', 'blocks/search', { + id: genesisBlock.id, + generatorPublicKey: genesisBlock.generatorPublicKey, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(1) + + const block = response.data.data[0] + utils.expectBlock(block) + expect(block.id).toBe(genesisBlock.id) + expect(block.generator.publicKey).toBe(genesisBlock.generatorPublicKey) }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const block = response.data.data[0] - utils.expectBlock(block) - expect(block.id).toBe(genesisBlock.id) - expect(block.generator.publicKey).toBe(genesisBlock.generatorPublicKey) }) - it('should POST a search for blocks with the exact specified blockSignature', async () => { - const response = await utils.request('POST', 'blocks/search', { - id: genesisBlock.id, blockSignature: genesisBlock.blockSignature + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for blocks with the exact specified blockSignature', async () => { + const response = await utils[request]('POST', 'blocks/search', { + id: genesisBlock.id, + blockSignature: genesisBlock.blockSignature, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(1) + + const block = response.data.data[0] + utils.expectBlock(block) + expect(block.id).toBe(genesisBlock.id) + expect(block.signature).toBe(genesisBlock.blockSignature) }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const block = response.data.data[0] - utils.expectBlock(block) - expect(block.id).toBe(genesisBlock.id) - expect(block.signature).toBe(genesisBlock.blockSignature) }) - it('should POST a search for blocks with the exact specified timestamp', async () => { - const response = await utils.request('POST', 'blocks/search', { - id: genesisBlock.id, - timestamp: { - from: genesisBlock.timestamp, - to: genesisBlock.timestamp - } + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for blocks with the exact specified timestamp', async () => { + const response = await utils[request]('POST', 'blocks/search', { + id: genesisBlock.id, + timestamp: { + from: genesisBlock.timestamp, + to: genesisBlock.timestamp, + }, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(1) + + const block = response.data.data[0] + utils.expectBlock(block) + expect(block.id).toBe(genesisBlock.id) }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const block = response.data.data[0] - utils.expectBlock(block) - expect(block.id).toBe(genesisBlock.id) }) - it('should POST a search for blocks with the exact specified height', async () => { - const response = await utils.request('POST', 'blocks/search', { - id: genesisBlock.id, - height: { - from: genesisBlock.height, - to: genesisBlock.height - } + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for blocks with the exact specified height', async () => { + const response = await utils[request]('POST', 'blocks/search', { + id: genesisBlock.id, + height: { + from: genesisBlock.height, + to: genesisBlock.height, + }, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(1) + + const block = response.data.data[0] + utils.expectBlock(block) + expect(block.id).toBe(genesisBlock.id) + expect(block.height).toBe(genesisBlock.height) }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const block = response.data.data[0] - utils.expectBlock(block) - expect(block.id).toBe(genesisBlock.id) - expect(block.height).toBe(genesisBlock.height) }) - it('should POST a search for blocks with the specified height range', async () => { - const response = await utils.request('POST', 'blocks/search', { - id: genesisBlock.id, - height: { - from: genesisBlock.height, - to: genesisBlock.height - } + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for blocks with the specified height range', async () => { + const response = await utils[request]('POST', 'blocks/search', { + id: genesisBlock.id, + height: { + from: genesisBlock.height, + to: genesisBlock.height, + }, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(1) + + const block = response.data.data[0] + utils.expectBlock(block) + expect(block.id).toBe(genesisBlock.id) + expect(block.height).toBe(genesisBlock.height) }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const block = response.data.data[0] - utils.expectBlock(block) - expect(block.id).toBe(genesisBlock.id) - expect(block.height).toBe(genesisBlock.height) }) - it('should POST a search for blocks with the exact specified numberOfTransactions', async () => { - const response = await utils.request('POST', 'blocks/search', { - id: genesisBlock.id, - numberOfTransactions: { - from: genesisBlock.numberOfTransactions, - to: genesisBlock.numberOfTransactions - } + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for blocks with the exact specified numberOfTransactions', async () => { + const response = await utils[request]('POST', 'blocks/search', { + id: genesisBlock.id, + numberOfTransactions: { + from: genesisBlock.numberOfTransactions, + to: genesisBlock.numberOfTransactions, + }, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(1) + + const block = response.data.data[0] + utils.expectBlock(block) + expect(block.id).toBe(genesisBlock.id) + expect(block.transactions).toBe(genesisBlock.numberOfTransactions) }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const block = response.data.data[0] - utils.expectBlock(block) - expect(block.id).toBe(genesisBlock.id) - expect(block.transactions).toBe(genesisBlock.numberOfTransactions) }) - it('should POST a search for blocks with the specified numberOfTransactions range', async () => { - const response = await utils.request('POST', 'blocks/search', { - id: genesisBlock.id, - numberOfTransactions: { - from: genesisBlock.numberOfTransactions, - to: genesisBlock.numberOfTransactions - } + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for blocks with the specified numberOfTransactions range', async () => { + const response = await utils[request]('POST', 'blocks/search', { + id: genesisBlock.id, + numberOfTransactions: { + from: genesisBlock.numberOfTransactions, + to: genesisBlock.numberOfTransactions, + }, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(1) + + const block = response.data.data[0] + utils.expectBlock(block) + expect(block.id).toBe(genesisBlock.id) + expect(block.transactions).toBe(genesisBlock.numberOfTransactions) }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const block = response.data.data[0] - utils.expectBlock(block) - expect(block.id).toBe(genesisBlock.id) - expect(block.transactions).toBe(genesisBlock.numberOfTransactions) }) - it('should POST a search for blocks with the exact specified totalAmount', async () => { - const response = await utils.request('POST', 'blocks/search', { - id: genesisBlock.id, - totalAmount: { from: 1 } - }) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for blocks with the exact specified totalAmount', async () => { + const response = await utils[request]('POST', 'blocks/search', { + id: genesisBlock.id, + totalAmount: { from: 1 }, + }) - utils.expectSuccessful(response) - utils.expectCollection(response) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() - expect(response.data.data).toHaveLength(1) + expect(response.data.data).toHaveLength(1) - const block = response.data.data[0] - utils.expectBlock(block) - expect(block.id).toBe(genesisBlock.id) + const block = response.data.data[0] + utils.expectBlock(block) + expect(block.id).toBe(genesisBlock.id) + }) }) - it('should POST a search for blocks with the specified totalAmount range', async () => { - const response = await utils.request('POST', 'blocks/search', { - id: genesisBlock.id, - totalAmount: { from: 1 } + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for blocks with the specified totalAmount range', async () => { + const response = await utils[request]('POST', 'blocks/search', { + id: genesisBlock.id, + totalAmount: { from: 1 }, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(1) + + const block = response.data.data[0] + utils.expectBlock(block) + expect(block.id).toBe(genesisBlock.id) }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const block = response.data.data[0] - utils.expectBlock(block) - expect(block.id).toBe(genesisBlock.id) }) - it('should POST a search for blocks with the exact specified totalFee', async () => { - const response = await utils.request('POST', 'blocks/search', { - id: genesisBlock.id, - totalFee: { from: 1 } + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for blocks with the exact specified totalFee', async () => { + const response = await utils[request]('POST', 'blocks/search', { + id: genesisBlock.id, + totalFee: { from: 0 }, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(1) + + const block = response.data.data[0] + utils.expectBlock(block) + expect(block.id).toBe(genesisBlock.id) + expect(+block.forged.fee).toBe(genesisBlock.totalFee) }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const block = response.data.data[0] - utils.expectBlock(block) - expect(block.id).toBe(genesisBlock.id) - expect(+block.forged.fee).toBe(genesisBlock.totalFee) }) - it('should POST a search for blocks with the specified totalFee range', async () => { - const response = await utils.request('POST', 'blocks/search', { - id: genesisBlock.id, - totalFee: { from: 1 } + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for blocks with the specified totalFee range', async () => { + const response = await utils[request]('POST', 'blocks/search', { + id: genesisBlock.id, + totalFee: { from: 0 }, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(1) + + const block = response.data.data[0] + utils.expectBlock(block) + expect(block.id).toBe(genesisBlock.id) + expect(+block.forged.fee).toBe(genesisBlock.totalFee) }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const block = response.data.data[0] - utils.expectBlock(block) - expect(block.id).toBe(genesisBlock.id) - expect(+block.forged.fee).toBe(genesisBlock.totalFee) }) - it('should POST a search for blocks with the exact specified reward', async () => { - const response = await utils.request('POST', 'blocks/search', { - id: genesisBlock.id, - reward: { - from: genesisBlock.reward, - to: genesisBlock.reward - } + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for blocks with the exact specified reward', async () => { + const response = await utils[request]('POST', 'blocks/search', { + id: genesisBlock.id, + reward: { + from: genesisBlock.reward, + to: genesisBlock.reward, + }, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(1) + + const block = response.data.data[0] + utils.expectBlock(block) + expect(block.id).toBe(genesisBlock.id) + expect(+block.forged.reward).toBe(genesisBlock.reward) }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const block = response.data.data[0] - utils.expectBlock(block) - expect(block.id).toBe(genesisBlock.id) - expect(+block.forged.reward).toBe(genesisBlock.reward) }) - it('should POST a search for blocks with the specified reward range', async () => { - const response = await utils.request('POST', 'blocks/search', { - id: genesisBlock.id, - reward: { - from: genesisBlock.reward, - to: genesisBlock.reward - } + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for blocks with the specified reward range', async () => { + const response = await utils[request]('POST', 'blocks/search', { + id: genesisBlock.id, + reward: { + from: genesisBlock.reward, + to: genesisBlock.reward, + }, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(1) + + const block = response.data.data[0] + utils.expectBlock(block) + expect(block.id).toBe(genesisBlock.id) + expect(+block.forged.reward).toBe(genesisBlock.reward) }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const block = response.data.data[0] - utils.expectBlock(block) - expect(block.id).toBe(genesisBlock.id) - expect(+block.forged.reward).toBe(genesisBlock.reward) }) - it('should POST a search for blocks with the exact specified payloadLength', async () => { - const response = await utils.request('POST', 'blocks/search', { - id: genesisBlock.id, - payloadLength: { - from: genesisBlock.payloadLength, - to: genesisBlock.payloadLength - } + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for blocks with the exact specified payloadLength', async () => { + const response = await utils[request]('POST', 'blocks/search', { + id: genesisBlock.id, + payloadLength: { + from: genesisBlock.payloadLength, + to: genesisBlock.payloadLength, + }, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(1) + + const block = response.data.data[0] + utils.expectBlock(block) + expect(block.id).toBe(genesisBlock.id) + expect(block.payload.length).toBe(genesisBlock.payloadLength) }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const block = response.data.data[0] - utils.expectBlock(block) - expect(block.id).toBe(genesisBlock.id) - expect(block.payload.length).toBe(genesisBlock.payloadLength) }) - it('should POST a search for blocks with the specified payloadLength range', async () => { - const response = await utils.request('POST', 'blocks/search', { - id: genesisBlock.id, - payloadLength: { - from: genesisBlock.payloadLength, - to: genesisBlock.payloadLength - } + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for blocks with the specified payloadLength range', async () => { + const response = await utils[request]('POST', 'blocks/search', { + id: genesisBlock.id, + payloadLength: { + from: genesisBlock.payloadLength, + to: genesisBlock.payloadLength, + }, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(1) + + const block = response.data.data[0] + utils.expectBlock(block) + expect(block.id).toBe(genesisBlock.id) + expect(block.payload.length).toBe(genesisBlock.payloadLength) }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const block = response.data.data[0] - utils.expectBlock(block) - expect(block.id).toBe(genesisBlock.id) - expect(block.payload.length).toBe(genesisBlock.payloadLength) }) - it('should POST a search for blocks with the wrong specified version', async () => { - const response = await utils.request('POST', 'blocks/search', { - id: genesisBlock.id, version: 2 + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for blocks with the wrong specified version', async () => { + const response = await utils[request]('POST', 'blocks/search', { + id: genesisBlock.id, + version: 2, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(0) }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(0) }) - it('should POST a search for blocks with the specific criteria', async () => { - const response = await utils.request('POST', 'blocks/search', { - generatorPublicKey: genesisBlock.generatorPublicKey, - version: genesisBlock.version, - timestamp: { - from: genesisBlock.timestamp, - to: genesisBlock.timestamp - } + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for blocks with the specific criteria', async () => { + const response = await utils[request]('POST', 'blocks/search', { + generatorPublicKey: genesisBlock.generatorPublicKey, + version: genesisBlock.version, + timestamp: { + from: genesisBlock.timestamp, + to: genesisBlock.timestamp, + }, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(1) + + const block = response.data.data[0] + utils.expectBlock(block) + expect(block.id).toBe(genesisBlock.id) }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const block = response.data.data[0] - utils.expectBlock(block) - expect(block.id).toBe(genesisBlock.id) }) }) }) diff --git a/packages/core-api/__tests__/v2/handlers/delegates.test.js b/packages/core-api/__tests__/v2/handlers/delegates.test.js index 79e1903b57..082581d75c 100644 --- a/packages/core-api/__tests__/v2/handlers/delegates.test.js +++ b/packages/core-api/__tests__/v2/handlers/delegates.test.js @@ -1,16 +1,21 @@ -'use strict' - +require('@arkecosystem/core-test-utils/lib/matchers') +const { Block } = require('@arkecosystem/crypto').models +const blocks2to100 = require('@arkecosystem/core-test-utils/fixtures/testnet/blocks.2-100') const app = require('../../__support__/setup') const utils = require('../utils') const delegate = { username: 'genesis_9', address: 'AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo', - publicKey: '0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647' + publicKey: + '0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647', } +let container + beforeAll(async () => { await app.setUp() + container = require('@arkecosystem/core-container') }) afterAll(async () => { @@ -19,69 +24,128 @@ afterAll(async () => { describe('API 2.0 - Delegates', () => { describe('GET /delegates', () => { - it('should GET all the delegates', async () => { - const response = await utils.request('GET', 'delegates') - utils.expectSuccessful(response) - utils.expectCollection(response) - - utils.expectDelegate(response.data.data[0]) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should GET all the delegates', async () => { + const response = await utils[request]('GET', 'delegates') + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + utils.expectDelegate(response.data.data[0]) + }) }) }) describe('GET /delegates/:id', () => { - it('should GET a delegate by the given username', async () => { - const response = await utils.request('GET', `delegates/${delegate.username}`) - utils.expectSuccessful(response) - utils.expectResource(response) - - utils.expectDelegate(response.data.data, delegate) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should GET a delegate by the given username', async () => { + const response = await utils[request]( + 'GET', + `delegates/${delegate.username}`, + ) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeObject() + + utils.expectDelegate(response.data.data, delegate) + }) }) - it('should GET a delegate by the given address', async () => { - const response = await utils.request('GET', `delegates/${delegate.address}`) - utils.expectSuccessful(response) - utils.expectResource(response) - - utils.expectDelegate(response.data.data, delegate) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should GET a delegate by the given address', async () => { + const response = await utils[request]( + 'GET', + `delegates/${delegate.address}`, + ) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeObject() + + utils.expectDelegate(response.data.data, delegate) + }) }) - it('should GET a delegate by the given public key', async () => { - const response = await utils.request('GET', `delegates/${delegate.publicKey}`) - utils.expectSuccessful(response) - utils.expectResource(response) - - utils.expectDelegate(response.data.data, delegate) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should GET a delegate by the given public key', async () => { + const response = await utils[request]( + 'GET', + `delegates/${delegate.publicKey}`, + ) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeObject() + + utils.expectDelegate(response.data.data, delegate) + }) }) }) describe('POST /delegates/search', () => { - it('should POST a search for delegates with a username that matches the given string', async () => { - const response = await utils.request('POST', 'delegates/search', { username: delegate.username }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - utils.expectDelegate(response.data.data[0], delegate) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for delegates with a username that matches the given string', async () => { + const response = await utils[request]('POST', 'delegates/search', { + username: delegate.username, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(1) + + utils.expectDelegate(response.data.data[0], delegate) + }) }) }) - describe.skip('GET /delegates/:id/blocks', () => { - it('should GET all blocks for a delegate by the given identifier', async () => { - const response = await utils.request('GET', `delegates/${delegate.publicKey}/blocks`) - utils.expectSuccessful(response) - utils.expectCollection(response) - utils.expectBlock(response.data.data[0]) + describe('GET /delegates/:id/blocks', () => { + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should GET all blocks for a delegate by the given identifier', async () => { + // save a new block so that we can make the request with generatorPublicKey + const block2 = new Block(blocks2to100[0]) + const database = container.resolvePlugin('database') + await database.saveBlock(block2) + + const response = await utils[request]( + 'GET', + `delegates/${blocks2to100[0].generatorPublicKey}/blocks`, + ) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + utils.expectBlock(response.data.data[0]) + + await database.deleteBlock(block2) // reset to genesis block + }) }) }) describe('GET /delegates/:id/voters', () => { - it('should GET all voters (wallets) for a delegate by the given identifier', async () => { - const response = await utils.request('GET', `delegates/${delegate.publicKey}/voters`) - utils.expectSuccessful(response) - utils.expectCollection(response) - - utils.expectWallet(response.data.data[0]) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should GET all voters (wallets) for a delegate by the given identifier', async () => { + const response = await utils[request]( + 'GET', + `delegates/${delegate.publicKey}/voters`, + ) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + utils.expectWallet(response.data.data[0]) + }) }) }) }) diff --git a/packages/core-api/__tests__/v2/handlers/node.test.js b/packages/core-api/__tests__/v2/handlers/node.test.js index 64bcfb8519..de4833564f 100644 --- a/packages/core-api/__tests__/v2/handlers/node.test.js +++ b/packages/core-api/__tests__/v2/handlers/node.test.js @@ -1,5 +1,4 @@ -'use strict' - +require('@arkecosystem/core-test-utils/lib/matchers') const app = require('../../__support__/setup') const utils = require('../utils') @@ -13,41 +12,56 @@ afterAll(async () => { describe('API 2.0 - Loader', () => { describe('GET /node/status', () => { - it('should GET the node status', async () => { - const response = await utils.request('GET', 'node/status') - utils.expectSuccessful(response) - utils.expectResource(response) - - expect(response.data.data.synced).toBeBoolean() - expect(response.data.data.now).toBeNumber() - expect(response.data.data.blocksCount).toBeNumber() + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should GET the node status', async () => { + const response = await utils[request]('GET', 'node/status') + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeObject() + + expect(response.data.data.synced).toBeBoolean() + expect(response.data.data.now).toBeNumber() + expect(response.data.data.blocksCount).toBeNumber() + }) }) }) describe('GET /node/syncing', () => { - it('should GET the node syncing status', async () => { - const response = await utils.request('GET', 'node/syncing') - utils.expectSuccessful(response) - utils.expectResource(response) - - expect(response.data.data.syncing).toBeBoolean() - expect(response.data.data.blocks).toBeNumber() - expect(response.data.data.height).toBeNumber() - expect(response.data.data.id).toBeString() + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should GET the node syncing status', async () => { + const response = await utils[request]('GET', 'node/syncing') + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeObject() + + expect(response.data.data.syncing).toBeBoolean() + expect(response.data.data.blocks).toBeNumber() + expect(response.data.data.height).toBeNumber() + expect(response.data.data.id).toBeString() + }) }) }) describe('GET /node/configuration', () => { - it('should GET the node configuration', async () => { - const response = await utils.request('GET', 'node/configuration') - utils.expectSuccessful(response) - utils.expectResource(response) - - expect(response.data.data.nethash).toBeString() - expect(response.data.data.token).toBeString() - expect(response.data.data.symbol).toBeString() - expect(response.data.data.explorer).toBeString() - expect(response.data.data.version).toBeNumber() + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should GET the node configuration', async () => { + const response = await utils[request]('GET', 'node/configuration') + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeObject() + + expect(response.data.data.nethash).toBeString() + expect(response.data.data.token).toBeString() + expect(response.data.data.symbol).toBeString() + expect(response.data.data.explorer).toBeString() + expect(response.data.data.version).toBeNumber() + }) }) }) }) diff --git a/packages/core-api/__tests__/v2/handlers/peers.test.js b/packages/core-api/__tests__/v2/handlers/peers.test.js index db5f39c9cb..4bebbe5d6c 100644 --- a/packages/core-api/__tests__/v2/handlers/peers.test.js +++ b/packages/core-api/__tests__/v2/handlers/peers.test.js @@ -1,10 +1,8 @@ -'use strict' - +require('@arkecosystem/core-test-utils/lib/matchers') +const peers = require('@arkecosystem/core-test-utils/config/testnet/peers.json') const app = require('../../__support__/setup') const utils = require('../utils') -const peerIp = '167.114.29.32' - beforeAll(async () => { await app.setUp() }) @@ -15,22 +13,35 @@ afterAll(async () => { describe('API 2.0 - Peers', () => { describe('GET /peers', () => { - it('should GET all the peers', async () => { - const response = await utils.request('GET', 'peers') - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data[0]).toBeObject() + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should GET all the peers', async () => { + const response = await utils[request]('GET', 'peers') + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data[0]).toBeObject() + }) }) }) describe('GET /peers/:ip', () => { - it('should GET a peer by the given ip', async () => { - const response = await utils.request('GET', `peers/${peerIp}`) - utils.expectSuccessful(response) - utils.expectResource(response) - - expect(response.data.data).toBeObject() + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should GET a peer by the given ip', async () => { + const response = await utils[request]( + 'GET', + `peers/${peers.list[0].ip}`, + ) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeObject() + + expect(response.data.data).toBeObject() + }) }) }) }) diff --git a/packages/core-api/__tests__/v2/handlers/statistics.test.js b/packages/core-api/__tests__/v2/handlers/statistics.test.js deleted file mode 100644 index d8db2bbea1..0000000000 --- a/packages/core-api/__tests__/v2/handlers/statistics.test.js +++ /dev/null @@ -1,92 +0,0 @@ -'use strict' - -const app = require('../../__support__/setup') -const utils = require('../utils') - -beforeAll(async () => { - await app.setUp() -}) - -afterAll(async () => { - await app.tearDown() -}) - -describe.skip('API 2.0 - Statistics', () => { - describe('GET /statistics/blockchain', () => { - it('should GET the blockchain statistics', async () => { - const response = await utils.request('GET', 'statistics/blockchain') - utils.expectSuccessful(response) - utils.expectResource(response) - - expect(response.data.data.supply).toBeObject() - expect(response.data.data.supply.initial).toBeNumber() - expect(response.data.data.supply.current).toBeNumber() - - expect(response.data.data.blocks).toBeObject() - expect(response.data.data.blocks.forged).toBeNumber() - expect(response.data.data.blocks.rewards).toBeNumber() - - expect(response.data.data.rewards).toBeObject() - expect(response.data.data.rewards.start).toBeNumber() - expect(response.data.data.rewards.total).toBeNumber() - - expect(response.data.data.productivity).toBeObject() - expect(response.data.data.productivity.best.username).toBeString() - expect(response.data.data.productivity.best.productivity).toBeString() - - expect(response.data.data.productivity.worst).toBeObject() - expect(response.data.data.productivity.worst.username).toBeString() - expect(response.data.data.productivity.worst.productivity).toBeString() - }) - }) - - // TODO: big performance impact, think about storing them in memory on boot - describe.skip('GET /statistics/transactions', () => { - it('should GET the transaction statistics', async () => { - const response = await utils.request('GET', 'statistics/transactions') - utils.expectSuccessful(response) - utils.expectResource(response) - - expect(response.data.data.count).toBeNumber() - expect(response.data.data.amount).toBeNumber() - expect(response.data.data.fees).toBeNumber() - }) - }) - - // TODO: big performance impact, think about storing them in memory on boot - describe.skip('GET /statistics/blocks', () => { - it('should GET the block statistics', async () => { - const response = await utils.request('GET', 'statistics/blocks') - utils.expectSuccessful(response) - utils.expectResource(response) - - expect(response.data.data.count).toBeNumber() - expect(response.data.data.rewards).toBeNumber() - expect(response.data.data.fees).toBeNumber() - }) - }) - - describe('GET /statistics/votes', () => { - it('should GET the vote statistics', async () => { - const response = await utils.request('GET', 'statistics/votes') - utils.expectSuccessful(response) - utils.expectResource(response) - - expect(response.data.data.count).toBeNumber() - expect(response.data.data.amount).toBeNumber() - expect(response.data.data.fees).toBeNumber() - }) - }) - - describe('GET /statistics/unvotes', () => { - it('should GET the unvote statistics', async () => { - const response = await utils.request('GET', 'statistics/unvotes') - utils.expectSuccessful(response) - utils.expectResource(response) - - expect(response.data.data.count).toBeNumber() - expect(response.data.data.amount).toBeNumber() - expect(response.data.data.fees).toBeNumber() - }) - }) -}) diff --git a/packages/core-api/__tests__/v2/handlers/transactions.test.js b/packages/core-api/__tests__/v2/handlers/transactions.test.js index 7e04b2cc35..8b860d59f4 100644 --- a/packages/core-api/__tests__/v2/handlers/transactions.test.js +++ b/packages/core-api/__tests__/v2/handlers/transactions.test.js @@ -1,8 +1,14 @@ -'use strict' +/* eslint max-len: "off" */ +require('@arkecosystem/core-test-utils/lib/matchers') +const generateTransfers = require('@arkecosystem/core-test-utils/lib/generators/transactions/transfer') +const generateWallets = require('@arkecosystem/core-test-utils/lib/generators/wallets') +const delegates = require('@arkecosystem/core-test-utils/fixtures/testnet/delegates') const app = require('../../__support__/setup') const utils = require('../utils') +const transferFee = 10000000 + let genesisBlock let genesisTransactions @@ -29,7 +35,7 @@ beforeAll(async () => { // Create the genesis block after the setup has finished or else it uses a potentially // wrong network config. - genesisBlock = require('../../__support__/config/genesisBlock.json') + genesisBlock = require('@arkecosystem/core-test-utils/config/testnet/genesisBlock.json') genesisTransactions = genesisBlock.transactions[0] transactionId = genesisTransactions.id @@ -57,299 +63,643 @@ afterAll(async () => { describe('API 2.0 - Transactions', () => { describe('GET /transactions', () => { - it('should GET all the transactions', async () => { - const response = await utils.request('GET', 'transactions') - utils.expectSuccessful(response) - utils.expectCollection(response) - - utils.expectTransaction(response.data.data[0]) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should GET all the transactions', async () => { + const response = await utils[request]('GET', 'transactions') + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + utils.expectTransaction(response.data.data[0]) + }) }) }) describe('GET /transactions/:id', () => { - it('should GET a transaction by the given identifier', async () => { - const response = await utils.request('GET', `transactions/${transactionId}`) - utils.expectSuccessful(response) - utils.expectResource(response) - - const transaction = response.data.data - utils.expectTransaction(transaction) - expect(transaction.id).toBe(transactionId) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should GET a transaction by the given identifier', async () => { + const response = await utils[request]( + 'GET', + `transactions/${transactionId}`, + ) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeObject() + + const transaction = response.data.data + utils.expectTransaction(transaction) + expect(transaction.id).toBe(transactionId) + }) }) }) describe('GET /transactions/unconfirmed', () => { - it('should GET all the unconfirmed transactions', async () => { - await utils.createTransaction() - - const response = await utils.request('GET', 'transactions/unconfirmed') - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toBeArray() - expect(response.data.data).not.toBeEmpty() + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should GET all the unconfirmed transactions', async () => { + await utils.createTransaction() + + const response = await utils[request]('GET', 'transactions/unconfirmed') + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toBeArray() + expect(response.data.data).not.toBeEmpty() + }) }) }) describe('GET /transactions/unconfirmed/:id', () => { - it('should GET an unconfirmed transaction by the given identifier', async () => { - const transaction = await utils.createTransaction() - - const response = await utils.request('GET', `transactions/unconfirmed/${transaction.id}`) - utils.expectSuccessful(response) - utils.expectResource(response) - - expect(response.data.data).toHaveProperty('id', transaction.id) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should GET an unconfirmed transaction by the given identifier', async () => { + const transaction = await utils.createTransaction() + + const response = await utils[request]( + 'GET', + `transactions/unconfirmed/${transaction.id}`, + ) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeObject() + + expect(response.data.data).toHaveProperty('id', transaction.id) + }) }) }) describe('POST /transactions/search', () => { - it('should POST a search for transactions with the exact specified transactionId', async () => { - const response = await utils.request('POST', 'transactions/search', { id: transactionId }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const transaction = response.data.data[0] - utils.expectTransaction(transaction) - expect(transaction.id).toBe(transactionId) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for transactions with the exact specified transactionId', async () => { + const response = await utils[request]('POST', 'transactions/search', { + id: transactionId, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(1) + + const transaction = response.data.data[0] + utils.expectTransaction(transaction) + expect(transaction.id).toBe(transactionId) + }) }) - it('should POST a search for transactions with the exact specified blockId', async () => { - const response = await utils.request('POST', 'transactions/search', { blockId }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const transaction = response.data.data[0] - utils.expectTransaction(transaction) - expect(transaction.id).toBe(transactionId) - expect(transaction.blockId).toBe(blockId) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for transactions with the exact specified blockId', async () => { + const response = await utils[request]('POST', 'transactions/search', { + blockId, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(100) + expect(response.data.meta.totalCount).toBe(153) + + for (const transaction of response.data.data) { + utils.expectTransaction(transaction) + expect(transaction.blockId).toBe(blockId) + } + }) }) - // TODO remove the search by id, to be sure that is OK - it('should POST a search for transactions with the exact specified type', async () => { - const response = await utils.request('POST', 'transactions/search', { type }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const transaction = response.data.data[0] - utils.expectTransaction(transaction) - expect(transaction.id).toBe(transactionId) - expect(transaction.type).toBe(type) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for transactions with the exact specified type', async () => { + const response = await utils[request]('POST', 'transactions/search', { + type, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(51) + + const transaction = response.data.data[0] + utils.expectTransaction(transaction) + expect(transaction.id).toBe(transactionId) + expect(transaction.type).toBe(type) + }) }) - // TODO remove the search by id, to be sure that is OK - it('should POST a search for transactions with the exact specified version', async () => { - const response = await utils.request('POST', 'transactions/search', { version }) - utils.expectSuccessful(response) - utils.expectCollection(response) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for transactions with the exact specified version', async () => { + const response = await utils[request]('POST', 'transactions/search', { + version, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(100) + expect(response.data.meta.totalCount).toBe(153) + + const transaction = response.data.data[0] + utils.expectTransaction(transaction) + expect(transaction.id).toBe(transactionId) + }) + }) - expect(response.data.data).toHaveLength(1) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for transactions with the exact specified senderPublicKey', async () => { + const response = await utils[request]('POST', 'transactions/search', { + senderPublicKey, + }) - const transaction = response.data.data[0] - utils.expectTransaction(transaction) - expect(transaction.id).toBe(transactionId) - }) + expect(response).toBeSuccessfulResponse() - // TODO remove the search by id, to be sure that is OK - it('should POST a search for transactions with the exact specified senderPublicKey', async () => { - const response = await utils.request('POST', 'transactions/search', { senderPublicKey }) - utils.expectSuccessful(response) - utils.expectCollection(response) + const data = response.data.data + expect(data).toBeArray() - expect(response.data.data).toHaveLength(1) + const transactions = {} + genesisBlock.transactions.forEach(transaction => { + transactions[transaction.id] = true + }) + const failed = data.some(transaction => !transactions[transaction.id]) - const transaction = response.data.data[0] - utils.expectTransaction(transaction) - expect(transaction.id).toBe(transactionId) - expect(transaction.sender).toBe(senderAddress) + expect(!failed).toBeTrue() + }) }) - // TODO remove the search by id, to be sure that is OK - it('should POST a search for transactions with the exact specified senderId', async () => { - const response = await utils.request('POST', 'transactions/search', { senderId: senderAddress }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for transactions with the exact specified senderId', async () => { + const response = await utils[request]('POST', 'transactions/search', { + senderId: senderAddress, + }) - const transaction = response.data.data[0] - utils.expectTransaction(transaction) - expect(transaction.id).toBe(transactionId) - expect(transaction.sender).toBe(senderAddress) - }) + expect(response).toBeSuccessfulResponse() - // TODO remove the search by id, to be sure that is OK - it('should POST a search for transactions with the exact specified recipientId (Address)', async () => { - const response = await utils.request('POST', 'transactions/search', { recipientId: recipientAddress }) - utils.expectSuccessful(response) - utils.expectCollection(response) + const data = response.data.data + expect(data).toBeArray() - expect(response.data.data).toHaveLength(1) + const transactions = {} + genesisBlock.transactions.forEach(transaction => { + transactions[transaction.id] = true + }) + const failed = data.some(transaction => !transactions[transaction.id]) - const transaction = response.data.data[0] - utils.expectTransaction(transaction) - expect(transaction.id).toBe(transactionId) - expect(transaction.recipient).toBe(recipientAddress) + expect(!failed).toBeTrue() + }) }) - // TODO remove the search by id, to be sure that is OK - it('should POST a search for transactions with the exact specified timestamp', async () => { - const response = await utils.request('POST', 'transactions/search', { - id: transactionId, - timestamp: { - from: timestamp, - to: timestamp - } + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for transactions with the exact specified recipientId (Address)', async () => { + const response = await utils[request]('POST', 'transactions/search', { + recipientId: recipientAddress, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(2) + + const transaction = response.data.data[0] + utils.expectTransaction(transaction) + expect(transaction.id).toBe(transactionId) + expect(transaction.recipient).toBe(recipientAddress) }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const transaction = response.data.data[0] - utils.expectTransaction(transaction) - expect(transaction.id).toBe(transactionId) }) - // TODO remove the search by id, to be sure that is OK - it('should POST a search for transactions with the specified timestamp range', async () => { - const response = await utils.request('POST', 'transactions/search', { - id: transactionId, - timestamp: { - from: timestampFrom, - to: timestampTo - } + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for transactions with the exact specified timestamp', async () => { + const response = await utils[request]('POST', 'transactions/search', { + timestamp: { + from: timestamp, + to: timestamp, + }, + }) + + expect(response).toBeSuccessfulResponse() + + const data = response.data.data + expect(data).toBeArray() + expect(data.length).toEqual(100) + + data.forEach(transaction => { + utils.expectTransaction(transaction) + }) + + const transactions = {} + genesisBlock.transactions.forEach(transaction => { + transactions[transaction.id] = true + }) + const failed = data.some(transaction => !transactions[transaction.id]) + + expect(!failed).toBeTrue() }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const transaction = response.data.data[0] - utils.expectTransaction(transaction) - expect(transaction.id).toBe(transactionId) }) - // TODO remove the search by id, to be sure that is OK - it('should POST a search for transactions with the exact specified amount', async () => { - const response = await utils.request('POST', 'transactions/search', { - id: transactionId, - amount: { - from: amount, - to: amount - } + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for transactions with the specified timestamp range', async () => { + const response = await utils[request]('POST', 'transactions/search', { + timestamp: { + from: timestampFrom, + to: timestampTo, + }, + }) + + expect(response).toBeSuccessfulResponse() + + const data = response.data.data + expect(data).toBeArray() + expect(data).toHaveLength(100) + + data.forEach(transaction => { + utils.expectTransaction(transaction) + }) + + const transactions = {} + genesisBlock.transactions.forEach(transaction => { + transactions[transaction.id] = true + }) + const failed = data.some(transaction => !transactions[transaction.id]) + + expect(!failed).toBeTrue() }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const transaction = response.data.data[0] - utils.expectTransaction(transaction) - expect(transaction.id).toBe(transactionId) }) - // TODO remove the search by id, to be sure that is OK - it('should POST a search for transactions with the specified amount range', async () => { - const response = await utils.request('POST', 'transactions/search', { - id: transactionId, - amount: { - from: amountFrom, - to: amountTo - } + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for transactions with the exact specified amount', async () => { + const response = await utils[request]('POST', 'transactions/search', { + amount: { + from: amount, + to: amount, + }, + }) + + expect(response).toBeSuccessfulResponse() + + const data = response.data.data + expect(data).toBeArray() + expect(data).toHaveLength(50) + + data.forEach(transaction => { + utils.expectTransaction(transaction) + }) + + const transactions = {} + genesisBlock.transactions.forEach(transaction => { + transactions[transaction.id] = true + }) + const failed = data.some(transaction => !transactions[transaction.id]) + + expect(!failed).toBeTrue() }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const transaction = response.data.data[0] - utils.expectTransaction(transaction) - expect(transaction.id).toBe(transactionId) }) - // TODO remove the search by id, to be sure that is OK - it('should POST a search for transactions with the exact specified fee', async () => { - const response = await utils.request('POST', 'transactions/search', { - id: transactionId, - fee: { - from: fee, - to: fee - } + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for transactions with the specified amount range', async () => { + const response = await utils[request]('POST', 'transactions/search', { + amount: { + from: amountFrom, + to: amountTo, + }, + }) + + expect(response).toBeSuccessfulResponse() + + const data = response.data.data + expect(data).toBeArray() + expect(data).toHaveLength(50) + + data.forEach(transaction => { + utils.expectTransaction(transaction) + }) + + const transactions = {} + genesisBlock.transactions.forEach(transaction => { + transactions[transaction.id] = true + }) + const failed = data.some(transaction => !transactions[transaction.id]) + + expect(!failed).toBeTrue() }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const transaction = response.data.data[0] - utils.expectTransaction(transaction) - expect(transaction.id).toBe(transactionId) }) - // TODO remove the search by id, to be sure that is OK - it('should POST a search for transactions with the specified fee range', async () => { - const response = await utils.request('POST', 'transactions/search', { - id: transactionId, - fee: { - from: feeFrom, - to: feeTo - } + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for transactions with the exact specified fee', async () => { + const response = await utils[request]('POST', 'transactions/search', { + fee: { + from: fee, + to: fee, + }, + }) + + expect(response).toBeSuccessfulResponse() + + const data = response.data.data + expect(data).toBeArray() + expect(data).toHaveLength(100) + + data.forEach(transaction => { + utils.expectTransaction(transaction) + }) + + const transactions = {} + genesisBlock.transactions.forEach(transaction => { + transactions[transaction.id] = true + }) + const failed = data.some(transaction => !transactions[transaction.id]) + + expect(!failed).toBeTrue() }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) + }) - const transaction = response.data.data[0] - utils.expectTransaction(transaction) - expect(transaction.id).toBe(transactionId) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for transactions with the specified fee range', async () => { + const response = await utils[request]('POST', 'transactions/search', { + fee: { + from: feeFrom, + to: feeTo, + }, + }) + + expect(response).toBeSuccessfulResponse() + + const data = response.data.data + expect(data).toBeArray() + expect(data).toHaveLength(100) + + data.forEach(transaction => { + utils.expectTransaction(transaction) + }) + + const transactions = {} + genesisBlock.transactions.forEach(transaction => { + transactions[transaction.id] = true + }) + const failed = data.some(transaction => !transactions[transaction.id]) + + expect(!failed).toBeTrue() + }) }) // TODO remove the search by id, to be sure that is OK - it.skip('should POST a search for transactions with the exact specified vendorFieldHex', async () => { - const transactionId = '0000faa27b422f7648b1a2f634f15c7e5c8e96b84929624fda44abf716bdf784' - const vendorFieldHex = '64656c65676174653a20766f746572732073686172652e205468616e6b20796f7521207c74782062792061726b2d676f' - - const response = await utils.request('POST', 'transactions/search', { id: transactionId, vendorFieldHex }) - utils.expectSuccessful(response) - utils.expectCollection(response) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it.skip('should POST a search for transactions with the exact specified vendorFieldHex', async () => { + const id = + '0000faa27b422f7648b1a2f634f15c7e5c8e96b84929624fda44abf716bdf784' + const vendorFieldHex = + '64656c65676174653a20766f746572732073686172652e205468616e6b20796f7521207c74782062792061726b2d676f' + + const response = await utils[request]('POST', 'transactions/search', { + id, + vendorFieldHex, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(1) + + const transaction = response.data.data[0] + utils.expectTransaction(transaction) + expect(transaction.id).toBe(transactionId) + }) + }) - expect(response.data.data).toHaveLength(1) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for transactions with the wrong specified type', async () => { + const response = await utils[request]('POST', 'transactions/search', { + id: transactionId, + type: wrongType, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(0) + }) + }) - const transaction = response.data.data[0] - utils.expectTransaction(transaction) - expect(transaction.id).toBe(transactionId) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for transactions with the specific criteria', async () => { + const response = await utils[request]('POST', 'transactions/search', { + senderPublicKey, + type, + timestamp: { + from: timestampFrom, + to: timestampTo, + }, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + utils.expectTransaction(response.data.data[0]) + }) }) + }) - it('should POST a search for transactions with the wrong specified type', async () => { - const response = await utils.request('POST', 'transactions/search', { id: transactionId, type: wrongType }) - utils.expectSuccessful(response) - utils.expectCollection(response) + describe('POST /transactions', () => { + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + const transactions = generateTransfers( + 'testnet', + delegates[0].secret, + delegates[1].address, + 1, + 40, + true, + ) + + it('should POST all the transactions', async () => { + const response = await utils[request]('POST', 'transactions', { + transactions, + }) + expect(response).toBeSuccessfulResponse() + }) - expect(response.data.data).toHaveLength(0) - }) + it('should not POST all the transactions', async () => { + const response = await utils[request]('POST', 'transactions', { + transactions: transactions.concat(transactions), + }) - it('should POST a search for transactions with the specific criteria', async () => { - const response = await utils.request('POST', 'transactions/search', { - senderPublicKey, - type, - timestamp: { - from: timestampFrom, - to: timestampTo - } + expect(response.data.statusCode).toBe(413) + expect(response.data.message).toBe( + 'Received 80 transactions. Only 40 are allowed per request.', + ) }) - utils.expectSuccessful(response) - utils.expectCollection(response) + }) - expect(response.data.data).toBeArray() - utils.expectTransaction(response.data.data[0]) + it('should POST 2 transactions double spending and get only 1 accepted and broadcasted', async () => { + const transactions = generateTransfers( + 'testnet', + delegates[0].secret, + delegates[1].address, + 245098000000000 - 5098000000000, // a bit less than the delegates' balance + 2, + true, + ) + const response = await utils.requestWithAcceptHeader( + 'POST', + 'transactions', + { + transactions, + }, + ) + + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeObject() + + expect(response.data.data.accept.length).toBe(1) + expect(response.data.data.accept[0]).toBe(transactions[0].id) + + expect(response.data.data.broadcast.length).toBe(1) + expect(response.data.data.broadcast[0]).toBe(transactions[0].id) + + expect(response.data.data.invalid.length).toBe(1) + expect(response.data.data.invalid[0]).toBe(transactions[1].id) }) + + it.each([3, 5, 8])( + 'should accept and broadcast %i transactions emptying a wallet', + async txNumber => { + const sender = delegates[txNumber] // use txNumber so that we use a different delegate for each test case + const receivers = generateWallets('testnet', 2) + const amountPlusFee = Math.floor(sender.balance / txNumber) + const lastAmountPlusFee = + sender.balance - (txNumber - 1) * amountPlusFee + + const transactions = generateTransfers( + 'testnet', + sender.secret, + receivers[0].address, + amountPlusFee - transferFee, + txNumber - 1, + true, + ) + const lastTransaction = generateTransfers( + 'testnet', + sender.secret, + receivers[1].address, + lastAmountPlusFee - transferFee, + 1, + true, + ) + // we change the receiver in lastTransaction to prevent having 2 exact same transactions with same id (if not, could be same as transactions[0]) + + const allTransactions = transactions.concat(lastTransaction) + + const response = await utils.requestWithAcceptHeader( + 'POST', + 'transactions', + { + transactions: allTransactions, + }, + ) + + expect(response).toBeSuccessfulResponse() + + expect(response.data.data.accept.sort()).toEqual( + allTransactions.map(transaction => transaction.id).sort(), + ) + expect(response.data.data.broadcast.sort()).toEqual( + allTransactions.map(transaction => transaction.id).sort(), + ) + expect(response.data.data.invalid.length).toBe(0) + }, + ) + + it.each([3, 5, 8])( + 'should not accept the last of %i transactions emptying a wallet when the last one is 1 arktoshi too much', + async txNumber => { + const sender = delegates[txNumber + 1] // use txNumber + 1 so that we don't use the same delegates as the above test + const receivers = generateWallets('testnet', 2) + const amountPlusFee = Math.floor(sender.balance / txNumber) + const lastAmountPlusFee = + sender.balance - (txNumber - 1) * amountPlusFee + 1 + + const transactions = generateTransfers( + 'testnet', + sender.secret, + receivers[0].address, + amountPlusFee - transferFee, + txNumber - 1, + true, + ) + const lastTransaction = generateTransfers( + 'testnet', + sender.secret, + receivers[1].address, + lastAmountPlusFee - transferFee, + 1, + true, + ) + // we change the receiver in lastTransaction to prevent having 2 exact same transactions with same id (if not, could be same as transactions[0]) + + const allTransactions = transactions.concat(lastTransaction) + + const response = await utils.requestWithAcceptHeader( + 'POST', + 'transactions', + { + transactions: allTransactions, + }, + ) + + expect(response).toBeSuccessfulResponse() + + expect(response.data.data.accept.sort()).toEqual( + transactions.map(transaction => transaction.id).sort(), + ) + expect(response.data.data.broadcast.sort()).toEqual( + transactions.map(transaction => transaction.id).sort(), + ) + expect(response.data.data.invalid).toEqual( + lastTransaction.map(transaction => transaction.id), + ) + }, + ) }) }) diff --git a/packages/core-api/__tests__/v2/handlers/votes.test.js b/packages/core-api/__tests__/v2/handlers/votes.test.js index 703ea3be63..70de25f462 100644 --- a/packages/core-api/__tests__/v2/handlers/votes.test.js +++ b/packages/core-api/__tests__/v2/handlers/votes.test.js @@ -1,5 +1,4 @@ -'use strict' - +require('@arkecosystem/core-test-utils/lib/matchers') const app = require('../../__support__/setup') const utils = require('../utils') @@ -15,25 +14,35 @@ afterAll(async () => { describe('API 2.0 - Votes', () => { describe('GET /votes', () => { - it('should GET all the votes', async () => { - const response = await utils.request('GET', 'votes') - utils.expectSuccessful(response) - utils.expectCollection(response) - utils.expectPaginator(response) - - expect(response.data.data[0]).toBeObject() - expect(response.data.meta.count).toBeNumber() + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should GET all the votes', async () => { + const response = await utils[request]('GET', 'votes') + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + utils.expectPaginator(response) + + expect(response.data.data[0]).toBeObject() + expect(response.data.meta.count).toBeNumber() + }) }) }) describe('GET /votes/:id', () => { - it('should GET a vote by the given identifier', async () => { - const response = await utils.request('GET', `votes/${voteId}`) - utils.expectSuccessful(response) - utils.expectResource(response) - - expect(response.data.data).toBeObject() - expect(response.data.data.id).toBe(voteId) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should GET a vote by the given identifier', async () => { + const response = await utils[request]('GET', `votes/${voteId}`) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeObject() + + expect(response.data.data).toBeObject() + expect(response.data.data.id).toBe(voteId) + }) }) }) }) diff --git a/packages/core-api/__tests__/v2/handlers/wallets.test.js b/packages/core-api/__tests__/v2/handlers/wallets.test.js index ccf0859ef4..9af90bc5f1 100644 --- a/packages/core-api/__tests__/v2/handlers/wallets.test.js +++ b/packages/core-api/__tests__/v2/handlers/wallets.test.js @@ -1,11 +1,13 @@ -'use strict' +/* eslint max-len: "off" */ +require('@arkecosystem/core-test-utils/lib/matchers') const app = require('../../__support__/setup') const utils = require('../utils') const username = 'genesis_9' const address = 'AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo' -const publicKey = '0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647' +const publicKey = + '0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647' const balance = 245098000000000 beforeAll(async () => { @@ -18,245 +20,338 @@ afterAll(async () => { describe('API 2.0 - Wallets', () => { describe('GET /wallets', () => { - it('should GET all the wallets', async () => { - const response = await utils.request('GET', 'wallets') - utils.expectSuccessful(response) - utils.expectCollection(response) - - utils.expectWallet(response.data.data[0]) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should GET all the wallets', async () => { + const response = await utils[request]('GET', 'wallets') + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + utils.expectWallet(response.data.data[0]) + }) }) }) describe('GET /wallets/top', () => { - it('should GET all the top wallets', async () => { - const response = await utils.request('GET', 'wallets/top') - utils.expectSuccessful(response) - utils.expectCollection(response) - - utils.expectWallet(response.data.data[0]) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should GET all the top wallets', async () => { + const response = await utils[request]('GET', 'wallets/top') + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + utils.expectWallet(response.data.data[0]) + }) }) }) describe('GET /wallets/:id', () => { - it('should GET a wallet by the given identifier', async () => { - const response = await utils.request('GET', `wallets/${address}`) - utils.expectSuccessful(response) - utils.expectResource(response) - - const wallet = response.data.data - utils.expectWallet(wallet) - expect(wallet.address).toBe(address) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should GET a wallet by the given identifier', async () => { + const response = await utils[request]('GET', `wallets/${address}`) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeObject() + + const wallet = response.data.data + utils.expectWallet(wallet) + expect(wallet.address).toBe(address) + }) }) describe('when requesting an unknown address', () => { - it('should return ResourceNotFound error', async () => { - try { - await utils.request('GET', 'wallets/dummy') - } catch (error) { - expect(error.response.status).toEqual(404) - } + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should return ResourceNotFound error', async () => { + try { + await utils[request]('GET', 'wallets/dummy') + } catch (error) { + expect(error.response.status).toEqual(404) + } + }) }) }) }) describe('GET /wallets/:id/transactions', () => { - it('should GET all the transactions for the given wallet by id', async () => { - const response = await utils.request('GET', `wallets/${address}/transactions`) - utils.expectSuccessful(response) - utils.expectCollection(response) - - utils.expectTransaction(response.data.data[0]) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should GET all the transactions for the given wallet by id', async () => { + const response = await utils[request]( + 'GET', + `wallets/${address}/transactions`, + ) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + utils.expectTransaction(response.data.data[0]) + }) }) }) describe('GET /wallets/:id/transactions/sent', () => { - it('should GET all the send transactions for the given wallet by id', async () => { - const response = await utils.request('GET', `wallets/${address}/transactions/sent`) - utils.expectSuccessful(response) - utils.expectCollection(response) - - const transaction = response.data.data[0] - utils.expectTransaction(transaction) - expect(transaction.sender).toBe(address) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should GET all the send transactions for the given wallet by id', async () => { + const response = await utils[request]( + 'GET', + `wallets/${address}/transactions/sent`, + ) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + const transaction = response.data.data[0] + utils.expectTransaction(transaction) + expect(transaction.sender).toBe(address) + }) }) }) describe('GET /wallets/:id/transactions/received', () => { - it('should GET all the received transactions for the given wallet by id', async () => { - const response = await utils.request('GET', `wallets/${address}/transactions/received`) - utils.expectSuccessful(response) - utils.expectCollection(response) - - utils.expectTransaction(response.data.data[0]) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should GET all the received transactions for the given wallet by id', async () => { + const response = await utils[request]( + 'GET', + `wallets/${address}/transactions/received`, + ) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + utils.expectTransaction(response.data.data[0]) + }) }) }) describe('GET /wallets/:id/votes', () => { - it('should GET all the votes for the given wallet by id', async () => { - const response = await utils.request('GET', `wallets/${address}/votes`) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data[0]).toBeObject() + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should GET all the votes for the given wallet by id', async () => { + const response = await utils[request]('GET', `wallets/${address}/votes`) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data[0]).toBeObject() + }) }) }) describe('POST /wallets/search', () => { - it('should POST a search for wallets with the exact specified address', async () => { - const response = await utils.request('POST', 'wallets/search', { address }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const wallet = response.data.data[0] - utils.expectWallet(wallet) - expect(wallet.address).toBe(address) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for wallets with the exact specified address', async () => { + const response = await utils[request]('POST', 'wallets/search', { + address, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(1) + + const wallet = response.data.data[0] + utils.expectWallet(wallet) + expect(wallet.address).toBe(address) + }) }) - it('should POST a search for wallets with the exact specified publicKey', async () => { - const response = await utils.request('POST', 'wallets/search', { address, publicKey }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const wallet = response.data.data[0] - utils.expectWallet(wallet) - expect(wallet.address).toBe(address) - expect(wallet.publicKey).toBe(publicKey) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for wallets with the exact specified publicKey', async () => { + const response = await utils[request]('POST', 'wallets/search', { + address, + publicKey, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(1) + + const wallet = response.data.data[0] + utils.expectWallet(wallet) + expect(wallet.address).toBe(address) + expect(wallet.publicKey).toBe(publicKey) + }) }) - // it('should POST a search for wallets with the exact specified secondPublicKey', async () => { - // const response = await utils.request('POST', 'wallets/search', { address: addressSecondPassphrase, secondPublicKey }) - // utils.expectSuccessful(response) - // utils.expectCollection(response) - - // expect(response.data.data).toHaveLength(1) - - // const wallet = response.data.data[0] - // utils.expectWallet(wallet) - // expect(wallet.address).toBe(addressSecondPassphrase) + // describe.each([ + // ['API-Version', 'request'], + // ['Accept', 'requestWithAcceptHeader'] + // ])('using the %s header', (header, request) => { + // it('should POST a search for wallets with the exact specified secondPublicKey', async () => { + // const response = await utils[request]('POST', 'wallets/search', { address: addressSecondPassphrase, secondPublicKey }) + // expect(response).toBeSuccessfulResponse() + // expect(response.data.data).toBeArray() + + // expect(response.data.data).toHaveLength(1) + + // const wallet = response.data.data[0] + // utils.expectWallet(wallet) + // expect(wallet.address).toBe(addressSecondPassphrase) + // }) // }) - // it('should POST a search for wallets with the exact specified vote', async () => { - // const response = await utils.request('POST', 'wallets/search', { address: address, vote }) - // utils.expectSuccessful(response) - // utils.expectCollection(response) - - // expect(response.data.data).toHaveLength(1) - - // const wallet = response.data.data[0] - // utils.expectWallet(wallet) - // expect(wallet.address).toBe(address) + // describe.each([ + // ['API-Version', 'request'], + // ['Accept', 'requestWithAcceptHeader'] + // ])('using the %s header', (header, request) => { + // it('should POST a search for wallets with the exact specified vote', async () => { + // const response = await utils[request]('POST', 'wallets/search', { address: address, vote }) + // expect(response).toBeSuccessfulResponse() + // expect(response.data.data).toBeArray() + + // expect(response.data.data).toHaveLength(1) + + // const wallet = response.data.data[0] + // utils.expectWallet(wallet) + // expect(wallet.address).toBe(address) + // }) // }) - it('should POST a search for wallets with the exact specified username', async () => { - const response = await utils.request('POST', 'wallets/search', { address, username }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const wallet = response.data.data[0] - utils.expectWallet(wallet) - expect(wallet.address).toBe(address) - }) - - it('should POST a search for wallets with the exact specified balance', async () => { - const response = await utils.request('POST', 'wallets/search', { - address, - balance: { - from: balance, - to: balance - } + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for wallets with the exact specified username', async () => { + const response = await utils[request]('POST', 'wallets/search', { + address, + username, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(1) + + const wallet = response.data.data[0] + utils.expectWallet(wallet) + expect(wallet.address).toBe(address) }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const wallet = response.data.data[0] - utils.expectWallet(wallet) - expect(wallet.address).toBe(address) - expect(wallet.balance).toBe(balance) }) - it('should POST a search for wallets with the specified balance range', async () => { - const response = await utils.request('POST', 'wallets/search', { - address, - balance: { - from: balance, - to: balance - } + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for wallets with the exact specified balance', async () => { + const response = await utils[request]('POST', 'wallets/search', { + address, + balance: { + from: balance, + to: balance, + }, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(1) + + const wallet = response.data.data[0] + utils.expectWallet(wallet) + expect(wallet.address).toBe(address) + expect(wallet.balance).toBe(balance) }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const wallet = response.data.data[0] - utils.expectWallet(wallet) - expect(wallet.address).toBe(address) - expect(wallet.balance).toBe(balance) }) - it.skip('should POST a search for wallets with the exact specified votebalance', async () => { - const response = await utils.request('POST', 'wallets/search', { - address, - votebalance: { - from: 0, - to: 0 - } + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for wallets with the specified balance range', async () => { + const response = await utils[request]('POST', 'wallets/search', { + address, + balance: { + from: balance - 1000, + to: balance + 1000, + }, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(1) + + const wallet = response.data.data[0] + utils.expectWallet(wallet) + expect(wallet.address).toBe(address) + expect(wallet.balance).toBe(balance) }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const wallet = response.data.data[0] - utils.expectWallet(wallet) - expect(wallet.address).toBe(address) }) - it.skip('should POST a search for wallets with the specified votebalance range', async () => { - const response = await utils.request('POST', 'wallets/search', { - address, - votebalance: { - from: 0, - to: 0 - } + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for wallets with the exact specified voteBalance', async () => { + const response = await utils[request]('POST', 'wallets/search', { + address, + voteBalance: { + from: balance, + to: balance, + }, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(1) + + const wallet = response.data.data[0] + utils.expectWallet(wallet) + expect(wallet.address).toBe(address) }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const wallet = response.data.data[0] - utils.expectWallet(wallet) - expect(wallet.address).toBe(address) }) - it('should POST a search for wallets with the wrong specified username', async () => { - const response = await utils.request('POST', 'wallets/search', { address, username: 'dummy' }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(0) + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for wallets with the wrong specified username', async () => { + const response = await utils[request]('POST', 'wallets/search', { + address, + username: 'dummy', + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(0) + }) }) - it('should POST a search for wallets with the specific criteria', async () => { - const response = await utils.request('POST', 'wallets/search', { - publicKey, username + describe.each([ + ['API-Version', 'request'], + ['Accept', 'requestWithAcceptHeader'], + ])('using the %s header', (header, request) => { + it('should POST a search for wallets with the specific criteria', async () => { + const response = await utils[request]('POST', 'wallets/search', { + publicKey, + username, + }) + expect(response).toBeSuccessfulResponse() + expect(response.data.data).toBeArray() + + expect(response.data.data).toHaveLength(1) + + const wallet = response.data.data[0] + utils.expectWallet(wallet) + expect(wallet.address).toBe(address) }) - utils.expectSuccessful(response) - utils.expectCollection(response) - - expect(response.data.data).toHaveLength(1) - - const wallet = response.data.data[0] - utils.expectWallet(wallet) - expect(wallet.address).toBe(address) }) }) }) diff --git a/packages/core-api/__tests__/v2/utils.js b/packages/core-api/__tests__/v2/utils.js index 0cfc133fa8..71076a0823 100644 --- a/packages/core-api/__tests__/v2/utils.js +++ b/packages/core-api/__tests__/v2/utils.js @@ -1,41 +1,58 @@ -'use strict' - const axios = require('axios') -const { client, transactionBuilder, NetworkManager } = require('@arkecosystem/crypto') +const { + client, + transactionBuilder, + NetworkManager, +} = require('@arkecosystem/crypto') +const apiHelpers = require('@arkecosystem/core-test-utils/lib/helpers/api') class Helpers { - request (method, path, params = {}) { + async request(method, path, params = {}) { const url = `http://localhost:4003/api/${path}` - const headers = { 'API-Version': 2 } - const request = axios[method.toLowerCase()] + const headers = { + 'API-Version': 2, + 'Content-Type': 'application/json', + } - return ['GET', 'DELETE'].includes(method) - ? request(url, { params, headers }) - : request(url, params, { headers }) + const server = require('@arkecosystem/core-container').resolvePlugin('api') + + return apiHelpers.request(server.http, method, url, headers, params) } - expectJson (response) { + async requestWithAcceptHeader(method, path, params = {}) { + const url = `http://localhost:4003/api/${path}` + const headers = { + Accept: 'application/vnd.ark.core-api.v2+json', + 'Content-Type': 'application/json', + } + + const server = require('@arkecosystem/core-container').resolvePlugin('api') + + return apiHelpers.request(server.http, method, url, headers, params) + } + + expectJson(response) { expect(response.data).toBeObject() } - expectStatus (response, code) { + expectStatus(response, code) { expect(response.status).toBe(code) } - assertVersion (response, version) { + assertVersion(response, version) { expect(response.headers).toBeObject() expect(response.headers).toHaveProperty('api-version', version) } - expectResource (response) { + expectResource(response) { expect(response.data.data).toBeObject() } - expectCollection (response) { + expectCollection(response) { expect(Array.isArray(response.data.data)).toBe(true) } - expectPaginator (response, firstPage = true) { + expectPaginator(response, firstPage = true) { expect(response.data.meta).toBeObject() expect(response.data.meta).toHaveProperty('count') expect(response.data.meta).toHaveProperty('pageCount') @@ -47,13 +64,13 @@ class Helpers { expect(response.data.meta).toHaveProperty('last') } - expectSuccessful (response, statusCode = 200) { + expectSuccessful(response, statusCode = 200) { this.expectStatus(response, statusCode) this.expectJson(response) - this.assertVersion(response, '2') + this.assertVersion(response, 2) } - expectError (response, statusCode = 404) { + expectError(response, statusCode = 404) { this.expectStatus(response, statusCode) this.expectJson(response) expect(response.data.statusCode).toBeNumber() @@ -61,7 +78,7 @@ class Helpers { expect(response.data.message).toBeString() } - expectTransaction (transaction) { + expectTransaction(transaction) { expect(transaction).toBeObject() expect(transaction).toHaveProperty('id') expect(transaction).toHaveProperty('blockId') @@ -78,25 +95,31 @@ class Helpers { expect(transaction.confirmations).toBeNumber() } - expectBlock (block) { + expectBlock(block, expected) { expect(block).toBeObject() - expect(block).toHaveProperty('id') - expect(block).toHaveProperty('version') - expect(block).toHaveProperty('height') - expect(block).toHaveProperty('previous') + expect(block.id).toBeString() + expect(block.version).toBeNumber() + expect(block.height).toBeNumber() + expect(block).toHaveProperty('previous') // `null` or String expect(block).toHaveProperty('forged') - expect(block.forged).toHaveProperty('reward') - expect(block.forged).toHaveProperty('fee') + expect(block.forged.reward).toBeNumber() + expect(block.forged.fee).toBeNumber() + expect(block.forged.total).toBeNumber() + expect(block.forged.amount).toBeNumber() expect(block).toHaveProperty('payload') - expect(block.payload).toHaveProperty('length') - expect(block.payload).toHaveProperty('hash') + expect(block.payload.length).toBeNumber() + expect(block.payload.hash).toBeString() expect(block).toHaveProperty('generator') - expect(block.generator).toHaveProperty('publicKey') - expect(block).toHaveProperty('signature') - expect(block).toHaveProperty('transactions') + expect(block.generator.publicKey).toBeString() + expect(block.signature).toBeString() + expect(block.transactions).toBeNumber() + + Object.keys(expected || {}).forEach(attr => { + expect(block[attr]).toEqual(expected[attr]) + }) } - expectDelegate (delegate, expected) { + expectDelegate(delegate, expected) { expect(delegate).toBeObject() expect(delegate.username).toBeString() expect(delegate.address).toBeString() @@ -107,15 +130,18 @@ class Helpers { expect(delegate.blocks.missed).toBeNumber() expect(delegate.blocks.produced).toBeNumber() expect(delegate.production).toBeObject() - expect(delegate.production.approval).toBeString() - expect(delegate.production.productivity).toBeString() + expect(delegate.production.approval).toBeNumber() + expect(delegate.production.productivity).toBeNumber() + expect(delegate.forged.fees).toBeNumber() + expect(delegate.forged.rewards).toBeNumber() + expect(delegate.forged.total).toBeNumber() Object.keys(expected || {}).forEach(attr => { expect(delegate[attr]).toBe(expected[attr]) }) } - expectWallet (wallet) { + expectWallet(wallet) { expect(wallet).toBeObject() expect(wallet).toHaveProperty('address') expect(wallet).toHaveProperty('publicKey') @@ -123,20 +149,28 @@ class Helpers { expect(wallet).toHaveProperty('isDelegate') } - async createTransaction () { + async createTransaction() { client.setConfig(NetworkManager.findByName('testnet')) - let transaction = transactionBuilder + const transaction = transactionBuilder .transfer() - .amount(1 * Math.pow(10, 8)) + .amount(1 * 1e8) .recipientId('AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1') .vendorField('test') - .sign('prison tobacco acquire stone dignity palace note decade they current lesson robot') + .sign( + 'prison tobacco acquire stone dignity palace note decade they current lesson robot', + ) .getStruct() - await axios.post('http://127.0.0.1:4003/api/v2/transactions', { - transactions: [transaction] - }) + await axios.post( + 'http://127.0.0.1:4003/api/v2/transactions', + { + transactions: [transaction], + }, + { + headers: { 'Content-Type': 'application/json' }, + }, + ) return transaction } diff --git a/packages/core-api/jest.config.js b/packages/core-api/jest.config.js index 26f7a25796..57770a97bb 100644 --- a/packages/core-api/jest.config.js +++ b/packages/core-api/jest.config.js @@ -1,22 +1,12 @@ -'use strict' - module.exports = { testEnvironment: 'node', bail: false, verbose: true, - testMatch: [ - '**/__tests__/**/*.test.js' - ], - moduleFileExtensions: [ - 'js', - 'json' - ], + testMatch: ['**/__tests__/**/*.test.js'], + moduleFileExtensions: ['js', 'json'], collectCoverage: false, coverageDirectory: '/.coverage', - collectCoverageFrom: [ - 'lib/**/*.js', - '!**/node_modules/**' - ], + collectCoverageFrom: ['lib/**/*.js', '!**/node_modules/**'], watchman: false, - setupTestFrameworkScriptFile: 'jest-extended' + setupTestFrameworkScriptFile: 'jest-extended', } diff --git a/packages/core-api/jsdoc.json b/packages/core-api/jsdoc.json index 23276f74ea..f3ea8aab33 100644 --- a/packages/core-api/jsdoc.json +++ b/packages/core-api/jsdoc.json @@ -7,9 +7,7 @@ "includePattern": ".js$", "excludePattern": "(node_modules/|docs)" }, - "plugins": [ - "plugins/markdown" - ], + "plugins": ["plugins/markdown"], "opts": { "template": "../../node_modules/docdash", "encoding": "utf8", diff --git a/packages/core-api/lib/defaults.js b/packages/core-api/lib/defaults.js index 56d2c906f8..bef35ca154 100644 --- a/packages/core-api/lib/defaults.js +++ b/packages/core-api/lib/defaults.js @@ -1,29 +1,35 @@ -'use strict' +const path = require('path') module.exports = { enabled: false, host: process.env.ARK_API_HOST || '0.0.0.0', port: process.env.ARK_API_PORT || 4003, - versions: { - default: 1, - valid: [1, 2] + // @see https://hapijs.com/api#-serveroptionstls + ssl: { + enabled: process.env.ARK_API_SSL, + host: process.env.ARK_API_SSL_HOST || '0.0.0.0', + port: process.env.ARK_API_SSL_PORT || 8443, + key: process.env.ARK_API_SSL_KEY, + cert: process.env.ARK_API_SSL_CERT, }, - cache: { - enabled: false, - options: { - name: 'redisCache', - engine: 'catbox-redis', - host: process.env.ARK_REDIS_HOST || 'localhost', - port: process.env.ARK_REDIS_PORT || 6379, - partition: 'cache', - expiresIn: 60000 - } + // @see https://github.com/p-meier/hapi-api-version + versions: { + validVersions: [1, 2], + defaultVersion: 1, + basePath: '/api/', + vendorName: 'ark.core-api', }, + // @see https://github.com/wraithgar/hapi-rate-limit rateLimit: { - enabled: false, - limit: 300, - expires: 60000 + enabled: !process.env.ARK_API_RATE_LIMIT, + pathLimit: false, + userLimit: 300, + userCache: { + expiresIn: 60000, + }, + ipWhitelist: ['127.0.0.1', '::ffff:127.0.0.1'], }, + // @see https://github.com/fknop/hapi-pagination pagination: { limit: 100, include: [ @@ -45,11 +51,18 @@ module.exports = { '/api/v2/wallets/{id}/transactions/received', '/api/v2/wallets/{id}/transactions/sent', '/api/v2/wallets/{id}/votes', - '/api/v2/wallets/search' - ] + '/api/v2/wallets/search', + ], }, - whitelist: [ - '127.0.0.1', - '::ffff:127.0.0.1' - ] + whitelist: ['127.0.0.1', '::ffff:127.0.0.1'], + plugins: [ + { + plugin: path.resolve(__dirname, './versions/1'), + routes: { prefix: '/api/v1' }, + }, + { + plugin: path.resolve(__dirname, './versions/2'), + routes: { prefix: '/api/v2' }, + }, + ], } diff --git a/packages/core-api/lib/index.js b/packages/core-api/lib/index.js index 9cfa215a26..811bf3ad83 100644 --- a/packages/core-api/lib/index.js +++ b/packages/core-api/lib/index.js @@ -1,5 +1,3 @@ -'use strict' - /** * The struct used by the plugin container. * @type {Object} @@ -8,20 +6,26 @@ exports.plugin = { pkg: require('../package.json'), defaults: require('./defaults'), alias: 'api', - async register (container, options) { + async register(container, options) { if (!options.enabled) { - container.resolvePlugin('logger').info('Public API is disabled :grey_exclamation:') + container + .resolvePlugin('logger') + .info('Public API is disabled :grey_exclamation:') return } return require('./server')(options) }, - async deregister (container, options) { + async deregister(container, options) { if (options.enabled) { - container.resolvePlugin('logger').info('Stopping Public API') + const servers = Object.entries(container.resolvePlugin('api')) + + for (const [type, server] of servers) { + container.resolvePlugin('logger').info(`Stopping Public ${type} API`) - return container.resolvePlugin('api').stop() + return server.stop() + } } - } + }, } diff --git a/packages/core-api/lib/plugins/caster.js b/packages/core-api/lib/plugins/caster.js index adcdd90c65..6d5db8529e 100644 --- a/packages/core-api/lib/plugins/caster.js +++ b/packages/core-api/lib/plugins/caster.js @@ -1,17 +1,15 @@ -'use strict' - /* eslint-disable */ -const BigNumber = require('bignumber.js') +const { bignumify } = require('@arkecosystem/core-utils') /** * Check if the given value is a boolean. * @param {*} value * @return {Boolean} */ -function isBoolean (value) { +function isBoolean(value) { try { - return (value.toLowerCase() === 'true' || value.toLowerCase() === 'false') + return value.toLowerCase() === 'true' || value.toLowerCase() === 'false' } catch (e) { return false } @@ -22,7 +20,7 @@ function isBoolean (value) { * @param {*} value * @return {Boolean} */ -function isNumber (value) { +function isNumber(value) { return !isNaN(value) } @@ -51,9 +49,10 @@ const register = async (server, options) => { } // Integers - making sure "BigNumbers" are kept as strings else if (isNumber(query[key])) { - query[key] = (query[key] == Number(query[key])) - ? Number(query[key]) - : BigNumber(query[key]).toString() + query[key] = + query[key] == Number(query[key]) + ? Number(query[key]) + : bignumify(query[key]).toString() } // Strings else { @@ -64,7 +63,7 @@ const register = async (server, options) => { request.query = query return h.continue - } + }, }) } @@ -75,5 +74,5 @@ const register = async (server, options) => { exports.plugin = { name: 'core-caster', version: '0.1.0', - register + register, } diff --git a/packages/core-api/lib/plugins/endpoint-version.js b/packages/core-api/lib/plugins/endpoint-version.js new file mode 100644 index 0000000000..83f5415841 --- /dev/null +++ b/packages/core-api/lib/plugins/endpoint-version.js @@ -0,0 +1,39 @@ +const Boom = require('boom') + +const versionRegex = /^\/api\/v([0-9])\// + +/** + * The register method used by hapi.js. + * @param {Hapi.Server} server + * @param {Object} options + * @return {void} + */ +const register = async (server, options) => { + server.ext({ + type: 'onRequest', + async method(request, h) { + const match = versionRegex.exec(request.path) + if (match && match.length === 2) { + const apiVersion = parseInt(match[1]) + if (options.validVersions.includes(apiVersion)) { + request.pre.apiVersion = apiVersion + } else { + return Boom.badRequest( + `Invalid api-version! Valid values: ${options.validVersions.join()}`, + ) + } + } + return h.continue + }, + }) +} + +/** + * The struct used by hapi.js. + * @type {Object} + */ +module.exports = { + name: 'endpoint-version', + version: '0.1.0', + register, +} diff --git a/packages/core-api/lib/plugins/set-headers.js b/packages/core-api/lib/plugins/set-headers.js new file mode 100644 index 0000000000..a0415af0be --- /dev/null +++ b/packages/core-api/lib/plugins/set-headers.js @@ -0,0 +1,32 @@ +/** + * The register method used by hapi.js. + * @param {Hapi.Server} server + * @param {Object} options + * @return {void} + */ +const register = async (server, options) => { + server.ext({ + type: 'onPreResponse', + async method(request, h) { + const response = request.response + if (response.isBoom && response.data) { + // Deleting the property beforehand makes it appear last in the + // response body. + delete response.output.payload.error + response.output.payload.error = response.data + } + + return h.continue + }, + }) +} + +/** + * The struct used by hapi.js. + * @type {Object} + */ +exports.plugin = { + name: 'set-headers', + version: '0.1.0', + register, +} diff --git a/packages/core-api/lib/plugins/validation/formats/address.js b/packages/core-api/lib/plugins/validation/formats/address.js index 2e4e268a34..f2423b6560 100644 --- a/packages/core-api/lib/plugins/validation/formats/address.js +++ b/packages/core-api/lib/plugins/validation/formats/address.js @@ -1,5 +1,3 @@ -'use strict' - const bs58check = require('bs58check') const config = require('@arkecosystem/core-container').resolvePlugin('config') @@ -8,15 +6,15 @@ const config = require('@arkecosystem/core-container').resolvePlugin('config') * @param {AJV} ajv * @return {void} */ -module.exports = (ajv) => { +module.exports = ajv => { ajv.addFormat('address', { type: 'string', - validate: (value) => { + validate: value => { try { return bs58check.decode(value)[0] === config.network.pubKeyHash } catch (e) { return false } - } + }, }) } diff --git a/packages/core-api/lib/plugins/validation/formats/csv.js b/packages/core-api/lib/plugins/validation/formats/csv.js index 0dd7256fe6..4c5fcb66cf 100644 --- a/packages/core-api/lib/plugins/validation/formats/csv.js +++ b/packages/core-api/lib/plugins/validation/formats/csv.js @@ -1,14 +1,12 @@ -'use strict' - /** * Register the "csv" validation rule. * @param {AJV} ajv * @return {void} */ -module.exports = (ajv) => { +module.exports = ajv => { ajv.addFormat('csv', { type: 'string', - validate: (value) => { + validate: value => { try { const a = value.split(',') @@ -16,6 +14,6 @@ module.exports = (ajv) => { } catch (e) { return false } - } + }, }) } diff --git a/packages/core-api/lib/plugins/validation/formats/hex.js b/packages/core-api/lib/plugins/validation/formats/hex.js index b8de290e49..2fc0f03575 100644 --- a/packages/core-api/lib/plugins/validation/formats/hex.js +++ b/packages/core-api/lib/plugins/validation/formats/hex.js @@ -1,14 +1,12 @@ -'use strict' - /** * Register the "hex" validation rule. * @param {AJV} ajv * @return {void} */ -module.exports = (ajv) => { +module.exports = ajv => { ajv.addFormat('hex', { type: 'string', - validate: (value) => { + validate: value => { try { Buffer.from(value, 'hex') @@ -16,6 +14,6 @@ module.exports = (ajv) => { } catch (e) { return false } - } + }, }) } diff --git a/packages/core-api/lib/plugins/validation/formats/ip.js b/packages/core-api/lib/plugins/validation/formats/ip.js index 56d87ca384..a9833fea0c 100644 --- a/packages/core-api/lib/plugins/validation/formats/ip.js +++ b/packages/core-api/lib/plugins/validation/formats/ip.js @@ -1,5 +1,3 @@ -'use strict' - const ip = require('ip') /** @@ -7,11 +5,9 @@ const ip = require('ip') * @param {AJV} ajv * @return {void} */ -module.exports = (ajv) => { +module.exports = ajv => { ajv.addFormat('ip', { type: 'string', - validate: (value) => { - return ip.isV4Format(value) || ip.isV6Format(value) - } + validate: value => ip.isV4Format(value) || ip.isV6Format(value), }) } diff --git a/packages/core-api/lib/plugins/validation/formats/parsedInt.js b/packages/core-api/lib/plugins/validation/formats/parsedInt.js index 9381e94e37..8c0db25163 100644 --- a/packages/core-api/lib/plugins/validation/formats/parsedInt.js +++ b/packages/core-api/lib/plugins/validation/formats/parsedInt.js @@ -1,21 +1,25 @@ -'use strict' +/* eslint no-restricted-globals: "off" */ /** * Register the "parsedInt" validation rule. * @param {AJV} ajv * @return {void} */ -module.exports = (ajv) => { +module.exports = ajv => { ajv.addFormat('parsedInt', { type: 'string', - validate: (value) => { - if (isNaN(value) || parseInt(value) !== value || isNaN(parseInt(value, 10))) { + validate: value => { + if ( + isNaN(value) || + parseInt(value) !== value || + isNaN(parseInt(value, 10)) + ) { return false } value = parseInt(value) return true - } + }, }) } diff --git a/packages/core-api/lib/plugins/validation/formats/publicKey.js b/packages/core-api/lib/plugins/validation/formats/publicKey.js index 4ce2c1d6cc..5a732a71cc 100644 --- a/packages/core-api/lib/plugins/validation/formats/publicKey.js +++ b/packages/core-api/lib/plugins/validation/formats/publicKey.js @@ -1,19 +1,17 @@ -'use strict' - /** * Register the "publicKey" validation rule. * @param {AJV} ajv * @return {void} */ -module.exports = (ajv) => { +module.exports = ajv => { ajv.addFormat('publicKey', { type: 'string', - validate: (value) => { + validate: value => { try { return Buffer.from(value, 'hex').length === 33 } catch (e) { return false } - } + }, }) } diff --git a/packages/core-api/lib/plugins/validation/formats/signature.js b/packages/core-api/lib/plugins/validation/formats/signature.js index 45e8dce044..80080ef1b3 100644 --- a/packages/core-api/lib/plugins/validation/formats/signature.js +++ b/packages/core-api/lib/plugins/validation/formats/signature.js @@ -1,19 +1,17 @@ -'use strict' - /** * Register the "signature" validation rule. * @param {AJV} ajv * @return {void} */ -module.exports = (ajv) => { +module.exports = ajv => { ajv.addFormat('signature', { type: 'string', - validate: (value) => { + validate: value => { try { return Buffer.from(value, 'hex').length < 73 } catch (e) { return false } - } + }, }) } diff --git a/packages/core-api/lib/plugins/validation/formats/vendorField.js b/packages/core-api/lib/plugins/validation/formats/vendorField.js index c26a2fd262..d78f5c2279 100644 --- a/packages/core-api/lib/plugins/validation/formats/vendorField.js +++ b/packages/core-api/lib/plugins/validation/formats/vendorField.js @@ -1,19 +1,17 @@ -'use strict' - /** * Register the "vendorField" validation rule. * @param {AJV} ajv * @return {void} */ -module.exports = (ajv) => { +module.exports = ajv => { ajv.addFormat('vendorField', { type: 'string', - validate: (value) => { + validate: value => { try { return Buffer.from(value).length < 65 } catch (e) { return false } - } + }, }) } diff --git a/packages/core-api/lib/plugins/validation/index.js b/packages/core-api/lib/plugins/validation/index.js index 374ccaf63d..f9a302ce7b 100644 --- a/packages/core-api/lib/plugins/validation/index.js +++ b/packages/core-api/lib/plugins/validation/index.js @@ -1,5 +1,3 @@ -'use strict' - const PLUGIN_NAME = 'hapi-ajv' const fs = require('fs') @@ -15,7 +13,7 @@ const ajv = new AJV() * @param {Object} data * @return {(Boolean|Object)} */ -function validate (schema, data) { +function validate(schema, data) { return ajv.validate(schema, data) ? null : ajv.errors } @@ -26,13 +24,15 @@ function validate (schema, data) { * @param {Array} errors * @return {Hapi.Response} */ -function createErrorResponse (request, h, errors) { +function createErrorResponse(request, h, errors) { if (request.pre.apiVersion === 1) { - return h.response({ - path: errors[0].dataPath, - error: errors[0].message, - success: false - }).takeover() + return h + .response({ + path: errors[0].dataPath, + error: errors[0].message, + success: false, + }) + .takeover() } return Boom.badData(errors) } @@ -41,12 +41,12 @@ function createErrorResponse (request, h, errors) { * Register all custom validation formats * @return {void} */ -function registerCustomFormats () { - let directory = path.resolve(__dirname, 'formats') +function registerCustomFormats() { + const directory = path.resolve(__dirname, 'formats') fs.readdirSync(directory).forEach(file => { if (file.indexOf('.js') !== -1) { - require(directory + '/' + file)(ajv) + require(`${directory}/${file}`)(ajv) } }) } @@ -84,7 +84,7 @@ const register = async (server, options) => { } return h.continue - } + }, }) } @@ -95,5 +95,5 @@ const register = async (server, options) => { exports.plugin = { name: PLUGIN_NAME, version: '0.1.0', - register + register, } diff --git a/packages/core-api/lib/repositories/blocks.js b/packages/core-api/lib/repositories/blocks.js new file mode 100644 index 0000000000..2b3c190ad7 --- /dev/null +++ b/packages/core-api/lib/repositories/blocks.js @@ -0,0 +1,153 @@ +const app = require('@arkecosystem/core-container') + +const database = app.resolvePlugin('database') + +const buildFilterQuery = require('./utils/filter-query') +const Repository = require('./repository') + +class BlocksRepository extends Repository { + /** + * Get all blocks for the given parameters. + * @param {Object} parameters + * @return {Object} + */ + async findAll(parameters = {}) { + const selectQuery = this.query.select().from(this.query) + const countQuery = this._makeEstimateQuery() + + const applyConditions = queries => { + const conditions = Object.entries(this._formatConditions(parameters)) + + if (conditions.length) { + const first = conditions.shift() + + for (const item of queries) { + item.where(this.query[first[0]].equals(first[1])) + + for (const condition of conditions) { + item.and(this.query[condition[0]].equals(condition[1])) + } + } + } + } + + applyConditions([selectQuery, countQuery]) + + return this._findManyWithCount(selectQuery, countQuery, { + limit: parameters.limit, + offset: parameters.offset, + orderBy: this.__orderBy(parameters), + }) + } + + /** + * Get all blocks for the given generator. + * @param {String} generatorPublicKey + * @param {Object} paginator + * @return {Object} + */ + async findAllByGenerator(generatorPublicKey, paginator) { + return this.findAll({ ...{ generatorPublicKey }, ...paginator }) + } + + /** + * Get a block. + * @param {Number} id + * @return {Object} + */ + async findById(id) { + const query = this.query + .select() + .from(this.query) + .where(this.query.id.equals(id)) + + return this._find(query) + } + + /** + * Get the last block for the given generator. + * TODO is this right? + * @param {String} generatorPublicKey + * @return {Object} + */ + async findLastByPublicKey(generatorPublicKey) { + const query = this.query + .select(this.query.id, this.query.timestamp) + .from(this.query) + .where(this.query.generator_public_key.equals(generatorPublicKey)) + .order(this.query.height.desc) + + return this._find(query) + } + + /** + * Search all blocks. + * @param {Object} parameters + * @return {Object} + */ + async search(parameters) { + const selectQuery = this.query.select().from(this.query) + const countQuery = this._makeEstimateQuery() + + const applyConditions = queries => { + const conditions = buildFilterQuery(this._formatConditions(parameters), { + exact: [ + 'id', + 'version', + 'previous_block', + 'payload_hash', + 'generator_public_key', + 'block_signature', + ], + between: [ + 'timestamp', + 'height', + 'number_of_transactions', + 'total_amount', + 'total_fee', + 'reward', + 'payload_length', + ], + }) + + if (conditions.length) { + const first = conditions.shift() + + for (const item of queries) { + item.where(this.query[first.column][first.method](first.value)) + + for (const condition of conditions) { + item.and( + this.query[condition.column][condition.method](condition.value), + ) + } + } + } + } + + applyConditions([selectQuery, countQuery]) + + return this._findManyWithCount(selectQuery, countQuery, { + limit: parameters.limit, + offset: parameters.offset, + orderBy: this.__orderBy(parameters), + }) + } + + getModel() { + return database.models.block + } + + __orderBy(parameters) { + if (!parameters.orderBy) return ['height', 'desc'] + + const orderBy = parameters.orderBy.split(':').map(p => p.toLowerCase()) + if (orderBy.length !== 2 || ['desc', 'asc'].includes(orderBy[1]) !== true) { + return ['height', 'desc'] + } + + return orderBy + } +} + +module.exports = new BlocksRepository() diff --git a/packages/core-api/lib/repositories/index.js b/packages/core-api/lib/repositories/index.js new file mode 100644 index 0000000000..5724a9e9b4 --- /dev/null +++ b/packages/core-api/lib/repositories/index.js @@ -0,0 +1,4 @@ +module.exports = { + blocks: require('./blocks'), + transactions: require('./transactions'), +} diff --git a/packages/core-api/lib/repositories/repository.js b/packages/core-api/lib/repositories/repository.js new file mode 100644 index 0000000000..59af86586c --- /dev/null +++ b/packages/core-api/lib/repositories/repository.js @@ -0,0 +1,82 @@ +const snakeCase = require('lodash/snakeCase') +const app = require('@arkecosystem/core-container') + +const database = app.resolvePlugin('database') + +module.exports = class Repository { + constructor() { + this.cache = database.getCache() + this.model = this.getModel() + this.query = this.model.query() + + this.__mapColumns() + } + + async _find(query) { + return database.query.oneOrNone(query.toQuery()) + } + + async _findMany(query) { + return database.query.manyOrNone(query.toQuery()) + } + + async _findManyWithCount( + selectQuery, + countQuery, + { limit, offset, orderBy }, + ) { + const { count } = await this._find(countQuery) + + if (this.columns.includes(orderBy[0])) { + selectQuery.order(this.query[snakeCase(orderBy[0])][orderBy[1]]) + } + + selectQuery.offset(offset).limit(limit) + + return { + rows: await this._findMany(selectQuery), + count: +count, + } + } + + _makeCountQuery() { + return this.query.select('count(*) AS count').from(this.query) + } + + _makeEstimateQuery() { + return this.query + .select('count(*) AS count') + .from(`${this.model.getTable()} TABLESAMPLE SYSTEM (100)`) + } + + _formatConditions(parameters) { + const columns = this.model.getColumnSet().columns.map(column => ({ + name: column.name, + prop: column.prop || column.name, + })) + + return Object.keys(parameters) + .filter(arg => this.columns.includes(arg)) + .reduce((items, item) => { + const column = columns.find( + value => value.name === item || value.prop === item, + ) + + column ? (items[column.name] = parameters[item]) : delete items[item] + + return items + }, {}) + } + + __mapColumns() { + this.columns = [] + + for (const column of this.model.getColumnSet().columns) { + this.columns.push(column.name) + + if (column.prop) { + this.columns.push(column.prop) + } + } + } +} diff --git a/packages/core-api/lib/repositories/transactions.js b/packages/core-api/lib/repositories/transactions.js new file mode 100644 index 0000000000..0f3eb59a13 --- /dev/null +++ b/packages/core-api/lib/repositories/transactions.js @@ -0,0 +1,457 @@ +const app = require('@arkecosystem/core-container') + +const database = app.resolvePlugin('database') + +const dayjs = require('dayjs-ext') +const { slots } = require('@arkecosystem/crypto') +const { TRANSACTION_TYPES } = require('@arkecosystem/crypto').constants +const buildFilterQuery = require('./utils/filter-query') +const Repository = require('./repository') + +class TransactionsRepository extends Repository { + /** + * Get all transactions. + * @param {Object} params + * @return {Object} + */ + async findAll(parameters = {}) { + const selectQuery = this.query.select().from(this.query) + const countQuery = this._makeEstimateQuery() + + if (parameters.senderId) { + const senderPublicKey = this.__publicKeyFromSenderId(parameters.senderId) + + if (!senderPublicKey) { + return { rows: [], count: 0 } + } + + parameters.senderPublicKey = senderPublicKey + } + + const applyConditions = queries => { + const conditions = Object.entries(this._formatConditions(parameters)) + + if (conditions.length) { + const first = conditions.shift() + + for (const item of queries) { + item.where(this.query[first[0]].equals(first[1])) + + for (const condition of conditions) { + item.and(this.query[condition[0]].equals(condition[1])) + } + } + } + + for (const item of queries) { + if (parameters.ownerId) { + const owner = database.walletManager.findByAddress(parameters.ownerId) + + item.and(this.query.sender_public_key.equals(owner.publicKey)) + item.or(this.query.recipient_id.equals(owner.address)) + } + } + } + + applyConditions([selectQuery, countQuery]) + + const results = await this._findManyWithCount(selectQuery, countQuery, { + limit: parameters.limit, + offset: parameters.offset, + orderBy: this.__orderBy(parameters), + }) + + results.rows = await this.__mapBlocksToTransactions(results.rows) + + return results + } + + /** + * Get all transactions (LEGACY, for V1 only). + * @param {Object} params + * @return {Object} + */ + async findAllLegacy(parameters = {}) { + const selectQuery = this.query + .select(this.query.block_id, this.query.serialized) + .from(this.query) + const countQuery = this._makeEstimateQuery() + + if (parameters.senderId) { + parameters.senderPublicKey = this.__publicKeyFromSenderId( + parameters.senderId, + ) + } + + const applyConditions = queries => { + const conditions = Object.entries(this._formatConditions(parameters)) + + if (conditions.length) { + const first = conditions.shift() + + for (const item of queries) { + item.where(this.query[first[0]].equals(first[1])) + + for (const [key, value] of conditions) { + item.or(this.query[key].equals(value)) + } + } + } + } + + applyConditions([selectQuery, countQuery]) + + const results = await this._findManyWithCount(selectQuery, countQuery, { + limit: parameters.limit, + offset: parameters.offset, + orderBy: this.__orderBy(parameters), + }) + + results.rows = await this.__mapBlocksToTransactions(results.rows) + + return results + } + + /** + * Get all transactions for the given Wallet object. + * @param {Wallet} wallet + * @param {Object} parameters + * @return {Object} + */ + async findAllByWallet(wallet, parameters = {}) { + const selectQuery = this.query + .select(this.query.block_id, this.query.serialized) + .from(this.query) + const countQuery = this._makeEstimateQuery() + + const applyConditions = queries => { + for (const item of queries) { + item + .where(this.query.sender_public_key.equals(wallet.publicKey)) + .or(this.query.recipient_id.equals(wallet.address)) + } + } + + applyConditions([selectQuery, countQuery]) + + const results = await this._findManyWithCount(selectQuery, countQuery, { + limit: parameters.limit, + offset: parameters.offset, + orderBy: this.__orderBy(parameters), + }) + + results.rows = await this.__mapBlocksToTransactions(results.rows) + + return results + } + + /** + * Get all transactions for the given sender public key. + * @param {String} senderPublicKey + * @param {Object} parameters + * @return {Object} + */ + async findAllBySender(senderPublicKey, parameters = {}) { + return this.findAll({ ...{ senderPublicKey }, ...parameters }) + } + + /** + * Get all transactions for the given recipient address. + * @param {String} recipientId + * @param {Object} parameters + * @return {Object} + */ + async findAllByRecipient(recipientId, parameters = {}) { + return this.findAll({ ...{ recipientId }, ...parameters }) + } + + /** + * Get all vote transactions for the given sender public key. + * TODO rename to findAllVotesBySender or not? + * @param {String} senderPublicKey + * @param {Object} parameters + * @return {Object} + */ + async allVotesBySender(senderPublicKey, parameters = {}) { + return this.findAll({ + ...{ senderPublicKey, type: TRANSACTION_TYPES.VOTE }, + ...parameters, + }) + } + + /** + * Get all transactions for the given block. + * @param {Number} blockId + * @param {Object} parameters + * @return {Object} + */ + async findAllByBlock(blockId, parameters = {}) { + return this.findAll({ ...{ blockId }, ...parameters }) + } + + /** + * Get all transactions for the given type. + * @param {Number} type + * @param {Object} parameters + * @return {Object} + */ + async findAllByType(type, parameters = {}) { + return this.findAll({ ...{ type }, ...parameters }) + } + + /** + * Get a transaction. + * @param {Number} id + * @return {Object} + */ + async findById(id) { + const query = this.query + .select(this.query.block_id, this.query.serialized) + .from(this.query) + .where(this.query.id.equals(id)) + + const transaction = await this._find(query) + + return this.__mapBlocksToTransactions(transaction) + } + + /** + * Get a transactions for the given type and id. + * @param {Number} type + * @param {Number} id + * @return {Object} + */ + async findByTypeAndId(type, id) { + const query = this.query + .select(this.query.block_id, this.query.serialized) + .from(this.query) + .where(this.query.id.equals(id).and(this.query.type.equals(type))) + + const transaction = await this._find(query) + + return this.__mapBlocksToTransactions(transaction) + } + + /** + * Get transactions for the given ids. + * @param {Array} ids + * @return {Object} + */ + async findByIds(ids) { + const query = this.query + .select(this.query.block_id, this.query.serialized) + .from(this.query) + .where(this.query.id.in(ids)) + + return this._findMany(query) + } + + /** + * Get all transactions that have a vendor field. + * @return {Object} + */ + async findWithVendorField() { + const query = this.query + .select(this.query.block_id, this.query.serialized) + .from(this.query) + .where(this.query.vendor_field_hex.isNotNull()) + + const transactions = await this._findMany(query) + + return this.__mapBlocksToTransactions(transactions) + } + + /** + * Calculates min, max and average fee statistics based on transactions table + * @return {Object} + */ + async getFeeStatistics() { + const query = this.query + .select( + this.query.type, + this.query.fee.min('minFee'), + this.query.fee.max('maxFee'), + this.query.fee.avg('avgFee'), + this.query.timestamp.max('timestamp'), + ) + .from(this.query) + .where( + this.query.timestamp.gte(slots.getTime(dayjs().subtract(30, 'days'))), + ) + .group(this.query.type) + .order('"timestamp" DESC') + + return this._findMany(query) + } + + /** + * Search all transactions. + * + * @param {Object} params + * @return {Object} + */ + async search(parameters) { + const selectQuery = this.query.select().from(this.query) + const countQuery = this._makeEstimateQuery() + + if (parameters.senderId) { + const senderPublicKey = this.__publicKeyFromSenderId(parameters.senderId) + + if (senderPublicKey) { + parameters.senderPublicKey = senderPublicKey + } + } + + const applyConditions = queries => { + const conditions = buildFilterQuery(this._formatConditions(parameters), { + exact: [ + 'id', + 'block_id', + 'type', + 'version', + 'sender_public_key', + 'recipient_id', + ], + between: ['timestamp', 'amount', 'fee'], + wildcard: ['vendor_field_hex'], + }) + + if (conditions.length) { + const first = conditions.shift() + + for (const item of queries) { + item.where(this.query[first.column][first.method](first.value)) + + for (const condition of conditions) { + item.and( + this.query[condition.column][condition.method](condition.value), + ) + } + } + } + } + + applyConditions([selectQuery, countQuery]) + + const results = await this._findManyWithCount(selectQuery, countQuery, { + limit: parameters.limit || 100, + offset: parameters.offset || 0, + orderBy: this.__orderBy(parameters), + }) + + results.rows = await this.__mapBlocksToTransactions(results.rows) + + return results + } + + getModel() { + return database.models.transaction + } + + /** + * [__mapBlocksToTransactions description] + * @param {Array|Object} data + * @return {Object} + */ + async __mapBlocksToTransactions(data) { + const blockQuery = database.models.block.query() + + // Array... + if (Array.isArray(data)) { + // 1. get heights from cache + const missingFromCache = [] + + for (let i = 0; i < data.length; i++) { + const cachedBlock = this.__getBlockCache(data[i].blockId) + + if (cachedBlock) { + data[i].block = cachedBlock + } else { + missingFromCache.push({ + index: i, + blockId: data[i].blockId, + }) + } + } + + // 2. get missing heights from database + if (missingFromCache.length) { + const query = blockQuery + .select(blockQuery.id, blockQuery.height) + .from(blockQuery) + .where(blockQuery.id.in(missingFromCache.map(d => d.blockId))) + .group(blockQuery.id) + + const blocks = await this._findMany(query) + + for (const missing of missingFromCache) { + const block = blocks.find(item => item.id === missing.blockId) + if (block) { + data[missing.index].block = block + this.__setBlockCache(block) + } + } + } + + return data + } + + // Object... + if (data) { + const cachedBlock = this.__getBlockCache(data.blockId) + + if (cachedBlock) { + data.block = cachedBlock + } else { + const query = blockQuery + .select(blockQuery.id, blockQuery.height) + .from(blockQuery) + .where(blockQuery.id.equals(data.blockId)) + + data.block = await this._find(query) + + this.__setBlockCache(data.block) + } + } + + return data + } + + /** + * Tries to retrieve the height of the block from the cache + * @param {String} blockId + * @return {Object|null} + */ + __getBlockCache(blockId) { + const height = this.cache.get(`heights:${blockId}`) + + return height ? { height, id: blockId } : null + } + + /** + * Stores the height of the block on the cache + * @param {Object} block + * @param {String} block.id + * @param {Number} block.height + */ + __setBlockCache({ id, height }) { + this.cache.set(`heights:${id}`, height) + } + + /** + * Retrieves the publicKey of the address from the WalletManager in-memory data + * @param {String} senderId + * @return {String} + */ + __publicKeyFromSenderId(senderId) { + return database.walletManager.findByAddress(senderId).publicKey + } + + __orderBy(parameters) { + return parameters.orderBy + ? parameters.orderBy.split(':').map(p => p.toLowerCase()) + : ['timestamp', 'desc'] + } +} + +module.exports = new TransactionsRepository() diff --git a/packages/core-api/lib/repositories/utils/filter-query.js b/packages/core-api/lib/repositories/utils/filter-query.js new file mode 100644 index 0000000000..0e2614354b --- /dev/null +++ b/packages/core-api/lib/repositories/utils/filter-query.js @@ -0,0 +1,79 @@ +/* eslint no-prototype-builtins: "off" */ + +/** + * Create a "where" object for a sql query. + * @param {Object} parameters + * @param {Object} filters + * @return {Object} + */ +module.exports = (parameters, filters) => { + const where = [] + + if (filters.hasOwnProperty('exact')) { + for (const elem of filters.exact) { + if (typeof parameters[elem] !== 'undefined') { + where.push({ + column: elem, + method: 'equals', + value: parameters[elem], + }) + } + } + } + + if (filters.hasOwnProperty('between')) { + for (const elem of filters.between) { + if (!parameters[elem]) { + continue + } + + if ( + !parameters[elem].hasOwnProperty('from') && + !parameters[elem].hasOwnProperty('to') + ) { + where.push({ + column: elem, + method: 'equals', + value: parameters[elem], + }) + } + + if ( + parameters[elem].hasOwnProperty('from') || + parameters[elem].hasOwnProperty('to') + ) { + where[elem] = {} + + if (parameters[elem].hasOwnProperty('from')) { + where.push({ + column: elem, + method: 'gte', + value: parameters[elem].from, + }) + } + + if (parameters[elem].hasOwnProperty('to')) { + where.push({ + column: elem, + method: 'lte', + value: parameters[elem].to, + }) + } + } + } + } + + if (filters.hasOwnProperty('wildcard')) { + for (const elem of filters.wildcard) { + if (parameters[elem]) { + where.push({ + column: elem, + method: 'like', + value: `%${parameters[elem]}%`, + }) + } + } + } + + return where +} diff --git a/packages/core-api/lib/server.js b/packages/core-api/lib/server.js index 8410289be4..81f8088683 100644 --- a/packages/core-api/lib/server.js +++ b/packages/core-api/lib/server.js @@ -1,114 +1,125 @@ -'use strict' +/* eslint no-await-in-loop: "off" */ -const Hapi = require('hapi') -const logger = require('@arkecosystem/core-container').resolvePlugin('logger') +const { + createServer, + createSecureServer, + mountServer, + plugins, +} = require('@arkecosystem/core-http-utils') /** * Create a new hapi.js server. * @param {Object} config * @return {Hapi.Server} */ -module.exports = async (config) => { - const baseConfig = { +module.exports = async config => { + const options = { host: config.host, port: config.port, routes: { cors: { - additionalHeaders: ['api-version'] + additionalHeaders: ['api-version'], }, validate: { - async failAction (request, h, err) { + async failAction(request, h, err) { throw err - } - } - } - } - - if (config.cache.enabled) { - const cacheOptions = config.cache.options - cacheOptions.engine = require(cacheOptions.engine) - baseConfig.cache = [cacheOptions] - baseConfig.routes.cache = { expiresIn: cacheOptions.expiresIn } + }, + }, + }, } - const server = new Hapi.Server(baseConfig) - - await server.register([require('vision'), require('inert'), require('lout')]) + const servers = { http: await createServer(options) } - await server.register({ - plugin: require('./plugins/whitelist'), - options: { - whitelist: config.whitelist - } - }) - - await server.register({ - plugin: require('hapi-api-version'), - options: { - validVersions: config.versions.valid, - defaultVersion: config.versions.default, - basePath: '/api/', - vendorName: 'ark-core-api' - } - }) - - await server.register({ plugin: require('./plugins/caster') }) - - await server.register({ plugin: require('./plugins/validation') }) - - await server.register({ - plugin: require('hapi-rate-limit'), - options: { - enabled: config.rateLimit.enabled, - pathLimit: false, - userLimit: config.rateLimit.limit, - userCache: { - expiresIn: config.rateLimit.expires - } - } - }) + if (config.ssl.enabled) { + servers.https = await createSecureServer(options, null, config.ssl) + } - await server.register({ - plugin: require('hapi-pagination'), - options: { - meta: { - baseUri: '' + for (const [type, server] of Object.entries(servers)) { + // TODO: enable after mainnet migration + // await server.register({ plugin: plugins.contentType }) + + await server.register({ + plugin: plugins.corsHeaders, + }) + + await server.register({ + plugin: plugins.transactionPayload, + options: { + routes: [ + { + method: 'POST', + path: '/api/v2/transactions', + }, + ], }, - query: { - limit: { - default: config.pagination.limit - } + }) + + await server.register({ + plugin: plugins.whitelist, + options: { + whitelist: config.whitelist, + name: 'Public API', }, - results: { - name: 'data' + }) + + await server.register({ + plugin: require('./plugins/set-headers'), + }) + + await server.register({ + plugin: require('hapi-api-version'), + options: config.versions, + }) + + await server.register({ + plugin: require('./plugins/endpoint-version'), + options: { validVersions: config.versions.validVersions }, + }) + + await server.register({ + plugin: require('./plugins/caster'), + }) + + await server.register({ + plugin: require('./plugins/validation'), + }) + + await server.register({ + plugin: require('hapi-rate-limit'), + options: config.rateLimit, + }) + + await server.register({ + plugin: require('hapi-pagination'), + options: { + meta: { + baseUri: '', + }, + query: { + limit: { + default: config.pagination.limit, + }, + }, + results: { + name: 'data', + }, + routes: { + include: config.pagination.include, + exclude: ['*'], + }, }, - routes: { - include: config.pagination.include, - exclude: ['*'] - } - } - }) - - await server.register({ - plugin: require('./versions/1'), - routes: { prefix: '/api/v1' } - }) + }) - await server.register({ - plugin: require('./versions/2'), - routes: { prefix: '/api/v2' }, - options: config - }) - - try { - await server.start() - - logger.info(`Public API Server running at: ${server.info.uri}`) + for (const plugin of config.plugins) { + if (typeof plugin.plugin === 'string') { + plugin.plugin = require(plugin.plugin) + } - return server - } catch (error) { - logger.error(error.stack) + await server.register(plugin) + } - process.exit(1) + await mountServer(`Public ${type} API`, server) } + + return servers } diff --git a/packages/core-api/lib/utils/delegate-calculator.js b/packages/core-api/lib/utils/delegate-calculator.js deleted file mode 100644 index fb9efa81cf..0000000000 --- a/packages/core-api/lib/utils/delegate-calculator.js +++ /dev/null @@ -1,31 +0,0 @@ -'use strict' - -const container = require('@arkecosystem/core-container') -const blockchain = container.resolvePlugin('blockchain') -const config = container.resolvePlugin('config') - -/** - * Calculate the approval for the given delegate. - * @param {Delegate} delegate - * @return {Number} - */ -exports.calculateApproval = (delegate) => { - const lastBlock = blockchain.getLastBlock() - const constants = config.getConstants(lastBlock.data.height) - const totalSupply = config.genesisBlock.totalAmount + (lastBlock.data.height - constants.height) * constants.reward - - return +((delegate.votebalance / totalSupply) * 100).toFixed(2) -} - -/** - * Calculate the productivity of the given delegate. - * @param {Delegate} delegate - * @return {Number} - */ -exports.calculateProductivity = (delegate) => { - if (!delegate.missedBlocks && !delegate.producedBlocks) { - return 0 - } - - return +(100 - (delegate.missedBlocks / ((delegate.producedBlocks + delegate.missedBlocks) / 100))).toFixed(2) -} diff --git a/packages/core-api/lib/utils/generate-cache-key.js b/packages/core-api/lib/utils/generate-cache-key.js new file mode 100644 index 0000000000..9c72414078 --- /dev/null +++ b/packages/core-api/lib/utils/generate-cache-key.js @@ -0,0 +1,5 @@ +module.exports = value => + require('crypto') + .createHash('sha256') + .update(JSON.stringify(value)) + .digest('hex') diff --git a/packages/core-api/lib/utils/transformer.js b/packages/core-api/lib/utils/transformer.js index d6212ba88c..af05e063c4 100644 --- a/packages/core-api/lib/utils/transformer.js +++ b/packages/core-api/lib/utils/transformer.js @@ -1,4 +1,4 @@ -'use strict' +/* eslint max-len: "off" */ const path = require('path') @@ -9,9 +9,11 @@ const path = require('path') * @param {Object} transformer * @return {Object} */ -const transformResource = (request, data, transformer) => { - return require(path.resolve(__dirname, `../versions/${request.pre.apiVersion}/transformers/${transformer}`))(data) -} +const transformResource = (request, data, transformer) => + require(path.resolve( + __dirname, + `../versions/${request.pre.apiVersion}/transformers/${transformer}`, + ))(data) /** * Transform the given data to a collection. @@ -20,14 +22,13 @@ const transformResource = (request, data, transformer) => { * @param {Object} transformer * @return {Object} */ -const transformCollection = (request, data, transformer) => { - return data.map(d => transformResource(request, d, transformer)) -} +const transformCollection = (request, data, transformer) => + data.map(d => transformResource(request, d, transformer)) /** * @type {Object} */ module.exports = { transformResource, - transformCollection + transformCollection, } diff --git a/packages/core-api/lib/versions/1/handlers/accounts.js b/packages/core-api/lib/versions/1/handlers/accounts.js index e96ebcb705..e3806f558d 100644 --- a/packages/core-api/lib/versions/1/handlers/accounts.js +++ b/packages/core-api/lib/versions/1/handlers/accounts.js @@ -1,9 +1,8 @@ -'use strict' +const app = require('@arkecosystem/core-container') -const container = require('@arkecosystem/core-container') -const config = container.resolvePlugin('config') -const database = container.resolvePlugin('database') -const blockchain = container.resolvePlugin('blockchain') +const config = app.resolvePlugin('config') +const database = app.resolvePlugin('database') +const blockchain = app.resolvePlugin('blockchain') const utils = require('../utils') const schema = require('../schemas/accounts') @@ -17,15 +16,11 @@ exports.index = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const { rows } = await database.wallets.findAll({ - ...request.query, ...utils.paginate(request) - }) + async handler(request, h) { + const data = await request.server.methods.v1.accounts.index(request) - return utils.respondWith({ - accounts: utils.toCollection(request, rows, 'account') - }) - } + return utils.respondWithCache(data, h) + }, } /** @@ -37,24 +32,18 @@ exports.show = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const account = await database.wallets.findById(request.query.address) + async handler(request, h) { + const data = await request.server.methods.v1.accounts.show(request) - if (!account) { - return utils.respondWith('Account not found', true) - } - - return utils.respondWith({ - account: utils.toResource(request, account, 'account') - }) + return utils.respondWithCache(data, h) }, config: { plugins: { 'hapi-ajv': { - querySchema: schema.getAccount - } - } - } + querySchema: schema.getAccount, + }, + }, + }, } /** @@ -66,25 +55,18 @@ exports.balance = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const account = await database.wallets.findById(request.query.address) + async handler(request, h) { + const data = await request.server.methods.v1.accounts.balance(request) - if (!account) { - return utils.respondWith({balance: '0', unconfirmedBalance: '0'}) - } - - return utils.respondWith({ - balance: account ? `${account.balance}` : '0', - unconfirmedBalance: account ? `${account.balance}` : '0' - }) + return utils.respondWithCache(data, h) }, config: { plugins: { 'hapi-ajv': { - querySchema: schema.getBalance - } - } - } + querySchema: schema.getBalance, + }, + }, + }, } /** @@ -96,22 +78,18 @@ exports.publicKey = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const account = await database.wallets.findById(request.query.address) + async handler(request, h) { + const data = await request.server.methods.v1.accounts.publicKey(request) - if (!account) { - return utils.respondWith('Account not found', true) - } - - return utils.respondWith({ publicKey: account.publicKey }) + return utils.respondWithCache(data, h) }, config: { plugins: { 'hapi-ajv': { - querySchema: schema.getPublicKey - } - } - } + querySchema: schema.getPublicKey, + }, + }, + }, } /** @@ -123,11 +101,12 @@ exports.fee = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - handler (request, h) { + handler(request, h) { return utils.respondWith({ - fee: config.getConstants(blockchain.getLastBlock().data.height).fees.delegateRegistration + fee: config.getConstants(blockchain.getLastBlock().data.height).fees + .staticFees.delegateRegistration, }) - } + }, } /** @@ -139,30 +118,33 @@ exports.delegates = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - let account = await database.wallets.findById(request.query.address) + async handler(request, h) { + const account = await database.wallets.findById(request.query.address) if (!account) { return utils.respondWith('Address not found.', true) } if (!account.vote) { - return utils.respondWith(`Address ${request.query.address} hasn't voted yet.`, true) + return utils.respondWith( + `Address ${request.query.address} hasn't voted yet.`, + true, + ) } const delegate = await database.delegates.findById(account.vote) return utils.respondWith({ - delegates: [utils.toResource(request, delegate, 'delegate')] + delegates: [utils.toResource(request, delegate, 'delegate')], }) }, config: { plugins: { 'hapi-ajv': { - querySchema: schema.getDelegates - } - } - } + querySchema: schema.getDelegates, + }, + }, + }, } /** @@ -174,13 +156,13 @@ exports.top = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { + async handler(request, h) { let accounts = database.wallets.top(utils.paginate(request)) accounts = accounts.rows.map(account => ({ address: account.address, - balance: account.balance + '', - publicKey: account.publicKey + balance: `${account.balance}`, + publicKey: account.publicKey, })) return utils.respondWith({ accounts }) @@ -188,10 +170,10 @@ exports.top = { config: { plugins: { 'hapi-ajv': { - querySchema: schema.top - } - } - } + querySchema: schema.top, + }, + }, + }, } /** @@ -203,9 +185,9 @@ exports.count = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { + async handler(request, h) { const { count } = await database.wallets.findAll() return utils.respondWith({ count }) - } + }, } diff --git a/packages/core-api/lib/versions/1/handlers/blocks.js b/packages/core-api/lib/versions/1/handlers/blocks.js index beafec7e20..0b5c69cfa9 100644 --- a/packages/core-api/lib/versions/1/handlers/blocks.js +++ b/packages/core-api/lib/versions/1/handlers/blocks.js @@ -1,9 +1,8 @@ -'use strict' +const app = require('@arkecosystem/core-container') +const { bignumify } = require('@arkecosystem/core-utils') -const container = require('@arkecosystem/core-container') -const config = container.resolvePlugin('config') -const database = container.resolvePlugin('database') -const blockchain = container.resolvePlugin('blockchain') +const config = app.resolvePlugin('config') +const blockchain = app.resolvePlugin('blockchain') const utils = require('../utils') const schema = require('../schemas/blocks') @@ -17,27 +16,18 @@ exports.index = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const { count, rows } = await database.blocks.findAll({ - ...request.query, ...utils.paginate(request) - }) - - if (!rows) { - return utils.respondWith('No blocks found', true) - } + async handler(request, h) { + const data = await request.server.methods.v1.blocks.index(request) - return utils.respondWith({ - blocks: utils.toCollection(request, rows, 'block'), - count - }) + return utils.respondWithCache(data, h) }, config: { plugins: { 'hapi-ajv': { - querySchema: schema.getBlocks - } - } - } + querySchema: schema.getBlocks, + }, + }, + }, } /** @@ -49,22 +39,18 @@ exports.show = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const block = await database.blocks.findById(request.query.id) - - if (!block) { - return utils.respondWith(`Block with id ${request.query.id} not found`, true) - } + async handler(request, h) { + const data = await request.server.methods.v1.blocks.show(request) - return utils.respondWith({ block: utils.toResource(request, block, 'block') }) + return utils.respondWithCache(data, h) }, config: { plugins: { 'hapi-ajv': { - querySchema: schema.getBlock - } - } - } + querySchema: schema.getBlock, + }, + }, + }, } /** @@ -76,11 +62,11 @@ exports.epoch = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - handler (request, h) { + handler(request, h) { return utils.respondWith({ - epoch: config.getConstants(blockchain.getLastBlock().data.height).epoch + epoch: config.getConstants(blockchain.getLastBlock().data.height).epoch, }) - } + }, } /** @@ -92,11 +78,11 @@ exports.height = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - handler (request, h) { + handler(request, h) { const block = blockchain.getLastBlock() return utils.respondWith({ height: block.data.height, id: block.data.id }) - } + }, } /** @@ -108,9 +94,9 @@ exports.nethash = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - handler (request, h) { + handler(request, h) { return utils.respondWith({ nethash: config.network.nethash }) - } + }, } /** @@ -122,11 +108,12 @@ exports.fee = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - handler (request, h) { + handler(request, h) { return utils.respondWith({ - fee: config.getConstants(blockchain.getLastBlock().data.height).fees.transfer + fee: config.getConstants(blockchain.getLastBlock().data.height).fees + .staticFees.transfer, }) - } + }, } /** @@ -138,8 +125,9 @@ exports.fees = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - handler (request, h) { + handler(request, h) { const fees = config.getConstants(blockchain.getLastBlock().data.height).fees + .staticFees return utils.respondWith({ fees: { @@ -147,10 +135,10 @@ exports.fees = { vote: fees.vote, secondsignature: fees.secondSignature, delegate: fees.delegateRegistration, - multisignature: fees.multiSignature - } + multisignature: fees.multiSignature, + }, }) - } + }, } /** @@ -162,11 +150,11 @@ exports.milestone = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - handler (request, h) { + handler(request, h) { return utils.respondWith({ - milestone: ~~(blockchain.getLastBlock().data.height / 3000000) + milestone: Math.floor(blockchain.getLastBlock().data.height / 3000000), }) - } + }, } /** @@ -178,11 +166,11 @@ exports.reward = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - handler (request, h) { + handler(request, h) { return utils.respondWith({ - reward: config.getConstants(blockchain.getLastBlock().data.height).reward + reward: config.getConstants(blockchain.getLastBlock().data.height).reward, }) - } + }, } /** @@ -194,14 +182,19 @@ exports.supply = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - handler (request, h) { + handler(request, h) { const lastBlock = blockchain.getLastBlock() const constants = config.getConstants(lastBlock.data.height) + const rewards = bignumify(constants.reward).times( + lastBlock.data.height - constants.height, + ) return utils.respondWith({ - supply: config.genesisBlock.totalAmount + (lastBlock.data.height - constants.height) * constants.reward + supply: +bignumify(config.genesisBlock.totalAmount) + .plus(rewards) + .toFixed(), }) - } + }, } /** @@ -213,18 +206,23 @@ exports.status = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - handler (request, h) { + handler(request, h) { const lastBlock = blockchain.getLastBlock() const constants = config.getConstants(lastBlock.data.height) + const rewards = bignumify(constants.reward).times( + lastBlock.data.height - constants.height, + ) return utils.respondWith({ epoch: constants.epoch, height: lastBlock.data.height, - fee: constants.fees.transfer, - milestone: ~~(lastBlock.data.height / 3000000), + fee: constants.fees.staticFees.transfer, + milestone: Math.floor(lastBlock.data.height / 3000000), nethash: config.network.nethash, reward: constants.reward, - supply: config.genesisBlock.totalAmount + (lastBlock.data.height - constants.height) * constants.reward + supply: +bignumify(config.genesisBlock.totalAmount) + .plus(rewards) + .toFixed(), }) - } + }, } diff --git a/packages/core-api/lib/versions/1/handlers/delegates.js b/packages/core-api/lib/versions/1/handlers/delegates.js index 7809ebf9f5..87cc25d3ee 100644 --- a/packages/core-api/lib/versions/1/handlers/delegates.js +++ b/packages/core-api/lib/versions/1/handlers/delegates.js @@ -1,9 +1,8 @@ -'use strict' +const app = require('@arkecosystem/core-container') -const container = require('@arkecosystem/core-container') -const config = container.resolvePlugin('config') -const database = container.resolvePlugin('database') -const blockchain = container.resolvePlugin('blockchain') +const config = app.resolvePlugin('config') +const database = app.resolvePlugin('database') +const blockchain = app.resolvePlugin('blockchain') const { slots } = require('@arkecosystem/crypto') const utils = require('../utils') @@ -18,21 +17,18 @@ exports.index = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const { count, rows } = await database.delegates.findAll(request.query) + async handler(request, h) { + const data = await request.server.methods.v1.delegates.index(request) - return utils.respondWith({ - delegates: utils.toCollection(request, rows, 'delegate'), - totalCount: count - }) + return utils.respondWithCache(data, h) }, config: { plugins: { 'hapi-ajv': { - querySchema: schema.getDelegates - } - } - } + querySchema: schema.getDelegates, + }, + }, + }, } /** @@ -44,28 +40,18 @@ exports.show = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - if (!request.query.publicKey && !request.query.username) { - return utils.respondWith('Delegate not found', true) - } - - const delegate = await database.delegates.findById(request.query.publicKey || request.query.username) - - if (!delegate) { - return utils.respondWith('Delegate not found', true) - } + async handler(request, h) { + const data = await request.server.methods.v1.delegates.show(request) - return utils.respondWith({ - delegate: utils.toResource(request, delegate, 'delegate') - }) + return utils.respondWithCache(data, h) }, config: { plugins: { 'hapi-ajv': { - querySchema: schema.getDelegate - } - } - } + querySchema: schema.getDelegate, + }, + }, + }, } /** @@ -77,11 +63,11 @@ exports.count = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const { count } = await database.delegates.findAll() + async handler(request, h) { + const data = await request.server.methods.v1.delegates.count(request) - return utils.respondWith({ count }) - } + return utils.respondWithCache(data, h) + }, } /** @@ -93,23 +79,18 @@ exports.search = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const query = { - username: request.query.q - } - const { rows } = await database.delegates.search({...query, ...utils.paginate(request)}) + async handler(request, h) { + const data = await request.server.methods.v1.delegates.search(request) - return utils.respondWith({ - delegates: utils.toCollection(request, rows, 'delegate') - }) + return utils.respondWithCache(data, h) }, config: { plugins: { 'hapi-ajv': { - querySchema: schema.search - } - } - } + querySchema: schema.search, + }, + }, + }, } /** @@ -121,21 +102,18 @@ exports.voters = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const delegate = await database.delegates.findById(request.query.publicKey) - const accounts = await database.wallets.findAllByVote(delegate.publicKey) + async handler(request, h) { + const data = await request.server.methods.v1.delegates.voters(request) - return utils.respondWith({ - accounts: utils.toCollection(request, accounts.rows, 'voter') - }) + return utils.respondWithCache(data, h) }, config: { plugins: { 'hapi-ajv': { - querySchema: schema.getVoters - } - } - } + querySchema: schema.getVoters, + }, + }, + }, } /** @@ -147,11 +125,12 @@ exports.fee = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - handler (request, h) { + handler(request, h) { return utils.respondWith({ - fee: config.getConstants(blockchain.getLastBlock().data.height).fees.delegateRegistration + fee: config.getConstants(blockchain.getLastBlock().data.height).fees + .staticFees.delegateRegistration, }) - } + }, } /** @@ -163,22 +142,24 @@ exports.forged = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const wallet = database.walletManager.getWalletByPublicKey(request.query.generatorPublicKey) + async handler(request, h) { + const wallet = database.walletManager.findByPublicKey( + request.query.generatorPublicKey, + ) return utils.respondWith({ fees: Number(wallet.forgedFees), rewards: Number(wallet.forgedRewards), - forged: Number(wallet.forgedFees) + Number(wallet.forgedRewards) + forged: Number(wallet.forgedFees) + Number(wallet.forgedRewards), }) }, config: { plugins: { 'hapi-ajv': { - querySchema: schema.getForgedByAccount - } - } - } + querySchema: schema.getForgedByAccount, + }, + }, + }, } /** @@ -190,14 +171,16 @@ exports.nextForgers = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { + async handler(request, h) { const lastBlock = blockchain.getLastBlock() const limit = request.query.limit || 10 const delegatesCount = config.getConstants(lastBlock).activeDelegates const currentSlot = slots.getSlotNumber(lastBlock.data.timestamp) - let activeDelegates = await database.getActiveDelegates(lastBlock.data.height) + let activeDelegates = await database.getActiveDelegates( + lastBlock.data.height, + ) activeDelegates = activeDelegates.map(delegate => delegate.publicKey) const nextForgers = [] @@ -211,8 +194,8 @@ exports.nextForgers = { return utils.respondWith({ currentBlock: lastBlock.data.height, - currentSlot: currentSlot, - delegates: nextForgers + currentSlot, + delegates: nextForgers, }) - } + }, } diff --git a/packages/core-api/lib/versions/1/handlers/loader.js b/packages/core-api/lib/versions/1/handlers/loader.js index f7f7679247..693991de95 100644 --- a/packages/core-api/lib/versions/1/handlers/loader.js +++ b/packages/core-api/lib/versions/1/handlers/loader.js @@ -1,9 +1,9 @@ -'use strict' +const app = require('@arkecosystem/core-container') -const container = require('@arkecosystem/core-container') -const config = container.resolvePlugin('config') -const blockchain = container.resolvePlugin('blockchain') +const config = app.resolvePlugin('config') +const blockchain = app.resolvePlugin('blockchain') const utils = require('../utils') +const { transactions } = require('../../../repositories') /** * @type {Object} @@ -14,13 +14,18 @@ exports.status = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - handler (request, h) { + handler(request, h) { + const lastBlock = blockchain.getLastBlock() + return utils.respondWith({ loaded: blockchain.isSynced(), - now: blockchain.state.lastBlock ? blockchain.getLastBlock().data.height : 0, - blocksCount: blockchain.p2p.getNetworkHeight() - blockchain.getLastBlock().data.height + now: lastBlock ? lastBlock.data.height : 0, + blocksCount: + blockchain.p2p.getNetworkHeight() - lastBlock + ? lastBlock.data.height + : 0, }) - } + }, } /** @@ -32,14 +37,16 @@ exports.syncing = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - handler (request, h) { + handler(request, h) { + const lastBlock = blockchain.getLastBlock() + return utils.respondWith({ syncing: !blockchain.isSynced(), - blocks: blockchain.p2p.getNetworkHeight() - blockchain.getLastBlock().data.height, - height: blockchain.getLastBlock().data.height, - id: blockchain.getLastBlock().data.id + blocks: blockchain.p2p.getNetworkHeight() - lastBlock.data.height, + height: lastBlock.data.height, + id: lastBlock.data.id, }) - } + }, } /** @@ -51,8 +58,9 @@ exports.autoconfigure = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const feeStatisticsData = await blockchain.database.transactions.getFeeStatistics() + async handler(request, h) { + const feeStatisticsData = await transactions.getFeeStatistics() + return utils.respondWith({ network: { nethash: config.network.nethash, @@ -61,8 +69,12 @@ exports.autoconfigure = { explorer: config.network.client.explorer, version: config.network.pubKeyHash, ports: utils.toResource(request, config, 'ports'), - feeStatistics: utils.toCollection(request, feeStatisticsData, 'fee-statistics') - } + feeStatistics: utils.toCollection( + request, + feeStatisticsData, + 'fee-statistics', + ), + }, }) - } + }, } diff --git a/packages/core-api/lib/versions/1/handlers/peers.js b/packages/core-api/lib/versions/1/handlers/peers.js index 93d103b8b9..27c95c6378 100644 --- a/packages/core-api/lib/versions/1/handlers/peers.js +++ b/packages/core-api/lib/versions/1/handlers/peers.js @@ -1,7 +1,6 @@ -'use strict' +const app = require('@arkecosystem/core-container') -const container = require('@arkecosystem/core-container') -const p2p = container.resolvePlugin('p2p') +const p2p = app.resolvePlugin('p2p') const utils = require('../utils') const schema = require('../schemas/peers') @@ -15,40 +14,59 @@ exports.index = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { + async handler(request, h) { const allPeers = await p2p.getPeers() if (!allPeers) { return utils.respondWith('No peers found', true) } - let peers = allPeers.sort((a, b) => a.delay - b.delay) - peers = request.query.os ? allPeers.filter(peer => peer.os === request.query.os) : peers - peers = request.query.status ? allPeers.filter(peer => peer.status === request.query.status) : peers - peers = request.query.port ? allPeers.filter(peer => peer.port === request.query.port) : peers - peers = request.query.version ? allPeers.filter(peer => peer.version === request.query.version) : peers - peers = peers.slice(0, (request.query.limit || 100)) + let peers = allPeers + .map(peer => { + // just use 'OK' status for API instead of p2p http status codes + peer.status = peer.status === 200 ? 'OK' : peer.status + return peer + }) + .sort((a, b) => a.delay - b.delay) + peers = request.query.os + ? allPeers.filter(peer => peer.os === request.query.os) + : peers + peers = request.query.status + ? allPeers.filter(peer => peer.status === request.query.status) + : peers + peers = request.query.port + ? allPeers.filter(peer => peer.port === request.query.port) + : peers + peers = request.query.version + ? allPeers.filter(peer => peer.version === request.query.version) + : peers + peers = peers.slice(0, request.query.limit || 100) if (request.query.orderBy) { const order = request.query.orderBy.split(':') if (['port', 'status', 'os', 'version'].includes(order[0])) { - peers = order[1].toUpperCase() === 'ASC' - ? peers.sort((a, b) => a[order[0]] - b[order[0]]) - : peers.sort((a, b) => a[order[0]] + b[order[0]]) + peers = + order[1].toUpperCase() === 'ASC' + ? peers.sort((a, b) => a[order[0]] - b[order[0]]) + : peers.sort((a, b) => a[order[0]] + b[order[0]]) } } return utils.respondWith({ - peers: utils.toCollection(request, peers.map(peer => peer.toBroadcastInfo()), 'peer') + peers: utils.toCollection( + request, + peers.map(peer => peer.toBroadcastInfo()), + 'peer', + ), }) }, config: { plugins: { 'hapi-ajv': { - querySchema: schema.getPeers - } - } - } + querySchema: schema.getPeers, + }, + }, + }, } /** @@ -60,30 +78,36 @@ exports.show = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { + async handler(request, h) { const peers = await p2p.getPeers() if (!peers) { return utils.respondWith('No peers found', true) } - const peer = peers.find(elem => { - return elem.ip === request.query.ip && elem.port === +request.query.port - }) + const peer = peers.find( + elem => + elem.ip === request.query.ip && +elem.port === +request.query.port, + ) if (!peer) { - return utils.respondWith(`Peer ${request.query.ip}:${request.query.port} not found`, true) + return utils.respondWith( + `Peer ${request.query.ip}:${request.query.port} not found`, + true, + ) } - return utils.respondWith({ peer: utils.toResource(request, peer.toBroadcastInfo(), 'peer') }) + return utils.respondWith({ + peer: utils.toResource(request, peer.toBroadcastInfo(), 'peer'), + }) }, config: { plugins: { 'hapi-ajv': { - querySchema: schema.getPeer - } - } - } + querySchema: schema.getPeer, + }, + }, + }, } /** @@ -95,9 +119,9 @@ exports.version = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - handler (request, h) { + handler(request, h) { return utils.respondWith({ - version: container.resolveOptions('blockchain').version + version: app.getVersion(), }) - } + }, } diff --git a/packages/core-api/lib/versions/1/handlers/signatures.js b/packages/core-api/lib/versions/1/handlers/signatures.js index 4a88237875..5a32cea6b0 100644 --- a/packages/core-api/lib/versions/1/handlers/signatures.js +++ b/packages/core-api/lib/versions/1/handlers/signatures.js @@ -1,8 +1,7 @@ -'use strict' +const app = require('@arkecosystem/core-container') -const container = require('@arkecosystem/core-container') -const config = container.resolvePlugin('config') -const blockchain = container.resolvePlugin('blockchain') +const config = app.resolvePlugin('config') +const blockchain = app.resolvePlugin('blockchain') const utils = require('../utils') @@ -15,9 +14,10 @@ exports.fee = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - handler (request, h) { + handler(request, h) { return utils.respondWith({ - fee: config.getConstants(blockchain.getLastBlock().data.height).fees.secondSignature + fee: config.getConstants(blockchain.getLastBlock().data.height).fees + .staticFees.secondSignature, }) - } + }, } diff --git a/packages/core-api/lib/versions/1/handlers/transactions.js b/packages/core-api/lib/versions/1/handlers/transactions.js index 056469ad0f..9ac43c1d87 100644 --- a/packages/core-api/lib/versions/1/handlers/transactions.js +++ b/packages/core-api/lib/versions/1/handlers/transactions.js @@ -1,8 +1,6 @@ -'use strict' +const app = require('@arkecosystem/core-container') -const container = require('@arkecosystem/core-container') -const database = container.resolvePlugin('database') -const transactionPool = container.resolvePlugin('transactionPool') +const transactionPool = app.resolvePlugin('transactionPool') const utils = require('../utils') const schema = require('../schemas/transactions') @@ -16,27 +14,18 @@ exports.index = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const { count, rows } = await database.transactions.findAllLegacy({ - ...request.query, ...utils.paginate(request) - }) - - if (!rows) { - return utils.respondWith('No transactions found', true) - } + async handler(request, h) { + const data = await request.server.methods.v1.transactions.index(request) - return utils.respondWith({ - transactions: utils.toCollection(request, rows, 'transaction'), - count - }) + return utils.respondWithCache(data, h) }, config: { plugins: { 'hapi-ajv': { - querySchema: schema.getTransactions - } - } - } + querySchema: schema.getTransactions, + }, + }, + }, } /** @@ -48,24 +37,18 @@ exports.show = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const result = await database.transactions.findById(request.query.id) + async handler(request, h) { + const data = await request.server.methods.v1.transactions.show(request) - if (!result) { - return utils.respondWith('No transactions found', true) - } - - return utils.respondWith({ - transaction: utils.toResource(request, result, 'transaction') - }) + return utils.respondWithCache(data, h) }, config: { plugins: { 'hapi-ajv': { - querySchema: schema.getTransaction - } - } - } + querySchema: schema.getTransaction, + }, + }, + }, } /** @@ -77,16 +60,21 @@ exports.unconfirmed = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { + handler(request, h) { const pagination = utils.paginate(request) - let transactions = await transactionPool.getTransactions(pagination.offset, pagination.limit) - transactions = transactions.map(transaction => ({ serialized: transaction })) + let transactions = transactionPool.getTransactions( + pagination.offset, + pagination.limit, + ) + transactions = transactions.map(transaction => ({ + serialized: transaction, + })) return utils.respondWith({ - transactions: utils.toCollection(request, transactions, 'transaction') + transactions: utils.toCollection(request, transactions, 'transaction'), }) - } + }, } /** @@ -98,17 +86,21 @@ exports.showUnconfirmed = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - let transaction = await transactionPool.getTransaction(request.query.id) + handler(request, h) { + const transaction = transactionPool.getTransaction(request.query.id) if (!transaction) { return utils.respondWith('Transaction not found', true) } return utils.respondWith({ - transaction: utils.toResource(request, { - serialized: transaction.serialized.toString('hex') - }, 'transaction') + transaction: utils.toResource( + request, + { + serialized: transaction.serialized, + }, + 'transaction', + ), }) - } + }, } diff --git a/packages/core-api/lib/versions/1/index.js b/packages/core-api/lib/versions/1/index.js index 220b79fbae..45ef7237a5 100644 --- a/packages/core-api/lib/versions/1/index.js +++ b/packages/core-api/lib/versions/1/index.js @@ -1,5 +1,3 @@ -'use strict' - const blocks = require('./handlers/blocks') const delegates = require('./handlers/delegates') const loader = require('./handlers/loader') @@ -8,6 +6,11 @@ const signatures = require('./handlers/signatures') const transactions = require('./handlers/transactions') const accounts = require('./handlers/accounts') +const registerAccountMethods = require('./methods/accounts') +const registerBlockMethods = require('./methods/blocks') +const registerDelegateMethods = require('./methods/delegates') +const registerTransactionMethods = require('./methods/transactions') + /** * Register the v1 routes. * @param {Hapi.Server} server @@ -15,15 +18,18 @@ const accounts = require('./handlers/accounts') * @return {void} */ const register = async (server, options) => { + registerAccountMethods(server) + registerBlockMethods(server) + registerDelegateMethods(server) + registerTransactionMethods(server) + server.route([ { method: 'GET', path: '/accounts/getAllAccounts', ...accounts.index }, { method: 'GET', path: '/accounts', ...accounts.show }, - { method: 'GET', path: '/accounts/', ...accounts.show }, // v1 inconsistency { method: 'GET', path: '/accounts/getBalance', ...accounts.balance }, { method: 'GET', path: '/accounts/getPublicKey', ...accounts.publicKey }, { method: 'GET', path: '/accounts/delegates/fee', ...accounts.fee }, { method: 'GET', path: '/accounts/delegates', ...accounts.delegates }, - { method: 'GET', path: '/accounts/delegates/', ...accounts.delegates }, // v1 inconsistency { method: 'GET', path: '/accounts/top', ...accounts.top }, { method: 'GET', path: '/accounts/count', ...accounts.count }, @@ -43,13 +49,20 @@ const register = async (server, options) => { { method: 'GET', path: '/delegates', ...delegates.index }, { method: 'GET', path: '/delegates/get', ...delegates.show }, - { method: 'GET', path: '/delegates/get/', ...delegates.show }, // v1 inconsistency { method: 'GET', path: '/delegates/count', ...delegates.count }, { method: 'GET', path: '/delegates/search', ...delegates.search }, { method: 'GET', path: '/delegates/voters', ...delegates.voters }, { method: 'GET', path: '/delegates/fee', ...delegates.fee }, - { method: 'GET', path: '/delegates/forging/getForgedByAccount', ...delegates.forged }, - { method: 'GET', path: '/delegates/getNextForgers', ...delegates.nextForgers }, + { + method: 'GET', + path: '/delegates/forging/getForgedByAccount', + ...delegates.forged, + }, + { + method: 'GET', + path: '/delegates/getNextForgers', + ...delegates.nextForgers, + }, { method: 'GET', path: '/loader/status', ...loader.status }, { method: 'GET', path: '/loader/status/sync', ...loader.syncing }, @@ -57,16 +70,22 @@ const register = async (server, options) => { { method: 'GET', path: '/peers', ...peers.index }, { method: 'GET', path: '/peers/get', ...peers.show }, - { method: 'GET', path: '/peers/get/', ...peers.show }, // v1 inconsistency { method: 'GET', path: '/peers/version', ...peers.version }, { method: 'GET', path: '/signatures/fee', ...signatures.fee }, { method: 'GET', path: '/transactions', ...transactions.index }, { method: 'GET', path: '/transactions/get', ...transactions.show }, - { method: 'GET', path: '/transactions/get/', ...transactions.show }, // v1 inconsistency - { method: 'GET', path: '/transactions/unconfirmed', ...transactions.unconfirmed }, - { method: 'GET', path: '/transactions/unconfirmed/get', ...transactions.showUnconfirmed } + { + method: 'GET', + path: '/transactions/unconfirmed', + ...transactions.unconfirmed, + }, + { + method: 'GET', + path: '/transactions/unconfirmed/get', + ...transactions.showUnconfirmed, + }, ]) } @@ -75,7 +94,7 @@ const register = async (server, options) => { * @type {Object} */ exports.plugin = { - name: 'ARK Public API - v1', + name: 'Ark Public API - v1', version: '0.1.0', - register + register, } diff --git a/packages/core-api/lib/versions/1/methods/accounts.js b/packages/core-api/lib/versions/1/methods/accounts.js new file mode 100644 index 0000000000..74aa8ea00b --- /dev/null +++ b/packages/core-api/lib/versions/1/methods/accounts.js @@ -0,0 +1,96 @@ +const app = require('@arkecosystem/core-container') +const generateCacheKey = require('../../../utils/generate-cache-key') +const utils = require('../utils') + +const database = app.resolvePlugin('database') + +const index = async request => { + const { rows } = await database.wallets.findAll({ + ...request.query, + ...utils.paginate(request), + }) + + return utils.respondWith({ + accounts: utils.toCollection(request, rows, 'account'), + }) +} + +const show = async request => { + const account = await database.wallets.findById(request.query.address) + + if (!account) { + return utils.respondWith('Account not found', true) + } + + return utils.respondWith({ + account: utils.toResource(request, account, 'account'), + }) +} + +const balance = async request => { + const account = await database.wallets.findById(request.query.address) + + if (!account) { + return utils.respondWith({ balance: '0', unconfirmedBalance: '0' }) + } + + return utils.respondWith({ + balance: account ? `${account.balance}` : '0', + unconfirmedBalance: account ? `${account.balance}` : '0', + }) +} + +const publicKey = async request => { + const account = await database.wallets.findById(request.query.address) + + if (!account) { + return utils.respondWith('Account not found', true) + } + + return utils.respondWith({ publicKey: account.publicKey }) +} + +module.exports = server => { + server.method('v1.accounts.index', index, { + cache: { + expiresIn: 8 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => + generateCacheKey({ + ...request.query, + ...utils.paginate(request), + }), + }) + + server.method('v1.accounts.show', show, { + cache: { + expiresIn: 8 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => + generateCacheKey({ address: request.query.address }), + }) + + server.method('v1.accounts.balance', balance, { + cache: { + expiresIn: 8 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => + generateCacheKey({ address: request.query.address }), + }) + + server.method('v1.accounts.publicKey', publicKey, { + cache: { + expiresIn: 600 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => + generateCacheKey({ address: request.query.address }), + }) +} diff --git a/packages/core-api/lib/versions/1/methods/blocks.js b/packages/core-api/lib/versions/1/methods/blocks.js new file mode 100644 index 0000000000..df3870b17f --- /dev/null +++ b/packages/core-api/lib/versions/1/methods/blocks.js @@ -0,0 +1,58 @@ +const generateCacheKey = require('../../../utils/generate-cache-key') +const { blocks: blocksRepository } = require('../../../repositories') +const utils = require('../utils') + +const index = async request => { + const { count, rows } = await blocksRepository.findAll({ + ...request.query, + ...utils.paginate(request), + }) + + if (!rows) { + return utils.respondWith('No blocks found', true) + } + + return utils.respondWith({ + blocks: utils.toCollection(request, rows, 'block'), + count, + }) +} + +const show = async request => { + const block = await blocksRepository.findById(request.query.id) + + if (!block) { + return utils.respondWith( + `Block with id ${request.query.id} not found`, + true, + ) + } + + return utils.respondWith({ + block: utils.toResource(request, block, 'block'), + }) +} + +module.exports = server => { + server.method('v1.blocks.index', index, { + cache: { + expiresIn: 8 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => + generateCacheKey({ + ...request.query, + ...utils.paginate(request), + }), + }) + + server.method('v1.blocks.show', show, { + cache: { + expiresIn: 600 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => generateCacheKey({ id: request.query.id }), + }) +} diff --git a/packages/core-api/lib/versions/1/methods/delegates.js b/packages/core-api/lib/versions/1/methods/delegates.js new file mode 100644 index 0000000000..6ce3b34816 --- /dev/null +++ b/packages/core-api/lib/versions/1/methods/delegates.js @@ -0,0 +1,132 @@ +const app = require('@arkecosystem/core-container') +const generateCacheKey = require('../../../utils/generate-cache-key') +const utils = require('../utils') + +const database = app.resolvePlugin('database') + +const index = async request => { + const { count, rows } = await database.delegates.paginate({ + ...request.query, + ...{ + offset: request.query.offset || 0, + limit: request.query.limit || 51, + }, + }) + + return utils.respondWith({ + delegates: utils.toCollection(request, rows, 'delegate'), + totalCount: count, + }) +} + +const show = async request => { + if (!request.query.publicKey && !request.query.username) { + return utils.respondWith('Delegate not found', true) + } + + const delegate = await database.delegates.findById( + request.query.publicKey || request.query.username, + ) + + if (!delegate) { + return utils.respondWith('Delegate not found', true) + } + + return utils.respondWith({ + delegate: utils.toResource(request, delegate, 'delegate'), + }) +} + +const count = async request => { + const delegate = await database.delegates.findAll() + + return utils.respondWith({ count: delegate.count }) +} + +const search = async request => { + const { rows } = await database.delegates.search({ + ...{ username: request.query.q }, + ...utils.paginate(request), + }) + + return utils.respondWith({ + delegates: utils.toCollection(request, rows, 'delegate'), + }) +} + +const voters = async request => { + const delegate = await database.delegates.findById(request.query.publicKey) + + if (!delegate) { + return utils.respondWith({ + accounts: [], + }) + } + + const accounts = await database.wallets.findAllByVote(delegate.publicKey) + + return utils.respondWith({ + accounts: utils.toCollection(request, accounts.rows, 'voter'), + }) +} + +module.exports = server => { + server.method('v1.delegates.index', index, { + cache: { + expiresIn: 8 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => + generateCacheKey({ + ...request.query, + ...{ + offset: request.query.offset || 0, + limit: request.query.limit || 51, + }, + }), + }) + + server.method('v1.delegates.show', show, { + cache: { + expiresIn: 8 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => + generateCacheKey({ + id: request.query.publicKey || request.query.username, + }), + }) + + server.method('v1.delegates.count', count, { + cache: { + expiresIn: 8 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => generateCacheKey({ time: +new Date() }), + }) + + server.method('v1.delegates.search', search, { + cache: { + expiresIn: 8 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => + generateCacheKey({ + ...{ username: request.query.q }, + ...utils.paginate(request), + }), + }) + + server.method('v1.delegates.voters', voters, { + cache: { + expiresIn: 8 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => generateCacheKey({ id: request.query.publicKey }), + }) +} diff --git a/packages/core-api/lib/versions/1/methods/transactions.js b/packages/core-api/lib/versions/1/methods/transactions.js new file mode 100644 index 0000000000..e0998c3e05 --- /dev/null +++ b/packages/core-api/lib/versions/1/methods/transactions.js @@ -0,0 +1,57 @@ +const generateCacheKey = require('../../../utils/generate-cache-key') +const { + transactions: transactionsRepository, +} = require('../../../repositories') +const utils = require('../utils') + +const index = async request => { + const { count, rows } = await transactionsRepository.findAllLegacy({ + ...request.query, + ...utils.paginate(request), + }) + + if (!rows) { + return utils.respondWith('No transactions found', true) + } + + return utils.respondWith({ + transactions: utils.toCollection(request, rows, 'transaction'), + count, + }) +} + +const show = async request => { + const result = await transactionsRepository.findById(request.query.id) + + if (!result) { + return utils.respondWith('No transactions found', true) + } + + return utils.respondWith({ + transaction: utils.toResource(request, result, 'transaction'), + }) +} + +module.exports = server => { + server.method('v1.transactions.index', index, { + cache: { + expiresIn: 8 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => + generateCacheKey({ + ...request.query, + ...utils.paginate(request), + }), + }) + + server.method('v1.transactions.show', show, { + cache: { + expiresIn: 8 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => generateCacheKey({ id: request.query.id }), + }) +} diff --git a/packages/core-api/lib/versions/1/schemas/accounts.js b/packages/core-api/lib/versions/1/schemas/accounts.js index 7392449545..3e64a77fc0 100755 --- a/packages/core-api/lib/versions/1/schemas/accounts.js +++ b/packages/core-api/lib/versions/1/schemas/accounts.js @@ -1,5 +1,3 @@ -'use strict' - /** * The AJV schema for the account endpoints. * @type {Object} @@ -11,10 +9,10 @@ module.exports = { address: { type: 'string', minLength: 1, - format: 'address' - } + format: 'address', + }, }, - required: ['address'] + required: ['address'], }, getPublicKey: { type: 'object', @@ -22,20 +20,20 @@ module.exports = { address: { type: 'string', minLength: 1, - format: 'address' - } + format: 'address', + }, }, - required: ['address'] + required: ['address'], }, generatePublicKey: { type: 'object', properties: { secret: { type: 'string', - minLength: 1 - } + minLength: 1, + }, }, - required: ['secret'] + required: ['secret'], }, getDelegates: { type: 'object', @@ -43,10 +41,10 @@ module.exports = { address: { type: 'string', minLength: 1, - format: 'address' - } + format: 'address', + }, }, - required: ['address'] + required: ['address'], }, getAccount: { type: 'object', @@ -54,10 +52,10 @@ module.exports = { address: { type: 'string', minLength: 1, - format: 'address' - } + format: 'address', + }, }, - required: ['address'] + required: ['address'], }, top: { type: 'object', @@ -65,12 +63,12 @@ module.exports = { limit: { type: 'integer', minimum: 0, - maximum: 100 + maximum: 100, }, offset: { type: 'integer', - minimum: 0 - } - } - } -}; + minimum: 0, + }, + }, + }, +} diff --git a/packages/core-api/lib/versions/1/schemas/blocks.js b/packages/core-api/lib/versions/1/schemas/blocks.js index f4a4ac3757..699cc691d4 100755 --- a/packages/core-api/lib/versions/1/schemas/blocks.js +++ b/packages/core-api/lib/versions/1/schemas/blocks.js @@ -1,5 +1,3 @@ -'use strict' - /** * The AJV schema for the block endpoints. * @type {Object} @@ -10,10 +8,10 @@ module.exports = { properties: { id: { type: 'string', - minLength: 1 - } + minLength: 1, + }, }, - required: ['id'] + required: ['id'], }, getBlocks: { type: 'object', @@ -21,37 +19,37 @@ module.exports = { limit: { type: 'integer', minimum: 0, - maximum: 100 + maximum: 100, }, orderBy: { - type: 'string' + type: 'string', }, offset: { type: 'integer', - minimum: 0 + minimum: 0, }, generatorPublicKey: { type: 'string', - format: 'publicKey' + format: 'publicKey', }, totalAmount: { type: 'integer', - minimum: 0 + minimum: 0, }, totalFee: { type: 'integer', - minimum: 0 + minimum: 0, }, reward: { type: 'integer', - minimum: 0 + minimum: 0, }, previousBlock: { - type: 'string' + type: 'string', }, height: { - type: 'integer' - } - } - } + type: 'integer', + }, + }, + }, } diff --git a/packages/core-api/lib/versions/1/schemas/delegates.js b/packages/core-api/lib/versions/1/schemas/delegates.js index cf0819e865..7ce2953c4d 100755 --- a/packages/core-api/lib/versions/1/schemas/delegates.js +++ b/packages/core-api/lib/versions/1/schemas/delegates.js @@ -1,7 +1,6 @@ -'use strict' +const app = require('@arkecosystem/core-container') -const container = require('@arkecosystem/core-container') -const lastBlock = container.resolvePlugin('blockchain').getLastBlock() +const lastBlock = app.resolvePlugin('blockchain').getLastBlock() /** * The AJV schema for the delegate endpoints. @@ -13,21 +12,21 @@ module.exports = { properties: { publicKey: { type: 'string', - format: 'publicKey' - } + format: 'publicKey', + }, }, - required: ['publicKey'] + required: ['publicKey'], }, getDelegate: { type: 'object', properties: { publicKey: { - type: 'string' + type: 'string', }, username: { - type: 'string' - } - } + type: 'string', + }, + }, }, search: { type: 'object', @@ -35,53 +34,55 @@ module.exports = { q: { type: 'string', minLength: 1, - maxLength: 20 + maxLength: 20, }, limit: { type: 'integer', minimum: 1, - maximum: 100 - } + maximum: 100, + }, }, - required: ['q'] + required: ['q'], }, getVoters: { type: 'object', properties: { publicKey: { type: 'string', - format: 'publicKey' - } + format: 'publicKey', + }, }, - required: ['publicKey'] + required: ['publicKey'], }, getDelegates: { type: 'object', properties: { orderBy: { - type: 'string' + type: 'string', }, limit: { type: 'integer', minimum: 1, maximum: lastBlock - ? container.resolvePlugin('config').getConstants(lastBlock.data.height).activeDelegates - : 51 + ? app + .resolvePlugin('config') + .getConstants(lastBlock.data.height).activeDelegates + : 51, }, offset: { type: 'integer', - minimum: 0 - } - } + minimum: 0, + }, + }, }, getForgedByAccount: { type: 'object', properties: { generatorPublicKey: { type: 'string', - format: 'publicKey' - } + format: 'publicKey', + }, }, - required: ['generatorPublicKey'] - } + required: ['generatorPublicKey'], + }, } diff --git a/packages/core-api/lib/versions/1/schemas/loader.js b/packages/core-api/lib/versions/1/schemas/loader.js index 2a8101de37..72e4a5ab05 100755 --- a/packages/core-api/lib/versions/1/schemas/loader.js +++ b/packages/core-api/lib/versions/1/schemas/loader.js @@ -1,5 +1,3 @@ -'use strict' - /** * The AJV schema for the loader endpoints. * @type {Object} @@ -10,20 +8,20 @@ module.exports = { properties: { signatures: { type: 'array', - uniqueItems: true - } + uniqueItems: true, + }, }, - required: ['signatures'] + required: ['signatures'], }, loadUnconfirmedTransactions: { type: 'object', properties: { transactions: { type: 'array', - uniqueItems: true - } + uniqueItems: true, + }, }, - required: ['transactions'] + required: ['transactions'], }, getNetwork: { peers: { @@ -31,50 +29,50 @@ module.exports = { properties: { peers: { type: 'array', - uniqueItems: true - } + uniqueItems: true, + }, }, - required: ['peers'] + required: ['peers'], }, peer: { type: 'object', properties: { ip: { type: 'string', - format: 'ip' + format: 'ip', }, port: { type: 'integer', minimum: 1, - maximum: 65535 + maximum: 65535, }, state: { type: 'integer', minimum: 0, - maximum: 3 + maximum: 3, }, os: { - type: 'string' + type: 'string', }, version: { - type: 'string' - } + type: 'string', + }, }, - required: ['ip', 'port'] + required: ['ip', 'port'], }, height: { type: 'object', properties: { height: { type: 'integer', - minimum: 0 + minimum: 0, }, id: { type: 'string', - minLength: 1 - } + minLength: 1, + }, }, - required: ['height'] - } - } -}; + required: ['height'], + }, + }, +} diff --git a/packages/core-api/lib/versions/1/schemas/peers.js b/packages/core-api/lib/versions/1/schemas/peers.js index 410f40acaf..d0625846bd 100755 --- a/packages/core-api/lib/versions/1/schemas/peers.js +++ b/packages/core-api/lib/versions/1/schemas/peers.js @@ -1,5 +1,3 @@ -'use strict' - /** * The AJV schema for the peer endpoints. * @type {Object} @@ -11,29 +9,29 @@ module.exports = { port: { type: 'integer', minimum: 1, - maximum: 65535 + maximum: 65535, }, os: { type: 'string', - maxLength: 64 + maxLength: 64, }, nethash: { type: 'string', - maxLength: 64 + maxLength: 64, }, height: { type: 'integer', - minimum: 0 + minimum: 0, }, version: { type: 'string', - maxLength: 11 + maxLength: 11, }, blockheader: { - type: 'object' - } + type: 'object', + }, }, - required: ['port', 'nethash', 'version'] + required: ['port', 'nethash', 'version'], }, updatePeersList: { peers: { @@ -41,39 +39,39 @@ module.exports = { properties: { peers: { type: 'array', - uniqueItems: true - } + uniqueItems: true, + }, }, - required: ['peers'] + required: ['peers'], }, peer: { type: 'object', properties: { ip: { type: 'string', - format: 'ip' + format: 'ip', }, port: { type: 'integer', minimum: 1, - maximum: 65535 + maximum: 65535, }, state: { type: 'integer', minimum: 0, - maximum: 3 + maximum: 3, }, os: { type: 'string', - maxLength: 64 + maxLength: 64, }, version: { type: 'string', - maxLength: 11 - } + maxLength: 11, + }, }, - required: ['ip', 'port'] - } + required: ['ip', 'port'], + }, }, getPeers: { type: 'object', @@ -81,47 +79,47 @@ module.exports = { port: { type: 'integer', minimum: 1, - maximum: 65535 + maximum: 65535, }, status: { type: 'string', - maxLength: 20 + maxLength: 20, }, os: { type: 'string', - maxLength: 64 + maxLength: 64, }, version: { type: 'string', - maxLength: 11 + maxLength: 11, }, orderBy: { - type: 'string' + type: 'string', }, limit: { type: 'integer', minimum: 0, - maximum: 100 + maximum: 100, }, offset: { type: 'integer', - minimum: 0 - } - } + minimum: 0, + }, + }, }, getPeer: { type: 'object', properties: { ip: { type: 'string', - format: 'ip' + format: 'ip', }, port: { type: 'integer', minimum: 0, - maximum: 65535 - } + maximum: 65535, + }, }, - required: ['ip', 'port'] - } -}; + required: ['ip', 'port'], + }, +} diff --git a/packages/core-api/lib/versions/1/schemas/signatures.js b/packages/core-api/lib/versions/1/schemas/signatures.js index df47031f33..bfe01d1373 100755 --- a/packages/core-api/lib/versions/1/schemas/signatures.js +++ b/packages/core-api/lib/versions/1/schemas/signatures.js @@ -1,5 +1,3 @@ -'use strict' - /** * The AJV schema for the signature endpoints. * @type {Object} @@ -11,9 +9,9 @@ module.exports = { address: { type: 'string', minLength: 1, - format: 'address' - } + format: 'address', + }, }, - required: ['address'] - } + required: ['address'], + }, } diff --git a/packages/core-api/lib/versions/1/schemas/transactions.js b/packages/core-api/lib/versions/1/schemas/transactions.js index 906a907a4d..f100b71157 100755 --- a/packages/core-api/lib/versions/1/schemas/transactions.js +++ b/packages/core-api/lib/versions/1/schemas/transactions.js @@ -1,5 +1,3 @@ -'use strict' - /** * The AJV schema for the transaction endpoints. * @type {Object} @@ -9,90 +7,90 @@ module.exports = { type: 'object', properties: { blockId: { - type: 'string' + type: 'string', }, limit: { type: 'integer', minimum: 0, - maximum: 100 + maximum: 100, }, type: { type: 'integer', minimum: 0, - maximum: 10 + maximum: 10, }, orderBy: { - type: 'string' + type: 'string', }, offset: { type: 'integer', - minimum: 0 + minimum: 0, }, senderPublicKey: { type: 'string', - format: 'publicKey' + format: 'publicKey', }, vendorField: { type: 'string', - format: 'vendorField' + format: 'vendorField', }, ownerPublicKey: { type: 'string', - format: 'publicKey' + format: 'publicKey', }, ownerAddress: { - type: 'string' + type: 'string', }, senderId: { type: 'string', - format: 'address' + format: 'address', }, recipientId: { type: 'string', - format: 'address' + format: 'address', }, amount: { type: 'integer', minimum: 0, - maximum: 10 ** 8 + maximum: 10 ** 8, }, fee: { type: 'integer', minimum: 0, - maximum: 10 ** 8 - } - } + maximum: 10 ** 8, + }, + }, }, getTransaction: { type: 'object', properties: { id: { type: 'string', - minLength: 1 - } + minLength: 1, + }, }, - required: ['id'] + required: ['id'], }, getUnconfirmedTransaction: { type: 'object', properties: { id: { type: 'string', - minLength: 1 - } + minLength: 1, + }, }, - required: ['id'] + required: ['id'], }, getUnconfirmedTransactions: { type: 'object', properties: { senderPublicKey: { type: 'string', - format: 'publicKey' + format: 'publicKey', }, address: { - type: 'string' - } - } - } + type: 'string', + }, + }, + }, } diff --git a/packages/core-api/lib/versions/1/schemas/transport.js b/packages/core-api/lib/versions/1/schemas/transport.js old mode 100755 new mode 100644 index da609f27be..125c5f03c3 --- a/packages/core-api/lib/versions/1/schemas/transport.js +++ b/packages/core-api/lib/versions/1/schemas/transport.js @@ -1,5 +1,3 @@ -'use strict' - /** * The AJV schema for the transport endpoints. * @type {Object} @@ -10,63 +8,63 @@ module.exports = { properties: { ip: { type: 'string', - format: 'ip' + format: 'ip', }, port: { type: 'integer', minimum: 1, - maximum: 65535 + maximum: 65535, }, os: { type: 'string', - maxLength: 64 + maxLength: 64, }, nethash: { type: 'string', - maxLength: 64 + maxLength: 64, }, version: { type: 'string', - maxLength: 11 - } + maxLength: 11, + }, }, - required: ['ip', 'port', 'nethash', 'version'] + required: ['ip', 'port', 'nethash', 'version'], }, - commonBlock: { + commonBlocks: { type: 'object', properties: { ids: { type: 'string', - format: 'csv' - } + format: 'csv', + }, }, - required: ['ids'] + required: ['ids'], }, transactionsFromIds: { type: 'object', properties: { ids: { type: 'string', - format: 'csv' - } + format: 'csv', + }, }, - required: ['ids'] + required: ['ids'], }, blocks: { type: 'object', properties: { lastBlockHeight: { - type: 'integer' - } - } + type: 'integer', + }, + }, }, block: { type: 'object', properties: { id: { - type: 'string' - } - } + type: 'string', + }, + }, }, signatures: { type: 'object', @@ -75,22 +73,22 @@ module.exports = { type: 'object', properties: { transaction: { - type: 'string' + type: 'string', }, signature: { type: 'string', - format: 'signature' - } + format: 'signature', + }, }, - required: ['transaction', 'signature'] - } + required: ['transaction', 'signature'], + }, }, - required: ['signature'] + required: ['signature'], }, transactions: { id: 'nodeManager.transactions', type: 'array', uniqueItems: true, - required: ['transactions'] - } -}; + required: ['transactions'], + }, +} diff --git a/packages/core-api/lib/versions/1/transformers/account.js b/packages/core-api/lib/versions/1/transformers/account.js index c958e18ce6..42552aa92e 100644 --- a/packages/core-api/lib/versions/1/transformers/account.js +++ b/packages/core-api/lib/versions/1/transformers/account.js @@ -1,11 +1,11 @@ -'use strict' +/* eslint camelcase: "off" */ /** * Turns a "wallet" object into a generic object. * @param {Object} model * @return {Object} */ -module.exports = (model) => { +module.exports = model => { const hasSecondSignature = !!model.secondPublicKey return { @@ -19,6 +19,6 @@ module.exports = (model) => { multisignatures: [], u_multisignatures: [], unconfirmedSignature: hasSecondSignature ? 1 : 0, - secondSignature: hasSecondSignature ? 1 : 0 + secondSignature: hasSecondSignature ? 1 : 0, } } diff --git a/packages/core-api/lib/versions/1/transformers/block.js b/packages/core-api/lib/versions/1/transformers/block.js index cd95e2aec3..f400f8dcd7 100644 --- a/packages/core-api/lib/versions/1/transformers/block.js +++ b/packages/core-api/lib/versions/1/transformers/block.js @@ -1,14 +1,15 @@ -'use strict' - -const blockchain = require('@arkecosystem/core-container').resolvePlugin('blockchain') +const { bignumify } = require('@arkecosystem/core-utils') +const blockchain = require('@arkecosystem/core-container').resolvePlugin( + 'blockchain', +) /** * Turns a "block" object into a generic object. * @param {Object} model * @return {Object} */ -module.exports = (model) => { - const lastBlock = blockchain.state.lastBlock +module.exports = model => { + const lastBlock = blockchain.getLastBlock() return { id: model.id, @@ -17,14 +18,16 @@ module.exports = (model) => { previousBlock: model.previousBlock, height: model.height, numberOfTransactions: model.numberOfTransactions, - totalAmount: Number(model.totalAmount), - totalForged: (Number(model.reward) + Number(model.totalFee)).toString(), - totalFee: Number(model.totalFee), - reward: Number(model.reward), + totalAmount: +bignumify(model.totalAmount).toFixed(), + totalForged: +bignumify(model.reward) + .plus(model.totalFee) + .toString(), + totalFee: +bignumify(model.totalFee).toFixed(), + reward: +bignumify(model.reward).toFixed(), payloadLength: model.payloadLength, payloadHash: model.payloadHash, generatorPublicKey: model.generatorPublicKey, blockSignature: model.blockSignature, - confirmations: lastBlock ? lastBlock.data.height - model.height : 0 + confirmations: lastBlock ? lastBlock.data.height - model.height : 0, } } diff --git a/packages/core-api/lib/versions/1/transformers/delegate.js b/packages/core-api/lib/versions/1/transformers/delegate.js index 4652836655..b453280f1c 100644 --- a/packages/core-api/lib/versions/1/transformers/delegate.js +++ b/packages/core-api/lib/versions/1/transformers/delegate.js @@ -1,23 +1,19 @@ -'use strict' - -const { calculateApproval, calculateProductivity } = require('../../../utils/delegate-calculator') +const { delegateCalculator } = require('@arkecosystem/core-utils') /** * Turns a "delegate" object into a generic object. * @param {Object} delegate * @return {Object} */ -module.exports = (delegate) => { - return { - username: delegate.username, - address: delegate.address, - publicKey: delegate.publicKey, - vote: delegate.votebalance + '', - producedblocks: delegate.producedBlocks, - missedblocks: delegate.missedBlocks, - forged: delegate.forged, - rate: delegate.rate, - approval: calculateApproval(delegate), - productivity: calculateProductivity(delegate) - } -} +module.exports = delegate => ({ + username: delegate.username, + address: delegate.address, + publicKey: delegate.publicKey, + vote: `${delegate.voteBalance}`, + producedblocks: delegate.producedBlocks, + missedblocks: delegate.missedBlocks, + forged: delegate.forged, + rate: delegate.rate, + approval: delegateCalculator.calculateApproval(delegate), + productivity: delegateCalculator.calculateProductivity(delegate), +}) diff --git a/packages/core-api/lib/versions/1/transformers/fee-statistics.js b/packages/core-api/lib/versions/1/transformers/fee-statistics.js index 64500e0a67..2a5e5fd250 100644 --- a/packages/core-api/lib/versions/1/transformers/fee-statistics.js +++ b/packages/core-api/lib/versions/1/transformers/fee-statistics.js @@ -1,17 +1,13 @@ -'use strict' - /** * Turns a "fee-statistics" object into readable object. * @param {Object} model * @return {Object} */ -module.exports = (model) => { - return { - type: model.type, - fees: { - minFee: parseInt(model.minFee), - maxFee: parseInt(model.maxFee), - avgFee: parseInt(model.avgFee) - } - } -} +module.exports = model => ({ + type: model.type, + fees: { + minFee: parseInt(model.minFee), + maxFee: parseInt(model.maxFee), + avgFee: parseInt(model.avgFee), + }, +}) diff --git a/packages/core-api/lib/versions/1/transformers/peer.js b/packages/core-api/lib/versions/1/transformers/peer.js index 1791d988db..cde2573111 100644 --- a/packages/core-api/lib/versions/1/transformers/peer.js +++ b/packages/core-api/lib/versions/1/transformers/peer.js @@ -1,18 +1,26 @@ -'use strict' +const app = require('@arkecosystem/core-container') + +const config = app.resolvePlugin('config') /** * Turns a "peer" object into a generic object. * @param {Object} model * @return {Object} */ -module.exports = (model) => { - return { +module.exports = model => { + const peer = { ip: model.ip, port: model.port, version: model.version, height: model.height, status: model.status, os: model.os, - delay: model.delay - }; + delay: model.delay, + } + + if (config.network.name !== 'mainnet') { + peer.hashid = model.hashid + } + + return peer } diff --git a/packages/core-api/lib/versions/1/transformers/ports.js b/packages/core-api/lib/versions/1/transformers/ports.js index 03ca3b8809..8c8615740f 100644 --- a/packages/core-api/lib/versions/1/transformers/ports.js +++ b/packages/core-api/lib/versions/1/transformers/ports.js @@ -1,21 +1,19 @@ -'use strict' - /** * Turns a "config" object into readable object. * @param {Object} model * @return {Object} */ -module.exports = (config) => { - let result = {} +module.exports = config => { + const result = {} const keys = [ '@arkecosystem/core-p2p', '@arkecosystem/core-api', '@arkecosystem/core-graphql', '@arkecosystem/core-json-rpc', - '@arkecosystem/core-webhooks' + '@arkecosystem/core-webhooks', ] - for (let [name, options] of Object.entries(config.plugins)) { + for (const [name, options] of Object.entries(config.plugins)) { if (keys.includes(name) && options.enabled) { if (options.server && options.server.enabled) { result[name] = options.server.port diff --git a/packages/core-api/lib/versions/1/transformers/transaction.js b/packages/core-api/lib/versions/1/transformers/transaction.js index f8c0afc94a..4c5dc11f9c 100644 --- a/packages/core-api/lib/versions/1/transformers/transaction.js +++ b/packages/core-api/lib/versions/1/transformers/transaction.js @@ -1,10 +1,10 @@ -'use strict' - const { crypto } = require('@arkecosystem/crypto') +const { bignumify } = require('@arkecosystem/core-utils') + +const app = require('@arkecosystem/core-container') -const container = require('@arkecosystem/core-container') -const config = container.resolvePlugin('config') -const blockchain = container.resolvePlugin('blockchain') +const config = app.resolvePlugin('config') +const blockchain = app.resolvePlugin('blockchain') const { Transaction } = require('@arkecosystem/crypto').models @@ -13,24 +13,29 @@ const { Transaction } = require('@arkecosystem/crypto').models * @param {Object} model * @return {Object} */ -module.exports = (model) => { - const data = Transaction.deserialize(model.serialized.toString('hex')) +module.exports = model => { + const data = new Transaction(model.serialized.toString('hex')) return { id: data.id, blockid: model.blockId, type: data.type, timestamp: data.timestamp, - amount: data.amount, - fee: data.fee, + amount: +bignumify(data.amount).toFixed(), + fee: +bignumify(data.fee).toFixed(), recipientId: data.recipientId, - senderId: crypto.getAddress(data.senderPublicKey, config.network.pubKeyHash), + senderId: crypto.getAddress( + data.senderPublicKey, + config.network.pubKeyHash, + ), senderPublicKey: data.senderPublicKey, vendorField: data.vendorField, signature: data.signature, + signSignature: data.signSignature, + signatures: data.signatures, asset: data.asset || {}, confirmations: model.block ? blockchain.getLastBlock().data.height - model.block.height - : 0 + : 0, } } diff --git a/packages/core-api/lib/versions/1/transformers/voter.js b/packages/core-api/lib/versions/1/transformers/voter.js index 044046c238..e40f5b76c6 100644 --- a/packages/core-api/lib/versions/1/transformers/voter.js +++ b/packages/core-api/lib/versions/1/transformers/voter.js @@ -1,15 +1,11 @@ -'use strict' - /** * Turns a "voter" object into a generic object. * @param {Object} model * @return {Object} */ -module.exports = (model) => { - return { - username: model.username, - address: model.address, - publicKey: model.publicKey, - balance: model.balance + '' - } -} +module.exports = model => ({ + username: model.username, + address: model.address, + publicKey: model.publicKey, + balance: `${model.balance}`, +}) diff --git a/packages/core-api/lib/versions/1/utils.js b/packages/core-api/lib/versions/1/utils.js index c55780dfc5..eeaf7dbbbb 100644 --- a/packages/core-api/lib/versions/1/utils.js +++ b/packages/core-api/lib/versions/1/utils.js @@ -1,18 +1,19 @@ -'use strict' +/* eslint max-len: "off" */ -const { transformResource, transformCollection } = require('../../utils/transformer') +const { + transformResource, + transformCollection, +} = require('../../utils/transformer') /** * Create a pagination object for the request. * @param {Hapi.Request} request * @return {Object} */ -const paginate = request => { - return { - offset: request.query.offset || 0, - limit: request.query.limit || 100 - } -} +const paginate = request => ({ + offset: request.query.offset || 0, + limit: request.query.limit || 100, +}) /** * Create a hapi.js response. @@ -20,10 +21,22 @@ const paginate = request => { * @param {Boolean} error * @return {Object} */ -const respondWith = (data, error = false) => { - return error - ? { error: data, success: false } - : { ...data, success: true } +const respondWith = (data, error = false) => + error ? { error: data, success: false } : { ...data, success: true } + +/** + * Respond with data from cache. + * @param {Object} data + * @param {Hapi.Toolkit} h + * @return {Object} + */ +const respondWithCache = (data, h) => { + const { value, cached } = data + const lastModified = cached ? new Date(cached.stored) : new Date() + + return value.isBoom + ? h.response(value.output.payload).code(value.output.statusCode) + : h.response(value).header('Last-modified', lastModified.toUTCString()) } /** @@ -33,9 +46,8 @@ const respondWith = (data, error = false) => { * @param {String} transformer * @return {Object} */ -const toResource = (request, data, transformer) => { - return transformResource(request, data, transformer) -} +const toResource = (request, data, transformer) => + transformResource(request, data, transformer) /** * Transform the given data into a collection. @@ -52,6 +64,7 @@ const toCollection = transformCollection module.exports = { paginate, respondWith, + respondWithCache, toResource, - toCollection + toCollection, } diff --git a/packages/core-api/lib/versions/2/handlers/blockchain.js b/packages/core-api/lib/versions/2/handlers/blockchain.js new file mode 100644 index 0000000000..e3511e4be9 --- /dev/null +++ b/packages/core-api/lib/versions/2/handlers/blockchain.js @@ -0,0 +1,36 @@ +const app = require('@arkecosystem/core-container') +const { bignumify } = require('@arkecosystem/core-utils') + +const config = app.resolvePlugin('config') +const blockchain = app.resolvePlugin('blockchain') + +/** + * @type {Object} + */ +exports.index = { + /** + * @param {Hapi.Request} request + * @param {Hapi.Toolkit} h + * @return {Hapi.Response} + */ + handler(request, h) { + const lastBlock = blockchain.getLastBlock() + + const constants = config.getConstants(lastBlock.data.height) + const rewards = bignumify(constants.reward).times( + lastBlock.data.height - constants.height, + ) + + return { + data: { + block: { + height: lastBlock.data.height, + id: lastBlock.data.id, + }, + supply: +bignumify(config.genesisBlock.totalAmount) + .plus(rewards) + .toFixed(), + }, + } + }, +} diff --git a/packages/core-api/lib/versions/2/handlers/blocks.js b/packages/core-api/lib/versions/2/handlers/blocks.js index 5cae292b93..8f5356be0e 100644 --- a/packages/core-api/lib/versions/2/handlers/blocks.js +++ b/packages/core-api/lib/versions/2/handlers/blocks.js @@ -1,8 +1,4 @@ -'use strict' - -const Boom = require('boom') -const database = require('@arkecosystem/core-container').resolvePlugin('database') -const utils = require('../utils') +const { respondWithCache } = require('../utils') const schema = require('../schema/blocks') /** @@ -14,14 +10,14 @@ exports.index = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const blocks = await database.blocks.findAll(utils.paginate(request)) + async handler(request, h) { + const data = await request.server.methods.v2.blocks.index(request) - return utils.toPagination(request, blocks, 'block') + return respondWithCache(data, h) }, options: { - validate: schema.index - } + validate: schema.index, + }, } /** @@ -33,18 +29,14 @@ exports.show = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const block = await database.blocks.findById(request.params.id) + async handler(request, h) { + const data = await request.server.methods.v2.blocks.show(request) - if (!block) { - return Boom.notFound('Block not found') - } - - return utils.respondWithResource(request, block, 'block') + return respondWithCache(data, h) }, options: { - validate: schema.show - } + validate: schema.show, + }, } /** @@ -56,20 +48,14 @@ exports.transactions = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const block = await database.blocks.findById(request.params.id) + async handler(request, h) { + const data = await request.server.methods.v2.blocks.transactions(request) - if (!block) { - return Boom.notFound('Block not found') - } - - const transactions = await database.transactions.findAllByBlock(block.id, utils.paginate(request)) - - return utils.toPagination(request, transactions, 'transaction') + return respondWithCache(data, h) }, options: { - validate: schema.transactions - } + validate: schema.transactions, + }, } /** @@ -81,16 +67,12 @@ exports.search = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const blocks = await database.blocks.search({ - ...request.payload, - ...request.query, - ...utils.paginate(request) - }) + async handler(request, h) { + const data = await request.server.methods.v2.blocks.search(request) - return utils.toPagination(request, blocks, 'block') + return respondWithCache(data, h) }, options: { - validate: schema.search - } + validate: schema.search, + }, } diff --git a/packages/core-api/lib/versions/2/handlers/delegates.js b/packages/core-api/lib/versions/2/handlers/delegates.js index 7fc1d10201..71d9626cf7 100644 --- a/packages/core-api/lib/versions/2/handlers/delegates.js +++ b/packages/core-api/lib/versions/2/handlers/delegates.js @@ -1,9 +1,4 @@ -'use strict' - -const Boom = require('boom') -const orderBy = require('lodash/orderBy') -const database = require('@arkecosystem/core-container').resolvePlugin('database') -const utils = require('../utils') +const { respondWithCache } = require('../utils') const schema = require('../schema/delegates') /** @@ -15,14 +10,14 @@ exports.index = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const delegates = await database.delegates.paginate(utils.paginate(request)) + async handler(request, h) { + const data = await request.server.methods.v2.delegates.index(request) - return utils.toPagination(request, delegates, 'delegate') + return respondWithCache(data, h) }, options: { - validate: schema.index - } + validate: schema.index, + }, } /** @@ -34,18 +29,14 @@ exports.show = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const delegate = await database.delegates.findById(request.params.id) + async handler(request, h) { + const data = await request.server.methods.v2.delegates.show(request) - if (!delegate) { - return Boom.notFound('Delegate not found') - } - - return utils.respondWithResource(request, delegate, 'delegate') + return respondWithCache(data, h) }, options: { - validate: schema.show - } + validate: schema.show, + }, } /** @@ -57,18 +48,14 @@ exports.search = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const delegates = await database.delegates.search({ - ...request.payload, - ...request.query, - ...utils.paginate(request) - }) + async handler(request, h) { + const data = await request.server.methods.v2.delegates.search(request) - return utils.toPagination(request, delegates, 'delegate') + return respondWithCache(data, h) }, options: { - validate: schema.search - } + validate: schema.search, + }, } /** @@ -80,20 +67,14 @@ exports.blocks = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const delegate = await database.delegates.findById(request.params.id) - - if (!delegate) { - return Boom.notFound('Delegate not found') - } + async handler(request, h) { + const data = await request.server.methods.v2.delegates.blocks(request) - const blocks = await database.blocks.findAllByGenerator(delegate.publicKey, utils.paginate(request)) - - return utils.toPagination(request, blocks, 'block') + return respondWithCache(data, h) }, options: { - validate: schema.blocks - } + validate: schema.blocks, + }, } /** @@ -105,20 +86,14 @@ exports.voters = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const delegate = await database.delegates.findById(request.params.id) + async handler(request, h) { + const data = await request.server.methods.v2.delegates.voters(request) - if (!delegate) { - return Boom.notFound('Delegate not found') - } - - const wallets = await database.wallets.findAllByVote(delegate.publicKey, utils.paginate(request)) - - return utils.toPagination(request, wallets, 'wallet') + return respondWithCache(data, h) }, options: { - validate: schema.voters - } + validate: schema.voters, + }, } /** @@ -130,24 +105,14 @@ exports.voterBalances = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const delegate = await database.delegates.findById(request.params.id) - - if (!delegate) { - return Boom.notFound('Delegate not found') - } + async handler(request, h) { + const data = await request.server.methods.v2.delegates.voterBalances( + request, + ) - const wallets = await database.wallets - .getLocalWallets() - .filter(wallet => wallet.vote === delegate.publicKey) - - const voters = {} - orderBy(wallets, ['balance'], ['desc']) - .forEach(wallet => (voters[wallet.address] = wallet.balance)) - - return { data: voters } + return respondWithCache(data, h) }, options: { - validate: schema.voterBalances - } + validate: schema.voterBalances, + }, } diff --git a/packages/core-api/lib/versions/2/handlers/node.js b/packages/core-api/lib/versions/2/handlers/node.js index 2286e6d122..b2a164a521 100644 --- a/packages/core-api/lib/versions/2/handlers/node.js +++ b/packages/core-api/lib/versions/2/handlers/node.js @@ -1,9 +1,9 @@ -'use strict' +const app = require('@arkecosystem/core-container') -const container = require('@arkecosystem/core-container') -const blockchain = container.resolvePlugin('blockchain') -const config = container.resolvePlugin('config') +const blockchain = app.resolvePlugin('blockchain') +const config = app.resolvePlugin('config') const utils = require('../utils') +const { transactions } = require('../../../repositories') /** * @type {Object} @@ -14,7 +14,7 @@ exports.status = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { + async handler(request, h) { const lastBlock = blockchain.getLastBlock() const networkHeight = await blockchain.p2p.getNetworkHeight() @@ -22,10 +22,10 @@ exports.status = { data: { synced: blockchain.isSynced(), now: lastBlock ? lastBlock.data.height : 0, - blocksCount: networkHeight - lastBlock.data.height || 0 - } + blocksCount: networkHeight - lastBlock.data.height || 0, + }, } - } + }, } /** @@ -37,7 +37,7 @@ exports.syncing = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { + async handler(request, h) { const lastBlock = blockchain.getLastBlock() const networkHeight = await blockchain.p2p.getNetworkHeight() @@ -46,10 +46,10 @@ exports.syncing = { syncing: !blockchain.isSynced(), blocks: networkHeight - lastBlock.data.height || 0, height: lastBlock.data.height, - id: lastBlock.data.id - } + id: lastBlock.data.id, + }, } - } + }, } /** @@ -61,8 +61,8 @@ exports.configuration = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const feeStatisticsData = await blockchain.database.transactions.getFeeStatistics() + async handler(request, h) { + const feeStatisticsData = await transactions.getFeeStatistics() return { data: { @@ -73,8 +73,12 @@ exports.configuration = { version: config.network.pubKeyHash, ports: utils.toResource(request, config, 'ports'), constants: config.getConstants(blockchain.getLastBlock().data.height), - feeStatistics: utils.toCollection(request, feeStatisticsData, 'fee-statistics') - } + feeStatistics: utils.toCollection( + request, + feeStatisticsData, + 'fee-statistics', + ), + }, } - } + }, } diff --git a/packages/core-api/lib/versions/2/handlers/peers.js b/packages/core-api/lib/versions/2/handlers/peers.js index 560dad4912..24afd2cf0e 100644 --- a/packages/core-api/lib/versions/2/handlers/peers.js +++ b/packages/core-api/lib/versions/2/handlers/peers.js @@ -1,7 +1,7 @@ -'use strict' - const Boom = require('boom') -const blockchain = require('@arkecosystem/core-container').resolvePlugin('blockchain') +const app = require('@arkecosystem/core-container') + +const blockchain = app.resolvePlugin('blockchain') const utils = require('../utils') const schema = require('../schema/peers') @@ -14,15 +14,23 @@ exports.index = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { + async handler(request, h) { const allPeers = await blockchain.p2p.getPeers() let result = allPeers.sort((a, b) => a.delay - b.delay) - result = request.query.os ? result.filter(peer => peer.os === request.query.os) : result - result = request.query.status ? result.filter(peer => peer.status === request.query.status) : result - result = request.query.port ? result.filter(peer => peer.port === request.query.port) : result - result = request.query.version ? result.filter(peer => peer.version === request.query.version) : result - result = result.slice(0, (request.query.limit || 100)) + result = request.query.os + ? result.filter(peer => peer.os === request.query.os) + : result + result = request.query.status + ? result.filter(peer => peer.status === request.query.status) + : result + result = request.query.port + ? result.filter(peer => peer.port === request.query.port) + : result + result = request.query.version + ? result.filter(peer => peer.version === request.query.version) + : result + result = result.slice(0, request.query.limit || 100) if (request.query.orderBy) { const order = request.query.orderBy.split(':') @@ -34,11 +42,15 @@ exports.index = { } } - return utils.toPagination(request, { rows: result, count: result.length }, 'peer') + return utils.toPagination( + request, + { rows: result, count: result.length }, + 'peer', + ) }, options: { - validate: schema.index - } + validate: schema.index, + }, } /** @@ -50,7 +62,7 @@ exports.show = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { + async handler(request, h) { const peers = await blockchain.p2p.getPeers() const peer = peers.find(p => p.ip === request.params.ip) @@ -61,8 +73,8 @@ exports.show = { return utils.respondWithResource(request, peer, 'peer') }, options: { - validate: schema.show - } + validate: schema.show, + }, } /** @@ -74,9 +86,13 @@ exports.suspended = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const peers = blockchain.p2p.getSuspendedPeers() + async handler(request, h) { + const peers = app.resolvePlugin('p2p').getSuspendedPeers() - return utils.respondWithCollection(request, Object.values(peers).map(peer => peer.peer), 'peer') - } + return utils.respondWithCollection( + request, + Object.values(peers).map(peer => peer.peer), + 'peer', + ) + }, } diff --git a/packages/core-api/lib/versions/2/handlers/transactions.js b/packages/core-api/lib/versions/2/handlers/transactions.js index 66dc9dc363..cda76c5e98 100644 --- a/packages/core-api/lib/versions/2/handlers/transactions.js +++ b/packages/core-api/lib/versions/2/handlers/transactions.js @@ -1,15 +1,13 @@ -'use strict' - const Boom = require('boom') const { TRANSACTION_TYPES } = require('@arkecosystem/crypto').constants const { TransactionGuard } = require('@arkecosystem/core-transaction-pool') -const container = require('@arkecosystem/core-container') -const config = container.resolvePlugin('config') -const database = container.resolvePlugin('database') -const logger = container.resolvePlugin('logger') -const transactionPool = container.resolvePlugin('transactionPool') +const app = require('@arkecosystem/core-container') + +const blockchain = app.resolvePlugin('blockchain') +const config = app.resolvePlugin('config') +const transactionPool = app.resolvePlugin('transactionPool') const utils = require('../utils') const schema = require('../schema/transactions') @@ -23,11 +21,14 @@ exports.index = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const transactions = await database.transactions.findAll(utils.paginate(request)) + async handler(request, h) { + const data = await request.server.methods.v2.transactions.index(request) - return utils.toPagination(request, transactions, 'transaction') - } + return utils.respondWithCache(data, h) + }, + options: { + validate: schema.index, + }, } /** @@ -39,57 +40,39 @@ exports.store = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - if (!transactionPool) { - return { - data: [] - } + async handler(request, h) { + if (!transactionPool.options.enabled) { + return Boom.serverUnavailable('Transaction pool is disabled.') } - /** - * Here we will make sure we memorize the transactions for future requests - * and decide which transactions are valid or invalid in order to prevent - * duplication and race conditions caused by concurrent requests. - */ - const { valid, invalid } = transactionPool.memory.memorize(request.payload.transactions) - const guard = new TransactionGuard(transactionPool) - guard.invalid = invalid - await guard.validate(valid) - - if (guard.hasAny('accept')) { - logger.info(`Received ${guard.accept.length} new transactions`) - await transactionPool.addTransactions(guard.accept) + const result = await guard.validate(request.payload.transactions) - transactionPool.memory - .forget(guard.getIds('accept')) - .forget(guard.getIds('excess')) - } - - if (!request.payload.isBroadCasted && guard.hasAny('broadcast')) { - await container + if (result.broadcast.length > 0) { + app .resolvePlugin('p2p') - .broadcastTransactions(guard.broadcast) + .broadcastTransactions(guard.getBroadcastTransactions()) } return { data: { - accept: guard.getIds('accept'), - excess: guard.getIds('excess'), - invalid: guard.getIds('invalid'), - broadcast: guard.getIds('broadcast') - } + accept: result.accept, + broadcast: result.broadcast, + excess: result.excess, + invalid: result.invalid, + }, + errors: result.errors, } }, options: { validate: schema.store, plugins: { pagination: { - enabled: false - } - } - } + enabled: false, + }, + }, + }, } /** @@ -101,18 +84,14 @@ exports.show = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const transaction = await database.transactions.findById(request.params.id) - - if (!transaction) { - return Boom.notFound('Transaction not found') - } + async handler(request, h) { + const data = await request.server.methods.v2.transactions.show(request) - return utils.respondWithResource(request, transaction, 'transaction') + return utils.respondWithCache(data, h) }, options: { - validate: schema.show - } + validate: schema.show, + }, } /** @@ -124,21 +103,33 @@ exports.unconfirmed = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - if (!container.resolve('transactionPool').options.enabled) { - return Boom.teapot() + async handler(request, h) { + if (!transactionPool.options.enabled) { + return Boom.serverUnavailable('Transaction pool is disabled.') } const pagination = utils.paginate(request) - let transactions = await transactionPool.getTransactions(pagination.offset, pagination.limit) - transactions = transactions.map(transaction => ({ serialized: transaction })) - - return utils.toPagination(request, { - count: await transactionPool.getPoolSize(), - rows: transactions - }, 'transaction') - } + let transactions = transactionPool.getTransactions( + pagination.offset, + pagination.limit, + ) + transactions = transactions.map(transaction => ({ + serialized: transaction, + })) + + return utils.toPagination( + request, + { + count: transactionPool.getPoolSize(), + rows: transactions, + }, + 'transaction', + ) + }, + options: { + validate: schema.unconfirmed, + }, } /** @@ -150,21 +141,24 @@ exports.showUnconfirmed = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - if (!container.resolve('transactionPool').options.enabled) { - return Boom.teapot() + handler(request, h) { + if (!transactionPool.options.enabled) { + return Boom.serverUnavailable('Transaction pool is disabled.') } - let transaction = await transactionPool.getTransaction(request.params.id) + let transaction = transactionPool.getTransaction(request.params.id) if (!transaction) { return Boom.notFound('Transaction not found') } - transaction = { serialized: transaction.serialized.toString('hex') } + transaction = { serialized: transaction.serialized } return utils.respondWithResource(request, transaction, 'transaction') - } + }, + options: { + validate: schema.showUnconfirmed, + }, } /** @@ -176,18 +170,14 @@ exports.search = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const transactions = await database.transactions.search({ - ...request.query, - ...request.payload, - ...utils.paginate(request) - }) - - return utils.toPagination(request, transactions, 'transaction') + async handler(request, h) { + const data = await request.server.methods.v2.transactions.search(request) + + return utils.respondWithCache(data, h) }, options: { - validate: schema.search - } + validate: schema.search, + }, } /** @@ -199,11 +189,11 @@ exports.types = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { + async handler(request, h) { return { - data: TRANSACTION_TYPES + data: TRANSACTION_TYPES, } - } + }, } /** @@ -215,9 +205,10 @@ exports.fees = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { + async handler(request, h) { return { - data: config.getConstants().fees + data: config.getConstants(blockchain.getLastBlock().data.height).fees + .staticFees, } - } + }, } diff --git a/packages/core-api/lib/versions/2/handlers/votes.js b/packages/core-api/lib/versions/2/handlers/votes.js index f875111c25..18804a03be 100644 --- a/packages/core-api/lib/versions/2/handlers/votes.js +++ b/packages/core-api/lib/versions/2/handlers/votes.js @@ -1,9 +1,4 @@ -'use strict' - -const Boom = require('boom') -const { TRANSACTION_TYPES } = require('@arkecosystem/crypto').constants -const database = require('@arkecosystem/core-container').resolvePlugin('database') -const utils = require('../utils') +const { respondWithCache } = require('../utils') const schema = require('../schema/votes') /** @@ -15,14 +10,14 @@ exports.index = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const transactions = await database.transactions.findAllByType(TRANSACTION_TYPES.VOTE, utils.paginate(request)) + async handler(request, h) { + const data = await request.server.methods.v2.votes.index(request) - return utils.toPagination(request, transactions, 'transaction') + return respondWithCache(data, h) }, options: { - validate: schema.index - } + validate: schema.index, + }, } /** @@ -34,16 +29,12 @@ exports.show = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const transaction = await database.transactions.findByTypeAndId(TRANSACTION_TYPES.VOTE, request.params.id) + async handler(request, h) { + const data = await request.server.methods.v2.votes.show(request) - if (!transaction) { - return Boom.notFound('Vote not found') - } - - return utils.respondWithResource(request, transaction, 'transaction') + return respondWithCache(data, h) }, options: { - validate: schema.show - } + validate: schema.show, + }, } diff --git a/packages/core-api/lib/versions/2/handlers/wallets.js b/packages/core-api/lib/versions/2/handlers/wallets.js index f720c9c2bb..44e31f8da8 100644 --- a/packages/core-api/lib/versions/2/handlers/wallets.js +++ b/packages/core-api/lib/versions/2/handlers/wallets.js @@ -1,8 +1,4 @@ -'use strict' - -const Boom = require('boom') -const database = require('@arkecosystem/core-container').resolvePlugin('database') -const utils = require('../utils') +const { respondWithCache } = require('../utils') const schema = require('../schema/wallets') /** @@ -14,14 +10,14 @@ exports.index = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const wallets = await database.wallets.findAll(utils.paginate(request)) + async handler(request, h) { + const data = await request.server.methods.v2.wallets.index(request) - return utils.toPagination(request, wallets, 'wallet') + return respondWithCache(data, h) }, options: { - validate: schema.index - } + validate: schema.index, + }, } /** @@ -33,11 +29,12 @@ exports.top = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const wallets = await database.wallets.top(utils.paginate(request)) + async handler(request, h) { + const data = await request.server.methods.v2.wallets.top(request) - return utils.toPagination(request, wallets, 'wallet') - } + return respondWithCache(data, h) + }, + // TODO: create top schema } /** @@ -49,18 +46,14 @@ exports.show = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const wallet = await database.wallets.findById(request.params.id) - - if (!wallet) { - return Boom.notFound('Wallet not found') - } + async handler(request, h) { + const data = await request.server.methods.v2.wallets.show(request) - return utils.respondWithResource(request, wallet, 'wallet') + return respondWithCache(data, h) }, options: { - validate: schema.show - } + validate: schema.show, + }, } /** @@ -72,25 +65,14 @@ exports.transactions = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const wallet = await database.wallets.findById(request.params.id) - - if (!wallet) { - return Boom.notFound('Wallet not found') - } - - const transactions = await database.transactions.findAllByWallet( - wallet, { - ...request.params, - ...utils.paginate(request) - } - ) + async handler(request, h) { + const data = await request.server.methods.v2.wallets.transactions(request) - return utils.toPagination(request, transactions, 'transaction') + return respondWithCache(data, h) }, options: { - validate: schema.transactions - } + validate: schema.transactions, + }, } /** @@ -102,25 +84,16 @@ exports.transactionsSent = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const wallet = await database.wallets.findById(request.params.id) - - if (!wallet) { - return Boom.notFound('Wallet not found') - } - - const transactions = await database.transactions.findAllBySender( - wallet.publicKey, { - ...request.params, - ...utils.paginate(request) - } + async handler(request, h) { + const data = await request.server.methods.v2.wallets.transactionsSent( + request, ) - return utils.toPagination(request, transactions, 'transaction') + return respondWithCache(data, h) }, options: { - validate: schema.transactionsSent - } + validate: schema.transactionsSent, + }, } /** @@ -132,25 +105,16 @@ exports.transactionsReceived = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const wallet = await database.wallets.findById(request.params.id) - - if (!wallet) { - return Boom.notFound('Wallet not found') - } - - const transactions = await database.transactions.findAllByRecipient( - wallet.address, { - ...request.params, - ...utils.paginate(request) - } + async handler(request, h) { + const data = await request.server.methods.v2.wallets.transactionsReceived( + request, ) - return utils.toPagination(request, transactions, 'transaction') + return respondWithCache(data, h) }, options: { - validate: schema.transactionsReceived - } + validate: schema.transactionsReceived, + }, } /** @@ -162,25 +126,14 @@ exports.votes = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const wallet = await database.wallets.findById(request.params.id) - - if (!wallet) { - return Boom.notFound('Wallet not found') - } - - const transactions = await database.transactions.allVotesBySender( - wallet.publicKey, { - ...request.params, - ...utils.paginate(request) - } - ) + async handler(request, h) { + const data = await request.server.methods.v2.wallets.votes(request) - return utils.toPagination(request, transactions, 'transaction') + return respondWithCache(data, h) }, options: { - validate: schema.votes - } + validate: schema.votes, + }, } /** @@ -192,16 +145,12 @@ exports.search = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const wallets = await database.wallets.search({ - ...request.payload, - ...request.query, - ...utils.paginate(request) - }) - - return utils.toPagination(request, wallets, 'wallet') + async handler(request, h) { + const data = await request.server.methods.v2.wallets.search(request) + + return respondWithCache(data, h) }, options: { - validate: schema.search - } + validate: schema.search, + }, } diff --git a/packages/core-api/lib/versions/2/index.js b/packages/core-api/lib/versions/2/index.js index caea17522d..c16c9cd1be 100644 --- a/packages/core-api/lib/versions/2/index.js +++ b/packages/core-api/lib/versions/2/index.js @@ -1,5 +1,4 @@ -'use strict' - +const blockchain = require('./handlers/blockchain') const blocks = require('./handlers/blocks') const delegates = require('./handlers/delegates') const node = require('./handlers/node') @@ -8,6 +7,12 @@ const transactions = require('./handlers/transactions') const votes = require('./handlers/votes') const wallets = require('./handlers/wallets') +const registerBlockMethods = require('./methods/blocks') +const registerDelegateMethods = require('./methods/delegates') +const registerTransactionMethods = require('./methods/transactions') +const registerWalletMethods = require('./methods/wallets') +const registerVoteMethods = require('./methods/votes') + /** * Register the v2 routes. * @param {Hapi.Server} server @@ -15,17 +20,33 @@ const wallets = require('./handlers/wallets') * @return {void} */ const register = async (server, options) => { + registerBlockMethods(server) + registerDelegateMethods(server) + registerTransactionMethods(server) + registerWalletMethods(server) + registerVoteMethods(server) + server.route([ + { method: 'GET', path: '/blockchain', ...blockchain.index }, + { method: 'GET', path: '/blocks', ...blocks.index }, { method: 'GET', path: '/blocks/{id}', ...blocks.show }, - { method: 'GET', path: '/blocks/{id}/transactions', ...blocks.transactions }, + { + method: 'GET', + path: '/blocks/{id}/transactions', + ...blocks.transactions, + }, { method: 'POST', path: '/blocks/search', ...blocks.search }, { method: 'GET', path: '/delegates', ...delegates.index }, { method: 'GET', path: '/delegates/{id}', ...delegates.show }, { method: 'GET', path: '/delegates/{id}/blocks', ...delegates.blocks }, { method: 'GET', path: '/delegates/{id}/voters', ...delegates.voters }, - { method: 'GET', path: '/delegates/{id}/voters/balances', ...delegates.voterBalances }, + { + method: 'GET', + path: '/delegates/{id}/voters/balances', + ...delegates.voterBalances, + }, { method: 'POST', path: '/delegates/search', ...delegates.search }, { method: 'GET', path: '/node/status', ...node.status }, @@ -39,8 +60,16 @@ const register = async (server, options) => { { method: 'GET', path: '/transactions', ...transactions.index }, { method: 'POST', path: '/transactions', ...transactions.store }, { method: 'GET', path: '/transactions/{id}', ...transactions.show }, - { method: 'GET', path: '/transactions/unconfirmed', ...transactions.unconfirmed }, - { method: 'GET', path: '/transactions/unconfirmed/{id}', ...transactions.showUnconfirmed }, + { + method: 'GET', + path: '/transactions/unconfirmed', + ...transactions.unconfirmed, + }, + { + method: 'GET', + path: '/transactions/unconfirmed/{id}', + ...transactions.showUnconfirmed, + }, { method: 'POST', path: '/transactions/search', ...transactions.search }, { method: 'GET', path: '/transactions/types', ...transactions.types }, { method: 'GET', path: '/transactions/fees', ...transactions.fees }, @@ -51,11 +80,23 @@ const register = async (server, options) => { { method: 'GET', path: '/wallets', ...wallets.index }, { method: 'GET', path: '/wallets/top', ...wallets.top }, { method: 'GET', path: '/wallets/{id}', ...wallets.show }, - { method: 'GET', path: '/wallets/{id}/transactions', ...wallets.transactions }, - { method: 'GET', path: '/wallets/{id}/transactions/sent', ...wallets.transactionsSent }, - { method: 'GET', path: '/wallets/{id}/transactions/received', ...wallets.transactionsReceived }, + { + method: 'GET', + path: '/wallets/{id}/transactions', + ...wallets.transactions, + }, + { + method: 'GET', + path: '/wallets/{id}/transactions/sent', + ...wallets.transactionsSent, + }, + { + method: 'GET', + path: '/wallets/{id}/transactions/received', + ...wallets.transactionsReceived, + }, { method: 'GET', path: '/wallets/{id}/votes', ...wallets.votes }, - { method: 'POST', path: '/wallets/search', ...wallets.search } + { method: 'POST', path: '/wallets/search', ...wallets.search }, ]) } @@ -64,7 +105,7 @@ const register = async (server, options) => { * @type {Object} */ exports.plugin = { - name: 'ARK Public API - v2', + name: 'Ark Public API - v2', version: '2.0.0', - register + register, } diff --git a/packages/core-api/lib/versions/2/methods/blocks.js b/packages/core-api/lib/versions/2/methods/blocks.js new file mode 100644 index 0000000000..2ae658908c --- /dev/null +++ b/packages/core-api/lib/versions/2/methods/blocks.js @@ -0,0 +1,102 @@ +const Boom = require('boom') +const generateCacheKey = require('../../../utils/generate-cache-key') +const { + blocks: blocksRepository, + transactions: transactionsRepository, +} = require('../../../repositories') +const utils = require('../utils') + +const index = async request => { + const blocks = await blocksRepository.findAll({ + ...request.query, + ...utils.paginate(request), + }) + + return utils.toPagination(request, blocks, 'block') +} + +const show = async request => { + const block = await blocksRepository.findById(request.params.id) + + if (!block) { + return Boom.notFound('Block not found') + } + + return utils.respondWithResource(request, block, 'block') +} + +const transactions = async request => { + const block = await blocksRepository.findById(request.params.id) + + if (!block) { + return Boom.notFound('Block not found') + } + + const rows = await transactionsRepository.findAllByBlock(block.id, { + ...request.query, + ...utils.paginate(request), + }) + + return utils.toPagination(request, rows, 'transaction') +} + +const search = async request => { + const blocks = await blocksRepository.search({ + ...request.payload, + ...request.query, + ...utils.paginate(request), + }) + + return utils.toPagination(request, blocks, 'block') +} + +module.exports = server => { + server.method('v2.blocks.index', index, { + cache: { + expiresIn: 8 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => + generateCacheKey({ + ...request.query, + ...utils.paginate(request), + }), + }) + + server.method('v2.blocks.show', show, { + cache: { + expiresIn: 600 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => generateCacheKey({ id: request.params.id }), + }) + + server.method('v2.blocks.transactions', transactions, { + cache: { + expiresIn: 600 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => + generateCacheKey({ + ...request.query, + ...utils.paginate(request), + }), + }) + + server.method('v2.blocks.search', search, { + cache: { + expiresIn: 30 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => + generateCacheKey({ + ...request.payload, + ...request.query, + ...utils.paginate(request), + }), + }) +} diff --git a/packages/core-api/lib/versions/2/methods/delegates.js b/packages/core-api/lib/versions/2/methods/delegates.js new file mode 100644 index 0000000000..f11268cb5c --- /dev/null +++ b/packages/core-api/lib/versions/2/methods/delegates.js @@ -0,0 +1,159 @@ +const Boom = require('boom') +const orderBy = require('lodash/orderBy') +const app = require('@arkecosystem/core-container') +const generateCacheKey = require('../../../utils/generate-cache-key') +const { blocks: blocksRepository } = require('../../../repositories') +const utils = require('../utils') + +const database = app.resolvePlugin('database') + +const index = async request => { + const delegates = await database.delegates.paginate({ + ...request.query, + ...utils.paginate(request), + }) + + return utils.toPagination(request, delegates, 'delegate') +} + +const show = async request => { + const delegate = await database.delegates.findById(request.params.id) + + if (!delegate) { + return Boom.notFound('Delegate not found') + } + + return utils.respondWithResource(request, delegate, 'delegate') +} + +const search = async request => { + const delegates = await database.delegates.search({ + ...request.payload, + ...request.query, + ...utils.paginate(request), + }) + + return utils.toPagination(request, delegates, 'delegate') +} + +const blocks = async request => { + const delegate = await database.delegates.findById(request.params.id) + + if (!delegate) { + return Boom.notFound('Delegate not found') + } + + const rows = await blocksRepository.findAllByGenerator( + delegate.publicKey, + utils.paginate(request), + ) + + return utils.toPagination(request, rows, 'block') +} + +const voters = async request => { + const delegate = await database.delegates.findById(request.params.id) + + if (!delegate) { + return Boom.notFound('Delegate not found') + } + + const wallets = await database.wallets.findAllByVote( + delegate.publicKey, + utils.paginate(request), + ) + + return utils.toPagination(request, wallets, 'wallet') +} + +const voterBalances = async request => { + const delegate = await database.delegates.findById(request.params.id) + + if (!delegate) { + return Boom.notFound('Delegate not found') + } + + const wallets = await database.wallets + .all() + .filter(wallet => wallet.vote === delegate.publicKey) + + const data = {} + orderBy(wallets, ['balance'], ['desc']).forEach(wallet => { + data[wallet.address] = +wallet.balance.toFixed() + }) + + return { data } +} + +module.exports = server => { + server.method('v2.delegates.index', index, { + cache: { + expiresIn: 8 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => + generateCacheKey({ + ...request.query, + ...utils.paginate(request), + }), + }) + + server.method('v2.delegates.show', show, { + cache: { + expiresIn: 8 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => generateCacheKey({ id: request.params.id }), + }) + + server.method('v2.delegates.search', search, { + cache: { + expiresIn: 30 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => + generateCacheKey({ + ...request.payload, + ...request.query, + ...utils.paginate(request), + }), + }) + + server.method('v2.delegates.blocks', blocks, { + cache: { + expiresIn: 8 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => + generateCacheKey({ + ...{ id: request.params.id }, + ...utils.paginate(request), + }), + }) + + server.method('v2.delegates.voters', voters, { + cache: { + expiresIn: 8 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => + generateCacheKey({ + ...{ id: request.params.id }, + ...utils.paginate(request), + }), + }) + + server.method('v2.delegates.voterBalances', voterBalances, { + cache: { + expiresIn: 8 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => generateCacheKey({ id: request.params.id }), + }) +} diff --git a/packages/core-api/lib/versions/2/methods/transactions.js b/packages/core-api/lib/versions/2/methods/transactions.js new file mode 100644 index 0000000000..a8532091ed --- /dev/null +++ b/packages/core-api/lib/versions/2/methods/transactions.js @@ -0,0 +1,73 @@ +const Boom = require('boom') +const generateCacheKey = require('../../../utils/generate-cache-key') +const { + transactions: transactionsRepository, +} = require('../../../repositories') +const utils = require('../utils') + +const index = async request => { + const transactions = await transactionsRepository.findAll({ + ...request.query, + ...utils.paginate(request), + }) + + return utils.toPagination(request, transactions, 'transaction') +} + +const show = async request => { + const transaction = await transactionsRepository.findById(request.params.id) + + if (!transaction) { + return Boom.notFound('Transaction not found') + } + + return utils.respondWithResource(request, transaction, 'transaction') +} + +const search = async request => { + const transactions = await transactionsRepository.search({ + ...request.query, + ...request.payload, + ...utils.paginate(request), + }) + + return utils.toPagination(request, transactions, 'transaction') +} + +module.exports = server => { + server.method('v2.transactions.index', index, { + cache: { + expiresIn: 8 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => + generateCacheKey({ + ...request.query, + ...utils.paginate(request), + }), + }) + + server.method('v2.transactions.show', show, { + cache: { + expiresIn: 8 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => generateCacheKey({ id: request.params.id }), + }) + + server.method('v2.transactions.search', search, { + cache: { + expiresIn: 30 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => + generateCacheKey({ + ...request.payload, + ...request.query, + ...utils.paginate(request), + }), + }) +} diff --git a/packages/core-api/lib/versions/2/methods/votes.js b/packages/core-api/lib/versions/2/methods/votes.js new file mode 100644 index 0000000000..297766bd20 --- /dev/null +++ b/packages/core-api/lib/versions/2/methods/votes.js @@ -0,0 +1,56 @@ +const Boom = require('boom') +const { TRANSACTION_TYPES } = require('@arkecosystem/crypto').constants +const generateCacheKey = require('../../../utils/generate-cache-key') +const { + transactions: transactionsRepository, +} = require('../../../repositories') +const utils = require('../utils') + +const index = async request => { + const transactions = await transactionsRepository.findAllByType( + TRANSACTION_TYPES.VOTE, + { + ...request.query, + ...utils.paginate(request), + }, + ) + + return utils.toPagination(request, transactions, 'transaction') +} + +const show = async request => { + const transaction = await transactionsRepository.findByTypeAndId( + TRANSACTION_TYPES.VOTE, + request.params.id, + ) + + if (!transaction) { + return Boom.notFound('Vote not found') + } + + return utils.respondWithResource(request, transaction, 'transaction') +} + +module.exports = server => { + server.method('v2.votes.index', index, { + cache: { + expiresIn: 8 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => + generateCacheKey({ + ...request.query, + ...utils.paginate(request), + }), + }) + + server.method('v2.votes.show', show, { + cache: { + expiresIn: 8 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => generateCacheKey({ id: request.params.id }), + }) +} diff --git a/packages/core-api/lib/versions/2/methods/wallets.js b/packages/core-api/lib/versions/2/methods/wallets.js new file mode 100644 index 0000000000..c06de18f69 --- /dev/null +++ b/packages/core-api/lib/versions/2/methods/wallets.js @@ -0,0 +1,219 @@ +const Boom = require('boom') +const app = require('@arkecosystem/core-container') +const generateCacheKey = require('../../../utils/generate-cache-key') +const utils = require('../utils') +const { + transactions: transactionsRepository, +} = require('../../../repositories') + +const database = app.resolvePlugin('database') + +const index = async request => { + const wallets = await database.wallets.findAll({ + ...request.query, + ...utils.paginate(request), + }) + + return utils.toPagination(request, wallets, 'wallet') +} + +const top = async request => { + const wallets = await database.wallets.top(utils.paginate(request)) + + return utils.toPagination(request, wallets, 'wallet') +} + +const show = async request => { + const wallet = await database.wallets.findById(request.params.id) + + if (!wallet) { + return Boom.notFound('Wallet not found') + } + + return utils.respondWithResource(request, wallet, 'wallet') +} + +const transactions = async request => { + const wallet = await database.wallets.findById(request.params.id) + + if (!wallet) { + return Boom.notFound('Wallet not found') + } + + const rows = await transactionsRepository.findAllByWallet(wallet, { + ...request.query, + ...request.params, + ...utils.paginate(request), + }) + + return utils.toPagination(request, rows, 'transaction') +} + +const transactionsSent = async request => { + const wallet = await database.wallets.findById(request.params.id) + + if (!wallet) { + return Boom.notFound('Wallet not found') + } + + // NOTE: We unset this value because it otherwise will produce a faulty SQL query + delete request.params.id + + const rows = await transactionsRepository.findAllBySender(wallet.publicKey, { + ...request.query, + ...request.params, + ...utils.paginate(request), + }) + + return utils.toPagination(request, rows, 'transaction') +} + +const transactionsReceived = async request => { + const wallet = await database.wallets.findById(request.params.id) + + if (!wallet) { + return Boom.notFound('Wallet not found') + } + + // NOTE: We unset this value because it otherwise will produce a faulty SQL query + delete request.params.id + + const rows = await transactionsRepository.findAllByRecipient(wallet.address, { + ...request.query, + ...request.params, + ...utils.paginate(request), + }) + + return utils.toPagination(request, rows, 'transaction') +} + +const votes = async request => { + const wallet = await database.wallets.findById(request.params.id) + + if (!wallet) { + return Boom.notFound('Wallet not found') + } + + // NOTE: We unset this value because it otherwise will produce a faulty SQL query + delete request.params.id + + const rows = await transactionsRepository.allVotesBySender(wallet.publicKey, { + ...request.params, + ...utils.paginate(request), + }) + + return utils.toPagination(request, rows, 'transaction') +} + +const search = async request => { + const wallets = await database.wallets.search({ + ...request.payload, + ...request.query, + ...utils.paginate(request), + }) + + return utils.toPagination(request, wallets, 'wallet') +} + +module.exports = server => { + server.method('v2.wallets.index', index, { + cache: { + expiresIn: 30 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => + generateCacheKey({ + ...request.payload, + ...request.query, + ...utils.paginate(request), + }), + }) + + server.method('v2.wallets.top', top, { + cache: { + expiresIn: 30 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => generateCacheKey(utils.paginate(request)), + }) + + server.method('v2.wallets.show', show, { + cache: { + expiresIn: 30 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => generateCacheKey({ id: request.params.id }), + }) + + server.method('v2.wallets.transactions', transactions, { + cache: { + expiresIn: 30 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => + generateCacheKey({ + ...request.query, + ...request.params, + ...utils.paginate(request), + }), + }) + + server.method('v2.wallets.transactionsSent', transactionsSent, { + cache: { + expiresIn: 30 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => + generateCacheKey({ + ...request.query, + ...request.params, + ...utils.paginate(request), + }), + }) + + server.method('v2.wallets.transactionsReceived', transactionsReceived, { + cache: { + expiresIn: 30 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => + generateCacheKey({ + ...request.query, + ...request.params, + ...utils.paginate(request), + }), + }) + + server.method('v2.wallets.votes', votes, { + cache: { + expiresIn: 30 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => + generateCacheKey({ + ...request.params, + ...utils.paginate(request), + }), + }) + + server.method('v2.wallets.search', search, { + cache: { + expiresIn: 30 * 1000, + generateTimeout: 3000, + getDecoratedValue: true, + }, + generateKey: request => + generateCacheKey({ + ...request.payload, + ...request.query, + ...utils.paginate(request), + }), + }) +} diff --git a/packages/core-api/lib/versions/2/schema/blocks.js b/packages/core-api/lib/versions/2/schema/blocks.js index a37c939617..8960fcab17 100644 --- a/packages/core-api/lib/versions/2/schema/blocks.js +++ b/packages/core-api/lib/versions/2/schema/blocks.js @@ -1,15 +1,47 @@ -'use strict' - const Joi = require('joi') +const pagination = require('./pagination') /** * @type {Object} */ exports.index = { query: { - page: Joi.number().integer(), - limit: Joi.number().integer() - } + ...pagination, + ...{ + orderBy: Joi.string(), + id: Joi.string().regex(/^[0-9]+$/, 'numbers'), + version: Joi.number() + .integer() + .min(0), + timestamp: Joi.number() + .integer() + .min(0), + previousBlock: Joi.string().regex(/^[0-9]+$/, 'numbers'), + height: Joi.number() + .integer() + .positive(), + numberOfTransactions: Joi.number() + .integer() + .min(0), + totalAmount: Joi.number() + .integer() + .min(0), + totalFee: Joi.number() + .integer() + .min(0), + reward: Joi.number() + .integer() + .min(0), + payloadLength: Joi.number() + .integer() + .positive(), + payloadHash: Joi.string().hex(), + generatorPublicKey: Joi.string() + .hex() + .length(66), + blockSignature: Joi.string().hex(), + }, + }, } /** @@ -17,8 +49,8 @@ exports.index = { */ exports.show = { params: { - id: Joi.string() - } + id: Joi.string().regex(/^[0-9]+$/, 'numbers'), + }, } /** @@ -26,56 +58,116 @@ exports.show = { */ exports.transactions = { params: { - id: Joi.string() + id: Joi.string(), }, query: { - page: Joi.number().integer(), - limit: Joi.number().integer() - } + ...pagination, + ...{ + orderBy: Joi.string(), + id: Joi.string() + .hex() + .length(66), + blockId: Joi.string().regex(/^[0-9]+$/, 'numbers'), + type: Joi.number() + .integer() + .min(0), + version: Joi.number() + .integer() + .min(0), + senderPublicKey: Joi.string() + .hex() + .length(66), + senderId: Joi.string() + .alphanum() + .length(34), + recipientId: Joi.string() + .alphanum() + .length(34), + timestamp: Joi.number() + .integer() + .min(0), + amount: Joi.number() + .integer() + .min(0), + fee: Joi.number() + .integer() + .min(0), + vendorFieldHex: Joi.string().hex(), + }, + }, } /** * @type {Object} */ exports.search = { - query: { - page: Joi.number().integer(), - limit: Joi.number().integer() - }, + query: pagination, payload: { - id: Joi.string(), - version: Joi.number().integer(), - previousBlock: Joi.string(), - payloadHash: Joi.string(), - generatorPublicKey: Joi.string(), - blockSignature: Joi.string(), + id: Joi.string().regex(/^[0-9]+$/, 'numbers'), + version: Joi.number() + .integer() + .min(0), + previousBlock: Joi.string().regex(/^[0-9]+$/, 'numbers'), + payloadHash: Joi.string().hex(), + generatorPublicKey: Joi.string() + .hex() + .length(66), + blockSignature: Joi.string().hex(), timestamp: Joi.object().keys({ - from: Joi.number().integer(), - to: Joi.number().integer() + from: Joi.number() + .integer() + .min(0), + to: Joi.number() + .integer() + .min(0), }), height: Joi.object().keys({ - from: Joi.number().integer(), - to: Joi.number().integer() + from: Joi.number() + .integer() + .positive(), + to: Joi.number() + .integer() + .positive(), }), numberOfTransactions: Joi.object().keys({ - from: Joi.number().integer(), - to: Joi.number().integer() + from: Joi.number() + .integer() + .min(0), + to: Joi.number() + .integer() + .min(0), }), totalAmount: Joi.object().keys({ - from: Joi.number().integer(), - to: Joi.number().integer() + from: Joi.number() + .integer() + .min(0), + to: Joi.number() + .integer() + .min(0), }), totalFee: Joi.object().keys({ - from: Joi.number().integer(), - to: Joi.number().integer() + from: Joi.number() + .integer() + .min(0), + to: Joi.number() + .integer() + .min(0), }), reward: Joi.object().keys({ - from: Joi.number().integer(), - to: Joi.number().integer() + from: Joi.number() + .integer() + .min(0), + to: Joi.number() + .integer() + .min(0), }), payloadLength: Joi.object().keys({ - from: Joi.number().integer(), - to: Joi.number().integer() - }) - } + from: Joi.number() + .integer() + .min(0), + to: Joi.number() + .integer() + .min(0), + }), + }, } diff --git a/packages/core-api/lib/versions/2/schema/delegates.js b/packages/core-api/lib/versions/2/schema/delegates.js index 6d5a0e9d19..200911d270 100644 --- a/packages/core-api/lib/versions/2/schema/delegates.js +++ b/packages/core-api/lib/versions/2/schema/delegates.js @@ -1,15 +1,41 @@ -'use strict' - const Joi = require('joi') +const pagination = require('./pagination') /** * @type {Object} */ exports.index = { query: { - page: Joi.number().integer(), - limit: Joi.number().integer() - } + ...pagination, + ...{ + orderBy: Joi.string(), + address: Joi.string() + .alphanum() + .length(34), + publicKey: Joi.string() + .hex() + .length(66), + secondPublicKey: Joi.string() + .hex() + .length(66), + vote: Joi.string() + .hex() + .length(66), + username: Joi.string(), + balance: Joi.number() + .integer() + .min(0), + voteBalance: Joi.number() + .integer() + .min(0), + producedBlocks: Joi.number() + .integer() + .min(0), + missedBlocks: Joi.number() + .integer() + .min(0), + }, + }, } /** @@ -17,21 +43,18 @@ exports.index = { */ exports.show = { params: { - id: Joi.string() - } + id: Joi.string(), + }, } /** * @type {Object} */ exports.search = { - query: { - page: Joi.number().integer(), - limit: Joi.number().integer() - }, + query: pagination, payload: { - username: Joi.string() - } + username: Joi.string(), + }, } /** @@ -39,12 +62,45 @@ exports.search = { */ exports.blocks = { params: { - id: Joi.string() + id: Joi.string(), }, query: { - page: Joi.number().integer(), - limit: Joi.number().integer() - } + ...pagination, + ...{ + orderBy: Joi.string(), + id: Joi.string().regex(/^[0-9]+$/, 'numbers'), + version: Joi.number() + .integer() + .min(0), + timestamp: Joi.number() + .integer() + .min(0), + previousBlock: Joi.string().regex(/^[0-9]+$/, 'numbers'), + height: Joi.number() + .integer() + .positive(), + numberOfTransactions: Joi.number() + .integer() + .min(0), + totalAmount: Joi.number() + .integer() + .min(0), + totalFee: Joi.number() + .integer() + .min(0), + reward: Joi.number() + .integer() + .min(0), + payloadLength: Joi.number() + .integer() + .min(0), + payloadHash: Joi.string().hex(), + generatorPublicKey: Joi.string() + .hex() + .length(66), + blockSignature: Joi.string().hex(), + }, + }, } /** @@ -52,12 +108,39 @@ exports.blocks = { */ exports.voters = { params: { - id: Joi.string() + id: Joi.string(), }, query: { - page: Joi.number().integer(), - limit: Joi.number().integer() - } + ...pagination, + ...{ + orderBy: Joi.string(), + address: Joi.string() + .alphanum() + .length(34), + publicKey: Joi.string() + .hex() + .length(66), + secondPublicKey: Joi.string() + .hex() + .length(66), + vote: Joi.string() + .hex() + .length(66), + username: Joi.string(), + balance: Joi.number() + .integer() + .min(0), + voteBalance: Joi.number() + .integer() + .min(0), + producedBlocks: Joi.number() + .integer() + .min(0), + missedBlocks: Joi.number() + .integer() + .min(0), + }, + }, } /** @@ -65,6 +148,6 @@ exports.voters = { */ exports.voterBalances = { params: { - id: Joi.string() - } + id: Joi.string(), + }, } diff --git a/packages/core-api/lib/versions/2/schema/pagination.js b/packages/core-api/lib/versions/2/schema/pagination.js new file mode 100644 index 0000000000..62543ef181 --- /dev/null +++ b/packages/core-api/lib/versions/2/schema/pagination.js @@ -0,0 +1,14 @@ +const Joi = require('joi') + +module.exports = { + page: Joi.number() + .integer() + .positive(), + offset: Joi.number() + .integer() + .min(0), + limit: Joi.number() + .integer() + .min(1) + .max(100), +} diff --git a/packages/core-api/lib/versions/2/schema/peers.js b/packages/core-api/lib/versions/2/schema/peers.js index 8babe0b5c6..958ce07a61 100644 --- a/packages/core-api/lib/versions/2/schema/peers.js +++ b/packages/core-api/lib/versions/2/schema/peers.js @@ -1,20 +1,21 @@ -'use strict' - const Joi = require('joi') +const pagination = require('./pagination') /** * @type {Object} */ exports.index = { query: { - os: Joi.string(), - status: Joi.string(), - port: Joi.number().integer(), - version: Joi.string(), - orderBy: Joi.string(), - page: Joi.number().integer(), - limit: Joi.number().integer() - } + ...pagination, + ...{ + ip: Joi.string().ip(), + os: Joi.string(), + status: Joi.string(), + port: Joi.number().port(), + version: Joi.string(), + orderBy: Joi.string(), + }, + }, } /** @@ -22,6 +23,6 @@ exports.index = { */ exports.show = { params: { - ip: Joi.string().ip() - } + ip: Joi.string().ip(), + }, } diff --git a/packages/core-api/lib/versions/2/schema/statistics.js b/packages/core-api/lib/versions/2/schema/statistics.js deleted file mode 100644 index a87a102945..0000000000 --- a/packages/core-api/lib/versions/2/schema/statistics.js +++ /dev/null @@ -1,43 +0,0 @@ -'use strict' - -const Joi = require('joi') - -/** - * @type {Object} - */ -exports.transactions = { - query: { - from: Joi.date().timestamp('unix'), - to: Joi.date().timestamp('unix') - } -} - -/** - * @type {Object} - */ -exports.blocks = { - query: { - from: Joi.date().timestamp('unix'), - to: Joi.date().timestamp('unix') - } -} - -/** - * @type {Object} - */ -exports.votes = { - query: { - from: Joi.date().timestamp('unix'), - to: Joi.date().timestamp('unix') - } -} - -/** - * @type {Object} - */ -exports.unvotes = { - query: { - from: Joi.date().timestamp('unix'), - to: Joi.date().timestamp('unix') - } -} diff --git a/packages/core-api/lib/versions/2/schema/transactions.js b/packages/core-api/lib/versions/2/schema/transactions.js index 867f0a0f08..d21de61550 100644 --- a/packages/core-api/lib/versions/2/schema/transactions.js +++ b/packages/core-api/lib/versions/2/schema/transactions.js @@ -1,15 +1,49 @@ -'use strict' - -const Joi = require('joi') +const app = require('@arkecosystem/core-container') +const Joi = require('@arkecosystem/crypto').validator.engine.joi +const pagination = require('./pagination') /** * @type {Object} */ exports.index = { query: { - page: Joi.number().integer(), - limit: Joi.number().integer() - } + ...pagination, + ...{ + orderBy: Joi.string(), + id: Joi.string() + .hex() + .length(64), + blockId: Joi.string().regex(/^[0-9]+$/, 'numbers'), + type: Joi.number() + .integer() + .min(0), + version: Joi.number() + .integer() + .positive(), + senderPublicKey: Joi.string() + .hex() + .length(66), + senderId: Joi.string() + .alphanum() + .length(34), + recipientId: Joi.string() + .alphanum() + .length(34), + ownerId: Joi.string() + .alphanum() + .length(34), + timestamp: Joi.number() + .integer() + .min(0), + amount: Joi.number() + .integer() + .min(0), + fee: Joi.number() + .integer() + .min(0), + vendorFieldHex: Joi.string().hex(), + }, + }, } /** @@ -17,8 +51,13 @@ exports.index = { */ exports.store = { payload: { - transactions: Joi.array().items(Joi.object()) - } + transactions: Joi.arkTransactions() + .min(1) + .max( + app.resolveOptions('transactionPool').maxTransactionsPerRequest, + ) + .options({ stripUnknown: true }), + }, } /** @@ -27,17 +66,16 @@ exports.store = { exports.show = { params: { id: Joi.string() - } + .hex() + .length(64), + }, } /** * @type {Object} */ exports.unconfirmed = { - query: { - page: Joi.number().integer(), - limit: Joi.number().integer() - } + query: pagination, } /** @@ -46,37 +84,64 @@ exports.unconfirmed = { exports.showUnconfirmed = { params: { id: Joi.string() - } + .hex() + .length(64), + }, } /** * @type {Object} */ exports.search = { - query: { - page: Joi.number().integer(), - limit: Joi.number().integer() - }, + query: pagination, payload: { - id: Joi.string(), - blockId: Joi.string(), - type: Joi.number().integer(), - version: Joi.number().integer(), - senderId: Joi.string(), - senderPublicKey: Joi.string(), - recipientId: Joi.string(), + orderBy: Joi.string(), + id: Joi.string() + .hex() + .length(64), + blockId: Joi.string().regex(/^[0-9]+$/, 'numbers'), + type: Joi.number() + .integer() + .min(0), + version: Joi.number() + .integer() + .positive(), + senderPublicKey: Joi.string() + .hex() + .length(66), + senderId: Joi.string() + .alphanum() + .length(34), + recipientId: Joi.string() + .alphanum() + .length(34), + ownerId: Joi.string() + .alphanum() + .length(34), vendorFieldHex: Joi.string().hex(), timestamp: Joi.object().keys({ - from: Joi.number().integer(), - to: Joi.number().integer() + from: Joi.number() + .integer() + .min(0), + to: Joi.number() + .integer() + .min(0), }), amount: Joi.object().keys({ - from: Joi.number().integer(), - to: Joi.number().integer() + from: Joi.number() + .integer() + .min(0), + to: Joi.number() + .integer() + .min(0), }), fee: Joi.object().keys({ - from: Joi.number().integer(), - to: Joi.number().integer() - }) - } + from: Joi.number() + .integer() + .min(0), + to: Joi.number() + .integer() + .min(0), + }), + }, } diff --git a/packages/core-api/lib/versions/2/schema/votes.js b/packages/core-api/lib/versions/2/schema/votes.js index 7b973e13b3..c98075f7b7 100644 --- a/packages/core-api/lib/versions/2/schema/votes.js +++ b/packages/core-api/lib/versions/2/schema/votes.js @@ -1,15 +1,42 @@ -'use strict' - const Joi = require('joi') +const pagination = require('./pagination') /** * @type {Object} */ exports.index = { query: { - page: Joi.number().integer(), - limit: Joi.number().integer() - } + ...pagination, + ...{ + orderBy: Joi.string(), + id: Joi.string() + .hex() + .length(64), + blockId: Joi.string().regex(/^[0-9]+$/, 'numbers'), + version: Joi.number() + .integer() + .positive(), + senderPublicKey: Joi.string() + .hex() + .length(66), + senderId: Joi.string() + .alphanum() + .length(34), + recipientId: Joi.string() + .alphanum() + .length(34), + timestamp: Joi.number() + .integer() + .min(0), + amount: Joi.number() + .integer() + .min(0), + fee: Joi.number() + .integer() + .min(0), + vendorFieldHex: Joi.string().hex(), + }, + }, } /** @@ -18,5 +45,7 @@ exports.index = { exports.show = { params: { id: Joi.string() - } + .hex() + .length(64), + }, } diff --git a/packages/core-api/lib/versions/2/schema/wallets.js b/packages/core-api/lib/versions/2/schema/wallets.js index 8ac79ee00b..1c086c9b9a 100644 --- a/packages/core-api/lib/versions/2/schema/wallets.js +++ b/packages/core-api/lib/versions/2/schema/wallets.js @@ -1,15 +1,39 @@ -'use strict' - const Joi = require('joi') +const pagination = require('./pagination') /** * @type {Object} */ exports.index = { query: { - page: Joi.number().integer(), - limit: Joi.number().integer() - } + ...pagination, + ...{ + orderBy: Joi.string(), + address: Joi.string() + .alphanum() + .length(34), + publicKey: Joi.string() + .hex() + .length(66), + secondPublicKey: Joi.string() + .hex() + .length(66), + vote: Joi.string() + .hex() + .length(66), + username: Joi.string(), + balance: Joi.number().integer(), + voteBalance: Joi.number() + .integer() + .min(0), + producedBlocks: Joi.number() + .integer() + .min(0), + missedBlocks: Joi.number() + .integer() + .min(0), + }, + }, } /** @@ -17,8 +41,8 @@ exports.index = { */ exports.show = { params: { - id: Joi.string() - } + id: Joi.string(), + }, } /** @@ -26,12 +50,12 @@ exports.show = { */ exports.transactions = { params: { - id: Joi.string() + id: Joi.string(), }, query: { - page: Joi.number().integer(), - limit: Joi.number().integer() - } + ...pagination, + orderBy: Joi.string(), + }, } /** @@ -39,12 +63,12 @@ exports.transactions = { */ exports.transactionsSent = { params: { - id: Joi.string() + id: Joi.string(), }, query: { - page: Joi.number().integer(), - limit: Joi.number().integer() - } + ...pagination, + orderBy: Joi.string(), + }, } /** @@ -52,12 +76,12 @@ exports.transactionsSent = { */ exports.transactionsReceived = { params: { - id: Joi.string() + id: Joi.string(), }, query: { - page: Joi.number().integer(), - limit: Joi.number().integer() - } + ...pagination, + orderBy: Joi.string(), + }, } /** @@ -65,35 +89,48 @@ exports.transactionsReceived = { */ exports.votes = { params: { - id: Joi.string() + id: Joi.string(), }, - query: { - page: Joi.number().integer(), - limit: Joi.number().integer() - } + query: pagination, } /** * @type {Object} */ exports.search = { - query: { - page: Joi.number().integer(), - limit: Joi.number().integer() - }, + query: pagination, payload: { - address: Joi.string(), - publicKey: Joi.string(), - secondPublicKey: Joi.string(), - vote: Joi.string(), + orderBy: Joi.string(), + address: Joi.string() + .alphanum() + .length(34), + publicKey: Joi.string() + .hex() + .length(66), + secondPublicKey: Joi.string() + .hex() + .length(66), + vote: Joi.string() + .hex() + .length(66), username: Joi.string(), + producedBlocks: Joi.number() + .integer() + .min(0), + missedBlocks: Joi.number() + .integer() + .min(0), balance: Joi.object().keys({ from: Joi.number().integer(), - to: Joi.number().integer() + to: Joi.number().integer(), }), - votebalance: Joi.object().keys({ - from: Joi.number().integer(), - to: Joi.number().integer() - }) - } + voteBalance: Joi.object().keys({ + from: Joi.number() + .integer() + .min(0), + to: Joi.number() + .integer() + .min(0), + }), + }, } diff --git a/packages/core-api/lib/versions/2/transformers/block.js b/packages/core-api/lib/versions/2/transformers/block.js index f940a8ca9d..45baf0495c 100644 --- a/packages/core-api/lib/versions/2/transformers/block.js +++ b/packages/core-api/lib/versions/2/transformers/block.js @@ -1,38 +1,44 @@ -'use strict' - -const database = require('@arkecosystem/core-container').resolvePlugin('database') -const formatTimestamp = require('./utils/format-timestamp') +const database = require('@arkecosystem/core-container').resolvePlugin( + 'database', +) +const { formatTimestamp, bignumify } = require('@arkecosystem/core-utils') /** * Turns a "block" object into a generic object. * @param {Object} model * @return {Object} */ -module.exports = (model) => { - const generator = database.walletManager.getWalletByPublicKey(model.generatorPublicKey) +module.exports = model => { + const generator = database.walletManager.findByPublicKey( + model.generatorPublicKey, + ) + + model.reward = bignumify(model.reward) + model.totalFee = bignumify(model.totalFee) return { id: model.id, - version: model.version, - height: model.height, + version: +model.version, + height: +model.height, previous: model.previousBlock, forged: { - reward: Number(model.reward), - fee: Number(model.totalFee), - total: Number(model.reward) + Number(model.totalFee) + reward: +model.reward.toFixed(), + fee: +model.totalFee.toFixed(), + total: +model.reward.plus(model.totalFee).toFixed(), + amount: +bignumify(model.totalAmount).toFixed(), }, payload: { hash: model.payloadHash, - length: model.payloadLength + length: model.payloadLength, }, generator: { username: generator.username, address: generator.address, - publicKey: generator.publicKey + publicKey: generator.publicKey, }, signature: model.blockSignature, confirmations: model.confirmations, transactions: model.numberOfTransactions, - timestamp: formatTimestamp(model.timestamp) + timestamp: formatTimestamp(model.timestamp), } } diff --git a/packages/core-api/lib/versions/2/transformers/delegate.js b/packages/core-api/lib/versions/2/transformers/delegate.js index 00bc21e962..ef81fb2246 100644 --- a/packages/core-api/lib/versions/2/transformers/delegate.js +++ b/packages/core-api/lib/versions/2/transformers/delegate.js @@ -1,28 +1,34 @@ -'use strict' - -const { calculateApproval, calculateProductivity } = require('../../../utils/delegate-calculator') -const formatTimestamp = require('./utils/format-timestamp') +const { + bignumify, + formatTimestamp, + delegateCalculator, +} = require('@arkecosystem/core-utils') /** * Turns a "delegate" object into a generic object. * @param {Object} delegate * @return {Object} */ -module.exports = (delegate) => { +module.exports = delegate => { const data = { username: delegate.username, address: delegate.address, publicKey: delegate.publicKey, - votes: delegate.votebalance, + votes: +bignumify(delegate.voteBalance).toFixed(), rank: delegate.rate, blocks: { produced: delegate.producedBlocks, - missed: delegate.missedBlocks + missed: delegate.missedBlocks, }, production: { - approval: calculateApproval(delegate), - productivity: calculateProductivity(delegate) - } + approval: delegateCalculator.calculateApproval(delegate), + productivity: delegateCalculator.calculateProductivity(delegate), + }, + forged: { + fees: +delegate.forgedFees.toFixed(), + rewards: +delegate.forgedRewards.toFixed(), + total: +delegate.forgedFees.plus(delegate.forgedRewards).toFixed(), + }, } const lastBlock = delegate.lastBlock @@ -30,7 +36,7 @@ module.exports = (delegate) => { if (lastBlock) { data.blocks.last = { id: lastBlock.id, - timestamp: formatTimestamp(lastBlock.timestamp) + timestamp: formatTimestamp(lastBlock.timestamp), } } diff --git a/packages/core-api/lib/versions/2/transformers/fee-statistics.js b/packages/core-api/lib/versions/2/transformers/fee-statistics.js index 64500e0a67..2a5e5fd250 100644 --- a/packages/core-api/lib/versions/2/transformers/fee-statistics.js +++ b/packages/core-api/lib/versions/2/transformers/fee-statistics.js @@ -1,17 +1,13 @@ -'use strict' - /** * Turns a "fee-statistics" object into readable object. * @param {Object} model * @return {Object} */ -module.exports = (model) => { - return { - type: model.type, - fees: { - minFee: parseInt(model.minFee), - maxFee: parseInt(model.maxFee), - avgFee: parseInt(model.avgFee) - } - } -} +module.exports = model => ({ + type: model.type, + fees: { + minFee: parseInt(model.minFee), + maxFee: parseInt(model.maxFee), + avgFee: parseInt(model.avgFee), + }, +}) diff --git a/packages/core-api/lib/versions/2/transformers/peer.js b/packages/core-api/lib/versions/2/transformers/peer.js index 8824277bfd..379050e9d2 100644 --- a/packages/core-api/lib/versions/2/transformers/peer.js +++ b/packages/core-api/lib/versions/2/transformers/peer.js @@ -1,18 +1,26 @@ -'use strict' +const app = require('@arkecosystem/core-container') + +const config = app.resolvePlugin('config') /** * Turns a "peer" object into a generic object. * @param {Object} model * @return {Object} */ -module.exports = (model) => { - return { +module.exports = model => { + const peer = { ip: model.ip, - port: model.port, + port: +model.port, version: model.version, - height: model.height, + height: model.state ? model.state.height : model.height, status: model.status, os: model.os, - latency: model.delay + latency: model.delay, + } + + if (config.network.name !== 'mainnet') { + peer.hashid = model.hashid || 'unknown' } + + return peer } diff --git a/packages/core-api/lib/versions/2/transformers/ports.js b/packages/core-api/lib/versions/2/transformers/ports.js index 0dc43b473e..02f3f4ee21 100644 --- a/packages/core-api/lib/versions/2/transformers/ports.js +++ b/packages/core-api/lib/versions/2/transformers/ports.js @@ -1,23 +1,21 @@ -'use strict' - /** * Turns a "config" object into readable object. * @param {Object} model * @return {Object} */ -module.exports = (config) => { - let result = {} +module.exports = config => { + const result = {} const keys = [ '@arkecosystem/core-p2p', '@arkecosystem/core-api', '@arkecosystem/core-graphql', '@arkecosystem/core-json-rpc', - '@arkecosystem/core-webhooks' + '@arkecosystem/core-webhooks', ] result[keys[0]] = config.plugins[keys[0]].port - for (let [name, options] of Object.entries(config.plugins)) { + for (const [name, options] of Object.entries(config.plugins)) { if (keys.includes(name) && options.enabled) { if (options.server && options.server.enabled) { result[name] = options.server.port diff --git a/packages/core-api/lib/versions/2/transformers/transaction.js b/packages/core-api/lib/versions/2/transformers/transaction.js index 5dff0e6020..d144ba5c95 100644 --- a/packages/core-api/lib/versions/2/transformers/transaction.js +++ b/packages/core-api/lib/versions/2/transformers/transaction.js @@ -1,35 +1,36 @@ -'use strict' +const app = require('@arkecosystem/core-container') -const container = require('@arkecosystem/core-container') -const config = container.resolvePlugin('config') -const blockchain = container.resolvePlugin('blockchain') +const config = app.resolvePlugin('config') +const blockchain = app.resolvePlugin('blockchain') const { crypto } = require('@arkecosystem/crypto') const { Transaction } = require('@arkecosystem/crypto').models -const formatTimestamp = require('./utils/format-timestamp') +const { bignumify, formatTimestamp } = require('@arkecosystem/core-utils') /** * Turns a "transaction" object into a generic object. * @param {Object} model * @return {Object} */ -module.exports = (model) => { - const data = Transaction.deserialize(model.serialized.toString('hex')) +module.exports = model => { + const data = new Transaction(model.serialized.toString('hex')) const lastBlock = blockchain.getLastBlock() return { id: data.id, blockId: model.blockId, type: data.type, - amount: data.amount, - fee: data.fee, + amount: +bignumify(data.amount).toFixed(), + fee: +bignumify(data.fee).toFixed(), sender: crypto.getAddress(data.senderPublicKey, config.network.pubKeyHash), recipient: data.recipientId, signature: data.signature, + signSignature: data.signSignature, + signatures: data.signatures, vendorField: data.vendorField, asset: data.asset, confirmations: model.block ? lastBlock.data.height - model.block.height : 0, - timestamp: formatTimestamp(data.timestamp) + timestamp: formatTimestamp(data.timestamp), } } diff --git a/packages/core-api/lib/versions/2/transformers/utils/format-timestamp.js b/packages/core-api/lib/versions/2/transformers/utils/format-timestamp.js deleted file mode 100644 index ec94bd6b9f..0000000000 --- a/packages/core-api/lib/versions/2/transformers/utils/format-timestamp.js +++ /dev/null @@ -1,19 +0,0 @@ -'use strict' - -const moment = require('moment') -const config = require('@arkecosystem/core-container').resolvePlugin('config') - -/** - * Format the given epoch based timestamp into human and unix. - * @param {Number} epochStamp - * @return {Object} - */ -module.exports = (epochStamp) => { - const timestamp = moment(config.getConstants(1).epoch).utc().add(epochStamp, 'seconds') - - return { - epoch: epochStamp, - unix: timestamp.unix(), - human: timestamp.format() - } -} diff --git a/packages/core-api/lib/versions/2/transformers/wallet.js b/packages/core-api/lib/versions/2/transformers/wallet.js index 6f91c4974d..584e5b6ae9 100644 --- a/packages/core-api/lib/versions/2/transformers/wallet.js +++ b/packages/core-api/lib/versions/2/transformers/wallet.js @@ -1,16 +1,15 @@ -'use strict' +const { bignumify } = require('@arkecosystem/core-utils') /** * Turns a "wallet" object into a generic object. * @param {Object} model * @return {Object} */ -module.exports = (model) => { - return { - address: model.address, - publicKey: model.publicKey, - secondPublicKey: model.secondPublicKey, - balance: model.balance, - isDelegate: !!model.username - } -} +module.exports = model => ({ + address: model.address, + publicKey: model.publicKey, + username: model.username, + secondPublicKey: model.secondPublicKey, + balance: +bignumify(model.balance).toFixed(), + isDelegate: !!model.username, +}) diff --git a/packages/core-api/lib/versions/2/utils.js b/packages/core-api/lib/versions/2/utils.js index 400bac4638..262aa477a1 100644 --- a/packages/core-api/lib/versions/2/utils.js +++ b/packages/core-api/lib/versions/2/utils.js @@ -1,18 +1,25 @@ -'use strict' - const Boom = require('boom') -const { transformResource, transformCollection } = require('../../utils/transformer') +const { + transformResource, + transformCollection, +} = require('../../utils/transformer') /** * Create a pagination object for the request. * @param {Hapi.Request} request * @return {Object} */ -const paginate = (request) => { - return { +const paginate = request => { + const pagination = { offset: (request.query.page - 1) * request.query.limit || 0, - limit: request.query.limit || 100 + limit: request.query.limit || 100, + } + + if (request.query.offset) { + pagination.offset = request.query.offset } + + return pagination } /** @@ -22,11 +29,10 @@ const paginate = (request) => { * @param {String} transformer * @return {Object} */ -const respondWithResource = (request, data, transformer) => { - return data +const respondWithResource = (request, data, transformer) => + data ? { data: transformResource(request, data, transformer) } : Boom.notFound() -} /** * Respond with a collection. @@ -35,8 +41,23 @@ const respondWithResource = (request, data, transformer) => { * @param {String} transformer * @return {Object} */ -const respondWithCollection = (request, data, transformer) => { - return { data: transformCollection(request, data, transformer) } +const respondWithCollection = (request, data, transformer) => ({ + data: transformCollection(request, data, transformer), +}) + +/** + * Respond with data from cache. + * @param {Object} data + * @param {Hapi.Toolkit} h + * @return {Object} + */ +const respondWithCache = (data, h) => { + const { value, cached } = data + const lastModified = cached ? new Date(cached.stored) : new Date() + + return value.isBoom + ? h.response(value.output.payload).code(value.output.statusCode) + : h.response(value).header('Last-modified', lastModified.toUTCString()) } /** @@ -46,9 +67,8 @@ const respondWithCollection = (request, data, transformer) => { * @param {String} transformer * @return {Object} */ -const toResource = (request, data, transformer) => { - return transformResource(request, data, transformer) -} +const toResource = (request, data, transformer) => + transformResource(request, data, transformer) /** * Transform the given data into a collection. @@ -57,9 +77,8 @@ const toResource = (request, data, transformer) => { * @param {String} transformer * @return {Object} */ -const toCollection = (request, data, transformer) => { - return transformCollection(request, data, transformer) -} +const toCollection = (request, data, transformer) => + transformCollection(request, data, transformer) /** * Transform the given data into a pagination. @@ -68,12 +87,10 @@ const toCollection = (request, data, transformer) => { * @param {String} transformer * @return {Object} */ -const toPagination = (request, data, transformer) => { - return { - results: transformCollection(request, data.rows, transformer), - totalCount: data.count - } -} +const toPagination = (request, data, transformer) => ({ + results: transformCollection(request, data.rows, transformer), + totalCount: data.count, +}) /** * @type {Object} @@ -82,7 +99,8 @@ module.exports = { paginate, respondWithResource, respondWithCollection, + respondWithCache, toResource, toCollection, - toPagination + toPagination, } diff --git a/packages/core-api/package.json b/packages/core-api/package.json index 2885c12bb9..fc2b9c3c5b 100644 --- a/packages/core-api/package.json +++ b/packages/core-api/package.json @@ -1,7 +1,7 @@ { "name": "@arkecosystem/core-api", - "description": "Public API for ARK Core", - "version": "0.1.1", + "description": "Public API for Ark Core", + "version": "0.2.0", "contributors": [ "Kristjan Košič ", "Brian Faust " @@ -9,43 +9,41 @@ "license": "MIT", "main": "lib/index.js", "scripts": { - "build:docs": "../../node_modules/.bin/jsdoc -c jsdoc.json", "test": "cross-env ARK_ENV=test jest --runInBand --detectOpenHandles", - "test:coverage": "cross-env ARK_ENV=test jest --coverage --runInBand --detectOpenHandles", - "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand --watch", + "test:coverage": "cross-env ARK_ENV=test jest --coverage --coveragePathIgnorePatterns='/(defaults.js|index.js)$' --runInBand --detectOpenHandles", + "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand", "test:watch": "cross-env ARK_ENV=test jest --runInBand --watch", "test:watch:all": "cross-env ARK_ENV=test jest --runInBand --watchAll", "lint": "eslint ./ --fix", - "depcheck": "depcheck ./ --ignores catbox-redis" + "depcheck": "depcheck ./ --ignores=lodash,lodash.*" }, "dependencies": { - "@arkecosystem/core-container": "^0.1.1", - "@arkecosystem/core-transaction-pool": "^0.1.1", - "@arkecosystem/crypto": "^0.1.1", - "ajv": "^6.5.0", - "bignumber.js": "^7.1.0", - "boom": "^7.2.0", - "bs58check": "^2.1.1", - "catbox-redis": "^4.1.0", - "hapi": "^17.5.0", - "hapi-api-version": "https://github.com/faustbrian/hapi-api-version", + "@arkecosystem/core-container": "~0.2", + "@arkecosystem/core-http-utils": "~0.2", + "@arkecosystem/core-transaction-pool": "~0.2", + "@arkecosystem/core-utils": "~0.2", + "@arkecosystem/crypto": "~0.2", + "ajv": "^6.5.5", + "boom": "^7.3.0", + "bs58check": "^2.1.2", + "dayjs-ext": "^2.2.0", + "hapi-api-version": "^2.1.0", "hapi-pagination": "https://github.com/faustbrian/hapi-pagination", - "hapi-rate-limit": "^2.1.2", - "inert": "^5.1.0", + "hapi-rate-limit": "^2.1.4", "ip": "^1.1.5", - "joi": "^13.3.0", - "lodash": "^4.17.10", - "lout": "^11.0.1", - "micromatch": "^3.1.10", - "moment": "^2.22.1", - "request-ip": "^2.1.1", - "vision": "^5.3.2" + "joi": "^14.3.0", + "lodash": "^4.17.11", + "lodash.orderby": "^4.6.0", + "lodash.snakecase": "^4.1.1" + }, + "devDependencies": { + "@arkecosystem/core-test-utils": "~0.2", + "axios": "^0.18.0" }, "publishConfig": { "access": "public" }, - "devDependencies": { - "@arkecosystem/core-test-utils": "^0.1.1", - "axios": "^0.18.0" + "engines": { + "node": ">=10.x" } } diff --git a/packages/core-blockchain/CHANGELOG.md b/packages/core-blockchain/CHANGELOG.md index 127cc35e42..a610e92d4e 100644 --- a/packages/core-blockchain/CHANGELOG.md +++ b/packages/core-blockchain/CHANGELOG.md @@ -7,6 +7,28 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Unreleased -## 0.0.1 - 2018-05-31 +## 0.2.0 - 2018-12-03 + +### Added + +- More graceful handling of shutdown +- State Storage to handle state machine data +- Peer banning after forks + +### Changed + +- Improved the logic of how blocks are being processed +- Dropped node.js 9 as minimum requirement in favour of node.js 10 + +### Fixed + +- Properly stop blockchain if manually started +- Various state issues with the last downloaded blocks +- Various state issues with the wallet manager +- Properly handle forks while idle + +## 0.1.1 - 2018-06-14 + ### Added + - initial release diff --git a/packages/core-blockchain/README.md b/packages/core-blockchain/README.md index f3029c44e0..3254f8dc58 100644 --- a/packages/core-blockchain/README.md +++ b/packages/core-blockchain/README.md @@ -1,12 +1,12 @@ -![ARK Core](https://i.imgur.com/1aP6F2o.png) +# Ark Core - Blockchain -# ARK Core - Blockchain Management +

+ +

-## Installation +## Documentation -```bash -yarn add @arkecosystem/core-blockchain -``` +You can find installation instructions and detailed instructions on how to use this package at the [dedicated documentation site](https://docs.ark.io/guidebook/core/plugins/core-blockchain.html). ## Security diff --git a/packages/core-blockchain/__tests__/__fixtures__/genesisBlock.js b/packages/core-blockchain/__tests__/__fixtures__/genesisBlock.js deleted file mode 100644 index e01041c65e..0000000000 --- a/packages/core-blockchain/__tests__/__fixtures__/genesisBlock.js +++ /dev/null @@ -1,845 +0,0 @@ -const { Block } = require('@arkecosystem/crypto').models - -module.exports = new Block({ - 'version': 0, - 'totalAmount': 12500000000000000, - 'totalFee': 0, - 'reward': 0, - 'payloadHash': '578e820911f24e039733b45e4882b73e301f813a0d2c31330dafda84534ffa23', - 'timestamp': 0, - 'numberOfTransactions': 52, - 'payloadLength': 11401, - 'previousBlock': null, - 'generatorPublicKey': '024c8247388a02ecd1de2a3e3fd5b7c61ecc2797fa3776599d558333ef1802d231', - 'transactions': [{ - 'type': 0, - 'amount': 12500000000000000, - 'fee': 0, - 'recipientId': 'DGihocTkwDygiFvmg6aG8jThYTic47GzU9', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '03cb7bca143376721d0e9e3f3ccb0dc2e7e8470c06e630c3cef73f03e309b558ad', - 'signature': '3044022016ecdf3039e69514c7d75861b22fc076496b61c07a1fcf793dc4f5c76fa0532b0220579c4c0c9d13720f9db5d9df29ed8ceab0adc266c6c160d612d4894dc5867eb1', - 'id': 'e40ce11cab82736da1cc91191716f3c1f446ca7b6a9f4f93b7120ef105ba06e8', - 'senderId': 'DUFeXjJmYt1mWY3auywA1EQSqfCv5kYYfP' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03e5b39a83e6c7c952c5908089d4524bb8dda93acc2b2b953247e43dc4fe9aa3d1', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_1', - 'publicKey': '03e5b39a83e6c7c952c5908089d4524bb8dda93acc2b2b953247e43dc4fe9aa3d1' - } - }, - 'signature': '3045022100e3e38811778023e6f17fefd447f179d45ab92c398c7cfb1e34e2f6e1b167c95a022070c36439ecec0fc3c43850070f29515910435d389e059579878d61b5ff2ea337', - 'id': 'eb0146ac79afc228f0474a5ae1c4771970ae7880450b998c401029f522cd8a21', - 'senderId': 'DNL81CT6WNG1PHjobBmLvKwLV3UUscBymB' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '031137050d5fed0b5229b150257da2ac9c135efdf4bcb382b0ad0c197d7be458f4', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_3', - 'publicKey': '031137050d5fed0b5229b150257da2ac9c135efdf4bcb382b0ad0c197d7be458f4' - } - }, - 'signature': '30440220124baaa04491287d0abbf5a167c9b0f5ac95c22b196f42ff3d275cc9a213c2fd02206e6ebada85f67063e642dbcde6b956f8c99c05f4b9c55f1551d3eebba6375043', - 'id': 'c9c554056b3428951633a7059dd64dfcbd776fef7f4a156ea362b37ee6ce74c7', - 'senderId': 'DG9LYv5rqX67wuGvGVa9is5k1r86LKCVTA' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '037def83d085778d7767a182a179f345207953441089081f5bc13f86d3891308aa', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_4', - 'publicKey': '037def83d085778d7767a182a179f345207953441089081f5bc13f86d3891308aa' - } - }, - 'signature': '3045022100900cea3c2df393414899c9d74db57d89c9f311c70d08b974d0fd4a98bfae2fc902204a2aa51a1ec71da27c26afc033de6bd2d15978813c120c95e1a4dafca75ce876', - 'id': 'c82ccaa16be0e3c7ff4a53e2807968b71a0d88115223c3af2eb320f32449ac32', - 'senderId': 'DMSwarrHg5N9ZAZ6nsqPuUjyAU6gdRAM9d' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '033f28ad2e9b897d46f1e67c7c52070e9ca46b04c0679ebb21fb236719e38aade3', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_5', - 'publicKey': '033f28ad2e9b897d46f1e67c7c52070e9ca46b04c0679ebb21fb236719e38aade3' - } - }, - 'signature': '30440220285188d8900cd3cffccf5e1de305b18856451dd04d2ed21165dffe9a7ce4afc1022009457be6bfe536971697105d47ad1f829738a5cacdb27a23c5d1e8a8dddf3ebd', - 'id': 'ee6a19fff622ab4e6e96d159396de56d6034b4b18a9cf5c99efcf4e61b28e15a', - 'senderId': 'DFcYHfCwhGWcBNy6cp48wy5SfXbQmfBYgT' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '023e577a7b3362e0aba70e6911d230e86d729b4cb640f0e0b25637b812a3e38b53', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_6', - 'publicKey': '023e577a7b3362e0aba70e6911d230e86d729b4cb640f0e0b25637b812a3e38b53' - } - }, - 'signature': '3045022100afa56542dd473c424b36d4d9f24da68180cfd90527681ab84098f415b2544a8702201e8ebdd619a2dd200e37a57c39a4529afe76d35f6089c00f6dffba6bf7b8a836', - 'id': '0dcd6e380bd7eaef8724f64f4b86104ce7497308dacf775afbe6ec0d401007fe', - 'senderId': 'D5e2FzTPqdEHridjzpFZCCVyepAu6Vpmk4' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02af5e6341efc14f4ba39a9ff65e151cc7304fc742ce7b2678d9aa446c555ee9c1', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_7', - 'publicKey': '02af5e6341efc14f4ba39a9ff65e151cc7304fc742ce7b2678d9aa446c555ee9c1' - } - }, - 'signature': '3045022100c8980155c8f8964d76baf3e8d690075708f1a84757c1de52e311772466382da2022012599acfc7839fa1ef6bbd445ab34555fb718491db3089f40d4842b1bc2d3178', - 'id': '8af6abb117c69c130e388970d595b741374b1bbca709d9e91459e9e3c721397b', - 'senderId': 'DDLbnve6XK48cGsQiFhesUJQRQdKkZTfPh' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02845161cfca4d6ddde8e0d53538b6f881fb3ad9383cd77cebc55375dd6fd17663', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_8', - 'publicKey': '02845161cfca4d6ddde8e0d53538b6f881fb3ad9383cd77cebc55375dd6fd17663' - } - }, - 'signature': '30450221009bce7c5c10a4b6306cebe5724adfd3de049a425c44dd314a10154774764c11090220070fb775e71dda6a68f7fc9e0c762fbf96021908911f0de0ca8e9b0c613cb896', - 'id': 'bd346035d4516b85fb3a2cce6260fdcc6f1c434999e586978e065de3bf98e02a', - 'senderId': 'DDAHPjVTTV3uur653TB27fcLGh7XXWnvxW' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03f264a6d2ebb62279313a6fd7fec4e2244785839b625a0b0c261e689ce5401d87', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_9', - 'publicKey': '03f264a6d2ebb62279313a6fd7fec4e2244785839b625a0b0c261e689ce5401d87' - } - }, - 'signature': '30450221009f74425c2ec50dbee462e735dee3e7917c8433fd5250ff09af4506c38d2df05902206a14a19b9a5defe3c8c59c77d52c182ea34d81d2e0b05dc5925133f2829a1960', - 'id': 'b48068fb7c848ffd57e82a4d381f53bb69916f3943e0e8935971a028ba245564', - 'senderId': 'DFHdEBuVCz5zfj8yeo3BmKEdsEKpMaYRRw' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03efd265a086c2a099cda4f4fd202adbac07567e1229ce5e6fe39963b714c1e2d5', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_10', - 'publicKey': '03efd265a086c2a099cda4f4fd202adbac07567e1229ce5e6fe39963b714c1e2d5' - } - }, - 'signature': '3044022004df492965ed328134aa6443d38ac4dd951a640e00330da9aa4e80c1577af41a0220588f030f5f9584959647898bb977a1ffe6bba639b1c64a728880f2cd3fd7aa3c', - 'id': '73b3b4375e39aabe51ec205559cd728a18c987dabaa0599c611b3076c38c7a49', - 'senderId': 'DL7Y6smfHHs3Ms3hAYmSYYd5PZukmtDY1i' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '027d616d20f03c375067676c79ff9787e8e42991fbd9e878501d704d23d246d9b0', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_11', - 'publicKey': '027d616d20f03c375067676c79ff9787e8e42991fbd9e878501d704d23d246d9b0' - } - }, - 'signature': '3044022051c2f8af62163ca621eeb3087a35bfaca0d679f7be8b19a25972f5a4b24ad8c90220422f3e0e480bf1bf2211e871a102edc15a957c0f97a553d9d707418e6538df26', - 'id': '80f1d01158452da31d44f0c24f464a0ade37da51d2f61356ad75a019a91a1ff5', - 'senderId': 'DBVoRSXBHBPPvssBXrswv22r4dUSpN1fbA' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '038918951152a37b74dfe61115f83e4b5e3521145065650c4a6d3e94add57d9a9b', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_12', - 'publicKey': '038918951152a37b74dfe61115f83e4b5e3521145065650c4a6d3e94add57d9a9b' - } - }, - 'signature': '3045022100facf6ed992c28d41595419666b006800fcb33c6bad4b522e013b4d688e51dc8502207695e968059f7a35486389c430d6a3037e69d3e5f1d4f0a294d8818e4750cf0d', - 'id': '86d76b0aad8f496d8c20926bfdeb50ad10db242ea6152b68266680c48e1e1aca', - 'senderId': 'DHsSK81gRWjgNx1A9gtHgkRsEwshsog7AM' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03231d8f2f39925fa79efc8f8561e6a8d29b95164a753cbb604a46e8a2e96606fc', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_13', - 'publicKey': '03231d8f2f39925fa79efc8f8561e6a8d29b95164a753cbb604a46e8a2e96606fc' - } - }, - 'signature': '304402204c627ec3d24fb7b4f86709c0566cee9909ebddb26039e87a2fa673f1f7227362022003be5aa3303b8f4cdab768f80b4699440a61814950cab0fd983526771c4c52ec', - 'id': '464614909ac7531a016a0489d78defe262dc0934324f41199975ad42a86f37ac', - 'senderId': 'DDr7UTGQuPTjxLDWZ8RMjWJMKNXAMj3Bor' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '021e6d971e5885a3147ddf1e45bf5c8d0887ad9fc659e24bdf95c2c9607e7e3fe8', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_14', - 'publicKey': '021e6d971e5885a3147ddf1e45bf5c8d0887ad9fc659e24bdf95c2c9607e7e3fe8' - } - }, - 'signature': '3045022100898e59efe518745d3eb3f2b16f7b6192e3289bb4289d43013224549f2015aa4902204e7be92cbba37a05551151e46224da4e5d0ad86ee2106d3a9c0b9afee5f1c4cf', - 'id': '9559866ff439959529f69b0947ad2e72d739511ee1f6533c0bca2ebd6dd4ae4a', - 'senderId': 'DRXNNQ9gQXh6VNUVKaAn9xHAViyiHKtBHZ' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03d5b3efbe98631443c5cdf4de8a610dd2655b86427bf70aa209451b54256f6758', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_15', - 'publicKey': '03d5b3efbe98631443c5cdf4de8a610dd2655b86427bf70aa209451b54256f6758' - } - }, - 'signature': '3044022037fa085e37a582b2e0b3734d44b813bb18be939f73100c5b6f977d4f53ae708f022064ae54f6a1b17b193ab6b6d633f7b7a7b8171a158cdba7480afe380f383930dc', - 'id': '7bab92d5397a4ad291c5d01b8d681e480d19b437a7ab5cbd4c6807c96ef2716f', - 'senderId': 'DT12wf9erZyNJbBQrpbPDmfH3J8txiDgTE' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0297f2e8e609b2a6799214481e7573a043a197f8adf7b8bb306576fc3da83d2aaa', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_16', - 'publicKey': '0297f2e8e609b2a6799214481e7573a043a197f8adf7b8bb306576fc3da83d2aaa' - } - }, - 'signature': '304402202eee94bc3b53c64f8dee7790fe3eed8639da8faf0aa1f785e921cf139df0fb7e02200224efb0c07ae3972287c12a32143c1356adb93e00ac9e04a1358c8245a24cab', - 'id': '1e59740fa596b615231660974d0b656122b799a8b13102ade8c1b779aa5de7b5', - 'senderId': 'DKGYWPSqa4m4z6h3433rNFbWPDdvHj5wwd' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0361b914fd5823bf39ae467e95d99e9f6ddb7d85cc6df3055ce00274b8e4a976cc', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_17', - 'publicKey': '0361b914fd5823bf39ae467e95d99e9f6ddb7d85cc6df3055ce00274b8e4a976cc' - } - }, - 'signature': '3044022002ad92b9b9d81dabf96ac7d90034debc55eeeae879b3fe6ffc026bde86bb7ad902205c57d31c5e5e0099b504ba4c49e220a00ff325dceb64c46aefbb7a0ad8570099', - 'id': 'bf305776da902802923c19b9d2c7f1a809b0847992131cfa578d5e5518c924bf', - 'senderId': 'DJshaeFyHcFTjiGJnVPaDmFXhnJ9bp96i5' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03fa6bc09bd2ff348b304e0cfbc2d2ec50aa3b9aee0de6a66c13fcd8ee5ac891cd', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_18', - 'publicKey': '03fa6bc09bd2ff348b304e0cfbc2d2ec50aa3b9aee0de6a66c13fcd8ee5ac891cd' - } - }, - 'signature': '3045022100be50b19c17a9ff221aae20394a45d92ea47e8c1072b6d5a302937d2fc48cba8002205e9bcb3471a734c07ceff0083ad9ba1570507a29e5014e889ba42a85e797cb5e', - 'id': '44e48364b5b8cff3c68ae03de7dfde8d7ba6bcb99bf82b32fdc8bc3d0d9adeca', - 'senderId': 'DSuNttSb1UvCWg8iormfwPwi67EA84P5Mu' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03241957edca9ed28308e35cbf36762d22de706ebbd7c6a3a2d235d905d660c5c7', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_19', - 'publicKey': '03241957edca9ed28308e35cbf36762d22de706ebbd7c6a3a2d235d905d660c5c7' - } - }, - 'signature': '3045022100c11f8b863133535192e6c3fff20253a2695a2df74cdf1445d4ca0966803f708c0220200d4c2723d84f6334ba5d1cc1a0d45854867f4523fbcc9d09b3d53dd1972950', - 'id': '5cba288f9ffc1361ba8f7f19f28347ffd917f37df8cf46ba1e0816725f288528', - 'senderId': 'DCZt1ozEVvPdYVvkHmUKK6k7gnyNNQDpMq' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '035ae2364c838bc21edf4c04a99c85799f26fb02cc0740c5a1c67d4dc1748ff913', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_20', - 'publicKey': '035ae2364c838bc21edf4c04a99c85799f26fb02cc0740c5a1c67d4dc1748ff913' - } - }, - 'signature': '304402203066f06a1c165795d8a069499a8c0998913ec93e689219f14145754aa3e26e4e02206e9f88da16f1f8a8ebaf481eff798452487738714fe9b5694fec6a5ef8c152a5', - 'id': 'ada1696532f7faad1dda594bc6db7bfc029a1759402c924348b74222873a3a27', - 'senderId': 'D7JyqWMPKhhRNQcKTAvrPGBjEjjBcGgPca' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '023aff4a16c3876e885aea70e5bce9734ce5acc95a2c41c9783f5acd617f7c7533', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_21', - 'publicKey': '023aff4a16c3876e885aea70e5bce9734ce5acc95a2c41c9783f5acd617f7c7533' - } - }, - 'signature': '3045022100f5150c23596b9479c8b277401ab9e7da9b2275436f3927dabd70395e52c3ea7c02204e318d498b0176b5f05bb96418c49da3375a8d9b47b3b1e72a6f4db30b3f8c34', - 'id': 'e186a679f2e47300ec2f24c670192bcede1cb12f359cb8e827374b22f41fbe12', - 'senderId': 'D6itxYJr4n7ZZk2bd9cZbJE1xaDmpfkNFL' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0217d7ce9c3754f7fc7e5b4c64a1ff397dc75931cd6c92e32d8b42068ad50fe4eb', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_22', - 'publicKey': '0217d7ce9c3754f7fc7e5b4c64a1ff397dc75931cd6c92e32d8b42068ad50fe4eb' - } - }, - 'signature': '3045022100b84f69a7ff67ed147fc0a750c3b7b2ecabd582b6d0cb698c0bb4a531daa6ca46022039d2722e486e1674d0db422078d63fcdb90b21bed0dcc1265adff72d0c2bf8b9', - 'id': '86d9d146b62dbafe212aba5ec9764223b67f72c3c1aa93e54a270e3a528a8b20', - 'senderId': 'DDy4aKhF3cMadGhjFZnjaA1tx2rwnSEWcc' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '024019207f50dcb3e8aeb9ac1b00993d2bf131346e7e6d296429ea813a8373818e', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_23', - 'publicKey': '024019207f50dcb3e8aeb9ac1b00993d2bf131346e7e6d296429ea813a8373818e' - } - }, - 'signature': '3045022100aa83596b740639ee8947aa6d0f0ee123e4a5b87c39a4c6dd8a50304d4a7c97d102205fd45f85f5bdb076585a77888ef880bea52ade689731dff694d777de34913efc', - 'id': '6301b791844e02116df528b1ea46d788e91521189c3828ce224e45a1b72cda59', - 'senderId': 'D6BwyDJkNFkaDLedcJTE4rPUw5bRtb4K8f' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0275db912c21dca0f0213a76f4544137d7c741b47f281cfd4f8b7cb8187e7ce3cc', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_24', - 'publicKey': '0275db912c21dca0f0213a76f4544137d7c741b47f281cfd4f8b7cb8187e7ce3cc' - } - }, - 'signature': '3045022100c7eda0d9cd7ef522615643d1b985c73add2d3612344bdcc0117779fa4f4f54d302203e33fb5d185f5174e9cb7634a3d307b74d3bb56cc2354024ce69c74905a85203', - 'id': 'eee776fcb8024469eacab3e4b23c3d14185326431369aa84f17921abab8ad0ad', - 'senderId': 'DHQSmrRdfYAp9Y6CuebKnkoQNzuN7Pk2oQ' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0331c615ca4bc89d4eeb8d7a9cfbb5c0d4ce49d2f480afbce499b0c7f8c6a24f2f', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_25', - 'publicKey': '0331c615ca4bc89d4eeb8d7a9cfbb5c0d4ce49d2f480afbce499b0c7f8c6a24f2f' - } - }, - 'signature': '304402203e69be3a73c5917d89d58f3c0ae18febbbf364d3f9dfbec6b526a5294f9c435902201750bcf6368c181aabc53c73fd271a2967a6f215e1d0506eded5dd1800fea1c8', - 'id': 'ec3d17c6d38c0b9848c7cb57b968efd1f3872b1d1b8bcfb74bae2b0aaa15877c', - 'senderId': 'D6EVFQx5Z7M2X9DWXHtfX51CtVekuKPMQF' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0338ca9b719f8047580eed23b64a40aecad3803a12c0dde83e3ec2c2a9bfaa8147', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_26', - 'publicKey': '0338ca9b719f8047580eed23b64a40aecad3803a12c0dde83e3ec2c2a9bfaa8147' - } - }, - 'signature': '3045022100e0bf90949739012b641793da162b3daa88b34c8753ee31b26850729e9df579810220439a3f2f1b8e719767ee68df46f4bc1f18c8c3b2da4118edff22396616d319fb', - 'id': '14cd65c5f28f4cefc7c0157518a24f90c2260eb7166105b6b3358d91164ddf39', - 'senderId': 'DLCQ1jPsYbBCV7JfUJTasKbKoyGbK4a4HG' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03127001718bee76f14133272f0f4a928ffa8c2b38cafd94d7100253dac732c644', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_2', - 'publicKey': '03127001718bee76f14133272f0f4a928ffa8c2b38cafd94d7100253dac732c644' - } - }, - 'signature': '3044022003d2e76aca2848aedfe25415c11b9368dc72f687b66bef4527b40e2997b86b8c022076f7f82cbeb282d26535a2c1f0af0f02b48025d42c1bd56ac687fba1a3adb706', - 'id': '0daff3992b54b1384f52f751c933c727cbaaf4fac435eba88a1817a425753614', - 'senderId': 'D9rv3h61heDYHQ3b3Xk3V5epHSTTC6Vn1d' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0241734825ba45b6de29d6f26242c25ae1ef125b82615ee89a9fdd5b0f3c6b5132', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_28', - 'publicKey': '0241734825ba45b6de29d6f26242c25ae1ef125b82615ee89a9fdd5b0f3c6b5132' - } - }, - 'signature': '3045022100bb2903424bcd0a72da531470779144d60286191bea1b200c5617ae4f92229ba6022046a876e3e6cb85469a16f34d2f937e2eef787011c6a313ee50258f15116148ac', - 'id': 'bd17dbd23f8dbba2736688702ac185a87c88c43b24ee6d7764a5b4138b2f38b7', - 'senderId': 'DAcQPbKa8zBWwDHbxj37N13C61iseMDWM9' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03b9409203d7091e3f4d49168529b749e942ed18f21beddd236d57d692f09a8f86', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_29', - 'publicKey': '03b9409203d7091e3f4d49168529b749e942ed18f21beddd236d57d692f09a8f86' - } - }, - 'signature': '3044022016d7ecfa776930a6f83464548e7a686735fde752903539a38eb9da0ce2488bbd02203c5e23a4072c8de35a90b296145cce3156a31cc0d754b8a37d363fb088bc7387', - 'id': '16e02d3ef24dca4b03a1e489e20335224f18d888ed04f7e3512572f8e0cf92ae', - 'senderId': 'D5mmTaDAMSyPNKiDKrqwTFGWzWrZA3xaF8' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02c7b92a2d0027309e21855cf9c42a432b21ad13925e9dfc206f9c01e18fefa08a', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_30', - 'publicKey': '02c7b92a2d0027309e21855cf9c42a432b21ad13925e9dfc206f9c01e18fefa08a' - } - }, - 'signature': '30450221009de8828a7ad87cb5d52900e09d5beb680f9edc7640a3707d08a379511a7ba0f102202aa1d9294f9631f1325f252adb87c0d866e7398ce410037a42dc861d94308e15', - 'id': 'fece556bee4de2c7f1bb3099a05a84a33d0c963979fe1a222a899c13b7abb1fc', - 'senderId': 'DJ3NywAwQh4srbooLH1jTs9ma1hJE79v3z' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0221297804a26a93bb441a9d20a2916abf27fa7b29967678ef1a7a58062f73f40d', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_31', - 'publicKey': '0221297804a26a93bb441a9d20a2916abf27fa7b29967678ef1a7a58062f73f40d' - } - }, - 'signature': '3045022100b969611ef532557fa3da8a0325b2c88f3ebec954d64f158431d86b8e07929ea50220520affdcd0728cb7c5f63a58a1200d44133e90b1f7a6a9e28744ad6b0dcc2a75', - 'id': 'ee086317ea2fdc522f5eb502a0db9f3d4955b2318559e40a1f22a3f5f8d6344b', - 'senderId': 'D5P7eti7FUY4Tk5KXoxdf2tDAVQrRVCESA' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '027f504f6f20648e3bf171952629c7b868a2f799aa4b60f8eb3fe96afff16bbef0', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_32', - 'publicKey': '027f504f6f20648e3bf171952629c7b868a2f799aa4b60f8eb3fe96afff16bbef0' - } - }, - 'signature': '3044022006be7cbaa74089cabe47d02621f756762587d210a3f211ee941b5fcd0650908f02207d4040408bd25a2de03e5724362735ee8ad36c099b0c16efd4716e1dd7ec62ae', - 'id': '764dd21aa4d0e2e0fa17bb2ff5e7ca304995d9e3593542badecc8ed24d5ea3ea', - 'senderId': 'D9q26yBTrEYuxHg7bbfZphv6129KvLu4v2' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '031954315b84db8f49ab7ee21357270450bb68d06b34472e5e93ddfa5710edc0c9', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_33', - 'publicKey': '031954315b84db8f49ab7ee21357270450bb68d06b34472e5e93ddfa5710edc0c9' - } - }, - 'signature': '3045022100859f93df994d86995fdf834bfe86b41eebaa04e5ab7d09f0b37acb50d313cd9802203c8993b793602c96d305fa795a9f2459f4706b340993584f3c56579392c0995c', - 'id': 'efd9e7c638afe62bec9be61783193ea52eea7b335053bd5af6c758d5b0e5847c', - 'senderId': 'D9iPFb5kAVnuDdomehRP9LncJj5ng2vrsr' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0267b310eac2bb0d6594de382a1ab74ac75b91e9d64a590b6249247b10fd9be829', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_34', - 'publicKey': '0267b310eac2bb0d6594de382a1ab74ac75b91e9d64a590b6249247b10fd9be829' - } - }, - 'signature': '3045022100a678978ab899e3903e760ee98640e3f658792a096a8d771c575944af6536cfdb0220428c312f1e0eb4be73ce4b256a754447570176200cfb6c09b3eb55f66526dd80', - 'id': '70edcce5df67a250b6ba3567879bae6379ce4c688597fcedfbfd0313da6998e8', - 'senderId': 'D6xZmtyBzZKCEkK29JNPAD581TJ8XXrXYn' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '028f32320c66a89779756b04946d2aa256dff6cd547349d46e1938710063e387c4', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_35', - 'publicKey': '028f32320c66a89779756b04946d2aa256dff6cd547349d46e1938710063e387c4' - } - }, - 'signature': '304402206bc95876897527b39eacf4c961f9c036a9c8a0e53a17ce925c592d079fa643030220096e115d7fbd54aca4af7f621d64178dfcf2c13361106a3e3b5025dca97b44ee', - 'id': '7f23f44157f3a677e81514fa431227410a27442e5fd1f2491b177c0f580f296d', - 'senderId': 'D9dW4eXJjABDQXSQB9GtvY5UBuRWWWejWb' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0218b889a24988527ab3948d80f97cfc37b923082e1f0398bc162190fd66ec4dee', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_36', - 'publicKey': '0218b889a24988527ab3948d80f97cfc37b923082e1f0398bc162190fd66ec4dee' - } - }, - 'signature': '3045022100c40a3f4cf15f9274e2b25ca8608cb965316aa0f00fa77817b79620ad8ccbdd5902206203a1043b03ba58aa9b7399694f8215cf45d30eb0caa748cc06f1a85a8faea9', - 'id': 'a65244ed17a9280aa694abdf6804b1a0b78dfc052b4845abcd3c89380159b29e', - 'senderId': 'DFHK7SdmPdjxNZ9uweqLZAv6v5GQ1NnBNe' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '035392ee88c60617764b4fe89ae2cc96560dfa5f992b03be31ce5680db9b863f73', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_37', - 'publicKey': '035392ee88c60617764b4fe89ae2cc96560dfa5f992b03be31ce5680db9b863f73' - } - }, - 'signature': '3044022036200c3191f8f01b77676644b9b94728b5afb2ab2de8c5c7c5582e795465661c02207848f1f2f0ab378d8906fd45aa048f354d5dbac4cb87c15973ffa86fe84ff0cd', - 'id': '219e0942afe5f65c548ec2118a1c49febb7ec03fca4334ac16649062db9d146b', - 'senderId': 'DSh7AAC9KahXU2JZ539HAqEa5sHafxsxDQ' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03e75127d1deccf65844a1761bd26611b6c65c5b51a52eba27e3ee20a539fd63f1', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_38', - 'publicKey': '03e75127d1deccf65844a1761bd26611b6c65c5b51a52eba27e3ee20a539fd63f1' - } - }, - 'signature': '304402201a2990b2baae72f5cc8f2d1890f328e4082af0cf2a787d8f05208c3424ce089d0220790dbc7606dd6c03568fd0a771e9e8e89557257238ae90cfcb3bb8f3b475987b', - 'id': 'ee9ad2a66e9b2009a9fc671f80d0493803fc422161140169c7bc1fd401cd9ad6', - 'senderId': 'D85WuxGZrFs1QUYTvnRpmc6dd8rmBbpnaX' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0329fc1580906307ac9f2f55cec66e47983f8287d542408fb19f473a305d3638d8', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_39', - 'publicKey': '0329fc1580906307ac9f2f55cec66e47983f8287d542408fb19f473a305d3638d8' - } - }, - 'signature': '30450221008f66e89ec4c7af4b77e5b7ff36c542cc02672c8df70806b5a0fab7a7e8c7067502200d99ba19ceb1b471c39c4e95107ad6f8b978a623a790080b16f863347fe06b4f', - 'id': 'dd3077ed04a76343d340074270ce9826354802bd99e08cb864c1c5ad09f367df', - 'senderId': 'D85kwsBJKZ4pw5uQpc81eRj95f6a536AP6' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '035ec848e9388877dac88f121d19c8f5e870ac90d8ccb0116be9f734e4bd1a9405', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_40', - 'publicKey': '035ec848e9388877dac88f121d19c8f5e870ac90d8ccb0116be9f734e4bd1a9405' - } - }, - 'signature': '304402202b220d6c028bc23213edddaf303f18eef059551891aadbf7a4b4d7d3287457bb0220245678354bb8960b42ba2f2ceb12f926e82ff0d027b44988d799c8c0d8d7d9f2', - 'id': '3afc6ea52b8edc7df0230ceac71baf45460f3bd761c5e75fe796bc7415063220', - 'senderId': 'DGBJdDadBwJD2xY8VsdAykdd6vPakMMUt6' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0356f5885306e45402aeb354a74d13c104699b3b53da46a5e922e4a6d6132a67e8', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_41', - 'publicKey': '0356f5885306e45402aeb354a74d13c104699b3b53da46a5e922e4a6d6132a67e8' - } - }, - 'signature': '3045022100f18bf2e013f2d9dcac013a76037d787f79baaa65f4f31ffe2b4ed8de249bdc8902202abcf77e809599d3e3a96225363c8e760ed4b4e20f97645547b381dba830c3da', - 'id': 'aea1fc173a2f4a9233b0fe59a5f6804167bee5658cb3e4e19dfe2be20f5772cd', - 'senderId': 'DG4VbapL3H39NJLB3DqQEefU47EMVqtxVw' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03ff8ab980434516ca28c982d0ecc8fc3107116d6c8b3e09c7ee5033f32adbd2ff', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_42', - 'publicKey': '03ff8ab980434516ca28c982d0ecc8fc3107116d6c8b3e09c7ee5033f32adbd2ff' - } - }, - 'signature': '3045022100e938d9901afeaa5a56d18abd9292ace93be03c84c09a6c4cb58fca96dfb54bc502201e921d27f9886d189f803b14d93655a42c4e095d49ee61051a4e70c7a173f3f1', - 'id': 'f18426d3ef81d4b7bf0337d70afcecddbd6db2206a2f139f1ca5823c381c7817', - 'senderId': 'DC3oNWedP48ypGxAeKbFC7gMjWxcNc2JhL' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0393f1590771a8ad1cf2baa086858f3029c4444cb82243917a7011f1f66cf8fd05', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_43', - 'publicKey': '0393f1590771a8ad1cf2baa086858f3029c4444cb82243917a7011f1f66cf8fd05' - } - }, - 'signature': '304502210095745c36a8af07e21546bd064f1ed1bd90e6c2a8db9c0c8e4853d0a8255443db0220259d2ce3677abb42f08b9d22aa13bbe383fd882ed38911b738ebaefc04589694', - 'id': '6c51bea35b5e3270dcf7b7dfae8d984e19f476ea7e0435f157c4e0d22b7e7ea1', - 'senderId': 'DJm2sfcUKhyxakowY9TjyAytkdq7JrFgVj' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0234e24ff1dbc447c804eb385cd05bbd1dc59ef03b44a3346b13e7cccf00b61075', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_44', - 'publicKey': '0234e24ff1dbc447c804eb385cd05bbd1dc59ef03b44a3346b13e7cccf00b61075' - } - }, - 'signature': '3045022100ee1e8df480f2be042386d383d776b3fd6bd2d3f5a9035071153f23dbfdceeaae02203a0834aae4834da3ca7858779d474b9255ead754867d5b4a18873e9ecaa5045e', - 'id': '66fb3e36233f4577ba585ccd7daf83e62d8df262d3d832b806479ac67c1ef35d', - 'senderId': 'D5oS8xfNebiPsjpwPWoZS6sA9qcYjTGT5h' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03a5789a4486f20f1fdca78a52b528b3bf9952e7c057de71a22adcfb444ba4c5d3', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_45', - 'publicKey': '03a5789a4486f20f1fdca78a52b528b3bf9952e7c057de71a22adcfb444ba4c5d3' - } - }, - 'signature': '3045022100cb037530bcff9a4d19899431648747022c28aa3239563379d96692bd525eb38902205f3cabb8dd470d9eb3d425e333ad1bc9f0643d489c600a811748fb5f4a203f7f', - 'id': '5df9c5e350136571af4b86697bc9d4cfca3ff8b669e254b36f00be1dbde063f7', - 'senderId': 'D5SzHHdPdGqYUkH7BGNkmGHEUqfZrWb17r' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0347f692345fa7bf90e944eb55246da5f9f595d3f5a20ad50aeb6f9b973aaae17e', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_46', - 'publicKey': '0347f692345fa7bf90e944eb55246da5f9f595d3f5a20ad50aeb6f9b973aaae17e' - } - }, - 'signature': '3045022100c377efe5ffab58017473699cd7c839dcf48fa5b20b5ddf9bdc4801e22a579b2b02204d35c1a1416069544e3ec01d2ce21bb409f9f2fa4adedc8c03d6417c034a3fec', - 'id': 'da4cfad78e37d56421dd6676e5618a507340ef1e496831d1968c509e35ef9202', - 'senderId': 'DCLdibuZB6UsJP8KmdzcDLWzizrDtJQuxt' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '028a32b441377a69aa76e867026f3109b2f0aef8651fe91e2a4ab01eff102a6b98', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_47', - 'publicKey': '028a32b441377a69aa76e867026f3109b2f0aef8651fe91e2a4ab01eff102a6b98' - } - }, - 'signature': '3045022100e098672958be15989bb125d9018adb4a54e95ab664e64a673997e617e28b39df02206e8459997074d5976b77f90eb9d7180e9d4a0e0efdf433958ffeb2f04d9de382', - 'id': '85bafcd07e7ba47ec95cb5b5a6759d4f9f87e036bb7660c7717504e845ef975e', - 'senderId': 'DSkivgRyimdAVqmm2ZAKwKmKN39WEbbPnL' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0223ac52179903e79865b9a98cf0b52ddc1ab46180c157e8f6bd1e63e7f14fcf31', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_48', - 'publicKey': '0223ac52179903e79865b9a98cf0b52ddc1ab46180c157e8f6bd1e63e7f14fcf31' - } - }, - 'signature': '304402200a005716f67d6cd3963a3c752c95f1bca01aa127c91ab1a632eb3022d11e3e67022024c4746078e440da441bcb366ee8999ffd2419e9a6f9cbf971d696d5b7f8733b', - 'id': '0df1ed07d3f95ddf0385bad83a17b3a8fde6bd6532cd3479e48668064672b34f', - 'senderId': 'DDgKyKqdA6SuamB1eW77WvFu6RQFMZoU36' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '039de0390f28c7731d86ae7006a31888f12856cde3cc3c2619d4d4a42b6dfd6c51', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_49', - 'publicKey': '039de0390f28c7731d86ae7006a31888f12856cde3cc3c2619d4d4a42b6dfd6c51' - } - }, - 'signature': '3045022100efa5d51ca79992be4a87af049b3e9ec1b796576e4d937ea9e3760ab0bdcd301e022027e22a6c3395df155bd399643c241e4cc317eaead1f273fd7a709339dfa9dc99', - 'id': '436bebc107fad38e944fd14785e09f0600df4d75d31cf3eac53f850462d0be74', - 'senderId': 'DKCaoaXApw1xE7K1BJcVkr1KGzjKmFWyTk' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02b87b0e70a7ae10613390f405620e24c495ba2b0cfcdbc67688e9b483dea564ee', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_50', - 'publicKey': '02b87b0e70a7ae10613390f405620e24c495ba2b0cfcdbc67688e9b483dea564ee' - } - }, - 'signature': '304502210096cdd35f803a37730ac73a97a23061dceac96319c67bfb1ddcfbac737febe96102202fa0b279f697da3afc043ffd3ecc838789be07ff119b5527a5c13468cecf66e9', - 'id': 'bb65f9dbe6272fd07a555fc86762d6a487f538b972f2926ff7698cdc906a32df', - 'senderId': 'DJQXFKEguZVabsAs46JbXXnQJ5jFhUtN9m' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03c9f8f4001216603c152b4b4429c2ead322ac34672999e808d567a7d1140e46be', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_51', - 'publicKey': '03c9f8f4001216603c152b4b4429c2ead322ac34672999e808d567a7d1140e46be' - } - }, - 'signature': '3045022100ee961089d02d7bb68fe2257f6a972eeaf6e2c1a1ad2f491c417e161fedbb556b02204c834644e5b5cde9a0b3f92fa23bade7670efab0a067597f6c151ee633932706', - 'id': 'cef44df9684f05dab67c0568a2c5295bb50cbb3c88f5cfbe672365bda274620f', - 'senderId': 'DKpt7cm2tZk4RPLyQ5ugwEH7gkriRaA7ov' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02cf70f73328d490cfb03ee822d3fc0cf9259d67c0564e843491e739501809d657', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_27', - 'publicKey': '02cf70f73328d490cfb03ee822d3fc0cf9259d67c0564e843491e739501809d657' - } - }, - 'signature': '30440220645b912b60f829c0bce58bfe9890ef9253418b6898416aaead663bdf158a99f2022061abbbabd454ec7f7e3f4b502216eec28110e945a4b9b913b1fc0b9758e7e6e4', - 'id': '09408dbcf3e3e0835bf92a05330c023a7d6471f3825301a34efa094e0fd4fc30', - 'senderId': 'DQfjSqDuKr5YZaLAF8rWpFMqMYwEbPtGKg' - }], - 'height': 1, - 'id': '13149578060728881902', - 'blockSignature': '3045022100a6605198e0f590c88798405bc76748d84e280d179bcefed2c993e70cded2a5dd022008c7f915b89fc4f3250fc4b481abb753c68f30ac351871c50bd6cfaf151370e8' -}) diff --git a/packages/core-blockchain/__tests__/__support__/setup.js b/packages/core-blockchain/__tests__/__support__/setup.js index 3875a664e9..b2ba0ce46e 100644 --- a/packages/core-blockchain/__tests__/__support__/setup.js +++ b/packages/core-blockchain/__tests__/__support__/setup.js @@ -1,20 +1,17 @@ -'use strict' +const app = require('@arkecosystem/core-container') +const appHelper = require('@arkecosystem/core-test-utils/lib/helpers/container') -const path = require('path') -const container = require('@arkecosystem/core-container') +jest.setTimeout(60000) exports.setUp = async () => { - await container.setUp({ - data: '~/.ark', - config: path.resolve(__dirname, '../../../core/lib/config/testnet'), - token: 'ark', - network: 'testnet' - }, { + await appHelper.setUp({ exit: '@arkecosystem/core-p2p', - exclude: ['@arkecosystem/core-blockchain'] + exclude: ['@arkecosystem/core-blockchain'], }) - return container + return app } -exports.tearDown = async () => container.tearDown() +exports.tearDown = async () => { + await app.tearDown() +} diff --git a/packages/core-blockchain/__tests__/blockchain.test.js b/packages/core-blockchain/__tests__/blockchain.test.js index 9e520bf870..d3d67990a5 100644 --- a/packages/core-blockchain/__tests__/blockchain.test.js +++ b/packages/core-blockchain/__tests__/blockchain.test.js @@ -1,48 +1,75 @@ -'use strict' +/* eslint no-use-before-define: "warn" */ +/* eslint max-len: "off" */ +/* eslint no-await-in-loop: "off" */ -const { asValue } = require('awilix') -const { slots } = require('@arkecosystem/crypto') +const axios = require('axios') +const MockAdapter = require('axios-mock-adapter') -const app = require('./__support__/setup') +const axiosMock = new MockAdapter(axios) +const delay = require('delay') + +const { asValue } = require('awilix') +const { crypto, slots } = require('@arkecosystem/crypto') +const { Block, Wallet } = require('@arkecosystem/crypto').models let genesisBlock +let configManager let container let blockchain +let logger +let loggerDebugBackup +let peerMock + +const blocks1to100 = require('@arkecosystem/core-test-utils/fixtures/testnet/blocks.2-100') +const blocks101to155 = require('@arkecosystem/core-test-utils/fixtures/testnet/blocks.101-155') +const app = require('./__support__/setup') beforeAll(async () => { container = await app.setUp() + // Backup logger.debug function as we are going to mock it in the test suite + logger = container.resolvePlugin('logger') + loggerDebugBackup = logger.debug + + // Mock peer responses so that we can have blocks + __mockPeer() + // Create the genesis block after the setup has finished or else it uses a potentially // wrong network config. - genesisBlock = require('./__fixtures__/genesisBlock') + genesisBlock = new Block( + require('@arkecosystem/core-test-utils/config/testnet/genesisBlock.json'), + ) + + configManager = container.resolvePlugin('config') + + // Workaround: Add genesis transactions to the exceptions list, because they have a fee of 0 + // and otherwise don't pass validation. + configManager.network.exceptions.transactions = genesisBlock.transactions.map( + tx => tx.id, + ) + + // Manually register the blockchain and start it + await __start() }) afterAll(async () => { - await app.tearDown() -}) + axiosMock.reset() -beforeEach(async () => { - process.env.ARK_SKIP_BLOCKCHAIN = true + delete configManager.network.exceptions.transactions - // manually register the blockchain - const plugin = require('../lib').plugin + await __resetToHeight1() - blockchain = await plugin.register(container, { - networkStart: false - }) + // Manually stop the blockchain + await blockchain.stop() - await container.register('blockchain', asValue({ - name: 'blockchain', - version: '0.1.0', - plugin: blockchain, - options: {} - })) + await app.tearDown() }) afterEach(async () => { - process.env.ARK_SKIP_BLOCKCHAIN = false + // Restore original logger.debug function + logger.debug = loggerDebugBackup - await blockchain.resetState() + await __resetBlocksInCurrentRound() }) describe('Blockchain', () => { @@ -58,7 +85,7 @@ describe('Blockchain', () => { it('should be ok', () => { const nextState = blockchain.dispatch('START') - expect(blockchain.stateMachine.state.blockchain).toEqual(nextState) + expect(blockchain.state.blockchain).toEqual(nextState) }) }) @@ -72,7 +99,7 @@ describe('Blockchain', () => { const started = await blockchain.start(true) - expect(started).toBeTruthy() + expect(started).toBeTrue() }) }) @@ -82,7 +109,9 @@ describe('Blockchain', () => { }) it('should throw an exception', () => { - expect(() => blockchain.checkNetwork()).toThrowError('Method [checkNetwork] not implemented!') + expect(() => blockchain.checkNetwork()).toThrow( + 'Method [checkNetwork] not implemented!', + ) }) }) @@ -98,7 +127,9 @@ describe('Blockchain', () => { }) it('should throw an exception', () => { - expect(() => blockchain.rebuild()).toThrowError('Method [rebuild] not implemented!') + expect(() => blockchain.rebuild()).toThrow( + 'Method [rebuild] not implemented!', + ) }) }) @@ -106,17 +137,6 @@ describe('Blockchain', () => { it('should be a function', () => { expect(blockchain.resetState).toBeFunction() }) - - it('should be ok', async () => { - await blockchain.resetState() - - expect(blockchain.stateMachine.state).toEqual({ - blockchain: blockchain.stateMachine.initialState, - started: false, - lastBlock: null, - lastDownloadedBlock: null - }) - }) }) describe('postTransactions', () => { @@ -125,10 +145,21 @@ describe('Blockchain', () => { }) it('should be ok', async () => { - const response = await blockchain.postTransactions(genesisBlock.transactions, false) + const transactionsWithoutType2 = genesisBlock.transactions.filter( + tx => tx.type !== 2, + ) + + await blockchain.transactionPool.flush() + await blockchain.postTransactions(transactionsWithoutType2, false) + const transactions = blockchain.transactionPool.getTransactions(0, 200) - expect(genesisBlock.transactions.length).toBe(52) - expect(response.length).toBe(52) + expect(transactions.length).toBe(transactionsWithoutType2.length) + + expect(transactions).toEqual( + transactionsWithoutType2.map(transaction => transaction.serialized), + ) + + await blockchain.transactionPool.flush() }) }) @@ -138,54 +169,184 @@ describe('Blockchain', () => { }) it('should be ok', async () => { - blockchain.queueBlock = jest.fn(block => (blockchain.stateMachine.state.lastDownloadedBlock = block)) + const block = new Block(blocks101to155[54]) - await blockchain.queueBlock(genesisBlock) + await blockchain.queueBlock(blocks101to155[54]) - expect(blockchain.stateMachine.state.lastDownloadedBlock).toEqual(genesisBlock) + expect(blockchain.state.lastDownloadedBlock).toEqual(block) }) }) - describe.skip('rollbackCurrentRound', () => { + describe('rollbackCurrentRound', () => { it('should be a function', () => { expect(blockchain.rollbackCurrentRound).toBeFunction() }) + + it('should rollback', async () => { + await blockchain.rollbackCurrentRound() + expect(blockchain.getLastBlock().data.height).toBe(153) + }) }) - describe.skip('removeBlocks', () => { + describe('removeBlocks', () => { it('should be a function', () => { expect(blockchain.removeBlocks).toBeFunction() }) + + it('should remove blocks', async () => { + const lastBlockHeight = blockchain.getLastBlock().data.height + + await blockchain.removeBlocks(2) + expect(blockchain.getLastBlock().data.height).toBe(lastBlockHeight - 2) + }) }) - describe.skip('rebuildBlock', () => { + describe('rebuildBlock', () => { it('should be a function', () => { expect(blockchain.rebuildBlock).toBeFunction() }) + + it('should rebuild with a known block', async () => { + const mockCallback = jest.fn(() => true) + const lastBlock = blockchain.getLastBlock() + + await blockchain.rebuildBlock(lastBlock, mockCallback) + await delay(2000) // wait a bit to give enough time for the callback to be called + + expect(mockCallback.mock.calls.length).toBe(1) + }) + + it('should rebuild with a new chained block', async () => { + const mockCallback = jest.fn(() => true) + const lastBlock = blockchain.getLastBlock() + + await blockchain.removeBlocks(1) // remove 1 block so that we can add it then as a chained block + + expect(blockchain.getLastBlock()).not.toEqual(lastBlock) + + await blockchain.rebuildBlock(lastBlock, mockCallback) + await delay(2000) // wait a bit to give enough time for the callback to be called + + expect(mockCallback.mock.calls.length).toBe(1) + expect(blockchain.getLastBlock()).toEqual(lastBlock) + }) }) - describe.skip('processBlock', () => { + describe('processBlock', () => { it('should be a function', () => { expect(blockchain.processBlock).toBeFunction() }) + + it('should process a new chained block', async () => { + const mockCallback = jest.fn(() => true) + const lastBlock = blockchain.getLastBlock() + + await blockchain.removeBlocks(1) // remove 1 block so that we can add it then as a chained block + + expect(blockchain.getLastBlock()).not.toEqual(lastBlock) + + await blockchain.processBlock(lastBlock, mockCallback) + await delay(2000) // wait a bit to give enough time for the callback to be called + + expect(mockCallback.mock.calls.length).toBe(1) + expect(blockchain.getLastBlock()).toEqual(lastBlock) + }) + + it('should process a valid block already known', async () => { + const mockCallback = jest.fn(() => true) + const lastBlock = blockchain.getLastBlock() + + await blockchain.processBlock(lastBlock, mockCallback) + await delay(2000) // wait a bit to give enough time for the callback to be called + + expect(mockCallback.mock.calls.length).toBe(1) + expect(blockchain.getLastBlock()).toEqual(lastBlock) + }) }) - describe.skip('acceptChainedBlock', () => { + describe('acceptChainedBlock', () => { it('should be a function', () => { expect(blockchain.acceptChainedBlock).toBeFunction() }) + + it('should process a new chained block', async () => { + const lastBlock = blockchain.getLastBlock() + + await blockchain.removeBlocks(1) // remove 1 block so that we can add it then as a chained block + + expect(await blockchain.database.getLastBlock()).not.toEqual(lastBlock) + + await blockchain.acceptChainedBlock(lastBlock) + + expect(await blockchain.database.getLastBlock()).toEqual(lastBlock) + + // manually set lastBlock because acceptChainedBlock doesn't do it + blockchain.state.setLastBlock(lastBlock) + }) }) - describe.skip('manageUnchainedBlock', () => { + describe('manageUnchainedBlock', () => { it('should be a function', () => { expect(blockchain.manageUnchainedBlock).toBeFunction() }) + + it('should process a new unchained block', async () => { + const mockLoggerDebug = jest.fn(message => true) + logger.debug = mockLoggerDebug + + const lastBlock = blockchain.getLastBlock() + await blockchain.removeBlocks(2) // remove 2 blocks so that we can have _lastBlock_ as an unchained block + await blockchain.manageUnchainedBlock(lastBlock) + + expect(mockLoggerDebug).toHaveBeenCalled() + + const debugMessage = `Blockchain not ready to accept new block at height ${lastBlock.data.height.toLocaleString()}. Last block: ${( + lastBlock.data.height - 2 + ).toLocaleString()} :warning:` + expect(mockLoggerDebug).toHaveBeenLastCalledWith(debugMessage) + + expect(blockchain.getLastBlock().data.height).toBe( + lastBlock.data.height - 2, + ) + }) }) - describe.skip('getUnconfirmedTransactions', () => { + describe('getUnconfirmedTransactions', () => { it('should be a function', () => { expect(blockchain.getUnconfirmedTransactions).toBeFunction() }) + + it('should get unconfirmed transactions', async () => { + const transactionsWithoutType2 = genesisBlock.transactions.filter( + tx => tx.type !== 2, + ) + + await blockchain.transactionPool.flush() + await blockchain.postTransactions(transactionsWithoutType2, false) + const unconfirmedTransactions = blockchain.getUnconfirmedTransactions(200) + + expect(unconfirmedTransactions.transactions.length).toBe( + transactionsWithoutType2.length, + ) + + expect(unconfirmedTransactions.transactions).toEqual( + transactionsWithoutType2.map(transaction => transaction.serialized), + ) + + await blockchain.transactionPool.flush() + }) + }) + + describe('getLastBlock', () => { + it('should be a function', () => { + expect(blockchain.getLastBlock).toBeFunction() + }) + + it('should be ok', () => { + blockchain.state.setLastBlock(genesisBlock) + + expect(blockchain.getLastBlock()).toEqual(genesisBlock) + }) }) describe('isSynced', () => { @@ -195,22 +356,27 @@ describe('Blockchain', () => { describe('with a block param', () => { it('should be ok', () => { - expect(blockchain.isSynced({ - timestamp: slots.getTime() - genesisBlock.data.timestamp, - height: genesisBlock.data.height - })).toBeTruthy() + expect( + blockchain.isSynced({ + data: { + timestamp: slots.getTime(), + height: genesisBlock.height, + }, + }), + ).toBeTrue() }) }) - // TODO check that works well with Redis fixed - xdescribe('without a block param', () => { + describe('without a block param', () => { it('should use the last block', () => { - blockchain.getLastBlock = jest.fn(() => ({ - timestamp: slots.getTime() - genesisBlock.data.timestamp, - height: genesisBlock.data.height - })) - expect(blockchain.isSynced()).toBeTruthy() - expect(blockchain.getLastBlock()).toHaveBeenCalledWith(true) + blockchain.getLastBlock = jest.fn().mockReturnValueOnce({ + data: { + timestamp: slots.getTime(), + height: genesisBlock.height, + }, + }) + expect(blockchain.isSynced()).toBeTrue() + expect(blockchain.getLastBlock).toHaveBeenCalled() }) }) }) @@ -222,44 +388,31 @@ describe('Blockchain', () => { describe('with a block param', () => { it('should be ok', () => { - expect(blockchain.isRebuildSynced({ - timestamp: slots.getTime() - genesisBlock.data.timestamp, - height: genesisBlock.data.height - })).toBeTruthy() + expect( + blockchain.isRebuildSynced({ + data: { + timestamp: slots.getTime() - 3600 * 24 * 6, + height: blocks101to155[52].height, + }, + }), + ).toBeTrue() }) }) - // TODO check that works well with Redis fixed - xdescribe('without a block param', () => { + describe('without a block param', () => { it('should use the last block', () => { - blockchain.getLastBlock = jest.fn(() => ({ - timestamp: slots.getTime() - genesisBlock.data.timestamp, - height: genesisBlock.data.height - })) - expect(blockchain.isRebuildSynced()).toBeTruthy() - expect(blockchain.getLastBlock()).toHaveBeenCalledWith(true) + blockchain.getLastBlock = jest.fn().mockReturnValueOnce({ + data: { + timestamp: slots.getTime(), + height: genesisBlock.height, + }, + }) + expect(blockchain.isRebuildSynced()).toBeTrue() + expect(blockchain.getLastBlock).toHaveBeenCalled() }) }) }) - describe('getLastBlock', () => { - it('should be a function', () => { - expect(blockchain.getLastBlock).toBeFunction() - }) - - it('should be ok', () => { - blockchain.stateMachine.state.lastBlock = genesisBlock - - expect(blockchain.getLastBlock()).toEqual(genesisBlock) - }) - - it('should be ok using onlyData', () => { - blockchain.stateMachine.state.lastBlock = genesisBlock - - expect(blockchain.getLastBlock()).toEqual(genesisBlock.data) - }) - }) - describe('__isChained', () => { it('should be a function', () => { expect(blockchain.__isChained).toBeFunction() @@ -270,8 +423,8 @@ describe('Blockchain', () => { data: { id: 1, timestamp: 1, - height: 1 - } + height: 1, + }, } const nextBlock = { @@ -279,11 +432,11 @@ describe('Blockchain', () => { id: 2, timestamp: 2, height: 2, - previousBlock: 1 - } + previousBlock: 1, + }, } - expect(blockchain.__isChained(previousBlock, nextBlock)).toBeTruthy() + expect(blockchain.__isChained(previousBlock, nextBlock)).toBeTrue() }) it('should not be ok', () => { @@ -291,8 +444,8 @@ describe('Blockchain', () => { data: { id: 2, timestamp: 2, - height: 2 - } + height: 2, + }, } const nextBlock = { @@ -300,11 +453,11 @@ describe('Blockchain', () => { id: 1, timestamp: 1, height: 1, - previousBlock: 1 - } + previousBlock: 1, + }, } - expect(blockchain.__isChained(previousBlock, nextBlock)).toBeFalsy() + expect(blockchain.__isChained(previousBlock, nextBlock)).toBeFalse() }) }) @@ -322,3 +475,113 @@ describe('Blockchain', () => { }) }) }) + +async function __start() { + process.env.ARK_SKIP_BLOCKCHAIN = false + process.env.ARK_ENV = false + + const plugin = require('../lib').plugin + + blockchain = await plugin.register(container, { + networkStart: false, + }) + + await container.register( + 'blockchain', + asValue({ + name: 'blockchain', + version: '0.1.0', + plugin: blockchain, + options: {}, + }), + ) + + const p2p = container.resolvePlugin('p2p') + await p2p.acceptNewPeer(peerMock) + + await __resetToHeight1() + + await blockchain.start(true) + while ( + !blockchain.getLastBlock() || + blockchain.getLastBlock().data.height < 155 + ) { + await delay(1000) + } +} + +async function __resetBlocksInCurrentRound() { + blockchain.database.blocksInCurrentRound = await blockchain.database.__getBlocksForRound() +} + +async function __resetToHeight1() { + const lastBlock = await blockchain.database.getLastBlock() + if (lastBlock) { + // Make sure the wallet manager has been fed or else revertRound + // cannot determine the previous delegates. This is only necessary, because + // the database is not dropped after the unit tests are done. + await blockchain.database.buildWallets(lastBlock.data.height) + + // Index the genesis wallet or else revert block at height 1 fails + const generator = crypto.getAddress(genesisBlock.data.generatorPublicKey) + const genesis = new Wallet(generator) + genesis.publicKey = genesisBlock.data.generatorPublicKey + genesis.username = 'genesis' + blockchain.database.walletManager.reindex(genesis) + + blockchain.state.clear() + + blockchain.state.setLastBlock(lastBlock) + await __resetBlocksInCurrentRound(lastBlock) + await blockchain.removeBlocks(lastBlock.data.height - 1) + } +} + +function __mockPeer() { + // Mocking a peer which will send blocks until height 155 + const Peer = require('@arkecosystem/core-p2p/lib/peer') + peerMock = new Peer('0.0.0.99', 4002) + Object.assign(peerMock, peerMock.headers, { status: 200 }) + + axiosMock + .onGet(/.*\/peer\/blocks\/common.*/) + .reply(() => [ + 200, + { status: 200, success: true, common: true }, + peerMock.headers, + ]) + axiosMock.onGet(/.*\/peer\/blocks/).reply(config => { + let blocks = [] + + if (config.params.lastBlockHeight === 1) { + blocks = blocks1to100 + } else if (config.params.lastBlockHeight === 100) { + blocks = blocks101to155 + } + + return [200, { status: 200, success: true, blocks }, peerMock.headers] + }) + axiosMock + .onGet(/.*\/peer\/status/) + .reply(() => [ + 200, + { status: 200, success: true, height: 155 }, + peerMock.headers, + ]) + axiosMock.onGet(/.*\/peer\/list/).reply(() => [ + 200, + { + success: true, + peers: [ + { + status: 200, + ip: peerMock.ip, + port: 4002, + height: 155, + delay: 8, + }, + ], + }, + peerMock.headers, + ]) +} diff --git a/packages/core-blockchain/__tests__/machines/actions/fork.test.js b/packages/core-blockchain/__tests__/machines/actions/fork.test.js index 7cdb5be473..324ec1e2ff 100644 --- a/packages/core-blockchain/__tests__/machines/actions/fork.test.js +++ b/packages/core-blockchain/__tests__/machines/actions/fork.test.js @@ -1,6 +1,4 @@ -'use strict' - -require('@arkecosystem/core-test-utils/lib') // eslint-disable-line no-unused-vars +require('@arkecosystem/core-test-utils/lib/matchers') // eslint-disable-line no-unused-vars const machine = require('../../../lib/machines/blockchain') @@ -11,35 +9,44 @@ describe('Blockchain machine > Fork', () => { describe('state `analysing`', () => { it('should execute the `analyseFork` action when is entered', () => { - expect(machine).toExecuteOnEntry({ state: 'fork.analysing', actions: ['analyseFork'] }) + expect(machine).toExecuteOnEntry({ + state: 'fork.analysing', + actions: ['analyseFork'], + }) }) it('should transition to `revertBlocks` on `REBUILD`', () => { - expect(machine).toTransition({ from: 'fork.analysing', on: 'REBUILD', to: 'fork.revertBlocks' }) + expect(machine).toTransition({ + from: 'fork.analysing', + on: 'REBUILD', + to: 'fork.revertBlocks', + }) }) it('should transition to `exit` on `NOFORK`', () => { - expect(machine).toTransition({ from: 'fork.analysing', on: 'NOFORK', to: 'fork.exit' }) + expect(machine).toTransition({ + from: 'fork.analysing', + on: 'NOFORK', + to: 'fork.exit', + }) }) }) describe('state `network`', () => { it('should execute the `checkNetwork` action when is entered', () => { - expect(machine).toExecuteOnEntry({ state: 'fork.network', actions: ['checkNetwork'] }) - }) - - it('should transition to `blockchain` on `SUCCESS`', () => { - expect(machine).toTransition({ from: 'fork.network', on: 'SUCCESS', to: 'fork.blockchain' }) - }) - - it('should transition to `exit` on `FAILURE`', () => { - expect(machine).toTransition({ from: 'fork.network', on: 'FAILURE', to: 'fork.reset' }) + expect(machine).toExecuteOnEntry({ + state: 'fork.network', + actions: ['checkNetwork'], + }) }) }) describe('state `exit`', () => { it('should execute the `forkRecovered` action when is entered', () => { - expect(machine).toExecuteOnEntry({ state: 'fork.exit', actions: ['forkRecovered'] }) + expect(machine).toExecuteOnEntry({ + state: 'fork.exit', + actions: ['forkRecovered'], + }) }) }) }) diff --git a/packages/core-blockchain/__tests__/machines/actions/rebuild-from-network.test.js b/packages/core-blockchain/__tests__/machines/actions/rebuild-from-network.test.js index 5f439e69a4..ceb699213c 100644 --- a/packages/core-blockchain/__tests__/machines/actions/rebuild-from-network.test.js +++ b/packages/core-blockchain/__tests__/machines/actions/rebuild-from-network.test.js @@ -1,6 +1,4 @@ -'use strict' - -require('@arkecosystem/core-test-utils/lib') // eslint-disable-line no-unused-vars +require('@arkecosystem/core-test-utils/lib/matchers') // eslint-disable-line no-unused-vars const machine = require('../../../lib/machines/blockchain') @@ -11,85 +9,147 @@ describe('Blockchain machine > Rebuilding', () => { describe('state `rebuilding`', () => { it('should execute the `checkLastDownloadedBlockSynced` action when is entered', () => { - expect(machine).toExecuteOnEntry({ state: 'rebuild.rebuilding', actions: ['checkLastDownloadedBlockSynced'] }) + expect(machine).toExecuteOnEntry({ + state: 'rebuild.rebuilding', + actions: ['checkLastDownloadedBlockSynced'], + }) }) it('should transition to `waitingFinished` on `SYNCED`', () => { - expect(machine).toTransition({ from: 'rebuild.rebuilding', on: 'SYNCED', to: 'rebuild.waitingFinished' }) + expect(machine).toTransition({ + from: 'rebuild.rebuilding', + on: 'SYNCED', + to: 'rebuild.waitingFinished', + }) }) it('should transition to `revertBlocks` on `NOTSYNCED`', () => { - expect(machine).toTransition({ from: 'rebuild.rebuilding', on: 'NOTSYNCED', to: 'rebuild.rebuildBlocks' }) + expect(machine).toTransition({ + from: 'rebuild.rebuilding', + on: 'NOTSYNCED', + to: 'rebuild.rebuildBlocks', + }) }) it('should transition to `rebuildPaused` on `PAUSED`', () => { - expect(machine).toTransition({ from: 'rebuild.rebuilding', on: 'PAUSED', to: 'rebuild.rebuildPaused' }) + expect(machine).toTransition({ + from: 'rebuild.rebuilding', + on: 'PAUSED', + to: 'rebuild.rebuildPaused', + }) }) }) describe('state `idle`', () => { it('should transition to `rebuildBlocks` on `DOWNLOADED`', () => { - expect(machine).toTransition({ from: 'rebuild.idle', on: 'DOWNLOADED', to: 'rebuild.rebuildBlocks' }) + expect(machine).toTransition({ + from: 'rebuild.idle', + on: 'DOWNLOADED', + to: 'rebuild.rebuildBlocks', + }) }) }) describe('state `rebuildBlocks`', () => { it('should execute the `rebuildBlocks` action when is entered', () => { - expect(machine).toExecuteOnEntry({ state: 'rebuild.rebuildBlocks', actions: ['rebuildBlocks'] }) + expect(machine).toExecuteOnEntry({ + state: 'rebuild.rebuildBlocks', + actions: ['rebuildBlocks'], + }) }) it('should transition to `rebuilding` on `DOWNLOADED`', () => { - expect(machine).toTransition({ from: 'rebuild.rebuildBlocks', on: 'DOWNLOADED', to: 'rebuild.rebuilding' }) + expect(machine).toTransition({ + from: 'rebuild.rebuildBlocks', + on: 'DOWNLOADED', + to: 'rebuild.rebuilding', + }) }) it('should transition to `rebuilding` on `NOBLOCK`', () => { - expect(machine).toTransition({ from: 'rebuild.rebuildBlocks', on: 'NOBLOCK', to: 'rebuild.rebuilding' }) + expect(machine).toTransition({ + from: 'rebuild.rebuildBlocks', + on: 'NOBLOCK', + to: 'rebuild.rebuilding', + }) }) }) describe('state `waitingFinished`', () => { it('should transition to `rebuildFinished` on `REBUILDFINISHED`', () => { - expect(machine).toTransition({ from: 'rebuild.waitingFinished', on: 'REBUILDFINISHED', to: 'rebuild.rebuildFinished' }) + expect(machine).toTransition({ + from: 'rebuild.waitingFinished', + on: 'REBUILDFINISHED', + to: 'rebuild.rebuildFinished', + }) }) }) describe('state `processFinished`', () => { it('should execute the `checkRebuildBlockSynced` action when is entered', () => { - expect(machine).toExecuteOnEntry({ state: 'rebuild.processFinished', actions: ['checkRebuildBlockSynced'] }) + expect(machine).toExecuteOnEntry({ + state: 'rebuild.processFinished', + actions: ['checkRebuildBlockSynced'], + }) }) it('should transition to `processFinished` on `SYNCED`', () => { - expect(machine).toTransition({ from: 'rebuild.processFinished', on: 'SYNCED', to: 'rebuild.end' }) + expect(machine).toTransition({ + from: 'rebuild.processFinished', + on: 'SYNCED', + to: 'rebuild.end', + }) }) it('should transition to `processFinished` on `NOTSYNCED`', () => { - expect(machine).toTransition({ from: 'rebuild.processFinished', on: 'NOTSYNCED', to: 'rebuild.rebuildBlocks' }) + expect(machine).toTransition({ + from: 'rebuild.processFinished', + on: 'NOTSYNCED', + to: 'rebuild.rebuildBlocks', + }) }) }) describe('state `rebuildPaused`', () => { it('should execute the `downloadPaused` action when is entered', () => { - expect(machine).toExecuteOnEntry({ state: 'rebuild.rebuildPaused', actions: ['downloadPaused'] }) + expect(machine).toExecuteOnEntry({ + state: 'rebuild.rebuildPaused', + actions: ['downloadPaused'], + }) }) it('should transition to `processFinished` on `REBUILDFINISHED`', () => { - expect(machine).toTransition({ from: 'rebuild.rebuildPaused', on: 'REBUILDFINISHED', to: 'rebuild.processFinished' }) + expect(machine).toTransition({ + from: 'rebuild.rebuildPaused', + on: 'REBUILDFINISHED', + to: 'rebuild.processFinished', + }) }) }) describe('state `rebuildFinished`', () => { it('should execute the `rebuildFinished` action when is entered', () => { - expect(machine).toExecuteOnEntry({ state: 'rebuild.rebuildFinished', actions: ['rebuildFinished'] }) + expect(machine).toExecuteOnEntry({ + state: 'rebuild.rebuildFinished', + actions: ['rebuildFinished'], + }) }) it('should transition to `processFinished` on `PROCESSFINISHED`', () => { - expect(machine).toTransition({ from: 'rebuild.rebuildFinished', on: 'PROCESSFINISHED', to: 'rebuild.processFinished' }) + expect(machine).toTransition({ + from: 'rebuild.rebuildFinished', + on: 'PROCESSFINISHED', + to: 'rebuild.processFinished', + }) }) }) describe('state `end`', () => { it('should execute the `rebuildingComplete` action when is entered', () => { - expect(machine).toExecuteOnEntry({ state: 'rebuild.end', actions: ['rebuildingComplete'] }) + expect(machine).toExecuteOnEntry({ + state: 'rebuild.end', + actions: ['rebuildingComplete'], + }) }) }) }) diff --git a/packages/core-blockchain/__tests__/machines/actions/sync-with-network.test.js b/packages/core-blockchain/__tests__/machines/actions/sync-with-network.test.js index 8c2376168a..e46a59a922 100644 --- a/packages/core-blockchain/__tests__/machines/actions/sync-with-network.test.js +++ b/packages/core-blockchain/__tests__/machines/actions/sync-with-network.test.js @@ -1,6 +1,4 @@ -'use strict' - -require('@arkecosystem/core-test-utils/lib') // eslint-disable-line no-unused-vars +require('@arkecosystem/core-test-utils/lib/matchers') // eslint-disable-line no-unused-vars const machine = require('../../../lib/machines/blockchain') @@ -11,83 +9,145 @@ describe('Blockchain machine > SyncWithNetwork', () => { describe('state `syncing`', () => { it('should execute the `checkLastDownloadedBlockSynced` action when is entered', () => { - expect(machine).toExecuteOnEntry({ state: 'syncWithNetwork.syncing', actions: ['checkLastDownloadedBlockSynced'] }) + expect(machine).toExecuteOnEntry({ + state: 'syncWithNetwork.syncing', + actions: ['checkLastDownloadedBlockSynced'], + }) }) it('should transition to `downloadFinished` on `SYNCED`', () => { - expect(machine).toTransition({ from: 'syncWithNetwork.syncing', on: 'SYNCED', to: 'syncWithNetwork.downloadFinished' }) + expect(machine).toTransition({ + from: 'syncWithNetwork.syncing', + on: 'SYNCED', + to: 'syncWithNetwork.downloadFinished', + }) }) it('should transition to `downloadBlocks` on `NOTSYNCED`', () => { - expect(machine).toTransition({ from: 'syncWithNetwork.syncing', on: 'NOTSYNCED', to: 'syncWithNetwork.downloadBlocks' }) + expect(machine).toTransition({ + from: 'syncWithNetwork.syncing', + on: 'NOTSYNCED', + to: 'syncWithNetwork.downloadBlocks', + }) }) it('should transition to `downloadPaused` on `PAUSED`', () => { - expect(machine).toTransition({ from: 'syncWithNetwork.syncing', on: 'PAUSED', to: 'syncWithNetwork.downloadPaused' }) + expect(machine).toTransition({ + from: 'syncWithNetwork.syncing', + on: 'PAUSED', + to: 'syncWithNetwork.downloadPaused', + }) }) it('should transition to `end` on `NETWORKHALTED`', () => { - expect(machine).toTransition({ from: 'syncWithNetwork.syncing', on: 'NETWORKHALTED', to: 'syncWithNetwork.end' }) + expect(machine).toTransition({ + from: 'syncWithNetwork.syncing', + on: 'NETWORKHALTED', + to: 'syncWithNetwork.end', + }) }) }) describe('state `idle`', () => { it('should transition to `downloadBlocks` on `DOWNLOADED`', () => { - expect(machine).toTransition({ from: 'syncWithNetwork.idle', on: 'DOWNLOADED', to: 'syncWithNetwork.downloadBlocks' }) + expect(machine).toTransition({ + from: 'syncWithNetwork.idle', + on: 'DOWNLOADED', + to: 'syncWithNetwork.downloadBlocks', + }) }) }) describe('state `downloadBlocks`', () => { it('should execute the `downloadBlocks` action when is entered', () => { - expect(machine).toExecuteOnEntry({ state: 'syncWithNetwork.downloadBlocks', actions: ['downloadBlocks'] }) + expect(machine).toExecuteOnEntry({ + state: 'syncWithNetwork.downloadBlocks', + actions: ['downloadBlocks'], + }) }) it('should transition to `syncing` on `DOWNLOADED`', () => { - expect(machine).toTransition({ from: 'syncWithNetwork.downloadBlocks', on: 'DOWNLOADED', to: 'syncWithNetwork.syncing' }) + expect(machine).toTransition({ + from: 'syncWithNetwork.downloadBlocks', + on: 'DOWNLOADED', + to: 'syncWithNetwork.syncing', + }) }) it('should transition to `syncing` on `NOBLOCK`', () => { - expect(machine).toTransition({ from: 'syncWithNetwork.downloadBlocks', on: 'NOBLOCK', to: 'syncWithNetwork.syncing' }) + expect(machine).toTransition({ + from: 'syncWithNetwork.downloadBlocks', + on: 'NOBLOCK', + to: 'syncWithNetwork.syncing', + }) }) }) describe('state `downloadFinished`', () => { it('should execute the `downloadFinished` action when is entered', () => { - expect(machine).toExecuteOnEntry({ state: 'syncWithNetwork.downloadFinished', actions: ['downloadFinished'] }) + expect(machine).toExecuteOnEntry({ + state: 'syncWithNetwork.downloadFinished', + actions: ['downloadFinished'], + }) }) it('should transition to `processFinished` on `PROCESSFINISHED`', () => { - expect(machine).toTransition({ from: 'syncWithNetwork.downloadFinished', on: 'PROCESSFINISHED', to: 'syncWithNetwork.processFinished' }) + expect(machine).toTransition({ + from: 'syncWithNetwork.downloadFinished', + on: 'PROCESSFINISHED', + to: 'syncWithNetwork.processFinished', + }) }) }) describe('state `downloadPaused`', () => { it('should execute the `downloadPaused` action when is entered', () => { - expect(machine).toExecuteOnEntry({ state: 'syncWithNetwork.downloadPaused', actions: ['downloadPaused'] }) + expect(machine).toExecuteOnEntry({ + state: 'syncWithNetwork.downloadPaused', + actions: ['downloadPaused'], + }) }) it('should transition to `processFinished` on `PROCESSFINISHED`', () => { - expect(machine).toTransition({ from: 'syncWithNetwork.downloadPaused', on: 'PROCESSFINISHED', to: 'syncWithNetwork.processFinished' }) + expect(machine).toTransition({ + from: 'syncWithNetwork.downloadPaused', + on: 'PROCESSFINISHED', + to: 'syncWithNetwork.processFinished', + }) }) }) describe('state `processFinished`', () => { it('should execute the `checkLastBlockSynced` action when is entered', () => { - expect(machine).toExecuteOnEntry({ state: 'syncWithNetwork.processFinished', actions: ['checkLastBlockSynced'] }) + expect(machine).toExecuteOnEntry({ + state: 'syncWithNetwork.processFinished', + actions: ['checkLastBlockSynced'], + }) }) it('should transition to `end` on `SYNCED`', () => { - expect(machine).toTransition({ from: 'syncWithNetwork.processFinished', on: 'SYNCED', to: 'syncWithNetwork.end' }) + expect(machine).toTransition({ + from: 'syncWithNetwork.processFinished', + on: 'SYNCED', + to: 'syncWithNetwork.end', + }) }) it('should transition to `downloadBlocks` on `NOTSYNCED`', () => { - expect(machine).toTransition({ from: 'syncWithNetwork.processFinished', on: 'NOTSYNCED', to: 'syncWithNetwork.downloadBlocks' }) + expect(machine).toTransition({ + from: 'syncWithNetwork.processFinished', + on: 'NOTSYNCED', + to: 'syncWithNetwork.downloadBlocks', + }) }) }) describe('state `end`', () => { it('should execute the `syncingComplete` action when is entered', () => { - expect(machine).toExecuteOnEntry({ state: 'syncWithNetwork.end', actions: ['syncingComplete'] }) + expect(machine).toExecuteOnEntry({ + state: 'syncWithNetwork.end', + actions: ['syncingComplete'], + }) }) }) }) diff --git a/packages/core-blockchain/__tests__/machines/blockchain.test.js b/packages/core-blockchain/__tests__/machines/blockchain.test.js index ae5803be27..5e850caaff 100644 --- a/packages/core-blockchain/__tests__/machines/blockchain.test.js +++ b/packages/core-blockchain/__tests__/machines/blockchain.test.js @@ -1,6 +1,4 @@ -'use strict' - -require('@arkecosystem/core-test-utils/lib') // eslint-disable-line no-unused-vars +require('@arkecosystem/core-test-utils/lib/matchers') // eslint-disable-line no-unused-vars const machine = require('../../lib/machines/blockchain') @@ -15,7 +13,11 @@ describe('Blockchain machine', () => { describe('state `uninitialised`', () => { it('should transition to `init` on `START`', () => { - expect(machine).toTransition({ from: 'uninitialised', on: 'START', to: 'init' }) + expect(machine).toTransition({ + from: 'uninitialised', + on: 'START', + to: 'init', + }) }) }) @@ -25,15 +27,27 @@ describe('Blockchain machine', () => { }) it('should transition to `rebuild` on `REBUILD`', () => { - expect(machine).toTransition({ from: 'init', on: 'REBUILD', to: 'rebuild' }) + expect(machine).toTransition({ + from: 'init', + on: 'REBUILD', + to: 'rebuild', + }) }) it('should transition to `rebuild` on `NETWORKSTART`', () => { - expect(machine).toTransition({ from: 'init', on: 'NETWORKSTART', to: 'idle' }) + expect(machine).toTransition({ + from: 'init', + on: 'NETWORKSTART', + to: 'idle', + }) }) it('should transition to `rebuild` on `STARTED`', () => { - expect(machine).toTransition({ from: 'init', on: 'STARTED', to: 'syncWithNetwork' }) + expect(machine).toTransition({ + from: 'init', + on: 'STARTED', + to: 'syncWithNetwork', + }) }) it('should transition to `rebuild` on `FAILURE`', () => { @@ -43,7 +57,11 @@ describe('Blockchain machine', () => { describe('state `rebuild`', () => { it('should transition to `syncWithNetwork` on `REBUILDCOMPLETE`', () => { - expect(machine).toTransition({ from: 'rebuild', on: 'REBUILDCOMPLETE', to: 'syncWithNetwork' }) + expect(machine).toTransition({ + from: 'rebuild', + on: 'REBUILDCOMPLETE', + to: 'syncWithNetwork', + }) }) it('should transition to `fork` on `FORK`', () => { @@ -53,53 +71,99 @@ describe('Blockchain machine', () => { describe('state `syncWithNetwork`', () => { it('should transition to `idle` on `TEST`', () => { - expect(machine).toTransition({ from: 'syncWithNetwork', on: 'TEST', to: 'idle' }) + expect(machine).toTransition({ + from: 'syncWithNetwork', + on: 'TEST', + to: 'idle', + }) }) it('should transition to `idle` on `SYNCFINISHED`', () => { - expect(machine).toTransition({ from: 'syncWithNetwork', on: 'SYNCFINISHED', to: 'idle' }) + expect(machine).toTransition({ + from: 'syncWithNetwork', + on: 'SYNCFINISHED', + to: 'idle', + }) }) it('should transition to `fork` on `FORK`', () => { - expect(machine).toTransition({ from: 'syncWithNetwork', on: 'FORK', to: 'fork' }) + expect(machine).toTransition({ + from: 'syncWithNetwork', + on: 'FORK', + to: 'fork', + }) }) }) describe('state `idle`', () => { it('should execute the `checkLater` and `blockchainReady` actions when is entered', () => { - expect(machine).toExecuteOnEntry({ state: 'idle', actions: ['checkLater', 'blockchainReady'] }) + expect(machine).toExecuteOnEntry({ + state: 'idle', + actions: ['checkLater', 'blockchainReady'], + }) }) it('should transition to `syncWithNetwork` on `WAKEUP`', () => { - expect(machine).toTransition({ from: 'idle', on: 'WAKEUP', to: 'syncWithNetwork' }) + expect(machine).toTransition({ + from: 'idle', + on: 'WAKEUP', + to: 'syncWithNetwork', + }) + }) + + it('should transition to `newBlock` on `NEWBLOCK`', () => { + expect(machine).toTransition({ + from: 'idle', + on: 'NEWBLOCK', + to: 'newBlock', + }) }) - it('should transition to `processingBlock` on `NEWBLOCK`', () => { - expect(machine).toTransition({ from: 'idle', on: 'NEWBLOCK', to: 'processingBlock' }) + it('should transition to `stopped` on `STOP`', () => { + expect(machine).toTransition({ from: 'idle', on: 'STOP', to: 'stopped' }) }) }) - describe('state `processingBlock`', () => { - it('should execute the `processBlock` action when is entered', () => { - expect(machine).toExecuteOnEntry({ state: 'processingBlock', actions: ['processBlock'] }) + describe('state `newBlock`', () => { + it('should transition to `idle` on `PROCESSFINISHED`', () => { + expect(machine).toTransition({ + from: 'newBlock', + on: 'PROCESSFINISHED', + to: 'idle', + }) }) - it('should transition to `idle` on `SUCCESS`', () => { - expect(machine).toTransition({ from: 'processingBlock', on: 'SUCCESS', to: 'idle' }) + it('should transition to `fork` on `FORK`', () => { + expect(machine).toTransition({ + from: 'newBlock', + on: 'FORK', + to: 'fork', + }) }) - it('should transition to `fork` on `FAILURE`', () => { - expect(machine).toTransition({ from: 'processingBlock', on: 'FAILURE', to: 'fork' }) + it('should transition to `stopped` on `STOP`', () => { + expect(machine).toTransition({ + from: 'newBlock', + on: 'STOP', + to: 'stopped', + }) }) }) describe('state `fork`', () => { it('should execute the `processBlock` action when is entered', () => { - expect(machine).toExecuteOnEntry({ state: 'fork', actions: ['startForkRecovery'] }) + expect(machine).toExecuteOnEntry({ + state: 'fork', + actions: ['startForkRecovery'], + }) }) it('should transition to `idle` on `SUCCESS`', () => { - expect(machine).toTransition({ from: 'fork', on: 'SUCCESS', to: 'syncWithNetwork' }) + expect(machine).toTransition({ + from: 'fork', + on: 'SUCCESS', + to: 'syncWithNetwork', + }) }) it('should transition to `fork` on `FAILURE`', () => { @@ -107,6 +171,15 @@ describe('Blockchain machine', () => { }) }) + describe('state `stopped`', () => { + it('should execute the `stopped` action when is entered', () => { + expect(machine).toExecuteOnEntry({ + state: 'stopped', + actions: ['stopped'], + }) + }) + }) + describe('state `exit`', () => { it('should execute the `exitApp` action when is entered', () => { expect(machine).toExecuteOnEntry({ state: 'exit', actions: ['exitApp'] }) diff --git a/packages/core-blockchain/__tests__/state-machine.test.js b/packages/core-blockchain/__tests__/state-machine.test.js index 551d459480..c0ebdedff1 100644 --- a/packages/core-blockchain/__tests__/state-machine.test.js +++ b/packages/core-blockchain/__tests__/state-machine.test.js @@ -1,6 +1,4 @@ -'use strict' - -require('@arkecosystem/core-test-utils/lib') // eslint-disable-line no-unused-vars +require('@arkecosystem/core-test-utils/lib/matchers') // eslint-disable-line no-unused-vars const { asValue } = require('awilix') @@ -13,35 +11,38 @@ let blockchain beforeAll(async () => { container = await app.setUp() - stateMachine = require('../lib/state-machine') -}) - -afterAll(async () => { - await app.tearDown() -}) - -beforeEach(async () => { process.env.ARK_SKIP_BLOCKCHAIN = true - // manually register the blockchain + // Manually register the blockchain const plugin = require('../lib').plugin blockchain = await plugin.register(container, { - networkStart: false + networkStart: false, }) - await container.register('blockchain', asValue({ - name: 'blockchain', - version: '0.1.0', - plugin: blockchain, - options: {} - })) + await container.register( + 'blockchain', + asValue({ + name: 'blockchain', + version: '0.1.0', + plugin: blockchain, + options: {}, + }), + ) + + stateMachine = require('../lib/state-machine') }) -afterEach(async () => { - process.env.ARK_SKIP_BLOCKCHAIN = false +afterAll(async () => { + // Manually stop the blockchain + await blockchain.stop() - await blockchain.resetState() + await app.tearDown() +}) + +beforeEach(async () => { + process.env.ARK_SKIP_BLOCKCHAIN = false + blockchain.resetState() }) describe('State Machine', () => { @@ -61,8 +62,18 @@ describe('State Machine', () => { expect(actionMap.checkLater).toBeFunction() }) - xit('should dispatch the event "WAKEUP" after a delay', async () => { - await expect(() => actionMap.checkLater()).toDispatch([blockchain, 'WAKEUP']) + it('should dispatch the event "WAKEUP" after a delay', async () => { + jest.useFakeTimers() + blockchain.dispatch = jest.fn() + + actionMap.checkLater() + expect(blockchain.dispatch).not.toBeCalled() + + jest.runAllTimers() + expect(blockchain.dispatch).toHaveBeenCalled() + expect(blockchain.dispatch).toHaveBeenCalledWith('WAKEUP') + + jest.useRealTimers() // restore standard timers }) }) @@ -73,12 +84,15 @@ describe('State Machine', () => { it('should dispatch the event "SYNCED" if the blockchain is synced', () => { blockchain.isSynced = jest.fn(() => true) - expect(() => actionMap.checkLastBlockSynced()).toDispatch([blockchain, 'SYNCED']) + expect(actionMap.checkLastBlockSynced).toDispatch(blockchain, 'SYNCED') }) it('should dispatch the event "NOTSYNCED" if the blockchain is not synced', () => { blockchain.isSynced = jest.fn(() => false) - expect(() => actionMap.checkLastBlockSynced()).toDispatch([blockchain, 'NOTSYNCED']) + expect(() => actionMap.checkLastBlockSynced()).toDispatch( + blockchain, + 'NOTSYNCED', + ) }) }) @@ -89,12 +103,18 @@ describe('State Machine', () => { it('should dispatch the event "SYNCED" if the blockchain is synced after a rebuild', () => { blockchain.isRebuildSynced = jest.fn(() => true) - expect(() => actionMap.checkRebuildBlockSynced()).toDispatch([blockchain, 'SYNCED']) + expect(() => actionMap.checkRebuildBlockSynced()).toDispatch( + blockchain, + 'SYNCED', + ) }) it('should dispatch the event "NOTSYNCED" if the blockchain is not synced after a rebuild', () => { blockchain.isRebuildSynced = jest.fn(() => false) - expect(() => actionMap.checkRebuildBlockSynced()).toDispatch([blockchain, 'NOTSYNCED']) + expect(() => actionMap.checkRebuildBlockSynced()).toDispatch( + blockchain, + 'NOTSYNCED', + ) }) }) @@ -109,10 +129,13 @@ describe('State Machine', () => { expect(actionMap.downloadFinished).toBeFunction() }) - xdescribe('if the network has started', () => { + describe('if the network has started', () => { it('should dispatch the event "SYNCFINISHED"', () => { stateMachine.state.networkStart = true - expect(() => actionMap.downloadFinished()).toDispatch([blockchain, 'SYNCFINISHED']) + expect(actionMap.downloadFinished).toDispatch( + blockchain, + 'SYNCFINISHED', + ) }) it('should toggle its state', () => { @@ -125,7 +148,10 @@ describe('State Machine', () => { describe('if the network has not started', () => { it('should not do anything', () => { stateMachine.state.networkStart = false - expect(() => actionMap.downloadFinished()).not.toDispatch([blockchain, 'SYNCFINISHED']) + expect(() => actionMap.downloadFinished()).not.toDispatch([ + blockchain, + 'SYNCFINISHED', + ]) expect(stateMachine.state.networkStart).toBe(false) }) }) @@ -137,19 +163,16 @@ describe('State Machine', () => { }) }) - describe('downloadPaused', () => { - it('should be a function', () => { - expect(actionMap.downloadPaused).toBeFunction() - }) - }) - describe('downloadPaused', () => { it('should be a function', () => { expect(actionMap.downloadPaused).toBeFunction() }) it('should dispatch the event "SYNCFINISHED"', () => { - expect(() => actionMap.syncingComplete()).toDispatch([blockchain, 'SYNCFINISHED']) + expect(() => actionMap.syncingComplete()).toDispatch( + blockchain, + 'SYNCFINISHED', + ) }) }) @@ -159,7 +182,10 @@ describe('State Machine', () => { }) it('should dispatch the event "REBUILDCOMPLETE"', () => { - expect(() => actionMap.rebuildingComplete()).toDispatch([blockchain, 'REBUILDCOMPLETE']) + expect(() => actionMap.rebuildingComplete()).toDispatch( + blockchain, + 'REBUILDCOMPLETE', + ) }) }) diff --git a/packages/core-blockchain/__tests__/state-storage.test.js b/packages/core-blockchain/__tests__/state-storage.test.js new file mode 100644 index 0000000000..8ea7aa96b9 --- /dev/null +++ b/packages/core-blockchain/__tests__/state-storage.test.js @@ -0,0 +1,326 @@ +const { Block } = require('@arkecosystem/crypto').models +const blocks1to100 = require('@arkecosystem/core-test-utils/fixtures/testnet/blocks.2-100') +const blocks101to155 = require('@arkecosystem/core-test-utils/fixtures/testnet/blocks.101-155') + +const state = require('../lib/state-storage') +const app = require('./__support__/setup') + +const blocks = blocks1to100 + .concat(blocks101to155) + .map(block => new Block(block)) + +beforeAll(async () => { + await app.setUp() +}) + +afterAll(async () => { + await app.tearDown() +}) + +beforeEach(() => { + state.reset() +}) + +describe('State Storage', () => { + it('should be an object', () => { + expect(state).toBeObject() + }) + + describe('getLastBlock', () => { + it('should be a function', () => { + expect(state.getLastBlock).toBeFunction() + }) + + it('should return null when no last block', () => { + expect(state.getLastBlock()).toBeNull() + }) + + it('should return the last block', () => { + state.setLastBlock(blocks[0]) + state.setLastBlock(blocks[1]) + + expect(state.getLastBlock()).toBe(blocks[1]) + }) + }) + + describe('setLastBlock', () => { + it('should be a function', () => { + expect(state.setLastBlock).toBeFunction() + }) + + it('should set the last block', () => { + state.setLastBlock(blocks[0]) + expect(state.getLastBlock()).toBe(blocks[0]) + }) + + it('should not exceed the max last blocks', () => { + for (let i = 0; i < 100; i++) { + // 100 is default + state.setLastBlock(blocks[i]) + } + + expect(state.getLastBlocks()).toHaveLength(100) + expect(state.getLastBlock()).toBe(blocks[99]) + expect(state.getLastBlocks().slice(-1)[0]).toBe(blocks[0]) + + // Push one more to remove the first last block. + state.setLastBlock(blocks[100]) + + expect(state.getLastBlocks()).toHaveLength(100) + expect(state.getLastBlock()).toBe(blocks[100]) + expect(state.getLastBlocks().slice(-1)[0]).toBe(blocks[1]) + }) + + it('should remove last blocks when going to lower height', () => { + for (let i = 0; i < 100; i++) { + // 100 is default + state.setLastBlock(blocks[i]) + } + + expect(state.getLastBlocks()).toHaveLength(100) + expect(state.getLastBlock()).toBe(blocks[99]) + + // Set last height - 1 + state.setLastBlock(blocks[98]) + + expect(state.getLastBlocks()).toHaveLength(99) + expect(state.getLastBlock()).toBe(blocks[98]) + + // Set to first block + state.setLastBlock(blocks[0]) + expect(state.getLastBlocks()).toHaveLength(1) + expect(state.getLastBlock()).toBe(blocks[0]) + }) + }) + + describe('getLastBlocks', () => { + it('should be a function', () => { + expect(state.getLastBlocks).toBeFunction() + }) + + it('should return the last blocks', () => { + for (let i = 0; i < 5; i++) { + state.setLastBlock(blocks[i]) + } + + const lastBlocks = state.getLastBlocks() + expect(lastBlocks).toHaveLength(5) + + for (let i = 0; i < 5; i++) { + expect(lastBlocks[i]).toBeInstanceOf(Block) + expect(lastBlocks[i].data.height).toBe(6 - i) // Height started at 2 + expect(lastBlocks[i]).toBe(blocks[4 - i]) + } + }) + }) + + describe('getLastBlocksData', () => { + it('should be a function', () => { + expect(state.getLastBlocksData).toBeFunction() + }) + + it('should return the last blocks data', () => { + for (let i = 0; i < 5; i++) { + state.setLastBlock(blocks[i]) + } + + const lastBlocksData = state.getLastBlocksData().toArray() + expect(lastBlocksData).toHaveLength(5) + + for (let i = 0; i < 5; i++) { + expect(lastBlocksData[0]).not.toBeInstanceOf(Block) + expect(lastBlocksData[i].height).toBe(6 - i) // Height started at 2 + expect(lastBlocksData[i]).toHaveProperty('transactions') + delete lastBlocksData[i].transactions + expect(lastBlocksData[i]).toEqual(blocks[4 - i].data) + } + }) + }) + + describe('getLastBlockIds', () => { + it('should be a function', () => { + expect(state.getLastBlockIds).toBeFunction() + }) + + it('should return the last blocks data', () => { + for (let i = 0; i < 5; i++) { + state.setLastBlock(blocks[i]) + } + + const lastBlockIds = state.getLastBlockIds() + expect(lastBlockIds).toHaveLength(5) + + for (let i = 0; i < 5; i++) { + expect(lastBlockIds[i]).toBe(blocks[4 - i].data.id) + } + }) + }) + + describe('getLastBlocksByHeight', () => { + it('should be a function', () => { + expect(state.getLastBlocksByHeight).toBeFunction() + }) + + it('should return the last blocks data', () => { + for (let i = 0; i < 100; i++) { + state.setLastBlock(blocks[i]) + } + + const lastBlocksByHeight = state.getLastBlocksByHeight(0, 101) + expect(lastBlocksByHeight).toHaveLength(100) + expect(lastBlocksByHeight[0].height).toBe(blocks[0].data.height) + }) + + it('should return one last block if no end height', () => { + for (let i = 0; i < 100; i++) { + state.setLastBlock(blocks[i]) + } + + const lastBlocksByHeight = state.getLastBlocksByHeight(50) + expect(lastBlocksByHeight).toHaveLength(1) + expect(lastBlocksByHeight[0].height).toBe(50) + }) + }) + + describe('getCommonBlocks', () => { + it('should be a function', () => { + expect(state.getCommonBlocks).toBeFunction() + }) + + it('should get common blocks', () => { + for (let i = 0; i < 100; i++) { + state.setLastBlock(blocks[i]) + } + + // Heights 90 - 100 + const ids = blocks.slice(89, 99).map(block => block.data.id) + const commonBlocks = state.getCommonBlocks(ids) + expect(ids).toHaveLength(10) + expect(commonBlocks).toHaveLength(10) + + for (let i = 0; i < commonBlocks.length; i++) { + expect(commonBlocks[i].height).toBe(blocks[98 - i].data.height) + } + }) + }) + + describe('cacheTransactions', () => { + it('should be a function', () => { + expect(state.cacheTransactions).toBeFunction() + }) + + it('should add transaction id', () => { + expect(state.cacheTransactions([{ id: '1' }])).toEqual({ + added: [{ id: '1' }], + notAdded: [], + }) + expect(state.getCachedTransactionIds()).toHaveLength(1) + }) + + it('should not add duplicate transaction ids', () => { + expect(state.cacheTransactions([{ id: '1' }])).toEqual({ + added: [{ id: '1' }], + notAdded: [], + }) + expect(state.cacheTransactions([{ id: '1' }])).toEqual({ + added: [], + notAdded: [{ id: '1' }], + }) + expect(state.getCachedTransactionIds()).toHaveLength(1) + }) + + it('should not add more than 10000 unique transaction ids', () => { + const transactions = [] + for (let i = 0; i < 10000; i++) { + transactions.push({ id: i.toString() }) + } + + expect(state.cacheTransactions(transactions)).toEqual({ + added: transactions, + notAdded: [], + }) + + expect(state.getCachedTransactionIds()).toHaveLength(10000) + expect(state.getCachedTransactionIds()[0]).toEqual('0') + + expect(state.cacheTransactions([{ id: '10000' }])).toEqual({ + added: [{ id: '10000' }], + notAdded: [], + }) + expect(state.getCachedTransactionIds()).toHaveLength(10000) + expect(state.getCachedTransactionIds()[0]).toEqual('1') + }) + }) + + describe('removeCachedTransactionIds', () => { + it('should be a function', () => { + expect(state.removeCachedTransactionIds).toBeFunction() + }) + + it('should remove cached transaction ids', () => { + const transactions = [] + for (let i = 0; i < 10; i++) { + transactions.push({ id: i.toString() }) + } + + expect(state.cacheTransactions(transactions)).toEqual({ + added: transactions, + notAdded: [], + }) + + expect(state.getCachedTransactionIds()).toHaveLength(10) + state.removeCachedTransactionIds(transactions.map(tx => tx.id)) + expect(state.getCachedTransactionIds()).toHaveLength(0) + }) + }) + + describe('getCachedTransactionIds', () => { + it('should be a function', () => { + expect(state.getCachedTransactionIds).toBeFunction() + }) + }) + + describe('pingBlock', () => { + it('should be a function', () => { + expect(state.pingBlock).toBeFunction() + }) + }) + + describe('pushPingBlock', () => { + it('should be a function', () => { + expect(state.pushPingBlock).toBeFunction() + }) + }) + + describe('reset', () => { + it('should be a function', () => { + expect(state.reset).toBeFunction() + }) + + it('should reset the state', () => { + for (let i = 0; i < 100; i++) { + state.setLastBlock(blocks[i]) + } + + expect(state.getLastBlocks()).toHaveLength(100) + state.reset() + expect(state.getLastBlocks()).toHaveLength(0) + }) + }) + + describe('clear', () => { + it('should be a function', () => { + expect(state.clear).toBeFunction() + }) + + it('should clear the last blocks', () => { + for (let i = 0; i < 100; i++) { + state.setLastBlock(blocks[i]) + } + + expect(state.getLastBlocks()).toHaveLength(100) + state.clear() + expect(state.getLastBlocks()).toHaveLength(0) + }) + }) +}) diff --git a/packages/core-blockchain/jest.config.js b/packages/core-blockchain/jest.config.js index 26f7a25796..57770a97bb 100644 --- a/packages/core-blockchain/jest.config.js +++ b/packages/core-blockchain/jest.config.js @@ -1,22 +1,12 @@ -'use strict' - module.exports = { testEnvironment: 'node', bail: false, verbose: true, - testMatch: [ - '**/__tests__/**/*.test.js' - ], - moduleFileExtensions: [ - 'js', - 'json' - ], + testMatch: ['**/__tests__/**/*.test.js'], + moduleFileExtensions: ['js', 'json'], collectCoverage: false, coverageDirectory: '/.coverage', - collectCoverageFrom: [ - 'lib/**/*.js', - '!**/node_modules/**' - ], + collectCoverageFrom: ['lib/**/*.js', '!**/node_modules/**'], watchman: false, - setupTestFrameworkScriptFile: 'jest-extended' + setupTestFrameworkScriptFile: 'jest-extended', } diff --git a/packages/core-blockchain/jsdoc.json b/packages/core-blockchain/jsdoc.json index 23276f74ea..f3ea8aab33 100644 --- a/packages/core-blockchain/jsdoc.json +++ b/packages/core-blockchain/jsdoc.json @@ -7,9 +7,7 @@ "includePattern": ".js$", "excludePattern": "(node_modules/|docs)" }, - "plugins": [ - "plugins/markdown" - ], + "plugins": ["plugins/markdown"], "opts": { "template": "../../node_modules/docdash", "encoding": "utf8", diff --git a/packages/core-blockchain/lib/blockchain.js b/packages/core-blockchain/lib/blockchain.js index 6bd779ba9b..a3d691fcd9 100644 --- a/packages/core-blockchain/lib/blockchain.js +++ b/packages/core-blockchain/lib/blockchain.js @@ -1,13 +1,17 @@ -'use strict' +/* eslint max-len: "off" */ +/* eslint no-await-in-loop: "off" */ const { slots } = require('@arkecosystem/crypto') -const container = require('@arkecosystem/core-container') -const logger = container.resolvePlugin('logger') -const config = container.resolvePlugin('config') +const { Block } = require('@arkecosystem/crypto').models +const app = require('@arkecosystem/core-container') + +const logger = app.resolvePlugin('logger') +const config = app.resolvePlugin('config') +const emitter = app.resolvePlugin('event-emitter') +const delay = require('delay') +const pluralize = require('pluralize') const stateMachine = require('./state-machine') const Queue = require('./queue') -const delay = require('delay') -const { Block } = require('@arkecosystem/crypto').models module.exports = class Blockchain { /** @@ -15,13 +19,15 @@ module.exports = class Blockchain { * @param {Boolean} networkStart * @return {void} */ - constructor (networkStart) { + constructor(networkStart) { // flag to force a network start - stateMachine.state.networkStart = !!networkStart + this.state.networkStart = !!networkStart - if (stateMachine.state.networkStart) { - logger.warn('ARK Core is launched in Genesis Start mode. This is usually for starting the first node on the blockchain. Unless you know what you are doing, this is likely wrong. :warning:') - logger.info('Starting ARK Core for a new world, welcome aboard :rocket:') + if (this.state.networkStart) { + logger.warn( + 'Ark Core is launched in Genesis Start mode. This is usually for starting the first node on the blockchain. Unless you know what you are doing, this is likely wrong. :warning:', + ) + logger.info('Starting Ark Core for a new world, welcome aboard :rocket:') } this.actions = stateMachine.actionMap(this) @@ -34,14 +40,20 @@ module.exports = class Blockchain { * @param {String} event * @return {void} */ - dispatch (event) { - const nextState = stateMachine.transition(stateMachine.state.blockchain, event) + dispatch(event) { + const nextState = stateMachine.transition(this.state.blockchain, event) if (nextState.actions.length > 0) { - logger.debug(`event '${event}': ${JSON.stringify(stateMachine.state.blockchain.value)} -> ${JSON.stringify(nextState.value)} -> actions: ${JSON.stringify(nextState.actions)}`) + logger.debug( + `event '${event}': ${JSON.stringify( + this.state.blockchain.value, + )} -> ${JSON.stringify( + nextState.value, + )} -> actions: [${nextState.actions.map(a => a.type).join(', ')}]`, + ) } - stateMachine.state.blockchain = nextState + this.state.blockchain = nextState nextState.actions.forEach(actionKey => { const action = this.actions[actionKey] @@ -60,24 +72,41 @@ module.exports = class Blockchain { * Start the blockchain and wait for it to be ready. * @return {void} */ - async start (skipStartedCheck = false) { + async start(skipStartedCheck = false) { logger.info('Starting Blockchain Manager :chains:') this.dispatch('START') + emitter.once('shutdown', () => { + this.stop() + }) + if (skipStartedCheck || process.env.ARK_SKIP_BLOCKCHAIN_STARTED_CHECK) { return true } - // TODO: this state needs to be set after the state.lastBlock is available if ARK_ENV=test - while (!stateMachine.state.started) { + // TODO: this state needs to be set after state.getLastBlock() is available if ARK_ENV=test + while (!this.state.started && !this.isStopped) { await delay(1000) } return true } - checkNetwork () { + async stop() { + if (!this.isStopped) { + logger.info('Stopping Blockchain Manager :chains:') + + this.isStopped = true + this.state.clearCheckLater() + + this.dispatch('STOP') + + this.queue.destroy() + } + } + + checkNetwork() { throw new Error('Method [checkNetwork] not implemented!') } @@ -85,7 +114,7 @@ module.exports = class Blockchain { * Update network status. * @return {void} */ - async updateNetworkStatus () { + async updateNetworkStatus() { return this.p2p.updateNetworkStatus() } @@ -94,7 +123,7 @@ module.exports = class Blockchain { * @param {Number} nblocks * @return {void} */ - rebuild (nblocks) { + rebuild(nblocks) { throw new Error('Method [rebuild] not implemented!') } @@ -102,33 +131,27 @@ module.exports = class Blockchain { * Reset the state of the blockchain. * @return {void} */ - async resetState () { + resetState() { this.queue.pause() - this.queue.clear(stateMachine) - - stateMachine.state = { - blockchain: stateMachine.initialState, - started: false, - lastBlock: null, - lastDownloadedBlock: null, - blockPing: null, - noBlockCounter: 0 - } + this.queue.clear() - // this.queue.resume() - - // return this.start() + this.state.reset() } /** * Hand the given transactions to the transaction handler. * @param {Array} transactions - * @return {Array} + * @return {void} */ - postTransactions (transactions) { - logger.info(`Received ${transactions.length} new transactions :moneybag:`) - - return this.transactionPool.addTransactions(transactions) + async postTransactions(transactions) { + logger.info( + `Received ${transactions.length} new ${pluralize( + 'transaction', + transactions.length, + )} :moneybag:`, + ) + + await this.transactionPool.addTransactions(transactions) } /** @@ -136,15 +159,30 @@ module.exports = class Blockchain { * @param {Block} block * @return {void} */ - queueBlock (block) { - logger.info(`Received new block at height ${block.height.toLocaleString()} with ${block.numberOfTransactions} transactions from ${block.ip}`) + queueBlock(block) { + logger.info( + `Received new block at height ${block.height.toLocaleString()} with ${pluralize( + 'transaction', + block.numberOfTransactions, + true, + )} from ${block.ip}`, + ) + + if ( + this.state.started && + this.state.blockchain.value === 'idle' && + !this.state.forked + ) { + this.dispatch('NEWBLOCK') - if (stateMachine.state.started) { this.processQueue.push(block) - - stateMachine.state.lastDownloadedBlock = new Block(block) + this.state.lastDownloadedBlock = new Block(block) } else { - logger.info('Block disregarded because blockchain is not ready :exclamation:') + logger.info( + `Block disregarded because blockchain is ${ + this.state.forked ? 'forked' : 'not ready' + } :exclamation:`, + ) } } @@ -152,8 +190,8 @@ module.exports = class Blockchain { * Rollback all blocks up to the previous round. * @return {void} */ - async rollbackCurrentRound () { - const height = this.getLastBlock().data.height + async rollbackCurrentRound() { + const height = this.state.getLastBlock().data.height const maxDelegates = config.getConstants(height).activeDelegates const previousRound = Math.floor((height - 1) / maxDelegates) @@ -162,33 +200,50 @@ module.exports = class Blockchain { } const newHeight = previousRound * maxDelegates - const blocksToRemove = await this.database.getBlocks(newHeight, height - newHeight - 1) + const blocksToRemove = await this.database.getBlocks( + newHeight, + height - newHeight - 1, + ) const deleteLastBlock = async () => { - const lastBlock = stateMachine.state.lastBlock - await this.database.deleteBlockAsync(lastBlock) + const lastBlock = this.state.getLastBlock() + await this.database.enqueueDeleteBlock(lastBlock) const newLastBlock = new Block(blocksToRemove.pop()) - stateMachine.state.lastBlock = newLastBlock - stateMachine.state.lastDownloadedBlock = newLastBlock + this.state.setLastBlock(newLastBlock) + this.state.lastDownloadedBlock = newLastBlock } - logger.info(`Removing ${height - newHeight} blocks to reset current round :warning:`) + logger.info( + `Removing ${pluralize( + 'block', + height - newHeight, + true, + )} to reset current round :warning:`, + ) let count = 0 - const max = this.getLastBlock().data.height - newHeight - - while (this.getLastBlock().data.height >= newHeight + 1) { - const removalBlockId = this.getLastBlock().data.id - const removalBlockHeight = this.getLastBlock().data.height.toLocaleString() - logger.printTracker('Removing block', count++, max, `ID: ${removalBlockId}, Height: ${removalBlockHeight}`) + const max = this.state.getLastBlock().data.height - newHeight + + while (this.state.getLastBlock().data.height >= newHeight + 1) { + const removalBlockId = this.state.getLastBlock().data.id + const removalBlockHeight = this.state + .getLastBlock() + .data.height.toLocaleString() + logger.printTracker( + 'Removing block', + count++, + max, + `ID: ${removalBlockId}, height: ${removalBlockHeight}`, + ) await deleteLastBlock() } - await this.database.deleteBlockCommit() + // Commit delete blocks + await this.database.commitQueuedQueries() - logger.stopTracker(`${max} blocks removed`, count, max) + logger.stopTracker(`${pluralize('block', max, true)} removed`, count, max) await this.database.deleteRound(previousRound + 1) } @@ -198,15 +253,18 @@ module.exports = class Blockchain { * @param {Number} nblocks * @return {void} */ - async removeBlocks (nblocks) { - const blocksToRemove = await this.database.getBlocks(stateMachine.state.lastBlock.data.height - nblocks, nblocks - 1) + async removeBlocks(nblocks) { + const blocksToRemove = await this.database.getBlocks( + this.state.getLastBlock().data.height - nblocks, + nblocks - 1, + ) const revertLastBlock = async () => { - const lastBlock = stateMachine.state.lastBlock + const lastBlock = this.state.getLastBlock() // TODO: if revertBlock Failed, it might corrupt the database because one block could be left stored await this.database.revertBlock(lastBlock) - await this.database.deleteBlockAsync(lastBlock) + this.database.enqueueDeleteBlock(lastBlock) if (this.transactionPool) { await this.transactionPool.addTransactions(lastBlock.transactions) @@ -214,35 +272,79 @@ module.exports = class Blockchain { const newLastBlock = new Block(blocksToRemove.pop()) - stateMachine.state.lastBlock = newLastBlock - stateMachine.state.lastDownloadedBlock = newLastBlock + this.state.setLastBlock(newLastBlock) + this.state.lastDownloadedBlock = newLastBlock } - const __removeBlocks = async (nblocks) => { - if (nblocks < 1) { + const __removeBlocks = async numberOfBlocks => { + if (numberOfBlocks < 1) { return } - logger.info(`Undoing block ${this.getLastBlock().data.height.toLocaleString()}`) + logger.info( + `Undoing block ${this.state + .getLastBlock() + .data.height.toLocaleString()}`, + ) await revertLastBlock() - await __removeBlocks(nblocks - 1) + await __removeBlocks(numberOfBlocks - 1) } - if (nblocks >= this.getLastBlock().data.height) { - nblocks = this.getLastBlock().data.height - 1 + const lastBlock = this.state.getLastBlock() + if (nblocks >= lastBlock.data.height) { + nblocks = lastBlock.data.height - 1 } - const resetHeight = this.getLastBlock().data.height - nblocks - logger.info(`Removing ${nblocks} blocks. Reset to height ${resetHeight.toLocaleString()}`) + const resetHeight = lastBlock.data.height - nblocks + logger.info( + `Removing ${pluralize( + 'block', + nblocks, + true, + )}. Reset to height ${resetHeight.toLocaleString()}`, + ) this.queue.pause() - this.queue.clear(stateMachine) + this.queue.clear() + + this.state.lastDownloadedBlock = lastBlock + await __removeBlocks(nblocks) - await this.database.deleteBlockCommit() + + // Commit delete blocks + await this.database.commitQueuedQueries() + this.queue.resume() } + /** + * Remove the top blocks from database. + * NOTE: Only used when trying to restore database integrity. + * @param {Number} count + * @return {void} + */ + async removeTopBlocks(count) { + const blocks = await this.database.getTopBlocks(count) + + logger.info( + `Removing ${pluralize( + 'block', + blocks.length, + true, + )} from height ${blocks[0].height.toLocaleString()}`, + ) + + for (let block of blocks) { + block = new Block(block) + + this.database.enqueueDeleteRound(block.data.height) + this.database.enqueueDeleteBlock(block) + } + + await this.database.commitQueuedQueries() + } + /** * Hande a block during a rebuild. * NOTE: We should be sure this is fail safe (ie callback() is being called only ONCE) @@ -250,37 +352,46 @@ module.exports = class Blockchain { * @param {Function} callback * @return {Object} */ - async rebuildBlock (block, callback) { - const state = stateMachine.state + async rebuildBlock(block, callback) { + const lastBlock = this.state.getLastBlock() if (block.verification.verified) { - if (this.__isChained(state.lastBlock, block)) { + if (this.__isChained(lastBlock, block)) { // save block on database - await this.database.saveBlockAsync(block) + this.database.enqueueSaveBlock(block) - // committing to db every 10,000 blocks - if (block.data.height % 10000 === 0) { - await this.database.saveBlockCommit() + // committing to db every 20,000 blocks + if (block.data.height % 20000 === 0) { + await this.database.commitQueuedQueries() } - state.lastBlock = block + this.state.setLastBlock(block) return callback() - } else if (block.data.height > this.getLastBlock().data.height + 1) { - state.lastDownloadedBlock = state.lastBlock - return callback() - } else if (block.data.height < this.getLastBlock().data.height || (block.data.height === this.getLastBlock().data.height && block.data.id === this.getLastBlock().data.id)) { - state.lastDownloadedBlock = state.lastBlock + } + if (block.data.height > lastBlock.data.height + 1) { + this.state.lastDownloadedBlock = lastBlock return callback() - } else { - state.lastDownloadedBlock = state.lastBlock - logger.info(`Block ${block.data.height.toLocaleString()} disregarded because on a fork :knife_fork_plate:`) + } + if ( + block.data.height < lastBlock.data.height || + (block.data.height === lastBlock.data.height && + block.data.id === lastBlock.data.id) + ) { + this.state.lastDownloadedBlock = lastBlock return callback() } - } else { - logger.warn(`Block ${block.data.height.toLocaleString()} disregarded because verification failed :scroll:`) + this.state.lastDownloadedBlock = lastBlock + logger.info( + `Block ${block.data.height.toLocaleString()} disregarded because on a fork :knife_fork_plate:`, + ) return callback() } + logger.warn( + `Block ${block.data.height.toLocaleString()} disregarded because verification failed :scroll:`, + ) + logger.warn(block.verification) + return callback() } /** @@ -290,22 +401,30 @@ module.exports = class Blockchain { * @param {Function} callback * @return {(Function|void)} */ - async processBlock (block, callback) { + async processBlock(block, callback) { if (!block.verification.verified) { - logger.warn(`Block ${block.data.height.toLocaleString()} disregarded because verification failed :scroll:`) + logger.warn( + `Block ${block.data.height.toLocaleString()} disregarded because verification failed :scroll:`, + ) + + this.transactionPool.purgeSendersWithInvalidTransactions(block) + return callback() } try { - if (this.__isChained(stateMachine.state.lastBlock, block)) { + if (this.__isChained(this.state.getLastBlock(), block)) { await this.acceptChainedBlock(block) - stateMachine.state.lastBlock = block + this.state.setLastBlock(block) } else { await this.manageUnchainedBlock(block) } } catch (error) { logger.error(`Refused new block ${JSON.stringify(block.data)}`) logger.debug(error.stack) + + this.transactionPool.purgeBlock(block) + this.dispatch('FORK') return callback() } @@ -317,7 +436,9 @@ module.exports = class Blockchain { this.p2p.broadcastBlock(block) } } catch (error) { - logger.warn(`Can't broadcast properly block ${JSON.stringify(block.data.heigt)}`) + logger.warn( + `Can't properly broadcast block ${block.data.height.toLocaleString()}`, + ) logger.debug(error.stack) } @@ -330,13 +451,23 @@ module.exports = class Blockchain { * @param {Object} state * @return {void} */ - async acceptChainedBlock (block) { + async acceptChainedBlock(block) { await this.database.applyBlock(block) await this.database.saveBlock(block) + // Check if we recovered from a fork + if ( + this.state.forked && + this.state.forkedBlock.height === block.data.height + ) { + logger.info('Successfully recovered from fork :star2:') + this.state.forked = false + this.state.forkedBlock = null + } + if (this.transactionPool) { try { - await this.transactionPool.acceptChainedBlock(block) + this.transactionPool.acceptChainedBlock(block) } catch (error) { logger.warn('Issue applying block to transaction pool') logger.debug(error.stack) @@ -350,40 +481,67 @@ module.exports = class Blockchain { * @param {Object} state * @return {void} */ - async manageUnchainedBlock (block) { - if (block.data.height > this.getLastBlock().data.height + 1) { - logger.info(`Blockchain not ready to accept new block at height ${block.data.height.toLocaleString()}. Last block: ${this.getLastBlock().data.height.toLocaleString()} :warning:`) - stateMachine.state.lastDownloadedBlock = stateMachine.state.lastBlock - } else if (block.data.height < this.getLastBlock().data.height) { - logger.debug(`Block ${block.data.height.toLocaleString()} disregarded because already in blockchain :warning:`) - } else if (block.data.height === this.getLastBlock().data.height && block.data.id === this.getLastBlock().data.id) { - logger.debug(`Block ${block.data.height.toLocaleString()} just received :chains:`) + async manageUnchainedBlock(block) { + const lastBlock = this.state.getLastBlock() + + if (block.data.height > lastBlock.data.height + 1) { + logger.debug( + `Blockchain not ready to accept new block at height ${block.data.height.toLocaleString()}. Last block: ${lastBlock.data.height.toLocaleString()} :warning:`, + ) + this.state.lastDownloadedBlock = lastBlock + } else if (block.data.height < lastBlock.data.height) { + logger.debug( + `Block ${block.data.height.toLocaleString()} disregarded because already in blockchain :warning:`, + ) + } else if ( + block.data.height === lastBlock.data.height && + block.data.id === lastBlock.data.id + ) { + logger.debug( + `Block ${block.data.height.toLocaleString()} just received :chains:`, + ) } else { const isValid = await this.database.validateForkedBlock(block) if (isValid) { this.dispatch('FORK') } else { - logger.info(`Forked block disregarded because it is not allowed to forge. Caused by delegate: ${block.data.generatorPublicKey} :bangbang:`) + logger.info( + `Forked block disregarded because it is not allowed to forge. Caused by delegate: ${ + block.data.generatorPublicKey + } :bangbang:`, + ) } } } + /** + * Called by forger to wake up and sync with the network. + * It clears the checkLaterTimeout if set. + * @param {Number} blockSize + * @param {Boolean} forForging + * @return {Object} + */ + forceWakeup() { + this.state.clearCheckLater() + this.dispatch('WAKEUP') + } + /** * Get unconfirmed transactions for the specified block size. * @param {Number} blockSize * @param {Boolean} forForging * @return {Object} */ - async getUnconfirmedTransactions (blockSize, forForging = false) { - const transactions = forForging - ? await this.transactionPool.getTransactionsForForging(0, blockSize) - : await this.transactionPool.getTransactions(0, blockSize) + getUnconfirmedTransactions(blockSize) { + const transactions = this.transactionPool.getTransactionsForForging( + blockSize, + ) return { transactions, - poolSize: await this.transactionPool.getPoolSize(), - count: transactions ? transactions.length : -1 + poolSize: this.transactionPool.getPoolSize(), + count: transactions ? transactions.length : -1, } } @@ -392,10 +550,17 @@ module.exports = class Blockchain { * @param {Block} [block=getLastBlock()] block * @return {Boolean} */ - isSynced (block) { + isSynced(block) { + if (!this.p2p.hasPeers()) { + return true + } + block = block || this.getLastBlock() - return slots.getTime() - block.data.timestamp < 3 * config.getConstants(block.height).blocktime + return ( + slots.getTime() - block.data.timestamp < + 3 * config.getConstants(block.data.height).blocktime + ) } /** @@ -403,7 +568,11 @@ module.exports = class Blockchain { * @param {Block} block * @return {Boolean} */ - isRebuildSynced (block) { + isRebuildSynced(block) { + if (!this.p2p.hasPeers()) { + return true + } + block = block || this.getLastBlock() const remaining = slots.getTime() - block.data.timestamp @@ -418,87 +587,107 @@ module.exports = class Blockchain { * Get the last block of the blockchain. * @return {Object} */ - getLastBlock () { - return stateMachine.state.lastBlock + getLastBlock() { + return this.state.getLastBlock() } /** - * Get the last downloaded block of the blockchain. + * Get the last height of the blockchain. * @return {Object} */ - getLastDownloadedBlock () { - return stateMachine.state.lastDownloadedBlock + getLastHeight() { + return this.state.getLastBlock().data.height } - getBlockPing () { - return stateMachine.state.blockPing + /** + * Get the last downloaded block of the blockchain. + * @return {Object} + */ + getLastDownloadedBlock() { + return this.state.lastDownloadedBlock } - pingBlock (incomingBlock) { - if (!stateMachine.state.blockPing) return false - - if (stateMachine.state.blockPing.block.height === incomingBlock.height && stateMachine.state.blockPing.block.id === incomingBlock.id) { - stateMachine.state.blockPing.count++ - stateMachine.state.blockPing.last = new Date().getTime() - - return true - } - - return false + /** + * Get the block ping. + * @return {Object} + */ + getBlockPing() { + return this.state.blockPing } - pushPingBlock (block) { - // logging for stats about network health - if (stateMachine.state.blockPing) { - logger.info(`Block ${stateMachine.state.blockPing.block.height.toLocaleString()} pinged blockchain ${stateMachine.state.blockPing.count} times`) - } - - stateMachine.state.blockPing = { - count: 1, - first: new Date().getTime(), - last: new Date().getTime(), - block - } + /** + * Ping a block. + * @return {Object} + */ + pingBlock(incomingBlock) { + return this.state.pingBlock(incomingBlock) } /** - * Get the state of the blockchain. + * Push ping block. * @return {Object} */ - get state () { - return stateMachine.state + pushPingBlock(block) { + this.state.pushPingBlock(block) } /** - * Get the state machine. - * @return {Object} + * Get the list of events that are available. + * @return {Array} + */ + getEvents() { + return [ + 'block.applied', + 'block.forged', + 'block.reverted', + 'delegate.registered', + 'delegate.resigned', + 'forger.failed', + 'forger.missing', + 'forger.started', + 'peer.added', + 'peer.removed', + 'round.created', + 'state:started', + 'transaction.applied', + 'transaction.expired', + 'transaction.forged', + 'transaction.reverted', + 'wallet.saved', + 'wallet.created.cold', + ] + } + + /** + * Get the state of the blockchain. + * @return {StateStorage} */ - get stateMachine () { - return stateMachine + get state() { + return stateMachine.state } /** * Get the network (p2p) interface. * @return {P2PInterface} */ - get p2p () { - return container.resolvePlugin('p2p') + get p2p() { + return app.resolvePlugin('p2p') } /** * Get the transaction handler. * @return {TransactionPool} */ - get transactionPool () { - return container.resolvePlugin('transactionPool') + get transactionPool() { + return app.resolvePlugin('transactionPool') } /** * Get the database connection. * @return {ConnectionInterface} */ - get database () { - return container.resolvePlugin('database') + get database() { + return app.resolvePlugin('database') } /** @@ -507,8 +696,9 @@ module.exports = class Blockchain { * @param {Block} nextBlock * @return {Boolean} */ - __isChained (previousBlock, nextBlock) { - const followsPrevious = nextBlock.data.previousBlock === previousBlock.data.id + __isChained(previousBlock, nextBlock) { + const followsPrevious = + nextBlock.data.previousBlock === previousBlock.data.id const isFuture = nextBlock.data.timestamp > previousBlock.data.timestamp const isPlusOne = nextBlock.data.height === previousBlock.data.height + 1 @@ -519,10 +709,10 @@ module.exports = class Blockchain { * Register the block queue. * @return {void} */ - __registerQueue () { + __registerQueue() { this.queue = new Queue(this, { process: 'PROCESSFINISHED', - rebuild: 'REBUILDFINISHED' + rebuild: 'REBUILDFINISHED', }) this.processQueue = this.queue.process diff --git a/packages/core-blockchain/lib/defaults.js b/packages/core-blockchain/lib/defaults.js index a840efde34..24f90de245 100644 --- a/packages/core-blockchain/lib/defaults.js +++ b/packages/core-blockchain/lib/defaults.js @@ -1,6 +1,11 @@ -'use strict' - module.exports = { - version: '2.0.0', - fastRebuild: true + fastRebuild: false, + databaseRollback: { + maxBlockRewind: 10000, + steps: 1000, + }, + state: { + maxLastBlocks: 100, + maxLastTransactionIds: 10000, + }, } diff --git a/packages/core-blockchain/lib/index.js b/packages/core-blockchain/lib/index.js index f2a9698008..54d667b686 100644 --- a/packages/core-blockchain/lib/index.js +++ b/packages/core-blockchain/lib/index.js @@ -1,5 +1,4 @@ -'use strict' - +const { asValue } = require('awilix') const Blockchain = require('./blockchain') /** @@ -10,13 +9,24 @@ exports.plugin = { pkg: require('../package.json'), defaults: require('./defaults'), alias: 'blockchain', - async register (container, options) { + async register(container, options) { const blockchain = new Blockchain(options.networkStart) + container.register('state', asValue(require('./state-storage'))) + if (!process.env.ARK_SKIP_BLOCKCHAIN) { await blockchain.start() } return blockchain - } + }, + async deregister(container, options) { + await container.resolvePlugin('blockchain').stop() + }, } + +/** + * Access to the state. + * @type {StateStorage} + */ +exports.state = require('./state-storage') diff --git a/packages/core-blockchain/lib/machines/actions/fork.js b/packages/core-blockchain/lib/machines/actions/fork.js index 52e6ec643f..87d90d65f1 100644 --- a/packages/core-blockchain/lib/machines/actions/fork.js +++ b/packages/core-blockchain/lib/machines/actions/fork.js @@ -5,22 +5,23 @@ module.exports = { onEntry: ['analyseFork'], on: { REBUILD: 'revertBlocks', - NOFORK: 'exit' - } + NOFORK: 'exit', + }, }, network: { onEntry: ['checkNetwork'], + /* these transitions are not used yet (TODO?) on: { SUCCESS: 'blockchain', FAILURE: 'reset' } + */ }, - revertBlocks: { - }, + revertBlocks: {}, exit: { - onEntry: ['forkRecovered'] - } - } + onEntry: ['forkRecovered'], + }, + }, } // const fork = { diff --git a/packages/core-blockchain/lib/machines/actions/rebuild-from-network.js b/packages/core-blockchain/lib/machines/actions/rebuild-from-network.js index 2649346399..afd3749fc4 100644 --- a/packages/core-blockchain/lib/machines/actions/rebuild-from-network.js +++ b/packages/core-blockchain/lib/machines/actions/rebuild-from-network.js @@ -6,47 +6,47 @@ module.exports = { on: { SYNCED: 'waitingFinished', NOTSYNCED: 'rebuildBlocks', - PAUSED: 'rebuildPaused' - } + PAUSED: 'rebuildPaused', + }, }, idle: { on: { - DOWNLOADED: 'rebuildBlocks' - } + DOWNLOADED: 'rebuildBlocks', + }, }, rebuildBlocks: { onEntry: ['rebuildBlocks'], on: { DOWNLOADED: 'rebuilding', - NOBLOCK: 'rebuilding' - } + NOBLOCK: 'rebuilding', + }, }, waitingFinished: { on: { - REBUILDFINISHED: 'rebuildFinished' - } + REBUILDFINISHED: 'rebuildFinished', + }, }, rebuildFinished: { onEntry: ['rebuildFinished'], on: { - PROCESSFINISHED: 'processFinished' - } + PROCESSFINISHED: 'processFinished', + }, }, rebuildPaused: { onEntry: ['downloadPaused'], on: { - REBUILDFINISHED: 'processFinished' - } + REBUILDFINISHED: 'processFinished', + }, }, processFinished: { onEntry: ['checkRebuildBlockSynced'], on: { SYNCED: 'end', - NOTSYNCED: 'rebuildBlocks' - } + NOTSYNCED: 'rebuildBlocks', + }, }, end: { - onEntry: ['rebuildingComplete'] - } - } + onEntry: ['rebuildingComplete'], + }, + }, } diff --git a/packages/core-blockchain/lib/machines/actions/sync-with-network.js b/packages/core-blockchain/lib/machines/actions/sync-with-network.js index c140b6ce0a..eb81479e88 100644 --- a/packages/core-blockchain/lib/machines/actions/sync-with-network.js +++ b/packages/core-blockchain/lib/machines/actions/sync-with-network.js @@ -7,42 +7,42 @@ module.exports = { SYNCED: 'downloadFinished', NOTSYNCED: 'downloadBlocks', PAUSED: 'downloadPaused', - NETWORKHALTED: 'end' - } + NETWORKHALTED: 'end', + }, }, idle: { on: { - DOWNLOADED: 'downloadBlocks' - } + DOWNLOADED: 'downloadBlocks', + }, }, downloadBlocks: { onEntry: ['downloadBlocks'], on: { DOWNLOADED: 'syncing', - NOBLOCK: 'syncing' - } + NOBLOCK: 'syncing', + }, }, downloadFinished: { onEntry: ['downloadFinished'], on: { - PROCESSFINISHED: 'processFinished' - } + PROCESSFINISHED: 'processFinished', + }, }, downloadPaused: { onEntry: ['downloadPaused'], on: { - PROCESSFINISHED: 'processFinished' - } + PROCESSFINISHED: 'processFinished', + }, }, processFinished: { onEntry: ['checkLastBlockSynced'], on: { SYNCED: 'end', - NOTSYNCED: 'downloadBlocks' - } + NOTSYNCED: 'downloadBlocks', + }, }, end: { - onEntry: ['syncingComplete'] - } - } + onEntry: ['syncingComplete'], + }, + }, } diff --git a/packages/core-blockchain/lib/machines/blockchain.js b/packages/core-blockchain/lib/machines/blockchain.js index cba2d235db..ed8a167e7a 100644 --- a/packages/core-blockchain/lib/machines/blockchain.js +++ b/packages/core-blockchain/lib/machines/blockchain.js @@ -9,8 +9,9 @@ module.exports = Machine({ states: { uninitialised: { on: { - START: 'init' - } + START: 'init', + STOP: 'stopped', + }, }, init: { onEntry: ['init'], @@ -18,49 +19,71 @@ module.exports = Machine({ REBUILD: 'rebuild', NETWORKSTART: 'idle', STARTED: 'syncWithNetwork', - FAILURE: 'exit' - } + ROLLBACK: 'rollback', + FAILURE: 'exit', + STOP: 'stopped', + }, }, rebuild: { on: { REBUILDCOMPLETE: 'syncWithNetwork', FORK: 'fork', - TEST: 'syncWithNetwork' + TEST: 'syncWithNetwork', + STOP: 'stopped', }, - ...rebuildFromNetwork + ...rebuildFromNetwork, }, syncWithNetwork: { on: { TEST: 'idle', SYNCFINISHED: 'idle', - FORK: 'fork' + FORK: 'fork', + STOP: 'stopped', }, - ...syncWithNetwork + ...syncWithNetwork, }, idle: { onEntry: ['checkLater', 'blockchainReady'], on: { WAKEUP: 'syncWithNetwork', - NEWBLOCK: 'processingBlock' - } + NEWBLOCK: 'newBlock', + STOP: 'stopped', + }, }, - processingBlock: { - onEntry: ['processBlock'], + newBlock: { on: { - SUCCESS: 'idle', - FAILURE: 'fork' - } + PROCESSFINISHED: 'idle', + FORK: 'fork', + STOP: 'stopped', + }, }, fork: { onEntry: ['startForkRecovery'], on: { SUCCESS: 'syncWithNetwork', - FAILURE: 'exit' + FAILURE: 'exit', + STOP: 'stopped', }, - ...fork + ...fork, + }, + rollback: { + onEntry: ['rollbackDatabase'], + on: { + SUCCESS: 'init', + FAILURE: 'exit', + STOP: 'stopped', + }, + }, + /** + * This state should be used for stopping the blockchain on purpose, not as + * a result of critical errors. In those cases, using the `exit` state would + * be a better option + */ + stopped: { + onEntry: ['stopped'], }, exit: { - onEntry: ['exitApp'] - } - } + onEntry: ['exitApp'], + }, + }, }) diff --git a/packages/core-blockchain/lib/queue/index.js b/packages/core-blockchain/lib/queue/index.js index adbdcce66a..e132cfebee 100644 --- a/packages/core-blockchain/lib/queue/index.js +++ b/packages/core-blockchain/lib/queue/index.js @@ -8,7 +8,7 @@ module.exports = class Queue { * @param {Object} events * @return {void} */ - constructor (blockchain, events) { + constructor(blockchain, events) { this.process = new ProcessQueue(blockchain, events.process) this.rebuild = new RebuildQueue(blockchain, events.rebuild) } @@ -17,29 +17,31 @@ module.exports = class Queue { * Pause all queues. * @return {void} */ - pause () { + pause() { this.rebuild.pause() this.process.pause() } /** * Flush all queues. - * @param {Object} stateMachine * @return {void} */ - clear (stateMachine) { - this.rebuild.remove(() => true) - // TODO: move this, not the responsibility of the queue - stateMachine.state.lastDownloadedBlock = stateMachine.state.lastBlock - this.process.remove(() => true) + clear() { + this.rebuild.clear() + this.process.clear() } /** * Resue all queues. * @return {void} */ - resume () { + resume() { this.rebuild.resume() this.process.resume() } + + destroy() { + this.rebuild.destroy() + this.process.destroy() + } } diff --git a/packages/core-blockchain/lib/queue/interface.js b/packages/core-blockchain/lib/queue/interface.js index 9807b93c3b..e2731b7498 100644 --- a/packages/core-blockchain/lib/queue/interface.js +++ b/packages/core-blockchain/lib/queue/interface.js @@ -5,7 +5,7 @@ module.exports = class QueueInterface { * @param {String} event * @return {void} */ - constructor (blockchain, event) { + constructor(blockchain, event) { this.blockchain = blockchain this.event = event } @@ -14,7 +14,7 @@ module.exports = class QueueInterface { * Drain the queue. * @return {void} */ - drain () { + drain() { this.queue.drain = () => this.blockchain.dispatch(this.event) } @@ -22,7 +22,7 @@ module.exports = class QueueInterface { * Pause the queue. * @return {void} */ - pause () { + pause() { return this.queue.pause() } @@ -30,7 +30,7 @@ module.exports = class QueueInterface { * Flush the queue. * @return {void} */ - clear () { + clear() { return this.queue.remove(() => true) } @@ -38,7 +38,7 @@ module.exports = class QueueInterface { * Resume the queue. * @return {void} */ - resume () { + resume() { return this.queue.resume() } @@ -46,23 +46,28 @@ module.exports = class QueueInterface { * Remove the item from the queue. * @return {void} */ - remove (item) { + remove(item) { return this.queue.remove(item) } /** * Push the item to the queue. + * @param {Function} callback * @return {void} */ - push (item) { - return this.queue.push(item) + push(callback) { + return this.queue.push(callback) } /** * Get the length of the queue. * @return {void} */ - length () { + length() { return this.queue.length() } + + destroy() { + return this.queue.kill() + } } diff --git a/packages/core-blockchain/lib/queue/process.js b/packages/core-blockchain/lib/queue/process.js index 37a0096a4c..b2e3fc8d13 100644 --- a/packages/core-blockchain/lib/queue/process.js +++ b/packages/core-blockchain/lib/queue/process.js @@ -9,14 +9,17 @@ module.exports = class ProcessQueue extends QueueInterface { * @param {Blockchain} blockchain * @return {void} */ - constructor (blockchain, event) { + constructor(blockchain, event) { super(blockchain, event) this.queue = async.queue((block, cb) => { try { return blockchain.processBlock(new Block(block), cb) } catch (error) { - logger.error(`Failed to process block in ProcessQueue: ${block.height.toLocaleString()}`) + logger.error( + `Failed to process block in ProcessQueue: ${block.height.toLocaleString()}`, + ) + logger.error(error.stack) return cb() } }, 1) diff --git a/packages/core-blockchain/lib/queue/rebuild.js b/packages/core-blockchain/lib/queue/rebuild.js index cb50bdaaed..5d75f81ec3 100644 --- a/packages/core-blockchain/lib/queue/rebuild.js +++ b/packages/core-blockchain/lib/queue/rebuild.js @@ -9,20 +9,20 @@ module.exports = class RebuildQueue extends QueueInterface { * @param {Blockchain} blockchain * @return {void} */ - constructor (blockchain, event) { + constructor(blockchain, event) { super(blockchain, event) - this.queue = async.queue( - (block, cb) => { - if (this.queue.paused) return cb() - try { - return blockchain.rebuildBlock(new Block(block), cb) - } catch (error) { - logger.error(`Failed to rebuild block in RebuildQueue: ${block.height.toLocaleString()}`) - return cb() - } - }, 1 - ) + this.queue = async.queue((block, cb) => { + if (this.queue.paused) return cb() + try { + return blockchain.rebuildBlock(new Block(block), cb) + } catch (error) { + logger.error( + `Failed to rebuild block in RebuildQueue: ${block.height.toLocaleString()}`, + ) + return cb() + } + }, 1) this.drain() } diff --git a/packages/core-blockchain/lib/state-machine.js b/packages/core-blockchain/lib/state-machine.js index db3f4c3b86..75773136c3 100644 --- a/packages/core-blockchain/lib/state-machine.js +++ b/packages/core-blockchain/lib/state-machine.js @@ -1,34 +1,22 @@ -'use strict' +/* eslint no-await-in-loop: "off" */ -const container = require('@arkecosystem/core-container') -const config = container.resolvePlugin('config') -const emitter = container.resolvePlugin('event-emitter') -const logger = container.resolvePlugin('logger') +const app = require('@arkecosystem/core-container') + +const config = app.resolvePlugin('config') +const emitter = app.resolvePlugin('event-emitter') +const logger = app.resolvePlugin('logger') const { slots } = require('@arkecosystem/crypto') const { Block } = require('@arkecosystem/crypto').models +const { roundCalculator } = require('@arkecosystem/core-utils') -const delay = require('delay') +const pluralize = require('pluralize') const tickSyncTracker = require('./utils/tick-sync-tracker') const blockchainMachine = require('./machines/blockchain') +const state = require('./state-storage') /** - * Initial state of the machine. - * @type {Object} - */ -const state = { - blockchain: blockchainMachine.initialState, - lastDownloadedBlock: null, - lastBlock: null, - blockPing: null, - started: false, - rebuild: true, - fastRebuild: true, - noBlockCounter: 0 -} - -/** - * @type {Object} + * @type {StateStorage} */ blockchainMachine.state = state @@ -37,305 +25,426 @@ blockchainMachine.state = state * @param {Blockchain} blockchain * @return {Object} */ -blockchainMachine.actionMap = blockchain => { - return { - blockchainReady: () => { - if (!state.started) { - state.started = true - emitter.emit('state:started', true) - } - }, - - async checkLater () { - await delay(60000) - - return blockchain.dispatch('WAKEUP') - }, - - checkLastBlockSynced () { - return blockchain.dispatch(blockchain.isSynced() ? 'SYNCED' : 'NOTSYNCED') - }, +blockchainMachine.actionMap = blockchain => ({ + blockchainReady: () => { + if (!state.started) { + state.started = true + emitter.emit('state:started', true) + } + }, + + checkLater() { + if (!blockchain.isStopped && !state.checkLaterTimeout) { + state.checkLaterTimeout = setTimeout(() => { + state.checkLaterTimeout = null + return blockchain.dispatch('WAKEUP') + }, 60000) + } + }, + + checkLastBlockSynced() { + return blockchain.dispatch(blockchain.isSynced() ? 'SYNCED' : 'NOTSYNCED') + }, + + checkRebuildBlockSynced() { + return blockchain.dispatch( + blockchain.isRebuildSynced() ? 'SYNCED' : 'NOTSYNCED', + ) + }, + + async checkLastDownloadedBlockSynced() { + let event = 'NOTSYNCED' + logger.debug( + `Queued blocks (rebuild: ${blockchain.rebuildQueue.length()} process: ${blockchain.processQueue.length()})`, + ) + + await blockchain.p2p.updateNetworkStatusIfNotEnoughPeers() + + if ( + blockchain.rebuildQueue.length() > 10000 || + blockchain.processQueue.length() > 10000 + ) { + event = 'PAUSED' + } - checkRebuildBlockSynced () { - return blockchain.dispatch(blockchain.isRebuildSynced() ? 'SYNCED' : 'NOTSYNCED') - }, + // tried to download but no luck after 5 tries (looks like network missing blocks) + if (state.noBlockCounter > 5) { + // TODO: make this dynamic in 2.1 + logger.info( + 'Tried to sync 5 times to different nodes, looks like the network is missing blocks :umbrella:', + ) - checkLastDownloadedBlockSynced () { - let event = 'NOTSYNCED' - logger.debug(`Blocks in queue: ${blockchain.rebuildQueue.length()}`) + state.noBlockCounter = 0 + event = 'NETWORKHALTED' - if (blockchain.rebuildQueue.length() > 10000) { - event = 'PAUSED' - } + if (state.p2pUpdateCounter + 1 > 3) { + logger.info('Network keeps missing blocks. :umbrella:') - // tried to download but no luck after 5 tries (looks like network missing blocks) - if (state.noBlockCounter > 5) { - logger.info('Tried to sync 5 times to different nodes, looks like the network is missing blocks :umbrella:') - - state.noBlockCounter = 0 + const result = await blockchain.p2p.updatePeersOnMissingBlocks() + if (result === 'rollback') { + event = 'FORK' + } - event = 'NETWORKHALTED' + state.p2pUpdateCounter = 0 + } else { + state.p2pUpdateCounter++ } + } - if (blockchain.isSynced(state.lastDownloadedBlock)) { - state.noBlockCounter = 0 - event = 'SYNCED' - } + if (blockchain.isSynced(state.lastDownloadedBlock)) { + state.noBlockCounter = 0 + state.p2pUpdateCounter = 0 - if (state.networkStart) { - event = 'SYNCED' - } + event = 'SYNCED' + } - if (process.env.ARK_ENV === 'test') { - event = 'TEST' - } + if (state.networkStart) { + event = 'SYNCED' + } - blockchain.dispatch(event) - }, + if (process.env.ARK_ENV === 'test') { + event = 'TEST' + } - downloadFinished () { - logger.info('Block download finished :rocket:') + blockchain.dispatch(event) + }, - if (state.networkStart) { - // next time we will use normal behaviour - state.networkStart = false + downloadFinished() { + logger.info('Block download finished :rocket:') - blockchain.dispatch('SYNCFINISHED') - } else if (blockchain.rebuildQueue.length() === 0) { - blockchain.dispatch('PROCESSFINISHED') - } - }, + if (state.networkStart) { + // next time we will use normal behaviour + state.networkStart = false - async rebuildFinished () { - try { - logger.info('Blockchain rebuild finished :chains:') + blockchain.dispatch('SYNCFINISHED') + } else if (blockchain.rebuildQueue.length() === 0) { + blockchain.dispatch('PROCESSFINISHED') + } + }, - state.rebuild = false + async rebuildFinished() { + try { + logger.info('Blockchain rebuild finished :chains:') - await blockchain.database.saveBlockCommit() - await blockchain.rollbackCurrentRound() - await blockchain.database.buildWallets(state.lastBlock.data.height) - await blockchain.database.saveWallets(true) - await blockchain.transactionPool.buildWallets() - // await blockchain.database.applyRound(blockchain.getLastBlock().data.height) + state.rebuild = false - return blockchain.dispatch('PROCESSFINISHED') - } catch (error) { - logger.error(error.stack) - return blockchain.dispatch('FAILURE') - } - }, + await blockchain.database.commitQueuedQueries() + await blockchain.rollbackCurrentRound() + await blockchain.database.buildWallets(state.getLastBlock().data.height) + await blockchain.database.saveWallets(true) + await blockchain.transactionPool.buildWallets() - downloadPaused: () => logger.info('Blockchain download paused :clock1030:'), + return blockchain.dispatch('PROCESSFINISHED') + } catch (error) { + logger.error(error.stack) + return blockchain.dispatch('FAILURE') + } + }, - syncingComplete () { - logger.info('Blockchain 100% in sync :100:') - blockchain.dispatch('SYNCFINISHED') - }, + downloadPaused: () => logger.info('Blockchain download paused :clock1030:'), - rebuildingComplete () { - logger.info('Blockchain rebuild complete :unicorn_face:') - blockchain.dispatch('REBUILDCOMPLETE') - }, + syncingComplete() { + logger.info('Blockchain 100% in sync :100:') + blockchain.dispatch('SYNCFINISHED') + }, - exitApp () { - logger.error('Failed to startup blockchain. Exiting ARK Core! :rotating_light:') - process.exit(1) - }, + rebuildingComplete() { + logger.info('Blockchain rebuild complete :unicorn_face:') + blockchain.dispatch('REBUILDCOMPLETE') + }, - async init () { - // p2p = container.resolvePlugin('p2p') + stopped() { + logger.info('The blockchain has been stopped :guitar:') + }, - try { - let block = await blockchain.database.getLastBlock() + exitApp() { + app.forceExit( + 'Failed to startup blockchain. Exiting Ark Core! :rotating_light:', + ) + }, - if (!block) { - logger.warn('No block found in database :hushed:') + async init() { + try { + let block = await blockchain.database.getLastBlock() - block = new Block(config.genesisBlock) + if (!block) { + logger.warn('No block found in database :hushed:') - if (block.data.payloadHash !== config.network.nethash) { - logger.error('FATAL: The genesis block payload hash is different from configured the nethash :rotating_light:') + block = new Block(config.genesisBlock) - return blockchain.dispatch('FAILURE') - } + if (block.data.payloadHash !== config.network.nethash) { + logger.error( + 'FATAL: The genesis block payload hash is different from configured the nethash :rotating_light:', + ) - await blockchain.database.saveBlock(block) + return blockchain.dispatch('FAILURE') } - logger.info('Verifying database integrity :hourglass_flowing_sand:') - - const databaseBlokchain = await blockchain.database.verifyBlockchain() + await blockchain.database.saveBlock(block) + } - if (!databaseBlokchain.valid) { - logger.error('FATAL: The database is corrupted :rotating_light:') + if (!blockchain.restoredDatabaseIntegrity) { + logger.info('Verifying database integrity :hourglass_flowing_sand:') - console.error(databaseBlokchain.errors) + const blockchainAudit = await blockchain.database.verifyBlockchain() + if (!blockchainAudit.valid) { + logger.error('FATAL: The database is corrupted :fire:') + logger.error(JSON.stringify(blockchainAudit.errors, null, 4)) - return blockchain.dispatch('FAILURE') + return blockchain.dispatch('ROLLBACK') } logger.info('Verified database integrity :smile_cat:') + } else { + logger.info( + 'Skipping database integrity check after successful database recovery :smile_cat:', + ) + } - // only genesis block? special case of first round needs to be dealt with - if (block.data.height === 1) { - await blockchain.database.deleteRound(1) - } + // only genesis block? special case of first round needs to be dealt with + if (block.data.height === 1) { + await blockchain.database.deleteRound(1) + } - /********************************* - * state machine data init * - ********************************/ - const constants = config.getConstants(block.data.height) - state.lastBlock = block - state.lastDownloadedBlock = block + /** ******************************* + * state machine data init * + ******************************* */ + const constants = config.getConstants(block.data.height) + state.setLastBlock(block) + state.lastDownloadedBlock = block - if (state.networkStart) { - await blockchain.database.buildWallets(block.data.height) - await blockchain.database.saveWallets(true) - await blockchain.database.applyRound(block.data.height) - await blockchain.transactionPool.buildWallets() + if (state.networkStart) { + await blockchain.database.buildWallets(block.data.height) + await blockchain.database.saveWallets(true) + await blockchain.database.applyRound(block.data.height) + await blockchain.transactionPool.buildWallets() - return blockchain.dispatch('STARTED') - } + return blockchain.dispatch('STARTED') + } - state.rebuild = (slots.getTime() - block.data.timestamp > (constants.activeDelegates + 1) * constants.blocktime) - // no fast rebuild if in last week - state.fastRebuild = (slots.getTime() - block.data.timestamp > 3600 * 24 * 7) && !!container.resolveOptions('blockchain').fastRebuild + state.rebuild = + slots.getTime() - block.data.timestamp > + (constants.activeDelegates + 1) * constants.blocktime + // no fast rebuild if in last week + state.fastRebuild = + slots.getTime() - block.data.timestamp > 3600 * 24 * 7 && + !!app.resolveOptions('blockchain').fastRebuild - if (process.env.NODE_ENV === 'test') { - logger.verbose('TEST SUITE DETECTED! SYNCING WALLETS AND STARTING IMMEDIATELY. :bangbang:') + if (process.env.NODE_ENV === 'test') { + logger.verbose( + 'TEST SUITE DETECTED! SYNCING WALLETS AND STARTING IMMEDIATELY. :bangbang:', + ) - state.lastBlock = new Block(config.genesisBlock) - await blockchain.database.buildWallets(block.data.height) + state.setLastBlock(new Block(config.genesisBlock)) + await blockchain.database.buildWallets(block.data.height) - return blockchain.dispatch('STARTED') - } + return blockchain.dispatch('STARTED') + } - logger.info(`Fast rebuild: ${state.fastRebuild}`) - logger.info(`Last block in database: ${block.data.height.toLocaleString()}`) + logger.info(`Fast rebuild: ${state.fastRebuild}`) + logger.info( + `Last block in database: ${block.data.height.toLocaleString()}`, + ) - if (state.fastRebuild) { - return blockchain.dispatch('REBUILD') - } + if (state.fastRebuild) { + return blockchain.dispatch('REBUILD') + } - // removing blocks up to the last round to compute active delegate list later if needed - const activeDelegates = await blockchain.database.getActiveDelegates(block.data.height) + // removing blocks up to the last round to compute active delegate list later if needed + const activeDelegates = await blockchain.database.getActiveDelegates( + block.data.height, + ) - if (!activeDelegates) { - await blockchain.rollbackCurrentRound() - } + if (!activeDelegates) { + await blockchain.rollbackCurrentRound() + } - /********************************* - * database init * - ********************************/ - // SPV rebuild - await blockchain.database.buildWallets(block.data.height) + /** ******************************* + * database init * + ******************************* */ + // SPV rebuild + const verifiedWalletsIntegrity = await blockchain.database.buildWallets( + block.data.height, + ) + if (!verifiedWalletsIntegrity && block.data.height > 1) { + logger.warn( + 'Rebuilding wallets table because of some inconsistencies. Most likely due to an unfortunate shutdown. :hammer:', + ) await blockchain.database.saveWallets(true) + } - // Edge case: if the node is shutdown between round, the round has already been applied - if (blockchain.database.isNewRound(block.data.height + 1)) { - const round = blockchain.database.getRound(block.data.height + 1) + // NOTE: if the node is shutdown between round, the round has already been applied + if (roundCalculator.isNewRound(block.data.height + 1)) { + const { round } = roundCalculator.calculateRound(block.data.height + 1) - logger.info(`New round ${round} detected. Cleaning calculated data before restarting!`) + logger.info( + `New round ${round.toLocaleString()} detected. Cleaning calculated data before restarting!`, + ) - await blockchain.database.deleteRound(round) - } + await blockchain.database.deleteRound(round) + } - await blockchain.database.applyRound(block.data.height) - await blockchain.transactionPool.buildWallets() + await blockchain.database.applyRound(block.data.height) + await blockchain.transactionPool.buildWallets() - return blockchain.dispatch('STARTED') - } catch (error) { - logger.error(error.stack) + return blockchain.dispatch('STARTED') + } catch (error) { + logger.error(error.stack) + + return blockchain.dispatch('FAILURE') + } + }, + + async rebuildBlocks() { + const lastBlock = state.lastDownloadedBlock || state.getLastBlock() + const blocks = await blockchain.p2p.downloadBlocks(lastBlock.data.height) + + tickSyncTracker(blocks.length, lastBlock.data.height) + + if (!blocks || blocks.length === 0) { + logger.info('No new blocks found on this peer') + + blockchain.dispatch('NOBLOCK') + } else { + logger.info( + `Downloaded ${blocks.length} new ${pluralize( + 'block', + blocks.length, + )} accounting for a total of ${pluralize( + 'transaction', + blocks.reduce((sum, b) => sum + b.numberOfTransactions, 0), + true, + )}`, + ) + + if (blocks.length && blocks[0].previousBlock === lastBlock.data.id) { + state.lastDownloadedBlock = { data: blocks.slice(-1)[0] } + blockchain.rebuildQueue.push(blocks) + blockchain.dispatch('DOWNLOADED') + } else { + logger.warn( + `Downloaded block not accepted: ${JSON.stringify(blocks[0])}`, + ) + logger.warn(`Last block: ${JSON.stringify(lastBlock.data)}`) - return blockchain.dispatch('FAILURE') + // disregard the whole block list + blockchain.dispatch('NOBLOCK') } - }, + } + }, + + async downloadBlocks() { + const lastBlock = state.lastDownloadedBlock || state.getLastBlock() + const blocks = await blockchain.p2p.downloadBlocks(lastBlock.data.height) - async rebuildBlocks () { - const lastBlock = state.lastDownloadedBlock || state.lastBlock - const blocks = await blockchain.p2p.downloadBlocks(lastBlock.data.height) + if (blockchain.isStopped) { + return + } - tickSyncTracker(blocks.length) + if (!blocks || blocks.length === 0) { + logger.info('No new block found on this peer') + + state.noBlockCounter++ + + blockchain.dispatch('NOBLOCK') + } else { + logger.info( + `Downloaded ${blocks.length} new ${pluralize( + 'block', + blocks.length, + )} accounting for a total of ${pluralize( + 'transaction', + blocks.reduce((sum, b) => sum + b.numberOfTransactions, 0), + true, + )}`, + ) + + if (blocks.length && blocks[0].previousBlock === lastBlock.data.id) { + state.noBlockCounter = 0 + state.p2pUpdateCounter = 0 + state.lastDownloadedBlock = { data: blocks.slice(-1)[0] } - if (!blocks || blocks.length === 0) { - logger.info('No new blocks found on this peer') + blockchain.processQueue.push(blocks) - blockchain.dispatch('NOBLOCK') + blockchain.dispatch('DOWNLOADED') } else { - logger.info(`Downloaded ${blocks.length} new blocks accounting for a total of ${blocks.reduce((sum, b) => sum + b.numberOfTransactions, 0)} transactions`) - if (blocks.length && blocks[0].previousBlock === lastBlock.data.id) { - state.lastDownloadedBlock = {data: blocks.slice(-1)[0]} - blockchain.rebuildQueue.push(blocks) - blockchain.dispatch('DOWNLOADED') - } else { - // state.lastDownloadedBlock = state.lastBlock - - logger.warn('Downloaded block not accepted: ' + JSON.stringify(blocks[0])) - logger.warn('Last block: ' + JSON.stringify(lastBlock.data)) - - // disregard the whole block list - blockchain.dispatch('NOBLOCK') - } - } - }, + state.lastDownloadedBlock = lastBlock - async downloadBlocks () { - const lastBlock = state.lastDownloadedBlock || state.lastBlock - const blocks = await blockchain.p2p.downloadBlocks(lastBlock.data.height) + logger.warn( + `Downloaded block not accepted: ${JSON.stringify(blocks[0])}`, + ) + logger.warn(`Last block: ${JSON.stringify(lastBlock.data)}`) - if (!blocks || blocks.length === 0) { - logger.info('No new block found on this peer') + state.forked = true + state.forkedBlock = blocks[0] - state.noBlockCounter++ + // disregard the whole block list + blockchain.dispatch('FORK') + } + } + }, - blockchain.dispatch('NOBLOCK') - } else { - logger.info(`Downloaded ${blocks.length} new blocks accounting for a total of ${blocks.reduce((sum, b) => sum + b.numberOfTransactions, 0)} transactions`) + async analyseFork() { + logger.info('Analysing fork :mag:') + }, - if (blocks.length && blocks[0].previousBlock === lastBlock.data.id) { - state.noBlockCounter = 0 - state.lastDownloadedBlock = {data: blocks.slice(-1)[0]} + async startForkRecovery() { + logger.info('Starting fork recovery :fork_and_knife:') - blockchain.processQueue.push(blocks) + await blockchain.database.commitQueuedQueries() - blockchain.dispatch('DOWNLOADED') - } else { - state.lastDownloadedBlock = state.lastBlock + let random = Math.floor(4 / Math.random()) - logger.warn('Downloaded block not accepted: ' + JSON.stringify(blocks[0])) - logger.warn('Last block: ' + JSON.stringify(lastBlock.data)) + if (random > 102) { + random = 102 + } - blockchain.p2p.banPeer(blocks[0].ip) + await blockchain.removeBlocks(random) - // disregard the whole block list - blockchain.dispatch('FORK') - } - } - }, + logger.info(`Removed ${pluralize('block', random, true)} :wastebasket:`) - async analyseFork () { - logger.info('Analysing fork :mag:') - }, + await blockchain.transactionPool.buildWallets() + await blockchain.p2p.refreshPeersAfterFork() - async startForkRecovery () { - logger.info('Starting fork recovery :fork_and_knife:') + blockchain.dispatch('SUCCESS') + }, - await blockchain.database.saveBlockCommit() - // state.forked = true - let random = ~~(4 / Math.random()) + async rollbackDatabase() { + logger.info('Trying to restore database integrity :fire_engine:') - if (random > 102) { - random = 102 - } + const { maxBlockRewind, steps } = app.resolveOptions( + 'blockchain', + ).databaseRollback + let blockchainAudit - await blockchain.removeBlocks(random) + for (let i = maxBlockRewind; i >= 0; i -= steps) { + await blockchain.removeTopBlocks(steps) - logger.info(`Removed ${random} blocks :wastebasket:`) + blockchainAudit = await blockchain.database.verifyBlockchain() + if (blockchainAudit.valid) { + break + } + } - blockchain.dispatch('SUCCESS') + if (!blockchainAudit.valid) { + // TODO: multiple attempts? rewind further? restore snapshot? + logger.error( + 'FATAL: Failed to restore database integrity :skull: :skull: :skull:', + ) + logger.error(JSON.stringify(blockchainAudit.errors, null, 4)) + blockchain.dispatch('FAILURE') + return } - } -} + + blockchain.restoredDatabaseIntegrity = true + + const lastBlock = await blockchain.database.getLastBlock() + logger.info( + `Database integrity verified again after rollback to height ${lastBlock.data.height.toLocaleString()} :green_heart:`, + ) + + blockchain.dispatch('SUCCESS') + }, +}) module.exports = blockchainMachine diff --git a/packages/core-blockchain/lib/state-storage.js b/packages/core-blockchain/lib/state-storage.js new file mode 100644 index 0000000000..92e9ddc0e3 --- /dev/null +++ b/packages/core-blockchain/lib/state-storage.js @@ -0,0 +1,254 @@ +/* eslint max-len: "off" */ + +const app = require('@arkecosystem/core-container') + +const logger = app.resolvePlugin('logger') +const immutable = require('immutable') +const assert = require('assert') +const blockchainMachine = require('./machines/blockchain') + +// Stores the last n blocks in ascending height. The amount of last blocks +// can be configured with the option `state.maxLastBlocks`. +let _lastBlocks = immutable.OrderedMap() + +// Stores the last n incoming transaction ids. The amount of transaction ids +// can be configred with the option `state.maxLastTransactionIds`. +let _cachedTransactionIds = immutable.OrderedSet() + +// Map Block instances to block data. +const _mapToBlockData = blocks => + blocks.map(block => ({ ...block.data, transactions: block.transactions })) + +/** + * Represents an in-memory storage for state machine data. + */ +class StateStorage { + constructor() { + this.reset() + } + + /** + * Resets the state. + * @returns {void} + */ + reset() { + this.blockchain = blockchainMachine.initialState + this.lastDownloadedBlock = null + this.blockPing = null + this.started = false + this.forked = false + this.forkedBlock = null + this.rebuild = true + this.fastRebuild = false + this.checkLaterTimeout = null + this.noBlockCounter = 0 + this.p2pUpdateCounter = 0 + this.networkStart = false + + this.clear() + } + + /** + * Clear last blocks. + * @returns {void} + */ + clear() { + _lastBlocks = _lastBlocks.clear() + _cachedTransactionIds = _cachedTransactionIds.clear() + } + + /** + * Clear check later timeout. + * @returns {void} + */ + clearCheckLater() { + if (this.checkLaterTimeout) { + clearTimeout(this.checkLaterTimeout) + this.checkLaterTimeout = null + } + } + + /** + * Get the last block. + * @returns {Block|null} + */ + getLastBlock() { + return _lastBlocks.last() || null + } + + /** + * Sets the last block. + * @returns {void} + */ + setLastBlock(block) { + // Only keep blocks which are below the new block height (i.e. rollback) + if ( + _lastBlocks.last() && + _lastBlocks.last().data.height !== block.data.height - 1 + ) { + assert(block.data.height - 1 <= _lastBlocks.last().data.height) + _lastBlocks = _lastBlocks.filter(b => b.data.height < block.data.height) + } + + _lastBlocks = _lastBlocks.set(block.data.height, block) + + // Delete oldest block if size exceeds the maximum + if ( + _lastBlocks.size > + app.resolveOptions('blockchain').state.maxLastBlocks + ) { + _lastBlocks = _lastBlocks.delete(_lastBlocks.first().data.height) + } + } + + /** + * Get the last blocks. + * @returns {Array} + */ + getLastBlocks() { + return _lastBlocks + .valueSeq() + .reverse() + .toArray() + } + + /** + * Get the last blocks data. + * @returns {Seq} + */ + getLastBlocksData() { + return _mapToBlockData(_lastBlocks.valueSeq().reverse()) + } + + /** + * Get the last block ids. + * @returns {Array} + */ + getLastBlockIds() { + return _lastBlocks + .valueSeq() + .reverse() + .map(b => b.data.id) + .toArray() + } + + /** + * Get last blocks in the given height range in ascending order. + * @param {Number} start + * @param {Number} end + */ + getLastBlocksByHeight(start, end) { + end = end || start + + const blocks = _lastBlocks + .valueSeq() + .filter(block => block.data.height >= start && block.data.height <= end) + + return _mapToBlockData(blocks).toArray() + } + + /** + * Get common blocks for the given IDs. + * @returns {Array} + */ + getCommonBlocks(ids) { + return this.getLastBlocksData() + .filter(block => ids.includes(block.id)) + .toArray() + } + + /** + * Cache the ids of the given transactions. + * @param {Array} transactions + * @return Object { + * added: array of added transactions, + * notAdded: array of previously added transactions + * } + */ + cacheTransactions(transactions) { + const notAdded = [] + const added = transactions.filter(tx => { + if (_cachedTransactionIds.has(tx.id)) { + notAdded.push(tx) + return false + } + return true + }) + + _cachedTransactionIds = _cachedTransactionIds.withMutations(cache => { + added.forEach(tx => cache.add(tx.id)) + }) + + // Cap the Set of last transaction ids to maxLastTransactionIds + const limit = app.resolveOptions('blockchain').state + .maxLastTransactionIds + if (_cachedTransactionIds.size > limit) { + _cachedTransactionIds = _cachedTransactionIds.takeLast(limit) + } + + return { added, notAdded } + } + + /** + * Remove the given transaction ids from the cache. + * @param {Array} transactionIds + * @returns {void} + */ + removeCachedTransactionIds(transactionIds) { + _cachedTransactionIds = _cachedTransactionIds.subtract(transactionIds) + } + + /** + * Get cached transaction ids. + * @returns {Array} + */ + getCachedTransactionIds() { + return _cachedTransactionIds.toArray() + } + + /** + * Ping a block. + * @param {Block} incomingBlock + * @returns {Boolean} + */ + pingBlock(incomingBlock) { + if (!this.blockPing) return false + + if ( + this.blockPing.block.height === incomingBlock.height && + this.blockPing.block.id === incomingBlock.id + ) { + this.blockPing.count++ + this.blockPing.last = new Date().getTime() + + return true + } + + return false + } + + /** + * Push ping block + * @param {Block} block + * @returns {void} + */ + pushPingBlock(block) { + // logging for stats about network health + if (this.blockPing) { + logger.info( + `Block ${this.blockPing.block.height.toLocaleString()} pinged blockchain ${ + this.blockPing.count + } times`, + ) + } + + this.blockPing = { + count: 1, + first: new Date().getTime(), + last: new Date().getTime(), + block, + } + } +} + +module.exports = Object.seal(new StateStorage()) diff --git a/packages/core-blockchain/lib/utils/tick-sync-tracker.js b/packages/core-blockchain/lib/utils/tick-sync-tracker.js index c41250a29b..e80ed908e8 100644 --- a/packages/core-blockchain/lib/utils/tick-sync-tracker.js +++ b/packages/core-blockchain/lib/utils/tick-sync-tracker.js @@ -1,23 +1,20 @@ const prettyMs = require('pretty-ms') -const container = require('@arkecosystem/core-container') -const logger = container.resolvePlugin('logger') -const database = container.resolvePlugin('database') +const app = require('@arkecosystem/core-container') +const logger = app.resolvePlugin('logger') let tracker = null -module.exports = async blockCount => { +module.exports = async (blockCount, count) => { if (!tracker) { - const { count } = await database.blocks.count() - tracker = { start: new Date().getTime(), - networkHeight: container.resolvePlugin('p2p').getMonitor().getNetworkHeight(), + networkHeight: app.resolvePlugin('p2p').getNetworkHeight(), blocksInitial: +count, blocksDownloaded: +count, blocksSession: 0, blocksPerMillisecond: 0, remainingInMilliseconds: 0, - percent: 0 + percent: 0, } } @@ -32,18 +29,32 @@ module.exports = async blockCount => { tracker.blocksPerMillisecond = tracker.blocksSession / diffSinceStart // The time left to download the missing blocks in milliseconds - tracker.remainingInMilliseconds = (tracker.networkHeight - tracker.blocksDownloaded) / tracker.blocksPerMillisecond - tracker.remainingInMilliseconds = Math.abs(Math.trunc(tracker.remainingInMilliseconds)) + tracker.remainingInMilliseconds = + (tracker.networkHeight - tracker.blocksDownloaded) / + tracker.blocksPerMillisecond + tracker.remainingInMilliseconds = Math.abs( + Math.trunc(tracker.remainingInMilliseconds), + ) // The percentage of total blocks that has been downloaded tracker.percent = (tracker.blocksDownloaded * 100) / tracker.networkHeight - if (tracker.percent < 100 && isFinite(tracker.remainingInMilliseconds)) { + if ( + tracker.percent < 100 && + Number.isFinite(tracker.remainingInMilliseconds) + ) { const blocksDownloaded = tracker.blocksDownloaded.toLocaleString() const networkHeight = tracker.networkHeight.toLocaleString() - const timeLeft = prettyMs(tracker.remainingInMilliseconds, { secDecimalDigits: 0 }) + const timeLeft = prettyMs(tracker.remainingInMilliseconds, { + secDecimalDigits: 0, + }) - logger.printTracker('Fast Sync', tracker.percent, 100, `(${blocksDownloaded} of ${networkHeight} blocks - Est. ${timeLeft})`) + logger.printTracker( + 'Fast Sync', + tracker.percent, + 100, + `(${blocksDownloaded} of ${networkHeight} blocks - Est. ${timeLeft})`, + ) } if (tracker.percent === 100) { diff --git a/packages/core-blockchain/package.json b/packages/core-blockchain/package.json index dad705ff46..d2aab7980e 100644 --- a/packages/core-blockchain/package.json +++ b/packages/core-blockchain/package.json @@ -1,7 +1,7 @@ { "name": "@arkecosystem/core-blockchain", - "description": "Blockchain Manager for ARK Core", - "version": "0.1.1", + "description": "Blockchain Manager for Ark Core", + "version": "0.2.0", "contributors": [ "François-Xavier Thoorens ", "Kristjan Košič ", @@ -10,28 +10,36 @@ "license": "MIT", "main": "lib/index.js", "scripts": { - "build:docs": "../../node_modules/.bin/jsdoc -c jsdoc.json", "test": "cross-env ARK_ENV=test jest --runInBand --detectOpenHandles", - "test:coverage": "cross-env ARK_ENV=test jest --coverage --runInBand --detectOpenHandles", - "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand --watch", + "test:coverage": "cross-env ARK_ENV=test jest --coverage --coveragePathIgnorePatterns='/(defaults.js|index.js)$' --runInBand --detectOpenHandles", + "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand", "test:watch": "cross-env ARK_ENV=test jest --runInBand --watch", "test:watch:all": "cross-env ARK_ENV=test jest --runInBand --watchAll", "lint": "eslint ./ --fix", "depcheck": "depcheck ./" }, "dependencies": { - "@arkecosystem/core-container": "^0.1.1", - "@arkecosystem/crypto": "^0.1.1", + "@arkecosystem/core-container": "~0.2", + "@arkecosystem/core-utils": "~0.2", + "@arkecosystem/crypto": "~0.2", "async": "^2.6.1", - "awilix": "^3.0.8", - "delay": "^2.0.0", - "pretty-ms": "^3.2.0", - "xstate": "^3.2.1" + "awilix": "^4.0.1", + "delay": "^4.1.0", + "pretty-ms": "^4.0.0", + "xstate": "^4.1.2", + "immutable": "^4.0.0-rc.12", + "pluralize": "^7.0.0" + }, + "devDependencies": { + "@arkecosystem/core-p2p": "~0.2", + "@arkecosystem/core-test-utils": "~0.2", + "axios": "^0.18.0", + "axios-mock-adapter": "^1.15.0" }, "publishConfig": { "access": "public" }, - "devDependencies": { - "@arkecosystem/core-test-utils": "^0.1.1" + "engines": { + "node": ">=10.x" } } diff --git a/packages/core-config/CHANGELOG.md b/packages/core-config/CHANGELOG.md index 127cc35e42..1158e8a0d3 100644 --- a/packages/core-config/CHANGELOG.md +++ b/packages/core-config/CHANGELOG.md @@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Unreleased -## 0.0.1 - 2018-05-31 +## 0.2.0 - 2018-12-03 + +### Fixed + +- Stricter regular expression to avoid picking wrong config files + +### Changed + +- Dropped node.js 9 as minimum requirement in favour of node.js 10 + +## 0.1.1 - 2018-06-14 + ### Added + - initial release diff --git a/packages/core-config/README.md b/packages/core-config/README.md index 5aee8fc4b6..49ea1474a3 100644 --- a/packages/core-config/README.md +++ b/packages/core-config/README.md @@ -1,12 +1,12 @@ -![ARK Core](https://i.imgur.com/1aP6F2o.png) +# Ark Core - Configuration -# ARK Core - Configuration +

+ +

-## Installation +## Documentation -```bash -yarn add @arkecosystem/core-config -``` +You can find installation instructions and detailed instructions on how to use this package at the [dedicated documentation site](https://docs.ark.io/guidebook/core/plugins/core-config.html). ## Security diff --git a/packages/core-config/__tests__/__fixtures__/constants.json b/packages/core-config/__tests__/__fixtures__/constants.json deleted file mode 100644 index ff15b7bc83..0000000000 --- a/packages/core-config/__tests__/__fixtures__/constants.json +++ /dev/null @@ -1,45 +0,0 @@ -[{ - "height": 1, - "reward": 0, - "activeDelegates": 51, - "blocktime": 8, - "block": { - "version": 0, - "maxTransactions": 50, - "maxPayload": 2097152 - }, - "epoch": "2017-03-21T13:00:00.000Z", - "fees": { - "transfer": 10000000, - "secondSignature": 500000000, - "delegateRegistration": 2500000000, - "vote": 100000000, - "multiSignature": 500000000, - "ipfs": 0, - "timelockTransfer": 0, - "multiPayment": 0, - "delegateResignation": 0 - } -}, { - "height": 75600, - "reward": 200000000, - "activeDelegates": 51, - "blocktime": 8, - "block": { - "version": 0, - "maxTransactions": 50, - "maxPayload": 2097152 - }, - "epoch": "2017-03-21T13:00:00.000Z", - "fees": { - "transfer": 10000000, - "secondSignature": 500000000, - "delegateRegistration": 2500000000, - "vote": 100000000, - "multiSignature": 500000000, - "ipfs": 0, - "timelockTransfer": 0, - "multiPayment": 0, - "delegateResignation": 0 - } -}] diff --git a/packages/core-config/__tests__/__stubs__/genesisBlock.json b/packages/core-config/__tests__/__stubs__/genesisBlock.json index bc42a7e15c..1f6b5c1bf0 100644 --- a/packages/core-config/__tests__/__stubs__/genesisBlock.json +++ b/packages/core-config/__tests__/__stubs__/genesisBlock.json @@ -9,834 +9,887 @@ "payloadLength": 11401, "previousBlock": null, "generatorPublicKey": "024c8247388a02ecd1de2a3e3fd5b7c61ecc2797fa3776599d558333ef1802d231", - "transactions": [{ - "type": 0, - "amount": 12500000000000000, - "fee": 0, - "recipientId": "DGihocTkwDygiFvmg6aG8jThYTic47GzU9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "03cb7bca143376721d0e9e3f3ccb0dc2e7e8470c06e630c3cef73f03e309b558ad", - "signature": "3044022016ecdf3039e69514c7d75861b22fc076496b61c07a1fcf793dc4f5c76fa0532b0220579c4c0c9d13720f9db5d9df29ed8ceab0adc266c6c160d612d4894dc5867eb1", - "id": "e40ce11cab82736da1cc91191716f3c1f446ca7b6a9f4f93b7120ef105ba06e8", - "senderId": "DUFeXjJmYt1mWY3auywA1EQSqfCv5kYYfP" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03e5b39a83e6c7c952c5908089d4524bb8dda93acc2b2b953247e43dc4fe9aa3d1", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_1", - "publicKey": "03e5b39a83e6c7c952c5908089d4524bb8dda93acc2b2b953247e43dc4fe9aa3d1" - } - }, - "signature": "3045022100e3e38811778023e6f17fefd447f179d45ab92c398c7cfb1e34e2f6e1b167c95a022070c36439ecec0fc3c43850070f29515910435d389e059579878d61b5ff2ea337", - "id": "eb0146ac79afc228f0474a5ae1c4771970ae7880450b998c401029f522cd8a21", - "senderId": "DNL81CT6WNG1PHjobBmLvKwLV3UUscBymB" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "031137050d5fed0b5229b150257da2ac9c135efdf4bcb382b0ad0c197d7be458f4", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_3", - "publicKey": "031137050d5fed0b5229b150257da2ac9c135efdf4bcb382b0ad0c197d7be458f4" - } - }, - "signature": "30440220124baaa04491287d0abbf5a167c9b0f5ac95c22b196f42ff3d275cc9a213c2fd02206e6ebada85f67063e642dbcde6b956f8c99c05f4b9c55f1551d3eebba6375043", - "id": "c9c554056b3428951633a7059dd64dfcbd776fef7f4a156ea362b37ee6ce74c7", - "senderId": "DG9LYv5rqX67wuGvGVa9is5k1r86LKCVTA" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "037def83d085778d7767a182a179f345207953441089081f5bc13f86d3891308aa", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_4", - "publicKey": "037def83d085778d7767a182a179f345207953441089081f5bc13f86d3891308aa" - } - }, - "signature": "3045022100900cea3c2df393414899c9d74db57d89c9f311c70d08b974d0fd4a98bfae2fc902204a2aa51a1ec71da27c26afc033de6bd2d15978813c120c95e1a4dafca75ce876", - "id": "c82ccaa16be0e3c7ff4a53e2807968b71a0d88115223c3af2eb320f32449ac32", - "senderId": "DMSwarrHg5N9ZAZ6nsqPuUjyAU6gdRAM9d" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "033f28ad2e9b897d46f1e67c7c52070e9ca46b04c0679ebb21fb236719e38aade3", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_5", - "publicKey": "033f28ad2e9b897d46f1e67c7c52070e9ca46b04c0679ebb21fb236719e38aade3" - } - }, - "signature": "30440220285188d8900cd3cffccf5e1de305b18856451dd04d2ed21165dffe9a7ce4afc1022009457be6bfe536971697105d47ad1f829738a5cacdb27a23c5d1e8a8dddf3ebd", - "id": "ee6a19fff622ab4e6e96d159396de56d6034b4b18a9cf5c99efcf4e61b28e15a", - "senderId": "DFcYHfCwhGWcBNy6cp48wy5SfXbQmfBYgT" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "023e577a7b3362e0aba70e6911d230e86d729b4cb640f0e0b25637b812a3e38b53", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_6", - "publicKey": "023e577a7b3362e0aba70e6911d230e86d729b4cb640f0e0b25637b812a3e38b53" - } - }, - "signature": "3045022100afa56542dd473c424b36d4d9f24da68180cfd90527681ab84098f415b2544a8702201e8ebdd619a2dd200e37a57c39a4529afe76d35f6089c00f6dffba6bf7b8a836", - "id": "0dcd6e380bd7eaef8724f64f4b86104ce7497308dacf775afbe6ec0d401007fe", - "senderId": "D5e2FzTPqdEHridjzpFZCCVyepAu6Vpmk4" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02af5e6341efc14f4ba39a9ff65e151cc7304fc742ce7b2678d9aa446c555ee9c1", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_7", - "publicKey": "02af5e6341efc14f4ba39a9ff65e151cc7304fc742ce7b2678d9aa446c555ee9c1" - } - }, - "signature": "3045022100c8980155c8f8964d76baf3e8d690075708f1a84757c1de52e311772466382da2022012599acfc7839fa1ef6bbd445ab34555fb718491db3089f40d4842b1bc2d3178", - "id": "8af6abb117c69c130e388970d595b741374b1bbca709d9e91459e9e3c721397b", - "senderId": "DDLbnve6XK48cGsQiFhesUJQRQdKkZTfPh" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02845161cfca4d6ddde8e0d53538b6f881fb3ad9383cd77cebc55375dd6fd17663", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_8", - "publicKey": "02845161cfca4d6ddde8e0d53538b6f881fb3ad9383cd77cebc55375dd6fd17663" - } - }, - "signature": "30450221009bce7c5c10a4b6306cebe5724adfd3de049a425c44dd314a10154774764c11090220070fb775e71dda6a68f7fc9e0c762fbf96021908911f0de0ca8e9b0c613cb896", - "id": "bd346035d4516b85fb3a2cce6260fdcc6f1c434999e586978e065de3bf98e02a", - "senderId": "DDAHPjVTTV3uur653TB27fcLGh7XXWnvxW" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03f264a6d2ebb62279313a6fd7fec4e2244785839b625a0b0c261e689ce5401d87", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_9", - "publicKey": "03f264a6d2ebb62279313a6fd7fec4e2244785839b625a0b0c261e689ce5401d87" - } - }, - "signature": "30450221009f74425c2ec50dbee462e735dee3e7917c8433fd5250ff09af4506c38d2df05902206a14a19b9a5defe3c8c59c77d52c182ea34d81d2e0b05dc5925133f2829a1960", - "id": "b48068fb7c848ffd57e82a4d381f53bb69916f3943e0e8935971a028ba245564", - "senderId": "DFHdEBuVCz5zfj8yeo3BmKEdsEKpMaYRRw" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03efd265a086c2a099cda4f4fd202adbac07567e1229ce5e6fe39963b714c1e2d5", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_10", - "publicKey": "03efd265a086c2a099cda4f4fd202adbac07567e1229ce5e6fe39963b714c1e2d5" - } - }, - "signature": "3044022004df492965ed328134aa6443d38ac4dd951a640e00330da9aa4e80c1577af41a0220588f030f5f9584959647898bb977a1ffe6bba639b1c64a728880f2cd3fd7aa3c", - "id": "73b3b4375e39aabe51ec205559cd728a18c987dabaa0599c611b3076c38c7a49", - "senderId": "DL7Y6smfHHs3Ms3hAYmSYYd5PZukmtDY1i" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "027d616d20f03c375067676c79ff9787e8e42991fbd9e878501d704d23d246d9b0", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_11", - "publicKey": "027d616d20f03c375067676c79ff9787e8e42991fbd9e878501d704d23d246d9b0" - } - }, - "signature": "3044022051c2f8af62163ca621eeb3087a35bfaca0d679f7be8b19a25972f5a4b24ad8c90220422f3e0e480bf1bf2211e871a102edc15a957c0f97a553d9d707418e6538df26", - "id": "80f1d01158452da31d44f0c24f464a0ade37da51d2f61356ad75a019a91a1ff5", - "senderId": "DBVoRSXBHBPPvssBXrswv22r4dUSpN1fbA" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "038918951152a37b74dfe61115f83e4b5e3521145065650c4a6d3e94add57d9a9b", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_12", - "publicKey": "038918951152a37b74dfe61115f83e4b5e3521145065650c4a6d3e94add57d9a9b" - } - }, - "signature": "3045022100facf6ed992c28d41595419666b006800fcb33c6bad4b522e013b4d688e51dc8502207695e968059f7a35486389c430d6a3037e69d3e5f1d4f0a294d8818e4750cf0d", - "id": "86d76b0aad8f496d8c20926bfdeb50ad10db242ea6152b68266680c48e1e1aca", - "senderId": "DHsSK81gRWjgNx1A9gtHgkRsEwshsog7AM" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03231d8f2f39925fa79efc8f8561e6a8d29b95164a753cbb604a46e8a2e96606fc", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_13", - "publicKey": "03231d8f2f39925fa79efc8f8561e6a8d29b95164a753cbb604a46e8a2e96606fc" - } - }, - "signature": "304402204c627ec3d24fb7b4f86709c0566cee9909ebddb26039e87a2fa673f1f7227362022003be5aa3303b8f4cdab768f80b4699440a61814950cab0fd983526771c4c52ec", - "id": "464614909ac7531a016a0489d78defe262dc0934324f41199975ad42a86f37ac", - "senderId": "DDr7UTGQuPTjxLDWZ8RMjWJMKNXAMj3Bor" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "021e6d971e5885a3147ddf1e45bf5c8d0887ad9fc659e24bdf95c2c9607e7e3fe8", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_14", - "publicKey": "021e6d971e5885a3147ddf1e45bf5c8d0887ad9fc659e24bdf95c2c9607e7e3fe8" - } - }, - "signature": "3045022100898e59efe518745d3eb3f2b16f7b6192e3289bb4289d43013224549f2015aa4902204e7be92cbba37a05551151e46224da4e5d0ad86ee2106d3a9c0b9afee5f1c4cf", - "id": "9559866ff439959529f69b0947ad2e72d739511ee1f6533c0bca2ebd6dd4ae4a", - "senderId": "DRXNNQ9gQXh6VNUVKaAn9xHAViyiHKtBHZ" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03d5b3efbe98631443c5cdf4de8a610dd2655b86427bf70aa209451b54256f6758", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_15", - "publicKey": "03d5b3efbe98631443c5cdf4de8a610dd2655b86427bf70aa209451b54256f6758" - } - }, - "signature": "3044022037fa085e37a582b2e0b3734d44b813bb18be939f73100c5b6f977d4f53ae708f022064ae54f6a1b17b193ab6b6d633f7b7a7b8171a158cdba7480afe380f383930dc", - "id": "7bab92d5397a4ad291c5d01b8d681e480d19b437a7ab5cbd4c6807c96ef2716f", - "senderId": "DT12wf9erZyNJbBQrpbPDmfH3J8txiDgTE" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0297f2e8e609b2a6799214481e7573a043a197f8adf7b8bb306576fc3da83d2aaa", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_16", - "publicKey": "0297f2e8e609b2a6799214481e7573a043a197f8adf7b8bb306576fc3da83d2aaa" - } - }, - "signature": "304402202eee94bc3b53c64f8dee7790fe3eed8639da8faf0aa1f785e921cf139df0fb7e02200224efb0c07ae3972287c12a32143c1356adb93e00ac9e04a1358c8245a24cab", - "id": "1e59740fa596b615231660974d0b656122b799a8b13102ade8c1b779aa5de7b5", - "senderId": "DKGYWPSqa4m4z6h3433rNFbWPDdvHj5wwd" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0361b914fd5823bf39ae467e95d99e9f6ddb7d85cc6df3055ce00274b8e4a976cc", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_17", - "publicKey": "0361b914fd5823bf39ae467e95d99e9f6ddb7d85cc6df3055ce00274b8e4a976cc" - } - }, - "signature": "3044022002ad92b9b9d81dabf96ac7d90034debc55eeeae879b3fe6ffc026bde86bb7ad902205c57d31c5e5e0099b504ba4c49e220a00ff325dceb64c46aefbb7a0ad8570099", - "id": "bf305776da902802923c19b9d2c7f1a809b0847992131cfa578d5e5518c924bf", - "senderId": "DJshaeFyHcFTjiGJnVPaDmFXhnJ9bp96i5" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03fa6bc09bd2ff348b304e0cfbc2d2ec50aa3b9aee0de6a66c13fcd8ee5ac891cd", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_18", - "publicKey": "03fa6bc09bd2ff348b304e0cfbc2d2ec50aa3b9aee0de6a66c13fcd8ee5ac891cd" - } - }, - "signature": "3045022100be50b19c17a9ff221aae20394a45d92ea47e8c1072b6d5a302937d2fc48cba8002205e9bcb3471a734c07ceff0083ad9ba1570507a29e5014e889ba42a85e797cb5e", - "id": "44e48364b5b8cff3c68ae03de7dfde8d7ba6bcb99bf82b32fdc8bc3d0d9adeca", - "senderId": "DSuNttSb1UvCWg8iormfwPwi67EA84P5Mu" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03241957edca9ed28308e35cbf36762d22de706ebbd7c6a3a2d235d905d660c5c7", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_19", - "publicKey": "03241957edca9ed28308e35cbf36762d22de706ebbd7c6a3a2d235d905d660c5c7" - } - }, - "signature": "3045022100c11f8b863133535192e6c3fff20253a2695a2df74cdf1445d4ca0966803f708c0220200d4c2723d84f6334ba5d1cc1a0d45854867f4523fbcc9d09b3d53dd1972950", - "id": "5cba288f9ffc1361ba8f7f19f28347ffd917f37df8cf46ba1e0816725f288528", - "senderId": "DCZt1ozEVvPdYVvkHmUKK6k7gnyNNQDpMq" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "035ae2364c838bc21edf4c04a99c85799f26fb02cc0740c5a1c67d4dc1748ff913", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_20", - "publicKey": "035ae2364c838bc21edf4c04a99c85799f26fb02cc0740c5a1c67d4dc1748ff913" - } - }, - "signature": "304402203066f06a1c165795d8a069499a8c0998913ec93e689219f14145754aa3e26e4e02206e9f88da16f1f8a8ebaf481eff798452487738714fe9b5694fec6a5ef8c152a5", - "id": "ada1696532f7faad1dda594bc6db7bfc029a1759402c924348b74222873a3a27", - "senderId": "D7JyqWMPKhhRNQcKTAvrPGBjEjjBcGgPca" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "023aff4a16c3876e885aea70e5bce9734ce5acc95a2c41c9783f5acd617f7c7533", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_21", - "publicKey": "023aff4a16c3876e885aea70e5bce9734ce5acc95a2c41c9783f5acd617f7c7533" - } - }, - "signature": "3045022100f5150c23596b9479c8b277401ab9e7da9b2275436f3927dabd70395e52c3ea7c02204e318d498b0176b5f05bb96418c49da3375a8d9b47b3b1e72a6f4db30b3f8c34", - "id": "e186a679f2e47300ec2f24c670192bcede1cb12f359cb8e827374b22f41fbe12", - "senderId": "D6itxYJr4n7ZZk2bd9cZbJE1xaDmpfkNFL" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0217d7ce9c3754f7fc7e5b4c64a1ff397dc75931cd6c92e32d8b42068ad50fe4eb", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_22", - "publicKey": "0217d7ce9c3754f7fc7e5b4c64a1ff397dc75931cd6c92e32d8b42068ad50fe4eb" - } - }, - "signature": "3045022100b84f69a7ff67ed147fc0a750c3b7b2ecabd582b6d0cb698c0bb4a531daa6ca46022039d2722e486e1674d0db422078d63fcdb90b21bed0dcc1265adff72d0c2bf8b9", - "id": "86d9d146b62dbafe212aba5ec9764223b67f72c3c1aa93e54a270e3a528a8b20", - "senderId": "DDy4aKhF3cMadGhjFZnjaA1tx2rwnSEWcc" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "024019207f50dcb3e8aeb9ac1b00993d2bf131346e7e6d296429ea813a8373818e", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_23", - "publicKey": "024019207f50dcb3e8aeb9ac1b00993d2bf131346e7e6d296429ea813a8373818e" - } - }, - "signature": "3045022100aa83596b740639ee8947aa6d0f0ee123e4a5b87c39a4c6dd8a50304d4a7c97d102205fd45f85f5bdb076585a77888ef880bea52ade689731dff694d777de34913efc", - "id": "6301b791844e02116df528b1ea46d788e91521189c3828ce224e45a1b72cda59", - "senderId": "D6BwyDJkNFkaDLedcJTE4rPUw5bRtb4K8f" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0275db912c21dca0f0213a76f4544137d7c741b47f281cfd4f8b7cb8187e7ce3cc", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_24", - "publicKey": "0275db912c21dca0f0213a76f4544137d7c741b47f281cfd4f8b7cb8187e7ce3cc" - } - }, - "signature": "3045022100c7eda0d9cd7ef522615643d1b985c73add2d3612344bdcc0117779fa4f4f54d302203e33fb5d185f5174e9cb7634a3d307b74d3bb56cc2354024ce69c74905a85203", - "id": "eee776fcb8024469eacab3e4b23c3d14185326431369aa84f17921abab8ad0ad", - "senderId": "DHQSmrRdfYAp9Y6CuebKnkoQNzuN7Pk2oQ" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0331c615ca4bc89d4eeb8d7a9cfbb5c0d4ce49d2f480afbce499b0c7f8c6a24f2f", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_25", - "publicKey": "0331c615ca4bc89d4eeb8d7a9cfbb5c0d4ce49d2f480afbce499b0c7f8c6a24f2f" - } - }, - "signature": "304402203e69be3a73c5917d89d58f3c0ae18febbbf364d3f9dfbec6b526a5294f9c435902201750bcf6368c181aabc53c73fd271a2967a6f215e1d0506eded5dd1800fea1c8", - "id": "ec3d17c6d38c0b9848c7cb57b968efd1f3872b1d1b8bcfb74bae2b0aaa15877c", - "senderId": "D6EVFQx5Z7M2X9DWXHtfX51CtVekuKPMQF" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0338ca9b719f8047580eed23b64a40aecad3803a12c0dde83e3ec2c2a9bfaa8147", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_26", - "publicKey": "0338ca9b719f8047580eed23b64a40aecad3803a12c0dde83e3ec2c2a9bfaa8147" - } - }, - "signature": "3045022100e0bf90949739012b641793da162b3daa88b34c8753ee31b26850729e9df579810220439a3f2f1b8e719767ee68df46f4bc1f18c8c3b2da4118edff22396616d319fb", - "id": "14cd65c5f28f4cefc7c0157518a24f90c2260eb7166105b6b3358d91164ddf39", - "senderId": "DLCQ1jPsYbBCV7JfUJTasKbKoyGbK4a4HG" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03127001718bee76f14133272f0f4a928ffa8c2b38cafd94d7100253dac732c644", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_2", - "publicKey": "03127001718bee76f14133272f0f4a928ffa8c2b38cafd94d7100253dac732c644" - } - }, - "signature": "3044022003d2e76aca2848aedfe25415c11b9368dc72f687b66bef4527b40e2997b86b8c022076f7f82cbeb282d26535a2c1f0af0f02b48025d42c1bd56ac687fba1a3adb706", - "id": "0daff3992b54b1384f52f751c933c727cbaaf4fac435eba88a1817a425753614", - "senderId": "D9rv3h61heDYHQ3b3Xk3V5epHSTTC6Vn1d" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0241734825ba45b6de29d6f26242c25ae1ef125b82615ee89a9fdd5b0f3c6b5132", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_28", - "publicKey": "0241734825ba45b6de29d6f26242c25ae1ef125b82615ee89a9fdd5b0f3c6b5132" - } - }, - "signature": "3045022100bb2903424bcd0a72da531470779144d60286191bea1b200c5617ae4f92229ba6022046a876e3e6cb85469a16f34d2f937e2eef787011c6a313ee50258f15116148ac", - "id": "bd17dbd23f8dbba2736688702ac185a87c88c43b24ee6d7764a5b4138b2f38b7", - "senderId": "DAcQPbKa8zBWwDHbxj37N13C61iseMDWM9" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03b9409203d7091e3f4d49168529b749e942ed18f21beddd236d57d692f09a8f86", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_29", - "publicKey": "03b9409203d7091e3f4d49168529b749e942ed18f21beddd236d57d692f09a8f86" - } - }, - "signature": "3044022016d7ecfa776930a6f83464548e7a686735fde752903539a38eb9da0ce2488bbd02203c5e23a4072c8de35a90b296145cce3156a31cc0d754b8a37d363fb088bc7387", - "id": "16e02d3ef24dca4b03a1e489e20335224f18d888ed04f7e3512572f8e0cf92ae", - "senderId": "D5mmTaDAMSyPNKiDKrqwTFGWzWrZA3xaF8" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02c7b92a2d0027309e21855cf9c42a432b21ad13925e9dfc206f9c01e18fefa08a", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_30", - "publicKey": "02c7b92a2d0027309e21855cf9c42a432b21ad13925e9dfc206f9c01e18fefa08a" - } - }, - "signature": "30450221009de8828a7ad87cb5d52900e09d5beb680f9edc7640a3707d08a379511a7ba0f102202aa1d9294f9631f1325f252adb87c0d866e7398ce410037a42dc861d94308e15", - "id": "fece556bee4de2c7f1bb3099a05a84a33d0c963979fe1a222a899c13b7abb1fc", - "senderId": "DJ3NywAwQh4srbooLH1jTs9ma1hJE79v3z" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0221297804a26a93bb441a9d20a2916abf27fa7b29967678ef1a7a58062f73f40d", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_31", - "publicKey": "0221297804a26a93bb441a9d20a2916abf27fa7b29967678ef1a7a58062f73f40d" - } - }, - "signature": "3045022100b969611ef532557fa3da8a0325b2c88f3ebec954d64f158431d86b8e07929ea50220520affdcd0728cb7c5f63a58a1200d44133e90b1f7a6a9e28744ad6b0dcc2a75", - "id": "ee086317ea2fdc522f5eb502a0db9f3d4955b2318559e40a1f22a3f5f8d6344b", - "senderId": "D5P7eti7FUY4Tk5KXoxdf2tDAVQrRVCESA" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "027f504f6f20648e3bf171952629c7b868a2f799aa4b60f8eb3fe96afff16bbef0", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_32", - "publicKey": "027f504f6f20648e3bf171952629c7b868a2f799aa4b60f8eb3fe96afff16bbef0" - } - }, - "signature": "3044022006be7cbaa74089cabe47d02621f756762587d210a3f211ee941b5fcd0650908f02207d4040408bd25a2de03e5724362735ee8ad36c099b0c16efd4716e1dd7ec62ae", - "id": "764dd21aa4d0e2e0fa17bb2ff5e7ca304995d9e3593542badecc8ed24d5ea3ea", - "senderId": "D9q26yBTrEYuxHg7bbfZphv6129KvLu4v2" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "031954315b84db8f49ab7ee21357270450bb68d06b34472e5e93ddfa5710edc0c9", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_33", - "publicKey": "031954315b84db8f49ab7ee21357270450bb68d06b34472e5e93ddfa5710edc0c9" - } - }, - "signature": "3045022100859f93df994d86995fdf834bfe86b41eebaa04e5ab7d09f0b37acb50d313cd9802203c8993b793602c96d305fa795a9f2459f4706b340993584f3c56579392c0995c", - "id": "efd9e7c638afe62bec9be61783193ea52eea7b335053bd5af6c758d5b0e5847c", - "senderId": "D9iPFb5kAVnuDdomehRP9LncJj5ng2vrsr" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0267b310eac2bb0d6594de382a1ab74ac75b91e9d64a590b6249247b10fd9be829", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_34", - "publicKey": "0267b310eac2bb0d6594de382a1ab74ac75b91e9d64a590b6249247b10fd9be829" - } - }, - "signature": "3045022100a678978ab899e3903e760ee98640e3f658792a096a8d771c575944af6536cfdb0220428c312f1e0eb4be73ce4b256a754447570176200cfb6c09b3eb55f66526dd80", - "id": "70edcce5df67a250b6ba3567879bae6379ce4c688597fcedfbfd0313da6998e8", - "senderId": "D6xZmtyBzZKCEkK29JNPAD581TJ8XXrXYn" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "028f32320c66a89779756b04946d2aa256dff6cd547349d46e1938710063e387c4", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_35", - "publicKey": "028f32320c66a89779756b04946d2aa256dff6cd547349d46e1938710063e387c4" - } - }, - "signature": "304402206bc95876897527b39eacf4c961f9c036a9c8a0e53a17ce925c592d079fa643030220096e115d7fbd54aca4af7f621d64178dfcf2c13361106a3e3b5025dca97b44ee", - "id": "7f23f44157f3a677e81514fa431227410a27442e5fd1f2491b177c0f580f296d", - "senderId": "D9dW4eXJjABDQXSQB9GtvY5UBuRWWWejWb" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0218b889a24988527ab3948d80f97cfc37b923082e1f0398bc162190fd66ec4dee", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_36", - "publicKey": "0218b889a24988527ab3948d80f97cfc37b923082e1f0398bc162190fd66ec4dee" - } - }, - "signature": "3045022100c40a3f4cf15f9274e2b25ca8608cb965316aa0f00fa77817b79620ad8ccbdd5902206203a1043b03ba58aa9b7399694f8215cf45d30eb0caa748cc06f1a85a8faea9", - "id": "a65244ed17a9280aa694abdf6804b1a0b78dfc052b4845abcd3c89380159b29e", - "senderId": "DFHK7SdmPdjxNZ9uweqLZAv6v5GQ1NnBNe" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "035392ee88c60617764b4fe89ae2cc96560dfa5f992b03be31ce5680db9b863f73", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_37", - "publicKey": "035392ee88c60617764b4fe89ae2cc96560dfa5f992b03be31ce5680db9b863f73" - } - }, - "signature": "3044022036200c3191f8f01b77676644b9b94728b5afb2ab2de8c5c7c5582e795465661c02207848f1f2f0ab378d8906fd45aa048f354d5dbac4cb87c15973ffa86fe84ff0cd", - "id": "219e0942afe5f65c548ec2118a1c49febb7ec03fca4334ac16649062db9d146b", - "senderId": "DSh7AAC9KahXU2JZ539HAqEa5sHafxsxDQ" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03e75127d1deccf65844a1761bd26611b6c65c5b51a52eba27e3ee20a539fd63f1", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_38", - "publicKey": "03e75127d1deccf65844a1761bd26611b6c65c5b51a52eba27e3ee20a539fd63f1" - } - }, - "signature": "304402201a2990b2baae72f5cc8f2d1890f328e4082af0cf2a787d8f05208c3424ce089d0220790dbc7606dd6c03568fd0a771e9e8e89557257238ae90cfcb3bb8f3b475987b", - "id": "ee9ad2a66e9b2009a9fc671f80d0493803fc422161140169c7bc1fd401cd9ad6", - "senderId": "D85WuxGZrFs1QUYTvnRpmc6dd8rmBbpnaX" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0329fc1580906307ac9f2f55cec66e47983f8287d542408fb19f473a305d3638d8", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_39", - "publicKey": "0329fc1580906307ac9f2f55cec66e47983f8287d542408fb19f473a305d3638d8" - } - }, - "signature": "30450221008f66e89ec4c7af4b77e5b7ff36c542cc02672c8df70806b5a0fab7a7e8c7067502200d99ba19ceb1b471c39c4e95107ad6f8b978a623a790080b16f863347fe06b4f", - "id": "dd3077ed04a76343d340074270ce9826354802bd99e08cb864c1c5ad09f367df", - "senderId": "D85kwsBJKZ4pw5uQpc81eRj95f6a536AP6" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "035ec848e9388877dac88f121d19c8f5e870ac90d8ccb0116be9f734e4bd1a9405", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_40", - "publicKey": "035ec848e9388877dac88f121d19c8f5e870ac90d8ccb0116be9f734e4bd1a9405" - } - }, - "signature": "304402202b220d6c028bc23213edddaf303f18eef059551891aadbf7a4b4d7d3287457bb0220245678354bb8960b42ba2f2ceb12f926e82ff0d027b44988d799c8c0d8d7d9f2", - "id": "3afc6ea52b8edc7df0230ceac71baf45460f3bd761c5e75fe796bc7415063220", - "senderId": "DGBJdDadBwJD2xY8VsdAykdd6vPakMMUt6" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0356f5885306e45402aeb354a74d13c104699b3b53da46a5e922e4a6d6132a67e8", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_41", - "publicKey": "0356f5885306e45402aeb354a74d13c104699b3b53da46a5e922e4a6d6132a67e8" - } - }, - "signature": "3045022100f18bf2e013f2d9dcac013a76037d787f79baaa65f4f31ffe2b4ed8de249bdc8902202abcf77e809599d3e3a96225363c8e760ed4b4e20f97645547b381dba830c3da", - "id": "aea1fc173a2f4a9233b0fe59a5f6804167bee5658cb3e4e19dfe2be20f5772cd", - "senderId": "DG4VbapL3H39NJLB3DqQEefU47EMVqtxVw" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03ff8ab980434516ca28c982d0ecc8fc3107116d6c8b3e09c7ee5033f32adbd2ff", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_42", - "publicKey": "03ff8ab980434516ca28c982d0ecc8fc3107116d6c8b3e09c7ee5033f32adbd2ff" - } - }, - "signature": "3045022100e938d9901afeaa5a56d18abd9292ace93be03c84c09a6c4cb58fca96dfb54bc502201e921d27f9886d189f803b14d93655a42c4e095d49ee61051a4e70c7a173f3f1", - "id": "f18426d3ef81d4b7bf0337d70afcecddbd6db2206a2f139f1ca5823c381c7817", - "senderId": "DC3oNWedP48ypGxAeKbFC7gMjWxcNc2JhL" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0393f1590771a8ad1cf2baa086858f3029c4444cb82243917a7011f1f66cf8fd05", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_43", - "publicKey": "0393f1590771a8ad1cf2baa086858f3029c4444cb82243917a7011f1f66cf8fd05" - } - }, - "signature": "304502210095745c36a8af07e21546bd064f1ed1bd90e6c2a8db9c0c8e4853d0a8255443db0220259d2ce3677abb42f08b9d22aa13bbe383fd882ed38911b738ebaefc04589694", - "id": "6c51bea35b5e3270dcf7b7dfae8d984e19f476ea7e0435f157c4e0d22b7e7ea1", - "senderId": "DJm2sfcUKhyxakowY9TjyAytkdq7JrFgVj" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0234e24ff1dbc447c804eb385cd05bbd1dc59ef03b44a3346b13e7cccf00b61075", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_44", - "publicKey": "0234e24ff1dbc447c804eb385cd05bbd1dc59ef03b44a3346b13e7cccf00b61075" - } - }, - "signature": "3045022100ee1e8df480f2be042386d383d776b3fd6bd2d3f5a9035071153f23dbfdceeaae02203a0834aae4834da3ca7858779d474b9255ead754867d5b4a18873e9ecaa5045e", - "id": "66fb3e36233f4577ba585ccd7daf83e62d8df262d3d832b806479ac67c1ef35d", - "senderId": "D5oS8xfNebiPsjpwPWoZS6sA9qcYjTGT5h" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03a5789a4486f20f1fdca78a52b528b3bf9952e7c057de71a22adcfb444ba4c5d3", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_45", - "publicKey": "03a5789a4486f20f1fdca78a52b528b3bf9952e7c057de71a22adcfb444ba4c5d3" - } - }, - "signature": "3045022100cb037530bcff9a4d19899431648747022c28aa3239563379d96692bd525eb38902205f3cabb8dd470d9eb3d425e333ad1bc9f0643d489c600a811748fb5f4a203f7f", - "id": "5df9c5e350136571af4b86697bc9d4cfca3ff8b669e254b36f00be1dbde063f7", - "senderId": "D5SzHHdPdGqYUkH7BGNkmGHEUqfZrWb17r" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0347f692345fa7bf90e944eb55246da5f9f595d3f5a20ad50aeb6f9b973aaae17e", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_46", - "publicKey": "0347f692345fa7bf90e944eb55246da5f9f595d3f5a20ad50aeb6f9b973aaae17e" - } - }, - "signature": "3045022100c377efe5ffab58017473699cd7c839dcf48fa5b20b5ddf9bdc4801e22a579b2b02204d35c1a1416069544e3ec01d2ce21bb409f9f2fa4adedc8c03d6417c034a3fec", - "id": "da4cfad78e37d56421dd6676e5618a507340ef1e496831d1968c509e35ef9202", - "senderId": "DCLdibuZB6UsJP8KmdzcDLWzizrDtJQuxt" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "028a32b441377a69aa76e867026f3109b2f0aef8651fe91e2a4ab01eff102a6b98", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_47", - "publicKey": "028a32b441377a69aa76e867026f3109b2f0aef8651fe91e2a4ab01eff102a6b98" - } - }, - "signature": "3045022100e098672958be15989bb125d9018adb4a54e95ab664e64a673997e617e28b39df02206e8459997074d5976b77f90eb9d7180e9d4a0e0efdf433958ffeb2f04d9de382", - "id": "85bafcd07e7ba47ec95cb5b5a6759d4f9f87e036bb7660c7717504e845ef975e", - "senderId": "DSkivgRyimdAVqmm2ZAKwKmKN39WEbbPnL" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0223ac52179903e79865b9a98cf0b52ddc1ab46180c157e8f6bd1e63e7f14fcf31", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_48", - "publicKey": "0223ac52179903e79865b9a98cf0b52ddc1ab46180c157e8f6bd1e63e7f14fcf31" - } - }, - "signature": "304402200a005716f67d6cd3963a3c752c95f1bca01aa127c91ab1a632eb3022d11e3e67022024c4746078e440da441bcb366ee8999ffd2419e9a6f9cbf971d696d5b7f8733b", - "id": "0df1ed07d3f95ddf0385bad83a17b3a8fde6bd6532cd3479e48668064672b34f", - "senderId": "DDgKyKqdA6SuamB1eW77WvFu6RQFMZoU36" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "039de0390f28c7731d86ae7006a31888f12856cde3cc3c2619d4d4a42b6dfd6c51", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_49", - "publicKey": "039de0390f28c7731d86ae7006a31888f12856cde3cc3c2619d4d4a42b6dfd6c51" - } - }, - "signature": "3045022100efa5d51ca79992be4a87af049b3e9ec1b796576e4d937ea9e3760ab0bdcd301e022027e22a6c3395df155bd399643c241e4cc317eaead1f273fd7a709339dfa9dc99", - "id": "436bebc107fad38e944fd14785e09f0600df4d75d31cf3eac53f850462d0be74", - "senderId": "DKCaoaXApw1xE7K1BJcVkr1KGzjKmFWyTk" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02b87b0e70a7ae10613390f405620e24c495ba2b0cfcdbc67688e9b483dea564ee", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_50", - "publicKey": "02b87b0e70a7ae10613390f405620e24c495ba2b0cfcdbc67688e9b483dea564ee" - } - }, - "signature": "304502210096cdd35f803a37730ac73a97a23061dceac96319c67bfb1ddcfbac737febe96102202fa0b279f697da3afc043ffd3ecc838789be07ff119b5527a5c13468cecf66e9", - "id": "bb65f9dbe6272fd07a555fc86762d6a487f538b972f2926ff7698cdc906a32df", - "senderId": "DJQXFKEguZVabsAs46JbXXnQJ5jFhUtN9m" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03c9f8f4001216603c152b4b4429c2ead322ac34672999e808d567a7d1140e46be", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_51", - "publicKey": "03c9f8f4001216603c152b4b4429c2ead322ac34672999e808d567a7d1140e46be" - } - }, - "signature": "3045022100ee961089d02d7bb68fe2257f6a972eeaf6e2c1a1ad2f491c417e161fedbb556b02204c834644e5b5cde9a0b3f92fa23bade7670efab0a067597f6c151ee633932706", - "id": "cef44df9684f05dab67c0568a2c5295bb50cbb3c88f5cfbe672365bda274620f", - "senderId": "DKpt7cm2tZk4RPLyQ5ugwEH7gkriRaA7ov" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02cf70f73328d490cfb03ee822d3fc0cf9259d67c0564e843491e739501809d657", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_27", - "publicKey": "02cf70f73328d490cfb03ee822d3fc0cf9259d67c0564e843491e739501809d657" - } - }, - "signature": "30440220645b912b60f829c0bce58bfe9890ef9253418b6898416aaead663bdf158a99f2022061abbbabd454ec7f7e3f4b502216eec28110e945a4b9b913b1fc0b9758e7e6e4", - "id": "09408dbcf3e3e0835bf92a05330c023a7d6471f3825301a34efa094e0fd4fc30", - "senderId": "DQfjSqDuKr5YZaLAF8rWpFMqMYwEbPtGKg" - }], + "transactions": [ + { + "type": 0, + "amount": 12500000000000000, + "fee": 0, + "recipientId": "DGihocTkwDygiFvmg6aG8jThYTic47GzU9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "03cb7bca143376721d0e9e3f3ccb0dc2e7e8470c06e630c3cef73f03e309b558ad", + "signature": "3044022016ecdf3039e69514c7d75861b22fc076496b61c07a1fcf793dc4f5c76fa0532b0220579c4c0c9d13720f9db5d9df29ed8ceab0adc266c6c160d612d4894dc5867eb1", + "id": "e40ce11cab82736da1cc91191716f3c1f446ca7b6a9f4f93b7120ef105ba06e8", + "senderId": "DUFeXjJmYt1mWY3auywA1EQSqfCv5kYYfP" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03e5b39a83e6c7c952c5908089d4524bb8dda93acc2b2b953247e43dc4fe9aa3d1", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_1", + "publicKey": "03e5b39a83e6c7c952c5908089d4524bb8dda93acc2b2b953247e43dc4fe9aa3d1" + } + }, + "signature": "3045022100e3e38811778023e6f17fefd447f179d45ab92c398c7cfb1e34e2f6e1b167c95a022070c36439ecec0fc3c43850070f29515910435d389e059579878d61b5ff2ea337", + "id": "eb0146ac79afc228f0474a5ae1c4771970ae7880450b998c401029f522cd8a21", + "senderId": "DNL81CT6WNG1PHjobBmLvKwLV3UUscBymB" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "031137050d5fed0b5229b150257da2ac9c135efdf4bcb382b0ad0c197d7be458f4", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_3", + "publicKey": "031137050d5fed0b5229b150257da2ac9c135efdf4bcb382b0ad0c197d7be458f4" + } + }, + "signature": "30440220124baaa04491287d0abbf5a167c9b0f5ac95c22b196f42ff3d275cc9a213c2fd02206e6ebada85f67063e642dbcde6b956f8c99c05f4b9c55f1551d3eebba6375043", + "id": "c9c554056b3428951633a7059dd64dfcbd776fef7f4a156ea362b37ee6ce74c7", + "senderId": "DG9LYv5rqX67wuGvGVa9is5k1r86LKCVTA" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "037def83d085778d7767a182a179f345207953441089081f5bc13f86d3891308aa", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_4", + "publicKey": "037def83d085778d7767a182a179f345207953441089081f5bc13f86d3891308aa" + } + }, + "signature": "3045022100900cea3c2df393414899c9d74db57d89c9f311c70d08b974d0fd4a98bfae2fc902204a2aa51a1ec71da27c26afc033de6bd2d15978813c120c95e1a4dafca75ce876", + "id": "c82ccaa16be0e3c7ff4a53e2807968b71a0d88115223c3af2eb320f32449ac32", + "senderId": "DMSwarrHg5N9ZAZ6nsqPuUjyAU6gdRAM9d" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "033f28ad2e9b897d46f1e67c7c52070e9ca46b04c0679ebb21fb236719e38aade3", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_5", + "publicKey": "033f28ad2e9b897d46f1e67c7c52070e9ca46b04c0679ebb21fb236719e38aade3" + } + }, + "signature": "30440220285188d8900cd3cffccf5e1de305b18856451dd04d2ed21165dffe9a7ce4afc1022009457be6bfe536971697105d47ad1f829738a5cacdb27a23c5d1e8a8dddf3ebd", + "id": "ee6a19fff622ab4e6e96d159396de56d6034b4b18a9cf5c99efcf4e61b28e15a", + "senderId": "DFcYHfCwhGWcBNy6cp48wy5SfXbQmfBYgT" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "023e577a7b3362e0aba70e6911d230e86d729b4cb640f0e0b25637b812a3e38b53", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_6", + "publicKey": "023e577a7b3362e0aba70e6911d230e86d729b4cb640f0e0b25637b812a3e38b53" + } + }, + "signature": "3045022100afa56542dd473c424b36d4d9f24da68180cfd90527681ab84098f415b2544a8702201e8ebdd619a2dd200e37a57c39a4529afe76d35f6089c00f6dffba6bf7b8a836", + "id": "0dcd6e380bd7eaef8724f64f4b86104ce7497308dacf775afbe6ec0d401007fe", + "senderId": "D5e2FzTPqdEHridjzpFZCCVyepAu6Vpmk4" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02af5e6341efc14f4ba39a9ff65e151cc7304fc742ce7b2678d9aa446c555ee9c1", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_7", + "publicKey": "02af5e6341efc14f4ba39a9ff65e151cc7304fc742ce7b2678d9aa446c555ee9c1" + } + }, + "signature": "3045022100c8980155c8f8964d76baf3e8d690075708f1a84757c1de52e311772466382da2022012599acfc7839fa1ef6bbd445ab34555fb718491db3089f40d4842b1bc2d3178", + "id": "8af6abb117c69c130e388970d595b741374b1bbca709d9e91459e9e3c721397b", + "senderId": "DDLbnve6XK48cGsQiFhesUJQRQdKkZTfPh" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02845161cfca4d6ddde8e0d53538b6f881fb3ad9383cd77cebc55375dd6fd17663", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_8", + "publicKey": "02845161cfca4d6ddde8e0d53538b6f881fb3ad9383cd77cebc55375dd6fd17663" + } + }, + "signature": "30450221009bce7c5c10a4b6306cebe5724adfd3de049a425c44dd314a10154774764c11090220070fb775e71dda6a68f7fc9e0c762fbf96021908911f0de0ca8e9b0c613cb896", + "id": "bd346035d4516b85fb3a2cce6260fdcc6f1c434999e586978e065de3bf98e02a", + "senderId": "DDAHPjVTTV3uur653TB27fcLGh7XXWnvxW" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03f264a6d2ebb62279313a6fd7fec4e2244785839b625a0b0c261e689ce5401d87", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_9", + "publicKey": "03f264a6d2ebb62279313a6fd7fec4e2244785839b625a0b0c261e689ce5401d87" + } + }, + "signature": "30450221009f74425c2ec50dbee462e735dee3e7917c8433fd5250ff09af4506c38d2df05902206a14a19b9a5defe3c8c59c77d52c182ea34d81d2e0b05dc5925133f2829a1960", + "id": "b48068fb7c848ffd57e82a4d381f53bb69916f3943e0e8935971a028ba245564", + "senderId": "DFHdEBuVCz5zfj8yeo3BmKEdsEKpMaYRRw" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03efd265a086c2a099cda4f4fd202adbac07567e1229ce5e6fe39963b714c1e2d5", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_10", + "publicKey": "03efd265a086c2a099cda4f4fd202adbac07567e1229ce5e6fe39963b714c1e2d5" + } + }, + "signature": "3044022004df492965ed328134aa6443d38ac4dd951a640e00330da9aa4e80c1577af41a0220588f030f5f9584959647898bb977a1ffe6bba639b1c64a728880f2cd3fd7aa3c", + "id": "73b3b4375e39aabe51ec205559cd728a18c987dabaa0599c611b3076c38c7a49", + "senderId": "DL7Y6smfHHs3Ms3hAYmSYYd5PZukmtDY1i" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "027d616d20f03c375067676c79ff9787e8e42991fbd9e878501d704d23d246d9b0", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_11", + "publicKey": "027d616d20f03c375067676c79ff9787e8e42991fbd9e878501d704d23d246d9b0" + } + }, + "signature": "3044022051c2f8af62163ca621eeb3087a35bfaca0d679f7be8b19a25972f5a4b24ad8c90220422f3e0e480bf1bf2211e871a102edc15a957c0f97a553d9d707418e6538df26", + "id": "80f1d01158452da31d44f0c24f464a0ade37da51d2f61356ad75a019a91a1ff5", + "senderId": "DBVoRSXBHBPPvssBXrswv22r4dUSpN1fbA" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "038918951152a37b74dfe61115f83e4b5e3521145065650c4a6d3e94add57d9a9b", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_12", + "publicKey": "038918951152a37b74dfe61115f83e4b5e3521145065650c4a6d3e94add57d9a9b" + } + }, + "signature": "3045022100facf6ed992c28d41595419666b006800fcb33c6bad4b522e013b4d688e51dc8502207695e968059f7a35486389c430d6a3037e69d3e5f1d4f0a294d8818e4750cf0d", + "id": "86d76b0aad8f496d8c20926bfdeb50ad10db242ea6152b68266680c48e1e1aca", + "senderId": "DHsSK81gRWjgNx1A9gtHgkRsEwshsog7AM" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03231d8f2f39925fa79efc8f8561e6a8d29b95164a753cbb604a46e8a2e96606fc", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_13", + "publicKey": "03231d8f2f39925fa79efc8f8561e6a8d29b95164a753cbb604a46e8a2e96606fc" + } + }, + "signature": "304402204c627ec3d24fb7b4f86709c0566cee9909ebddb26039e87a2fa673f1f7227362022003be5aa3303b8f4cdab768f80b4699440a61814950cab0fd983526771c4c52ec", + "id": "464614909ac7531a016a0489d78defe262dc0934324f41199975ad42a86f37ac", + "senderId": "DDr7UTGQuPTjxLDWZ8RMjWJMKNXAMj3Bor" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "021e6d971e5885a3147ddf1e45bf5c8d0887ad9fc659e24bdf95c2c9607e7e3fe8", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_14", + "publicKey": "021e6d971e5885a3147ddf1e45bf5c8d0887ad9fc659e24bdf95c2c9607e7e3fe8" + } + }, + "signature": "3045022100898e59efe518745d3eb3f2b16f7b6192e3289bb4289d43013224549f2015aa4902204e7be92cbba37a05551151e46224da4e5d0ad86ee2106d3a9c0b9afee5f1c4cf", + "id": "9559866ff439959529f69b0947ad2e72d739511ee1f6533c0bca2ebd6dd4ae4a", + "senderId": "DRXNNQ9gQXh6VNUVKaAn9xHAViyiHKtBHZ" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03d5b3efbe98631443c5cdf4de8a610dd2655b86427bf70aa209451b54256f6758", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_15", + "publicKey": "03d5b3efbe98631443c5cdf4de8a610dd2655b86427bf70aa209451b54256f6758" + } + }, + "signature": "3044022037fa085e37a582b2e0b3734d44b813bb18be939f73100c5b6f977d4f53ae708f022064ae54f6a1b17b193ab6b6d633f7b7a7b8171a158cdba7480afe380f383930dc", + "id": "7bab92d5397a4ad291c5d01b8d681e480d19b437a7ab5cbd4c6807c96ef2716f", + "senderId": "DT12wf9erZyNJbBQrpbPDmfH3J8txiDgTE" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0297f2e8e609b2a6799214481e7573a043a197f8adf7b8bb306576fc3da83d2aaa", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_16", + "publicKey": "0297f2e8e609b2a6799214481e7573a043a197f8adf7b8bb306576fc3da83d2aaa" + } + }, + "signature": "304402202eee94bc3b53c64f8dee7790fe3eed8639da8faf0aa1f785e921cf139df0fb7e02200224efb0c07ae3972287c12a32143c1356adb93e00ac9e04a1358c8245a24cab", + "id": "1e59740fa596b615231660974d0b656122b799a8b13102ade8c1b779aa5de7b5", + "senderId": "DKGYWPSqa4m4z6h3433rNFbWPDdvHj5wwd" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0361b914fd5823bf39ae467e95d99e9f6ddb7d85cc6df3055ce00274b8e4a976cc", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_17", + "publicKey": "0361b914fd5823bf39ae467e95d99e9f6ddb7d85cc6df3055ce00274b8e4a976cc" + } + }, + "signature": "3044022002ad92b9b9d81dabf96ac7d90034debc55eeeae879b3fe6ffc026bde86bb7ad902205c57d31c5e5e0099b504ba4c49e220a00ff325dceb64c46aefbb7a0ad8570099", + "id": "bf305776da902802923c19b9d2c7f1a809b0847992131cfa578d5e5518c924bf", + "senderId": "DJshaeFyHcFTjiGJnVPaDmFXhnJ9bp96i5" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03fa6bc09bd2ff348b304e0cfbc2d2ec50aa3b9aee0de6a66c13fcd8ee5ac891cd", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_18", + "publicKey": "03fa6bc09bd2ff348b304e0cfbc2d2ec50aa3b9aee0de6a66c13fcd8ee5ac891cd" + } + }, + "signature": "3045022100be50b19c17a9ff221aae20394a45d92ea47e8c1072b6d5a302937d2fc48cba8002205e9bcb3471a734c07ceff0083ad9ba1570507a29e5014e889ba42a85e797cb5e", + "id": "44e48364b5b8cff3c68ae03de7dfde8d7ba6bcb99bf82b32fdc8bc3d0d9adeca", + "senderId": "DSuNttSb1UvCWg8iormfwPwi67EA84P5Mu" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03241957edca9ed28308e35cbf36762d22de706ebbd7c6a3a2d235d905d660c5c7", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_19", + "publicKey": "03241957edca9ed28308e35cbf36762d22de706ebbd7c6a3a2d235d905d660c5c7" + } + }, + "signature": "3045022100c11f8b863133535192e6c3fff20253a2695a2df74cdf1445d4ca0966803f708c0220200d4c2723d84f6334ba5d1cc1a0d45854867f4523fbcc9d09b3d53dd1972950", + "id": "5cba288f9ffc1361ba8f7f19f28347ffd917f37df8cf46ba1e0816725f288528", + "senderId": "DCZt1ozEVvPdYVvkHmUKK6k7gnyNNQDpMq" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "035ae2364c838bc21edf4c04a99c85799f26fb02cc0740c5a1c67d4dc1748ff913", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_20", + "publicKey": "035ae2364c838bc21edf4c04a99c85799f26fb02cc0740c5a1c67d4dc1748ff913" + } + }, + "signature": "304402203066f06a1c165795d8a069499a8c0998913ec93e689219f14145754aa3e26e4e02206e9f88da16f1f8a8ebaf481eff798452487738714fe9b5694fec6a5ef8c152a5", + "id": "ada1696532f7faad1dda594bc6db7bfc029a1759402c924348b74222873a3a27", + "senderId": "D7JyqWMPKhhRNQcKTAvrPGBjEjjBcGgPca" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "023aff4a16c3876e885aea70e5bce9734ce5acc95a2c41c9783f5acd617f7c7533", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_21", + "publicKey": "023aff4a16c3876e885aea70e5bce9734ce5acc95a2c41c9783f5acd617f7c7533" + } + }, + "signature": "3045022100f5150c23596b9479c8b277401ab9e7da9b2275436f3927dabd70395e52c3ea7c02204e318d498b0176b5f05bb96418c49da3375a8d9b47b3b1e72a6f4db30b3f8c34", + "id": "e186a679f2e47300ec2f24c670192bcede1cb12f359cb8e827374b22f41fbe12", + "senderId": "D6itxYJr4n7ZZk2bd9cZbJE1xaDmpfkNFL" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0217d7ce9c3754f7fc7e5b4c64a1ff397dc75931cd6c92e32d8b42068ad50fe4eb", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_22", + "publicKey": "0217d7ce9c3754f7fc7e5b4c64a1ff397dc75931cd6c92e32d8b42068ad50fe4eb" + } + }, + "signature": "3045022100b84f69a7ff67ed147fc0a750c3b7b2ecabd582b6d0cb698c0bb4a531daa6ca46022039d2722e486e1674d0db422078d63fcdb90b21bed0dcc1265adff72d0c2bf8b9", + "id": "86d9d146b62dbafe212aba5ec9764223b67f72c3c1aa93e54a270e3a528a8b20", + "senderId": "DDy4aKhF3cMadGhjFZnjaA1tx2rwnSEWcc" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "024019207f50dcb3e8aeb9ac1b00993d2bf131346e7e6d296429ea813a8373818e", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_23", + "publicKey": "024019207f50dcb3e8aeb9ac1b00993d2bf131346e7e6d296429ea813a8373818e" + } + }, + "signature": "3045022100aa83596b740639ee8947aa6d0f0ee123e4a5b87c39a4c6dd8a50304d4a7c97d102205fd45f85f5bdb076585a77888ef880bea52ade689731dff694d777de34913efc", + "id": "6301b791844e02116df528b1ea46d788e91521189c3828ce224e45a1b72cda59", + "senderId": "D6BwyDJkNFkaDLedcJTE4rPUw5bRtb4K8f" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0275db912c21dca0f0213a76f4544137d7c741b47f281cfd4f8b7cb8187e7ce3cc", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_24", + "publicKey": "0275db912c21dca0f0213a76f4544137d7c741b47f281cfd4f8b7cb8187e7ce3cc" + } + }, + "signature": "3045022100c7eda0d9cd7ef522615643d1b985c73add2d3612344bdcc0117779fa4f4f54d302203e33fb5d185f5174e9cb7634a3d307b74d3bb56cc2354024ce69c74905a85203", + "id": "eee776fcb8024469eacab3e4b23c3d14185326431369aa84f17921abab8ad0ad", + "senderId": "DHQSmrRdfYAp9Y6CuebKnkoQNzuN7Pk2oQ" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0331c615ca4bc89d4eeb8d7a9cfbb5c0d4ce49d2f480afbce499b0c7f8c6a24f2f", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_25", + "publicKey": "0331c615ca4bc89d4eeb8d7a9cfbb5c0d4ce49d2f480afbce499b0c7f8c6a24f2f" + } + }, + "signature": "304402203e69be3a73c5917d89d58f3c0ae18febbbf364d3f9dfbec6b526a5294f9c435902201750bcf6368c181aabc53c73fd271a2967a6f215e1d0506eded5dd1800fea1c8", + "id": "ec3d17c6d38c0b9848c7cb57b968efd1f3872b1d1b8bcfb74bae2b0aaa15877c", + "senderId": "D6EVFQx5Z7M2X9DWXHtfX51CtVekuKPMQF" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0338ca9b719f8047580eed23b64a40aecad3803a12c0dde83e3ec2c2a9bfaa8147", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_26", + "publicKey": "0338ca9b719f8047580eed23b64a40aecad3803a12c0dde83e3ec2c2a9bfaa8147" + } + }, + "signature": "3045022100e0bf90949739012b641793da162b3daa88b34c8753ee31b26850729e9df579810220439a3f2f1b8e719767ee68df46f4bc1f18c8c3b2da4118edff22396616d319fb", + "id": "14cd65c5f28f4cefc7c0157518a24f90c2260eb7166105b6b3358d91164ddf39", + "senderId": "DLCQ1jPsYbBCV7JfUJTasKbKoyGbK4a4HG" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03127001718bee76f14133272f0f4a928ffa8c2b38cafd94d7100253dac732c644", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_2", + "publicKey": "03127001718bee76f14133272f0f4a928ffa8c2b38cafd94d7100253dac732c644" + } + }, + "signature": "3044022003d2e76aca2848aedfe25415c11b9368dc72f687b66bef4527b40e2997b86b8c022076f7f82cbeb282d26535a2c1f0af0f02b48025d42c1bd56ac687fba1a3adb706", + "id": "0daff3992b54b1384f52f751c933c727cbaaf4fac435eba88a1817a425753614", + "senderId": "D9rv3h61heDYHQ3b3Xk3V5epHSTTC6Vn1d" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0241734825ba45b6de29d6f26242c25ae1ef125b82615ee89a9fdd5b0f3c6b5132", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_28", + "publicKey": "0241734825ba45b6de29d6f26242c25ae1ef125b82615ee89a9fdd5b0f3c6b5132" + } + }, + "signature": "3045022100bb2903424bcd0a72da531470779144d60286191bea1b200c5617ae4f92229ba6022046a876e3e6cb85469a16f34d2f937e2eef787011c6a313ee50258f15116148ac", + "id": "bd17dbd23f8dbba2736688702ac185a87c88c43b24ee6d7764a5b4138b2f38b7", + "senderId": "DAcQPbKa8zBWwDHbxj37N13C61iseMDWM9" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03b9409203d7091e3f4d49168529b749e942ed18f21beddd236d57d692f09a8f86", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_29", + "publicKey": "03b9409203d7091e3f4d49168529b749e942ed18f21beddd236d57d692f09a8f86" + } + }, + "signature": "3044022016d7ecfa776930a6f83464548e7a686735fde752903539a38eb9da0ce2488bbd02203c5e23a4072c8de35a90b296145cce3156a31cc0d754b8a37d363fb088bc7387", + "id": "16e02d3ef24dca4b03a1e489e20335224f18d888ed04f7e3512572f8e0cf92ae", + "senderId": "D5mmTaDAMSyPNKiDKrqwTFGWzWrZA3xaF8" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02c7b92a2d0027309e21855cf9c42a432b21ad13925e9dfc206f9c01e18fefa08a", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_30", + "publicKey": "02c7b92a2d0027309e21855cf9c42a432b21ad13925e9dfc206f9c01e18fefa08a" + } + }, + "signature": "30450221009de8828a7ad87cb5d52900e09d5beb680f9edc7640a3707d08a379511a7ba0f102202aa1d9294f9631f1325f252adb87c0d866e7398ce410037a42dc861d94308e15", + "id": "fece556bee4de2c7f1bb3099a05a84a33d0c963979fe1a222a899c13b7abb1fc", + "senderId": "DJ3NywAwQh4srbooLH1jTs9ma1hJE79v3z" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0221297804a26a93bb441a9d20a2916abf27fa7b29967678ef1a7a58062f73f40d", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_31", + "publicKey": "0221297804a26a93bb441a9d20a2916abf27fa7b29967678ef1a7a58062f73f40d" + } + }, + "signature": "3045022100b969611ef532557fa3da8a0325b2c88f3ebec954d64f158431d86b8e07929ea50220520affdcd0728cb7c5f63a58a1200d44133e90b1f7a6a9e28744ad6b0dcc2a75", + "id": "ee086317ea2fdc522f5eb502a0db9f3d4955b2318559e40a1f22a3f5f8d6344b", + "senderId": "D5P7eti7FUY4Tk5KXoxdf2tDAVQrRVCESA" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "027f504f6f20648e3bf171952629c7b868a2f799aa4b60f8eb3fe96afff16bbef0", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_32", + "publicKey": "027f504f6f20648e3bf171952629c7b868a2f799aa4b60f8eb3fe96afff16bbef0" + } + }, + "signature": "3044022006be7cbaa74089cabe47d02621f756762587d210a3f211ee941b5fcd0650908f02207d4040408bd25a2de03e5724362735ee8ad36c099b0c16efd4716e1dd7ec62ae", + "id": "764dd21aa4d0e2e0fa17bb2ff5e7ca304995d9e3593542badecc8ed24d5ea3ea", + "senderId": "D9q26yBTrEYuxHg7bbfZphv6129KvLu4v2" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "031954315b84db8f49ab7ee21357270450bb68d06b34472e5e93ddfa5710edc0c9", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_33", + "publicKey": "031954315b84db8f49ab7ee21357270450bb68d06b34472e5e93ddfa5710edc0c9" + } + }, + "signature": "3045022100859f93df994d86995fdf834bfe86b41eebaa04e5ab7d09f0b37acb50d313cd9802203c8993b793602c96d305fa795a9f2459f4706b340993584f3c56579392c0995c", + "id": "efd9e7c638afe62bec9be61783193ea52eea7b335053bd5af6c758d5b0e5847c", + "senderId": "D9iPFb5kAVnuDdomehRP9LncJj5ng2vrsr" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0267b310eac2bb0d6594de382a1ab74ac75b91e9d64a590b6249247b10fd9be829", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_34", + "publicKey": "0267b310eac2bb0d6594de382a1ab74ac75b91e9d64a590b6249247b10fd9be829" + } + }, + "signature": "3045022100a678978ab899e3903e760ee98640e3f658792a096a8d771c575944af6536cfdb0220428c312f1e0eb4be73ce4b256a754447570176200cfb6c09b3eb55f66526dd80", + "id": "70edcce5df67a250b6ba3567879bae6379ce4c688597fcedfbfd0313da6998e8", + "senderId": "D6xZmtyBzZKCEkK29JNPAD581TJ8XXrXYn" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "028f32320c66a89779756b04946d2aa256dff6cd547349d46e1938710063e387c4", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_35", + "publicKey": "028f32320c66a89779756b04946d2aa256dff6cd547349d46e1938710063e387c4" + } + }, + "signature": "304402206bc95876897527b39eacf4c961f9c036a9c8a0e53a17ce925c592d079fa643030220096e115d7fbd54aca4af7f621d64178dfcf2c13361106a3e3b5025dca97b44ee", + "id": "7f23f44157f3a677e81514fa431227410a27442e5fd1f2491b177c0f580f296d", + "senderId": "D9dW4eXJjABDQXSQB9GtvY5UBuRWWWejWb" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0218b889a24988527ab3948d80f97cfc37b923082e1f0398bc162190fd66ec4dee", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_36", + "publicKey": "0218b889a24988527ab3948d80f97cfc37b923082e1f0398bc162190fd66ec4dee" + } + }, + "signature": "3045022100c40a3f4cf15f9274e2b25ca8608cb965316aa0f00fa77817b79620ad8ccbdd5902206203a1043b03ba58aa9b7399694f8215cf45d30eb0caa748cc06f1a85a8faea9", + "id": "a65244ed17a9280aa694abdf6804b1a0b78dfc052b4845abcd3c89380159b29e", + "senderId": "DFHK7SdmPdjxNZ9uweqLZAv6v5GQ1NnBNe" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "035392ee88c60617764b4fe89ae2cc96560dfa5f992b03be31ce5680db9b863f73", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_37", + "publicKey": "035392ee88c60617764b4fe89ae2cc96560dfa5f992b03be31ce5680db9b863f73" + } + }, + "signature": "3044022036200c3191f8f01b77676644b9b94728b5afb2ab2de8c5c7c5582e795465661c02207848f1f2f0ab378d8906fd45aa048f354d5dbac4cb87c15973ffa86fe84ff0cd", + "id": "219e0942afe5f65c548ec2118a1c49febb7ec03fca4334ac16649062db9d146b", + "senderId": "DSh7AAC9KahXU2JZ539HAqEa5sHafxsxDQ" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03e75127d1deccf65844a1761bd26611b6c65c5b51a52eba27e3ee20a539fd63f1", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_38", + "publicKey": "03e75127d1deccf65844a1761bd26611b6c65c5b51a52eba27e3ee20a539fd63f1" + } + }, + "signature": "304402201a2990b2baae72f5cc8f2d1890f328e4082af0cf2a787d8f05208c3424ce089d0220790dbc7606dd6c03568fd0a771e9e8e89557257238ae90cfcb3bb8f3b475987b", + "id": "ee9ad2a66e9b2009a9fc671f80d0493803fc422161140169c7bc1fd401cd9ad6", + "senderId": "D85WuxGZrFs1QUYTvnRpmc6dd8rmBbpnaX" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0329fc1580906307ac9f2f55cec66e47983f8287d542408fb19f473a305d3638d8", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_39", + "publicKey": "0329fc1580906307ac9f2f55cec66e47983f8287d542408fb19f473a305d3638d8" + } + }, + "signature": "30450221008f66e89ec4c7af4b77e5b7ff36c542cc02672c8df70806b5a0fab7a7e8c7067502200d99ba19ceb1b471c39c4e95107ad6f8b978a623a790080b16f863347fe06b4f", + "id": "dd3077ed04a76343d340074270ce9826354802bd99e08cb864c1c5ad09f367df", + "senderId": "D85kwsBJKZ4pw5uQpc81eRj95f6a536AP6" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "035ec848e9388877dac88f121d19c8f5e870ac90d8ccb0116be9f734e4bd1a9405", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_40", + "publicKey": "035ec848e9388877dac88f121d19c8f5e870ac90d8ccb0116be9f734e4bd1a9405" + } + }, + "signature": "304402202b220d6c028bc23213edddaf303f18eef059551891aadbf7a4b4d7d3287457bb0220245678354bb8960b42ba2f2ceb12f926e82ff0d027b44988d799c8c0d8d7d9f2", + "id": "3afc6ea52b8edc7df0230ceac71baf45460f3bd761c5e75fe796bc7415063220", + "senderId": "DGBJdDadBwJD2xY8VsdAykdd6vPakMMUt6" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0356f5885306e45402aeb354a74d13c104699b3b53da46a5e922e4a6d6132a67e8", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_41", + "publicKey": "0356f5885306e45402aeb354a74d13c104699b3b53da46a5e922e4a6d6132a67e8" + } + }, + "signature": "3045022100f18bf2e013f2d9dcac013a76037d787f79baaa65f4f31ffe2b4ed8de249bdc8902202abcf77e809599d3e3a96225363c8e760ed4b4e20f97645547b381dba830c3da", + "id": "aea1fc173a2f4a9233b0fe59a5f6804167bee5658cb3e4e19dfe2be20f5772cd", + "senderId": "DG4VbapL3H39NJLB3DqQEefU47EMVqtxVw" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03ff8ab980434516ca28c982d0ecc8fc3107116d6c8b3e09c7ee5033f32adbd2ff", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_42", + "publicKey": "03ff8ab980434516ca28c982d0ecc8fc3107116d6c8b3e09c7ee5033f32adbd2ff" + } + }, + "signature": "3045022100e938d9901afeaa5a56d18abd9292ace93be03c84c09a6c4cb58fca96dfb54bc502201e921d27f9886d189f803b14d93655a42c4e095d49ee61051a4e70c7a173f3f1", + "id": "f18426d3ef81d4b7bf0337d70afcecddbd6db2206a2f139f1ca5823c381c7817", + "senderId": "DC3oNWedP48ypGxAeKbFC7gMjWxcNc2JhL" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0393f1590771a8ad1cf2baa086858f3029c4444cb82243917a7011f1f66cf8fd05", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_43", + "publicKey": "0393f1590771a8ad1cf2baa086858f3029c4444cb82243917a7011f1f66cf8fd05" + } + }, + "signature": "304502210095745c36a8af07e21546bd064f1ed1bd90e6c2a8db9c0c8e4853d0a8255443db0220259d2ce3677abb42f08b9d22aa13bbe383fd882ed38911b738ebaefc04589694", + "id": "6c51bea35b5e3270dcf7b7dfae8d984e19f476ea7e0435f157c4e0d22b7e7ea1", + "senderId": "DJm2sfcUKhyxakowY9TjyAytkdq7JrFgVj" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0234e24ff1dbc447c804eb385cd05bbd1dc59ef03b44a3346b13e7cccf00b61075", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_44", + "publicKey": "0234e24ff1dbc447c804eb385cd05bbd1dc59ef03b44a3346b13e7cccf00b61075" + } + }, + "signature": "3045022100ee1e8df480f2be042386d383d776b3fd6bd2d3f5a9035071153f23dbfdceeaae02203a0834aae4834da3ca7858779d474b9255ead754867d5b4a18873e9ecaa5045e", + "id": "66fb3e36233f4577ba585ccd7daf83e62d8df262d3d832b806479ac67c1ef35d", + "senderId": "D5oS8xfNebiPsjpwPWoZS6sA9qcYjTGT5h" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03a5789a4486f20f1fdca78a52b528b3bf9952e7c057de71a22adcfb444ba4c5d3", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_45", + "publicKey": "03a5789a4486f20f1fdca78a52b528b3bf9952e7c057de71a22adcfb444ba4c5d3" + } + }, + "signature": "3045022100cb037530bcff9a4d19899431648747022c28aa3239563379d96692bd525eb38902205f3cabb8dd470d9eb3d425e333ad1bc9f0643d489c600a811748fb5f4a203f7f", + "id": "5df9c5e350136571af4b86697bc9d4cfca3ff8b669e254b36f00be1dbde063f7", + "senderId": "D5SzHHdPdGqYUkH7BGNkmGHEUqfZrWb17r" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0347f692345fa7bf90e944eb55246da5f9f595d3f5a20ad50aeb6f9b973aaae17e", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_46", + "publicKey": "0347f692345fa7bf90e944eb55246da5f9f595d3f5a20ad50aeb6f9b973aaae17e" + } + }, + "signature": "3045022100c377efe5ffab58017473699cd7c839dcf48fa5b20b5ddf9bdc4801e22a579b2b02204d35c1a1416069544e3ec01d2ce21bb409f9f2fa4adedc8c03d6417c034a3fec", + "id": "da4cfad78e37d56421dd6676e5618a507340ef1e496831d1968c509e35ef9202", + "senderId": "DCLdibuZB6UsJP8KmdzcDLWzizrDtJQuxt" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "028a32b441377a69aa76e867026f3109b2f0aef8651fe91e2a4ab01eff102a6b98", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_47", + "publicKey": "028a32b441377a69aa76e867026f3109b2f0aef8651fe91e2a4ab01eff102a6b98" + } + }, + "signature": "3045022100e098672958be15989bb125d9018adb4a54e95ab664e64a673997e617e28b39df02206e8459997074d5976b77f90eb9d7180e9d4a0e0efdf433958ffeb2f04d9de382", + "id": "85bafcd07e7ba47ec95cb5b5a6759d4f9f87e036bb7660c7717504e845ef975e", + "senderId": "DSkivgRyimdAVqmm2ZAKwKmKN39WEbbPnL" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0223ac52179903e79865b9a98cf0b52ddc1ab46180c157e8f6bd1e63e7f14fcf31", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_48", + "publicKey": "0223ac52179903e79865b9a98cf0b52ddc1ab46180c157e8f6bd1e63e7f14fcf31" + } + }, + "signature": "304402200a005716f67d6cd3963a3c752c95f1bca01aa127c91ab1a632eb3022d11e3e67022024c4746078e440da441bcb366ee8999ffd2419e9a6f9cbf971d696d5b7f8733b", + "id": "0df1ed07d3f95ddf0385bad83a17b3a8fde6bd6532cd3479e48668064672b34f", + "senderId": "DDgKyKqdA6SuamB1eW77WvFu6RQFMZoU36" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "039de0390f28c7731d86ae7006a31888f12856cde3cc3c2619d4d4a42b6dfd6c51", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_49", + "publicKey": "039de0390f28c7731d86ae7006a31888f12856cde3cc3c2619d4d4a42b6dfd6c51" + } + }, + "signature": "3045022100efa5d51ca79992be4a87af049b3e9ec1b796576e4d937ea9e3760ab0bdcd301e022027e22a6c3395df155bd399643c241e4cc317eaead1f273fd7a709339dfa9dc99", + "id": "436bebc107fad38e944fd14785e09f0600df4d75d31cf3eac53f850462d0be74", + "senderId": "DKCaoaXApw1xE7K1BJcVkr1KGzjKmFWyTk" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02b87b0e70a7ae10613390f405620e24c495ba2b0cfcdbc67688e9b483dea564ee", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_50", + "publicKey": "02b87b0e70a7ae10613390f405620e24c495ba2b0cfcdbc67688e9b483dea564ee" + } + }, + "signature": "304502210096cdd35f803a37730ac73a97a23061dceac96319c67bfb1ddcfbac737febe96102202fa0b279f697da3afc043ffd3ecc838789be07ff119b5527a5c13468cecf66e9", + "id": "bb65f9dbe6272fd07a555fc86762d6a487f538b972f2926ff7698cdc906a32df", + "senderId": "DJQXFKEguZVabsAs46JbXXnQJ5jFhUtN9m" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03c9f8f4001216603c152b4b4429c2ead322ac34672999e808d567a7d1140e46be", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_51", + "publicKey": "03c9f8f4001216603c152b4b4429c2ead322ac34672999e808d567a7d1140e46be" + } + }, + "signature": "3045022100ee961089d02d7bb68fe2257f6a972eeaf6e2c1a1ad2f491c417e161fedbb556b02204c834644e5b5cde9a0b3f92fa23bade7670efab0a067597f6c151ee633932706", + "id": "cef44df9684f05dab67c0568a2c5295bb50cbb3c88f5cfbe672365bda274620f", + "senderId": "DKpt7cm2tZk4RPLyQ5ugwEH7gkriRaA7ov" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02cf70f73328d490cfb03ee822d3fc0cf9259d67c0564e843491e739501809d657", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_27", + "publicKey": "02cf70f73328d490cfb03ee822d3fc0cf9259d67c0564e843491e739501809d657" + } + }, + "signature": "30440220645b912b60f829c0bce58bfe9890ef9253418b6898416aaead663bdf158a99f2022061abbbabd454ec7f7e3f4b502216eec28110e945a4b9b913b1fc0b9758e7e6e4", + "id": "09408dbcf3e3e0835bf92a05330c023a7d6471f3825301a34efa094e0fd4fc30", + "senderId": "DQfjSqDuKr5YZaLAF8rWpFMqMYwEbPtGKg" + } + ], "height": 1, "id": "13149578060728881902", "blockSignature": "3045022100a6605198e0f590c88798405bc76748d84e280d179bcefed2c993e70cded2a5dd022008c7f915b89fc4f3250fc4b481abb753c68f30ac351871c50bd6cfaf151370e8" diff --git a/packages/core-config/__tests__/__stubs__/network.json b/packages/core-config/__tests__/__stubs__/network.json index 18944d3ae2..d57a1c1694 100644 --- a/packages/core-config/__tests__/__stubs__/network.json +++ b/packages/core-config/__tests__/__stubs__/network.json @@ -13,27 +13,52 @@ "symbol": "DѦ", "explorer": "https://dexplorer.ark.io" }, - "constants": [{ - "height": 1, - "reward": 0, - "activeDelegates": 51, - "blocktime": 8, - "block": { - "version": 0, - "maxTransactions": 50, - "maxPayload": 2097152 + "constants": [ + { + "height": 1, + "reward": 0, + "activeDelegates": 51, + "blocktime": 8, + "block": { + "version": 0, + "maxTransactions": 150, + "maxPayload": 2097152 + }, + "epoch": "2017-03-21T13:00:00.000Z", + "fees": { + "dynamic": false, + "dynamicFees": { + "minFeePool": 1000, + "minFeeBroadcast": 1000, + "addonBytes": { + "transfer": 100, + "secondSignature": 250, + "delegateRegistration": 500, + "vote": 100, + "multiSignature": 500, + "ipfs": 250, + "timelockTransfer": 500, + "multiPayment": 500, + "delegateResignation": 500 + } + }, + "staticFees": { + "transfer": 10000000, + "secondSignature": 500000000, + "delegateRegistration": 2500000000, + "vote": 100000000, + "multiSignature": 500000000, + "ipfs": 0, + "timelockTransfer": 0, + "multiPayment": 0, + "delegateResignation": 0 + } + } }, - "epoch": "2017-03-21T13:00:00.000Z", - "fees": { - "send": 10000000, - "vote": 100000000, - "secondsignature": 500000000, - "delegateRegistration": 2500000000, - "multisignature": 500000000 + { + "height": 75600, + "reward": 200000000 } - }, { - "height": 75600, - "reward": 200000000 - }], + ], "exceptions": {} } diff --git a/packages/core-config/__tests__/__stubs__/peers.json b/packages/core-config/__tests__/__stubs__/peers.json index ff90ec2735..f1f6038735 100644 --- a/packages/core-config/__tests__/__stubs__/peers.json +++ b/packages/core-config/__tests__/__stubs__/peers.json @@ -1,10 +1,13 @@ { "blackList": [], - "list": [{ - "ip": "127.0.0.1", - "port": 4102 - }, { - "ip": "127.0.0.1", - "port": 4202 - }] + "list": [ + { + "ip": "127.0.0.1", + "port": 4102 + }, + { + "ip": "127.0.0.1", + "port": 4202 + } + ] } diff --git a/packages/core-config/__tests__/loader.test.js b/packages/core-config/__tests__/loader.test.js index 21fc3e8c9b..8db2ae1f63 100644 --- a/packages/core-config/__tests__/loader.test.js +++ b/packages/core-config/__tests__/loader.test.js @@ -1,5 +1,3 @@ -'use strict' - const path = require('path') const configLoader = require('../lib/loader') @@ -8,7 +6,7 @@ const stubConfigPath = path.resolve(__dirname, './__stubs__') const stubConfig = { delegates: require('./__stubs__/delegates'), genesisBlock: require('./__stubs__/genesisBlock'), - network: require('./__stubs__/network') + network: require('./__stubs__/network'), } beforeEach(() => { diff --git a/packages/core-config/jest.config.js b/packages/core-config/jest.config.js index 26f7a25796..57770a97bb 100644 --- a/packages/core-config/jest.config.js +++ b/packages/core-config/jest.config.js @@ -1,22 +1,12 @@ -'use strict' - module.exports = { testEnvironment: 'node', bail: false, verbose: true, - testMatch: [ - '**/__tests__/**/*.test.js' - ], - moduleFileExtensions: [ - 'js', - 'json' - ], + testMatch: ['**/__tests__/**/*.test.js'], + moduleFileExtensions: ['js', 'json'], collectCoverage: false, coverageDirectory: '/.coverage', - collectCoverageFrom: [ - 'lib/**/*.js', - '!**/node_modules/**' - ], + collectCoverageFrom: ['lib/**/*.js', '!**/node_modules/**'], watchman: false, - setupTestFrameworkScriptFile: 'jest-extended' + setupTestFrameworkScriptFile: 'jest-extended', } diff --git a/packages/core-config/jsdoc.json b/packages/core-config/jsdoc.json index 23276f74ea..f3ea8aab33 100644 --- a/packages/core-config/jsdoc.json +++ b/packages/core-config/jsdoc.json @@ -7,9 +7,7 @@ "includePattern": ".js$", "excludePattern": "(node_modules/|docs)" }, - "plugins": [ - "plugins/markdown" - ], + "plugins": ["plugins/markdown"], "opts": { "template": "../../node_modules/docdash", "encoding": "utf8", diff --git a/packages/core-config/lib/index.js b/packages/core-config/lib/index.js index 6b633eadcc..86e71cb89a 100644 --- a/packages/core-config/lib/index.js +++ b/packages/core-config/lib/index.js @@ -1,5 +1,3 @@ -'use strict' - const { client } = require('@arkecosystem/crypto') const loader = require('./loader') @@ -10,11 +8,11 @@ const loader = require('./loader') exports.plugin = { pkg: require('../package.json'), alias: 'config', - async register (container, options) { + async register(container, options) { const config = await loader.setUp(options) client.setConfig(config.network) return config - } + }, } diff --git a/packages/core-config/lib/loader.js b/packages/core-config/lib/loader.js index c6fea7bab3..b98060672d 100644 --- a/packages/core-config/lib/loader.js +++ b/packages/core-config/lib/loader.js @@ -1,4 +1,4 @@ -'use strict' +/* eslint no-await-in-loop: "off" */ const axios = require('axios') const dirTree = require('directory-tree') @@ -13,7 +13,7 @@ class ConfigLoader { * @param {Object} options * @return {ConfigLoader} */ - async setUp (options) { + async setUp(options) { this.options = options this.network = JSON.parse(process.env.ARK_NETWORK) @@ -21,7 +21,7 @@ class ConfigLoader { this._validateConfig() - this.buildConstants() + this.configureCrypto() return this } @@ -31,16 +31,16 @@ class ConfigLoader { * @param {Number} height * @return {void} */ - getConstants (height) { + getConstants(height) { return configManager.getConstants(height) } /** - * Build constants from the config. + * Configure the crypto package. * @return {void} */ - buildConstants () { - configManager.buildConstants() + configureCrypto() { + configManager.setConfig(this.network) } /** @@ -48,7 +48,7 @@ class ConfigLoader { * @param {String} dest * @return {Promise} */ - async copyFiles (dest) { + async copyFiles(dest) { if (!dest) { dest = `${process.env.ARK_PATH_DATA}/config` } @@ -62,7 +62,7 @@ class ConfigLoader { * Load and bind the config. * @return {void} */ - async __createFromDirectory () { + async __createFromDirectory() { const files = this.__getFiles() this.__createBindings(files) @@ -75,7 +75,7 @@ class ConfigLoader { * @param {Array} files * @return {void} */ - __createBindings (files) { + __createBindings(files) { for (const [key, value] of Object.entries(files)) { this[key] = require(value) } @@ -85,23 +85,27 @@ class ConfigLoader { * Get all config files. * @return {Object} */ - __getFiles () { + __getFiles() { const basePath = path.resolve(process.env.ARK_PATH_CONFIG) if (!fs.existsSync(basePath)) { - throw new Error('An invalid configuration was provided or is inaccessible due to it\'s security settings.') + throw new Error( + "An invalid configuration was provided or is inaccessible due to it's security settings.", + ) process.exit(1) // eslint-disable-line no-unreachable } - const formatName = (file) => path.basename(file.name, path.extname(file.name)) + const formatName = file => path.basename(file.name, path.extname(file.name)) - let configTree = {} + const configTree = {} - dirTree(basePath, { extensions: /\.js/ }).children.forEach(entry => { - if (entry.type === 'file') { - configTree[formatName(entry)] = entry.path - } - }) + dirTree(basePath, { extensions: /\.(js|json)$/ }).children.forEach( + entry => { + if (entry.type === 'file') { + configTree[formatName(entry)] = entry.path + } + }, + ) return configTree } @@ -111,16 +115,14 @@ class ConfigLoader { * @param {String} configFile * @return {void} */ - async __buildPeers (configFile) { + async __buildPeers(configFile) { if (!this.peers.sources) { return } - let output = require(configFile) - - for (let i = this.peers.sources.length - 1; i >= 0; i--) { - const source = this.peers.sources[i] + const output = require(configFile) + for (const source of this.peers.sources) { // Local File... if (source.startsWith('/')) { output.list = require(source) @@ -149,7 +151,7 @@ class ConfigLoader { * Validate crucial parts of the configuration. * @return {void} */ - _validateConfig () { + _validateConfig() { try { ow(this.network.pubKeyHash, ow.number) ow(this.network.nethash, ow.string.length(64)) diff --git a/packages/core-config/package.json b/packages/core-config/package.json index 3e14cfb03c..f8967a1a7b 100644 --- a/packages/core-config/package.json +++ b/packages/core-config/package.json @@ -1,7 +1,7 @@ { "name": "@arkecosystem/core-config", - "version": "0.1.1", - "description": "Configuration Loader for ARK Core", + "version": "0.2.0", + "description": "Configuration Loader for Ark Core", "contributors": [ "François-Xavier Thoorens ", "Brian Faust " @@ -9,23 +9,25 @@ "license": "MIT", "main": "lib/index.js", "scripts": { - "build:docs": "../../node_modules/.bin/jsdoc -c jsdoc.json", "test": "cross-env ARK_ENV=test jest --runInBand --detectOpenHandles", - "test:coverage": "cross-env ARK_ENV=test jest --coverage --runInBand --detectOpenHandles", - "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand --watch", + "test:coverage": "cross-env ARK_ENV=test jest --coverage --coveragePathIgnorePatterns='/(defaults.js|index.js)$' --runInBand --detectOpenHandles", + "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand", "test:watch": "cross-env ARK_ENV=test jest --runInBand --watch", "test:watch:all": "cross-env ARK_ENV=test jest --runInBand --watchAll", "lint": "eslint ./ --fix", "depcheck": "depcheck ./" }, "dependencies": { - "@arkecosystem/crypto": "^0.1.1", + "@arkecosystem/crypto": "~0.2", "axios": "^0.18.0", - "directory-tree": "^2.1.0", - "fs-extra": "^6.0.1", - "ow": "^0.3.0" + "directory-tree": "^2.1.1", + "fs-extra": "^7.0.1", + "ow": "^0.8.0" }, "publishConfig": { "access": "public" + }, + "engines": { + "node": ">=10.x" } } diff --git a/packages/core-container/.gitignore b/packages/core-container/.gitignore new file mode 100644 index 0000000000..5d1942c190 --- /dev/null +++ b/packages/core-container/.gitignore @@ -0,0 +1,2 @@ +config +data diff --git a/packages/core-container/CHANGELOG.md b/packages/core-container/CHANGELOG.md index 127cc35e42..5a2008de88 100644 --- a/packages/core-container/CHANGELOG.md +++ b/packages/core-container/CHANGELOG.md @@ -7,6 +7,27 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Unreleased -## 0.0.1 - 2018-05-31 +## 0.2.0 - 2018-12-03 + +### Added + +- Support plugin extensions +- More graceful handling of shutdown +- Silent shutdown to hide output +- Configuration through a remote peer +- Expose the git commit hash on development networks + +### Fixed + +- Cast numerical strings to numbers + +### Changed + +- No longer load the `.env` file in test environments +- Dropped node.js 9 as minimum requirement in favour of node.js 10 + +## 0.1.1 - 2018-06-14 + ### Added + - initial release diff --git a/packages/core-container/README.md b/packages/core-container/README.md index dae2a2ccf6..dc6a8b990b 100644 --- a/packages/core-container/README.md +++ b/packages/core-container/README.md @@ -1,12 +1,12 @@ -![ARK Core](https://i.imgur.com/1aP6F2o.png) +# Ark Core - Container -# ARK Core - Container +

+ +

-## Installation +## Documentation -```bash -yarn add @arkecosystem/core-container -``` +You can find installation instructions and detailed instructions on how to use this package at the [dedicated documentation site](https://docs.ark.io/guidebook/core/plugins/core-container.html). ## Security diff --git a/packages/core-container/__tests__/__stubs__/plugin-a.js b/packages/core-container/__tests__/__stubs__/plugin-a.js index 58e6a6ab35..c7595c7c40 100644 --- a/packages/core-container/__tests__/__stubs__/plugin-a.js +++ b/packages/core-container/__tests__/__stubs__/plugin-a.js @@ -1,16 +1,14 @@ -'use strict' - exports.plugin = { pkg: { name: 'stub/plugin-a', - version: '1.0.0' + version: '1.0.0', }, alias: 'stub-plugin-a', - register (container, options) { + register(container, options) { return { container, - options + options, } }, - deregister () {} + deregister() {}, } diff --git a/packages/core-container/__tests__/__stubs__/plugin-b.js b/packages/core-container/__tests__/__stubs__/plugin-b.js index ccb11d85a2..6023222e04 100644 --- a/packages/core-container/__tests__/__stubs__/plugin-b.js +++ b/packages/core-container/__tests__/__stubs__/plugin-b.js @@ -1,16 +1,14 @@ -'use strict' - exports.plugin = { pkg: { name: 'stub/plugin-b', - version: '1.0.0' + version: '1.0.0', }, alias: 'stub-plugin-b', - register (container, options) { + register(container, options) { return { container, - options + options, } }, - deregister () {} + deregister() {}, } diff --git a/packages/core-container/__tests__/__stubs__/plugin-c.js b/packages/core-container/__tests__/__stubs__/plugin-c.js index 05db0364fb..7d262d985b 100644 --- a/packages/core-container/__tests__/__stubs__/plugin-c.js +++ b/packages/core-container/__tests__/__stubs__/plugin-c.js @@ -1,15 +1,13 @@ -'use strict' - exports.plugin = { pkg: { name: 'stub/plugin-c', - version: '1.0.0' + version: '1.0.0', }, alias: 'stub-plugin-c', - register (container, options) { + register(container, options) { return { container, - options + options, } - } + }, } diff --git a/packages/core-container/__tests__/__stubs__/plugins.js b/packages/core-container/__tests__/__stubs__/plugins.js index dd81292fcf..ad2a319c0c 100644 --- a/packages/core-container/__tests__/__stubs__/plugins.js +++ b/packages/core-container/__tests__/__stubs__/plugins.js @@ -1,12 +1,12 @@ module.exports = { './plugin-a': { - enabled: true + enabled: true, }, './plugin-b': { enabled: true, - property: 'value' + property: 'value', }, './plugin-c': { - enabled: true - } + enabled: true, + }, } diff --git a/packages/core-container/__tests__/container.test.js b/packages/core-container/__tests__/container.test.js index 8be08191fe..f0ac16b9f1 100644 --- a/packages/core-container/__tests__/container.test.js +++ b/packages/core-container/__tests__/container.test.js @@ -1,43 +1,45 @@ -'use strict' - const path = require('path') const { asValue } = require('awilix') -let container +let app beforeEach(async () => { - container = require('../lib') - - await container.setUp({ - data: 'fake-path', - config: path.resolve(__dirname, '../../core/lib/config/testnet'), - token: 'ark', - network: 'testnet' - }, { - skipPlugins: true - }) + app = require('../lib') + + await app.setUp( + '2.0.0', + { + data: 'fake-path', + config: path.resolve(__dirname, '../../core/lib/config/testnet'), + token: 'ark', + network: 'testnet', + }, + { + skipPlugins: true, + }, + ) }) describe('Container', () => { it('should be an object', () => { - expect(container).toBeObject() + expect(app).toBeObject() }) it('should add a new registration', () => { - container.register('fake', asValue('value')) + app.register('fake', asValue('value')) - expect(container.container.registrations['fake']).toBeTruthy() + expect(app.container.registrations.fake).toBeTruthy() }) it('should resolve a registration', () => { - container.register('fake', asValue('value')) + app.register('fake', asValue('value')) - expect(container.resolve('fake')).toBe('value') + expect(app.resolve('fake')).toBe('value') }) it('should determine if a registration exists', () => { - container.register('fake', asValue('value')) + app.register('fake', asValue('value')) - expect(container.has('fake')).toBeTruthy() + expect(app.has('fake')).toBeTrue() }) it('should resolve and export paths', () => { diff --git a/packages/core-container/__tests__/registrars/plugin.test.js b/packages/core-container/__tests__/registrars/plugin.test.js index d6039a4ebe..7e09eb1cdb 100644 --- a/packages/core-container/__tests__/registrars/plugin.test.js +++ b/packages/core-container/__tests__/registrars/plugin.test.js @@ -1,5 +1,3 @@ -'use strict' - const path = require('path') const Container = require('../../lib/container') const PluginRegistrar = require('../../lib/registrars/plugin') @@ -40,8 +38,7 @@ describe('Plugin Registrar', () => { expect(instance.container.has('stub-plugin-a')).toBeTrue() }) - xit('should register plugins with @ paths', () => { - }) + it.skip('should register plugins with @ paths', () => {}) }) describe('setUp', () => { @@ -51,7 +48,6 @@ describe('Plugin Registrar', () => { it('should register each plugin', async () => { await instance.setUp() - ;['a', 'b', 'c'].forEach(char => { expect(instance.container.has(`stub-plugin-${char}`)).toBeTrue() }) @@ -64,7 +60,6 @@ describe('Plugin Registrar', () => { await instance.setUp() expect(instance.container.has('stub-plugin-a')).toBeTrue() - ;['b', 'c'].forEach(char => { expect(instance.container.has(`stub-plugin-${char}`)).toBeFalse() }) @@ -77,13 +72,11 @@ describe('Plugin Registrar', () => { beforeEach(async () => { await instance.setUp() - ;['a', 'b', 'c'].forEach(char => { expect(instance.container.has(`stub-plugin-${char}`)).toBeTrue() }) - ;['a', 'b', 'c'].forEach(char => { - plugins[char] = (require(`${stubPluginPath}/plugin-${char}`)) + plugins[char] = require(`${stubPluginPath}/plugin-${char}`) }) }) @@ -93,17 +86,15 @@ describe('Plugin Registrar', () => { }) await instance.tearDown() - ;['a', 'b'].forEach(char => { expect(plugins[char].plugin.deregister).toHaveBeenCalled() }) - expect(plugins['c'].deregister).not.toBeDefined() + expect(plugins.c.deregister).not.toBeDefined() }) it('should deregister all the plugins in inverse order', async () => { const spy = jest.fn() - ;['a', 'b'].forEach(char => { plugins[char].plugin.deregister = () => spy(char) }) @@ -114,4 +105,17 @@ describe('Plugin Registrar', () => { expect(spy).toHaveBeenNthCalledWith(2, 'a') }) }) + + describe('__castOptions', () => { + it('should cast options', async () => { + const options = { + number: '1', + notANumber: '0.0.0.0', + } + + instance.__castOptions(options) + expect(options.number).toEqual(1) + expect(options.notANumber).toEqual('0.0.0.0') + }) + }) }) diff --git a/packages/core-container/__tests__/remote-loader.test.js b/packages/core-container/__tests__/remote-loader.test.js new file mode 100644 index 0000000000..ca4d002486 --- /dev/null +++ b/packages/core-container/__tests__/remote-loader.test.js @@ -0,0 +1,171 @@ +const fs = require('fs-extra') +const mockProcess = require('jest-mock-process') + +const axios = require('axios') +const MockAdapter = require('axios-mock-adapter') +const RemoteLoader = require('../lib/remote-loader') + +const axiosMock = new MockAdapter(axios) +const configDir = './__test-remote-config__' + +let testSubject + +afterAll(() => { + fs.removeSync(configDir) +}) + +beforeEach(() => { + testSubject = new RemoteLoader({ + remote: '127.0.0.1:4002', + config: configDir, + data: './data', + }) +}) + +afterEach(() => { + axiosMock.reset() +}) + +describe('Remote Loader', () => { + it('should be an object', () => { + expect(testSubject).toBeObject() + }) + + it('should ensure the config directory exists', () => { + expect(fs.pathExistsSync(testSubject.config)).toBeTrue() + }) + + describe('__configureNetwork', () => { + it('should be a function', () => { + expect(testSubject.__configureNetwork).toBeFunction() + }) + + it('should not be OK', async () => { + const mockExit = mockProcess.mockProcessExit() + + axiosMock + .onGet('http://127.0.0.1:4002/config/network') + .reply(() => [404, {}]) + + await testSubject.__configureNetwork() + + expect(mockExit).toHaveBeenCalledWith(1) + }) + + it('should be OK', async () => { + axiosMock.onGet('http://127.0.0.1:4002/config/network').reply(() => [ + 200, + { + data: require('../../crypto/lib/networks/ark/devnet.json'), + }, + ]) + + await testSubject.__configureNetwork() + + expect(fs.existsSync(`${configDir}/network.json`)).toBeTrue() + }) + }) + + describe('__configureGenesisBlock', () => { + it('should be a function', () => { + expect(testSubject.__configureGenesisBlock).toBeFunction() + }) + + it('should not be OK', async () => { + axiosMock + .onGet('http://127.0.0.1:4002/config/genesis-block') + .reply(() => [404, {}]) + + await expect(testSubject.__configureGenesisBlock()).rejects.toThrowError() + }) + + it('should be OK', async () => { + axiosMock + .onGet('http://127.0.0.1:4002/config/genesis-block') + .reply(() => [ + 200, + { + data: require('../../core/lib/config/devnet/genesisBlock.json'), + }, + ]) + + await testSubject.__configureGenesisBlock() + + expect(fs.existsSync(`${configDir}/genesisBlock.json`)).toBeTrue() + }) + }) + + describe('__configurePeers', () => { + it('should be a function', () => { + expect(testSubject.__configurePeers).toBeFunction() + }) + + it('should not be OK', async () => { + const mockExit = mockProcess.mockProcessExit() + + axiosMock + .onGet('http://127.0.0.1:4002/config/peers') + .reply(() => [404, {}]) + + await testSubject.__configurePeers() + + expect(mockExit).toHaveBeenCalledWith(1) + }) + + it('should be OK', async () => { + axiosMock.onGet('http://127.0.0.1:4002/config/peers').reply(() => [ + 200, + { + data: require('../../core/lib/config/devnet/peers.json'), + }, + ]) + + await testSubject.__configurePeers() + + expect(fs.existsSync(`${configDir}/peers.json`)).toBeTrue() + }) + }) + + describe('__configureDelegates', () => { + it('should be a function', () => { + expect(testSubject.__configureDelegates).toBeFunction() + }) + + it('should not be OK', async () => { + const mockExit = mockProcess.mockProcessExit() + + axiosMock + .onGet('http://127.0.0.1:4002/config/delegates') + .reply(() => [404, {}]) + + await testSubject.__configureDelegates() + + expect(mockExit).toHaveBeenCalledWith(1) + }) + + it('should be OK', async () => { + axiosMock.onGet('http://127.0.0.1:4002/config/delegates').reply(() => [ + 200, + { + data: require('../../core/lib/config/devnet/delegates.json'), + }, + ]) + + await testSubject.__configureDelegates() + + expect(fs.existsSync(`${configDir}/delegates.json`)).toBeTrue() + }) + }) + + describe('__configurePlugins', () => { + it('should be a function', () => { + expect(testSubject.__configurePlugins).toBeFunction() + }) + + it('should be OK', async () => { + await testSubject.__configurePlugins({ name: 'devnet' }) + + expect(fs.existsSync(`${configDir}/plugins.js`)).toBeTrue() + }) + }) +}) diff --git a/packages/core-container/jest.config.js b/packages/core-container/jest.config.js index 26f7a25796..57770a97bb 100644 --- a/packages/core-container/jest.config.js +++ b/packages/core-container/jest.config.js @@ -1,22 +1,12 @@ -'use strict' - module.exports = { testEnvironment: 'node', bail: false, verbose: true, - testMatch: [ - '**/__tests__/**/*.test.js' - ], - moduleFileExtensions: [ - 'js', - 'json' - ], + testMatch: ['**/__tests__/**/*.test.js'], + moduleFileExtensions: ['js', 'json'], collectCoverage: false, coverageDirectory: '/.coverage', - collectCoverageFrom: [ - 'lib/**/*.js', - '!**/node_modules/**' - ], + collectCoverageFrom: ['lib/**/*.js', '!**/node_modules/**'], watchman: false, - setupTestFrameworkScriptFile: 'jest-extended' + setupTestFrameworkScriptFile: 'jest-extended', } diff --git a/packages/core-container/jsdoc.json b/packages/core-container/jsdoc.json index 23276f74ea..f3ea8aab33 100644 --- a/packages/core-container/jsdoc.json +++ b/packages/core-container/jsdoc.json @@ -7,9 +7,7 @@ "includePattern": ".js$", "excludePattern": "(node_modules/|docs)" }, - "plugins": [ - "plugins/markdown" - ], + "plugins": ["plugins/markdown"], "opts": { "template": "../../node_modules/docdash", "encoding": "utf8", diff --git a/packages/core-container/lib/container.js b/packages/core-container/lib/container.js index 0866813ccb..f5d25cf845 100644 --- a/packages/core-container/lib/container.js +++ b/packages/core-container/lib/container.js @@ -1,27 +1,56 @@ -'use strict' - +const { createContainer } = require('awilix') +const semver = require('semver') +const delay = require('delay') const PluginRegistrar = require('./registrars/plugin') const Environment = require('./environment') -const { createContainer } = require('awilix') +const RemoteLoader = require('./remote-loader') module.exports = class Container { /** * Create a new container instance. * @constructor */ - constructor () { + constructor() { this.container = createContainer() - - this.__registerExitHandler() + this.exitEvents = ['SIGINT', 'exit'] + + /** + * May be used by CLI programs to suppress the shutdown + * messages. + */ + this.silentShutdown = false + + /** + * The git commit hash of the repository. Used during development to + * easily idenfity nodes based on their commit hash and version. + */ + try { + this.hashid = require('child_process') + .execSync('git rev-parse --short=8 HEAD') + .toString() + .trim() + } catch (e) { + this.hashid = 'unknown' + } } /** - * Set up the container. + * Set up the app. + * @param {String} version * @param {Object} variables * @param {Object} options * @return {void} */ - async setUp (variables, options = {}) { + async setUp(version, variables, options = {}) { + this.__registerExitHandler() + + this.setVersion(version) + + if (variables.remote) { + const remoteLoader = new RemoteLoader(variables) + await remoteLoader.setUp() + } + this.env = new Environment(variables) this.env.setUp() @@ -35,10 +64,10 @@ module.exports = class Container { } /** - * Tear down the container. + * Tear down the app. * @return {Promise} */ - async tearDown () { + async tearDown() { return this.plugins.tearDown() } @@ -48,7 +77,7 @@ module.exports = class Container { * @return {Object} * @throws {Error} */ - register (name, resolver) { + register(name, resolver) { try { return this.container.register(name, resolver) } catch (err) { @@ -62,7 +91,7 @@ module.exports = class Container { * @return {Object} * @throws {Error} */ - resolve (key) { + resolve(key) { try { return this.container.resolve(key) } catch (err) { @@ -76,7 +105,7 @@ module.exports = class Container { * @return {Object} * @throws {Error} */ - resolvePlugin (key) { + resolvePlugin(key) { try { return this.container.resolve(key).plugin } catch (err) { @@ -90,7 +119,7 @@ module.exports = class Container { * @return {Object} * @throws {Error} */ - resolveOptions (key) { + resolveOptions(key) { return this.plugins.resolveOptions(key) } @@ -99,7 +128,7 @@ module.exports = class Container { * @param {String} key * @return {Boolean} */ - has (key) { + has(key) { try { this.container.resolve(key) @@ -110,34 +139,102 @@ module.exports = class Container { } /** - * Handle any exit signals. + * Force the container to exit and print the given message and associated error. + * @param {String} message + * @param {Error} error + * @return {void} + */ + forceExit(message, error = null) { + this.exit(1, message, error) + } + + /** + * Exit the container with the given exitCode, message and associated error. + * @param {Number} exitCode + * @param {String} message + * @param {Error} error + * @return {void} + */ + exit(exitCode, message, error = null) { + this.shuttingDown = true + + const logger = this.resolvePlugin('logger') + logger.error(':boom: Container force shutdown :boom:') + logger.error(message) + + if (error) { + logger.error(error.stack) + } + + process.exit(exitCode) + } + + /** + * Get the application git commit hash. + * @throws {String} + */ + getHashid() { + return this.hashid + } + + /** + * Get the application version. + * @throws {String} + */ + getVersion() { + return this.version + } + + /** + * Set the application version. + * @param {String} version * @return {void} */ - __registerExitHandler () { - let shuttingDown = false + setVersion(version) { + if (!semver.valid(version)) { + this.forceExit( + `The provided version ("${version}") is invalid. Please check https://semver.org/ and make sure you follow the spec.`, + ) + } + this.version = version + } + + /** + * Handle any exit signals. + * @return {void} + */ + __registerExitHandler() { const handleExit = async () => { - if (shuttingDown) { + if (this.shuttingDown) { return } - shuttingDown = true + this.shuttingDown = true const logger = this.resolvePlugin('logger') - logger.info('EXIT handled, trying to shut down gracefully') - logger.info('Stopping ARK Core') + logger.suppressConsoleOutput(this.silentShutdown) + logger.info( + 'Ark Core is trying to gracefully shut down to avoid data corruption :pizza:', + ) try { - logger.info('Saving wallets') - await this.resolvePlugin('database').saveWallets(false) - } catch (error) {} + const database = this.resolvePlugin('database') + if (database) { + const emitter = this.resolvePlugin('event-emitter') - // const lastBlock = this.resolvePlugin('blockchain').getLastBlock() + // Notify plugins about shutdown + emitter.emit('shutdown') - // if (lastBlock) { - // const spvFile = `${process.env.ARK_PATH_DATA}/spv.json` - // await fs.writeFile(spvFile, JSON.stringify(lastBlock.data)) - // } + // Wait for event to be emitted and give time to finish + await delay(1000) + + // Save dirty wallets + await database.saveWallets(false) + } + } catch (error) { + console.error(error.stack) + } await this.plugins.tearDown() @@ -145,6 +242,6 @@ module.exports = class Container { } // Handle exit events - ['SIGINT', 'exit'].forEach(eventType => process.on(eventType, handleExit)) + this.exitEvents.forEach(eventType => process.on(eventType, handleExit)) } } diff --git a/packages/core-container/lib/environment.js b/packages/core-container/lib/environment.js index 745d77b7e6..67aa61f0c7 100644 --- a/packages/core-container/lib/environment.js +++ b/packages/core-container/lib/environment.js @@ -1,5 +1,3 @@ -'use strict' - const fs = require('fs-extra') const path = require('path') const expandHomeDir = require('expand-home-dir') @@ -11,14 +9,14 @@ module.exports = class Environment { * @param {Object} variables * @return {void} */ - constructor (variables) { + constructor(variables) { this.variables = variables } /** * Set up the environment variables. */ - setUp () { + setUp() { this.__exportPaths() this.__exportNetwork() this.__exportVariables() @@ -28,12 +26,14 @@ module.exports = class Environment { * Export all path variables for the core environment. * @return {void} */ - __exportPaths () { + __exportPaths() { const allowedKeys = ['config', 'data'] - for (let [key, value] of Object.entries(this.variables)) { + for (const [key, value] of Object.entries(this.variables)) { if (allowedKeys.includes(key)) { - process.env[`ARK_PATH_${key.toUpperCase()}`] = path.resolve(expandHomeDir(value)) + process.env[`ARK_PATH_${key.toUpperCase()}`] = path.resolve( + expandHomeDir(value), + ) } } } @@ -42,21 +42,30 @@ module.exports = class Environment { * Export all network variables for the core environment. * @return {void} */ - __exportNetwork () { + __exportNetwork() { let config if (this.variables.token && this.variables.network) { - config = NetworkManager.findByName(this.variables.network, this.variables.token) + config = NetworkManager.findByName( + this.variables.network, + this.variables.token, + ) } else { try { - const networkPath = path.resolve(expandHomeDir(`${process.env.ARK_PATH_CONFIG}/network.json`)) + const networkPath = path.resolve( + expandHomeDir(`${process.env.ARK_PATH_CONFIG}/network.json`), + ) config = require(networkPath) - } catch (error) {} + } catch (error) { + config = false + } } if (!config) { - throw new Error('An invalid network configuration was provided or is inaccessible due to it\'s security settings.') + throw new Error( + "An invalid network configuration was provided or is inaccessible due to it's security settings.", + ) process.exit(1) // eslint-disable-line no-unreachable } @@ -68,13 +77,21 @@ module.exports = class Environment { * Export all additional variables for the core environment. * @return {void} */ - __exportVariables () { + __exportVariables() { + // Don't pollute the test environment, which is more in line with how + // travis runs the tests. + if (process.env.NODE_ENV === 'test') { + return + } + const envPath = expandHomeDir(`${process.env.ARK_PATH_DATA}/.env`) if (fs.existsSync(envPath)) { const env = require('envfile').parseFileSync(envPath) - Object.keys(env).forEach(key => (process.env[key] = env[key])) + Object.keys(env).forEach(key => { + process.env[key] = env[key] + }) } } } diff --git a/packages/core-container/lib/registrars/plugin.js b/packages/core-container/lib/registrars/plugin.js index d52be3a1c8..48035f49a9 100644 --- a/packages/core-container/lib/registrars/plugin.js +++ b/packages/core-container/lib/registrars/plugin.js @@ -1,3 +1,5 @@ +/* eslint no-await-in-loop: "off" */ + const path = require('path') const fs = require('fs') const semver = require('semver') @@ -12,11 +14,11 @@ module.exports = class PluginRegistrars { * @param {Container} container * @param {Object} options */ - constructor (container, options = {}) { + constructor(container, options = {}) { this.container = container this.plugins = this.__loadPlugins() this.resolvedPlugins = [] - this.options = options + this.options = this.__castOptions(options) this.deregister = [] } @@ -24,29 +26,36 @@ module.exports = class PluginRegistrars { * Set up all available plugins. * @return {void} */ - resolveOptions (name) { + resolveOptions(name) { if (!this.resolvedPlugins.length) { - this.resolvedPlugins = Object - .keys(this.plugins) - .map(plugin => require(plugin).plugin) + this.resolvedPlugins = Object.keys(this.plugins).map( + item => require(item).plugin, + ) } - const plugin = Object.values(this.resolvedPlugins).find(plugin => { - return plugin.alias === name || plugin.pkg.name === name - }) + const plugin = Object.values(this.resolvedPlugins).find( + item => item.alias === name || item.pkg.name === name, + ) - return this.__applyToDefaults(plugin.pkg.name, plugin.defaults, this.plugins[plugin.pkg.name]) + return this.__applyToDefaults( + plugin.pkg.name, + plugin.defaults, + this.plugins[plugin.pkg.name], + ) } /** * Set up all available plugins. * @return {void} */ - async setUp () { + async setUp() { for (const [name, options] of Object.entries(this.plugins)) { await this.register(name, options) - if (this.options.exit && this.options.exit === name) { + if ( + (this.options.exit && this.options.exit === name) || + this.container.shuttingDown + ) { break } } @@ -56,7 +65,7 @@ module.exports = class PluginRegistrars { * Deregister all plugins. * @return {void} */ - async tearDown () { + async tearDown() { const plugins = this.deregister.reverse() for (let i = 0; i < plugins.length; i++) { @@ -70,7 +79,7 @@ module.exports = class PluginRegistrars { * @param {Object} options * @return {void} */ - async register (name, options = {}) { + async register(name, options = {}) { if (!this.__shouldBeRegistered(name)) { return } @@ -88,28 +97,42 @@ module.exports = class PluginRegistrars { * @param {Object} options * @return {void} */ - async __registerWithContainer (plugin, options = {}) { + async __registerWithContainer(plugin, options = {}) { const item = this.__resolve(plugin) if (!item.plugin.register) { return } + if (item.plugin.extends) { + await this.__registerWithContainer(item.plugin.extends) + } + const name = item.plugin.name || item.plugin.pkg.name const version = item.plugin.version || item.plugin.pkg.version const defaults = item.plugin.defaults || item.plugin.pkg.defaults const alias = item.plugin.alias || item.plugin.pkg.alias if (!semver.valid(version)) { - throw new Error(`The plugin "${name}" provided an invalid version "${version}". Please check https://semver.org/ and make sure you follow the spec.`) + throw new Error( + `The plugin "${name}" provided an invalid version "${version}". Please check https://semver.org/ and make sure you follow the spec.`, + ) } options = this.__applyToDefaults(name, defaults, options) plugin = await item.plugin.register(this.container, options || {}) - this.container.register(alias || name, asValue({ name, version, plugin, options })) - - if (item.plugin.hasOwnProperty('deregister')) { + this.container.register( + alias || name, + asValue({ + name, + version, + plugin, + options, + }), + ) + + if (item.plugin.deregister) { this.deregister.push({ plugin: item.plugin, options }) } } @@ -122,15 +145,36 @@ module.exports = class PluginRegistrars { * @param {Object} options * @return {Object} */ - __applyToDefaults (name, defaults, options) { + __applyToDefaults(name, defaults, options) { if (defaults) { options = Hoek.applyToDefaults(defaults, options) } - if (this.options.options && this.options.options.hasOwnProperty(name)) { + if (this.options.options && this.options.options[name]) { options = Hoek.applyToDefaults(options, this.options.options[name]) } + return this.__castOptions(options) + } + + /** + * When the env is used to overwrite options, we get strings even if we + * expect a number. This is in most cases not desired and leads to side- + * effects. Here is assumed all numeric strings except blacklisted ones + * should be treated as numbers. + * @param {Object} options + * @return {Object} options + */ + __castOptions(options) { + const blacklist = [] + const regex = new RegExp(/^\d+$/) + Object.keys(options).forEach(key => { + const value = options[key] + if (isString(value) && !blacklist.includes(key) && regex.test(value)) { + options[key] = +value + } + }) + return options } @@ -139,12 +183,14 @@ module.exports = class PluginRegistrars { * @param {(String|Object)} plugin - plugin name or path, or object * @return {Object} */ - __resolve (plugin) { + __resolve(plugin) { let item = {} if (isString(plugin)) { if (plugin.startsWith('.')) { - plugin = path.resolve(`${path.dirname(this.pluginsConfigPath)}/${plugin}`) + plugin = path.resolve( + `${path.dirname(this.pluginsConfigPath)}/${plugin}`, + ) } else if (!plugin.startsWith('@')) { plugin = path.resolve(plugin) } @@ -152,7 +198,7 @@ module.exports = class PluginRegistrars { try { item = require(plugin) } catch (error) { - console.log(error) + console.error(error) } if (!item.plugin) { @@ -168,7 +214,7 @@ module.exports = class PluginRegistrars { * @param {String} name * @return {Boolean} */ - __shouldBeRegistered (name) { + __shouldBeRegistered(name) { let register = true if (this.options.include) { @@ -186,18 +232,24 @@ module.exports = class PluginRegistrars { * Load plugins from any of the available files (plugins.js or plugins.json). * @return {[Object|void]} */ - __loadPlugins () { - const available = ['plugins.js', 'plugins.json'] + __loadPlugins() { + const files = ['plugins.js', 'plugins.json'] + + for (const file of files) { + const configPath = path.resolve( + expandHomeDir(`${process.env.ARK_PATH_CONFIG}/${file}`), + ) - for (let i = 0; i < available.length; i++) { - const configPath = path.resolve(expandHomeDir(`${process.env.ARK_PATH_CONFIG}/${available[i]}`)) if (fs.existsSync(configPath)) { this.pluginsConfigPath = configPath + return require(configPath) } } - throw new Error('An invalid configuration was provided or is inaccessible due to it\'s security settings.') + throw new Error( + "An invalid configuration was provided or is inaccessible due to it's security settings.", + ) process.exit(1) // eslint-disable-line no-unreachable } } diff --git a/packages/core-container/lib/remote-loader.js b/packages/core-container/lib/remote-loader.js new file mode 100644 index 0000000000..f4e5896b75 --- /dev/null +++ b/packages/core-container/lib/remote-loader.js @@ -0,0 +1,112 @@ +const axios = require('axios') +const expandHomeDir = require('expand-home-dir') +const fs = require('fs-extra') +const path = require('path') +const { + models: { Block }, +} = require('@arkecosystem/crypto') +const { spawnSync } = require('child_process') + +module.exports = class RemoteLoader { + constructor(variables) { + this.remote = variables.remote + this.config = expandHomeDir(variables.config) + this.data = expandHomeDir(variables.data) + + fs.ensureDirSync(this.config) + } + + async setUp() { + const network = await this.__configureNetwork() + + await this.__configureGenesisBlock() + + await this.__configurePeers() + + await this.__configureDelegates() + + this.__configurePlugins(network) + + this.__configureDatabase(network) + } + + async __configureNetwork() { + const network = await this.__getConfig('network') + + this.__writeConfig('network', network) + + return network + } + + async __configureGenesisBlock() { + const genesisBlock = await this.__getConfig('genesis-block') + const genesisBlockModel = new Block(genesisBlock) + + if (!genesisBlockModel.verification.verified) { + console.error( + 'Failed to verify the genesis block. Try another remote host.', + ) + process.exit(1) + } + + this.__writeConfig('genesisBlock', genesisBlock) + } + + async __configurePeers() { + const peers = await this.__getConfig('peers') + + this.__writeConfig('peers', peers) + } + + async __configureDelegates() { + const delegates = await this.__getConfig('delegates') + + this.__writeConfig('delegates', delegates) + } + + __configurePlugins(network) { + const plugins = path.resolve( + __dirname, + `../../core/lib/config/${network.name}/plugins.js`, + ) + + fs.copySync(plugins, `${this.config}/plugins.js`) + } + + __configureDatabase(network) { + const command = spawnSync('createdb', [`ark_${network.name}`]) + + if (command.stderr.length > 0) { + console.error(command.stderr.toString()) + process.exit(1) + } + + console.info(command.stdout.toString()) + } + + async __getConfig(type) { + try { + const { data } = await axios.get(`http://${this.remote}/config/${type}`, { + headers: { 'Content-Type': 'application/json' }, + }) + + return data.data + } catch (error) { + if (!this.__exists(type)) { + console.error(error.message) + process.exit(1) + } + } + } + + __writeConfig(file, data) { + fs.writeFileSync( + `${this.config}/${file}.json`, + JSON.stringify(data, null, 4), + ) + } + + __exists(file) { + return fs.existsSync(`${this.config}/${file}.json`) + } +} diff --git a/packages/core-container/package.json b/packages/core-container/package.json index b4526440ff..27ad09bafc 100644 --- a/packages/core-container/package.json +++ b/packages/core-container/package.json @@ -1,33 +1,41 @@ { "name": "@arkecosystem/core-container", - "description": "Container for ARK Core", - "version": "0.1.1", + "description": "Container for Ark Core", + "version": "0.2.0", "contributors": [ "Brian Faust " ], "license": "MIT", "main": "lib/index.js", "scripts": { - "build:docs": "../../node_modules/.bin/jsdoc -c jsdoc.json", "test": "cross-env ARK_ENV=test jest --runInBand --detectOpenHandles", - "test:coverage": "cross-env ARK_ENV=test jest --coverage --runInBand --detectOpenHandles", - "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand --watch", + "test:coverage": "cross-env ARK_ENV=test jest --coverage --coveragePathIgnorePatterns='/(defaults.js|index.js)$' --runInBand --detectOpenHandles", + "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand", "test:watch": "cross-env ARK_ENV=test jest --runInBand --watch", "test:watch:all": "cross-env ARK_ENV=test jest --runInBand --watchAll", "lint": "eslint ./ --fix", - "depcheck": "depcheck ./" + "depcheck": "depcheck ./ --ignores=lodash,lodash.*" }, "dependencies": { - "@arkecosystem/crypto": "^0.1.1", - "awilix": "^3.0.8", + "@arkecosystem/crypto": "~0.2", + "awilix": "^4.0.1", + "axios": "^0.18.0", + "delay": "^4.1.0", "envfile": "^2.3.0", "expand-home-dir": "^0.0.3", - "fs-extra": "^6.0.1", - "hoek": "^5.0.3", - "lodash": "^4.17.10", - "semver": "^5.5.0" + "fs-extra": "^7.0.1", + "hoek": "^6.1.1", + "lodash.isstring": "^4.0.1", + "semver": "^5.6.0" + }, + "devDependencies": { + "axios-mock-adapter": "^1.15.0", + "jest-mock-process": "^1.1.0" }, "publishConfig": { "access": "public" + }, + "engines": { + "node": ">=10.x" } } diff --git a/packages/client/.gitattributes b/packages/core-database-postgres/.gitattributes similarity index 100% rename from packages/client/.gitattributes rename to packages/core-database-postgres/.gitattributes diff --git a/packages/core-database-postgres/CHANGELOG.md b/packages/core-database-postgres/CHANGELOG.md new file mode 100644 index 0000000000..87348132a1 --- /dev/null +++ b/packages/core-database-postgres/CHANGELOG.md @@ -0,0 +1,46 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +## Unreleased + +## 0.2.0 - 2018-12-03 + +### Added + +- Database rollback + +### Changed + +- Build delegate list in-memory to reduce database load +- Perform vote balance calculations in-memory to reduce database load +- Handle numbers as `BigNumber` instances +- Reduced complexity and duplicated logic +- Improved performance of various SQL queries +- Improved performance of wallet saving +- Dropped node.js 9 as minimum requirement in favour of node.js 10 + +### Removed + +- All `redis` integrations and dependencies + +### Fixed + +- Wrong documentation +- Bad method calls for `sync/async` methods +- Cast rounds to integers +- Only commit data when `saveBlockCommit` is called +- Various bad method calls for expected query results +- Sorting of votes during SPV +- Added a missing index for the `block_id` column in the `transactions` table +- Moved the wallets integrity check after the wallet rebuild process to avoid false positive blockchain rebuilds +- Insert bignumber objects as strings to avoid rounding issues caused by `Number.MAX_SAFE_INTEGER` + +## 0.1.0 - 2018-09-11 + +### Added + +- initial release diff --git a/packages/client/LICENSE b/packages/core-database-postgres/LICENSE similarity index 100% rename from packages/client/LICENSE rename to packages/core-database-postgres/LICENSE diff --git a/packages/core-database-postgres/README.md b/packages/core-database-postgres/README.md new file mode 100644 index 0000000000..3ef5117887 --- /dev/null +++ b/packages/core-database-postgres/README.md @@ -0,0 +1,22 @@ +# Ark Core - Database - Postgres + +

+ +

+ +## Documentation + +You can find installation instructions and detailed instructions on how to use this package at the [dedicated documentation site](https://docs.ark.io/guidebook/core/plugins/core-database-postgres.html). + +## Security + +If you discover a security vulnerability within this package, please send an e-mail to security@ark.io. All security vulnerabilities will be promptly addressed. + +## Credits + +- [Brian Faust](https://github.com/faustbrian) +- [All Contributors](../../../../contributors) + +## License + +[MIT](LICENSE) © [ArkEcosystem](https://ark.io) diff --git a/packages/core-database-postgres/__tests__/.gitkeep b/packages/core-database-postgres/__tests__/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/core-database-postgres/jest.config.js b/packages/core-database-postgres/jest.config.js new file mode 100644 index 0000000000..57770a97bb --- /dev/null +++ b/packages/core-database-postgres/jest.config.js @@ -0,0 +1,12 @@ +module.exports = { + testEnvironment: 'node', + bail: false, + verbose: true, + testMatch: ['**/__tests__/**/*.test.js'], + moduleFileExtensions: ['js', 'json'], + collectCoverage: false, + coverageDirectory: '/.coverage', + collectCoverageFrom: ['lib/**/*.js', '!**/node_modules/**'], + watchman: false, + setupTestFrameworkScriptFile: 'jest-extended', +} diff --git a/packages/validation/jsdoc.json b/packages/core-database-postgres/jsdoc.json similarity index 90% rename from packages/validation/jsdoc.json rename to packages/core-database-postgres/jsdoc.json index 23276f74ea..f3ea8aab33 100644 --- a/packages/validation/jsdoc.json +++ b/packages/core-database-postgres/jsdoc.json @@ -7,9 +7,7 @@ "includePattern": ".js$", "excludePattern": "(node_modules/|docs)" }, - "plugins": [ - "plugins/markdown" - ], + "plugins": ["plugins/markdown"], "opts": { "template": "../../node_modules/docdash", "encoding": "utf8", diff --git a/packages/core-database-postgres/lib/connection.js b/packages/core-database-postgres/lib/connection.js new file mode 100644 index 0000000000..d20d86e4e1 --- /dev/null +++ b/packages/core-database-postgres/lib/connection.js @@ -0,0 +1,718 @@ +/* eslint no-await-in-loop: "off" */ +/* eslint no-use-before-define: "warn" */ +/* eslint max-len: "off" */ + +const pgPromise = require('pg-promise') +const crypto = require('crypto') +const chunk = require('lodash/chunk') +const pluralize = require('pluralize') +const fs = require('fs') + +const { ConnectionInterface } = require('@arkecosystem/core-database') + +const app = require('@arkecosystem/core-container') + +const config = app.resolvePlugin('config') +const logger = app.resolvePlugin('logger') +const emitter = app.resolvePlugin('event-emitter') + +const { roundCalculator } = require('@arkecosystem/core-utils') + +const { + Bignum, + models: { Block, Transaction }, +} = require('@arkecosystem/crypto') + +const SPV = require('./spv') + +const migrations = require('./migrations') +const QueryExecutor = require('./sql/query-executor') +const repositories = require('./repositories') +const { camelizeColumns } = require('./utils') + +module.exports = class PostgresConnection extends ConnectionInterface { + /** + * Make the database connection instance. + * @return {PostgresConnection} + */ + async make() { + if (this.db) { + throw new Error('Database connection already initialised') + } + + logger.debug('Connecting to database') + + this.queuedQueries = null + this.cache = new Map() + + try { + await this.connect() + await this.__registerQueryExecutor() + await this.__runMigrations() + await this.__registerModels() + await super._registerRepositories() + await super._registerWalletManager() + + this.blocksInCurrentRound = await this.__getBlocksForRound() + + return this + } catch (error) { + app.forceExit('Unable to connect to the database!', error) + } + } + + /** + * Connect to the database. + * @return {void} + */ + async connect() { + const initialization = { + receive(data, result, e) { + camelizeColumns(pgp, data) + }, + extend(object) { + for (const repository of Object.keys(repositories)) { + object[repository] = new repositories[repository](object, pgp) + } + }, + } + + const pgp = pgPromise({ ...this.config.initialization, ...initialization }) + + this.pgp = pgp + this.db = this.pgp(this.config.connection) + } + + /** + * Disconnects from the database and closes the cache. + * @return {Promise} The successfulness of closing the Sequelize connection + */ + async disconnect() { + try { + await this.commitQueuedQueries() + this.cache.clear() + } catch (error) { + logger.warn('Issue in commiting blocks, database might be corrupted') + logger.warn(error.message) + } + + logger.debug('Disconnecting from database') + + return this.pgp.end() + } + + /** + * Verify the blockchain stored on db is not corrupted making simple assertions: + * - Last block is available + * - Last block height equals the number of stored blocks + * - Number of stored transactions equals the sum of block.numberOfTransactions in the database + * - Sum of all tx fees equals the sum of block.totalFee + * - Sum of all tx amount equals the sum of block.totalAmount + * @return {Object} An object { valid, errors } with the result of the verification and the errors + */ + async verifyBlockchain() { + const errors = [] + + const lastBlock = await this.getLastBlock() + + // Last block is available + if (!lastBlock) { + errors.push('Last block is not available') + } else { + const { count: numberOfBlocks } = await this.db.blocks.count() + + // Last block height equals the number of stored blocks + if (lastBlock.data.height !== +numberOfBlocks) { + errors.push( + `Last block height: ${lastBlock.data.height.toLocaleString()}, number of stored blocks: ${numberOfBlocks}`, + ) + } + } + + const blockStats = await this.db.blocks.statistics() + const transactionStats = await this.db.transactions.statistics() + + // Number of stored transactions equals the sum of block.numberOfTransactions in the database + if (blockStats.numberOfTransactions !== transactionStats.count) { + errors.push( + `Number of transactions: ${ + transactionStats.count + }, number of transactions included in blocks: ${ + blockStats.numberOfTransactions + }`, + ) + } + + // Sum of all tx fees equals the sum of block.totalFee + if (blockStats.totalFee !== transactionStats.totalFee) { + errors.push( + `Total transaction fees: ${ + transactionStats.totalFee + }, total of block.totalFee : ${blockStats.totalFee}`, + ) + } + + // Sum of all tx amount equals the sum of block.totalAmount + if (blockStats.totalAmount !== transactionStats.totalAmount) { + errors.push( + `Total transaction amounts: ${ + transactionStats.totalAmount + }, total of block.totalAmount : ${blockStats.totalAmount}`, + ) + } + + return { + valid: !errors.length, + errors, + } + } + + /** + * Get the top 51 delegates. + * @param {Number} height + * @param {Array} delegates + * @return {Array} + */ + async getActiveDelegates(height, delegates) { + const maxDelegates = config.getConstants(height).activeDelegates + const round = Math.floor((height - 1) / maxDelegates) + 1 + + if ( + this.forgingDelegates && + this.forgingDelegates.length && + this.forgingDelegates[0].round === round + ) { + return this.forgingDelegates + } + + // When called during applyRound we already know the delegates, so we don't have to query the database. + if (!delegates || delegates.length === 0) { + delegates = await this.db.rounds.findById(round) + } + + const seedSource = round.toString() + let currentSeed = crypto + .createHash('sha256') + .update(seedSource, 'utf8') + .digest() + + for (let i = 0, delCount = delegates.length; i < delCount; i++) { + for (let x = 0; x < 4 && i < delCount; i++, x++) { + const newIndex = currentSeed[x] % delCount + const b = delegates[newIndex] + delegates[newIndex] = delegates[i] + delegates[i] = b + } + currentSeed = crypto + .createHash('sha256') + .update(currentSeed) + .digest() + } + + this.forgingDelegates = delegates.map(delegate => { + delegate.round = +delegate.round + return delegate + }) + + return this.forgingDelegates + } + + /** + * Store the given round. + * @param {Array} delegates + * @return {Array} + */ + async saveRound(delegates) { + logger.info(`Saving round ${delegates[0].round.toLocaleString()}`) + + await this.db.rounds.create(delegates) + + emitter.emit('round.created', delegates) + } + + /** + * Delete the given round. + * @param {Number} round + * @return {Promise} + */ + async deleteRound(round) { + return this.db.rounds.delete(round) + } + + /** + * Load a list of wallets into memory. + * @param {Number} height + * @return {Boolean} success + */ + async buildWallets(height) { + this.walletManager.reset() + + const spvPath = `${process.env.ARK_PATH_DATA}/spv.json` + + if (fs.existsSync(spvPath)) { + fs.removeSync(spvPath) + + logger.info( + 'Ark Core ended unexpectedly - resuming from where we left off :runner:', + ) + + return true + } + + try { + const spv = new SPV(this) + const success = await spv.build(height) + + this._spvFinished = true + + await this.__registerListeners() + + return success + } catch (error) { + logger.error(error.stack) + } + } + + /** + * Load all wallets from database. + * @return {Array} + */ + async loadWallets() { + const wallets = await this.db.wallets.all() + + this.walletManager.index(wallets) + + return this.walletManager.all() + } + + /** + * Commit wallets from the memory. + * @param {Boolean} force + * @return {void} + */ + async saveWallets(force) { + const wallets = this.walletManager + .allByPublicKey() + .filter(wallet => wallet.publicKey && (force || wallet.dirty)) + + // Remove dirty flags first to not save all dirty wallets in the exit handler + // when called during a force insert right after SPV. + this.walletManager.clear() + + if (force) { + // all wallets to be updated, performance is better without upsert + await this.db.wallets.truncate() + + try { + const chunks = chunk(wallets, 5000).map(c => this.db.wallets.create(c)) + await this.db.tx(t => t.batch(chunks)) + } catch (error) { + logger.error(error.stack) + } + } else { + // NOTE: The list of delegates is calculated in-memory against the WalletManager, + // so it is safe to perform the costly UPSERT non-blocking during round change only: + // 'await saveWallets(false)' -> 'saveWallets(false)' + try { + const queries = wallets.map(wallet => + this.db.wallets.updateOrCreate(wallet), + ) + await this.db.tx(t => t.batch(queries)) + } catch (error) { + logger.error(error.stack) + } + } + + logger.info( + `${wallets.length} modified ${pluralize( + 'wallet', + wallets.length, + )} committed to database`, + ) + + emitter.emit('wallet.saved', wallets.length) + + // NOTE: commented out as more use cases to be taken care of + // this.walletManager.purgeEmptyNonDelegates() + } + + /** + * Commit the given block. + * NOTE: to be used when node is in sync and committing newly received blocks + * @param {Block} block + * @return {void} + */ + async saveBlock(block) { + try { + const queries = [this.db.blocks.create(block.data)] + + if (block.transactions.length > 0) { + queries.push(this.db.transactions.create(block.transactions)) + } + + await this.db.tx(t => t.batch(queries)) + } catch (err) { + logger.error(err.message) + } + } + + /** + * Delete the given block. + * @param {Block} block + * @return {void} + */ + async deleteBlock(block) { + try { + const queries = [ + this.db.transactions.deleteByBlock(block.data.id), + this.db.blocks.delete(block.data.id), + ] + + await this.db.tx(t => t.batch(queries)) + } catch (error) { + logger.error(error.stack) + + throw error + } + } + + /** + * Stores the block in memory. Generated insert statements are stored in this.queuedQueries, to be later saved to the database by calling commit. + * NOTE: to use when rebuilding to decrease the number of database tx, and commit blocks (save only every 1000s for instance) by calling commit. + * @param {Block} block + * @return {void} + */ + enqueueSaveBlock(block) { + const queries = [this.db.blocks.create(block.data)] + + if (block.transactions.length > 0) { + queries.push(this.db.transactions.create(block.transactions)) + } + + this.enqueueQueries(queries) + } + + /** + * Generated delete statements are stored in this.queuedQueries to be later executed by calling this.commitQueuedQueries. + * See also enqueueSaveBlock. + * @param {Block} block + * @return {void} + */ + enqueueDeleteBlock(block) { + const queries = [ + this.db.transactions.deleteByBlock(block.data.id), + this.db.blocks.delete(block.data.id), + ] + + this.enqueueQueries(queries) + } + + /** + * Generated delete statements are stored in this.queuedQueries to be later executed by calling this.commitQueuedQueries. + * @param {Number} round + * @return {void} + */ + enqueueDeleteRound(height) { + const { round, nextRound, maxDelegates } = roundCalculator.calculateRound( + height, + ) + + if (nextRound === round + 1 && height >= maxDelegates) { + this.enqueueQueries([this.db.rounds.delete(nextRound)]) + } + } + + /** + * Add queries to the queue to be executed when calling commit. + * @param {Array} queries + */ + enqueueQueries(queries) { + if (!this.queuedQueries) { + this.queuedQueries = [] + } + + this.queuedQueries.push(...queries) + } + + /** + * Commit all queued queries. + * NOTE: to be used in combination with enqueueSaveBlock and enqueueDeleteBlock. + * @return {void} + */ + async commitQueuedQueries() { + if (!this.queuedQueries || this.queuedQueries.length === 0) { + return + } + + logger.debug('Committing database transactions.') + + try { + await this.db.tx(t => t.batch(this.queuedQueries)) + } catch (error) { + logger.error(error) + + throw error + } finally { + this.queuedQueries = null + } + } + + /** + * Get a block. + * @param {Number} id + * @return {Block} + */ + async getBlock(id) { + // TODO: caching the last 1000 blocks, in combination with `saveBlock` could help to optimise + const block = await this.db.blocks.findById(id) + + if (!block) { + return null + } + + const transactions = await this.db.transactions.findByBlock(block.id) + + block.transactions = transactions.map(({ serialized }) => + Transaction.deserialize(serialized.toString('hex')), + ) + + return new Block(block) + } + + /** + * Get the last block. + * @return {(Block|null)} + */ + async getLastBlock() { + const block = await this.db.blocks.latest() + + if (!block) { + return null + } + + const transactions = await this.db.transactions.latestByBlock(block.id) + + block.transactions = transactions.map(({ serialized }) => + Transaction.deserialize(serialized.toString('hex')), + ) + + return new Block(block) + } + + /** + * Get a transaction. + * @param {Number} id + * @return {Promise} + */ + async getTransaction(id) { + return this.db.transactions.findById(id) + } + + /** + * Get common blocks for the given IDs. + * @param {Array} ids + * @return {Array} + */ + async getCommonBlocks(ids) { + const state = app.resolve('state') + let commonBlocks = state.getCommonBlocks(ids) + if (commonBlocks.length < ids.length) { + commonBlocks = await this.db.blocks.common(ids) + } + + return commonBlocks + } + + /** + * Get transactions for the given IDs. + * @param {Array} ids + * @return {Array} + */ + async getTransactionsFromIds(ids) { + return this.db.transactions.findManyById(ids) + } + + /** + * Get forged transactions for the given IDs. + * @param {Array} ids + * @return {Array} + */ + async getForgedTransactionsIds(ids) { + if (!ids.length) { + return [] + } + + const transactions = await this.db.transactions.forged(ids) + + return transactions.map(transaction => transaction.id) + } + + /** + * Get blocks for the given offset and limit. + * @param {Number} offset + * @param {Number} limit + * @return {Array} + */ + async getBlocks(offset, limit) { + let blocks = [] + + if (app.has('state')) { + blocks = app + .resolve('state') + .getLastBlocksByHeight(offset, offset + limit) + } + + if (blocks.length !== limit) { + blocks = await this.db.blocks.heightRange(offset, offset + limit) + + await this.loadTransactionsForBlocks(blocks) + } + + return blocks + } + + /** + * Get top count blocks ordered by height DESC. + * NOTE: Only used when trying to restore database integrity. The returned blocks may be unchained. + * @param {Number} count + * @return {Array} + */ + async getTopBlocks(count) { + const blocks = await this.db.blocks.top(count) + + await this.loadTransactionsForBlocks(blocks) + + return blocks + } + + /** + * Load all transactions for the given blocks + * @param {Array} blocks + * @return {void} + */ + async loadTransactionsForBlocks(blocks) { + if (!blocks.length) { + return + } + + const ids = blocks.map(block => block.id) + + let transactions = await this.db.transactions.latestByBlocks(ids) + transactions = transactions.map(tx => { + const data = Transaction.deserialize(tx.serialized.toString('hex')) + data.blockId = tx.blockId + return data + }) + + for (const block of blocks) { + if (block.numberOfTransactions > 0) { + block.transactions = transactions.filter( + transaction => transaction.blockId === block.id, + ) + } + } + } + + /** + * Get the 10 recent block ids. + * @return {[]String} + */ + async getRecentBlockIds() { + const state = app.resolve('state') + let blocks = state + .getLastBlockIds() + .reverse() + .slice(0, 10) + + if (blocks.length < 10) { + blocks = await this.db.blocks.recent() + blocks = blocks.map(block => block.id) + } + + return blocks + } + + /** + * Get the headers of blocks for the given offset and limit. + * @param {Number} offset + * @param {Number} limit + * @return {Array} + */ + async getBlockHeaders(offset, limit) { + const blocks = await this.db.blocks.headers(offset, offset + limit) + + return blocks.map(block => Block.serialize(block)) + } + + /** + * Get the cache object + * @return {Cache} + */ + getCache() { + return this.cache + } + + /** + * Run all migrations. + * @return {void} + */ + async __runMigrations() { + for (const migration of migrations) { + await this.query.none(migration) + } + } + + /** + * Register all models. + * @return {void} + */ + async __registerModels() { + this.models = {} + + for (const [key, Value] of Object.entries(require('./models'))) { + this.models[key.toLowerCase()] = new Value(this.pgp) + } + } + + /** + * Register the query builder. + * @return {void} + */ + __registerQueryExecutor() { + this.query = new QueryExecutor(this) + } + + /** + * Register event listeners. + * @return {void} + */ + __registerListeners() { + super.__registerListeners() + + emitter.on('wallet.created.cold', async coldWallet => { + try { + const wallet = await this.db.wallets.findByAddress(coldWallet.address) + + if (wallet) { + Object.keys(wallet).forEach(key => { + if (['balance'].indexOf(key) !== -1) { + return + } + + coldWallet[key] = + key !== 'voteBalance' ? wallet[key] : new Bignum(wallet[key]) + }) + } + } catch (err) { + logger.error(err) + } + }) + + emitter.once('shutdown', async () => { + if (!this._spvFinished) { + // Prevent dirty wallets to be saved when SPV didn't finish + this.walletManager.clear() + } + }) + } +} diff --git a/packages/core-database-postgres/lib/defaults.js b/packages/core-database-postgres/lib/defaults.js new file mode 100644 index 0000000000..b6e0e4b74e --- /dev/null +++ b/packages/core-database-postgres/lib/defaults.js @@ -0,0 +1,15 @@ +module.exports = { + initialization: { + capSQL: true, + promiseLib: require('bluebird'), + noLocking: process.env.NODE_ENV === 'test', + }, + connection: { + host: process.env.ARK_DB_HOST || 'localhost', + port: process.env.ARK_DB_PORT || 5432, + database: + process.env.ARK_DB_DATABASE || `ark_${process.env.ARK_NETWORK_NAME}`, + user: process.env.ARK_DB_USERNAME || 'ark', + password: process.env.ARK_DB_PASSWORD || 'password', + }, +} diff --git a/packages/core-database-sequelize/lib/index.js b/packages/core-database-postgres/lib/index.js similarity index 56% rename from packages/core-database-sequelize/lib/index.js rename to packages/core-database-postgres/lib/index.js index 2567115735..6b128c71e4 100644 --- a/packages/core-database-sequelize/lib/index.js +++ b/packages/core-database-postgres/lib/index.js @@ -1,6 +1,4 @@ -'use strict' - -const SequelizeConnection = require('./connection') +const PostgresConnection = require('./connection') /** * The struct used by the plugin container. @@ -10,19 +8,26 @@ exports.plugin = { pkg: require('../package.json'), defaults: require('./defaults'), alias: 'database', - async register (container, options) { + extends: '@arkecosystem/core-database', + async register(container, options) { container.resolvePlugin('logger').info('Establishing Database Connection') - const sequelize = new SequelizeConnection(options) + const postgres = new PostgresConnection(options) const databaseManager = container.resolvePlugin('databaseManager') - await databaseManager.makeConnection(sequelize) + await databaseManager.makeConnection(postgres) return databaseManager.connection() }, - async deregister (container, options) { + async deregister(container, options) { container.resolvePlugin('logger').info('Closing Database Connection') return container.resolvePlugin('database').disconnect() - } + }, } + +/** + * The files required to migrate the database. + * @type {Array} + */ +exports.migrations = require('./migrations') diff --git a/packages/core-database-postgres/lib/migrations/20180305100000-create-wallets-table.sql b/packages/core-database-postgres/lib/migrations/20180305100000-create-wallets-table.sql new file mode 100644 index 0000000000..4e1082abaf --- /dev/null +++ b/packages/core-database-postgres/lib/migrations/20180305100000-create-wallets-table.sql @@ -0,0 +1,15 @@ +-- Table Definition +CREATE TABLE IF NOT EXISTS ${schema~}.wallets ( + "address" VARCHAR(36) PRIMARY KEY NOT NULL, + "public_key" VARCHAR(66) UNIQUE NOT NULL, + "second_public_key" VARCHAR(66) UNIQUE, + "vote" VARCHAR(66), + "username" VARCHAR(64) UNIQUE, + "balance" BIGINT NOT NULL, + "vote_balance" BIGINT NOT NULL, + "produced_blocks" BIGINT NOT NULL, + "missed_blocks" BIGINT NOT NULL +); + +-- Constraints +CREATE UNIQUE INDEX IF NOT EXISTS "wallets_votes_unique" ON wallets ("public_key", "vote"); diff --git a/packages/core-database-postgres/lib/migrations/20180305200000-create-rounds-table.sql b/packages/core-database-postgres/lib/migrations/20180305200000-create-rounds-table.sql new file mode 100644 index 0000000000..3cfdb8b990 --- /dev/null +++ b/packages/core-database-postgres/lib/migrations/20180305200000-create-rounds-table.sql @@ -0,0 +1,10 @@ +-- Table Definition +CREATE TABLE IF NOT EXISTS ${schema~}.rounds ( + "id" SERIAL PRIMARY KEY, + "public_key" VARCHAR(66) NOT NULL, + "balance" BIGINT NOT NULL, + "round" BIGINT NOT NULL +); + +-- Constraints +CREATE UNIQUE INDEX IF NOT EXISTS "rounds_unique" ON rounds ("round", "public_key"); diff --git a/packages/core-database-postgres/lib/migrations/20180305300000-create-blocks-table.sql b/packages/core-database-postgres/lib/migrations/20180305300000-create-blocks-table.sql new file mode 100644 index 0000000000..86c32105d6 --- /dev/null +++ b/packages/core-database-postgres/lib/migrations/20180305300000-create-blocks-table.sql @@ -0,0 +1,19 @@ +-- Table Definition +CREATE TABLE IF NOT EXISTS ${schema~}.blocks ( + "id" VARCHAR(64) PRIMARY KEY, + "version" SMALLINT NOT NULL, + "timestamp" INTEGER UNIQUE NOT NULL, + "previous_block" VARCHAR(64) UNIQUE, + "height" INTEGER UNIQUE NOT NULL, + "number_of_transactions" INTEGER NOT NULL, + "total_amount" BIGINT NOT NULL, + "total_fee" BIGINT NOT NULL, + "reward" BIGINT NOT NULL, + "payload_length" INTEGER NOT NULL, + "payload_hash" VARCHAR(64) NOT NULL, + "generator_public_key" VARCHAR(66) NOT NULL, + "block_signature" VARCHAR(256) NOT NULL +); + +-- Constraints +CREATE UNIQUE INDEX IF NOT EXISTS "blocks_unique" ON blocks ("height", "generator_public_key"); diff --git a/packages/core-database-postgres/lib/migrations/20180305400000-create-transactions-table.sql b/packages/core-database-postgres/lib/migrations/20180305400000-create-transactions-table.sql new file mode 100644 index 0000000000..2697bfb91c --- /dev/null +++ b/packages/core-database-postgres/lib/migrations/20180305400000-create-transactions-table.sql @@ -0,0 +1,18 @@ +-- Table Definition +CREATE TABLE IF NOT EXISTS ${schema~}.transactions ( + "id" VARCHAR(64) PRIMARY KEY, + "version" SMALLINT NOT NULL, + "block_id" VARCHAR(64) NOT NULL, + "sequence" SMALLINT NOT NULL, + "timestamp" INTEGER NOT NULL, + "sender_public_key" VARCHAR(66) NOT NULL, + "recipient_id" VARCHAR(36), + "type" SMALLINT NOT NULL, + "vendor_field_hex" bytea, + "amount" BIGINT NOT NULL, + "fee" BIGINT NOT NULL, + "serialized" bytea NOT NULL +); + +-- Constraints +CREATE INDEX IF NOT EXISTS "transactions_unique" ON transactions ("sender_public_key", "recipient_id", "vendor_field_hex", "timestamp"); diff --git a/packages/core-database-postgres/lib/migrations/20181129400000-add-block_id-index-to-transactions-table.sql b/packages/core-database-postgres/lib/migrations/20181129400000-add-block_id-index-to-transactions-table.sql new file mode 100644 index 0000000000..0300b968a1 --- /dev/null +++ b/packages/core-database-postgres/lib/migrations/20181129400000-add-block_id-index-to-transactions-table.sql @@ -0,0 +1,2 @@ +-- Constraints +CREATE INDEX IF NOT EXISTS "transactions_block_id" ON transactions ("block_id"); diff --git a/packages/core-database-postgres/lib/migrations/index.js b/packages/core-database-postgres/lib/migrations/index.js new file mode 100644 index 0000000000..73479ba42d --- /dev/null +++ b/packages/core-database-postgres/lib/migrations/index.js @@ -0,0 +1,9 @@ +const { loadQueryFile } = require('../utils') + +module.exports = [ + loadQueryFile(__dirname, './20180305100000-create-wallets-table.sql'), + loadQueryFile(__dirname, './20180305200000-create-rounds-table.sql'), + loadQueryFile(__dirname, './20180305300000-create-blocks-table.sql'), + loadQueryFile(__dirname, './20180305400000-create-transactions-table.sql'), + loadQueryFile(__dirname, './20181129400000-add-block_id-index-to-transactions-table.sql'), +] diff --git a/packages/core-database-postgres/lib/models/block.js b/packages/core-database-postgres/lib/models/block.js new file mode 100644 index 0000000000..979f5ea1ad --- /dev/null +++ b/packages/core-database-postgres/lib/models/block.js @@ -0,0 +1,72 @@ +const { bignumify } = require('@arkecosystem/core-utils') +const Model = require('./model') + +module.exports = class Block extends Model { + /** + * The table associated with the model. + * @return {String} + */ + getTable() { + return 'blocks' + } + + /** + * The read-only structure with query-formatting columns. + * @return {Object} + */ + getColumnSet() { + return this.createColumnSet([ + { + name: 'id', + }, + { + name: 'version', + }, + { + name: 'timestamp', + }, + { + name: 'previous_block', + prop: 'previousBlock', + def: null, + }, + { + name: 'height', + }, + { + name: 'number_of_transactions', + prop: 'numberOfTransactions', + }, + { + name: 'total_amount', + prop: 'totalAmount', + init: col => bignumify(col.value).toFixed(), + }, + { + name: 'total_fee', + prop: 'totalFee', + init: col => bignumify(col.value).toFixed(), + }, + { + name: 'reward', + init: col => bignumify(col.value).toFixed(), + }, + { + name: 'payload_length', + prop: 'payloadLength', + }, + { + name: 'payload_hash', + prop: 'payloadHash', + }, + { + name: 'generator_public_key', + prop: 'generatorPublicKey', + }, + { + name: 'block_signature', + prop: 'blockSignature', + }, + ]) + } +} diff --git a/packages/core-database-postgres/lib/models/index.js b/packages/core-database-postgres/lib/models/index.js new file mode 100644 index 0000000000..b00c00cc7f --- /dev/null +++ b/packages/core-database-postgres/lib/models/index.js @@ -0,0 +1,6 @@ +module.exports = { + Block: require('./block'), + Round: require('./round'), + Transaction: require('./transaction'), + Wallet: require('./wallet'), +} diff --git a/packages/core-database-postgres/lib/models/model.js b/packages/core-database-postgres/lib/models/model.js new file mode 100644 index 0000000000..718ee30a9d --- /dev/null +++ b/packages/core-database-postgres/lib/models/model.js @@ -0,0 +1,55 @@ +const sql = require('sql') + +module.exports = class Model { + /** + * Create a new model instance. + * @param {Object} pgp + */ + constructor(pgp) { + this.pgp = pgp + } + + /** + * Return the model & table definition. + * @return {Object} + */ + query() { + return sql.define({ + name: this.getTable(), + columns: this.getColumnSet().columns.map(column => ({ + name: column.name, + prop: column.prop || column.name, + })), + }) + } + + /** + * Convert the "camelCase" keys to "snake_case". + * @return {Object} + */ + transform(model) { + const mappings = Object.entries(this.getMappings()) + + const transformed = {} + + for (const [original, mapping] of mappings) { + transformed[mapping] = model[original] + } + + return transformed + } + + /** + * Convert the "camelCase" keys to "snake_case". + * @param {Array} v + * @return {ColumnSet} + */ + createColumnSet(columns) { + return new this.pgp.helpers.ColumnSet(columns, { + table: { + table: this.getTable(), + schema: 'public', + }, + }) + } +} diff --git a/packages/core-database-postgres/lib/models/round.js b/packages/core-database-postgres/lib/models/round.js new file mode 100644 index 0000000000..c572f4997f --- /dev/null +++ b/packages/core-database-postgres/lib/models/round.js @@ -0,0 +1,33 @@ +const { bignumify } = require('@arkecosystem/core-utils') +const Model = require('./model') + +module.exports = class Round extends Model { + /** + * The table associated with the model. + * @return {String} + */ + getTable() { + return 'rounds' + } + + /** + * The read-only structure with query-formatting columns. + * @return {Object} + */ + getColumnSet() { + return this.createColumnSet([ + { + name: 'public_key', + prop: 'publicKey', + }, + { + name: 'balance', + prop: 'voteBalance', + init: col => bignumify(col.value).toFixed(), + }, + { + name: 'round', + }, + ]) + } +} diff --git a/packages/core-database-postgres/lib/models/transaction.js b/packages/core-database-postgres/lib/models/transaction.js new file mode 100644 index 0000000000..98ab7f004a --- /dev/null +++ b/packages/core-database-postgres/lib/models/transaction.js @@ -0,0 +1,64 @@ +const { bignumify } = require('@arkecosystem/core-utils') +const Model = require('./model') + +module.exports = class Transaction extends Model { + /** + * The table associated with the model. + * @return {String} + */ + getTable() { + return 'transactions' + } + + /** + * The read-only structure with query-formatting columns. + * @return {Object} + */ + getColumnSet() { + return this.createColumnSet([ + { + name: 'id', + }, + { + name: 'version', + }, + { + name: 'block_id', + prop: 'blockId', + }, + { + name: 'sequence', + }, + { + name: 'timestamp', + }, + { + name: 'sender_public_key', + prop: 'senderPublicKey', + }, + { + name: 'recipient_id', + prop: 'recipientId', + }, + { + name: 'type', + }, + { + name: 'vendor_field_hex', + prop: 'vendorFieldHex', + }, + { + name: 'amount', + init: col => bignumify(col.value).toFixed(), + }, + { + name: 'fee', + init: col => bignumify(col.value).toFixed(), + }, + { + name: 'serialized', + init: col => Buffer.from(col.value, 'hex'), + }, + ]) + } +} diff --git a/packages/core-database-postgres/lib/models/wallet.js b/packages/core-database-postgres/lib/models/wallet.js new file mode 100644 index 0000000000..72bd3faa51 --- /dev/null +++ b/packages/core-database-postgres/lib/models/wallet.js @@ -0,0 +1,55 @@ +const { bignumify } = require('@arkecosystem/core-utils') +const Model = require('./model') + +module.exports = class WalletModel extends Model { + /** + * The table associated with the model. + * @return {String} + */ + getTable() { + return 'wallets' + } + + /** + * The read-only structure with query-formatting columns. + * @return {Object} + */ + getColumnSet() { + return this.createColumnSet([ + { + name: 'address', + }, + { + name: 'public_key', + prop: 'publicKey', + }, + { + name: 'second_public_key', + prop: 'secondPublicKey', + }, + { + name: 'vote', + }, + { + name: 'username', + }, + { + name: 'balance', + init: col => bignumify(col.value).toFixed(), + }, + { + name: 'vote_balance', + prop: 'voteBalance', + init: col => (col.value ? bignumify(col.value).toFixed() : null), + }, + { + name: 'produced_blocks', + prop: 'producedBlocks', + }, + { + name: 'missed_blocks', + prop: 'missedBlocks', + }, + ]) + } +} diff --git a/packages/core-database-postgres/lib/queries/blocks/common.sql b/packages/core-database-postgres/lib/queries/blocks/common.sql new file mode 100644 index 0000000000..eab4fce7c8 --- /dev/null +++ b/packages/core-database-postgres/lib/queries/blocks/common.sql @@ -0,0 +1,8 @@ +SELECT MAX("height") AS "height", + "id", + "previous_block", + "timestamp" +FROM blocks +WHERE "id" IN (${ids:list}) +GROUP BY "id" +ORDER BY "height" DESC diff --git a/packages/core-database-postgres/lib/queries/blocks/count.sql b/packages/core-database-postgres/lib/queries/blocks/count.sql new file mode 100644 index 0000000000..f32d46a236 --- /dev/null +++ b/packages/core-database-postgres/lib/queries/blocks/count.sql @@ -0,0 +1,2 @@ +SELECT COUNT (DISTINCT "height") AS "count" +FROM blocks diff --git a/packages/core-database-postgres/lib/queries/blocks/delete.sql b/packages/core-database-postgres/lib/queries/blocks/delete.sql new file mode 100644 index 0000000000..23559f3602 --- /dev/null +++ b/packages/core-database-postgres/lib/queries/blocks/delete.sql @@ -0,0 +1,3 @@ +DELETE +FROM blocks +WHERE id = ${id} diff --git a/packages/core-database-postgres/lib/queries/blocks/find-by-id.sql b/packages/core-database-postgres/lib/queries/blocks/find-by-id.sql new file mode 100644 index 0000000000..2d58b1ad25 --- /dev/null +++ b/packages/core-database-postgres/lib/queries/blocks/find-by-id.sql @@ -0,0 +1,3 @@ +SELECT * +FROM blocks +WHERE id = ${id} diff --git a/packages/core-database-postgres/lib/queries/blocks/headers.sql b/packages/core-database-postgres/lib/queries/blocks/headers.sql new file mode 100644 index 0000000000..35206c04a3 --- /dev/null +++ b/packages/core-database-postgres/lib/queries/blocks/headers.sql @@ -0,0 +1,3 @@ +SELECT * +FROM blocks +WHERE height BETWEEN ${start} AND ${end} diff --git a/packages/core-database-postgres/lib/queries/blocks/height-range.sql b/packages/core-database-postgres/lib/queries/blocks/height-range.sql new file mode 100644 index 0000000000..f5a12786bf --- /dev/null +++ b/packages/core-database-postgres/lib/queries/blocks/height-range.sql @@ -0,0 +1,4 @@ +SELECT * +FROM blocks +WHERE height BETWEEN ${start} AND ${end} +ORDER BY height ASC diff --git a/packages/core-database-postgres/lib/queries/blocks/latest.sql b/packages/core-database-postgres/lib/queries/blocks/latest.sql new file mode 100644 index 0000000000..daa603cba0 --- /dev/null +++ b/packages/core-database-postgres/lib/queries/blocks/latest.sql @@ -0,0 +1,3 @@ +SELECT * +FROM blocks +ORDER BY height DESC LIMIT 1 diff --git a/packages/core-database-postgres/lib/queries/blocks/recent.sql b/packages/core-database-postgres/lib/queries/blocks/recent.sql new file mode 100644 index 0000000000..b2deb3ea85 --- /dev/null +++ b/packages/core-database-postgres/lib/queries/blocks/recent.sql @@ -0,0 +1,3 @@ +SELECT id +FROM blocks +ORDER BY TIMESTAMP DESC LIMIT 10 diff --git a/packages/core-database-postgres/lib/queries/blocks/statistics.sql b/packages/core-database-postgres/lib/queries/blocks/statistics.sql new file mode 100644 index 0000000000..f8fa7c2f0d --- /dev/null +++ b/packages/core-database-postgres/lib/queries/blocks/statistics.sql @@ -0,0 +1,5 @@ +SELECT SUM ("number_of_transactions") AS "numberOfTransactions", + SUM ("total_fee") AS "totalFee", + SUM ("total_amount") AS "totalAmount", + COUNT (DISTINCT "height") AS "count" +FROM blocks diff --git a/packages/core-database-postgres/lib/queries/blocks/top.sql b/packages/core-database-postgres/lib/queries/blocks/top.sql new file mode 100644 index 0000000000..3d36d50f6a --- /dev/null +++ b/packages/core-database-postgres/lib/queries/blocks/top.sql @@ -0,0 +1,3 @@ +SELECT * +FROM blocks +ORDER BY height DESC LIMIT ${top} diff --git a/packages/core-database-postgres/lib/queries/index.js b/packages/core-database-postgres/lib/queries/index.js new file mode 100644 index 0000000000..6a5b83cf1b --- /dev/null +++ b/packages/core-database-postgres/lib/queries/index.js @@ -0,0 +1,72 @@ +const { loadQueryFile } = require('../utils') + +module.exports = { + blocks: { + common: loadQueryFile(__dirname, './blocks/common.sql'), + count: loadQueryFile(__dirname, './blocks/count.sql'), + delete: loadQueryFile(__dirname, './blocks/delete.sql'), + findById: loadQueryFile(__dirname, './blocks/find-by-id.sql'), + headers: loadQueryFile(__dirname, './blocks/headers.sql'), + heightRange: loadQueryFile(__dirname, './blocks/height-range.sql'), + latest: loadQueryFile(__dirname, './blocks/latest.sql'), + recent: loadQueryFile(__dirname, './blocks/recent.sql'), + statistics: loadQueryFile(__dirname, './blocks/statistics.sql'), + top: loadQueryFile(__dirname, './blocks/top.sql'), + }, + rounds: { + delete: loadQueryFile(__dirname, './rounds/delete.sql'), + find: loadQueryFile(__dirname, './rounds/find.sql'), + }, + spv: { + blockRewards: loadQueryFile(__dirname, './spv/block-rewards.sql'), + delegates: loadQueryFile(__dirname, './spv/delegates.sql'), + delegatesForgedBlocks: loadQueryFile( + __dirname, + './spv/delegates-forged-blocks.sql', + ), + delegatesRanks: loadQueryFile(__dirname, './spv/delegates-ranks.sql'), + lastForgedBlocks: loadQueryFile(__dirname, './spv/last-forged-blocks.sql'), + multiSignatures: loadQueryFile(__dirname, './spv/multi-signatures.sql'), + receivedTransactions: loadQueryFile( + __dirname, + './spv/received-transactions.sql', + ), + secondSignatures: loadQueryFile(__dirname, './spv/second-signatures.sql'), + sentTransactions: loadQueryFile(__dirname, './spv/sent-transactions.sql'), + votes: loadQueryFile(__dirname, './spv/votes.sql'), + }, + transactions: { + findByBlock: loadQueryFile(__dirname, './transactions/find-by-block.sql'), + latestByBlock: loadQueryFile( + __dirname, + './transactions/latest-by-block.sql', + ), + latestByBlocks: loadQueryFile( + __dirname, + './transactions/latest-by-blocks.sql', + ), + statistics: loadQueryFile(__dirname, './transactions/statistics.sql'), + forged: loadQueryFile(__dirname, './transactions/forged.sql'), + findById: loadQueryFile(__dirname, './transactions/find-by-id.sql'), + findManyById: loadQueryFile( + __dirname, + './transactions/find-many-by-id.sql', + ), + deleteByBlock: loadQueryFile( + __dirname, + './transactions/delete-by-block.sql', + ), + }, + wallets: { + all: loadQueryFile(__dirname, './wallets/all.sql'), + findByAddress: loadQueryFile(__dirname, './wallets/find-by-address.sql'), + findNegativeBalances: loadQueryFile( + __dirname, + './wallets/find-negative-balances.sql', + ), + findNegativeVoteBalances: loadQueryFile( + __dirname, + './wallets/find-negative-vote-balances.sql', + ), + }, +} diff --git a/packages/core-database-postgres/lib/queries/rounds/delete.sql b/packages/core-database-postgres/lib/queries/rounds/delete.sql new file mode 100644 index 0000000000..ecce94e63d --- /dev/null +++ b/packages/core-database-postgres/lib/queries/rounds/delete.sql @@ -0,0 +1,3 @@ +DELETE +FROM rounds +WHERE round = ${round} diff --git a/packages/core-database-postgres/lib/queries/rounds/find.sql b/packages/core-database-postgres/lib/queries/rounds/find.sql new file mode 100644 index 0000000000..57d13ddf1c --- /dev/null +++ b/packages/core-database-postgres/lib/queries/rounds/find.sql @@ -0,0 +1,5 @@ +SELECT * +FROM rounds +WHERE round = ${round} +ORDER BY balance DESC, + public_key ASC diff --git a/packages/core-database-postgres/lib/queries/spv/block-rewards.sql b/packages/core-database-postgres/lib/queries/spv/block-rewards.sql new file mode 100644 index 0000000000..dbf2a3e452 --- /dev/null +++ b/packages/core-database-postgres/lib/queries/spv/block-rewards.sql @@ -0,0 +1,4 @@ +SELECT generator_public_key, + SUM ("reward"+"total_fee") AS "reward" +FROM blocks +GROUP BY "generator_public_key" diff --git a/packages/core-database-postgres/lib/queries/spv/delegates-forged-blocks.sql b/packages/core-database-postgres/lib/queries/spv/delegates-forged-blocks.sql new file mode 100644 index 0000000000..c871527058 --- /dev/null +++ b/packages/core-database-postgres/lib/queries/spv/delegates-forged-blocks.sql @@ -0,0 +1,6 @@ +SELECT generator_public_key, + SUM ("total_fee") AS "total_fees", + SUM ("reward") AS "total_rewards", + COUNT ("total_amount") AS "total_produced" +FROM blocks +GROUP BY "generator_public_key" diff --git a/packages/core-database-postgres/lib/queries/spv/delegates-ranks.sql b/packages/core-database-postgres/lib/queries/spv/delegates-ranks.sql new file mode 100644 index 0000000000..ea16718904 --- /dev/null +++ b/packages/core-database-postgres/lib/queries/spv/delegates-ranks.sql @@ -0,0 +1,7 @@ +SELECT public_key, + vote_balance, + missed_blocks +FROM wallets +WHERE username IS NOT NULL +ORDER BY vote_balance DESC, + public_key ASC diff --git a/packages/core-database-postgres/lib/queries/spv/delegates.sql b/packages/core-database-postgres/lib/queries/spv/delegates.sql new file mode 100644 index 0000000000..9ea51abd44 --- /dev/null +++ b/packages/core-database-postgres/lib/queries/spv/delegates.sql @@ -0,0 +1,4 @@ +SELECT sender_public_key, + serialized +FROM transactions +WHERE TYPE = 2 diff --git a/packages/core-database-postgres/lib/queries/spv/last-forged-blocks.sql b/packages/core-database-postgres/lib/queries/spv/last-forged-blocks.sql new file mode 100644 index 0000000000..b2fe36352b --- /dev/null +++ b/packages/core-database-postgres/lib/queries/spv/last-forged-blocks.sql @@ -0,0 +1,5 @@ +SELECT id, + generator_public_key, + TIMESTAMP +FROM blocks +ORDER BY TIMESTAMP DESC LIMIT ${limit} diff --git a/packages/core-database-postgres/lib/queries/spv/multi-signatures.sql b/packages/core-database-postgres/lib/queries/spv/multi-signatures.sql new file mode 100644 index 0000000000..ad6f6c03e1 --- /dev/null +++ b/packages/core-database-postgres/lib/queries/spv/multi-signatures.sql @@ -0,0 +1,5 @@ +SELECT sender_public_key, + serialized +FROM transactions +WHERE TYPE = 4 +ORDER BY (timestamp + sequence) DESC diff --git a/packages/core-database-postgres/lib/queries/spv/received-transactions.sql b/packages/core-database-postgres/lib/queries/spv/received-transactions.sql new file mode 100644 index 0000000000..128798d081 --- /dev/null +++ b/packages/core-database-postgres/lib/queries/spv/received-transactions.sql @@ -0,0 +1,5 @@ +SELECT recipient_id, + SUM ("amount") AS "amount" +FROM transactions +WHERE TYPE = 0 +GROUP BY "recipient_id" diff --git a/packages/core-database-postgres/lib/queries/spv/second-signatures.sql b/packages/core-database-postgres/lib/queries/spv/second-signatures.sql new file mode 100644 index 0000000000..ad929ad146 --- /dev/null +++ b/packages/core-database-postgres/lib/queries/spv/second-signatures.sql @@ -0,0 +1,4 @@ +SELECT sender_public_key, + serialized +FROM transactions +WHERE TYPE = 1 diff --git a/packages/core-database-postgres/lib/queries/spv/sent-transactions.sql b/packages/core-database-postgres/lib/queries/spv/sent-transactions.sql new file mode 100644 index 0000000000..ee161ec08c --- /dev/null +++ b/packages/core-database-postgres/lib/queries/spv/sent-transactions.sql @@ -0,0 +1,5 @@ +SELECT sender_public_key, + SUM ("amount") AS "amount", + SUM ("fee") AS "fee" +FROM transactions +GROUP BY "sender_public_key" diff --git a/packages/core-database-postgres/lib/queries/spv/votes.sql b/packages/core-database-postgres/lib/queries/spv/votes.sql new file mode 100644 index 0000000000..63e71e02c3 --- /dev/null +++ b/packages/core-database-postgres/lib/queries/spv/votes.sql @@ -0,0 +1,5 @@ +SELECT sender_public_key, + serialized +FROM transactions +WHERE TYPE = 3 +ORDER BY timestamp DESC, sequence ASC diff --git a/packages/core-database-postgres/lib/queries/transactions/delete-by-block.sql b/packages/core-database-postgres/lib/queries/transactions/delete-by-block.sql new file mode 100644 index 0000000000..1ec6aeb057 --- /dev/null +++ b/packages/core-database-postgres/lib/queries/transactions/delete-by-block.sql @@ -0,0 +1,3 @@ +DELETE +FROM transactions +WHERE block_id = ${id} diff --git a/packages/core-database-postgres/lib/queries/transactions/find-by-block.sql b/packages/core-database-postgres/lib/queries/transactions/find-by-block.sql new file mode 100644 index 0000000000..922708b6b4 --- /dev/null +++ b/packages/core-database-postgres/lib/queries/transactions/find-by-block.sql @@ -0,0 +1,3 @@ +SELECT serialized +FROM transactions +WHERE block_id = ${id} diff --git a/packages/core-database-postgres/lib/queries/transactions/find-by-id.sql b/packages/core-database-postgres/lib/queries/transactions/find-by-id.sql new file mode 100644 index 0000000000..4109e2e635 --- /dev/null +++ b/packages/core-database-postgres/lib/queries/transactions/find-by-id.sql @@ -0,0 +1,3 @@ +SELECT * +FROM transactions +WHERE id = ${id} diff --git a/packages/core-database-postgres/lib/queries/transactions/find-many-by-id.sql b/packages/core-database-postgres/lib/queries/transactions/find-many-by-id.sql new file mode 100644 index 0000000000..5b20ec290a --- /dev/null +++ b/packages/core-database-postgres/lib/queries/transactions/find-many-by-id.sql @@ -0,0 +1,4 @@ +SELECT serialized, + block_id +FROM transactions +WHERE id IN (${ids:list}) diff --git a/packages/core-database-postgres/lib/queries/transactions/forged.sql b/packages/core-database-postgres/lib/queries/transactions/forged.sql new file mode 100644 index 0000000000..a7b2d24be2 --- /dev/null +++ b/packages/core-database-postgres/lib/queries/transactions/forged.sql @@ -0,0 +1,3 @@ +SELECT id +FROM transactions +WHERE id IN (${ids:list}) diff --git a/packages/core-database-postgres/lib/queries/transactions/latest-by-block.sql b/packages/core-database-postgres/lib/queries/transactions/latest-by-block.sql new file mode 100644 index 0000000000..acf776d38d --- /dev/null +++ b/packages/core-database-postgres/lib/queries/transactions/latest-by-block.sql @@ -0,0 +1,4 @@ +SELECT serialized +FROM transactions +WHERE block_id = ${id} +ORDER BY sequence ASC diff --git a/packages/core-database-postgres/lib/queries/transactions/latest-by-blocks.sql b/packages/core-database-postgres/lib/queries/transactions/latest-by-blocks.sql new file mode 100644 index 0000000000..594234ab7c --- /dev/null +++ b/packages/core-database-postgres/lib/queries/transactions/latest-by-blocks.sql @@ -0,0 +1,5 @@ +SELECT block_id, + serialized +FROM transactions +WHERE block_id IN (${ids:list}) +ORDER BY sequence ASC diff --git a/packages/core-database-postgres/lib/queries/transactions/statistics.sql b/packages/core-database-postgres/lib/queries/transactions/statistics.sql new file mode 100644 index 0000000000..4beef227a6 --- /dev/null +++ b/packages/core-database-postgres/lib/queries/transactions/statistics.sql @@ -0,0 +1,4 @@ +SELECT COUNT ("id") AS "count", + SUM ("fee") AS "totalFee", + SUM ("amount") AS "totalAmount" +FROM transactions diff --git a/packages/core-database-postgres/lib/queries/wallets/all.sql b/packages/core-database-postgres/lib/queries/wallets/all.sql new file mode 100644 index 0000000000..5435ffc400 --- /dev/null +++ b/packages/core-database-postgres/lib/queries/wallets/all.sql @@ -0,0 +1,2 @@ +SELECT * +FROM wallets diff --git a/packages/core-database-postgres/lib/queries/wallets/find-by-address.sql b/packages/core-database-postgres/lib/queries/wallets/find-by-address.sql new file mode 100644 index 0000000000..98fe3cdfef --- /dev/null +++ b/packages/core-database-postgres/lib/queries/wallets/find-by-address.sql @@ -0,0 +1,3 @@ +SELECT * +FROM wallets +WHERE address = ${address} diff --git a/packages/core-database-postgres/lib/queries/wallets/find-negative-balances.sql b/packages/core-database-postgres/lib/queries/wallets/find-negative-balances.sql new file mode 100644 index 0000000000..83ebbad129 --- /dev/null +++ b/packages/core-database-postgres/lib/queries/wallets/find-negative-balances.sql @@ -0,0 +1,3 @@ +SELECT COUNT (DISTINCT "address") AS "count" +FROM wallets +WHERE balance < 0; diff --git a/packages/core-database-postgres/lib/queries/wallets/find-negative-vote-balances.sql b/packages/core-database-postgres/lib/queries/wallets/find-negative-vote-balances.sql new file mode 100644 index 0000000000..af79cbad33 --- /dev/null +++ b/packages/core-database-postgres/lib/queries/wallets/find-negative-vote-balances.sql @@ -0,0 +1,3 @@ +SELECT COUNT (DISTINCT "address") AS "count" +FROM wallets +WHERE vote_balance < 0; diff --git a/packages/core-database-postgres/lib/repositories/blocks.js b/packages/core-database-postgres/lib/repositories/blocks.js new file mode 100644 index 0000000000..61569cfd73 --- /dev/null +++ b/packages/core-database-postgres/lib/repositories/blocks.js @@ -0,0 +1,100 @@ +const Repository = require('./repository') +const { Block } = require('../models') +const { blocks: sql } = require('../queries') + +module.exports = class BlocksRepository extends Repository { + /** + * Find a block by its ID. + * @param {Number} id + * @return {Promise} + */ + async findById(id) { + return this.db.one(sql.findById, { id }) + } + + /** + * Count the number of records in the database. + * @return {Promise} + */ + async count() { + return this.db.one(sql.count) + } + + /** + * Get all of the common blocks from the database. + * @param {Array} ids + * @return {Promise} + */ + async common(ids) { + return this.db.manyOrNone(sql.common, { ids }) + } + + /** + * Get all of the blocks within the given height range. + * @param {Number} start + * @param {Number} end + * @return {Promise} + */ + async headers(start, end) { + return this.db.many(sql.headers, { start, end }) + } + + /** + * Get all of the blocks within the given height range and order them by height. + * @param {Number} start + * @param {Number} end + * @return {Promise} + */ + async heightRange(start, end) { + return this.db.manyOrNone(sql.heightRange, { start, end }) + } + + /** + * Get the last created block from the database. + * @return {Promise} + */ + async latest() { + return this.db.oneOrNone(sql.latest) + } + + /** + * Get the 10 most recently created blocks from the database. + * @return {Promise} + */ + async recent() { + return this.db.many(sql.recent) + } + + /** + * Get statistics about all blocks from the database. + * @return {Promise} + */ + async statistics() { + return this.db.one(sql.statistics) + } + + /** + * Get top count blocks + * @return {Promise} + */ + async top(count) { + return this.db.many(sql.top, { top: count }) + } + + /** + * Delete the block from the database. + * @param {Number} id + * @return {Promise} + */ + async delete(id) { + return this.db.none(sql.delete, { id }) + } + + /** + * Get the model related to this repository. + * @return {Object} + */ + getModel() { + return new Block(this.pgp) + } +} diff --git a/packages/core-database-postgres/lib/repositories/index.js b/packages/core-database-postgres/lib/repositories/index.js new file mode 100644 index 0000000000..686c136090 --- /dev/null +++ b/packages/core-database-postgres/lib/repositories/index.js @@ -0,0 +1,6 @@ +module.exports = { + blocks: require('./blocks'), + rounds: require('./rounds'), + transactions: require('./transactions'), + wallets: require('./wallets'), +} diff --git a/packages/core-database-postgres/lib/repositories/repository.js b/packages/core-database-postgres/lib/repositories/repository.js new file mode 100644 index 0000000000..e34f7f7ea0 --- /dev/null +++ b/packages/core-database-postgres/lib/repositories/repository.js @@ -0,0 +1,74 @@ +module.exports = class Repository { + /** + * Create a new repository instance. + * @param {Object} db + * @param {Object} pgp + */ + constructor(db, pgp) { + this.db = db + this.pgp = pgp + this.model = this.getModel() + } + + /** + * Estimate the number of records in the table. + * @return {Promise} + */ + async estimate() { + return this.db.one( + `SELECT count_estimate('SELECT * FROM ${this.model.getTable()})`, + ) + } + + /** + * Run a truncate statement on the table. + * @return {Promise} + */ + async truncate() { + return this.db.none(`TRUNCATE ${this.model.getTable()} RESTART IDENTITY`) + } + + /** + * Create one or many instances of the related models. + * @param {Array|Object} item + * @return {Promise} + */ + async create(item) { + return this.db.none(this.__insertQuery(item)) + } + + /** + * Update one or many instances of the related models. + * @param {Array|Object} item + * @return {Promise} + */ + async update(item) { + return this.db.none(this.__updateQuery(item)) + } + + /** + * Get the model related to this repository. + * @return {Object} + */ + getModel() { + throw new Error('Method [getModel] not implemented!') + } + + /** + * Generate an "INSERT" query for the given data. + * @param {Array|Object} data + * @return {String} + */ + __insertQuery(data) { + return this.pgp.helpers.insert(data, this.model.getColumnSet()) + } + + /** + * Generate an "UPDATE" query for the given data. + * @param {Array|Object} data + * @return {String} + */ + __updateQuery(data) { + return this.pgp.helpers.update(data, this.model.getColumnSet()) + } +} diff --git a/packages/core-database-postgres/lib/repositories/rounds.js b/packages/core-database-postgres/lib/repositories/rounds.js new file mode 100644 index 0000000000..ea55b11f76 --- /dev/null +++ b/packages/core-database-postgres/lib/repositories/rounds.js @@ -0,0 +1,31 @@ +const Repository = require('./repository') +const { Round } = require('../models') +const { rounds: sql } = require('../queries') + +module.exports = class RoundsRepository extends Repository { + /** + * Find a round by its ID. + * @param {Number} round + * @return {Promise} + */ + async findById(round) { + return this.db.manyOrNone(sql.find, { round }) + } + + /** + * Delete the round from the database. + * @param {Number} round + * @return {Promise} + */ + async delete(round) { + return this.db.none(sql.delete, { round }) + } + + /** + * Get the model related to this repository. + * @return {Object} + */ + getModel() { + return new Round(this.pgp) + } +} diff --git a/packages/core-database-postgres/lib/repositories/transactions.js b/packages/core-database-postgres/lib/repositories/transactions.js new file mode 100644 index 0000000000..66cf3158c5 --- /dev/null +++ b/packages/core-database-postgres/lib/repositories/transactions.js @@ -0,0 +1,84 @@ +const Repository = require('./repository') +const { Transaction } = require('../models') +const { transactions: sql } = require('../queries') + +module.exports = class TransactionsRepository extends Repository { + /** + * Find a transactions by its ID. + * @param {String} id + * @return {Promise} + */ + async findById(id) { + return this.db.oneOrNone(sql.findById, { id }) + } + + /** + * Find multiple transactionss by their IDs. + * @param {Array} ids + * @return {Promise} + */ + async findManyById(ids) { + return this.db.manyOrNone(sql.findManyById, { ids }) + } + + /** + * Find multiple transactionss by their block ID. + * @param {String} id + * @return {Promise} + */ + async findByBlock(id) { + return this.db.manyOrNone(sql.findByBlock, { id }) + } + + /** + * Find multiple transactionss by their block ID and order them by sequence. + * @param {Number} id + * @return {Promise} + */ + async latestByBlock(id) { + return this.db.manyOrNone(sql.latestByBlock, { id }) + } + + /** + * Find multiple transactionss by their block IDs and order them by sequence. + * @param {Array} ids + * @return {Promise} + */ + async latestByBlocks(ids) { + return this.db.manyOrNone(sql.latestByBlocks, { ids }) + } + + /** + * Get all of the forged transactions from the database. + * @param {Array} ids + * @return {Promise} + */ + async forged(ids) { + return this.db.manyOrNone(sql.forged, { ids }) + } + + /** + * Get statistics about all transactions from the database. + * @return {Promise} + */ + async statistics() { + return this.db.one(sql.statistics) + } + + /** + * Delete the transactions from the database. + * @param {Number} id + * @return {Promise} + */ + async deleteByBlock(id) { + return this.db.none(sql.deleteByBlock, { id }) + } + + /** + * Get the model related to this repository. + * @return {Object} + */ + getModel() { + return new Transaction(this.pgp) + } +} diff --git a/packages/core-database-postgres/lib/repositories/wallets.js b/packages/core-database-postgres/lib/repositories/wallets.js new file mode 100644 index 0000000000..95a01041eb --- /dev/null +++ b/packages/core-database-postgres/lib/repositories/wallets.js @@ -0,0 +1,62 @@ +const Repository = require('./repository') +const { Wallet } = require('../models') +const { wallets: sql } = require('../queries') + +module.exports = class WalletsRepository extends Repository { + /** + * Get all of the wallets from the database. + * @return {Promise} + */ + async all() { + return this.db.manyOrNone(sql.all) + } + + /** + * Find a wallet by its address. + * @param {String} address + * @return {Promise} + */ + async findByAddress(address) { + return this.db.oneOrNone(sql.findByAddress, { address }) + } + + /** + * Get the count of wallets that have a negative balance. + * @return {Promise} + */ + async findNegativeBalances() { + return this.db.oneOrNone(sql.findNegativeBalances) + } + + /** + * Get the count of wallets that have a negative vote balance. + * @return {Promise} + */ + async findNegativeVoteBalances() { + return this.db.oneOrNone(sql.findNegativeVoteBalances) + } + + /** + * Create or update a record matching the attributes, and fill it with values. + * @param {Object} wallet + * @return {Promise} + */ + async updateOrCreate(wallet) { + const query = `${this.__insertQuery( + wallet, + )} ON CONFLICT(address) DO UPDATE SET ${this.pgp.helpers.sets( + wallet, + this.model.getColumnSet(), + )}` + + return this.db.none(query) + } + + /** + * Get the model related to this repository. + * @return {Object} + */ + getModel() { + return new Wallet(this.pgp) + } +} diff --git a/packages/core-database-postgres/lib/spv.js b/packages/core-database-postgres/lib/spv.js new file mode 100644 index 0000000000..3266252c45 --- /dev/null +++ b/packages/core-database-postgres/lib/spv.js @@ -0,0 +1,325 @@ +const { + Bignum, + models: { Transaction }, +} = require('@arkecosystem/crypto') +const app = require('@arkecosystem/core-container') + +const logger = app.resolvePlugin('logger') +const config = app.resolvePlugin('config') +const queries = require('./queries') + +const genesisWallets = config.genesisBlock.transactions.map(tx => tx.senderId) + +module.exports = class SPV { + /** + * Create a new wallet builder instance. + * @param {SequelizeConnection} database + * @return {void} + */ + constructor(database) { + this.connection = database.connection + this.models = database.models + this.walletManager = database.walletManager + this.query = database.query + } + + /** + * Perform the SPV (Simple Payment Verification). + * @param {Number} height + * @return {void} + */ + async build(height) { + this.activeDelegates = config.getConstants(height).activeDelegates + + logger.printTracker('SPV', 1, 8, 'Received Transactions') + await this.__buildReceivedTransactions() + + logger.printTracker('SPV', 2, 8, 'Block Rewards') + await this.__buildBlockRewards() + + logger.printTracker('SPV', 3, 8, 'Last Forged Blocks') + await this.__buildLastForgedBlocks() + + logger.printTracker('SPV', 4, 8, 'Sent Transactions') + await this.__buildSentTransactions() + + logger.printTracker('SPV', 5, 8, 'Second Signatures') + await this.__buildSecondSignatures() + + logger.printTracker('SPV', 6, 8, 'Votes') + await this.__buildVotes() + + logger.printTracker('SPV', 7, 8, 'Delegates') + await this.__buildDelegates() + + logger.printTracker('SPV', 8, 8, 'MultiSignatures') + await this.__buildMultisignatures() + + logger.stopTracker('SPV', 8, 8) + logger.info( + `SPV rebuild finished, wallets in memory: ${ + Object.keys(this.walletManager.byAddress).length + }`, + ) + logger.info( + `Number of registered delegates: ${ + Object.keys(this.walletManager.byUsername).length + }`, + ) + + return this.__verifyWalletsConsistency() + } + + /** + * Load and apply received transactions to wallets. + * @return {void} + */ + async __buildReceivedTransactions() { + const transactions = await this.query.many(queries.spv.receivedTransactions) + + for (const transaction of transactions) { + const wallet = this.walletManager.findByAddress(transaction.recipientId) + + wallet + ? (wallet.balance = new Bignum(transaction.amount)) + : logger.warn( + `Lost cold wallet: ${transaction.recipientId} ${ + transaction.amount + }`, + ) + } + } + + /** + * Load and apply block rewards to wallets. + * @return {void} + */ + async __buildBlockRewards() { + const blocks = await this.query.many(queries.spv.blockRewards) + + for (const block of blocks) { + const wallet = this.walletManager.findByPublicKey( + block.generatorPublicKey, + ) + wallet.balance = wallet.balance.plus(block.reward) + } + } + + /** + * Load and apply last forged blocks to wallets. + * @return {void} + */ + async __buildLastForgedBlocks() { + const blocks = await this.query.many(queries.spv.lastForgedBlocks, { + limit: this.activeDelegates, + }) + + for (const block of blocks) { + const wallet = this.walletManager.findByPublicKey( + block.generatorPublicKey, + ) + wallet.lastBlock = block + } + } + + /** + * Load and apply sent transactions to wallets. + * @return {void} + */ + async __buildSentTransactions() { + const transactions = await this.query.many(queries.spv.sentTransactions) + + for (const transaction of transactions) { + const wallet = this.walletManager.findByPublicKey( + transaction.senderPublicKey, + ) + wallet.balance = wallet.balance + .minus(transaction.amount) + .minus(transaction.fee) + + if (wallet.balance.isLessThan(0) && !this.isGenesis(wallet)) { + logger.warn(`Negative balance: ${wallet}`) + } + } + } + + /** + * Used to determine if a wallet is a Genesis wallet. + * @return {Boolean} + */ + isGenesis(wallet) { + return genesisWallets.includes(wallet.address) + } + + /** + * Load and apply second signature transactions to wallets. + * @return {void} + */ + async __buildSecondSignatures() { + const transactions = await this.query.manyOrNone( + queries.spv.secondSignatures, + ) + + for (const transaction of transactions) { + const wallet = this.walletManager.findByPublicKey( + transaction.senderPublicKey, + ) + wallet.secondPublicKey = Transaction.deserialize( + transaction.serialized.toString('hex'), + ).asset.signature.publicKey + } + } + + /** + * Load and apply votes to wallets. + * @return {void} + */ + async __buildVotes() { + const transactions = await this.query.manyOrNone(queries.spv.votes) + + for (const transaction of transactions) { + const wallet = this.walletManager.findByPublicKey( + transaction.senderPublicKey, + ) + + if (!wallet.voted) { + const vote = Transaction.deserialize( + transaction.serialized.toString('hex'), + ).asset.votes[0] + + if (vote.startsWith('+')) { + wallet.vote = vote.slice(1) + } + + // NOTE: The "voted" property is only used within this loop to avoid an issue + // that results in not properly applying "unvote" transactions as the "vote" property + // would be empty in that case and return a false result. + wallet.voted = true + } + } + + this.walletManager.buildVoteBalances() + } + + /** + * Load and apply delegate usernames to wallets. + * @return {void} + */ + async __buildDelegates() { + // Register... + const transactions = await this.query.manyOrNone(queries.spv.delegates) + + transactions.forEach(transaction => { + const wallet = this.walletManager.findByPublicKey( + transaction.senderPublicKey, + ) + wallet.username = Transaction.deserialize( + transaction.serialized.toString('hex'), + ).asset.delegate.username + this.walletManager.reindex(wallet) + }) + + // Forged Blocks... + const forgedBlocks = await this.query.manyOrNone( + queries.spv.delegatesForgedBlocks, + ) + forgedBlocks.forEach(block => { + const wallet = this.walletManager.findByPublicKey( + block.generatorPublicKey, + ) + wallet.forgedFees = wallet.forgedFees.plus(block.totalFees) + wallet.forgedRewards = wallet.forgedRewards.plus(block.totalRewards) + wallet.producedBlocks = +block.totalProduced + }) + + // NOTE: This is highly NOT reliable, however the number of missed blocks + // is NOT used for the consensus + const delegates = await this.query.manyOrNone(queries.spv.delegatesRanks) + delegates.forEach((delegate, i) => { + const wallet = this.walletManager.findByPublicKey(delegate.publicKey) + wallet.missedBlocks = parseInt(delegate.missedBlocks) + wallet.rate = i + 1 + this.walletManager.reindex(wallet) + }) + } + + /** + * Load and apply multisignatures to wallets. + * @return {void} + */ + async __buildMultisignatures() { + const transactions = await this.query.manyOrNone( + queries.spv.multiSignatures, + ) + + for (const transaction of transactions) { + const wallet = this.walletManager.findByPublicKey( + transaction.senderPublicKey, + ) + + if (!wallet.multisignature) { + wallet.multisignature = Transaction.deserialize( + transaction.serialized.toString('hex'), + ).asset.multisignature + } + } + } + + /** + * Verify the consistency of the wallets table by comparing all records against + * the in memory wallets. + * NOTE: This is faster than rebuilding the entire table from scratch each time. + * @returns {Boolean} + */ + async __verifyWalletsConsistency() { + const dbWallets = await this.query.manyOrNone(queries.wallets.all) + const inMemoryWallets = this.walletManager.allByPublicKey() + + let detectedInconsistency = false + if (dbWallets.length !== inMemoryWallets.length) { + detectedInconsistency = true + } else { + for (const dbWallet of dbWallets) { + if (dbWallet.balance < 0 && !this.isGenesis(dbWallet)) { + detectedInconsistency = true + logger.warn( + `Wallet '${dbWallet.address}' has a negative balance of '${ + dbWallet.balance + }'`, + ) + break + } + + if (dbWallet.voteBalance < 0) { + detectedInconsistency = true + logger.warn( + `Wallet ${dbWallet.address} has a negative vote balance of '${ + dbWallet.voteBalance + }'`, + ) + break + } + + const inMemoryWallet = this.walletManager.findByPublicKey( + dbWallet.publicKey, + ) + + if ( + !inMemoryWallet.balance.isEqualTo(dbWallet.balance) || + !inMemoryWallet.voteBalance.isEqualTo(dbWallet.voteBalance) || + dbWallet.username !== inMemoryWallet.username + ) { + detectedInconsistency = true + break + } + } + } + + // Remove dirty flags when no inconsistency has been found + if (!detectedInconsistency) { + this.walletManager.clear() + } + + return !detectedInconsistency + } +} diff --git a/packages/core-database-postgres/lib/sql/query-executor.js b/packages/core-database-postgres/lib/sql/query-executor.js new file mode 100644 index 0000000000..4a1d3b58a0 --- /dev/null +++ b/packages/core-database-postgres/lib/sql/query-executor.js @@ -0,0 +1,81 @@ +module.exports = class QueryExecutor { + /** + * Create a new QueryExecutor instance. + * @param {[type]} connection + * @return {QueryBuilder} + */ + constructor(connection) { + this.connection = connection + } + + /** + * Execute the given query and expect no results. + * @param {QueryFile} query + * @param {Array} parameters + * @return {Promise} + */ + async none(query, parameters) { + return this.__executeQueryFile(query, parameters, 'none') + } + + /** + * Execute the given query and expect one result. + * @param {QueryFile} query + * @param {Array} parameters + * @return {Promise} + */ + async one(query, parameters) { + return this.__executeQueryFile(query, parameters, 'one') + } + + /** + * Execute the given query and expect one or no results. + * @param {QueryFile} query + * @param {Array} parameters + * @return {Promise} + */ + async oneOrNone(query, parameters) { + return this.__executeQueryFile(query, parameters, 'oneOrNone') + } + + /** + * Execute the given query and expect many results. + * @param {QueryFile} query + * @param {Array} parameters + * @return {Promise} + */ + async many(query, parameters) { + return this.__executeQueryFile(query, parameters, 'many') + } + + /** + * Execute the given query and expect many or no results. + * @param {QueryFile} query + * @param {Array} parameters + * @return {Promise} + */ + async manyOrNone(query, parameters) { + return this.__executeQueryFile(query, parameters, 'manyOrNone') + } + + /** + * Execute the given query and expect any results. + * @param {QueryFile} query + * @param {Array} parameters + * @return {Promise} + */ + async any(query, parameters) { + return this.__executeQueryFile(query, parameters, 'any') + } + + /** + * Execute the given query using the given method and parameters. + * @param {QueryFile} query + * @param {Array} parameters + * @param {String} method + * @return {QueryBuilder} + */ + async __executeQueryFile(query, parameters, method) { + return this.connection.db[method](query, parameters) + } +} diff --git a/packages/core-database-postgres/lib/utils/camelize-columns.js b/packages/core-database-postgres/lib/utils/camelize-columns.js new file mode 100644 index 0000000000..d0721f31d5 --- /dev/null +++ b/packages/core-database-postgres/lib/utils/camelize-columns.js @@ -0,0 +1,17 @@ +/* eslint guard-for-in: "off" */ + +module.exports = (pgp, data) => { + const tmp = data[0] + + for (const prop in tmp) { + const camel = pgp.utils.camelize(prop) + + if (!(camel in tmp)) { + for (let i = 0; i < data.length; i++) { + const d = data[i] + d[camel] = d[prop] + delete d[prop] + } + } + } +} diff --git a/packages/core-database-postgres/lib/utils/index.js b/packages/core-database-postgres/lib/utils/index.js new file mode 100644 index 0000000000..a80bd79d5b --- /dev/null +++ b/packages/core-database-postgres/lib/utils/index.js @@ -0,0 +1,4 @@ +module.exports = { + camelizeColumns: require('./camelize-columns'), + loadQueryFile: require('./load-query-file'), +} diff --git a/packages/core-database-postgres/lib/utils/load-query-file.js b/packages/core-database-postgres/lib/utils/load-query-file.js new file mode 100644 index 0000000000..20302d61aa --- /dev/null +++ b/packages/core-database-postgres/lib/utils/load-query-file.js @@ -0,0 +1,25 @@ +const QueryFile = require('pg-promise').QueryFile +const path = require('path') + +const app = require('@arkecosystem/core-container') + +const logger = app.resolvePlugin('logger') + +module.exports = (directory, file) => { + const fullPath = path.join(directory, file) + + const options = { + minify: true, + params: { + schema: 'public', + }, + } + + const query = new QueryFile(fullPath, options) + + if (query.error) { + logger.error(query.error) + } + + return query +} diff --git a/packages/core-database-postgres/package.json b/packages/core-database-postgres/package.json new file mode 100644 index 0000000000..714a054d1e --- /dev/null +++ b/packages/core-database-postgres/package.json @@ -0,0 +1,36 @@ +{ + "name": "@arkecosystem/core-database-postgres", + "description": "PostgreSQL integration for Ark Core", + "version": "0.2.0", + "contributors": [ + "Brian Faust " + ], + "license": "MIT", + "main": "lib/index.js", + "scripts": { + "test": "cross-env ARK_ENV=test jest --runInBand --detectOpenHandles", + "test:coverage": "cross-env ARK_ENV=test jest --coverage --coveragePathIgnorePatterns='/(defaults.js|index.js)$' --runInBand --detectOpenHandles", + "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand", + "test:watch": "cross-env ARK_ENV=test jest --runInBand --watch", + "test:watch:all": "cross-env ARK_ENV=test jest --runInBand --watchAll", + "lint": "eslint ./ --fix", + "depcheck": "depcheck ./ --ignores=lodash,lodash.*" + }, + "dependencies": { + "@arkecosystem/core-container": "~0.2", + "@arkecosystem/core-database": "~0.2", + "@arkecosystem/core-utils": "~0.2", + "@arkecosystem/crypto": "~0.2", + "bluebird": "^3.5.3", + "lodash.chunk": "^4.2.0", + "pg-promise": "^8.5.2", + "pluralize": "^7.0.0", + "sql": "^0.78.0" + }, + "publishConfig": { + "access": "public" + }, + "engines": { + "node": ">=10.x" + } +} diff --git a/packages/core-database-sequelize/README.md b/packages/core-database-sequelize/README.md deleted file mode 100644 index 6a9664590b..0000000000 --- a/packages/core-database-sequelize/README.md +++ /dev/null @@ -1,39 +0,0 @@ -![ARK Core](https://i.imgur.com/1aP6F2o.png) - -# ARK Core - Sequelize Database Provider - -## Installation - -```bash -yarn add @arkecosystem/core-database-sequelize -``` - -## Configuration - -### Defaults - -```js -module.exports = { - dialect: 'sqlite', - storage: `${process.env.ARK_PATH_DATA}/database/${process.env.ARK_NETWORK_NAME}.sqlite`, - logging: process.env.ARK_DB_LOGGING -} -``` - -If you want to see all available configuration properties head over to http://docs.sequelizejs.com/manual/installation/usage.html#options. - -## Security - -If you discover a security vulnerability within this package, please send an e-mail to security@ark.io. All security vulnerabilities will be promptly addressed. - -## Credits - -- [François-Xavier Thoorens](https://github.com/fix) -- [Kristjan Košič](https://github.com/kristjank) -- [Brian Faust](https://github.com/faustbrian) -- [Alex Barnsley](https://github.com/alexbarnsley) -- [All Contributors](../../../../contributors) - -## License - -[MIT](LICENSE) © [ArkEcosystem](https://ark.io) diff --git a/packages/core-database-sequelize/__tests__/__fixtures__/delegates.json b/packages/core-database-sequelize/__tests__/__fixtures__/delegates.json deleted file mode 100644 index 925645bd62..0000000000 --- a/packages/core-database-sequelize/__tests__/__fixtures__/delegates.json +++ /dev/null @@ -1,53 +0,0 @@ -[ - "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f", - "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a", - "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983", - "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689", - "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c", - "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0", - "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294", - "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883", - "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d", - "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565", - "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e", - "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb", - "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a", - "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b", - "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964", - "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751", - "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca", - "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9", - "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d", - "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd", - "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055", - "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252", - "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1", - "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4", - "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80", - "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d", - "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37", - "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e", - "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374", - "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f", - "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904", - "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c", - "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e", - "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a", - "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc", - "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564", - "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd", - "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28", - "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647", - "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2", - "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17", - "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5", - "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93", - "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a", - "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95", - "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a", - "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe", - "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12", - "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24", - "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357", - "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b" -] diff --git a/packages/core-database-sequelize/__tests__/__fixtures__/genesisBlock.js b/packages/core-database-sequelize/__tests__/__fixtures__/genesisBlock.js deleted file mode 100644 index 821ca9f0f8..0000000000 --- a/packages/core-database-sequelize/__tests__/__fixtures__/genesisBlock.js +++ /dev/null @@ -1,2160 +0,0 @@ -const { Block } = require('@arkecosystem/crypto').models - -module.exports = new Block({ - 'version': 0, - 'totalAmount': 12500000000000000, - 'totalFee': 0, - 'reward': 0, - 'payloadHash': 'd9acd04bde4234a81addb8482333b4ac906bed7be5a9970ce8ada428bd083192', - 'timestamp': 0, - 'numberOfTransactions': 153, - 'payloadLength': 35960, - 'previousBlock': null, - 'generatorPublicKey': '03b47f6b6719c76bad46a302d9cff7be9b1c2b2a20602a0d880f139b5b8901f068', - 'transactions': [{ - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402205fcb0677e06bde7aac3dc776665615f4b93ef8c3ed0fddecef9900e74fcb00f302206958a0c9868ea1b1f3d151bdfa92da1ce24de0b1fcd91933e64fb7971e92f48d', - 'id': 'db1aa687737858cc9199bfa336f9b1c035915c30aaee60b1e0f8afadfdb946bd', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100ffff4e9ba62e5e3beb37deee052824da83c4030925bce09f190151652d0669b8022056a432e56a2e1b026d4b54f6c34ce88a0c9cebdccc730659c03449fe878c66f8', - 'id': '0762007f825f02979a883396839d6f7425d5ab18f4b8c266bebe60212c793c6d', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3044022001a6326e5d1eb06d0ba1fa39446bd6d56ea45f0c269ebbce5dfc6a649277cfcc02203b252d3a6ef2b22349d9d0a9110ce28a199c39dc8b911edfa82c297a02009d07', - 'id': '3c39aca95ad807ce19c0325e3059d7b1cf967751c6929035214a4ef320fb8154', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304502210084d855eddfe616cf1dc238b19226c7959c2fc4027ae2e8aea6fd8e9eb8928e6b0220440f980e40c1c56348782fd69d49a96944df7ee5b68d18028600e0e7501d4000', - 'id': '9fdf6ae86f7c005b3b7dc1b9fb6411219407ecaa93adff85fdb61710f5121638', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402205438b8b9058bbde5d30794e7681e400e52b5fbd22324c5b6b521f97bc8b8aabc022000fe04d7afbd2e668b1d4576988ed596dc92251e33efebc081e2cba14ad5a898', - 'id': '1d7c68087c875d7ce555b2c3e71e1d91a1ad62d0c2497efe3cab91415e634041', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'APRiwbs17FdbaF8DYU9js2jChRehQc2e6P', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100b2e634a95b011a68489870f003e4bac4a4f0578bfdc6b9f645c934016c2c0463022022cd4ebf276dd627d98be4b697bae2df10b86d94e984da2eb7e011b08d6dffd2', - 'id': '0c993e115ba26981b0be9d22e7c4a13b0f106e0cb472f9d34eabfc8e414dd528', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100f965e5c280acb22d1cde405223fe9a6fcb765844adbc5321b17a268924e1f597022043d31b1edc5fe0cf60a960d84e3528472cdf34560c9463979043a409f37e7f29', - 'id': 'c279f2eb1f9e6e7d4b0ba7a98233a0f1a2536231976c99f56f64b248eb06a0c1', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '30440220715463c316a75959dbfb6a59a013fbf914bef1ff739ac8000d49dabbf5118df9022019345ae1c34173dc214bae82f3cfbf438092f0fd2d277acafe3e9deb644b1a3b', - 'id': '7e2fc9ecf23e909a3d0fbecd615445a0eed8c2cef18e01b1492d63f616f5d87d', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100fdd8aff26dceeb5abb6e5e8a8f468c8ac1997a587225298e3d8135d57dadf4dc022072ab80a81b301a162ed5cfa67d213d5a3980185088632f5f592351aff8aa0e9c', - 'id': '511c0e1076104743f98932f8e7720bdb3f1539134edadd331914fd9ece1ebede', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '30440220635e04ce278870f17fcd1883aa26c568e63dfbdd302add39aa30fd3637c79c2c02206fdd9e7b1f4d238a97d26ef1758927e2d39f121687490f2bd79831e36afdd43b', - 'id': '0768d5016c53d884e3d68a09d1bab0d730b7067c71ef4ca1c4d61b3815f5ff66', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402200b1dac57ca6565ac31afb99686f2e0f0e8dc219b9860b295ca5444a1663cecfb02205787393561fe407449af4aaf2f621db9e4d3f11c7438666cd694d495c0a0c41f', - 'id': '1aeb50080ea118165e5041f7a897974c2ed1ebde08add85dc78cc7cf73566a91', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304502210098dea25eccf31ce6f874a9528578805aaf07be8b41f1571865793f9e3e6e3c97022033ae9c73dad44c01fe6362665fccf63bb1a0ae8e26f77a1cf60b67dc96b05343', - 'id': '254f0f4fa277cc651a746d6ac371eb27afc3ea155ba060552dd26b8e83d17b72', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402207f4bf346aac501e766156818089fb16905a9bdca69ff6d5a55ba918a08afc7ab02200ec2c25cc4bb30e2c176d55630d8e2679b899c14ab4ba43c3d62955dd940425b', - 'id': 'e5ebb02e8e8a6708e22ee5ef99fe1dd8b6eea1095be6b772aa21bf63cf7ade5a', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100a0bbc15bdad648bb9b439f1d34b12b853442d1cfd4ce7f569905082801fa58e8022036b4e73edf7ab7226f8007233f77b1d497cb6b4736f02721bf1b399312ebe114', - 'id': '8a686b21477b64dfd85f08f8598a0f121ca1c7d65ccaca9e42326c75fb5f3abb', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402205d77dfcde527dcc6669bcb01c27b92c1a6399e35ebac9e69415645f596ab1d2802204179497bfd952f44d5f9e295b2a3219a290a4a82841c084a18553b7712e26415', - 'id': '21175347e2acfabc09a7593aae0682e39fe7152199a90561c11125f525211243', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100cf77c16df9185727ff717b71a94f8b29ceeae1e5bb3a28da8cef9df5bc63b7c202207bca394ce9ebd344a548e5a5697f672dedbef640dc1f9105f7c063287bcd1840', - 'id': 'ce1d9b7377551f36568127f5b635b5443f5a58abba6566b50a8d4d7b53c8a874', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100eb8daebb5484f3b0a738c9344fb28298c596f9486963f8fe36e2501ee6876f2a0220559df66986dc9a9a8e76982ef85f907c62745757990c69f0b17b6ae5a7ca4719', - 'id': 'b56702f5eddad0d8dbbb33b6b1ca3e07e4740def9c5dd2aaed9a70b90a4e31b7', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100d088e9bcd78978f2d67e7c7bccecfb73ddd0d1a2dad5b039390812320355722d02207affe83d815f04f6b11abf98eebe0488bfb87f8cd6513d44b829008ed1c15ceb', - 'id': 'a73c053c42e83a83498cf58e5b077b31443e265ddf8228081cb17a36bba366ae', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100db16a8e9682f07efb607bc7c75b654646ff449761ed146ab9358e69d29fadd7f0220436554ad78db0e04ae5b573258e2c8067848e89b55a6e8e1e25011a43882a643', - 'id': '2dccb8b44ad2e598673628fd9d74e336b467a0c941d5e257dceb85c8e0a0000c', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100b03738eccce8ad0b8ac0a656119c2cdd202089c5650d8e1486bd13eb9c3158980220059079900c7fdc16e799c50dccc074726fbf0068044462faabdf1e73f9f9bc38', - 'id': 'b2cce30021d139f97925807da796722bf4d5459442523823388c259ca5ad73db', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100becb49fe5edd6806d5ba6eddbbb34ca8eaf3a12dba123d1610b2b120ca8bd017022072972992ee0ca0f319ae754a2a5a10d715a08b23f8239f9d6d59774f790543ea', - 'id': '9e4841f43ab355be7a4f93b09f3d82c17065fbe25387dd6c5eb4e2692ea05b0b', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402207f1a3fe8c5aa7a77a58ed35c34f128b5df6fba89aa918af35eff432be7d1f8e00220460d4f2a457e1a477974157e33bf2974de6588d56e59729ae980720e9794827a', - 'id': '2c7ca823be21724a4876de632dded3b9afca45df357819ed028488128d85d29e', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3044022067266dfe9d8f2550b590e1eae2f73d28c6b80fecb24c3eb1b4539bc864b3b4f4022031e5122145c35874c0c48673d088e76fb3e11c308ffe9d5dee6431d3441d627e', - 'id': 'a91119f04e2201184761f7fdcb26e4aa81c7e1076cb11a58a422d351241d4e4a', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100b970ec89927de0cb7805e614a742d42c2967db5a9c68d0892956dc89d68ca7d1022067fa30265dd2e1a2985980be2bf876748a7a8c7f3cde0382265b601fa658dc17', - 'id': '94955e6bac6269fbd19e92d2292ac947225fc6f68c6216001b528596a961040c', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402203671b82ddf8a824b8e5aac8bc28be4aef1c00aca1097d14ec1a55003d7a3f28d02203aacb6e7517e916478432b81399828ba7425183ce0fc43feb361bcf345fb0519', - 'id': 'df563ee9822bd3d7aada600d4800952743ec64fafdc7697428d7a19a60745885', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100b77653317c93eb20ee19c71e64a7f9ecb985351bfb1fe351ac65a5738cb37ae202203d540395e1d55f87caaaa867afbfbaf98c553be0b4c7d1748418a76b0c258c89', - 'id': 'd21b6341e2b4be5ffdc3dd8fbcdf2c576ba02e2ef4ab5eab0e4bfc9da4e9e442', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3044022046239e39062a58925099b005888355b8cd6700af66972bf509a10123f9abdec60220202321ea74e56177606fc079d19c29851d832e6d00c93985ffbec3dba6f0d675', - 'id': 'df6bc7a17ad34f8e9faaa2646e8e5dd8bca35affba352537184f690e200e17b6', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402204eeab87f7ecc2097b85606b986177964f3ae777535f6fc0cf08a55fec587d87602203779d59903b8de63511e4ed0a7967bd85e9cb1fc9d84bbc5091e3caa87d8bd52', - 'id': '5f0d5f0dff464d0ad587da5bc93e600a8e2657d359d0a1224bdd4ccc3b6f376a', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402200a2b9d0f61066fa00a2a2882379aa8ee60e949bdc2a85103bbbb69ce3eafccd9022057364f349faceb3047fa95ada210c64fc4a81978d66925b37d3dbc21ede885af', - 'id': '1b39e3702576e6ad7775e34d53e43210549d52a56b3f246031e6ba4121a66bf0', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304502210099e568d3d0c1b48410e0b85c74d04234dacfb2fdf2b1d4b51fca1cfb3445347a02207a2509645aae54560762a37422b66ba4b3ee1c42de35d58c36d2f9d8fdea11b4', - 'id': '0f21e53dbb1edb1cfb4c31bb675aa4672b452a03ec363a2b3300a9dda49e3be3', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3044022026cc5f2b588a86241badca73cd9c1686916d516b8c6c397c66a9d5bb6b5d4cd402204ab5a8c8589ee954bda4a116999d2a0e4ab0e3e96f0c7fe131d7c57b9a1ede43', - 'id': '410826c255a23a78ac5c3aa10dd48132693bc955845af16c20d9c6f69b05dfe9', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402205fedd8d3b5c8d69cdd7db5ca8e9e7c5004f6ba751e45eb1b85b26d9e89800a2402202be56bb2cd824bccf325b6b11432bf6d0ddb5ec97fcc121839ac2ebf884c7173', - 'id': 'ddb57d8270b2b6c876191c1e1c5974388b9fb3ae0980cb2245d8a7c426237f47', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3044022053cd42ad147eea33801b2b57388b33f633b4bfe2ad902190e12480522250d07802203066dc0d0c2ffacc4c74cca1e0187fbea1cef7e78a78666d2ec7e4e87ef546eb', - 'id': '29e1aedf98935c369946c8dadb2d6784f9ab5ce8d73b9b4de2466c7757e2557b', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100c10448b87e7176735c8ddfc8fb3c4d5d55c2d71d18b7ce3ab321209ec299fd41022013517a09e4b366ab386698286ec7bb20410bdfb7f6674fab25a739259083b297', - 'id': '4cf04852529b5525f22cc540790e36e61ed36045ad1b5b788f61ebe42637391e', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402204cc1588b204ebc0c20f44a31ce53d15ab5e4d1f9c103c02dd4e4eaa1c33630b40220194b6e427b6def0783461cd8d765f97b105d048942be468be2ee9b0a2785d2ac', - 'id': '35c6bc3f0799d9c79efc6515f232c58be0d03a3a797d066cba879eef4afaae2c', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100be44f7ea12e2ee89245fb474643ec6c2c75afa00276826a4ecd6fca4cad5ff30022071a2c083b353a821345e4bbf74d98db0760b8721856572572cc3436ebdb8f08c', - 'id': '45f75a349f3b4d73434c0f2ac9c291d5d07278b79e6eaa0d38d6e005f66c4783', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402202090f506e8f18fde70b87a3fd6c470a23e9e262f20ec6268dd59b6362e51a29202202b838c598b33c6317c998dc179fad2b660b8a72bfaf8223d7cc82414ab4c6af4', - 'id': 'a8d9034d1091a4dbe595647ad5f64ca8b243e7842301aee48f7eaf8b8ae98119', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100be59b689a48e198267305f1ae7e116f69f7c360857ea0b1fa81db122278cad69022033436d24ec0103674522f0c559e2357f8696bd498deccad2e0f66b2cf7469538', - 'id': '061cb438ba1216cfd5a0f268ce18e6f280557bc944d9aed3655e2bc5f08bdf51', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402203b5d2aa7c4554d6d2dd6723043350df0199e6e7bbd9f21a1a20dbba8c63918cc022014a78064c5f9c5e2f43d3be36de2b5e2f17e9af557bb6c75e8d82d9f725d0188', - 'id': '239f0640ddc3170a737ef349c07cb82b2493d207421b6f71b6b3dab856f16088', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3044022005eb29ad4cf79fd4f6898de19459e15cc816acb0975e53530a202e69c29d0d4a0220686cf6e0c14779d6d68dcb9d16358c0e859094d2eec8083598b7bb5869478bf2', - 'id': '25d8eef755cfee7cab0d7f9fbbea0fad6d5f906c432d997ae8ef1c49d23735f5', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100b93096a287d59545fa3a08593dfc740d9d47f3cfa3c4bd3c8ff8ef53d3a2e957022027eda62e47220774cf799f46916195e5a8b30015c56ceff4f4a1c10a918e3675', - 'id': 'aac25996e3be809ee88996b6b4063e2097d6306e77a067de8ebc8d7076a28d43', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3044022017282aa4fac7b18e834abc3ca37b2f60cf989c26b12e2f2398a66cb907015a760220428218d39db812a22cc138acc7d5d4d2d5713f0546751c02d2c3fabecca0e724', - 'id': 'b040f86b75750b49c83ca7eb8f2a458f16b44789796ff306c5f942ca5f19164d', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402205970d53cb0921a62bbef540dc33189b2313f3574e44f046097067e6991d63b1102200a356c87642cc781df661a1fee21cce354a144463d37053280e000e1b75da7a5', - 'id': '25ce96f951d7b7d886ef487331125b3413f655f9c5ee7fb4691a728c3cbce18f', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100aab0201c9d9a9641c11605d32353685cbaa051ecc276da1e6a3b309be9f20cf7022067aecbc7329bdf1770974e317a1243815511efa8c7af7801217a83c96d86eb0e', - 'id': '285143b8b19cbde7c680b0f62ef51293e8f315c823ffbd97608c38c02045d831', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100dc7752f6f8acaa3a1ee2ed1bed306ee04556b3866db92a1e770c4b970c7a932e02202d137b312342f9d0708704833b26b6611d0464c87df97049ad8b616483e9d1f8', - 'id': '87b06fccbb63809e976b3405cccec2eeaa3694d5510203f04c0e60bb6c2c0020', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402205ccad5c77ea339f5e3f2b7900b4b1c409d3c8204273e89b6401314fb61f0d224022026a63fef86356de64fe571ff8488a951dcacab56e980fc044ef9f43b9d37439c', - 'id': '5597ed52e4123756bea9307c09c916ff9d0f9fbce8d2e9a3a2ff719a87ad0966', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402207c91153f820f34228bec62772e0d78876bd3277912eacd866fe35b5c86a316c80220104529c6f786cb387ec1e3d5826271c837f0d0a6d0fa5731b9a5c6663cce7108', - 'id': 'd46fde78608fcc668246cc35336210b3c167ba55c82e91b0fd99df7e36872130', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100acc0cf119c18861d3683bb3b0f6e209f2d62acfdd958f86dfbd35137ada814320220448f6f8adcd46204629b45a4a06f5dc7ccb4dbc2a1d702e107d91053847adf2f', - 'id': 'aa92faf5d80459b4e058dc8a8212608b589925052e22148384835ab687a4e875', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3044022055b6bbde5fa886db3cf1224a59f1fb43e850e2d9237db593368e1043698fe2c30220067dd20195e794af4152f1ff9e3ae4261698a86c54803ba1890bf176d97844d4', - 'id': '432e67db0d5fc8c66376aa96c7324e5a1e6d00a415a9c8898b5e3bf25d8b083d', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '30450221009d6f38067264df8497d6888e4a8c316ec58ceba8a54c39ccb0ce261d114fbbab02200fae3f2f950f5c5e3387679f8ca341ec70cd90d0e32a30112f03cfb12cd9fc23', - 'id': '9321e1b08faa544f592ad8dc7b60ff1cf845efcd28fedf8b445be3bda60434cb', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245100000000000, - 'fee': 0, - 'recipientId': 'ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402200aed5a4102bdafda00fda575294f149b393a798c510af8ba877b8c2d7ec8051e022004f7487c4f728c633aee5baa62ab0017f4b91cf2f494eb1c4cc9addc3e9155da', - 'id': '0bbc9340798a18a81109bdfdbee9c9003f20a586dd9f80a39507c84588c1b4b1', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_9', - 'publicKey': '0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647' - } - }, - 'signature': '30440220072124721ba7c997f7c29ad3d4819515fae7a67be2bc395cb73f114eb8d4abe60220523ac295e114de30ce8a4300f4670db91ad2abe1268460e6ad3463fbe9834b84', - 'id': 'd2e70f9d2de57240571905aa81db0b6883e27a83be2422530722d76b56e63ecd', - 'senderId': 'AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_18', - 'publicKey': '02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a' - } - }, - 'signature': '304402204b93b06e08e71e3317f9426a1d3d450d6293fdbf5a6b3043fce27b3ce65431e20220683609720ea1d7d921238ca8b5098d3d9c0caab7b1e26efe42a6aebbc095471a', - 'id': '8695bcb906f5fd81d858794f7d90447aadaa38418d312e33115a81e856b34d12', - 'senderId': 'AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_47', - 'publicKey': '036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd' - } - }, - 'signature': '30450221009711559a43005c808113a1e9a01b1665495ff4bf30d635f7d98c752ead4cc3fc02207879e2a939914effe2b5c80cd515c4b3ff77a071b707c85c4444481878803db9', - 'id': '55853d2d2a98def00c5ab842866a44d1db91678a07b6dd63d062508db28a00a5', - 'senderId': 'AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_5', - 'publicKey': '026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565' - } - }, - 'signature': '3044022025ba51a588253524557547ec492d71bd485fe5b291e60eef681c39eaf8ee781702202bf24c3d295c7a2c9aed97a79fb835506797dcfe7e7a2853e2578e7773c7e134', - 'id': '553298aadf692c9c5d0334c307dd4ac0e277a49ed165c97ce1362f8ec639ee3f', - 'senderId': 'AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_19', - 'publicKey': '0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb' - } - }, - 'signature': '3044022041291ba10ad30fb9ebcb0e13902e92d85e2c3e98493b6d369d7d1e70e8474e31022009083444460c415eab6b4beed9e0206eb0733bad5d2a476af4db4f5b5e74b835', - 'id': '90af927db7b258538c8e21116b5a31418c88ecc163628b2b65fac92a5a949b14', - 'senderId': 'ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_42', - 'publicKey': '0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d' - } - }, - 'signature': '304402205d4111c87874e696b8f4b8897d0dfe68fabe4ad5c5769026c6ecdd04f09a1e2f02207b9c8a2a16b50164215eb1efea6d5d9f4e693cbb7eec8535e526cf8ba68bb796', - 'id': '8a920ebf5255a102d0c9c5fd720e0d36a6a3539991a2267442facf1fea2d0b86', - 'senderId': 'AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_10', - 'publicKey': '02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd' - } - }, - 'signature': '3045022100f15ff048872020d9efc561b8c837f542d54d43b9b071f7a6cc09643c6d4180f002207d0e82153a30b66f43fc4cb4b9b3093bb3d5dfd70f96928c8780c838b1448c19', - 'id': '30738f376aa40fb3c8d8849a5dc698786aeb1409fa801c18729f8da624631391', - 'senderId': 'AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_20', - 'publicKey': '02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751' - } - }, - 'signature': '3045022100babb7410d09215def98078bbab6b5e5690c2ebf54960d94527226ed3925877320220342576d1d8fd2d2fe3b6974cab48a2e16b4813f022b341b32f88e13f572bf060', - 'id': 'ccbe1c27eadc1b3b33f3f87f645be4f756021ee3d4c96f4f094e1f82d5728a3a', - 'senderId': 'ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_49', - 'publicKey': '032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374' - } - }, - 'signature': '3044022032f2c350cc1319f5838d6880e91b49ae0438fb3a626ed9ab5e27ce8788e3347c02202cca18567c8491e0feea8a5f078e28605029346c509fac0c0a192e934f8c5326', - 'id': 'f99af0fbb4d65c2c3f2c1c558f0c0c0eac2724942802fcde02fa6da1d3a9000c', - 'senderId': 'AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_3', - 'publicKey': '038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17' - } - }, - 'signature': '3045022100f0cb5d885ddf3bd4a58837f9b86486da4171652a5eb39228dfd0ff9d34d9c7c602202dc6e3d268d745a7e8633311a337ec097382342049672880c7c2215cf58e5da2', - 'id': '2dca03aed08533585d8bc609da5deb9f17ac9be5a8352769d7ae63d0db16ff59', - 'senderId': 'ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_21', - 'publicKey': '0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a' - } - }, - 'signature': '3045022100999f19fbdc9a12eebbb8c748a4cfc6c91b2233f333a09cddfd49dfeab6aaf38602203d8dc9d1551d400572a88ee812f51f897f8b35508713b789b2c1bf6dd0e88945', - 'id': '5d7e51d57b5914ec201ab65a019ecdf651c4f267cbffe403fd2170bb95145f9d', - 'senderId': 'Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_41', - 'publicKey': '03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f' - } - }, - 'signature': '3045022100e86e648add940a1e637e32ea9187497c281b843da09597e62d0c927d7f43235102200479f64ae63abb55e338f9ce1073a5c46907f7a2a82ea6f9bd9bc29811683515', - 'id': 'eaeed4133da26612c53550b6572722d8c3380d0a2344da1bd270eed1ea91fdf3', - 'senderId': 'AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_11', - 'publicKey': '0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904' - } - }, - 'signature': '3045022100bc3b2ebc58a92bf38672206e8311e7ef0e54912abce7338155b11e7d191b0b5d0220765a568c1fa4665c0ace6b4bd3b7ba0f8329e2f25af7a3cc0d78b2ea398084c3', - 'id': 'bb91e78e43c59a19ac06c015d8a7ef09d7c5b274c9f98505e5a978027354b71c', - 'senderId': 'AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_22', - 'publicKey': '03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a' - } - }, - 'signature': '3045022100aae4868ab75a33e4e77f9bf6c53b920c5e7c523a7cfe271d1afc472655f3d6a60220499f1bcb79bc0fa830dfa939898db5c9fa8571a2788c8de0da7e550bfc818bcc', - 'id': 'a6e687647dde9c1db68690090afc4fcf11833dd35fff3186b6b709a1e7d24260', - 'senderId': 'AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_46', - 'publicKey': '034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c' - } - }, - 'signature': '3045022100c0cf1fc54705c13f70fde39c55a1703a4c612b8a919379cd5b1ada464c7cc8de022074ee62490a184010ad2418d3177ff2ab03d02d2589000176312b90422b1bd64b', - 'id': '70262b0eec3ab5a60a736eb8a628cb600eae7522464a49791c0bf26e82318ec6', - 'senderId': 'AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_6', - 'publicKey': '0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc' - } - }, - 'signature': '3044022045db446b109215c6d3dfb0ee5869154a8a7624376c3760eec4fadc75a29033cf022003e524d64f3ccd0c6de4ca80a7327e2c47ffd16b3ad042bd25a02f5f64500ab7', - 'id': '56048c449694964bee3d367609a7bc46c8da20f66878c09c01dcc53c3abd932e', - 'senderId': 'Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_23', - 'publicKey': '034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a' - } - }, - 'signature': '3045022100f8f69f2957781ed02d64983744c8e51fae613ebe5bbb330d4f509bdcf4fc6b6602205568ad1fd840e01ec26a24ac9a0ff093e978172da55d494138d018a45eb67893', - 'id': 'e15dfc4e18106480083b3c6211349fd9c803e334e9ba5eb62cca19ae3f57d8e7', - 'senderId': 'AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_40', - 'publicKey': '022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689' - } - }, - 'signature': '3044022021eeb9e1db8915a9adb99db72972cd17fc7b5b377fc532ac2c9deffcb2707edf022068b9e08f45bbebad89295f520ad40d7786fe64059d45df95551576e3acb736d1', - 'id': '2bd0f888ccdeeca24a0134e3c1bf729582d284f32ee000d97f1417f1349a6594', - 'senderId': 'AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_12', - 'publicKey': '03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12' - } - }, - 'signature': '3044022040a9d0975f747df19792211546410d7c735aff2d26f367d1bf9233ffd1d993d702206890c66d4d0eb5de37df088c082d8fbd8da043817b48a76bd5d70f1e3f6b6529', - 'id': 'f75ac5ccd243e09fc9da2b3842a0654ca860d2dba5bb73866693a8a918937994', - 'senderId': 'AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_24', - 'publicKey': '039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95' - } - }, - 'signature': '30440220550c0ab565ab2de649ca7a2aaf2975453a1e4ab8b0d392d69663c0c9b6b80b7b022039047d4d1bf4e9b167a95adcde0a5a8631aeca060dfd426da28a10d968fb3a64', - 'id': 'aa2ed932faf4832848356beaf87e5381ee56a1a84fb485ba975acb28f8fcf5df', - 'senderId': 'AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_50', - 'publicKey': '030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1' - } - }, - 'signature': '3044022038df37ef25928d1a04516e982c99f49cbdc193603f814b48ab3802153bdd352002204c918915a3cbfa305c5f898ae4bcdd75394b57460f85c80daa0999751d466c08', - 'id': 'd30a726e1bb8d199d8f44700bc999c9a0a1a8be86e4be6a15764ecd424f9db1b', - 'senderId': 'APRiwbs17FdbaF8DYU9js2jChRehQc2e6P' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_2', - 'publicKey': '02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d' - } - }, - 'signature': '3044022028dd44b9609b0b599c15a257757fd068f9014e33947c77776a6fcbe71879271b02200b46fd8eb0827da6de13f5efd63b17f29e8ba4600e4a690ec31eb08bf2d9af33', - 'id': '1410b8b5f15c05528013378251bf5da30e04c8a6b7ac0f729b527664cfbdfbc4', - 'senderId': 'AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_25', - 'publicKey': '02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964' - } - }, - 'signature': '3044022038edfe34f7b89b4e69ea8b94e3335063b60deaee28246932147f53b2525924a402205b89f5e3d956aa49f24f81e2ba3447c19bd5c026568b3bef73a7a7d5160ad661', - 'id': '58d14b74b71586e18f0499a50004ec2e0cc2e5b56aa53f4cf57084030ff90fa3', - 'senderId': 'AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_39', - 'publicKey': '03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5' - } - }, - 'signature': '3045022100bc1e477994bf4cbcdb5cbe2bd92c7d955a03adfe562f8e3bf04d2f62965e9f78022045512772d8453314361161b2bd2a39aa0a7fbb897a5a83f4c7ab54ced615b42c', - 'id': '3ee53b3f1455ef0ddb52afe08854c9d87f42c7313babd3e05bb3ca4f94c495ef', - 'senderId': 'AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_13', - 'publicKey': '021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f' - } - }, - 'signature': '3044022052fe00e8e9f05b1d890f6910beab0627c823eb2d5875b4b9813a33aed11edfb6022034a723b827ce0e73bfdc0f535b244ffc983f8d549ee72b4d432de90d658db72e', - 'id': '4a3d204c2916c93360d7bb11390e355bc1a930e3cf503965a45253d65bfe928b', - 'senderId': 'ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_1', - 'publicKey': '03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37' - } - }, - 'signature': '3044022013b2798a4ab4d741850abac10d962360cd4ab6a47dfac7c1c806d6f9c3d810cc02202742414ad8a04ce679b445fcd040fb877bbfed3d2692b873dec8cb46c01c8c4c', - 'id': '7d0c5a44a7517f6ad7a1253db45d58e85aa1c735a282a32f45d28efdb7869d7e', - 'senderId': 'ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_45', - 'publicKey': '02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b' - } - }, - 'signature': '304402202c372b7b9679a8fe66f952a1d47d4327968d6e98770b215ada2fed6a8d87ed5502205a797fb511cfba557255dd37e028fb40981b7b65ad2ce8fe0e559a46eb274bf8', - 'id': '70bfe97ae7452dc752ab4de0e2a0e81bd18bef07392c56e7a101257683d4d932', - 'senderId': 'ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_7', - 'publicKey': '022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0' - } - }, - 'signature': '3044022058851712200f7386d6b3c188444f9c8f05788667649ec17c71b9e514206eb105022061e6a4bc4cd11599792e03298f95509893d56af54d51e9f639981045e754b974', - 'id': 'f6f90ff09dee5be7d8f3d58d217772df7a95865bf8609d7d5b0b673e9a5bc953', - 'senderId': 'AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_27', - 'publicKey': '02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d' - } - }, - 'signature': '304402204878d69a166e60e0a779c31fbc48c67b70d2e4aed1d63c60beb9f070963e2894022078c46b6687f23493a4c2ed39709a183a0f7352568cc9cc2c1f0d7bf0d809a4a4', - 'id': 'f68809e407d20a50029fe460d411c866b79c7e09c076dada768a38d81f184aa3', - 'senderId': 'ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_38', - 'publicKey': '0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294' - } - }, - 'signature': '3045022100d5576393a1dea704cf79a5d0bc2757a3a5e66e1055103b52157fca05fc5693ec0220522832ce0e31b779decef83ac8ce764930de927df9ae1d6f6f99a3312d99c90c', - 'id': '2ec6c6f33f00431ef063fbb8a79fb90eadb13a79bf46e6e1df36dd9434314df0', - 'senderId': 'ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_14', - 'publicKey': '03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24' - } - }, - 'signature': '3044022008a7d0bfe9c4c150566ddf701d08e84b4a5f84b07e3b1c91dde1cefa16d2a3c202200b787e898c0b2c68f4343e74f18ae7363f62b5f4ef2962386932aee09a9fa0d4', - 'id': 'e37b3efbf034bea4c852be7d7013978f8999eacc39549ceea775de197e14e8da', - 'senderId': 'AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_28', - 'publicKey': '03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28' - } - }, - 'signature': '3044022023b6fbfa5f4482a4dcc34411846696052b1592786ca87243b7d3344fc9fe9954022035402fbca22691de2497552c743f0f68c7591edd1bd7954ab7639548fcd558a3', - 'id': '08268f5e6c15cf146523ca928f24aca65b162f363593d927c66144ee5df297cc', - 'senderId': 'AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_48', - 'publicKey': '03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b' - } - }, - 'signature': '3045022100b3cad169f29a3a95995b87e1b50b35583c1bff91d69cfa236f58ce452491c579022026775f4ef50b50ecf6d78b530b4633711394983456e6a45ec227b652c86e3014', - 'id': 'ad94ee2ae94813a638b93909930c7cc631c364b6c8528b2dcd6fa8f69260cc2d', - 'senderId': 'AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_4', - 'publicKey': '03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93' - } - }, - 'signature': '3044022007ac9ff2f272f3fda4947393b8688586cc8b2958ff5dc7931ac8f82c697bb76802202a66c28852bbff86ef17ac7f51e7eee52e611e825d91a9846f531ab3c3115c81', - 'id': '76fb1984da9ef90fd7d588756163c97e00d3e4d6e9dfe78d9e3d3cb6d71ddd38', - 'senderId': 'ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_29', - 'publicKey': '0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252' - } - }, - 'signature': '304402204416e428688ad29928303fb2b00a26996cf79753fe70fb91c1f4635c644ba859022068ac5eab7d05f87c40ba36bd9dc149607c196778120c061698d7ab64aaade7ac', - 'id': '0f442a91857061e87dd193b0b9f17a71719ca7e3da62841a63568713fc12b5e7', - 'senderId': 'Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_37', - 'publicKey': '030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4' - } - }, - 'signature': '304402206a248caa5949024202f297c38cee18845e344c5f140be74349787097d3b0a33c02207ac84336e02592bb5e00dcd0c490d30eb856b34177ab9ac03410d82a355a7b0d', - 'id': 'eed30a45c350fdffc5877458f7fe29f28dc4bf81aa1a197d003c9433148b71aa', - 'senderId': 'AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_15', - 'publicKey': '02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca' - } - }, - 'signature': '3045022100c99336ce666cb4a6db3727a61c04c14d8746365f72280d9984441b7d2b568b5402201759e4f417f683743e1d4a14f8a7a215009321cdfa29834b2dbdbe54ee22c1d9', - 'id': 'ecfba14a58f9d79782c4f905646df28bf566e3e7d1f17b39df6fe6b52c11de59', - 'senderId': 'AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_30', - 'publicKey': '02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883' - } - }, - 'signature': '3044022070de7b4d4ce64bd605c9d008142544c2b113cc84df07ed1982e0adf3cf69f4520220211b01710a6533a270dc2814c7f968adf27eb6dbf437e7a72960b013b9651a0c', - 'id': '36ce5323859a92f302f77f27bd08ee3485d720f55842ccba353a47ea96a964c2', - 'senderId': 'AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_44', - 'publicKey': '022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c' - } - }, - 'signature': '3045022100a7c271633ecbf3c6641c7db36913b5fa0ea521f400a4848edf024648f3d7128002206a271f8a88644062b64d856407af9567c0b2937d4a3d89a3b3d07edbd3a0f177', - 'id': 'e120452e7c56a9327b2be7dfd3dcecae193f2e2e772903008b03cdf00146ebd1', - 'senderId': 'AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_8', - 'publicKey': '03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564' - } - }, - 'signature': '304402200394b6545015bcf2d0f291de57a4197cb6ef57b2ad5fa37f05e8a220913ba83502204d0d2f2206edba54ada5b8e5afd194ba83dd1bf15f744258409595251dbe3ff0', - 'id': '7d15eee8e4e3be3d2c44acd51b87a816bdb593565d4ac358dab24ae9c8a5bae2', - 'senderId': 'AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_31', - 'publicKey': '03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2' - } - }, - 'signature': '3045022100989eb331951a13152aa03583efc765499e836c6fbafcafec4302b243ada8de5002203876fc4cf7fdeee4a095667e55a2fef84e5a7053e807b4d8e029883f0d578019', - 'id': 'baa686d521f95d265e7099cfd9ef14e0a9a92254dd94c16ce50c460bd013c588', - 'senderId': 'ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_36', - 'publicKey': '0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e' - } - }, - 'signature': '304402202be177dddfad323302565a866d38a3e7939e0234b16e7dc02075cf258502eba302200928a139ec1a82b4609fcc1bd6d1d027ad050e93fcd2eff94181936d2d43e39c', - 'id': '9fcf7ec6fe98ed94710e212226d8b90df7e7467d66dd4c5c9d48474388be3099', - 'senderId': 'ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_16', - 'publicKey': '02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9' - } - }, - 'signature': '304402207b4f8c09a728acedf3b6ba0632e12d01670c683215053e49dde8598954d85a9a02202a7d7930baa17c2134b314e47dd6c334c828f78e573a2bf92fcbc1146d630541', - 'id': 'c35e4b1e7a2435664fc0939251c2052633ebf4b51fb22d15e71bfcab85b26de9', - 'senderId': 'AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_32', - 'publicKey': '0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055' - } - }, - 'signature': '30440220127d27312345e015c681adb799c1a87d16fb0caaabd5020b39257d567816b91c022018b2388f6d2d9afb3714d84ed102b3ea61159772786033c855947613c7ce7b5b', - 'id': '0d682a3a9c252a674043bee5240e456dae2685d76fbd3bdeda6ff50f0c442fff', - 'senderId': 'AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_51', - 'publicKey': '02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a' - } - }, - 'signature': '304402203d0ee691830e4d001553bf4e49b6d9669b3c959376f391410551c8adc679dac902203ba6e275bf6d543efd19d20428649f802d9396bb0967114a1f09c24827be1da7', - 'id': 'ec2373b0d609ae72fb400ffdfbffc59670ebbf1c15f59c0ac22a4030dae700e3', - 'senderId': 'AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_26', - 'publicKey': '02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983' - } - }, - 'signature': '3045022100f2cf77b0510f589b5aaaf2b0027ffbce6ce8d4873cdc67dc8900865d156de3be02203c22e30945618683182f3d3873e6b3657e0900b062f866bab2705cd593669e79', - 'id': '3cb2f0f7d05a515d4c5c873cbe96e33b1dfba1b7718e4548de7f9da54933b652', - 'senderId': 'AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_33', - 'publicKey': '03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe' - } - }, - 'signature': '304402201e328159172d543d2225c247c6b728800c52eb724f67c0e919f6b7215e6bd7f2022075fc02fe0b14a1499c5602d87ca2c99d6e789beaceed2b9702060dece872d14a', - 'id': '2fd77e744399c9632cc8f106c39237f201dafda976f1040235359f99eea3b832', - 'senderId': 'AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_35', - 'publicKey': '032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e' - } - }, - 'signature': '3044022063903d82e8bd15a6741a298b9a6007d0dc3626acfe2f072c3b624ccbf91ce3360220486ba4cc5591d8aa31b77dfde025b61691dbaad0feabe13e840d26e40010c5df', - 'id': '5baf9e318c9e4cb0513a21eaea27e51c849f95fddc963207fb07aa2fd2b9f9d4', - 'senderId': 'AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_17', - 'publicKey': '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357' - } - }, - 'signature': '3045022100efc1bc16e0b646da48f84822543b62ef5253bfa98bed6613f2d6d4634076e61802200ef243f9dbac7633a8819ce45e2a85d0eacfdc9a33a92bd3a03e90cbd312b823', - 'id': 'b4a959ad75f81b7fdbb957c90a3a63a6c5589e7819e2c455733a3a2b4b034634', - 'senderId': 'AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_34', - 'publicKey': '030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80' - } - }, - 'signature': '3044022012e52a479648990bfc1ed12bf901cad865708ff45962c3724ea67967be4f9d0102201901525ed8dd090af6a2637c123afb304e9fd178794addcb88d916227e66887d', - 'id': '6439f2308efe31ac52ad06ef1caa45b9abf6c589118b7997da6a287325ca36e7', - 'senderId': 'AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_43', - 'publicKey': '034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e' - } - }, - 'signature': '3045022100a0874d1582ce210081f7ab30e7f951dfb9ce8f512d237f8a8cbd5d85569ef3b902200f0053c05de3d6e5ada4e4cf1403a836779d653573c2f374055645cc954c4c4a', - 'id': 'b0733072e98d3d6afe977e32f3dd118c15e79212232417743ffb551dc2a2ba55', - 'senderId': 'AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW', - 'senderPublicKey': '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357' - ] - }, - 'signature': '30440220158ed59156e0eef2d2b94a296451dffe079be701b3d74f0443ef43bc266b334202205a2c39f57abfcd279d568608b90884b3ebe107316aa7552eca35c743b318a47c', - 'id': 'ea294b610e51efb3ceb4229f27bf773e87f41d21b6bb1f3bf68629ffd652c2d3', - 'senderId': 'AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7', - 'senderPublicKey': '030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80' - ] - }, - 'signature': '3045022100898da9f693a458a6875344c6c4cb73069c4075904c75595ffbc665967d84b07002200f168aaf3ab1b52dfa74599394387dc4cf627a447fbc5a91000e9d251cdb20c0', - 'id': '3639b5dc6d19d46d8254d941bf7ace0f3da8a7cf8a56361921b260820c7239cd', - 'senderId': 'AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1', - 'senderPublicKey': '032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e' - ] - }, - 'signature': '3044022055ed9a8b55ccb3bd0945a710269b6f243f1dbfaa28467d3218a17565eb0c962d02207d31561478f16d93a20f5454ad565dea24e8dda4ddc464cb011f4b6b360c4e81', - 'id': 'fe24509580cde0c2e2f49defedd3a0f7572d2f78f90b51a253b0d8cebd74c20d', - 'senderId': 'AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof', - 'senderPublicKey': '0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055' - ] - }, - 'signature': '30440220092f367f833d677e8d0609ad1df65f389c2c35d1501c71c245c2982e6a832268022018e67445f525613d6cb6ac0c9683bd0f55bd40d9c929165649414f083c9041f9', - 'id': '6a76553db794ebf4d5f60a7d7d71cfe29f4dbcaad9610106fbc578cdc7167cd4', - 'senderId': 'AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy', - 'senderPublicKey': '03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2' - ] - }, - 'signature': '304402203dc028b5013c36b03f97b111a8d7c05d0cd8e505b0b0d18747c0656c9b5cfe8102205e9ce8a78d1183b3e9880c69635d04218d94d17808bcc3f92e7af53195c23daf', - 'id': '0f9d7e7708918b77afbdfffb63eef8fe87ba36e0131c88b44c1a7f81750cc025', - 'senderId': 'ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9', - 'senderPublicKey': '0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e' - ] - }, - 'signature': '3045022100a80ddd7c3adaf0e97ab938773fc78a716f3054d7e03afc1ddfcb5005badbd2810220231c0dabe2262149f994c939f9dc90d46b9bd7ca96b19aad6788cd3571e4f71a', - 'id': '0ac77b2637fb25be42b3b60d1651bbbd788aeaba933a08ec4a417c7b4c54e087', - 'senderId': 'ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT', - 'senderPublicKey': '02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883' - ] - }, - 'signature': '30440220772c9cd8b96f74fcddc429d57d466eca6fc40fc211845f59eeb78cb027e116c5022004cda291587eb118d622de21333d2a5783969794b5b0101ad8b1044c7d8058af', - 'id': '4b0dda465564d53981c0e36d73caec888e3523633eaa80dfb99a9c81b2604c7d', - 'senderId': 'AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU', - 'senderPublicKey': '0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252' - ] - }, - 'signature': '30440220406d54714b6425ae4553ea8bec75f31fe52e9b1a9b6f6897151253ab7f637d3b022040a2df4b69840f4d9b0b67658c75efdae8d8269780d4cc50d055fa63922dbb9a', - 'id': 'c7db9d36d97ff0168d0d670ec695e1dc786dfb93f4081586870c8793b50e5f17', - 'senderId': 'Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK', - 'senderPublicKey': '030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4' - ] - }, - 'signature': '3044022018b7e51118ec83c985fa4eb3d7f0cf0655753bcbde7e82bac521665fb1c0ffaf02204e2ace460b2542db8c77e41d05d5e02fa5514b746a0a1e947256925846ed19f1', - 'id': 'c41f4cffcdd523f1718154d5bd5f4f0bec0376076b5f8dd340337e9edb4821ae', - 'senderId': 'AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW', - 'senderPublicKey': '03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28' - ] - }, - 'signature': '304502210088dbe249503da43c157485bfd4f2c95babfe4d0b8bbefe44afa52529b824a79e022045239b6a374fd9aca52c27171ee66b4863c956ae4085c9760d863b1902596c1a', - 'id': 'b1736ec6a1ea4c6d4eb278430a8ee214c88daefe296ba98530e692f8b7a7434c', - 'senderId': 'AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej', - 'senderPublicKey': '02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d' - ] - }, - 'signature': '3045022100fcdf750a775e728a31691a1b38908a7f990b579da510959cc2c63442f5ffde760220316ebb051d9fecb2486771dd39921fb12675b6d46b2441dd1db3c42fad0a59b0', - 'id': '069271456015c2ff842771775993b8afc3404bc070572eeeb0f2fd72d58e18dc', - 'senderId': 'ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U', - 'senderPublicKey': '0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294' - ] - }, - 'signature': '3044022034ce8f77ea9d0f5cf3a9135d7b72d0ba3b96ac6d7eaa3670e9956aef2c9a83cb0220626d1f269128f673a23f9993ce00ba78a08103e697298be29a4c8ee94f204e3a', - 'id': '9a99bba8340e7ad4e05d8424a0977ebbde428d31ee066c9828bd06b42bb42a72', - 'senderId': 'ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2', - 'senderPublicKey': '02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983' - ] - }, - 'signature': '3044022039ae1155f8b87a61c38b25cbbf30da6ecf6cfcc12b25c2e7fe576373754a41eb0220061a66a893129fbad5d48cdd19cf48b1a0d133dd2f3ecdc60ee7b87277e1f81d', - 'id': '6c2c8926420ac269b50fa30127e0e791afb2131aff5821ca7aa80d38a0182048', - 'senderId': 'AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf', - 'senderPublicKey': '02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964' - ] - }, - 'signature': '3045022100d0dac2b7691aa059b1048d7925a0c5d5099f6e9b0f2e321e6d4f128ab1b3272b02207e8c4f643f8f9d1c3f81f0cce6a698df2da2ab71d5b01042766bbe0f46f4a775', - 'id': '9259193c5de72276ed7a99f9d507dd6ea9856411fda521074fb41a556294fdf7', - 'senderId': 'AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9', - 'senderPublicKey': '03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5' - ] - }, - 'signature': '3045022100d5496fec447367ab6b53956a8c40cd8566e050ebb3b92d2c0b2a9d09bef36c7402205e32367605372375801f7b9db39aaafb46ee763b1494f0aca144fb91f3415752', - 'id': '2a41e5946ab0773ca2334bba9d3510184bdd258f1c651ff8ec95b7b64a01dc2e', - 'senderId': 'AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW', - 'senderPublicKey': '039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95' - ] - }, - 'signature': '304502210099249695dc38826e04c8fcffd2570b98c43dec4788cc6a19737ed0872f17ec3302205301f645d803ad5df4ab1a700446e28c7cd76153607f6a2d68ae9168d46f3fe9', - 'id': 'e5c09b0fb2c24c57a4dcef0078953093800329ab4dc8e16a9d9f68215b5acd3d', - 'senderId': 'AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU', - 'senderPublicKey': '034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a' - ] - }, - 'signature': '3045022100f983b03e319aaa6c6ab6381e3ef8c0c035d6e3cc2139cedf70fd4e385393e38a0220286f73577765eb3e89e362785ad8a6de572bebf41bbc1f515b0ea93e41801eb3', - 'id': '00b2c0455ef6f508d65f11bb49e3cfe1e6062d5fd153cafdfdfd2ccbf9c646e5', - 'senderId': 'AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr', - 'senderPublicKey': '022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689' - ] - }, - 'signature': '30440220103862ec51621ca27a0ec6b2817848e8824d2d09dbf7e6aac2f45aeea5d2dc9102205e8cce78b5cd7148aa4d406dc7b491dd7758047200e10cfe1e5fde5c56107ac5', - 'id': 'e25439ad11cb8db3d49ccb3b8b608c1bcb24cb29b2e5ea15101cce3e475224eb', - 'senderId': 'AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ', - 'senderPublicKey': '03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a' - ] - }, - 'signature': '304502210099241ced4a0fd1eb02f5cdcc880ae5f48eb3c7e490d4520c20124ecbf403893602204729dc6cacf3e87c97ca57c1be54d1e80791bf31ef022135e68fc06c950f6994', - 'id': '1474f50815c6c7df41ab652414806d61abe15bee0d41f32d772f4e2793badce4', - 'senderId': 'AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX', - 'senderPublicKey': '0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a' - ] - }, - 'signature': '3045022100eccf81d44992c49a5ee37c6fc2ccc4b6bee9aa44888513b3e18e79452ede3156022056b0ddf079d2918d72e8781d3af009c87e6058563591dfd6ee0117b7df5534b2', - 'id': 'b394e2a8b5c2d20a72ed288408b8f0d48aed922edbee6e16c1c5b0e67517214c', - 'senderId': 'Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf', - 'senderPublicKey': '03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f' - ] - }, - 'signature': '3045022100bdb87894846eccc5a5473edaee1e6dca5f3469963e22f06123b6bde195aede0e02203d0c6833e87c5e60f4597ce624d4c2502a0562b4e54d943f82a4889e3cd69532', - 'id': '6a399099bac6c74fa5e956512ef8b3a39f6f946d5d6996f192c2f1dd5ba172dc', - 'senderId': 'AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv', - 'senderPublicKey': '02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751' - ] - }, - 'signature': '304402200785771ccf1a6a40b51183a190d4cb4ce76b9ffd4c2c736d7724e6c667113d020220649ecfe73017d8dda96a7914793470ee7e582693e4866df123b1032194c163b1', - 'id': 'f20a831a6bae0a85470e308fb66517e70db479657459f6bb39f2cd1783c565e6', - 'senderId': 'ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv', - 'senderPublicKey': '0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb' - ] - }, - 'signature': '3044022020b79e1f07bcb17cae9485b9f44e9f583ca235da4ddd363b905fafb884347f71022015a20481b43720ddb3b1e3ca64b1f47e59b5cc2016a62f43327ca14533384dd4', - 'id': '7a1285be87dca9718bece5b84266c1bf6801a39cc111d534e660aef9e6d26929', - 'senderId': 'ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg', - 'senderPublicKey': '0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d' - ] - }, - 'signature': '3045022100b1615d16763c46d42ca2aae967f04c1c07c119b5af7a378c262ba85515a8d35002202cf7df91676cd137943720e93f06c11907412a6bdc5ef2157cf536a203cf83a3', - 'id': '76fb5a1de90f245b1eeb79cb11c7bea7c8b738add0fb8cd95191186a944b0229', - 'senderId': 'AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri', - 'senderPublicKey': '02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a' - ] - }, - 'signature': '3045022100e3c7b5d6a72acde4d22e8c1c6cd864c549deba89683f4b84320407d6c380827c02202da57df0ab7cd381b776bdf85802aed371e7cea7269a84f911b1d8e9956badee', - 'id': '8da75c8100e6248ab37cc92f72ed9facec3067f4f82f03db8bb8063791463fb3', - 'senderId': 'AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t', - 'senderPublicKey': '03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe' - ] - }, - 'signature': '304402205779b5d8acbfedfc105fedb6fcbd4636713ed27605faa9bd988598072640a958022042d8a8b3d7910c7c385f3707a317c5d445d56da250f8d127c71df2d9d4c5d86e', - 'id': 'fd26e265be88289828d0ce7ffc5faeb9849e1f4cb37a8f1dd5d6fcc436d910b7', - 'senderId': 'AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf', - 'senderPublicKey': '034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e' - ] - }, - 'signature': '3045022100e18a89fe1fe0a8acaca2b6461314e784ffebbe7374f6aafdb06934e83985ccbf022027314b21a4a25b477bd7cc070b4e00ef8f3d69f3f1af028b96571dc245924c00', - 'id': '41d92e128e6b8367cbf8fd111e5263d52e1abad553653f975dd60d7f7c5b637b', - 'senderId': 'AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9', - 'senderPublicKey': '02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9' - ] - }, - 'signature': '304402201c614c84dbae26f87973c9e2b38df883fe0c8c469080e31fe32a4c4946d50b67022075b8fb498fb1384aa6be785845da02813185ccf095597b5782618033828af4d5', - 'id': '1e4a1f8aab6fbf8682c2b35e0d04e9e007ae717ce3f4a82894747e5807e3c759', - 'senderId': 'AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV', - 'senderPublicKey': '02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca' - ] - }, - 'signature': '3045022100b1ee6becc59d594776a40e5b3caec82390d273b703ecb0d7caece44953141449022016543cc29a28882845118afab6e51296cd216bc662260c28e5efd9597b6025b1', - 'id': '2ce068bfccb3f967f4004e9a1e81614a738e55e45c80114c0af30a085f71a2e9', - 'senderId': 'AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ', - 'senderPublicKey': '022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c' - ] - }, - 'signature': '3044022036698a329d7f5f751f91ce02bc188a7527a377d01583b70427cfce64def945ec022079afafea10aa32394a1e42a80577de3869856656221d5f259e05fb44f01668b8', - 'id': '3478d1ad3655e10fcc864f191972322c866616866bb1dbf66d7b66b31cd95de6', - 'senderId': 'AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA', - 'senderPublicKey': '03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24' - ] - }, - 'signature': '3044022035fa7be80cf881eefefc12b11de04ffb2e2e92815cf05074afef54a3c5b2eccb022041f3347f59db0b3caadefcbfbc5ae275d3fe3e2a52fe1504b23628d4b79a43bf', - 'id': '8adfd8e73e96188ed9fdec459d88db1fb041a2b25b3f64830476aec661ae5010', - 'senderId': 'AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm', - 'senderPublicKey': '021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f' - ] - }, - 'signature': '30440220630da8a73979bd3988b7f84fe9e83a429cf3239f54c140c3dbcc407140513fc002203664ad54ed9f199f2683479b988bd97ad8fffb2c2d5dfdbdb10858aca4abfaca', - 'id': 'e306328ffefcd9e3809e7390a358199a62cf8ef037d57af1f5c7b54d728d427e', - 'senderId': 'ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1', - 'senderPublicKey': '02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b' - ] - }, - 'signature': '304402206f1df93f299ffedacc25aa201807df47d32c43369315cf9db280963c357be56302206a66acd553710f49bbb7b803a2bcb71128c8e617ffce66b37b7c968817349247', - 'id': 'dc69bc8f78502ba34655ed062987788939189709a4112760cd8807245d7461f5', - 'senderId': 'ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8', - 'senderPublicKey': '03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12' - ] - }, - 'signature': '30440220629e696a10e04d4fbc10a5ac443bf9bd40dd5d89d4b214224abe47d7ab5600340220643f361a24d9916e2c5aaec7bd7d8a6a0d3ffc5fc0b62c3ac4906eb799a862fa', - 'id': 'c3f49fb80c40f7779b32ba23616f5573a6ba58fc60c4629c2252933038dd89f0', - 'senderId': 'AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2', - 'senderPublicKey': '0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904' - ] - }, - 'signature': '30440220660f9604896dad2a97820b0d7524f0bce5a8b5766f150517d5061fd02bddf768022055e87c25891d4480e66e5d1a71e42cd5a4bef3ab2b2651cd72d44f30a4b32309', - 'id': '8e8ac1b1a586e86867abbf25d63387bb6dfb793c691f0b06333c1581a9a568b3', - 'senderId': 'AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT', - 'senderPublicKey': '034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c' - ] - }, - 'signature': '304402202e2ad64129f61ef1156c4c7e80ab862d4823d62dac502685f53028536ddfb41a02201a3ec777fdfe8fae9f7cd5251fac322c1b6a2a4d41b3ec456daed474986d4872', - 'id': 'ff73565c373f2cefebf86c72dda3a6a6205750eb03b69178cb83378620715e1d', - 'senderId': 'AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q', - 'senderPublicKey': '02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd' - ] - }, - 'signature': '304402202e5c78cf21a088db10e1e1f64d98d84c8d3294fde7bc322d4af06bfe99d4c2e302207e7912a16a37b641a9f8c7c722f2b0d699917ca73e4d0f21584b717fb7f02f13', - 'id': '3822273b496f2e253081cedf382e4f9937713fabb83449e1f892377cf536e68a', - 'senderId': 'AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo', - 'senderPublicKey': '0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647' - ] - }, - 'signature': '3045022100a65ce45164c9bc3e018e26703370c9deb2933ee3b4e814619043cc37c4a39c4802205ae4931ac9e8dffd714c3b601fe248a49c0185c8367887205f497d951c52eb54', - 'id': '430d6db0b87c25dce4ce14ac907c13bcc6efa5d95135f05aa4ba7596ea9d400c', - 'senderId': 'AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN', - 'senderPublicKey': '036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd' - ] - }, - 'signature': '3045022100f3cdd7f688ad2d7b6a5b9cc7e793cb8a6e6e07d3327bc67add64691a53fd2911022026ae1adc8f4fcfc01bcca3efc83019026755b443a504265ad1f46f69d1f5951c', - 'id': 'dda86ecc0332e6c4eed1c0a5af7424374089b85dd274a300fed51b86e2655587', - 'senderId': 'AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj', - 'senderPublicKey': '03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564' - ] - }, - 'signature': '3045022100d419072a752acd55792257c96099fb14c56c29112a00535d39bca96fbd7951c902201abdf4db247dc956d79f4543c389823fbd1a9337f95d30df39603a3b52486bfb', - 'id': '0998e9a055c53bf6697ee76af94c7a830c1364016d78fce889a21bc38ed70cd5', - 'senderId': 'AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN', - 'senderPublicKey': '022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0' - ] - }, - 'signature': '3045022100ba1e0ab761326d2a53cbda2a4a5135033c94d8166864d2ad3ceb963b4a0c046402207d755ecf4ada9fa2a598fd75e73a59d30cb83e01f510020b48b6bf162dc60b27', - 'id': 'be13743deb8486a575d1fb564d2b07d797ac77148d35793c9aca43c0d47aad61', - 'senderId': 'AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA', - 'senderPublicKey': '03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b' - ] - }, - 'signature': '3044022038a491e2e13ac32025209d00aec1af31b73a8b6ee77ad9b8bb80a34f5df59dfc02200ce82c89fe9f88bd5af236ceeaa80f9954e3fb4af7bc884c447505751d49c134', - 'id': 'f1d3d44cc289837de9623cba8891a1ed1cde8918473a91e2daead29975afad22', - 'senderId': 'AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx', - 'senderPublicKey': '0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc' - ] - }, - 'signature': '304402202ae599ce389cd030b8ab48ef53113458b9ba8bf9c9ed09c662eba2849bf540f802202ed63f8af492dd0b67d1b451170a989418a42466a3a7ffe89c4c5a18337e8fb9', - 'id': '65ab302a44ea7550891eabc3b4a8d5ecbcb80784c4666195d5d0b7e33394300d', - 'senderId': 'Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK', - 'senderPublicKey': '026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565' - ] - }, - 'signature': '304502210088a3a4e82d307c238e01ce154b57631d4429e0b591e828ec36839a783736e842022042c6e1d719781e2edca3dbfe84ad13b9e490821a47ccadfcff379decb9c873c0', - 'id': 'd26a7ea56f398634a81086bb15c2f0c863c71b8bd728304d324d8245a8fb6c73', - 'senderId': 'AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz', - 'senderPublicKey': '032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374' - ] - }, - 'signature': '3045022100ae5805541f085a50076835422b2581d3b7a128a05b4f068ad7e3c14cd02799b802205f4bb40e06f90e02282ae74c0aba97923e601fd78234b9585468c4fb73f47893', - 'id': '02504eae7ff4963c081219523bc48d7a07de4c29fdc1622224547f9a7c133abf', - 'senderId': 'AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp', - 'senderPublicKey': '03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93' - ] - }, - 'signature': '3044022078d38cabd8f427ef381d0aa6a0b98c6a590cb18f47acc1d80b429a1c1959b0ab022022a70d4d93d650ca3121dde6065e80cd90d1e2e91cb90f0d0b2eadde609e0d75', - 'id': 'addb8c1baa833baa52a5b51d8a86f8524bde826b5c9f0a99e57070e6323e1dfc', - 'senderId': 'ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv', - 'senderPublicKey': '038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17' - ] - }, - 'signature': '3044022076dd065e3fba825b77884a179d0231d7fc9e7d3a02e34bc6565fab81a84e559e02200a880c028e690a9d6f2c4c6576b1bf3e913817c834da8ec6afdbadfae78d341d', - 'id': '72f31f9a829b93045ef2e860b24c33b9be6a2621c26914acd42121215c1d517e', - 'senderId': 'ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'APRiwbs17FdbaF8DYU9js2jChRehQc2e6P', - 'senderPublicKey': '030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1' - ] - }, - 'signature': '304402205261d9d8ded6364fda8b10bd477982be84990cb010f9214d52c492676814e1f40220489f441ffe2478d361a12ab96caa59da495fe62d61d0e2255aa5ec4ed789afb8', - 'id': '1f17b4ba072d205761ed3f786491eaf684ed3601b69082e487e568aa74a319e8', - 'senderId': 'APRiwbs17FdbaF8DYU9js2jChRehQc2e6P' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd', - 'senderPublicKey': '02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d' - ] - }, - 'signature': '3044022040219da41054a3eebd3122df7f09a62a4e8b4fdc287ae77221f2217b42f291ad02202b9a70c54bb546a604eafadcc086ef6b6570f57542374d87de02ad7f61fe51a4', - 'id': '5fa837023159d6a3d6cf7c5b2ed6fe05ff7df19300226b2f0be5a48a06993780', - 'senderId': 'AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo', - 'senderPublicKey': '03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37' - ] - }, - 'signature': '3045022100ded426768f114f459485ba6ae293c9649b340cf2dcb15e8e887fbb5fed6f7e0b0220752297022de6e93ff64bb9e07b4efef8e946cd2872f84d9e1cb3165ff5c342cb', - 'id': '0a16dc31514629a36d7237968ada6a95d6cbec027b7d26e1e0f0d7d4febe9494', - 'senderId': 'ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD', - 'senderPublicKey': '02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a' - ] - }, - 'signature': '304402203aa292e7aedcd62bb5a79c2521b666b8e1886b57923d98f51911b0461cfdb5db0220539657d5c1dcb78c2c86376da87cc0db428e03c53da3f4f64ebe7115998f00b6', - 'id': '8816f8d8c257ea0c951deba911266394b0f2614df023f8b4ffd9da43d36efd9d', - 'senderId': 'AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD' - }], - 'height': 1, - 'id': '17184958558311101492', - 'blockSignature': '304402202fe5de5697fa25d3d3c0cb24617ac02ddfb1c915ee9194a89f8392f948c6076402200d07c5244642fe36afa53fb2d048735f1adfa623e8fa4760487e5f72e17d253b' -}) diff --git a/packages/core-database-sequelize/__tests__/__support__/matchers/block-table-row.js b/packages/core-database-sequelize/__tests__/__support__/matchers/block-table-row.js deleted file mode 100644 index 5b0b80c316..0000000000 --- a/packages/core-database-sequelize/__tests__/__support__/matchers/block-table-row.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict' - -module.exports = (actual, expected) => { - const allowed = ['id', 'version', 'timestamp', 'previousBlock', 'height', 'numberOfTransactions', 'totalAmount', 'totalFee', 'reward', 'payloadLength', 'payloadHash', 'generatorPublicKey', 'blockSignature'] - const notAllowed = ['createdAt', 'updatedAt'] - - return { - message: () => `Expected ${JSON.stringify(actual)} to be a block table row`, - pass: allowed.every(key => actual.hasOwnProperty(key)) && notAllowed.every(key => !actual.hasOwnProperty(key)) - } -} diff --git a/packages/core-database-sequelize/__tests__/__support__/matchers/minimal-transaction-fields.js b/packages/core-database-sequelize/__tests__/__support__/matchers/minimal-transaction-fields.js deleted file mode 100644 index 536d9cfa6f..0000000000 --- a/packages/core-database-sequelize/__tests__/__support__/matchers/minimal-transaction-fields.js +++ /dev/null @@ -1,14 +0,0 @@ -'use strict' - -const { isEqual, sortBy } = require('lodash') - -module.exports = (actual, expected) => { - // TODO deserialize transaction and compare with expected - const allowedKeys = sortBy(['blockId', 'serialized']) - const actualKeys = Object.keys(actual).filter(key => allowedKeys.includes(key)) - - return { - message: () => `Expected ${actual} to be a valid object with the minimal transaction fields (blockId and serialized)`, - pass: isEqual(sortBy(actualKeys), allowedKeys) - } -} diff --git a/packages/core-database-sequelize/__tests__/__support__/setup.js b/packages/core-database-sequelize/__tests__/__support__/setup.js deleted file mode 100644 index 385c31a0ee..0000000000 --- a/packages/core-database-sequelize/__tests__/__support__/setup.js +++ /dev/null @@ -1,28 +0,0 @@ -'use strict' - -const path = require('path') -const container = require('@arkecosystem/core-container') - -exports.setUp = async () => { - jest.setTimeout(10000) - - process.env.ARK_SKIP_BLOCKCHAIN = true - - await container.setUp({ - data: '~/.ark', - config: path.resolve(__dirname, '../../../core/lib/config/testnet'), - token: 'ark', - network: 'testnet' - }, { - exit: '@arkecosystem/core-blockchain', - exclude: [ - '@arkecosystem/core-p2p', - '@arkecosystem/core-transaction-pool', - '@arkecosystem/core-transaction-pool-redis' - ] - }) -} - -exports.tearDown = async () => { - await container.tearDown() -} diff --git a/packages/core-database-sequelize/__tests__/__support__/utils/create-connection.js b/packages/core-database-sequelize/__tests__/__support__/utils/create-connection.js deleted file mode 100644 index 58c783329e..0000000000 --- a/packages/core-database-sequelize/__tests__/__support__/utils/create-connection.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = async () => { - const sequelize = new (require('../../../lib/connection'))({ - dialect: 'sqlite', - storage: ':memory:' - }) - - return sequelize.make() -} diff --git a/packages/core-database-sequelize/__tests__/__support__/utils/generate-round.js b/packages/core-database-sequelize/__tests__/__support__/utils/generate-round.js deleted file mode 100644 index 0904a056bc..0000000000 --- a/packages/core-database-sequelize/__tests__/__support__/utils/generate-round.js +++ /dev/null @@ -1,13 +0,0 @@ -module.exports = (delegates, round) => { - const roundForgers = [] - - for (let i = 0; i < delegates.length; i++) { - roundForgers.push({ - round: round, - publicKey: delegates[i], - balance: '245098000000000' - }) - } - - return roundForgers -} diff --git a/packages/core-database-sequelize/__tests__/connection.test.js b/packages/core-database-sequelize/__tests__/connection.test.js deleted file mode 100644 index 39c3df966c..0000000000 --- a/packages/core-database-sequelize/__tests__/connection.test.js +++ /dev/null @@ -1,579 +0,0 @@ -'use strict' - -const app = require('./__support__/setup') -const generateRound = require('./__support__/utils/generate-round') -const createConnection = require('./__support__/utils/create-connection') -const activeDelegates = require('./__fixtures__/delegates.json') -const { Transaction } = require('@arkecosystem/crypto').models - -let genesisBlock -let Connection -let connection - -beforeAll(async () => { - await app.setUp() - - Connection = require('../lib/connection') - - // Create the genesis block after the setup has finished or else it uses a potentially - // wrong network config. - genesisBlock = require('./__fixtures__/genesisBlock') -}) - -afterAll(async () => { - await app.tearDown() -}) - -beforeEach(async () => { - connection = await createConnection() -}) - -afterEach(async () => { - connection.disconnect() -}) - -describe('Sequelize Connection', () => { - it('should be an object', () => { - expect(connection).toBeObject() - }) - - describe('make', () => { - it('should be a function', () => { - expect(connection.make).toBeFunction() - }) - - it('should instantiate sequelize', async () => { - const connection = new Connection({ - dialect: 'sqlite', - storage: ':memory:' - }) - - await connection.make() - - expect(connection.connection).toBeInstanceOf(require('sequelize')) - }) - - it('should have the Cache correctly configured', async () => { - const redisOptionsInit = { host: 'customRedisHost', port: 6666 } - const connection = new Connection({ - dialect: 'sqlite', - storage: ':memory:', - redis: redisOptionsInit - }) - - await connection.make() - const cache = connection.getCache() - const redisOptions = cache.getRedisOptions() - - expect(redisOptions.host).toBe(redisOptionsInit.host) - expect(redisOptions.port).toBe(redisOptionsInit.port) - }) - - describe('when the db is already initialised', () => { - it('should throw an Error', async () => { - const connection = new Connection({ - dialect: 'sqlite', - storage: ':memory:' - }) - - await connection.make() - - try { - await connection.make() - expect().fail('Should throw an Error') - } catch (error) { - expect(error.message).toMatch(/sequelize.*connect/i) - } - }) - }) - }) - - describe('getActiveDelegates', () => { - it('should be a function', () => { - expect(connection.getActiveDelegates).toBeFunction() - }) - - it('should return active delegates', async () => { - await connection.saveRound(generateRound(activeDelegates, 1)) - - const delegates = await connection.getActiveDelegates(1) - - expect(delegates).toBeArray() - expect(delegates).toHaveLength(51) - expect(delegates[0]).toBeObject() - expect(delegates[0]).toHaveProperty('id') - expect(delegates[0]).toHaveProperty('round') - expect(delegates[0]).toHaveProperty('publicKey') - expect(delegates[0]).toHaveProperty('balance') - }) - }) - - describe('verifyBlockchain', () => { - const stubBlockchain = ({ lastBlock, numberOfBlocks, blockStats, transactionStats } = {}) => { - lastBlock || lastBlock === null || (lastBlock = genesisBlock) - numberOfBlocks || (numberOfBlocks = 1) - blockStats || (blockStats = { totalFee: 10, numberOfTransactions: 5, totalAmount: 100 }) - transactionStats || (transactionStats = { totalFee: 10, count: 5, totalAmount: 100 }) - - connection.getLastBlock = jest.fn(() => lastBlock) - connection.__numberOfBlocks = jest.fn(() => numberOfBlocks) - connection.__blockStats = jest.fn(() => blockStats) - connection.__transactionStats = jest.fn(() => transactionStats) - } - - it('should be a function', () => { - expect(connection.verifyBlockchain).toBeFunction() - }) - - describe('when the blockchain state is valid', () => { - beforeEach(stubBlockchain) - - it('should return that the blockchain state is valid', async () => { - const { valid } = await connection.verifyBlockchain() - expect(valid).toBeTruthy() - }) - - it('should not include any error', async () => { - const { errors } = await connection.verifyBlockchain() - expect(errors).toBeEmpty() - }) - }) - - describe('when the last block is not available', () => { - beforeEach(() => { - stubBlockchain({ lastBlock: null }) - }) - - it('should return that the blockchain state is invalid', async () => { - const { valid } = await connection.verifyBlockchain() - expect(valid).toBeFalsy() - }) - - it('should return an error message about it', async () => { - const { errors } = await connection.verifyBlockchain() - expect(errors).toEqual(expect.arrayContaining([ - expect.stringMatching(/last.*block.*available/i) - ])) - }) - }) - - describe('when the number of transactions on the block table is different from the transactions table', () => { - beforeEach(() => { - stubBlockchain({ - blockStats: { numberOfTransactions: 30 }, - transactionStats: { count: 25 } - }) - }) - - it('should return that the blockchain state is invalid', async () => { - const { valid } = await connection.verifyBlockchain() - expect(valid).toBeFalsy() - }) - - it('should return an error message about it', async () => { - const { errors } = await connection.verifyBlockchain() - expect(errors).toEqual(expect.arrayContaining([ - expect.stringMatching(/number.*transaction/i) - ])) - }) - }) - - describe('when the sum of fees on the block table is different from the transactions table', () => { - beforeEach(() => { - stubBlockchain({ - blockStats: { totalFee: 276 }, - transactionStats: { totalFee: 275.998 } - }) - }) - - it('should return that the blockchain state is invalid', async () => { - const { valid } = await connection.verifyBlockchain() - expect(valid).toBeFalsy() - }) - - it('should return an error message about it', async () => { - const { errors } = await connection.verifyBlockchain() - expect(errors).toEqual(expect.arrayContaining([ - expect.stringMatching(/total.*fee/i) - ])) - }) - }) - - describe('when the sum of amounts on the block table is different from the transactions table', () => { - beforeEach(() => { - stubBlockchain({ - blockStats: { totalAmount: 3000 }, - transactionStats: { totalAmount: 3003 } - }) - }) - - it('should return that the blockchain state is invalid', async () => { - const { valid } = await connection.verifyBlockchain() - expect(valid).toBeFalsy() - }) - - it('should return an error message about it', async () => { - const { errors } = await connection.verifyBlockchain() - expect(errors).toEqual(expect.arrayContaining([ - expect.stringMatching(/total.*amount/i) - ])) - }) - }) - }) - - describe('saveRound', () => { - it('should be a function', () => { - expect(connection.saveRound).toBeFunction() - }) - - it('should save round to the database', async () => { - const round = await connection.saveRound(generateRound(activeDelegates, 1)) - expect(round).toBeArray() - expect(round[0]).toBeObject() - expect(round[0].publicKey).toBe(activeDelegates[0]) - }) - }) - - describe('deleteRound', () => { - it('should be a function', () => { - expect(connection.deleteRound).toBeFunction() - }) - - it('should remove round from the database', async () => { - const round = await connection.saveRound(generateRound(activeDelegates, 1)) - expect(round).toBeArray() - - const before = await connection.models.round.findAndCountAll() - expect(before.count).toBe(51) - - await connection.deleteRound(1) - - const after = await connection.models.round.findAndCountAll() - expect(after.count).toBe(0) - }) - }) - - describe('buildDelegates', () => { - it('should be a function', () => { - expect(connection.buildDelegates).toBeFunction() - }) - - it('should return a list of delegates', async () => { - await connection.saveBlock(genesisBlock) - - await connection.buildWallets(1) - await connection.saveWallets(true) - - const delegates = await connection.buildDelegates(51, 1) - - expect(delegates).toHaveLength(51) - }) - }) - - describe('buildWallets', () => { - it('should be a function', () => { - expect(connection.buildWallets).toBeFunction() - }) - - it('should return a list of wallets', async () => { - await connection.saveBlock(genesisBlock) - - const wallets = await connection.buildWallets(1) - - expect(Object.keys(wallets)).toHaveLength(53) - }) - }) - - describe('updateDelegateStats', () => { - it('should be a function', () => { - expect(connection.updateDelegateStats).toBeFunction() - }) - - it('should update the delegate', async () => { - await connection.saveBlock(genesisBlock) - - await connection.buildWallets(1) - await connection.saveWallets(true) - - const delegates = await connection.buildDelegates(51, 1) - - const wallet = connection.walletManager.getWalletByPublicKey('03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b') - expect(wallet.missedBlocks).toBe(0) - - const { height } = genesisBlock.data - await connection.applyRound(height) - await connection.updateDelegateStats(height, delegates) - - expect(wallet.missedBlocks).toBe(1) - }) - }) - - describe('saveWallets', () => { - it('should be a function', () => { - expect(connection.saveWallets).toBeFunction() - }) - - it('should save the wallets', async () => { - await connection.saveBlock(genesisBlock) - - await connection.buildWallets(1) - await connection.saveWallets(true) - - const walletCount = await connection.models.wallet.count() - expect(walletCount).toBe(53) - }) - }) - - describe('saveBlock', () => { - it('should be a function', () => { - expect(connection.saveBlock).toBeFunction() - }) - - it('should save the block and transactions', async () => { - await connection.saveBlock(genesisBlock) - - const blockCount = await connection.models.block.count() - expect(blockCount).toBe(1) - - const transactionCount = await connection.models.transaction.count() - expect(transactionCount).toBe(153) - }) - }) - - describe('saveBlockAsync', () => { - it('should be a function', () => { - expect(connection.saveBlockAsync).toBeFunction() - }) - - it('should save the block and transactions', async () => { - await connection.saveBlockAsync(genesisBlock) - - const blockCount = await connection.models.block.count() - expect(blockCount).toBe(1) - - const transactionCount = await connection.models.transaction.count() - expect(transactionCount).toBe(153) - }) - }) - - describe('saveBlockCommit', () => { - it('should be a function', () => { - expect(connection.saveBlockCommit).toBeFunction() - }) - - it('should save the block and transactions', async () => { - await connection.saveBlockAsync(genesisBlock) - await connection.saveBlockCommit() - - const blockCount = await connection.models.block.count() - expect(blockCount).toBe(1) - - const transactionCount = await connection.models.transaction.count() - expect(transactionCount).toBe(153) - }) - }) - - describe('deleteBlock', () => { - it('should be a function', () => { - expect(connection.deleteBlock).toBeFunction() - }) - - it('should remove the block and transactions', async () => { - await connection.saveBlock(genesisBlock) - - let blockCount = await connection.models.block.count() - expect(blockCount).toBe(1) - - let transactionCount = await connection.models.transaction.count() - expect(transactionCount).toBe(153) - - await connection.deleteBlock(genesisBlock) - - blockCount = await connection.models.block.count() - expect(blockCount).toBe(0) - - transactionCount = await connection.models.transaction.count() - expect(transactionCount).toBe(0) - }) - }) - - describe('getBlock', () => { - it('should be a function', () => { - expect(connection.getBlock).toBeFunction() - }) - - it('should get the block and transactions', async () => { - await connection.saveBlock(genesisBlock) - - const block = await connection.getBlock(genesisBlock.data.id) - expect(block).toBeObject() - expect(block.data.id).toBe(genesisBlock.data.id) - }) - }) - - describe('getTransaction', () => { - it('should be a function', () => { - expect(connection.getTransaction).toBeFunction() - }) - - it('should get the transaction', async () => { - const genesisTransaction = genesisBlock.transactions[0].id - - await connection.saveBlock(genesisBlock) - - const transaction = await connection.getTransaction(genesisTransaction) - expect(transaction).toBeObject() - expect(transaction.id).toBe(genesisTransaction) - }) - }) - - describe('getCommonBlock', () => { - it('should be a function', () => { - expect(connection.getCommonBlock).toBeFunction() - }) - - it('should get the common block', async () => { - await connection.saveBlock(genesisBlock) - - const blocks = await connection.getCommonBlock([genesisBlock.data.id]) - - expect(blocks).toBeObject() - expect(blocks[0].id).toBe(genesisBlock.data.id) - }) - }) - - describe('getTransactionsFromIds', () => { - it('should be a function', () => { - expect(connection.getTransactionsFromIds).toBeFunction() - }) - - it('should get the transactions', async () => { - await connection.saveBlock(genesisBlock) - - const transactions = await connection.getTransactionsFromIds([ - 'db1aa687737858cc9199bfa336f9b1c035915c30aaee60b1e0f8afadfdb946bd', - '0762007f825f02979a883396839d6f7425d5ab18f4b8c266bebe60212c793c6d', - '3c39aca95ad807ce19c0325e3059d7b1cf967751c6929035214a4ef320fb8154' - ]) - - const transactionIds = transactions.map(transaction => { - return Transaction.deserialize(transaction.serialized.toString('hex')).id - }) - - expect(transactions).toBeArray() - expect(transactions).toHaveLength(3) - expect(transactionIds[0]).toBe('0762007f825f02979a883396839d6f7425d5ab18f4b8c266bebe60212c793c6d') - expect(transactionIds[1]).toBe('3c39aca95ad807ce19c0325e3059d7b1cf967751c6929035214a4ef320fb8154') - expect(transactionIds[2]).toBe('db1aa687737858cc9199bfa336f9b1c035915c30aaee60b1e0f8afadfdb946bd') - }) - }) - - describe('getForgedTransactionsIds', () => { - it('should be a function', () => { - expect(connection.getForgedTransactionsIds).toBeFunction() - }) - - it('should get the transactions', async () => { - await connection.saveBlock(genesisBlock) - - const transactions = await connection.getForgedTransactionsIds([ - 'db1aa687737858cc9199bfa336f9b1c035915c30aaee60b1e0f8afadfdb946bd', - '0762007f825f02979a883396839d6f7425d5ab18f4b8c266bebe60212c793c6d', - '3c39aca95ad807ce19c0325e3059d7b1cf967751c6929035214a4ef320fb8154' - ]) - - expect(transactions).toBeObject() - expect(transactions[0]).toBe('0762007f825f02979a883396839d6f7425d5ab18f4b8c266bebe60212c793c6d') - expect(transactions[1]).toBe('3c39aca95ad807ce19c0325e3059d7b1cf967751c6929035214a4ef320fb8154') - expect(transactions[2]).toBe('db1aa687737858cc9199bfa336f9b1c035915c30aaee60b1e0f8afadfdb946bd') - }) - }) - - describe('getLastBlock', () => { - it('should be a function', () => { - expect(connection.getLastBlock).toBeFunction() - }) - - it('should get the last block', async () => { - await connection.saveBlock(genesisBlock) - - const block = await connection.getLastBlock() - - expect(block).toBeObject() - expect(block.data.id).toBe(genesisBlock.data.id) - }) - }) - - describe('getBlocks', () => { - it('should be a function', () => { - expect(connection.getBlocks).toBeFunction() - }) - - it('should get the blocks', async () => { - await connection.saveBlock(genesisBlock) - - const blocks = await connection.getBlocks(0, 1) - - expect(blocks).toBeObject() - expect(blocks[0].id).toBe(genesisBlock.data.id) - }) - }) - - describe('getRecentBlockIds', () => { - it('should be a function', () => { - expect(connection.getRecentBlockIds).toBeFunction() - }) - - it('should get genesis block id from database if empty', async () => { - await connection.saveBlock(genesisBlock) - - const blockIds = await connection.getRecentBlockIds() - - expect(blockIds).toBeArray() - expect(blockIds).toIncludeAllMembers([genesisBlock.data.id]) - }) - }) - - describe('getBlockHeaders', () => { - it('should be a function', () => { - expect(connection.getBlockHeaders).toBeFunction() - }) - - it('should get the block headers', async () => { - await connection.saveBlock(genesisBlock) - - const blocks = await connection.getBlockHeaders(0, 1) - - expect(blocks).toBeObject() - expect(blocks[0]).toBeInstanceOf(Buffer) - }) - }) - - describe('sql injection', () => { - it('should be ok #1', async () => { - await connection.saveBlock(genesisBlock) - - const blocks = await connection.query - .select('*') - .from('blocks') - .where('generator_public_key', '\' or \'\'=\'') - .all() - - expect(blocks).toEqual([]) - }) - - it('should be ok #2', async () => { - const blocks = await connection.query - .select('*') - .from('blocks') - .where('number_of_transactions', '153\'; DROP TABLE blocks') - .all() - - expect(blocks).toEqual([]) - - const result = await connection.connection.query('SELECT name FROM sqlite_master WHERE type=\'table\' AND name=\'blocks\';') - expect(result).toBeArray(); - expect(result).toHaveLength(1); - }) - }) -}) diff --git a/packages/core-database-sequelize/__tests__/query-builder/clauses/aggregates/avg.test.js b/packages/core-database-sequelize/__tests__/query-builder/clauses/aggregates/avg.test.js deleted file mode 100644 index 83c0259a24..0000000000 --- a/packages/core-database-sequelize/__tests__/query-builder/clauses/aggregates/avg.test.js +++ /dev/null @@ -1,19 +0,0 @@ -'use strict' - -const clause = require('../../../../lib/query-builder/clauses/aggregates/avg') - -describe('Clauses - Aggregates - AVG', () => { - it('should be a function', () => { - expect(clause).toBeFunction() - }) - - describe('using values', () => { - it('should be ok without an alias', () => { - expect(clause('balance')).toEqual(['AVG ("balance") AS "balance"']) - }) - - it('should be ok with an alias', () => { - expect(clause('balance', 'dummy-alias')).toEqual(['AVG ("balance") AS "dummy-alias"']) - }) - }) -}) diff --git a/packages/core-database-sequelize/__tests__/query-builder/clauses/aggregates/count-distinct.test.js b/packages/core-database-sequelize/__tests__/query-builder/clauses/aggregates/count-distinct.test.js deleted file mode 100644 index fc0470453a..0000000000 --- a/packages/core-database-sequelize/__tests__/query-builder/clauses/aggregates/count-distinct.test.js +++ /dev/null @@ -1,19 +0,0 @@ -'use strict' - -const clause = require('../../../../lib/query-builder/clauses/aggregates/count-distinct') - -describe('Clauses - Aggregates - COUNT DISTINCT', () => { - it('should be a function', () => { - expect(clause).toBeFunction() - }) - - describe('using values', () => { - it('should be ok without an alias', () => { - expect(clause('balance')).toEqual(['COUNT (DISTINCT "balance") AS "balance"']) - }) - - it('should be ok with an alias', () => { - expect(clause('balance', 'dummy-alias')).toEqual(['COUNT (DISTINCT "balance") AS "dummy-alias"']) - }) - }) -}) diff --git a/packages/core-database-sequelize/__tests__/query-builder/clauses/aggregates/count.test.js b/packages/core-database-sequelize/__tests__/query-builder/clauses/aggregates/count.test.js deleted file mode 100644 index 4eb55fbff0..0000000000 --- a/packages/core-database-sequelize/__tests__/query-builder/clauses/aggregates/count.test.js +++ /dev/null @@ -1,19 +0,0 @@ -'use strict' - -const clause = require('../../../../lib/query-builder/clauses/aggregates/count') - -describe('Clauses - Aggregates - COUNT', () => { - it('should be a function', () => { - expect(clause).toBeFunction() - }) - - describe('using values', () => { - it('should be ok without an alias', () => { - expect(clause('balance')).toEqual(['COUNT ("balance") AS "balance"']) - }) - - it('should be ok with an alias', () => { - expect(clause('balance', 'dummy-alias')).toEqual(['COUNT ("balance") AS "dummy-alias"']) - }) - }) -}) diff --git a/packages/core-database-sequelize/__tests__/query-builder/clauses/aggregates/max.test.js b/packages/core-database-sequelize/__tests__/query-builder/clauses/aggregates/max.test.js deleted file mode 100644 index 3da346f709..0000000000 --- a/packages/core-database-sequelize/__tests__/query-builder/clauses/aggregates/max.test.js +++ /dev/null @@ -1,19 +0,0 @@ -'use strict' - -const clause = require('../../../../lib/query-builder/clauses/aggregates/max') - -describe('Clauses - Aggregates - MAX', () => { - it('should be a function', () => { - expect(clause).toBeFunction() - }) - - describe('using values', () => { - it('should be ok without an alias', () => { - expect(clause('balance')).toEqual(['MAX ("balance") AS "balance"']) - }) - - it('should be ok with an alias', () => { - expect(clause('balance', 'dummy-alias')).toEqual(['MAX ("balance") AS "dummy-alias"']) - }) - }) -}) diff --git a/packages/core-database-sequelize/__tests__/query-builder/clauses/aggregates/min.test.js b/packages/core-database-sequelize/__tests__/query-builder/clauses/aggregates/min.test.js deleted file mode 100644 index f35af75899..0000000000 --- a/packages/core-database-sequelize/__tests__/query-builder/clauses/aggregates/min.test.js +++ /dev/null @@ -1,19 +0,0 @@ -'use strict' - -const clause = require('../../../../lib/query-builder/clauses/aggregates/min') - -describe('Clauses - Aggregates - MIN', () => { - it('should be a function', () => { - expect(clause).toBeFunction() - }) - - describe('using values', () => { - it('should be ok without an alias', () => { - expect(clause('balance')).toEqual(['MIN ("balance") AS "balance"']) - }) - - it('should be ok with an alias', () => { - expect(clause('balance', 'dummy-alias')).toEqual(['MIN ("balance") AS "dummy-alias"']) - }) - }) -}) diff --git a/packages/core-database-sequelize/__tests__/query-builder/clauses/aggregates/sum.test.js b/packages/core-database-sequelize/__tests__/query-builder/clauses/aggregates/sum.test.js deleted file mode 100644 index 7ea4931529..0000000000 --- a/packages/core-database-sequelize/__tests__/query-builder/clauses/aggregates/sum.test.js +++ /dev/null @@ -1,19 +0,0 @@ -'use strict' - -const clause = require('../../../../lib/query-builder/clauses/aggregates/sum') - -describe('Clauses - Aggregates - SUM', () => { - it('should be a function', () => { - expect(clause).toBeFunction() - }) - - describe('using values', () => { - it('should be ok without an alias', () => { - expect(clause('balance')).toEqual(['SUM ("balance") AS "balance"']) - }) - - it('should be ok with an alias', () => { - expect(clause('balance', 'dummy-alias')).toEqual(['SUM ("balance") AS "dummy-alias"']) - }) - }) -}) diff --git a/packages/core-database-sequelize/__tests__/query-builder/clauses/from.test.js b/packages/core-database-sequelize/__tests__/query-builder/clauses/from.test.js deleted file mode 100644 index 9402516a26..0000000000 --- a/packages/core-database-sequelize/__tests__/query-builder/clauses/from.test.js +++ /dev/null @@ -1,13 +0,0 @@ -'use strict' - -const clause = require('../../../lib/query-builder/clauses/from') - -describe('Clauses - FROM', () => { - it('should be a function', () => { - expect(clause).toBeFunction() - }) - - it('should be ok', () => { - expect(clause('wallets')).toBe('wallets') - }) -}) diff --git a/packages/core-database-sequelize/__tests__/query-builder/clauses/group-by.test.js b/packages/core-database-sequelize/__tests__/query-builder/clauses/group-by.test.js deleted file mode 100644 index 595de5e48b..0000000000 --- a/packages/core-database-sequelize/__tests__/query-builder/clauses/group-by.test.js +++ /dev/null @@ -1,13 +0,0 @@ -'use strict' - -const clause = require('../../../lib/query-builder/clauses/group-by') - -describe('Clauses - GROUP BY', () => { - it('should be a function', () => { - expect(clause).toBeFunction() - }) - - it('should be ok', () => { - expect(clause('balance')).toBe('balance') - }) -}) diff --git a/packages/core-database-sequelize/__tests__/query-builder/clauses/limit.test.js b/packages/core-database-sequelize/__tests__/query-builder/clauses/limit.test.js deleted file mode 100644 index c02541b843..0000000000 --- a/packages/core-database-sequelize/__tests__/query-builder/clauses/limit.test.js +++ /dev/null @@ -1,13 +0,0 @@ -'use strict' - -const clause = require('../../../lib/query-builder/clauses/limit') - -describe('Clauses - LIMIT', () => { - it('should be a function', () => { - expect(clause).toBeFunction() - }) - - it('should be ok', () => { - expect(clause(10)).toBe(10) - }) -}) diff --git a/packages/core-database-sequelize/__tests__/query-builder/clauses/offset.test.js b/packages/core-database-sequelize/__tests__/query-builder/clauses/offset.test.js deleted file mode 100644 index 8200148f11..0000000000 --- a/packages/core-database-sequelize/__tests__/query-builder/clauses/offset.test.js +++ /dev/null @@ -1,13 +0,0 @@ -'use strict' - -const clause = require('../../../lib/query-builder/clauses/offset') - -describe('Clauses - OFFSET', () => { - it('should be a function', () => { - expect(clause).toBeFunction() - }) - - it('should be ok', () => { - expect(clause(10)).toBe(10) - }) -}) diff --git a/packages/core-database-sequelize/__tests__/query-builder/clauses/order-by.test.js b/packages/core-database-sequelize/__tests__/query-builder/clauses/order-by.test.js deleted file mode 100644 index 558eb77e9c..0000000000 --- a/packages/core-database-sequelize/__tests__/query-builder/clauses/order-by.test.js +++ /dev/null @@ -1,29 +0,0 @@ -'use strict' - -const clause = require('../../../lib/query-builder/clauses/order-by') - -describe('Clauses - ORDER BY', () => { - it('should be a function', () => { - expect(clause).toBeFunction() - }) - - it('should be ok with string', () => { - expect(clause(['balance', 'desc'])).toEqual([{ - column: 'balance', - direction: 'desc' - }]) - }) - - it('should be ok with object', () => { - expect(clause([{ - id: 'asc', - balance: 'desc' - }])).toEqual([{ - column: 'id', - direction: 'asc' - }, { - column: 'balance', - direction: 'desc' - }]) - }) -}) diff --git a/packages/core-database-sequelize/__tests__/query-builder/clauses/select.test.js b/packages/core-database-sequelize/__tests__/query-builder/clauses/select.test.js deleted file mode 100644 index 32376a31e8..0000000000 --- a/packages/core-database-sequelize/__tests__/query-builder/clauses/select.test.js +++ /dev/null @@ -1,13 +0,0 @@ -'use strict' - -const clause = require('../../../lib/query-builder/clauses/select') - -describe('Clauses - SELECT', () => { - it('should be a function', () => { - expect(clause).toBeFunction() - }) - - it('should be ok', () => { - expect(clause(['balance'])).toEqual(['balance']) - }) -}) diff --git a/packages/core-database-sequelize/__tests__/query-builder/clauses/where/between.test.js b/packages/core-database-sequelize/__tests__/query-builder/clauses/where/between.test.js deleted file mode 100644 index 9c770d1beb..0000000000 --- a/packages/core-database-sequelize/__tests__/query-builder/clauses/where/between.test.js +++ /dev/null @@ -1,35 +0,0 @@ -'use strict' - -const clause = require('../../../../lib/query-builder/clauses/where/between') - -describe('Clauses - Where - BETWEEN', () => { - it('should be a function', () => { - expect(clause).toBeFunction() - }) - - it('should be ok using values', () => { - expect(clause(['balance', 123, 456])).toEqual([{ - column: 'balance', - from: 123, - operator: 'BETWEEN', - to: 456 - }]) - }) - - it('should be ok using an object', () => { - expect(clause([ - ['balance', 123, 456], - ['height', 123, 456] - ])).toEqual([{ - column: 'balance', - from: 123, - operator: 'BETWEEN', - to: 456 - }, { - column: 'height', - from: 123, - operator: 'BETWEEN', - to: 456 - }]) - }) -}) diff --git a/packages/core-database-sequelize/__tests__/query-builder/clauses/where/in.test.js b/packages/core-database-sequelize/__tests__/query-builder/clauses/where/in.test.js deleted file mode 100644 index 59cbf9765c..0000000000 --- a/packages/core-database-sequelize/__tests__/query-builder/clauses/where/in.test.js +++ /dev/null @@ -1,32 +0,0 @@ -'use strict' - -const clause = require('../../../../lib/query-builder/clauses/where/in') - -describe('Clauses - Where - IN', () => { - it('should be a function', () => { - expect(clause).toBeFunction() - }) - - it('should be ok using values', () => { - expect(clause(['balance', 123])).toEqual([{ - column: 'balance', - operator: 'IN', - value: 123 - }]) - }) - - it('should be ok using an object', () => { - expect(clause([{ - balance: 123, - height: 456 - }])).toEqual([{ - column: 'balance', - operator: 'IN', - value: 123 - }, { - column: 'height', - operator: 'IN', - value: 456 - }]) - }) -}) diff --git a/packages/core-database-sequelize/__tests__/query-builder/clauses/where/index.test.js b/packages/core-database-sequelize/__tests__/query-builder/clauses/where/index.test.js deleted file mode 100644 index 94cfec0281..0000000000 --- a/packages/core-database-sequelize/__tests__/query-builder/clauses/where/index.test.js +++ /dev/null @@ -1,44 +0,0 @@ -'use strict' - -const clause = require('../../../../lib/query-builder/clauses/where') - -describe('Clauses - Where', () => { - it('should be a function', () => { - expect(clause).toBeFunction() - }) - - describe('2 Parameters', () => { - it('should be ok using values', () => { - expect(clause(['balance', 123])).toEqual([{ - column: 'balance', - operator: '=', - value: 123 - }]) - }) - - it('should be ok using an object', () => { - expect(clause([{ - balance: 123, - height: 456 - }])).toEqual([{ - column: 'balance', - operator: '=', - value: 123 - }, { - column: 'height', - operator: '=', - value: 456 - }]) - }) - }) - - describe('3 Parameters', () => { - it('should be ok using values', () => { - expect(clause(['balance', '>=', 123])).toEqual([{ - column: 'balance', - operator: '>=', - value: 123 - }]) - }) - }) -}) diff --git a/packages/core-database-sequelize/__tests__/query-builder/clauses/where/like.test.js b/packages/core-database-sequelize/__tests__/query-builder/clauses/where/like.test.js deleted file mode 100644 index 7d09124e75..0000000000 --- a/packages/core-database-sequelize/__tests__/query-builder/clauses/where/like.test.js +++ /dev/null @@ -1,32 +0,0 @@ -'use strict' - -const clause = require('../../../../lib/query-builder/clauses/where/like') - -describe('Clauses - Where - LIKE', () => { - it('should be a function', () => { - expect(clause).toBeFunction() - }) - - it('should be ok using values', () => { - expect(clause(['balance', 123])).toEqual([{ - column: 'balance', - operator: 'LIKE', - value: '%123%' - }]) - }) - - it('should be ok using values', () => { - expect(clause([{ - balance: 123, - height: 456 - }])).toEqual([{ - column: 'balance', - operator: 'LIKE', - value: '%123%' - }, { - column: 'height', - operator: 'LIKE', - value: '%456%' - }]) - }) -}) diff --git a/packages/core-database-sequelize/__tests__/query-builder/clauses/where/not-between.test.js b/packages/core-database-sequelize/__tests__/query-builder/clauses/where/not-between.test.js deleted file mode 100644 index 7770987580..0000000000 --- a/packages/core-database-sequelize/__tests__/query-builder/clauses/where/not-between.test.js +++ /dev/null @@ -1,35 +0,0 @@ -'use strict' - -const clause = require('../../../../lib/query-builder/clauses/where/not-between') - -describe('Clauses - Where - NOT BETWEEN', () => { - it('should be a function', () => { - expect(clause).toBeFunction() - }) - - it('should be ok using values', () => { - expect(clause(['balance', 123, 456])).toEqual([{ - column: 'balance', - from: 123, - operator: 'NOT BETWEEN', - to: 456 - }]) - }) - - it('should be ok using an object', () => { - expect(clause([ - ['balance', 123, 456], - ['height', 123, 456] - ])).toEqual([{ - column: 'balance', - from: 123, - operator: 'NOT BETWEEN', - to: 456 - }, { - column: 'height', - from: 123, - operator: 'NOT BETWEEN', - to: 456 - }]) - }) -}) diff --git a/packages/core-database-sequelize/__tests__/query-builder/clauses/where/not-in.test.js b/packages/core-database-sequelize/__tests__/query-builder/clauses/where/not-in.test.js deleted file mode 100644 index ae24c3f81d..0000000000 --- a/packages/core-database-sequelize/__tests__/query-builder/clauses/where/not-in.test.js +++ /dev/null @@ -1,32 +0,0 @@ -'use strict' - -const clause = require('../../../../lib/query-builder/clauses/where/not-in') - -describe('Clauses - Where - NOT IN', () => { - it('should be a function', () => { - expect(clause).toBeFunction() - }) - - it('should be ok using values', () => { - expect(clause(['balance', 123])).toEqual([{ - column: 'balance', - operator: 'NOT IN', - value: 123 - }]) - }) - - it('should be ok using an object', () => { - expect(clause([{ - balance: 123, - height: 456 - }])).toEqual([{ - column: 'balance', - operator: 'NOT IN', - value: 123 - }, { - column: 'height', - operator: 'NOT IN', - value: 456 - }]) - }) -}) diff --git a/packages/core-database-sequelize/__tests__/query-builder/clauses/where/not-like.test.js b/packages/core-database-sequelize/__tests__/query-builder/clauses/where/not-like.test.js deleted file mode 100644 index 8584214f33..0000000000 --- a/packages/core-database-sequelize/__tests__/query-builder/clauses/where/not-like.test.js +++ /dev/null @@ -1,32 +0,0 @@ -'use strict' - -const clause = require('../../../../lib/query-builder/clauses/where/not-like') - -describe('Clauses - Where - NOT LIKE', () => { - it('should be a function', () => { - expect(clause).toBeFunction() - }) - - it('should be ok using values', () => { - expect(clause(['balance', 123])).toEqual([{ - column: 'balance', - operator: 'NOT LIKE', - value: '%123%' - }]) - }) - - it('should be ok using values', () => { - expect(clause([{ - balance: 123, - height: 456 - }])).toEqual([{ - column: 'balance', - operator: 'NOT LIKE', - value: '%123%' - }, { - column: 'height', - operator: 'NOT LIKE', - value: '%456%' - }]) - }) -}) diff --git a/packages/core-database-sequelize/__tests__/query-builder/clauses/where/not-null.test.js b/packages/core-database-sequelize/__tests__/query-builder/clauses/where/not-null.test.js deleted file mode 100644 index 5b0c9ce1b4..0000000000 --- a/packages/core-database-sequelize/__tests__/query-builder/clauses/where/not-null.test.js +++ /dev/null @@ -1,28 +0,0 @@ -'use strict' - -const clause = require('../../../../lib/query-builder/clauses/where/not-null') - -describe('Clauses - Where - NOT NULL', () => { - it('should be a function', () => { - expect(clause).toBeFunction() - }) - - it('should be ok using values', () => { - expect(clause(['balance'])).toEqual([{ - column: 'balance', - operator: 'IS NOT NULL' - }]) - }) - - it('should be ok using an array', () => { - expect(clause([ - ['balance', 'height'] - ])).toEqual([{ - column: 'balance', - operator: 'IS NOT NULL' - }, { - column: 'height', - operator: 'IS NOT NULL' - }]) - }) -}) diff --git a/packages/core-database-sequelize/__tests__/query-builder/clauses/where/null.test.js b/packages/core-database-sequelize/__tests__/query-builder/clauses/where/null.test.js deleted file mode 100644 index 864afc1305..0000000000 --- a/packages/core-database-sequelize/__tests__/query-builder/clauses/where/null.test.js +++ /dev/null @@ -1,28 +0,0 @@ -'use strict' - -const clause = require('../../../../lib/query-builder/clauses/where/null') - -describe('Clauses - Where - NULL', () => { - it('should be a function', () => { - expect(clause).toBeFunction() - }) - - it('should be ok using values', () => { - expect(clause(['balance'])).toEqual([{ - column: 'balance', - operator: 'IS NULL' - }]) - }) - - it('should be ok using an array', () => { - expect(clause([ - ['balance', 'height'] - ])).toEqual([{ - column: 'balance', - operator: 'IS NULL' - }, { - column: 'height', - operator: 'IS NULL' - }]) - }) -}) diff --git a/packages/core-database-sequelize/__tests__/query-builder/query-builder.test.js b/packages/core-database-sequelize/__tests__/query-builder/query-builder.test.js deleted file mode 100644 index 88201266e5..0000000000 --- a/packages/core-database-sequelize/__tests__/query-builder/query-builder.test.js +++ /dev/null @@ -1,473 +0,0 @@ -'use strict' - -const QueryBuiler = require('../../lib/query-builder') - -let builder - -beforeEach(() => { - builder = new QueryBuiler({}) - builder.__reset() -}) - -describe('Utils - Query Builder', () => { - it('should be an instance', () => { - expect(builder).toBeInstanceOf(QueryBuiler) - }) - - describe('select', () => { - it('should be a function', () => { - expect(builder.select).toBeFunction() - }) - - it('should be ok', () => { - builder.select('id', 'height') - - expect(builder.clauses.select.columns).toEqual(['id', 'height']) - }) - }) - - describe('from', () => { - it('should be a function', () => { - expect(builder.from).toBeFunction() - }) - - it('should be ok', () => { - builder.from('blocks') - - expect(builder.clauses.from).toBe('blocks') - }) - }) - - describe('where', () => { - it('should be a function', () => { - expect(builder.where).toBeFunction() - }) - - it('should be ok', () => { - builder.where('reward', 2 * Math.pow(10, 8)) - - expect(builder.clauses.where.and).toEqual([{ - column: 'reward', - operator: '=', - value: 200000000 - }]) - }) - }) - - describe('whereIn', () => { - it('should be a function', () => { - expect(builder.whereIn).toBeFunction() - }) - - it('should be ok', () => { - builder.whereIn('reward', [3 * Math.pow(10, 8)]) - - expect(builder.clauses.where.and).toEqual([{ - column: 'reward', - operator: 'IN', - value: [300000000] - }]) - }) - }) - - describe('whereNotIn', () => { - it('should be a function', () => { - expect(builder.whereNotIn).toBeFunction() - }) - - it('should be ok', () => { - builder.whereNotIn('reward', [3 * Math.pow(10, 8)]) - - expect(builder.clauses.where.and).toEqual([{ - column: 'reward', - operator: 'NOT IN', - value: [300000000] - }]) - }) - }) - - describe('whereNull', () => { - it('should be a function', () => { - expect(builder.whereNull).toBeFunction() - }) - - it('should be ok', () => { - builder.whereNull('reward') - - expect(builder.clauses.where.and).toEqual([{ - column: 'reward', - operator: 'IS NULL' - }]) - }) - }) - - describe('whereNotNull', () => { - it('should be a function', () => { - expect(builder.whereNotNull).toBeFunction() - }) - - it('should be ok', () => { - builder.whereNotNull('reward') - - expect(builder.clauses.where.and).toEqual([{ - column: 'reward', - operator: 'IS NOT NULL' - }]) - }) - }) - - describe('whereBetween', () => { - it('should be a function', () => { - expect(builder.whereBetween).toBeFunction() - }) - - it('should be ok', () => { - builder.whereBetween('reward', 123, 456) - - expect(builder.clauses.where.and).toEqual([{ - column: 'reward', - from: 123, - operator: 'BETWEEN', - to: 456 - }]) - }) - }) - - describe('whereNotBetween', () => { - it('should be a function', () => { - expect(builder.whereNotBetween).toBeFunction() - }) - - it('should be ok', () => { - builder.whereNotBetween('reward', 123, 456) - - expect(builder.clauses.where.and).toEqual([{ - column: 'reward', - from: 123, - operator: 'NOT BETWEEN', - to: 456 - }]) - }) - }) - - describe('orWhere', () => { - it('should be a function', () => { - expect(builder.orWhere).toBeFunction() - }) - - it('should be ok', () => { - builder.orWhere('reward', 2 * Math.pow(10, 8)) - - expect(builder.clauses.where.or).toEqual([{ - column: 'reward', - operator: '=', - value: 200000000 - }]) - }) - }) - - describe('orWhereIn', () => { - it('should be a function', () => { - expect(builder.orWhereIn).toBeFunction() - }) - - it('should be ok', () => { - builder.orWhereIn('reward', [3 * Math.pow(10, 8)]) - - expect(builder.clauses.where.or).toEqual([{ - column: 'reward', - operator: 'IN', - value: [300000000] - }]) - }) - }) - - describe('orWhereNotIn', () => { - it('should be a function', () => { - expect(builder.orWhereNotIn).toBeFunction() - }) - - it('should be ok', () => { - builder.orWhereNotIn('reward', [3 * Math.pow(10, 8)]) - - expect(builder.clauses.where.or).toEqual([{ - column: 'reward', - operator: 'NOT IN', - value: [300000000] - }]) - }) - }) - - describe('orWhereNull', () => { - it('should be a function', () => { - expect(builder.orWhereNull).toBeFunction() - }) - - it('should be ok', () => { - builder.orWhereNull('reward') - - expect(builder.clauses.where.or).toEqual([{ - column: 'reward', - operator: 'IS NULL' - }]) - }) - }) - - describe('orWhereNotNull', () => { - it('should be a function', () => { - expect(builder.orWhereNotNull).toBeFunction() - }) - - it('should be ok', () => { - builder.orWhereNotNull('reward') - - expect(builder.clauses.where.or).toEqual([{ - column: 'reward', - operator: 'IS NOT NULL' - }]) - }) - }) - - describe('orWhereBetween', () => { - it('should be a function', () => { - expect(builder.orWhereBetween).toBeFunction() - }) - - it('should be ok', () => { - builder.orWhereBetween('reward', 123, 456) - - expect(builder.clauses.where.or).toEqual([{ - column: 'reward', - from: 123, - operator: 'BETWEEN', - to: 456 - }]) - }) - }) - - describe('orWhereNotBetween', () => { - it('should be a function', () => { - expect(builder.orWhereNotBetween).toBeFunction() - }) - - it('should be ok', () => { - builder.orWhereNotBetween('reward', 123, 456) - - expect(builder.clauses.where.or).toEqual([{ - column: 'reward', - from: 123, - operator: 'NOT BETWEEN', - to: 456 - }]) - }) - }) - - describe('groupBy', () => { - it('should be a function', () => { - expect(builder.groupBy).toBeFunction() - }) - - it('should be ok', () => { - builder.groupBy('height') - - expect(builder.clauses.groupBy).toBe('height') - }) - }) - - describe('orderBy', () => { - it('should be a function', () => { - expect(builder.orderBy).toBeFunction() - }) - - it('should be ok using key/value', () => { - builder.orderBy('reward', 'desc') - - expect(builder.clauses.orderBy).toEqual([{ - column: 'reward', - direction: 'desc' - }]) - }) - - it('should be ok using an object', () => { - builder.orderBy({ - reward: 'desc' - }) - - expect(builder.clauses.orderBy).toEqual([{ - column: 'reward', - direction: 'desc' - }]) - }) - }) - - describe('limit', () => { - it('should be a function', () => { - expect(builder.limit).toBeFunction() - }) - - it('should be ok', () => { - builder.limit(10) - - expect(builder.clauses.limit).toBe(10) - }) - }) - - describe('offset', () => { - it('should be a function', () => { - expect(builder.offset).toBeFunction() - }) - - it('should be ok', () => { - builder.offset(10) - - expect(builder.clauses.offset).toBe(10) - }) - }) - - describe('count', () => { - it('should be a function', () => { - expect(builder.count).toBeFunction() - }) - - it('should be ok', () => { - builder.count('reward') - - expect(builder.clauses.select.aggregates).toEqual(['COUNT ("reward") AS "reward"']) - }) - - it('should be ok using an alias', () => { - builder.count('reward', 'alias') - - expect(builder.clauses.select.aggregates).toEqual(['COUNT ("reward") AS "alias"']) - }) - }) - - describe('countDistinct', () => { - it('should be a function', () => { - expect(builder.countDistinct).toBeFunction() - }) - - it('should be ok', () => { - builder.countDistinct('reward') - - expect(builder.clauses.select.aggregates).toEqual(['COUNT (DISTINCT "reward") AS "reward"']) - }) - - it('should be ok using an alias', () => { - builder.countDistinct('reward', 'alias') - - expect(builder.clauses.select.aggregates).toEqual(['COUNT (DISTINCT "reward") AS "alias"']) - }) - }) - - describe('min', () => { - it('should be a function', () => { - expect(builder.min).toBeFunction() - }) - - it('should be ok', () => { - builder.min('reward') - - expect(builder.clauses.select.aggregates).toEqual(['MIN ("reward") AS "reward"']) - }) - - it('should be ok using an alias', () => { - builder.min('reward', 'alias') - - expect(builder.clauses.select.aggregates).toEqual(['MIN ("reward") AS "alias"']) - }) - }) - - describe('max', () => { - it('should be a function', () => { - expect(builder.max).toBeFunction() - }) - - it('should be ok', () => { - builder.max('reward') - - expect(builder.clauses.select.aggregates).toEqual(['MAX ("reward") AS "reward"']) - }) - - it('should be ok using an alias', () => { - builder.max('reward', 'alias') - - expect(builder.clauses.select.aggregates).toEqual(['MAX ("reward") AS "alias"']) - }) - }) - - describe('sum', () => { - it('should be a function', () => { - expect(builder.sum).toBeFunction() - }) - - it('should be ok', () => { - builder.sum('reward') - - expect(builder.clauses.select.aggregates).toEqual(['SUM ("reward") AS "reward"']) - }) - - it('should be ok using an alias', () => { - builder.sum('reward', 'alias') - - expect(builder.clauses.select.aggregates).toEqual(['SUM ("reward") AS "alias"']) - }) - }) - - describe('avg', () => { - it('should be a function', () => { - expect(builder.avg).toBeFunction() - }) - - it('should be ok', () => { - builder.avg('reward') - - expect(builder.clauses.select.aggregates).toEqual(['AVG ("reward") AS "reward"']) - }) - - it('should be ok using an alias', () => { - builder.avg('reward', 'alias') - - expect(builder.clauses.select.aggregates).toEqual(['AVG ("reward") AS "alias"']) - }) - }) - - describe('all', () => { - it('should be a function', () => { - expect(builder.all).toBeFunction() - }) - - it.skip('should be ok', () => { - // - }) - }) - - describe('first', () => { - it('should be a function', () => { - expect(builder.first).toBeFunction() - }) - - it.skip('should be ok', () => { - // - }) - }) - - describe('__reset', () => { - it('should be a function', () => { - expect(builder.__reset).toBeFunction() - }) - - it('should be ok', () => { - expect(builder.clauses).toEqual({ - select: { - columns: [], - aggregates: [] - }, - where: { - and: [], - or: [] - } - }) - }) - }) -}) diff --git a/packages/core-database-sequelize/__tests__/query-builder/sql-builder.test.js b/packages/core-database-sequelize/__tests__/query-builder/sql-builder.test.js deleted file mode 100644 index 52ddb894cc..0000000000 --- a/packages/core-database-sequelize/__tests__/query-builder/sql-builder.test.js +++ /dev/null @@ -1,158 +0,0 @@ -'use strict' - -const builder = require('../../lib/query-builder/sql-builder') -const { Utils } = require('sequelize') - -const clauses = { - select: { - columns: ['reward', 'height'], - aggregates: [] - }, - from: 'blocks', - where: { - and: [{ - column: 'balance', - operator: '=', - value: 2 * Math.pow(10, 8) - }], - or: [] - }, - groupBy: 'reward', - orderBy: [{ - column: 'reward', - direction: 'asc' - }, { - column: 'height', - direction: 'desc' - }], - limit: 123, - offset: 123 -} - -describe('Utils - SQL Builder', () => { - beforeEach(() => { - builder.__replacements = [] - }) - - it('should be an object', () => { - expect(builder).toBeObject() - }) - - describe('build', () => { - it('should be a function', () => { - expect(builder.build).toBeFunction() - }) - - it('should be ok', () => { - let { sql, replacements } = builder.build(clauses) - sql = Utils.format([sql].concat(replacements), 'sqlite') - - expect(sql).toBe('SELECT reward,height FROM blocks WHERE balance = 200000000 GROUP BY "reward" ORDER BY reward ASC,height DESC LIMIT 123 OFFSET 123') - }) - }) - - describe('__buildSelect', () => { - it('should be a function', () => { - expect(builder.__buildSelect).toBeFunction() - }) - - it('should be ok', () => { - const clause = builder.__buildSelect(clauses) - - expect(clause).toBe('SELECT reward,height ') - }) - }) - - describe('__buildFrom', () => { - it('should be a function', () => { - expect(builder.__buildFrom).toBeFunction() - }) - - it('should be ok', () => { - const clause = builder.__buildFrom(clauses) - - expect(clause).toBe('FROM blocks ') - }) - }) - - describe('__buildWhere', () => { - it('should be a function', () => { - expect(builder.__buildWhere).toBeFunction() - }) - - it('should be ok', () => { - let clause = builder.__buildWhere(clauses) - const replacements = builder.__replacements - - clause = Utils.format([clause].concat(replacements), 'sqlite') - - expect(clause).toBe('WHERE balance = 200000000 ') - }) - }) - - describe('__buildGroupBy', () => { - it('should be a function', () => { - expect(builder.__buildGroupBy).toBeFunction() - }) - - it('should be ok', () => { - const clause = builder.__buildGroupBy(clauses) - - expect(clause).toBe('GROUP BY "reward" ') - }) - }) - - describe('__buildOrderBy', () => { - it('should be a function', () => { - expect(builder.__buildOrderBy).toBeFunction() - }) - - it('should be ok', () => { - const clause = builder.__buildOrderBy(clauses) - - expect(clause).toBe('ORDER BY reward ASC,height DESC ') - }) - }) - - describe('__buildLimit', () => { - it('should be a function', () => { - expect(builder.__buildLimit).toBeFunction() - }) - - it('should be ok', () => { - const clause = builder.__buildLimit(clauses) - - expect(clause).toBe('LIMIT 123 ') - }) - }) - - describe('__buildOffset', () => { - it('should be a function', () => { - expect(builder.__buildOffset).toBeFunction() - }) - - it('should be ok', () => { - const clause = builder.__buildOffset(clauses) - - expect(clause).toBe('OFFSET 123 ') - }) - }) - - describe('__replacements', () => { - it('should escape SQL Injection based on ""="" is always true', () => { - const sql = 'SELECT * FROM blocks WHERE generator_public_key = ?' - const replacements = ['\' or \'\'=\'\''] - const formatted = Utils.format([sql].concat(replacements), 'sqlite') - - expect(formatted).toBe('SELECT * FROM blocks WHERE generator_public_key = \'\'\' or \'\'\'\'=\'\'\'\'\'') - }) - - it('should escape SQL Injection based on batched statements', () => { - const sql = 'SELECT * FROM blocks WHERE number_of_transactions = ?' - const replacements = ['153\'; DROP TABLE blocks'] - const formatted = Utils.format([sql].concat(replacements), 'sqlite') - - expect(formatted).toBe('SELECT * FROM blocks WHERE number_of_transactions = \'153\'\'; DROP TABLE blocks\'') - }) - }) -}) diff --git a/packages/core-database-sequelize/__tests__/query-builder/utils/escape.test.js b/packages/core-database-sequelize/__tests__/query-builder/utils/escape.test.js deleted file mode 100644 index 2b9366e922..0000000000 --- a/packages/core-database-sequelize/__tests__/query-builder/utils/escape.test.js +++ /dev/null @@ -1,17 +0,0 @@ -'use strict' - -const escape = require('../../../lib/query-builder/utils/escape') - -describe('Utils - escape', () => { - it('should be an object', () => { - expect(escape).toBeFunction() - }) - - it('should be ok with strings', () => { - expect(escape('test string')).toBe('"test string"') - }) - - it('should be ok with numbers', () => { - expect(escape(123)).toBe('\'123\'') - }) -}) diff --git a/packages/core-database-sequelize/__tests__/query-builder/utils/is-array.test.js b/packages/core-database-sequelize/__tests__/query-builder/utils/is-array.test.js deleted file mode 100644 index 87eb71c5fa..0000000000 --- a/packages/core-database-sequelize/__tests__/query-builder/utils/is-array.test.js +++ /dev/null @@ -1,17 +0,0 @@ -'use strict' - -const isArray = require('../../../lib/query-builder/utils/is-array') - -describe('Utils - isArray', () => { - it('should be an array', () => { - expect(isArray).toBeFunction() - }) - - it('should be truthy', () => { - expect(isArray([])).toBeTruthy() - }) - - it('should be falsy', () => { - expect(isArray('string')).toBeFalsy() - }) -}) diff --git a/packages/core-database-sequelize/__tests__/query-builder/utils/is-object.test.js b/packages/core-database-sequelize/__tests__/query-builder/utils/is-object.test.js deleted file mode 100644 index c8c7c84e6b..0000000000 --- a/packages/core-database-sequelize/__tests__/query-builder/utils/is-object.test.js +++ /dev/null @@ -1,17 +0,0 @@ -'use strict' - -const isObject = require('../../../lib/query-builder/utils/is-object') - -describe('Utils - isObject', () => { - it('should be an object', () => { - expect(isObject).toBeFunction() - }) - - it('should be truthy', () => { - expect(isObject({})).toBeTruthy() - }) - - it('should be falsy', () => { - expect(isObject('string')).toBeFalsy() - }) -}) diff --git a/packages/core-database-sequelize/__tests__/query-builder/utils/is-string.test.js b/packages/core-database-sequelize/__tests__/query-builder/utils/is-string.test.js deleted file mode 100644 index c8234eb54b..0000000000 --- a/packages/core-database-sequelize/__tests__/query-builder/utils/is-string.test.js +++ /dev/null @@ -1,17 +0,0 @@ -'use strict' - -const isString = require('../../../lib/query-builder/utils/is-string') - -describe('Utils - isString', () => { - it('should be an string', () => { - expect(isString).toBeFunction() - }) - - it('should be truthy', () => { - expect(isString('string')).toBeTruthy() - }) - - it('should be falsy', () => { - expect(isString(123)).toBeFalsy() - }) -}) diff --git a/packages/core-database-sequelize/__tests__/repositories/blocks.test.js b/packages/core-database-sequelize/__tests__/repositories/blocks.test.js deleted file mode 100644 index 610b8a8ad2..0000000000 --- a/packages/core-database-sequelize/__tests__/repositories/blocks.test.js +++ /dev/null @@ -1,272 +0,0 @@ -'use strict' - -const toBeBlockTableRow = require('../__support__/matchers/block-table-row') -expect.extend({ toBeBlockTableRow }) - -const app = require('../__support__/setup') -const createConnection = require('../__support__/utils/create-connection') - -// TODO theses tests should use more than 1 block to be sure that they're correct - -let genesisBlock -let connection -let repository - -beforeAll(async () => { - await app.setUp() - - // Create the genesis block after the setup has finished or else it uses a potentially - // wrong network config. - genesisBlock = require('../__fixtures__/genesisBlock') -}) - -afterAll(async () => { - await app.tearDown() -}) - -beforeEach(async () => { - connection = await createConnection() - repository = connection.blocks -}) - -afterEach(async () => { - connection.disconnect() -}) - -describe('Block Repository', () => { - it('should be an object', () => { - expect(repository).toBeObject() - }) - - describe('findAll', () => { - it('should be a function', () => { - expect(repository.findAll).toBeFunction() - }) - - it('should find all blocks', async () => { - await connection.saveBlock(genesisBlock) - - const blocks = await repository.findAll() - expect(blocks.count).toBe(1) - expect(blocks.rows).toBeArray() - expect(blocks.rows).not.toBeEmpty() - expect(blocks.rows[0]).toBeBlockTableRow() - }) - - describe('when no results', () => { - it('should not return them', async () => { - await connection.saveBlock(genesisBlock) - - const blocks = await repository.findAll({ generatorPublicKey: 'none' }) - expect(blocks.count).toBe(0) - expect(blocks.rows).toBeArray() - expect(blocks.rows).toBeEmpty() - }) - - // TODO this and other methods - xit('should not perform a query to get the results', () => { - }) - }) - }) - - describe('findAllByGenerator', () => { - it('should be a function', () => { - expect(repository.findAllByGenerator).toBeFunction() - }) - - it('should find all blocks by the public key of the forger', async () => { - await connection.saveBlock(genesisBlock) - - const generatorPublicKey = genesisBlock.data.generatorPublicKey - - const blocks = await repository.findAllByGenerator(generatorPublicKey) - expect(blocks.count).toBe(1) - expect(blocks.rows).toBeArray() - expect(blocks.rows).not.toBeEmpty() - expect(blocks.rows[0]).toBeBlockTableRow() - expect(blocks.rows[0].generatorPublicKey).toBe(generatorPublicKey) - }) - - describe('when no results', () => { - it('should not return them', async () => { - await connection.saveBlock(genesisBlock) - - const blocks = await repository.findAllByGenerator('none') - expect(blocks.count).toBe(0) - expect(blocks.rows).toBeArray() - expect(blocks.rows).toBeEmpty() - }) - - xit('should not perform a query to get the results', () => { - }) - }) - }) - - describe('findById', () => { - it('should be a function', () => { - expect(repository.findById).toBeFunction() - }) - - it('should find a block by id', async () => { - await connection.saveBlock(genesisBlock) - - const block = await repository.findById(genesisBlock.data.id) - expect(block).toBeBlockTableRow() - expect(block.id).toBe(genesisBlock.data.id) - }) - }) - - describe('findLastByPublicKey', () => { - it('should be a function', () => { - expect(repository.findLastByPublicKey).toBeFunction() - }) - - it('should find the last forged block by public key', async () => { - await connection.saveBlock(genesisBlock) - - const generatorPublicKey = genesisBlock.data.generatorPublicKey - - const block = await repository.findLastByPublicKey(generatorPublicKey) - expect(block).toBeObject() - expect(block.id).toBe(genesisBlock.data.id) - }) - }) - - describe('search', async () => { - const expectSearch = async (params) => { - await connection.saveBlock(genesisBlock) - - const blocks = await repository.search(params) - expect(blocks).toBeObject() - - expect(blocks).toHaveProperty('count') - expect(blocks.count).toBeNumber() - expect(blocks.count).toBe(1) - - expect(blocks).toHaveProperty('rows') - expect(blocks.rows).toBeObject() - expect(blocks.rows).not.toBeEmpty() - expect(blocks.rows[0]).toBeBlockTableRow() - } - - it('should be a function', () => { - expect(repository.search).toBeFunction() - }) - - it('should search blocks by the specified ID', async () => { - await expectSearch({ - id: genesisBlock.data.id - }) - }) - - it('should search blocks by the specified previousBlock', async () => { - await expectSearch({ - previousBlock: genesisBlock.data.previousBlock - }) - }) - - it('should search blocks by the specified ID', async () => { - await expectSearch({ - payloadHash: genesisBlock.data.payloadHash - }) - }) - - it('should search blocks by the specified generatorPublicKey', async () => { - await expectSearch({ - generatorPublicKey: genesisBlock.data.generatorPublicKey - }) - }) - - it('should search blocks by the specified blockSignature', async () => { - await expectSearch({ - blockSignature: genesisBlock.data.blockSignature - }) - }) - - it('should search blocks by the specified timestamp', async () => { - await expectSearch({ - timestamp: { - from: genesisBlock.data.timestamp, - to: genesisBlock.data.timestamp - } - }) - }) - - it('should search blocks by the specified height', async () => { - await expectSearch({ - height: { - from: genesisBlock.data.height, - to: genesisBlock.data.height - } - }) - }) - - it('should search blocks by the specified numberOfTransactions', async () => { - await expectSearch({ - numberOfTransactions: { - from: genesisBlock.data.numberOfTransactions, - to: genesisBlock.data.numberOfTransactions - } - }) - }) - - it('should search blocks by the specified totalAmount', async () => { - await expectSearch({ - totalAmount: { - from: genesisBlock.data.totalAmount, - to: genesisBlock.data.totalAmount - } - }) - }) - - it('should search blocks by the specified totalFee', async () => { - await expectSearch({ - totalFee: { - from: genesisBlock.data.totalFee, - to: genesisBlock.data.totalFee - } - }) - }) - - it('should search blocks by the specified reward', async () => { - await expectSearch({ - reward: { - from: genesisBlock.data.reward, - to: genesisBlock.data.reward - } - }) - }) - - it('should search blocks by the specified payloadLength', async () => { - await expectSearch({ - payloadLength: { - from: genesisBlock.data.payloadLength, - to: genesisBlock.data.payloadLength - } - }) - }) - - describe('when no results', () => { - it('should not return them', async () => { - await connection.saveBlock(genesisBlock) - - const blocks = await repository.search({ amount: 9, totalFee: 1 }) - expect(blocks.count).toBe(0) - expect(blocks.rows).toBeArray() - expect(blocks.rows).toBeEmpty() - }) - - xit('should not perform a query to get the results', () => { - }) - }) - }) - - describe('count', () => { - it('should return the total number of blocks', async () => { - await connection.saveBlock(genesisBlock) - - const { count } = await repository.count() - expect(count).toBe(1) - }) - }) -}) diff --git a/packages/core-database-sequelize/__tests__/repositories/transactions.test.js b/packages/core-database-sequelize/__tests__/repositories/transactions.test.js deleted file mode 100644 index 0fc7736c9c..0000000000 --- a/packages/core-database-sequelize/__tests__/repositories/transactions.test.js +++ /dev/null @@ -1,640 +0,0 @@ -'use strict' - -const toBeMinimalTransactionFields = require('../__support__/matchers/minimal-transaction-fields') -expect.extend({ toBeMinimalTransactionFields }) - -const { crypto, models } = require('@arkecosystem/crypto') -const { Transaction } = models -const SPV = require('../../lib/spv') - -const app = require('../__support__/setup') -const createConnection = require('../__support__/utils/create-connection') - -let genesisBlock -let genesisTransaction -let connection -let repository -let spv - -const getWallet = address => { - return spv.walletManager.getWalletByAddress(address) -} - -beforeAll(async () => { - await app.setUp() - - // Create the genesis block after the setup has finished or else it uses a potentially - // wrong network config. - genesisBlock = require('../__fixtures__/genesisBlock') - genesisTransaction = genesisBlock.transactions[0] -}) - -afterAll(async () => { - await app.tearDown() -}) - -beforeEach(async () => { - connection = await createConnection() - repository = connection.transactions - spv = new SPV(connection) - - // To avoid timing out - const cache = {} - repository.cache.get = jest.fn(key => cache[key]) - repository.cache.set = jest.fn((key, value) => (cache[key] = value)) -}) - -afterEach(async () => { - connection.disconnect() -}) - -describe('Transaction Repository', () => { - it('should be an object', () => { - expect(repository).toBeObject() - }) - - describe('findAll', () => { - it('should be a function', () => { - expect(repository.findAll).toBeFunction() - }) - - it('should find all transactions', async () => { - await connection.saveBlock(genesisBlock) - - const transactions = await repository.findAll() - - // NOTE: The real count is avoided because it degrades the performance of the node - // expect(transactions.count).toBe(153) - expect(transactions.count).toBe(100) - expect(transactions.rows).toBeArray() - expect(transactions.rows).not.toBeEmpty() - transactions.rows.forEach(transaction => { - expect(transaction).toBeMinimalTransactionFields() - }) - }) - - it('should find all transactions that holds the condition', async () => { - await connection.saveBlock(genesisBlock) - - const transactions = await repository.findAll({ - type: 3 - }) - - expect(transactions.count).toBe(51) - expect(transactions.rows).toBeArray() - expect(transactions.rows).not.toBeEmpty() - transactions.rows.forEach(transaction => { - expect(transaction).toBeMinimalTransactionFields() - }) - }) - - it('should find all transactions that holds all the conditions (AND)', async () => { - await connection.saveBlock(genesisBlock) - - const transactions = await repository.findAll({ - recipientId: genesisTransaction.recipientId, - type: 3 - }) - - expect(transactions.count).toBe(1) - expect(transactions.rows).toBeArray() - expect(transactions.rows).not.toBeEmpty() - transactions.rows.forEach(transaction => { - expect(transaction).toBeMinimalTransactionFields() - }) - }) - - it('should find the same transactions with parameter senderId and corresponding senderPublicKey', async () => { - await connection.saveBlock(genesisBlock) - const senderWallet = await spv.walletManager.getWalletByPublicKey('034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c') - - const transactionsSenderPublicKey = await repository.findAll({ senderPublicKey: senderWallet.publicKey }) - const transactionsSenderId = await repository.findAll({ senderId: senderWallet.address }) - - expect(transactionsSenderPublicKey.count).toBe(transactionsSenderId.count) - expect(transactionsSenderPublicKey.rows.length).toBe(transactionsSenderPublicKey.count) - expect(transactionsSenderId.rows.length).toBe(transactionsSenderId.count) - - transactionsSenderPublicKey.rows.forEach((transactionSenderPublicKey, index) => { - const transactionSenderId = transactionsSenderId.rows[index] - expect(transactionSenderId).toEqual(transactionSenderPublicKey) - }) - }) - - it('should find no transaction when passed parameter senderId is invalid or unknown', async () => { - await connection.saveBlock(genesisBlock) - const invalidSenderId = 'thisIsNotAValidSenderId' - - const transactionsSenderId = await repository.findAll({ senderId: invalidSenderId }) - - expect(transactionsSenderId.count).toBe(0) - expect(transactionsSenderId.rows.length).toBe(0) - }) - - xit('should find all transactions by some fields only', () => { - }) - - describe('when no results', () => { - it('should not return them', async () => { - await connection.saveBlock(genesisBlock) - - const transactions = await repository.findAll({ type: 99 }) - - expect(transactions.count).toBe(0) - expect(transactions.rows).toBeArray() - expect(transactions.rows).toBeEmpty() - }) - - // TODO this and other methods - xit('should not perform a query to get the results', () => { - }) - }) - }) - - describe('findAllLegacy', () => { - it('should be a function', () => { - expect(repository.findAllLegacy).toBeFunction() - }) - - it('should find all transactions', async () => { - await connection.saveBlock(genesisBlock) - - const transactions = await repository.findAllLegacy() - - // NOTE: The real count is avoided because it degrades the performance of the node - // expect(transactions.count).toBe(153) - expect(transactions.count).toBe(100) - expect(transactions.rows).toBeArray() - expect(transactions.rows).not.toBeEmpty() - transactions.rows.forEach(transaction => { - expect(transaction).toBeMinimalTransactionFields() - }) - }) - - it('should find all transactions that holds the condition', async () => { - await connection.saveBlock(genesisBlock) - - const transactions = await repository.findAllLegacy({ - type: 3 - }) - - expect(transactions.count).toBe(51) - expect(transactions.rows).toBeArray() - expect(transactions.rows).not.toBeEmpty() - transactions.rows.forEach(transaction => { - expect(transaction).toBeMinimalTransactionFields() - }) - }) - - it('should find all transactions that holds any of the conditions (OR)', async () => { - await connection.saveBlock(genesisBlock) - - const transactions = await repository.findAllLegacy({ - recipientId: genesisTransaction.recipientId, - type: 3 - }) - - expect(transactions.count).toBe(52) - expect(transactions.rows).toBeArray() - expect(transactions.rows).not.toBeEmpty() - transactions.rows.forEach(transaction => { - expect(transaction).toBeMinimalTransactionFields() - }) - }) - - it('should find the same transactions with parameter senderId and corresponding senderPublicKey', async () => { - await connection.saveBlock(genesisBlock) - const senderWallet = await spv.walletManager.getWalletByPublicKey('034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c') - - const transactionsSenderPublicKey = await repository.findAllLegacy({ senderPublicKey: senderWallet.publicKey }) - const transactionsSenderId = await repository.findAllLegacy({ senderId: senderWallet.address }) - - expect(transactionsSenderPublicKey.count).toBe(transactionsSenderId.count) - expect(transactionsSenderPublicKey.rows.length).toBe(transactionsSenderPublicKey.count) - expect(transactionsSenderId.rows.length).toBe(transactionsSenderId.count) - - transactionsSenderPublicKey.rows.forEach((transactionSenderPublicKey, index) => { - const transactionSenderId = transactionsSenderId.rows[index] - expect(transactionSenderId).toEqual(transactionSenderPublicKey) - }) - }) - - it('should find no transaction when passed parameter senderId is invalid or unknown', async () => { - await connection.saveBlock(genesisBlock) - const invalidSenderId = 'thisIsNotAValidSenderId' - - const transactionsSenderId = await repository.findAllLegacy({ senderId: invalidSenderId }) - - expect(transactionsSenderId.count).toBe(0) - expect(transactionsSenderId.rows.length).toBe(0) - }) - - xit('should find all transactions by any field', () => { - }) - - describe('when no results', () => { - it('should not return them', async () => { - await connection.saveBlock(genesisBlock) - - const transactions = await repository.findAllLegacy({ type: 99 }) - - expect(transactions.count).toBe(0) - expect(transactions.rows).toBeArray() - expect(transactions.rows).toBeEmpty() - }) - - xit('should not perform a query to get the results', () => { - }) - }) - }) - - describe('findAllByWallet', () => { - it('should be a function', () => { - expect(repository.findAllByWallet).toBeFunction() - }) - - it('should find all transactions', async () => { - await connection.saveBlock(genesisBlock) - - const receiver = await getWallet('AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri') - expect(receiver).toBeObject() - - const receiverTransactions = await repository.findAllByWallet(receiver) - - expect(receiverTransactions.count).toBe(2) - expect(receiverTransactions.rows).toBeArray() - expect(receiverTransactions.rows).not.toBeEmpty() - receiverTransactions.rows.forEach(transaction => { - expect(transaction).toBeMinimalTransactionFields() - }) - - const sender = await getWallet('APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn') - expect(sender).toBeObject() - sender.publicKey = '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788' - - const senderTransactions = await repository.findAllByWallet(sender) - - expect(senderTransactions.count).toBe(51) - expect(receiverTransactions.rows).toBeArray() - expect(receiverTransactions.rows).not.toBeEmpty() - senderTransactions.rows.forEach(transaction => { - expect(transaction).toBeMinimalTransactionFields() - }) - }) - - describe('when no results', () => { - it('should not return them', async () => { - await connection.saveBlock(genesisBlock) - - const transactions = await repository.findAll({ type: 99 }) - - expect(transactions.count).toBe(0) - expect(transactions.rows).toBeArray() - expect(transactions.rows).toBeEmpty() - }) - }) - }) - - describe('findAllBySender', () => { - it('should be a function', () => { - expect(repository.findAllBySender).toBeFunction() - }) - - it('should find all transactions', async () => { - await connection.saveBlock(genesisBlock) - - const transactions = await repository.findAllBySender('03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe') - - expect(transactions.count).toBe(2) - expect(transactions.rows).toBeArray() - expect(transactions.rows).not.toBeEmpty() - transactions.rows.forEach(transaction => { - expect(transaction).toBeMinimalTransactionFields() - }) - }) - - describe('when no results', () => { - it('should not return them', async () => { - await connection.saveBlock(genesisBlock) - - const transactions = await repository.findAll({ type: 99 }) - - expect(transactions.count).toBe(0) - expect(transactions.rows).toBeArray() - expect(transactions.rows).toBeEmpty() - }) - }) - }) - - describe('findAllByRecipient', () => { - it('should be a function', () => { - expect(repository.findAllByRecipient).toBeFunction() - }) - - it('should find all transactions', async () => { - await connection.saveBlock(genesisBlock) - - const transactions = await repository.findAllByRecipient('AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t') - - expect(transactions.count).toBe(2) - expect(transactions.rows).toBeArray() - expect(transactions.rows).not.toBeEmpty() - transactions.rows.forEach(transaction => { - expect(transaction).toBeMinimalTransactionFields() - }) - }) - - describe('when no results', () => { - it('should not return them', async () => { - await connection.saveBlock(genesisBlock) - - const transactions = await repository.findAllByRecipient('none') - - expect(transactions.count).toBe(0) - expect(transactions.rows).toBeArray() - expect(transactions.rows).toBeEmpty() - }) - }) - }) - - describe('allVotesBySender', () => { - it('should be a function', () => { - expect(repository.allVotesBySender).toBeFunction() - }) - - it('should find all transactions', async () => { - await connection.saveBlock(genesisBlock) - - const transactions = await repository.allVotesBySender('03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357') - - expect(transactions.count).toBe(1) - expect(transactions.rows).toBeArray() - expect(transactions.rows).not.toBeEmpty() - transactions.rows.forEach(transaction => { - expect(transaction).toBeMinimalTransactionFields() - }) - }) - - describe('when no results', () => { - it('should not return them', async () => { - await connection.saveBlock(genesisBlock) - - const transactions = await repository.allVotesBySender('none') - - expect(transactions.count).toBe(0) - expect(transactions.rows).toBeArray() - expect(transactions.rows).toBeEmpty() - }) - }) - }) - - describe('findAllByBlock', () => { - it('should be a function', () => { - expect(repository.findAllByBlock).toBeFunction() - }) - - it('should find all transactions', async () => { - await connection.saveBlock(genesisBlock) - - const transactions = await repository.findAllByBlock(genesisBlock.data.id) - - // NOTE: The real count is avoided because it degrades the performance of the node - // expect(transactions.count).toBe(153) - expect(transactions.count).toBe(100) - expect(transactions.rows).toBeArray() - expect(transactions.rows).not.toBeEmpty() - transactions.rows.forEach(transaction => { - expect(transaction).toBeMinimalTransactionFields() - }) - }) - - describe('when no results', () => { - it('should not return them', async () => { - await connection.saveBlock(genesisBlock) - - const transactions = await repository.findAllByBlock('none') - - expect(transactions.count).toBe(0) - expect(transactions.rows).toBeArray() - expect(transactions.rows).toBeEmpty() - }) - }) - }) - - describe('findAllByType', () => { - it('should be a function', () => { - expect(repository.findAllByType).toBeFunction() - }) - - it('should find all transactions', async () => { - await connection.saveBlock(genesisBlock) - - const transactions = await repository.findAllByType(2) - - expect(transactions.count).toBe(51) - expect(transactions.rows).toBeArray() - expect(transactions.rows).not.toBeEmpty() - transactions.rows.forEach(transaction => { - expect(transaction).toBeMinimalTransactionFields() - }) - }) - - describe('when no results', () => { - it('should not return them', async () => { - await connection.saveBlock(genesisBlock) - - const transactions = await repository.findAllByType(88) - expect(transactions.rows).toBeArray() - expect(transactions.rows).toBeEmpty() - expect(transactions.count).toBe(0) - }) - }) - }) - - describe('findOne', () => { - it('should be a function', () => { - expect(repository.findOne).toBeFunction() - }) - - it('should find the transaction fields', async () => { - await connection.saveBlock(genesisBlock) - - const recipientId = 'AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri' - const senderPublicKey = '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788' - - const fields = await repository.findOne({ recipientId, senderPublicKey }) - expect(fields).toBeMinimalTransactionFields() - - const transaction = Transaction.deserialize(fields.serialized.toString('hex')) - expect(transaction.id).toBe('db1aa687737858cc9199bfa336f9b1c035915c30aaee60b1e0f8afadfdb946bd') - expect(transaction.recipientId).toBe(recipientId) - expect(transaction.senderPublicKey).toBe(senderPublicKey) - }) - - describe('when the block is cached', () => { - xit('uses it without executing additional queries', () => { - }) - }) - }) - - describe('findById', () => { - it('should be a function', () => { - expect(repository.findById).toBeFunction() - }) - - it('should find the transaction fields', async () => { - await connection.saveBlock(genesisBlock) - - const fields = await repository.findById(genesisTransaction.id) - expect(fields).toBeMinimalTransactionFields() - - const transaction = Transaction.deserialize(fields.serialized.toString('hex')) - expect(transaction.id).toBe(genesisTransaction.id) - }) - }) - - describe('findByTypeAndId', () => { - it('should be a function', () => { - expect(repository.findByTypeAndId).toBeFunction() - }) - - it('should find the transaction fields', async () => { - await connection.saveBlock(genesisBlock) - - const id = 'ea294b610e51efb3ceb4229f27bf773e87f41d21b6bb1f3bf68629ffd652c2d3' - const type = 3 - - const fields = await repository.findByTypeAndId(type, id) - expect(fields).toBeMinimalTransactionFields() - - const transaction = Transaction.deserialize(fields.serialized.toString('hex')) - expect(transaction.id).toBe(id) - expect(transaction.type).toBe(type) - }) - }) - - describe('search', async () => { - const expectSearch = async (params, expected) => { - await connection.saveBlock(genesisBlock) - - const transactions = await repository.search(params) - expect(transactions).toBeObject() - - expect(transactions.count).toBeNumber() - - expect(transactions.rows).toBeArray() - expect(transactions.rows).not.toBeEmpty() - transactions.rows.forEach(transaction => { - expect(transaction).toBeMinimalTransactionFields() - }) - - expect(transactions.count).toBe(expected) - } - - it('should be a function', () => { - expect(repository.search).toBeFunction() - }) - - it('should search transactions by the specified `id`', async () => { - await expectSearch({ id: genesisTransaction.id }, 1) - }) - - it('should search transactions by the specified `blockId`', async () => { - await expectSearch({ blockId: genesisTransaction.blockId }, 153) - }) - - it('should search transactions by the specified `type`', async () => { - await expectSearch({ type: genesisTransaction.type }, 153) - }) - - it('should search transactions by the specified `version`', async () => { - await expectSearch({ version: genesisTransaction.version }, 153) - }) - - // TODO when is not on the blockchain? - // TODO when is not indexed? - describe('when the wallet is indexed', () => { - const senderId = () => { - return crypto.getAddress(genesisTransaction.senderPublicKey, 23) - } - - beforeEach(() => { - const wallet = getWallet(senderId()) - wallet.publicKey = genesisTransaction.senderPublicKey - spv.walletManager.reindex(wallet) - }) - - it('should search transactions by the specified `senderId`', async () => { - await expectSearch({ senderId: senderId() }, 51) - }) - }) - - it('should search transactions by the specified `senderPublicKey`', async () => { - await expectSearch({ senderPublicKey: genesisTransaction.senderPublicKey }, 51) - }) - - it('should search transactions by the specified `recipientId`', async () => { - await expectSearch({ recipientId: genesisTransaction.recipientId }, 2) - }) - - it('should search transactions by the specified `timestamp`', async () => { - await expectSearch({ - timestamp: { - from: genesisTransaction.timestamp, - to: genesisTransaction.timestamp - } - }, 153) - }) - - it('should search transactions by the specified `amount`', async () => { - await expectSearch({ - amount: { - from: genesisTransaction.amount, - to: genesisTransaction.amount - } - }, 50) - }) - - it('should search transactions by the specified `fee`', async () => { - await expectSearch({ - fee: { - from: genesisTransaction.fee, - to: genesisTransaction.fee - } - }, 153) - }) - - it('should search transactions by the specified `vendorFieldHex`', async () => { - await expectSearch({ vendorFieldHex: genesisTransaction.vendorFieldHex }, 153) - }) - - describe('when there are more than 1 condition', () => { - it('should search transactions that includes all of them (AND)', async () => { - await expectSearch({ recipientId: genesisTransaction.recipientId, type: 3 }, 1) - }) - }) - - describe('when no results', () => { - it('should not return them', async () => { - await connection.saveBlock(genesisBlock) - - const transactions = await repository.search({ recipientId: 'dummy' }) - expect(transactions).toBeObject() - - expect(transactions).toHaveProperty('count', 0) - - expect(transactions.rows).toBeArray() - expect(transactions.rows).toBeEmpty() - }) - }) - }) - - describe('count', () => { - it('should return the total number of transactions', async () => { - await connection.saveBlock(genesisBlock) - - const { count } = await repository.count() - expect(count).toBe(153) - }) - }) -}) diff --git a/packages/core-database-sequelize/__tests__/spv.test.js b/packages/core-database-sequelize/__tests__/spv.test.js deleted file mode 100644 index c44baaa614..0000000000 --- a/packages/core-database-sequelize/__tests__/spv.test.js +++ /dev/null @@ -1,202 +0,0 @@ -'use strict' - -const app = require('./__support__/setup') -const createConnection = require('./__support__/utils/create-connection') - -let genesisBlock -let connection -let spv - -beforeAll(async () => { - await app.setUp() - - // Create the genesis block after the setup has finished or else it uses a potentially - // wrong network config. - genesisBlock = require('./__fixtures__/genesisBlock') -}) - -afterAll(async () => { - await app.tearDown() -}) - -beforeEach(async () => { - connection = await createConnection() - spv = new (require('../lib/spv'))(connection) -}) - -afterEach(async () => { - connection.disconnect() -}) - -const getWallet = address => { - return spv.walletManager.getWalletByAddress(address) -} - -const getWalletByPublicKey = publicKey => { - return spv.walletManager.getWalletByPublicKey(publicKey) -} - -describe('SPV', () => { - it('should be an object', () => { - expect(spv).toBeObject() - }) - - describe('build', () => { - it('should be a function', () => { - expect(spv.build).toBeFunction() - }) - }) - - describe('__buildReceivedTransactions', () => { - it('should be a function', () => { - expect(spv.__buildReceivedTransactions).toBeFunction() - }) - - it('should apply the transactions', async () => { - await connection.saveBlock(genesisBlock) - - expect(getWallet('AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof').balance).toBe(0) - - await spv.__buildReceivedTransactions() - - expect(getWallet('AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof').balance).toBe(245098000000000) - }) - }) - - describe('__buildBlockRewards', () => { - it('should be a function', () => { - expect(spv.__buildBlockRewards).toBeFunction() - }) - - it('should apply the transactions', async () => { - await connection.saveBlock(genesisBlock) - - const publicKey = '03b47f6b6719c76bad46a302d9cff7be9b1c2b2a20602a0d880f139b5b8901f068' - - spv.__buildBlockRewards = jest.fn(pass => { - const wallet = spv.walletManager.getWalletByPublicKey(pass) - wallet.balance += 10 - }) - - expect(getWalletByPublicKey(publicKey).balance).toBe(0) - - await spv.__buildBlockRewards(publicKey) - - expect(getWalletByPublicKey(publicKey).balance).toBe(10) - }) - }) - - describe('__buildLastForgedBlocks', () => { - it('should be a function', () => { - expect(spv.__buildLastForgedBlocks).toBeFunction() - }) - - it('should apply the last forged blocks', async () => { - await connection.saveBlock(genesisBlock) - - spv.activeDelegates = 51 - - const publicKey = '03b47f6b6719c76bad46a302d9cff7be9b1c2b2a20602a0d880f139b5b8901f068' - - expect(getWalletByPublicKey(publicKey).lastBlock).toBeNull() - - await spv.__buildLastForgedBlocks() - - expect(getWalletByPublicKey(publicKey).lastBlock.id).toBe('17184958558311101492') - }) - }) - - describe('__buildSentTransactions', () => { - it('should be a function', () => { - expect(spv.__buildSentTransactions).toBeFunction() - }) - - it('should apply the transactions', async () => { - await connection.saveBlock(genesisBlock) - - expect(getWallet('APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn').balance).toBe(0) - - await spv.__buildSentTransactions() - - expect(getWallet('APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn').balance).toBe(-12500000000000000) - }) - }) - - describe('__buildSecondSignatures', () => { - it('should be a function', () => { - expect(spv.__buildSecondSignatures).toBeFunction() - }) - - it('should apply the transactions', async () => { - await connection.saveBlock(genesisBlock) - - const publicKey = '03b47f6b6719c76bad46a302d9cff7be9b1c2b2a20602a0d880f139b5b8901f068' - - expect(getWalletByPublicKey(publicKey).secondPublicKey).toBeNull() - - spv.__buildSecondSignatures = jest.fn(pass => { - const wallet = spv.walletManager.getWalletByPublicKey(pass) - wallet.secondPublicKey = 'fake-key' - }) - - await spv.__buildSecondSignatures(publicKey) - - expect(getWalletByPublicKey(publicKey).secondPublicKey).toBe('fake-key') - }) - }) - - describe('__buildDelegates', () => { - it('should be a function', () => { - expect(spv.__buildDelegates).toBeFunction() - }) - - it('should apply the transactions', async () => { - await connection.saveBlock(genesisBlock) - - expect(getWallet('AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf').username).toBeNull() - - await spv.__buildDelegates() - - expect(getWallet('AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf').username).toBe('genesis_43') - }) - }) - - describe('__buildVotes', () => { - it('should be a function', () => { - expect(spv.__buildVotes).toBeFunction() - }) - - it('should apply the transactions', async () => { - await connection.saveBlock(genesisBlock) - - expect(getWallet('AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD').vote).toBeNull() - - await spv.__buildVotes() - - expect(getWallet('AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD').vote).toBe('02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a') - }) - }) - - describe('__buildMultisignatures', () => { - it('should be a function', () => { - expect(spv.__buildMultisignatures).toBeFunction() - }) - - it('should apply the transactions', async () => { - await connection.saveBlock(genesisBlock) - - const publicKey = '03b47f6b6719c76bad46a302d9cff7be9b1c2b2a20602a0d880f139b5b8901f068' - - expect(getWalletByPublicKey(publicKey).multisignature).toBeNull() - - spv.__buildMultisignatures = jest.fn(pass => { - const wallet = spv.walletManager.getWalletByPublicKey(pass) - wallet.multisignature = 'fake-multi-signature' - }) - - await spv.__buildMultisignatures(publicKey) - - expect(getWalletByPublicKey(publicKey).multisignature).toBe('fake-multi-signature') - }) - }) -}) diff --git a/packages/core-database-sequelize/jest.config.js b/packages/core-database-sequelize/jest.config.js deleted file mode 100644 index 26f7a25796..0000000000 --- a/packages/core-database-sequelize/jest.config.js +++ /dev/null @@ -1,22 +0,0 @@ -'use strict' - -module.exports = { - testEnvironment: 'node', - bail: false, - verbose: true, - testMatch: [ - '**/__tests__/**/*.test.js' - ], - moduleFileExtensions: [ - 'js', - 'json' - ], - collectCoverage: false, - coverageDirectory: '/.coverage', - collectCoverageFrom: [ - 'lib/**/*.js', - '!**/node_modules/**' - ], - watchman: false, - setupTestFrameworkScriptFile: 'jest-extended' -} diff --git a/packages/core-database-sequelize/lib/cache.js b/packages/core-database-sequelize/lib/cache.js deleted file mode 100644 index ac637e710e..0000000000 --- a/packages/core-database-sequelize/lib/cache.js +++ /dev/null @@ -1,34 +0,0 @@ -const Redis = require('ioredis') - -/** - * This is a simple implementation of a cache, currently using Redis only. - * More things to add: flushing, expiration, etc. - */ -module.exports = class Cache { - /** - * Instantiates new Redis object and connects automatically - */ - constructor (options) { - this.mount(options) - } - - getRedisOptions () { - return this.redis.options - } - - async get (key) { - this.redis.get(key) - } - - async set (key, value) { - this.redis.set(key, value) - } - - mount (options) { - this.redis = new Redis(options) - } - - destroy () { - this.redis.disconnect() - } -} diff --git a/packages/core-database-sequelize/lib/connection.js b/packages/core-database-sequelize/lib/connection.js deleted file mode 100644 index 8cab8658ef..0000000000 --- a/packages/core-database-sequelize/lib/connection.js +++ /dev/null @@ -1,817 +0,0 @@ -'use strict' - -const Sequelize = require('sequelize') -const Op = Sequelize.Op -const crypto = require('crypto') -const Umzug = require('umzug') -const glob = require('tiny-glob') -const path = require('path') -const fs = require('fs-extra') - -const { ConnectionInterface } = require('@arkecosystem/core-database') - -const container = require('@arkecosystem/core-container') -const config = container.resolvePlugin('config') -const logger = container.resolvePlugin('logger') -const emitter = container.resolvePlugin('event-emitter') - -const { Block, Transaction } = require('@arkecosystem/crypto').models - -const SPV = require('./spv') -const QueryBuilder = require('./query-builder') -const Cache = require('./cache') - -module.exports = class SequelizeConnection extends ConnectionInterface { - /** - * Make the database connection instance. - * @return {SequelizeConnection} - */ - async make () { - logger.verbose(`Connecting to Sequelize database (${this.config.dialect})`) - - if (this.connection) { - throw new Error('Sequelize connection already initialised') - } - - if (this.config.dialect === 'sqlite' && this.config.storage !== ':memory:') { - await fs.ensureFile(this.config.storage) - } - - const config = Object.assign({}, this.config) // shallow copy of this.config to safely delete config.redis below - delete config.redis - - this.connection = new Sequelize({ - ...config, - ...{ - operatorsAliases: Op, - logging: process.env.NODE_ENV === 'test' && !process.env.ARK_CI_TEST - } - }) - - this.asyncTransaction = null - - try { - await this.connect() - await this.__registerModels() - await this.__registerQueryBuilder() - await this.__registerCache() - await this.__runMigrations() - await this.__registerRepositories() - await super._registerWalletManager() - - this.blocksInCurrentRound = await this.__getBlocksForRound() - - return this - } catch (error) { - logger.error('Unable to connect to the database', error.stack) - process.exit(1) - } - } - - /** - * Connect to the database. - * @return {Boolean} - */ - async connect () { - return this.connection.authenticate() - } - - /** - * Disconnects from the database and closes the cache. - * @return {Promise} The successfulness of closing the Sequelize connection - */ - async disconnect () { - try { - await this.saveBlockCommit() - await this.deleteBlockCommit() - this.cache.destroy() - } catch (error) { - logger.warn('Issue in commiting blocks, database might be corrupted') - logger.warn(error.message) - } - - logger.verbose(`Disconnecting from Sequelize database (${this.config.dialect})`) - - return this.connection.close() - } - - /** - * Get the cache object - * @return {Cache} - */ - getCache () { - return this.cache - } - - /** - * Verify the blockchain stored on db is not corrupted making simple assertions: - * - Last block is available - * - Last block height equals the number of stored blocks - * - Number of stored transactions equals the sum of block.numberOfTransactions in the database - * - Sum of all tx fees equals the sum of block.totalFee - * - Sum of all tx amount equals the sum of block.totalAmount - * @return {Object} An object { valid, errors } with the result of the verification and the errors - */ - async verifyBlockchain () { - const errors = [] - - const lastBlock = await this.getLastBlock() - - // Last block is available - if (!lastBlock) { - errors.push('Last block is not available') - } else { - const numberOfBlocks = await this.__numberOfBlocks() - - // Last block height equals the number of stored blocks - if (lastBlock.data.height !== +numberOfBlocks) { - errors.push(`Last block height: ${lastBlock.data.height.toLocaleString()}, number of stored blocks: ${numberOfBlocks}`) - } - } - - const blockStats = await this.__blockStats() - const transactionStats = await this.__transactionStats() - - // Number of stored transactions equals the sum of block.numberOfTransactions in the database - if (blockStats.numberOfTransactions !== transactionStats.count) { - errors.push(`Number of transactions: ${transactionStats.count}, number of transactions included in blocks: ${blockStats.numberOfTransactions}`) - } - - // Sum of all tx fees equals the sum of block.totalFee - if (blockStats.totalFee !== transactionStats.totalFee) { - errors.push(`Total transaction fees: ${transactionStats.totalFee}, total of block.totalFee : ${blockStats.totalFee}`) - } - - // Sum of all tx amount equals the sum of block.totalAmount - if (blockStats.totalAmount !== transactionStats.totalAmount) { - errors.push(`Total transaction amounts: ${transactionStats.totalAmount}, total of block.totalAmount : ${blockStats.totalAmount}`) - } - - return { - valid: !errors.length, - errors - } - } - - /** - * Get the top 51 delegates. - * @param {Number} height - * @return {Array} - */ - async getActiveDelegates (height) { - const maxDelegates = config.getConstants(height).activeDelegates - const round = Math.floor((height - 1) / maxDelegates) + 1 - - if (this.activedelegates && this.activedelegates.length && this.activedelegates[0].round === round) { - return this.activedelegates - } - - const data = await this.query - .select('*') - .from('rounds') - .where('round', round) - .orderBy({ - 'balance': 'DESC', - 'public_key': 'ASC' - }) - .all() - - const seedSource = round.toString() - let currentSeed = crypto.createHash('sha256').update(seedSource, 'utf8').digest() - - for (let i = 0, delCount = data.length; i < delCount; i++) { - for (let x = 0; x < 4 && i < delCount; i++, x++) { - const newIndex = currentSeed[x] % delCount - const b = data[newIndex] - data[newIndex] = data[i] - data[i] = b - } - currentSeed = crypto.createHash('sha256').update(currentSeed).digest() - } - - this.activedelegates = data - - return this.activedelegates - } - - /** - * Store the given round. - * @param {Array} activeDelegates - * @return {Array} - */ - saveRound (activeDelegates) { - logger.info(`Saving round ${activeDelegates[0].round}`) - - return this.models.round.bulkCreate(activeDelegates) - } - - /** - * Delete the given round. - * @param {Number} round - * @return {Boolean} - */ - deleteRound (round) { - return this.models.round.destroy({ where: {round} }) - } - - /** - * Load a list of delegates into memory. - * @param {Number} maxDelegates - * @param {Number} height - * @return {Array} - */ - async buildDelegates (maxDelegates, height) { - if (height > 1 && height % maxDelegates !== 1) { - throw new Error('Trying to build delegates outside of round change') - } - - let data = await this.query - .select('"vote" AS "publicKey"') - .sum('balance', 'balance') - .from('wallets') - .whereNotNull('vote') - .groupBy('vote') - .all() - - // at the launch of blockchain, we may have not enough voted delegates, completing in a deterministic way (alphabetical order of publicKey) - if (data.length < maxDelegates) { - const chosen = data.map(delegate => delegate.publicKey) - - let query = this.query - .select('public_key') - .sum('balance', 'balance') - .from('wallets') - .whereNotNull('username') - - if (chosen.length) { - query = query.whereNotIn('public_key', chosen) - } - - const data2 = await query.groupBy('public_key') - .orderBy('public_key', 'ASC') - .limit(maxDelegates - data.length) - .all() - - data = data.concat(data2) - } - - // logger.info(`got ${data.length} voted delegates`) - const round = Math.floor((height - 1) / maxDelegates) + 1 - data = data - .sort((a, b) => b.balance - a.balance) - .slice(0, maxDelegates) - .map(delegate => ({ ...{ round }, ...delegate })) - - logger.debug(`Loaded ${data.length} active delegates`) - - return data - } - - /** - * Load a list of wallets into memory. - * @param {Number} height - * @return {Array} - */ - async buildWallets (height) { - this.walletManager.reset() - - const spvPath = `${process.env.ARK_PATH_DATA}/spv.json` - if (fs.existsSync(spvPath)) { - fs.removeSync(spvPath) - logger.info('ARK Core ended unexpectedly - resuming from where we left off :runner:') - return this.loadWallets() - } - - try { - const spv = new SPV(this) - await spv.build(height) - - await this.__registerListeners() - - return this.walletManager.walletsByAddress || [] - } catch (error) { - logger.error(error.stack) - } - } - - /** - * Load all wallets from database. - * @return {void} - */ - async loadWallets () { - const wallets = await this.query.select('*').from('wallets').all() - wallets.forEach(wallet => this.walletManager.reindex(wallet)) - - return this.walletManager.walletsByAddress || [] - } - - /** - * Commit wallets from the memory. - * @param {Boolean} force - * @return {Object} - */ - async saveWallets (force) { - const wallets = Object.values(this.walletManager.walletsByPublicKey || {}).filter(wallet => { - return wallet.publicKey && (force || wallet.dirty) - }) - - if (force) { // all wallets to be updated, performance is better without upsert - await this.models.wallet.destroy({truncate: true}) - const chunk = 5000 - // breaking into chunks of 5k wallets, to prevent from loading RAM with GB of SQL data - for (let i = 0, j = wallets.length; i < j; i += chunk) { - await this.connection.transaction(async dbtransaction => - this.models.wallet.bulkCreate(wallets.slice(i, i + chunk), { transaction: dbtransaction }) - ) - } - } else { - // NOTE: UPSERT is far from optimal. It can takes several seconds here - // if many accounts have to be updated at each round turn - // - // What can be done is to update accounts at each block in unsync manner - // what is really important is that db is sync with wallets in memory - // at round turn because votes computation to calculate active delegate list is made against database - // - // Other solution is to calculate the list of delegates against WalletManager so we can get rid off - // calling this function in sync manner i.e. 'await saveWallets()' -> 'saveWallets()' - await this.connection.transaction(async dbtransaction => - Promise.all(wallets.map(wallet => this.models.wallet.upsert(wallet, {transaction: dbtransaction}))) - ) - } - logger.info(`${wallets.length} modified wallets committed to database`) - - // commented out as more use cases to be taken care of - // this.walletManager.purgeEmptyNonDelegates() - - return Object.values(this.walletManager.walletsByAddress).forEach(wallet => (wallet.dirty = false)) - } - - /** - * Commit the given block. - * NOTE: to be used when node is in sync and committing newly received blocks - * @param {Block} block - * @return {Object} - */ - async saveBlock (block) { - let transaction - - try { - transaction = await this.connection.transaction() - await this.models.block.create(block.data, { transaction }) - if (block.transactions.length > 0) { - await this.models.transaction.bulkCreate(block.transactions, { transaction }) - } - await transaction.commit() - } catch (error) { - logger.error(error.stack) - if (error.sql) { - logger.info('Function saveBlock') - logger.info(error.sql) - } - await transaction.rollback() - throw error - } - } - - /** - * Commit the given block (async version). - * NOTE: to use when rebuilding to decrease the number of database tx, and commit blocks (save only every 1000s for instance) using saveBlockCommit - * @param {Block} block - * @return {void} - */ - async saveBlockAsync (block) { - if (!this.asyncTransaction) { - this.asyncTransaction = await this.connection.transaction() - } - - await this.models.block.create(block.data, { transaction: this.asyncTransaction }) - if (block.transactions.length > 0) { - await this.models.transaction.bulkCreate(block.transactions, { transaction: this.asyncTransaction }) - } - } - - /** - * Commit the block database transaction. - * NOTE: to be used in combination with saveBlockAsync - * @return {void} - */ - async saveBlockCommit () { - if (!this.asyncTransaction) { - return - } - - logger.debug('Committing database transaction') - - try { - await this.asyncTransaction.commit() - this.asyncTransaction = null - } catch (error) { - logger.error(error) - if (error.sql) { - logger.info('Function saveBlockCommit') - logger.info(error.sql) - } - await this.asyncTransaction.rollback() - this.asyncTransaction = null - throw error - } - } - - /** - * Delete the given block. - * @param {Block} block - * @return {void} - */ - async deleteBlock (block) { - let transaction - - try { - transaction = await this.connection.transaction() - await this.models.transaction.destroy({ where: { blockId: block.data.id } }, { transaction }) - await this.models.block.destroy({ where: { id: block.data.id } }, { transaction }) - await transaction.commit() - } catch (error) { - logger.error(error.stack) - if (error.sql) { - logger.info('Function deleteBlock') - logger.info(error.sql) - } - await transaction.rollback() - throw error - } - } - - /** - * Delete the given block (async version). - * @param {Block} block - * @return {void} - */ - async deleteBlockAsync (block) { - if (!this.asyncTransaction) { - this.asyncTransaction = await this.connection.transaction() - } - await this.models.transaction.destroy({ where: { blockId: block.data.id } }, { transaction: this.asyncTransaction }) - await this.models.block.destroy({ where: { id: block.data.id } }, { transaction: this.asyncTransaction }) - } - - /** - * Commit the block database transaction. - * NOTE: to be used in combination with deleteBlockAsync - * @return {void} - */ - async deleteBlockCommit () { - if (!this.asyncTransaction) { - return - } - - logger.debug('Committing database transaction') - - try { - await this.asyncTransaction.commit() - this.asyncTransaction = null - } catch (error) { - logger.error(error) - if (error.sql) { - logger.info('Function deleteBlockCommit') - logger.info(error.sql) - } - await this.asyncTransaction.rollback() - this.asyncTransaction = null - throw error - } - } - - /** - * Get a block. - * @param {Number} id - * @return {Block} - */ - async getBlock (id) { - // TODO: caching the last 1000 blocks, in combination with `saveBlock` could help to optimise - const block = await this.query - .select('*') - .from('blocks') - .where('id', id) - .first() - - if (!block) { - return null - } - - const transactions = await this.query - .select('serialized') - .from('transactions') - .where('block_id', block.id) - .all() - - block.transactions = transactions.map(({ serialized }) => Transaction.deserialize(serialized.toString('hex'))) - - return new Block(block) - } - - /** - * Get the last block. - * @return {(Block|null)} - */ - async getLastBlock () { - const block = await this.query - .select('*') - .from('blocks') - .orderBy('height', 'DESC') - .limit(1) - .first() - - if (!block) { - return null - } - - const transactions = await this.query - .select('serialized') - .from('transactions') - .where('block_id', block.id) - .orderBy('sequence', 'ASC') - .all() - - block.transactions = transactions.map(({ serialized }) => Transaction.deserialize(serialized.toString('hex'))) - - return new Block(block) - } - - /** - * Get a transaction. - * @param {Number} id - * @return {Promise} - */ - async getTransaction (id) { - const rows = await this.connection.query(`SELECT * FROM transactions WHERE id = '${id}'`, {type: Sequelize.QueryTypes.SELECT}) - - return rows[0] - } - - /** - * Get common blocks for the given IDs. - * @param {Array} ids - * @return {Promise} - */ - getCommonBlock (ids) { - return this.connection.query(`SELECT MAX("height") AS "height", "id", "previous_block", "timestamp" FROM blocks WHERE "id" IN ('${ids.join('\',\'')}') GROUP BY "id" ORDER BY "height" DESC`, {type: Sequelize.QueryTypes.SELECT}) - } - - /** - * Get transactions for the given IDs. - * @param {Array} transactionIds - * @return {Array} - */ - async getTransactionsFromIds (transactionIds) { - return this.connection.query(`SELECT serialized, block_id FROM transactions WHERE id IN ('${transactionIds.join('\',\'')}')`, {type: Sequelize.QueryTypes.SELECT}) - } - - /** - * Get forged transactions for the given IDs. - * @param {Array} transactionIds - * @return {Array} - */ - async getForgedTransactionsIds (transactionIds) { - const rows = await this.connection.query(`SELECT id FROM transactions WHERE id IN ('${transactionIds.join('\',\'')}')`, {type: Sequelize.QueryTypes.SELECT}) - - return rows.map(transaction => transaction.id) - } - - /** - * Get blocks for the given offset and limit. - * @param {Number} offset - * @param {Number} limit - * @return {Array} - */ - async getBlocks (offset, limit) { - let blocks = await this.query - .select('*') - .from('blocks') - .whereBetween('height', offset, offset + limit) - .orderBy('height', 'ASC') - .all() - - let transactions = [] - - const ids = blocks.map(block => block.id) - - if (ids.length) { - transactions = await this.query - .select('block_id', 'serialized') - .from('transactions') - .whereIn('block_id', ids) - .orderBy('sequence', 'ASC') - .all() - transactions = transactions.map(tx => { - const data = Transaction.deserialize(tx.serialized.toString('hex')) - data.blockId = tx.blockId - return data - }) - } - - for (let block of blocks) { - if (block.numberOfTransactions > 0) { - block.transactions = transactions.filter(transaction => transaction.blockId === block.id) - } - } - - return blocks - } - - /** - * Get recent block ids. - * @return {[]String} - */ - async getRecentBlockIds () { - const blocks = await this.query - .select('id') - .from('blocks') - .orderBy({ timestamp: 'DESC' }) - .limit(10) - .all() - - return blocks.map(block => block.id) - } - - /** - * Get the headers of blocks for the given offset and limit. - * @param {Number} offset - * @param {Number} limit - * @return {Array} - */ - async getBlockHeaders (offset, limit) { - let blocks = await this.query - .select('*') - .from('blocks') - .whereBetween('height', offset, offset + limit) - .all() - - return blocks.map(block => Block.serialize(block)) - } - - /** - * Create an OR or AND condition. - * @param {String} type - * @param {Object} params - * @return {} - */ - createCondition (type, params) { - if (!Object.keys(Sequelize.Op).includes(type)) { - return {} - } - - return { [Sequelize.Op[type]]: params } - } - - /** - * Register the query builder. - * @return {void} - */ - __registerQueryBuilder () { - this.query = new QueryBuilder(this.connection, this.models) - } - - /** - * Run all migrations. - * @return {Boolean} - */ - __runMigrations () { - const umzug = new Umzug({ - storage: 'sequelize', - storageOptions: { - sequelize: this.connection - }, - migrations: { - params: [ - this.connection.getQueryInterface(), - Sequelize, - this - ], - path: path.join(__dirname, 'migrations') - } - }) - - return umzug.up() - } - - /** - * Register all models. - * @return {void} - */ - async __registerModels () { - this.models = {} - - const entries = await glob('models/**/*.js', { - cwd: __dirname, absolute: true, filesOnly: true - }) - - entries.forEach(file => { - const model = this.connection['import'](file) - this.models[model.name] = model - }) - - Object.keys(this.models).forEach(modelName => { - if (this.models[modelName].associate) { - this.models[modelName].associate(this.models) - } - }) - } - - /** - * Register all repositories. - * @return {void} - */ - async __registerRepositories () { - const repositories = { - blocks: require('./repositories/blocks'), - transactions: require('./repositories/transactions') - } - - for (const [key, Value] of Object.entries(repositories)) { - this[key] = new Value(this) // eslint-disable-line new-cap - } - - await super._registerRepositories() - } - - /** - * Register event listeners. - * @return {void} - */ - __registerListeners () { - super.__registerListeners() - emitter.on('wallet:cold:created', async coldWallet => { - try { - const wallet = await this.query - .select('*') - .from('wallets') - .where('address', coldWallet.address) - .first() - - if (wallet) { - Object.keys(wallet).forEach(key => { - if (['balance'].indexOf(key) !== -1) { - return - } - - coldWallet[key] = wallet[key] - }) - } - } catch (err) { - logger.error(err) - } - }) - } - - /** - * Register the cache. - * @return {void} - */ - __registerCache () { - this.cache = new Cache(this.config.redis) - } - - /** - * This auxiliary method returns the number of blocks of the blockchain and - * is used to verify it - * @return {Number} - */ - async __numberOfBlocks () { - const { count } = await this.query - .select() - .countDistinct('height', 'count') - .from('blocks') - .first() - return count - } - - /** - * This auxiliary method returns some stats about the blocks that are - * used to verify the blockchain - * @return {Object} - */ - async __blockStats () { - return this.query - .select() - .sum('number_of_transactions', 'numberOfTransactions') - .sum('total_fee', 'totalFee') - .sum('total_amount', 'totalAmount') - .from('blocks') - .first() - } - - /** - * This auxiliary method returns some stats about the transactions that are - * used to verify the blockchain - * @return {Object} - */ - async __transactionStats () { - return this.query - .select() - .countDistinct('id', 'count') - .sum('fee', 'totalFee') - .sum('amount', 'totalAmount') - .from('transactions') - .first() - } -} diff --git a/packages/core-database-sequelize/lib/defaults.js b/packages/core-database-sequelize/lib/defaults.js deleted file mode 100644 index cbdc2930c6..0000000000 --- a/packages/core-database-sequelize/lib/defaults.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict' - -module.exports = { - dialect: 'sqlite', - storage: process.env.ARK_DB_STORAGE || `${process.env.ARK_PATH_DATA}/database/${process.env.ARK_NETWORK_NAME}.sqlite`, - logging: process.env.ARK_DB_LOGGING, - redis: { - host: process.env.ARK_REDIS_HOST || 'localhost', - port: process.env.ARK_REDIS_PORT || 6379 - } -} diff --git a/packages/core-database-sequelize/lib/migrations/20180305163239-create-wallet.js b/packages/core-database-sequelize/lib/migrations/20180305163239-create-wallet.js deleted file mode 100644 index b8036936c2..0000000000 --- a/packages/core-database-sequelize/lib/migrations/20180305163239-create-wallet.js +++ /dev/null @@ -1,55 +0,0 @@ -'use strict' - -/** - * The wallets migration. - * @type {Object} - */ -module.exports = { - /** - * Run the migrations. - * @param {Sequelize.QueryInterface} queryInterface - * @param {Sequelize} Sequelize - * @return {void} - */ - async up (queryInterface, Sequelize) { - await queryInterface.createTable('wallets', { - address: { - allowNull: false, - unique: true, - primaryKey: true, - type: Sequelize.STRING(36) - }, - publicKey: { - unique: true, - allowNull: false, - type: Sequelize.STRING(66) - }, - secondPublicKey: Sequelize.STRING(66), - vote: Sequelize.STRING(66), - username: Sequelize.STRING(64), - balance: Sequelize.BIGINT, - votebalance: Sequelize.BIGINT, - producedBlocks: Sequelize.BIGINT, - missedBlocks: Sequelize.BIGINT, - createdAt: { - allowNull: false, - type: Sequelize.DATE - }, - updatedAt: { - allowNull: false, - type: Sequelize.DATE - } - }) - - queryInterface.addIndex('wallets', ['address', 'publicKey', 'vote', 'username']) - }, - /** - * Reverse the migrations. - * @param {Sequelize.QueryInterface} queryInterface - * @param {Sequelize} Sequelize - * @return {void} - */ - async down (queryInterface, Sequelize) { - return queryInterface.dropTable('wallets') - } -} diff --git a/packages/core-database-sequelize/lib/migrations/20180305163240-create-round.js b/packages/core-database-sequelize/lib/migrations/20180305163240-create-round.js deleted file mode 100644 index 26b7859f5c..0000000000 --- a/packages/core-database-sequelize/lib/migrations/20180305163240-create-round.js +++ /dev/null @@ -1,53 +0,0 @@ -'use strict' - -/** - * The rounds migration. - * @type {Object} - */ -module.exports = { - /** - * Run the migrations. - * @param {Sequelize.QueryInterface} queryInterface - * @param {Sequelize} Sequelize - * @return {void} - */ - async up (queryInterface, Sequelize) { - await queryInterface.createTable('rounds', { - id: { - allowNull: false, - autoIncrement: true, - primaryKey: true, - type: Sequelize.INTEGER - }, - publicKey: { - type: Sequelize.STRING(66) - }, - balance: Sequelize.BIGINT, - round: Sequelize.BIGINT, - createdAt: { - allowNull: false, - type: Sequelize.DATE - }, - updatedAt: { - allowNull: false, - type: Sequelize.DATE - } - }) - - await queryInterface.addConstraint('rounds', ['publicKey', 'round'], { - type: 'unique', - name: 'rounds_unique' - }) - - queryInterface.addIndex('rounds', ['publicKey', 'round']) - }, - /** - * Reverse the migrations. - * @param {Sequelize.QueryInterface} queryInterface - * @param {Sequelize} Sequelize - * @return {void} - */ - async down (queryInterface, Sequelize) { - return queryInterface.dropTable('rounds') - } -} diff --git a/packages/core-database-sequelize/lib/migrations/20180305163241-create-block.js b/packages/core-database-sequelize/lib/migrations/20180305163241-create-block.js deleted file mode 100644 index cfb4833cf0..0000000000 --- a/packages/core-database-sequelize/lib/migrations/20180305163241-create-block.js +++ /dev/null @@ -1,63 +0,0 @@ -'use strict' - -/** - * The blocks migration. - * @type {Object} - */ -module.exports = { - /** - * Run the migrations. - * @param {Sequelize.QueryInterface} queryInterface - * @param {Sequelize} Sequelize - * @return {void} - */ - async up (queryInterface, Sequelize) { - await queryInterface.createTable('blocks', { - id: { - allowNull: false, - autoIncrement: false, - primaryKey: true, - type: Sequelize.STRING(64) - }, - version: Sequelize.SMALLINT, // TODO - timestamp: { - unique: true, - type: Sequelize.INTEGER - }, - previousBlock: Sequelize.STRING(64), - height: { - unique: true, - type: Sequelize.INTEGER - }, - numberOfTransactions: Sequelize.INTEGER, // TODO - totalAmount: Sequelize.BIGINT, - totalFee: Sequelize.BIGINT, - reward: Sequelize.BIGINT, - payloadLength: Sequelize.INTEGER, - payloadHash: Sequelize.STRING(64), - generatorPublicKey: { - type: Sequelize.STRING(66) - }, - blockSignature: Sequelize.STRING(256), - createdAt: { - allowNull: false, - type: Sequelize.DATE - }, - updatedAt: { - allowNull: false, - type: Sequelize.DATE - } - }) - - queryInterface.addIndex('blocks', ['height', 'generatorPublicKey']) - }, - /** - * Reverse the migrations. - * @param {Sequelize.QueryInterface} queryInterface - * @param {Sequelize} Sequelize - * @return {void} - */ - async down (queryInterface, Sequelize) { - return queryInterface.dropTable('blocks') - } -} diff --git a/packages/core-database-sequelize/lib/migrations/20180305163243-create-transaction.js b/packages/core-database-sequelize/lib/migrations/20180305163243-create-transaction.js deleted file mode 100644 index 42bd7b9b56..0000000000 --- a/packages/core-database-sequelize/lib/migrations/20180305163243-create-transaction.js +++ /dev/null @@ -1,63 +0,0 @@ -'use strict' - -/** - * The transactions migration. - * @type {Object} - */ -module.exports = { - /** - * Run the migrations. - * @param {Sequelize.QueryInterface} queryInterface - * @param {Sequelize} Sequelize - * @return {void} - */ - async up (queryInterface, Sequelize) { - await queryInterface.createTable('transactions', { - id: { - allowNull: false, - autoIncrement: false, - primaryKey: true, - type: Sequelize.STRING(64) - }, - version: Sequelize.SMALLINT, // TODO - blockId: { - type: Sequelize.STRING(64) - }, - sequence: { - allowNull: false, - type: Sequelize.SMALLINT - }, - timestamp: Sequelize.INTEGER, - senderPublicKey: { - type: Sequelize.STRING(66) - }, - recipientId: { - type: Sequelize.STRING(36) - }, - type: Sequelize.SMALLINT, - vendorFieldHex: Sequelize.BLOB, - amount: Sequelize.BIGINT, - fee: Sequelize.BIGINT, - serialized: Sequelize.BLOB(), - createdAt: { - allowNull: false, - type: Sequelize.DATE - }, - updatedAt: { - allowNull: false, - type: Sequelize.DATE - } - }) - - queryInterface.addIndex('transactions', ['senderPublicKey', 'recipientId', 'vendorFieldHex', 'timestamp']) - }, - /** - * Reverse the migrations. - * @param {Sequelize.QueryInterface} queryInterface - * @param {Sequelize} Sequelize - * @return {void} - */ - async down (queryInterface, Sequelize) { - return queryInterface.dropTable('transactions') - } -} diff --git a/packages/core-database-sequelize/lib/migrations/20180628100408-update-transaction.js.back b/packages/core-database-sequelize/lib/migrations/20180628100408-update-transaction.js.back deleted file mode 100644 index 64d3008c11..0000000000 --- a/packages/core-database-sequelize/lib/migrations/20180628100408-update-transaction.js.back +++ /dev/null @@ -1,64 +0,0 @@ -'use strict' -const { Block, Transaction } = require('@arkecosystem/crypto').models -const logger = require('@arkecosystem/core-container').resolvePlugin('logger') - -/** - * The transactions migration. - * @type {Object} - */ -module.exports = { - /** - * Run the migrations. - * @param {Sequelize.QueryInterface} queryInterface - * @param {Sequelize} Sequelize - * @return {void} - */ - async up (queryInterface, Sequelize, manager) { - // await queryInterface.addColumn('transactions', 'sequence', { - // allowNull: false, - // defaultValue: 0, - // type: Sequelize.SMALLINT - // }) - const blocks = await manager.query - .select('*') - .from('blocks') - .where('numberOfTransactions', '>', 1) - .all() - - let index = 0 - const max = blocks.length - const wrongBlocks = [] - await Promise.all(blocks.map(async block => { - const transactions = await manager.query - .select('serialized') - .from('transactions') - .where('blockId', block.id) - .all() - - block.transactions = transactions.map(transaction => Transaction.deserialize(transaction.serialized.toString('hex'))) - const test = new Block(block) - let message = 'Checking transaction orders' - if (wrongBlocks.length > 0) message = `Found ${wrongBlocks.length} errorneous blocks` - logger.printTracker('Database Migration', index++, max, message) - if (!test.verification.verified) { - wrongBlocks.push(test) - } - return test - })) - - await Promise.all(wrongBlocks.map(async block => { - - })) - - // throw new Error('dummy') - }, - /** - * Reverse the migrations. - * @param {Sequelize.QueryInterface} queryInterface - * @param {Sequelize} Sequelize - * @return {void} - */ - async down (queryInterface, Sequelize) { - return queryInterface.removeColumn('transactions', 'sequence') - } -} diff --git a/packages/core-database-sequelize/lib/migrations/20182506163244-rename-block-columns.js b/packages/core-database-sequelize/lib/migrations/20182506163244-rename-block-columns.js deleted file mode 100644 index a004337c77..0000000000 --- a/packages/core-database-sequelize/lib/migrations/20182506163244-rename-block-columns.js +++ /dev/null @@ -1,53 +0,0 @@ -'use strict' - -/** - * The blocks migration. - * @type {Object} - */ -module.exports = { - /** - * Run the migrations. - * @param {Sequelize.QueryInterface} queryInterface - * @param {Sequelize} Sequelize - * @return {void} - */ - async up (queryInterface, Sequelize) { - await queryInterface.removeIndex('blocks', ['height', 'generatorPublicKey']) - - await queryInterface.renameColumn('blocks', 'previousBlock', 'previous_block') - await queryInterface.renameColumn('blocks', 'numberOfTransactions', 'number_of_transactions') - await queryInterface.renameColumn('blocks', 'totalAmount', 'total_amount') - await queryInterface.renameColumn('blocks', 'totalFee', 'total_fee') - await queryInterface.renameColumn('blocks', 'payloadLength', 'payload_length') - await queryInterface.renameColumn('blocks', 'payloadHash', 'payload_hash') - await queryInterface.renameColumn('blocks', 'generatorPublicKey', 'generator_public_key') - await queryInterface.renameColumn('blocks', 'blockSignature', 'block_signature') - await queryInterface.renameColumn('blocks', 'createdAt', 'created_at') - await queryInterface.renameColumn('blocks', 'updatedAt', 'updated_at') - - return queryInterface.addIndex('blocks', ['height', 'generator_public_key']) - }, - - /** - * Reverse the migrations. - * @param {Sequelize.QueryInterface} queryInterface - * @param {Sequelize} Sequelize - * @return {void} - */ - async down (queryInterface, Sequelize) { - await queryInterface.removeIndex('blocks', ['height', 'generator_public_key']) - - await queryInterface.renameColumn('blocks', 'updated_at', 'updatedAt') - await queryInterface.renameColumn('blocks', 'created_at', 'createdAt') - await queryInterface.renameColumn('blocks', 'block_signature', 'blockSignature') - await queryInterface.renameColumn('blocks', 'generator_public_key', 'generatorPublicKey') - await queryInterface.renameColumn('blocks', 'payload_hash', 'payloadHash') - await queryInterface.renameColumn('blocks', 'payload_length', 'payloadLength') - await queryInterface.renameColumn('blocks', 'total_fee', 'totalFee') - await queryInterface.renameColumn('blocks', 'total_amount', 'totalAmount') - await queryInterface.renameColumn('blocks', 'number_of_transactions', 'numberOfTransactions') - await queryInterface.renameColumn('blocks', 'previous_block', 'previousBlock') - - return queryInterface.addIndex('blocks', ['height', 'generatorPublicKey']) - } -} diff --git a/packages/core-database-sequelize/lib/migrations/20182506163244-rename-round-columns.js b/packages/core-database-sequelize/lib/migrations/20182506163244-rename-round-columns.js deleted file mode 100644 index 45a1f87015..0000000000 --- a/packages/core-database-sequelize/lib/migrations/20182506163244-rename-round-columns.js +++ /dev/null @@ -1,51 +0,0 @@ -'use strict' - -/** - * The rounds migration. - * @type {Object} - */ -module.exports = { - /** - * Run the migrations. - * @param {Sequelize.QueryInterface} queryInterface - * @param {Sequelize} Sequelize - * @return {void} - */ - async up (queryInterface, Sequelize) { - await queryInterface.removeConstraint('rounds', 'rounds_unique') - await queryInterface.removeIndex('rounds', ['publicKey', 'round']) - - await queryInterface.renameColumn('rounds', 'publicKey', 'public_key') - await queryInterface.renameColumn('rounds', 'createdAt', 'created_at') - await queryInterface.renameColumn('rounds', 'updatedAt', 'updated_at') - - await queryInterface.addConstraint('rounds', ['public_key', 'round'], { - type: 'unique', - name: 'rounds_unique' - }) - - return queryInterface.addIndex('rounds', ['public_key', 'round']) - }, - - /** - * Reverse the migrations. - * @param {Sequelize.QueryInterface} queryInterface - * @param {Sequelize} Sequelize - * @return {void} - */ - async down (queryInterface, Sequelize) { - await queryInterface.removeConstraint('rounds', 'rounds_unique') - await queryInterface.removeIndex('rounds', ['public_key', 'round']) - - await queryInterface.renameColumn('rounds', 'updated_at', 'updatedAt') - await queryInterface.renameColumn('rounds', 'created_at', 'createdAt') - await queryInterface.renameColumn('rounds', 'public_key', 'publicKey') - - await queryInterface.addConstraint('rounds', ['publicKey', 'round'], { - type: 'unique', - name: 'rounds_unique' - }) - - return queryInterface.addIndex('rounds', ['publicKey', 'round']) - } -} diff --git a/packages/core-database-sequelize/lib/migrations/20182506163244-rename-transaction-columns.js b/packages/core-database-sequelize/lib/migrations/20182506163244-rename-transaction-columns.js deleted file mode 100644 index 44ba5f8786..0000000000 --- a/packages/core-database-sequelize/lib/migrations/20182506163244-rename-transaction-columns.js +++ /dev/null @@ -1,45 +0,0 @@ -'use strict' - -/** - * The transactions migration. - * @type {Object} - */ -module.exports = { - /** - * Run the migrations. - * @param {Sequelize.QueryInterface} queryInterface - * @param {Sequelize} Sequelize - * @return {void} - */ - async up (queryInterface, Sequelize) { - await queryInterface.removeIndex('transactions', ['senderPublicKey', 'recipientId', 'vendorFieldHex', 'timestamp']) - - await queryInterface.renameColumn('transactions', 'blockId', 'block_id') - await queryInterface.renameColumn('transactions', 'senderPublicKey', 'sender_public_key') - await queryInterface.renameColumn('transactions', 'recipientId', 'recipient_id') - await queryInterface.renameColumn('transactions', 'vendorFieldHex', 'vendor_field_hex') - await queryInterface.renameColumn('transactions', 'createdAt', 'created_at') - await queryInterface.renameColumn('transactions', 'updatedAt', 'updated_at') - - return queryInterface.addIndex('transactions', ['sender_public_key', 'recipient_id', 'vendor_field_hex', 'timestamp']) - }, - - /** - * Reverse the migrations. - * @param {Sequelize.QueryInterface} queryInterface - * @param {Sequelize} Sequelize - * @return {void} - */ - async down (queryInterface, Sequelize) { - await queryInterface.removeIndex('transactions', ['sender_public_key', 'recipient_id', 'vendor_field_hex', 'timestamp']) - - await queryInterface.renameColumn('transactions', 'updated_at', 'updatedAt') - await queryInterface.renameColumn('transactions', 'created_at', 'createdAt') - await queryInterface.renameColumn('transactions', 'vendor_field_hex', 'vendorFieldHex') - await queryInterface.renameColumn('transactions', 'recipient_id', 'recipientId') - await queryInterface.renameColumn('transactions', 'sender_public_key', 'senderPublicKey') - await queryInterface.renameColumn('transactions', 'block_id', 'blockId') - - await queryInterface.addIndex('transactions', ['senderPublicKey', 'recipientId', 'vendorFieldHex', 'timestamp']) - } -} diff --git a/packages/core-database-sequelize/lib/migrations/20182506163244-rename-wallet-columns.js b/packages/core-database-sequelize/lib/migrations/20182506163244-rename-wallet-columns.js deleted file mode 100644 index 7a60abf77d..0000000000 --- a/packages/core-database-sequelize/lib/migrations/20182506163244-rename-wallet-columns.js +++ /dev/null @@ -1,47 +0,0 @@ -'use strict' - -/** - * The wallets migration. - * @type {Object} - */ -module.exports = { - /** - * Run the migrations. - * @param {Sequelize.QueryInterface} queryInterface - * @param {Sequelize} Sequelize - * @return {void} - */ - async up (queryInterface, Sequelize) { - await queryInterface.removeIndex('wallets', ['address', 'publicKey', 'vote', 'username']) - - await queryInterface.renameColumn('wallets', 'publicKey', 'public_key') - await queryInterface.renameColumn('wallets', 'secondPublicKey', 'second_public_key') - await queryInterface.renameColumn('wallets', 'votebalance', 'vote_balance') - await queryInterface.renameColumn('wallets', 'producedBlocks', 'produced_blocks') - await queryInterface.renameColumn('wallets', 'missedBlocks', 'missed_blocks') - await queryInterface.renameColumn('wallets', 'createdAt', 'created_at') - await queryInterface.renameColumn('wallets', 'updatedAt', 'updated_at') - - return queryInterface.addIndex('wallets', ['address', 'public_key', 'vote', 'username']) - }, - - /** - * Reverse the migrations. - * @param {Sequelize.QueryInterface} queryInterface - * @param {Sequelize} Sequelize - * @return {void} - */ - async down (queryInterface, Sequelize) { - await queryInterface.removeIndex('wallets', ['address', 'public_key', 'vote', 'username']) - - await queryInterface.renameColumn('wallets', 'updated_at', 'updatedAt') - await queryInterface.renameColumn('wallets', 'created_at', 'createdAt') - await queryInterface.renameColumn('wallets', 'missed_blocks', 'missedBlocks') - await queryInterface.renameColumn('wallets', 'produced_blocks', 'producedBlocks') - await queryInterface.renameColumn('wallets', 'vote_balance', 'votebalance') - await queryInterface.renameColumn('wallets', 'second_public_key', 'secondPublicKey') - await queryInterface.renameColumn('wallets', 'public_key', 'publicKey') - - return queryInterface.addIndex('wallets', ['address', 'publicKey', 'vote', 'username']) - } -} diff --git a/packages/core-database-sequelize/lib/models/block.js b/packages/core-database-sequelize/lib/models/block.js deleted file mode 100644 index 283af52cc4..0000000000 --- a/packages/core-database-sequelize/lib/models/block.js +++ /dev/null @@ -1,70 +0,0 @@ -'use strict' - -/** - * Define the block model. - * @param {Sequelize} sequelize - * @param {Sequelize.DataTypes} DataTypes - * @return {Sequelize.Model} - */ -module.exports = (sequelize, DataTypes) => { - const Block = sequelize.define('block', { - id: { - allowNull: false, - autoIncrement: false, - primaryKey: true, - type: DataTypes.STRING(64) - }, - version: DataTypes.SMALLINT, // TODO - timestamp: { - unique: true, - type: DataTypes.INTEGER - }, - previousBlock: { - type: DataTypes.STRING(64), - field: 'previous_block' - }, - height: { - unique: true, - type: DataTypes.INTEGER - }, - numberOfTransactions: { - type: DataTypes.INTEGER, // TODO - field: 'number_of_transactions' - }, - totalAmount: { - type: DataTypes.BIGINT, - field: 'total_amount' - }, - totalFee: { - type: DataTypes.BIGINT, - field: 'total_fee' - }, - reward: DataTypes.BIGINT, - payloadLength: { - type: DataTypes.INTEGER, - field: 'payload_length' - }, - payloadHash: { - type: DataTypes.STRING(64), - field: 'payload_hash' - }, - generatorPublicKey: { - type: DataTypes.STRING(66), - field: 'generator_public_key' - }, - blockSignature: { - type: DataTypes.STRING(256), - field: 'block_signature' - }, - createdAt: { - type: DataTypes.DATE, - field: 'created_at' - }, - updatedAt: { - type: DataTypes.DATE, - field: 'updated_at' - } - }, {}) - - return Block -} diff --git a/packages/core-database-sequelize/lib/models/round.js b/packages/core-database-sequelize/lib/models/round.js deleted file mode 100644 index 2ed198b9cf..0000000000 --- a/packages/core-database-sequelize/lib/models/round.js +++ /dev/null @@ -1,34 +0,0 @@ -'use strict' - -/** - * Define the round model. - * @param {Sequelize} sequelize - * @param {Sequelize.DataTypes} DataTypes - * @return {Sequelize.Model} - */ -module.exports = (sequelize, DataTypes) => { - const Round = sequelize.define('round', { - id: { - allowNull: false, - autoIncrement: true, - primaryKey: true, - type: DataTypes.INTEGER - }, - publicKey: { - type: DataTypes.STRING(66), - field: 'public_key' - }, - balance: DataTypes.BIGINT, - round: DataTypes.BIGINT, - createdAt: { - type: DataTypes.DATE, - field: 'created_at' - }, - updatedAt: { - type: DataTypes.DATE, - field: 'updated_at' - } - }, {}) - - return Round -} diff --git a/packages/core-database-sequelize/lib/models/transaction.js b/packages/core-database-sequelize/lib/models/transaction.js deleted file mode 100644 index 731eb94952..0000000000 --- a/packages/core-database-sequelize/lib/models/transaction.js +++ /dev/null @@ -1,54 +0,0 @@ -'use strict' - -/** - * Define the transaction model. - * @param {Sequelize} sequelize - * @param {Sequelize.DataTypes} DataTypes - * @return {Sequelize.Model} - */ -module.exports = (sequelize, DataTypes) => { - const Transaction = sequelize.define('transaction', { - id: { - allowNull: false, - autoIncrement: false, - primaryKey: true, - type: DataTypes.STRING(64) - }, - version: DataTypes.SMALLINT, // TODO - blockId: { - type: DataTypes.STRING(64), - field: 'block_id' - }, - sequence: { - allowNull: false, - type: DataTypes.SMALLINT - }, - timestamp: DataTypes.INTEGER, - senderPublicKey: { - type: DataTypes.STRING(66), - field: 'sender_public_key' - }, - recipientId: { - type: DataTypes.STRING(36), - field: 'recipient_id' - }, - type: DataTypes.SMALLINT, - vendorFieldHex: { - type: DataTypes.BLOB, - field: 'vendor_field_hex' - }, - amount: DataTypes.BIGINT, - fee: DataTypes.BIGINT, - serialized: DataTypes.BLOB, - createdAt: { - type: DataTypes.DATE, - field: 'created_at' - }, - updatedAt: { - type: DataTypes.DATE, - field: 'updated_at' - } - }, {}) - - return Transaction -} diff --git a/packages/core-database-sequelize/lib/models/wallet.js b/packages/core-database-sequelize/lib/models/wallet.js deleted file mode 100644 index a4d58777a6..0000000000 --- a/packages/core-database-sequelize/lib/models/wallet.js +++ /dev/null @@ -1,52 +0,0 @@ -'use strict' - -/** - * Define the wallet model. - * @param {Sequelize} sequelize - * @param {Sequelize.DataTypes} DataTypes - * @return {Sequelize.Model} - */ -module.exports = (sequelize, DataTypes) => { - const Wallet = sequelize.define('wallet', { - address: { - allowNull: false, - unique: true, - primaryKey: true, - type: DataTypes.STRING(36) - }, - publicKey: { - unique: true, - type: DataTypes.STRING(66), - field: 'public_key' - }, - secondPublicKey: { - type: DataTypes.STRING(66), - field: 'second_public_key' - }, - vote: DataTypes.STRING(66), - username: DataTypes.STRING(64), - balance: DataTypes.BIGINT, - votebalance: { - type: DataTypes.BIGINT, - field: 'vote_balance' - }, - producedBlocks: { - type: DataTypes.BIGINT, - field: 'produced_blocks' - }, - missedBlocks: { - type: DataTypes.BIGINT, - field: 'missed_blocks' - }, - createdAt: { - type: DataTypes.DATE, - field: 'created_at' - }, - updatedAt: { - type: DataTypes.DATE, - field: 'updated_at' - } - }, {}) - - return Wallet -} diff --git a/packages/core-database-sequelize/lib/query-builder/clauses/abstracts/aggregate.js b/packages/core-database-sequelize/lib/query-builder/clauses/abstracts/aggregate.js deleted file mode 100644 index 354e0bc59a..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/clauses/abstracts/aggregate.js +++ /dev/null @@ -1,11 +0,0 @@ -const escape = require('../../utils/escape') - -module.exports = (method, column, alias) => { - column = Array.isArray(column) - ? column.map(item => escape(item)).join('+') - : escape(column) - - return alias - ? `${method} (${column}) AS ${escape(alias)}` - : `${method} (${column}) AS ${column}` -} diff --git a/packages/core-database-sequelize/lib/query-builder/clauses/aggregates/avg.js b/packages/core-database-sequelize/lib/query-builder/clauses/aggregates/avg.js deleted file mode 100644 index 9cc10f3663..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/clauses/aggregates/avg.js +++ /dev/null @@ -1,5 +0,0 @@ -const aggregate = require('../abstracts/aggregate') - -module.exports = function (column, alias) { - return [aggregate('AVG', column, alias)] -} diff --git a/packages/core-database-sequelize/lib/query-builder/clauses/aggregates/count-distinct.js b/packages/core-database-sequelize/lib/query-builder/clauses/aggregates/count-distinct.js deleted file mode 100644 index efa55d2ec3..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/clauses/aggregates/count-distinct.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = function (column, alias) { - return alias - ? [`COUNT (DISTINCT "${column}") AS "${alias}"`] - : [`COUNT (DISTINCT "${column}") AS "${column}"`] -} diff --git a/packages/core-database-sequelize/lib/query-builder/clauses/aggregates/count.js b/packages/core-database-sequelize/lib/query-builder/clauses/aggregates/count.js deleted file mode 100644 index 91fc2ad4fb..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/clauses/aggregates/count.js +++ /dev/null @@ -1,5 +0,0 @@ -const aggregate = require('../abstracts/aggregate') - -module.exports = function (column, alias) { - return [aggregate('COUNT', column, alias)] -} diff --git a/packages/core-database-sequelize/lib/query-builder/clauses/aggregates/max.js b/packages/core-database-sequelize/lib/query-builder/clauses/aggregates/max.js deleted file mode 100644 index 71ee8d9381..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/clauses/aggregates/max.js +++ /dev/null @@ -1,5 +0,0 @@ -const aggregate = require('../abstracts/aggregate') - -module.exports = function (column, alias) { - return [aggregate('MAX', column, alias)] -} diff --git a/packages/core-database-sequelize/lib/query-builder/clauses/aggregates/min.js b/packages/core-database-sequelize/lib/query-builder/clauses/aggregates/min.js deleted file mode 100644 index bc43bd9a47..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/clauses/aggregates/min.js +++ /dev/null @@ -1,5 +0,0 @@ -const aggregate = require('../abstracts/aggregate') - -module.exports = function (column, alias) { - return [aggregate('MIN', column, alias)] -} diff --git a/packages/core-database-sequelize/lib/query-builder/clauses/aggregates/sum.js b/packages/core-database-sequelize/lib/query-builder/clauses/aggregates/sum.js deleted file mode 100644 index a330072534..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/clauses/aggregates/sum.js +++ /dev/null @@ -1,5 +0,0 @@ -const aggregate = require('../abstracts/aggregate') - -module.exports = function (column, alias) { - return [aggregate('SUM', column, alias)] -} diff --git a/packages/core-database-sequelize/lib/query-builder/clauses/from.js b/packages/core-database-sequelize/lib/query-builder/clauses/from.js deleted file mode 100644 index a5ba31c76b..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/clauses/from.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = function (table) { - return table -} diff --git a/packages/core-database-sequelize/lib/query-builder/clauses/group-by.js b/packages/core-database-sequelize/lib/query-builder/clauses/group-by.js deleted file mode 100644 index c45c7ebe0d..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/clauses/group-by.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = function (column) { - return column -} diff --git a/packages/core-database-sequelize/lib/query-builder/clauses/index.js b/packages/core-database-sequelize/lib/query-builder/clauses/index.js deleted file mode 100644 index d11a6097d7..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/clauses/index.js +++ /dev/null @@ -1,23 +0,0 @@ -module.exports = { - avg: require('./aggregates/avg'), - count: require('./aggregates/count'), - countDistinct: require('./aggregates/count-distinct'), - from: require('./from'), - groupBy: require('./group-by'), - limit: require('./limit'), - max: require('./aggregates/max'), - min: require('./aggregates/min'), - offset: require('./offset'), - orderBy: require('./order-by'), - select: require('./select'), - sum: require('./aggregates/sum'), - where: require('./where'), - whereBetween: require('./where/between'), - whereIn: require('./where/in'), - whereLike: require('./where/like'), - whereNotBetween: require('./where/not-between'), - whereNotIn: require('./where/not-in'), - whereNotLike: require('./where/not-like'), - whereNotNull: require('./where/not-null'), - whereNull: require('./where/null') -} diff --git a/packages/core-database-sequelize/lib/query-builder/clauses/limit.js b/packages/core-database-sequelize/lib/query-builder/clauses/limit.js deleted file mode 100644 index b76f1fa2b7..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/clauses/limit.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = function (limit) { - return limit -} diff --git a/packages/core-database-sequelize/lib/query-builder/clauses/offset.js b/packages/core-database-sequelize/lib/query-builder/clauses/offset.js deleted file mode 100644 index 7883fc5df5..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/clauses/offset.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = function (value) { - return value -} diff --git a/packages/core-database-sequelize/lib/query-builder/clauses/order-by.js b/packages/core-database-sequelize/lib/query-builder/clauses/order-by.js deleted file mode 100644 index 1030c0e4d5..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/clauses/order-by.js +++ /dev/null @@ -1,18 +0,0 @@ -const isString = require('../utils/is-string') - -module.exports = function () { - const transform = condition => ({ - column: condition[0], - direction: condition[1] - }) - - const args = arguments[0] - - if (isString(args[0])) { - return [transform(args)] - } - - return Object - .entries(args[0]) - .map(argument => transform(argument)) -} diff --git a/packages/core-database-sequelize/lib/query-builder/clauses/select.js b/packages/core-database-sequelize/lib/query-builder/clauses/select.js deleted file mode 100644 index b6497f0c91..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/clauses/select.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = function () { - return Object.values(arguments[0]) -} diff --git a/packages/core-database-sequelize/lib/query-builder/clauses/where/between.js b/packages/core-database-sequelize/lib/query-builder/clauses/where/between.js deleted file mode 100644 index f3e6842027..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/clauses/where/between.js +++ /dev/null @@ -1,20 +0,0 @@ -const isString = require('../../utils/is-string') - -module.exports = function () { - const transform = condition => ({ - column: condition[0], - operator: 'BETWEEN', - from: condition[1], - to: condition[2] - }) - - const args = arguments[0] - - if (isString(args[0])) { - return [transform(args)] - } - - return Object - .values(args) - .map(argument => transform(argument)) -} diff --git a/packages/core-database-sequelize/lib/query-builder/clauses/where/in.js b/packages/core-database-sequelize/lib/query-builder/clauses/where/in.js deleted file mode 100644 index 3018c3d2fe..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/clauses/where/in.js +++ /dev/null @@ -1,16 +0,0 @@ -const isString = require('../../utils/is-string') -const map = require('./utils/map') - -module.exports = function () { - const transform = condition => map(condition[0], 'IN', condition[1]) - - const args = arguments[0] - - if (isString(args[0])) { - return [transform(args)] - } - - return Object - .entries(args[0]) - .map(argument => transform(argument)) -} diff --git a/packages/core-database-sequelize/lib/query-builder/clauses/where/index.js b/packages/core-database-sequelize/lib/query-builder/clauses/where/index.js deleted file mode 100644 index 3a28b3b654..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/clauses/where/index.js +++ /dev/null @@ -1,23 +0,0 @@ -const isString = require('../../utils/is-string') -const map = require('./utils/map') - -module.exports = function () { - const transform = condition => { - if (condition.length === 2) { - condition[2] = condition[1] - condition[1] = '=' - } - - return map(condition[0], condition[1], condition[2]) - } - - const args = arguments[0] - - if (isString(args[0])) { - return [transform(args)] - } - - return Object - .entries(args[0]) - .map(argument => transform(argument)) -} diff --git a/packages/core-database-sequelize/lib/query-builder/clauses/where/like.js b/packages/core-database-sequelize/lib/query-builder/clauses/where/like.js deleted file mode 100644 index 7c9c1862b3..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/clauses/where/like.js +++ /dev/null @@ -1,16 +0,0 @@ -const isString = require('../../utils/is-string') -const map = require('./utils/map') - -module.exports = function () { - const transform = condition => map(condition[0], 'LIKE', `%${condition[1]}%`) - - const args = arguments[0] - - if (isString(args[0])) { - return [transform(args)] - } - - return Object - .entries(args[0]) - .map(argument => transform(argument)) -} diff --git a/packages/core-database-sequelize/lib/query-builder/clauses/where/not-between.js b/packages/core-database-sequelize/lib/query-builder/clauses/where/not-between.js deleted file mode 100644 index 685002b328..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/clauses/where/not-between.js +++ /dev/null @@ -1,20 +0,0 @@ -const isString = require('../../utils/is-string') - -module.exports = function () { - const transform = condition => ({ - column: condition[0], - operator: 'NOT BETWEEN', - from: condition[1], - to: condition[2] - }) - - const args = arguments[0] - - if (isString(args[0])) { - return [transform(args)] - } - - return Object - .values(args) - .map(argument => transform(argument)) -} diff --git a/packages/core-database-sequelize/lib/query-builder/clauses/where/not-in.js b/packages/core-database-sequelize/lib/query-builder/clauses/where/not-in.js deleted file mode 100644 index 4301ca1e59..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/clauses/where/not-in.js +++ /dev/null @@ -1,16 +0,0 @@ -const isString = require('../../utils/is-string') -const map = require('./utils/map') - -module.exports = function () { - const transform = condition => map(condition[0], 'NOT IN', condition[1]) - - const args = arguments[0] - - if (isString(args[0])) { - return [transform(args)] - } - - return Object - .entries(args[0]) - .map(argument => transform(argument)) -} diff --git a/packages/core-database-sequelize/lib/query-builder/clauses/where/not-like.js b/packages/core-database-sequelize/lib/query-builder/clauses/where/not-like.js deleted file mode 100644 index 457df0eca5..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/clauses/where/not-like.js +++ /dev/null @@ -1,16 +0,0 @@ -const isString = require('../../utils/is-string') -const map = require('./utils/map') - -module.exports = function () { - const transform = condition => map(condition[0], 'NOT LIKE', `%${condition[1]}%`) - - const args = arguments[0] - - if (isString(args[0])) { - return [transform(args)] - } - - return Object - .entries(args[0]) - .map(argument => transform(argument)) -} diff --git a/packages/core-database-sequelize/lib/query-builder/clauses/where/not-null.js b/packages/core-database-sequelize/lib/query-builder/clauses/where/not-null.js deleted file mode 100644 index 302f466d2e..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/clauses/where/not-null.js +++ /dev/null @@ -1,16 +0,0 @@ -const isString = require('../../utils/is-string') - -module.exports = function () { - const transform = condition => ({ - column: condition, - operator: 'IS NOT NULL' - }) - - const args = arguments[0] - - if (isString(args[0])) { - return [transform(args[0])] - } - - return args[0].map(argument => transform(argument)) -} diff --git a/packages/core-database-sequelize/lib/query-builder/clauses/where/null.js b/packages/core-database-sequelize/lib/query-builder/clauses/where/null.js deleted file mode 100644 index 0d2aeee2a7..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/clauses/where/null.js +++ /dev/null @@ -1,16 +0,0 @@ -const isString = require('../../utils/is-string') - -module.exports = function () { - const transform = condition => ({ - column: condition, - operator: 'IS NULL' - }) - - const args = arguments[0] - - if (isString(args[0])) { - return [transform(args[0])] - } - - return args[0].map(argument => transform(argument)) -} diff --git a/packages/core-database-sequelize/lib/query-builder/clauses/where/utils/map.js b/packages/core-database-sequelize/lib/query-builder/clauses/where/utils/map.js deleted file mode 100644 index 7b57733642..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/clauses/where/utils/map.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = (column, operator, value) => ({ column, operator, value }) diff --git a/packages/core-database-sequelize/lib/query-builder/index.js b/packages/core-database-sequelize/lib/query-builder/index.js deleted file mode 100644 index 2033661187..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/index.js +++ /dev/null @@ -1,330 +0,0 @@ -const { QueryTypes } = require('sequelize') -const clauses = require('./clauses') -const SqlBuilder = require('./sql-builder') -const { get, set } = require('lodash') - -module.exports = class QueryBuiler { - /** - * [constructor description] - * @param {[type]} connection - * @return {QueryBuilder} - */ - constructor (connection, models) { - this.connection = connection - this.models = models ? Object.keys(models).map(k => models[k]) : [] - } - - /** - * [select description] - * @return {QueryBuilder} - */ - select () { - this.__reset() - - this.clauses.select.columns = clauses.select(arguments) - - return this - } - - /** - * [from description] - * @param {String} table - * @return {QueryBuilder} - */ - from (table) { - this.clauses.from = clauses.from(table) - - return this - } - - /** - * [where description] - * @return {QueryBuilder} - */ - where () { - this.__pushClause('clauses.where.and', clauses.where(arguments)) - - return this - } - - /** - * [whereIn description] - * @return {QueryBuilder} - */ - whereIn () { - this.__pushClause('clauses.where.and', clauses.whereIn(arguments)) - - return this - } - - /** - * [whereNotIn description] - * @return {QueryBuilder} - */ - whereNotIn () { - this.__pushClause('clauses.where.and', clauses.whereNotIn(arguments)) - - return this - } - - /** - * [whereNull description] - * @return {QueryBuilder} - */ - whereNull () { - this.__pushClause('clauses.where.and', clauses.whereNull(arguments)) - - return this - } - - /** - * [whereNotNull description] - * @return {QueryBuilder} - */ - whereNotNull () { - this.__pushClause('clauses.where.and', clauses.whereNotNull(arguments)) - - return this - } - - /** - * [whereBetween description] - * @return {QueryBuilder} - */ - whereBetween () { - this.__pushClause('clauses.where.and', clauses.whereBetween(arguments)) - - return this - } - - /** - * [whereNotBetween description] - * @return {QueryBuilder} - */ - whereNotBetween () { - this.__pushClause('clauses.where.and', clauses.whereNotBetween(arguments)) - - return this - } - - /** - * [orWhere description] - * @return {QueryBuilder} - */ - orWhere () { - this.__pushClause('clauses.where.or', clauses.where(arguments)) - - return this - } - - /** - * [orWhereIn description] - * @return {QueryBuilder} - */ - orWhereIn () { - this.__pushClause('clauses.where.or', clauses.whereIn(arguments)) - - return this - } - - /** - * [orWhereNotIn description] - * @return {QueryBuilder} - */ - orWhereNotIn () { - this.__pushClause('clauses.where.or', clauses.whereNotIn(arguments)) - - return this - } - - /** - * [orWhereNull description] - * @return {QueryBuilder} - */ - orWhereNull () { - this.__pushClause('clauses.where.or', clauses.whereNull(arguments)) - - return this - } - - /** - * [orWhereNotNull description] - * @return {QueryBuilder} - */ - orWhereNotNull () { - this.__pushClause('clauses.where.or', clauses.whereNotNull(arguments)) - - return this - } - - /** - * [orWhereBetween description] - * @return {QueryBuilder} - */ - orWhereBetween () { - this.__pushClause('clauses.where.or', clauses.whereBetween(arguments)) - - return this - } - - /** - * [orWhereNotBetween description] - * @return {QueryBuilder} - */ - orWhereNotBetween () { - this.__pushClause('clauses.where.or', clauses.whereNotBetween(arguments)) - - return this - } - - /** - * [groupBy description] - * @param {String} column - * @return {QueryBuilder} - */ - groupBy (column) { - this.clauses.groupBy = clauses.groupBy(column) - - return this - } - - /** - * [orderBy description] - * @return {QueryBuilder} - */ - orderBy () { - this.clauses.orderBy = clauses.orderBy(arguments) - - return this - } - - /** - * [limit description] - * @param {Number} value - * @return {QueryBuilder} - */ - limit (value) { - this.clauses.limit = clauses.limit(value) - - return this - } - - /** - * [offset description] - * @param {Number} value - * @return {QueryBuilder} - */ - offset (value) { - this.clauses.offset = clauses.offset(value) - - return this - } - - /** - * [count description] - * @return {QueryBuilder} - */ - count (column, alias) { - this.__pushClause('clauses.select.aggregates', clauses.count(column, alias)) - - return this - } - - /** - * [countDistinct description] - * @return {QueryBuilder} - */ - countDistinct (column, alias) { - this.__pushClause('clauses.select.aggregates', clauses.countDistinct(column, alias)) - - return this - } - - /** - * [min description] - * @return {QueryBuilder} - */ - min (column, alias) { - this.__pushClause('clauses.select.aggregates', clauses.min(column, alias)) - - return this - } - - /** - * [max description] - * @return {QueryBuilder} - */ - max (column, alias) { - this.__pushClause('clauses.select.aggregates', clauses.max(column, alias)) - - return this - } - - /** - * [sum description] - * @return {QueryBuilder} - */ - sum (column, alias) { - this.__pushClause('clauses.select.aggregates', clauses.sum(column, alias)) - - return this - } - - /** - * [avg description] - * @return {QueryBuilder} - */ - avg (column, alias) { - this.__pushClause('clauses.select.aggregates', clauses.avg(column, alias)) - - return this - } - - /** - * [all description] - * @return {QueryBuilder} - */ - async all () { - const { sql, replacements } = SqlBuilder.build(this.clauses) - const { fieldAttributeMap } = this.models.find(m => m.tableName === this.clauses.from) || {} - - // logger.verbose(`SQL: ${sql}`) - - return this.connection.query(sql, { - type: QueryTypes.SELECT, - fieldMap: fieldAttributeMap, - replacements - }) - } - - /** - * [first description] - * @return {QueryBuilder} - */ - async first () { - const data = await this.all() - - return data[0] - } - - /** - * [__reset description] - * @return {void} - */ - __reset () { - this.clauses = { - select: { - columns: [], - aggregates: [] - }, - where: { - and: [], - or: [] - } - } - } - - __pushClause (collection, clause) { - set(this, collection, get(this, collection).concat(clause)) - } -} diff --git a/packages/core-database-sequelize/lib/query-builder/sql-builder.js b/packages/core-database-sequelize/lib/query-builder/sql-builder.js deleted file mode 100644 index 71653c62b2..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/sql-builder.js +++ /dev/null @@ -1,144 +0,0 @@ -const { camelCase, upperFirst } = require('lodash') - -class SqlBuilder { - /** - * Build the clauses. - * @param {Object} clauses - * @return {String} - */ - build (clauses) { - const clauseOrder = [ - 'select', 'from', 'where', - 'groupBy', 'orderBy', 'limit', 'offset' - ] - - this.__replacements = [] - - const sql = clauseOrder - .map(clause => { - if (!clauses[clause]) { - return false - } - - return this[`__build${upperFirst(camelCase(clause))}`](clauses) - }) - .filter(item => !!item) - .join('') - .trim() - - return { sql, replacements: this.__replacements.length > 0 ? this.__replacements : undefined } - } - - /** - * Build the "SELECT" clause. - * @param {Object} clauses - * @return {String} - */ - __buildSelect (clauses) { - const { columns, aggregates } = clauses.select - return `SELECT ${columns.concat(aggregates).join(',')} ` - } - - /** - * Build the "FROM" clause. - * @param {Object} clauses - * @return {String} - */ - __buildFrom (clauses) { - return `FROM ${clauses.from} ` - } - - /** - * Build the "WHERE" clause. - * @param {Object} clauses - * @return {String} - */ - __buildWhere (clauses) { - const map = (item) => { - if (item.hasOwnProperty('from') && item.hasOwnProperty('to')) { - this.__replacements.push(item.from) - this.__replacements.push(item.to) - return `${item.column} ${item.operator} ? AND ?` - } - - if (['IN', 'NOT IN'].includes(item.operator)) { - this.__replacements.push(item.value) - return `${item.column} ${item.operator} (?)` - } - - if (['IS NULL', 'IS NOT NULL'].includes(item.operator)) { - return `${item.column} ${item.operator}` - } - - this.__replacements.push(item.value) - return `${item.column} ${item.operator} ?` - } - - const andQuery = Object - .values(clauses.where.and) - .map(item => map(item)) - .join(' AND ') - - const orQuery = Object - .values(clauses.where.or) - .map(item => map(item)) - .join(' OR ') - - if (!andQuery && !orQuery) { - return '' - } - - let query = 'WHERE ' - - if (andQuery) { - query += andQuery - } - - if (orQuery) { - query += ` OR ${orQuery}` - } - - return `${query} ` - } - - /** - * Build the "GROUP BY" clause. - * @param {Object} clauses - * @return {String} - */ - __buildGroupBy (clauses) { - return `GROUP BY "${clauses.groupBy}" ` - } - - /** - * Build the "ORDER BY" clause. - * @param {Object} clauses - * @return {String} - */ - __buildOrderBy (clauses) { - const values = Object - .values(clauses.orderBy) - .map(item => `${item.column} ${item.direction.toUpperCase()}`) - return `ORDER BY ${values.join(',')} ` - } - - /** - * Build the "LIMIT" clause. - * @param {Object} clauses - * @return {String} - */ - __buildLimit (clauses) { - return `LIMIT ${clauses.limit} ` - } - - /** - * Build the "OFFSET" clause. - * @param {Object} clauses - * @return {String} - */ - __buildOffset (clauses) { - return `OFFSET ${clauses.offset} ` - } -} - -module.exports = new SqlBuilder() diff --git a/packages/core-database-sequelize/lib/query-builder/utils/cast-to-array.js b/packages/core-database-sequelize/lib/query-builder/utils/cast-to-array.js deleted file mode 100644 index fa3192b726..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/utils/cast-to-array.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = value => Array.isArray(value) ? value : [value] diff --git a/packages/core-database-sequelize/lib/query-builder/utils/escape.js b/packages/core-database-sequelize/lib/query-builder/utils/escape.js deleted file mode 100644 index 4c30cd7e6b..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/utils/escape.js +++ /dev/null @@ -1,18 +0,0 @@ -const isNumber = require('./is-number') -const isString = require('./is-string') - -module.exports = (value, singleQuotes = false) => { - if (value === '*') { - return value - } - - if (isNumber(value) || singleQuotes) { - return `'${value}'` - } - - if (isString(value) && value.startsWith('"') && value.endsWith('"')) { - return value - } - - return `"${value}"` -} diff --git a/packages/core-database-sequelize/lib/query-builder/utils/is-array.js b/packages/core-database-sequelize/lib/query-builder/utils/is-array.js deleted file mode 100644 index e205867612..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/utils/is-array.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = value => Array.isArray(value) diff --git a/packages/core-database-sequelize/lib/query-builder/utils/is-number.js b/packages/core-database-sequelize/lib/query-builder/utils/is-number.js deleted file mode 100644 index 5505946632..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/utils/is-number.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = value => (typeof value === 'number') diff --git a/packages/core-database-sequelize/lib/query-builder/utils/is-object.js b/packages/core-database-sequelize/lib/query-builder/utils/is-object.js deleted file mode 100644 index 79faffec25..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/utils/is-object.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = value => (value === Object(value)) diff --git a/packages/core-database-sequelize/lib/query-builder/utils/is-string.js b/packages/core-database-sequelize/lib/query-builder/utils/is-string.js deleted file mode 100644 index fdb8ebbf42..0000000000 --- a/packages/core-database-sequelize/lib/query-builder/utils/is-string.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = value => (typeof value === 'string') diff --git a/packages/core-database-sequelize/lib/repositories/blocks.js b/packages/core-database-sequelize/lib/repositories/blocks.js deleted file mode 100644 index 9f40b5b48a..0000000000 --- a/packages/core-database-sequelize/lib/repositories/blocks.js +++ /dev/null @@ -1,144 +0,0 @@ -'use strict' - -const buildFilterQuery = require('./utils/filter-query') -const Repository = require('./repository') - -const blocksTableColumns = ['id', 'version', 'timestamp', 'previous_block', 'height', 'number_of_transactions', 'total_amount', 'total_fee', 'reward', 'payload_length', 'payload_hash', 'generator_public_key', 'block_signature'] - -module.exports = class BlocksRepository extends Repository { - /** - * Create a new block repository instance. - * @param {ConnectionInterface} connection - */ - constructor (connection) { - super(connection, 'block') - } - - /** - * Get all blocks for the given parameters. - * TODO throw an Error if the params aren't the available filters - * @param {Object} params - * @return {Object} - */ - async findAll (params = {}) { - const { conditions } = this.__formatConditions(params) - - const orderBy = params.orderBy - ? params.orderBy.split(':') - : ['height', 'DESC'] - - const buildQuery = query => { - query = query.from('blocks') - - for (let [key, value] of Object.entries(conditions)) { - query = query.where(key, value) - } - - return query - } - - let rows = [] - - // NOTE: The real count is avoided because it degrades the performance of the node - // const { count } = await buildQuery(this.query.select().countDistinct('id', 'count')).first() - - // if (count) { - const selectQuery = buildQuery(this.query.select(...blocksTableColumns)) - rows = await this.__runQuery(selectQuery, { - limit: params.limit, - offset: params.offset, - orderBy - }) - // } - - return { rows, count: rows.length } - } - - /** - * Get all blocks for the given generator. - * @param {String} generatorPublicKey - * @param {Object} paginator - * @return {Object} - */ - async findAllByGenerator (generatorPublicKey, paginator) { - return this.findAll({...{generatorPublicKey}, ...paginator}) - } - - /** - * Get a block. - * @param {Number} id - * @return {Object} - */ - async findById (id) { - return this.query - .select(...blocksTableColumns) - .from('blocks') - .where('id', id) - .first() - } - - /** - * Get the last block for the given generator. - * TODO is this right? - * @param {String} generatorPublicKey - * @return {Object} - */ - async findLastByPublicKey (generatorPublicKey) { - return this.query - .select('id', 'timestamp') - .from('blocks') - .where('generator_public_key', generatorPublicKey) - .orderBy('created_at', 'DESC') - .limit(1) - .first() - } - - /** - * Search all blocks. - * @param {Object} params - * @return {Object} - */ - async search (params) { - let { conditions } = this.__formatConditions(params) - conditions = buildFilterQuery(conditions, { - exact: ['id', 'version', 'previous_block', 'payload_hash', 'generator_public_key', 'block_signature'], - between: ['timestamp', 'height', 'number_of_transactions', 'total_amount', 'total_fee', 'reward', 'payload_length'] - }) - - const orderBy = params.orderBy - ? params.orderBy.split(':') - : ['height', 'DESC'] - - const buildQuery = query => { - query = query.from('blocks') - - conditions.forEach(condition => { - query = query.where(condition.column, condition.operator, condition.value) - }) - - return query - } - - let rows = [] - const { count } = await buildQuery(this.query.select().countDistinct('id', 'count')).first() - - if (count) { - const selectQuery = buildQuery(this.query.select(...blocksTableColumns)) - rows = await this.__runQuery(selectQuery, { - limit: params.limit, - offset: params.offset, - orderBy - }) - } - - return { rows, count } - } - - /** - * Count all blocks. - * @return {Number} - */ - async count () { - return super.__count('blocks') - } -} diff --git a/packages/core-database-sequelize/lib/repositories/repository.js b/packages/core-database-sequelize/lib/repositories/repository.js deleted file mode 100644 index 83406e6e90..0000000000 --- a/packages/core-database-sequelize/lib/repositories/repository.js +++ /dev/null @@ -1,77 +0,0 @@ -'use strict' - -const invertBy = require('lodash/invertBy') - -const defaults = { - limit: 100, - offset: 0 -} - -module.exports = class Repository { - /** - * Create a new repository instance. - * @param {ConnectionInterface} connection - */ - constructor (connection, model) { - this.connection = connection - this.query = connection.query - - this.model = connection.models[model] - if (!this.model) { - throw new Error(`${model} model not found.`) - } -} - - /** - * Executes the query. It admits some parameters to sort the results and to - * reduce their number. - * - * @param {QueryBuilder} query - The query to execute - * @param {Object} params - * @param {Number} [params.limit] - Limit the results to this number of rows - * @param {Number} [params.offset] - Use this number as the offset - * @param {Array} params.orderBy - Sort the results by this field, ASC or DESC - */ - async __runQuery (query, { limit, offset, orderBy }) { - return query - .limit(limit || defaults.limit) - .offset(offset || defaults.offset) - .orderBy(orderBy[0], orderBy[1]) - .all() - } - - /** - * Count all the records of a table. - * @return {Number} - */ - async __count (table) { - return this - .query - .select() - .countDistinct('id', 'count') - .from(table) - .first() - } - - __formatConditions (params) { - const { fieldAttributeMap, tableAttributes } = this.model - - const validParams = Object.keys(tableAttributes) - const filter = args => { - return args.filter(elem => validParams.includes(elem)) - } - - // invert direction of mapping, camelCase => snake_case - // the mapping is necessary if a param is camelCase otherwise - // the param can be directly used. - // e.g. recipientId => recipient_id, but type => type - const fieldMappings = invertBy(fieldAttributeMap) - const conditions = filter(Object.keys(params)).reduce((all, column) => { - const columnName = fieldMappings[column] || column - all[columnName] = params[column] - return all - }, {}) - - return { conditions, filter } - } -} diff --git a/packages/core-database-sequelize/lib/repositories/transactions.js b/packages/core-database-sequelize/lib/repositories/transactions.js deleted file mode 100644 index 4da841dd22..0000000000 --- a/packages/core-database-sequelize/lib/repositories/transactions.js +++ /dev/null @@ -1,480 +0,0 @@ -'use strict' - -const { Op } = require('sequelize') -const moment = require('moment') -const { slots } = require('@arkecosystem/crypto') -const { TRANSACTION_TYPES } = require('@arkecosystem/crypto').constants -const buildFilterQuery = require('./utils/filter-query') -const Repository = require('./repository') - -module.exports = class TransactionsRepository extends Repository { - /** - * Create a new transaction repository instance. - * @param {ConnectionInterface} connection - */ - constructor (connection) { - super(connection, 'transaction') - - // Used to store the height of the block - this.cache = connection.cache - } - - /** - * Get all transactions. - * @param {Object} params - * @return {Object} - */ - async findAll (params = {}) { - if (params.senderId) { - const senderPublicKey = this.__publicKeyfromSenderId(params.senderId) - - if (!senderPublicKey) { - return { rows: [], count: 0 } - } - params.senderPublicKey = senderPublicKey - } - - const { conditions } = this.__formatConditions(params) - - const orderBy = this.__orderBy(params) - - const buildQuery = query => { - query = query.from('transactions') - - for (let [key, value] of Object.entries(conditions)) { - query = query.where(key, value) - } - - return query - } - - let rows = [] - - // NOTE: The real count is avoided because it degrades the performance of the node - // const { count } = await buildQuery(this.query.select().countDistinct('id', 'count')).first() - - // if (count) { - const selectQuery = buildQuery(this.query.select('block_id', 'serialized')) - const transactions = await this.__runQuery(selectQuery, { - limit: params.limit, - offset: params.offset, - orderBy - }) - - rows = await this.__mapBlocksToTransactions(transactions) - // } - - return { rows, count: rows.length } - } - - /** - * Get all transactions (LEGACY, for V1 only). - * @param {Object} params - * @return {Object} - */ - async findAllLegacy (params = {}) { - if (params.senderId) { - params.senderPublicKey = this.__publicKeyfromSenderId(params.senderId) - } - - const conditions = this.__formatConditionsV1(params) - - const orderBy = this.__orderBy(params) - - const buildQuery = query => { - query = query.from('transactions') - - const parts = Object.entries(conditions) - if (parts.length) { - const first = parts.shift() - query = query.where(first[0], first[1]) - - for (let [key, value] of parts) { - query = query.orWhere(key, value) - } - } - - return query - } - - let rows = [] - // NOTE: The real count is avoided because it degrades the performance of the node - // const { count } = await buildQuery(this.query.select().countDistinct('id', 'count')).first() - - // if (count) { - const selectQuery = buildQuery(this.query.select('block_id', 'serialized')) - const transactions = await this.__runQuery(selectQuery, { - limit: params.limit, - offset: params.offset, - orderBy - }) - - rows = await this.__mapBlocksToTransactions(transactions) - // } - - return { rows, count: rows.length } - } - - /** - * Get all transactions for the given Wallet object. - * @param {Wallet} wallet - * @param {Object} params - * @return {Object} - */ - async findAllByWallet (wallet, params = {}) { - const orderBy = this.__orderBy(params) - - const buildQuery = query => { - return query - .from('transactions') - .where('sender_public_key', wallet.publicKey) - .orWhere('recipient_id', wallet.address) - } - - let rows = [] - const { count } = await buildQuery(this.query.select().countDistinct('id', 'count')).first() - - if (count) { - const query = buildQuery(this.query.select('block_id', 'serialized')) - const transactions = await this.__runQuery(query, { - limit: params.limit, - offset: params.offset, - orderBy - }) - - rows = await this.__mapBlocksToTransactions(transactions) - } - - return { rows, count } - } - - /** - * Get all transactions for the given sender public key. - * @param {String} senderPublicKey - * @param {Object} params - * @return {Object} - */ - async findAllBySender (senderPublicKey, params = {}) { - return this.findAll({...{senderPublicKey}, ...params}) - } - - /** - * Get all transactions for the given recipient address. - * @param {String} recipientId - * @param {Object} params - * @return {Object} - */ - async findAllByRecipient (recipientId, params = {}) { - return this.findAll({...{recipientId}, ...params}) - } - - /** - * Get all vote transactions for the given sender public key. - * TODO rename to findAllVotesBySender or not? - * @param {String} senderPublicKey - * @param {Object} params - * @return {Object} - */ - async allVotesBySender (senderPublicKey, params = {}) { - return this.findAll({...{senderPublicKey, type: TRANSACTION_TYPES.VOTE}, ...params}) - } - - /** - * Get all transactions for the given block. - * @param {Number} blockId - * @param {Object} params - * @return {Object} - */ - async findAllByBlock (blockId, params = {}) { - return this.findAll({...{blockId}, ...params}) - } - - /** - * Get all transactions for the given type. - * @param {Number} type - * @param {Object} params - * @return {Object} - */ - async findAllByType (type, params = {}) { - return this.findAll({...{type}, ...params}) - } - - /** - * Get a transaction. - * @param {Object} conditions - * @return {Object} - */ - async findOne (conditions) { - conditions = this.__formatConditions(conditions).conditions - const transaction = await this.query - .select('block_id', 'serialized') - .from('transactions') - .where(conditions) - .first() - - return this.__mapBlocksToTransactions(transaction) - } - - /** - * Get a transaction. - * @param {Number} id - * @return {Object} - */ - async findById (id) { - return this.findOne({ id }) - } - - /** - * Get a transactions for the given type and id. - * @param {Number} type - * @param {Number} id - * @return {Object} - */ - async findByTypeAndId (type, id) { - return this.findOne({ id, type }) - } - - /** - * Get transactions for the given ids. - * @param {Array} ids - * @return {Object} - */ - async findByIds (ids) { - return this - .connection - .query - .select('block_id', 'serialized') - .from('transactions') - .whereIn('id', ids) - .all() - } - - /** - * Search all transactions. - * - * @param {Object} params - * @return {Object} - */ - async search (params) { - const orderBy = this.__orderBy(params) - - if (params.senderId) { - const senderPublicKey = this.__publicKeyfromSenderId(params.senderId) - - if (senderPublicKey) { - params.senderPublicKey = senderPublicKey - } - } - - let { conditions } = this.__formatConditions(params) - conditions = buildFilterQuery(conditions, { - exact: ['id', 'block_id', 'type', 'version', 'sender_public_key', 'recipient_id'], - between: ['timestamp', 'amount', 'fee'], - wildcard: ['vendor_field_hex'] - }) - - const buildQuery = query => { - query = query.from('transactions') - - conditions.forEach(condition => { - query = query.where(condition.column, condition.operator, condition.value) - }) - - return query - } - - let rows = [] - const { count } = await buildQuery(this.query.select().countDistinct('id', 'count')).first() - - if (count) { - const query = await buildQuery(this.query.select('block_id', 'serialized')) - const transactions = await this.__runQuery(query, { - limit: params.limit, - offset: params.offset, - orderBy - }) - - rows = await this.__mapBlocksToTransactions(transactions) - } - - return { rows, count } - } - - /** - * Get all transactions that have a vendor field. - * @return {Object} - */ - async findWithVendorField () { - const transactions = await this.query - .select('block_id', 'serialized') - .from('transactions') - .whereNotNull('vendor_field_hex') - .all() - - return this.__mapBlocksToTransactions(transactions) - } - - /** - * Count all transactions. - * @return {Number} - */ - async count () { - return super.__count('transactions') - } - - /** - * Calculates min, max and average fee statistics based on transactions table - * @return {Object} - */ - async getFeeStatistics () { - return this - .connection - .query - .select('type') - .min('fee', 'minFee') - .max('fee', 'maxFee') - .avg('fee', 'avgFee') - .max('timestamp', 'timestamp') - .from('transactions') - .where('timestamp', '>=', slots.getTime(moment().subtract(30, 'days'))) - .groupBy('type') - .orderBy('timestamp', 'DESC') - .all() - } - - /** - * Format any raw conditions. - * TODO if condition is invalid, raise an Error - * @param {Object} params - * @return {Object} - */ - __formatConditions (params) { - const { conditions, filter } = super.__formatConditions(params) - - // NOTE: This could be used to produce complex queries, but currently isn't used - ;[Op.or, Op.and].map(elem => { - if (!params[elem]) { - return - } - - const fields = Object.assign({}, ...params[elem]) - - conditions[elem] = filter(Object.keys(fields)).reduce((all, value) => { - return all.concat({ [value]: fields[value] }) - }, []) - }) - - return { conditions, filter } - } - - /** - * Format any raw conditions. - * TODO if condition is invalid, raise an Error - * @param {Object} params - * @return {Object} - */ - __formatConditionsV1 (params) { - return super.__formatConditions(params).conditions - } - - /** - * [__mapBlocksToTransactions description] - * @param {Array|Object} data - * @return {Object} - */ - async __mapBlocksToTransactions (data) { - // Array... - if (Array.isArray(data)) { - // 1. get heights from cache - const missingFromCache = [] - - for (let i = 0; i < data.length; i++) { - const cachedBlock = await this.__getBlockCache(data[i].blockId) - - if (cachedBlock) { - data[i].block = cachedBlock - } else { - missingFromCache.push({ - index: i, - blockId: data[i].blockId - }) - } - } - - // 2. get missing heights from database - if (missingFromCache.length) { - const blocks = await this.query - .select('id', 'height') - .from('blocks') - .whereIn('id', missingFromCache.map(d => d.blockId)) - .groupBy('id') - .all() - - for (let i = 0; i < missingFromCache.length; i++) { - const missing = missingFromCache[i] - const block = blocks.find(block => (block.id === missing.blockId)) - if (block) { - data[missing.index].block = block - this.__setBlockCache(block) - } - } - } - - return data - } - - // Object... - if (data) { - const cachedBlock = await this.__getBlockCache(data.blockId) - - if (cachedBlock) { - data.block = cachedBlock - } else { - data.block = await this.query - .select('id', 'height') - .from('blocks') - .where('id', data.blockId) - .first() - - this.__setBlockCache(data.block) - } - } - - return data - } - - /** - * Tries to retrieve the height of the block from the cache - * @param {String} blockId - * @return {Object|null} - */ - async __getBlockCache (blockId) { - const height = await this.cache.get(`heights:${blockId}`) - return height ? ({ height, id: blockId }) : null - } - - /** - * Stores the height of the block on the cache - * @param {Object} block - * @param {String} block.id - * @param {Number} block.height - */ - __setBlockCache ({ id, height }) { - this.cache.set(`heights:${id}`, height) - } - - /** - * Retrieves the publicKey of the address from the WalletManager in-memory data - * @param {String} senderId - * @return {String} - */ - __publicKeyfromSenderId (senderId) { - return this.connection.walletManager.getWalletByAddress(senderId).publicKey - } - - __orderBy (params) { - return params.orderBy - ? params.orderBy.split(':') - : ['timestamp', 'DESC'] - } -} diff --git a/packages/core-database-sequelize/lib/repositories/utils/filter-query.js b/packages/core-database-sequelize/lib/repositories/utils/filter-query.js deleted file mode 100644 index 7b55b26ccd..0000000000 --- a/packages/core-database-sequelize/lib/repositories/utils/filter-query.js +++ /dev/null @@ -1,73 +0,0 @@ -'use strict' - -/** - * Create a "where" object for a sequelize query. - * @param {Object} params - * @param {Object} filters - * @return {Object} - */ -module.exports = (params, filters) => { - let where = [] - - if (filters.hasOwnProperty('exact')) { - for (const elem of filters['exact']) { - if (params[elem]) { - where.push({ - column: elem, - operator: '=', - value: params[elem] - }) - } - } - } - - if (filters.hasOwnProperty('between')) { - for (const elem of filters['between']) { - if (!params[elem]) { - continue - } - - if (!params[elem].hasOwnProperty('from') && !params[elem].hasOwnProperty('to')) { - where.push({ - column: elem, - operator: '=', - value: params[elem] - }) - } - - if (params[elem].hasOwnProperty('from') || params[elem].hasOwnProperty('to')) { - where[elem] = {} - - if (params[elem].hasOwnProperty('from')) { - where.push({ - column: elem, - operator: '>=', - value: params[elem].from - }) - } - - if (params[elem].hasOwnProperty('to')) { - where.push({ - column: elem, - operator: '<=', - value: params[elem].to - }) - } - } - } - } - - if (filters.hasOwnProperty('wildcard')) { - for (const elem of filters['wildcard']) { - if (params[elem]) { - where.push({ - column: elem, - operator: 'LIKE', - value: `%${params[elem]}%` - }) - } - } - } - - return where -} diff --git a/packages/core-database-sequelize/lib/spv.js b/packages/core-database-sequelize/lib/spv.js deleted file mode 100644 index c8e844fafa..0000000000 --- a/packages/core-database-sequelize/lib/spv.js +++ /dev/null @@ -1,262 +0,0 @@ -const { Transaction } = require('@arkecosystem/crypto').models -const { TRANSACTION_TYPES } = require('@arkecosystem/crypto').constants -const container = require('@arkecosystem/core-container') -const logger = container.resolvePlugin('logger') -const config = container.resolvePlugin('config') - -module.exports = class SPV { - /** - * Create a new wallet builder instance. - * @param {SequelizeConnection} database - * @return {void} - */ - constructor (database) { - this.connection = database.connection - this.models = database.models - this.walletManager = database.walletManager - this.query = database.query - } - - /** - * Perform the SPV (Simple Payment Verification). - * @param {Number} height - * @return {void} - */ - async build (height) { - this.activeDelegates = config.getConstants(height).activeDelegates - - logger.printTracker('SPV Building', 1, 8, 'Received Transactions') - await this.__buildReceivedTransactions() - - logger.printTracker('SPV Building', 2, 8, 'Block Rewards') - await this.__buildBlockRewards() - - logger.printTracker('SPV Building', 3, 8, 'Last Forged Blocks') - await this.__buildLastForgedBlocks() - - logger.printTracker('SPV Building', 4, 8, 'Sent Transactions') - await this.__buildSentTransactions() - - logger.printTracker('SPV Building', 5, 8, 'Second Signatures') - await this.__buildSecondSignatures() - - logger.printTracker('SPV Building', 6, 8, 'Delegates') - await this.__buildDelegates() - - logger.printTracker('SPV Building', 7, 8, 'Votes') - await this.__buildVotes() - - logger.printTracker('SPV Building', 8, 8, 'MultiSignatures') - await this.__buildMultisignatures() - - logger.stopTracker('SPV Building', 8, 8) - logger.info(`SPV rebuild finished, wallets in memory: ${Object.keys(this.walletManager.walletsByAddress).length}`) - logger.info(`Number of registered delegates: ${Object.keys(this.walletManager.walletsByUsername).length}`) - } - - /** - * Load and apply received transactions to wallets. - * @return {void} - */ - async __buildReceivedTransactions () { - const data = await this.query - .select('recipient_id') - .sum('amount', 'amount') - .from('transactions') - .where('type', TRANSACTION_TYPES.TRANSFER) - .groupBy('recipient_id') - .all() - - data.forEach(row => { - const wallet = this.walletManager.getWalletByAddress(row.recipientId) - - wallet - ? wallet.balance = parseInt(row.amount) - : logger.warn(`Lost cold wallet: ${row.recipientId} ${row.amount}`) - }) - } - - /** - * Load and apply block rewards to wallets. - * @return {void} - */ - async __buildBlockRewards () { - const data = await this.query - .select('generator_public_key') - .sum(['reward', 'total_fee'], 'reward') - .from('blocks') - .groupBy('generator_public_key') - .all() - - data.forEach(row => { - const wallet = this.walletManager.getWalletByPublicKey(row.generatorPublicKey) - wallet.balance += parseInt(row.reward) - }) - } - - /** - * Load and apply last forged blocks to wallets. - * @return {void} - */ - async __buildLastForgedBlocks () { - const data = await this.query - .select('id', 'generator_public_key', 'timestamp') - .from('blocks') - .orderBy('timestamp', 'DESC') - .limit(this.activeDelegates) - .all() - - data.forEach(row => { - const wallet = this.walletManager.getWalletByPublicKey(row.generatorPublicKey) - wallet.lastBlock = row - }) - } - - /** - * Load and apply sent transactions to wallets. - * @return {void} - */ - async __buildSentTransactions () { - const data = await this.query - .select('sender_public_key') - .sum('amount', 'amount') - .sum('fee', 'fee') - .from('transactions') - .groupBy('sender_public_key') - .all() - - data.forEach(row => { - let wallet = this.walletManager.getWalletByPublicKey(row.senderPublicKey) - wallet.balance -= parseInt(row.amount) + parseInt(row.fee) - - if (wallet.balance < 0 && !this.walletManager.isGenesis(wallet)) { - logger.warn(`Negative balance: ${wallet}`) - } - }) - } - - /** - * Load and apply second signature transactions to wallets. - * @return {void} - */ - async __buildSecondSignatures () { - const data = await this.query - .select('sender_public_key', 'serialized') - .from('transactions') - .where('type', TRANSACTION_TYPES.SECOND_SIGNATURE) - .all() - - data.forEach(row => { - const wallet = this.walletManager.getWalletByPublicKey(row.senderPublicKey) - wallet.secondPublicKey = Transaction.deserialize(row.serialized.toString('hex')).asset.signature.publicKey - }) - } - - /** - * Load and apply delegate usernames to wallets. - * @return {void} - */ - async __buildDelegates () { - // Register... - const transactions = await this.query - .select('sender_public_key', 'serialized') - .from('transactions') - .where('type', TRANSACTION_TYPES.DELEGATE_REGISTRATION) - .all() - - for (let i = 0; i < transactions.length; i++) { - const wallet = this.walletManager.getWalletByPublicKey(transactions[i].senderPublicKey) - wallet.username = Transaction.deserialize(transactions[i].serialized.toString('hex')).asset.delegate.username - - this.walletManager.reindex(wallet) - } - - // Rate... - const delegates = await this.query - .select('public_key', 'vote_balance', 'missed_blocks') - .from('wallets') - .whereIn('public_key', transactions.map(transaction => transaction.senderPublicKey)) - .orderBy({ - 'vote_balance': 'DESC', - 'public_key': 'ASC' - }) - .all() - - // Forged Blocks... - const forgedBlocks = await this.query - .select('generator_public_key') - .sum('total_fee', 'totalFees') - .sum('reward', 'totalRewards') - .count('total_amount', 'totalProduced') - .from('blocks') - .whereIn('generator_public_key', transactions.map(transaction => transaction.senderPublicKey)) - .groupBy('generator_public_key') - .all() - - for (let i = 0; i < delegates.length; i++) { - const forgedBlock = forgedBlocks.filter(block => { - return block.generatorPublicKey === delegates[i].publicKey - })[0] - - const wallet = this.walletManager.getWalletByPublicKey(delegates[i].publicKey) - wallet.votebalance = delegates[i].votebalance - wallet.missedBlocks = delegates[i].missedBlocks - - if (forgedBlock) { - wallet.forgedFees = +forgedBlock.totalFees - wallet.forgedRewards = +forgedBlock.totalRewards - wallet.producedBlocks = +forgedBlock.totalProduced - } - - this.walletManager.reindex(wallet) - } - } - - /** - * Load and apply votes to wallets. - * @return {void} - */ - async __buildVotes () { - const data = await this.query - .select('sender_public_key', 'serialized') - .from('transactions') - .where('type', TRANSACTION_TYPES.VOTE) - .orderBy('created_at', 'DESC') - .all() - - data.forEach(row => { - const wallet = this.walletManager.getWalletByPublicKey(row.senderPublicKey) - - if (!wallet.voted) { - const vote = Transaction.deserialize(row.serialized.toString('hex')).asset.votes[0] - if (vote.startsWith('+')) { - wallet.vote = vote.slice(1) - } - wallet.voted = true - } - }) - - this.walletManager.updateDelegates() - } - - /** - * Load and apply multisignatures to wallets. - * @return {void} - */ - async __buildMultisignatures () { - const data = await this.query - .select('sender_public_key', 'serialized') - .from('transactions') - .where('type', TRANSACTION_TYPES.MULTI_SIGNATURE) - .orderBy('created_at', 'DESC') - .all() - - data.forEach(row => { - const wallet = this.walletManager.getWalletByPublicKey(row.senderPublicKey) - - if (!wallet.multisignature) { - wallet.multisignature = Transaction.deserialize(row.serialized.toString('hex')).asset.multisignature - } - }) - } -} diff --git a/packages/core-database-sequelize/package.json b/packages/core-database-sequelize/package.json deleted file mode 100644 index cfd1f1c063..0000000000 --- a/packages/core-database-sequelize/package.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "name": "@arkecosystem/core-database-sequelize", - "description": "Sequelize ORM for ARK Core", - "version": "0.1.1", - "contributors": [ - "François-Xavier Thoorens ", - "Kristjan Košič ", - "Brian Faust ", - "Alex Barnsley " - ], - "license": "MIT", - "main": "lib/index.js", - "scripts": { - "build:docs": "../../node_modules/.bin/jsdoc -c jsdoc.json", - "test": "cross-env ARK_ENV=test jest --runInBand --detectOpenHandles", - "test:coverage": "cross-env ARK_ENV=test jest --coverage --runInBand --detectOpenHandles", - "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand --watch", - "test:watch": "cross-env ARK_ENV=test jest --runInBand --watch", - "test:watch:all": "cross-env ARK_ENV=test jest --runInBand --watchAll", - "lint": "eslint ./ --fix", - "depcheck": "depcheck ./ --ignores mysql2,pg,pg-hstore,sqlite3" - }, - "dependencies": { - "@arkecosystem/core-container": "^0.1.1", - "@arkecosystem/core-database": "^0.1.1", - "@arkecosystem/crypto": "^0.1.1", - "fs-extra": "^6.0.1", - "ioredis": "^3.2.2", - "lodash": "^4.17.10", - "moment": "^2.22.2", - "mysql2": "^1.5.3", - "pg": "^7.4.3", - "pg-hstore": "^2.3.2", - "sequelize": "^4.37.8", - "sqlite3": "^4.0.0", - "tiny-glob": "^0.2.1", - "umzug": "^2.1.0" - }, - "publishConfig": { - "access": "public" - } -} diff --git a/packages/core-database/CHANGELOG.md b/packages/core-database/CHANGELOG.md index 127cc35e42..a413403460 100644 --- a/packages/core-database/CHANGELOG.md +++ b/packages/core-database/CHANGELOG.md @@ -7,6 +7,40 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Unreleased -## 0.0.1 - 2018-05-31 +## 0.2.0 - 2018-12-03 + +### Added + +- Database rollback +- Block exceptions +- Common blocks +- More graceful handling of shutdown + +### Changed + +- Build delegate list in-memory to reduce database load +- Perform vote balance calculations in-memory to reduce database load +- Handle numbers as `BigNumber` instances +- Reduced complexity and duplicated logic +- Improved method names to more clearly show their intent +- Calculate previous rounds in-memory rather then hitting the database +- non-blocking wallet saving +- Dropped node.js 9 as minimum requirement in favour of node.js 10 + +### Fixed + +- Wrong documentation +- Bad method calls for `sync/async` methods +- Only commit data when `saveBlockCommit` is called +- Properly log the transaction audit +- Properly update delegate ranks +- Only save dirty wallets +- Various memory leaks +- Forger order on mainnet +- Delegate registration handling + +## 0.1.1 - 2018-06-14 + ### Added + - initial release diff --git a/packages/core-database/README.md b/packages/core-database/README.md index ee50e4235d..9e7bec4119 100644 --- a/packages/core-database/README.md +++ b/packages/core-database/README.md @@ -1,22 +1,12 @@ -![ARK Core](https://i.imgur.com/1aP6F2o.png) +# Ark Core - Database - Interface -# ARK Core - Database Interface +

+ +

-## Installation +## Documentation -```bash -yarn add @arkecosystem/core-database -``` - -## Configuration - -### Defaults - -```js -module.exports = { - snapshots: `${process.env.ARK_PATH_DATA}/${process.env.ARK_NETWORK_NAME}/snapshots` -} -``` +You can find installation instructions and detailed instructions on how to use this package at the [dedicated documentation site](https://docs.ark.io/guidebook/core/plugins/core-database.html). ## Security diff --git a/packages/core-database/__tests__/__fixtures__/block.json b/packages/core-database/__tests__/__fixtures__/block.json deleted file mode 100644 index 5c4981ada2..0000000000 --- a/packages/core-database/__tests__/__fixtures__/block.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "id": "8112264681535929351", - "version": 0, - "timestamp": 35082816, - "height": 3270350, - "previousBlock": "1870866055892158347", - "numberOfTransactions": 1, - "totalAmount": 0, - "totalFee": 100000000, - "reward": 200000000, - "payloadLength": 32, - "payloadHash": "ee6338900db67987666d9eaae85616ad0c5f956773da557b84534fc8d0fd204d", - "generatorPublicKey": "0299deebff24ebf2bb53ad78f3ea3ada5b3c8819132e191b02c263ee4aa4af3d9b", - "generatorId": "DSHrJ5tyqcbbu44GkXiUKf7YyY1FXspZ3i", - "blockSignature": "304402207c0b344bbeb5f6fe3a30db7b2905796c6b1621a4bad24c4343af00f1bdcde437022009472870c5e07ed1561a45b3d9d754d7a18b917ab18cda6b4faa67960c252997", - "confirmations": 8360, - "totalForged": "300000000", - "transactions": [{ - "id": "e0aa2d77c87f4c98d239d2b7842806eaded12434cecfa367a7c34889de5c189f", - "blockid": "8112264681535929351", - "height": 3270350, - "type": 3, - "timestamp": 35082808, - "amount": 0, - "fee": 100000000, - "senderId": "DK2v39r3hD9Lw8R5fFFHjUyCtXm1VETi42", - "recipientId": "DK2v39r3hD9Lw8R5fFFHjUyCtXm1VETi42", - "senderPublicKey": "035440a82cb44faef75c3d7d881696530aac4d50da314b91795740cdbeaba9113c", - "signature": "3045022100ec46d743f77727359be026c332be9d3c11d4197ca563a0ee9fa2274a2ab480800220520f70b7e9636fa7445ba9c722b5bb01b06b8c04f5ccd8872aa928680c35c0f4", - "asset": { - "votes": [ - "-036a520acf24036ff691a4f8ba19514828e9b5aa36ca4ba0452e9012023caccfef" - ] - }, - "confirmations": 8363, - "votes": { - "added": [ - - ], - "deleted": [ - "036a520acf24036ff691a4f8ba19514828e9b5aa36ca4ba0452e9012023caccfef" - ] - } - }] -} diff --git a/packages/core-database/__tests__/__fixtures__/genesisBlock.js b/packages/core-database/__tests__/__fixtures__/genesisBlock.js deleted file mode 100644 index 821ca9f0f8..0000000000 --- a/packages/core-database/__tests__/__fixtures__/genesisBlock.js +++ /dev/null @@ -1,2160 +0,0 @@ -const { Block } = require('@arkecosystem/crypto').models - -module.exports = new Block({ - 'version': 0, - 'totalAmount': 12500000000000000, - 'totalFee': 0, - 'reward': 0, - 'payloadHash': 'd9acd04bde4234a81addb8482333b4ac906bed7be5a9970ce8ada428bd083192', - 'timestamp': 0, - 'numberOfTransactions': 153, - 'payloadLength': 35960, - 'previousBlock': null, - 'generatorPublicKey': '03b47f6b6719c76bad46a302d9cff7be9b1c2b2a20602a0d880f139b5b8901f068', - 'transactions': [{ - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402205fcb0677e06bde7aac3dc776665615f4b93ef8c3ed0fddecef9900e74fcb00f302206958a0c9868ea1b1f3d151bdfa92da1ce24de0b1fcd91933e64fb7971e92f48d', - 'id': 'db1aa687737858cc9199bfa336f9b1c035915c30aaee60b1e0f8afadfdb946bd', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100ffff4e9ba62e5e3beb37deee052824da83c4030925bce09f190151652d0669b8022056a432e56a2e1b026d4b54f6c34ce88a0c9cebdccc730659c03449fe878c66f8', - 'id': '0762007f825f02979a883396839d6f7425d5ab18f4b8c266bebe60212c793c6d', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3044022001a6326e5d1eb06d0ba1fa39446bd6d56ea45f0c269ebbce5dfc6a649277cfcc02203b252d3a6ef2b22349d9d0a9110ce28a199c39dc8b911edfa82c297a02009d07', - 'id': '3c39aca95ad807ce19c0325e3059d7b1cf967751c6929035214a4ef320fb8154', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304502210084d855eddfe616cf1dc238b19226c7959c2fc4027ae2e8aea6fd8e9eb8928e6b0220440f980e40c1c56348782fd69d49a96944df7ee5b68d18028600e0e7501d4000', - 'id': '9fdf6ae86f7c005b3b7dc1b9fb6411219407ecaa93adff85fdb61710f5121638', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402205438b8b9058bbde5d30794e7681e400e52b5fbd22324c5b6b521f97bc8b8aabc022000fe04d7afbd2e668b1d4576988ed596dc92251e33efebc081e2cba14ad5a898', - 'id': '1d7c68087c875d7ce555b2c3e71e1d91a1ad62d0c2497efe3cab91415e634041', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'APRiwbs17FdbaF8DYU9js2jChRehQc2e6P', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100b2e634a95b011a68489870f003e4bac4a4f0578bfdc6b9f645c934016c2c0463022022cd4ebf276dd627d98be4b697bae2df10b86d94e984da2eb7e011b08d6dffd2', - 'id': '0c993e115ba26981b0be9d22e7c4a13b0f106e0cb472f9d34eabfc8e414dd528', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100f965e5c280acb22d1cde405223fe9a6fcb765844adbc5321b17a268924e1f597022043d31b1edc5fe0cf60a960d84e3528472cdf34560c9463979043a409f37e7f29', - 'id': 'c279f2eb1f9e6e7d4b0ba7a98233a0f1a2536231976c99f56f64b248eb06a0c1', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '30440220715463c316a75959dbfb6a59a013fbf914bef1ff739ac8000d49dabbf5118df9022019345ae1c34173dc214bae82f3cfbf438092f0fd2d277acafe3e9deb644b1a3b', - 'id': '7e2fc9ecf23e909a3d0fbecd615445a0eed8c2cef18e01b1492d63f616f5d87d', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100fdd8aff26dceeb5abb6e5e8a8f468c8ac1997a587225298e3d8135d57dadf4dc022072ab80a81b301a162ed5cfa67d213d5a3980185088632f5f592351aff8aa0e9c', - 'id': '511c0e1076104743f98932f8e7720bdb3f1539134edadd331914fd9ece1ebede', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '30440220635e04ce278870f17fcd1883aa26c568e63dfbdd302add39aa30fd3637c79c2c02206fdd9e7b1f4d238a97d26ef1758927e2d39f121687490f2bd79831e36afdd43b', - 'id': '0768d5016c53d884e3d68a09d1bab0d730b7067c71ef4ca1c4d61b3815f5ff66', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402200b1dac57ca6565ac31afb99686f2e0f0e8dc219b9860b295ca5444a1663cecfb02205787393561fe407449af4aaf2f621db9e4d3f11c7438666cd694d495c0a0c41f', - 'id': '1aeb50080ea118165e5041f7a897974c2ed1ebde08add85dc78cc7cf73566a91', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304502210098dea25eccf31ce6f874a9528578805aaf07be8b41f1571865793f9e3e6e3c97022033ae9c73dad44c01fe6362665fccf63bb1a0ae8e26f77a1cf60b67dc96b05343', - 'id': '254f0f4fa277cc651a746d6ac371eb27afc3ea155ba060552dd26b8e83d17b72', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402207f4bf346aac501e766156818089fb16905a9bdca69ff6d5a55ba918a08afc7ab02200ec2c25cc4bb30e2c176d55630d8e2679b899c14ab4ba43c3d62955dd940425b', - 'id': 'e5ebb02e8e8a6708e22ee5ef99fe1dd8b6eea1095be6b772aa21bf63cf7ade5a', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100a0bbc15bdad648bb9b439f1d34b12b853442d1cfd4ce7f569905082801fa58e8022036b4e73edf7ab7226f8007233f77b1d497cb6b4736f02721bf1b399312ebe114', - 'id': '8a686b21477b64dfd85f08f8598a0f121ca1c7d65ccaca9e42326c75fb5f3abb', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402205d77dfcde527dcc6669bcb01c27b92c1a6399e35ebac9e69415645f596ab1d2802204179497bfd952f44d5f9e295b2a3219a290a4a82841c084a18553b7712e26415', - 'id': '21175347e2acfabc09a7593aae0682e39fe7152199a90561c11125f525211243', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100cf77c16df9185727ff717b71a94f8b29ceeae1e5bb3a28da8cef9df5bc63b7c202207bca394ce9ebd344a548e5a5697f672dedbef640dc1f9105f7c063287bcd1840', - 'id': 'ce1d9b7377551f36568127f5b635b5443f5a58abba6566b50a8d4d7b53c8a874', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100eb8daebb5484f3b0a738c9344fb28298c596f9486963f8fe36e2501ee6876f2a0220559df66986dc9a9a8e76982ef85f907c62745757990c69f0b17b6ae5a7ca4719', - 'id': 'b56702f5eddad0d8dbbb33b6b1ca3e07e4740def9c5dd2aaed9a70b90a4e31b7', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100d088e9bcd78978f2d67e7c7bccecfb73ddd0d1a2dad5b039390812320355722d02207affe83d815f04f6b11abf98eebe0488bfb87f8cd6513d44b829008ed1c15ceb', - 'id': 'a73c053c42e83a83498cf58e5b077b31443e265ddf8228081cb17a36bba366ae', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100db16a8e9682f07efb607bc7c75b654646ff449761ed146ab9358e69d29fadd7f0220436554ad78db0e04ae5b573258e2c8067848e89b55a6e8e1e25011a43882a643', - 'id': '2dccb8b44ad2e598673628fd9d74e336b467a0c941d5e257dceb85c8e0a0000c', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100b03738eccce8ad0b8ac0a656119c2cdd202089c5650d8e1486bd13eb9c3158980220059079900c7fdc16e799c50dccc074726fbf0068044462faabdf1e73f9f9bc38', - 'id': 'b2cce30021d139f97925807da796722bf4d5459442523823388c259ca5ad73db', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100becb49fe5edd6806d5ba6eddbbb34ca8eaf3a12dba123d1610b2b120ca8bd017022072972992ee0ca0f319ae754a2a5a10d715a08b23f8239f9d6d59774f790543ea', - 'id': '9e4841f43ab355be7a4f93b09f3d82c17065fbe25387dd6c5eb4e2692ea05b0b', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402207f1a3fe8c5aa7a77a58ed35c34f128b5df6fba89aa918af35eff432be7d1f8e00220460d4f2a457e1a477974157e33bf2974de6588d56e59729ae980720e9794827a', - 'id': '2c7ca823be21724a4876de632dded3b9afca45df357819ed028488128d85d29e', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3044022067266dfe9d8f2550b590e1eae2f73d28c6b80fecb24c3eb1b4539bc864b3b4f4022031e5122145c35874c0c48673d088e76fb3e11c308ffe9d5dee6431d3441d627e', - 'id': 'a91119f04e2201184761f7fdcb26e4aa81c7e1076cb11a58a422d351241d4e4a', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100b970ec89927de0cb7805e614a742d42c2967db5a9c68d0892956dc89d68ca7d1022067fa30265dd2e1a2985980be2bf876748a7a8c7f3cde0382265b601fa658dc17', - 'id': '94955e6bac6269fbd19e92d2292ac947225fc6f68c6216001b528596a961040c', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402203671b82ddf8a824b8e5aac8bc28be4aef1c00aca1097d14ec1a55003d7a3f28d02203aacb6e7517e916478432b81399828ba7425183ce0fc43feb361bcf345fb0519', - 'id': 'df563ee9822bd3d7aada600d4800952743ec64fafdc7697428d7a19a60745885', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100b77653317c93eb20ee19c71e64a7f9ecb985351bfb1fe351ac65a5738cb37ae202203d540395e1d55f87caaaa867afbfbaf98c553be0b4c7d1748418a76b0c258c89', - 'id': 'd21b6341e2b4be5ffdc3dd8fbcdf2c576ba02e2ef4ab5eab0e4bfc9da4e9e442', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3044022046239e39062a58925099b005888355b8cd6700af66972bf509a10123f9abdec60220202321ea74e56177606fc079d19c29851d832e6d00c93985ffbec3dba6f0d675', - 'id': 'df6bc7a17ad34f8e9faaa2646e8e5dd8bca35affba352537184f690e200e17b6', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402204eeab87f7ecc2097b85606b986177964f3ae777535f6fc0cf08a55fec587d87602203779d59903b8de63511e4ed0a7967bd85e9cb1fc9d84bbc5091e3caa87d8bd52', - 'id': '5f0d5f0dff464d0ad587da5bc93e600a8e2657d359d0a1224bdd4ccc3b6f376a', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402200a2b9d0f61066fa00a2a2882379aa8ee60e949bdc2a85103bbbb69ce3eafccd9022057364f349faceb3047fa95ada210c64fc4a81978d66925b37d3dbc21ede885af', - 'id': '1b39e3702576e6ad7775e34d53e43210549d52a56b3f246031e6ba4121a66bf0', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304502210099e568d3d0c1b48410e0b85c74d04234dacfb2fdf2b1d4b51fca1cfb3445347a02207a2509645aae54560762a37422b66ba4b3ee1c42de35d58c36d2f9d8fdea11b4', - 'id': '0f21e53dbb1edb1cfb4c31bb675aa4672b452a03ec363a2b3300a9dda49e3be3', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3044022026cc5f2b588a86241badca73cd9c1686916d516b8c6c397c66a9d5bb6b5d4cd402204ab5a8c8589ee954bda4a116999d2a0e4ab0e3e96f0c7fe131d7c57b9a1ede43', - 'id': '410826c255a23a78ac5c3aa10dd48132693bc955845af16c20d9c6f69b05dfe9', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402205fedd8d3b5c8d69cdd7db5ca8e9e7c5004f6ba751e45eb1b85b26d9e89800a2402202be56bb2cd824bccf325b6b11432bf6d0ddb5ec97fcc121839ac2ebf884c7173', - 'id': 'ddb57d8270b2b6c876191c1e1c5974388b9fb3ae0980cb2245d8a7c426237f47', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3044022053cd42ad147eea33801b2b57388b33f633b4bfe2ad902190e12480522250d07802203066dc0d0c2ffacc4c74cca1e0187fbea1cef7e78a78666d2ec7e4e87ef546eb', - 'id': '29e1aedf98935c369946c8dadb2d6784f9ab5ce8d73b9b4de2466c7757e2557b', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100c10448b87e7176735c8ddfc8fb3c4d5d55c2d71d18b7ce3ab321209ec299fd41022013517a09e4b366ab386698286ec7bb20410bdfb7f6674fab25a739259083b297', - 'id': '4cf04852529b5525f22cc540790e36e61ed36045ad1b5b788f61ebe42637391e', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402204cc1588b204ebc0c20f44a31ce53d15ab5e4d1f9c103c02dd4e4eaa1c33630b40220194b6e427b6def0783461cd8d765f97b105d048942be468be2ee9b0a2785d2ac', - 'id': '35c6bc3f0799d9c79efc6515f232c58be0d03a3a797d066cba879eef4afaae2c', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100be44f7ea12e2ee89245fb474643ec6c2c75afa00276826a4ecd6fca4cad5ff30022071a2c083b353a821345e4bbf74d98db0760b8721856572572cc3436ebdb8f08c', - 'id': '45f75a349f3b4d73434c0f2ac9c291d5d07278b79e6eaa0d38d6e005f66c4783', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402202090f506e8f18fde70b87a3fd6c470a23e9e262f20ec6268dd59b6362e51a29202202b838c598b33c6317c998dc179fad2b660b8a72bfaf8223d7cc82414ab4c6af4', - 'id': 'a8d9034d1091a4dbe595647ad5f64ca8b243e7842301aee48f7eaf8b8ae98119', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100be59b689a48e198267305f1ae7e116f69f7c360857ea0b1fa81db122278cad69022033436d24ec0103674522f0c559e2357f8696bd498deccad2e0f66b2cf7469538', - 'id': '061cb438ba1216cfd5a0f268ce18e6f280557bc944d9aed3655e2bc5f08bdf51', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402203b5d2aa7c4554d6d2dd6723043350df0199e6e7bbd9f21a1a20dbba8c63918cc022014a78064c5f9c5e2f43d3be36de2b5e2f17e9af557bb6c75e8d82d9f725d0188', - 'id': '239f0640ddc3170a737ef349c07cb82b2493d207421b6f71b6b3dab856f16088', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3044022005eb29ad4cf79fd4f6898de19459e15cc816acb0975e53530a202e69c29d0d4a0220686cf6e0c14779d6d68dcb9d16358c0e859094d2eec8083598b7bb5869478bf2', - 'id': '25d8eef755cfee7cab0d7f9fbbea0fad6d5f906c432d997ae8ef1c49d23735f5', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100b93096a287d59545fa3a08593dfc740d9d47f3cfa3c4bd3c8ff8ef53d3a2e957022027eda62e47220774cf799f46916195e5a8b30015c56ceff4f4a1c10a918e3675', - 'id': 'aac25996e3be809ee88996b6b4063e2097d6306e77a067de8ebc8d7076a28d43', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3044022017282aa4fac7b18e834abc3ca37b2f60cf989c26b12e2f2398a66cb907015a760220428218d39db812a22cc138acc7d5d4d2d5713f0546751c02d2c3fabecca0e724', - 'id': 'b040f86b75750b49c83ca7eb8f2a458f16b44789796ff306c5f942ca5f19164d', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402205970d53cb0921a62bbef540dc33189b2313f3574e44f046097067e6991d63b1102200a356c87642cc781df661a1fee21cce354a144463d37053280e000e1b75da7a5', - 'id': '25ce96f951d7b7d886ef487331125b3413f655f9c5ee7fb4691a728c3cbce18f', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100aab0201c9d9a9641c11605d32353685cbaa051ecc276da1e6a3b309be9f20cf7022067aecbc7329bdf1770974e317a1243815511efa8c7af7801217a83c96d86eb0e', - 'id': '285143b8b19cbde7c680b0f62ef51293e8f315c823ffbd97608c38c02045d831', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100dc7752f6f8acaa3a1ee2ed1bed306ee04556b3866db92a1e770c4b970c7a932e02202d137b312342f9d0708704833b26b6611d0464c87df97049ad8b616483e9d1f8', - 'id': '87b06fccbb63809e976b3405cccec2eeaa3694d5510203f04c0e60bb6c2c0020', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402205ccad5c77ea339f5e3f2b7900b4b1c409d3c8204273e89b6401314fb61f0d224022026a63fef86356de64fe571ff8488a951dcacab56e980fc044ef9f43b9d37439c', - 'id': '5597ed52e4123756bea9307c09c916ff9d0f9fbce8d2e9a3a2ff719a87ad0966', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402207c91153f820f34228bec62772e0d78876bd3277912eacd866fe35b5c86a316c80220104529c6f786cb387ec1e3d5826271c837f0d0a6d0fa5731b9a5c6663cce7108', - 'id': 'd46fde78608fcc668246cc35336210b3c167ba55c82e91b0fd99df7e36872130', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3045022100acc0cf119c18861d3683bb3b0f6e209f2d62acfdd958f86dfbd35137ada814320220448f6f8adcd46204629b45a4a06f5dc7ccb4dbc2a1d702e107d91053847adf2f', - 'id': 'aa92faf5d80459b4e058dc8a8212608b589925052e22148384835ab687a4e875', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '3044022055b6bbde5fa886db3cf1224a59f1fb43e850e2d9237db593368e1043698fe2c30220067dd20195e794af4152f1ff9e3ae4261698a86c54803ba1890bf176d97844d4', - 'id': '432e67db0d5fc8c66376aa96c7324e5a1e6d00a415a9c8898b5e3bf25d8b083d', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245098000000000, - 'fee': 0, - 'recipientId': 'AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '30450221009d6f38067264df8497d6888e4a8c316ec58ceba8a54c39ccb0ce261d114fbbab02200fae3f2f950f5c5e3387679f8ca341ec70cd90d0e32a30112f03cfb12cd9fc23', - 'id': '9321e1b08faa544f592ad8dc7b60ff1cf845efcd28fedf8b445be3bda60434cb', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 0, - 'amount': 245100000000000, - 'fee': 0, - 'recipientId': 'ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - 'signature': '304402200aed5a4102bdafda00fda575294f149b393a798c510af8ba877b8c2d7ec8051e022004f7487c4f728c633aee5baa62ab0017f4b91cf2f494eb1c4cc9addc3e9155da', - 'id': '0bbc9340798a18a81109bdfdbee9c9003f20a586dd9f80a39507c84588c1b4b1', - 'senderId': 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_9', - 'publicKey': '0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647' - } - }, - 'signature': '30440220072124721ba7c997f7c29ad3d4819515fae7a67be2bc395cb73f114eb8d4abe60220523ac295e114de30ce8a4300f4670db91ad2abe1268460e6ad3463fbe9834b84', - 'id': 'd2e70f9d2de57240571905aa81db0b6883e27a83be2422530722d76b56e63ecd', - 'senderId': 'AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_18', - 'publicKey': '02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a' - } - }, - 'signature': '304402204b93b06e08e71e3317f9426a1d3d450d6293fdbf5a6b3043fce27b3ce65431e20220683609720ea1d7d921238ca8b5098d3d9c0caab7b1e26efe42a6aebbc095471a', - 'id': '8695bcb906f5fd81d858794f7d90447aadaa38418d312e33115a81e856b34d12', - 'senderId': 'AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_47', - 'publicKey': '036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd' - } - }, - 'signature': '30450221009711559a43005c808113a1e9a01b1665495ff4bf30d635f7d98c752ead4cc3fc02207879e2a939914effe2b5c80cd515c4b3ff77a071b707c85c4444481878803db9', - 'id': '55853d2d2a98def00c5ab842866a44d1db91678a07b6dd63d062508db28a00a5', - 'senderId': 'AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_5', - 'publicKey': '026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565' - } - }, - 'signature': '3044022025ba51a588253524557547ec492d71bd485fe5b291e60eef681c39eaf8ee781702202bf24c3d295c7a2c9aed97a79fb835506797dcfe7e7a2853e2578e7773c7e134', - 'id': '553298aadf692c9c5d0334c307dd4ac0e277a49ed165c97ce1362f8ec639ee3f', - 'senderId': 'AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_19', - 'publicKey': '0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb' - } - }, - 'signature': '3044022041291ba10ad30fb9ebcb0e13902e92d85e2c3e98493b6d369d7d1e70e8474e31022009083444460c415eab6b4beed9e0206eb0733bad5d2a476af4db4f5b5e74b835', - 'id': '90af927db7b258538c8e21116b5a31418c88ecc163628b2b65fac92a5a949b14', - 'senderId': 'ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_42', - 'publicKey': '0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d' - } - }, - 'signature': '304402205d4111c87874e696b8f4b8897d0dfe68fabe4ad5c5769026c6ecdd04f09a1e2f02207b9c8a2a16b50164215eb1efea6d5d9f4e693cbb7eec8535e526cf8ba68bb796', - 'id': '8a920ebf5255a102d0c9c5fd720e0d36a6a3539991a2267442facf1fea2d0b86', - 'senderId': 'AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_10', - 'publicKey': '02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd' - } - }, - 'signature': '3045022100f15ff048872020d9efc561b8c837f542d54d43b9b071f7a6cc09643c6d4180f002207d0e82153a30b66f43fc4cb4b9b3093bb3d5dfd70f96928c8780c838b1448c19', - 'id': '30738f376aa40fb3c8d8849a5dc698786aeb1409fa801c18729f8da624631391', - 'senderId': 'AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_20', - 'publicKey': '02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751' - } - }, - 'signature': '3045022100babb7410d09215def98078bbab6b5e5690c2ebf54960d94527226ed3925877320220342576d1d8fd2d2fe3b6974cab48a2e16b4813f022b341b32f88e13f572bf060', - 'id': 'ccbe1c27eadc1b3b33f3f87f645be4f756021ee3d4c96f4f094e1f82d5728a3a', - 'senderId': 'ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_49', - 'publicKey': '032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374' - } - }, - 'signature': '3044022032f2c350cc1319f5838d6880e91b49ae0438fb3a626ed9ab5e27ce8788e3347c02202cca18567c8491e0feea8a5f078e28605029346c509fac0c0a192e934f8c5326', - 'id': 'f99af0fbb4d65c2c3f2c1c558f0c0c0eac2724942802fcde02fa6da1d3a9000c', - 'senderId': 'AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_3', - 'publicKey': '038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17' - } - }, - 'signature': '3045022100f0cb5d885ddf3bd4a58837f9b86486da4171652a5eb39228dfd0ff9d34d9c7c602202dc6e3d268d745a7e8633311a337ec097382342049672880c7c2215cf58e5da2', - 'id': '2dca03aed08533585d8bc609da5deb9f17ac9be5a8352769d7ae63d0db16ff59', - 'senderId': 'ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_21', - 'publicKey': '0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a' - } - }, - 'signature': '3045022100999f19fbdc9a12eebbb8c748a4cfc6c91b2233f333a09cddfd49dfeab6aaf38602203d8dc9d1551d400572a88ee812f51f897f8b35508713b789b2c1bf6dd0e88945', - 'id': '5d7e51d57b5914ec201ab65a019ecdf651c4f267cbffe403fd2170bb95145f9d', - 'senderId': 'Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_41', - 'publicKey': '03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f' - } - }, - 'signature': '3045022100e86e648add940a1e637e32ea9187497c281b843da09597e62d0c927d7f43235102200479f64ae63abb55e338f9ce1073a5c46907f7a2a82ea6f9bd9bc29811683515', - 'id': 'eaeed4133da26612c53550b6572722d8c3380d0a2344da1bd270eed1ea91fdf3', - 'senderId': 'AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_11', - 'publicKey': '0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904' - } - }, - 'signature': '3045022100bc3b2ebc58a92bf38672206e8311e7ef0e54912abce7338155b11e7d191b0b5d0220765a568c1fa4665c0ace6b4bd3b7ba0f8329e2f25af7a3cc0d78b2ea398084c3', - 'id': 'bb91e78e43c59a19ac06c015d8a7ef09d7c5b274c9f98505e5a978027354b71c', - 'senderId': 'AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_22', - 'publicKey': '03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a' - } - }, - 'signature': '3045022100aae4868ab75a33e4e77f9bf6c53b920c5e7c523a7cfe271d1afc472655f3d6a60220499f1bcb79bc0fa830dfa939898db5c9fa8571a2788c8de0da7e550bfc818bcc', - 'id': 'a6e687647dde9c1db68690090afc4fcf11833dd35fff3186b6b709a1e7d24260', - 'senderId': 'AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_46', - 'publicKey': '034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c' - } - }, - 'signature': '3045022100c0cf1fc54705c13f70fde39c55a1703a4c612b8a919379cd5b1ada464c7cc8de022074ee62490a184010ad2418d3177ff2ab03d02d2589000176312b90422b1bd64b', - 'id': '70262b0eec3ab5a60a736eb8a628cb600eae7522464a49791c0bf26e82318ec6', - 'senderId': 'AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_6', - 'publicKey': '0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc' - } - }, - 'signature': '3044022045db446b109215c6d3dfb0ee5869154a8a7624376c3760eec4fadc75a29033cf022003e524d64f3ccd0c6de4ca80a7327e2c47ffd16b3ad042bd25a02f5f64500ab7', - 'id': '56048c449694964bee3d367609a7bc46c8da20f66878c09c01dcc53c3abd932e', - 'senderId': 'Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_23', - 'publicKey': '034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a' - } - }, - 'signature': '3045022100f8f69f2957781ed02d64983744c8e51fae613ebe5bbb330d4f509bdcf4fc6b6602205568ad1fd840e01ec26a24ac9a0ff093e978172da55d494138d018a45eb67893', - 'id': 'e15dfc4e18106480083b3c6211349fd9c803e334e9ba5eb62cca19ae3f57d8e7', - 'senderId': 'AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_40', - 'publicKey': '022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689' - } - }, - 'signature': '3044022021eeb9e1db8915a9adb99db72972cd17fc7b5b377fc532ac2c9deffcb2707edf022068b9e08f45bbebad89295f520ad40d7786fe64059d45df95551576e3acb736d1', - 'id': '2bd0f888ccdeeca24a0134e3c1bf729582d284f32ee000d97f1417f1349a6594', - 'senderId': 'AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_12', - 'publicKey': '03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12' - } - }, - 'signature': '3044022040a9d0975f747df19792211546410d7c735aff2d26f367d1bf9233ffd1d993d702206890c66d4d0eb5de37df088c082d8fbd8da043817b48a76bd5d70f1e3f6b6529', - 'id': 'f75ac5ccd243e09fc9da2b3842a0654ca860d2dba5bb73866693a8a918937994', - 'senderId': 'AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_24', - 'publicKey': '039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95' - } - }, - 'signature': '30440220550c0ab565ab2de649ca7a2aaf2975453a1e4ab8b0d392d69663c0c9b6b80b7b022039047d4d1bf4e9b167a95adcde0a5a8631aeca060dfd426da28a10d968fb3a64', - 'id': 'aa2ed932faf4832848356beaf87e5381ee56a1a84fb485ba975acb28f8fcf5df', - 'senderId': 'AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_50', - 'publicKey': '030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1' - } - }, - 'signature': '3044022038df37ef25928d1a04516e982c99f49cbdc193603f814b48ab3802153bdd352002204c918915a3cbfa305c5f898ae4bcdd75394b57460f85c80daa0999751d466c08', - 'id': 'd30a726e1bb8d199d8f44700bc999c9a0a1a8be86e4be6a15764ecd424f9db1b', - 'senderId': 'APRiwbs17FdbaF8DYU9js2jChRehQc2e6P' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_2', - 'publicKey': '02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d' - } - }, - 'signature': '3044022028dd44b9609b0b599c15a257757fd068f9014e33947c77776a6fcbe71879271b02200b46fd8eb0827da6de13f5efd63b17f29e8ba4600e4a690ec31eb08bf2d9af33', - 'id': '1410b8b5f15c05528013378251bf5da30e04c8a6b7ac0f729b527664cfbdfbc4', - 'senderId': 'AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_25', - 'publicKey': '02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964' - } - }, - 'signature': '3044022038edfe34f7b89b4e69ea8b94e3335063b60deaee28246932147f53b2525924a402205b89f5e3d956aa49f24f81e2ba3447c19bd5c026568b3bef73a7a7d5160ad661', - 'id': '58d14b74b71586e18f0499a50004ec2e0cc2e5b56aa53f4cf57084030ff90fa3', - 'senderId': 'AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_39', - 'publicKey': '03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5' - } - }, - 'signature': '3045022100bc1e477994bf4cbcdb5cbe2bd92c7d955a03adfe562f8e3bf04d2f62965e9f78022045512772d8453314361161b2bd2a39aa0a7fbb897a5a83f4c7ab54ced615b42c', - 'id': '3ee53b3f1455ef0ddb52afe08854c9d87f42c7313babd3e05bb3ca4f94c495ef', - 'senderId': 'AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_13', - 'publicKey': '021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f' - } - }, - 'signature': '3044022052fe00e8e9f05b1d890f6910beab0627c823eb2d5875b4b9813a33aed11edfb6022034a723b827ce0e73bfdc0f535b244ffc983f8d549ee72b4d432de90d658db72e', - 'id': '4a3d204c2916c93360d7bb11390e355bc1a930e3cf503965a45253d65bfe928b', - 'senderId': 'ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_1', - 'publicKey': '03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37' - } - }, - 'signature': '3044022013b2798a4ab4d741850abac10d962360cd4ab6a47dfac7c1c806d6f9c3d810cc02202742414ad8a04ce679b445fcd040fb877bbfed3d2692b873dec8cb46c01c8c4c', - 'id': '7d0c5a44a7517f6ad7a1253db45d58e85aa1c735a282a32f45d28efdb7869d7e', - 'senderId': 'ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_45', - 'publicKey': '02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b' - } - }, - 'signature': '304402202c372b7b9679a8fe66f952a1d47d4327968d6e98770b215ada2fed6a8d87ed5502205a797fb511cfba557255dd37e028fb40981b7b65ad2ce8fe0e559a46eb274bf8', - 'id': '70bfe97ae7452dc752ab4de0e2a0e81bd18bef07392c56e7a101257683d4d932', - 'senderId': 'ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_7', - 'publicKey': '022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0' - } - }, - 'signature': '3044022058851712200f7386d6b3c188444f9c8f05788667649ec17c71b9e514206eb105022061e6a4bc4cd11599792e03298f95509893d56af54d51e9f639981045e754b974', - 'id': 'f6f90ff09dee5be7d8f3d58d217772df7a95865bf8609d7d5b0b673e9a5bc953', - 'senderId': 'AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_27', - 'publicKey': '02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d' - } - }, - 'signature': '304402204878d69a166e60e0a779c31fbc48c67b70d2e4aed1d63c60beb9f070963e2894022078c46b6687f23493a4c2ed39709a183a0f7352568cc9cc2c1f0d7bf0d809a4a4', - 'id': 'f68809e407d20a50029fe460d411c866b79c7e09c076dada768a38d81f184aa3', - 'senderId': 'ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_38', - 'publicKey': '0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294' - } - }, - 'signature': '3045022100d5576393a1dea704cf79a5d0bc2757a3a5e66e1055103b52157fca05fc5693ec0220522832ce0e31b779decef83ac8ce764930de927df9ae1d6f6f99a3312d99c90c', - 'id': '2ec6c6f33f00431ef063fbb8a79fb90eadb13a79bf46e6e1df36dd9434314df0', - 'senderId': 'ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_14', - 'publicKey': '03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24' - } - }, - 'signature': '3044022008a7d0bfe9c4c150566ddf701d08e84b4a5f84b07e3b1c91dde1cefa16d2a3c202200b787e898c0b2c68f4343e74f18ae7363f62b5f4ef2962386932aee09a9fa0d4', - 'id': 'e37b3efbf034bea4c852be7d7013978f8999eacc39549ceea775de197e14e8da', - 'senderId': 'AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_28', - 'publicKey': '03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28' - } - }, - 'signature': '3044022023b6fbfa5f4482a4dcc34411846696052b1592786ca87243b7d3344fc9fe9954022035402fbca22691de2497552c743f0f68c7591edd1bd7954ab7639548fcd558a3', - 'id': '08268f5e6c15cf146523ca928f24aca65b162f363593d927c66144ee5df297cc', - 'senderId': 'AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_48', - 'publicKey': '03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b' - } - }, - 'signature': '3045022100b3cad169f29a3a95995b87e1b50b35583c1bff91d69cfa236f58ce452491c579022026775f4ef50b50ecf6d78b530b4633711394983456e6a45ec227b652c86e3014', - 'id': 'ad94ee2ae94813a638b93909930c7cc631c364b6c8528b2dcd6fa8f69260cc2d', - 'senderId': 'AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_4', - 'publicKey': '03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93' - } - }, - 'signature': '3044022007ac9ff2f272f3fda4947393b8688586cc8b2958ff5dc7931ac8f82c697bb76802202a66c28852bbff86ef17ac7f51e7eee52e611e825d91a9846f531ab3c3115c81', - 'id': '76fb1984da9ef90fd7d588756163c97e00d3e4d6e9dfe78d9e3d3cb6d71ddd38', - 'senderId': 'ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_29', - 'publicKey': '0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252' - } - }, - 'signature': '304402204416e428688ad29928303fb2b00a26996cf79753fe70fb91c1f4635c644ba859022068ac5eab7d05f87c40ba36bd9dc149607c196778120c061698d7ab64aaade7ac', - 'id': '0f442a91857061e87dd193b0b9f17a71719ca7e3da62841a63568713fc12b5e7', - 'senderId': 'Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_37', - 'publicKey': '030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4' - } - }, - 'signature': '304402206a248caa5949024202f297c38cee18845e344c5f140be74349787097d3b0a33c02207ac84336e02592bb5e00dcd0c490d30eb856b34177ab9ac03410d82a355a7b0d', - 'id': 'eed30a45c350fdffc5877458f7fe29f28dc4bf81aa1a197d003c9433148b71aa', - 'senderId': 'AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_15', - 'publicKey': '02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca' - } - }, - 'signature': '3045022100c99336ce666cb4a6db3727a61c04c14d8746365f72280d9984441b7d2b568b5402201759e4f417f683743e1d4a14f8a7a215009321cdfa29834b2dbdbe54ee22c1d9', - 'id': 'ecfba14a58f9d79782c4f905646df28bf566e3e7d1f17b39df6fe6b52c11de59', - 'senderId': 'AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_30', - 'publicKey': '02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883' - } - }, - 'signature': '3044022070de7b4d4ce64bd605c9d008142544c2b113cc84df07ed1982e0adf3cf69f4520220211b01710a6533a270dc2814c7f968adf27eb6dbf437e7a72960b013b9651a0c', - 'id': '36ce5323859a92f302f77f27bd08ee3485d720f55842ccba353a47ea96a964c2', - 'senderId': 'AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_44', - 'publicKey': '022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c' - } - }, - 'signature': '3045022100a7c271633ecbf3c6641c7db36913b5fa0ea521f400a4848edf024648f3d7128002206a271f8a88644062b64d856407af9567c0b2937d4a3d89a3b3d07edbd3a0f177', - 'id': 'e120452e7c56a9327b2be7dfd3dcecae193f2e2e772903008b03cdf00146ebd1', - 'senderId': 'AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_8', - 'publicKey': '03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564' - } - }, - 'signature': '304402200394b6545015bcf2d0f291de57a4197cb6ef57b2ad5fa37f05e8a220913ba83502204d0d2f2206edba54ada5b8e5afd194ba83dd1bf15f744258409595251dbe3ff0', - 'id': '7d15eee8e4e3be3d2c44acd51b87a816bdb593565d4ac358dab24ae9c8a5bae2', - 'senderId': 'AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_31', - 'publicKey': '03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2' - } - }, - 'signature': '3045022100989eb331951a13152aa03583efc765499e836c6fbafcafec4302b243ada8de5002203876fc4cf7fdeee4a095667e55a2fef84e5a7053e807b4d8e029883f0d578019', - 'id': 'baa686d521f95d265e7099cfd9ef14e0a9a92254dd94c16ce50c460bd013c588', - 'senderId': 'ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_36', - 'publicKey': '0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e' - } - }, - 'signature': '304402202be177dddfad323302565a866d38a3e7939e0234b16e7dc02075cf258502eba302200928a139ec1a82b4609fcc1bd6d1d027ad050e93fcd2eff94181936d2d43e39c', - 'id': '9fcf7ec6fe98ed94710e212226d8b90df7e7467d66dd4c5c9d48474388be3099', - 'senderId': 'ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_16', - 'publicKey': '02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9' - } - }, - 'signature': '304402207b4f8c09a728acedf3b6ba0632e12d01670c683215053e49dde8598954d85a9a02202a7d7930baa17c2134b314e47dd6c334c828f78e573a2bf92fcbc1146d630541', - 'id': 'c35e4b1e7a2435664fc0939251c2052633ebf4b51fb22d15e71bfcab85b26de9', - 'senderId': 'AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_32', - 'publicKey': '0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055' - } - }, - 'signature': '30440220127d27312345e015c681adb799c1a87d16fb0caaabd5020b39257d567816b91c022018b2388f6d2d9afb3714d84ed102b3ea61159772786033c855947613c7ce7b5b', - 'id': '0d682a3a9c252a674043bee5240e456dae2685d76fbd3bdeda6ff50f0c442fff', - 'senderId': 'AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_51', - 'publicKey': '02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a' - } - }, - 'signature': '304402203d0ee691830e4d001553bf4e49b6d9669b3c959376f391410551c8adc679dac902203ba6e275bf6d543efd19d20428649f802d9396bb0967114a1f09c24827be1da7', - 'id': 'ec2373b0d609ae72fb400ffdfbffc59670ebbf1c15f59c0ac22a4030dae700e3', - 'senderId': 'AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_26', - 'publicKey': '02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983' - } - }, - 'signature': '3045022100f2cf77b0510f589b5aaaf2b0027ffbce6ce8d4873cdc67dc8900865d156de3be02203c22e30945618683182f3d3873e6b3657e0900b062f866bab2705cd593669e79', - 'id': '3cb2f0f7d05a515d4c5c873cbe96e33b1dfba1b7718e4548de7f9da54933b652', - 'senderId': 'AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_33', - 'publicKey': '03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe' - } - }, - 'signature': '304402201e328159172d543d2225c247c6b728800c52eb724f67c0e919f6b7215e6bd7f2022075fc02fe0b14a1499c5602d87ca2c99d6e789beaceed2b9702060dece872d14a', - 'id': '2fd77e744399c9632cc8f106c39237f201dafda976f1040235359f99eea3b832', - 'senderId': 'AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_35', - 'publicKey': '032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e' - } - }, - 'signature': '3044022063903d82e8bd15a6741a298b9a6007d0dc3626acfe2f072c3b624ccbf91ce3360220486ba4cc5591d8aa31b77dfde025b61691dbaad0feabe13e840d26e40010c5df', - 'id': '5baf9e318c9e4cb0513a21eaea27e51c849f95fddc963207fb07aa2fd2b9f9d4', - 'senderId': 'AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_17', - 'publicKey': '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357' - } - }, - 'signature': '3045022100efc1bc16e0b646da48f84822543b62ef5253bfa98bed6613f2d6d4634076e61802200ef243f9dbac7633a8819ce45e2a85d0eacfdc9a33a92bd3a03e90cbd312b823', - 'id': 'b4a959ad75f81b7fdbb957c90a3a63a6c5589e7819e2c455733a3a2b4b034634', - 'senderId': 'AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_34', - 'publicKey': '030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80' - } - }, - 'signature': '3044022012e52a479648990bfc1ed12bf901cad865708ff45962c3724ea67967be4f9d0102201901525ed8dd090af6a2637c123afb304e9fd178794addcb88d916227e66887d', - 'id': '6439f2308efe31ac52ad06ef1caa45b9abf6c589118b7997da6a287325ca36e7', - 'senderId': 'AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_43', - 'publicKey': '034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e' - } - }, - 'signature': '3045022100a0874d1582ce210081f7ab30e7f951dfb9ce8f512d237f8a8cbd5d85569ef3b902200f0053c05de3d6e5ada4e4cf1403a836779d653573c2f374055645cc954c4c4a', - 'id': 'b0733072e98d3d6afe977e32f3dd118c15e79212232417743ffb551dc2a2ba55', - 'senderId': 'AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW', - 'senderPublicKey': '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357' - ] - }, - 'signature': '30440220158ed59156e0eef2d2b94a296451dffe079be701b3d74f0443ef43bc266b334202205a2c39f57abfcd279d568608b90884b3ebe107316aa7552eca35c743b318a47c', - 'id': 'ea294b610e51efb3ceb4229f27bf773e87f41d21b6bb1f3bf68629ffd652c2d3', - 'senderId': 'AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7', - 'senderPublicKey': '030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80' - ] - }, - 'signature': '3045022100898da9f693a458a6875344c6c4cb73069c4075904c75595ffbc665967d84b07002200f168aaf3ab1b52dfa74599394387dc4cf627a447fbc5a91000e9d251cdb20c0', - 'id': '3639b5dc6d19d46d8254d941bf7ace0f3da8a7cf8a56361921b260820c7239cd', - 'senderId': 'AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1', - 'senderPublicKey': '032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e' - ] - }, - 'signature': '3044022055ed9a8b55ccb3bd0945a710269b6f243f1dbfaa28467d3218a17565eb0c962d02207d31561478f16d93a20f5454ad565dea24e8dda4ddc464cb011f4b6b360c4e81', - 'id': 'fe24509580cde0c2e2f49defedd3a0f7572d2f78f90b51a253b0d8cebd74c20d', - 'senderId': 'AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof', - 'senderPublicKey': '0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055' - ] - }, - 'signature': '30440220092f367f833d677e8d0609ad1df65f389c2c35d1501c71c245c2982e6a832268022018e67445f525613d6cb6ac0c9683bd0f55bd40d9c929165649414f083c9041f9', - 'id': '6a76553db794ebf4d5f60a7d7d71cfe29f4dbcaad9610106fbc578cdc7167cd4', - 'senderId': 'AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy', - 'senderPublicKey': '03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2' - ] - }, - 'signature': '304402203dc028b5013c36b03f97b111a8d7c05d0cd8e505b0b0d18747c0656c9b5cfe8102205e9ce8a78d1183b3e9880c69635d04218d94d17808bcc3f92e7af53195c23daf', - 'id': '0f9d7e7708918b77afbdfffb63eef8fe87ba36e0131c88b44c1a7f81750cc025', - 'senderId': 'ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9', - 'senderPublicKey': '0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e' - ] - }, - 'signature': '3045022100a80ddd7c3adaf0e97ab938773fc78a716f3054d7e03afc1ddfcb5005badbd2810220231c0dabe2262149f994c939f9dc90d46b9bd7ca96b19aad6788cd3571e4f71a', - 'id': '0ac77b2637fb25be42b3b60d1651bbbd788aeaba933a08ec4a417c7b4c54e087', - 'senderId': 'ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT', - 'senderPublicKey': '02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883' - ] - }, - 'signature': '30440220772c9cd8b96f74fcddc429d57d466eca6fc40fc211845f59eeb78cb027e116c5022004cda291587eb118d622de21333d2a5783969794b5b0101ad8b1044c7d8058af', - 'id': '4b0dda465564d53981c0e36d73caec888e3523633eaa80dfb99a9c81b2604c7d', - 'senderId': 'AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU', - 'senderPublicKey': '0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252' - ] - }, - 'signature': '30440220406d54714b6425ae4553ea8bec75f31fe52e9b1a9b6f6897151253ab7f637d3b022040a2df4b69840f4d9b0b67658c75efdae8d8269780d4cc50d055fa63922dbb9a', - 'id': 'c7db9d36d97ff0168d0d670ec695e1dc786dfb93f4081586870c8793b50e5f17', - 'senderId': 'Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK', - 'senderPublicKey': '030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4' - ] - }, - 'signature': '3044022018b7e51118ec83c985fa4eb3d7f0cf0655753bcbde7e82bac521665fb1c0ffaf02204e2ace460b2542db8c77e41d05d5e02fa5514b746a0a1e947256925846ed19f1', - 'id': 'c41f4cffcdd523f1718154d5bd5f4f0bec0376076b5f8dd340337e9edb4821ae', - 'senderId': 'AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW', - 'senderPublicKey': '03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28' - ] - }, - 'signature': '304502210088dbe249503da43c157485bfd4f2c95babfe4d0b8bbefe44afa52529b824a79e022045239b6a374fd9aca52c27171ee66b4863c956ae4085c9760d863b1902596c1a', - 'id': 'b1736ec6a1ea4c6d4eb278430a8ee214c88daefe296ba98530e692f8b7a7434c', - 'senderId': 'AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej', - 'senderPublicKey': '02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d' - ] - }, - 'signature': '3045022100fcdf750a775e728a31691a1b38908a7f990b579da510959cc2c63442f5ffde760220316ebb051d9fecb2486771dd39921fb12675b6d46b2441dd1db3c42fad0a59b0', - 'id': '069271456015c2ff842771775993b8afc3404bc070572eeeb0f2fd72d58e18dc', - 'senderId': 'ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U', - 'senderPublicKey': '0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294' - ] - }, - 'signature': '3044022034ce8f77ea9d0f5cf3a9135d7b72d0ba3b96ac6d7eaa3670e9956aef2c9a83cb0220626d1f269128f673a23f9993ce00ba78a08103e697298be29a4c8ee94f204e3a', - 'id': '9a99bba8340e7ad4e05d8424a0977ebbde428d31ee066c9828bd06b42bb42a72', - 'senderId': 'ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2', - 'senderPublicKey': '02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983' - ] - }, - 'signature': '3044022039ae1155f8b87a61c38b25cbbf30da6ecf6cfcc12b25c2e7fe576373754a41eb0220061a66a893129fbad5d48cdd19cf48b1a0d133dd2f3ecdc60ee7b87277e1f81d', - 'id': '6c2c8926420ac269b50fa30127e0e791afb2131aff5821ca7aa80d38a0182048', - 'senderId': 'AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf', - 'senderPublicKey': '02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964' - ] - }, - 'signature': '3045022100d0dac2b7691aa059b1048d7925a0c5d5099f6e9b0f2e321e6d4f128ab1b3272b02207e8c4f643f8f9d1c3f81f0cce6a698df2da2ab71d5b01042766bbe0f46f4a775', - 'id': '9259193c5de72276ed7a99f9d507dd6ea9856411fda521074fb41a556294fdf7', - 'senderId': 'AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9', - 'senderPublicKey': '03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5' - ] - }, - 'signature': '3045022100d5496fec447367ab6b53956a8c40cd8566e050ebb3b92d2c0b2a9d09bef36c7402205e32367605372375801f7b9db39aaafb46ee763b1494f0aca144fb91f3415752', - 'id': '2a41e5946ab0773ca2334bba9d3510184bdd258f1c651ff8ec95b7b64a01dc2e', - 'senderId': 'AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW', - 'senderPublicKey': '039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95' - ] - }, - 'signature': '304502210099249695dc38826e04c8fcffd2570b98c43dec4788cc6a19737ed0872f17ec3302205301f645d803ad5df4ab1a700446e28c7cd76153607f6a2d68ae9168d46f3fe9', - 'id': 'e5c09b0fb2c24c57a4dcef0078953093800329ab4dc8e16a9d9f68215b5acd3d', - 'senderId': 'AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU', - 'senderPublicKey': '034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a' - ] - }, - 'signature': '3045022100f983b03e319aaa6c6ab6381e3ef8c0c035d6e3cc2139cedf70fd4e385393e38a0220286f73577765eb3e89e362785ad8a6de572bebf41bbc1f515b0ea93e41801eb3', - 'id': '00b2c0455ef6f508d65f11bb49e3cfe1e6062d5fd153cafdfdfd2ccbf9c646e5', - 'senderId': 'AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr', - 'senderPublicKey': '022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689' - ] - }, - 'signature': '30440220103862ec51621ca27a0ec6b2817848e8824d2d09dbf7e6aac2f45aeea5d2dc9102205e8cce78b5cd7148aa4d406dc7b491dd7758047200e10cfe1e5fde5c56107ac5', - 'id': 'e25439ad11cb8db3d49ccb3b8b608c1bcb24cb29b2e5ea15101cce3e475224eb', - 'senderId': 'AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ', - 'senderPublicKey': '03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a' - ] - }, - 'signature': '304502210099241ced4a0fd1eb02f5cdcc880ae5f48eb3c7e490d4520c20124ecbf403893602204729dc6cacf3e87c97ca57c1be54d1e80791bf31ef022135e68fc06c950f6994', - 'id': '1474f50815c6c7df41ab652414806d61abe15bee0d41f32d772f4e2793badce4', - 'senderId': 'AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX', - 'senderPublicKey': '0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a' - ] - }, - 'signature': '3045022100eccf81d44992c49a5ee37c6fc2ccc4b6bee9aa44888513b3e18e79452ede3156022056b0ddf079d2918d72e8781d3af009c87e6058563591dfd6ee0117b7df5534b2', - 'id': 'b394e2a8b5c2d20a72ed288408b8f0d48aed922edbee6e16c1c5b0e67517214c', - 'senderId': 'Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf', - 'senderPublicKey': '03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f' - ] - }, - 'signature': '3045022100bdb87894846eccc5a5473edaee1e6dca5f3469963e22f06123b6bde195aede0e02203d0c6833e87c5e60f4597ce624d4c2502a0562b4e54d943f82a4889e3cd69532', - 'id': '6a399099bac6c74fa5e956512ef8b3a39f6f946d5d6996f192c2f1dd5ba172dc', - 'senderId': 'AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv', - 'senderPublicKey': '02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751' - ] - }, - 'signature': '304402200785771ccf1a6a40b51183a190d4cb4ce76b9ffd4c2c736d7724e6c667113d020220649ecfe73017d8dda96a7914793470ee7e582693e4866df123b1032194c163b1', - 'id': 'f20a831a6bae0a85470e308fb66517e70db479657459f6bb39f2cd1783c565e6', - 'senderId': 'ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv', - 'senderPublicKey': '0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb' - ] - }, - 'signature': '3044022020b79e1f07bcb17cae9485b9f44e9f583ca235da4ddd363b905fafb884347f71022015a20481b43720ddb3b1e3ca64b1f47e59b5cc2016a62f43327ca14533384dd4', - 'id': '7a1285be87dca9718bece5b84266c1bf6801a39cc111d534e660aef9e6d26929', - 'senderId': 'ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg', - 'senderPublicKey': '0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d' - ] - }, - 'signature': '3045022100b1615d16763c46d42ca2aae967f04c1c07c119b5af7a378c262ba85515a8d35002202cf7df91676cd137943720e93f06c11907412a6bdc5ef2157cf536a203cf83a3', - 'id': '76fb5a1de90f245b1eeb79cb11c7bea7c8b738add0fb8cd95191186a944b0229', - 'senderId': 'AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri', - 'senderPublicKey': '02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a' - ] - }, - 'signature': '3045022100e3c7b5d6a72acde4d22e8c1c6cd864c549deba89683f4b84320407d6c380827c02202da57df0ab7cd381b776bdf85802aed371e7cea7269a84f911b1d8e9956badee', - 'id': '8da75c8100e6248ab37cc92f72ed9facec3067f4f82f03db8bb8063791463fb3', - 'senderId': 'AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t', - 'senderPublicKey': '03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe' - ] - }, - 'signature': '304402205779b5d8acbfedfc105fedb6fcbd4636713ed27605faa9bd988598072640a958022042d8a8b3d7910c7c385f3707a317c5d445d56da250f8d127c71df2d9d4c5d86e', - 'id': 'fd26e265be88289828d0ce7ffc5faeb9849e1f4cb37a8f1dd5d6fcc436d910b7', - 'senderId': 'AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf', - 'senderPublicKey': '034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e' - ] - }, - 'signature': '3045022100e18a89fe1fe0a8acaca2b6461314e784ffebbe7374f6aafdb06934e83985ccbf022027314b21a4a25b477bd7cc070b4e00ef8f3d69f3f1af028b96571dc245924c00', - 'id': '41d92e128e6b8367cbf8fd111e5263d52e1abad553653f975dd60d7f7c5b637b', - 'senderId': 'AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9', - 'senderPublicKey': '02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9' - ] - }, - 'signature': '304402201c614c84dbae26f87973c9e2b38df883fe0c8c469080e31fe32a4c4946d50b67022075b8fb498fb1384aa6be785845da02813185ccf095597b5782618033828af4d5', - 'id': '1e4a1f8aab6fbf8682c2b35e0d04e9e007ae717ce3f4a82894747e5807e3c759', - 'senderId': 'AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV', - 'senderPublicKey': '02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca' - ] - }, - 'signature': '3045022100b1ee6becc59d594776a40e5b3caec82390d273b703ecb0d7caece44953141449022016543cc29a28882845118afab6e51296cd216bc662260c28e5efd9597b6025b1', - 'id': '2ce068bfccb3f967f4004e9a1e81614a738e55e45c80114c0af30a085f71a2e9', - 'senderId': 'AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ', - 'senderPublicKey': '022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c' - ] - }, - 'signature': '3044022036698a329d7f5f751f91ce02bc188a7527a377d01583b70427cfce64def945ec022079afafea10aa32394a1e42a80577de3869856656221d5f259e05fb44f01668b8', - 'id': '3478d1ad3655e10fcc864f191972322c866616866bb1dbf66d7b66b31cd95de6', - 'senderId': 'AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA', - 'senderPublicKey': '03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24' - ] - }, - 'signature': '3044022035fa7be80cf881eefefc12b11de04ffb2e2e92815cf05074afef54a3c5b2eccb022041f3347f59db0b3caadefcbfbc5ae275d3fe3e2a52fe1504b23628d4b79a43bf', - 'id': '8adfd8e73e96188ed9fdec459d88db1fb041a2b25b3f64830476aec661ae5010', - 'senderId': 'AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm', - 'senderPublicKey': '021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f' - ] - }, - 'signature': '30440220630da8a73979bd3988b7f84fe9e83a429cf3239f54c140c3dbcc407140513fc002203664ad54ed9f199f2683479b988bd97ad8fffb2c2d5dfdbdb10858aca4abfaca', - 'id': 'e306328ffefcd9e3809e7390a358199a62cf8ef037d57af1f5c7b54d728d427e', - 'senderId': 'ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1', - 'senderPublicKey': '02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b' - ] - }, - 'signature': '304402206f1df93f299ffedacc25aa201807df47d32c43369315cf9db280963c357be56302206a66acd553710f49bbb7b803a2bcb71128c8e617ffce66b37b7c968817349247', - 'id': 'dc69bc8f78502ba34655ed062987788939189709a4112760cd8807245d7461f5', - 'senderId': 'ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8', - 'senderPublicKey': '03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12' - ] - }, - 'signature': '30440220629e696a10e04d4fbc10a5ac443bf9bd40dd5d89d4b214224abe47d7ab5600340220643f361a24d9916e2c5aaec7bd7d8a6a0d3ffc5fc0b62c3ac4906eb799a862fa', - 'id': 'c3f49fb80c40f7779b32ba23616f5573a6ba58fc60c4629c2252933038dd89f0', - 'senderId': 'AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2', - 'senderPublicKey': '0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904' - ] - }, - 'signature': '30440220660f9604896dad2a97820b0d7524f0bce5a8b5766f150517d5061fd02bddf768022055e87c25891d4480e66e5d1a71e42cd5a4bef3ab2b2651cd72d44f30a4b32309', - 'id': '8e8ac1b1a586e86867abbf25d63387bb6dfb793c691f0b06333c1581a9a568b3', - 'senderId': 'AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT', - 'senderPublicKey': '034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c' - ] - }, - 'signature': '304402202e2ad64129f61ef1156c4c7e80ab862d4823d62dac502685f53028536ddfb41a02201a3ec777fdfe8fae9f7cd5251fac322c1b6a2a4d41b3ec456daed474986d4872', - 'id': 'ff73565c373f2cefebf86c72dda3a6a6205750eb03b69178cb83378620715e1d', - 'senderId': 'AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q', - 'senderPublicKey': '02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd' - ] - }, - 'signature': '304402202e5c78cf21a088db10e1e1f64d98d84c8d3294fde7bc322d4af06bfe99d4c2e302207e7912a16a37b641a9f8c7c722f2b0d699917ca73e4d0f21584b717fb7f02f13', - 'id': '3822273b496f2e253081cedf382e4f9937713fabb83449e1f892377cf536e68a', - 'senderId': 'AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo', - 'senderPublicKey': '0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647' - ] - }, - 'signature': '3045022100a65ce45164c9bc3e018e26703370c9deb2933ee3b4e814619043cc37c4a39c4802205ae4931ac9e8dffd714c3b601fe248a49c0185c8367887205f497d951c52eb54', - 'id': '430d6db0b87c25dce4ce14ac907c13bcc6efa5d95135f05aa4ba7596ea9d400c', - 'senderId': 'AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN', - 'senderPublicKey': '036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd' - ] - }, - 'signature': '3045022100f3cdd7f688ad2d7b6a5b9cc7e793cb8a6e6e07d3327bc67add64691a53fd2911022026ae1adc8f4fcfc01bcca3efc83019026755b443a504265ad1f46f69d1f5951c', - 'id': 'dda86ecc0332e6c4eed1c0a5af7424374089b85dd274a300fed51b86e2655587', - 'senderId': 'AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj', - 'senderPublicKey': '03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564' - ] - }, - 'signature': '3045022100d419072a752acd55792257c96099fb14c56c29112a00535d39bca96fbd7951c902201abdf4db247dc956d79f4543c389823fbd1a9337f95d30df39603a3b52486bfb', - 'id': '0998e9a055c53bf6697ee76af94c7a830c1364016d78fce889a21bc38ed70cd5', - 'senderId': 'AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN', - 'senderPublicKey': '022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0' - ] - }, - 'signature': '3045022100ba1e0ab761326d2a53cbda2a4a5135033c94d8166864d2ad3ceb963b4a0c046402207d755ecf4ada9fa2a598fd75e73a59d30cb83e01f510020b48b6bf162dc60b27', - 'id': 'be13743deb8486a575d1fb564d2b07d797ac77148d35793c9aca43c0d47aad61', - 'senderId': 'AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA', - 'senderPublicKey': '03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b' - ] - }, - 'signature': '3044022038a491e2e13ac32025209d00aec1af31b73a8b6ee77ad9b8bb80a34f5df59dfc02200ce82c89fe9f88bd5af236ceeaa80f9954e3fb4af7bc884c447505751d49c134', - 'id': 'f1d3d44cc289837de9623cba8891a1ed1cde8918473a91e2daead29975afad22', - 'senderId': 'AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx', - 'senderPublicKey': '0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc' - ] - }, - 'signature': '304402202ae599ce389cd030b8ab48ef53113458b9ba8bf9c9ed09c662eba2849bf540f802202ed63f8af492dd0b67d1b451170a989418a42466a3a7ffe89c4c5a18337e8fb9', - 'id': '65ab302a44ea7550891eabc3b4a8d5ecbcb80784c4666195d5d0b7e33394300d', - 'senderId': 'Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK', - 'senderPublicKey': '026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565' - ] - }, - 'signature': '304502210088a3a4e82d307c238e01ce154b57631d4429e0b591e828ec36839a783736e842022042c6e1d719781e2edca3dbfe84ad13b9e490821a47ccadfcff379decb9c873c0', - 'id': 'd26a7ea56f398634a81086bb15c2f0c863c71b8bd728304d324d8245a8fb6c73', - 'senderId': 'AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz', - 'senderPublicKey': '032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374' - ] - }, - 'signature': '3045022100ae5805541f085a50076835422b2581d3b7a128a05b4f068ad7e3c14cd02799b802205f4bb40e06f90e02282ae74c0aba97923e601fd78234b9585468c4fb73f47893', - 'id': '02504eae7ff4963c081219523bc48d7a07de4c29fdc1622224547f9a7c133abf', - 'senderId': 'AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp', - 'senderPublicKey': '03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93' - ] - }, - 'signature': '3044022078d38cabd8f427ef381d0aa6a0b98c6a590cb18f47acc1d80b429a1c1959b0ab022022a70d4d93d650ca3121dde6065e80cd90d1e2e91cb90f0d0b2eadde609e0d75', - 'id': 'addb8c1baa833baa52a5b51d8a86f8524bde826b5c9f0a99e57070e6323e1dfc', - 'senderId': 'ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv', - 'senderPublicKey': '038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17' - ] - }, - 'signature': '3044022076dd065e3fba825b77884a179d0231d7fc9e7d3a02e34bc6565fab81a84e559e02200a880c028e690a9d6f2c4c6576b1bf3e913817c834da8ec6afdbadfae78d341d', - 'id': '72f31f9a829b93045ef2e860b24c33b9be6a2621c26914acd42121215c1d517e', - 'senderId': 'ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'APRiwbs17FdbaF8DYU9js2jChRehQc2e6P', - 'senderPublicKey': '030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1' - ] - }, - 'signature': '304402205261d9d8ded6364fda8b10bd477982be84990cb010f9214d52c492676814e1f40220489f441ffe2478d361a12ab96caa59da495fe62d61d0e2255aa5ec4ed789afb8', - 'id': '1f17b4ba072d205761ed3f786491eaf684ed3601b69082e487e568aa74a319e8', - 'senderId': 'APRiwbs17FdbaF8DYU9js2jChRehQc2e6P' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd', - 'senderPublicKey': '02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d' - ] - }, - 'signature': '3044022040219da41054a3eebd3122df7f09a62a4e8b4fdc287ae77221f2217b42f291ad02202b9a70c54bb546a604eafadcc086ef6b6570f57542374d87de02ad7f61fe51a4', - 'id': '5fa837023159d6a3d6cf7c5b2ed6fe05ff7df19300226b2f0be5a48a06993780', - 'senderId': 'AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo', - 'senderPublicKey': '03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37' - ] - }, - 'signature': '3045022100ded426768f114f459485ba6ae293c9649b340cf2dcb15e8e887fbb5fed6f7e0b0220752297022de6e93ff64bb9e07b4efef8e946cd2872f84d9e1cb3165ff5c342cb', - 'id': '0a16dc31514629a36d7237968ada6a95d6cbec027b7d26e1e0f0d7d4febe9494', - 'senderId': 'ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo' - }, { - 'type': 3, - 'amount': 0, - 'fee': 0, - 'recipientId': 'AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD', - 'senderPublicKey': '02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a', - 'timestamp': 0, - 'asset': { - 'votes': [ - '+02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a' - ] - }, - 'signature': '304402203aa292e7aedcd62bb5a79c2521b666b8e1886b57923d98f51911b0461cfdb5db0220539657d5c1dcb78c2c86376da87cc0db428e03c53da3f4f64ebe7115998f00b6', - 'id': '8816f8d8c257ea0c951deba911266394b0f2614df023f8b4ffd9da43d36efd9d', - 'senderId': 'AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD' - }], - 'height': 1, - 'id': '17184958558311101492', - 'blockSignature': '304402202fe5de5697fa25d3d3c0cb24617ac02ddfb1c915ee9194a89f8392f948c6076402200d07c5244642fe36afa53fb2d048735f1adfa623e8fa4760487e5f72e17d253b' -}) diff --git a/packages/core-database/__tests__/__fixtures__/wallets.json b/packages/core-database/__tests__/__fixtures__/wallets.json index 4ea9c54ce4..61d49f59e8 100644 --- a/packages/core-database/__tests__/__fixtures__/wallets.json +++ b/packages/core-database/__tests__/__fixtures__/wallets.json @@ -1,10 +1,14 @@ -[{ - "address": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn", - "publicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788" -}, { - "address": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU", - "publicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252" -}, { - "address": "fake-address", - "publicKey": "fake-publicKey" -}] +[ + { + "address": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn", + "publicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788" + }, + { + "address": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU", + "publicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252" + }, + { + "address": "fake-address", + "publicKey": "fake-publicKey" + } +] diff --git a/packages/core-database/__tests__/__support__/setup.js b/packages/core-database/__tests__/__support__/setup.js index 160df813f2..a2358e432c 100644 --- a/packages/core-database/__tests__/__support__/setup.js +++ b/packages/core-database/__tests__/__support__/setup.js @@ -1,26 +1,20 @@ -'use strict' - -const path = require('path') -const container = require('@arkecosystem/core-container') +const app = require('@arkecosystem/core-container') +const appHelper = require('@arkecosystem/core-test-utils/lib/helpers/container') exports.setUp = async () => { + jest.setTimeout(60000) + process.env.ARK_SKIP_BLOCKCHAIN = true - await container.setUp({ - data: '~/.ark', - config: path.resolve(__dirname, '../../../core/lib/config/testnet'), - token: 'ark', - network: 'testnet' - }, { + await appHelper.setUp({ exit: '@arkecosystem/core-blockchain', exclude: [ '@arkecosystem/core-p2p', - '@arkecosystem/core-transaction-pool', - '@arkecosystem/core-transaction-pool-redis' - ] + '@arkecosystem/core-transaction-pool-mem', + ], }) } exports.tearDown = async () => { - await container.tearDown() + await app.tearDown() } diff --git a/packages/core-database/__tests__/interface.test.js b/packages/core-database/__tests__/interface.test.js index 447208d3a7..499cd679fc 100644 --- a/packages/core-database/__tests__/interface.test.js +++ b/packages/core-database/__tests__/interface.test.js @@ -1,20 +1,28 @@ -'use strict' - +const { Block, Transaction, Wallet } = require('@arkecosystem/crypto').models +const { Bignum, transactionBuilder } = require('@arkecosystem/crypto') +const { + ARKTOSHI, + TRANSACTION_TYPES, +} = require('@arkecosystem/crypto').constants const app = require('./__support__/setup') let ConnectionInterface let connectionInterface +let genesisBlock // eslint-disable-line no-unused-vars -beforeAll(async (done) => { +beforeAll(async done => { await app.setUp() ConnectionInterface = require('../lib/interface') connectionInterface = new ConnectionInterface() + genesisBlock = new Block( + require('@arkecosystem/core-test-utils/config/testnet/genesisBlock.json'), + ) done() }) -afterAll(async (done) => { +afterAll(async done => { await app.tearDown() done() @@ -43,7 +51,9 @@ describe('Connection Interface', () => { }) it('should throw an exception', async () => { - await expect(connectionInterface.connect()).rejects.toThrowError('Method [connect] not implemented!') + await expect(connectionInterface.connect()).rejects.toThrowError( + 'Method [connect] not implemented!', + ) }) }) @@ -53,7 +63,9 @@ describe('Connection Interface', () => { }) it('should throw an exception', async () => { - await expect(connectionInterface.disconnect()).rejects.toThrowError('Method [disconnect] not implemented!') + await expect(connectionInterface.disconnect()).rejects.toThrowError( + 'Method [disconnect] not implemented!', + ) }) }) @@ -63,67 +75,93 @@ describe('Connection Interface', () => { }) it('should throw an exception', async () => { - await expect(connectionInterface.getActiveDelegates()).rejects.toThrowError('Method [getActiveDelegates] not implemented!') + await expect( + connectionInterface.getActiveDelegates(), + ).rejects.toThrowError('Method [getActiveDelegates] not implemented!') }) }) - describe('buildDelegates', () => { + describe('buildWallets', () => { it('should be a function', () => { - expect(connectionInterface.buildDelegates).toBeFunction() + expect(connectionInterface.buildWallets).toBeFunction() }) it('should throw an exception', async () => { - await expect(connectionInterface.buildDelegates()).rejects.toThrowError('Method [buildDelegates] not implemented!') + await expect(connectionInterface.buildWallets()).rejects.toThrowError( + 'Method [buildWallets] not implemented!', + ) }) }) - describe('buildWallets', () => { + describe('saveWallets', () => { it('should be a function', () => { - expect(connectionInterface.buildWallets).toBeFunction() + expect(connectionInterface.saveWallets).toBeFunction() }) it('should throw an exception', async () => { - await expect(connectionInterface.buildWallets()).rejects.toThrowError('Method [buildWallets] not implemented!') + await expect(connectionInterface.saveWallets()).rejects.toThrowError( + 'Method [saveWallets] not implemented!', + ) }) }) - describe('saveWallets', () => { + describe('saveBlock', () => { it('should be a function', () => { - expect(connectionInterface.saveWallets).toBeFunction() + expect(connectionInterface.saveBlock).toBeFunction() }) it('should throw an exception', async () => { - await expect(connectionInterface.saveWallets()).rejects.toThrowError('Method [saveWallets] not implemented!') + await expect(connectionInterface.saveBlock()).rejects.toThrowError( + 'Method [saveBlock] not implemented!', + ) }) }) - describe('saveBlock', () => { + describe('enqueueSaveBlock', () => { it('should be a function', () => { - expect(connectionInterface.saveBlock).toBeFunction() + expect(connectionInterface.enqueueSaveBlock).toBeFunction() }) it('should throw an exception', async () => { - await expect(connectionInterface.saveBlock()).rejects.toThrowError('Method [saveBlock] not implemented!') + expect(connectionInterface.enqueueSaveBlock).toThrow( + 'Method [enqueueSaveBlock] not implemented!', + ) }) }) - describe('saveBlockAsync', () => { + describe('enqueueDeleteBlock', () => { it('should be a function', () => { - expect(connectionInterface.saveBlockAsync).toBeFunction() + expect(connectionInterface.enqueueDeleteBlock).toBeFunction() }) it('should throw an exception', async () => { - await expect(connectionInterface.saveBlockAsync()).rejects.toThrowError('Method [saveBlockAsync] not implemented!') + expect(connectionInterface.enqueueDeleteBlock).toThrow( + 'Method [enqueueDeleteBlock] not implemented!', + ) }) }) - describe('saveBlockCommit', () => { + describe('enqueueDeleteRound', () => { it('should be a function', () => { - expect(connectionInterface.saveBlockCommit).toBeFunction() + expect(connectionInterface.enqueueDeleteRound).toBeFunction() }) it('should throw an exception', async () => { - await expect(connectionInterface.saveBlockCommit()).rejects.toThrowError('Method [saveBlockCommit] not implemented!') + expect(connectionInterface.enqueueDeleteRound).toThrow( + 'Method [enqueueDeleteRound] not implemented!', + ) + }) + }) + + describe('commitQueuedQueries', () => { + it('should be a function', () => { + expect(connectionInterface.commitQueuedQueries).toBeFunction() + }) + + it('should throw an exception', async () => { + await expect( + connectionInterface.commitQueuedQueries(), + ).rejects.toThrowError('Method [commitQueuedQueries] not implemented!') }) }) @@ -133,7 +171,9 @@ describe('Connection Interface', () => { }) it('should throw an exception', async () => { - await expect(connectionInterface.deleteBlock()).rejects.toThrowError('Method [deleteBlock] not implemented!') + await expect(connectionInterface.deleteBlock()).rejects.toThrowError( + 'Method [deleteBlock] not implemented!', + ) }) }) @@ -143,7 +183,9 @@ describe('Connection Interface', () => { }) it('should throw an exception', async () => { - await expect(connectionInterface.getBlock()).rejects.toThrowError('Method [getBlock] not implemented!') + await expect(connectionInterface.getBlock()).rejects.toThrowError( + 'Method [getBlock] not implemented!', + ) }) }) @@ -153,7 +195,9 @@ describe('Connection Interface', () => { }) it('should throw an exception', async () => { - await expect(connectionInterface.getLastBlock()).rejects.toThrowError('Method [getLastBlock] not implemented!') + await expect(connectionInterface.getLastBlock()).rejects.toThrowError( + 'Method [getLastBlock] not implemented!', + ) }) }) @@ -163,7 +207,9 @@ describe('Connection Interface', () => { }) it('should throw an exception', async () => { - await expect(connectionInterface.getBlocks()).rejects.toThrowError('Method [getBlocks] not implemented!') + await expect(connectionInterface.getBlocks()).rejects.toThrowError( + 'Method [getBlocks] not implemented!', + ) }) }) @@ -173,15 +219,9 @@ describe('Connection Interface', () => { }) it('should throw an exception', async () => { - await expect(connectionInterface.getRecentBlockIds()).rejects.toThrowError('Method [getRecentBlockIds] not implemented!') - }) - - xit('should return an array', async () => { - connectionInterface.recentBlockIds = ['10'] - const blockIds = await connectionInterface.getRecentBlockIds() - - expect(blockIds).toBeArray() - expect(blockIds).toIncludeAllMembers(['10']) + await expect( + connectionInterface.getRecentBlockIds(), + ).rejects.toThrowError('Method [getRecentBlockIds] not implemented!') }) }) @@ -191,7 +231,9 @@ describe('Connection Interface', () => { }) it('should throw an exception', async () => { - await expect(() => connectionInterface.saveRound()).toThrowError('Method [saveRound] not implemented!') + await expect(connectionInterface.saveRound()).rejects.toThrowError( + 'Method [saveRound] not implemented!', + ) }) }) @@ -201,7 +243,9 @@ describe('Connection Interface', () => { }) it('should throw an exception', async () => { - await expect(() => connectionInterface.deleteRound()).toThrowError('Method [deleteRound] not implemented!') + await expect(connectionInterface.deleteRound()).rejects.toThrowError( + 'Method [deleteRound] not implemented!', + ) }) }) @@ -253,21 +297,120 @@ describe('Connection Interface', () => { }) }) - describe.skip('applyTransaction', () => { - it('should be a function', () => { - expect(connectionInterface.applyTransaction).toBeFunction() - }) - }) - - describe.skip('revertTransaction', () => { - it('should be a function', () => { - expect(connectionInterface.revertTransaction).toBeFunction() - }) - }) - - describe.skip('snapshot', () => { + describe('__calcPreviousActiveDelegates', () => { it('should be a function', () => { - expect(connectionInterface.snapshot).toBeFunction() + expect(connectionInterface.__calcPreviousActiveDelegates).toBeFunction() + }) + + it('should calculate the previous delegate list', async () => { + const walletManager = new (require('../lib/wallet-manager'))() + const initialHeight = 52 + + // Create delegates + for (const transaction of genesisBlock.transactions) { + if (transaction.type === TRANSACTION_TYPES.DELEGATE_REGISTRATION) { + const wallet = walletManager.findByPublicKey( + transaction.senderPublicKey, + ) + wallet.username = Transaction.deserialize( + transaction.serialized.toString('hex'), + ).asset.delegate.username + walletManager.reindex(wallet) + } + } + + const keys = { + passphrase: 'this is a secret passphrase', + publicKey: + '02c71ab1a1b5b7c278145382eb0b535249483b3c4715a4fe6169d40388bbb09fa7', + privateKey: + 'dcf4ead2355090279aefba91540f32e93b15c541ecb48ca73071f161b4f3e2e3', + address: 'D64cbDctaiADEH7NREnvRQGV27bnb1v2kE', + } + + // Beginning of round 2 with all delegates 0 vote balance. + const delegatesRound2 = walletManager.loadActiveDelegateList( + 51, + initialHeight, + ) + + // Prepare sender wallet + const sender = new Wallet(keys.address) + sender.publicKey = keys.publicKey + sender.canApply = jest.fn(() => true) + walletManager.reindex(sender) + + // Apply 51 blocks, where each increases the vote balance of a delegate to + // reverse the current delegate order. + const blocksInRound = [] + for (let i = 0; i < 51; i++) { + const transfer = transactionBuilder + .transfer() + .amount(i * ARKTOSHI) + .recipientId(delegatesRound2[i].address) + .sign(keys.passphrase) + .build() + + // Vote for itself + walletManager.byPublicKey[delegatesRound2[i].publicKey].vote = + delegatesRound2[i].publicKey + + const block = Block.create( + { + version: 0, + timestamp: 0, + height: initialHeight + i, + numberOfTransactions: 0, + totalAmount: transfer.amount, + totalFee: new Bignum(0.1), + reward: new Bignum(2), + payloadLength: 32 * 0, + payloadHash: '', + transactions: [transfer], + }, + keys, + ) + + block.data.generatorPublicKey = keys.publicKey + walletManager.applyBlock(block) + + blocksInRound.push(block) + } + + // The delegates from round 2 are now reversed in rank in round 3. + const delegatesRound3 = walletManager.loadActiveDelegateList( + 51, + initialHeight + 51, + ) + for (let i = 0; i < delegatesRound3.length; i++) { + expect(delegatesRound3[i].rate).toBe(i + 1) + expect(delegatesRound3[i].publicKey).toBe( + delegatesRound2[delegatesRound3.length - i - 1].publicKey, + ) + } + + const connection = new ConnectionInterface() + connection.__getBlocksForRound = jest.fn(async () => blocksInRound) + connection.walletManager = walletManager + + // Necessary for revertRound to not blow up. + walletManager.allByUsername = jest.fn(() => { + const usernames = Object.values(walletManager.byUsername) + usernames.push(sender) + return usernames + }) + + // Finally recalculate the round 2 list and compare against the original list + const restoredDelegatesRound2 = await connection.__calcPreviousActiveDelegates( + 2, + ) + + for (let i = 0; i < restoredDelegatesRound2.length; i++) { + expect(restoredDelegatesRound2[i].rate).toBe(i + 1) + expect(restoredDelegatesRound2[i].publicKey).toBe( + delegatesRound2[i].publicKey, + ) + } }) }) @@ -297,10 +440,14 @@ describe('Connection Interface', () => { connectionInterface._registerRepositories() await expect(connectionInterface).toHaveProperty('wallets') - await expect(connectionInterface.wallets).toBeInstanceOf(require('../lib/repositories/wallets')) + await expect(connectionInterface.wallets).toBeInstanceOf( + require('../lib/repositories/wallets'), + ) await expect(connectionInterface).toHaveProperty('delegates') - await expect(connectionInterface.delegates).toBeInstanceOf(require('../lib/repositories/delegates')) + await expect(connectionInterface.delegates).toBeInstanceOf( + require('../lib/repositories/delegates'), + ) }) }) }) diff --git a/packages/core-database/__tests__/repositories/delegates.test.js b/packages/core-database/__tests__/repositories/delegates.test.js index 8d513cbbfa..a6511dff96 100644 --- a/packages/core-database/__tests__/repositories/delegates.test.js +++ b/packages/core-database/__tests__/repositories/delegates.test.js @@ -1,42 +1,44 @@ -'use strict' - +const { + Bignum, + crypto, + constants: { ARKTOSHI }, +} = require('@arkecosystem/crypto') +const { Block } = require('@arkecosystem/crypto').models +const { delegateCalculator } = require('@arkecosystem/core-utils') const app = require('../__support__/setup') -const { crypto } = require('@arkecosystem/crypto') let genesisBlock let repository let walletManager -let calculateApproval -let calculateProductivity -beforeAll(async (done) => { +beforeAll(async done => { await app.setUp() // Create the genesis block after the setup has finished or else it uses a potentially // wrong network config. - genesisBlock = require('../__fixtures__/genesisBlock') - - const delegateCalculator = require('../../lib/repositories/utils/delegate-calculator') - calculateApproval = delegateCalculator.calculateApproval - calculateProductivity = delegateCalculator.calculateProductivity + genesisBlock = new Block( + require('@arkecosystem/core-test-utils/config/testnet/genesisBlock.json'), + ) done() }) -afterAll(async (done) => { +afterAll(async done => { await app.tearDown() done() }) -beforeEach(async (done) => { +beforeEach(async done => { walletManager = new (require('../../lib/wallet-manager'))() - repository = new (require('../../lib/repositories/delegates'))({ walletManager }) + repository = new (require('../../lib/repositories/delegates'))({ + walletManager, + }) done() }) -function generateWallets () { +function generateWallets() { return genesisBlock.transactions.map(transaction => { const address = crypto.getAddress(transaction.senderPublicKey) @@ -46,8 +48,8 @@ function generateWallets () { secondPublicKey: `secondPublicKey-${address}`, vote: `vote-${address}`, username: `username-${address}`, - balance: 100, - votebalance: 200 + balance: new Bignum(100), + voteBalance: new Bignum(200), } }) } @@ -61,7 +63,7 @@ describe('Delegate Repository', () => { const delegates = [ { username: 'delegate-0' }, { username: 'delegate-1' }, - { username: 'delegate-2' } + { username: 'delegate-2' }, ] const wallets = [ delegates[0], @@ -69,7 +71,7 @@ describe('Delegate Repository', () => { delegates[1], { username: '' }, delegates[2], - {} + {}, ] it('should be a function', () => { @@ -77,10 +79,12 @@ describe('Delegate Repository', () => { }) it('should return the local wallets of the connection that are delegates', () => { - repository.connection.walletManager.getLocalWallets = jest.fn(() => wallets) + repository.connection.walletManager.all = jest.fn(() => wallets) - expect(repository.getLocalDelegates()).toEqual(expect.arrayContaining(delegates)) - expect(repository.connection.walletManager.getLocalWallets).toHaveBeenCalled() + expect(repository.getLocalDelegates()).toEqual( + expect.arrayContaining(delegates), + ) + expect(repository.connection.walletManager.all).toHaveBeenCalled() }) }) @@ -195,7 +199,9 @@ describe('Delegate Repository', () => { const wallets = generateWallets() walletManager.index(wallets) - const { count, rows } = repository.search({ username: 'username-APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' }) + const { count, rows } = repository.search({ + username: 'username-APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn', + }) expect(count).toBe(1) expect(rows).toHaveLength(1) @@ -213,7 +219,9 @@ describe('Delegate Repository', () => { describe('when no results', () => { it('should be ok', () => { - const { count, rows } = repository.search({ username: 'unknown-dummy-username' }) + const { count, rows } = repository.search({ + username: 'unknown-dummy-username', + }) expect(count).toBe(0) expect(rows).toHaveLength(0) @@ -224,7 +232,11 @@ describe('Delegate Repository', () => { const wallets = generateWallets() walletManager.index(wallets) - const { count, rows } = repository.search({ username: 'username', offset: 10, limit: 10 }) + const { count, rows } = repository.search({ + username: 'username', + offset: 10, + limit: 10, + }) expect(count).toBe(52) expect(rows).toHaveLength(10) }) @@ -233,7 +245,10 @@ describe('Delegate Repository', () => { const wallets = generateWallets() walletManager.index(wallets) - const { count, rows } = repository.search({ username: 'username', limit: 10 }) + const { count, rows } = repository.search({ + username: 'username', + limit: 10, + }) expect(count).toBe(52) expect(rows).toHaveLength(10) }) @@ -242,7 +257,11 @@ describe('Delegate Repository', () => { const wallets = generateWallets() walletManager.index(wallets) - const { count, rows } = repository.search({ username: 'username', offset: 0, limit: 12 }) + const { count, rows } = repository.search({ + username: 'username', + offset: 0, + limit: 12, + }) expect(count).toBe(52) expect(rows).toHaveLength(12) }) @@ -251,14 +270,17 @@ describe('Delegate Repository', () => { const wallets = generateWallets() walletManager.index(wallets) - const { count, rows } = repository.search({ username: 'username', offset: 10 }) + const { count, rows } = repository.search({ + username: 'username', + offset: 10, + }) expect(count).toBe(52) expect(rows).toHaveLength(42) }) }) describe('findById', () => { - const expectWallet = (key) => { + const expectWallet = key => { const wallets = generateWallets() walletManager.index(wallets) @@ -298,25 +320,29 @@ describe('Delegate Repository', () => { const delegate = { username: 'test', publicKey: 'test', - balance: 10000 * Math.pow(10, 8), + voteBalance: new Bignum(10000 * ARKTOSHI), producedBlocks: 1000, - missedBlocks: 500 + missedBlocks: 500, } const height = 1 repository.connection.getActiveDelegates = jest.fn(() => [delegate]) repository.connection.wallets = { - findById: jest.fn(() => delegate) + findById: jest.fn(() => delegate), } const results = repository.getActiveAtHeight(height) expect(results).toBeArray() expect(results[0].username).toBeString() - expect(results[0].approval).toBeNumber() // 0.18 - expect(results[0].productivity).toBeNumber() // 98.97 - expect(results[0].approval).toBe(calculateApproval(delegate, height)) - expect(results[0].productivity).toBe(calculateProductivity(delegate)) + expect(results[0].approval).toBeNumber() + expect(results[0].productivity).toBeNumber() + expect(results[0].approval).toBe( + delegateCalculator.calculateApproval(delegate, height), + ) + expect(results[0].productivity).toBe( + delegateCalculator.calculateProductivity(delegate), + ) }) }) }) diff --git a/packages/core-database/__tests__/repositories/utils/delegate-calculator.test.js b/packages/core-database/__tests__/repositories/utils/delegate-calculator.test.js deleted file mode 100644 index 02a3eaa1fe..0000000000 --- a/packages/core-database/__tests__/repositories/utils/delegate-calculator.test.js +++ /dev/null @@ -1,47 +0,0 @@ -'use strict' - -const app = require('../../__support__/setup') - -let calculatorModule - -beforeAll(async (done) => { - await app.setUp() - - calculatorModule = require('../../../lib/repositories/utils/delegate-calculator') - - done() -}) - -afterAll(async (done) => { - await app.tearDown() - - done() -}) - -const delegate = { - balance: 10000000 * Math.pow(10, 8), - producedBlocks: 100, - missedBlocks: 10 -} - -describe('Delegate Calculator', () => { - describe('calculateApproval', () => { - it('should be a function', () => { - expect(calculatorModule.calculateApproval).toBeFunction() - }) - - it('should calculate the approval', () => { - expect(calculatorModule.calculateApproval(delegate, 1)).toBe(8) - }) - }) - - describe('calculateProductivity', () => { - it('should be a function', () => { - expect(calculatorModule.calculateProductivity).toBeFunction() - }) - - it('should calculate the productivity', () => { - expect(calculatorModule.calculateProductivity(delegate)).toBe(90.91) - }) - }) -}) diff --git a/packages/core-database/__tests__/repositories/utils/filter-rows.test.js b/packages/core-database/__tests__/repositories/utils/filter-rows.test.js index 39de7c937b..ad92e0f46a 100644 --- a/packages/core-database/__tests__/repositories/utils/filter-rows.test.js +++ b/packages/core-database/__tests__/repositories/utils/filter-rows.test.js @@ -1,10 +1,8 @@ -'use strict' - const app = require('../../__support__/setup') let filterRows -beforeAll(async (done) => { +beforeAll(async done => { await app.setUp() filterRows = require('../../../lib/repositories/utils/filter-rows') @@ -12,7 +10,7 @@ beforeAll(async (done) => { done() }) -afterAll(async (done) => { +afterAll(async done => { await app.tearDown() done() @@ -21,27 +19,31 @@ afterAll(async (done) => { describe('Filter Rows', () => { const rows = [ { a: 1, b: 2, c: [] }, - { a: 2, b: 2, c: ['dummy-1'], d: ['dummy-0'] }, + { + a: 2, b: 2, c: ['dummy-1'], d: ['dummy-0'], + }, { a: 3, b: 3, c: ['dummy-3', 'dummy-1', 'dummy-4'] }, - { a: 2, b: 4, c: ['dummy-2'], d: 'dummy-0' }, - { a: 3, b: 4, c: ['DUMMY-1'] } + { + a: 2, b: 4, c: ['dummy-2'], d: 'dummy-0', + }, + { a: 3, b: 4, c: ['DUMMY-1'] }, ] describe('exact', () => { it('match objects with the same value than the parameter', () => { expect(filterRows(rows, { a: 1 }, { exact: ['a'] })).toEqual([ - { a: 1, b: 2, c: [] } + { a: 1, b: 2, c: [] }, ]) expect(filterRows(rows, { a: 3 }, { exact: ['a'] })).toEqual([ { a: 3, b: 3, c: ['dummy-3', 'dummy-1', 'dummy-4'] }, - { a: 3, b: 4, c: ['DUMMY-1'] } + { a: 3, b: 4, c: ['DUMMY-1'] }, ]) expect(filterRows(rows, { a: 3, b: 3 }, { exact: ['a'] })).toEqual([ { a: 3, b: 3, c: ['dummy-3', 'dummy-1', 'dummy-4'] }, - { a: 3, b: 4, c: ['DUMMY-1'] } + { a: 3, b: 4, c: ['DUMMY-1'] }, ]) expect(filterRows(rows, { a: 3, b: 3 }, { exact: ['a', 'b'] })).toEqual([ - { a: 3, b: 3, c: ['dummy-3', 'dummy-1', 'dummy-4'] } + { a: 3, b: 3, c: ['dummy-3', 'dummy-1', 'dummy-4'] }, ]) }) }) @@ -50,21 +52,35 @@ describe('Filter Rows', () => { it('match objects that include a value beween two parameters (included)', () => { expect(filterRows(rows, { a: { from: 3 } }, { between: ['a'] })).toEqual([ { a: 3, b: 3, c: ['dummy-3', 'dummy-1', 'dummy-4'] }, - { a: 3, b: 4, c: ['DUMMY-1'] } + { a: 3, b: 4, c: ['DUMMY-1'] }, ]) - expect(filterRows(rows, { a: { from: 2, to: 2 } }, { between: ['a'] })).toEqual([ - { a: 2, b: 2, c: ['dummy-1'], d: ['dummy-0'] }, - { a: 2, b: 4, c: ['dummy-2'], d: 'dummy-0' } + expect( + filterRows(rows, { a: { from: 2, to: 2 } }, { between: ['a'] }), + ).toEqual([ + { + a: 2, b: 2, c: ['dummy-1'], d: ['dummy-0'], + }, + { + a: 2, b: 4, c: ['dummy-2'], d: 'dummy-0', + }, ]) expect(filterRows(rows, { a: { to: 2 } }, { between: ['a'] })).toEqual([ { a: 1, b: 2, c: [] }, - { a: 2, b: 2, c: ['dummy-1'], d: ['dummy-0'] }, - { a: 2, b: 4, c: ['dummy-2'], d: 'dummy-0' } + { + a: 2, b: 2, c: ['dummy-1'], d: ['dummy-0'], + }, + { + a: 2, b: 4, c: ['dummy-2'], d: 'dummy-0', + }, ]) - expect(filterRows(rows, { b: { from: 3, to: 4 } }, { between: ['b'] })).toEqual([ + expect( + filterRows(rows, { b: { from: 3, to: 4 } }, { between: ['b'] }), + ).toEqual([ { a: 3, b: 3, c: ['dummy-3', 'dummy-1', 'dummy-4'] }, - { a: 2, b: 4, c: ['dummy-2'], d: 'dummy-0' }, - { a: 3, b: 4, c: ['DUMMY-1'] } + { + a: 2, b: 4, c: ['dummy-2'], d: 'dummy-0', + }, + { a: 3, b: 4, c: ['DUMMY-1'] }, ]) }) }) @@ -73,16 +89,30 @@ describe('Filter Rows', () => { describe('any', () => { it('match objects that include some values of the parameters', () => { expect(filterRows(rows, { c: ['dummy-1'] }, { any: ['c'] })).toEqual([ - { a: 2, b: 2, c: ['dummy-1'], d: ['dummy-0'] }, - { a: 3, b: 3, c: ['dummy-3', 'dummy-1', 'dummy-4'] } + { + a: 2, b: 2, c: ['dummy-1'], d: ['dummy-0'], + }, + { a: 3, b: 3, c: ['dummy-3', 'dummy-1', 'dummy-4'] }, ]) - expect(filterRows(rows, { c: ['dummy-1'], d: ['dummy-0'] }, { any: ['c'] })).toEqual([ - { a: 2, b: 2, c: ['dummy-1'], d: ['dummy-0'] }, - { a: 3, b: 3, c: ['dummy-3', 'dummy-1', 'dummy-4'] } + expect( + filterRows(rows, { c: ['dummy-1'], d: ['dummy-0'] }, { any: ['c'] }), + ).toEqual([ + { + a: 2, b: 2, c: ['dummy-1'], d: ['dummy-0'], + }, + { a: 3, b: 3, c: ['dummy-3', 'dummy-1', 'dummy-4'] }, ]) - expect(filterRows(rows, { c: ['dummy-1'], d: ['dummy-0'] }, { any: ['c', 'd'] })).toEqual([ - { a: 2, b: 2, c: ['dummy-1'], d: ['dummy-0'] }, - { a: 3, b: 3, c: ['dummy-3', 'dummy-1', 'dummy-4'] } + expect( + filterRows( + rows, + { c: ['dummy-1'], d: ['dummy-0'] }, + { any: ['c', 'd'] }, + ), + ).toEqual([ + { + a: 2, b: 2, c: ['dummy-1'], d: ['dummy-0'], + }, + { a: 3, b: 3, c: ['dummy-3', 'dummy-1', 'dummy-4'] }, ]) }) }) diff --git a/packages/core-database/__tests__/repositories/wallets.test.js b/packages/core-database/__tests__/repositories/wallets.test.js index 5350ce3dc2..fef65f64aa 100644 --- a/packages/core-database/__tests__/repositories/wallets.test.js +++ b/packages/core-database/__tests__/repositories/wallets.test.js @@ -1,52 +1,58 @@ -'use strict' - -const _ = require('lodash') +const uniq = require('lodash/uniq') +const compact = require('lodash/compact') +const { Bignum, crypto } = require('@arkecosystem/crypto') +const { Block } = require('@arkecosystem/crypto').models const app = require('../__support__/setup') -const { crypto } = require('@arkecosystem/crypto') let genesisBlock let genesisSenders let repository let walletManager -beforeAll(async (done) => { +beforeAll(async done => { await app.setUp() // Create the genesis block after the setup has finished or else it uses a potentially // wrong network config. - genesisBlock = require('../__fixtures__/genesisBlock') - genesisSenders = _.uniq(_.compact(genesisBlock.transactions.map(tx => tx.senderPublicKey))) + genesisBlock = new Block( + require('@arkecosystem/core-test-utils/config/testnet/genesisBlock.json'), + ) + genesisSenders = uniq( + compact(genesisBlock.transactions.map(tx => tx.senderPublicKey)), + ) done() }) -afterAll(async (done) => { +afterAll(async done => { await app.tearDown() done() }) -beforeEach(async (done) => { +beforeEach(async done => { walletManager = new (require('../../lib/wallet-manager'))() - repository = new (require('../../lib/repositories/wallets'))({ walletManager }) + repository = new (require('../../lib/repositories/wallets'))({ + walletManager, + }) done() }) -function generateWallets () { +function generateWallets() { return genesisSenders.map(senderPublicKey => ({ - address: crypto.getAddress(senderPublicKey) + address: crypto.getAddress(senderPublicKey), })) } -function generateVotes () { +function generateVotes() { return genesisSenders.map(senderPublicKey => ({ address: crypto.getAddress(senderPublicKey), - vote: genesisBlock.transactions[0].senderPublicKey + vote: genesisBlock.transactions[0].senderPublicKey, })) } -function generateFullWallets () { +function generateFullWallets() { return genesisSenders.map(senderPublicKey => { const address = crypto.getAddress(senderPublicKey) @@ -57,7 +63,7 @@ function generateFullWallets () { vote: `vote-${address}`, username: `username-${address}`, balance: 100, - votebalance: 200 + voteBalance: 200, } }) } @@ -67,15 +73,15 @@ describe('Wallet Repository', () => { expect(repository).toBeObject() }) - describe('getLocalWallets', () => { + describe('all', () => { it('should be a function', () => { - expect(repository.getLocalWallets).toBeFunction() + expect(repository.all).toBeFunction() }) it('should return the local wallets of the connection', () => { - repository.connection.walletManager.getLocalWallets = jest.fn() - repository.getLocalWallets() - expect(repository.connection.walletManager.getLocalWallets).toHaveBeenCalled() + repository.connection.walletManager.all = jest.fn() + repository.all() + expect(repository.connection.walletManager.all).toHaveBeenCalled() }) }) @@ -154,7 +160,10 @@ describe('Wallet Repository', () => { }) it('should be ok with params', () => { - const { count, rows } = repository.findAllByVote(vote, { offset: 10, limit: 10 }) + const { count, rows } = repository.findAllByVote(vote, { + offset: 10, + limit: 10, + }) expect(count).toBe(17) expect(rows).toHaveLength(7) }) @@ -166,7 +175,10 @@ describe('Wallet Repository', () => { }) it('should be ok with params (offset = 0)', () => { - const { count, rows } = repository.findAllByVote(vote, { offset: 0, limit: 1 }) + const { count, rows } = repository.findAllByVote(vote, { + offset: 0, + limit: 1, + }) expect(count).toBe(17) expect(rows).toHaveLength(1) }) @@ -178,8 +190,8 @@ describe('Wallet Repository', () => { }) }) - describe('findById', async () => { - const expectWallet = (key) => { + describe('findById', () => { + const expectWallet = key => { const wallets = generateFullWallets() walletManager.index(wallets) @@ -222,9 +234,9 @@ describe('Wallet Repository', () => { describe('top', () => { beforeEach(() => { - walletManager.reindex({ address: 'dummy-1', balance: 1000 }) - walletManager.reindex({ address: 'dummy-2', balance: 2000 }) - walletManager.reindex({ address: 'dummy-3', balance: 3000 }) + walletManager.reindex({ address: 'dummy-1', balance: new Bignum(1000) }) + walletManager.reindex({ address: 'dummy-2', balance: new Bignum(2000) }) + walletManager.reindex({ address: 'dummy-3', balance: new Bignum(3000) }) }) it('should be a function', () => { @@ -236,9 +248,9 @@ describe('Wallet Repository', () => { expect(count).toBe(3) expect(rows.length).toBe(3) - expect(rows[0].balance).toBe(3000) - expect(rows[1].balance).toBe(2000) - expect(rows[2].balance).toBe(1000) + expect(rows[0].balance).toEqual(new Bignum(3000)) + expect(rows[1].balance).toEqual(new Bignum(2000)) + expect(rows[2].balance).toEqual(new Bignum(1000)) }) it('should be ok with params', () => { @@ -246,8 +258,8 @@ describe('Wallet Repository', () => { expect(count).toBe(3) expect(rows.length).toBe(2) - expect(rows[0].balance).toBe(2000) - expect(rows[1].balance).toBe(1000) + expect(rows[0].balance).toEqual(new Bignum(2000)) + expect(rows[1].balance).toEqual(new Bignum(1000)) }) it('should be ok with params (offset = 0)', () => { @@ -255,8 +267,8 @@ describe('Wallet Repository', () => { expect(count).toBe(3) expect(rows.length).toBe(2) - expect(rows[0].balance).toBe(3000) - expect(rows[1].balance).toBe(2000) + expect(rows[0].balance).toEqual(new Bignum(3000)) + expect(rows[1].balance).toEqual(new Bignum(2000)) }) it('should be ok with params (no offset)', () => { @@ -264,8 +276,8 @@ describe('Wallet Repository', () => { expect(count).toBe(3) expect(rows.length).toBe(2) - expect(rows[0].balance).toBe(3000) - expect(rows[1].balance).toBe(2000) + expect(rows[0].balance).toEqual(new Bignum(3000)) + expect(rows[1].balance).toEqual(new Bignum(2000)) }) it('should be ok with params (no limit)', () => { @@ -273,8 +285,8 @@ describe('Wallet Repository', () => { expect(count).toBe(3) expect(rows.length).toBe(2) - expect(rows[0].balance).toBe(2000) - expect(rows[1].balance).toBe(1000) + expect(rows[0].balance).toEqual(new Bignum(2000)) + expect(rows[1].balance).toEqual(new Bignum(1000)) }) it('should be ok with legacy', () => { @@ -282,13 +294,13 @@ describe('Wallet Repository', () => { expect(count).toBe(3) expect(rows.length).toBe(3) - expect(rows[0].balance).toBe(3000) - expect(rows[1].balance).toBe(2000) - expect(rows[2].balance).toBe(1000) + expect(rows[0].balance).toEqual(new Bignum(3000)) + expect(rows[1].balance).toEqual(new Bignum(2000)) + expect(rows[2].balance).toEqual(new Bignum(1000)) }) }) - describe('search', async () => { + describe('search', () => { const expectSearch = (params, rows = 1, count = 1) => { const wallets = repository.search(params) expect(wallets).toBeObject() @@ -354,31 +366,39 @@ describe('Wallet Repository', () => { }) walletManager.index(wallets) - expectSearch({ - balance: { - from: 53, - to: 99 - } - }, 36, 36) + expectSearch( + { + balance: { + from: 53, + to: 99, + }, + }, + 36, + 36, + ) }) - it('should search wallets by the specified closed interval (included) of votebalance', () => { + it('should search wallets by the specified closed interval (included) of voteBalance', () => { const wallets = generateFullWallets() wallets.forEach((wallet, i) => { if (i < 17) { - wallet.votebalance = 12 + wallet.voteBalance = 12 } else if (i < 29) { - wallet.votebalance = 17 + wallet.voteBalance = 17 } }) walletManager.index(wallets) - expectSearch({ - votebalance: { - from: 11, - to: 18 - } - }, 29, 29) + expectSearch( + { + voteBalance: { + from: 11, + to: 18, + }, + }, + 29, + 29, + ) }) }) }) diff --git a/packages/core-database/__tests__/wallet-manager.test.js b/packages/core-database/__tests__/wallet-manager.test.js index 5bd0e938d5..b033e223ed 100644 --- a/packages/core-database/__tests__/wallet-manager.test.js +++ b/packages/core-database/__tests__/wallet-manager.test.js @@ -1,25 +1,34 @@ -'use strict' - -const app = require('./__support__/setup') +/* eslint max-len: "off" */ const { Block, Transaction, Wallet } = require('@arkecosystem/crypto').models -const { transactionBuilder } = require('@arkecosystem/crypto') -const { TRANSACTION_TYPES } = require('@arkecosystem/crypto').constants +const { Bignum, crypto, transactionBuilder } = require('@arkecosystem/crypto') +const { + ARKTOSHI, + TRANSACTION_TYPES, +} = require('@arkecosystem/crypto').constants + +const genTransfer = require('@arkecosystem/core-test-utils/lib/generators/transactions/transfer') +const genDelegateReg = require('@arkecosystem/core-test-utils/lib/generators/transactions/delegate') +const gen2ndSignature = require('@arkecosystem/core-test-utils/lib/generators/transactions/signature') +const genvote = require('@arkecosystem/core-test-utils/lib/generators/transactions/vote') +const block3 = require('@arkecosystem/core-test-utils/fixtures/testnet/blocks.2-100')[1] +const app = require('./__support__/setup') -const block = new Block(require('./__fixtures__/block.json')) // eslint-disable-line no-unused-vars +const block = new Block(block3) const walletData1 = require('./__fixtures__/wallets.json')[0] const walletData2 = require('./__fixtures__/wallets.json')[1] -const walletDataFake = require('./__fixtures__/wallets.json')[2] let genesisBlock // eslint-disable-line no-unused-vars let walletManager -beforeAll(async (done) => { +beforeAll(async done => { await app.setUp() // Create the genesis block after the setup has finished or else it uses a potentially // wrong network config. - genesisBlock = require('./__fixtures__/genesisBlock') + genesisBlock = new Block( + require('@arkecosystem/core-test-utils/config/testnet/genesisBlock.json'), + ) walletManager = new (require('../lib/wallet-manager'))() @@ -30,7 +39,7 @@ beforeEach(() => { walletManager = new (require('../lib/wallet-manager'))() }) -afterAll(async (done) => { +afterAll(async done => { await app.tearDown() done() @@ -50,10 +59,10 @@ describe('Wallet Manager', () => { const wallet = new Wallet(walletData1.address) walletManager.reindex(wallet) - expect(walletManager.getLocalWallets()).toEqual([wallet]) + expect(walletManager.all()).toEqual([wallet]) walletManager.reset() - expect(walletManager.getLocalWallets()).toEqual([]) + expect(walletManager.all()).toEqual([]) }) }) @@ -65,10 +74,10 @@ describe('Wallet Manager', () => { it('should index the wallets', () => { const wallet = new Wallet(walletData1.address) - expect(walletManager.getLocalWallets()).toEqual([]) + expect(walletManager.all()).toEqual([]) walletManager.reindex(wallet) - expect(walletManager.getLocalWallets()).toEqual([wallet]) + expect(walletManager.all()).toEqual([wallet]) }) }) @@ -76,7 +85,7 @@ describe('Wallet Manager', () => { let delegateMock let block2 - const delegatePublicKey = '036a520acf24036ff691a4f8ba19514828e9b5aa36ca4ba0452e9012023caccfef' + const delegatePublicKey = block3.generatorPublicKey // '0299deebff24ebf2bb53ad78f3ea3ada5b3c8819132e191b02c263ee4aa4af3d9b' const txs = [] for (let i = 0; i < 3; i++) { @@ -89,7 +98,7 @@ describe('Wallet Manager', () => { beforeEach(() => { delegateMock = { applyBlock: jest.fn(), publicKey: delegatePublicKey } - walletManager.getWalletByPublicKey = jest.fn(() => delegateMock) + walletManager.findByPublicKey = jest.fn(() => delegateMock) walletManager.applyTransaction = jest.fn() walletManager.revertTransaction = jest.fn() @@ -111,7 +120,9 @@ describe('Wallet Manager', () => { await walletManager.applyBlock(block2) block2.transactions.forEach((transaction, i) => { - expect(walletManager.applyTransaction.mock.calls[i][0]).toBe(block2.transactions[i]) + expect(walletManager.applyTransaction.mock.calls[i][0]).toBe( + block2.transactions[i], + ) }) }) @@ -138,7 +149,9 @@ describe('Wallet Manager', () => { } catch (_error) { expect(walletManager.revertTransaction).toHaveBeenCalledTimes(2) block2.transactions.slice(0, 1).forEach((transaction, i) => { - expect(walletManager.revertTransaction.mock.calls[1 - i][0]).toEqual(block2.transactions[i]) + expect( + walletManager.revertTransaction.mock.calls[1 - i][0], + ).toEqual(block2.transactions[i]) }) } }) @@ -149,7 +162,7 @@ describe('Wallet Manager', () => { }) try { - await walletManager.applyBlock(block) + await walletManager.applyBlock(block2) expect(null).toBe('this should fail if no error is thrown') } catch (error) { @@ -159,17 +172,13 @@ describe('Wallet Manager', () => { }) }) - xdescribe('the delegate of the block is not indexed', () => { + describe.skip('the delegate of the block is not indexed', () => { describe('not genesis block', () => { - it('throw an Error', () => { - - }) + it('throw an Error', () => {}) }) describe('genesis block', () => { - it('generates a new wallet', () => { - - }) + it('generates a new wallet', () => {}) }) }) }) @@ -179,12 +188,9 @@ describe('Wallet Manager', () => { expect(walletManager.revertBlock).toBeFunction() }) - it('should revert all transactions of the block', () => { - }) - - it('should revert the block of the delegate', () => { + it('should revert all transactions of the block', () => {}) - }) + it('should revert the block of the delegate', () => {}) }) describe('applyTransaction', () => { @@ -192,73 +198,92 @@ describe('Wallet Manager', () => { expect(walletManager.applyTransaction).toBeFunction() }) - describe('when the recipient is a cold wallet', () => { - }) - - describe('when the transaction is a transfer', () => { - const amount = 96579 - - let sender - let recipient - let transaction - - beforeEach(() => { - sender = new Wallet(walletData1.address) - recipient = new Wallet(walletData2.address) - recipient.publicKey = walletData2.publicKey - - // NOTE: the order is important: we sign a transaction with a random pass - // to override the sender public key with a fake one - - transaction = transactionBuilder - .transfer() - .vendorField('dummy A transfer to dummy B') - .sign(Math.random().toString(36)) - .recipientId(recipient.address) - .amount(amount) - .build() - - sender.publicKey = transaction.senderPublicKey - - walletManager.reindex(sender) - walletManager.reindex(recipient) - }) + describe('when the recipient is a cold wallet', () => {}) + + const transfer = genTransfer( + 'testnet', + Math.random().toString(36), + walletData2.address, + 96579, + 1, + )[0] + const delegateReg = genDelegateReg( + 'testnet', + Math.random().toString(36), + 1, + )[0] + const secondSign = gen2ndSignature( + 'testnet', + Math.random().toString(36), + 1, + )[0] + const vote = genvote( + 'testnet', + Math.random().toString(36), + walletData2.publicKey, + 1, + )[0] + describe.each` + type | transaction | amount | balanceSuccess | balanceFail + ${'transfer'} | ${transfer} | ${new Bignum(96579)} | ${new Bignum(1 * ARKTOSHI)} | ${Bignum.ONE} + ${'delegate'} | ${delegateReg} | ${Bignum.ZERO} | ${new Bignum(30 * ARKTOSHI)} | ${Bignum.ONE} + ${'2nd sign'} | ${secondSign} | ${Bignum.ZERO} | ${new Bignum(10 * ARKTOSHI)} | ${Bignum.ONE} + ${'vote'} | ${vote} | ${Bignum.ZERO} | ${new Bignum(5 * ARKTOSHI)} | ${Bignum.ONE} + `( + 'when the transaction is a $type', + ({ type, transaction, amount, balanceSuccess, balanceFail }) => { + let sender + let recipient + + beforeEach(() => { + sender = new Wallet(walletData1.address) + recipient = new Wallet(walletData2.address) + recipient.publicKey = walletData2.publicKey + + sender.publicKey = transaction.senderPublicKey + + walletManager.reindex(sender) + walletManager.reindex(recipient) + + walletManager.__isDelegate = jest.fn(() => true) // for vote transaction + }) - it('should apply the transaction to the sender & recipient', async () => { - const balance = 100000000 - sender.balance = balance + it('should apply the transaction to the sender & recipient', async () => { + sender.balance = balanceSuccess - expect(sender.balance).toBe(balance) - expect(recipient.balance).toBe(0) + expect(+sender.balance.toFixed()).toBe(+balanceSuccess) + expect(+recipient.balance.toFixed()).toBe(0) - await walletManager.applyTransaction(transaction) + await walletManager.applyTransaction(transaction) - expect(sender.balance).toBe(balance - amount - transaction.fee) - expect(recipient.balance).toBe(amount) - }) + expect(sender.balance).toEqual( + balanceSuccess.minus(amount).minus(transaction.fee), + ) - it('should fail if the transaction cannot be applied', async () => { - const balance = 1 - sender.balance = balance + if (type === 'transfer') { + expect(recipient.balance).toEqual(amount) + } + }) - expect(sender.balance).toBe(balance) - expect(recipient.balance).toBe(0) + it('should fail if the transaction cannot be applied', async () => { + sender.balance = balanceFail - try { - expect(async () => { - await walletManager.applyTransaction(transaction) - }).toThrowError(/apply transaction/) + expect(+sender.balance.toFixed()).toBe(+balanceFail) + expect(+recipient.balance.toFixed()).toBe(0) - expect(null).toBe('this should fail if no error is thrown') - } catch (error) { - expect(sender.balance).toBe(balance) - expect(recipient.balance).toBe(0) - } - }) - }) + try { + expect(async () => { + await walletManager.applyTransaction(transaction) + }).toThrow(/apply transaction/) - describe('when the transaction is not a transfer', () => { - }) + expect(null).toBe('this should fail if no error is thrown') + } catch (error) { + expect(+sender.balance.toFixed()).toBe(+balanceFail) + expect(+recipient.balance.toFixed()).toBe(0) + } + }) + }, + ) }) describe('revertTransaction', () => { @@ -274,49 +299,57 @@ describe('Wallet Manager', () => { recipientId: 'AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri', timestamp: 0, asset: {}, - senderPublicKey: '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', - signature: '304402205fcb0677e06bde7aac3dc776665615f4b93ef8c3ed0fddecef9900e74fcb00f302206958a0c9868ea1b1f3d151bdfa92da1ce24de0b1fcd91933e64fb7971e92f48d', + senderPublicKey: + '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', + signature: + '304402205fcb0677e06bde7aac3dc776665615f4b93ef8c3ed0fddecef9900e74fcb00f302206958a0c9868ea1b1f3d151bdfa92da1ce24de0b1fcd91933e64fb7971e92f48d', id: 'db1aa687737858cc9199bfa336f9b1c035915c30aaee60b1e0f8afadfdb946bd', - senderId: 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn' + senderId: 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn', }) - const sender = walletManager.getWalletByPublicKey(transaction.data.senderPublicKey) - const recipient = walletManager.getWalletByAddress(transaction.data.recipientId) + const sender = walletManager.findByPublicKey( + transaction.data.senderPublicKey, + ) + const recipient = walletManager.findByAddress( + transaction.data.recipientId, + ) recipient.balance = transaction.data.amount - expect(sender.balance).toBe(0) - expect(recipient.balance).toBe(transaction.data.amount) + expect(sender.balance).toEqual(Bignum.ZERO) + expect(recipient.balance).toEqual(transaction.data.amount) await walletManager.revertTransaction(transaction) - expect(sender.balance).toBe(transaction.data.amount) - expect(recipient.balance).toBe(0) + expect(sender.balance).toEqual(transaction.data.amount) + expect(recipient.balance).toEqual(Bignum.ZERO) }) }) - describe('getWalletByAddress', () => { + describe('findByAddress', () => { it('should be a function', () => { - expect(walletManager.getWalletByAddress).toBeFunction() + expect(walletManager.findByAddress).toBeFunction() }) it('should index it by address', () => { const wallet = new Wallet(walletData1.address) walletManager.reindex(wallet) - expect(Object.keys(walletManager.walletsByAddress)[0]).toBe(wallet.address) + expect(walletManager.byAddress[wallet.address]).toBe(wallet) }) it('should return it by address', () => { const wallet = new Wallet(walletData1.address) walletManager.reindex(wallet) - expect(walletManager.getWalletByAddress(wallet.address).address).toBe(wallet.address) + expect(walletManager.findByAddress(wallet.address).address).toBe( + wallet.address, + ) }) }) - describe('getWalletByPublicKey', () => { + describe('findByPublicKey', () => { it('should be a function', () => { - expect(walletManager.getWalletByPublicKey).toBeFunction() + expect(walletManager.findByPublicKey).toBeFunction() }) it('should index it by publicKey', () => { @@ -324,7 +357,7 @@ describe('Wallet Manager', () => { wallet.publicKey = walletData1.publicKey walletManager.reindex(wallet) - expect(Object.keys(walletManager.walletsByPublicKey)[0]).toBe(wallet.publicKey) + expect(walletManager.byPublicKey[wallet.publicKey]).toBe(wallet) }) it('should return it by publicKey', () => { @@ -332,13 +365,15 @@ describe('Wallet Manager', () => { wallet.publicKey = 'dummy-public-key' walletManager.reindex(wallet) - expect(walletManager.getWalletByPublicKey(wallet.publicKey).publicKey).toBe(wallet.publicKey) + expect(walletManager.findByPublicKey(wallet.publicKey).publicKey).toBe( + wallet.publicKey, + ) }) }) - describe('getWalletByUsername', () => { + describe('findByUsername', () => { it('should be a function', () => { - expect(walletManager.getWalletByUsername).toBeFunction() + expect(walletManager.findByUsername).toBeFunction() }) it('should index it by username', () => { @@ -346,7 +381,7 @@ describe('Wallet Manager', () => { wallet.username = 'dummy-username' walletManager.reindex(wallet) - expect(Object.keys(walletManager.walletsByUsername)[0]).toBe(wallet.username) + expect(walletManager.byUsername[wallet.username]).toBe(wallet) }) it('should return it by username', () => { @@ -354,13 +389,15 @@ describe('Wallet Manager', () => { wallet.username = 'dummy-username' walletManager.reindex(wallet) - expect(walletManager.getWalletByUsername(wallet.username).username).toBe(wallet.username) + expect(walletManager.findByUsername(wallet.username).username).toBe( + wallet.username, + ) }) }) - describe('getLocalWallets', () => { + describe('all', () => { it('should be a function', () => { - expect(walletManager.getLocalWallets).toBeFunction() + expect(walletManager.all).toBeFunction() }) it('should return indexed', () => { @@ -370,7 +407,7 @@ describe('Wallet Manager', () => { const wallet2 = new Wallet(walletData2.address) walletManager.reindex(wallet2) - expect(walletManager.getLocalWallets()).toEqual([wallet1, wallet2]) + expect(walletManager.all()).toEqual([wallet1, wallet2]) }) }) @@ -378,7 +415,7 @@ describe('Wallet Manager', () => { it('should be removed if all criteria are satisfied', async () => { const wallet = new Wallet(walletData1.address) - expect(walletManager.__canBePurged(wallet)).toBeTruthy() + expect(walletManager.__canBePurged(wallet)).toBeTrue() }) it('should not be removed if wallet.secondPublicKey is set', async () => { @@ -386,7 +423,7 @@ describe('Wallet Manager', () => { wallet.secondPublicKey = 'secondPublicKey' expect(wallet.secondPublicKey).toBe('secondPublicKey') - expect(walletManager.__canBePurged(wallet)).toBeFalsy() + expect(walletManager.__canBePurged(wallet)).toBeFalse() }) it('should not be removed if wallet.multisignature is set', async () => { @@ -394,7 +431,7 @@ describe('Wallet Manager', () => { wallet.multisignature = 'multisignature' expect(wallet.multisignature).toBe('multisignature') - expect(walletManager.__canBePurged(wallet)).toBeFalsy() + expect(walletManager.__canBePurged(wallet)).toBeFalse() }) it('should not be removed if wallet.username is set', async () => { @@ -402,7 +439,7 @@ describe('Wallet Manager', () => { wallet.username = 'username' expect(wallet.username).toBe('username') - expect(walletManager.__canBePurged(wallet)).toBeFalsy() + expect(walletManager.__canBePurged(wallet)).toBeFalse() }) }) @@ -423,7 +460,7 @@ describe('Wallet Manager', () => { walletManager.purgeEmptyNonDelegates() - expect(walletManager.getLocalWallets()).toEqual([wallet2]) + expect(walletManager.all()).toEqual([wallet2]) }) it('should not be purged if wallet.secondPublicKey is set', async () => { @@ -439,7 +476,7 @@ describe('Wallet Manager', () => { walletManager.purgeEmptyNonDelegates() - expect(walletManager.getLocalWallets()).toEqual([wallet1, wallet2]) + expect(walletManager.all()).toEqual([wallet1, wallet2]) }) it('should not be purged if wallet.multisignature is set', async () => { @@ -455,7 +492,7 @@ describe('Wallet Manager', () => { walletManager.purgeEmptyNonDelegates() - expect(walletManager.getLocalWallets()).toEqual([wallet1, wallet2]) + expect(walletManager.all()).toEqual([wallet1, wallet2]) }) it('should not be purged if wallet.username is set', async () => { @@ -471,25 +508,44 @@ describe('Wallet Manager', () => { walletManager.purgeEmptyNonDelegates() - expect(walletManager.getLocalWallets()).toEqual([wallet1, wallet2]) + expect(walletManager.all()).toEqual([wallet1, wallet2]) }) }) - describe('isGenesis', () => { + describe('buildVoteBalances', () => { it('should be a function', () => { - expect(walletManager.isGenesis).toBeFunction() + expect(walletManager.buildVoteBalances).toBeFunction() }) - it('should be truthy', async () => { - const wallet = new Wallet(walletData1.address) + it('should update vote balance of delegates', async () => { + for (let i = 0; i < 5; i++) { + const delegateKey = i.toString().repeat(66) + const delegate = { + address: crypto.getAddress(delegateKey), + publicKey: delegateKey, + username: `delegate${i}`, + voteBalance: Bignum.ZERO, + } - expect(walletManager.isGenesis(wallet)).toBeTruthy() - }) + const voter = { + address: crypto.getAddress((i + 5).toString().repeat(66)), + balance: new Bignum((i + 1) * 1000 * ARKTOSHI), + publicKey: `v${delegateKey}`, + vote: delegateKey, + } + + walletManager.index([delegate, voter]) + } - it('should be falsy', async () => { - const wallet = new Wallet(walletDataFake.address) + walletManager.buildVoteBalances() - expect(walletManager.isGenesis(wallet)).toBeFalsy() + const delegates = walletManager.allByUsername() + for (let i = 0; i < 5; i++) { + const delegate = delegates[4 - i] + expect(delegate.voteBalance).toEqual( + new Bignum((5 - i) * 1000 * ARKTOSHI), + ) + } }) }) }) diff --git a/packages/core-database/jest.config.js b/packages/core-database/jest.config.js index 26f7a25796..57770a97bb 100644 --- a/packages/core-database/jest.config.js +++ b/packages/core-database/jest.config.js @@ -1,22 +1,12 @@ -'use strict' - module.exports = { testEnvironment: 'node', bail: false, verbose: true, - testMatch: [ - '**/__tests__/**/*.test.js' - ], - moduleFileExtensions: [ - 'js', - 'json' - ], + testMatch: ['**/__tests__/**/*.test.js'], + moduleFileExtensions: ['js', 'json'], collectCoverage: false, coverageDirectory: '/.coverage', - collectCoverageFrom: [ - 'lib/**/*.js', - '!**/node_modules/**' - ], + collectCoverageFrom: ['lib/**/*.js', '!**/node_modules/**'], watchman: false, - setupTestFrameworkScriptFile: 'jest-extended' + setupTestFrameworkScriptFile: 'jest-extended', } diff --git a/packages/core-database/jsdoc.json b/packages/core-database/jsdoc.json index 23276f74ea..f3ea8aab33 100644 --- a/packages/core-database/jsdoc.json +++ b/packages/core-database/jsdoc.json @@ -7,9 +7,7 @@ "includePattern": ".js$", "excludePattern": "(node_modules/|docs)" }, - "plugins": [ - "plugins/markdown" - ], + "plugins": ["plugins/markdown"], "opts": { "template": "../../node_modules/docdash", "encoding": "utf8", diff --git a/packages/core-database/lib/defaults.js b/packages/core-database/lib/defaults.js index ce6b233ccc..09837607a6 100644 --- a/packages/core-database/lib/defaults.js +++ b/packages/core-database/lib/defaults.js @@ -1,5 +1,5 @@ -'use strict' - module.exports = { - snapshots: `${process.env.ARK_PATH_DATA}/snapshots/${process.env.ARK_NETWORK_NAME}` + snapshots: `${process.env.ARK_PATH_DATA}/snapshots/${ + process.env.ARK_NETWORK_NAME + }`, } diff --git a/packages/core-database/lib/index.js b/packages/core-database/lib/index.js index e8e5047be5..e2bb02bb2c 100644 --- a/packages/core-database/lib/index.js +++ b/packages/core-database/lib/index.js @@ -1,5 +1,3 @@ -'use strict' - const databaseManager = require('./manager') /** @@ -10,11 +8,11 @@ exports.plugin = { pkg: require('../package.json'), defaults: require('./defaults'), alias: 'databaseManager', - async register (container, options) { + async register(container, options) { container.resolvePlugin('logger').info('Starting Database Manager') return databaseManager - } + }, } /** diff --git a/packages/core-database/lib/interface.js b/packages/core-database/lib/interface.js index 489994887b..8cc78d7c10 100644 --- a/packages/core-database/lib/interface.js +++ b/packages/core-database/lib/interface.js @@ -1,21 +1,23 @@ -'use strict' - -const async = require('async') const { crypto, slots } = require('@arkecosystem/crypto') -const container = require('@arkecosystem/core-container') -const config = container.resolvePlugin('config') -const logger = container.resolvePlugin('logger') -const emitter = container.resolvePlugin('event-emitter') -const WalletManager = require('./wallet-manager') +const app = require('@arkecosystem/core-container') + +const config = app.resolvePlugin('config') +const logger = app.resolvePlugin('logger') +const emitter = app.resolvePlugin('event-emitter') const { Block } = require('@arkecosystem/crypto').models +const { TRANSACTION_TYPES } = require('@arkecosystem/crypto').constants +const { roundCalculator } = require('@arkecosystem/core-utils') +const cloneDeep = require('lodash/cloneDeep') +const assert = require('assert') +const WalletManager = require('./wallet-manager') module.exports = class ConnectionInterface { /** * @constructor - * @param {Object} config + * @param {Object} options */ - constructor (config) { - this.config = config + constructor(options) { + this.config = options this.connection = null this.blocksInCurrentRound = null this.stateStarted = false @@ -27,7 +29,7 @@ module.exports = class ConnectionInterface { * Get the current connection. * @return {ConnectionInterface} */ - getConnection () { + getConnection() { return this.connection } @@ -36,7 +38,7 @@ module.exports = class ConnectionInterface { * @return {void} * @throws Error */ - async connect () { + async connect() { throw new Error('Method [connect] not implemented!') } @@ -45,7 +47,7 @@ module.exports = class ConnectionInterface { * @return {void} * @throws Error */ - async disconnect () { + async disconnect() { throw new Error('Method [disconnect] not implemented!') } @@ -58,38 +60,28 @@ module.exports = class ConnectionInterface { * - Sum of all tx amount equals the sum of block.totalAmount * @return {Object} An object { valid, errors } with the result of the verification and the errors */ - async verifyBlockchain () { + async verifyBlockchain() { throw new Error('Method [verifyBlockchain] not implemented!') } /** * Get the top 51 delegates. * @param {Number} height + * @param {Array} delegates * @return {void} * @throws Error */ - async getActiveDelegates (height) { + async getActiveDelegates(height, delegates) { throw new Error('Method [getActiveDelegates] not implemented!') } - /** - * Load a list of delegates into memory. - * @param {Number} maxDelegates - * @param {Number} height - * @return {void} - * @throws Error - */ - async buildDelegates (maxDelegates, height) { - throw new Error('Method [buildDelegates] not implemented!') - } - /** * Load a list of wallets into memory. * @param {Number} height - * @return {void} + * @return {Boolean} success * @throws Error */ - async buildWallets (height) { + async buildWallets(height) { throw new Error('Method [buildWallets] not implemented!') } @@ -99,7 +91,7 @@ module.exports = class ConnectionInterface { * @return {void} * @throws Error */ - async saveWallets (force) { + async saveWallets(force) { throw new Error('Method [saveWallets] not implemented!') } @@ -110,50 +102,53 @@ module.exports = class ConnectionInterface { * @return {void} * @throws Error */ - async saveBlock (block) { + async saveBlock(block) { throw new Error('Method [saveBlock] not implemented!') } /** - * Save the given block (async version). - * NOTE: to use when rebuilding to decrease the number of database transactions, and commit blocks (save only every 1000s for instance) using saveBlockCommit + * Queue a query to save the given block. + * NOTE: Must call commitQueuedQueries() to save to database. + * NOTE: to use when rebuilding to decrease the number of database transactions, + * and commit blocks (save only every 1000s for instance) by calling commit * @param {Block} block * @return {void} * @throws Error */ - async saveBlockAsync (block) { - throw new Error('Method [saveBlockAsync] not implemented!') + enqueueSaveBlock(block) { + throw new Error('Method [enqueueSaveBlock] not implemented!') } /** - * Commit the block save database transaction. - * NOTE: to be used in combination with saveBlockAsync + * Queue a query to delete the given block. + * See also enqueueSaveBlock + * @param {Block} block * @return {void} * @throws Error */ - async saveBlockCommit () { - throw new Error('Method [saveBlockCommit] not implemented!') + enqueueDeleteBlock(block) { + throw new Error('Method [enqueueDeleteBlock] not implemented!') } /** - * Delete the given block (async version). - * NOTE: to use when rebuilding to decrease the number of database transactions, and commit blocks (save only every 1000s for instance) using saveBlockCommit - * @param {Block} block + * Queue a query to delete the round at given height. + * See also enqueueSaveBlock and enqueueDeleteBlock + * @param {Number} height * @return {void} * @throws Error */ - async deleteBlockAsync (block) { - throw new Error('Method [saveBlockAsync] not implemented!') + enqueueDeleteRound(height) { + throw new Error('Method [enqueueDeleteRound] not implemented!') } /** - * Commit the block delete database transaction. - * NOTE: to be used in combination with deleteBlockAsync + * Commit all queued queries to the database. + * NOTE: to be used in combination with other enqueue-functions. * @return {void} * @throws Error */ - async deleteBlockCommit () { - throw new Error('Method [deleteBlockCommit] not implemented!') + async commitQueuedQueries() { + throw new Error('Method [commitQueuedQueries] not implemented!') } /** @@ -162,7 +157,7 @@ module.exports = class ConnectionInterface { * @return {void} * @throws Error */ - async deleteBlock (block) { + async deleteBlock(block) { throw new Error('Method [deleteBlock] not implemented!') } @@ -172,7 +167,7 @@ module.exports = class ConnectionInterface { * @return {void} * @throws Error */ - async getBlock (id) { + async getBlock(id) { throw new Error('Method [getBlock] not implemented!') } @@ -181,7 +176,7 @@ module.exports = class ConnectionInterface { * @return {void} * @throws Error */ - async getLastBlock () { + async getLastBlock() { throw new Error('Method [getLastBlock] not implemented!') } @@ -192,15 +187,27 @@ module.exports = class ConnectionInterface { * @return {void} * @throws Error */ - async getBlocks (offset, limit) { + async getBlocks(offset, limit) { throw new Error('Method [getBlocks] not implemented!') } + /** + * Get top count blocks ordered by height DESC. + * NOTE: Only used when trying to restore database integrity. + * The returned blocks may be unchained. + * @param {Number} count + * @return {void} + * @throws Error + */ + async getTopBlocks(count) { + throw new Error('Method [getTopBlocks] not implemented!') + } + /** * Get recent block ids. * @return {[]String} */ - async getRecentBlockIds () { + async getRecentBlockIds() { throw new Error('Method [getRecentBlockIds] not implemented!') } @@ -210,7 +217,7 @@ module.exports = class ConnectionInterface { * @return {void} * @throws Error */ - saveRound (activeDelegates) { + async saveRound(activeDelegates) { throw new Error('Method [saveRound] not implemented!') } @@ -220,7 +227,7 @@ module.exports = class ConnectionInterface { * @return {void} * @throws Error */ - deleteRound (round) { + async deleteRound(round) { throw new Error('Method [deleteRound] not implemented!') } @@ -231,7 +238,7 @@ module.exports = class ConnectionInterface { * @param {Array} delegates * @return {void} */ - async updateDelegateStats (height, delegates) { + updateDelegateStats(height, delegates) { if (!delegates || !this.blocksInCurrentRound) { return } @@ -240,15 +247,22 @@ module.exports = class ConnectionInterface { try { delegates.forEach(delegate => { - let producedBlocks = this.blocksInCurrentRound.filter(blockGenerator => blockGenerator.data.generatorPublicKey === delegate.publicKey) - let wallet = this.walletManager.getWalletByPublicKey(delegate.publicKey) + const producedBlocks = this.blocksInCurrentRound.filter( + blockGenerator => + blockGenerator.data.generatorPublicKey === delegate.publicKey, + ) + const wallet = this.walletManager.findByPublicKey(delegate.publicKey) if (producedBlocks.length === 0) { wallet.missedBlocks++ - logger.debug(`Delegate ${wallet.username} (${wallet.publicKey}) just missed a block. Total: ${wallet.missedBlocks}`) + logger.debug( + `Delegate ${wallet.username} (${ + wallet.publicKey + }) just missed a block. Total: ${wallet.missedBlocks}`, + ) wallet.dirty = true emitter.emit('forger.missing', { - delegate: wallet + delegate: wallet, }) } }) @@ -257,27 +271,6 @@ module.exports = class ConnectionInterface { } } - /** - * Detect if height is the beginning of a new round. - * @param {Number} height - * @return {boolean} true if new round, false if not - */ - isNewRound (height) { - const maxDelegates = config.getConstants(height).activeDelegates - - return height % maxDelegates === 1 - } - - getRound (height) { - const maxDelegates = config.getConstants(height).activeDelegates - - if (height < maxDelegates + 1) { - return 1 - } - - return Math.floor((height - 1) / maxDelegates) + 1 - } - /** * Apply the round. * Note that the round is applied and the end of the round (so checking height + 1) @@ -285,36 +278,43 @@ module.exports = class ConnectionInterface { * @param {Number} height * @return {void} */ - async applyRound (height) { + async applyRound(height) { const nextHeight = height === 1 ? 1 : height + 1 const maxDelegates = config.getConstants(nextHeight).activeDelegates if (nextHeight % maxDelegates === 1) { const round = Math.floor((nextHeight - 1) / maxDelegates) + 1 - if (!this.activedelegates || this.activedelegates.length === 0 || (this.activedelegates.length && this.activedelegates[0].round !== round)) { - logger.info(`Starting Round ${round} :dove_of_peace:`) + if ( + !this.forgingDelegates || + this.forgingDelegates.length === 0 || + (this.forgingDelegates.length && + this.forgingDelegates[0].round !== round) + ) { + logger.info(`Starting Round ${round.toLocaleString()} :dove_of_peace:`) try { - await this.updateDelegateStats(height, this.activedelegates) - await this.saveWallets(false) // save only modified wallets during the last round - - const delegates = await this.buildDelegates(maxDelegates, nextHeight) // active build delegate list from database state - await this.saveRound(delegates) // save next round delegate list - await this.getActiveDelegates(nextHeight) // generate the new active delegates list - this.blocksInCurrentRound = [] - // TODO: find a betxter place to call this as this - // currently blocks execution but needs to be updated every round - if (this.stateStarted) { - this.walletManager.updateDelegates() - } + this.updateDelegateStats(height, this.forgingDelegates) + this.saveWallets(false) // save only modified wallets during the last round + const delegates = this.walletManager.loadActiveDelegateList( + maxDelegates, + nextHeight, + ) // get active delegate list from in-memory wallet manager + this.saveRound(delegates) // save next round delegate list non-blocking + this.forgingDelegates = await this.getActiveDelegates( + nextHeight, + delegates, + ) // generate the new active delegates list + this.blocksInCurrentRound.length = 0 } catch (error) { // trying to leave database state has it was - this.deleteRound(round) + await this.deleteRound(round) throw error } } else { - logger.warn(`Round ${round} has already been applied. This should happen only if you are a forger. :warning:`) + logger.warn( + `Round ${round.toLocaleString()} has already been applied. This should happen only if you are a forger. :warning:`, + ) } } } @@ -324,55 +324,116 @@ module.exports = class ConnectionInterface { * @param {Number} height * @return {void} */ - async revertRound (height) { - const maxDelegates = config.getConstants(height).activeDelegates - const nextHeight = height + 1 - - const round = Math.floor((height - 1) / maxDelegates) + 1 - const nextRound = Math.floor((nextHeight - 1) / config.getConstants(nextHeight).activeDelegates) + 1 + async revertRound(height) { + const { round, nextRound, maxDelegates } = roundCalculator.calculateRound( + height, + ) - if (nextRound === round + 1 && height > maxDelegates) { - logger.info(`Back to previous round: ${round} :back:`) - this.blocksInCurrentRound = await this.__getBlocksForRound(round) + if (nextRound === round + 1 && height >= maxDelegates) { + logger.info(`Back to previous round: ${round.toLocaleString()} :back:`) - this.activedelegates = await this.getActiveDelegates(height) + const delegates = await this.__calcPreviousActiveDelegates(round) + this.forgingDelegates = await this.getActiveDelegates(height, delegates) await this.deleteRound(nextRound) } } + /** + * Calculate the active delegates of the previous round. In order to do + * so we need to go back to the start of that round. Therefore we create + * a temporary wallet manager with all delegates and revert all blocks + * and transactions of that round to get the initial vote balances + * which are then used to restore the original order. + * @param {Number} round + */ + async __calcPreviousActiveDelegates(round) { + // TODO: cache the blocks of the last X rounds + this.blocksInCurrentRound = await this.__getBlocksForRound(round) + + // Create temp wallet manager from all delegates + const tempWalletManager = new WalletManager() + tempWalletManager.index(cloneDeep(this.walletManager.allByUsername())) + + // Revert all blocks in reverse order + let height = 0 + for (let i = this.blocksInCurrentRound.length - 1; i >= 0; i--) { + tempWalletManager.revertBlock(this.blocksInCurrentRound[i]) + height = this.blocksInCurrentRound[i].data.height + } + + // The first round has no active delegates + if (height === 1) { + return [] + } + + // Assert that the height is the beginning of a round. + const { maxDelegates } = roundCalculator.calculateRound(height) + assert(height > 1 && height % maxDelegates === 1) + + // Now retrieve the active delegate list from the temporary wallet manager. + return tempWalletManager.loadActiveDelegateList(maxDelegates, height) + } + /** * Validate a delegate. * @param {Block} block * @return {void} */ - async validateDelegate (block) { + async validateDelegate(block) { + if (this.__isException(block.data)) { + return + } + const delegates = await this.getActiveDelegates(block.data.height) const slot = slots.getSlotNumber(block.data.timestamp) const forgingDelegate = delegates[slot % delegates.length] - const generatorUsername = this.walletManager.getWalletByPublicKey(block.data.generatorPublicKey).username + const generatorUsername = this.walletManager.findByPublicKey( + block.data.generatorPublicKey, + ).username if (!forgingDelegate) { - logger.debug(`Could not decide if delegate ${generatorUsername} (${block.data.generatorPublicKey}) is allowed to forge block ${block.data.height.toLocaleString()} :grey_question:`) + logger.debug( + `Could not decide if delegate ${generatorUsername} (${ + block.data.generatorPublicKey + }) is allowed to forge block ${block.data.height.toLocaleString()} :grey_question:`, + ) } else if (forgingDelegate.publicKey !== block.data.generatorPublicKey) { - const forgingUsername = this.walletManager.getWalletByPublicKey(forgingDelegate.publicKey).username - - throw new Error(`Delegate ${generatorUsername} (${block.data.generatorPublicKey}) not allowed to forge, should be ${forgingUsername} (${forgingDelegate.publicKey}) :-1:`) + const forgingUsername = this.walletManager.findByPublicKey( + forgingDelegate.publicKey, + ).username + + throw new Error( + `Delegate ${generatorUsername} (${ + block.data.generatorPublicKey + }) not allowed to forge, should be ${forgingUsername} (${ + forgingDelegate.publicKey + }) :-1:`, + ) } else { - logger.debug(`Delegate ${generatorUsername} (${block.data.generatorPublicKey}) allowed to forge block ${block.data.height.toLocaleString()} :+1:`) + logger.debug( + `Delegate ${generatorUsername} (${ + block.data.generatorPublicKey + }) allowed to forge block ${block.data.height.toLocaleString()} :+1:`, + ) } - - return true } /** * Validate a forked block. * @param {Block} block - * @return {void} + * @return {Boolean} */ - async validateForkedBlock (block) { - await this.validateDelegate(block) + async validateForkedBlock(block) { + try { + await this.validateDelegate(block) + } catch (error) { + logger.debug(error.stack) + return false + } + + return true } /** @@ -380,33 +441,56 @@ module.exports = class ConnectionInterface { * @param {Block} block * @return {void} */ - async applyBlock (block) { + async applyBlock(block) { await this.validateDelegate(block) - await this.walletManager.applyBlock(block) + this.walletManager.applyBlock(block) + if (this.blocksInCurrentRound) { this.blocksInCurrentRound.push(block) } + await this.applyRound(block.data.height) + block.transactions.forEach(tx => this.__emitTransactionEvents(tx)) emitter.emit('block.applied', block.data) } + /** + * Emit events for the specified transaction. + * @param {Object} transaction + * @return {void} + */ + __emitTransactionEvents(transaction) { + emitter.emit('transaction.applied', transaction.data) + + if (transaction.type === TRANSACTION_TYPES.DELEGATE_REGISTRATION) { + emitter.emit('delegate.registered', transaction.data) + } + + if (transaction.type === TRANSACTION_TYPES.DELEGATE_RESIGNATION) { + emitter.emit('delegate.resigned', transaction.data) + } + + if (transaction.type === TRANSACTION_TYPES.VOTE) { + const vote = transaction.asset.votes[0] + + emitter.emit(vote.startsWith('+') ? 'wallet.vote' : 'wallet.unvote', { + delegate: vote, + transaction: transaction.data, + }) + } + } + /** * Remove the given block. * @param {Block} block * @return {void} */ - async revertBlock (block) { + async revertBlock(block) { await this.revertRound(block.data.height) await this.walletManager.revertBlock(block) - if (this.blocksInCurrentRound) { - this.blocksInCurrentRound.pop() - // COMMENTED OUT: needs to be sure is properly synced - // if (b.data.id !== block.data.id) { - // logger.debug(`block to revert: ${JSON.stringify(b.data)}`) - // logger.debug(`reverted block: ${JSON.stringify(block.data)}`) - // throw new Error('Reverted wrong block. Restart is needed 💣') - // } - } + + assert(this.blocksInCurrentRound.pop().data.id === block.data.id) + emitter.emit('block.reverted', block.data) } @@ -415,10 +499,13 @@ module.exports = class ConnectionInterface { * @param {Transaction} transaction * @return {Boolean} */ - async verifyTransaction (transaction) { - const senderId = crypto.getAddress(transaction.data.senderPublicKey, config.network.pubKeyHash) + async verifyTransaction(transaction) { + const senderId = crypto.getAddress( + transaction.data.senderPublicKey, + config.network.pubKeyHash, + ) - let sender = this.walletManager.getWalletByAddress[senderId] // should exist + const sender = this.walletManager.findByAddress(senderId) // should exist if (!sender.publicKey) { sender.publicKey = transaction.data.senderPublicKey @@ -427,43 +514,7 @@ module.exports = class ConnectionInterface { const dbTransaction = await this.getTransaction(transaction.data.id) - return sender.canApply(transaction.data) && !dbTransaction - } - - /** - * Write blocks to file as a snapshot. - * @return {void} - */ - async snapshot () { - const expandHomeDir = require('expand-home-dir') - const path = expandHomeDir(container.config('databaseManager').snapshots) - - const fs = require('fs-extra') - await fs.ensureFile(`${path}/blocks.dat`) - - const wstream = fs.createWriteStream(`${path}/blocks.dat`) - - let max = 100000 // eslint-disable-line no-unused-vars - let offset = 0 - const writeQueue = async.queue((block, qcallback) => { - wstream.write(block) - qcallback() - }, 1) - - let blocks = await this.getBlockHeaders(offset, offset + 100000) - writeQueue.push(blocks) - max = blocks.length - offset += 100000 - console.log(offset) - - writeQueue.drain = async () => { - console.log('drain') - blocks = await this.getBlockHeaders(offset, offset + 100000) - writeQueue.push(blocks) - max = blocks.length - offset += 100000 - console.log(offset) - } + return sender.canApply(transaction.data, []) && !dbTransaction } /** @@ -471,38 +522,45 @@ module.exports = class ConnectionInterface { * @param {number} round * @return {[]Block} */ - async __getBlocksForRound (round) { - const lastBlock = await this.getLastBlock() + async __getBlocksForRound(round) { + let lastBlock + if (app.has('state')) { + lastBlock = app.resolve('state').getLastBlock() + } else { + lastBlock = await this.getLastBlock() + } + if (!lastBlock) { return [] } let height = +lastBlock.data.height if (!round) { - round = this.getRound(height) + round = roundCalculator.calculateRound(height).round } const maxDelegates = config.getConstants(height).activeDelegates - height = (round * maxDelegates) + 1 + height = round * maxDelegates + 1 - return (await this.getBlocks(height - maxDelegates, maxDelegates)).map(b => new Block(b)) + const blocks = await this.getBlocks(height - maxDelegates, maxDelegates - 1) + return blocks.map(b => new Block(b)) } /** * Register event listeners. * @return {void} */ - __registerListeners () { + __registerListeners() { emitter.on('state:started', () => { this.stateStarted = true }) } /** - * Register the wallet container. + * Register the wallet app. * @return {void} */ - async _registerWalletManager () { + async _registerWalletManager() { this.walletManager = new WalletManager() } @@ -510,8 +568,25 @@ module.exports = class ConnectionInterface { * Register the wallet and delegate repositories. * @return {void} */ - async _registerRepositories () { - this['wallets'] = new (require('./repositories/wallets'))(this) - this['delegates'] = new (require('./repositories/delegates'))(this) + async _registerRepositories() { + this.wallets = new (require('./repositories/wallets'))(this) + this.delegates = new (require('./repositories/delegates'))(this) + } + + /** + * Determine if the given block is an exception. + * @param {Object} block + * @return {Boolean} + */ + __isException(block) { + if (!config) { + return false + } + + if (!Array.isArray(config.network.exceptions.blocks)) { + return false + } + + return config.network.exceptions.blocks.includes(block.id) } } diff --git a/packages/core-database/lib/manager.js b/packages/core-database/lib/manager.js index b5e78efa3c..00b00833ab 100644 --- a/packages/core-database/lib/manager.js +++ b/packages/core-database/lib/manager.js @@ -1,11 +1,9 @@ -'use strict' - class DatabaseManager { /** * Create a new database manager instance. * @constructor */ - constructor () { + constructor() { this.connections = {} } @@ -14,7 +12,7 @@ class DatabaseManager { * @param {String} name * @return {ConnectionInterface} */ - connection (name = 'default') { + connection(name = 'default') { return this.connections[name] } @@ -24,7 +22,7 @@ class DatabaseManager { * @param {String} name * @return {void} */ - async makeConnection (connection, name = 'default') { + async makeConnection(connection, name = 'default') { this.connections[name] = await connection.make() } } diff --git a/packages/core-database/lib/repositories/delegates.js b/packages/core-database/lib/repositories/delegates.js index d200f2f200..f11b258c63 100644 --- a/packages/core-database/lib/repositories/delegates.js +++ b/packages/core-database/lib/repositories/delegates.js @@ -1,15 +1,13 @@ -'use strict' - -const { calculateApproval, calculateProductivity } = require('./utils/delegate-calculator') -const limitRows = require('./utils/limit-rows') +const { delegateCalculator } = require('@arkecosystem/core-utils') const orderBy = require('lodash/orderBy') +const limitRows = require('./utils/limit-rows') module.exports = class DelegatesRepository { /** * Create a new delegate repository instance. * @param {ConnectionInterface} connection */ - constructor (connection) { + constructor(connection) { this.connection = connection } @@ -17,8 +15,10 @@ module.exports = class DelegatesRepository { * Get all local delegates. * @return {Array} */ - getLocalDelegates () { - return this.connection.walletManager.getLocalWallets().filter(wallet => !!wallet.username) + getLocalDelegates() { + return this.connection.walletManager + .all() + .filter(wallet => !!wallet.username) } /** @@ -26,16 +26,14 @@ module.exports = class DelegatesRepository { * @param {Object} params * @return {Object} */ - findAll (params = {}) { + findAll(params = {}) { const rows = this.getLocalDelegates() - const order = params.orderBy - ? params.orderBy.split(':') - : ['rate', 'asc'] + const order = params.orderBy ? params.orderBy.split(':') : ['rate', 'asc'] return { rows: limitRows(orderBy(rows, order), params), - count: rows.length + count: rows.length, } } @@ -44,7 +42,7 @@ module.exports = class DelegatesRepository { * @param {Object} params * @return {Object} */ - paginate (params) { + paginate(params) { return this.findAll(params) } @@ -55,21 +53,21 @@ module.exports = class DelegatesRepository { * @param {String} [params.username] - Search by username * @return {Object} */ - search (params) { - let delegates = this.getLocalDelegates().filter(delegate => { - return delegate.username.indexOf(params.username) > -1 - }) + search(params) { + let delegates = this.getLocalDelegates().filter( + delegate => delegate.username.indexOf(params.username) > -1, + ) if (params.orderBy) { const orderByField = params.orderBy.split(':')[0] const orderByDirection = params.orderBy.split(':')[1] || 'desc' delegates = delegates.sort((a, b) => { - if (orderByDirection === 'desc' && (a[orderByField] < b[orderByField])) { + if (orderByDirection === 'desc' && a[orderByField] < b[orderByField]) { return -1 } - if (orderByDirection === 'asc' && (a[orderByField] > b[orderByField])) { + if (orderByDirection === 'asc' && a[orderByField] > b[orderByField]) { return 1 } @@ -79,7 +77,7 @@ module.exports = class DelegatesRepository { return { rows: limitRows(delegates, params), - count: delegates.length + count: delegates.length, } } @@ -88,8 +86,10 @@ module.exports = class DelegatesRepository { * @param {String} id * @return {Object} */ - findById (id) { - return this.getLocalDelegates().find(a => (a.address === id || a.publicKey === id || a.username === id)) + findById(id) { + return this.getLocalDelegates().find( + a => a.address === id || a.publicKey === id || a.username === id, + ) } /** @@ -97,7 +97,7 @@ module.exports = class DelegatesRepository { * @param {Number} height * @return {Array} */ - getActiveAtHeight (height) { + getActiveAtHeight(height) { const delegates = this.connection.getActiveDelegates(height) return delegates.map(delegate => { @@ -105,8 +105,8 @@ module.exports = class DelegatesRepository { return { username: wallet.username, - approval: calculateApproval(delegate, height), - productivity: calculateProductivity(wallet) + approval: delegateCalculator.calculateApproval(delegate, height), + productivity: delegateCalculator.calculateProductivity(wallet), } }) } diff --git a/packages/core-database/lib/repositories/utils/delegate-calculator.js b/packages/core-database/lib/repositories/utils/delegate-calculator.js deleted file mode 100644 index 1d79fbbd14..0000000000 --- a/packages/core-database/lib/repositories/utils/delegate-calculator.js +++ /dev/null @@ -1,29 +0,0 @@ -'use strict' - -const config = require('@arkecosystem/core-container').resolvePlugin('config') - -/** - * Calculate the approval for the given delegate. - * @param {Delegate} delegate - * @param {Number} height - * @return {String} Approval, as a String with 2 decimals - */ -exports.calculateApproval = (delegate, height) => { - const constants = config.getConstants(height) - const totalSupply = config.genesisBlock.totalAmount + (height - constants.height) * constants.reward - - return ((delegate.balance / totalSupply) * 100).toFixed(2) -} - -/** - * Calculate the productivity of the given delegate. - * @param {Delegate} delegate - * @return {String} Productivity, as a String with 2 decimals - */ -exports.calculateProductivity = delegate => { - if (!delegate.missedBlocks && !delegate.producedBlocks) { - return (0).toFixed(2) - } - - return (100 - (delegate.missedBlocks / ((delegate.producedBlocks + delegate.missedBlocks) / 100))).toFixed(2) -} diff --git a/packages/core-database/lib/repositories/utils/filter-rows.js b/packages/core-database/lib/repositories/utils/filter-rows.js index 98ec57ff56..197ab448c5 100644 --- a/packages/core-database/lib/repositories/utils/filter-rows.js +++ b/packages/core-database/lib/repositories/utils/filter-rows.js @@ -1,4 +1,4 @@ -'use strict' +/* eslint no-prototype-builtins: "off" */ /** * Filter an Array of Objects based on the given parameters. @@ -7,10 +7,10 @@ * @param {Object} filters * @return {Array} */ -module.exports = (rows, params, filters) => { - return rows.filter(item => { +module.exports = (rows, params, filters) => + rows.filter(item => { if (filters.hasOwnProperty('exact')) { - for (const elem of filters['exact']) { + for (const elem of filters.exact) { if (params[elem] && item[elem] !== params[elem]) { return false } @@ -18,16 +18,23 @@ module.exports = (rows, params, filters) => { } if (filters.hasOwnProperty('between')) { - for (const elem of filters['between']) { + for (const elem of filters.between) { if (!params[elem]) { continue } - if (!params[elem].hasOwnProperty('from') && !params[elem].hasOwnProperty('to') && item[elem] !== params[elem]) { + if ( + !params[elem].hasOwnProperty('from') && + !params[elem].hasOwnProperty('to') && + item[elem] !== params[elem] + ) { return false } - if (params[elem].hasOwnProperty('from') || params[elem].hasOwnProperty('to')) { + if ( + params[elem].hasOwnProperty('from') || + params[elem].hasOwnProperty('to') + ) { let isMoreThan = true let isLessThan = true @@ -47,7 +54,7 @@ module.exports = (rows, params, filters) => { // NOTE: it was used to filter by `votes`, but that field was rejected and // replaced by `vote`. This filter is kept here just in case if (filters.hasOwnProperty('any')) { - for (const elem of filters['any']) { + for (const elem of filters.any) { if (params[elem] && item[elem]) { if (Array.isArray(params[elem])) { if (item[elem].every(a => params[elem].indexOf(a) === -1)) { @@ -62,4 +69,3 @@ module.exports = (rows, params, filters) => { return true }) -} diff --git a/packages/core-database/lib/repositories/utils/limit-rows.js b/packages/core-database/lib/repositories/utils/limit-rows.js index 31ace13310..28a7d5ddd9 100644 --- a/packages/core-database/lib/repositories/utils/limit-rows.js +++ b/packages/core-database/lib/repositories/utils/limit-rows.js @@ -1,5 +1,3 @@ -'use strict' - /** * Return some rows by an offset and a limit. * @param {Array} rows diff --git a/packages/core-database/lib/repositories/wallets.js b/packages/core-database/lib/repositories/wallets.js index 5decfeac5c..1c6e53b522 100644 --- a/packages/core-database/lib/repositories/wallets.js +++ b/packages/core-database/lib/repositories/wallets.js @@ -1,6 +1,4 @@ -'use strict' - -const sortBy = require('lodash/sortBy') +const orderBy = require('lodash/orderBy') const filterRows = require('./utils/filter-rows') const limitRows = require('./utils/limit-rows') @@ -9,7 +7,7 @@ module.exports = class WalletsRepository { * Create a new wallet repository instance. * @param {ConnectionInterface} connection */ - constructor (connection) { + constructor(connection) { this.connection = connection } @@ -17,8 +15,8 @@ module.exports = class WalletsRepository { * Get all local wallets. * @return {Array} */ - getLocalWallets () { - return this.connection.walletManager.getLocalWallets() + all() { + return this.connection.walletManager.all() } /** @@ -26,12 +24,16 @@ module.exports = class WalletsRepository { * @param {Object} params * @return {Object} */ - findAll (params = {}) { - const wallets = this.getLocalWallets() + findAll(params = {}) { + const wallets = this.all() + + const [iteratee, order] = params.orderBy + ? params.orderBy.split(':') + : ['rate', 'asc'] return { - rows: limitRows(wallets, params), - count: wallets.length + rows: limitRows(orderBy(wallets, iteratee, order), params), + count: wallets.length, } } @@ -41,14 +43,12 @@ module.exports = class WalletsRepository { * @param {Object} params * @return {Object} */ - findAllByVote (publicKey, params = {}) { - const wallets = this - .getLocalWallets() - .filter(wallet => wallet.vote === publicKey) + findAllByVote(publicKey, params = {}) { + const wallets = this.all().filter(wallet => wallet.vote === publicKey) return { rows: limitRows(wallets, params), - count: wallets.length + count: wallets.length, } } @@ -57,16 +57,20 @@ module.exports = class WalletsRepository { * @param {Number} id * @return {Object} */ - findById (id) { - return this.getLocalWallets().find(wallet => (wallet.address === id || wallet.publicKey === id || wallet.username === id)) + findById(id) { + return this.all().find( + wallet => wallet.address === id + || wallet.publicKey === id + || wallet.username === id, + ) } /** * Count all wallets. * @return {Number} */ - count () { - return this.getLocalWallets().length + count() { + return this.all().length } /** @@ -74,12 +78,14 @@ module.exports = class WalletsRepository { * @param {Object} params * @return {Object} */ - top (params = {}) { - const wallets = sortBy(this.getLocalWallets(), 'balance').reverse() + top(params = {}) { + const wallets = Object.values(this.all()).sort( + (a, b) => +b.balance.minus(a.balance).toFixed(), + ) return { rows: limitRows(wallets, params), - count: wallets.length + count: wallets.length, } } @@ -97,20 +103,20 @@ module.exports = class WalletsRepository { * @param {Object} [params.balance] - Search by balance * @param {Number} [params.balance.from] - Search by balance (minimum) * @param {Number} [params.balance.to] - Search by balance (maximum) - * @param {Object} [params.votebalance] - Search by votebalance - * @param {Number} [params.votebalance.from] - Search by votebalance (minimum) - * @param {Number} [params.votebalance.to] - Search by votebalance (maximum) + * @param {Object} [params.voteBalance] - Search by voteBalance + * @param {Number} [params.voteBalance.from] - Search by voteBalance (minimum) + * @param {Number} [params.voteBalance.to] - Search by voteBalance (maximum) * @return {Object} */ - search (params) { - const wallets = filterRows(this.getLocalWallets(), params, { + search(params) { + const wallets = filterRows(this.all(), params, { exact: ['address', 'publicKey', 'secondPublicKey', 'username', 'vote'], - between: ['balance', 'votebalance'] + between: ['balance', 'voteBalance'], }) return { rows: limitRows(wallets, params), - count: wallets.length + count: wallets.length, } } } diff --git a/packages/core-database/lib/wallet-manager.js b/packages/core-database/lib/wallet-manager.js index d7f1a92c6f..bceb8f037d 100644 --- a/packages/core-database/lib/wallet-manager.js +++ b/packages/core-database/lib/wallet-manager.js @@ -1,38 +1,152 @@ -'use strict' - -const Promise = require('bluebird') - -const { map, orderBy, sumBy } = require('lodash') -const { crypto } = require('@arkecosystem/crypto') +const { crypto, formatArktoshi } = require('@arkecosystem/crypto') const { Wallet } = require('@arkecosystem/crypto').models const { TRANSACTION_TYPES } = require('@arkecosystem/crypto').constants -const container = require('@arkecosystem/core-container') -const config = container.resolvePlugin('config') -const logger = container.resolvePlugin('logger') -const emitter = container.resolvePlugin('event-emitter') +const { roundCalculator } = require('@arkecosystem/core-utils') +const app = require('@arkecosystem/core-container') + +const config = app.resolvePlugin('config') +const logger = app.resolvePlugin('logger') -const genesisWallets = map(config.genesisBlock.transactions, 'senderId') +const pluralize = require('pluralize') module.exports = class WalletManager { /** * Create a new wallet manager instance. * @constructor */ - constructor () { + constructor() { + this.networkId = config ? config.network.pubKeyHash : 0x17 this.reset() - - this.emitEvents = true } /** * Reset the wallets index. * @return {void} */ - reset () { - // TODO rename to by... - this.walletsByAddress = {} - this.walletsByPublicKey = {} - this.walletsByUsername = {} + reset() { + this.byAddress = {} + this.byPublicKey = {} + this.byUsername = {} + } + + /** + * Get all wallets by address. + * @return {Array} + */ + all() { + return Object.values(this.byAddress) + } + + /** + * Get all wallets by publicKey. + * @return {Array} + */ + allByPublicKey() { + return Object.values(this.byPublicKey) + } + + /** + * Get all wallets by username. + * @return {Array} + */ + allByUsername() { + return Object.values(this.byUsername) + } + + /** + * Find a wallet by the given address. + * @param {String} address + * @return {Wallet} + */ + findByAddress(address) { + if (!this.byAddress[address]) { + this.byAddress[address] = new Wallet(address) + } + + return this.byAddress[address] + } + + /** + * Find a wallet by the given public key. + * @param {String} publicKey + * @return {Wallet} + */ + findByPublicKey(publicKey) { + if (!this.byPublicKey[publicKey]) { + const address = crypto.getAddress(publicKey, config.network.pubKeyHash) + + const wallet = this.findByAddress(address) + wallet.publicKey = publicKey + this.byPublicKey[publicKey] = wallet + } + + return this.byPublicKey[publicKey] + } + + /** + * Find a wallet by the given username. + * @param {String} username + * @return {Wallet} + */ + findByUsername(username) { + return this.byUsername[username] + } + + /** + * Set wallet by address. + * @param {String} address + * @param {Wallet} wallet + * @param {void} + */ + setByAddress(address, wallet) { + this.byAddress[address] = wallet + } + + /** + * Set wallet by publicKey. + * @param {String} publicKey + * @param {Wallet} wallet + * @param {void} + */ + setByPublicKey(publicKey, wallet) { + this.byPublicKey[publicKey] = wallet + } + + /** + * Set wallet by username. + * @param {String} username + * @param {Wallet} wallet + * @param {void} + */ + setByUsername(username, wallet) { + this.byUsername[username] = wallet + } + + /** + * Remove wallet by address. + * @param {String} address + * @param {void} + */ + forgetByAddress(address) { + delete this.byAddress[address] + } + + /** + * Remove wallet by publicKey. + * @param {String} publicKey + * @param {void} + */ + forgetByPublicKey(publicKey) { + delete this.byPublicKey[publicKey] + } + + /** + * Remove wallet by username. + * @param {String} username + * @param {void} + */ + forgetByUsername(username) { + delete this.byUsername[username] } /** @@ -40,8 +154,10 @@ module.exports = class WalletManager { * @param {Array} wallets * @return {void} */ - index (wallets) { - wallets.forEach(wallet => this.reindex(wallet)) + index(wallets) { + for (const wallet of wallets) { + this.reindex(wallet) + } } /** @@ -49,63 +165,129 @@ module.exports = class WalletManager { * @param {Wallet} wallet * @return {void} */ - reindex (wallet) { + reindex(wallet) { if (wallet.address) { - this.walletsByAddress[wallet.address] = wallet + this.byAddress[wallet.address] = wallet } if (wallet.publicKey) { - this.walletsByPublicKey[wallet.publicKey] = wallet + this.byPublicKey[wallet.publicKey] = wallet } if (wallet.username) { - this.walletsByUsername[wallet.username] = wallet + this.byUsername[wallet.username] = wallet } } + clear() { + Object.values(this.byAddress).forEach(wallet => { + wallet.dirty = false + }) + } + /** - * Update the vote balances and ranks of delegates. - * @return {void} + * Load a list of all active delegates. + * @param {Number} maxDelegates + * @return {Array} */ - async updateDelegates () { - let delegates = this.getDelegates().map(delegate => { - const voters = this - .getLocalWallets() - .filter(w => w.vote === delegate.publicKey) + loadActiveDelegateList(maxDelegates, height) { + if (height > 1 && height % maxDelegates !== 1) { + throw new Error('Trying to build delegates outside of round change') + } - delegate.votebalance = sumBy(voters, 'balance') + const { round } = roundCalculator.calculateRound(height, maxDelegates) + let delegates = this.allByUsername() - return delegate - }) + if (delegates.length < maxDelegates) { + throw new Error( + `Expected to find ${maxDelegates} delegates but only found ${ + delegates.length + }. This indicates an issue with the genesis block & delegates.`, + ) + } - delegates = orderBy(delegates, ['votebalance'], ['desc']).map((delegate, index) => { - delegate.rate = index + 1 + const equalVotesMap = new Map() - return delegate - }) + delegates = delegates + .sort((a, b) => { + const diff = b.voteBalance.comparedTo(a.voteBalance) + + if (diff === 0) { + if (!equalVotesMap.has(a.voteBalance.toFixed())) { + equalVotesMap.set(a.voteBalance.toFixed(), new Set()) + } + + const set = equalVotesMap.get(a.voteBalance.toFixed()) + set.add(a) + set.add(b) + + if (a.publicKey === b.publicKey) { + throw new Error( + `The balance and public key of both delegates are identical! Delegate "${ + a.username + }" appears twice in the list.`, + ) + } + + return a.publicKey.localeCompare(b.publicKey, 'en') + } + + return diff + }) + .map((delegate, i) => { + const rate = i + 1 + this.byUsername[delegate.username].rate = rate + return { ...{ round }, ...delegate, rate } + }) + .slice(0, maxDelegates) + + for (const [voteBalance, set] of equalVotesMap.entries()) { + const values = Array.from(set.values()) + if (delegates.includes(values[0])) { + const mapped = values.map(v => `${v.username} (${v.publicKey})`) + logger.warn( + `Delegates ${JSON.stringify( + mapped, + null, + 4, + )} have a matching vote balance of ${formatArktoshi(voteBalance)}`, + ) + } + } - this.index(delegates) + logger.debug( + `Loaded ${delegates.length} active ${pluralize( + 'delegate', + delegates.length, + )}`, + ) + + return delegates } /** - * Used to determine if a wallet is a Genesis wallet. - * @return {Boolean} + * Build vote balances of all delegates. + * NOTE: Only called during SPV. + * @return {void} */ - isGenesis (wallet) { - return genesisWallets.includes(wallet.address) + buildVoteBalances() { + Object.values(this.byPublicKey).forEach(voter => { + if (voter.vote) { + const delegate = this.byPublicKey[voter.vote] + delegate.voteBalance = delegate.voteBalance.plus(voter.balance) + } + }) } /** * Remove non-delegate wallets that have zero (0) balance from memory. * @return {void} */ - purgeEmptyNonDelegates () { - Object.keys(this.walletsByPublicKey).forEach(publicKey => { - const wallet = this.walletsByPublicKey[publicKey] - + purgeEmptyNonDelegates() { + Object.values(this.byPublicKey).forEach(wallet => { if (this.__canBePurged(wallet)) { - delete this.walletsByPublicKey[publicKey] - delete this.walletsByAddress[wallet.address] + delete this.byPublicKey[wallet.publicKey] + delete this.byAddress[wallet.address] } }) } @@ -115,13 +297,13 @@ module.exports = class WalletManager { * @param {Block} block * @return {void} */ - async applyBlock (block) { + applyBlock(block) { const generatorPublicKey = block.data.generatorPublicKey - let delegate = this.getWalletByPublicKey(block.data.generatorPublicKey) + let delegate = this.byPublicKey[block.data.generatorPublicKey] if (!delegate) { - const generator = crypto.getAddress(generatorPublicKey, config.network.pubKeyHash) + const generator = crypto.getAddress(generatorPublicKey, this.networkId) if (block.data.height === 1) { delegate = new Wallet(generator) @@ -129,35 +311,47 @@ module.exports = class WalletManager { this.reindex(delegate) } else { - logger.debug(`Delegate by address: ${this.walletsByAddress[generator]}`) + logger.debug(`Delegate by address: ${this.byAddress[generator]}`) - if (this.walletsByAddress[generator]) { + if (this.byAddress[generator]) { logger.info('This look like a bug, please report :bug:') } - throw new Error(`Could not find delegate with publicKey ${generatorPublicKey}`) + throw new Error( + `Could not find delegate with publicKey ${generatorPublicKey}`, + ) } } const appliedTransactions = [] try { - for (let i = 0; i < block.transactions.length; i++) { - await this.applyTransaction(block.transactions[i]) + block.transactions.forEach(transaction => { + this.applyTransaction(transaction) + appliedTransactions.push(transaction) + }) - appliedTransactions.push(block.transactions[i]) - } + const applied = delegate.applyBlock(block.data) - delegate.applyBlock(block.data) + // If the block has been applied to the delegate, the balance is increased + // by reward + totalFee. In which case the vote balance of the + // delegate's delegate has to be updated. + if (applied && delegate.vote) { + const increase = block.data.reward.plus(block.data.totalFee) + const votedDelegate = this.byPublicKey[delegate.vote] + votedDelegate.voteBalance = votedDelegate.voteBalance.plus(increase) + } } catch (error) { - logger.error('Failed to apply all transactions in block - reverting previous transactions') - + logger.error( + 'Failed to apply all transactions in block - reverting previous transactions', + ) // Revert the applied transactions from last to first for (let i = appliedTransactions.length - 1; i >= 0; i--) { - await this.revertTransaction(appliedTransactions[i]) + this.revertTransaction(appliedTransactions[i]) } - // TODO should revert the delegate applyBlock ? + // TODO: should revert the delegate applyBlock ? + // TBC: whatever situation `delegate.applyBlock(block.data)` is never applied throw error } @@ -168,32 +362,43 @@ module.exports = class WalletManager { * @param {Block} block * @return {void} */ - async revertBlock (block) { - let delegate = this.getWalletByPublicKey(block.data.generatorPublicKey) + async revertBlock(block) { + const delegate = this.byPublicKey[block.data.generatorPublicKey] if (!delegate) { - const generator = crypto.getAddress(block.data.generatorPublicKey, config.network.pubKeyHash) - - delegate = new Wallet(generator) - delegate.publicKey = block.data.generatorPublicKey - - this.reindex(delegate) + app.forceExit( + `Failed to lookup generator '${ + block.data.generatorPublicKey + }' of block '${block.data.id}'. :skull:`, + ) } const revertedTransactions = [] try { - await Promise.each(block.transactions, async (transaction) => { - await this.revertTransaction(transaction) - + // Revert the transactions from last to first + for (let i = block.transactions.length - 1; i >= 0; i--) { + const transaction = block.transactions[i] + this.revertTransaction(transaction) revertedTransactions.push(transaction) - }) + } + + const reverted = delegate.revertBlock(block.data) - delegate.revertBlock(block.data) + // If the block has been reverted, the balance is decreased + // by reward + totalFee. In which case the vote balance of the + // delegate's delegate has to be updated. + if (reverted && delegate.vote) { + const decrease = block.data.reward.plus(block.data.totalFee) + const votedDelegate = this.byPublicKey[delegate.vote] + votedDelegate.voteBalance = votedDelegate.voteBalance.minus(decrease) + } } catch (error) { logger.error(error.stack) - await Promise.each(revertedTransactions, async (transaction) => this.applyTransaction(transaction)) + revertedTransactions + .reverse() + .forEach(transaction => this.applyTransaction(transaction)) throw error } @@ -204,132 +409,171 @@ module.exports = class WalletManager { * @param {Transaction} transaction * @return {Transaction} */ - async applyTransaction (transaction) { /* eslint padded-blocks: "off" */ + applyTransaction(transaction) { + /* eslint padded-blocks: "off" */ const { data } = transaction const { type, asset, recipientId, senderPublicKey } = data - const sender = this.getWalletByPublicKey(senderPublicKey) - let recipient = recipientId ? this.getWalletByAddress(recipientId) : null - - if (!recipient && recipientId) { // cold wallet - recipient = new Wallet(recipientId) - this.walletsByAddress[recipientId] = recipient - this.__emitEvent('wallet:cold:created', recipient) - - } else if (type === TRANSACTION_TYPES.DELEGATE_REGISTRATION && this.walletsByUsername[asset.delegate.username.toLowerCase()]) { - - logger.error(`Delegate transaction sent by ${sender.address}`, JSON.stringify(data)) - throw new Error(`Can't apply transaction ${data.id}: delegate name already taken`) - - // NOTE: We use the vote public key, because vote transactions have the same sender and recipient - } else if (type === TRANSACTION_TYPES.VOTE && !this.walletsByPublicKey[asset.votes[0].slice(1)]) { - - logger.error(`Vote transaction sent by ${sender.address}`, JSON.stringify(data)) - throw new Error(`Can't apply transaction ${data.id}: voted/unvoted delegate does not exist`) - - } else if (config.network.exceptions[data.id]) { - - logger.warn('Transaction forcibly applied because it has been added as an exception:', data) - - } else if (!sender.canApply(data)) { + const sender = this.findByPublicKey(senderPublicKey) + const recipient = this.findByAddress(recipientId) + const errors = [] + + // specific verifications / adjustments depending on transaction type + if ( + type === TRANSACTION_TYPES.DELEGATE_REGISTRATION && + this.byUsername[asset.delegate.username.toLowerCase()] + ) { + logger.error( + `Can't apply transaction ${ + data.id + }: delegate name '${asset.delegate.username.toLowerCase()}' already taken.`, + ) + throw new Error( + `Can't apply transaction ${data.id}: delegate name already taken.`, + ) + + // NOTE: We use the vote public key, because vote transactions + // have the same sender and recipient + } else if ( + type === TRANSACTION_TYPES.VOTE && + !this.__isDelegate(asset.votes[0].slice(1)) + ) { + logger.error( + `Can't apply vote transaction ${data.id}: delegate ${ + asset.votes[0] + } does not exist.`, + ) + throw new Error( + `Can't apply transaction ${data.id}: delegate ${ + asset.votes[0] + } does not exist.`, + ) + } else if (type === TRANSACTION_TYPES.SECOND_SIGNATURE) { + data.recipientId = '' + } - logger.error(`Can't apply transaction for ${sender.address}`, JSON.stringify(data)) - logger.debug('Audit', JSON.stringify(sender.auditApply(data), null, 2)) + // handle exceptions / verify that we can apply the transaction to the sender + if (this.__isException(data)) { + logger.warn( + `Transaction ${ + data.id + } forcibly applied because it has been added as an exception.`, + ) + } else if (!sender.canApply(data, errors)) { + logger.error( + `Can't apply transaction id:${data.id} from sender:${ + sender.address + } due to ${JSON.stringify(errors)}`, + ) + logger.debug(`Audit: ${JSON.stringify(sender.auditApply(data), null, 2)}`) throw new Error(`Can't apply transaction ${data.id}`) } sender.applyTransactionToSender(data) + if (type === TRANSACTION_TYPES.DELEGATE_REGISTRATION) { + this.reindex(sender) + } + if (recipient && type === TRANSACTION_TYPES.TRANSFER) { recipient.applyTransactionToRecipient(data) } - this.__emitTransactionEvents(transaction) + this._updateVoteBalances(sender, recipient, data) return transaction } /** - * Remove the given transaction from a delegate. - * @param {Number} type - * @param {Object} data + * Updates the vote balances of the respective delegates of sender and recipient. + * If the transaction is not a vote... + * 1. fee + amount is removed from the sender's delegate vote balance + * 2. amount is added to the recipient's delegate vote balance + * + * in case of a vote... + * 1. the full sender balance is added to the sender's delegate vote balance + * + * If revert is set to true, the operations are reversed (plus -> minus, minus -> plus). + * @param {Wallet} sender + * @param {Wallet} recipient + * @param {Transaction} transaction + * @param {Boolean} revert * @return {Transaction} */ - async revertTransaction ({ type, data }) { - const sender = this.getWalletByPublicKey(data.senderPublicKey) // Should exist - const recipient = this.getWalletByAddress(data.recipientId) + _updateVoteBalances(sender, recipient, transaction, revert = false) { + // TODO: multipayment? + if (transaction.type !== TRANSACTION_TYPES.VOTE) { + // Update vote balance of the sender's delegate + if (sender.vote) { + const delegate = this.findByPublicKey(sender.vote) + const total = transaction.amount.plus(transaction.fee) + delegate.voteBalance = revert + ? delegate.voteBalance.plus(total) + : delegate.voteBalance.minus(total) + } - sender.revertTransactionForSender(data) + // Update vote balance of recipient's delegate + if (recipient && recipient.vote) { + const delegate = this.findByPublicKey(recipient.vote) + delegate.voteBalance = revert + ? delegate.voteBalance.minus(transaction.amount) + : delegate.voteBalance.plus(transaction.amount) + } + } else { + const vote = transaction.asset.votes[0] + const delegate = this.findByPublicKey(vote.substr(1)) - if (recipient && type === TRANSACTION_TYPES.TRANSFER) { - recipient.revertTransactionForRecipient(data) + if (vote.startsWith('+')) { + delegate.voteBalance = revert + ? delegate.voteBalance.minus(sender.balance) + : delegate.voteBalance.plus(sender.balance) + } else { + delegate.voteBalance = revert + ? delegate.voteBalance.plus(sender.balance.plus(transaction.fee)) + : delegate.voteBalance.minus(sender.balance.plus(transaction.fee)) + } } - - this.__emitEvent('transaction.reverted', data) - - return data } /** - * Get a wallet by the given address. - * @param {String} address - * @return {(Wallet|null)} + * Remove the given transaction from a delegate. + * @param {Transaction} transaction + * @return {Transaction} */ - getWalletByAddress (address) { - if (!this.walletsByAddress[address]) { - this.walletsByAddress[address] = new Wallet(address) - } + revertTransaction(transaction) { + const { type, data } = transaction + const sender = this.findByPublicKey(data.senderPublicKey) // Should exist + const recipient = this.byAddress[data.recipientId] - return this.walletsByAddress[address] - } + sender.revertTransactionForSender(data) - /** - * Get a wallet by the given public key. - * @param {String} publicKey - * @return {Wallet} - */ - getWalletByPublicKey (publicKey) { - if (!this.walletsByPublicKey[publicKey]) { - const address = crypto.getAddress(publicKey, config.network.pubKeyHash) + // removing the wallet from the delegates index + if (type === TRANSACTION_TYPES.DELEGATE_REGISTRATION) { + delete this.byUsername[data.asset.delegate.username] + } - this.walletsByPublicKey[publicKey] = this.getWalletByAddress(address) - this.walletsByPublicKey[publicKey].publicKey = publicKey + if (recipient && type === TRANSACTION_TYPES.TRANSFER) { + recipient.revertTransactionForRecipient(data) } - return this.walletsByPublicKey[publicKey] - } + // Revert vote balance updates + this._updateVoteBalances(sender, recipient, data, true) - /** - * Get a wallet by the given username. - * @param {String} publicKey - * @return {Wallet} - */ - getWalletByUsername (username) { - return this.walletsByUsername[username] + return data } /** - * Getter for "walletsByUsername" for clear intent. - * @return {Wallet} + * Checks if a given publicKey is a registered delegate + * @param {String} publicKey */ - getDelegates () { - return Object.values(this.walletsByUsername) - } + __isDelegate(publicKey) { + const delegateWallet = this.byPublicKey[publicKey] - /** - * Get all wallets by address. - * @return {Array} - */ - getLocalWallets () { // for compatibility with API - return Object.values(this.walletsByAddress) - } + if (delegateWallet && delegateWallet.username) { + return !!this.byUsername[delegateWallet.username] + } - /** - * Get all wallets by publicKey. - * @return {Array} - */ - getLocalWalletsByPublicKey () { // for init of transaction pool manager - return Object.values(this.walletsByPublicKey) + return false } /** @@ -337,45 +581,29 @@ module.exports = class WalletManager { * @param {Object} wallet * @return {Boolean} */ - __canBePurged (wallet) { - return wallet.balance === 0 && !wallet.secondPublicKey && !wallet.multisignature && !wallet.username + __canBePurged(wallet) { + return ( + wallet.balance.isZero() && + !wallet.secondPublicKey && + !wallet.multisignature && + !wallet.username + ) } /** - * Emit events to the emmiter - * @param {String} event - * @param {Object} date - * @return {void} - */ - __emitEvent (event, data) { - if (this.emitEvents) { - emitter.emit(event, data) - } - } - - /** - * Emit events for the specified transaction. + * Determine if the given transaction is an exception. * @param {Object} transaction - * @return {void} + * @return {Boolean} */ - __emitTransactionEvents (transaction) { - this.__emitEvent('transaction.applied', transaction.data) - - if (transaction.type === TRANSACTION_TYPES.DELEGATE_REGISTRATION) { - this.__emitEvent('delegate.registered', transaction.data) + __isException(transaction) { + if (!config) { + return false } - if (transaction.type === TRANSACTION_TYPES.DELEGATE_RESIGNATION) { - this.__emitEvent('delegate.resigned', transaction.data) + if (!Array.isArray(config.network.exceptions.transactions)) { + return false } - if (transaction.type === TRANSACTION_TYPES.VOTE) { - const vote = transaction.asset.votes[0] - - this.__emitEvent(vote.startsWith('+') ? 'wallet.vote' : 'wallet.unvote', { - delegate: vote, - transaction: transaction.data - }) - } + return config.network.exceptions.transactions.includes(transaction.id) } } diff --git a/packages/core-database/package.json b/packages/core-database/package.json index cb49d3423e..8ec666fa8d 100644 --- a/packages/core-database/package.json +++ b/packages/core-database/package.json @@ -1,7 +1,7 @@ { "name": "@arkecosystem/core-database", - "description": "Database Interface for ARK Core", - "version": "0.1.1", + "description": "Database Interface for Ark Core", + "version": "0.2.0", "contributors": [ "François-Xavier Thoorens ", "Kristjan Košič ", @@ -10,25 +10,30 @@ "license": "MIT", "main": "lib/index.js", "scripts": { - "build:docs": "../../node_modules/.bin/jsdoc -c jsdoc.json", "test": "cross-env ARK_ENV=test jest --runInBand --detectOpenHandles", - "test:coverage": "cross-env ARK_ENV=test jest --coverage --runInBand --detectOpenHandles", - "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand --watch", + "test:coverage": "cross-env ARK_ENV=test jest --coverage --coveragePathIgnorePatterns='/(defaults.js|index.js)$' --runInBand --detectOpenHandles", + "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand", "test:watch": "cross-env ARK_ENV=test jest --runInBand --watch", "test:watch:all": "cross-env ARK_ENV=test jest --runInBand --watchAll", "lint": "eslint ./ --fix", - "depcheck": "depcheck ./" + "depcheck": "depcheck ./ --ignores=lodash,lodash.*" }, "dependencies": { - "@arkecosystem/core-container": "^0.1.1", - "@arkecosystem/crypto": "^0.1.1", - "async": "^2.6.1", - "bluebird": "^3.5.1", - "expand-home-dir": "^0.0.3", - "fs-extra": "^6.0.1", - "lodash": "^4.17.10" + "@arkecosystem/core-container": "~0.2", + "@arkecosystem/core-utils": "~0.2", + "@arkecosystem/crypto": "~0.2", + "lodash.clonedeep": "^4.5.0", + "lodash.compact": "^3.0.1", + "lodash.uniq": "^4.5.0", + "pluralize": "^7.0.0" + }, + "devDependencies": { + "@arkecosystem/core-test-utils": "~0.2" }, "publishConfig": { "access": "public" + }, + "engines": { + "node": ">=10.x" } } diff --git a/packages/core-database-sequelize/.gitattributes b/packages/core-debugger-cli/.gitattributes similarity index 100% rename from packages/core-database-sequelize/.gitattributes rename to packages/core-debugger-cli/.gitattributes diff --git a/packages/core-debugger-cli/.gitignore b/packages/core-debugger-cli/.gitignore new file mode 100644 index 0000000000..5dc9198e84 --- /dev/null +++ b/packages/core-debugger-cli/.gitignore @@ -0,0 +1 @@ +test-wallets \ No newline at end of file diff --git a/packages/core-debugger-cli/CHANGELOG.md b/packages/core-debugger-cli/CHANGELOG.md new file mode 100644 index 0000000000..95a15b0628 --- /dev/null +++ b/packages/core-debugger-cli/CHANGELOG.md @@ -0,0 +1,26 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +## Unreleased + +## 0.2.0 - 2018-12-03 + +### Added + +- Retrieve identities +- Verify second signature + +### Changed + +- Change `transaction.serialized` from `Buffer` to hex +- Dropped node.js 9 as minimum requirement in favour of node.js 10 + +## 0.1.0 - 2018-10-02 + +### Added + +- initial release diff --git a/packages/core-database-sequelize/LICENSE b/packages/core-debugger-cli/LICENSE similarity index 100% rename from packages/core-database-sequelize/LICENSE rename to packages/core-debugger-cli/LICENSE diff --git a/packages/core-debugger-cli/README.md b/packages/core-debugger-cli/README.md new file mode 100644 index 0000000000..5560b6d780 --- /dev/null +++ b/packages/core-debugger-cli/README.md @@ -0,0 +1,22 @@ +# Ark Core - Debugger CLI + +

+ +

+ +## Documentation + +You can find installation instructions and detailed instructions on how to use this package at the [dedicated documentation site](https://docs.ark.io/guidebook/core/plugins/core-debugger-cli.html). + +## Security + +If you discover a security vulnerability within this package, please send an e-mail to security@ark.io. All security vulnerabilities will be promptly addressed. + +## Credits + +- [Brian Faust](https://github.com/faustbrian) +- [All Contributors](../../../../contributors) + +## License + +[MIT](LICENSE) © [ArkEcosystem](https://ark.io) diff --git a/packages/core-debugger-cli/__tests__/__fixtures__/block.json b/packages/core-debugger-cli/__tests__/__fixtures__/block.json new file mode 100644 index 0000000000..85acc88b6f --- /dev/null +++ b/packages/core-debugger-cli/__tests__/__fixtures__/block.json @@ -0,0 +1,140 @@ +{ + "data": { + "id": "7176646138626297930", + "version": 0, + "height": 2243161, + "timestamp": 24760440, + "previousBlock": "3112633353705641986", + "numberOfTransactions": 7, + "totalAmount": "3890300", + "totalFee": "70000000", + "reward": "200000000", + "payloadLength": 224, + "payloadHash": "3784b953afcf936bdffd43fdf005b5732b49c1fc6b11e195c364c20b2eb06282", + "generatorPublicKey": "020f5df4d2bc736d12ce43af5b1663885a893fade7ee5e62b3cc59315a63e6a325", + "blockSignature": "3045022100eee6c37b5e592e99811d588532726353592923f347c701d52912e6d583443e400220277ffe38ad31e216ba0907c4738fed19b2071246b150c72c0a52bae4477ebe29", + "transactions": [ + { + "type": 0, + "amount": 555760, + "fee": 10000000, + "recipientId": "DB4gFuDztmdGALMb8i1U4Z4R5SktxpNTAY", + "timestamp": 24760418, + "asset": {}, + "vendorField": "Goose Voter - True Block Weight", + "senderPublicKey": "0265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c0", + "signature": "304402204f12469157b19edd06ba25fcad3d4a5ef5b057c23f9e02de4641e6f8eef0553e022010121ab282f83efe1043de9c16bbf2c6845a03684229a0d7c965ffb9abdfb978", + "signSignature": "30450221008327862f0b9178d6665f7d6674978c5caf749649558d814244b1c66cdf945c40022015918134ef01fed3fe2a2efde3327917731344332724522c75c2799a14f78717", + "id": "170543154a3b79459cbaa529f9f62b6f1342682799eb549dbf09fcca2d1f9c11", + "senderId": "DB8LnnQqYvHpG4WkGJ9AJWBYEct7G3yRZg", + "hop": 2, + "broadcast": false, + "blockId": "7176646138626297930" + }, + { + "type": 0, + "amount": 555750, + "fee": 10000000, + "recipientId": "DGExsNogZR7JFa2656ZFP9TMWJYJh5djzQ", + "timestamp": 24760416, + "asset": {}, + "vendorField": "Goose Voter - True Block Weight", + "senderPublicKey": "0265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c0", + "signature": "304402205f82feb8c5d1d79c565c2ff7badb93e4c9827b132d135dda11cb25427d4ef8ac02205ff136f970533c4ec4c7d0cd1ea7e02d7b62629b66c6c93265f608d7f2389727", + "signSignature": "304402207e912031fcc700d8a55fbc415993302a0d8e6aea128397141b640b6dba52331702201fd1ad3984e42af44f548907add6cb7ad72ca0070c8cc1d8dc9bbda208c56bd9", + "id": "1da153f37eceda233ff1b407ac18e47b3cae47c14cdcd5297d929618a916c4a7", + "senderId": "DB8LnnQqYvHpG4WkGJ9AJWBYEct7G3yRZg", + "hop": 2, + "broadcast": false, + "blockId": "7176646138626297930" + }, + { + "type": 0, + "amount": 555770, + "fee": 10000000, + "recipientId": "DHGK5np6LuMMErfRfC5CmjpGu3ME85c25n", + "timestamp": 24760420, + "asset": {}, + "vendorField": "Goose Voter - True Block Weight", + "senderPublicKey": "0265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c0", + "signature": "304502210083216e6969e068770e6d2fe5c244881002309df84d20290ddf3f858967ed010202202a479b3da5080ea475d310ff13494654b42db75886a8808bd211b4bdb9146a7a", + "signSignature": "3045022100e1dcab3406bbeb968146a4a391909ce41df9b71592a753b001e7c2ee1d382c5102202a74aeafd4a152ec61854636fbae829c41f1416c1e0637a0809408394973099f", + "id": "1e255f07dc25ce22d900ea81663c8f00d05a7b7c061e6fc3c731b05d642fa0b9", + "senderId": "DB8LnnQqYvHpG4WkGJ9AJWBYEct7G3yRZg", + "hop": 2, + "broadcast": false, + "blockId": "7176646138626297930" + }, + { + "type": 0, + "amount": 555750, + "fee": 10000000, + "recipientId": "D7pcLJNGe197ibmWEmT8mM9KKU1htrcDyW", + "timestamp": 24760417, + "asset": {}, + "vendorField": "Goose Voter - True Block Weight", + "senderPublicKey": "0265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c0", + "signature": "3045022100cd4fa9855227be11e17201419dacfbbd5d9946df8d6792a9488160025693821402207fb83969bad6a26959f437b5bb88e255b0a48eb04964d0c0d29f7ee94bd15e11", + "signSignature": "304402205f50c2991a17743d17ffbb09159cadc35a3f848044261842879ccf5be9d81c5e022023bf21c32fb6e94494104f15f8d3a942ab120d0abd6fb4c93790b68e1b307a79", + "id": "66336c61d6ec623f8a1d2fd156a0fac16a4fe93bb3fba337859355c2119923a8", + "senderId": "DB8LnnQqYvHpG4WkGJ9AJWBYEct7G3yRZg", + "hop": 2, + "broadcast": false, + "blockId": "7176646138626297930" + }, + { + "type": 0, + "amount": 555760, + "fee": 10000000, + "recipientId": "DD4yhwzryQdNGqKtezmycToQv63g27Tqqq", + "timestamp": 24760418, + "asset": {}, + "vendorField": "Goose Voter - True Block Weight", + "senderPublicKey": "0265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c0", + "signature": "30450221009c792062e13399ac6756b2e9f137194d06e106360ac0f3e24e55c7249cee0b3602205dc1d9c76d0451d1cb5a2396783a13e6d2d790ccfd49291e3d0a78349f7ea0e8", + "signSignature": "30440220083ba8a9af49b8be6e93794d71ec43ffc96a158375810e5d9f2478e71655315b0220278402ecaa1d224dab9f0f3b28295bbaea339c85c7400edafdc49df87439fc64", + "id": "78db36f7d79f51c67d7210ee3819dfb8d0d47b16a7484ebf55c5a055b17209a3", + "senderId": "DB8LnnQqYvHpG4WkGJ9AJWBYEct7G3yRZg", + "hop": 2, + "broadcast": false, + "blockId": "7176646138626297930" + }, + { + "type": 0, + "amount": 555760, + "fee": 10000000, + "recipientId": "D5LiYGXL5keycWuTF6AFFwSRc6Mt4uEHMu", + "timestamp": 24760419, + "asset": {}, + "vendorField": "Goose Voter - True Block Weight", + "senderPublicKey": "0265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c0", + "signature": "3044022063c65263e42be02bd9831b375c1d76a88332f00ed0557ecc1e7d2375ca40070902206797b5932c0bad68444beb5a38daa7cadf536ee2144e0d9777b812284d14374e", + "signSignature": "3045022100b04da6692f75d43229ffd8486c1517e8952d38b4c03dfac38b6b360190a5c33e0220776622e5f09f92a1258b4a011f22181c977b622b8d1bbb2f83b42f4126d00739", + "id": "83c80bb58777bb43f5037544b44ef69f191d3548fd1b2a00bed368f9f0d694c5", + "senderId": "DB8LnnQqYvHpG4WkGJ9AJWBYEct7G3yRZg", + "hop": 2, + "broadcast": false, + "blockId": "7176646138626297930" + }, + { + "type": 0, + "amount": 555750, + "fee": 10000000, + "recipientId": "DPopNLwMvv4zSjdZnqUk8HFH13Mcb7NbEK", + "timestamp": 24760416, + "asset": {}, + "vendorField": "Goose Voter - True Block Weight", + "senderPublicKey": "0265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c0", + "signature": "3045022100d4513c3608c2072e38e7a0e3bb8daf2cd5f7cc6fec9a5570dccd1eda696c591902202ecbbf3c9d0757be7b23c8b1cc6481c51600d158756c47fcb6f4a7f4893e31c4", + "signSignature": "304402201fed4858d0806dd32220960900a871dd2f60e1f623af75feef9b1034a9a0a46402205a29b27c63fcc3e1ee1e77ecbbf4dd6e7db09901e7a09b9fd490cd68d62392cb", + "id": "d2faf992fdd5da96d6d15038b6ddb65230338fa2096e45e44da51daad5e2f3ca", + "senderId": "DB8LnnQqYvHpG4WkGJ9AJWBYEct7G3yRZg", + "hop": 2, + "broadcast": false, + "blockId": "7176646138626297930" + } + ] + }, + "serialized": "0000000078d07901593a22002b324b8b33a85802070000007c5c3b0000000000801d2c040000000000c2eb0b00000000e00000003784b953afcf936bdffd43fdf005b5732b49c1fc6b11e195c364c20b2eb06282020f5df4d2bc736d12ce43af5b1663885a893fade7ee5e62b3cc59315a63e6a3253045022100eee6c37b5e592e99811d588532726353592923f347c701d52912e6d583443e400220277ffe38ad31e216ba0907c4738fed19b2071246b150c72c0a52bae4477ebe29", + "serializedFull": "0000000078d07901593a22002b324b8b33a85802070000007c5c3b0000000000801d2c040000000000c2eb0b00000000e00000003784b953afcf936bdffd43fdf005b5732b49c1fc6b11e195c364c20b2eb06282020f5df4d2bc736d12ce43af5b1663885a893fade7ee5e62b3cc59315a63e6a3253045022100eee6c37b5e592e99811d588532726353592923f347c701d52912e6d583443e400220277ffe38ad31e216ba0907c4738fed19b2071246b150c72c0a52bae4477ebe29ff000000fe00000000010000ff000000ff000000ff000000ff000000ff011e0062d079010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000001f476f6f736520566f746572202d205472756520426c6f636b20576569676874f07a080000000000000000001e40fad23d21da7a4fd4decb5c49726ea22f5e6bf6304402204f12469157b19edd06ba25fcad3d4a5ef5b057c23f9e02de4641e6f8eef0553e022010121ab282f83efe1043de9c16bbf2c6845a03684229a0d7c965ffb9abdfb97830450221008327862f0b9178d6665f7d6674978c5caf749649558d814244b1c66cdf945c40022015918134ef01fed3fe2a2efde3327917731344332724522c75c2799a14f78717ff011e0060d079010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000001f476f6f736520566f746572202d205472756520426c6f636b20576569676874e67a080000000000000000001e79c579fb08f448879c22fe965906b4e3b88d02ed304402205f82feb8c5d1d79c565c2ff7badb93e4c9827b132d135dda11cb25427d4ef8ac02205ff136f970533c4ec4c7d0cd1ea7e02d7b62629b66c6c93265f608d7f2389727304402207e912031fcc700d8a55fbc415993302a0d8e6aea128397141b640b6dba52331702201fd1ad3984e42af44f548907add6cb7ad72ca0070c8cc1d8dc9bbda208c56bd9ff011e0064d079010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000001f476f6f736520566f746572202d205472756520426c6f636b20576569676874fa7a080000000000000000001e84fee45dde2b11525afe192a2e991d014ff93a36304502210083216e6969e068770e6d2fe5c244881002309df84d20290ddf3f858967ed010202202a479b3da5080ea475d310ff13494654b42db75886a8808bd211b4bdb9146a7a3045022100e1dcab3406bbeb968146a4a391909ce41df9b71592a753b001e7c2ee1d382c5102202a74aeafd4a152ec61854636fbae829c41f1416c1e0637a0809408394973099fff011e0061d079010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000001f476f6f736520566f746572202d205472756520426c6f636b20576569676874e67a080000000000000000001e1d69583ede5ee82d220e74bffb36bae2ce762dfb3045022100cd4fa9855227be11e17201419dacfbbd5d9946df8d6792a9488160025693821402207fb83969bad6a26959f437b5bb88e255b0a48eb04964d0c0d29f7ee94bd15e11304402205f50c2991a17743d17ffbb09159cadc35a3f848044261842879ccf5be9d81c5e022023bf21c32fb6e94494104f15f8d3a942ab120d0abd6fb4c93790b68e1b307a79ff011e0062d079010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000001f476f6f736520566f746572202d205472756520426c6f636b20576569676874f07a080000000000000000001e56f9a37a859f4f84e93ce7593e809b15a524db2930450221009c792062e13399ac6756b2e9f137194d06e106360ac0f3e24e55c7249cee0b3602205dc1d9c76d0451d1cb5a2396783a13e6d2d790ccfd49291e3d0a78349f7ea0e830440220083ba8a9af49b8be6e93794d71ec43ffc96a158375810e5d9f2478e71655315b0220278402ecaa1d224dab9f0f3b28295bbaea339c85c7400edafdc49df87439fc64ff011e0063d079010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000001f476f6f736520566f746572202d205472756520426c6f636b20576569676874f07a080000000000000000001e0232a083c16aba4362dddec1b3050ffdd6d43f2e3044022063c65263e42be02bd9831b375c1d76a88332f00ed0557ecc1e7d2375ca40070902206797b5932c0bad68444beb5a38daa7cadf536ee2144e0d9777b812284d14374e3045022100b04da6692f75d43229ffd8486c1517e8952d38b4c03dfac38b6b360190a5c33e0220776622e5f09f92a1258b4a011f22181c977b622b8d1bbb2f83b42f4126d00739ff011e0060d079010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000001f476f6f736520566f746572202d205472756520426c6f636b20576569676874e67a080000000000000000001eccc4fce0dc95f9951ee40c09a7ae807746cf51403045022100d4513c3608c2072e38e7a0e3bb8daf2cd5f7cc6fec9a5570dccd1eda696c591902202ecbbf3c9d0757be7b23c8b1cc6481c51600d158756c47fcb6f4a7f4893e31c4304402201fed4858d0806dd32220960900a871dd2f60e1f623af75feef9b1034a9a0a46402205a29b27c63fcc3e1ee1e77ecbbf4dd6e7db09901e7a09b9fd490cd68d62392cb" +} diff --git a/packages/core-debugger-cli/__tests__/__fixtures__/identities.json b/packages/core-debugger-cli/__tests__/__fixtures__/identities.json new file mode 100644 index 0000000000..2ae9e9e891 --- /dev/null +++ b/packages/core-debugger-cli/__tests__/__fixtures__/identities.json @@ -0,0 +1,6 @@ +{ + "passphrase": "this is a top secret passphrase", + "publicKey": "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", + "privateKey": "d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712", + "address": "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib" +} diff --git a/packages/core-debugger-cli/__tests__/__fixtures__/transaction-second.json b/packages/core-debugger-cli/__tests__/__fixtures__/transaction-second.json new file mode 100644 index 0000000000..7f6a589dca --- /dev/null +++ b/packages/core-debugger-cli/__tests__/__fixtures__/transaction-second.json @@ -0,0 +1,15 @@ +{ + "data": { + "type": 0, + "amount": 200000000, + "fee": 10000000, + "recipientId": "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", + "timestamp": 41268430, + "asset": {}, + "senderPublicKey": "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", + "signature": "304402206da703bfcc11ec2ccb3f363fa0e23fc64050fdf68e1f1852b7d4a5bb07824166022031ed1d86b586a79f9c1e5010dbc4f4cb36641c62a196536f90b1dfd6be1c9868", + "signSignature": "304402200759b6f9de5257aa3fcf54b9cd7a426a00af9368b7ea3d5ea2b13a91b97fb277022076e4d2d7deb9bdd8245b2533cab1eeeef72981e18576ef8455a61ee3e6f3fb57", + "id": "bb8054b6298d659d4b5d655e82de17b3504ba27655ec3d6e35d311f3104b1c43" + }, + "serialized": "ff011e00ceb47502034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19280969800000000000000c2eb0b00000000000000001e0995750207ecaf0ccf251c1265b92ad84f553662304402206da703bfcc11ec2ccb3f363fa0e23fc64050fdf68e1f1852b7d4a5bb07824166022031ed1d86b586a79f9c1e5010dbc4f4cb36641c62a196536f90b1dfd6be1c9868304402200759b6f9de5257aa3fcf54b9cd7a426a00af9368b7ea3d5ea2b13a91b97fb277022076e4d2d7deb9bdd8245b2533cab1eeeef72981e18576ef8455a61ee3e6f3fb57" +} diff --git a/packages/core-debugger-cli/__tests__/__fixtures__/transaction.json b/packages/core-debugger-cli/__tests__/__fixtures__/transaction.json new file mode 100644 index 0000000000..74f4904255 --- /dev/null +++ b/packages/core-debugger-cli/__tests__/__fixtures__/transaction.json @@ -0,0 +1,14 @@ +{ + "data": { + "type": 0, + "amount": 200000000, + "fee": 10000000, + "recipientId": "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", + "timestamp": 41268326, + "asset": {}, + "senderPublicKey": "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", + "signature": "3044022002994b30e08b58825c8c16ebf2cc693cfe706fb26571674784ead098accc89d702205b79dedc752a84504ecfe4b9e1292997f22260ee4daa102d2d9a61432d93b286", + "id": "da61c6cba363cc39baa0ca3f9ba2c5db81b9805045bd0b9fc58af07ad4206856" + }, + "serialized": "ff011e0066b47502034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed19280969800000000000000c2eb0b00000000000000001e0995750207ecaf0ccf251c1265b92ad84f5536623044022002994b30e08b58825c8c16ebf2cc693cfe706fb26571674784ead098accc89d702205b79dedc752a84504ecfe4b9e1292997f22260ee4daa102d2d9a61432d93b286" +} diff --git a/packages/core-debugger-cli/__tests__/commands/deserialize.test.js b/packages/core-debugger-cli/__tests__/commands/deserialize.test.js new file mode 100644 index 0000000000..d46609efe5 --- /dev/null +++ b/packages/core-debugger-cli/__tests__/commands/deserialize.test.js @@ -0,0 +1,80 @@ +const testSubject = require('../../lib/commands/deserialize') +const fixtureBlock = require('../__fixtures__/block.json') +const fixtureTransaction = require('../__fixtures__/transaction.json') + +describe('Commands - Deserialize', () => { + it('should be a function', () => { + expect(testSubject).toBeFunction() + }) + + it('should deserialize a block (not-full)', () => { + const actual = JSON.parse( + testSubject({ + data: fixtureBlock.serialized, + type: 'block', + }), + ) + + expect(actual.data.version).toBe(fixtureBlock.data.version) + expect(actual.data.timestamp).toBe(fixtureBlock.data.timestamp) + expect(actual.data.height).toBe(fixtureBlock.data.height) + expect(actual.data.previousBlock).toBe(fixtureBlock.data.previousBlock) + expect(actual.data.numberOfTransactions).toBe( + fixtureBlock.data.numberOfTransactions, + ) + expect(actual.data.totalAmount).toBe(fixtureBlock.data.totalAmount) + expect(actual.data.totalFee).toBe(fixtureBlock.data.totalFee) + expect(actual.data.reward).toBe(fixtureBlock.data.reward) + expect(actual.data.payloadLength).toBe(fixtureBlock.data.payloadLength) + expect(actual.data.payloadHash).toBe(fixtureBlock.data.payloadHash) + expect(actual.data.generatorPublicKey).toBe( + fixtureBlock.data.generatorPublicKey, + ) + expect(actual.data.blockSignature).toBe(fixtureBlock.data.blockSignature) + }) + + it('should deserialize a block (full)', () => { + const actual = JSON.parse( + testSubject({ + data: fixtureBlock.serializedFull, + type: 'block', + }), + ) + + expect(actual.data.version).toBe(fixtureBlock.data.version) + expect(actual.data.timestamp).toBe(fixtureBlock.data.timestamp) + expect(actual.data.height).toBe(fixtureBlock.data.height) + expect(actual.data.previousBlock).toBe(fixtureBlock.data.previousBlock) + expect(actual.data.numberOfTransactions).toBe( + fixtureBlock.data.numberOfTransactions, + ) + expect(actual.data.totalAmount).toBe(fixtureBlock.data.totalAmount) + expect(actual.data.totalFee).toBe(fixtureBlock.data.totalFee) + expect(actual.data.reward).toBe(fixtureBlock.data.reward) + expect(actual.data.payloadLength).toBe(fixtureBlock.data.payloadLength) + expect(actual.data.payloadHash).toBe(fixtureBlock.data.payloadHash) + expect(actual.data.generatorPublicKey).toBe( + fixtureBlock.data.generatorPublicKey, + ) + expect(actual.data.blockSignature).toBe(fixtureBlock.data.blockSignature) + expect(actual.transactions).toHaveLength(7) + }) + + it('should deserialize a transaction', () => { + const actual = JSON.parse( + testSubject({ + data: fixtureTransaction.serialized, + type: 'transaction', + }), + ) + + expect(actual.type).toBe(fixtureTransaction.data.type) + expect(+actual.amount).toBe(fixtureTransaction.data.amount) + expect(+actual.fee).toBe(fixtureTransaction.data.fee) + expect(actual.recipientId).toBe(fixtureTransaction.data.recipientId) + expect(actual.timestamp).toBe(fixtureTransaction.data.timestamp) + expect(actual.senderPublicKey).toBe(fixtureTransaction.data.senderPublicKey) + expect(actual.signature).toBe(fixtureTransaction.data.signature) + expect(actual.id).toBe(fixtureTransaction.data.id) + }) +}) diff --git a/packages/core-debugger-cli/__tests__/commands/identity.test.js b/packages/core-debugger-cli/__tests__/commands/identity.test.js new file mode 100644 index 0000000000..1852332ce6 --- /dev/null +++ b/packages/core-debugger-cli/__tests__/commands/identity.test.js @@ -0,0 +1,58 @@ +const testSubject = require('../../lib/commands/identity') +const fixtureIdentities = require('../__fixtures__/identities.json') + +describe('Commands - Identity', () => { + it('should be a function', () => { + expect(testSubject).toBeFunction() + }) + + it('should return identities from passphrase', () => { + const expected = { + passphrase: 'this is a top secret passphrase', + publicKey: + '034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192', + privateKey: + 'd8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712', + address: 'D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib', + } + + expect( + testSubject({ + data: fixtureIdentities.passphrase, + type: 'passphrase', + }), + ).toEqual(expected) + }) + + it('should return identities from privateKey', () => { + const expected = { + publicKey: + '034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192', + privateKey: + 'd8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712', + address: 'D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib', + } + + expect( + testSubject({ + data: fixtureIdentities.privateKey, + type: 'privateKey', + }), + ).toEqual(expected) + }) + + it('should return identities from publicKey', () => { + const expected = { + publicKey: + '034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192', + address: 'D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib', + } + + expect( + testSubject({ + data: fixtureIdentities.publicKey, + type: 'publicKey', + }), + ).toEqual(expected) + }) +}) diff --git a/packages/core-debugger-cli/__tests__/commands/serialize.test.js b/packages/core-debugger-cli/__tests__/commands/serialize.test.js new file mode 100644 index 0000000000..74c12f82a1 --- /dev/null +++ b/packages/core-debugger-cli/__tests__/commands/serialize.test.js @@ -0,0 +1,38 @@ +const testSubject = require('../../lib/commands/serialize') +const fixtureBlock = require('../__fixtures__/block.json') +const fixtureTransaction = require('../__fixtures__/transaction.json') + +describe('Commands - Serialize', () => { + it('should be a function', () => { + expect(testSubject).toBeFunction() + }) + + it('should serialize a block (not-full)', () => { + expect( + testSubject({ + data: JSON.stringify(fixtureBlock.data), + type: 'block', + full: false, + }), + ).toEqual(fixtureBlock.serialized) + }) + + it('should serialize a block (full)', () => { + expect( + testSubject({ + data: JSON.stringify(fixtureBlock.data), + type: 'block', + full: true, + }), + ).toEqual(fixtureBlock.serializedFull) + }) + + it('should serialize a transaction', () => { + expect( + testSubject({ + data: JSON.stringify(fixtureTransaction.data), + type: 'transaction', + }), + ).toEqual(fixtureTransaction.serialized) + }) +}) diff --git a/packages/core-debugger-cli/__tests__/commands/verify-second.test.js b/packages/core-debugger-cli/__tests__/commands/verify-second.test.js new file mode 100644 index 0000000000..57ed595876 --- /dev/null +++ b/packages/core-debugger-cli/__tests__/commands/verify-second.test.js @@ -0,0 +1,18 @@ +const testSubject = require('../../lib/commands/verify-second') +const fixtureTransaction = require('../__fixtures__/transaction-second.json') + +describe('Commands - Verify Second', () => { + it('should be a function', () => { + expect(testSubject).toBeFunction() + }) + + it('should verify a second signature', () => { + expect( + testSubject({ + data: fixtureTransaction.serialized, + publicKey: + '03699e966b2525f9088a6941d8d94f7869964a000efe65783d78ac82e1199fe609', + }), + ).toBeTrue() + }) +}) diff --git a/packages/core-debugger-cli/__tests__/commands/verify.test.js b/packages/core-debugger-cli/__tests__/commands/verify.test.js new file mode 100644 index 0000000000..458933ebbc --- /dev/null +++ b/packages/core-debugger-cli/__tests__/commands/verify.test.js @@ -0,0 +1,27 @@ +const testSubject = require('../../lib/commands/verify') +const fixtureBlock = require('../__fixtures__/block.json') +const fixtureTransaction = require('../__fixtures__/transaction.json') + +describe('Commands - Verify', () => { + it('should be a function', () => { + expect(testSubject).toBeFunction() + }) + + it('should verify a block', () => { + expect( + testSubject({ + data: fixtureBlock.serializedFull, + type: 'block', + }), + ).toBeTrue() + }) + + it('should verify a transaction', () => { + expect( + testSubject({ + data: fixtureTransaction.serialized, + type: 'transaction', + }), + ).toBeTrue() + }) +}) diff --git a/packages/core-debugger-cli/bin/debugger b/packages/core-debugger-cli/bin/debugger new file mode 100755 index 0000000000..b07d0c62d5 --- /dev/null +++ b/packages/core-debugger-cli/bin/debugger @@ -0,0 +1,51 @@ +#!/usr/bin/env node + +const app = require('commander') + +app.version(require('../package.json').version) + +const registerCommand = (name, description) => { + return app + .command(name) + .description(description) + .option('-l, --log', 'log the data to the console') + .option('-c, --copy', 'copy the data to the clipboard') +} + +registerCommand('ser', 'serialize the given JSON') + .option('-d, --data ', 'JSON blob to serialize') + .option('-t, --type ', 'transaction or block', 'transaction') + .action(options => require('../lib/commands/serialize')(options)) + +registerCommand('des', 'deserialize the given HEX') + .option('-d, --data ', 'the HEX blob to deserialize') + .option('-t, --type ', 'transaction or block', 'transaction') + .action(options => require('../lib/commands/deserialize')(options)) + +registerCommand('verify', 'verify the given HEX') + .option('-d, --data ', 'the HEX blob to deserialize and verify') + .option('-t, --type ', 'transaction or block', 'transaction') + .action(options => require('../lib/commands/verify')(options)) + +registerCommand('verify-second', 'verify a second signature of a transaction') + .option('-d, --data ', 'the transaction HEX blob to deserialize and verify') + .option('-p, --publicKey ', 'the publicKey of the second signature in HEX') + .action(options => require('../lib/commands/verify-second')(options)) + +registerCommand('identity', 'get identities from the given input') + .option('-d, --data ', 'the data to get the identities from') + .option('-t, --type ', 'the input type is either of passphrase, privateKey or publicKey', 'passphrase') + .option('-n, --network ', 'the network version used for calculating the address.') + .action(options => require('../lib/commands/identity')(options)) + +app + .command('*') + .action(env => { + app.help() + }) + +app.parse(process.argv) + +if (app.args.length === 0) { + app.help() +} diff --git a/packages/core-debugger-cli/jest.config.js b/packages/core-debugger-cli/jest.config.js new file mode 100644 index 0000000000..57770a97bb --- /dev/null +++ b/packages/core-debugger-cli/jest.config.js @@ -0,0 +1,12 @@ +module.exports = { + testEnvironment: 'node', + bail: false, + verbose: true, + testMatch: ['**/__tests__/**/*.test.js'], + moduleFileExtensions: ['js', 'json'], + collectCoverage: false, + coverageDirectory: '/.coverage', + collectCoverageFrom: ['lib/**/*.js', '!**/node_modules/**'], + watchman: false, + setupTestFrameworkScriptFile: 'jest-extended', +} diff --git a/packages/core-debugger-cli/lib/commands/deserialize.js b/packages/core-debugger-cli/lib/commands/deserialize.js new file mode 100644 index 0000000000..5df757b104 --- /dev/null +++ b/packages/core-debugger-cli/lib/commands/deserialize.js @@ -0,0 +1,16 @@ +const { + models: { Block, Transaction }, +} = require('@arkecosystem/crypto') +const handleOutput = require('../utils/handle-output') + +module.exports = opts => { + let deserialized + + if (opts.type === 'transaction') { + deserialized = new Transaction(opts.data) + } else { + deserialized = new Block(opts.data) + } + + return handleOutput(opts, JSON.stringify(deserialized, null, 4)) +} diff --git a/packages/core-debugger-cli/lib/commands/identity.js b/packages/core-debugger-cli/lib/commands/identity.js new file mode 100644 index 0000000000..594243da9d --- /dev/null +++ b/packages/core-debugger-cli/lib/commands/identity.js @@ -0,0 +1,30 @@ +const { crypto } = require('@arkecosystem/crypto') +const handleOutput = require('../utils/handle-output') + +module.exports = opts => { + let output + + if (opts.type === 'passphrase') { + const keys = crypto.getKeys(opts.data) + output = { + passphrase: opts.data, + publicKey: keys.publicKey, + privateKey: keys.privateKey, + address: crypto.getAddress(keys.publicKey, opts.network), + } + } else if (opts.type === 'privateKey') { + const keys = crypto.getKeysByPrivateKey(opts.data) + output = { + publicKey: keys.publicKey, + privateKey: keys.privateKey, + address: crypto.getAddress(keys.publicKey, opts.network), + } + } else if (opts.type === 'publicKey') { + output = { + publicKey: opts.data, + address: crypto.getAddress(opts.data, opts.network), + } + } + + return handleOutput(opts, output) +} diff --git a/packages/core-debugger-cli/lib/commands/serialize.js b/packages/core-debugger-cli/lib/commands/serialize.js new file mode 100644 index 0000000000..561c32a658 --- /dev/null +++ b/packages/core-debugger-cli/lib/commands/serialize.js @@ -0,0 +1,12 @@ +const { + models: { Block, Transaction }, +} = require('@arkecosystem/crypto') +const handleOutput = require('../utils/handle-output') + +module.exports = opts => { + const serialized = opts.type === 'transaction' + ? Transaction.serialize(JSON.parse(opts.data)) + : Block[opts.full ? 'serializeFull' : 'serialize'](JSON.parse(opts.data)) + + return handleOutput(opts, serialized.toString('hex')) +} diff --git a/packages/core-debugger-cli/lib/commands/verify-second.js b/packages/core-debugger-cli/lib/commands/verify-second.js new file mode 100644 index 0000000000..8a312efd52 --- /dev/null +++ b/packages/core-debugger-cli/lib/commands/verify-second.js @@ -0,0 +1,13 @@ +const { + crypto, + models: { Transaction }, +} = require('@arkecosystem/crypto') +const handleOutput = require('../utils/handle-output') + +module.exports = opts => { + const transaction = new Transaction(opts.data) + const publicKey = opts.publicKey + + const output = crypto.verifySecondSignature(transaction, publicKey) + return handleOutput(opts, output) +} diff --git a/packages/core-debugger-cli/lib/commands/verify.js b/packages/core-debugger-cli/lib/commands/verify.js new file mode 100644 index 0000000000..33efadd177 --- /dev/null +++ b/packages/core-debugger-cli/lib/commands/verify.js @@ -0,0 +1,16 @@ +const { + models: { Block, Transaction }, +} = require('@arkecosystem/crypto') +const handleOutput = require('../utils/handle-output') + +module.exports = opts => { + const deserialized = opts.type === 'transaction' + ? new Transaction(opts.data) + : new Block(Block.deserialize(opts.data)) + + const output = opts.type === 'transaction' + ? deserialized.verify() + : deserialized.verify().verified + + return handleOutput(opts, output) +} diff --git a/packages/core-debugger-cli/lib/utils/copy-to-clipboard.js b/packages/core-debugger-cli/lib/utils/copy-to-clipboard.js new file mode 100644 index 0000000000..68720fb77f --- /dev/null +++ b/packages/core-debugger-cli/lib/utils/copy-to-clipboard.js @@ -0,0 +1,3 @@ +const clipboardy = require('clipboardy') + +module.exports = data => clipboardy.writeSync(JSON.stringify(data)) diff --git a/packages/core-debugger-cli/lib/utils/handle-output.js b/packages/core-debugger-cli/lib/utils/handle-output.js new file mode 100644 index 0000000000..32387f9eab --- /dev/null +++ b/packages/core-debugger-cli/lib/utils/handle-output.js @@ -0,0 +1,13 @@ +const copyToClipboard = require('../utils/copy-to-clipboard') + +module.exports = (opts, data) => { + if (opts.copy) { + return copyToClipboard(data) + } + + if (opts.log) { + return console.info(data) + } + + return data +} diff --git a/packages/core-debugger-cli/package.json b/packages/core-debugger-cli/package.json new file mode 100644 index 0000000000..4e975b69fc --- /dev/null +++ b/packages/core-debugger-cli/package.json @@ -0,0 +1,34 @@ +{ + "name": "@arkecosystem/core-debugger-cli", + "description": "Debugger CLI for Ark Core", + "version": "0.2.0", + "contributors": [ + "Brian Faust " + ], + "license": "MIT", + "main": "lib/index.js", + "bin": { + "ark:debugger": "./bin/debugger" + }, + "scripts": { + "start": "./bin/debugger", + "test": "cross-env ARK_ENV=test jest --runInBand --detectOpenHandles", + "test:coverage": "cross-env ARK_ENV=test jest --coverage --coveragePathIgnorePatterns='/(defaults.js|index.js)$' --runInBand --detectOpenHandles", + "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand", + "test:watch": "cross-env ARK_ENV=test jest --runInBand --watch", + "test:watch:all": "cross-env ARK_ENV=test jest --runInBand --watchAll", + "lint": "eslint ./ --fix", + "depcheck": "depcheck ./ --ignores=commander" + }, + "dependencies": { + "@arkecosystem/crypto": "~0.2", + "clipboardy": "^1.2.3", + "commander": "^2.19.0" + }, + "publishConfig": { + "access": "public" + }, + "engines": { + "node": ">=10.x" + } +} diff --git a/packages/core-deployer/CHANGELOG.md b/packages/core-deployer/CHANGELOG.md index 127cc35e42..7d7b5529b2 100644 --- a/packages/core-deployer/CHANGELOG.md +++ b/packages/core-deployer/CHANGELOG.md @@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Unreleased -## 0.0.1 - 2018-05-31 +## 0.2.0 - 2018-12-03 + +### Changed + +- Handle numbers as `BigNumber` instances +- Updated `@arkecosystem/crypto` to `0.2.0` +- Dropped node.js 9 as minimum requirement in favour of node.js 10 + +## 0.1.1 - 2018-07-26 + ### Added + - initial release diff --git a/packages/core-deployer/README.md b/packages/core-deployer/README.md index 316d0834d2..afa712cd5c 100644 --- a/packages/core-deployer/README.md +++ b/packages/core-deployer/README.md @@ -1,12 +1,12 @@ -![ARK Core](https://i.imgur.com/1aP6F2o.png) +# Ark Core - Deployer -# ARK Core - Deployer +

+ +

-## Installation +## Documentation -```bash -yarn add @arkecosystem/core-deployer -``` +You can find installation instructions and detailed instructions on how to use this package at the [dedicated documentation site](https://docs.ark.io/guidebook/core/plugins/core-deployer.html). ## Security diff --git a/packages/core-deployer/__tests__/builder/genesis-block.test.js b/packages/core-deployer/__tests__/builder/genesis-block.test.js index 2f68c3920d..7357a779b7 100644 --- a/packages/core-deployer/__tests__/builder/genesis-block.test.js +++ b/packages/core-deployer/__tests__/builder/genesis-block.test.js @@ -1,5 +1,3 @@ -'use strict' - const GenesisBlockBuilder = require('../../lib/builder/genesis-block') const network = require('../../../crypto/lib/networks/ark/testnet') @@ -12,7 +10,7 @@ let delegateWallets beforeEach(() => { builder = new GenesisBlockBuilder(network, { totalPremine: 2100000000000000, - activeDelegates: 2 + activeDelegates: 2, }) delegateWallets = builder.__buildDelegates() @@ -34,15 +32,19 @@ describe('Genesis Block Builder', () => { expect(genesis).toContainAllKeys([ 'genesisBlock', 'genesisWallet', - 'delegatePassphrases' + 'delegatePassphrases', ]) }) it('should call the expected methods', () => { builder.__createWallet = jest.fn(builder.__createWallet) builder.__buildDelegates = jest.fn(builder.__buildDelegates) - builder.__buildDelegateTransactions = jest.fn(builder.__buildDelegateTransactions) - builder.__createTransferTransaction = jest.fn(builder.__createTransferTransaction) + builder.__buildDelegateTransactions = jest.fn( + builder.__buildDelegateTransactions, + ) + builder.__createTransferTransaction = jest.fn( + builder.__createTransferTransaction, + ) builder.__createGenesisBlock = jest.fn(builder.__createGenesisBlock) builder.generate() @@ -67,11 +69,7 @@ describe('Genesis Block Builder', () => { }) it('should return a wallet object', () => { - expect(wallet).toContainAllKeys([ - 'address', - 'keys', - 'passphrase' - ]) + expect(wallet).toContainAllKeys(['address', 'keys', 'passphrase']) }) it('should have a valid address', () => { @@ -95,7 +93,7 @@ describe('Genesis Block Builder', () => { 'address', 'keys', 'passphrase', - 'username' + 'username', ]) }) @@ -104,7 +102,9 @@ describe('Genesis Block Builder', () => { }) it('should have a valid username', () => { - expect(delegateWallet.username).toEqual(expect.stringMatching(/^[a-z0-9!@$&_.]+$/)) + expect(delegateWallet.username).toEqual( + expect.stringMatching(/^[a-z0-9!@$&_.]+$/), + ) }) it('should call the expected methods', () => { @@ -140,13 +140,17 @@ describe('Genesis Block Builder', () => { }) it('should return an array of 2', () => { - const delegateTransactions = builder.__buildDelegateTransactions(delegateWallets) + const delegateTransactions = builder.__buildDelegateTransactions( + delegateWallets, + ) expect(delegateTransactions).toBeArrayOfSize(2) }) it('should call the expected methods', () => { - builder.__createDelegateTransaction = jest.fn(builder.__createDelegateTransaction) + builder.__createDelegateTransaction = jest.fn( + builder.__createDelegateTransaction, + ) builder.__buildDelegateTransactions(delegateWallets) @@ -160,18 +164,24 @@ describe('Genesis Block Builder', () => { }) it('should return a transaction object', () => { - const transferTransaction = builder.__createTransferTransaction(delegateWallet, wallet, 10) + const transferTransaction = builder.__createTransferTransaction( + delegateWallet, + wallet, + 10, + ) expect(transferTransaction).toContainEntries([ ['type', 0], ['amount', 10], ['fee', 0], - ['recipientId', wallet.address] + ['recipientId', wallet.address], ]) }) it('should call the expected methods', () => { - builder.__formatGenesisTransaction = jest.fn(builder.__formatGenesisTransaction) + builder.__formatGenesisTransaction = jest.fn( + builder.__formatGenesisTransaction, + ) builder.__createTransferTransaction(delegateWallet, wallet, 10) @@ -185,21 +195,31 @@ describe('Genesis Block Builder', () => { }) it('should return a transaction object', () => { - const delegateTransaction = builder.__createDelegateTransaction(delegateWallet) + const delegateTransaction = builder.__createDelegateTransaction( + delegateWallet, + ) expect(delegateTransaction).toContainEntries([ ['type', 2], ['amount', 0], ['fee', 0], - ['senderId', delegateWallet.address] + ['senderId', delegateWallet.address], ]) - expect(delegateTransaction.asset.delegate).toHaveProperty('username', delegateWallet.username) - expect(delegateTransaction.asset.delegate).toHaveProperty('publicKey', delegateWallet.keys.publicKey) + expect(delegateTransaction.asset.delegate).toHaveProperty( + 'username', + delegateWallet.username, + ) + expect(delegateTransaction.asset.delegate).toHaveProperty( + 'publicKey', + delegateWallet.keys.publicKey, + ) }) it('should call the expected methods', () => { - builder.__formatGenesisTransaction = jest.fn(builder.__formatGenesisTransaction) + builder.__formatGenesisTransaction = jest.fn( + builder.__formatGenesisTransaction, + ) builder.__createDelegateTransaction(delegateWallet) @@ -216,7 +236,7 @@ describe('Genesis Block Builder', () => { const genesisBlock = builder.__createGenesisBlock({ keys: wallet.keys, transactions: [], - timestamp: 0 + timestamp: 0, }) expect(genesisBlock).toContainAllKeys([ @@ -233,7 +253,7 @@ describe('Genesis Block Builder', () => { 'previousBlock', 'generatorPublicKey', 'transactions', - 'height' + 'height', ]) }) @@ -244,7 +264,7 @@ describe('Genesis Block Builder', () => { builder.__createGenesisBlock({ keys: wallet.keys, transactions: [], - timestamp: 0 + timestamp: 0, }) expect(builder.__getBlockId).toHaveBeenCalledTimes(1) diff --git a/packages/core-deployer/bin/deployer b/packages/core-deployer/bin/deployer index 6641efa06b..ccee9e2f02 100755 --- a/packages/core-deployer/bin/deployer +++ b/packages/core-deployer/bin/deployer @@ -7,7 +7,12 @@ const Joi = require('joi') const fs = require('fs-extra') const os = require('os') const path = require('path') -const { getRandomNumber, logger, updateConfig, writeEnv } = require('../lib/utils') +const { + getRandomNumber, + logger, + updateConfig, + writeEnv, +} = require('../lib/utils') const GenesisBlockBuilder = require('../lib/builder/genesis-block') process.env.ARK_PATH_CONFIG = path.resolve(os.homedir(), '.ark') @@ -23,30 +28,89 @@ commander .option('--dbPort ', 'Database port', 5432) .option('--dbUsername ', 'Database username', 'node') .option('--dbPassword ', 'Database password', 'password') - .option('--dbDatabase ', 'Database name', `ark_${commander.name.toLowerCase()}`) - .option('--explorerUrl ', 'URL to link to explorer', 'http://localhost:4200') - .option('--activeDelegates ', 'How many forgers for the network [51]', 51) + .option( + '--dbDatabase ', + 'Database name', + `ark_${commander.name.toLowerCase()}`, + ) + .option( + '--explorerUrl ', + 'URL to link to explorer', + 'http://localhost:4200', + ) + .option( + '--activeDelegates ', + 'How many forgers for the network [51]', + 51, + ) .option('--feeTransfer ', 'Fee for sending Transaction', 10000000) .option('--feeVote ', 'Fee for Vote Transaction', 100000000) - .option('--feeSecondSignature ', 'Fee for Second Passphrase Transaction', 500000000) - .option('--feeDelegateRegistration ', 'Fee for Register Delegate Transaction', 2500000000) - .option('--feeMultiSignature ', 'Fee for Multisignature Transaction', 500000000) - .option('--epoch ', 'Set Epoch based on time the chain was created', '2017-02-21T13:00:00.000Z') - .option('--rewardHeight ', 'Block Height when Forgers receive Rewards [1]', 1) - .option('--rewardPerBlock ', 'How many Rewarded Tokens per Forged Block [200000000 (2)]', 200000000) + .option( + '--feeSecondSignature ', + 'Fee for Second Passphrase Transaction', + 500000000, + ) + .option( + '--feeDelegateRegistration ', + 'Fee for Register Delegate Transaction', + 2500000000, + ) + .option( + '--feeMultiSignature ', + 'Fee for Multisignature Transaction', + 500000000, + ) + .option( + '--epoch ', + 'Set Epoch based on time the chain was created', + '2017-02-21T13:00:00.000Z', + ) + .option( + '--rewardHeight ', + 'Block Height when Forgers receive Rewards [1]', + 1, + ) + .option( + '--rewardPerBlock ', + 'How many Rewarded Tokens per Forged Block [200000000 (2)]', + 200000000, + ) .option('--blocktime ', 'Time per block (seconds) [8]', 8) .option('--token ', 'Token Name [CHAIN]', 'CHAIN') .option('--symbol ', 'Symbol for Token [C]', 'C') .option('--prefixHash ', 'Address Prefix Hash [28]', 28) - .option('--transactionsPerBlock ', 'Max Transaction count per Block [50]', 50) - .option('--wifPrefix ', 'Prefix for generating a WIF [rand(1, 255)]', getRandomNumber(1, 255)) - .option('--totalPremine ', 'How many tokens initially added to genesis account [2100000000000000 (21 million)]', 2100000000000000) + .option( + '--transactionsPerBlock ', + 'Max Transaction count per Block [50]', + 50, + ) + .option( + '--wifPrefix ', + 'Prefix for generating a WIF [rand(1, 255)]', + getRandomNumber(1, 255), + ) + .option( + '--totalPremine ', + 'How many tokens initially added to genesis account [2100000000000000 (21 million)]', + 2100000000000000, + ) // .option('--max-tokens-per-account', 'Max amount of tokens per account [12500000000000000 (125 million)]') - .option('--overwriteConfig', 'Overwrite current deployer config files [off]', false) - .option('--configPath ', 'Deployer config path destination [~/.ark/deployer]', `${process.env.ARK_PATH_CONFIG}/deployer`) + .option( + '--overwriteConfig', + 'Overwrite current deployer config files [off]', + false, + ) + .option( + '--configPath ', + 'Deployer config path destination [~/.ark/deployer]', + `${process.env.ARK_PATH_CONFIG}/deployer`, + ) .parse(process.argv) -const { error, value } = Joi.validate(commander, require('../lib/schema.js'), { allowUnknown: true, convert: true }) +const { error, value } = Joi.validate(commander, require('../lib/schema.js'), { + allowUnknown: true, + convert: true, +}) const options = value if (error) { @@ -58,13 +122,23 @@ if (fs.existsSync(options.configPath)) { if (options.overwriteConfig) { fs.removeSync(options.configPath) } else { - logger.error(`Deployer config already exists in '${options.configPath}' - to overwrite, use the '--overwriteConfig' flag`) + logger.error( + `Deployer config already exists in '${ + options.configPath + }' - to overwrite, use the '--overwriteConfig' flag`, + ) process.exit(1) } } fs.ensureDirSync(options.configPath) -fs.copySync(path.resolve(__dirname, `../../core/lib/config/${options.network}`), options.configPath) -const networkPath = path.resolve(__dirname, `../../crypto/lib/networks/ark/${options.network}.json`) +fs.copySync( + path.resolve(__dirname, `../../core/lib/config/${options.network}`), + options.configPath, +) +const networkPath = path.resolve( + __dirname, + `../../crypto/lib/networks/ark/${options.network}.json`, +) if (!fs.existsSync(networkPath)) { logger.error(`Network '${options.network}' does not exist`) process.exit(1) @@ -82,53 +156,57 @@ let networkConfig = { block: { version: 0, maxTransactions: options.transactionsPerBlock, - maxPayload: 2097152 + maxPayload: 2097152, }, epoch: options.epoch, activeDelegates: options.activeDelegates, fees: { - dynamic : false, - transfer: options.feeTransfer, - secondSignature: options.feeVote, - delegateRegistration: options.feeSecondSignature, - vote: options.feeDelegateRegistration, - multiSignature: options.feeMultiSignature, - ipfs: 0, - timelockTransfer: 0, - multiPayment: 0, - delegateResignation: 0 + dynamic: false, + dynamicFees: { + minFeePool: 1000, + minFeeBroadcast: 1000, + addonBytes: { + transfer: 100, + secondSignature: 250, + delegateRegistration: 500, + vote: 100, + multiSignature: 500, + ipfs: 250, + timelockTransfer: 500, + multiPayment: 500, + delegateResignation: 500, + }, + }, + staticFees: { + transfer: options.feeTransfer, + secondSignature: options.feeVote, + delegateRegistration: options.feeSecondSignature, + vote: options.feeDelegateRegistration, + multiSignature: options.feeMultiSignature, + ipfs: 0, + timelockTransfer: 0, + multiPayment: 0, + delegateResignation: 0, + }, }, - dynamicOffsets: { - transfer: 100, - secondSignature: 250, - delegateRegistration: 500, - vote: 100, - multiSignature: 500, - ipfs: 250, - timelockTransfer: 500, - multiPayment: 500, - delegateResignation: 500 - } - } + }, ], client: { token: options.token, symbol: options.symbol, explorer: options.explorerUrl, }, - exceptions: {} + exceptions: {}, } const network = updateConfig('network.json', networkConfig, options.configPath) -const genesis = (new GenesisBlockBuilder(network, options)).generate() +const genesis = new GenesisBlockBuilder(network, options).generate() network.nethash = genesis.genesisBlock.payloadHash if (options.rewardHeight === 1) { - network.constants = [ - network.constants[0] - ] + network.constants = [network.constants[0]] network.constants[0].height = options.rewardHeight network.constants[0].reward = options.rewardPerBlock } else { @@ -136,32 +214,58 @@ if (options.rewardHeight === 1) { network.constants[1].reward = options.rewardPerBlock } -const requestNodeIp = options.nodeIp === '0.0.0.0' ? '127.0.0.1' : options.nodeIp +const requestNodeIp = + options.nodeIp === '0.0.0.0' ? '127.0.0.1' : options.nodeIp updateConfig('network.json', networkConfig, options.configPath) -updateConfig('peers.json', { - minimumVersion: '>=1.1.1', - minimumNetworkReach: 1, - list: [{ - ip: requestNodeIp, - port: options.p2pPort - }], - sources: [] -}, options.configPath) - -updateConfig('genesisWallet.json', { - address: genesis.genesisWallet.address, - passphrase: genesis.genesisWallet.passphrase -}, options.configPath, true) -updateConfig('genesisBlock.json', genesis.genesisBlock, options.configPath, true) -updateConfig('delegates.json', { - secrets: genesis.delegatePassphrases -}, options.configPath, true) - -updateConfig('server.json', { - port: options.p2pPort, - fastRebuild: false -}, options.configPath) +updateConfig( + 'peers.json', + { + minimumVersion: '>=1.3.3', + minimumNetworkReach: 1, + list: [ + { + ip: requestNodeIp, + port: options.p2pPort, + }, + ], + sources: [], + }, + options.configPath, +) + +updateConfig( + 'genesisWallet.json', + { + address: genesis.genesisWallet.address, + passphrase: genesis.genesisWallet.passphrase, + }, + options.configPath, + true, +) +updateConfig( + 'genesisBlock.json', + genesis.genesisBlock, + options.configPath, + true, +) +updateConfig( + 'delegates.json', + { + secrets: genesis.delegatePassphrases, + }, + options.configPath, + true, +) + +updateConfig( + 'server.json', + { + port: options.p2pPort, + fastRebuild: false, + }, + options.configPath, +) updateConfig('api/public.json', { port: options.apiPort }, options.configPath) @@ -173,34 +277,36 @@ for (let plugin in pluginsOriginal) { plugins['@arkecosystem/core-p2p'] = { host: options.nodeIp, port: options.p2pPort, - whitelist: ['127.0.0.1', '192.168.*'] + whitelist: ['127.0.0.1', '192.168.*'], } plugins['@arkecosystem/core-api'] = { enabled: true, host: options.nodeIp, port: options.apiPort, - whitelist: ['*'] + whitelist: ['*'], } -plugins['@arkecosystem/core-database-sequelize'] = { +plugins['@arkecosystem/core-database-postgres'] = { host: options.dbHost, port: options.dbPort, username: options.dbUsername, password: options.dbPassword, database: options.dbDatabase, - dialect: 'postgres' } plugins['@arkecosystem/core-blockchain'] = { - fastRebuild: false + fastRebuild: false, } plugins['@arkecosystem/core-forger'] = { - hosts: [`http://${requestNodeIp}:${options.p2pPort}`] + hosts: [`http://${requestNodeIp}:${options.p2pPort}`], } updateConfig('plugins.json', plugins, options.configPath, true) fs.removeSync(path.resolve(options.configPath, 'plugins.js')) -writeEnv({ - P2P_PORT: options.p2pPort, - API_PORT: options.apiPort, - DB_PORT: options.dbPort -}, '~/.ark/.env') +writeEnv( + { + P2P_PORT: options.p2pPort, + API_PORT: options.apiPort, + DB_PORT: options.dbPort, + }, + '~/.ark/.env', +) diff --git a/packages/core-deployer/jest.config.js b/packages/core-deployer/jest.config.js index 26f7a25796..57770a97bb 100644 --- a/packages/core-deployer/jest.config.js +++ b/packages/core-deployer/jest.config.js @@ -1,22 +1,12 @@ -'use strict' - module.exports = { testEnvironment: 'node', bail: false, verbose: true, - testMatch: [ - '**/__tests__/**/*.test.js' - ], - moduleFileExtensions: [ - 'js', - 'json' - ], + testMatch: ['**/__tests__/**/*.test.js'], + moduleFileExtensions: ['js', 'json'], collectCoverage: false, coverageDirectory: '/.coverage', - collectCoverageFrom: [ - 'lib/**/*.js', - '!**/node_modules/**' - ], + collectCoverageFrom: ['lib/**/*.js', '!**/node_modules/**'], watchman: false, - setupTestFrameworkScriptFile: 'jest-extended' + setupTestFrameworkScriptFile: 'jest-extended', } diff --git a/packages/core-deployer/jsdoc.json b/packages/core-deployer/jsdoc.json index 23276f74ea..f3ea8aab33 100644 --- a/packages/core-deployer/jsdoc.json +++ b/packages/core-deployer/jsdoc.json @@ -7,9 +7,7 @@ "includePattern": ".js$", "excludePattern": "(node_modules/|docs)" }, - "plugins": [ - "plugins/markdown" - ], + "plugins": ["plugins/markdown"], "opts": { "template": "../../node_modules/docdash", "encoding": "utf8", diff --git a/packages/core-deployer/lib/builder/genesis-block.js b/packages/core-deployer/lib/builder/genesis-block.js index cdaacc3cb4..1f6d8d0c5e 100644 --- a/packages/core-deployer/lib/builder/genesis-block.js +++ b/packages/core-deployer/lib/builder/genesis-block.js @@ -1,8 +1,7 @@ -const ark = require('arkjs') -const bignum = require('bigi') +const { Bignum, client, crypto } = require('@arkecosystem/crypto') const bip39 = require('bip39') const ByteBuffer = require('bytebuffer') -const crypto = require('crypto') +const { createHash } = require('crypto') module.exports = class GenesisBlockBuilder { /** @@ -10,36 +9,39 @@ module.exports = class GenesisBlockBuilder { * @param {Object} options * @return {void} */ - constructor (network, options) { + constructor(network, options) { this.network = network this.prefixHash = network.pubKeyHash this.totalPremine = options.totalPremine this.activeDelegates = options.activeDelegates - ark.crypto.setNetworkVersion(this.prefixHash) } /** * Generate a Genesis Block. * @return {Object} */ - generate () { + generate() { const genesisWallet = this.__createWallet() const premineWallet = this.__createWallet() const delegates = this.__buildDelegates() const transactions = [ ...this.__buildDelegateTransactions(delegates), - this.__createTransferTransaction(premineWallet, genesisWallet, this.totalPremine) + this.__createTransferTransaction( + premineWallet, + genesisWallet, + this.totalPremine, + ), ] const genesisBlock = this.__createGenesisBlock({ keys: genesisWallet.keys, transactions, - timestamp: 0 + timestamp: 0, }) return { genesisWallet, genesisBlock, - delegatePassphrases: delegates.map(wallet => wallet.passphrase) + delegatePassphrases: delegates.map(wallet => wallet.passphrase), } } @@ -47,14 +49,14 @@ module.exports = class GenesisBlockBuilder { * Generate a new random wallet. * @return {Object} */ - __createWallet () { + __createWallet() { const passphrase = bip39.generateMnemonic() - const keys = ark.crypto.getKeys(passphrase, this.network) + const keys = crypto.getKeys(passphrase) return { - address: ark.crypto.getAddress(keys.publicKey, this.prefixHash), + address: crypto.getAddress(keys.publicKey, this.prefixHash), passphrase, - keys + keys, } } @@ -63,7 +65,7 @@ module.exports = class GenesisBlockBuilder { * @param {String} username * @return {Object} */ - __createDelegateWallet (username) { + __createDelegateWallet(username) { const wallet = this.__createWallet() wallet.username = username @@ -74,7 +76,7 @@ module.exports = class GenesisBlockBuilder { * Generate a collection of delegate wallets. * @return {Object[]} */ - __buildDelegates () { + __buildDelegates() { const wallets = [] for (let i = 0; i < this.activeDelegates; i++) { wallets.push(this.__createDelegateWallet(`genesis_${i + 1}`)) @@ -88,7 +90,7 @@ module.exports = class GenesisBlockBuilder { * @param {Object[]} wallets * @return {Object[]} */ - __buildDelegateTransactions (wallets) { + __buildDelegateTransactions(wallets) { return wallets.map(wallet => this.__createDelegateTransaction(wallet)) } @@ -99,11 +101,16 @@ module.exports = class GenesisBlockBuilder { * @param {Number} amount * @return {Object} */ - __createTransferTransaction (senderWallet, receiverWallet, amount) { - return this.__formatGenesisTransaction( - ark.transaction.createTransaction(receiverWallet.address, amount, null, senderWallet.passphrase, undefined, this.prefixHash), - senderWallet - ) + __createTransferTransaction(senderWallet, receiverWallet, amount) { + const { data } = client + .getBuilder() + .transfer() + .recipientId(receiverWallet.address) + .amount(amount) + .network(this.prefixHash) + .sign(senderWallet.passphrase) + + return this.__formatGenesisTransaction(data, senderWallet) } /** @@ -111,11 +118,14 @@ module.exports = class GenesisBlockBuilder { * @param {Object} wallet * @return {Object} */ - __createDelegateTransaction (wallet) { - return this.__formatGenesisTransaction( - ark.delegate.createDelegate(wallet.passphrase, wallet.username), - wallet - ) + __createDelegateTransaction(wallet) { + const { data } = client + .getBuilder() + .delegateRegistration() + .usernameAsset(wallet.username) + .sign(wallet.passphrase) + + return this.__formatGenesisTransaction(data, wallet) } /** @@ -124,14 +134,14 @@ module.exports = class GenesisBlockBuilder { * @param {Object} wallet * @return {Object} */ - __formatGenesisTransaction (transaction, wallet) { + __formatGenesisTransaction(transaction, wallet) { Object.assign(transaction, { fee: 0, timestamp: 0, - senderId: wallet.address + senderId: wallet.address, }) - transaction.signature = ark.crypto.sign(transaction, wallet.keys) - transaction.id = ark.crypto.getId(transaction) + transaction.signature = crypto.sign(transaction, wallet.keys) + transaction.id = crypto.getId(transaction) return transaction } @@ -141,7 +151,7 @@ module.exports = class GenesisBlockBuilder { * @param {Object} data * @return {Object} */ - __createGenesisBlock (data) { + __createGenesisBlock(data) { const transactions = data.transactions.sort((a, b) => { if (a.type === b.type) { return a.amount - b.amount @@ -153,10 +163,10 @@ module.exports = class GenesisBlockBuilder { let payloadLength = 0 let totalFee = 0 let totalAmount = 0 - let payloadHash = crypto.createHash('sha256') + const payloadHash = createHash('sha256') transactions.forEach(transaction => { - const bytes = ark.crypto.getBytes(transaction) + const bytes = crypto.getBytes(transaction) payloadLength += bytes.length totalFee += transaction.fee totalAmount += transaction.amount @@ -165,8 +175,8 @@ module.exports = class GenesisBlockBuilder { const block = { version: 0, - totalAmount: totalAmount, - totalFee: totalFee, + totalAmount, + totalFee, reward: 0, payloadHash: payloadHash.digest().toString('hex'), timestamp: data.timestamp, @@ -175,7 +185,7 @@ module.exports = class GenesisBlockBuilder { previousBlock: null, generatorPublicKey: data.keys.publicKey.toString('hex'), transactions, - height: 1 + height: 1, } block.id = this.__getBlockId(block) @@ -194,26 +204,25 @@ module.exports = class GenesisBlockBuilder { * @param {Object} block * @return {String} */ - __getBlockId (block) { - let hash = this.__getHash(block) - let blockBuffer = Buffer.alloc(8) + __getBlockId(block) { + const hash = this.__getHash(block) + const blockBuffer = Buffer.alloc(8) for (let i = 0; i < 8; i++) { blockBuffer[i] = hash[7 - i] } - return bignum.fromBuffer(blockBuffer).toString() + return new Bignum(blockBuffer.toString('hex'), 16).toString() } /** * Sign block with keys. * @param {Object} block - * @param {ECPair]} keys + * @param {Object]} keys * @return {String} */ - __signBlock (block, keys) { - var hash = this.__getHash(block) - - return keys.sign(hash).toDER().toString('hex') + __signBlock(block, keys) { + const hash = this.__getHash(block) + return crypto.signHash(hash, keys) } /** @@ -221,8 +230,10 @@ module.exports = class GenesisBlockBuilder { * @param {Object} block * @return {String} */ - __getHash (block) { - return crypto.createHash('sha256').update(this.__getBytes(block)).digest() + __getHash(block) { + return createHash('sha256') + .update(this.__getBytes(block)) + .digest() } /** @@ -230,17 +241,20 @@ module.exports = class GenesisBlockBuilder { * @param {Object} block * @return {(Buffer|undefined)} */ - __getBytes (block) { + __getBytes(block) { const size = 4 + 4 + 4 + 8 + 4 + 4 + 8 + 8 + 4 + 4 + 4 + 32 + 32 + 64 try { - var byteBuffer = new ByteBuffer(size, true) + const byteBuffer = new ByteBuffer(size, true) byteBuffer.writeInt(block.version) byteBuffer.writeInt(block.timestamp) byteBuffer.writeInt(block.height) if (block.previousBlock) { - var previousBlock = bignum(block.previousBlock).toBuffer({size: '8'}) + const previousBlock = Buffer.from( + new Bignum(block.previousBlock).toString(16), + 'hex', + ) for (let i = 0; i < 8; i++) { byteBuffer.writeByte(previousBlock[i]) @@ -258,18 +272,21 @@ module.exports = class GenesisBlockBuilder { byteBuffer.writeInt(block.payloadLength) - var payloadHashBuffer = Buffer.from(block.payloadHash, 'hex') + const payloadHashBuffer = Buffer.from(block.payloadHash, 'hex') for (let i = 0; i < payloadHashBuffer.length; i++) { byteBuffer.writeByte(payloadHashBuffer[i]) } - var generatorPublicKeyBuffer = Buffer.from(block.generatorPublicKey, 'hex') + const generatorPublicKeyBuffer = Buffer.from( + block.generatorPublicKey, + 'hex', + ) for (let i = 0; i < generatorPublicKeyBuffer.length; i++) { byteBuffer.writeByte(generatorPublicKeyBuffer[i]) } if (block.blockSignature) { - var blockSignatureBuffer = Buffer.from(block.blockSignature, 'hex') + const blockSignatureBuffer = Buffer.from(block.blockSignature, 'hex') for (let i = 0; i < blockSignatureBuffer.length; i++) { byteBuffer.writeByte(blockSignatureBuffer[i]) } diff --git a/packages/core-deployer/lib/logger.js b/packages/core-deployer/lib/logger.js index 181397255a..1659945fe0 100644 --- a/packages/core-deployer/lib/logger.js +++ b/packages/core-deployer/lib/logger.js @@ -1,10 +1,7 @@ const pino = require('pino') -const pretty = pino.pretty({ - formatter: (data, util) => `${util.prefix}: ${util.asColoredText(data, data.msg)}` -}) -pretty.pipe(process.stdout) module.exports = pino({ name: 'ark-tester-cli', - safe: true -}, pretty) + safe: true, + prettyPrint: true, +}) diff --git a/packages/core-deployer/lib/schema.js b/packages/core-deployer/lib/schema.js index 2696728d51..621d12766a 100644 --- a/packages/core-deployer/lib/schema.js +++ b/packages/core-deployer/lib/schema.js @@ -11,22 +11,35 @@ module.exports = Joi.object().keys({ dbUsername: Joi.string().required(), dbPassword: Joi.string().required(), dbDatabase: Joi.string().required(), - explorerUrl: Joi.string().uri({ scheme: ['http', 'https'] }).required(), + explorerUrl: Joi.string() + .uri({ scheme: ['http', 'https'] }) + .required(), activeDelegates: Joi.number().required(), feeTransfer: Joi.number().required(), feeVote: Joi.number().required(), feeSecondSignature: Joi.number().required(), feeDelegateRegistration: Joi.number().required(), feeMultiSignature: Joi.number().required(), - epoch: Joi.string().regex(/\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)/).required(), - rewardHeight: Joi.number().min(1).required(), + epoch: Joi.string() + .regex( + /\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)/, + ) + .required(), + rewardHeight: Joi.number() + .integer() + .positive() + .required(), rewardPerBlock: Joi.number().required(), blocktime: Joi.number().required(), token: Joi.string().required(), symbol: Joi.string().required(), prefixHash: Joi.number().required(), transactionsPerBlock: Joi.number().required(), - wifPrefix: Joi.number().min(1).max(255).required(), + wifPrefix: Joi.number() + .integer() + .min(1) + .max(255) + .required(), totalPremine: Joi.number().required(), - configPath: Joi.string().required() + configPath: Joi.string().required(), }) diff --git a/packages/core-deployer/lib/utils.js b/packages/core-deployer/lib/utils.js index e89787f09c..9692402880 100644 --- a/packages/core-deployer/lib/utils.js +++ b/packages/core-deployer/lib/utils.js @@ -1,6 +1,4 @@ -'use strict' - -const _ = require('lodash') +const set = require('lodash/set') const envfile = require('envfile') const expandHomeDir = require('expand-home-dir') const fs = require('fs-extra') @@ -12,9 +10,8 @@ const path = require('path') * @param {Number} max * @return {Number} */ -exports.getRandomNumber = (min, max) => { - return Math.floor(Math.random() * (max - min) + min) -} +exports.getRandomNumber = (min, max) => + Math.floor(Math.random() * (max - min) + min) exports.logger = require('./logger') @@ -25,7 +22,7 @@ exports.logger = require('./logger') * @return {Object} */ exports.updateConfig = (file, values, configPath, forceOverwrite) => { - configPath = (configPath || `${process.env.ARK_PATH_CONFIG}/deployer`) + configPath = configPath || `${process.env.ARK_PATH_CONFIG}/deployer` configPath = path.resolve(configPath, file) let config if (fs.existsSync(configPath) && !forceOverwrite) { @@ -34,9 +31,7 @@ exports.updateConfig = (file, values, configPath, forceOverwrite) => { config = {} } - for (let key in values) { - _.set(config, key, values[key]) - } + values.forEach(key => set(config, key, values[key])) fs.ensureFileSync(configPath) fs.writeFileSync(configPath, JSON.stringify(config, null, 2)) diff --git a/packages/core-deployer/package.json b/packages/core-deployer/package.json index 6faefdbf4e..b2ade3e882 100644 --- a/packages/core-deployer/package.json +++ b/packages/core-deployer/package.json @@ -1,7 +1,7 @@ { "name": "@arkecosystem/core-deployer", - "description": "Deployer for ARK Core", - "version": "0.1.1", + "description": "Deployer for Ark Core", + "version": "0.2.0", "contributors": [ "Brian Faust ", "Alex Barnsley " @@ -14,27 +14,30 @@ "scripts": { "start": "./bin/deployer", "test": "cross-env ARK_ENV=test jest --runInBand --detectOpenHandles", - "test:coverage": "cross-env ARK_ENV=test jest --coverage --runInBand --detectOpenHandles", - "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand --watch", + "test:coverage": "cross-env ARK_ENV=test jest --coverage --coveragePathIgnorePatterns='/(defaults.js|index.js)$' --runInBand --detectOpenHandles", + "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand", "test:watch": "cross-env ARK_ENV=test jest --runInBand --watch", "test:watch:all": "cross-env ARK_ENV=test jest --runInBand --watchAll", "lint": "eslint ./ --fix", - "depcheck": "depcheck ./ --ignores=commander" + "depcheck": "depcheck ./ --ignores=commander,pino-pretty,lodash,lodash.*" }, "dependencies": { - "arkjs": "https://github.com/ArkEcosystem/ark-js#master", - "bigi": "^1.4.2", + "@arkecosystem/crypto": "~0.2", "bip39": "^2.5.0", "bytebuffer": "^5.0.1", - "commander": "^2.15.1", + "commander": "^2.19.0", "envfile": "^2.3.0", "expand-home-dir": "0.0.3", - "fs-extra": "^6.0.1", - "joi": "^13.3.0", - "lodash": "^4.17.10", - "pino": "^4.16.1" + "fs-extra": "^7.0.1", + "joi": "^14.3.0", + "lodash.set": "^4.3.2", + "pino": "^5.9.0", + "pino-pretty": "^2.3.0" }, "publishConfig": { "access": "public" + }, + "engines": { + "node": ">=10.x" } } diff --git a/packages/core-transaction-pool-redis/.gitattributes b/packages/core-elasticsearch/.gitattributes similarity index 100% rename from packages/core-transaction-pool-redis/.gitattributes rename to packages/core-elasticsearch/.gitattributes diff --git a/packages/validation/CHANGELOG.md b/packages/core-elasticsearch/CHANGELOG.md similarity index 92% rename from packages/validation/CHANGELOG.md rename to packages/core-elasticsearch/CHANGELOG.md index 127cc35e42..6842caf9df 100644 --- a/packages/validation/CHANGELOG.md +++ b/packages/core-elasticsearch/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Unreleased -## 0.0.1 - 2018-05-31 +## 0.1.0 - 2018-12-03 + ### Added + - initial release diff --git a/packages/core-transaction-pool-redis/LICENSE b/packages/core-elasticsearch/LICENSE similarity index 100% rename from packages/core-transaction-pool-redis/LICENSE rename to packages/core-elasticsearch/LICENSE diff --git a/packages/core-elasticsearch/README.md b/packages/core-elasticsearch/README.md new file mode 100644 index 0000000000..140161d7f3 --- /dev/null +++ b/packages/core-elasticsearch/README.md @@ -0,0 +1,22 @@ +# Ark Core - Elasticsearch + +

+ +

+ +## Documentation + +You can find installation instructions and detailed instructions on how to use this package at the [dedicated documentation site](https://docs.ark.io/guidebook/core/plugins/core-elasticsearch.html). + +## Security + +If you discover a security vulnerability within this package, please send an e-mail to security@ark.io. All security vulnerabilities will be promptly addressed. + +## Credits + +- [Brian Faust](https://github.com/faustbrian) +- [All Contributors](../../../../contributors) + +## License + +[MIT](LICENSE) © [ArkEcosystem](https://ark.io) diff --git a/packages/core-elasticsearch/jest.config.js b/packages/core-elasticsearch/jest.config.js new file mode 100644 index 0000000000..57770a97bb --- /dev/null +++ b/packages/core-elasticsearch/jest.config.js @@ -0,0 +1,12 @@ +module.exports = { + testEnvironment: 'node', + bail: false, + verbose: true, + testMatch: ['**/__tests__/**/*.test.js'], + moduleFileExtensions: ['js', 'json'], + collectCoverage: false, + coverageDirectory: '/.coverage', + collectCoverageFrom: ['lib/**/*.js', '!**/node_modules/**'], + watchman: false, + setupTestFrameworkScriptFile: 'jest-extended', +} diff --git a/packages/core-transaction-pool-redis/jsdoc.json b/packages/core-elasticsearch/jsdoc.json similarity index 90% rename from packages/core-transaction-pool-redis/jsdoc.json rename to packages/core-elasticsearch/jsdoc.json index 23276f74ea..f3ea8aab33 100644 --- a/packages/core-transaction-pool-redis/jsdoc.json +++ b/packages/core-elasticsearch/jsdoc.json @@ -7,9 +7,7 @@ "includePattern": ".js$", "excludePattern": "(node_modules/|docs)" }, - "plugins": [ - "plugins/markdown" - ], + "plugins": ["plugins/markdown"], "opts": { "template": "../../node_modules/docdash", "encoding": "utf8", diff --git a/packages/core-elasticsearch/lib/defaults.js b/packages/core-elasticsearch/lib/defaults.js new file mode 100644 index 0000000000..229aa2c9af --- /dev/null +++ b/packages/core-elasticsearch/lib/defaults.js @@ -0,0 +1,12 @@ +module.exports = { + server: { + host: '0.0.0.0', + port: 4007, + whitelist: ['*'], + }, + client: { + host: 'localhost:9200', + log: 'info', + }, + chunkSize: 50000, +} diff --git a/packages/core-elasticsearch/lib/index.js b/packages/core-elasticsearch/lib/index.js new file mode 100644 index 0000000000..1546591aae --- /dev/null +++ b/packages/core-elasticsearch/lib/index.js @@ -0,0 +1,39 @@ +const blockIndex = require('./index/block') +const transactionIndex = require('./index/transaction') +const walletIndex = require('./index/wallet') +const roundIndex = require('./index/round') +const client = require('./services/client') +const storage = require('./services/storage') + +/** + * The struct used by the plugin container. + * @type {Object} + */ +exports.plugin = { + pkg: require('../package.json'), + defaults: require('./defaults'), + alias: 'elasticsearch', + async register(container, options) { + const logger = container.resolvePlugin('logger') + + logger.info('[Elasticsearch] Initialising History :hourglass:') + storage.ensure('history') + + logger.info('[Elasticsearch] Initialising Client :joystick:') + await client.setUp(options.client) + + blockIndex.setUp(options.chunkSize) + transactionIndex.setUp(options.chunkSize) + walletIndex.setUp(options.chunkSize) + roundIndex.setUp(options.chunkSize) + + return require('./server')(options.server) + }, + async deregister(container, options) { + container + .resolvePlugin('logger') + .info('[Elasticsearch] Stopping API :warning:') + + return container.resolvePlugin('elasticsearch').stop() + }, +} diff --git a/packages/core-elasticsearch/lib/index/block.js b/packages/core-elasticsearch/lib/index/block.js new file mode 100644 index 0000000000..c72cf21e9b --- /dev/null +++ b/packages/core-elasticsearch/lib/index/block.js @@ -0,0 +1,87 @@ +/* eslint no-await-in-loop: "off" */ + +const first = require('lodash/first') +const last = require('lodash/last') +const app = require('@arkecosystem/core-container') + +const database = app.resolvePlugin('database') +const logger = app.resolvePlugin('logger') +const Index = require('./index') +const client = require('../services/client') +const storage = require('../services/storage') + +class BlockIndex extends Index { + /** + * Index blocks using the specified chunk size. + * @return {void} + */ + async index() { + const { count } = await this.__count() + + const queries = Math.ceil(count / this.chunkSize) + + for (let i = 0; i < queries; i++) { + const modelQuery = this.__createQuery() + + const query = modelQuery + .select() + .from(modelQuery) + .where(modelQuery.timestamp.gte(storage.get('history', 'lastBlock'))) + .order(modelQuery.height.asc) + .limit(this.chunkSize) + .offset(this.chunkSize * i) + + const rows = await database.query.manyOrNone(query.toQuery()) + + if (!rows.length) { + continue + } + + const heights = rows.map(row => row.height) + logger.info( + `[Elasticsearch] Indexing blocks from height ${first( + heights, + )} to ${last(heights)} :card_index_dividers:`, + ) + + try { + await client.bulk(this._buildBulkUpsert(rows)) + + storage.update('history', { + lastBlock: last(heights), + }) + } catch (error) { + logger.error(`[Elasticsearch] ${error.message} :exclamation:`) + } + } + } + + /** + * Register listeners for "block.*" events. + * @return {void} + */ + listen() { + this._registerCreateListener('block.applied') + // this._registerCreateListener('block.forged') + + this._registerDeleteListener('block.reverted') + } + + /** + * Get the document index. + * @return {String} + */ + getIndex() { + return 'blocks' + } + + /** + * Get the document type. + * @return {String} + */ + getType() { + return 'block' + } +} + +module.exports = new BlockIndex() diff --git a/packages/core-elasticsearch/lib/index/index.js b/packages/core-elasticsearch/lib/index/index.js new file mode 100644 index 0000000000..27c67a9817 --- /dev/null +++ b/packages/core-elasticsearch/lib/index/index.js @@ -0,0 +1,181 @@ +/* eslint camelcase: "off" */ + +const app = require('@arkecosystem/core-container') + +const emitter = app.resolvePlugin('event-emitter') +const logger = app.resolvePlugin('logger') +const database = app.resolvePlugin('database') +const client = require('../services/client') +const storage = require('../services/storage') + +module.exports = class Index { + /** + * Create a new index instance. + * @param {Number} chunkSize + * @return {void} + */ + setUp(chunkSize) { + logger.info(`[Elasticsearch] Initialising ${this.getType()} index :scroll:`) + this.chunkSize = chunkSize + + logger.info( + `[Elasticsearch] Initialising ${this.getType()} listener :radio:`, + ) + this.listen() + + logger.info(`[Elasticsearch] Indexing ${this.getIndex()} :bookmark:`) + this.index() + } + + /** + * Register a new "CREATE" operation listener. + * @param {String} event + * @return {void} + */ + _registerCreateListener(event) { + emitter.on(event, async doc => { + try { + const exists = await this._exists(doc) + + if (!exists) { + await this._create(doc) + } + } catch (error) { + logger.error(`[Elasticsearch] ${error.message} :exclamation:`) + } + }) + } + + /** + * Register a new "DELETE" operation listener. + * @param {String} event + * @return {void} + */ + _registerDeleteListener(event) { + emitter.on(event, async doc => { + try { + const exists = await this._exists(doc) + + if (exists) { + await this._delete(doc) + } + } catch (error) { + logger.error(`[Elasticsearch] ${error.message} :exclamation:`) + } + }) + } + + /** + * Check if the specified document exists. + * @param {String} doc + * @return {Promise} + */ + _exists(doc) { + return client.exists(this._getReadQuery(doc)) + } + + /** + * Create a new document. + * @param {String} doc + * @return {Promise} + */ + _create(doc) { + logger.info(`[Elasticsearch] Creating ${this.getType()} with ID ${doc.id}`) + + if (this.getType() === 'block') { + storage.update('history', { lastBlock: doc.height }) + } else { + storage.update('history', { lastTransaction: doc.timestamp }) + } + + return client.create(this._getWriteQuery(doc)) + } + + /** + * Delete the specified document. + * @param {String} doc + * @return {Promise} + */ + _delete(doc) { + logger.info(`[Elasticsearch] Deleting ${this.getType()} with ID ${doc.id}`) + + return client.delete(this._getReadQuery(doc)) + } + + /** + * Get a query for a "WRITE" operation. + * @param {String} doc + * @return {Object} + */ + _getWriteQuery(doc) { + return { + index: this.getIndex(), + type: this.getType(), + id: doc.id, + body: doc, + } + } + + /** + * Get a query for a "READ" operation. + * @param {String} doc + * @return {Object} + */ + _getReadQuery(doc) { + return { + index: this.getIndex(), + type: this.getType(), + id: doc.id, + } + } + + /** + * Get a query for a "READ" operation. + * @param {String} doc + * @return {Object} + */ + _getUpsertQuery(doc) { + return { + action: { + update: { + _index: this.getIndex(), + _type: this.getType(), + _id: doc.id, + }, + }, + document: { + doc, + doc_as_upsert: true, + }, + } + } + + /** + * Get a query for a "READ" operation. + * @param {Array} items + * @return {Object} + */ + _buildBulkUpsert(items) { + const actions = [] + + items.forEach(item => { + const query = this._getUpsertQuery(item) + actions.push(query.action) + actions.push(query.document) + }) + + return actions + } + + __createQuery() { + return database.models[this.getType()].query() + } + + __count() { + const modelQuery = this.__createQuery() + + const query = modelQuery.select(modelQuery.count('count')).from(modelQuery) + + return database.query.one(query.toQuery()) + } +} diff --git a/packages/core-elasticsearch/lib/index/round.js b/packages/core-elasticsearch/lib/index/round.js new file mode 100644 index 0000000000..c0ee818141 --- /dev/null +++ b/packages/core-elasticsearch/lib/index/round.js @@ -0,0 +1,85 @@ +/* eslint no-await-in-loop: "off" */ + +const first = require('lodash/first') +const last = require('lodash/last') +const app = require('@arkecosystem/core-container') + +const emitter = app.resolvePlugin('event-emitter') +const database = app.resolvePlugin('database') +const logger = app.resolvePlugin('logger') +const Index = require('./index') +const client = require('../services/client') +const storage = require('../services/storage') + +class RoundIndex extends Index { + /** + * Index rounds using the specified chunk size. + * @return {void} + */ + async index() { + const { count } = await this.__count() + + const queries = Math.ceil(count / this.chunkSize) + + for (let i = 0; i < queries; i++) { + const modelQuery = this.__createQuery() + + const query = modelQuery + .select() + .from(modelQuery) + .where(modelQuery.round.gte(storage.get('history', 'lastRound'))) + .order(modelQuery.round.asc) + .limit(this.chunkSize) + .offset(this.chunkSize * i) + + const rows = await database.query.manyOrNone(query.toQuery()) + + if (!rows.length) { + continue + } + + const roundIds = rows.map(row => row.round) + logger.info( + `[Elasticsearch] Indexing rounds from ${first(roundIds)} to ${last( + roundIds, + )} :card_index_dividers:`, + ) + + try { + await client.bulk(this._buildBulkUpsert(rows)) + + storage.update('history', { + lastRound: last(roundIds), + }) + } catch (error) { + logger.error(`[Elasticsearch] ${error.message} :exclamation:`) + } + } + } + + /** + * Register listeners for "round.*" events. + * @return {void} + */ + listen() { + emitter.on('round.created', data => this.index()) + } + + /** + * Get the document index. + * @return {String} + */ + getIndex() { + return 'rounds' + } + + /** + * Get the document type. + * @return {String} + */ + getType() { + return 'round' + } +} + +module.exports = new RoundIndex() diff --git a/packages/core-elasticsearch/lib/index/transaction.js b/packages/core-elasticsearch/lib/index/transaction.js new file mode 100644 index 0000000000..903013867d --- /dev/null +++ b/packages/core-elasticsearch/lib/index/transaction.js @@ -0,0 +1,98 @@ +/* eslint no-await-in-loop: "off" */ + +const first = require('lodash/first') +const last = require('lodash/last') +const app = require('@arkecosystem/core-container') + +const database = app.resolvePlugin('database') +const logger = app.resolvePlugin('logger') +const { Transaction } = require('@arkecosystem/crypto').models +const Index = require('./index') +const client = require('../services/client') +const storage = require('../services/storage') + +class TransactionIndex extends Index { + /** + * Index transactions using the specified chunk size. + * @return {void} + */ + async index() { + const { count } = await this.__count() + + const queries = Math.ceil(count / this.chunkSize) + + for (let i = 0; i < queries; i++) { + const modelQuery = this.__createQuery() + + const query = modelQuery + .select(modelQuery.block_id, modelQuery.serialized) + .from(modelQuery) + .where( + modelQuery.timestamp.gte(storage.get('history', 'lastTransaction')), + ) + .order(modelQuery.timestamp.asc) + .limit(this.chunkSize) + .offset(this.chunkSize * i) + + let rows = await database.query.manyOrNone(query.toQuery()) + + if (!rows.length) { + continue + } + + rows = rows.map(row => { + const transaction = new Transaction(row.serialized.toString('hex')) + transaction.blockId = row.blockId + + return transaction + }) + + const blockIds = rows.map(row => row.blockId) + logger.info( + `[Elasticsearch] Indexing transactions from block ${first( + blockIds, + )} to ${last(blockIds)} :card_index_dividers:`, + ) + + try { + await client.bulk(this._buildBulkUpsert(rows)) + + storage.update('history', { + lastTransaction: last(rows.map(row => row.timestamp)), + }) + } catch (error) { + logger.error(`[Elasticsearch] ${error.message} :exclamation:`) + } + } + } + + /** + * Register listeners for "transaction.*" events. + * @return {void} + */ + listen() { + this._registerCreateListener('transaction.applied') + this._registerCreateListener('transaction.forged') + + this._registerDeleteListener('transaction.expired') + this._registerDeleteListener('transaction.reverted') + } + + /** + * Get the document index. + * @return {String} + */ + getIndex() { + return 'transactions' + } + + /** + * Get the document type. + * @return {String} + */ + getType() { + return 'transaction' + } +} + +module.exports = new TransactionIndex() diff --git a/packages/core-elasticsearch/lib/index/wallet.js b/packages/core-elasticsearch/lib/index/wallet.js new file mode 100644 index 0000000000..57f305b91d --- /dev/null +++ b/packages/core-elasticsearch/lib/index/wallet.js @@ -0,0 +1,77 @@ +/* eslint no-await-in-loop: "off" */ + +const app = require('@arkecosystem/core-container') + +const emitter = app.resolvePlugin('event-emitter') +const database = app.resolvePlugin('database') +const logger = app.resolvePlugin('logger') +const Index = require('./index') +const client = require('../services/client') + +class WalletIndex extends Index { + /** + * Index wallets using the specified chunk size. + * @return {void} + */ + async index() { + const { count } = await this.__count() + + const queries = Math.ceil(count / this.chunkSize) + + for (let i = 0; i < queries; i++) { + const modelQuery = this.__createQuery() + + const query = modelQuery + .select() + .from(modelQuery) + .limit(this.chunkSize) + .offset(this.chunkSize * i) + + const rows = await database.query.manyOrNone(query.toQuery()) + + if (!rows.length) { + continue + } + + logger.info( + `[Elasticsearch] Indexing ${rows.length} wallets :card_index_dividers:`, + ) + + try { + rows.forEach(row => { + row.id = row.address + }) + + await client.bulk(this._buildBulkUpsert(rows)) + } catch (error) { + logger.error(`[Elasticsearch] ${error.message} :exclamation:`) + } + } + } + + /** + * Register listeners for "wallet.*" events. + * @return {void} + */ + listen() { + emitter.on('wallets:updated', data => this.index()) + } + + /** + * Get the document index. + * @return {String} + */ + getIndex() { + return 'wallets' + } + + /** + * Get the document type. + * @return {String} + */ + getType() { + return 'wallet' + } +} + +module.exports = new WalletIndex() diff --git a/packages/core-elasticsearch/lib/server/handler.js b/packages/core-elasticsearch/lib/server/handler.js new file mode 100644 index 0000000000..4f762ef63e --- /dev/null +++ b/packages/core-elasticsearch/lib/server/handler.js @@ -0,0 +1,68 @@ +const Joi = require('joi') +const client = require('../services/client') + +/** + * @type {Object} + */ +exports.index = { + /** + * @param {Hapi.Request} request + * @param {Hapi.Toolkit} h + * @return {Hapi.Response} + */ + async handler(request, h) { + const query = await client.search(request.payload) + + return { + meta: { + count: query.hits.total, + }, + data: query.hits.hits.map(result => result._source), + } + }, + options: { + validate: { + payload: { + analyzer: Joi.string(), + analyzeWildcard: Joi.boolean(), + defaultOperator: Joi.string(), + df: Joi.string(), + explain: Joi.boolean(), + storedFields: Joi.any(), + docvalueFields: Joi.any(), + from: Joi.number(), + allowNoIndices: Joi.boolean(), + expandWildcards: Joi.string(), + lenient: Joi.boolean(), + preference: Joi.string(), + q: Joi.string(), + routing: Joi.any(), + scroll: Joi.string(), + searchType: Joi.string(), + size: Joi.number().default(10), + sort: Joi.any(), + _source: Joi.any(), + _sourceExclude: Joi.any(), + _sourceInclude: Joi.any(), + terminateAfter: Joi.number(), + stats: Joi.any(), + suggestField: Joi.string(), + suggestMode: Joi.string(), + suggestSize: Joi.number(), + suggestText: Joi.string(), + timeout: Joi.string(), + trackScores: Joi.boolean(), + trackTotalHits: Joi.boolean(), + typedKeys: Joi.boolean(), + version: Joi.boolean(), + requestCache: Joi.boolean(), + batchedReduceSize: Joi.number(), + maxConcurrentShardRequests: Joi.number(), + preFilterShardSize: Joi.number(), + index: Joi.any(), + type: Joi.any(), + body: Joi.object(), + }, + }, + }, +} diff --git a/packages/core-elasticsearch/lib/server/index.js b/packages/core-elasticsearch/lib/server/index.js new file mode 100644 index 0000000000..fbb0e30a85 --- /dev/null +++ b/packages/core-elasticsearch/lib/server/index.js @@ -0,0 +1,36 @@ +const { + createServer, + mountServer, + plugins, +} = require('@arkecosystem/core-http-utils') + +/** + * Creates a new hapi.js server. + * @param {Object} config + * @return {Hapi.Server} + */ +module.exports = async config => { + const server = await createServer({ + host: config.host, + port: config.port, + routes: { + validate: { + async failAction(request, h, err) { + throw err + }, + }, + }, + }) + + await server.register({ + plugin: plugins.whitelist, + options: { + whitelist: config.whitelist, + name: 'Elasticsearch API', + }, + }) + + await server.register(require('./routes')) + + return mountServer('Elasticsearch API', server) +} diff --git a/packages/core-elasticsearch/lib/server/routes.js b/packages/core-elasticsearch/lib/server/routes.js new file mode 100644 index 0000000000..f44a24626f --- /dev/null +++ b/packages/core-elasticsearch/lib/server/routes.js @@ -0,0 +1,27 @@ +const handler = require('./handler') + +/** + * Register search routes. + * @param {Hapi.Server} server + * @param {Object} options + * @return {void} + */ +const register = async (server, options) => { + server.route([ + { + method: 'POST', + path: '/', + ...handler.index, + }, + ]) +} + +/** + * The struct used by hapi.js. + * @type {Object} + */ +exports.plugin = { + name: 'routes', + version: '0.1.0', + register, +} diff --git a/packages/core-elasticsearch/lib/services/client.js b/packages/core-elasticsearch/lib/services/client.js new file mode 100644 index 0000000000..5b392b8193 --- /dev/null +++ b/packages/core-elasticsearch/lib/services/client.js @@ -0,0 +1,84 @@ +const elasticsearch = require('elasticsearch') + +class Client { + /** + * Create a new client instance. + * @param {Object} options + */ + async setUp(options) { + this.client = new elasticsearch.Client(options) + } + + /** + * Get the elasticsearch client. + * @return {elasticsearch.Client} + */ + async getClient() { + return this.client + } + + /** + * Perform an "UPDATE" operation. + * @param {Object} body + * @return {Promise} + */ + async bulk(body) { + return this.client.bulk({ body }) + } + + /** + * Perform an "UPDATE" operation. + * @param {Object} params + * @return {Promise} + */ + async count(params) { + return this.client.count(params) + } + + /** + * Perform an "UPDATE" operation. + * @param {Object} params + * @return {Promise} + */ + async search(params) { + return this.client.search(params) + } + + /** + * Perform an "UPDATE" operation. + * @param {Object} params + * @return {Promise} + */ + async create(params) { + return this.client.create(params) + } + + /** + * Perform an "UPDATE" operation. + * @param {Object} params + * @return {Promise} + */ + async update(params) { + return this.client.update(params) + } + + /** + * Perform an "UPDATE" operation. + * @param {Object} params + * @return {Promise} + */ + async delete(params) { + return this.client.delete(params) + } + + /** + * Perform an "UPDATE" operation. + * @param {Object} params + * @return {Promise} + */ + async exists(params) { + return this.client.exists(params) + } +} + +module.exports = new Client() diff --git a/packages/core-elasticsearch/lib/services/storage.js b/packages/core-elasticsearch/lib/services/storage.js new file mode 100644 index 0000000000..bf55f1b35f --- /dev/null +++ b/packages/core-elasticsearch/lib/services/storage.js @@ -0,0 +1,96 @@ +const fs = require('fs-extra') +const loget = require('lodash/get') + +class Storage { + /** + * Create a new storage instance. + * @return {void} + */ + constructor() { + this.base = `${process.env.ARK_PATH_DATA}/plugins/core-elasticsearch` + } + + /** + * Read & parse the specified file. + * @param {String} file + * @return {Object} + */ + read(file) { + return this.exists(file) + ? JSON.parse(fs.readFileSync(`${this.base}/${file}.json`)) + : {} + } + + /** + * Write the specified data to the specified file. + * @param {String} file + * @param {Object} data + * @return {void} + */ + write(file, data) { + fs.ensureFileSync(`${this.base}/${file}.json`) + + fs.writeFileSync(`${this.base}/${file}.json`, JSON.stringify(data, null, 2)) + } + + /** + * Update the specified data in the specified file. + * @param {String} file + * @param {Object} data + * @return {void} + */ + update(file, data) { + fs.ensureFileSync(`${this.base}/${file}.json`) + + data = Object.assign(this.read(file), data) + + fs.writeFileSync(`${this.base}/${file}.json`, JSON.stringify(data, null, 2)) + } + + /** + * Update the specified data in the specified file. + * @param {String} file + * @param {Object} data + * @return {void} + */ + ensure(file) { + if (!this.exists(file)) { + fs.ensureFileSync(`${this.base}/${file}.json`) + + fs.writeFileSync( + `${this.base}/${file}.json`, + JSON.stringify( + { + lastRound: 0, + lastBlock: 0, + lastTransaction: 0, + }, + null, + 2, + ), + ) + } + } + + /** + * Determine if the specified file exists. + * @param {String} file + * @return {Boolean} + */ + exists(file) { + return fs.existsSync(`${this.base}/${file}.json`) + } + + /** + * Get a value from the specified file for the specified key. + * @param {String} file + * @param {String} key + * @param {*} key + * @return {*} + */ + get(file, key, defaultValue = null) { + return loget(this.read(file), key, defaultValue) + } +} + +module.exports = new Storage() diff --git a/packages/core-elasticsearch/package.json b/packages/core-elasticsearch/package.json new file mode 100644 index 0000000000..6b98717671 --- /dev/null +++ b/packages/core-elasticsearch/package.json @@ -0,0 +1,36 @@ +{ + "name": "@arkecosystem/core-elasticsearch", + "description": "A powerful Elasticsearch integration for Ark Core", + "version": "0.2.0", + "contributors": [ + "Brian Faust " + ], + "license": "MIT", + "main": "lib/index.js", + "scripts": { + "test": "cross-env ARK_ENV=test jest --runInBand --detectOpenHandles", + "test:coverage": "cross-env ARK_ENV=test jest --coverage --coveragePathIgnorePatterns='/(defaults.js|index.js)$' --runInBand --detectOpenHandles", + "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand", + "test:watch": "cross-env ARK_ENV=test jest --runInBand --watch", + "test:watch:all": "cross-env ARK_ENV=test jest --runInBand --watchAll", + "lint": "eslint ./ --fix", + "depcheck": "depcheck ./ --ignores=lodash,lodash.*" + }, + "dependencies": { + "@arkecosystem/core-container": "~0.2", + "@arkecosystem/core-http-utils": "~0.2", + "@arkecosystem/crypto": "~0.2", + "elasticsearch": "^15.2.0", + "fs-extra": "^7.0.1", + "joi": "^14.3.0", + "lodash.first": "^3.0.0", + "lodash.get": "^4.4.2", + "lodash.last": "^3.0.0" + }, + "publishConfig": { + "access": "public" + }, + "engines": { + "node": ">=10.x" + } +} diff --git a/packages/validation/.gitattributes b/packages/core-error-tracker-bugsnag/.gitattributes similarity index 100% rename from packages/validation/.gitattributes rename to packages/core-error-tracker-bugsnag/.gitattributes diff --git a/packages/client/CHANGELOG.md b/packages/core-error-tracker-bugsnag/CHANGELOG.md similarity index 92% rename from packages/client/CHANGELOG.md rename to packages/core-error-tracker-bugsnag/CHANGELOG.md index 127cc35e42..6842caf9df 100644 --- a/packages/client/CHANGELOG.md +++ b/packages/core-error-tracker-bugsnag/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Unreleased -## 0.0.1 - 2018-05-31 +## 0.1.0 - 2018-12-03 + ### Added + - initial release diff --git a/packages/validation/LICENSE b/packages/core-error-tracker-bugsnag/LICENSE similarity index 100% rename from packages/validation/LICENSE rename to packages/core-error-tracker-bugsnag/LICENSE diff --git a/packages/core-error-tracker-bugsnag/README.md b/packages/core-error-tracker-bugsnag/README.md new file mode 100644 index 0000000000..4bac94326b --- /dev/null +++ b/packages/core-error-tracker-bugsnag/README.md @@ -0,0 +1,22 @@ +# Ark Core - Error Tracker - Bugsnag + +

+ +

+ +## Documentation + +You can find installation instructions and detailed instructions on how to use this package at the [dedicated documentation site](https://docs.ark.io/guidebook/core/plugins/core-error-tracker-bugsnag.html). + +## Security + +If you discover a security vulnerability within this package, please send an e-mail to security@ark.io. All security vulnerabilities will be promptly addressed. + +## Credits + +- [Brian Faust](https://github.com/faustbrian) +- [All Contributors](../../../../contributors) + +## License + +[MIT](LICENSE) © [ArkEcosystem](https://ark.io) diff --git a/packages/core-database-sequelize/jsdoc.json b/packages/core-error-tracker-bugsnag/jsdoc.json similarity index 90% rename from packages/core-database-sequelize/jsdoc.json rename to packages/core-error-tracker-bugsnag/jsdoc.json index 23276f74ea..f3ea8aab33 100644 --- a/packages/core-database-sequelize/jsdoc.json +++ b/packages/core-error-tracker-bugsnag/jsdoc.json @@ -7,9 +7,7 @@ "includePattern": ".js$", "excludePattern": "(node_modules/|docs)" }, - "plugins": [ - "plugins/markdown" - ], + "plugins": ["plugins/markdown"], "opts": { "template": "../../node_modules/docdash", "encoding": "utf8", diff --git a/packages/core-error-tracker-bugsnag/lib/defaults.js b/packages/core-error-tracker-bugsnag/lib/defaults.js new file mode 100644 index 0000000000..712d000cc7 --- /dev/null +++ b/packages/core-error-tracker-bugsnag/lib/defaults.js @@ -0,0 +1,8 @@ +module.exports = { + apiKey: process.env.ARK_ERROR_TRACKER_BUGSNAG_API_KEY, + configuration: { + metaData: { + network: process.env.ARK_NETWORK_NAME, + }, + }, +} diff --git a/packages/core-error-tracker-bugsnag/lib/index.js b/packages/core-error-tracker-bugsnag/lib/index.js new file mode 100644 index 0000000000..23c21c4035 --- /dev/null +++ b/packages/core-error-tracker-bugsnag/lib/index.js @@ -0,0 +1,16 @@ +const bugsnag = require('bugsnag') + +/** + * The struct used by the plugin container. + * @type {Object} + */ +exports.plugin = { + pkg: require('../package.json'), + defaults: require('./defaults'), + alias: 'error-tracker', + async register(container, options) { + bugsnag.register(options.apiKey, options.configuration) + + return bugsnag + }, +} diff --git a/packages/core-error-tracker-bugsnag/package.json b/packages/core-error-tracker-bugsnag/package.json new file mode 100644 index 0000000000..1d065240a3 --- /dev/null +++ b/packages/core-error-tracker-bugsnag/package.json @@ -0,0 +1,23 @@ +{ + "name": "@arkecosystem/core-error-tracker-bugsnag", + "description": "Bugsnag error tracker integration for Ark Core.", + "version": "0.2.0", + "contributors": [ + "Brian Faust " + ], + "license": "MIT", + "main": "lib/index.js", + "scripts": { + "lint": "eslint ./ --fix", + "depcheck": "depcheck ./" + }, + "dependencies": { + "bugsnag": "^2.4.3" + }, + "publishConfig": { + "access": "public" + }, + "engines": { + "node": ">=10.x" + } +} diff --git a/packages/core-error-tracker-sentry/.gitattributes b/packages/core-error-tracker-sentry/.gitattributes new file mode 100644 index 0000000000..60cc52db63 --- /dev/null +++ b/packages/core-error-tracker-sentry/.gitattributes @@ -0,0 +1,11 @@ +# Path-based git attributes +# https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html + +# Ignore all test and documentation with "export-ignore". +/.editorconfig export-ignore +/.gitattributes export-ignore +/.gitignore export-ignore +/.travis.yml export-ignore +/__tests__ export-ignore +/docs export-ignore +/README.md export-ignore diff --git a/packages/core-database-sequelize/CHANGELOG.md b/packages/core-error-tracker-sentry/CHANGELOG.md similarity index 92% rename from packages/core-database-sequelize/CHANGELOG.md rename to packages/core-error-tracker-sentry/CHANGELOG.md index 127cc35e42..6842caf9df 100644 --- a/packages/core-database-sequelize/CHANGELOG.md +++ b/packages/core-error-tracker-sentry/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Unreleased -## 0.0.1 - 2018-05-31 +## 0.1.0 - 2018-12-03 + ### Added + - initial release diff --git a/packages/core-error-tracker-sentry/LICENSE b/packages/core-error-tracker-sentry/LICENSE new file mode 100644 index 0000000000..d6dd75272f --- /dev/null +++ b/packages/core-error-tracker-sentry/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) Ark Ecosystem + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/core-error-tracker-sentry/README.md b/packages/core-error-tracker-sentry/README.md new file mode 100644 index 0000000000..c8e8102d8f --- /dev/null +++ b/packages/core-error-tracker-sentry/README.md @@ -0,0 +1,22 @@ +# Ark Core - Error Tracker - Sentry + +

+ +

+ +## Documentation + +You can find installation instructions and detailed instructions on how to use this package at the [dedicated documentation site](https://docs.ark.io/guidebook/core/plugins/core-error-tracker-sentry.html). + +## Security + +If you discover a security vulnerability within this package, please send an e-mail to security@ark.io. All security vulnerabilities will be promptly addressed. + +## Credits + +- [Brian Faust](https://github.com/faustbrian) +- [All Contributors](../../../../contributors) + +## License + +[MIT](LICENSE) © [ArkEcosystem](https://ark.io) diff --git a/packages/core-error-tracker-sentry/lib/defaults.js b/packages/core-error-tracker-sentry/lib/defaults.js new file mode 100644 index 0000000000..f981c94507 --- /dev/null +++ b/packages/core-error-tracker-sentry/lib/defaults.js @@ -0,0 +1,6 @@ +module.exports = { + dsn: process.env.ARK_ERROR_TRACKER_SENTRY_DSN, + debug: true, + attachStacktrace: true, + environment: process.env.ARK_NETWORK_NAME, +} diff --git a/packages/core-error-tracker-sentry/lib/index.js b/packages/core-error-tracker-sentry/lib/index.js new file mode 100644 index 0000000000..3ba27e5084 --- /dev/null +++ b/packages/core-error-tracker-sentry/lib/index.js @@ -0,0 +1,16 @@ +const Sentry = require('@sentry/node') + +/** + * The struct used by the plugin container. + * @type {Object} + */ +exports.plugin = { + pkg: require('../package.json'), + defaults: require('./defaults'), + alias: 'error-tracker', + async register(container, options) { + Sentry.init(options) + + return Sentry + }, +} diff --git a/packages/core-error-tracker-sentry/package.json b/packages/core-error-tracker-sentry/package.json new file mode 100644 index 0000000000..a502a45f3d --- /dev/null +++ b/packages/core-error-tracker-sentry/package.json @@ -0,0 +1,23 @@ +{ + "name": "@arkecosystem/core-error-tracker-sentry", + "description": "Sentry error tracker integration for Ark Core.", + "version": "0.2.0", + "contributors": [ + "Brian Faust " + ], + "license": "MIT", + "main": "lib/index.js", + "scripts": { + "lint": "eslint ./ --fix", + "depcheck": "depcheck ./" + }, + "dependencies": { + "@sentry/node": "^4.4.0" + }, + "publishConfig": { + "access": "public" + }, + "engines": { + "node": ">=10.x" + } +} diff --git a/packages/core-event-emitter/CHANGELOG.md b/packages/core-event-emitter/CHANGELOG.md index 127cc35e42..fd0a4f14d3 100644 --- a/packages/core-event-emitter/CHANGELOG.md +++ b/packages/core-event-emitter/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Unreleased -## 0.0.1 - 2018-05-31 +## 0.2.0 - 2018-12-03 + +### Changed + +- Dropped node.js 9 as minimum requirement in favour of node.js 10 + +## 0.1.1 - 2018-06-14 + ### Added + - initial release diff --git a/packages/core-event-emitter/README.md b/packages/core-event-emitter/README.md index e0f7e55c29..1016c52fb0 100644 --- a/packages/core-event-emitter/README.md +++ b/packages/core-event-emitter/README.md @@ -1,12 +1,12 @@ -![ARK Core](https://i.imgur.com/1aP6F2o.png) +# Ark Core - Event Emitter -# ARK Core - Event Emitter +

+ +

-## Installation +## Documentation -```bash -yarn add @arkecosystem/core-event-emitter -``` +You can find installation instructions and detailed instructions on how to use this package at the [dedicated documentation site](https://docs.ark.io/guidebook/core/plugins/core-event-emitter.html). ## Security diff --git a/packages/core-event-emitter/__tests__/emitter.test.js b/packages/core-event-emitter/__tests__/emitter.test.js index 4ca0d681fa..3707cd75da 100755 --- a/packages/core-event-emitter/__tests__/emitter.test.js +++ b/packages/core-event-emitter/__tests__/emitter.test.js @@ -1,11 +1,11 @@ -'use strict' - const EventEmitter = require('eventemitter3') const emitter = require('../lib/emitter') let lastEmit beforeAll(() => { - emitter.on('fake', (data) => (lastEmit = data)) + emitter.on('fake', data => { + lastEmit = data + }) }) describe('Event Manager', () => { diff --git a/packages/core-event-emitter/jest.config.js b/packages/core-event-emitter/jest.config.js index 26f7a25796..57770a97bb 100644 --- a/packages/core-event-emitter/jest.config.js +++ b/packages/core-event-emitter/jest.config.js @@ -1,22 +1,12 @@ -'use strict' - module.exports = { testEnvironment: 'node', bail: false, verbose: true, - testMatch: [ - '**/__tests__/**/*.test.js' - ], - moduleFileExtensions: [ - 'js', - 'json' - ], + testMatch: ['**/__tests__/**/*.test.js'], + moduleFileExtensions: ['js', 'json'], collectCoverage: false, coverageDirectory: '/.coverage', - collectCoverageFrom: [ - 'lib/**/*.js', - '!**/node_modules/**' - ], + collectCoverageFrom: ['lib/**/*.js', '!**/node_modules/**'], watchman: false, - setupTestFrameworkScriptFile: 'jest-extended' + setupTestFrameworkScriptFile: 'jest-extended', } diff --git a/packages/core-event-emitter/jsdoc.json b/packages/core-event-emitter/jsdoc.json index 23276f74ea..f3ea8aab33 100644 --- a/packages/core-event-emitter/jsdoc.json +++ b/packages/core-event-emitter/jsdoc.json @@ -7,9 +7,7 @@ "includePattern": ".js$", "excludePattern": "(node_modules/|docs)" }, - "plugins": [ - "plugins/markdown" - ], + "plugins": ["plugins/markdown"], "opts": { "template": "../../node_modules/docdash", "encoding": "utf8", diff --git a/packages/core-event-emitter/lib/emitter.js b/packages/core-event-emitter/lib/emitter.js index 89d35da7c3..c95b33e734 100644 --- a/packages/core-event-emitter/lib/emitter.js +++ b/packages/core-event-emitter/lib/emitter.js @@ -1,5 +1,3 @@ -'use strict' - const EventEmitter = require('eventemitter3') class Emitter { @@ -7,7 +5,7 @@ class Emitter { * Create a new event manager instance. * @return {WebhookManager} */ - constructor () { + constructor() { this.emitter = new EventEmitter() return this.emitter diff --git a/packages/core-event-emitter/lib/index.js b/packages/core-event-emitter/lib/index.js index f6c04cc63e..f4e1ce95a1 100644 --- a/packages/core-event-emitter/lib/index.js +++ b/packages/core-event-emitter/lib/index.js @@ -1,5 +1,3 @@ -'use strict' - const emitter = require('./emitter') /** @@ -9,7 +7,7 @@ const emitter = require('./emitter') exports.plugin = { pkg: require('../package.json'), alias: 'event-emitter', - async register (container, options) { + async register() { return emitter - } + }, } diff --git a/packages/core-event-emitter/package.json b/packages/core-event-emitter/package.json index d4330b351d..19c1d532e7 100644 --- a/packages/core-event-emitter/package.json +++ b/packages/core-event-emitter/package.json @@ -1,17 +1,16 @@ { "name": "@arkecosystem/core-event-emitter", - "description": "Event Manager for ARK Core", - "version": "0.1.1", + "description": "Event Manager for Ark Core", + "version": "0.2.0", "contributors": [ "Brian Faust " ], "license": "MIT", "main": "lib/index.js", "scripts": { - "build:docs": "../../node_modules/.bin/jsdoc -c jsdoc.json", "test": "cross-env ARK_ENV=test jest --runInBand --detectOpenHandles", - "test:coverage": "cross-env ARK_ENV=test jest --coverage --runInBand --detectOpenHandles", - "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand --watch", + "test:coverage": "cross-env ARK_ENV=test jest --coverage --coveragePathIgnorePatterns='/(defaults.js|index.js)$' --runInBand --detectOpenHandles", + "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand", "test:watch": "cross-env ARK_ENV=test jest --runInBand --watch", "test:watch:all": "cross-env ARK_ENV=test jest --runInBand --watchAll", "lint": "eslint ./ --fix", @@ -22,5 +21,8 @@ }, "publishConfig": { "access": "public" + }, + "engines": { + "node": ">=10.x" } } diff --git a/packages/core-forger/CHANGELOG.md b/packages/core-forger/CHANGELOG.md index f5b21d4f53..137e780335 100644 --- a/packages/core-forger/CHANGELOG.md +++ b/packages/core-forger/CHANGELOG.md @@ -6,11 +6,29 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). ## Unreleased -## 0.0.2 - -- Added PBFT call to p2p layer to assess network state + +## 0.2.0 - 2018-12-03 + +### Added + - Ping blockchain (relay node) to wake-up one slot before forging -- Refactor (spliting monitor into more functions) +- PBFT call to p2p layer to assess network state + +### Changed + +- Split monitor and client to seperate HTTP logic +- Read BIP38 from `.env` +- Read Passphrase from `.env` +- Dropped node.js 9 as minimum requirement in favour of node.js 10 +- Improved logging for transaction errors + +### Fixed + +- Properly exit if no delegates are configured +- Avoid duplicate secrets + +## 0.1.1 - 2018-06-14 -## 0.0.1 - 2018-05-31 ### Added + - initial release diff --git a/packages/core-forger/README.md b/packages/core-forger/README.md index 83091e7a42..6c3ac1f41c 100644 --- a/packages/core-forger/README.md +++ b/packages/core-forger/README.md @@ -1,22 +1,12 @@ -![ARK Core](https://i.imgur.com/1aP6F2o.png) +# Ark Core - Forger -# ARK Core - Forger Manager +

+ +

-## Installation +## Documentation -```bash -yarn add @arkecosystem/core-forger -``` - -## Configuration - -### Defaults - -```js -module.exports = { - hosts: ['http://127.0.0.1:4002'] -} -``` +You can find installation instructions and detailed instructions on how to use this package at the [dedicated documentation site](https://docs.ark.io/guidebook/core/plugins/core-forger.html). ## Security diff --git a/packages/core-forger/__tests__/__fixtures__/block.js b/packages/core-forger/__tests__/__fixtures__/block.js index adf97fd8e0..eebf8e3554 100644 --- a/packages/core-forger/__tests__/__fixtures__/block.js +++ b/packages/core-forger/__tests__/__fixtures__/block.js @@ -11,10 +11,13 @@ module.exports = new Block({ totalFee: 0, reward: 200000000, payloadLength: 0, - payloadHash: 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', - generatorPublicKey: '03806036bc1bb470144184b10f815431c580ae2b806d5fd0ba2118dca823c5c4a6', + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03806036bc1bb470144184b10f815431c580ae2b806d5fd0ba2118dca823c5c4a6', generatorId: 'DMrWy7PddjmDiJFm4bToMj4MhDBa9Wm9vN', - blockSignature: '3045022100d0ad616575b1039b89ae22bb8efbce80dd14f52d193ef7a1d0a76fab0253aa4f02206a347bb5d4dc372e5a7ad3f16ae44409d9190fbd8138e9b4e99f83ca3236f91d', + blockSignature: + '3045022100d0ad616575b1039b89ae22bb8efbce80dd14f52d193ef7a1d0a76fab0253aa4f02206a347bb5d4dc372e5a7ad3f16ae44409d9190fbd8138e9b4e99f83ca3236f91d', confirmations: 1, - totalForged: '200000000' + totalForged: '200000000', }) diff --git a/packages/core-forger/__tests__/__fixtures__/delegate.js b/packages/core-forger/__tests__/__fixtures__/delegate.js index 79361da268..1f4fe1d79a 100644 --- a/packages/core-forger/__tests__/__fixtures__/delegate.js +++ b/packages/core-forger/__tests__/__fixtures__/delegate.js @@ -1,4 +1,5 @@ module.exports = { username: 'arkxdev', - publicKey: '0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0' + publicKey: + '0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0', } diff --git a/packages/core-forger/__tests__/__fixtures__/transaction.js b/packages/core-forger/__tests__/__fixtures__/transaction.js new file mode 100644 index 0000000000..84a20a6472 --- /dev/null +++ b/packages/core-forger/__tests__/__fixtures__/transaction.js @@ -0,0 +1,16 @@ +const { Transaction } = require('@arkecosystem/crypto').models + +module.exports = new Transaction({ + type: 0, + amount: 245098000000000, + fee: 0, + recipientId: 'AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri', + timestamp: 0, + asset: {}, + senderPublicKey: + '035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788', + signature: + '304402205fcb0677e06bde7aac3dc776665615f4b93ef8c3ed0fddecef9900e74fcb00f302206958a0c9868ea1b1f3d151bdfa92da1ce24de0b1fcd91933e64fb7971e92f48d', + id: 'db1aa687737858cc9199bfa336f9b1c035915c30aaee60b1e0f8afadfdb946bd', + senderId: 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn', +}) diff --git a/packages/core-forger/__tests__/__support__/setup.js b/packages/core-forger/__tests__/__support__/setup.js index 57d0cac3ca..48e8a441d4 100644 --- a/packages/core-forger/__tests__/__support__/setup.js +++ b/packages/core-forger/__tests__/__support__/setup.js @@ -1,19 +1,12 @@ -'use strict' - -const path = require('path') -const container = require('@arkecosystem/core-container') +const app = require('@arkecosystem/core-container') +const appHelper = require('@arkecosystem/core-test-utils/lib/helpers/container') exports.setUp = async () => { - await container.setUp({ - data: '~/.ark', - config: path.resolve(__dirname, '../../../core/lib/config/testnet'), - token: 'ark', - network: 'testnet' - }, { - exit: '@arkecosystem/core-blockchain' + await appHelper.setUp({ + exit: '@arkecosystem/core-logger-winston', }) } exports.tearDown = async () => { - await container.tearDown() + await app.tearDown() } diff --git a/packages/core-forger/__tests__/client.test.js b/packages/core-forger/__tests__/client.test.js index dc13da19cf..4edc22b5f6 100644 --- a/packages/core-forger/__tests__/client.test.js +++ b/packages/core-forger/__tests__/client.test.js @@ -1,11 +1,13 @@ -'use strict' - +const axios = require('axios') +const MockAdapter = require('axios-mock-adapter') const app = require('./__support__/setup') const block = require('./__fixtures__/block') +const mockAxios = new MockAdapter(axios) + jest.setTimeout(30000) -const host = 'http://127.0.0.1:4000' +const host = `http://127.0.0.1:${process.env.ARK_P2P_PORT || 4000}` let Client let client @@ -16,11 +18,18 @@ beforeAll(async () => { afterAll(async () => { await app.tearDown() + mockAxios.restore() }) beforeEach(() => { Client = require('../lib/client') client = new Client(host) + + mockAxios.onGet(`${host}/peer/status`).reply(200) +}) + +afterEach(() => { + mockAxios.reset() }) describe('Client', () => { @@ -30,12 +39,11 @@ describe('Client', () => { describe('constructor', () => { it('accepts 1 or more hosts as parameter', () => { - client = new Client(host) - expect(client.hosts).toEqual([host]) + expect(new Client(host).hosts).toEqual([host]) + + const hosts = [host, 'http://localhost:4000'] - const hosts = [host, 'localhost:4000'] - client = new Client(hosts) - expect(client.hosts).toEqual(hosts) + expect(new Client(hosts).hosts).toEqual(hosts) }) }) @@ -46,7 +54,18 @@ describe('Client', () => { describe('when the host is available', () => { it('should be truthy if broadcasts', async () => { - const wasBroadcasted = await client.broadcast(block.toRawJson()) + mockAxios.onPost(`${host}/internal/blocks`).reply(c => { + expect(JSON.parse(c.data).block).toMatchObject( + expect.objectContaining({ + id: block.data.id, + }), + ) + return [200, true] + }) + + await client.__chooseHost() + + const wasBroadcasted = await client.broadcast(block.toJson()) expect(wasBroadcasted).toBeTruthy() }) }) @@ -59,16 +78,14 @@ describe('Client', () => { describe('when the host is available', () => { it('should be ok', async () => { - const round = await client.getRound() - - expect(round).toHaveProperty('current') - expect(round).toHaveProperty('reward') - expect(round).toHaveProperty('timestamp') - expect(round).toHaveProperty('delegates') - // expect(round).toHaveProperty('currentForger') - // expect(round).toHaveProperty('nextForger') - expect(round).toHaveProperty('lastBlock') - expect(round).toHaveProperty('canForge') + const expectedResponse = { foo: 'bar' } + mockAxios + .onGet(`${host}/internal/rounds/current`) + .reply(200, { data: expectedResponse }) + + const response = await client.getRound() + + expect(response).toEqual(expectedResponse) }) }) }) @@ -80,14 +97,15 @@ describe('Client', () => { describe('when the host is available', () => { it('should be ok', async () => { + const expectedResponse = { foo: 'bar' } + mockAxios + .onGet(`${host}/internal/transactions/forging`) + .reply(200, { data: expectedResponse }) + + await client.__chooseHost() const response = await client.getTransactions() - expect(response).toHaveProperty('count') - expect(response.count).toBeNumber() - expect(response).toHaveProperty('poolSize') - expect(response.poolSize).toBeNumber() - expect(response).toHaveProperty('transactions') - expect(response.transactions).toBeArray() + expect(response).toEqual(expectedResponse) }) }) }) @@ -99,14 +117,15 @@ describe('Client', () => { describe('when the host is available', () => { it('should be ok', async () => { - const networkState = await client.getNetworkState() - - expect(networkState).toHaveProperty('quorum') - expect(networkState).toHaveProperty('nodeHeight') - expect(networkState).toHaveProperty('lastBlockId') - expect(networkState).toHaveProperty('overHeightBlockHeader') - expect(networkState).toHaveProperty('minimumNetworkReach') - expect(networkState).toHaveProperty('coldStart') + const expectedResponse = { foo: 'bar' } + mockAxios + .onGet(`${host}/internal/network/state`) + .reply(200, { data: expectedResponse }) + + await client.__chooseHost() + const response = await client.getNetworkState() + + expect(response).toEqual(expectedResponse) }) }) }) @@ -115,5 +134,57 @@ describe('Client', () => { it('should be a function', () => { expect(client.syncCheck).toBeFunction() }) + + it('should induce network sync', async () => { + jest.spyOn(axios, 'get') + mockAxios.onGet(`${host}/internal/blockchain/sync`).reply(200) + + await client.syncCheck() + + expect(axios.get).toHaveBeenCalledWith( + `${host}/internal/blockchain/sync`, + expect.any(Object), + ) + }) + }) + + describe('getUsernames', () => { + it('should be a function', () => { + expect(client.getUsernames).toBeFunction() + }) + + it('should fetch usernames', async () => { + jest.spyOn(axios, 'get') + const expectedResponse = { foo: 'bar' } + mockAxios + .onGet(`${host}/internal/utils/usernames`) + .reply(200, { data: expectedResponse }) + + const response = await client.getUsernames() + + expect(response).toEqual(expectedResponse) + }) + }) + + describe('emitEvent', () => { + it('should be a function', () => { + expect(client.emitEvent).toBeFunction() + }) + it('should emit events', async () => { + jest.spyOn(axios, 'post') + mockAxios.onPost(`${host}/internal/utils/events`).reply(c => { + expect(JSON.parse(c.data)).toMatchObject({ event: 'foo', body: 'bar' }) + return [200] + }) + + await client.__chooseHost() + await client.emitEvent('foo', 'bar') + + expect(axios.post).toHaveBeenCalledWith( + `${host}/internal/utils/events`, + { event: 'foo', body: 'bar' }, + expect.any(Object), + ) + }) }) }) diff --git a/packages/core-forger/__tests__/manager.test.js b/packages/core-forger/__tests__/manager.test.js index 8a9172ae75..daa8a69d50 100644 --- a/packages/core-forger/__tests__/manager.test.js +++ b/packages/core-forger/__tests__/manager.test.js @@ -1,14 +1,14 @@ -'use strict' - +const { Delegate, Transaction } = require('@arkecosystem/crypto').models const app = require('./__support__/setup') const defaultConfig = require('../lib/defaults') const delegate = require('./__fixtures__/delegate') - -const { Delegate } = require('@arkecosystem/crypto').models +const sampleTransaction = require('./__fixtures__/transaction') +const sampleBlock = require('./__fixtures__/block') jest.setTimeout(30000) +jest.mock('../lib/client') -let manager +let forgeManager beforeAll(async () => { await app.setUp() @@ -16,119 +16,249 @@ beforeAll(async () => { afterAll(async () => { await app.tearDown() + jest.restoreAllMocks() }) beforeEach(() => { const ForgeManager = require('../lib/manager') - defaultConfig.hosts = ['http://127.0.0.1:4000'] - manager = new ForgeManager(defaultConfig) + defaultConfig.hosts = [`http://127.0.0.1:${process.env.ARK_P2P_PORT || 4000}`] + forgeManager = new ForgeManager(defaultConfig) }) describe('Forger Manager', () => { describe('loadDelegates', () => { it('should be a function', () => { - expect(manager.loadDelegates).toBeFunction() - }) - - it('should throw an error without configured delegates', async () => { - manager.secrets = null - await expect(manager.loadDelegates()).rejects.toThrowError('No delegate found') + expect(forgeManager.loadDelegates).toBeFunction() }) it('should be ok with configured delegates', async () => { - const delegates = await manager.loadDelegates() + const secret = 'a secret' + forgeManager.secrets = [secret] + forgeManager.client.getUsernames.mockReturnValue([]) - expect(delegates).toBeArray() + const delegates = await forgeManager.loadDelegates() - delegates.forEach(delegate => expect(delegate).toBeInstanceOf(Delegate)) + expect(delegates).toBeArray() + delegates.forEach(value => expect(value).toBeInstanceOf(Delegate)) + expect(forgeManager.client.getUsernames).toHaveBeenCalled() }) }) describe('startForging', () => { it('should be a function', () => { - expect(manager.startForging).toBeFunction() + expect(forgeManager.startForging).toBeFunction() }) }) describe('__forgeNewBlock', () => { it('should be a function', () => { - expect(manager.__forgeNewBlock).toBeFunction() + expect(forgeManager.__forgeNewBlock).toBeFunction() + }) + it('should forge a block', async () => { + forgeManager.client.getTransactions.mockReturnValue({ + transactions: [ + Transaction.serialize(sampleTransaction).toString('hex'), + ], + }) + forgeManager.usernames = [] + const del = new Delegate('a secret', 100) + const round = { + lastBlock: { id: sampleBlock.data.id, height: sampleBlock.data.height }, + timestamp: 1, + reward: 2, + } + + await forgeManager.__forgeNewBlock(del, round) + + expect(forgeManager.client.broadcast).toHaveBeenCalledWith( + expect.objectContaining({ + height: round.lastBlock.height + 1, + reward: round.reward, + }), + ) + expect(forgeManager.client.emitEvent).toHaveBeenCalledWith( + 'block.forged', + expect.any(Object), + ) + expect(forgeManager.client.emitEvent).toHaveBeenCalledWith( + 'transaction.forged', + expect.any(Object), + ) }) }) describe('__monitor', () => { it('should be a function', () => { - expect(manager.__monitor).toBeFunction() + expect(forgeManager.__monitor).toBeFunction() + }) + it('should emit failed event if error while monitoring', async () => { + forgeManager.client.getUsernames.mockRejectedValue( + new Error('oh bollocks'), + ) + + setTimeout(() => forgeManager.stop(), 1000) + await forgeManager.__monitor() + + expect(forgeManager.client.emitEvent).toHaveBeenCalledWith( + 'forger.failed', + 'oh bollocks', + ) }) }) describe('__getTransactionsForForging', () => { it('should be a function', () => { - expect(manager.__getTransactionsForForging).toBeFunction() + expect(forgeManager.__getTransactionsForForging).toBeFunction() + }) + it('should return zero transactions if none to forge', async () => { + forgeManager.client.getTransactions.mockReturnValue({}) + + const transactions = await forgeManager.__getTransactionsForForging() + + expect(transactions).toHaveLength(0) + expect(forgeManager.client.getTransactions).toHaveBeenCalled() + }) + it('should return deserialized transactions', async () => { + forgeManager.client.getTransactions.mockReturnValue({ + transactions: [ + Transaction.serialize(sampleTransaction).toString('hex'), + ], + }) + + const transactions = await forgeManager.__getTransactionsForForging() + + expect(transactions).toHaveLength(1) + expect(forgeManager.client.getTransactions).toHaveBeenCalled() + expect(transactions[0]).toBeInstanceOf(Transaction) + expect(transactions[0].data.recipientId).toEqual( + sampleTransaction.data.recipientId, + ) + expect(transactions[0].data.senderPublicKey).toEqual( + sampleTransaction.data.senderPublicKey, + ) }) }) describe('__isDelegateActivated', () => { it('should be a function', () => { - expect(manager.__isDelegateActivated).toBeFunction() + expect(forgeManager.__isDelegateActivated).toBeFunction() }) it('should be ok', async () => { - manager.delegates = [{ - username: 'arkxdev', - publicKey: '0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0' - }] - - const delegate = await manager.__isDelegateActivated('0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0') - - expect(delegate).toBeObject() - expect(delegate.username).toBe('arkxdev') - expect(delegate.publicKey).toBe('0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0') + forgeManager.delegates = [ + { + username: 'arkxdev', + publicKey: + '0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0', + }, + ] + + const forger = await forgeManager.__isDelegateActivated( + '0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0', + ) + + expect(forger).toBeObject() + expect(forger.username).toBe('arkxdev') + expect(forger.publicKey).toBe( + '0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0', + ) }) }) describe('__analyseNetworkState', () => { it('should be a function', () => { - expect(manager.__analyseNetworkState).toBeFunction() + expect(forgeManager.__analyseNetworkState).toBeFunction() }) it('should be TRUE when quorum > 0.66', async () => { - const networkState = {quorum: 0.9, nodeHeight: 100, lastBlockId: '1233443', overHeightBlockHeader: {}, minimumNetworkReach: true, coldStart: false} - const canForge = await manager.__analyseNetworkState(networkState, delegate) + const networkState = { + quorum: 0.9, + nodeHeight: 100, + lastBlockId: '1233443', + overHeightBlockHeader: {}, + minimumNetworkReach: true, + coldStart: false, + } + const canForge = await forgeManager.__analyseNetworkState( + networkState, + delegate, + ) expect(canForge).toBeTrue() }) it('should be FALSE when quorum < 0.66', async () => { - const networkState = {quorum: 0.65, nodeHeight: 100, lastBlockId: '1233443', overHeightBlockHeader: {}, minimumNetworkReach: true, coldStart: false} - const canForge = await manager.__analyseNetworkState(networkState, delegate) + const networkState = { + quorum: 0.65, + nodeHeight: 100, + lastBlockId: '1233443', + overHeightBlockHeader: {}, + minimumNetworkReach: true, + coldStart: false, + } + const canForge = await forgeManager.__analyseNetworkState( + networkState, + delegate, + ) expect(canForge).toBeFalse() }) it('should be FALSE when coldStart is active', async () => { - const networkState = {quorum: 1, nodeHeight: 100, lastBlockId: '1233443', overHeightBlockHeader: {}, minimumNetworkReach: true, coldStart: true} - const canForge = await manager.__analyseNetworkState(networkState, delegate) + const networkState = { + quorum: 1, + nodeHeight: 100, + lastBlockId: '1233443', + overHeightBlockHeader: {}, + minimumNetworkReach: true, + coldStart: true, + } + const canForge = await forgeManager.__analyseNetworkState( + networkState, + delegate, + ) expect(canForge).toBeFalse() }) it('should be FALSE when minimumNetworkReach is not sufficient', async () => { - const networkState = {quorum: 1, nodeHeight: 100, lastBlockId: '1233443', overHeightBlockHeader: {}, minimumNetworkReach: false, coldStart: true} - const canForge = await manager.__analyseNetworkState(networkState, delegate) + const networkState = { + quorum: 1, + nodeHeight: 100, + lastBlockId: '1233443', + overHeightBlockHeader: {}, + minimumNetworkReach: false, + coldStart: false, + } + const canForge = await forgeManager.__analyseNetworkState( + networkState, + delegate, + ) expect(canForge).toBeFalse() }) it('should be FAIL and detect possible double forging', async () => { + forgeManager.usernames = [] const overHeightBlockHeader = { id: '2816806946235018296', height: 2360065, - generatorPublicKey: '0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0' + generatorPublicKey: + '0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0', } - const networkState = {quorum: 1, nodeHeight: 100, lastBlockId: '1233443', overHeightBlockHeader: overHeightBlockHeader, minimumNetworkReach: 10, coldStart: true} - const canForge = await manager.__analyseNetworkState(networkState, delegate) + const networkState = { + quorum: 1, + nodeHeight: 100, + lastBlockId: '1233443', + overHeightBlockHeader, + minimumNetworkReach: 10, + coldStart: false, + } + const canForge = await forgeManager.__analyseNetworkState( + networkState, + delegate, + ) expect(canForge).toBeFalse() }) diff --git a/packages/core-forger/jest.config.js b/packages/core-forger/jest.config.js index 26f7a25796..57770a97bb 100644 --- a/packages/core-forger/jest.config.js +++ b/packages/core-forger/jest.config.js @@ -1,22 +1,12 @@ -'use strict' - module.exports = { testEnvironment: 'node', bail: false, verbose: true, - testMatch: [ - '**/__tests__/**/*.test.js' - ], - moduleFileExtensions: [ - 'js', - 'json' - ], + testMatch: ['**/__tests__/**/*.test.js'], + moduleFileExtensions: ['js', 'json'], collectCoverage: false, coverageDirectory: '/.coverage', - collectCoverageFrom: [ - 'lib/**/*.js', - '!**/node_modules/**' - ], + collectCoverageFrom: ['lib/**/*.js', '!**/node_modules/**'], watchman: false, - setupTestFrameworkScriptFile: 'jest-extended' + setupTestFrameworkScriptFile: 'jest-extended', } diff --git a/packages/core-forger/jsdoc.json b/packages/core-forger/jsdoc.json index 23276f74ea..f3ea8aab33 100644 --- a/packages/core-forger/jsdoc.json +++ b/packages/core-forger/jsdoc.json @@ -7,9 +7,7 @@ "includePattern": ".js$", "excludePattern": "(node_modules/|docs)" }, - "plugins": [ - "plugins/markdown" - ], + "plugins": ["plugins/markdown"], "opts": { "template": "../../node_modules/docdash", "encoding": "utf8", diff --git a/packages/core-forger/lib/client.js b/packages/core-forger/lib/client.js index 3b2ec1c2ad..6bb85ffd2b 100644 --- a/packages/core-forger/lib/client.js +++ b/packages/core-forger/lib/client.js @@ -1,23 +1,27 @@ -'use strict' -const Promise = require('bluebird') +/* eslint max-len: "off" */ + const axios = require('axios') const sample = require('lodash/sample') -const container = require('@arkecosystem/core-container') -const logger = container.resolvePlugin('logger') -const config = container.resolvePlugin('config') +const delay = require('delay') +const app = require('@arkecosystem/core-container') + +const logger = app.resolvePlugin('logger') +const config = app.resolvePlugin('config') module.exports = class Client { /** * Create a new client instance. * @param {(Array|String)} hosts - Host or Array of hosts */ - constructor (hosts) { + constructor(hosts) { this.hosts = Array.isArray(hosts) ? hosts : [hosts] this.headers = { - version: container.resolveOptions('blockchain').version, - port: container.resolveOptions('p2p').port, - nethash: config.network.nethash + version: app.getVersion(), + port: app.resolveOptions('p2p').port, + nethash: config.network.nethash, + 'x-auth': 'forger', + 'Content-Type': 'application/json', } } @@ -26,82 +30,133 @@ module.exports = class Client { * @param {(Block|Object)} block * @return {Object} */ - async broadcast (block) { - await this.__chooseHost() - - logger.info(`INTERNAL: Sending forged block ${block.id} at height ${block.height.toLocaleString()} with ${block.numberOfTransactions} transactions to ${this.host} :package:`) - - const response = await axios.post(`${this.host}/internal/block`, block, { - headers: this.headers, - timeout: 2000 - }) - - return response.data.success + async broadcast(block) { + logger.debug( + `Broadcasting forged block id:${ + block.id + } at height:${block.height.toLocaleString()} with ${ + block.numberOfTransactions + } transactions to ${this.host} :package:`, + ) + + return this.__post(`${this.host}/internal/blocks`, { block }) } /** * Sends the WAKEUP signal to the to relay hosts to check if synced and sync if necesarry */ - async syncCheck () { - await Promise.each(this.hosts, async (host) => { - logger.debug(`Sending wake-up check to relay node(s) ${host}`) - await this.__get(`${this.host}/internal/syncCheck`) - }) + async syncCheck() { + await this.__chooseHost() + + logger.debug(`Sending wake-up check to relay node ${this.host}`) + + try { + await this.__get(`${this.host}/internal/blockchain/sync`) + } catch (error) { + logger.error(`Could not sync check: ${error.message}`) + } } /** * Get the current round. * @return {Object} */ - async getRound () { - await this.__chooseHost() + async getRound() { + try { + await this.__chooseHost() - const response = await this.__get(`${this.host}/internal/round`) + const response = await this.__get(`${this.host}/internal/rounds/current`) - return response.data.round + return response.data.data + } catch (e) { + return {} + } } /** * Get the current network quorum. * @return {Object} */ - async getNetworkState () { - await this.__chooseHost() - - const response = await this.__get(`${this.host}/internal/networkState`) + async getNetworkState() { + try { + const response = await this.__get(`${this.host}/internal/network/state`) - return response.data.networkState + return response.data.data + } catch (e) { + return {} + } } /** * Get all transactions that are ready to be forged. * @return {Object} */ - async getTransactions () { - await this.__chooseHost() - - const response = await this.__get(`${this.host}/internal/forgingTransactions`) + async getTransactions() { + try { + const response = await this.__get( + `${this.host}/internal/transactions/forging`, + ) - return response.data.data || {} + return response.data.data + } catch (e) { + return {} + } } /** * Get a list of all active delegate usernames. * @return {Object} */ - async getUsernames () { - await this.__chooseHost() + async getUsernames(wait = 0) { + await this.__chooseHost(wait) + + try { + const response = await this.__get(`${this.host}/internal/utils/usernames`) - const response = await this.__get(`${this.host}/internal/usernames`) + return response.data.data + } catch (e) { + return {} + } + } + + /** + * Emit the given event and payload to the local host. + * @param {String} event + * @param {Object} body + * @return {Object} + */ + async emitEvent(event, body) { + // NOTE: Events need to be emitted to the localhost. If you need to trigger + // actions on a remote host based on events you should be using webhooks + // that get triggered by the events you wish to react to. + + const allowedHosts = [ + 'localhost', + '127.0.0.1', + '::ffff:127.0.0.1', + '192.168.*', + ] + + const host = this.hosts.find(item => + allowedHosts.some(allowedHost => item.includes(allowedHost)), + ) + + if (!host) { + return logger.error('Was unable to find any local hosts.') + } - return response.data.data || {} + try { + await this.__post(`${host}/internal/utils/events`, { event, body }) + } catch (error) { + logger.error(`Failed to emit "${event}" to "${host}"`) + } } /** * Chose a responsive host. * @return {void} */ - async __chooseHost () { + async __chooseHost(wait = 0) { const host = sample(this.hosts) try { @@ -109,13 +164,23 @@ module.exports = class Client { this.host = host } catch (error) { - logger.debug(`${host} didn't respond to the forger. Trying another host :sparkler:`) + logger.debug( + `${host} didn't respond to the forger. Trying another host :sparkler:`, + ) - await this.__chooseHost() + if (wait > 0) { + await delay(wait) + } + + await this.__chooseHost(wait) } } - async __get (url) { + async __get(url) { return axios.get(url, { headers: this.headers, timeout: 2000 }) } + + async __post(url, body) { + return axios.post(url, body, { headers: this.headers, timeout: 2000 }) + } } diff --git a/packages/core-forger/lib/defaults.js b/packages/core-forger/lib/defaults.js index 9c403ea130..43700e8a41 100644 --- a/packages/core-forger/lib/defaults.js +++ b/packages/core-forger/lib/defaults.js @@ -1,3 +1,3 @@ module.exports = { - hosts: ['http://127.0.0.1:4002'] + hosts: [`http://127.0.0.1:${process.env.ARK_P2P_PORT || 4002}`], } diff --git a/packages/core-forger/lib/index.js b/packages/core-forger/lib/index.js index 9f5116401a..c4a199a9ea 100644 --- a/packages/core-forger/lib/index.js +++ b/packages/core-forger/lib/index.js @@ -1,5 +1,4 @@ -'use strict' - +const pluralize = require('pluralize') const ForgerManager = require('./manager') /** @@ -10,15 +9,45 @@ exports.plugin = { pkg: require('../package.json'), defaults: require('./defaults'), alias: 'forger', - async register (container, options) { - const forgerManager = await new ForgerManager(options) + async register(container, options) { + const forgerManager = new ForgerManager(options) + const forgers = await forgerManager.loadDelegates( + options.bip38, + options.password, + ) + + if (!forgers) { + container + .resolvePlugin('logger') + .info('Forger is disabled :grey_exclamation:') + return + } - const forgers = await forgerManager.loadDelegates(options.bip38, options.password) + // Don't keep bip38 password in memory + delete process.env.ARK_FORGER_PASSWORD + delete options.password - container.resolvePlugin('logger').info(`ForgerManager started with ${forgers.length} forgers`) + container + .resolvePlugin('logger') + .info( + `Forger Manager started with ${pluralize( + 'forger', + forgers.length, + true, + )}`, + ) forgerManager.startForging() return forgerManager - } + }, + async deregister(container, options) { + const forger = container.resolvePlugin('forger') + + if (forger) { + container.resolvePlugin('logger').info('Stopping Forger Manager') + + return forger.stop() + } + }, } diff --git a/packages/core-forger/lib/manager.js b/packages/core-forger/lib/manager.js index 5928ec54a6..63ed5e3305 100644 --- a/packages/core-forger/lib/manager.js +++ b/packages/core-forger/lib/manager.js @@ -1,15 +1,19 @@ -'use strict' +/* eslint no-await-in-loop: "off" */ const delay = require('delay') -const container = require('@arkecosystem/core-container') -const logger = container.resolvePlugin('logger') -const config = container.resolvePlugin('config') -const emitter = container.resolvePlugin('event-emitter') +const app = require('@arkecosystem/core-container') + +const logger = app.resolvePlugin('logger') +const config = app.resolvePlugin('config') const { slots } = require('@arkecosystem/crypto') const { Delegate, Transaction } = require('@arkecosystem/crypto').models +const isEmpty = require('lodash/isEmpty') +const uniq = require('lodash/uniq') +const pluralize = require('pluralize') + const Client = require('./client') module.exports = class ForgerManager { @@ -17,7 +21,7 @@ module.exports = class ForgerManager { * Create a new forger manager instance. * @param {Object} options */ - constructor (options) { + constructor(options) { this.secrets = config.delegates ? config.delegates.secrets : null this.network = config.network this.client = new Client(options.hosts) @@ -29,12 +33,21 @@ module.exports = class ForgerManager { * @param {String} password * @return {Array} */ - async loadDelegates (bip38, password) { - if (!bip38 && !this.secrets) { - throw new Error('No delegate found') + async loadDelegates(bip38, password) { + if ( + !bip38 && + (!this.secrets || !this.secrets.length || !Array.isArray(this.secrets)) + ) { + logger.warn( + 'No delegate found! Please check your "delegates.json" file and try again.', + ) + return } - this.delegates = this.secrets.map(passphrase => new Delegate(passphrase, this.network, password)) + this.secrets = uniq(this.secrets.map(secret => secret.trim())) + this.delegates = this.secrets.map( + passphrase => new Delegate(passphrase, this.network, password), + ) if (bip38) { logger.info('BIP38 Delegate loaded') @@ -42,14 +55,20 @@ module.exports = class ForgerManager { this.delegates.push(new Delegate(bip38, this.network, password)) } - this.usernames = await this.client.getUsernames() + await this.__loadUsernames(2000) - const delegates = this.delegates.map(delegate => { - return `${this.usernames[delegate.publicKey]} (${delegate.publicKey})` - }) + const delegates = this.delegates.map( + delegate => + `${this.usernames[delegate.publicKey]} (${delegate.publicKey})`, + ) - logger.debug(`Loaded ${delegates} delegates.`) - logger.debug(JSON.stringify(delegates, null, 4)) + logger.debug( + `Loaded ${pluralize( + 'delegate', + delegates.length, + true, + )}: ${delegates.join(', ')}`, + ) return this.delegates } @@ -58,7 +77,7 @@ module.exports = class ForgerManager { * Start forging on the given node. * @return {Object} */ - async startForging () { + async startForging() { const slot = slots.getSlotNumber() while (slots.getSlotNumber() === slot) { @@ -68,57 +87,102 @@ module.exports = class ForgerManager { return this.__monitor(null) } + /** + * Stop forging on the given node. + * @return {void} + */ + async stop() { + this.isStopped = true + } + /** * Monitor the node for any actions that trigger forging. * @param {Object} round * @return {Function} */ - async __monitor (round) { + async __monitor(round) { try { - this.__loadUsernames() + if (this.isStopped) { + return + } + + await this.__loadUsernames() round = await this.client.getRound() - const delayTime = parseInt(config.getConstants(round.lastBlock.height).blocktime) * 1000 - 2000 + const delayTime = + parseInt(config.getConstants(round.lastBlock.height).blocktime) * 1000 - + 2000 if (!round.canForge) { // logger.debug('Block already forged in current slot') // technically it is possible to compute doing shennanigan with arkjs.slots lib + await delay(200) // basically looping until we lock at beginning of next slot + return this.__monitor(round) } const delegate = this.__isDelegateActivated(round.currentForger.publicKey) + if (!delegate) { - // logger.debug(`Current forging delegate ${round.currentForger.publicKey} is not configured on this node.`) + // logger.debug(`Current forging delegate ${ + // round.currentForger.publicKey + // } is not configured on this node.`) if (this.__isDelegateActivated(round.nextForger.publicKey)) { const username = this.usernames[round.nextForger.publicKey] - logger.info(`Next forging delegate ${username} (${round.nextForger.publicKey}) is active on this node.`) + logger.info( + `Next forging delegate ${username} (${ + round.nextForger.publicKey + }) is active on this node.`, + ) await this.client.syncCheck() } await delay(delayTime) // we will check at next slot + return this.__monitor(round) } const networkState = await this.client.getNetworkState() + if (!this.__analyseNetworkState(networkState, delegate)) { await delay(delayTime) // we will check at next slot + return this.__monitor(round) } await this.__forgeNewBlock(delegate, round) await delay(delayTime) // we will check at next slot + return this.__monitor(round) } catch (error) { + // README: The Blockchain is not ready, monitor until it is instead of crashing. + if (error.response && error.response.status === 503) { + logger.warn( + `Blockchain not ready - ${error.response.status} ${ + error.response.statusText + }`, + ) + + await delay(2000) + + return this.__monitor(round) + } + + // README: The Blockchain is ready but an action still failed. logger.error(`Forging failed: ${error.message} :bangbang:`) - logger.error(error.stack) - logger.info('Round:', round ? round.current : '', 'Height:', round ? round.lastBlock.height.toLocaleString() : '') + if (!isEmpty(round)) { + logger.info( + `Round: ${round.current.toLocaleString()}, height: ${round.lastBlock.height.toLocaleString()}`, + ) + } + await delay(2000) // no idea when this will be ok, so waiting 2s before checking again - emitter.emit('forger.failed', error.message) + this.client.emitEvent('forger.failed', error.message) return this.__monitor(round) } @@ -129,36 +193,66 @@ module.exports = class ForgerManager { * @param {Object} delegate * @param {Object} round */ - async __forgeNewBlock (delegate, round) { - emitter.emit('forger.started', delegate.publicKey) - - const transactions = await this.__getTransactionsForForging() - - const blockOptions = {} - blockOptions.previousBlock = round.lastBlock - blockOptions.timestamp = round.timestamp - blockOptions.reward = round.reward - - const block = await delegate.forge(transactions, blockOptions) - - const username = this.usernames[delegate.publicKey] - logger.info(`Forged new block ${block.data.id} by delegate ${username} (${delegate.publicKey}) :trident:`) - - emitter.emit('block.forged', block.data) - transactions.forEach(transaction => emitter.emit('transaction.forged', transaction.data)) - - await this.client.broadcast(block.toRawJson()) + async __forgeNewBlock(delegate, round) { + // TODO: Disabled for now as this could cause a delay in forging that + // results in missing a block which we want to avoid. + // + // We should either use a very radical timeout like 500ms or look + // into another solution for broadcasting this specific event. + // + // this.client.emitEvent('forger.started', delegate.publicKey) + + const transactions = await this.__getTransactionsForForging() + + const blockOptions = {} + blockOptions.previousBlock = round.lastBlock + blockOptions.timestamp = round.timestamp + blockOptions.reward = round.reward + + const block = await delegate.forge(transactions, blockOptions) + + const username = this.usernames[delegate.publicKey] + logger.info( + `Forged new block ${block.data.id} by delegate ${username} (${ + delegate.publicKey + }) :trident:`, + ) + + await this.client.broadcast(block.toJson()) + + this.client.emitEvent('block.forged', block.data) + transactions.forEach(transaction => + this.client.emitEvent('transaction.forged', transaction.data), + ) } /** - * Gets the unconfirmed transactions from the relay nodes transactio pool + * Gets the unconfirmed transactions from the relay nodes transaction pool */ - async __getTransactionsForForging () { - const transactionData = await this.client.getTransactions() - const transactions = transactionData.transactions ? transactionData.transactions.map(serializedTx => Transaction.fromBytes(serializedTx)) : [] - logger.debug(`Received ${transactions.length} transactions from the pool containing ${transactionData.poolSize} :money_with_wings:`) + async __getTransactionsForForging() { + const response = await this.client.getTransactions() + + const transactions = response.transactions + ? response.transactions.map(serializedTx => + Transaction.fromBytes(serializedTx), + ) + : [] + + if (isEmpty(response)) { + logger.error( + 'Could not get unconfirmed transactions from transaction pool.', + ) + } else { + logger.debug( + `Received ${pluralize( + 'transaction', + transactions.length, + true, + )} from the pool containing ${response.poolSize} :money_with_wings:`, + ) + } - return transactions + return transactions } /** @@ -166,8 +260,10 @@ module.exports = class ForgerManager { * @param {Object} PublicKey * @return {Object} */ - __isDelegateActivated (queryPublicKey) { - return this.delegates.find(delegate => delegate.publicKey === queryPublicKey) + __isDelegateActivated(queryPublicKey) { + return this.delegates.find( + delegate => delegate.publicKey === queryPublicKey, + ) } /** @@ -175,30 +271,40 @@ module.exports = class ForgerManager { * @param {Object} networkState internal response * @param {Booolean} isAllowedToForge */ - __analyseNetworkState (networkState, currentForger) { - if (networkState.coldStart) { - logger.info('Not allowed to forge during the cold start period. Check peers.json for coldStart setting.') - logger.debug(`Network State: ${JSON.stringify(networkState)}`) + __analyseNetworkState(networkState, currentForger) { + const badState = message => { + logger.info(message) + logger.debug(`Network State: ${JSON.stringify(networkState, null, 4)}`) + return false } + if (networkState.coldStart) { + return badState( + 'Not allowed to forge during the cold start period. Check peers.json for coldStart setting.', + ) + } + if (!networkState.minimumNetworkReach) { - logger.info('Network reach is not sufficient to get quorum.') - logger.debug(`Network State: ${JSON.stringify(networkState)}`) - return false + return badState('Network reach is not sufficient to get quorum.') } - if (networkState.overHeightBlockHeader && networkState.overHeightBlockHeader.generatorPublicKey === currentForger.publicKey) { - const username = this.usernames[currentForger.publicKey] - logger.info(`Possible double forging for delegate: ${username} (${currentForger.publicKey}).`) - logger.debug(`Network State: ${JSON.stringify(networkState)}`) - return false + if ( + networkState.overHeightBlockHeader && + networkState.overHeightBlockHeader.generatorPublicKey === + currentForger.publicKey + ) { + const usernames = this.usernames[currentForger.publicKey] + + return badState( + `Possible double forging for delegate: ${usernames} (${ + currentForger.publicKey + }).`, + ) } if (networkState.quorum < 0.66) { - logger.info('Fork 6 - Not enough quorum to forge next block.') - logger.debug(`Network State: ${JSON.stringify(networkState)}`) - return false + return badState('Fork 6 - Not enough quorum to forge next block.') } return true @@ -208,7 +314,7 @@ module.exports = class ForgerManager { * Get a list of all active delegate usernames. * @return {Object} */ - async __loadUsernames () { - this.usernames = await this.client.getUsernames() + async __loadUsernames(wait = 0) { + this.usernames = await this.client.getUsernames(wait) } } diff --git a/packages/core-forger/package.json b/packages/core-forger/package.json index 07671725e5..958919f6e5 100644 --- a/packages/core-forger/package.json +++ b/packages/core-forger/package.json @@ -1,7 +1,7 @@ { "name": "@arkecosystem/core-forger", - "description": "Forger for ARK Core", - "version": "0.1.1", + "description": "Forger for Ark Core", + "version": "0.2.0", "contributors": [ "François-Xavier Thoorens ", "Kristjan Košič ", @@ -10,24 +10,32 @@ "license": "MIT", "main": "lib/index.js", "scripts": { - "build:docs": "../../node_modules/.bin/jsdoc -c jsdoc.json", "test": "cross-env ARK_ENV=test jest --runInBand --detectOpenHandles", - "test:coverage": "cross-env ARK_ENV=test jest --coverage --runInBand --detectOpenHandles", - "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand --watch", + "test:coverage": "cross-env ARK_ENV=test jest --coverage --coveragePathIgnorePatterns='/(defaults.js|index.js)$' --runInBand --detectOpenHandles", + "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand", "test:watch": "cross-env ARK_ENV=test jest --runInBand --watch", "test:watch:all": "cross-env ARK_ENV=test jest --runInBand --watchAll", "lint": "eslint ./ --fix", - "depcheck": "depcheck ./" + "depcheck": "depcheck ./ --ignores=lodash,lodash.*" }, "dependencies": { - "@arkecosystem/core-container": "^0.1.1", - "@arkecosystem/crypto": "^0.1.1", + "@arkecosystem/core-container": "~0.2", + "@arkecosystem/crypto": "~0.2", "axios": "^0.18.0", - "bluebird": "^3.5.1", - "delay": "^2.0.0", - "lodash": "^4.17.10" + "delay": "^4.1.0", + "lodash.isempty": "^4.4.0", + "lodash.sample": "^4.2.1", + "lodash.uniq": "^4.5.0", + "pluralize": "^7.0.0" + }, + "devDependencies": { + "@arkecosystem/core-test-utils": "~0.2", + "axios-mock-adapter": "^1.15.0" }, "publishConfig": { "access": "public" + }, + "engines": { + "node": ">=10.x" } } diff --git a/packages/core-graphql/CHANGELOG.md b/packages/core-graphql/CHANGELOG.md index 127cc35e42..6782dc0f4b 100644 --- a/packages/core-graphql/CHANGELOG.md +++ b/packages/core-graphql/CHANGELOG.md @@ -7,6 +7,28 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Unreleased -## 0.0.1 - 2018-05-31 +## 0.2.0 - 2018-12-03 + +### Added + +- Increased test coverage + +### Fixed + +- Ensure order parameters are treated as lower-case +- Sorting and limit of records + +### Changed + +- Migrated to Apollo `2.0.0` +- Dropped node.js 9 as minimum requirement in favour of node.js 10 + +### Fixed + +- Wallet queries and filtering + +## 0.1.1 - 2018-06-14 + ### Added + - initial release diff --git a/packages/core-graphql/README.md b/packages/core-graphql/README.md index 0e634b076f..3f661fbb29 100644 --- a/packages/core-graphql/README.md +++ b/packages/core-graphql/README.md @@ -1,12 +1,12 @@ -![ARK Core](https://i.imgur.com/1aP6F2o.png) +# Ark Core - GraphQL -# ARK Core - GraphQL +

+ +

-## Installation +## Documentation -```bash -yarn add @arkecosystem/core-graphql -``` +You can find installation instructions and detailed instructions on how to use this package at the [dedicated documentation site](https://docs.ark.io/guidebook/core/plugins/core-graphql.html). ## Security diff --git a/packages/core-graphql/__tests__/__support__/config/peers.json b/packages/core-graphql/__tests__/__support__/config/peers.json deleted file mode 100644 index ca55614776..0000000000 --- a/packages/core-graphql/__tests__/__support__/config/peers.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "minimumVersion": ">=1.1.1", - "minimumNetworkReach": 5, - "globalTimeout": 5000, - "coldStart": 30, - "whiteList":[], - "blackList": [], - "list": [{ - "ip": "127.0.0.1", - "port": 4000 - }] -} diff --git a/packages/core-graphql/__tests__/__support__/config/plugins.js b/packages/core-graphql/__tests__/__support__/config/plugins.js deleted file mode 100644 index 76e37bed70..0000000000 --- a/packages/core-graphql/__tests__/__support__/config/plugins.js +++ /dev/null @@ -1,29 +0,0 @@ -module.exports = { - '@arkecosystem/core-config': {}, - '@arkecosystem/core-logger': {}, - '@arkecosystem/core-logger-winston': { - transports: { - console: { - options: { - colorize: true, - level: process.env.ARK_LOG_LEVEL || 'debug' - } - }, - dailyRotate: { - options: { - filename: process.env.ARK_LOG_FILE || `${process.env.ARK_PATH_DATA}/logs/core/${process.env.ARK_NETWORK_NAME}/%DATE%.log`, - datePattern: 'YYYY-MM-DD', - level: process.env.ARK_LOG_LEVEL || 'debug', - zippedArchive: true - } - } - } - }, -'@arkecosystem/core-graphql': { - enabled: true, - host: 'localhost', - port: 4005, - path: '/graphql', - graphiql: true - } -} diff --git a/packages/core-graphql/__tests__/__support__/setup.js b/packages/core-graphql/__tests__/__support__/setup.js index 276ff72947..74736c6bbc 100644 --- a/packages/core-graphql/__tests__/__support__/setup.js +++ b/packages/core-graphql/__tests__/__support__/setup.js @@ -1,18 +1,18 @@ -'use strict' +const app = require('@arkecosystem/core-container') +const appHelper = require('@arkecosystem/core-test-utils/lib/helpers/container') -const path = require('path') -const container = require('@arkecosystem/core-container') +jest.setTimeout(60000) exports.setUp = async () => { - await container.setUp({ - data: '~/.ark', - config: path.resolve(__dirname, './config'), - network: 'testnet', - token: 'ark' - }, { + process.env.ARK_GRAPHQL_ENABLED = true + + await appHelper.setUp({ + exclude: ['@arkecosystem/core-api', '@arkecosystem/core-forger'], }) - return container + return app } -exports.tearDown = () => container.tearDown() +exports.tearDown = async () => { + await app.tearDown() +} diff --git a/packages/core-graphql/__tests__/__support__/utils.js b/packages/core-graphql/__tests__/__support__/utils.js new file mode 100644 index 0000000000..55f834499d --- /dev/null +++ b/packages/core-graphql/__tests__/__support__/utils.js @@ -0,0 +1,17 @@ +const apiHelpers = require('@arkecosystem/core-test-utils/lib/helpers/api') + +class Helpers { + async request(query) { + const url = 'http://localhost:4005/graphql' + const server = require('@arkecosystem/core-container').resolvePlugin( + 'graphql', + ) + + return apiHelpers.request(server, 'POST', url, {}, { query }) + } +} + +/** + * @type {Helpers} + */ +module.exports = new Helpers() diff --git a/packages/core-graphql/__tests__/api/address.test.js b/packages/core-graphql/__tests__/api/address.test.js new file mode 100644 index 0000000000..d1f323d978 --- /dev/null +++ b/packages/core-graphql/__tests__/api/address.test.js @@ -0,0 +1,39 @@ +const app = require('../__support__/setup') +const utils = require('../__support__/utils') +require('@arkecosystem/core-test-utils/lib/matchers') + +beforeAll(async () => { + await app.setUp() +}) + +afterAll(() => { + app.tearDown() +}) + +describe('GraphQL API { address }', () => { + describe('GraphQL resolver for Address', () => { + it('should get wallter for a correctly formatted Address', async () => { + const query = '{ wallet(address: "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn") { producedBlocks } }' + const response = await utils.request(query) + + expect(response).toBeSuccessfulResponse() + + const data = response.data.data + expect(data).toBeObject() + expect(data.wallet).toBeObject() + + expect(data.wallet.producedBlocks).toBe(0) + }) + it('should return an error for an incorrectly formatted Address', async () => { + const query = '{ wallet(address: "bad address") { producedBlocks } }' + const response = await utils.request(query) + + expect(response).not.toBeSuccessfulResponse() + + const data = response.data.data + expect(data).toBeFalsy() + expect(response.data.errors[0]).toBeObject() + expect(response.data.errors[0].message).not.toBeNull() + }) + }) +}) diff --git a/packages/core-graphql/__tests__/api/block.test.js b/packages/core-graphql/__tests__/api/block.test.js new file mode 100644 index 0000000000..93ff1e3185 --- /dev/null +++ b/packages/core-graphql/__tests__/api/block.test.js @@ -0,0 +1,31 @@ +const app = require('../__support__/setup') +const utils = require('../__support__/utils') +require('@arkecosystem/core-test-utils/lib/matchers') + +let genesisBlock + +beforeAll(async () => { + await app.setUp() + + genesisBlock = require('@arkecosystem/core-test-utils/config/testnet/genesisBlock.json') +}) + +afterAll(() => { + app.tearDown() +}) + +describe('GraphQL API { block }', () => { + describe('GraphQL queries for Block', () => { + it('should get a block by its id', async () => { + const query = `{ block(id:"${genesisBlock.id}") { id } }` + const response = await utils.request(query) + + expect(response).toBeSuccessfulResponse() + + const data = response.data.data + expect(data).toBeObject() + expect(data.block).toBeObject() + expect(data.block.id).toBe(genesisBlock.id) + }) + }) +}) diff --git a/packages/core-graphql/__tests__/api/blocks.test.js b/packages/core-graphql/__tests__/api/blocks.test.js new file mode 100644 index 0000000000..1eb312ee51 --- /dev/null +++ b/packages/core-graphql/__tests__/api/blocks.test.js @@ -0,0 +1,60 @@ +const app = require('../__support__/setup') +const utils = require('../__support__/utils') +require('@arkecosystem/core-test-utils/lib/matchers') + +let genesisBlock + +beforeAll(async () => { + await app.setUp() + + genesisBlock = require('@arkecosystem/core-test-utils/config/testnet/genesisBlock.json') +}) + +afterAll(() => { + app.tearDown() +}) + +describe('GraphQL API { blocks }', () => { + describe('GraphQL queries for Blocks - filter by generatorPublicKey', () => { + it('should get blocks by generatorPublicKey', async () => { + const query = `{ blocks(filter: { generatorPublicKey: "${ + genesisBlock.generatorPublicKey + }" }) { id } }` + const response = await utils.request(query) + + expect(response).toBeSuccessfulResponse() + + const data = response.data.data + expect(data).toBeObject() + expect(data.blocks).toEqual([{ id: genesisBlock.id }]) + }) + }) + + describe('GraphQL queries for Blocks - testing relationships', () => { + it('should verify that relationships are valid', async () => { + const query = '{ blocks(limit: 1) { generator { address } } }' + const response = await utils.request(query) + + expect(response).toBeSuccessfulResponse() + + const data = response.data.data + expect(data).toBeObject() + expect(data.blocks[0].generator.address).toEqual( + 'AP6kAVdX1zQ3S8mfDnnHx9GaAohEqQUins', + ) + }) + }) + + describe('GraphQL queries for Blocks - testing api errors', () => { + it('should not be a successful query', async () => { + const query = '{ blocks(filter: { vers } ) { id } }' + const response = await utils.request(query) + + expect(response).not.toBeSuccessfulResponse() + + const error = response.data.errors + expect(error).toBeArray() + expect(response.status).toEqual(400) + }) + }) +}) diff --git a/packages/core-graphql/__tests__/api/transaction.test.js b/packages/core-graphql/__tests__/api/transaction.test.js new file mode 100644 index 0000000000..c9b4aa0d4d --- /dev/null +++ b/packages/core-graphql/__tests__/api/transaction.test.js @@ -0,0 +1,33 @@ +const app = require('../__support__/setup') +const utils = require('../__support__/utils') +require('@arkecosystem/core-test-utils/lib/matchers') + +let genesisBlock + +beforeAll(async () => { + await app.setUp() + + genesisBlock = require('@arkecosystem/core-test-utils/config/testnet/genesisBlock.json') +}) + +afterAll(() => { + app.tearDown() +}) + +describe('GraphQL API { transaction }', () => { + describe('GraphQL queries for Transaction', () => { + it('should get a transaction by its id', async () => { + const query = `{ transaction(id:"${ + genesisBlock.transactions[0].id + }") { id } }` + const response = await utils.request(query) + + expect(response).toBeSuccessfulResponse() + + const data = response.data.data + expect(data).toBeObject() + expect(data.transaction).toBeObject() + expect(data.transaction.id).toBe(genesisBlock.transactions[0].id) + }) + }) +}) diff --git a/packages/core-graphql/__tests__/api/transactions.test.js b/packages/core-graphql/__tests__/api/transactions.test.js new file mode 100644 index 0000000000..1a45068842 --- /dev/null +++ b/packages/core-graphql/__tests__/api/transactions.test.js @@ -0,0 +1,189 @@ +/* eslint max-len: "off" */ + +const app = require('../__support__/setup') +const utils = require('../__support__/utils') +require('@arkecosystem/core-test-utils/lib/matchers') + +let genesisBlock + +beforeAll(async () => { + await app.setUp() + genesisBlock = require('@arkecosystem/core-test-utils/config/testnet/genesisBlock.json') +}) + +afterAll(() => { + app.tearDown() +}) + +describe('GraphQL API { transactions }', () => { + describe('GraphQL queries for Transactions - all', () => { + it('should get 100 transactions', async () => { + const query = '{ transactions { id } }' + const response = await utils.request(query) + + expect(response).toBeSuccessfulResponse() + + const data = response.data.data + expect(data).toBeObject() + expect(data.transactions.length).toBe(100) + }) + }) + + describe('GraphQL queries for Transactions - orderBy', () => { + it('should get 100 transactionsin ascending order of their id', async () => { + const query = + '{ transactions(orderBy: { field: "id", direction: ASC }) { id } }' + const response = await utils.request(query) + + expect(response).toBeSuccessfulResponse() + + const data = response.data.data + expect(data).toBeObject() + expect(data.transactions.length).toBe(100) + expect( + data.transactions.sort((a, b) => (parseInt(a) <= parseInt(b) ? -1 : 0)), + ).toEqual(data.transactions) + }) + }) + + describe('GraphQL queries for Transactions - filter by fee', () => { + it('should get all transactions with fee = 0', async () => { + const query = '{ transactions(filter: { fee: 0 }) { id } }' + const response = await utils.request(query) + + expect(response).toBeSuccessfulResponse() + + const data = response.data.data + expect(data).toBeObject() + expect(data.transactions.length).toBe(100) // because of default limit = 100 + }) + + it('should get no transaction with fee = 987', async () => { + const query = '{ transactions(filter: { fee: 987 }) { id } }' + const response = await utils.request(query) + + expect(response).toBeSuccessfulResponse() + + const data = response.data.data + expect(data).toBeObject() + expect(data.transactions.length).toBe(0) + }) + }) + + describe('GraphQL queries for Transactions - filter by blockId', () => { + it('should get transactions for given blockId', async () => { + const query = `{ transactions(filter: { blockId: "${ + genesisBlock.id + }" }) { id } }` + const response = await utils.request(query) + + expect(response).toBeSuccessfulResponse() + + const data = response.data.data + expect(data).toBeObject() + + const genesisBlockTransactionIds = genesisBlock.transactions.map( + transaction => transaction.id, + ) + data.transactions.forEach(transaction => { + expect(genesisBlockTransactionIds).toContain(transaction.id) + }) + }) + }) + + describe('GraphQL queries for Transactions - filter by senderPublicKey', () => { + it('should get transactions for given senderPublicKey', async () => { + const query = `{ transactions(filter: { senderPublicKey: "${ + genesisBlock.transactions[0].senderPublicKey + }" }) { id } }` + const response = await utils.request(query) + + expect(response).toBeSuccessfulResponse() + + const data = response.data.data + expect(data).toBeObject() + expect(data.transactions.length).toEqual(51) // number of outgoing transactions for the 0th transaction's sender address + + const genesisBlockTransactionIds = genesisBlock.transactions.map( + transaction => transaction.id, + ) + + data.transactions.forEach(transaction => { + expect(genesisBlockTransactionIds).toContain(transaction.id) + }) + }) + }) + + describe('GraphQL queries for Transactions - filter by recipientId', () => { + it('should get transactions for given recipientId', async () => { + const query = + '{ transactions(filter: { recipientId: "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri" }) { id } }' + const response = await utils.request(query) + + expect(response).toBeSuccessfulResponse() + + const data = response.data.data + expect(data).toBeObject() + + expect(data.transactions.length).toBe(2) + }) + }) + + describe('GraphQL queries for Transactions - filter by type', () => { + it('should get transactions for given type', async () => { + const query = '{ transactions(filter: { type: TRANSFER } ) { type } }' + const response = await utils.request(query) + expect(response).toBeSuccessfulResponse() + + const data = response.data.data + expect(data).toBeObject() + + data.transactions.forEach(tx => { + expect(tx.type).toBe(Number(0)) + }) + }) + }) + + describe('GraphQL queries for Transactions - using orderBy, limit', () => { + it('should get 5 transactions in order of ASCending address', async () => { + const query = + '{ transactions(orderBy: { field: "id", direction: ASC }, limit: 5 ) { id } }' + const response = await utils.request(query) + expect(response).toBeSuccessfulResponse() + + const data = response.data.data + expect(data).toBeObject() + expect(data.transactions.length).toBe(5) + + expect(parseInt(data.transactions[0].id, 16)).toBeLessThan( + parseInt(data.transactions[1].id, 16), + ) + }) + }) + + describe('GraphQL queries for Transactions - testing relationships', () => { + it('should verify that relationships are valid', async () => { + const query = '{ transactions(limit: 1) { recipient { address } } }' + const response = await utils.request(query) + + expect(response).toBeSuccessfulResponse() + + const data = response.data.data + expect(data).toBeObject() + expect(data.transactions[0].recipient.address).not.toBeNull() + }) + }) + + describe('GraphQL queries for Transactions - testing api errors', () => { + it('should not be a successful query', async () => { + const query = '{ transaction(filter: { vers } ) { id } }' + const response = await utils.request(query) + + expect(response).not.toBeSuccessfulResponse() + + const error = response.data.errors + expect(error).toBeArray() + expect(response.status).toEqual(400) + }) + }) +}) diff --git a/packages/core-graphql/__tests__/api/wallet.test.js b/packages/core-graphql/__tests__/api/wallet.test.js new file mode 100644 index 0000000000..24c3851620 --- /dev/null +++ b/packages/core-graphql/__tests__/api/wallet.test.js @@ -0,0 +1,33 @@ +const app = require('../__support__/setup') +const utils = require('../__support__/utils') +require('@arkecosystem/core-test-utils/lib/matchers') + +let genesisBlock + +beforeAll(async () => { + await app.setUp() + + genesisBlock = require('@arkecosystem/core-test-utils/config/testnet/genesisBlock.json') +}) + +afterAll(() => { + app.tearDown() +}) + +describe('GraphQL API { wallet }', () => { + describe('GraphQL queries for Wallet', () => { + it('should get a wallet by address', async () => { + const query = `{ wallet(address:"${ + genesisBlock.transactions[0].senderId + }") { address } }` + const response = await utils.request(query) + + expect(response).toBeSuccessfulResponse() + + const data = response.data.data + expect(data).toBeObject() + expect(data.wallet).toBeObject() + expect(data.wallet.address).toBe(genesisBlock.transactions[0].senderId) + }) + }) +}) diff --git a/packages/core-graphql/__tests__/api/wallets.test.js b/packages/core-graphql/__tests__/api/wallets.test.js new file mode 100644 index 0000000000..ec908b8d61 --- /dev/null +++ b/packages/core-graphql/__tests__/api/wallets.test.js @@ -0,0 +1,96 @@ +/* eslint max-len: "off" */ + +const app = require('../__support__/setup') +const utils = require('../__support__/utils') +require('@arkecosystem/core-test-utils/lib/matchers') + +beforeAll(async () => { + await app.setUp() +}) + +afterAll(() => { + app.tearDown() +}) + +describe('GraphQL API { wallets }', () => { + describe('GraphQL queries for Wallets - get all', () => { + it('should get all wallets', async () => { + const query = '{ wallets { address } }' + const response = await utils.request(query) + + expect(response).toBeSuccessfulResponse() + + const data = response.data.data + expect(data).toBeObject() + expect(data.wallets.length).toBe(53) + // TODO why 53 ? From genesis block I can count 52, but there is an additional "AP6kAVdX1zQ3S8mfDnnHx9GaAohEqQUins" wallet. What did I miss ? + }) + }) + + describe('GraphQL queries for Wallets - filter by vote', () => { + it('should get all wallets with specific vote', async () => { + const query = + '{ wallets(filter: { vote: "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd" }) { address } }' + const response = await utils.request(query) + + expect(response).toBeSuccessfulResponse() + + const data = response.data.data + expect(data).toBeObject() + expect(data.wallets.length).toBe(1) + }) + + it('should get no wallet with unknown vote', async () => { + const query = + '{ wallets(filter: { vote: "unknownPublicKey" }) { address } }' + const response = await utils.request(query) + + expect(response).toBeSuccessfulResponse() + + const data = response.data.data + expect(data).toBeObject() + expect(data.wallets.length).toBe(0) + }) + }) + + describe('GraphQL queries for Wallets - using orderBy, limit', () => { + it('should get 5 wallets in order of ASCending address', async () => { + const query = + '{ wallets(orderBy: { field: "address", direction: ASC }, limit: 5 ) { address } }' + const response = await utils.request(query) + + expect(response).toBeSuccessfulResponse() + + const data = response.data.data + expect(data).toBeObject() + expect(data.wallets.length).toBe(5) + expect( + data.wallets.sort((a, b) => (parseInt(a) <= parseInt(b) ? -1 : 0)), + ).toEqual(data.wallets) + }) + }) + + describe('GraphQL queries for Wallets - testing relationships', () => { + it('should verify that relationships are valid', async () => { + const query = '{ wallets(limit: 1) { transactions { id } } }' + const response = await utils.request(query) + + expect(response).toBeSuccessfulResponse() + + expect(response.data.errors[0]).toBeObject() // relationships doesn't function well (unimplemented) + }) + }) + + describe('GraphQL queries for Wallets - testing api errors', () => { + it('should not be a successful query', async () => { + const query = '{ wallets(filter: { vers } ) { address } }' + const response = await utils.request(query) + + expect(response).not.toBeSuccessfulResponse() + + const error = response.data.errors + expect(error).toBeArray() + expect(response.status).toEqual(400) + }) + }) +}) diff --git a/packages/core-graphql/__tests__/graphql.test.js b/packages/core-graphql/__tests__/graphql.test.js deleted file mode 100644 index 1c38decf85..0000000000 --- a/packages/core-graphql/__tests__/graphql.test.js +++ /dev/null @@ -1,18 +0,0 @@ -const app = require('./__support__/setup') - -let graphql - -beforeAll(async () => { - const container = await app.setUp() - graphql = await container.resolvePlugin('graphql') -}) - -afterAll(() => { - app.tearDown() -}) - -describe('GraphQL', () => { - it('should be an object', () => { - expect(graphql).toBeObject() - }) -}) diff --git a/packages/core-graphql/jest.config.js b/packages/core-graphql/jest.config.js index 4a1ec0f05f..57770a97bb 100644 --- a/packages/core-graphql/jest.config.js +++ b/packages/core-graphql/jest.config.js @@ -1,22 +1,12 @@ -'use strict'; - module.exports = { testEnvironment: 'node', bail: false, verbose: true, - testMatch: [ - '**/__tests__/**/*.test.js' - ], - moduleFileExtensions: [ - 'js', - 'json' - ], + testMatch: ['**/__tests__/**/*.test.js'], + moduleFileExtensions: ['js', 'json'], collectCoverage: false, coverageDirectory: '/.coverage', - collectCoverageFrom: [ - 'lib/**/*.js', - '!**/node_modules/**' - ], + collectCoverageFrom: ['lib/**/*.js', '!**/node_modules/**'], watchman: false, - setupTestFrameworkScriptFile: 'jest-extended' + setupTestFrameworkScriptFile: 'jest-extended', } diff --git a/packages/core-graphql/jsdoc.json b/packages/core-graphql/jsdoc.json index 23276f74ea..f3ea8aab33 100644 --- a/packages/core-graphql/jsdoc.json +++ b/packages/core-graphql/jsdoc.json @@ -7,9 +7,7 @@ "includePattern": ".js$", "excludePattern": "(node_modules/|docs)" }, - "plugins": [ - "plugins/markdown" - ], + "plugins": ["plugins/markdown"], "opts": { "template": "../../node_modules/docdash", "encoding": "utf8", diff --git a/packages/core-graphql/lib/defaults.js b/packages/core-graphql/lib/defaults.js index d4908705aa..dfbc999d31 100644 --- a/packages/core-graphql/lib/defaults.js +++ b/packages/core-graphql/lib/defaults.js @@ -1,9 +1,9 @@ -'use strict'; - +/** + * Default configuration for the @arkecosystem/core-graphql plugin + */ module.exports = { enabled: false, host: process.env.ARK_GRAPHQL_HOST || '0.0.0.0', port: process.env.ARK_GRAPHQL_PORT || 4005, path: '/graphql', - graphiql: true } diff --git a/packages/core-graphql/lib/defs/index.js b/packages/core-graphql/lib/defs/index.js index 607fd7875c..643317b565 100644 --- a/packages/core-graphql/lib/defs/index.js +++ b/packages/core-graphql/lib/defs/index.js @@ -1,9 +1,11 @@ -'use strict'; - const inputs = require('./inputs') const types = require('./types') const root = require('./root') +/** + * Concatenated strings following the GraphQL syntax to define Types + * processed by the schema. + */ module.exports = ` ${inputs} ${root} diff --git a/packages/core-graphql/lib/defs/inputs.js b/packages/core-graphql/lib/defs/inputs.js index afe5fc33fe..082682184d 100644 --- a/packages/core-graphql/lib/defs/inputs.js +++ b/packages/core-graphql/lib/defs/inputs.js @@ -1,5 +1,11 @@ -'use strict'; - +/** + * Template for the inputs of our schema's types. + * Scalars are the possible base values for query parameters. + * OrderDirection defaults to DESC in the resolvers. + * Includes an enum to check TransactionTypes with supplied query parameter. + * Has filters to be used against the main types of queriable objects. + * Order query by specified field, with respect to OrderDirection. + */ module.exports = ` scalar JSON scalar Limit @@ -27,7 +33,7 @@ module.exports = ` fee: Float blockId: String senderPublicKey: String - recipientId: Address + recipientId: String type: TransactionType } diff --git a/packages/core-graphql/lib/defs/root.js b/packages/core-graphql/lib/defs/root.js index e6c78ce648..91e4c19759 100644 --- a/packages/core-graphql/lib/defs/root.js +++ b/packages/core-graphql/lib/defs/root.js @@ -1,5 +1,9 @@ -'use strict'; - +/** + * Necessary for the GraphQL engine to have a root schema and a base query. + * Here we have definitions for root queries, which are like endpoints in a + * REST API. Every root query has an associated return structure which is + * based on types defined in types.js. + */ module.exports = ` type Query { block(id: String): Block diff --git a/packages/core-graphql/lib/defs/types.js b/packages/core-graphql/lib/defs/types.js index f4e7069e3b..ff05a652ea 100644 --- a/packages/core-graphql/lib/defs/types.js +++ b/packages/core-graphql/lib/defs/types.js @@ -1,5 +1,12 @@ -'use strict'; - +/** + * Actual types which are relevant to queries issued to our GraphQL endpoint. + * The basic ones are Block, Wallet and Transaction. They each have specific + * properties and are representative of how they are stored in the Blockchain. + * For example, a Block type has an array of transactions [Transaction], and + * Transaction itself is a type which has sender and recipiet Wallet types. + * Same principles apply to Wallet types, there is interoperability between + * the defined types of this schema. + */ module.exports = ` type Block { id: String @@ -24,7 +31,7 @@ module.exports = ` version: Int! timestamp: Int! senderPublicKey: String - recipientId: String + recipientId: Address type: Int! vendorField: String amount: Float @@ -36,13 +43,13 @@ module.exports = ` } type Wallet { - address: String + address: Address publicKey: String secondPublicKey: String vote: String username: String balance: Float - votebalance: Float + voteBalance: Float producedBlocks: Float missedBlocks: Float transactions(limit: Limit, offset: Offset, orderBy: OrderByInput): [Transaction] diff --git a/packages/core-graphql/lib/helpers/format-orderBy.js b/packages/core-graphql/lib/helpers/format-orderBy.js index 63f22fde97..29961161f1 100644 --- a/packages/core-graphql/lib/helpers/format-orderBy.js +++ b/packages/core-graphql/lib/helpers/format-orderBy.js @@ -1,10 +1,14 @@ -'use strict'; - +/** + * Logic used by our orderBy input + * @param {Object} parameter + * @param {String} defaultValue + * @return {String} + */ module.exports = (parameter, defaultValue) => { let order if (parameter) { - order = `${parameter.field}:${parameter.direction}` + order = `${parameter.field}:${parameter.direction.toLowerCase()}` } return order || defaultValue diff --git a/packages/core-graphql/lib/helpers/index.js b/packages/core-graphql/lib/helpers/index.js index d25b077625..4bb2364535 100644 --- a/packages/core-graphql/lib/helpers/index.js +++ b/packages/core-graphql/lib/helpers/index.js @@ -1,6 +1,7 @@ -'use strict' - +/** + * Root module for our two helper functions + */ module.exports = { formatOrderBy: require('./format-orderBy'), - unserializeTransactions: require('./unserialize-transactions') + unserializeTransactions: require('./unserialize-transactions'), } diff --git a/packages/core-graphql/lib/helpers/unserialize-transactions.js b/packages/core-graphql/lib/helpers/unserialize-transactions.js index 86ac3facd0..37e9e9bb06 100644 --- a/packages/core-graphql/lib/helpers/unserialize-transactions.js +++ b/packages/core-graphql/lib/helpers/unserialize-transactions.js @@ -1,13 +1,20 @@ -'use strict'; - const { Transaction } = require('@arkecosystem/crypto').models -module.exports = async (data) => { - return data.reduce((total, value, key) => { - const serialized = Buffer.from(value.serialized).toString('hex') +/** + * Deserialize multiple transactions + */ +module.exports = async data => { + const deserialize = buffer => { + const serialized = Buffer.from(buffer).toString('hex') + return Transaction.deserialize(serialized) + } - total.push(Transaction.deserialize(serialized)) + if (Array.isArray(data)) { + return data.reduce((total, value, key) => { + total.push(deserialize(value.serialized)) - return total - }, []) + return total + }, []) + } + return deserialize(data) } diff --git a/packages/core-graphql/lib/index.js b/packages/core-graphql/lib/index.js index 7f0edb6cb5..d8137eb0fc 100644 --- a/packages/core-graphql/lib/index.js +++ b/packages/core-graphql/lib/index.js @@ -1,5 +1,3 @@ -'use strict'; - /** * The struct used by the plugin manager. * @type {Object} @@ -8,20 +6,22 @@ exports.plugin = { pkg: require('../package.json'), defaults: require('./defaults'), alias: 'graphql', - async register (container, options) { + async register(container, options) { if (!options.enabled) { - container.resolvePlugin('logger').info('GraphQL API is disabled :grey_exclamation:') + container + .resolvePlugin('logger') + .info('GraphQL API is disabled :grey_exclamation:') return } return require('./server')(options) }, - async deregister (container, options) { + async deregister(container, options) { if (options.enabled) { container.resolvePlugin('logger').info('Stopping GraphQL API') return container.resolvePlugin('graphql').stop() } - } + }, } diff --git a/packages/core-graphql/lib/repositories/blocks.js b/packages/core-graphql/lib/repositories/blocks.js new file mode 100644 index 0000000000..c779a84d46 --- /dev/null +++ b/packages/core-graphql/lib/repositories/blocks.js @@ -0,0 +1,148 @@ +const app = require('@arkecosystem/core-container') + +const database = app.resolvePlugin('database') + +const buildFilterQuery = require('./utils/filter-query') +const Repository = require('./repository') + +class BlocksRepository extends Repository { + /** + * Get all blocks for the given parameters. + * @param {Object} parameters + * @return {Object} + */ + async findAll(parameters = {}) { + const selectQuery = this.query.select().from(this.query) + const countQuery = this._makeEstimateQuery() + + const applyConditions = queries => { + const conditions = Object.entries(this._formatConditions(parameters)) + + if (conditions.length) { + const first = conditions.shift() + + for (const item of queries) { + item.where(this.query[first[0]].equals(first[1])) + + for (const condition of conditions) { + item.and(this.query[condition[0]].equals(condition[1])) + } + } + } + } + + applyConditions([selectQuery, countQuery]) + + return this._findManyWithCount(selectQuery, countQuery, { + limit: parameters.limit || 100, + offset: parameters.offset || 0, + orderBy: this.__orderBy(parameters), + }) + } + + /** + * Get all blocks for the given generator. + * @param {String} generatorPublicKey + * @param {Object} paginator + * @return {Object} + */ + async findAllByGenerator(generatorPublicKey, paginator) { + return this.findAll({ ...{ generatorPublicKey }, ...paginator }) + } + + /** + * Get a block. + * @param {Number} id + * @return {Object} + */ + async findById(id) { + const query = this.query + .select() + .from(this.query) + .where(this.query.id.equals(id)) + + return this._find(query) + } + + /** + * Get the last block for the given generator. + * TODO is this right? + * @param {String} generatorPublicKey + * @return {Object} + */ + async findLastByPublicKey(generatorPublicKey) { + const query = this.query + .select(this.query.id, this.query.timestamp) + .from(this.query) + .where(this.query.generator_public_key.equals(generatorPublicKey)) + .order(this.query.height.desc) + + return this._find(query) + } + + /** + * Search all blocks. + * @param {Object} parameters + * @return {Object} + */ + async search(parameters) { + const selectQuery = this.query.select().from(this.query) + const countQuery = this._makeEstimateQuery() + + const applyConditions = queries => { + const conditions = buildFilterQuery(this._formatConditions(parameters), { + exact: [ + 'id', + 'version', + 'previous_block', + 'payload_hash', + 'generator_public_key', + 'block_signature', + ], + between: [ + 'timestamp', + 'height', + 'number_of_transactions', + 'total_amount', + 'total_fee', + 'reward', + 'payload_length', + ], + }) + + if (conditions.length) { + const first = conditions.shift() + + for (const item of queries) { + item.where(this.query[first.column][first.method](first.value)) + + for (const condition of conditions) { + item.and( + this.query[condition.column][condition.method](condition.value), + ) + } + } + } + } + + applyConditions([selectQuery, countQuery]) + + return this._findManyWithCount(selectQuery, countQuery, { + limit: parameters.limit, + offset: parameters.offset, + orderBy: this.__orderBy(parameters), + }) + } + + getModel() { + return database.models.block + } + + __orderBy(parameters) { + return parameters.orderBy + ? parameters.orderBy.split(':').map(p => p.toLowerCase()) + : ['height', 'desc'] + } +} + +module.exports = new BlocksRepository() diff --git a/packages/core-graphql/lib/repositories/index.js b/packages/core-graphql/lib/repositories/index.js new file mode 100644 index 0000000000..5724a9e9b4 --- /dev/null +++ b/packages/core-graphql/lib/repositories/index.js @@ -0,0 +1,4 @@ +module.exports = { + blocks: require('./blocks'), + transactions: require('./transactions'), +} diff --git a/packages/core-graphql/lib/repositories/repository.js b/packages/core-graphql/lib/repositories/repository.js new file mode 100644 index 0000000000..044d25fc3a --- /dev/null +++ b/packages/core-graphql/lib/repositories/repository.js @@ -0,0 +1,73 @@ +/* eslint max-len: "off" */ + +const app = require('@arkecosystem/core-container') + +const database = app.resolvePlugin('database') + +module.exports = class Repository { + constructor() { + this.cache = database.getCache() + this.model = this.getModel() + this.query = this.model.query() + } + + async _find(query) { + return database.query.oneOrNone(query.toQuery()) + } + + async _findMany(query) { + return database.query.manyOrNone(query.toQuery()) + } + + async _findManyWithCount( + selectQuery, + countQuery, + { limit, offset, orderBy }, + ) { + const { count } = await this._find(countQuery) + + selectQuery + .order(this.query[orderBy[0]][orderBy[1]]) + .offset(offset) + .limit(limit) + + limit = 100 + offset = 0 + const rows = await this._findMany(selectQuery) + return { + rows, + count: +count, + } + } + + _makeCountQuery() { + return this.query.select('count(*) AS count').from(this.query) + } + + _makeEstimateQuery() { + return this.query + .select('count(*) AS count') + .from(`${this.model.getTable()} TABLESAMPLE SYSTEM (100)`) + } + + _formatConditions(parameters) { + const columns = this.model.getColumnSet().columns.map(column => ({ + name: column.name, + prop: column.prop || column.name, + })) + + const columnNames = columns.map(column => column.name) + const columnProps = columns.map(column => column.prop) + + const filter = args => + args.filter(arg => columnNames.includes(arg) || columnProps.includes(arg)) + + return filter(Object.keys(parameters)).reduce((items, item) => { + const columnName = columns.find(column => column.prop === item).name + + items[columnName] = parameters[item] + + return items + }, {}) + } +} diff --git a/packages/core-graphql/lib/repositories/transactions.js b/packages/core-graphql/lib/repositories/transactions.js new file mode 100644 index 0000000000..11001079ac --- /dev/null +++ b/packages/core-graphql/lib/repositories/transactions.js @@ -0,0 +1,451 @@ +const app = require('@arkecosystem/core-container') + +const database = app.resolvePlugin('database') + +const dayjs = require('dayjs-ext') +const { slots } = require('@arkecosystem/crypto') +const { TRANSACTION_TYPES } = require('@arkecosystem/crypto').constants +const buildFilterQuery = require('./utils/filter-query') +const Repository = require('./repository') + +class TransactionsRepository extends Repository { + /** + * Get all transactions. + * @param {Object} params + * @return {Object} + */ + async findAll(parameters = {}) { + const selectQuery = this.query.select().from(this.query) + const countQuery = this._makeEstimateQuery() + + if (parameters.senderId) { + const senderPublicKey = this.__publicKeyFromSenderId(parameters.senderId) + + if (!senderPublicKey) { + return { rows: [], count: 0 } + } + + parameters.senderPublicKey = senderPublicKey + } + + if (parameters.type) { + parameters.type = TRANSACTION_TYPES[parameters.type] + } + + const applyConditions = queries => { + const conditions = Object.entries(this._formatConditions(parameters)) + + if (conditions.length) { + const first = conditions.shift() + + for (const item of queries) { + item.where(this.query[first[0]].equals(first[1])) + + for (const condition of conditions) { + item.and(this.query[condition[0]].equals(condition[1])) + } + } + } + } + + applyConditions([selectQuery, countQuery]) + + const results = await this._findManyWithCount(selectQuery, countQuery, { + limit: parameters.limit || 100, + offset: parameters.offset || 0, + orderBy: this.__orderBy(parameters), + }) + + results.rows = await this.__mapBlocksToTransactions(results.rows) + return results + } + + /** + * Get all transactions (LEGACY, for V1 only). + * @param {Object} params + * @return {Object} + */ + async findAllLegacy(parameters = {}) { + const selectQuery = this.query + .select(this.query.block_id, this.query.serialized) + .from(this.query) + const countQuery = this._makeEstimateQuery() + + if (parameters.senderId) { + parameters.senderPublicKey = this.__publicKeyFromSenderId( + parameters.senderId, + ) + } + + const applyConditions = queries => { + const conditions = Object.entries(this._formatConditions(parameters)) + + if (conditions.length) { + const first = conditions.shift() + + for (const item of queries) { + item.where(this.query[first[0]].equals(first[1])) + + for (const [key, value] of conditions) { + item.or(this.query[key].equals(value)) + } + } + } + } + + applyConditions([selectQuery, countQuery]) + + const results = await this._findManyWithCount(selectQuery, countQuery, { + limit: parameters.limit, + offset: parameters.offset, + orderBy: this.__orderBy(parameters), + }) + + results.rows = await this.__mapBlocksToTransactions(results.rows) + + return results + } + + /** + * Get all transactions for the given Wallet object. + * @param {Wallet} wallet + * @param {Object} parameters + * @return {Object} + */ + async findAllByWallet(wallet, parameters = {}) { + const selectQuery = this.query + .select(this.query.block_id, this.query.serialized) + .from(this.query) + const countQuery = this._makeEstimateQuery() + + const applyConditions = queries => { + for (const item of queries) { + item + .where(this.query.sender_public_key.equals(wallet.publicKey)) + .or(this.query.recipient_id.equals(wallet.address)) + } + } + + applyConditions([selectQuery, countQuery]) + + const results = await this._findManyWithCount(selectQuery, countQuery, { + limit: parameters.limit, + offset: parameters.offset, + orderBy: this.__orderBy(parameters), + }) + + results.rows = await this.__mapBlocksToTransactions(results.rows) + + return results + } + + /** + * Get all transactions for the given sender public key. + * @param {String} senderPublicKey + * @param {Object} parameters + * @return {Object} + */ + async findAllBySender(senderPublicKey, parameters = {}) { + return this.findAll({ ...{ senderPublicKey }, ...parameters }) + } + + /** + * Get all transactions for the given recipient address. + * @param {String} recipientId + * @param {Object} parameters + * @return {Object} + */ + async findAllByRecipient(recipientId, parameters = {}) { + return this.findAll({ ...{ recipientId }, ...parameters }) + } + + /** + * Get all vote transactions for the given sender public key. + * TODO rename to findAllVotesBySender or not? + * @param {String} senderPublicKey + * @param {Object} parameters + * @return {Object} + */ + async allVotesBySender(senderPublicKey, parameters = {}) { + return this.findAll({ + ...{ senderPublicKey, type: TRANSACTION_TYPES.VOTE }, + ...parameters, + }) + } + + /** + * Get all transactions for the given block. + * @param {Number} blockId + * @param {Object} parameters + * @return {Object} + */ + async findAllByBlock(blockId, parameters = {}) { + return this.findAll({ ...{ blockId }, ...parameters }) + } + + /** + * Get all transactions for the given type. + * @param {Number} type + * @param {Object} parameters + * @return {Object} + */ + async findAllByType(type, parameters = {}) { + return this.findAll({ ...{ type }, ...parameters }) + } + + /** + * Get a transaction. + * @param {Number} id + * @return {Object} + */ + async findById(id) { + const query = this.query + .select(this.query.block_id, this.query.serialized) + .from(this.query) + .where(this.query.id.equals(id)) + + const transaction = await this._find(query) + + return this.__mapBlocksToTransactions(transaction) + } + + /** + * Get a transactions for the given type and id. + * @param {Number} type + * @param {Number} id + * @return {Object} + */ + async findByTypeAndId(type, id) { + const query = this.query + .select(this.query.block_id, this.query.serialized) + .from(this.query) + .where(this.query.id.equals(id).and(this.query.type.equals(type))) + + const transaction = await this._find(query) + + return this.__mapBlocksToTransactions(transaction) + } + + /** + * Get transactions for the given ids. + * @param {Array} ids + * @return {Object} + */ + async findByIds(ids) { + const query = this.query + .select(this.query.block_id, this.query.serialized) + .from(this.query) + .where(this.query.id.in(ids)) + + return this._findMany(query) + } + + /** + * Get all transactions that have a vendor field. + * @return {Object} + */ + async findWithVendorField() { + const query = this.query + .select(this.query.block_id, this.query.serialized) + .from(this.query) + .where(this.query.vendor_field_hex.isNotNull()) + + const transactions = await this._findMany(query) + + return this.__mapBlocksToTransactions(transactions) + } + + /** + * Calculates min, max and average fee statistics based on transactions table + * @return {Object} + */ + async getFeeStatistics() { + const query = this.query + .select( + this.query.type, + this.query.fee.min('minFee'), + this.query.fee.max('maxFee'), + this.query.fee.avg('avgFee'), + this.query.timestamp.max('timestamp'), + ) + .from(this.query) + .where( + this.query.timestamp.gte(slots.getTime(dayjs().subtract(30, 'days'))), + ) + .group(this.query.type) + .order('"timestamp" DESC') + + return this._findMany(query) + } + + /** + * Search all transactions. + * + * @param {Object} params + * @return {Object} + */ + async search(parameters) { + const selectQuery = this.query.select().from(this.query) + const countQuery = this._makeEstimateQuery() + + if (parameters.senderId) { + const senderPublicKey = this.__publicKeyFromSenderId(parameters.senderId) + + if (senderPublicKey) { + parameters.senderPublicKey = senderPublicKey + } + } + + const applyConditions = queries => { + const conditions = buildFilterQuery(this._formatConditions(parameters), { + exact: [ + 'id', + 'block_id', + 'type', + 'version', + 'sender_public_key', + 'recipient_id', + ], + between: ['timestamp', 'amount', 'fee'], + wildcard: ['vendor_field_hex'], + }) + + if (conditions.length) { + const first = conditions.shift() + + for (const item of queries) { + item.where(this.query[first.column][first.method](first.value)) + + for (const condition of conditions) { + item.and( + this.query[condition.column][condition.method](condition.value), + ) + } + } + } + } + + applyConditions([selectQuery, countQuery]) + + const results = await this._findManyWithCount(selectQuery, countQuery, { + limit: parameters.limit, + offset: parameters.offset, + orderBy: this.__orderBy(parameters), + }) + + results.rows = await this.__mapBlocksToTransactions(results.rows) + + return results + } + + getModel() { + return database.models.transaction + } + + /** + * [__mapBlocksToTransactions description] + * @param {Array|Object} data + * @return {Object} + */ + async __mapBlocksToTransactions(data) { + const blockQuery = database.models.block.query() + + // Array... + if (Array.isArray(data)) { + // 1. get heights from cache + const missingFromCache = [] + + for (let i = 0; i < data.length; i++) { + const cachedBlock = this.__getBlockCache(data[i].blockId) + + if (cachedBlock) { + data[i].block = cachedBlock + } else { + missingFromCache.push({ + index: i, + blockId: data[i].blockId, + }) + } + } + + // 2. get missing heights from database + if (missingFromCache.length) { + const query = blockQuery + .select(blockQuery.id, blockQuery.height) + .from(blockQuery) + .where(blockQuery.id.in(missingFromCache.map(d => d.blockId))) + .group(blockQuery.id) + + const blocks = await this._findMany(query) + + for (const missing of missingFromCache) { + const block = blocks.find(item => item.id === missing.blockId) + if (block) { + data[missing.index].block = block + this.__setBlockCache(block) + } + } + } + + return data + } + + // Object... + if (data) { + const cachedBlock = this.__getBlockCache(data.blockId) + + if (cachedBlock) { + data.block = cachedBlock + } else { + const query = blockQuery + .select(blockQuery.id, blockQuery.height) + .from(blockQuery) + .where(blockQuery.id.equals(data.blockId)) + + data.block = await this._find(query) + + this.__setBlockCache(data.block) + } + } + + return data + } + + /** + * Tries to retrieve the height of the block from the cache + * @param {String} blockId + * @return {Object|null} + */ + __getBlockCache(blockId) { + const height = this.cache.get(`heights:${blockId}`) + + return height ? { height, id: blockId } : null + } + + /** + * Stores the height of the block on the cache + * @param {Object} block + * @param {String} block.id + * @param {Number} block.height + */ + __setBlockCache({ id, height }) { + this.cache.set(`heights:${id}`, height) + } + + /** + * Retrieves the publicKey of the address from the WalletManager in-memory data + * @param {String} senderId + * @return {String} + */ + __publicKeyFromSenderId(senderId) { + return database.walletManager.findByAddress(senderId).publicKey + } + + __orderBy(parameters) { + return parameters.orderBy + ? parameters.orderBy.split(':').map(p => p.toLowerCase()) + : ['timestamp', 'desc'] + } +} + +module.exports = new TransactionsRepository() diff --git a/packages/core-graphql/lib/repositories/utils/filter-query.js b/packages/core-graphql/lib/repositories/utils/filter-query.js new file mode 100644 index 0000000000..5d7ce014e5 --- /dev/null +++ b/packages/core-graphql/lib/repositories/utils/filter-query.js @@ -0,0 +1,73 @@ +/* eslint no-prototype-builtins: "off" */ + +/** + * Create a "where" object for a sql query. + * @param {Object} parameters + * @param {Object} filters + * @return {Object} + */ +module.exports = (parameters, filters) => { + const where = [] + + if (filters.exact) { + for (const elem of filters.exact) { + if (typeof parameters[elem] !== 'undefined') { + where.push({ + column: elem, + method: 'equals', + value: parameters[elem], + }) + } + } + } + + if (filters.between) { + for (const elem of filters.between) { + if (!parameters[elem]) { + continue + } + + if (!parameters[elem].from && !parameters[elem].to) { + where.push({ + column: elem, + method: 'equals', + value: parameters[elem], + }) + } + + if (parameters[elem].from || parameters[elem].to) { + where[elem] = {} + + if (parameters[elem].from) { + where.push({ + column: elem, + method: 'gte', + value: parameters[elem].from, + }) + } + + if (parameters[elem].to) { + where.push({ + column: elem, + method: 'lte', + value: parameters[elem].to, + }) + } + } + } + } + + if (filters.wildcard) { + for (const elem of filters.wildcard) { + if (parameters[elem]) { + where.push({ + column: elem, + method: 'like', + value: `%${parameters[elem]}%`, + }) + } + } + } + + return where +} diff --git a/packages/core-graphql/lib/resolvers/index.js b/packages/core-graphql/lib/resolvers/index.js index 95eecb4537..cb1ddd8399 100644 --- a/packages/core-graphql/lib/resolvers/index.js +++ b/packages/core-graphql/lib/resolvers/index.js @@ -1,19 +1,31 @@ -'use strict'; - +const GraphQLTypes = require('graphql-tools-types') const queries = require('./queries') const Block = require('./relationship/block') const Transaction = require('./relationship/transaction') const Wallet = require('./relationship/wallet') -const GraphQLTypes = require('graphql-tools-types') + +/** + * Resolvers used by the executed schema when encountering a + * scalar or type. + * + * All of our scalars are based on graphql-tools-types which helps us with + * query standardization. + * + * We introduce relationships and queries for our own types, + * these hold the data processing responsibilities of the complete + * GraphQL query flow. + */ module.exports = { JSON: GraphQLTypes.JSON({ name: 'Json' }), Limit: GraphQLTypes.Int({ name: 'Limit', min: 1, max: 100 }), Offset: GraphQLTypes.Int({ name: 'Offset', min: 0 }), - Address: GraphQLTypes.String({ name: 'Address', regex: /^[AaDd]{1}[0-9a-zA-Z]{33}/g }), - + Address: GraphQLTypes.String({ + name: 'Address', + regex: /^[AaDd]{1}[0-9a-zA-Z]{33}/, + }), Query: queries, Block, Transaction, - Wallet + Wallet, } diff --git a/packages/core-graphql/lib/resolvers/queries/block/block.js b/packages/core-graphql/lib/resolvers/queries/block/block.js index 1b7a5f69d2..f6dbcd5967 100644 --- a/packages/core-graphql/lib/resolvers/queries/block/block.js +++ b/packages/core-graphql/lib/resolvers/queries/block/block.js @@ -1,5 +1,9 @@ -'use strict'; +const database = require('@arkecosystem/core-container').resolvePlugin( + 'database', +) -const database = require('@arkecosystem/core-container').resolvePlugin('database') - -module.exports = (_, { id }) => database.blocks.findById(id) +/** + * Get a single block from the database + * @return {Block} + */ +module.exports = (_, { id }) => database.db.blocks.findById(id) diff --git a/packages/core-graphql/lib/resolvers/queries/block/blocks.js b/packages/core-graphql/lib/resolvers/queries/block/blocks.js index 9e03c46dd0..2caa207afe 100644 --- a/packages/core-graphql/lib/resolvers/queries/block/blocks.js +++ b/packages/core-graphql/lib/resolvers/queries/block/blocks.js @@ -1,12 +1,16 @@ -'use strict'; - -const database = require('@arkecosystem/core-container').resolvePlugin('database') const { formatOrderBy } = require('../../../helpers') +const { blocks: repository } = require('../../../repositories') + +/** + * Get multiple blocks from the database + * @return {Block[]} + */ +module.exports = async (_, args) => { + const { orderBy, filter } = args -module.exports = (_, args) => { - const { orderBy, filter, ...params } = args + const order = formatOrderBy(orderBy, 'height:desc') - const order = formatOrderBy(orderBy, 'height:DESC') + const result = await repository.findAll({ ...filter, orderBy: order }) - return database.blocks.findAll({ ...filter, orderBy: order, ...params }, false) + return result ? result.rows : [] } diff --git a/packages/core-graphql/lib/resolvers/queries/index.js b/packages/core-graphql/lib/resolvers/queries/index.js index 4307e23e5e..204140ee6a 100644 --- a/packages/core-graphql/lib/resolvers/queries/index.js +++ b/packages/core-graphql/lib/resolvers/queries/index.js @@ -1,5 +1,3 @@ -'use strict'; - const block = require('./block/block') const blocks = require('./block/blocks') const transaction = require('./transaction/transaction') @@ -7,11 +5,14 @@ const transactions = require('./transaction/transactions') const wallet = require('./wallet/wallet') const wallets = require('./wallet/wallets') +/** + * Queries exposed by our GraphQL schema + */ module.exports = { block, blocks, transaction, transactions, wallet, - wallets + wallets, } diff --git a/packages/core-graphql/lib/resolvers/queries/transaction/transaction.js b/packages/core-graphql/lib/resolvers/queries/transaction/transaction.js index c9bf4577c1..69fc196221 100644 --- a/packages/core-graphql/lib/resolvers/queries/transaction/transaction.js +++ b/packages/core-graphql/lib/resolvers/queries/transaction/transaction.js @@ -1,5 +1,9 @@ -'use strict'; +const database = require('@arkecosystem/core-container').resolvePlugin( + 'database', +) -const database = require('@arkecosystem/core-container').resolvePlugin('database') - -module.exports = (_, { id }) => database.transactions.findById(id) +/** + * Get a single transaction from the database + * @return {Transaction} + */ +module.exports = async (_, { id }) => database.db.transactions.findById(id) diff --git a/packages/core-graphql/lib/resolvers/queries/transaction/transactions.js b/packages/core-graphql/lib/resolvers/queries/transaction/transactions.js index ff73d1e324..5e56d324b1 100644 --- a/packages/core-graphql/lib/resolvers/queries/transaction/transactions.js +++ b/packages/core-graphql/lib/resolvers/queries/transaction/transactions.js @@ -1,19 +1,14 @@ -'use strict'; - -const database = require('@arkecosystem/core-container').resolvePlugin('database') -const { constants } = require('@arkecosystem/crypto') -const { formatOrderBy, unserializeTransactions } = require('../../../helpers') +const { formatOrderBy } = require('../../../helpers') +const { transactions: repository } = require('../../../repositories') +/** + * Get multiple transactions from the database + * @return {Transaction[]} + */ module.exports = async (root, args) => { - const { orderBy, filter, ...params } = args - - const order = formatOrderBy(orderBy, 'timestamp:DESC') - - if (params.type) { - params.type = constants.TRANSACTION_TYPES[params.type] - } - - const transactions = await database.transactions.findAll({ ...filter, orderBy: order, ...params }, false) - - return unserializeTransactions(transactions) + const { orderBy, filter, limit } = args + const order = formatOrderBy(orderBy, 'timestamp:desc') + const result = await repository.findAll({ ...filter, orderBy: order, limit }) + const transactions = result ? result.rows : [] + return transactions } diff --git a/packages/core-graphql/lib/resolvers/queries/wallet/wallet.js b/packages/core-graphql/lib/resolvers/queries/wallet/wallet.js index e06701d47f..b7ae9d7d37 100644 --- a/packages/core-graphql/lib/resolvers/queries/wallet/wallet.js +++ b/packages/core-graphql/lib/resolvers/queries/wallet/wallet.js @@ -1,7 +1,12 @@ -'use strict'; +const database = require('@arkecosystem/core-container').resolvePlugin( + 'database', +) -const database = require('@arkecosystem/core-container').resolvePlugin('database') - -module.exports = (_, args) => { - return database.wallets.findById(args) +/** + * Get a single wallet from the database + * @return {Wallet} + */ +module.exports = async (_, args) => { + const param = args.address || args.publicKey || args.username + return database.wallets.findById(param) } diff --git a/packages/core-graphql/lib/resolvers/queries/wallet/wallets.js b/packages/core-graphql/lib/resolvers/queries/wallet/wallets.js index 36bb43bc07..2d1ff2b8d4 100644 --- a/packages/core-graphql/lib/resolvers/queries/wallet/wallets.js +++ b/packages/core-graphql/lib/resolvers/queries/wallet/wallets.js @@ -1,13 +1,22 @@ -'use strict'; - -const database = require('@arkecosystem/core-container').resolvePlugin('database') +const database = require('@arkecosystem/core-container').resolvePlugin( + 'database', +) const { formatOrderBy } = require('../../../helpers') +/** + * Get multiple wallets from the database + * @return {Wallet[]} + */ module.exports = async (_, args) => { const { orderBy, filter, ...params } = args - const order = formatOrderBy(orderBy, 'height:DESC') - const result = await database.wallets.findAll({ ...filter, orderBy: order, ...params }) + const order = formatOrderBy(orderBy, 'height:desc') + const result = filter && filter.vote + ? await database.wallets.findAllByVote(filter.vote, { + orderBy: order, + ...params, + }) + : await database.wallets.findAll({ orderBy: order, ...params }) return result ? result.rows : [] } diff --git a/packages/core-graphql/lib/resolvers/relationship/block.js b/packages/core-graphql/lib/resolvers/relationship/block.js index 2b3a95d266..dbd6e8b76c 100644 --- a/packages/core-graphql/lib/resolvers/relationship/block.js +++ b/packages/core-graphql/lib/resolvers/relationship/block.js @@ -1,21 +1,40 @@ -'use strict'; - -const database = require('@arkecosystem/core-container').resolvePlugin('database') +const database = require('@arkecosystem/core-container').resolvePlugin( + 'database', +) const { formatOrderBy, unserializeTransactions } = require('../../helpers') +/** + * Useful and common database operations with block data. + */ module.exports = { - async transactions (block, args) { + /** + * Get the transactions for a given block + * @param {Block}: block + * @param {Object}: args + * @return {Transaction[]} + */ + async transactions(block, args) { const { orderBy, filter, ...params } = args - const result = await database.transactions.findAll({ - ...filter, - orderBy: formatOrderBy(orderBy, 'timestamp:DESC'), - ...params - }, false) + const result = await database.transactions.findAll( + { + ...filter, + orderBy: formatOrderBy(orderBy, 'timestamp:DESC'), + ...params, + }, + false, + ) + const rows = result ? result.rows : [] - return unserializeTransactions(result) + return unserializeTransactions(rows) }, - generator (block) { + + /** + * Get the generator wallet for a given block + * @param {Block} block + * @return {Wallet} + */ + generator(block) { return database.wallets.findById(block.generatorPublicKey) - } + }, } diff --git a/packages/core-graphql/lib/resolvers/relationship/transaction.js b/packages/core-graphql/lib/resolvers/relationship/transaction.js index a1912ee2ba..d0b5c7feb2 100644 --- a/packages/core-graphql/lib/resolvers/relationship/transaction.js +++ b/packages/core-graphql/lib/resolvers/relationship/transaction.js @@ -1,19 +1,33 @@ -'use strict'; - -const database = require('@arkecosystem/core-container').resolvePlugin('database') +const database = require('@arkecosystem/core-container').resolvePlugin( + 'database', +) +/** + * Useful and common database operations with transaction data. + */ module.exports = { - block: (transaction) => { - return database.blocks.findById(transaction.blockId) - }, - recipient: (transaction) => { - return transaction.recipientId - ? database.wallets.findById(transaction.recipientId) - : [] - }, - sender: (transaction) => { - return transaction.senderPublicKey - ? database.wallets.findById(transaction.senderPublicKey) - : [] - } + /** + * Get the block of a transaction + * @param {Transaction} transaction + * @return {Block} + */ + block: transaction => database.blocks.findById(transaction.blockId), + + /** + * Get the recipient of a transaction + * @param {Transaction} transaction + * @return {Wallet} + */ + recipient: transaction => (transaction.recipientId + ? database.wallets.findById(transaction.recipientId) + : []), + + /** + * Get the sender of a transaction + * @param {Transaction} transaction + * @return {Wallet} + */ + sender: transaction => (transaction.senderPublicKey + ? database.wallets.findById(transaction.senderPublicKey) + : []), } diff --git a/packages/core-graphql/lib/resolvers/relationship/wallet.js b/packages/core-graphql/lib/resolvers/relationship/wallet.js index 0faabb1d4e..d266a216bd 100644 --- a/packages/core-graphql/lib/resolvers/relationship/wallet.js +++ b/packages/core-graphql/lib/resolvers/relationship/wallet.js @@ -1,35 +1,63 @@ -'use strict'; - -const database = require('@arkecosystem/core-container').resolvePlugin('database') +const database = require('@arkecosystem/core-container').resolvePlugin( + 'database', +) const { formatOrderBy, unserializeTransactions } = require('../../helpers') +/** + * Useful and common database operations with wallet data. + */ module.exports = { - async transactions (wallet, args) { + /* + * Get the transactions for a given wallet. + * @param {Wallet} wallet + * @param {Object} args + * @return {Transaction[]} + */ + async transactions(wallet, args) { const { orderBy, filter, ...params } = args - const walletOr = database.createCondition('OR', [{ - senderPublicKey: wallet.publicKey - }, { - recipientId: wallet.address - }]) + const walletOr = database.createCondition('OR', [ + { + senderPublicKey: wallet.publicKey, + }, + { + recipientId: wallet.address, + }, + ]) - const result = await database.transactions.findAll({ - ...filter, - orderBy: formatOrderBy(orderBy, 'timestamp:DESC'), - ...walletOr, - ...params - }, false) + const result = await database.transactions.findAll( + { + ...filter, + orderBy: formatOrderBy(orderBy, 'timestamp:DESC'), + ...walletOr, + ...params, + }, + false, + ) + const rows = result ? result.rows : [] - return unserializeTransactions(result) + return unserializeTransactions(rows) }, - blocks (wallet, args) { + + /* + * Get the blocks generated for a given wallet. + * @param {Wallet} wallet + * @param {Object} args + * @return {Block[]} + */ + blocks(wallet, args) { const { orderBy, ...params } = args params.generatorPublickKey = wallet.publicKey - return database.blocks.findAll({ - orderBy: formatOrderBy(orderBy, 'height:DESC'), - ...params - }, false) - } + const result = database.blocks.findAll( + { + orderBy: formatOrderBy(orderBy, 'height:DESC'), + ...params, + }, + false, + ) + const rows = result ? result.rows : [] + return rows + }, } diff --git a/packages/core-graphql/lib/schema.js b/packages/core-graphql/lib/schema.js index 2269c7f4bb..20fde37a9a 100644 --- a/packages/core-graphql/lib/schema.js +++ b/packages/core-graphql/lib/schema.js @@ -1,10 +1,11 @@ -'use strict'; - -const { makeExecutableSchema } = require('graphql-tools') +const { ApolloServer } = require('apollo-server-hapi') const resolvers = require('./resolvers') const typeDefs = require('./defs') -module.exports = makeExecutableSchema({ +/** + * Schema used by the Apollo GraphQL plugin for the hapi.js server. + */ +module.exports = new ApolloServer({ typeDefs, - resolvers + resolvers, }) diff --git a/packages/core-graphql/lib/server.js b/packages/core-graphql/lib/server.js index 556052acd3..0d7dcc2ff3 100644 --- a/packages/core-graphql/lib/server.js +++ b/packages/core-graphql/lib/server.js @@ -1,54 +1,23 @@ -'use strict'; - -const Hapi = require('hapi') -const logger = require('@arkecosystem/core-container').resolvePlugin('logger') -const { graphqlHapi, graphiqlHapi } = require('apollo-server-hapi') +const { createServer, mountServer } = require('@arkecosystem/core-http-utils') +const server = require('./schema') /** * Create a new hapi.js server. * @param {Object} config * @return {Hapi.Server} */ -module.exports = async (config) => { - const server = new Hapi.Server({ +module.exports = async config => { + const app = await createServer({ host: config.host, - port: config.port + port: config.port, }) - await server.register([require('vision'), require('inert'), require('lout')]) - - await server.register({ - plugin: graphqlHapi, - options: { - path: config.path, - graphqlOptions: require('./schema'), - route: { - cors: true - } - } + await server.applyMiddleware({ + app, + path: config.path, }) - if (config.graphiql) { - await server.register({ - plugin: graphiqlHapi, - options: { - path: '/graphiql', - graphiqlOptions: { - endpointURL: config.path - } - } - }) - } - - try { - await server.start() - - logger.info(`GraphQL API Server running at: ${server.info.uri}`) + await server.installSubscriptionHandlers(app.listener) - return server - } catch (error) { - logger.error(error.stack) - // TODO no exit here? - process.exit(1) - } + return mountServer('GraphQL', app) } diff --git a/packages/core-graphql/package.json b/packages/core-graphql/package.json index 4108382920..f639b3f2e2 100644 --- a/packages/core-graphql/package.json +++ b/packages/core-graphql/package.json @@ -1,34 +1,36 @@ { "name": "@arkecosystem/core-graphql", - "description": "GraphQL Integration for ARK Core", - "version": "0.1.1", + "description": "GraphQL Integration for Ark Core", + "version": "0.2.0", "contributors": [ "Lúcio Rubens " ], "license": "MIT", "main": "lib/index.js", "scripts": { - "build:docs": "../../node_modules/.bin/jsdoc -c jsdoc.json", "test": "cross-env ARK_ENV=test jest --runInBand --detectOpenHandles", - "test:coverage": "cross-env ARK_ENV=test jest --coverage --runInBand --detectOpenHandles", - "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand --watch", + "test:coverage": "cross-env ARK_ENV=test jest --coverage --coveragePathIgnorePatterns='/(defaults.js|index.js)$' --runInBand --detectOpenHandles", + "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand", "test:watch": "cross-env ARK_ENV=test jest --runInBand --watch", "test:watch:all": "cross-env ARK_ENV=test jest --runInBand --watchAll", "lint": "eslint ./ --fix", "depcheck": "depcheck ./" }, "dependencies": { - "@arkecosystem/core-container": "^0.1.1", - "@arkecosystem/crypto": "^0.1.1", - "apollo-server-hapi": "^1.3.6", - "graphql-tools": "^3.0.2", - "graphql-tools-types": "^1.1.21", - "hapi": "^17.5.0", - "inert": "^5.1.0", - "lout": "^11.0.1", - "vision": "^5.3.2" + "@arkecosystem/core-container": "~0.2", + "@arkecosystem/core-http-utils": "~0.2", + "@arkecosystem/crypto": "~0.2", + "apollo-server-hapi": "^2.2.4", + "dayjs-ext": "^2.2.0", + "graphql-tools-types": "^1.1.26" + }, + "devDependencies": { + "@arkecosystem/core-test-utils": "~0.2" }, "publishConfig": { "access": "public" + }, + "engines": { + "node": ">=10.x" } } diff --git a/packages/core-http-utils/.gitattributes b/packages/core-http-utils/.gitattributes new file mode 100644 index 0000000000..60cc52db63 --- /dev/null +++ b/packages/core-http-utils/.gitattributes @@ -0,0 +1,11 @@ +# Path-based git attributes +# https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html + +# Ignore all test and documentation with "export-ignore". +/.editorconfig export-ignore +/.gitattributes export-ignore +/.gitignore export-ignore +/.travis.yml export-ignore +/__tests__ export-ignore +/docs export-ignore +/README.md export-ignore diff --git a/packages/core-http-utils/CHANGELOG.md b/packages/core-http-utils/CHANGELOG.md new file mode 100644 index 0000000000..5d0bb1d1fe --- /dev/null +++ b/packages/core-http-utils/CHANGELOG.md @@ -0,0 +1,25 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +## Unreleased + +## 0.2.0 - 2018-12-03 + +### Added + +- cors-headers plugin for better CORS handling +- transaction payload size validation plugin + +### Changed + +- Dropped node.js 9 as minimum requirement in favour of node.js 10 + +## 0.1.0 - 2018-10-25 + +### Added + +- initial release diff --git a/packages/core-http-utils/LICENSE b/packages/core-http-utils/LICENSE new file mode 100644 index 0000000000..d6dd75272f --- /dev/null +++ b/packages/core-http-utils/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) Ark Ecosystem + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/core-http-utils/README.md b/packages/core-http-utils/README.md new file mode 100644 index 0000000000..12390ba2f9 --- /dev/null +++ b/packages/core-http-utils/README.md @@ -0,0 +1,22 @@ +# Ark Core - HTTP Utilities + +

+ +

+ +## Documentation + +You can find installation instructions and detailed instructions on how to use this package at the [dedicated documentation site](https://docs.ark.io/guidebook/core/plugins/core-http-utils.html). + +## Security + +If you discover a security vulnerability within this package, please send an e-mail to security@ark.io. All security vulnerabilities will be promptly addressed. + +## Credits + +- [Brian Faust](https://github.com/faustbrian) +- [All Contributors](../../../../contributors) + +## License + +[MIT](LICENSE) © [ArkEcosystem](https://ark.io) diff --git a/packages/core-http-utils/__tests__/__support__/mocks/core-container.js b/packages/core-http-utils/__tests__/__support__/mocks/core-container.js new file mode 100644 index 0000000000..03fbe49a7b --- /dev/null +++ b/packages/core-http-utils/__tests__/__support__/mocks/core-container.js @@ -0,0 +1,14 @@ +jest.mock('@arkecosystem/core-container', () => ({ + resolvePlugin: name => { + if (name === 'logger') { + return { + info: jest.fn(), + warn: jest.fn(), + error: jest.fn(), + debug: jest.fn(), + } + } + + return {} + }, +})) diff --git a/packages/core-http-utils/__tests__/plugins/content-type.test.js b/packages/core-http-utils/__tests__/plugins/content-type.test.js new file mode 100644 index 0000000000..68f790eb60 --- /dev/null +++ b/packages/core-http-utils/__tests__/plugins/content-type.test.js @@ -0,0 +1,49 @@ +require('../__support__/mocks/core-container') // before all so that the mock is used +const axios = require('axios') +const createServer = require('../../lib/server/create') +const mountServer = require('../../lib/server/mount') +const contentType = require('../../lib/plugins/content-type') + +let server +beforeAll(async () => { + server = await createServer({ + host: '0.0.0.0', + port: 3000, + }) + + await server.register({ plugin: contentType }) + + server.route({ + method: 'GET', + path: '/', + handler: (request, h) => 'Hello!', + }) + + await mountServer('Dummy', server) +}) + +afterAll(async () => { + await server.stop() +}) + +describe('Plugins - Content-Type', () => { + describe('GET /', () => { + it('should return code 200', async () => { + const response = await axios.get('http://0.0.0.0:3000/', { + headers: { 'Content-Type': 'application/json' }, + }) + + expect(response.status).toBe(200) + }) + + it('should return code 415', async () => { + try { + await axios.get('http://0.0.0.0:3000/', { + headers: { 'Content-Type': 'application/text' }, + }) + } catch (e) { + expect(e.response.status).toBe(415) + } + }) + }) +}) diff --git a/packages/core-http-utils/jest.config.js b/packages/core-http-utils/jest.config.js new file mode 100644 index 0000000000..57770a97bb --- /dev/null +++ b/packages/core-http-utils/jest.config.js @@ -0,0 +1,12 @@ +module.exports = { + testEnvironment: 'node', + bail: false, + verbose: true, + testMatch: ['**/__tests__/**/*.test.js'], + moduleFileExtensions: ['js', 'json'], + collectCoverage: false, + coverageDirectory: '/.coverage', + collectCoverageFrom: ['lib/**/*.js', '!**/node_modules/**'], + watchman: false, + setupTestFrameworkScriptFile: 'jest-extended', +} diff --git a/packages/core-http-utils/lib/index.js b/packages/core-http-utils/lib/index.js new file mode 100644 index 0000000000..f74cf387a8 --- /dev/null +++ b/packages/core-http-utils/lib/index.js @@ -0,0 +1,12 @@ +module.exports = { + createServer: require('./server/create'), + createSecureServer: require('./server/create-secure'), + monitorServer: require('./server/monitor'), + mountServer: require('./server/mount'), + plugins: { + contentType: require('./plugins/content-type'), + corsHeaders: require('./plugins/cors-headers'), + transactionPayload: require('./plugins/transaction-payload'), + whitelist: require('./plugins/whitelist'), + }, +} diff --git a/packages/core-http-utils/lib/plugins/content-type.js b/packages/core-http-utils/lib/plugins/content-type.js new file mode 100644 index 0000000000..74bdca7db8 --- /dev/null +++ b/packages/core-http-utils/lib/plugins/content-type.js @@ -0,0 +1,22 @@ +const Boom = require('boom') + +const register = async (server, options) => { + server.ext({ + type: 'onPreHandler', + async method(request, h) { + const contentType = request.headers['content-type'] + + if (contentType !== 'application/json') { + return Boom.unsupportedMediaType() + } + + return h.continue + }, + }) +} + +exports.plugin = { + name: 'content-type', + version: '0.1.0', + register, +} diff --git a/packages/core-http-utils/lib/plugins/cors-headers.js b/packages/core-http-utils/lib/plugins/cors-headers.js new file mode 100644 index 0000000000..9817ddee74 --- /dev/null +++ b/packages/core-http-utils/lib/plugins/cors-headers.js @@ -0,0 +1,42 @@ +// Based on https://github.com/gr2m/hapi-cors-headers which was never updated to support hapi.js 17 + +const register = async (server, options) => { + server.ext({ + type: 'onPreResponse', + method: (request, h) => { + if (!request.headers.origin) { + return h.continue + } + + const response = request.response.isBoom + ? request.response.output + : request.response + response.headers['access-control-allow-origin'] = request.headers.origin + response.headers['access-control-allow-credentials'] = 'true' + + if (request.method !== 'options') { + return h.continue + } + + response.statusCode = 200 + response.headers['access-control-expose-headers'] = 'content-type, content-length, etag' + response.headers['access-control-max-age'] = options.maxAge || 60 * 10 + + if (request.headers['access-control-request-headers']) { + response.headers['access-control-allow-headers'] = request.headers['access-control-request-headers'] + } + + if (request.headers['access-control-request-method']) { + response.headers['access-control-allow-methods'] = request.headers['access-control-request-method'] + } + + return h.continue + }, + }) +} + +exports.plugin = { + name: 'cors-headers', + version: '0.1.0', + register, +} diff --git a/packages/core-http-utils/lib/plugins/transaction-payload.js b/packages/core-http-utils/lib/plugins/transaction-payload.js new file mode 100644 index 0000000000..223aef676b --- /dev/null +++ b/packages/core-http-utils/lib/plugins/transaction-payload.js @@ -0,0 +1,54 @@ +const Boom = require('boom') +const app = require('@arkecosystem/core-container') + +const register = async (server, options) => { + server.ext({ + type: 'onPostAuth', + async method(request, h) { + const route = options.routes.find(item => item.path === request.path) + + if (!route) { + return h.continue + } + + if (route.method.toLowerCase() !== request.method.toLowerCase()) { + return h.continue + } + + const transactionPool = app.resolveOptions('transactionPool') + + if (!transactionPool) { + return h.continue + } + + // NOTE: this will only trigger if the JSON content-type header is not + // present. This will be avoided by the "content-type.js" plugin in the + // future which is currently disabled due to v1 still being on mainnet. + if (!request.payload.transactions) { + return Boom.badRequest() + } + + const transactionsCount = request.payload.transactions.length + const maxTransactionsPerRequest = + transactionPool.maxTransactionsPerRequest + + if (transactionsCount > maxTransactionsPerRequest) { + return Boom.entityTooLarge( + `Received ${transactionsCount} transactions. Only ${maxTransactionsPerRequest} are allowed per request.`, + { + allowed: maxTransactionsPerRequest, + received: transactionsCount, + }, + ) + } + + return h.continue + }, + }) +} + +exports.plugin = { + name: 'transaction-payload', + version: '0.1.0', + register, +} diff --git a/packages/core-api/lib/plugins/whitelist.js b/packages/core-http-utils/lib/plugins/whitelist.js similarity index 50% rename from packages/core-api/lib/plugins/whitelist.js rename to packages/core-http-utils/lib/plugins/whitelist.js index 3f9252ea4e..fe640b6775 100644 --- a/packages/core-api/lib/plugins/whitelist.js +++ b/packages/core-http-utils/lib/plugins/whitelist.js @@ -1,43 +1,35 @@ -'use strict' - const Boom = require('boom') const requestIp = require('request-ip') const mm = require('micromatch') const logger = require('@arkecosystem/core-container').resolvePlugin('logger') -/** - * The register method used by hapi.js. - * @param {Hapi.Server} server - * @param {Object} options - * @return {void} - */ const register = async (server, options) => { server.ext({ type: 'onRequest', - async method (request, h) { + async method(request, h) { const remoteAddress = requestIp.getClientIp(request) if (Array.isArray(options.whitelist)) { - for (let i = 0; i < options.whitelist.length; i++) { - if (mm.isMatch(remoteAddress, options.whitelist[i])) { + for (const ip of options.whitelist) { + if (mm.isMatch(remoteAddress, ip)) { return h.continue } } } - logger.warn(`${remoteAddress} tried to access the Public API without being whitelisted :warning:`) + logger.warn( + `${remoteAddress} tried to access the ${ + options.name + } without being whitelisted :warning:`, + ) return Boom.forbidden() - } + }, }) } -/** - * The struct used by hapi.js. - * @type {Object} - */ exports.plugin = { - name: 'core-api-whitelist', + name: 'whitelist', version: '0.1.0', - register + register, } diff --git a/packages/core-http-utils/lib/server/create-secure.js b/packages/core-http-utils/lib/server/create-secure.js new file mode 100644 index 0000000000..6609283afe --- /dev/null +++ b/packages/core-http-utils/lib/server/create-secure.js @@ -0,0 +1,14 @@ +const fs = require('fs') +const expandHomeDir = require('expand-home-dir') +const createServer = require('./create') + +module.exports = async (options, callback, secure) => { + options.host = secure.host + options.port = secure.port + options.tls = { + key: fs.readFileSync(expandHomeDir(secure.key)), + cert: fs.readFileSync(expandHomeDir(secure.cert)), + } + + return createServer(options, callback, secure) +} diff --git a/packages/core-http-utils/lib/server/create.js b/packages/core-http-utils/lib/server/create.js new file mode 100644 index 0000000000..44600929c5 --- /dev/null +++ b/packages/core-http-utils/lib/server/create.js @@ -0,0 +1,23 @@ +const Hapi = require('hapi') +const registerMonitor = require('./monitor') + +module.exports = async (options, callback) => { + const server = new Hapi.Server(options) + + await server.register([require('vision'), require('inert'), require('lout')]) + + await server.register({ + plugin: require('hapi-trailing-slash'), + options: { method: 'remove' }, + }) + + if (callback) { + await callback(server) + } + + if (process.env.NODE_ENV === 'test') { + await registerMonitor(server) + } + + return server +} diff --git a/packages/core-http-utils/lib/server/monitor.js b/packages/core-http-utils/lib/server/monitor.js new file mode 100644 index 0000000000..62207b97f2 --- /dev/null +++ b/packages/core-http-utils/lib/server/monitor.js @@ -0,0 +1,18 @@ +module.exports = async server => server.register({ + plugin: require('good'), + options: { + reporters: { + console: [ + { + module: 'good-squeeze', + name: 'Squeeze', + args: [{ log: '*', response: '*', request: '*' }], + }, + { + module: 'good-console', + }, + 'stdout', + ], + }, + }, +}) diff --git a/packages/core-http-utils/lib/server/mount.js b/packages/core-http-utils/lib/server/mount.js new file mode 100644 index 0000000000..4c8d3db6c6 --- /dev/null +++ b/packages/core-http-utils/lib/server/mount.js @@ -0,0 +1,15 @@ +const app = require('@arkecosystem/core-container') + +const logger = app.resolvePlugin('logger') + +module.exports = async (name, server) => { + try { + await server.start() + + logger.info(`${name} Server running at: ${server.info.uri}`) + + return server + } catch (error) { + app.forceExit(`Could not start ${name} Server!`, error) + } +} diff --git a/packages/core-http-utils/package.json b/packages/core-http-utils/package.json new file mode 100644 index 0000000000..c27ce6dfc9 --- /dev/null +++ b/packages/core-http-utils/package.json @@ -0,0 +1,43 @@ +{ + "name": "@arkecosystem/core-http-utils", + "description": "Http Utilities for Ark Core", + "version": "0.2.0", + "contributors": [ + "Brian Faust " + ], + "license": "MIT", + "main": "lib/index.js", + "scripts": { + "test": "cross-env ARK_ENV=test jest --runInBand --detectOpenHandles", + "test:coverage": "cross-env ARK_ENV=test jest --coverage --coveragePathIgnorePatterns='/(defaults.js|index.js)$' --runInBand --detectOpenHandles", + "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand", + "test:watch": "cross-env ARK_ENV=test jest --runInBand --watch", + "test:watch:all": "cross-env ARK_ENV=test jest --runInBand --watchAll", + "lint": "eslint ./ --fix", + "depcheck": "depcheck ./ --ignores=hapi,inert,lout,vision,good-console,good-squeeze" + }, + "dependencies": { + "@arkecosystem/core-container": "~0.2", + "boom": "^7.3.0", + "expand-home-dir": "^0.0.3", + "good": "^8.1.1", + "good-console": "^7.1.0", + "good-squeeze": "^5.1.0", + "hapi": "^17.8.1", + "hapi-trailing-slash": "^3.0.1", + "inert": "^5.1.2", + "lout": "^11.1.0", + "micromatch": "^3.1.10", + "request-ip": "^2.1.3", + "vision": "^5.4.3" + }, + "publishConfig": { + "access": "public" + }, + "engines": { + "node": ">=10.x" + }, + "devDependencies": { + "axios": "^0.18.0" + } +} diff --git a/packages/core-json-rpc/CHANGELOG.md b/packages/core-json-rpc/CHANGELOG.md index 127cc35e42..dd745b15ca 100644 --- a/packages/core-json-rpc/CHANGELOG.md +++ b/packages/core-json-rpc/CHANGELOG.md @@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Unreleased -## 0.0.1 - 2018-05-31 +## 0.2.0 - 2018-12-03 + +### Changed + +- Moved all API calls from v1 to v2 +- Using in-memory peer list rather then fetching it via API +- Dropped node.js 9 as minimum requirement in favour of node.js 10 + +### Fixed + +- Sign transaction _after_ filling in the recipientId and amount +- Fixed the failing test-suite +- BIP38 functionality + +## 0.1.1 - 2018-06-14 + ### Added + - initial release diff --git a/packages/core-json-rpc/README.md b/packages/core-json-rpc/README.md index a10199bf7a..cb084b89e4 100644 --- a/packages/core-json-rpc/README.md +++ b/packages/core-json-rpc/README.md @@ -1,26 +1,12 @@ -![ARK Core](https://i.imgur.com/1aP6F2o.png) +# Ark Core - JSON-RPC -# ARK Core - JSON-RPC Server +

+ +

-## Installation +## Documentation -```bash -yarn add @arkecosystem/core-json-rpc -``` - -## Configuration - -### Defaults - -```js -'use strict' - -module.exports = { - port: 8080, - allowRemote: true, - whitelist: ['127.0.0.1', '::ffff:127.0.0.1', '192.168.*'] -} -``` +You can find installation instructions and detailed instructions on how to use this package at the [dedicated documentation site](https://docs.ark.io/guidebook/core/plugins/core-json-rpc.html). ## Security diff --git a/packages/core-json-rpc/__tests__/__support__/request.js b/packages/core-json-rpc/__tests__/__support__/request.js index 20c41b6624..284c41c970 100644 --- a/packages/core-json-rpc/__tests__/__support__/request.js +++ b/packages/core-json-rpc/__tests__/__support__/request.js @@ -7,7 +7,7 @@ module.exports = async (method, params) => { jsonrpc: '2.0', id, method, - params + params, }) await expect(response.status).toBe(200) diff --git a/packages/core-json-rpc/__tests__/__support__/setup.js b/packages/core-json-rpc/__tests__/__support__/setup.js index 27b639c790..aefbf2fd59 100644 --- a/packages/core-json-rpc/__tests__/__support__/setup.js +++ b/packages/core-json-rpc/__tests__/__support__/setup.js @@ -1,31 +1,21 @@ -'use strict' - -const path = require('path') -const container = require('@arkecosystem/core-container') +const app = require('@arkecosystem/core-container') +const appHelper = require('@arkecosystem/core-test-utils/lib/helpers/container') jest.setTimeout(60000) -beforeAll(async () => { - await container.setUp({ - data: '~/.ark', - config: path.resolve(__dirname, '../../../core/lib/config/mainnet'), - token: 'ark', - network: 'mainnet' - }, { +exports.setUp = async () => { + process.env.ARK_JSON_RPC_ENABLED = true + + await appHelper.setUp({ exclude: [ '@arkecosystem/core-api', '@arkecosystem/core-webhooks', '@arkecosystem/core-graphql', - '@arkecosystem/core-forger' + '@arkecosystem/core-forger', ], - options: { - '@arkecosystem/core-json-rpc': { - enabled: true - } - } }) -}) +} -afterAll(async () => { - await container.tearDown() -}) +exports.tearDown = async () => { + await app.tearDown() +} diff --git a/packages/core-json-rpc/__tests__/accounts.test.js b/packages/core-json-rpc/__tests__/accounts.test.js deleted file mode 100644 index 07107e872d..0000000000 --- a/packages/core-json-rpc/__tests__/accounts.test.js +++ /dev/null @@ -1,74 +0,0 @@ -const request = require('./__support__/request') -const arkjs = require('arkjs') - -require('./__support__/setup') - -describe('Accounts', () => { - describe('GET /mainnet/accounts/{address}', () => { - it('should GET account with a given address on mainnet', async () => { - const response = await request('accounts.info', { - address: 'AUDud8tvyVZa67p3QY7XPRUTjRGnWQQ9Xv' - }) - - await expect(response.data.result.address).toBe('AUDud8tvyVZa67p3QY7XPRUTjRGnWQQ9Xv') - }) - }) - - describe('GET /mainnet/accounts/{address}/transactions', () => { - it('should GET last account transactions on mainnet', async () => { - const response = await request('accounts.transactions', { - address: 'AUDud8tvyVZa67p3QY7XPRUTjRGnWQQ9Xv' - }) - - await expect(parseInt(response.data.result.count)).toBeGreaterThan(3) - await expect(response.data.result.transactions.length).toBeGreaterThan(3) - }) - }) - - describe('POST /mainnet/accounts/*', () => { - it('should create an account on mainnet', async () => { - const response = await request('accounts.create', { - passphrase: 'this is a test' - }) - - await expect(response.data.result.address).toBe('AUdAwTiByRp5BFyGz9uxXuNYa1KGHT4rmt') - await expect(response.data.result.publicKey).toBe('03675c61dcc23eab75f9948c6510b54d34fced4a73d3c9f2132c76a29750e7a614') - }) - - let bip38wif - let userId = require('crypto').randomBytes(32).toString('hex') - - it('should create an account on mainnet using bip38 encryption', async () => { - const response = await request('accounts.bip38.create', { - bip38: 'master password', - userId - }) - - await expect(response.data.result).toHaveProperty('address') - await expect(response.data.result).toHaveProperty('publicKey') - await expect(response.data.result).toHaveProperty('wif') - - bip38wif = response.data.result.wif - }) - - it('should find bip38 backup from userId', async () => { - const response = await request('accounts.bip38.info', { userId - }) - - await expect(response.data.result).toHaveProperty('wif') - await expect(response.data.result.wif).toBe(bip38wif) - }) - - it('should create transaction from bip38 backup using userId', async () => { - const response = await request('transactions.bip38.create', { - bip38: 'master password', - userId, - amount: 1000000000, - recipientId: 'AUDud8tvyVZa67p3QY7XPRUTjRGnWQQ9Xv' - }) - - await expect(response.data.result.recipientId).toBe('AUDud8tvyVZa67p3QY7XPRUTjRGnWQQ9Xv') - await expect(arkjs.crypto.verify(response.data.result)).toBeTruthy() - }) - }) -}) diff --git a/packages/core-json-rpc/__tests__/blocks.test.js b/packages/core-json-rpc/__tests__/blocks.test.js index bc3e759d20..8f6d157ace 100644 --- a/packages/core-json-rpc/__tests__/blocks.test.js +++ b/packages/core-json-rpc/__tests__/blocks.test.js @@ -1,33 +1,95 @@ +const axios = require('axios') +const MockAdapter = require('axios-mock-adapter') const request = require('./__support__/request') -require('./__support__/setup') +const app = require('./__support__/setup') + +const axiosMock = new MockAdapter(axios) + +jest.mock('is-reachable', () => jest.fn(async peer => true)) + +let peerMock + +beforeAll(async () => { + await app.setUp() + + const Peer = require('@arkecosystem/core-p2p/lib/peer') + peerMock = new Peer('0.0.0.99', 4002) + Object.assign(peerMock, peerMock.headers, { status: 'OK' }) + + const monitor = require('@arkecosystem/core-container').resolvePlugin('p2p') + monitor.peers = {} + monitor.peers[peerMock.ip] = peerMock +}) + +afterAll(async () => { + await app.tearDown() +}) + +beforeEach(async () => { + axiosMock.onPost(/.*:8080.*/).passThrough() +}) + +afterEach(async () => { + axiosMock.reset() // important: resets any existing mocking behavior +}) describe('Blocks', () => { - describe('GET /mainnet/blocks/latest', () => { + describe('POST blocks.latest', () => { it('should get the latest block', async () => { + axiosMock + .onGet(/.*\/api\/blocks/) + .reply(() => [200, { data: [{ id: '123' }] }, peerMock.headers]) + const response = await request('blocks.latest') - await expect(response.data.result.id).toBeString() + expect(response.data.result.id).toBeString() }) }) - describe('GET /mainnet/blocks/{id}', () => { + describe('POST blocks.info', () => { it('should get the block information', async () => { + axiosMock + .onGet(/.*\/api\/blocks\/123/) + .reply(() => [200, { data: { id: '123' } }, peerMock.headers]) + const response = await request('blocks.info', { - id: '4366553906931540162' + id: '123', }) - await expect(response.data.result.id).toBe('4366553906931540162') + expect(response.data.result.id).toBe('123') + }) + + it('should fail to get the block information', async () => { + const response = await request('blocks.info', { id: '123' }) + + expect(response.data.error.code).toBe(404) + expect(response.data.error.message).toBe('Block 123 could not be found.') }) }) - describe('GET /mainnet/blocks/{id}/transactions', () => { + describe('POST blocks.transactions', () => { it('should get the block transactions', async () => { + axiosMock + .onGet(/.*\/api\/blocks\/123\/transactions/) + .reply(() => [ + 200, + { meta: { totalCount: 1 }, data: [{ id: '123' }, { id: '123' }] }, + peerMock.headers, + ]) + const response = await request('blocks.transactions', { - id: '4366553906931540162' + id: '123', }) - await expect(response.data.result.transactions).toHaveLength(50) + expect(response.data.result.data).toHaveLength(2) + }) + + it('should fail to get the block transactions', async () => { + const response = await request('blocks.transactions', { id: '123' }) + + expect(response.data.error.code).toBe(404) + expect(response.data.error.message).toBe('Block 123 could not be found.') }) }) }) diff --git a/packages/core-json-rpc/__tests__/transactions.test.js b/packages/core-json-rpc/__tests__/transactions.test.js index 6dfa151e4f..48eb2013b0 100644 --- a/packages/core-json-rpc/__tests__/transactions.test.js +++ b/packages/core-json-rpc/__tests__/transactions.test.js @@ -1,37 +1,156 @@ +const { crypto } = require('@arkecosystem/crypto') + +const axios = require('axios') +const MockAdapter = require('axios-mock-adapter') +const app = require('./__support__/setup') const request = require('./__support__/request') -const ark = require('@arkecosystem/crypto') -require('./__support__/setup') +const axiosMock = new MockAdapter(axios) + +jest.mock('is-reachable', () => jest.fn(async peer => true)) + +let peerMock + +beforeAll(async () => { + await app.setUp() + + const Peer = require('@arkecosystem/core-p2p/lib/peer') + peerMock = new Peer('0.0.0.99', 4002) + Object.assign(peerMock, peerMock.headers, { status: 'OK' }) + + const monitor = require('@arkecosystem/core-container').resolvePlugin('p2p') + monitor.peers = {} + monitor.peers[peerMock.ip] = peerMock +}) + +afterAll(async () => { + await app.tearDown() +}) + +beforeEach(async () => { + axiosMock.onPost(/.*:8080.*/).passThrough() +}) + +afterEach(async () => { + axiosMock.reset() // important: resets any existing mocking behavior +}) describe('Transactions', () => { - describe('POST /mainnet/transactions', () => { - let transaction + describe('POST transactions.info', () => { + it('should get the transaction for the given ID', async () => { + axiosMock.onGet(/.*\/api\/transactions/).reply(() => [ + 200, + { + data: { + id: + 'e4311204acf8a86ba833e494f5292475c6e9e0913fc455a12601b4b6b55818d8', + }, + }, + peerMock.headers, + ]) + + const response = await request('transactions.info', { + id: 'e4311204acf8a86ba833e494f5292475c6e9e0913fc455a12601b4b6b55818d8', + }) + + expect(response.data.result.id).toBe( + 'e4311204acf8a86ba833e494f5292475c6e9e0913fc455a12601b4b6b55818d8', + ) + }) + + it('should fail to get the transaction for the given ID', async () => { + const response = await request('transactions.info', { + id: 'e4311204acf8a86ba833e494f5292475c6e9e0913fc455a12601b4b6b55818d8', + }) + + expect(response.data.error.code).toBe(404) + expect(response.data.error.message).toBe( + 'Transaction e4311204acf8a86ba833e494f5292475c6e9e0913fc455a12601b4b6b55818d8 could not be found.', + ) + }) + }) - it('should create tx on mainnet and tx should verify', async () => { + describe('POST transactions.create', () => { + it('should create a new transaction and verify', async () => { const response = await request('transactions.create', { amount: 100000000, - recipientId: 'AUDud8tvyVZa67p3QY7XPRUTjRGnWQQ9Xv', - passphrase: 'This is a test' + recipientId: 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn', + passphrase: 'this is a top secret passphrase', }) - await expect(response.data.result.recipientId).toBe('AUDud8tvyVZa67p3QY7XPRUTjRGnWQQ9Xv') - await expect(ark.crypto.verify(response.data.result)).toBeTruthy() + expect(response.data.result.recipientId).toBe( + 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn', + ) + expect(crypto.verify(response.data.result)).toBeTrue() + }) + }) + + describe('POST transactions.broadcast', () => { + it('should broadcast the transaction', async () => { + const transaction = await request('transactions.create', { + amount: 100000000, + recipientId: 'APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn', + passphrase: 'this is a top secret passphrase', + }) + + axiosMock + .onPost(/.*\/api\/transactions/) + .reply(() => [200, { success: true }, peerMock.headers]) + + const response = await request('transactions.broadcast', { + id: transaction.data.result.id, + }) - transaction = response.data.result + expect(crypto.verify(response.data.result)).toBeTrue() }) - it('should broadcast tx on mainnet using the old method', async () => { + it('should fail to broadcast the transaction', async () => { const response = await request('transactions.broadcast', { - transactions: [transaction] + id: 'e4311204acf8a86ba833e494f5292475c6e9e0913fc455a12601b4b6b55818d8', }) - await expect(ark.crypto.verify(response.data.result[0])).toBeTruthy() + expect(response.data.error.code).toBe(404) + expect(response.data.error.message).toBe( + 'Transaction e4311204acf8a86ba833e494f5292475c6e9e0913fc455a12601b4b6b55818d8 could not be found.', + ) + }) + }) + + describe('POST transactions.bip38.create', () => { + it('should create a new transaction', async () => { + const userId = require('crypto') + .randomBytes(32) + .toString('hex') + await request('wallets.bip38.create', { + bip38: 'this is a top secret passphrase', + userId, + }) + + const response = await request('transactions.bip38.create', { + bip38: 'this is a top secret passphrase', + userId, + amount: 1000000000, + recipientId: 'AUDud8tvyVZa67p3QY7XPRUTjRGnWQQ9Xv', + }) + + expect(response.data.result.recipientId).toBe( + 'AUDud8tvyVZa67p3QY7XPRUTjRGnWQQ9Xv', + ) + expect(crypto.verify(response.data.result)).toBeTrue() }) - it('should broadcast tx on mainnet using the new method', async () => { - const response = await request('transactions.broadcast', { id: transaction.id }) + it('should fail to create a new transaction', async () => { + const response = await request('transactions.bip38.create', { + bip38: 'this is a top secret passphrase', + userId: '123456789', + amount: 1000000000, + recipientId: 'AUDud8tvyVZa67p3QY7XPRUTjRGnWQQ9Xv', + }) - await expect(ark.crypto.verify(response.data.result)).toBeTruthy() + expect(response.data.error.code).toBe(404) + expect(response.data.error.message).toBe( + 'User 123456789 could not be found.', + ) }) }) }) diff --git a/packages/core-json-rpc/__tests__/wallets.test.js b/packages/core-json-rpc/__tests__/wallets.test.js new file mode 100644 index 0000000000..fdefdc12d3 --- /dev/null +++ b/packages/core-json-rpc/__tests__/wallets.test.js @@ -0,0 +1,190 @@ +const axios = require('axios') +const MockAdapter = require('axios-mock-adapter') +const request = require('./__support__/request') +const app = require('./__support__/setup') + +const axiosMock = new MockAdapter(axios) + +jest.mock('is-reachable', () => jest.fn(async peer => true)) + +let peerMock + +beforeAll(async () => { + await app.setUp() + + const Peer = require('@arkecosystem/core-p2p/lib/peer') + peerMock = new Peer('0.0.0.99', 4002) + Object.assign(peerMock, peerMock.headers, { status: 'OK' }) + + const monitor = require('@arkecosystem/core-container').resolvePlugin('p2p') + monitor.peers = {} + monitor.peers[peerMock.ip] = peerMock +}) + +afterAll(async () => { + await app.tearDown() +}) + +beforeEach(async () => { + axiosMock + .onGet(/.*\/api\/loader\/autoconfigure/) + .reply(() => [200, { network: {} }, peerMock.headers]) + axiosMock + .onGet(/.*\/peer\/status/) + .reply(() => [200, { success: true, height: 5 }, peerMock.headers]) + axiosMock.onGet(/.*\/peer\/list/).reply(() => [ + 200, + { + success: true, + peers: [ + { + status: 'OK', + ip: peerMock.ip, + port: 4002, + height: 5, + delay: 8, + }, + ], + }, + peerMock.headers, + ]) + axiosMock.onPost(/.*:8080.*/).passThrough() +}) + +afterEach(async () => { + axiosMock.reset() // important: resets any existing mocking behavior +}) + +describe('Wallets', () => { + describe('POST wallets.info', () => { + it('should get information about the given wallet', async () => { + axiosMock + .onGet(/.*\/api\/wallets\/AUDud8tvyVZa67p3QY7XPRUTjRGnWQQ9Xv/) + .reply(() => [ + 200, + { data: { address: 'AUDud8tvyVZa67p3QY7XPRUTjRGnWQQ9Xv' } }, + peerMock.headers, + ]) + + const response = await request('wallets.info', { + address: 'AUDud8tvyVZa67p3QY7XPRUTjRGnWQQ9Xv', + }) + + expect(response.data.result.address).toBe( + 'AUDud8tvyVZa67p3QY7XPRUTjRGnWQQ9Xv', + ) + }) + + it('should fail to get information about the given wallet', async () => { + axiosMock + .onGet(/.*\/api\/wallets\/AUDud8tvyVZa67p3QY7XPRUTjRGnWQQ9Xv/) + .reply(() => [ + 404, + { + error: { + code: 404, + message: + 'Wallet AUDud8tvyVZa67p3QY7XPRUTjRGnWQQ9Xv could not be found.', + }, + }, + peerMock.headers, + ]) + + const response = await request('wallets.info', { + address: 'AUDud8tvyVZa67p3QY7XPRUTjRGnWQQ9Xv', + }) + + expect(response.data.error.code).toBe(404) + expect(response.data.error.message).toBe( + 'Wallet AUDud8tvyVZa67p3QY7XPRUTjRGnWQQ9Xv could not be found.', + ) + }) + }) + + describe('POST wallets.transactions', () => { + it('should get the transactions for the given wallet', async () => { + axiosMock + .onGet(/.*\/api\/transactions/) + .reply(() => [ + 200, + { meta: { totalCount: 2 }, data: [{ id: '123' }, { id: '1234' }] }, + peerMock.headers, + ]) + + const response = await request('wallets.transactions', { + address: 'AUDud8tvyVZa67p3QY7XPRUTjRGnWQQ9Xv', + }) + + expect(response.data.result.count).toBe(2) + expect(response.data.result.data).toHaveLength(2) + }) + + it('should fail to get transactions for the given wallet', async () => { + const response = await request('wallets.transactions', { + address: 'AUDud8tvyVZa67p3QY7XPRUTjRGnWQQ9Xv', + }) + + expect(response.data.error.code).toBe(404) + expect(response.data.error.message).toBe( + 'Wallet AUDud8tvyVZa67p3QY7XPRUTjRGnWQQ9Xv could not be found.', + ) + }) + }) + + describe('POST wallets.create', () => { + it('should create a new wallet', async () => { + const response = await request('wallets.create', { + passphrase: 'this is a top secret passphrase', + }) + + expect(response.data.result.address).toBe( + 'AGeYmgbg2LgGxRW2vNNJvQ88PknEJsYizC', + ) + expect(response.data.result.publicKey).toBe( + '034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192', + ) + }) + }) + + describe('POST wallets.bip38.*', () => { + let bip38wif + const userId = require('crypto') + .randomBytes(32) + .toString('hex') + + describe('create', () => { + it('should create a new wallet', async () => { + const response = await request('wallets.bip38.create', { + bip38: 'this is a top secret passphrase', + userId, + }) + + expect(response.data.result).toHaveProperty('address') + expect(response.data.result).toHaveProperty('publicKey') + expect(response.data.result).toHaveProperty('wif') + + bip38wif = response.data.result.wif + }) + }) + + describe('info', () => { + it('should find the wallet for the given userId', async () => { + const response = await request('wallets.bip38.info', { userId }) + + expect(response.data.result).toHaveProperty('wif') + expect(response.data.result.wif).toBe(bip38wif) + }) + + it('should fail to find the wallet for the given userId', async () => { + const response = await request('wallets.bip38.info', { + userId: '123456789', + }) + + expect(response.data.error.code).toBe(404) + expect(response.data.error.message).toBe( + 'User 123456789 could not be found.', + ) + }) + }) + }) +}) diff --git a/packages/core-json-rpc/jest.config.js b/packages/core-json-rpc/jest.config.js index 783753a35a..57770a97bb 100644 --- a/packages/core-json-rpc/jest.config.js +++ b/packages/core-json-rpc/jest.config.js @@ -1,22 +1,12 @@ -'use strict' - module.exports = { testEnvironment: 'node', - bail: true, + bail: false, verbose: true, - testMatch: [ - '**/__tests__/**/*.test.js' - ], - moduleFileExtensions: [ - 'js', - 'json' - ], + testMatch: ['**/__tests__/**/*.test.js'], + moduleFileExtensions: ['js', 'json'], collectCoverage: false, coverageDirectory: '/.coverage', - collectCoverageFrom: [ - 'lib/**/*.js', - '!**/node_modules/**' - ], + collectCoverageFrom: ['lib/**/*.js', '!**/node_modules/**'], watchman: false, - setupTestFrameworkScriptFile: 'jest-extended' + setupTestFrameworkScriptFile: 'jest-extended', } diff --git a/packages/core-json-rpc/jsdoc.json b/packages/core-json-rpc/jsdoc.json index 23276f74ea..f3ea8aab33 100644 --- a/packages/core-json-rpc/jsdoc.json +++ b/packages/core-json-rpc/jsdoc.json @@ -7,9 +7,7 @@ "includePattern": ".js$", "excludePattern": "(node_modules/|docs)" }, - "plugins": [ - "plugins/markdown" - ], + "plugins": ["plugins/markdown"], "opts": { "template": "../../node_modules/docdash", "encoding": "utf8", diff --git a/packages/core-json-rpc/lib/defaults.js b/packages/core-json-rpc/lib/defaults.js index e48d737304..c80fdad1f6 100644 --- a/packages/core-json-rpc/lib/defaults.js +++ b/packages/core-json-rpc/lib/defaults.js @@ -1,9 +1,13 @@ -'use strict' - module.exports = { enabled: process.env.ARK_JSON_RPC_ENABLED, host: process.env.ARK_JSON_RPC_HOST || '0.0.0.0', port: process.env.ARK_JSON_RPC_PORT || 8080, - allowRemote: true, - whitelist: ['127.0.0.1', '::ffff:127.0.0.1', '192.168.*'] + allowRemote: false, + whitelist: ['127.0.0.1', '::ffff:127.0.0.1'], + database: { + uri: + process.env.ARK_JSON_RPC_DATABASE + || `sqlite://${process.env.ARK_PATH_DATA}/database/json-rpc.sqlite`, + options: {}, + }, } diff --git a/packages/core-json-rpc/lib/index.js b/packages/core-json-rpc/lib/index.js index dadca36f0b..96b85e112f 100644 --- a/packages/core-json-rpc/lib/index.js +++ b/packages/core-json-rpc/lib/index.js @@ -1,4 +1,4 @@ -'use strict' +const database = require('./server/services/database') /** * The struct used by the plugin container. @@ -8,7 +8,7 @@ exports.plugin = { pkg: require('../package.json'), defaults: require('./defaults'), alias: 'json-rpc', - async register (container, options) { + async register(container, options) { const logger = container.resolvePlugin('logger') if (!options.enabled) { @@ -17,13 +17,15 @@ exports.plugin = { return } + database.init(options.database) + return require('./server')(options) }, - async deregister (container, options) { + async deregister(container, options) { if (options.enabled) { container.resolvePlugin('logger').info('Stopping JSON-RPC Server') return container.resolvePlugin('json-rpc').stop() } - } + }, } diff --git a/packages/core-json-rpc/lib/server/handler.js b/packages/core-json-rpc/lib/server/handler.js index eac34f827c..f68d062d1b 100644 --- a/packages/core-json-rpc/lib/server/handler.js +++ b/packages/core-json-rpc/lib/server/handler.js @@ -3,9 +3,9 @@ const processor = require('./services/processor') module.exports = { method: 'POST', path: '/', - async handler (request, h) { + async handler(request, h) { return Array.isArray(request.payload) ? processor.collection(request.server, request.payload) : processor.resource(request.server, request.payload) - } + }, } diff --git a/packages/core-json-rpc/lib/server/index.js b/packages/core-json-rpc/lib/server/index.js index a241d07d46..f84e12adfb 100755 --- a/packages/core-json-rpc/lib/server/index.js +++ b/packages/core-json-rpc/lib/server/index.js @@ -1,9 +1,11 @@ -'use strict' - -const Hapi = require('hapi') +const { + createServer, + mountServer, + plugins, +} = require('@arkecosystem/core-http-utils') const logger = require('@arkecosystem/core-container').resolvePlugin('logger') -function registerMethods (server, group) { +function registerMethods(server, group) { Object.values(require(`./methods/${group}`)).forEach(method => { server.app.schemas[method.name] = method.schema @@ -18,35 +20,35 @@ function registerMethods (server, group) { * @param {Object} options * @return {Hapi.Server} */ -module.exports = async (options) => { +module.exports = async options => { if (options.allowRemote) { - logger.warn('JSON-RPC server allows remote connections, this is a potential security risk :warning:') + logger.warn( + 'JSON-RPC server allows remote connections, this is a potential security risk :warning:', + ) } - const server = new Hapi.Server({ + const server = await createServer({ host: options.host, - port: options.port + port: options.port, }) server.app.schemas = {} - await server.register({ plugin: require('./plugins/whitelist'), options }) + if (!options.allowRemote) { + await server.register({ + plugin: plugins.whitelist, + options: { + whitelist: options.whitelist, + name: 'JSON-RPC', + }, + }) + } - registerMethods(server, 'accounts') + registerMethods(server, 'wallets') registerMethods(server, 'blocks') registerMethods(server, 'transactions') server.route(require('./handler')) - try { - await server.start() - - logger.info(`JSON-RPC Server running at: ${server.info.uri}`) - - return server - } catch (error) { - logger.error(error.message) - // TODO no exit here? - process.exit(1) - } + return mountServer('JSON-RPC', server) } diff --git a/packages/core-json-rpc/lib/server/methods/accounts/bip38/create.js b/packages/core-json-rpc/lib/server/methods/accounts/bip38/create.js deleted file mode 100644 index c151ea81d0..0000000000 --- a/packages/core-json-rpc/lib/server/methods/accounts/bip38/create.js +++ /dev/null @@ -1,36 +0,0 @@ -const Joi = require('joi') -const ark = require('@arkecosystem/crypto') -const bip39 = require('bip39') -const bip38 = require('bip38') -const database = require('../../../services/database') -const getBip38Keys = require('../../../utils/bip38-keys') - -module.exports = { - name: 'accounts.bip38.create', - async method (params) { - try { - const account = await getBip38Keys(params.userId, params.bip38) - - return { - publicKey: account.keys.getPublicKeyBuffer().toString('hex'), - address: account.keys.getAddress(), - wif: account.wif - } - } catch (error) { - const keys = ark.crypto.getKeys(bip39.generateMnemonic()) - - const encryptedWif = bip38.encrypt(keys.d.toBuffer(32), true, params.bip38 + params.userId) - database.setUTF8(ark.utils.sha256(Buffer.from(params.userId)).toString('hex'), encryptedWif) - - return { - publicKey: keys.getPublicKeyBuffer().toString('hex'), - address: keys.getAddress(), - wif: encryptedWif - } - } - }, - schema: { - bip38: Joi.string().required(), - userId: Joi.string().hex().required() - } -} diff --git a/packages/core-json-rpc/lib/server/methods/accounts/bip38/show.js b/packages/core-json-rpc/lib/server/methods/accounts/bip38/show.js deleted file mode 100644 index df4d81585c..0000000000 --- a/packages/core-json-rpc/lib/server/methods/accounts/bip38/show.js +++ /dev/null @@ -1,15 +0,0 @@ -const Joi = require('joi') -const { utils } = require('@arkecosystem/crypto') -const database = require('../../../services/database') - -module.exports = { - name: 'accounts.bip38.info', - async method (params) { - const wif = await database.getUTF8(utils.sha256(Buffer.from(params.userId)).toString('hex')) - - return { wif } - }, - schema: { - userId: Joi.string().hex().required() - } -} diff --git a/packages/core-json-rpc/lib/server/methods/accounts/create.js b/packages/core-json-rpc/lib/server/methods/accounts/create.js deleted file mode 100644 index 1992293fa5..0000000000 --- a/packages/core-json-rpc/lib/server/methods/accounts/create.js +++ /dev/null @@ -1,17 +0,0 @@ -const Joi = require('joi') -const ark = require('@arkecosystem/crypto') - -module.exports = { - name: 'accounts.create', - async method (params) { - const account = ark.crypto.getKeys(params.passphrase) - - return { - publicKey: account.publicKey, - address: ark.crypto.getAddress(account.publicKey) - } - }, - schema: { - passphrase: Joi.string().required() - } -} diff --git a/packages/core-json-rpc/lib/server/methods/accounts/info.js b/packages/core-json-rpc/lib/server/methods/accounts/info.js deleted file mode 100644 index 1b1411762d..0000000000 --- a/packages/core-json-rpc/lib/server/methods/accounts/info.js +++ /dev/null @@ -1,14 +0,0 @@ -const Joi = require('joi') -const network = require('../../services/network') - -module.exports = { - name: 'accounts.info', - async method (params) { - const response = await network.getFromNode(`/api/accounts?address=${params.address}`) - - return response.data.account - }, - schema: { - address: Joi.string().length(34).required() - } -} diff --git a/packages/core-json-rpc/lib/server/methods/accounts/transactions.js b/packages/core-json-rpc/lib/server/methods/accounts/transactions.js deleted file mode 100644 index c133dab5a0..0000000000 --- a/packages/core-json-rpc/lib/server/methods/accounts/transactions.js +++ /dev/null @@ -1,20 +0,0 @@ -const Joi = require('joi') -const network = require('../../services/network') - -module.exports = { - name: 'accounts.transactions', - async method (params) { - const response = await network.getFromNode('/api/transactions', { - offset: params.offset, - orderBy: 'timestamp:desc', - senderId: params.address, - recipientId: params.address - }) - - return response.data - }, - schema: { - address: Joi.string().length(34).required(), - offset: Joi.number().default(0) - } -} diff --git a/packages/core-json-rpc/lib/server/methods/blocks/index.js b/packages/core-json-rpc/lib/server/methods/blocks/index.js index 7476680906..d150e074cf 100644 --- a/packages/core-json-rpc/lib/server/methods/blocks/index.js +++ b/packages/core-json-rpc/lib/server/methods/blocks/index.js @@ -1,5 +1,5 @@ module.exports = [ require('./latest'), require('./info'), - require('./transactions') + require('./transactions'), ] diff --git a/packages/core-json-rpc/lib/server/methods/blocks/info.js b/packages/core-json-rpc/lib/server/methods/blocks/info.js index b329cece15..bb696702f9 100644 --- a/packages/core-json-rpc/lib/server/methods/blocks/info.js +++ b/packages/core-json-rpc/lib/server/methods/blocks/info.js @@ -1,14 +1,19 @@ +const Boom = require('boom') const Joi = require('joi') const network = require('../../services/network') module.exports = { name: 'blocks.info', - async method (params) { - const response = await network.getFromNode(`/api/blocks/get?id=${params.id}`) + async method(params) { + const response = await network.sendRequest(`blocks/${params.id}`) - return response.data.block + return response + ? response.data + : Boom.notFound(`Block ${params.id} could not be found.`) }, schema: { - id: Joi.number().required() - } + id: Joi.number() + .unsafe() + .required(), + }, } diff --git a/packages/core-json-rpc/lib/server/methods/blocks/latest.js b/packages/core-json-rpc/lib/server/methods/blocks/latest.js index b91157ded2..07196d78b8 100644 --- a/packages/core-json-rpc/lib/server/methods/blocks/latest.js +++ b/packages/core-json-rpc/lib/server/methods/blocks/latest.js @@ -2,9 +2,11 @@ const network = require('../../services/network') module.exports = { name: 'blocks.latest', - async method (params) { - const response = await network.getFromNode('/api/blocks?orderBy=height:desc&limit=1') + async method(params) { + const response = await network.sendRequest( + 'blocks?orderBy=height:desc&limit=1', + ) - return response.data.blocks[0] - } + return response.data[0] + }, } diff --git a/packages/core-json-rpc/lib/server/methods/blocks/transactions.js b/packages/core-json-rpc/lib/server/methods/blocks/transactions.js index 37e370f80a..75a53c21e9 100644 --- a/packages/core-json-rpc/lib/server/methods/blocks/transactions.js +++ b/packages/core-json-rpc/lib/server/methods/blocks/transactions.js @@ -1,22 +1,33 @@ +const Boom = require('boom') const Joi = require('joi') const network = require('../../services/network') module.exports = { name: 'blocks.transactions', - async method (params) { - const response = await network.getFromNode('/api/transactions', { - offset: params.offset, - orderBy: 'timestamp:desc', - blockId: params.id - }) + async method(params) { + const response = await network.sendRequest( + `blocks/${params.id}/transactions`, + { + offset: params.offset, + orderBy: 'timestamp:desc', + }, + ) - return { - count: response.data.count, - transactions: response.data.transactions + if (!response) { + return Boom.notFound(`Block ${params.id} could not be found.`) } + + return response + ? { + count: response.meta.totalCount, + data: response.data, + } + : {} }, schema: { - id: Joi.number().required(), - offset: Joi.number().default(0) - } + id: Joi.number() + .unsafe() + .required(), + offset: Joi.number().default(0), + }, } diff --git a/packages/core-json-rpc/lib/server/methods/index.js b/packages/core-json-rpc/lib/server/methods/index.js index bb21d4e84f..3e4c7c25cd 100644 --- a/packages/core-json-rpc/lib/server/methods/index.js +++ b/packages/core-json-rpc/lib/server/methods/index.js @@ -1,5 +1,5 @@ module.exports = { - ...require('./accounts'), + ...require('./wallets'), ...require('./blocks'), - ...require('./transactions') + ...require('./transactions'), } diff --git a/packages/core-json-rpc/lib/server/methods/transactions/bip38/create.js b/packages/core-json-rpc/lib/server/methods/transactions/bip38/create.js index 0137251122..48bd33b5f1 100644 --- a/packages/core-json-rpc/lib/server/methods/transactions/bip38/create.js +++ b/packages/core-json-rpc/lib/server/methods/transactions/bip38/create.js @@ -1,35 +1,37 @@ +const Boom = require('boom') const Joi = require('joi') -const ark = require('@arkecosystem/crypto') +const { transactionBuilder } = require('@arkecosystem/crypto') const database = require('../../../services/database') -const getBip38Keys = require('../../../utils/bip38-keys') +const getBIP38Wallet = require('../../../utils/bip38-keys') module.exports = { name: 'transactions.bip38.create', - async method (params) { - const account = await getBip38Keys(params.userId, params.bip38) + async method(params) { + const wallet = await getBIP38Wallet(params.userId, params.bip38) - const transaction = ark - .transactionBuilder + if (!wallet) { + return Boom.notFound(`User ${params.userId} could not be found.`) + } + + const transaction = transactionBuilder .transfer() .recipientId(params.recipientId) .amount(params.amount) - .sign('dummy') + .signWithWif(wallet.wif) .getStruct() - transaction.senderPublicKey = account.keys.getPublicKeyBuffer().toString('hex') - - delete transaction.signature - ark.crypto.sign(transaction, account.keys) - transaction.id = ark.crypto.getId(transaction) - - await database.setObject(transaction.id, transaction) + await database.set(transaction.id, transaction) return transaction }, schema: { amount: Joi.number().required(), - recipientId: Joi.string().length(34).required(), + recipientId: Joi.string() + .length(34) + .required(), bip38: Joi.string().required(), - userId: Joi.string().hex().required() - } + userId: Joi.string() + .hex() + .required(), + }, } diff --git a/packages/core-json-rpc/lib/server/methods/transactions/broadcast.js b/packages/core-json-rpc/lib/server/methods/transactions/broadcast.js index 131d337850..004f5edc3d 100644 --- a/packages/core-json-rpc/lib/server/methods/transactions/broadcast.js +++ b/packages/core-json-rpc/lib/server/methods/transactions/broadcast.js @@ -1,28 +1,20 @@ +const Boom = require('boom') const Joi = require('joi') -const ark = require('@arkecosystem/crypto') +const { crypto } = require('@arkecosystem/crypto') const network = require('../../services/network') const database = require('../../services/database') module.exports = { name: 'transactions.broadcast', - async method (params) { - if (params.transactions) { // old way - for (let i = 0; i < params.transactions.length; i++) { - await network.broadcast(params.transactions[i]) - } + async method(params) { + const transaction = await database.get(params.id) - return params.transactions + if (!transaction) { + return Boom.notFound(`Transaction ${params.id} could not be found.`) } - let transaction = await database.getObject(params.id) - transaction = transaction || params - - if (!ark.crypto.verify(transaction)) { - return { - success: false, - error: 'transaction does not verify', - transaction - } + if (!crypto.verify(transaction)) { + return Boom.badData() } await network.broadcast(transaction) @@ -31,6 +23,5 @@ module.exports = { }, schema: { id: Joi.string().length(64), - transactions: Joi.array() - } + }, } diff --git a/packages/core-json-rpc/lib/server/methods/transactions/create.js b/packages/core-json-rpc/lib/server/methods/transactions/create.js index 29272c8113..9e52bb14df 100644 --- a/packages/core-json-rpc/lib/server/methods/transactions/create.js +++ b/packages/core-json-rpc/lib/server/methods/transactions/create.js @@ -1,25 +1,24 @@ const Joi = require('joi') -const ark = require('@arkecosystem/crypto') +const { transactionBuilder } = require('@arkecosystem/crypto') const database = require('../../services/database') module.exports = { name: 'transactions.create', - async method (params) { - const transaction = ark - .transactionBuilder + async method(params) { + const transaction = transactionBuilder .transfer() - .sign(params.passphrase) .recipientId(params.recipientId) .amount(params.amount) + .sign(params.passphrase) .getStruct() - await database.setObject(transaction.id, transaction) + await database.set(transaction.id, transaction) return transaction }, schema: { amount: Joi.number().required(), recipientId: Joi.string().required(), - passphrase: Joi.string().required() - } + passphrase: Joi.string().required(), + }, } diff --git a/packages/core-json-rpc/lib/server/methods/transactions/index.js b/packages/core-json-rpc/lib/server/methods/transactions/index.js index 86a127f30d..9affc9f40d 100644 --- a/packages/core-json-rpc/lib/server/methods/transactions/index.js +++ b/packages/core-json-rpc/lib/server/methods/transactions/index.js @@ -2,6 +2,5 @@ module.exports = [ require('./bip38/create'), require('./broadcast'), require('./create'), - require('./list'), - require('./info') + require('./info'), ] diff --git a/packages/core-json-rpc/lib/server/methods/transactions/info.js b/packages/core-json-rpc/lib/server/methods/transactions/info.js index a41ec552eb..9594615ce4 100644 --- a/packages/core-json-rpc/lib/server/methods/transactions/info.js +++ b/packages/core-json-rpc/lib/server/methods/transactions/info.js @@ -1,14 +1,19 @@ +const Boom = require('boom') const Joi = require('joi') const network = require('../../services/network') module.exports = { name: 'transactions.info', - async method (params) { - const response = await network.getFromNode(`/api/transactions/get?id=${params.id}`) + async method(params) { + const response = await network.sendRequest(`transactions/${params.id}`) - return response.data.transaction + return response + ? response.data + : Boom.notFound(`Transaction ${params.id} could not be found.`) }, schema: { - id: Joi.string().length(64).required() - } + id: Joi.string() + .length(64) + .required(), + }, } diff --git a/packages/core-json-rpc/lib/server/methods/transactions/list.js b/packages/core-json-rpc/lib/server/methods/transactions/list.js deleted file mode 100644 index 5112550b57..0000000000 --- a/packages/core-json-rpc/lib/server/methods/transactions/list.js +++ /dev/null @@ -1,8 +0,0 @@ -const database = require('../../services/database') - -module.exports = { - name: 'transactions.list', - async method (params) { - return database.get('transactions') - } -} diff --git a/packages/core-json-rpc/lib/server/methods/wallets/bip38/create.js b/packages/core-json-rpc/lib/server/methods/wallets/bip38/create.js new file mode 100644 index 0000000000..1fc7e9ac0b --- /dev/null +++ b/packages/core-json-rpc/lib/server/methods/wallets/bip38/create.js @@ -0,0 +1,45 @@ +const Joi = require('joi') +const { crypto, utils } = require('@arkecosystem/crypto') +const bip39 = require('bip39') +const bip38 = require('bip38') +const database = require('../../../services/database') +const getBIP38Wallet = require('../../../utils/bip38-keys') + +module.exports = { + name: 'wallets.bip38.create', + async method(params) { + try { + const { keys, wif } = await getBIP38Wallet(params.userId, params.bip38) + + return { + publicKey: keys.publicKey, + address: crypto.getAddress(keys.publicKey), + wif, + } + } catch (error) { + const { publicKey, privateKey } = crypto.getKeys(bip39.generateMnemonic()) + + const encryptedWif = bip38.encrypt( + Buffer.from(privateKey, 'hex'), + true, + params.bip38 + params.userId, + ) + await database.set( + utils.sha256(Buffer.from(params.userId)).toString('hex'), + encryptedWif, + ) + + return { + publicKey, + address: crypto.getAddress(publicKey), + wif: encryptedWif, + } + } + }, + schema: { + bip38: Joi.string().required(), + userId: Joi.string() + .hex() + .required(), + }, +} diff --git a/packages/core-json-rpc/lib/server/methods/wallets/bip38/show.js b/packages/core-json-rpc/lib/server/methods/wallets/bip38/show.js new file mode 100644 index 0000000000..2e3694e673 --- /dev/null +++ b/packages/core-json-rpc/lib/server/methods/wallets/bip38/show.js @@ -0,0 +1,22 @@ +const Boom = require('boom') +const Joi = require('joi') +const { utils } = require('@arkecosystem/crypto') +const database = require('../../../services/database') + +module.exports = { + name: 'wallets.bip38.info', + async method(params) { + const wif = await database.get( + utils.sha256(Buffer.from(params.userId)).toString('hex'), + ) + + return wif + ? { wif } + : Boom.notFound(`User ${params.userId} could not be found.`) + }, + schema: { + userId: Joi.string() + .hex() + .required(), + }, +} diff --git a/packages/core-json-rpc/lib/server/methods/wallets/create.js b/packages/core-json-rpc/lib/server/methods/wallets/create.js new file mode 100644 index 0000000000..c16b13a74e --- /dev/null +++ b/packages/core-json-rpc/lib/server/methods/wallets/create.js @@ -0,0 +1,17 @@ +const Joi = require('joi') +const { crypto } = require('@arkecosystem/crypto') + +module.exports = { + name: 'wallets.create', + async method(params) { + const { publicKey } = crypto.getKeys(params.passphrase) + + return { + publicKey, + address: crypto.getAddress(publicKey), + } + }, + schema: { + passphrase: Joi.string().required(), + }, +} diff --git a/packages/core-json-rpc/lib/server/methods/accounts/index.js b/packages/core-json-rpc/lib/server/methods/wallets/index.js similarity index 80% rename from packages/core-json-rpc/lib/server/methods/accounts/index.js rename to packages/core-json-rpc/lib/server/methods/wallets/index.js index 69f25b0b79..3e124bf0c5 100644 --- a/packages/core-json-rpc/lib/server/methods/accounts/index.js +++ b/packages/core-json-rpc/lib/server/methods/wallets/index.js @@ -3,5 +3,5 @@ module.exports = [ require('./bip38/show'), require('./create'), require('./info'), - require('./transactions') + require('./transactions'), ] diff --git a/packages/core-json-rpc/lib/server/methods/wallets/info.js b/packages/core-json-rpc/lib/server/methods/wallets/info.js new file mode 100644 index 0000000000..35d14b8a3b --- /dev/null +++ b/packages/core-json-rpc/lib/server/methods/wallets/info.js @@ -0,0 +1,19 @@ +const Boom = require('boom') +const Joi = require('joi') +const network = require('../../services/network') + +module.exports = { + name: 'wallets.info', + async method(params) { + const response = await network.sendRequest(`wallets/${params.address}`) + + return response + ? response.data + : Boom.notFound(`Wallet ${params.address} could not be found.`) + }, + schema: { + address: Joi.string() + .length(34) + .required(), + }, +} diff --git a/packages/core-json-rpc/lib/server/methods/wallets/transactions.js b/packages/core-json-rpc/lib/server/methods/wallets/transactions.js new file mode 100644 index 0000000000..bfa27d1258 --- /dev/null +++ b/packages/core-json-rpc/lib/server/methods/wallets/transactions.js @@ -0,0 +1,29 @@ +const Boom = require('boom') +const Joi = require('joi') +const network = require('../../services/network') + +module.exports = { + name: 'wallets.transactions', + async method(params) { + const response = await network.sendRequest('transactions', { + offset: params.offset, + orderBy: 'timestamp:desc', + ownerId: params.address, + }) + + if (!response) { + return Boom.notFound(`Wallet ${params.address} could not be found.`) + } + + return { + count: response.meta.totalCount, + data: response.data, + } + }, + schema: { + address: Joi.string() + .length(34) + .required(), + offset: Joi.number().default(0), + }, +} diff --git a/packages/core-json-rpc/lib/server/plugins/whitelist.js b/packages/core-json-rpc/lib/server/plugins/whitelist.js deleted file mode 100644 index 10b853269a..0000000000 --- a/packages/core-json-rpc/lib/server/plugins/whitelist.js +++ /dev/null @@ -1,57 +0,0 @@ -'use strict' - -const mm = require('micromatch') -const logger = require('@arkecosystem/core-container').resolvePlugin('logger') - -/** - * The register method used by hapi.js. - * @param {Hapi.Server} server - * @param {Object} options - * @return {void} - */ -const register = async (server, options) => { - const defaultRemoteAddresses = ['::1', '127.0.0.1', '::ffff:127.0.0.1'] - - server.ext({ - type: 'onRequest', - async method (request, h) { - let remoteAddress = request.info.remoteAddress - - if (remoteAddress.startsWith('::ffff:')) { - remoteAddress = remoteAddress.replace('::ffff:', '') - } - - if (options.allowRemote) { - return h.continue - } - - if (request.path.includes('broadcast')) { - return h.continue - } - - if (options.whitelist) { - const whitelist = defaultRemoteAddresses.concat(options.whitelist) - - for (let i = 0; i < whitelist.length; i++) { - if (mm.isMatch(remoteAddress, whitelist[i])) { - return h.continue - } - } - } - - logger.warn(`${remoteAddress} tried to access the JSON-RPC without being whitelisted :warning:`) - - return h.response().code(403).takeover() - } - }) -} - -/** - * The struct used by hapi.js. - * @type {Object} - */ -exports.plugin = { - name: 'json-rpc-whitelist', - version: '0.1.0', - register -} diff --git a/packages/core-json-rpc/lib/server/services/database.js b/packages/core-json-rpc/lib/server/services/database.js index c6233b2401..7025732cf5 100644 --- a/packages/core-json-rpc/lib/server/services/database.js +++ b/packages/core-json-rpc/lib/server/services/database.js @@ -1,29 +1,24 @@ -const levelup = require('levelup') -const leveldown = require('leveldown') +const Keyv = require('keyv') class Database { - constructor () { - this.database = levelup(leveldown(`${process.env.ARK_PATH_DATA}/database/json-rpc`)) + init(options) { + this.database = new Keyv(options) } - async getUTF8 (id) { - const value = await this.database.get(id) - - return value.toString('UTF8') + async get(id) { + return this.database.get(id) } - async getObject (id) { - const value = await this.database.get(id) - - return JSON.parse(value.toString('UTF8')) + async set(id, value) { + return this.database.set(id, value) } - setUTF8 (id, value) { - return this.database.put(id, value) + async delete(id) { + return this.database.delete(id) } - setObject (id, value) { - return this.database.put(id, JSON.stringify(value)) + async clear() { + return this.database.clear() } } diff --git a/packages/core-json-rpc/lib/server/services/network.js b/packages/core-json-rpc/lib/server/services/network.js index da4d7a0d2f..cbca05e944 100644 --- a/packages/core-json-rpc/lib/server/services/network.js +++ b/packages/core-json-rpc/lib/server/services/network.js @@ -1,196 +1,115 @@ const axios = require('axios') -const { client } = require('@arkecosystem/crypto') +const { configManager } = require('@arkecosystem/crypto') const isReachable = require('is-reachable') -const { sample, orderBy } = require('lodash') -const container = require('@arkecosystem/core-container') -const logger = container.resolvePlugin('logger') -const p2p = container.resolvePlugin('p2p') -const config = container.resolvePlugin('config') +const sample = require('lodash/sample') +const app = require('@arkecosystem/core-container') + +const logger = app.resolvePlugin('logger') +const p2p = app.resolvePlugin('p2p') +const config = app.resolvePlugin('config') class Network { - setNetwork () { + constructor() { this.network = config.network this.__loadRemotePeers() - client.setConfig(config.network) + configManager.setConfig(config.network) - return this.network + this.client = axios.create({ + headers: { + Accept: 'application/vnd.ark.core-api.v2+json', + 'Content-Type': 'application/json', + }, + timeout: 3000, + }) } - setServer () { + setServer() { this.server = this.__getRandomPeer() - - return this.server } - async getFromNode (url, params = {}, peer = null) { - const nethash = this.network ? this.network.nethash : null - - if (!peer && !this.server) { + async sendRequest(url, params = {}) { + if (!this.server) { this.setServer() } - peer = await this.__selectResponsivePeer(peer || this.server) - - let uri - if (!url.startsWith('http')) { - uri = `http://${peer}${url}` - } + const peer = await this.__selectResponsivePeer(this.server) + const uri = `http://${peer.ip}:${peer.port}/api/${url}` try { logger.info(`Sending request on "${this.network.name}" to "${uri}"`) - return axios.get(uri, { - params, - headers: { - nethash, - version: '2.0.0', - port: 1 - } - }) - .catch(err => { - if (err.message === 'Request failed with status code 404') { - // We are trying on the wrong API version - let peerParts = peer.split(':') - let port = peerParts[peerParts.length - 1] - switch (port) { - case '4003': - if (this.network.name === 'devnet') { - peerParts[peerParts.length - 1] = '4002' // Set devnet port - } else if (this.network.name === 'mainnet') { - peerParts[peerParts.length - 1] = '4001' // Set mainnet port - } - break; - case '4001': - case '4002': - default: - peerParts[peerParts.length - 1] = '4003' // Set the public API port - } - peer = peerParts.join(':') - uri = `http://${peer}${url}` - logger.info(`Sending request on "${this.network.name}" to "${uri}"`) - return axios.get(uri, { - params, - headers: { - nethash, - version: '2.0.0', - port: 1 - } - }) - } - }) - } catch (error) { - logger.error(error.message) - } - } - - async findAvailablePeers () { - try { - const response = await this.getFromNode('/peer/list') - - let { networkHeight, peers } = this.__filterPeers(response.data.peers) - - if (process.env.NODE_ENV === 'test') { - peers = peers.slice(0, 10) - } - - let responsivePeers = [] - for (let i = 0; i < peers.length; i++) { - const response = await this.getFromNode('/peer/status', {}, peers[i]) - - if (Math.abs(response.data.height - networkHeight) <= 10) { - responsivePeers.push(peers[i]) - } - } + const response = await this.client.get(uri, { params }) - this.network.peers = responsivePeers + return response.data } catch (error) { logger.error(error.message) } } - async postTransaction (transaction, peer) { - const server = peer || this.server - - return axios.post(`http://${server}/peer/transactions`, { - transactions: [transaction] - }, { - headers: { - nethash: this.network.nethash, - version: '0.1.0', - port: 1 - } - }) + async broadcast(transaction) { + return this.client.post( + `http://${this.server.ip}:${this.server.port}/api/transactions`, + { + transactions: [transaction], + }, + ) } - async broadcast (transaction) { - const peers = this.network.peers.slice(0, 10) - - for (let i = 0; i < peers.length; i++) { - logger.info(`Broadcasting to ${peers[i]}`) - - await this.postTransaction(transaction, peers[i]) - } - } - - async connect () { + async connect() { if (this.server) { - logger.info(`Server is already configured as "${this.server}"`) + // logger.info(`Server is already configured as "${this.server.ip}:${this.server.port}"`) + return } - if (this.network) { - logger.info(`Network is already configured as "${this.network.name}"`) - } + this.setServer() - if (!this.server || !this.network) { - this.setNetwork() - this.setServer() + try { + const peerPort = app.resolveOptions('p2p').port + const response = await axios.get( + `http://${this.server.ip}:${peerPort}/config`, + ) + + const plugin = response.data.data.plugins['@arkecosystem/core-api'] - await this.findAvailablePeers() + if (!plugin.enabled) { + const index = this.peers.findIndex(peer => peer.ip === this.server.ip) + this.peers.splice(index, 1) - try { - const response = await this.getFromNode('/api/loader/autoconfigure') + if (!this.peers.length) { + this.__loadRemotePeers() + } - this.network.config = response.data.network - } catch (error) { return this.connect() } + + this.server.port = plugin.port + } catch (error) { + return this.connect() } } - __getRandomPeer () { + __getRandomPeer() { this.__loadRemotePeers() - return sample(this.network.peers) + return sample(this.peers) } - __loadRemotePeers () { - const response = p2p.getPeers() - - this.network.peers = response.map(peer => `${peer.ip}:${peer.port}`) - } - - // TODO: adjust this to core-p2p - __filterPeers (peers) { - let filteredPeers = peers - .filter(peer => peer.status === 'OK') - .filter(peer => peer.ip !== '127.0.0.1') - - filteredPeers = orderBy(filteredPeers, ['height', 'delay'], ['desc', 'asc']) - - const networkHeight = filteredPeers[0].height + __loadRemotePeers() { + this.peers = + this.network.name === 'testnet' + ? [{ ip: '127.0.0.1', port: app.resolveOptions('api').port }] + : p2p.getPeers() - return { - networkHeight, - peers: filteredPeers - .filter(peer => Math.abs(peer.height - networkHeight) <= 10) - .map(peer => (`${peer.ip}:${peer.port}`)) + if (!this.peers.length) { + logger.error('No peers found. Shutting down...') + process.exit() } } - async __selectResponsivePeer (peer) { - const reachable = await isReachable(peer) + async __selectResponsivePeer(peer) { + const reachable = await isReachable(`${peer.ip}:${peer.port}`) if (!reachable) { logger.warn(`${peer} is unresponsive. Choosing new peer.`) diff --git a/packages/core-json-rpc/lib/server/services/processor.js b/packages/core-json-rpc/lib/server/services/processor.js index 160342334a..5a4592b778 100644 --- a/packages/core-json-rpc/lib/server/services/processor.js +++ b/packages/core-json-rpc/lib/server/services/processor.js @@ -1,18 +1,27 @@ +/* eslint no-shadow: "off" */ +/* eslint no-await-in-loop: "off" */ + const Joi = require('joi') const get = require('lodash/get') const network = require('./network') class Processor { - async resource (server, payload) { + async resource(server, payload) { const { error } = Joi.validate(payload || {}, { - jsonrpc: Joi.string().valid('2.0').required(), + jsonrpc: Joi.string() + .valid('2.0') + .required(), method: Joi.string().required(), id: Joi.required(), - params: Joi.object() + params: Joi.object(), }) if (error) { - return this.__createErrorResponse(payload ? payload.id : null, -32600, error) + return this.__createErrorResponse( + payload ? payload.id : null, + -32600, + error, + ) } const { method, params, id } = payload @@ -21,10 +30,14 @@ class Processor { const targetMethod = get(server.methods, method) if (!targetMethod) { - return this.__createErrorResponse(id, -32601, 'The method does not exist / is not available.') + return this.__createErrorResponse( + id, + -32601, + 'The method does not exist / is not available.', + ) } - let schema = server.app.schemas[method] + const schema = server.app.schemas[method] if (schema) { const { error } = Joi.validate(params, schema) @@ -38,14 +51,20 @@ class Processor { const result = await targetMethod(params) - return this.__createSuccessResponse(id, result) + return result.isBoom + ? this.__createErrorResponse( + id, + result.output.statusCode, + result.output.payload, + ) + : this.__createSuccessResponse(id, result) } catch (error) { return this.__createErrorResponse(id, -32603, error) } } - async collection (server, payload) { - let results = [] + async collection(server, payload) { + const results = [] for (let i = 0; i < payload.length; i++) { const result = await this.resource(server, payload[i]) @@ -56,23 +75,23 @@ class Processor { return results } - __createSuccessResponse (id, result) { + __createSuccessResponse(id, result) { return { jsonrpc: '2.0', id, - result + result, } } - __createErrorResponse (id, code, error) { + __createErrorResponse(id, code, error) { return { jsonrpc: '2.0', id, error: { code, message: error.message, - data: error.stack - } + data: error.stack, + }, } } } diff --git a/packages/core-json-rpc/lib/server/utils/bip38-keys.js b/packages/core-json-rpc/lib/server/utils/bip38-keys.js index 450c6e9881..95a27f680d 100644 --- a/packages/core-json-rpc/lib/server/utils/bip38-keys.js +++ b/packages/core-json-rpc/lib/server/utils/bip38-keys.js @@ -1,17 +1,27 @@ -const { utils, ECPair } = require('@arkecosystem/crypto') +const { configManager, crypto, utils } = require('@arkecosystem/crypto') const bip38 = require('bip38') -const BigInteger = require('bigi') +const wif = require('wif') const database = require('../services/database') module.exports = async (userId, bip38password) => { try { - const wif = await database.getUTF8(utils.sha256(Buffer.from(userId)).toString('hex')) + const encryptedWif = await database.get( + utils.sha256(Buffer.from(userId)).toString('hex'), + ) - if (wif) { - const decrypted = bip38.decrypt(wif.toString('hex'), bip38password + userId) - const keys = new ECPair(BigInteger.fromBuffer(decrypted.privateKey), null) + if (encryptedWif) { + const decrypted = bip38.decrypt( + encryptedWif.toString('hex'), + bip38password + userId, + ) + const wifKey = wif.encode( + configManager.get('wif'), + decrypted.privateKey, + decrypted.compressed, + ) + const keys = crypto.getKeysFromWIF(wifKey) - return { keys, wif } + return { keys, wif: wifKey } } } catch (error) { throw Error('Could not find a matching WIF') diff --git a/packages/core-json-rpc/package.json b/packages/core-json-rpc/package.json index 55d7a99673..d64f2e6bc7 100644 --- a/packages/core-json-rpc/package.json +++ b/packages/core-json-rpc/package.json @@ -1,7 +1,7 @@ { "name": "@arkecosystem/core-json-rpc", - "description": "A JSON-RPC 2.0 Specification compliant server to interact with the ARK blockchain.", - "version": "0.1.1", + "description": "A JSON-RPC 2.0 Specification compliant server to interact with the Ark Blockchain.", + "version": "0.2.0", "contributors": [ "François-Xavier Thoorens ", "Brian Faust " @@ -9,33 +9,39 @@ "license": "MIT", "main": "lib/index.js", "scripts": { - "build:docs": "../../node_modules/.bin/jsdoc -c jsdoc.json", "test": "cross-env ARK_ENV=test jest --runInBand --detectOpenHandles", - "test:coverage": "cross-env ARK_ENV=test jest --coverage --runInBand --detectOpenHandles", - "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand --watch", + "test:coverage": "cross-env ARK_ENV=test jest --coverage --coveragePathIgnorePatterns='/(defaults.js|index.js)$' --runInBand --detectOpenHandles", + "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand", "test:watch": "cross-env ARK_ENV=test jest --runInBand --watch", "test:watch:all": "cross-env ARK_ENV=test jest --runInBand --watchAll", "lint": "eslint ./ --fix", - "depcheck": "depcheck ./" + "depcheck": "depcheck ./ --ignores=@keyv/sqlite,lodash,lodash.*" }, "dependencies": { - "@arkecosystem/core-container": "^0.1.1", - "@arkecosystem/crypto": "^0.1.1", - "arkjs": "https://github.com/ArkEcosystem/ark-js#master", + "@arkecosystem/core-container": "~0.2", + "@arkecosystem/core-http-utils": "~0.2", + "@arkecosystem/crypto": "~0.2", + "@keyv/sqlite": "^2.0.0", "axios": "^0.18.0", - "bigi": "^1.4.2", "bip38": "^2.0.2", "bip39": "^2.5.0", - "hapi": "^17.5.0", + "boom": "^7.3.0", "is-reachable": "^2.4.0", - "joi": "^13.3.0", - "leveldown": "^4.0.0", - "levelup": "^2.0.2", - "lodash": "^4.17.10", - "micromatch": "^3.1.10", - "uuid": "^3.3.2" + "joi": "^14.3.0", + "keyv": "^3.1.0", + "lodash.get": "^4.4.2", + "uuid": "^3.3.2", + "wif": "^2.0.6" + }, + "devDependencies": { + "@arkecosystem/core-p2p": "~0.2", + "@arkecosystem/core-test-utils": "~0.2", + "axios-mock-adapter": "^1.15.0" }, "publishConfig": { "access": "public" + }, + "engines": { + "node": ">=10.x" } } diff --git a/packages/core-logger-winston/CHANGELOG.md b/packages/core-logger-winston/CHANGELOG.md index 127cc35e42..d351b8c30a 100644 --- a/packages/core-logger-winston/CHANGELOG.md +++ b/packages/core-logger-winston/CHANGELOG.md @@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Unreleased -## 0.0.1 - 2018-05-31 +## 0.2.0 - 2018-12-03 + +### Added + +- Suppress output for silent shutdown + +### Changed + +- Upgraded `winston` to `3.0.0` +- Dropped node.js 9 as minimum requirement in favour of node.js 10 + +### Fixed + +- Calculate correct logger padding + +## 0.1.1 - 2018-06-14 + ### Added + - initial release diff --git a/packages/core-logger-winston/README.md b/packages/core-logger-winston/README.md index 025027aae0..5852f2b818 100644 --- a/packages/core-logger-winston/README.md +++ b/packages/core-logger-winston/README.md @@ -1,42 +1,12 @@ -![ARK Core](https://i.imgur.com/1aP6F2o.png) - -# ARK Core - Winston Logger - -## Installation - -```bash -yarn add @arkecosystem/core-logger-winston -``` - -## Configuration - -### Defaults - -```js -module.exports = { - transports: { - console: { - constructor: 'Console', - options: { - colorize: true, - level: process.env.ARK_LOG_LEVEL || 'debug', - timestamp: () => Date.now(), - formatter: (info) => require('./formatter')(info) - } - }, - dailyRotate: { - package: 'winston-daily-rotate-file', - constructor: 'DailyRotateFile', - options: { - filename: `${process.env.ARK_PATH_DATA}/logs/core/${process.env.ARK_NETWORK_NAME}/%DATE%.log`, - datePattern: 'YYYY-MM-DD', - level: process.env.ARK_LOG_LEVEL || 'debug', - zippedArchive: true - } - } - } -} -``` +# Ark Core - Winston Logger + +

+ +

+ +## Documentation + +You can find installation instructions and detailed instructions on how to use this package at the [dedicated documentation site](https://docs.ark.io/guidebook/core/plugins/core-logger-winston.html). ## Security diff --git a/packages/core-logger-winston/__tests__/logger.test.js b/packages/core-logger-winston/__tests__/logger.test.js index cfb4745c4a..0011e3c251 100644 --- a/packages/core-logger-winston/__tests__/logger.test.js +++ b/packages/core-logger-winston/__tests__/logger.test.js @@ -1,7 +1,4 @@ -'use strict' - const capcon = require('capture-console') -const winston = require('winston') const WinstonDriver = require('../lib/driver') let logger @@ -9,19 +6,23 @@ let message beforeAll(() => { const driver = new WinstonDriver({ - transports: [{ - constructor: 'Console' - }] + transports: [ + { + constructor: 'Console', + }, + ], }) logger = driver.make() - capcon.startCapture(process.stdout, (stdout) => (message += stdout)) + capcon.startCapture(process.stdout, stdout => { + message += stdout + }) }) describe('Logger', () => { it('should be an object', () => { - expect(logger).toBeInstanceOf(winston.Logger) + expect(logger).toBeObject() }) describe('error', () => { @@ -110,4 +111,24 @@ describe('Logger', () => { message = null }) }) + + describe('suppressConsoleOutput', () => { + it('should be a function', () => { + expect(logger.suppressConsoleOutput).toBeFunction() + }) + + it('should suppress console output', () => { + logger.suppressConsoleOutput(true) + + logger.info('silent_message') + expect(message).toBeNull() + + logger.suppressConsoleOutput(false) + + logger.info('non_silent_message') + expect(message).toMatch(/non_silent_message/) + + message = null + }) + }) }) diff --git a/packages/core-logger-winston/jest.config.js b/packages/core-logger-winston/jest.config.js index 26f7a25796..57770a97bb 100644 --- a/packages/core-logger-winston/jest.config.js +++ b/packages/core-logger-winston/jest.config.js @@ -1,22 +1,12 @@ -'use strict' - module.exports = { testEnvironment: 'node', bail: false, verbose: true, - testMatch: [ - '**/__tests__/**/*.test.js' - ], - moduleFileExtensions: [ - 'js', - 'json' - ], + testMatch: ['**/__tests__/**/*.test.js'], + moduleFileExtensions: ['js', 'json'], collectCoverage: false, coverageDirectory: '/.coverage', - collectCoverageFrom: [ - 'lib/**/*.js', - '!**/node_modules/**' - ], + collectCoverageFrom: ['lib/**/*.js', '!**/node_modules/**'], watchman: false, - setupTestFrameworkScriptFile: 'jest-extended' + setupTestFrameworkScriptFile: 'jest-extended', } diff --git a/packages/core-logger-winston/jsdoc.json b/packages/core-logger-winston/jsdoc.json index 23276f74ea..f3ea8aab33 100644 --- a/packages/core-logger-winston/jsdoc.json +++ b/packages/core-logger-winston/jsdoc.json @@ -7,9 +7,7 @@ "includePattern": ".js$", "excludePattern": "(node_modules/|docs)" }, - "plugins": [ - "plugins/markdown" - ], + "plugins": ["plugins/markdown"], "opts": { "template": "../../node_modules/docdash", "encoding": "utf8", diff --git a/packages/core-logger-winston/lib/defaults.js b/packages/core-logger-winston/lib/defaults.js index b056e86a48..5162118f25 100644 --- a/packages/core-logger-winston/lib/defaults.js +++ b/packages/core-logger-winston/lib/defaults.js @@ -1,25 +1,29 @@ -'use strict' - module.exports = { transports: { console: { constructor: 'Console', options: { - colorize: true, level: process.env.ARK_LOG_LEVEL || 'debug', - timestamp: () => Date.now(), - formatter: (info) => require('./formatter')(info) - } + format: require('./formatter')(true), + stderrLevels: ['error', 'warn'], + }, }, dailyRotate: { package: 'winston-daily-rotate-file', constructor: 'DailyRotateFile', options: { - filename: process.env.ARK_LOG_FILE || `${process.env.ARK_PATH_DATA}/logs/core/${process.env.ARK_NETWORK_NAME}/%DATE%.log`, - datePattern: 'YYYY-MM-DD', level: process.env.ARK_LOG_LEVEL || 'debug', - zippedArchive: true - } - } - } + format: require('./formatter')(false), + filename: + process.env.ARK_LOG_FILE + || `${process.env.ARK_PATH_DATA}/logs/core/${ + process.env.ARK_NETWORK_NAME + }/%DATE%.log`, + datePattern: 'YYYY-MM-DD', + zippedArchive: true, + maxSize: '100m', + maxFiles: '10', + }, + }, + }, } diff --git a/packages/core-logger-winston/lib/driver.js b/packages/core-logger-winston/lib/driver.js index 5c6592d9fd..b323430324 100644 --- a/packages/core-logger-winston/lib/driver.js +++ b/packages/core-logger-winston/lib/driver.js @@ -1,8 +1,7 @@ -'use strict' - const winston = require('winston') const { LoggerInterface } = require('@arkecosystem/core-logger') require('colors') + let tracker = null module.exports = class Logger extends LoggerInterface { @@ -10,15 +9,16 @@ module.exports = class Logger extends LoggerInterface { * Make the logger instance. * @return {Winston.Logger} */ - make () { - this.driver = new (winston.Logger)() + make() { + this.driver = winston.createLogger() this.__registerTransports() - this.__registerFilters() + // this.__registerFilters() this.driver.printTracker = this.printTracker this.driver.stopTracker = this.stopTracker + this.driver.suppressConsoleOutput = this.suppressConsoleOutput return this.driver } @@ -32,18 +32,18 @@ module.exports = class Logger extends LoggerInterface { * @param {Number} figures * @return {void} */ - printTracker (title, current, max, postTitle, figures = 0) { - const progress = 100 * current / max + printTracker(title, current, max, postTitle, figures = 0) { + const progress = (100 * current) / max let line = '\u{1b}[0G ' line += title.blue line += ' [' - line += ('='.repeat(progress / 2)).green - line += ' '.repeat(50 - progress / 2) + '] ' - line += progress.toFixed(figures) + '% ' + line += '='.repeat(Math.floor(progress / 2)).green + line += `${' '.repeat(Math.ceil(50 - progress / 2))}] ` + line += `${progress.toFixed(figures)}% ` if (postTitle) { - line += postTitle + ' ' + line += `${postTitle} ` } process.stdout.write(line) @@ -58,8 +58,8 @@ module.exports = class Logger extends LoggerInterface { * @param {Number} max * @return {void} */ - stopTracker (title, current, max) { - let progress = 100 * current / max + stopTracker(title, current, max) { + let progress = (100 * current) / max if (progress > 100) { progress = 100 @@ -68,9 +68,9 @@ module.exports = class Logger extends LoggerInterface { let line = '\u{1b}[0G ' line += title.blue line += ' [' - line += ('='.repeat(progress / 2)).green - line += ' '.repeat(50 - progress / 2) + '] ' - line += progress.toFixed(0) + '% ' + line += '='.repeat(progress / 2).green + line += `${' '.repeat(50 - progress / 2)}] ` + line += `${progress.toFixed(0)}% ` if (current === max) { line += '✔️' @@ -81,28 +81,44 @@ module.exports = class Logger extends LoggerInterface { tracker = null } + /** + * Suppress console output. + * @param {Boolean} + * @return {void} + */ + suppressConsoleOutput(suppress) { + const consoleTransport = this.transports.find(t => t.name === 'console') + if (consoleTransport) { + consoleTransport.silent = suppress + } + } + /** * Register all transports. * @return {void} */ - __registerTransports () { - Object.values(this.options.transports).forEach(transport => { + __registerTransports() { + for (const transport of Object.values(this.options.transports)) { if (transport.package) { require(transport.package) } - this.driver.add(winston.transports[transport.constructor], transport.options) - }) + this.driver.add( + new winston.transports[transport.constructor](transport.options), + ) + } } /** * Register all filters. * @return {void} */ - __registerFilters () { + __registerFilters() { this.driver.filters.push((level, message, meta) => { if (tracker) { - process.stdout.write('\u{1b}[0G \u{1b}[0G') + process.stdout.write( + '\u{1b}[0G \u{1b}[0G', + ) tracker = null } diff --git a/packages/core-logger-winston/lib/formatter.js b/packages/core-logger-winston/lib/formatter.js index 20be2551c9..38cd7c94ea 100644 --- a/packages/core-logger-winston/lib/formatter.js +++ b/packages/core-logger-winston/lib/formatter.js @@ -1,39 +1,45 @@ -'use strict' - +const { format } = require('winston') const chalk = require('chalk') -const moment = require('moment') +const dayjs = require('dayjs-ext') const emoji = require('node-emoji') -/** - * The winston message formatter. - * @param {Object} info - * @return {String} - */ -module.exports = (info) => { - let level = info.level.toUpperCase() - level = { - 'error': chalk.bold.red(level), - 'warn': chalk.bold.yellow(level), - 'info': chalk.bold.blue(level), - 'verbose': chalk.bold.cyan(level), - 'debug': chalk.bold.white(level), - 'silly': chalk.bold.magenta(level) - }[info.level] - - let message = emoji.emojify(info.message) || JSON.stringify(info.meta) - message = { - 'error': chalk.bold.bgRed(message), - 'warn': chalk.bold.black.bgYellow(message), - 'info': message, - 'verbose': chalk.bold.cyan(message), - 'debug': chalk.black.bgWhite(message), - 'silly': chalk.bold.black.bgWhite(message) - }[info.level] - - const timestamp = moment(info.timestamp()).format('YYYY-MM-DD HH:mm:ss') - - const dateAndLevel = `[${timestamp}][${level}]:` - const lineSpacer = ' '.repeat(Math.abs(dateAndLevel.length - 50) + 1) - - return `[${timestamp}][${level}]${lineSpacer}: ${message}` -} +const { colorize, combine, timestamp, printf } = format + +module.exports = (colorOutput = true) => + combine( + colorize(), + timestamp(), + printf(info => { + const infoLevel = info[Symbol.for('level')] + + let level = infoLevel.toUpperCase() + let message = emoji.emojify(info.message) || JSON.stringify(info.meta) + + if (colorOutput) { + level = { + error: chalk.bold.red(level), + warn: chalk.bold.yellow(level), + info: chalk.bold.blue(level), + verbose: chalk.bold.cyan(level), + debug: chalk.bold.white(level), + silly: chalk.bold.magenta(level), + }[infoLevel] + + message = { + error: chalk.bold.bgRed(message), + warn: chalk.bold.black.bgYellow(message), + info: message, + verbose: chalk.bold.cyan(message), + debug: chalk.black.bgWhite(message), + silly: chalk.bold.black.bgWhite(message), + }[infoLevel] + } + + const dateTime = dayjs(info.timestamp).format('YYYY-MM-DD HH:mm:ss') + + const dateTimeAndLevel = `[${dateTime}][${level}]:` + const lineSpacer = ' '.repeat(Math.abs(dateTimeAndLevel.length - 50) + 1) + + return `[${dateTime}][${level}]${lineSpacer}: ${message}` + }), + ) diff --git a/packages/core-logger-winston/lib/index.js b/packages/core-logger-winston/lib/index.js index ae3f9cb7c5..33fccd6819 100644 --- a/packages/core-logger-winston/lib/index.js +++ b/packages/core-logger-winston/lib/index.js @@ -1,5 +1,3 @@ -'use strict' - const WinstonDriver = require('./driver') /** @@ -10,12 +8,13 @@ exports.plugin = { pkg: require('../package.json'), defaults: require('./defaults'), alias: 'logger', - async register (container, options) { + extends: '@arkecosystem/core-logger', + async register(container, options) { const logManager = container.resolvePlugin('logManager') await logManager.makeDriver(new WinstonDriver(options)) return logManager.driver() - } + }, } /** diff --git a/packages/core-logger-winston/package.json b/packages/core-logger-winston/package.json index 7824958a37..a949055bf1 100644 --- a/packages/core-logger-winston/package.json +++ b/packages/core-logger-winston/package.json @@ -1,7 +1,7 @@ { "name": "@arkecosystem/core-logger-winston", - "description": "Winston Logger for ARK Core", - "version": "0.1.1", + "description": "Winston Logger for Ark Core", + "version": "0.2.0", "contributors": [ "François-Xavier Thoorens ", "Brian Faust " @@ -9,28 +9,30 @@ "license": "MIT", "main": "lib/index.js", "scripts": { - "build:docs": "../../node_modules/.bin/jsdoc -c jsdoc.json", "test": "cross-env ARK_ENV=test jest --runInBand --detectOpenHandles", - "test:coverage": "cross-env ARK_ENV=test jest --coverage --runInBand --detectOpenHandles", - "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand --watch", + "test:coverage": "cross-env ARK_ENV=test jest --coverage --coveragePathIgnorePatterns='/(defaults.js|index.js)$' --runInBand --detectOpenHandles", + "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand", "test:watch": "cross-env ARK_ENV=test jest --runInBand --watch", "test:watch:all": "cross-env ARK_ENV=test jest --runInBand --watchAll", "lint": "eslint ./ --fix", "depcheck": "depcheck ./ --ignores=winston-daily-rotate-file" }, "dependencies": { - "@arkecosystem/core-logger": "^0.1.1", + "@arkecosystem/core-logger": "~0.2", "chalk": "^2.4.1", - "colors": "^1.3.0", - "moment": "^2.22.1", + "colors": "^1.3.2", + "dayjs-ext": "^2.2.0", "node-emoji": "^1.8.1", - "winston": "^2.4.2", - "winston-daily-rotate-file": "^3.1.4" + "winston": "^3.1.0", + "winston-daily-rotate-file": "^3.5.1" }, "devDependencies": { "capture-console": "^1.0.1" }, "publishConfig": { "access": "public" + }, + "engines": { + "node": ">=10.x" } } diff --git a/packages/core-logger/CHANGELOG.md b/packages/core-logger/CHANGELOG.md index 127cc35e42..fd0a4f14d3 100644 --- a/packages/core-logger/CHANGELOG.md +++ b/packages/core-logger/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Unreleased -## 0.0.1 - 2018-05-31 +## 0.2.0 - 2018-12-03 + +### Changed + +- Dropped node.js 9 as minimum requirement in favour of node.js 10 + +## 0.1.1 - 2018-06-14 + ### Added + - initial release diff --git a/packages/core-logger/README.md b/packages/core-logger/README.md index 3655ea3a53..7461bb653d 100644 --- a/packages/core-logger/README.md +++ b/packages/core-logger/README.md @@ -1,12 +1,12 @@ -![ARK Core](https://i.imgur.com/1aP6F2o.png) +# Ark Core - Logger - Interface -# ARK Core - Logger +

+ +

-## Installation +## Documentation -```bash -yarn add @arkecosystem/core-logger -``` +You can find installation instructions and detailed instructions on how to use this package at the [dedicated documentation site](https://docs.ark.io/guidebook/core/plugins/core-logger.html). ## Security diff --git a/packages/core-logger/__tests__/interface.test.js b/packages/core-logger/__tests__/interface.test.js index 16847085e7..66a662e4ad 100644 --- a/packages/core-logger/__tests__/interface.test.js +++ b/packages/core-logger/__tests__/interface.test.js @@ -1,5 +1,3 @@ -'use strict' - const LoggerInterface = require('../lib/interface') const logger = new LoggerInterface() @@ -50,4 +48,10 @@ describe('Logger Interface', () => { expect(logger.stopTracker).toBeFunction() }) }) + + describe('suppressConsoleOutput', () => { + it('should be a function', () => { + expect(logger.suppressConsoleOutput).toBeFunction() + }) + }) }) diff --git a/packages/core-logger/__tests__/manager.test.js b/packages/core-logger/__tests__/manager.test.js index 7693078a91..7e9325e091 100644 --- a/packages/core-logger/__tests__/manager.test.js +++ b/packages/core-logger/__tests__/manager.test.js @@ -1,9 +1,7 @@ -'use strict' - const loggerManager = require('../lib/manager') class FakeDriver { - make () { + make() { return this } } diff --git a/packages/core-logger/jest.config.js b/packages/core-logger/jest.config.js index 26f7a25796..57770a97bb 100644 --- a/packages/core-logger/jest.config.js +++ b/packages/core-logger/jest.config.js @@ -1,22 +1,12 @@ -'use strict' - module.exports = { testEnvironment: 'node', bail: false, verbose: true, - testMatch: [ - '**/__tests__/**/*.test.js' - ], - moduleFileExtensions: [ - 'js', - 'json' - ], + testMatch: ['**/__tests__/**/*.test.js'], + moduleFileExtensions: ['js', 'json'], collectCoverage: false, coverageDirectory: '/.coverage', - collectCoverageFrom: [ - 'lib/**/*.js', - '!**/node_modules/**' - ], + collectCoverageFrom: ['lib/**/*.js', '!**/node_modules/**'], watchman: false, - setupTestFrameworkScriptFile: 'jest-extended' + setupTestFrameworkScriptFile: 'jest-extended', } diff --git a/packages/core-logger/jsdoc.json b/packages/core-logger/jsdoc.json index 23276f74ea..f3ea8aab33 100644 --- a/packages/core-logger/jsdoc.json +++ b/packages/core-logger/jsdoc.json @@ -7,9 +7,7 @@ "includePattern": ".js$", "excludePattern": "(node_modules/|docs)" }, - "plugins": [ - "plugins/markdown" - ], + "plugins": ["plugins/markdown"], "opts": { "template": "../../node_modules/docdash", "encoding": "utf8", diff --git a/packages/core-logger/lib/index.js b/packages/core-logger/lib/index.js index 80c6ab4ded..45eea19843 100644 --- a/packages/core-logger/lib/index.js +++ b/packages/core-logger/lib/index.js @@ -1,5 +1,3 @@ -'use strict' - const logManager = require('./manager') /** @@ -9,9 +7,9 @@ const logManager = require('./manager') exports.plugin = { pkg: require('../package.json'), alias: 'logManager', - async register (container, options) { + async register() { return logManager - } + }, } /** diff --git a/packages/core-logger/lib/interface.js b/packages/core-logger/lib/interface.js index 915b646a7c..ec61a1be9f 100644 --- a/packages/core-logger/lib/interface.js +++ b/packages/core-logger/lib/interface.js @@ -1,11 +1,9 @@ -'use strict' - module.exports = class LoggerInterface { /** * Create a new logger instance. * @param {Object} options */ - constructor (options) { + constructor(options) { this.options = options } @@ -13,7 +11,7 @@ module.exports = class LoggerInterface { * Get a driver instance. * @return {LoggerInterface} */ - driver () { + driver() { return this.driver } @@ -22,7 +20,7 @@ module.exports = class LoggerInterface { * @param {*} message * @return {void} */ - error (message) { + error(message) { throw new Error('Method [error] not implemented!') } @@ -31,7 +29,7 @@ module.exports = class LoggerInterface { * @param {*} message * @return {void} */ - warn (message) { + warn(message) { throw new Error('Method [warn] not implemented!') } @@ -40,7 +38,7 @@ module.exports = class LoggerInterface { * @param {*} message * @return {void} */ - info (message) { + info(message) { throw new Error('Method [info] not implemented!') } @@ -49,7 +47,7 @@ module.exports = class LoggerInterface { * @param {*} message * @return {void} */ - debug (message) { + debug(message) { throw new Error('Method [debug] not implemented!') } @@ -62,7 +60,7 @@ module.exports = class LoggerInterface { * @param {Number} figures * @return {void} */ - printTracker (title, current, max, postTitle, figures = 0) { + printTracker(title, current, max, postTitle, figures = 0) { throw new Error('Method [printTracker] not implemented!') } @@ -73,7 +71,16 @@ module.exports = class LoggerInterface { * @param {Number} max * @return {void} */ - stopTracker (title, current, max) { + stopTracker(title, current, max) { throw new Error('Method [stopTracker] not implemented!') } + + /** + * Suppress console output. + * @param {Boolean} + * @return {void} + */ + suppressConsoleOutput(suppress) { + throw new Error('Method [suppressConsoleOutput] not implemented!') + } } diff --git a/packages/core-logger/lib/manager.js b/packages/core-logger/lib/manager.js index dca3eb3b7b..485a72abfc 100644 --- a/packages/core-logger/lib/manager.js +++ b/packages/core-logger/lib/manager.js @@ -1,11 +1,9 @@ -'use strict' - class LogManager { /** * Create a new log manager instance. * @constructor */ - constructor () { + constructor() { this.drivers = {} } @@ -14,7 +12,7 @@ class LogManager { * @param {String} name * @return {LoggerInterface} */ - driver (name = 'default') { + driver(name = 'default') { return this.drivers[name] } @@ -24,7 +22,7 @@ class LogManager { * @param {String} name * @return {void} */ - async makeDriver (driver, name = 'default') { + async makeDriver(driver, name = 'default') { this.drivers[name] = await driver.make() } } diff --git a/packages/core-logger/package.json b/packages/core-logger/package.json index 64c8a81d44..3ab4853409 100644 --- a/packages/core-logger/package.json +++ b/packages/core-logger/package.json @@ -1,17 +1,16 @@ { "name": "@arkecosystem/core-logger", - "description": "Logger Manager for ARK Core", - "version": "0.1.1", + "description": "Logger Manager for Ark Core", + "version": "0.2.0", "contributors": [ "Brian Faust " ], "license": "MIT", "main": "lib/index.js", "scripts": { - "build:docs": "../../node_modules/.bin/jsdoc -c jsdoc.json", "test": "cross-env ARK_ENV=test jest --runInBand --detectOpenHandles", - "test:coverage": "cross-env ARK_ENV=test jest --coverage --runInBand --detectOpenHandles", - "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand --watch", + "test:coverage": "cross-env ARK_ENV=test jest --coverage --coveragePathIgnorePatterns='/(defaults.js|index.js)$' --runInBand --detectOpenHandles", + "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand", "test:watch": "cross-env ARK_ENV=test jest --runInBand --watch", "test:watch:all": "cross-env ARK_ENV=test jest --runInBand --watchAll", "lint": "eslint ./ --fix", @@ -19,5 +18,8 @@ }, "publishConfig": { "access": "public" + }, + "engines": { + "node": ">=10.x" } } diff --git a/packages/core-p2p/CHANGELOG.md b/packages/core-p2p/CHANGELOG.md index f490b4698e..368c2bf57f 100644 --- a/packages/core-p2p/CHANGELOG.md +++ b/packages/core-p2p/CHANGELOG.md @@ -6,13 +6,66 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). ## Unreleased -## 0.0.2 - + +## 0.2.0 - 2018-12-03 + +### Added + - Support for next forger calculations -- Network state calculation (new internal/networkState) taking PBFT into account -- Peer optimisations (blacklisting, whitelisting, coldstart) options for peers and forger - Relay support for wake-up from forger (to sync before forging) - Additional tests implemented +- Remote API authentication +- Return a 503 status code while the node is syncing/busy instead of crashing +- Updated peer heights on a regular basis +- Validate P2P headers +- Rule based peer banning to provide greater control +- Event emitting via API through the relay +- Configuration API +- Minimum peer version +- Peer whitelisting & blacklisting +- Common block checks +- Peer banning after forks +- Reject forgers as peers +- Recovery after a fork +- Enabled rate-limiting +- Enable/Disable peer discovery +- Dump the peer list on shutdown and load it on next start +- Log how many peers were found with what versions +- Log how many peers were found with what git commits _(development networks only)_ + +### Changed + +- Network state calculation (new internal/networkState) taking PBFT into account +- Peer optimisations (blacklisting, whitelisting, coldstart) options for peers and forger +- Overall reduced the complexity of how the P2P API is structured +- Allow config to be retrieved without P2P headers +- Dropped node.js 9 as minimum requirement in favour of node.js 10 +- Exclude transactions from broadcasting if they are in the transaction pool +- Reduced timeouts for HTTP requests +- Allow 20/rps instead of 1000/rpm +- Limit the number of peers a transaction is broadcasted to +- Broadcast transactions in chunks based on `maxTransactionsPerRequest` +- Improved ping behaviour by remembering ping times + +### Removed + +- Remove threading for block downloads + +### Fixed + +- Handle "no common block" banning +- Various cases of bad error handling +- Various inconsistencies between the v1 P2P API and current implementation +- Return ports as integers +- Handle CORS requests to the P2P API +- Return the last block if no height is provided to a method +- Race condition that would result in duplicate transactions in the transaction pool +- Accept v1 peers +- Avoid errors when banning peers before the state storage is not ready yet +- Grab transactions based on the transactions per block + +## 0.1.1 - 2018-06-14 -## 0.0.1 - 2018-05-31 ### Added + - initial release diff --git a/packages/core-p2p/README.md b/packages/core-p2p/README.md index 71ee0ea00f..0929a34301 100644 --- a/packages/core-p2p/README.md +++ b/packages/core-p2p/README.md @@ -1,38 +1,12 @@ -![ARK Core](https://i.imgur.com/1aP6F2o.png) - -# ARK Core - P2P API - -## Installation - -```bash -yarn add @arkecosystem/core-p2p -``` - -## Configuration - -### Defaults - -```js -module.exports = { - port: process.env.ARK_P2P_PORT || 4002, - remoteinterface: true, - dns: [ - // Google - '8.8.8.8', - '8.8.4.4', - // CloudFlare - '1.1.1.1', - '1.0.0.1', - // OpenDNS - '208.67.222.222', - '208.67.220.220' - ], - ntp: [ - 'pool.ntp.org', - 'time.google.com' - ] -} -``` +# Ark Core - P2P API + +

+ +

+ +## Documentation + +You can find installation instructions and detailed instructions on how to use this package at the [dedicated documentation site](https://docs.ark.io/guidebook/core/plugins/core-p2p.html). ## Security diff --git a/packages/core-p2p/__mocks__/sntp.js b/packages/core-p2p/__mocks__/sntp.js new file mode 100644 index 0000000000..b6cb8435ef --- /dev/null +++ b/packages/core-p2p/__mocks__/sntp.js @@ -0,0 +1,12 @@ +const Sntp = jest.genMockFromModule('sntp') + +const sntpTime = Sntp.time +Sntp.time = options => { + if (options.host === 'notime.unknown.not') { + // we actually want to call the real Sntp time() because we want it to fail + return sntpTime(options) + } + return { t: 111 } +} + +module.exports = Sntp diff --git a/packages/core-p2p/__tests__/__fixtures__/genesisBlock.js b/packages/core-p2p/__tests__/__fixtures__/genesisBlock.js deleted file mode 100644 index e01041c65e..0000000000 --- a/packages/core-p2p/__tests__/__fixtures__/genesisBlock.js +++ /dev/null @@ -1,845 +0,0 @@ -const { Block } = require('@arkecosystem/crypto').models - -module.exports = new Block({ - 'version': 0, - 'totalAmount': 12500000000000000, - 'totalFee': 0, - 'reward': 0, - 'payloadHash': '578e820911f24e039733b45e4882b73e301f813a0d2c31330dafda84534ffa23', - 'timestamp': 0, - 'numberOfTransactions': 52, - 'payloadLength': 11401, - 'previousBlock': null, - 'generatorPublicKey': '024c8247388a02ecd1de2a3e3fd5b7c61ecc2797fa3776599d558333ef1802d231', - 'transactions': [{ - 'type': 0, - 'amount': 12500000000000000, - 'fee': 0, - 'recipientId': 'DGihocTkwDygiFvmg6aG8jThYTic47GzU9', - 'timestamp': 0, - 'asset': {}, - 'senderPublicKey': '03cb7bca143376721d0e9e3f3ccb0dc2e7e8470c06e630c3cef73f03e309b558ad', - 'signature': '3044022016ecdf3039e69514c7d75861b22fc076496b61c07a1fcf793dc4f5c76fa0532b0220579c4c0c9d13720f9db5d9df29ed8ceab0adc266c6c160d612d4894dc5867eb1', - 'id': 'e40ce11cab82736da1cc91191716f3c1f446ca7b6a9f4f93b7120ef105ba06e8', - 'senderId': 'DUFeXjJmYt1mWY3auywA1EQSqfCv5kYYfP' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03e5b39a83e6c7c952c5908089d4524bb8dda93acc2b2b953247e43dc4fe9aa3d1', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_1', - 'publicKey': '03e5b39a83e6c7c952c5908089d4524bb8dda93acc2b2b953247e43dc4fe9aa3d1' - } - }, - 'signature': '3045022100e3e38811778023e6f17fefd447f179d45ab92c398c7cfb1e34e2f6e1b167c95a022070c36439ecec0fc3c43850070f29515910435d389e059579878d61b5ff2ea337', - 'id': 'eb0146ac79afc228f0474a5ae1c4771970ae7880450b998c401029f522cd8a21', - 'senderId': 'DNL81CT6WNG1PHjobBmLvKwLV3UUscBymB' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '031137050d5fed0b5229b150257da2ac9c135efdf4bcb382b0ad0c197d7be458f4', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_3', - 'publicKey': '031137050d5fed0b5229b150257da2ac9c135efdf4bcb382b0ad0c197d7be458f4' - } - }, - 'signature': '30440220124baaa04491287d0abbf5a167c9b0f5ac95c22b196f42ff3d275cc9a213c2fd02206e6ebada85f67063e642dbcde6b956f8c99c05f4b9c55f1551d3eebba6375043', - 'id': 'c9c554056b3428951633a7059dd64dfcbd776fef7f4a156ea362b37ee6ce74c7', - 'senderId': 'DG9LYv5rqX67wuGvGVa9is5k1r86LKCVTA' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '037def83d085778d7767a182a179f345207953441089081f5bc13f86d3891308aa', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_4', - 'publicKey': '037def83d085778d7767a182a179f345207953441089081f5bc13f86d3891308aa' - } - }, - 'signature': '3045022100900cea3c2df393414899c9d74db57d89c9f311c70d08b974d0fd4a98bfae2fc902204a2aa51a1ec71da27c26afc033de6bd2d15978813c120c95e1a4dafca75ce876', - 'id': 'c82ccaa16be0e3c7ff4a53e2807968b71a0d88115223c3af2eb320f32449ac32', - 'senderId': 'DMSwarrHg5N9ZAZ6nsqPuUjyAU6gdRAM9d' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '033f28ad2e9b897d46f1e67c7c52070e9ca46b04c0679ebb21fb236719e38aade3', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_5', - 'publicKey': '033f28ad2e9b897d46f1e67c7c52070e9ca46b04c0679ebb21fb236719e38aade3' - } - }, - 'signature': '30440220285188d8900cd3cffccf5e1de305b18856451dd04d2ed21165dffe9a7ce4afc1022009457be6bfe536971697105d47ad1f829738a5cacdb27a23c5d1e8a8dddf3ebd', - 'id': 'ee6a19fff622ab4e6e96d159396de56d6034b4b18a9cf5c99efcf4e61b28e15a', - 'senderId': 'DFcYHfCwhGWcBNy6cp48wy5SfXbQmfBYgT' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '023e577a7b3362e0aba70e6911d230e86d729b4cb640f0e0b25637b812a3e38b53', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_6', - 'publicKey': '023e577a7b3362e0aba70e6911d230e86d729b4cb640f0e0b25637b812a3e38b53' - } - }, - 'signature': '3045022100afa56542dd473c424b36d4d9f24da68180cfd90527681ab84098f415b2544a8702201e8ebdd619a2dd200e37a57c39a4529afe76d35f6089c00f6dffba6bf7b8a836', - 'id': '0dcd6e380bd7eaef8724f64f4b86104ce7497308dacf775afbe6ec0d401007fe', - 'senderId': 'D5e2FzTPqdEHridjzpFZCCVyepAu6Vpmk4' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02af5e6341efc14f4ba39a9ff65e151cc7304fc742ce7b2678d9aa446c555ee9c1', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_7', - 'publicKey': '02af5e6341efc14f4ba39a9ff65e151cc7304fc742ce7b2678d9aa446c555ee9c1' - } - }, - 'signature': '3045022100c8980155c8f8964d76baf3e8d690075708f1a84757c1de52e311772466382da2022012599acfc7839fa1ef6bbd445ab34555fb718491db3089f40d4842b1bc2d3178', - 'id': '8af6abb117c69c130e388970d595b741374b1bbca709d9e91459e9e3c721397b', - 'senderId': 'DDLbnve6XK48cGsQiFhesUJQRQdKkZTfPh' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02845161cfca4d6ddde8e0d53538b6f881fb3ad9383cd77cebc55375dd6fd17663', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_8', - 'publicKey': '02845161cfca4d6ddde8e0d53538b6f881fb3ad9383cd77cebc55375dd6fd17663' - } - }, - 'signature': '30450221009bce7c5c10a4b6306cebe5724adfd3de049a425c44dd314a10154774764c11090220070fb775e71dda6a68f7fc9e0c762fbf96021908911f0de0ca8e9b0c613cb896', - 'id': 'bd346035d4516b85fb3a2cce6260fdcc6f1c434999e586978e065de3bf98e02a', - 'senderId': 'DDAHPjVTTV3uur653TB27fcLGh7XXWnvxW' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03f264a6d2ebb62279313a6fd7fec4e2244785839b625a0b0c261e689ce5401d87', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_9', - 'publicKey': '03f264a6d2ebb62279313a6fd7fec4e2244785839b625a0b0c261e689ce5401d87' - } - }, - 'signature': '30450221009f74425c2ec50dbee462e735dee3e7917c8433fd5250ff09af4506c38d2df05902206a14a19b9a5defe3c8c59c77d52c182ea34d81d2e0b05dc5925133f2829a1960', - 'id': 'b48068fb7c848ffd57e82a4d381f53bb69916f3943e0e8935971a028ba245564', - 'senderId': 'DFHdEBuVCz5zfj8yeo3BmKEdsEKpMaYRRw' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03efd265a086c2a099cda4f4fd202adbac07567e1229ce5e6fe39963b714c1e2d5', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_10', - 'publicKey': '03efd265a086c2a099cda4f4fd202adbac07567e1229ce5e6fe39963b714c1e2d5' - } - }, - 'signature': '3044022004df492965ed328134aa6443d38ac4dd951a640e00330da9aa4e80c1577af41a0220588f030f5f9584959647898bb977a1ffe6bba639b1c64a728880f2cd3fd7aa3c', - 'id': '73b3b4375e39aabe51ec205559cd728a18c987dabaa0599c611b3076c38c7a49', - 'senderId': 'DL7Y6smfHHs3Ms3hAYmSYYd5PZukmtDY1i' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '027d616d20f03c375067676c79ff9787e8e42991fbd9e878501d704d23d246d9b0', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_11', - 'publicKey': '027d616d20f03c375067676c79ff9787e8e42991fbd9e878501d704d23d246d9b0' - } - }, - 'signature': '3044022051c2f8af62163ca621eeb3087a35bfaca0d679f7be8b19a25972f5a4b24ad8c90220422f3e0e480bf1bf2211e871a102edc15a957c0f97a553d9d707418e6538df26', - 'id': '80f1d01158452da31d44f0c24f464a0ade37da51d2f61356ad75a019a91a1ff5', - 'senderId': 'DBVoRSXBHBPPvssBXrswv22r4dUSpN1fbA' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '038918951152a37b74dfe61115f83e4b5e3521145065650c4a6d3e94add57d9a9b', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_12', - 'publicKey': '038918951152a37b74dfe61115f83e4b5e3521145065650c4a6d3e94add57d9a9b' - } - }, - 'signature': '3045022100facf6ed992c28d41595419666b006800fcb33c6bad4b522e013b4d688e51dc8502207695e968059f7a35486389c430d6a3037e69d3e5f1d4f0a294d8818e4750cf0d', - 'id': '86d76b0aad8f496d8c20926bfdeb50ad10db242ea6152b68266680c48e1e1aca', - 'senderId': 'DHsSK81gRWjgNx1A9gtHgkRsEwshsog7AM' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03231d8f2f39925fa79efc8f8561e6a8d29b95164a753cbb604a46e8a2e96606fc', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_13', - 'publicKey': '03231d8f2f39925fa79efc8f8561e6a8d29b95164a753cbb604a46e8a2e96606fc' - } - }, - 'signature': '304402204c627ec3d24fb7b4f86709c0566cee9909ebddb26039e87a2fa673f1f7227362022003be5aa3303b8f4cdab768f80b4699440a61814950cab0fd983526771c4c52ec', - 'id': '464614909ac7531a016a0489d78defe262dc0934324f41199975ad42a86f37ac', - 'senderId': 'DDr7UTGQuPTjxLDWZ8RMjWJMKNXAMj3Bor' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '021e6d971e5885a3147ddf1e45bf5c8d0887ad9fc659e24bdf95c2c9607e7e3fe8', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_14', - 'publicKey': '021e6d971e5885a3147ddf1e45bf5c8d0887ad9fc659e24bdf95c2c9607e7e3fe8' - } - }, - 'signature': '3045022100898e59efe518745d3eb3f2b16f7b6192e3289bb4289d43013224549f2015aa4902204e7be92cbba37a05551151e46224da4e5d0ad86ee2106d3a9c0b9afee5f1c4cf', - 'id': '9559866ff439959529f69b0947ad2e72d739511ee1f6533c0bca2ebd6dd4ae4a', - 'senderId': 'DRXNNQ9gQXh6VNUVKaAn9xHAViyiHKtBHZ' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03d5b3efbe98631443c5cdf4de8a610dd2655b86427bf70aa209451b54256f6758', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_15', - 'publicKey': '03d5b3efbe98631443c5cdf4de8a610dd2655b86427bf70aa209451b54256f6758' - } - }, - 'signature': '3044022037fa085e37a582b2e0b3734d44b813bb18be939f73100c5b6f977d4f53ae708f022064ae54f6a1b17b193ab6b6d633f7b7a7b8171a158cdba7480afe380f383930dc', - 'id': '7bab92d5397a4ad291c5d01b8d681e480d19b437a7ab5cbd4c6807c96ef2716f', - 'senderId': 'DT12wf9erZyNJbBQrpbPDmfH3J8txiDgTE' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0297f2e8e609b2a6799214481e7573a043a197f8adf7b8bb306576fc3da83d2aaa', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_16', - 'publicKey': '0297f2e8e609b2a6799214481e7573a043a197f8adf7b8bb306576fc3da83d2aaa' - } - }, - 'signature': '304402202eee94bc3b53c64f8dee7790fe3eed8639da8faf0aa1f785e921cf139df0fb7e02200224efb0c07ae3972287c12a32143c1356adb93e00ac9e04a1358c8245a24cab', - 'id': '1e59740fa596b615231660974d0b656122b799a8b13102ade8c1b779aa5de7b5', - 'senderId': 'DKGYWPSqa4m4z6h3433rNFbWPDdvHj5wwd' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0361b914fd5823bf39ae467e95d99e9f6ddb7d85cc6df3055ce00274b8e4a976cc', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_17', - 'publicKey': '0361b914fd5823bf39ae467e95d99e9f6ddb7d85cc6df3055ce00274b8e4a976cc' - } - }, - 'signature': '3044022002ad92b9b9d81dabf96ac7d90034debc55eeeae879b3fe6ffc026bde86bb7ad902205c57d31c5e5e0099b504ba4c49e220a00ff325dceb64c46aefbb7a0ad8570099', - 'id': 'bf305776da902802923c19b9d2c7f1a809b0847992131cfa578d5e5518c924bf', - 'senderId': 'DJshaeFyHcFTjiGJnVPaDmFXhnJ9bp96i5' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03fa6bc09bd2ff348b304e0cfbc2d2ec50aa3b9aee0de6a66c13fcd8ee5ac891cd', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_18', - 'publicKey': '03fa6bc09bd2ff348b304e0cfbc2d2ec50aa3b9aee0de6a66c13fcd8ee5ac891cd' - } - }, - 'signature': '3045022100be50b19c17a9ff221aae20394a45d92ea47e8c1072b6d5a302937d2fc48cba8002205e9bcb3471a734c07ceff0083ad9ba1570507a29e5014e889ba42a85e797cb5e', - 'id': '44e48364b5b8cff3c68ae03de7dfde8d7ba6bcb99bf82b32fdc8bc3d0d9adeca', - 'senderId': 'DSuNttSb1UvCWg8iormfwPwi67EA84P5Mu' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03241957edca9ed28308e35cbf36762d22de706ebbd7c6a3a2d235d905d660c5c7', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_19', - 'publicKey': '03241957edca9ed28308e35cbf36762d22de706ebbd7c6a3a2d235d905d660c5c7' - } - }, - 'signature': '3045022100c11f8b863133535192e6c3fff20253a2695a2df74cdf1445d4ca0966803f708c0220200d4c2723d84f6334ba5d1cc1a0d45854867f4523fbcc9d09b3d53dd1972950', - 'id': '5cba288f9ffc1361ba8f7f19f28347ffd917f37df8cf46ba1e0816725f288528', - 'senderId': 'DCZt1ozEVvPdYVvkHmUKK6k7gnyNNQDpMq' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '035ae2364c838bc21edf4c04a99c85799f26fb02cc0740c5a1c67d4dc1748ff913', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_20', - 'publicKey': '035ae2364c838bc21edf4c04a99c85799f26fb02cc0740c5a1c67d4dc1748ff913' - } - }, - 'signature': '304402203066f06a1c165795d8a069499a8c0998913ec93e689219f14145754aa3e26e4e02206e9f88da16f1f8a8ebaf481eff798452487738714fe9b5694fec6a5ef8c152a5', - 'id': 'ada1696532f7faad1dda594bc6db7bfc029a1759402c924348b74222873a3a27', - 'senderId': 'D7JyqWMPKhhRNQcKTAvrPGBjEjjBcGgPca' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '023aff4a16c3876e885aea70e5bce9734ce5acc95a2c41c9783f5acd617f7c7533', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_21', - 'publicKey': '023aff4a16c3876e885aea70e5bce9734ce5acc95a2c41c9783f5acd617f7c7533' - } - }, - 'signature': '3045022100f5150c23596b9479c8b277401ab9e7da9b2275436f3927dabd70395e52c3ea7c02204e318d498b0176b5f05bb96418c49da3375a8d9b47b3b1e72a6f4db30b3f8c34', - 'id': 'e186a679f2e47300ec2f24c670192bcede1cb12f359cb8e827374b22f41fbe12', - 'senderId': 'D6itxYJr4n7ZZk2bd9cZbJE1xaDmpfkNFL' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0217d7ce9c3754f7fc7e5b4c64a1ff397dc75931cd6c92e32d8b42068ad50fe4eb', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_22', - 'publicKey': '0217d7ce9c3754f7fc7e5b4c64a1ff397dc75931cd6c92e32d8b42068ad50fe4eb' - } - }, - 'signature': '3045022100b84f69a7ff67ed147fc0a750c3b7b2ecabd582b6d0cb698c0bb4a531daa6ca46022039d2722e486e1674d0db422078d63fcdb90b21bed0dcc1265adff72d0c2bf8b9', - 'id': '86d9d146b62dbafe212aba5ec9764223b67f72c3c1aa93e54a270e3a528a8b20', - 'senderId': 'DDy4aKhF3cMadGhjFZnjaA1tx2rwnSEWcc' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '024019207f50dcb3e8aeb9ac1b00993d2bf131346e7e6d296429ea813a8373818e', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_23', - 'publicKey': '024019207f50dcb3e8aeb9ac1b00993d2bf131346e7e6d296429ea813a8373818e' - } - }, - 'signature': '3045022100aa83596b740639ee8947aa6d0f0ee123e4a5b87c39a4c6dd8a50304d4a7c97d102205fd45f85f5bdb076585a77888ef880bea52ade689731dff694d777de34913efc', - 'id': '6301b791844e02116df528b1ea46d788e91521189c3828ce224e45a1b72cda59', - 'senderId': 'D6BwyDJkNFkaDLedcJTE4rPUw5bRtb4K8f' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0275db912c21dca0f0213a76f4544137d7c741b47f281cfd4f8b7cb8187e7ce3cc', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_24', - 'publicKey': '0275db912c21dca0f0213a76f4544137d7c741b47f281cfd4f8b7cb8187e7ce3cc' - } - }, - 'signature': '3045022100c7eda0d9cd7ef522615643d1b985c73add2d3612344bdcc0117779fa4f4f54d302203e33fb5d185f5174e9cb7634a3d307b74d3bb56cc2354024ce69c74905a85203', - 'id': 'eee776fcb8024469eacab3e4b23c3d14185326431369aa84f17921abab8ad0ad', - 'senderId': 'DHQSmrRdfYAp9Y6CuebKnkoQNzuN7Pk2oQ' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0331c615ca4bc89d4eeb8d7a9cfbb5c0d4ce49d2f480afbce499b0c7f8c6a24f2f', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_25', - 'publicKey': '0331c615ca4bc89d4eeb8d7a9cfbb5c0d4ce49d2f480afbce499b0c7f8c6a24f2f' - } - }, - 'signature': '304402203e69be3a73c5917d89d58f3c0ae18febbbf364d3f9dfbec6b526a5294f9c435902201750bcf6368c181aabc53c73fd271a2967a6f215e1d0506eded5dd1800fea1c8', - 'id': 'ec3d17c6d38c0b9848c7cb57b968efd1f3872b1d1b8bcfb74bae2b0aaa15877c', - 'senderId': 'D6EVFQx5Z7M2X9DWXHtfX51CtVekuKPMQF' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0338ca9b719f8047580eed23b64a40aecad3803a12c0dde83e3ec2c2a9bfaa8147', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_26', - 'publicKey': '0338ca9b719f8047580eed23b64a40aecad3803a12c0dde83e3ec2c2a9bfaa8147' - } - }, - 'signature': '3045022100e0bf90949739012b641793da162b3daa88b34c8753ee31b26850729e9df579810220439a3f2f1b8e719767ee68df46f4bc1f18c8c3b2da4118edff22396616d319fb', - 'id': '14cd65c5f28f4cefc7c0157518a24f90c2260eb7166105b6b3358d91164ddf39', - 'senderId': 'DLCQ1jPsYbBCV7JfUJTasKbKoyGbK4a4HG' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03127001718bee76f14133272f0f4a928ffa8c2b38cafd94d7100253dac732c644', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_2', - 'publicKey': '03127001718bee76f14133272f0f4a928ffa8c2b38cafd94d7100253dac732c644' - } - }, - 'signature': '3044022003d2e76aca2848aedfe25415c11b9368dc72f687b66bef4527b40e2997b86b8c022076f7f82cbeb282d26535a2c1f0af0f02b48025d42c1bd56ac687fba1a3adb706', - 'id': '0daff3992b54b1384f52f751c933c727cbaaf4fac435eba88a1817a425753614', - 'senderId': 'D9rv3h61heDYHQ3b3Xk3V5epHSTTC6Vn1d' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0241734825ba45b6de29d6f26242c25ae1ef125b82615ee89a9fdd5b0f3c6b5132', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_28', - 'publicKey': '0241734825ba45b6de29d6f26242c25ae1ef125b82615ee89a9fdd5b0f3c6b5132' - } - }, - 'signature': '3045022100bb2903424bcd0a72da531470779144d60286191bea1b200c5617ae4f92229ba6022046a876e3e6cb85469a16f34d2f937e2eef787011c6a313ee50258f15116148ac', - 'id': 'bd17dbd23f8dbba2736688702ac185a87c88c43b24ee6d7764a5b4138b2f38b7', - 'senderId': 'DAcQPbKa8zBWwDHbxj37N13C61iseMDWM9' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03b9409203d7091e3f4d49168529b749e942ed18f21beddd236d57d692f09a8f86', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_29', - 'publicKey': '03b9409203d7091e3f4d49168529b749e942ed18f21beddd236d57d692f09a8f86' - } - }, - 'signature': '3044022016d7ecfa776930a6f83464548e7a686735fde752903539a38eb9da0ce2488bbd02203c5e23a4072c8de35a90b296145cce3156a31cc0d754b8a37d363fb088bc7387', - 'id': '16e02d3ef24dca4b03a1e489e20335224f18d888ed04f7e3512572f8e0cf92ae', - 'senderId': 'D5mmTaDAMSyPNKiDKrqwTFGWzWrZA3xaF8' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02c7b92a2d0027309e21855cf9c42a432b21ad13925e9dfc206f9c01e18fefa08a', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_30', - 'publicKey': '02c7b92a2d0027309e21855cf9c42a432b21ad13925e9dfc206f9c01e18fefa08a' - } - }, - 'signature': '30450221009de8828a7ad87cb5d52900e09d5beb680f9edc7640a3707d08a379511a7ba0f102202aa1d9294f9631f1325f252adb87c0d866e7398ce410037a42dc861d94308e15', - 'id': 'fece556bee4de2c7f1bb3099a05a84a33d0c963979fe1a222a899c13b7abb1fc', - 'senderId': 'DJ3NywAwQh4srbooLH1jTs9ma1hJE79v3z' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0221297804a26a93bb441a9d20a2916abf27fa7b29967678ef1a7a58062f73f40d', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_31', - 'publicKey': '0221297804a26a93bb441a9d20a2916abf27fa7b29967678ef1a7a58062f73f40d' - } - }, - 'signature': '3045022100b969611ef532557fa3da8a0325b2c88f3ebec954d64f158431d86b8e07929ea50220520affdcd0728cb7c5f63a58a1200d44133e90b1f7a6a9e28744ad6b0dcc2a75', - 'id': 'ee086317ea2fdc522f5eb502a0db9f3d4955b2318559e40a1f22a3f5f8d6344b', - 'senderId': 'D5P7eti7FUY4Tk5KXoxdf2tDAVQrRVCESA' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '027f504f6f20648e3bf171952629c7b868a2f799aa4b60f8eb3fe96afff16bbef0', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_32', - 'publicKey': '027f504f6f20648e3bf171952629c7b868a2f799aa4b60f8eb3fe96afff16bbef0' - } - }, - 'signature': '3044022006be7cbaa74089cabe47d02621f756762587d210a3f211ee941b5fcd0650908f02207d4040408bd25a2de03e5724362735ee8ad36c099b0c16efd4716e1dd7ec62ae', - 'id': '764dd21aa4d0e2e0fa17bb2ff5e7ca304995d9e3593542badecc8ed24d5ea3ea', - 'senderId': 'D9q26yBTrEYuxHg7bbfZphv6129KvLu4v2' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '031954315b84db8f49ab7ee21357270450bb68d06b34472e5e93ddfa5710edc0c9', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_33', - 'publicKey': '031954315b84db8f49ab7ee21357270450bb68d06b34472e5e93ddfa5710edc0c9' - } - }, - 'signature': '3045022100859f93df994d86995fdf834bfe86b41eebaa04e5ab7d09f0b37acb50d313cd9802203c8993b793602c96d305fa795a9f2459f4706b340993584f3c56579392c0995c', - 'id': 'efd9e7c638afe62bec9be61783193ea52eea7b335053bd5af6c758d5b0e5847c', - 'senderId': 'D9iPFb5kAVnuDdomehRP9LncJj5ng2vrsr' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0267b310eac2bb0d6594de382a1ab74ac75b91e9d64a590b6249247b10fd9be829', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_34', - 'publicKey': '0267b310eac2bb0d6594de382a1ab74ac75b91e9d64a590b6249247b10fd9be829' - } - }, - 'signature': '3045022100a678978ab899e3903e760ee98640e3f658792a096a8d771c575944af6536cfdb0220428c312f1e0eb4be73ce4b256a754447570176200cfb6c09b3eb55f66526dd80', - 'id': '70edcce5df67a250b6ba3567879bae6379ce4c688597fcedfbfd0313da6998e8', - 'senderId': 'D6xZmtyBzZKCEkK29JNPAD581TJ8XXrXYn' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '028f32320c66a89779756b04946d2aa256dff6cd547349d46e1938710063e387c4', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_35', - 'publicKey': '028f32320c66a89779756b04946d2aa256dff6cd547349d46e1938710063e387c4' - } - }, - 'signature': '304402206bc95876897527b39eacf4c961f9c036a9c8a0e53a17ce925c592d079fa643030220096e115d7fbd54aca4af7f621d64178dfcf2c13361106a3e3b5025dca97b44ee', - 'id': '7f23f44157f3a677e81514fa431227410a27442e5fd1f2491b177c0f580f296d', - 'senderId': 'D9dW4eXJjABDQXSQB9GtvY5UBuRWWWejWb' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0218b889a24988527ab3948d80f97cfc37b923082e1f0398bc162190fd66ec4dee', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_36', - 'publicKey': '0218b889a24988527ab3948d80f97cfc37b923082e1f0398bc162190fd66ec4dee' - } - }, - 'signature': '3045022100c40a3f4cf15f9274e2b25ca8608cb965316aa0f00fa77817b79620ad8ccbdd5902206203a1043b03ba58aa9b7399694f8215cf45d30eb0caa748cc06f1a85a8faea9', - 'id': 'a65244ed17a9280aa694abdf6804b1a0b78dfc052b4845abcd3c89380159b29e', - 'senderId': 'DFHK7SdmPdjxNZ9uweqLZAv6v5GQ1NnBNe' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '035392ee88c60617764b4fe89ae2cc96560dfa5f992b03be31ce5680db9b863f73', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_37', - 'publicKey': '035392ee88c60617764b4fe89ae2cc96560dfa5f992b03be31ce5680db9b863f73' - } - }, - 'signature': '3044022036200c3191f8f01b77676644b9b94728b5afb2ab2de8c5c7c5582e795465661c02207848f1f2f0ab378d8906fd45aa048f354d5dbac4cb87c15973ffa86fe84ff0cd', - 'id': '219e0942afe5f65c548ec2118a1c49febb7ec03fca4334ac16649062db9d146b', - 'senderId': 'DSh7AAC9KahXU2JZ539HAqEa5sHafxsxDQ' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03e75127d1deccf65844a1761bd26611b6c65c5b51a52eba27e3ee20a539fd63f1', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_38', - 'publicKey': '03e75127d1deccf65844a1761bd26611b6c65c5b51a52eba27e3ee20a539fd63f1' - } - }, - 'signature': '304402201a2990b2baae72f5cc8f2d1890f328e4082af0cf2a787d8f05208c3424ce089d0220790dbc7606dd6c03568fd0a771e9e8e89557257238ae90cfcb3bb8f3b475987b', - 'id': 'ee9ad2a66e9b2009a9fc671f80d0493803fc422161140169c7bc1fd401cd9ad6', - 'senderId': 'D85WuxGZrFs1QUYTvnRpmc6dd8rmBbpnaX' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0329fc1580906307ac9f2f55cec66e47983f8287d542408fb19f473a305d3638d8', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_39', - 'publicKey': '0329fc1580906307ac9f2f55cec66e47983f8287d542408fb19f473a305d3638d8' - } - }, - 'signature': '30450221008f66e89ec4c7af4b77e5b7ff36c542cc02672c8df70806b5a0fab7a7e8c7067502200d99ba19ceb1b471c39c4e95107ad6f8b978a623a790080b16f863347fe06b4f', - 'id': 'dd3077ed04a76343d340074270ce9826354802bd99e08cb864c1c5ad09f367df', - 'senderId': 'D85kwsBJKZ4pw5uQpc81eRj95f6a536AP6' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '035ec848e9388877dac88f121d19c8f5e870ac90d8ccb0116be9f734e4bd1a9405', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_40', - 'publicKey': '035ec848e9388877dac88f121d19c8f5e870ac90d8ccb0116be9f734e4bd1a9405' - } - }, - 'signature': '304402202b220d6c028bc23213edddaf303f18eef059551891aadbf7a4b4d7d3287457bb0220245678354bb8960b42ba2f2ceb12f926e82ff0d027b44988d799c8c0d8d7d9f2', - 'id': '3afc6ea52b8edc7df0230ceac71baf45460f3bd761c5e75fe796bc7415063220', - 'senderId': 'DGBJdDadBwJD2xY8VsdAykdd6vPakMMUt6' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0356f5885306e45402aeb354a74d13c104699b3b53da46a5e922e4a6d6132a67e8', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_41', - 'publicKey': '0356f5885306e45402aeb354a74d13c104699b3b53da46a5e922e4a6d6132a67e8' - } - }, - 'signature': '3045022100f18bf2e013f2d9dcac013a76037d787f79baaa65f4f31ffe2b4ed8de249bdc8902202abcf77e809599d3e3a96225363c8e760ed4b4e20f97645547b381dba830c3da', - 'id': 'aea1fc173a2f4a9233b0fe59a5f6804167bee5658cb3e4e19dfe2be20f5772cd', - 'senderId': 'DG4VbapL3H39NJLB3DqQEefU47EMVqtxVw' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03ff8ab980434516ca28c982d0ecc8fc3107116d6c8b3e09c7ee5033f32adbd2ff', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_42', - 'publicKey': '03ff8ab980434516ca28c982d0ecc8fc3107116d6c8b3e09c7ee5033f32adbd2ff' - } - }, - 'signature': '3045022100e938d9901afeaa5a56d18abd9292ace93be03c84c09a6c4cb58fca96dfb54bc502201e921d27f9886d189f803b14d93655a42c4e095d49ee61051a4e70c7a173f3f1', - 'id': 'f18426d3ef81d4b7bf0337d70afcecddbd6db2206a2f139f1ca5823c381c7817', - 'senderId': 'DC3oNWedP48ypGxAeKbFC7gMjWxcNc2JhL' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0393f1590771a8ad1cf2baa086858f3029c4444cb82243917a7011f1f66cf8fd05', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_43', - 'publicKey': '0393f1590771a8ad1cf2baa086858f3029c4444cb82243917a7011f1f66cf8fd05' - } - }, - 'signature': '304502210095745c36a8af07e21546bd064f1ed1bd90e6c2a8db9c0c8e4853d0a8255443db0220259d2ce3677abb42f08b9d22aa13bbe383fd882ed38911b738ebaefc04589694', - 'id': '6c51bea35b5e3270dcf7b7dfae8d984e19f476ea7e0435f157c4e0d22b7e7ea1', - 'senderId': 'DJm2sfcUKhyxakowY9TjyAytkdq7JrFgVj' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0234e24ff1dbc447c804eb385cd05bbd1dc59ef03b44a3346b13e7cccf00b61075', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_44', - 'publicKey': '0234e24ff1dbc447c804eb385cd05bbd1dc59ef03b44a3346b13e7cccf00b61075' - } - }, - 'signature': '3045022100ee1e8df480f2be042386d383d776b3fd6bd2d3f5a9035071153f23dbfdceeaae02203a0834aae4834da3ca7858779d474b9255ead754867d5b4a18873e9ecaa5045e', - 'id': '66fb3e36233f4577ba585ccd7daf83e62d8df262d3d832b806479ac67c1ef35d', - 'senderId': 'D5oS8xfNebiPsjpwPWoZS6sA9qcYjTGT5h' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03a5789a4486f20f1fdca78a52b528b3bf9952e7c057de71a22adcfb444ba4c5d3', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_45', - 'publicKey': '03a5789a4486f20f1fdca78a52b528b3bf9952e7c057de71a22adcfb444ba4c5d3' - } - }, - 'signature': '3045022100cb037530bcff9a4d19899431648747022c28aa3239563379d96692bd525eb38902205f3cabb8dd470d9eb3d425e333ad1bc9f0643d489c600a811748fb5f4a203f7f', - 'id': '5df9c5e350136571af4b86697bc9d4cfca3ff8b669e254b36f00be1dbde063f7', - 'senderId': 'D5SzHHdPdGqYUkH7BGNkmGHEUqfZrWb17r' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0347f692345fa7bf90e944eb55246da5f9f595d3f5a20ad50aeb6f9b973aaae17e', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_46', - 'publicKey': '0347f692345fa7bf90e944eb55246da5f9f595d3f5a20ad50aeb6f9b973aaae17e' - } - }, - 'signature': '3045022100c377efe5ffab58017473699cd7c839dcf48fa5b20b5ddf9bdc4801e22a579b2b02204d35c1a1416069544e3ec01d2ce21bb409f9f2fa4adedc8c03d6417c034a3fec', - 'id': 'da4cfad78e37d56421dd6676e5618a507340ef1e496831d1968c509e35ef9202', - 'senderId': 'DCLdibuZB6UsJP8KmdzcDLWzizrDtJQuxt' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '028a32b441377a69aa76e867026f3109b2f0aef8651fe91e2a4ab01eff102a6b98', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_47', - 'publicKey': '028a32b441377a69aa76e867026f3109b2f0aef8651fe91e2a4ab01eff102a6b98' - } - }, - 'signature': '3045022100e098672958be15989bb125d9018adb4a54e95ab664e64a673997e617e28b39df02206e8459997074d5976b77f90eb9d7180e9d4a0e0efdf433958ffeb2f04d9de382', - 'id': '85bafcd07e7ba47ec95cb5b5a6759d4f9f87e036bb7660c7717504e845ef975e', - 'senderId': 'DSkivgRyimdAVqmm2ZAKwKmKN39WEbbPnL' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '0223ac52179903e79865b9a98cf0b52ddc1ab46180c157e8f6bd1e63e7f14fcf31', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_48', - 'publicKey': '0223ac52179903e79865b9a98cf0b52ddc1ab46180c157e8f6bd1e63e7f14fcf31' - } - }, - 'signature': '304402200a005716f67d6cd3963a3c752c95f1bca01aa127c91ab1a632eb3022d11e3e67022024c4746078e440da441bcb366ee8999ffd2419e9a6f9cbf971d696d5b7f8733b', - 'id': '0df1ed07d3f95ddf0385bad83a17b3a8fde6bd6532cd3479e48668064672b34f', - 'senderId': 'DDgKyKqdA6SuamB1eW77WvFu6RQFMZoU36' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '039de0390f28c7731d86ae7006a31888f12856cde3cc3c2619d4d4a42b6dfd6c51', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_49', - 'publicKey': '039de0390f28c7731d86ae7006a31888f12856cde3cc3c2619d4d4a42b6dfd6c51' - } - }, - 'signature': '3045022100efa5d51ca79992be4a87af049b3e9ec1b796576e4d937ea9e3760ab0bdcd301e022027e22a6c3395df155bd399643c241e4cc317eaead1f273fd7a709339dfa9dc99', - 'id': '436bebc107fad38e944fd14785e09f0600df4d75d31cf3eac53f850462d0be74', - 'senderId': 'DKCaoaXApw1xE7K1BJcVkr1KGzjKmFWyTk' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02b87b0e70a7ae10613390f405620e24c495ba2b0cfcdbc67688e9b483dea564ee', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_50', - 'publicKey': '02b87b0e70a7ae10613390f405620e24c495ba2b0cfcdbc67688e9b483dea564ee' - } - }, - 'signature': '304502210096cdd35f803a37730ac73a97a23061dceac96319c67bfb1ddcfbac737febe96102202fa0b279f697da3afc043ffd3ecc838789be07ff119b5527a5c13468cecf66e9', - 'id': 'bb65f9dbe6272fd07a555fc86762d6a487f538b972f2926ff7698cdc906a32df', - 'senderId': 'DJQXFKEguZVabsAs46JbXXnQJ5jFhUtN9m' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '03c9f8f4001216603c152b4b4429c2ead322ac34672999e808d567a7d1140e46be', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_51', - 'publicKey': '03c9f8f4001216603c152b4b4429c2ead322ac34672999e808d567a7d1140e46be' - } - }, - 'signature': '3045022100ee961089d02d7bb68fe2257f6a972eeaf6e2c1a1ad2f491c417e161fedbb556b02204c834644e5b5cde9a0b3f92fa23bade7670efab0a067597f6c151ee633932706', - 'id': 'cef44df9684f05dab67c0568a2c5295bb50cbb3c88f5cfbe672365bda274620f', - 'senderId': 'DKpt7cm2tZk4RPLyQ5ugwEH7gkriRaA7ov' - }, { - 'type': 2, - 'amount': 0, - 'fee': 0, - 'recipientId': null, - 'senderPublicKey': '02cf70f73328d490cfb03ee822d3fc0cf9259d67c0564e843491e739501809d657', - 'timestamp': 0, - 'asset': { - 'delegate': { - 'username': 'genesis_27', - 'publicKey': '02cf70f73328d490cfb03ee822d3fc0cf9259d67c0564e843491e739501809d657' - } - }, - 'signature': '30440220645b912b60f829c0bce58bfe9890ef9253418b6898416aaead663bdf158a99f2022061abbbabd454ec7f7e3f4b502216eec28110e945a4b9b913b1fc0b9758e7e6e4', - 'id': '09408dbcf3e3e0835bf92a05330c023a7d6471f3825301a34efa094e0fd4fc30', - 'senderId': 'DQfjSqDuKr5YZaLAF8rWpFMqMYwEbPtGKg' - }], - 'height': 1, - 'id': '13149578060728881902', - 'blockSignature': '3045022100a6605198e0f590c88798405bc76748d84e280d179bcefed2c993e70cded2a5dd022008c7f915b89fc4f3250fc4b481abb753c68f30ac351871c50bd6cfaf151370e8' -}) diff --git a/packages/core-p2p/__tests__/__fixtures__/genesisTransaction.js b/packages/core-p2p/__tests__/__fixtures__/genesisTransaction.js deleted file mode 100644 index 57c26b03e7..0000000000 --- a/packages/core-p2p/__tests__/__fixtures__/genesisTransaction.js +++ /dev/null @@ -1,16 +0,0 @@ -const { Transaction } = require('@arkecosystem/crypto').models - -module.exports = new Transaction({ - id: 'd766f3161566df6e9303fc537c70f08649499b52847b7294526e0cd915d7d890', - blockid: '11761354193382453590', - type: 0, - timestamp: 35811986, - amount: 30990000000, - fee: 10000000, - senderId: 'DHFZisf6kosVsZec3UKyFj2mMdz2HxMjMK', - recipientId: 'DQ4GxpAfYT7fR2mPk8CqSE9as3CPDtFLF8', - senderPublicKey: '03982fac21d5f53a5b2740d46983676ad1702c597019b58b9ca9710b6f96fead0a', - signature: '3044022036405925de530cd83899984905aad3acfc322433e6c632e782c19381e80e0325022064af6f1c5d403d184858c1c6292704445cc284394b26be05a653346313ae1019', - asset: {}, - confirmations: 4179 -}) diff --git a/packages/core-p2p/__tests__/__support__/config/delegates.json b/packages/core-p2p/__tests__/__support__/config/delegates.json deleted file mode 100644 index c615b110c3..0000000000 --- a/packages/core-p2p/__tests__/__support__/config/delegates.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "secrets": ["this is a test"] -} diff --git a/packages/core-p2p/__tests__/__support__/config/genesisBlock.json b/packages/core-p2p/__tests__/__support__/config/genesisBlock.json deleted file mode 100644 index bc42a7e15c..0000000000 --- a/packages/core-p2p/__tests__/__support__/config/genesisBlock.json +++ /dev/null @@ -1,843 +0,0 @@ -{ - "version": 0, - "totalAmount": 12500000000000000, - "totalFee": 0, - "reward": 0, - "payloadHash": "578e820911f24e039733b45e4882b73e301f813a0d2c31330dafda84534ffa23", - "timestamp": 0, - "numberOfTransactions": 52, - "payloadLength": 11401, - "previousBlock": null, - "generatorPublicKey": "024c8247388a02ecd1de2a3e3fd5b7c61ecc2797fa3776599d558333ef1802d231", - "transactions": [{ - "type": 0, - "amount": 12500000000000000, - "fee": 0, - "recipientId": "DGihocTkwDygiFvmg6aG8jThYTic47GzU9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "03cb7bca143376721d0e9e3f3ccb0dc2e7e8470c06e630c3cef73f03e309b558ad", - "signature": "3044022016ecdf3039e69514c7d75861b22fc076496b61c07a1fcf793dc4f5c76fa0532b0220579c4c0c9d13720f9db5d9df29ed8ceab0adc266c6c160d612d4894dc5867eb1", - "id": "e40ce11cab82736da1cc91191716f3c1f446ca7b6a9f4f93b7120ef105ba06e8", - "senderId": "DUFeXjJmYt1mWY3auywA1EQSqfCv5kYYfP" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03e5b39a83e6c7c952c5908089d4524bb8dda93acc2b2b953247e43dc4fe9aa3d1", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_1", - "publicKey": "03e5b39a83e6c7c952c5908089d4524bb8dda93acc2b2b953247e43dc4fe9aa3d1" - } - }, - "signature": "3045022100e3e38811778023e6f17fefd447f179d45ab92c398c7cfb1e34e2f6e1b167c95a022070c36439ecec0fc3c43850070f29515910435d389e059579878d61b5ff2ea337", - "id": "eb0146ac79afc228f0474a5ae1c4771970ae7880450b998c401029f522cd8a21", - "senderId": "DNL81CT6WNG1PHjobBmLvKwLV3UUscBymB" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "031137050d5fed0b5229b150257da2ac9c135efdf4bcb382b0ad0c197d7be458f4", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_3", - "publicKey": "031137050d5fed0b5229b150257da2ac9c135efdf4bcb382b0ad0c197d7be458f4" - } - }, - "signature": "30440220124baaa04491287d0abbf5a167c9b0f5ac95c22b196f42ff3d275cc9a213c2fd02206e6ebada85f67063e642dbcde6b956f8c99c05f4b9c55f1551d3eebba6375043", - "id": "c9c554056b3428951633a7059dd64dfcbd776fef7f4a156ea362b37ee6ce74c7", - "senderId": "DG9LYv5rqX67wuGvGVa9is5k1r86LKCVTA" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "037def83d085778d7767a182a179f345207953441089081f5bc13f86d3891308aa", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_4", - "publicKey": "037def83d085778d7767a182a179f345207953441089081f5bc13f86d3891308aa" - } - }, - "signature": "3045022100900cea3c2df393414899c9d74db57d89c9f311c70d08b974d0fd4a98bfae2fc902204a2aa51a1ec71da27c26afc033de6bd2d15978813c120c95e1a4dafca75ce876", - "id": "c82ccaa16be0e3c7ff4a53e2807968b71a0d88115223c3af2eb320f32449ac32", - "senderId": "DMSwarrHg5N9ZAZ6nsqPuUjyAU6gdRAM9d" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "033f28ad2e9b897d46f1e67c7c52070e9ca46b04c0679ebb21fb236719e38aade3", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_5", - "publicKey": "033f28ad2e9b897d46f1e67c7c52070e9ca46b04c0679ebb21fb236719e38aade3" - } - }, - "signature": "30440220285188d8900cd3cffccf5e1de305b18856451dd04d2ed21165dffe9a7ce4afc1022009457be6bfe536971697105d47ad1f829738a5cacdb27a23c5d1e8a8dddf3ebd", - "id": "ee6a19fff622ab4e6e96d159396de56d6034b4b18a9cf5c99efcf4e61b28e15a", - "senderId": "DFcYHfCwhGWcBNy6cp48wy5SfXbQmfBYgT" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "023e577a7b3362e0aba70e6911d230e86d729b4cb640f0e0b25637b812a3e38b53", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_6", - "publicKey": "023e577a7b3362e0aba70e6911d230e86d729b4cb640f0e0b25637b812a3e38b53" - } - }, - "signature": "3045022100afa56542dd473c424b36d4d9f24da68180cfd90527681ab84098f415b2544a8702201e8ebdd619a2dd200e37a57c39a4529afe76d35f6089c00f6dffba6bf7b8a836", - "id": "0dcd6e380bd7eaef8724f64f4b86104ce7497308dacf775afbe6ec0d401007fe", - "senderId": "D5e2FzTPqdEHridjzpFZCCVyepAu6Vpmk4" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02af5e6341efc14f4ba39a9ff65e151cc7304fc742ce7b2678d9aa446c555ee9c1", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_7", - "publicKey": "02af5e6341efc14f4ba39a9ff65e151cc7304fc742ce7b2678d9aa446c555ee9c1" - } - }, - "signature": "3045022100c8980155c8f8964d76baf3e8d690075708f1a84757c1de52e311772466382da2022012599acfc7839fa1ef6bbd445ab34555fb718491db3089f40d4842b1bc2d3178", - "id": "8af6abb117c69c130e388970d595b741374b1bbca709d9e91459e9e3c721397b", - "senderId": "DDLbnve6XK48cGsQiFhesUJQRQdKkZTfPh" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02845161cfca4d6ddde8e0d53538b6f881fb3ad9383cd77cebc55375dd6fd17663", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_8", - "publicKey": "02845161cfca4d6ddde8e0d53538b6f881fb3ad9383cd77cebc55375dd6fd17663" - } - }, - "signature": "30450221009bce7c5c10a4b6306cebe5724adfd3de049a425c44dd314a10154774764c11090220070fb775e71dda6a68f7fc9e0c762fbf96021908911f0de0ca8e9b0c613cb896", - "id": "bd346035d4516b85fb3a2cce6260fdcc6f1c434999e586978e065de3bf98e02a", - "senderId": "DDAHPjVTTV3uur653TB27fcLGh7XXWnvxW" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03f264a6d2ebb62279313a6fd7fec4e2244785839b625a0b0c261e689ce5401d87", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_9", - "publicKey": "03f264a6d2ebb62279313a6fd7fec4e2244785839b625a0b0c261e689ce5401d87" - } - }, - "signature": "30450221009f74425c2ec50dbee462e735dee3e7917c8433fd5250ff09af4506c38d2df05902206a14a19b9a5defe3c8c59c77d52c182ea34d81d2e0b05dc5925133f2829a1960", - "id": "b48068fb7c848ffd57e82a4d381f53bb69916f3943e0e8935971a028ba245564", - "senderId": "DFHdEBuVCz5zfj8yeo3BmKEdsEKpMaYRRw" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03efd265a086c2a099cda4f4fd202adbac07567e1229ce5e6fe39963b714c1e2d5", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_10", - "publicKey": "03efd265a086c2a099cda4f4fd202adbac07567e1229ce5e6fe39963b714c1e2d5" - } - }, - "signature": "3044022004df492965ed328134aa6443d38ac4dd951a640e00330da9aa4e80c1577af41a0220588f030f5f9584959647898bb977a1ffe6bba639b1c64a728880f2cd3fd7aa3c", - "id": "73b3b4375e39aabe51ec205559cd728a18c987dabaa0599c611b3076c38c7a49", - "senderId": "DL7Y6smfHHs3Ms3hAYmSYYd5PZukmtDY1i" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "027d616d20f03c375067676c79ff9787e8e42991fbd9e878501d704d23d246d9b0", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_11", - "publicKey": "027d616d20f03c375067676c79ff9787e8e42991fbd9e878501d704d23d246d9b0" - } - }, - "signature": "3044022051c2f8af62163ca621eeb3087a35bfaca0d679f7be8b19a25972f5a4b24ad8c90220422f3e0e480bf1bf2211e871a102edc15a957c0f97a553d9d707418e6538df26", - "id": "80f1d01158452da31d44f0c24f464a0ade37da51d2f61356ad75a019a91a1ff5", - "senderId": "DBVoRSXBHBPPvssBXrswv22r4dUSpN1fbA" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "038918951152a37b74dfe61115f83e4b5e3521145065650c4a6d3e94add57d9a9b", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_12", - "publicKey": "038918951152a37b74dfe61115f83e4b5e3521145065650c4a6d3e94add57d9a9b" - } - }, - "signature": "3045022100facf6ed992c28d41595419666b006800fcb33c6bad4b522e013b4d688e51dc8502207695e968059f7a35486389c430d6a3037e69d3e5f1d4f0a294d8818e4750cf0d", - "id": "86d76b0aad8f496d8c20926bfdeb50ad10db242ea6152b68266680c48e1e1aca", - "senderId": "DHsSK81gRWjgNx1A9gtHgkRsEwshsog7AM" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03231d8f2f39925fa79efc8f8561e6a8d29b95164a753cbb604a46e8a2e96606fc", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_13", - "publicKey": "03231d8f2f39925fa79efc8f8561e6a8d29b95164a753cbb604a46e8a2e96606fc" - } - }, - "signature": "304402204c627ec3d24fb7b4f86709c0566cee9909ebddb26039e87a2fa673f1f7227362022003be5aa3303b8f4cdab768f80b4699440a61814950cab0fd983526771c4c52ec", - "id": "464614909ac7531a016a0489d78defe262dc0934324f41199975ad42a86f37ac", - "senderId": "DDr7UTGQuPTjxLDWZ8RMjWJMKNXAMj3Bor" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "021e6d971e5885a3147ddf1e45bf5c8d0887ad9fc659e24bdf95c2c9607e7e3fe8", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_14", - "publicKey": "021e6d971e5885a3147ddf1e45bf5c8d0887ad9fc659e24bdf95c2c9607e7e3fe8" - } - }, - "signature": "3045022100898e59efe518745d3eb3f2b16f7b6192e3289bb4289d43013224549f2015aa4902204e7be92cbba37a05551151e46224da4e5d0ad86ee2106d3a9c0b9afee5f1c4cf", - "id": "9559866ff439959529f69b0947ad2e72d739511ee1f6533c0bca2ebd6dd4ae4a", - "senderId": "DRXNNQ9gQXh6VNUVKaAn9xHAViyiHKtBHZ" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03d5b3efbe98631443c5cdf4de8a610dd2655b86427bf70aa209451b54256f6758", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_15", - "publicKey": "03d5b3efbe98631443c5cdf4de8a610dd2655b86427bf70aa209451b54256f6758" - } - }, - "signature": "3044022037fa085e37a582b2e0b3734d44b813bb18be939f73100c5b6f977d4f53ae708f022064ae54f6a1b17b193ab6b6d633f7b7a7b8171a158cdba7480afe380f383930dc", - "id": "7bab92d5397a4ad291c5d01b8d681e480d19b437a7ab5cbd4c6807c96ef2716f", - "senderId": "DT12wf9erZyNJbBQrpbPDmfH3J8txiDgTE" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0297f2e8e609b2a6799214481e7573a043a197f8adf7b8bb306576fc3da83d2aaa", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_16", - "publicKey": "0297f2e8e609b2a6799214481e7573a043a197f8adf7b8bb306576fc3da83d2aaa" - } - }, - "signature": "304402202eee94bc3b53c64f8dee7790fe3eed8639da8faf0aa1f785e921cf139df0fb7e02200224efb0c07ae3972287c12a32143c1356adb93e00ac9e04a1358c8245a24cab", - "id": "1e59740fa596b615231660974d0b656122b799a8b13102ade8c1b779aa5de7b5", - "senderId": "DKGYWPSqa4m4z6h3433rNFbWPDdvHj5wwd" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0361b914fd5823bf39ae467e95d99e9f6ddb7d85cc6df3055ce00274b8e4a976cc", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_17", - "publicKey": "0361b914fd5823bf39ae467e95d99e9f6ddb7d85cc6df3055ce00274b8e4a976cc" - } - }, - "signature": "3044022002ad92b9b9d81dabf96ac7d90034debc55eeeae879b3fe6ffc026bde86bb7ad902205c57d31c5e5e0099b504ba4c49e220a00ff325dceb64c46aefbb7a0ad8570099", - "id": "bf305776da902802923c19b9d2c7f1a809b0847992131cfa578d5e5518c924bf", - "senderId": "DJshaeFyHcFTjiGJnVPaDmFXhnJ9bp96i5" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03fa6bc09bd2ff348b304e0cfbc2d2ec50aa3b9aee0de6a66c13fcd8ee5ac891cd", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_18", - "publicKey": "03fa6bc09bd2ff348b304e0cfbc2d2ec50aa3b9aee0de6a66c13fcd8ee5ac891cd" - } - }, - "signature": "3045022100be50b19c17a9ff221aae20394a45d92ea47e8c1072b6d5a302937d2fc48cba8002205e9bcb3471a734c07ceff0083ad9ba1570507a29e5014e889ba42a85e797cb5e", - "id": "44e48364b5b8cff3c68ae03de7dfde8d7ba6bcb99bf82b32fdc8bc3d0d9adeca", - "senderId": "DSuNttSb1UvCWg8iormfwPwi67EA84P5Mu" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03241957edca9ed28308e35cbf36762d22de706ebbd7c6a3a2d235d905d660c5c7", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_19", - "publicKey": "03241957edca9ed28308e35cbf36762d22de706ebbd7c6a3a2d235d905d660c5c7" - } - }, - "signature": "3045022100c11f8b863133535192e6c3fff20253a2695a2df74cdf1445d4ca0966803f708c0220200d4c2723d84f6334ba5d1cc1a0d45854867f4523fbcc9d09b3d53dd1972950", - "id": "5cba288f9ffc1361ba8f7f19f28347ffd917f37df8cf46ba1e0816725f288528", - "senderId": "DCZt1ozEVvPdYVvkHmUKK6k7gnyNNQDpMq" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "035ae2364c838bc21edf4c04a99c85799f26fb02cc0740c5a1c67d4dc1748ff913", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_20", - "publicKey": "035ae2364c838bc21edf4c04a99c85799f26fb02cc0740c5a1c67d4dc1748ff913" - } - }, - "signature": "304402203066f06a1c165795d8a069499a8c0998913ec93e689219f14145754aa3e26e4e02206e9f88da16f1f8a8ebaf481eff798452487738714fe9b5694fec6a5ef8c152a5", - "id": "ada1696532f7faad1dda594bc6db7bfc029a1759402c924348b74222873a3a27", - "senderId": "D7JyqWMPKhhRNQcKTAvrPGBjEjjBcGgPca" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "023aff4a16c3876e885aea70e5bce9734ce5acc95a2c41c9783f5acd617f7c7533", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_21", - "publicKey": "023aff4a16c3876e885aea70e5bce9734ce5acc95a2c41c9783f5acd617f7c7533" - } - }, - "signature": "3045022100f5150c23596b9479c8b277401ab9e7da9b2275436f3927dabd70395e52c3ea7c02204e318d498b0176b5f05bb96418c49da3375a8d9b47b3b1e72a6f4db30b3f8c34", - "id": "e186a679f2e47300ec2f24c670192bcede1cb12f359cb8e827374b22f41fbe12", - "senderId": "D6itxYJr4n7ZZk2bd9cZbJE1xaDmpfkNFL" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0217d7ce9c3754f7fc7e5b4c64a1ff397dc75931cd6c92e32d8b42068ad50fe4eb", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_22", - "publicKey": "0217d7ce9c3754f7fc7e5b4c64a1ff397dc75931cd6c92e32d8b42068ad50fe4eb" - } - }, - "signature": "3045022100b84f69a7ff67ed147fc0a750c3b7b2ecabd582b6d0cb698c0bb4a531daa6ca46022039d2722e486e1674d0db422078d63fcdb90b21bed0dcc1265adff72d0c2bf8b9", - "id": "86d9d146b62dbafe212aba5ec9764223b67f72c3c1aa93e54a270e3a528a8b20", - "senderId": "DDy4aKhF3cMadGhjFZnjaA1tx2rwnSEWcc" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "024019207f50dcb3e8aeb9ac1b00993d2bf131346e7e6d296429ea813a8373818e", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_23", - "publicKey": "024019207f50dcb3e8aeb9ac1b00993d2bf131346e7e6d296429ea813a8373818e" - } - }, - "signature": "3045022100aa83596b740639ee8947aa6d0f0ee123e4a5b87c39a4c6dd8a50304d4a7c97d102205fd45f85f5bdb076585a77888ef880bea52ade689731dff694d777de34913efc", - "id": "6301b791844e02116df528b1ea46d788e91521189c3828ce224e45a1b72cda59", - "senderId": "D6BwyDJkNFkaDLedcJTE4rPUw5bRtb4K8f" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0275db912c21dca0f0213a76f4544137d7c741b47f281cfd4f8b7cb8187e7ce3cc", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_24", - "publicKey": "0275db912c21dca0f0213a76f4544137d7c741b47f281cfd4f8b7cb8187e7ce3cc" - } - }, - "signature": "3045022100c7eda0d9cd7ef522615643d1b985c73add2d3612344bdcc0117779fa4f4f54d302203e33fb5d185f5174e9cb7634a3d307b74d3bb56cc2354024ce69c74905a85203", - "id": "eee776fcb8024469eacab3e4b23c3d14185326431369aa84f17921abab8ad0ad", - "senderId": "DHQSmrRdfYAp9Y6CuebKnkoQNzuN7Pk2oQ" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0331c615ca4bc89d4eeb8d7a9cfbb5c0d4ce49d2f480afbce499b0c7f8c6a24f2f", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_25", - "publicKey": "0331c615ca4bc89d4eeb8d7a9cfbb5c0d4ce49d2f480afbce499b0c7f8c6a24f2f" - } - }, - "signature": "304402203e69be3a73c5917d89d58f3c0ae18febbbf364d3f9dfbec6b526a5294f9c435902201750bcf6368c181aabc53c73fd271a2967a6f215e1d0506eded5dd1800fea1c8", - "id": "ec3d17c6d38c0b9848c7cb57b968efd1f3872b1d1b8bcfb74bae2b0aaa15877c", - "senderId": "D6EVFQx5Z7M2X9DWXHtfX51CtVekuKPMQF" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0338ca9b719f8047580eed23b64a40aecad3803a12c0dde83e3ec2c2a9bfaa8147", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_26", - "publicKey": "0338ca9b719f8047580eed23b64a40aecad3803a12c0dde83e3ec2c2a9bfaa8147" - } - }, - "signature": "3045022100e0bf90949739012b641793da162b3daa88b34c8753ee31b26850729e9df579810220439a3f2f1b8e719767ee68df46f4bc1f18c8c3b2da4118edff22396616d319fb", - "id": "14cd65c5f28f4cefc7c0157518a24f90c2260eb7166105b6b3358d91164ddf39", - "senderId": "DLCQ1jPsYbBCV7JfUJTasKbKoyGbK4a4HG" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03127001718bee76f14133272f0f4a928ffa8c2b38cafd94d7100253dac732c644", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_2", - "publicKey": "03127001718bee76f14133272f0f4a928ffa8c2b38cafd94d7100253dac732c644" - } - }, - "signature": "3044022003d2e76aca2848aedfe25415c11b9368dc72f687b66bef4527b40e2997b86b8c022076f7f82cbeb282d26535a2c1f0af0f02b48025d42c1bd56ac687fba1a3adb706", - "id": "0daff3992b54b1384f52f751c933c727cbaaf4fac435eba88a1817a425753614", - "senderId": "D9rv3h61heDYHQ3b3Xk3V5epHSTTC6Vn1d" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0241734825ba45b6de29d6f26242c25ae1ef125b82615ee89a9fdd5b0f3c6b5132", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_28", - "publicKey": "0241734825ba45b6de29d6f26242c25ae1ef125b82615ee89a9fdd5b0f3c6b5132" - } - }, - "signature": "3045022100bb2903424bcd0a72da531470779144d60286191bea1b200c5617ae4f92229ba6022046a876e3e6cb85469a16f34d2f937e2eef787011c6a313ee50258f15116148ac", - "id": "bd17dbd23f8dbba2736688702ac185a87c88c43b24ee6d7764a5b4138b2f38b7", - "senderId": "DAcQPbKa8zBWwDHbxj37N13C61iseMDWM9" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03b9409203d7091e3f4d49168529b749e942ed18f21beddd236d57d692f09a8f86", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_29", - "publicKey": "03b9409203d7091e3f4d49168529b749e942ed18f21beddd236d57d692f09a8f86" - } - }, - "signature": "3044022016d7ecfa776930a6f83464548e7a686735fde752903539a38eb9da0ce2488bbd02203c5e23a4072c8de35a90b296145cce3156a31cc0d754b8a37d363fb088bc7387", - "id": "16e02d3ef24dca4b03a1e489e20335224f18d888ed04f7e3512572f8e0cf92ae", - "senderId": "D5mmTaDAMSyPNKiDKrqwTFGWzWrZA3xaF8" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02c7b92a2d0027309e21855cf9c42a432b21ad13925e9dfc206f9c01e18fefa08a", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_30", - "publicKey": "02c7b92a2d0027309e21855cf9c42a432b21ad13925e9dfc206f9c01e18fefa08a" - } - }, - "signature": "30450221009de8828a7ad87cb5d52900e09d5beb680f9edc7640a3707d08a379511a7ba0f102202aa1d9294f9631f1325f252adb87c0d866e7398ce410037a42dc861d94308e15", - "id": "fece556bee4de2c7f1bb3099a05a84a33d0c963979fe1a222a899c13b7abb1fc", - "senderId": "DJ3NywAwQh4srbooLH1jTs9ma1hJE79v3z" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0221297804a26a93bb441a9d20a2916abf27fa7b29967678ef1a7a58062f73f40d", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_31", - "publicKey": "0221297804a26a93bb441a9d20a2916abf27fa7b29967678ef1a7a58062f73f40d" - } - }, - "signature": "3045022100b969611ef532557fa3da8a0325b2c88f3ebec954d64f158431d86b8e07929ea50220520affdcd0728cb7c5f63a58a1200d44133e90b1f7a6a9e28744ad6b0dcc2a75", - "id": "ee086317ea2fdc522f5eb502a0db9f3d4955b2318559e40a1f22a3f5f8d6344b", - "senderId": "D5P7eti7FUY4Tk5KXoxdf2tDAVQrRVCESA" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "027f504f6f20648e3bf171952629c7b868a2f799aa4b60f8eb3fe96afff16bbef0", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_32", - "publicKey": "027f504f6f20648e3bf171952629c7b868a2f799aa4b60f8eb3fe96afff16bbef0" - } - }, - "signature": "3044022006be7cbaa74089cabe47d02621f756762587d210a3f211ee941b5fcd0650908f02207d4040408bd25a2de03e5724362735ee8ad36c099b0c16efd4716e1dd7ec62ae", - "id": "764dd21aa4d0e2e0fa17bb2ff5e7ca304995d9e3593542badecc8ed24d5ea3ea", - "senderId": "D9q26yBTrEYuxHg7bbfZphv6129KvLu4v2" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "031954315b84db8f49ab7ee21357270450bb68d06b34472e5e93ddfa5710edc0c9", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_33", - "publicKey": "031954315b84db8f49ab7ee21357270450bb68d06b34472e5e93ddfa5710edc0c9" - } - }, - "signature": "3045022100859f93df994d86995fdf834bfe86b41eebaa04e5ab7d09f0b37acb50d313cd9802203c8993b793602c96d305fa795a9f2459f4706b340993584f3c56579392c0995c", - "id": "efd9e7c638afe62bec9be61783193ea52eea7b335053bd5af6c758d5b0e5847c", - "senderId": "D9iPFb5kAVnuDdomehRP9LncJj5ng2vrsr" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0267b310eac2bb0d6594de382a1ab74ac75b91e9d64a590b6249247b10fd9be829", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_34", - "publicKey": "0267b310eac2bb0d6594de382a1ab74ac75b91e9d64a590b6249247b10fd9be829" - } - }, - "signature": "3045022100a678978ab899e3903e760ee98640e3f658792a096a8d771c575944af6536cfdb0220428c312f1e0eb4be73ce4b256a754447570176200cfb6c09b3eb55f66526dd80", - "id": "70edcce5df67a250b6ba3567879bae6379ce4c688597fcedfbfd0313da6998e8", - "senderId": "D6xZmtyBzZKCEkK29JNPAD581TJ8XXrXYn" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "028f32320c66a89779756b04946d2aa256dff6cd547349d46e1938710063e387c4", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_35", - "publicKey": "028f32320c66a89779756b04946d2aa256dff6cd547349d46e1938710063e387c4" - } - }, - "signature": "304402206bc95876897527b39eacf4c961f9c036a9c8a0e53a17ce925c592d079fa643030220096e115d7fbd54aca4af7f621d64178dfcf2c13361106a3e3b5025dca97b44ee", - "id": "7f23f44157f3a677e81514fa431227410a27442e5fd1f2491b177c0f580f296d", - "senderId": "D9dW4eXJjABDQXSQB9GtvY5UBuRWWWejWb" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0218b889a24988527ab3948d80f97cfc37b923082e1f0398bc162190fd66ec4dee", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_36", - "publicKey": "0218b889a24988527ab3948d80f97cfc37b923082e1f0398bc162190fd66ec4dee" - } - }, - "signature": "3045022100c40a3f4cf15f9274e2b25ca8608cb965316aa0f00fa77817b79620ad8ccbdd5902206203a1043b03ba58aa9b7399694f8215cf45d30eb0caa748cc06f1a85a8faea9", - "id": "a65244ed17a9280aa694abdf6804b1a0b78dfc052b4845abcd3c89380159b29e", - "senderId": "DFHK7SdmPdjxNZ9uweqLZAv6v5GQ1NnBNe" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "035392ee88c60617764b4fe89ae2cc96560dfa5f992b03be31ce5680db9b863f73", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_37", - "publicKey": "035392ee88c60617764b4fe89ae2cc96560dfa5f992b03be31ce5680db9b863f73" - } - }, - "signature": "3044022036200c3191f8f01b77676644b9b94728b5afb2ab2de8c5c7c5582e795465661c02207848f1f2f0ab378d8906fd45aa048f354d5dbac4cb87c15973ffa86fe84ff0cd", - "id": "219e0942afe5f65c548ec2118a1c49febb7ec03fca4334ac16649062db9d146b", - "senderId": "DSh7AAC9KahXU2JZ539HAqEa5sHafxsxDQ" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03e75127d1deccf65844a1761bd26611b6c65c5b51a52eba27e3ee20a539fd63f1", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_38", - "publicKey": "03e75127d1deccf65844a1761bd26611b6c65c5b51a52eba27e3ee20a539fd63f1" - } - }, - "signature": "304402201a2990b2baae72f5cc8f2d1890f328e4082af0cf2a787d8f05208c3424ce089d0220790dbc7606dd6c03568fd0a771e9e8e89557257238ae90cfcb3bb8f3b475987b", - "id": "ee9ad2a66e9b2009a9fc671f80d0493803fc422161140169c7bc1fd401cd9ad6", - "senderId": "D85WuxGZrFs1QUYTvnRpmc6dd8rmBbpnaX" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0329fc1580906307ac9f2f55cec66e47983f8287d542408fb19f473a305d3638d8", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_39", - "publicKey": "0329fc1580906307ac9f2f55cec66e47983f8287d542408fb19f473a305d3638d8" - } - }, - "signature": "30450221008f66e89ec4c7af4b77e5b7ff36c542cc02672c8df70806b5a0fab7a7e8c7067502200d99ba19ceb1b471c39c4e95107ad6f8b978a623a790080b16f863347fe06b4f", - "id": "dd3077ed04a76343d340074270ce9826354802bd99e08cb864c1c5ad09f367df", - "senderId": "D85kwsBJKZ4pw5uQpc81eRj95f6a536AP6" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "035ec848e9388877dac88f121d19c8f5e870ac90d8ccb0116be9f734e4bd1a9405", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_40", - "publicKey": "035ec848e9388877dac88f121d19c8f5e870ac90d8ccb0116be9f734e4bd1a9405" - } - }, - "signature": "304402202b220d6c028bc23213edddaf303f18eef059551891aadbf7a4b4d7d3287457bb0220245678354bb8960b42ba2f2ceb12f926e82ff0d027b44988d799c8c0d8d7d9f2", - "id": "3afc6ea52b8edc7df0230ceac71baf45460f3bd761c5e75fe796bc7415063220", - "senderId": "DGBJdDadBwJD2xY8VsdAykdd6vPakMMUt6" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0356f5885306e45402aeb354a74d13c104699b3b53da46a5e922e4a6d6132a67e8", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_41", - "publicKey": "0356f5885306e45402aeb354a74d13c104699b3b53da46a5e922e4a6d6132a67e8" - } - }, - "signature": "3045022100f18bf2e013f2d9dcac013a76037d787f79baaa65f4f31ffe2b4ed8de249bdc8902202abcf77e809599d3e3a96225363c8e760ed4b4e20f97645547b381dba830c3da", - "id": "aea1fc173a2f4a9233b0fe59a5f6804167bee5658cb3e4e19dfe2be20f5772cd", - "senderId": "DG4VbapL3H39NJLB3DqQEefU47EMVqtxVw" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03ff8ab980434516ca28c982d0ecc8fc3107116d6c8b3e09c7ee5033f32adbd2ff", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_42", - "publicKey": "03ff8ab980434516ca28c982d0ecc8fc3107116d6c8b3e09c7ee5033f32adbd2ff" - } - }, - "signature": "3045022100e938d9901afeaa5a56d18abd9292ace93be03c84c09a6c4cb58fca96dfb54bc502201e921d27f9886d189f803b14d93655a42c4e095d49ee61051a4e70c7a173f3f1", - "id": "f18426d3ef81d4b7bf0337d70afcecddbd6db2206a2f139f1ca5823c381c7817", - "senderId": "DC3oNWedP48ypGxAeKbFC7gMjWxcNc2JhL" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0393f1590771a8ad1cf2baa086858f3029c4444cb82243917a7011f1f66cf8fd05", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_43", - "publicKey": "0393f1590771a8ad1cf2baa086858f3029c4444cb82243917a7011f1f66cf8fd05" - } - }, - "signature": "304502210095745c36a8af07e21546bd064f1ed1bd90e6c2a8db9c0c8e4853d0a8255443db0220259d2ce3677abb42f08b9d22aa13bbe383fd882ed38911b738ebaefc04589694", - "id": "6c51bea35b5e3270dcf7b7dfae8d984e19f476ea7e0435f157c4e0d22b7e7ea1", - "senderId": "DJm2sfcUKhyxakowY9TjyAytkdq7JrFgVj" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0234e24ff1dbc447c804eb385cd05bbd1dc59ef03b44a3346b13e7cccf00b61075", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_44", - "publicKey": "0234e24ff1dbc447c804eb385cd05bbd1dc59ef03b44a3346b13e7cccf00b61075" - } - }, - "signature": "3045022100ee1e8df480f2be042386d383d776b3fd6bd2d3f5a9035071153f23dbfdceeaae02203a0834aae4834da3ca7858779d474b9255ead754867d5b4a18873e9ecaa5045e", - "id": "66fb3e36233f4577ba585ccd7daf83e62d8df262d3d832b806479ac67c1ef35d", - "senderId": "D5oS8xfNebiPsjpwPWoZS6sA9qcYjTGT5h" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03a5789a4486f20f1fdca78a52b528b3bf9952e7c057de71a22adcfb444ba4c5d3", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_45", - "publicKey": "03a5789a4486f20f1fdca78a52b528b3bf9952e7c057de71a22adcfb444ba4c5d3" - } - }, - "signature": "3045022100cb037530bcff9a4d19899431648747022c28aa3239563379d96692bd525eb38902205f3cabb8dd470d9eb3d425e333ad1bc9f0643d489c600a811748fb5f4a203f7f", - "id": "5df9c5e350136571af4b86697bc9d4cfca3ff8b669e254b36f00be1dbde063f7", - "senderId": "D5SzHHdPdGqYUkH7BGNkmGHEUqfZrWb17r" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0347f692345fa7bf90e944eb55246da5f9f595d3f5a20ad50aeb6f9b973aaae17e", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_46", - "publicKey": "0347f692345fa7bf90e944eb55246da5f9f595d3f5a20ad50aeb6f9b973aaae17e" - } - }, - "signature": "3045022100c377efe5ffab58017473699cd7c839dcf48fa5b20b5ddf9bdc4801e22a579b2b02204d35c1a1416069544e3ec01d2ce21bb409f9f2fa4adedc8c03d6417c034a3fec", - "id": "da4cfad78e37d56421dd6676e5618a507340ef1e496831d1968c509e35ef9202", - "senderId": "DCLdibuZB6UsJP8KmdzcDLWzizrDtJQuxt" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "028a32b441377a69aa76e867026f3109b2f0aef8651fe91e2a4ab01eff102a6b98", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_47", - "publicKey": "028a32b441377a69aa76e867026f3109b2f0aef8651fe91e2a4ab01eff102a6b98" - } - }, - "signature": "3045022100e098672958be15989bb125d9018adb4a54e95ab664e64a673997e617e28b39df02206e8459997074d5976b77f90eb9d7180e9d4a0e0efdf433958ffeb2f04d9de382", - "id": "85bafcd07e7ba47ec95cb5b5a6759d4f9f87e036bb7660c7717504e845ef975e", - "senderId": "DSkivgRyimdAVqmm2ZAKwKmKN39WEbbPnL" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0223ac52179903e79865b9a98cf0b52ddc1ab46180c157e8f6bd1e63e7f14fcf31", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_48", - "publicKey": "0223ac52179903e79865b9a98cf0b52ddc1ab46180c157e8f6bd1e63e7f14fcf31" - } - }, - "signature": "304402200a005716f67d6cd3963a3c752c95f1bca01aa127c91ab1a632eb3022d11e3e67022024c4746078e440da441bcb366ee8999ffd2419e9a6f9cbf971d696d5b7f8733b", - "id": "0df1ed07d3f95ddf0385bad83a17b3a8fde6bd6532cd3479e48668064672b34f", - "senderId": "DDgKyKqdA6SuamB1eW77WvFu6RQFMZoU36" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "039de0390f28c7731d86ae7006a31888f12856cde3cc3c2619d4d4a42b6dfd6c51", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_49", - "publicKey": "039de0390f28c7731d86ae7006a31888f12856cde3cc3c2619d4d4a42b6dfd6c51" - } - }, - "signature": "3045022100efa5d51ca79992be4a87af049b3e9ec1b796576e4d937ea9e3760ab0bdcd301e022027e22a6c3395df155bd399643c241e4cc317eaead1f273fd7a709339dfa9dc99", - "id": "436bebc107fad38e944fd14785e09f0600df4d75d31cf3eac53f850462d0be74", - "senderId": "DKCaoaXApw1xE7K1BJcVkr1KGzjKmFWyTk" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02b87b0e70a7ae10613390f405620e24c495ba2b0cfcdbc67688e9b483dea564ee", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_50", - "publicKey": "02b87b0e70a7ae10613390f405620e24c495ba2b0cfcdbc67688e9b483dea564ee" - } - }, - "signature": "304502210096cdd35f803a37730ac73a97a23061dceac96319c67bfb1ddcfbac737febe96102202fa0b279f697da3afc043ffd3ecc838789be07ff119b5527a5c13468cecf66e9", - "id": "bb65f9dbe6272fd07a555fc86762d6a487f538b972f2926ff7698cdc906a32df", - "senderId": "DJQXFKEguZVabsAs46JbXXnQJ5jFhUtN9m" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03c9f8f4001216603c152b4b4429c2ead322ac34672999e808d567a7d1140e46be", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_51", - "publicKey": "03c9f8f4001216603c152b4b4429c2ead322ac34672999e808d567a7d1140e46be" - } - }, - "signature": "3045022100ee961089d02d7bb68fe2257f6a972eeaf6e2c1a1ad2f491c417e161fedbb556b02204c834644e5b5cde9a0b3f92fa23bade7670efab0a067597f6c151ee633932706", - "id": "cef44df9684f05dab67c0568a2c5295bb50cbb3c88f5cfbe672365bda274620f", - "senderId": "DKpt7cm2tZk4RPLyQ5ugwEH7gkriRaA7ov" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02cf70f73328d490cfb03ee822d3fc0cf9259d67c0564e843491e739501809d657", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_27", - "publicKey": "02cf70f73328d490cfb03ee822d3fc0cf9259d67c0564e843491e739501809d657" - } - }, - "signature": "30440220645b912b60f829c0bce58bfe9890ef9253418b6898416aaead663bdf158a99f2022061abbbabd454ec7f7e3f4b502216eec28110e945a4b9b913b1fc0b9758e7e6e4", - "id": "09408dbcf3e3e0835bf92a05330c023a7d6471f3825301a34efa094e0fd4fc30", - "senderId": "DQfjSqDuKr5YZaLAF8rWpFMqMYwEbPtGKg" - }], - "height": 1, - "id": "13149578060728881902", - "blockSignature": "3045022100a6605198e0f590c88798405bc76748d84e280d179bcefed2c993e70cded2a5dd022008c7f915b89fc4f3250fc4b481abb753c68f30ac351871c50bd6cfaf151370e8" -} diff --git a/packages/core-p2p/__tests__/__support__/config/network.json b/packages/core-p2p/__tests__/__support__/config/network.json deleted file mode 100644 index 18944d3ae2..0000000000 --- a/packages/core-p2p/__tests__/__support__/config/network.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "name": "devnet", - "messagePrefix": "ARK message:\n", - "bip32": { - "public": 46090600, - "private": 46089520 - }, - "pubKeyHash": 30, - "nethash": "578e820911f24e039733b45e4882b73e301f813a0d2c31330dafda84534ffa23", - "wif": 170, - "client": { - "token": "DARK", - "symbol": "DѦ", - "explorer": "https://dexplorer.ark.io" - }, - "constants": [{ - "height": 1, - "reward": 0, - "activeDelegates": 51, - "blocktime": 8, - "block": { - "version": 0, - "maxTransactions": 50, - "maxPayload": 2097152 - }, - "epoch": "2017-03-21T13:00:00.000Z", - "fees": { - "send": 10000000, - "vote": 100000000, - "secondsignature": 500000000, - "delegateRegistration": 2500000000, - "multisignature": 500000000 - } - }, { - "height": 75600, - "reward": 200000000 - }], - "exceptions": {} -} diff --git a/packages/core-p2p/__tests__/__support__/config/peers.json b/packages/core-p2p/__tests__/__support__/config/peers.json deleted file mode 100644 index 1f987924ab..0000000000 --- a/packages/core-p2p/__tests__/__support__/config/peers.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "minimumNetworkReach": 3, - "list": [ - { - "ip": "167.114.29.51", - "port": 4002 - }, - { - "ip": "167.114.29.52", - "port": 4002 - }, - { - "ip": "167.114.29.53", - "port": 4002 - }, - { - "ip": "167.114.29.54", - "port": 4002 - }, - { - "ip": "167.114.29.55", - "port": 4002 - } - ], - "blackList": [], - "sources": [ - "https://raw.githubusercontent.com/ArkEcosystem/ARK-Peers/master/devnet.json" - ] -} \ No newline at end of file diff --git a/packages/core-p2p/__tests__/__support__/config/plugins.js b/packages/core-p2p/__tests__/__support__/config/plugins.js deleted file mode 100644 index d7cc0acc20..0000000000 --- a/packages/core-p2p/__tests__/__support__/config/plugins.js +++ /dev/null @@ -1,19 +0,0 @@ -module.exports = { - '@arkecosystem/core-event-emitter': {}, - '@arkecosystem/core-config': {}, - '@arkecosystem/core-logger': {}, - '@arkecosystem/core-logger-winston': {}, - '@arkecosystem/core-database': {}, - '@arkecosystem/core-database-sequelize': { - dialect: 'sqlite', - storage: ':memory:' - }, - '@arkecosystem/core-transaction-pool': {}, - '@arkecosystem/core-transaction-pool-redis': {}, - '@arkecosystem/core-p2p': {}, - '@arkecosystem/core-blockchain': {}, - '@arkecosystem/core-api': { }, - '@arkecosystem/core-webhooks': {}, - '@arkecosystem/core-graphql': {}, - '@arkecosystem/core-forger': {} -} diff --git a/packages/core-p2p/__tests__/__support__/config/server.json b/packages/core-p2p/__tests__/__support__/config/server.json deleted file mode 100644 index edbc69b78d..0000000000 --- a/packages/core-p2p/__tests__/__support__/config/server.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "port": 4002, - "version": "2.0.0", - "fastRebuild": true -} diff --git a/packages/core-p2p/__tests__/__support__/setup.js b/packages/core-p2p/__tests__/__support__/setup.js index 0e297e9a7f..08cb29c352 100644 --- a/packages/core-p2p/__tests__/__support__/setup.js +++ b/packages/core-p2p/__tests__/__support__/setup.js @@ -1,19 +1,14 @@ -'use strict' - -const path = require('path') -const container = require('@arkecosystem/core-container') +const app = require('@arkecosystem/core-container') +const appHelper = require('@arkecosystem/core-test-utils/lib/helpers/container') jest.setTimeout(60000) exports.setUp = async () => { - await container.setUp({ - data: '~/.ark', - config: path.resolve(__dirname, './config') - }, { - exit: '@arkecosystem/core-blockchain' + await appHelper.setUp({ + exit: '@arkecosystem/core-blockchain', }) } exports.tearDown = async () => { - await container.tearDown() + await app.tearDown() } diff --git a/packages/core-p2p/__tests__/__support__/utils.js b/packages/core-p2p/__tests__/__support__/utils.js new file mode 100644 index 0000000000..83f3840f39 --- /dev/null +++ b/packages/core-p2p/__tests__/__support__/utils.js @@ -0,0 +1,33 @@ +const apiHelpers = require('@arkecosystem/core-test-utils/lib/helpers/api') + +class Helpers { + constructor() { + this.headers = { + nethash: + 'd9acd04bde4234a81addb8482333b4ac906bed7be5a9970ce8ada428bd083192', + port: 4000, + version: '2.0.0', + } + } + + async GET(endpoint, params = {}) { + return this.request('GET', endpoint, params) + } + + async POST(endpoint, params) { + return this.request('POST', endpoint, params) + } + + async request(method, path, params = {}) { + const url = `http://localhost:4002/${path}` + const server = require('@arkecosystem/core-container').resolvePlugin('p2p') + .server + + return apiHelpers.request(server, method, url, this.headers, params) + } +} + +/** + * @type {Helpers} + */ +module.exports = new Helpers() diff --git a/packages/core-p2p/__tests__/court/guard.test.js b/packages/core-p2p/__tests__/court/guard.test.js new file mode 100644 index 0000000000..063a4f9508 --- /dev/null +++ b/packages/core-p2p/__tests__/court/guard.test.js @@ -0,0 +1,240 @@ +/* eslint max-len: "off" */ + +const dayjs = require('dayjs-ext') +const app = require('../__support__/setup') + +const ARK_ENV = process.env.ARK_ENV + +const defaults = require('../../lib/defaults') +const offences = require('../../lib/court/offences') + +let container +let guard +let Peer +let peerMock + +beforeAll(async () => { + await app.setUp() + container = require('@arkecosystem/core-container') + + guard = require('../../lib/court/guard') + Peer = require('../../lib/peer') +}) + +afterAll(async () => { + await app.tearDown() +}) + +beforeEach(async () => { + guard.monitor.config = defaults + guard.monitor.peers = {} + + // this peer is here to be ready for future use in tests (not added to initial peers) + peerMock = new Peer('0.0.0.99', 4002) + Object.assign(peerMock, peerMock.headers) +}) + +describe('Guard', () => { + it('should be an object', () => { + expect(guard).toBeObject() + }) + + describe('isSuspended', () => { + it('should be a function', () => { + expect(guard.isSuspended).toBeFunction() + }) + + it('should return true', async () => { + process.env.ARK_ENV = false + await guard.monitor.acceptNewPeer(peerMock) + process.env.ARK_ENV = ARK_ENV + + expect(guard.isSuspended(peerMock)).toBe(true) + }) + + it('should return false because passed', async () => { + process.env.ARK_ENV = false + await guard.monitor.acceptNewPeer(peerMock) + guard.suspensions[peerMock.ip].until = dayjs().subtract(1, 'minutes') + process.env.ARK_ENV = ARK_ENV + + expect(guard.isSuspended(peerMock)).toBe(false) + }) + + it('should return false because not suspended', () => { + expect(guard.isSuspended(peerMock)).toBe(false) + }) + }) + + describe('isRepeatOffender', () => { + it('should be a function', () => { + expect(guard.isRepeatOffender).toBeFunction() + }) + + it('should be true if the threshold is met', () => { + const peer = { offences: [] } + + for (let i = 0; i < 10; i++) { + peer.offences.push({ weight: 10 }) + } + + expect(guard.isRepeatOffender(peer)).toBeFalse() + }) + + it('should be false if the threshold is not met', () => { + const peer = { offences: [] } + + for (let i = 0; i < 15; i++) { + peer.offences.push({ weight: 10 }) + } + + expect(guard.isRepeatOffender(peer)).toBeTrue() + }) + }) + + describe('__determineOffence', () => { + const convertToMinutes = actual => + Math.ceil(actual.diff(dayjs()) / 1000) / 60 + + const dummy = { + nethash: + 'd9acd04bde4234a81addb8482333b4ac906bed7be5a9970ce8ada428bd083192', + version: '2.0.0', + status: 200, + state: {}, + } + + it('should be a function', () => { + expect(guard.__determineOffence).toBeFunction() + }) + + it('should return a 1 day suspension for "Blacklisted"', () => { + const config = container.resolvePlugin('config') + config.peers.blackList = ['dummy-ip-addr'] + + const { until, reason } = guard.__determineOffence({ + nethash: + 'd9acd04bde4234a81addb8482333b4ac906bed7be5a9970ce8ada428bd083192', + ip: 'dummy-ip-addr', + }) + + expect(convertToMinutes(until)).toBe(720) + expect(reason).toBe('Blacklisted') + }) + + it('should return a 5 minutes suspension for "No Common Blocks"', () => { + const { until, reason } = guard.__determineOffence({ + ...dummy, + ...{ + commonBlocks: false, + }, + }) + + expect(convertToMinutes(until)).toBe(5) + expect(reason).toBe('No Common Blocks') + }) + + it('should return a 6 hours suspension for "Invalid Version"', () => { + const { until, reason } = guard.__determineOffence({ + nethash: + 'd9acd04bde4234a81addb8482333b4ac906bed7be5a9970ce8ada428bd083192', + version: '1.0.0', + status: 200, + delay: 1000, + }) + + expect(convertToMinutes(until)).toBe(360) + expect(reason).toBe('Invalid Version') + }) + + it('should return a 10 minutes suspension for "Node is not at height"', () => { + guard.monitor.getNetworkHeight = jest.fn(() => 154) + + const { until, reason } = guard.__determineOffence({ + ...dummy, + state: { + height: 1, + }, + }) + + expect(convertToMinutes(until)).toBe(10) + expect(reason).toBe('Node is not at height') + }) + + it('should return a 5 minutes suspension for "Invalid Response Status"', () => { + const { until, reason } = guard.__determineOffence({ + ...dummy, + ...{ status: 201 }, + }) + + expect(convertToMinutes(until)).toBe(5) + expect(reason).toBe('Invalid Response Status') + }) + + it('should return a 2 minutes suspension for "Timeout"', () => { + const { until, reason } = guard.__determineOffence({ + ...dummy, + ...{ delay: -1 }, + }) + + expect(convertToMinutes(until)).toBe(2) + expect(reason).toBe('Timeout') + }) + + it('should return a 1 minutes suspension for "High Latency"', () => { + const { until, reason } = guard.__determineOffence({ + ...dummy, + ...{ delay: 3000 }, + }) + + expect(convertToMinutes(until)).toBe(1) + expect(reason).toBe('High Latency') + }) + + it('should return a 30 seconds suspension for "Blockchain not ready"', () => { + const { until, reason } = guard.__determineOffence({ + ...dummy, + ...{ status: 503 }, + }) + + expect(convertToMinutes(until)).toBe(0.5) + expect(reason).toBe('Blockchain not ready') + }) + + it('should return a 60 seconds suspension for "Rate limit exceeded"', () => { + const { until, reason } = guard.__determineOffence({ + ...dummy, + ...{ status: 429 }, + }) + + expect(convertToMinutes(until)).toBe(1) + expect(reason).toBe('Rate limit exceeded') + }) + + it('should return a 30 minutes suspension for "Unknown"', () => { + const { until, reason } = guard.__determineOffence(dummy) + + expect(convertToMinutes(until)).toBe(30) + expect(reason).toBe('Unknown') + }) + }) + + describe('__determinePunishment', () => { + it('should be a function', () => { + expect(guard.__determinePunishment).toBeFunction() + }) + + it('should be true if the threshold is met', () => { + const actual = guard.__determinePunishment({}, offences.REPEAT_OFFENDER) + + expect(actual).toHaveProperty('until') + expect(actual.until).toBeObject() + + expect(actual).toHaveProperty('reason') + expect(actual.reason).toBeString() + + expect(actual).toHaveProperty('weight') + expect(actual.weight).toBeNumber() + }) + }) +}) diff --git a/packages/core-p2p/__tests__/manager.test.js b/packages/core-p2p/__tests__/manager.test.js deleted file mode 100644 index bd1bfb9d65..0000000000 --- a/packages/core-p2p/__tests__/manager.test.js +++ /dev/null @@ -1,89 +0,0 @@ -'use strict' - -const app = require('./__support__/setup') - -let manager - -beforeAll(async () => { - await app.setUp() -}) - -afterAll(async () => { - await app.tearDown() -}) - -beforeEach(() => { - manager = new (require('../lib/manager'))(require('../lib/defaults')) -}) - -describe('Peer Manager', () => { - it('should be an object', () => { - expect(manager).toBeObject() - }) - - describe('start', () => { - it('should be a function', () => { - expect(manager.start).toBeFunction() - }) - }) - - describe('stop', () => { - it('should be a function', () => { - expect(manager.stop).toBeFunction() - }) - }) - - describe('updateNetworkStatus', () => { - it('should be a function', () => { - expect(manager.updateNetworkStatus).toBeFunction() - }) - }) - - describe('downloadBlocks', () => { - it('should be a function', () => { - expect(manager.downloadBlocks).toBeFunction() - }) - }) - - describe('broadcastBlock', () => { - it('should be a function', () => { - expect(manager.broadcastBlock).toBeFunction() - }) - }) - - describe('broadcastTransactions', () => { - it('should be a function', () => { - expect(manager.broadcastTransactions).toBeFunction() - }) - }) - - describe('acceptNewPeer', () => { - it('should be a function', () => { - expect(manager.acceptNewPeer).toBeFunction() - }) - }) - - describe('getPeers', () => { - it('should be a function', () => { - expect(manager.getPeers).toBeFunction() - }) - }) - - describe('getNetworkHeight', () => { - it('should be a function', () => { - expect(manager.getNetworkHeight).toBeFunction() - }) - }) - - describe('__checkDNSConnectivity', () => { - it('should be a function', () => { - expect(manager.__checkDNSConnectivity).toBeFunction() - }) - }) - - describe('__checkNTPConnectivity', () => { - it('should be a function', () => { - expect(manager.__checkNTPConnectivity).toBeFunction() - }) - }) -}) diff --git a/packages/core-p2p/__tests__/monitor.test.js b/packages/core-p2p/__tests__/monitor.test.js index 13ba720da1..955fd47b91 100644 --- a/packages/core-p2p/__tests__/monitor.test.js +++ b/packages/core-p2p/__tests__/monitor.test.js @@ -1,35 +1,45 @@ -'use strict' +const axios = require('axios') +const MockAdapter = require('axios-mock-adapter') + +const axiosMock = new MockAdapter(axios) const app = require('./__support__/setup') -const moment = require('moment') -const ARK_ENV = process.env.ARK_ENV const defaults = require('../lib/defaults') -let Manager -let Monitor let monitor -let peer +let Peer +let peerMock beforeAll(async () => { await app.setUp() - Manager = require('../lib/manager') - Monitor = require('../lib/monitor') + monitor = require('../lib/monitor') + Peer = require('../lib/peer') }) afterAll(async () => { await app.tearDown() }) -beforeEach(() => { - const manager = new Manager(defaults) - monitor = new Monitor(manager) - peer = { - ip: '45.76.142.128', - port: 4002, - nethash: '578e820911f24e039733b45e4882b73e301f813a0d2c31330dafda84534ffa23' - } +beforeEach(async () => { + monitor.config = defaults + + const initialPeersMock = {} + ;['0.0.0.0', '0.0.0.1', '0.0.0.2', '0.0.0.3', '0.0.0.4'].forEach(ip => { + const initialPeer = new Peer(ip, 4000) + initialPeersMock[ip] = Object.assign(initialPeer, initialPeer.headers, { + ban: 0, + }) + }) + monitor.peers = initialPeersMock + + peerMock = new Peer('0.0.0.99', 4000) // this peer is just here to be picked up by tests below (not added to initial peers) + Object.assign(peerMock, peerMock.headers, { status: 200 }) + peerMock.nethash = + 'd9acd04bde4234a81addb8482333b4ac906bed7be5a9970ce8ada428bd083192' + + axiosMock.reset() // important: resets any existing mocking behavior }) describe('Monitor', () => { @@ -37,20 +47,24 @@ describe('Monitor', () => { expect(monitor).toBeObject() }) - describe.skip('updateNetworkStatus', () => { + describe('updateNetworkStatus', () => { it('should be a function', () => { expect(monitor.updateNetworkStatus).toBeFunction() }) }) + describe('updateNetworkStatusIfNotEnoughPeers', () => { + it('should be a function', () => { + expect(monitor.updateNetworkStatusIfNotEnoughPeers).toBeFunction() + }) + }) + describe('cleanPeers', () => { it('should be a function', () => { expect(monitor.cleanPeers).toBeFunction() }) - it('should be a function', async () => { - monitor.discoverPeers() - + it('should be ok', async () => { const previousLength = Object.keys(monitor.peers).length await monitor.cleanPeers(true) @@ -65,11 +79,14 @@ describe('Monitor', () => { }) it('should be ok', async () => { + axiosMock + .onGet(`${peerMock.url}/peer/status`) + .reply(() => [200, { success: true }, peerMock.headers]) process.env.ARK_ENV = false - await monitor.acceptNewPeer(peer) + await monitor.acceptNewPeer(peerMock) - expect(monitor.peers[peer.ip]).toBeObject() + expect(monitor.peers[peerMock.ip]).toBeObject() process.env.ARK_ENV = 'test' }) @@ -81,12 +98,10 @@ describe('Monitor', () => { }) it('should be ok', async () => { - await monitor.discoverPeers() - const peers = monitor.getPeers() expect(peers).toBeArray() - expect(peers.length).toBeGreaterThan(10) + expect(peers.length).toBe(5) // 5 from peers.json }) }) @@ -96,11 +111,11 @@ describe('Monitor', () => { }) it('should be ok', async () => { - const peers = monitor.getRandomPeer() + const peer = monitor.getRandomPeer() - expect(peers).toBeObject() - expect(peers).toHaveProperty('ip') - expect(peers).toHaveProperty('port') + expect(peer).toBeObject() + expect(peer).toHaveProperty('ip') + expect(peer).toHaveProperty('port') }) }) @@ -110,11 +125,14 @@ describe('Monitor', () => { }) it('should be ok', async () => { - const peers = await monitor.getRandomDownloadBlocksPeer() - - expect(peers).toBeObject() - expect(peers).toHaveProperty('ip') - expect(peers).toHaveProperty('port') + axiosMock + .onGet(/.*\/peer\/blocks\/common/) + .reply(() => [200, { success: true, common: true }, peerMock.headers]) + const peer = await monitor.getRandomDownloadBlocksPeer() + + expect(peer).toBeObject() + expect(peer).toHaveProperty('ip') + expect(peer).toHaveProperty('port') }) }) @@ -124,10 +142,28 @@ describe('Monitor', () => { }) it('should be ok', async () => { + axiosMock + .onGet(/.*\/peer\/status/) + .reply(() => [200, { success: true }, peerMock.headers]) + axiosMock + .onGet(/.*\/peer\/list/) + .reply(() => [ + 200, + { peers: [peerMock.toBroadcastInfo()] }, + peerMock.headers, + ]) + const peers = await monitor.discoverPeers() expect(peers).toBeObject() - expect(Object.keys(peers).length).toBeGreaterThan(10) + expect(Object.keys(peers).length).toBe(6) // 5 from initial peers + 1 from peerMock + expect(peers[peerMock.ip]).toBeObject() + }) + }) + + describe('hasPeers', () => { + it('should be a function', () => { + expect(monitor.hasPeers).toBeFunction() }) }) @@ -137,10 +173,19 @@ describe('Monitor', () => { }) it('should be ok', async () => { + axiosMock + .onGet(/.*\/peer\/status/) + .reply(() => [200, { success: true, height: 2 }, peerMock.headers]) + axiosMock + .onGet(/.*\/peer\/list/) + .reply(() => [200, { peers: [] }, peerMock.headers]) await monitor.discoverPeers() - await expect(monitor.getNetworkHeight()).resolves.toBeNumber() + const height = await monitor.getNetworkHeight() + expect(height).toBe(2) }) + + // TODO test with peers with different heights (use replyOnce) and check that median is OK }) describe('getPBFTForgingStatus', () => { @@ -149,9 +194,18 @@ describe('Monitor', () => { }) it('should be ok', async () => { + axiosMock + .onGet(/.*\/peer\/status/) + .reply(() => [200, { success: true, height: 2 }, peerMock.headers]) + axiosMock + .onGet(/.*\/peer\/list/) + .reply(() => [200, { peers: [] }, peerMock.headers]) + await monitor.discoverPeers() + const pbftForgingStatus = monitor.getPBFTForgingStatus() - await expect(monitor.getPBFTForgingStatus()).resolves.toBeNumber() + expect(pbftForgingStatus).toBeNumber() + // TODO test mocking peers currentSlot & forgingAllowed }) }) @@ -161,10 +215,24 @@ describe('Monitor', () => { }) it('should be ok', async () => { + axiosMock + .onGet(/.*\/peer\/blocks\/common/) + .reply(() => [200, { success: true, common: true }, peerMock.headers]) + axiosMock + .onGet(/.*\/peer\/status/) + .reply(() => [200, { success: true, height: 2 }, peerMock.headers]) + axiosMock + .onGet(/.*\/peer\/blocks/) + .reply(() => [ + 200, + { blocks: [{ id: 1 }, { id: 2 }] }, + peerMock.headers, + ]) + const blocks = await monitor.downloadBlocks(1) expect(blocks).toBeArray() - expect(blocks.length).toBeGreaterThan(10) + expect(blocks.length).toBe(2) }) }) @@ -178,44 +246,17 @@ describe('Monitor', () => { it('should be a function', () => { expect(monitor.broadcastTransactions).toBeFunction() }) - - it('should be ok', () => { - expect(monitor.broadcastTransactions).toBeFunction() - - expect(monitor.toBroadcastV1) - }) }) - describe('__isSuspended', () => { + describe('__checkDNSConnectivity', () => { it('should be a function', () => { - expect(monitor.__isSuspended).toBeFunction() - }) - - it('should have timeout of 60 minutes', () => { - expect(monitor.manager.config.suspendMinutes).toBe(60) - }) - - it('should return true', async () => { - process.env.ARK_ENV = false - peer.ip = '1.2.3.4' - await monitor.acceptNewPeer(peer) - process.env.ARK_ENV = ARK_ENV - - expect(monitor.__isSuspended(peer)).toBe(true) - }) - - it('should return false because passed', async () => { - process.env.ARK_ENV = false - peer.ip = '1.2.3.4' - await monitor.acceptNewPeer(peer) - monitor.suspendedPeers['1.2.3.4'].until = moment().subtract(1, 'minutes') - process.env.ARK_ENV = ARK_ENV - - expect(monitor.__isSuspended(peer)).toBe(false) + expect(monitor.__checkDNSConnectivity).toBeFunction() }) + }) - it('should return false because not suspended', () => { - expect(monitor.__isSuspended(peer)).toBe(false) + describe('__checkNTPConnectivity', () => { + it('should be a function', () => { + expect(monitor.__checkNTPConnectivity).toBeFunction() }) }) }) diff --git a/packages/core-p2p/__tests__/peer.test.js b/packages/core-p2p/__tests__/peer.test.js index 31bc5496a1..d9b949cbf8 100644 --- a/packages/core-p2p/__tests__/peer.test.js +++ b/packages/core-p2p/__tests__/peer.test.js @@ -1,23 +1,27 @@ -'use strict' +/* eslint no-empty: "off" */ const axios = require('axios') const MockAdapter = require('axios-mock-adapter') + const axiosMock = new MockAdapter(axios) +const { Block, Transaction } = require('@arkecosystem/crypto').models const app = require('./__support__/setup') let genesisBlock let genesisTransaction let Peer -let peer +let peerMock beforeAll(async () => { await app.setUp() // Create the genesis block after the setup has finished or else it uses a potentially // wrong network config. - genesisBlock = require('./__fixtures__/genesisBlock') - genesisTransaction = require('./__fixtures__/genesisTransaction') + genesisBlock = new Block( + require('@arkecosystem/core-test-utils/config/testnet/genesisBlock.json'), + ) + genesisTransaction = new Transaction(genesisBlock.transactions[0]) Peer = require('../lib/peer') }) @@ -27,21 +31,24 @@ afterAll(async () => { }) beforeEach(() => { - peer = new Peer('45.76.142.128', 4002) + peerMock = new Peer('0.0.0.99', 4002) + Object.assign(peerMock, peerMock.headers) + + axiosMock.reset() // important: resets any existing mocking behavior }) describe('Peer', () => { it('should be an object', () => { - expect(peer).toBeObject() + expect(peerMock).toBeObject() }) describe('toBroadcastInfo', () => { it('should be a function', () => { - expect(peer.toBroadcastInfo).toBeFunction() + expect(peerMock.toBroadcastInfo).toBeFunction() }) it('should be ok', async () => { - const struct = peer.toBroadcastInfo() + const struct = peerMock.toBroadcastInfo() expect(struct).toBeObject() expect(struct).toHaveProperty('ip') @@ -54,116 +61,223 @@ describe('Peer', () => { }) }) - describe.skip('postBlock', () => { + describe('postBlock', () => { it('should be a function', () => { - expect(peer.postBlock).toBeFunction() + expect(peerMock.postBlock).toBeFunction() }) it('should be ok', async () => { - const response = await peer.postBlock(genesisBlock.toBroadcastV1()) + axiosMock + .onPost(`${peerMock.url}/peer/blocks`) + .reply(200, { success: true }, peerMock.headers) + + const response = await peerMock.postBlock(genesisBlock.toJson()) expect(response).toBeObject() expect(response).toHaveProperty('success') - expect(response.success).toBeTruthy() + expect(response.success).toBeTrue() }) }) describe.skip('postTransactions', () => { it('should be a function', () => { - expect(peer.postTransactions).toBeFunction() + expect(peerMock.postTransactions).toBeFunction() }) it('should be ok', async () => { - const response = await peer.postTransactions([genesisTransaction.toBroadcastV1()]) + axiosMock + .onPost(`${peerMock.url}/peer/transactions`) + .reply(200, { success: true }, peerMock.headers) + + const response = await peerMock.postTransactions([ + genesisTransaction.toJson(), + ]) expect(response).toBeObject() expect(response).toHaveProperty('success') - expect(response.success).toBeTruthy() + expect(response.success).toBeTrue() }) }) describe('downloadBlocks', () => { // https://github.com/facebook/jest/issues/3601 - const errorCapturer = fn => fn.then(res => () => res).catch(err => () => { throw err }) + const errorCapturer = fn => + fn + .then(res => () => res) + .catch(err => () => { + throw err + }) it('should be a function', () => { - expect(peer.downloadBlocks).toBeFunction() + expect(peerMock.downloadBlocks).toBeFunction() }) - describe('when the request reply with the blocks', () => { - it('should return the blocks', async () => { - const blocks = [{}] - axiosMock.onGet(`${peer.url}/peer/blocks`).reply(200, { blocks }) - - const result = await peer.downloadBlocks(1) + it('should return the blocks with status 200', async () => { + const blocks = [{}] + axiosMock + .onGet(`${peerMock.url}/peer/blocks`) + .reply(200, { blocks }, peerMock.headers) + const result = await peerMock.downloadBlocks(1) - expect(result).toEqual(blocks) - }) + expect(result).toEqual(blocks) }) - describe('when the request reply with the blocks', () => { - it('should return the blocks', async () => { - axiosMock.onGet(`${peer.url}/peer/blocks`).reply(500, { data: {} }) + it('should not return the blocks with status 500', async () => { + axiosMock + .onGet(`${peerMock.url}/peer/blocks`) + .reply(500, { data: {} }, peerMock.headers) - expect(await errorCapturer(peer.downloadBlocks(1))).toThrowError(/request.*500/i) - }) + expect(await errorCapturer(peerMock.downloadBlocks(1))).toThrow( + /request.*500/i, + ) }) }) describe('ping', () => { it('should be a function', () => { - expect(peer.ping).toBeFunction() + expect(peerMock.ping).toBeFunction() }) it('should be ok', async () => { - const response = await peer.ping(5000) + axiosMock + .onGet(`${peerMock.url}/peer/status`) + .reply(() => [200, { success: true }, peerMock.headers]) + + const response = await peerMock.ping(5000) expect(response).toBeObject() expect(response).toHaveProperty('success') - expect(response.success).toBeTruthy() + expect(response.success).toBeTrue() }) it('should not be ok', async () => { - expect(await peer.ping(1)).toThrowError('is unreachable') + axiosMock + .onGet(`${peerMock.url}/peer/status`) + .reply(() => [500, {}, peerMock.headers]) + return expect(peerMock.ping(1)).rejects.toThrowError('is unresponsive') + }) + + it.each([200, 500, 503])( + 'should update peer status from http response %i', + async status => { + axiosMock + .onGet(`${peerMock.url}/peer/status`) + .replyOnce(() => [status, {}, peerMock.headers]) + try { + await peerMock.ping(1000) + } catch (e) {} + expect(peerMock.status).toBe(status) + }, + ) + }) + + describe('recentlyPinged', () => { + it('should be a function', () => { + expect(peerMock.recentlyPinged).toBeFunction() + }) + + it('should be recently pinged', async () => { + peerMock.lastPinged = null + + expect(peerMock.recentlyPinged()).toBeFalse() + + axiosMock + .onGet(`${peerMock.url}/peer/status`) + .reply(() => [200, { success: true }, peerMock.headers]) + + const response = await peerMock.ping(5000) + + expect(response).toBeObject() + expect(response).toHaveProperty('success') + expect(response.success).toBeTrue() + expect(peerMock.recentlyPinged()).toBeTrue() }) }) describe('getPeers', () => { it('should be a function', () => { - expect(peer.getPeers).toBeFunction() + expect(peerMock.getPeers).toBeFunction() }) it('should be ok', async () => { - const peers = await peer.getPeers() + const peersMock = [{ ip: '1.1.1.1' }] + axiosMock + .onGet(`${peerMock.url}/peer/status`) + .reply(() => [200, { success: true }, peerMock.headers]) + axiosMock + .onGet(`${peerMock.url}/peer/list`) + .reply(() => [200, { peers: peersMock }, peerMock.headers]) + + const peers = await peerMock.getPeers() + + expect(peers).toEqual(peersMock) + }) + }) + + describe('height', () => { + it('should update the height after download', async () => { + const blocks = [{}] + const headers = Object.assign({}, peerMock.headers, { height: 1 }) + + axiosMock + .onGet(`${peerMock.url}/peer/blocks`) + .reply(200, { blocks }, headers) + + expect(peerMock.state.height).toBeFalsy() + await peerMock.downloadBlocks(1) + expect(peerMock.state.height).toBe(1) + }) + + it('should update the height after post block', async () => { + const blocks = [{}] + const headers = Object.assign({}, peerMock.headers, { height: 1 }) + + axiosMock + .onPost(`${peerMock.url}/peer/blocks`) + .reply(200, { blocks }, headers) + + expect(peerMock.state.height).toBeFalsy() + await peerMock.postBlock(genesisBlock.toJson()) + expect(peerMock.state.height).toBe(1) + }) + + it('should update the height after post transaction', async () => { + const transactions = [{}] + const headers = Object.assign({}, peerMock.headers, { height: 1 }) + + axiosMock + .onPost(`${peerMock.url}/peer/transactions`) + .reply(200, { transactions }, headers) - expect(peers).toBeArray() - expect(peers.length).toBeGreaterThan(10) + expect(peerMock.state.height).toBeFalsy() + await peerMock.postTransactions([genesisTransaction.toJson()]) + expect(peerMock.state.height).toBe(1) }) }) describe('__get', () => { it('should be a function', () => { - expect(peer.__get).toBeFunction() + expect(peerMock.__get).toBeFunction() }) }) describe('__parseHeaders', () => { it('should be a function', () => { - expect(peer.__parseHeaders).toBeFunction() + expect(peerMock.__parseHeaders).toBeFunction() }) it('should be ok', async () => { const headers = { nethash: 'nethash', os: 'os', - version: 'version' + version: 'version', } - await peer.__parseHeaders({ headers }) + await peerMock.__parseHeaders({ headers }) - expect(peer.nethash).toBe(headers.nethash) - expect(peer.os).toBe(headers.os) - expect(peer.version).toBe(headers.version) + expect(peerMock.nethash).toBe(headers.nethash) + expect(peerMock.os).toBe(headers.os) + expect(peerMock.version).toBe(headers.version) }) }) }) diff --git a/packages/core-p2p/__tests__/server/1.test.js b/packages/core-p2p/__tests__/server/1.test.js index 4ffbceb1f3..248e864f39 100644 --- a/packages/core-p2p/__tests__/server/1.test.js +++ b/packages/core-p2p/__tests__/server/1.test.js @@ -1,44 +1,35 @@ -'use strict' - -const axios = require('axios') - +const { Block, Transaction } = require('@arkecosystem/crypto').models +const genTransfer = require('@arkecosystem/core-test-utils/lib/generators/transactions/transfer') const app = require('../__support__/setup') +const utils = require('../__support__/utils') let genesisBlock -let genesisTransaction beforeAll(async () => { await app.setUp() // Create the genesis block after the setup has finished or else it uses a potentially // wrong network config. - genesisBlock = require('../__fixtures__/genesisBlock') - genesisTransaction = require('../__fixtures__/genesisTransaction') + genesisBlock = new Block( + require('@arkecosystem/core-test-utils/config/testnet/genesisBlock.json'), + ) }) afterAll(async () => { await app.tearDown() }) -const sendGET = async (endpoint, params = {}) => { - return axios.get(`http://127.0.0.1:4002/${endpoint}`, { params }) -} - -const sendPOST = async (endpoint, params) => { - return axios.post(`http://127.0.0.1:4002/${endpoint}`, params) -} - describe('API - Version 1', () => { describe('GET /peer/list', () => { it('should be ok', async () => { - const response = await sendGET('peer/list') + const response = await utils.GET('peer/list') expect(response.status).toBe(200) expect(response.data).toBeObject() expect(response.data).toHaveProperty('success') - expect(response.data.success).toBeTruthy() + expect(response.data.success).toBeTrue() expect(response.data).toHaveProperty('peers') expect(response.data.peers).toBeArray() @@ -47,24 +38,38 @@ describe('API - Version 1', () => { describe('GET /peer/blocks', () => { it('should be ok', async () => { - const response = await sendGET('peer/blocks', { lastBlockHeight: 1 }) + const response = await utils.GET('peer/blocks', { lastBlockHeight: 1 }) expect(response.status).toBe(200) expect(response.data).toBeObject() expect(response.data).toHaveProperty('success') - expect(response.data.success).toBeTruthy() + expect(response.data.success).toBeTrue() expect(response.data).toHaveProperty('blocks') expect(response.data.blocks).toBeArray() }) + + it('should retrieve lastBlock if no "lastBlockHeight" specified', async () => { + const response = await utils.GET('peer/blocks') + + expect(response.status).toBe(200) + expect(response.data).toBeObject() + + expect(response.data).toHaveProperty('success') + expect(response.data.success).toBeTrue() + + expect(response.data).toHaveProperty('blocks') + expect(response.data.blocks).toBeArray() + expect(response.data.blocks).toHaveLength(1) + }) }) describe('GET /peer/transactionsFromIds', () => { it('should be ok', async () => { - const response = await sendGET('peer/transactionsFromIds', { - ids: 'e40ce11cab82736da1cc91191716f3c1f446ca7b6a9f4f93b7120ef105ba06e8' + const response = await utils.GET('peer/transactionsFromIds', { + ids: 'e40ce11cab82736da1cc91191716f3c1f446ca7b6a9f4f93b7120ef105ba06e8', }) expect(response.status).toBe(200) @@ -72,7 +77,7 @@ describe('API - Version 1', () => { expect(response.data).toBeObject() expect(response.data).toHaveProperty('success') - expect(response.data.success).toBeTruthy() + expect(response.data.success).toBeTrue() expect(response.data).toHaveProperty('transactions') expect(response.data.transactions).toBeArray() @@ -81,33 +86,33 @@ describe('API - Version 1', () => { describe('GET /peer/height', () => { it('should be ok', async () => { - const response = await sendGET('peer/height') + const response = await utils.GET('peer/height') expect(response.status).toBe(200) expect(response.data).toBeObject() expect(response.data).toHaveProperty('success') - expect(response.data.success).toBeTruthy() + expect(response.data.success).toBeTrue() expect(response.data).toHaveProperty('height') expect(response.data.height).toBeNumber() expect(response.data).toHaveProperty('id') - expect(response.data.id).toBeNumber() + expect(response.data.id).toBeString() }) }) describe('GET /peer/transactions', () => { it('should be ok', async () => { - const response = await sendGET('peer/transactions') + const response = await utils.GET('peer/transactions') expect(response.status).toBe(200) expect(response.data).toBeObject() expect(response.data).toHaveProperty('success') - expect(response.data.success).toBeTruthy() + expect(response.data.success).toBeTrue() expect(response.data).toHaveProperty('transactions') expect(response.data.transactions).toBeArray() @@ -116,8 +121,8 @@ describe('API - Version 1', () => { describe('GET /peer/blocks/common', () => { it('should be ok', async () => { - const response = await sendGET('peer/blocks/common', { - ids: '13149578060728881902' + const response = await utils.GET('peer/blocks/common', { + ids: '17184958558311101492', }) expect(response.status).toBe(200) @@ -125,12 +130,11 @@ describe('API - Version 1', () => { expect(response.data).toBeObject() expect(response.data).toHaveProperty('success') - expect(response.data.success).toBeTruthy() - + expect(response.data.success).toBeTrue() expect(response.data).toHaveProperty('common') expect(response.data.common).toBeObject() expect(response.data.common.height).toBe(1) - expect(response.data.common.id).toBe('13149578060728881902') + expect(response.data.common.id).toBe('17184958558311101492') expect(response.data).toHaveProperty('lastBlockHeight') expect(response.data.lastBlockHeight).toBeNumber() @@ -139,21 +143,21 @@ describe('API - Version 1', () => { describe('GET /peer/status', () => { it('should be ok', async () => { - const response = await sendGET('peer/status') + const response = await utils.GET('peer/status') expect(response.status).toBe(200) expect(response.data).toBeObject() expect(response.data).toHaveProperty('success') - expect(response.data.success).toBeTruthy() + expect(response.data.success).toBeTrue() }) }) describe('POST /peer/blocks', () => { it('should be ok', async () => { - const response = await sendPOST('peer/blocks', { - block: genesisBlock.toBroadcastV1() + const response = await utils.POST('peer/blocks', { + block: genesisBlock.toJson(), }) expect(response.status).toBe(200) @@ -161,14 +165,15 @@ describe('API - Version 1', () => { expect(response.data).toBeObject() expect(response.data).toHaveProperty('success') - expect(response.data.success).toBeTruthy() + expect(response.data.success).toBeTrue() }) }) describe('POST /peer/transactions', () => { it('should be ok', async () => { - const response = await sendPOST('peer/transactions', { - transactions: [genesisTransaction.toBroadcastV1()] + const transactions = genTransfer('testnet') + const response = await utils.POST('peer/transactions', { + transactions, }) expect(response.status).toBe(200) @@ -176,7 +181,7 @@ describe('API - Version 1', () => { expect(response.data).toBeObject() expect(response.data).toHaveProperty('success') - expect(response.data.success).toBeTruthy() + expect(response.data.success).toBeTrue() }) }) }) diff --git a/packages/core-p2p/__tests__/server/internal.test.js b/packages/core-p2p/__tests__/server/internal.test.js index dfde9fa822..b6ef16cf38 100644 --- a/packages/core-p2p/__tests__/server/internal.test.js +++ b/packages/core-p2p/__tests__/server/internal.test.js @@ -1,8 +1,8 @@ -'use strict' - -const axios = require('axios') - +const { Block, Transaction } = require('@arkecosystem/crypto').models +const genTransfer = require('@arkecosystem/core-test-utils/lib/generators/transactions/transfer') +const blockFixture = require('../../../core-debugger-cli/__tests__/__fixtures__/block.json') const app = require('../__support__/setup') +const utils = require('../__support__/utils') let genesisBlock let genesisTransaction @@ -12,87 +12,119 @@ beforeAll(async () => { // Create the genesis block after the setup has finished or else it uses a potentially // wrong network config. - genesisBlock = require('../__fixtures__/genesisBlock') - genesisTransaction = require('../__fixtures__/genesisTransaction') + genesisBlock = new Block( + require('@arkecosystem/core-test-utils/config/testnet/genesisBlock.json'), + ) + genesisTransaction = new Transaction(genesisBlock.transactions[0]) +}) + +beforeEach(() => { + utils.headers['x-auth'] = 'forger' }) afterAll(async () => { + delete utils.headers['x-auth'] await app.tearDown() }) -const sendGET = async (endpoint, params = {}) => { - return axios.get(`http://127.0.0.1:4002/internal/${endpoint}`, { params }) -} - -const sendPOST = async (endpoint, params) => { - return axios.post(`http://127.0.0.1:4002/internal/${endpoint}`, params) -} - describe('API - Internal', () => { - describe('GET /round', () => { + describe('GET /rounds/current', () => { it('should be ok', async () => { - const response = await sendGET('round') + const response = await utils.GET('internal/rounds/current') expect(response.status).toBe(200) expect(response.data).toBeObject() - expect(response.data).toHaveProperty('success') - expect(response.data.success).toBeTruthy() + expect(response.data).toHaveProperty('data') + }) + + it('should return 403 without x-auth', async () => { + delete utils.headers['x-auth'] + const response = await utils.GET('internal/rounds/current') + + expect(response.status).toBe(403) }) }) - describe('POST /block', () => { + describe('POST /blocks', () => { it('should be ok', async () => { - const response = await sendPOST('block', genesisBlock.toBroadcastV1()) - - expect(response.status).toBe(200) + const block = new Block(blockFixture.data) + const response = await utils.POST('internal/blocks', { + block: block.toJson(), + }) + expect(response.status).toBe(204) + }) - expect(response.data).toBeObject() + it('should return 403 without x-auth', async () => { + delete utils.headers['x-auth'] + const response = await utils.POST('internal/blocks', { + block: genesisBlock.toJson(), + }) - expect(response.data).toHaveProperty('success') - expect(response.data.success).toBeTruthy() + expect(response.status).toBe(403) }) }) - describe.skip('POST /verifyTransaction', () => { + describe('POST /transactions/verify', () => { it('should be ok', async () => { - const response = await sendPOST('verifyTransaction', { - transaction: genesisTransaction + const transaction = genTransfer('testnet')[0] + const response = await utils.POST('internal/transactions/verify', { + transaction: Transaction.serialize(transaction).toString('hex'), }) expect(response.status).toBe(200) expect(response.data).toBeObject() - expect(response.data).toHaveProperty('success') - expect(response.data.success).toBeTruthy() + expect(response.data).toHaveProperty('data') + }) + + it('should return 403 without x-auth', async () => { + delete utils.headers['x-auth'] + const response = await utils.POST('internal/transactions/verify', { + transaction: genesisTransaction, + }) + + expect(response.status).toBe(403) }) }) - describe('GET /forgingTransactions', () => { + describe('GET /transactions/forging', () => { it('should be ok', async () => { - const response = await sendGET('forgingTransactions') + const response = await utils.GET('internal/transactions/forging') expect(response.status).toBe(200) expect(response.data).toBeObject() - expect(response.data).toHaveProperty('success') - expect(response.data.success).toBeTruthy() + expect(response.data).toHaveProperty('data') + }) + + it('should return 403 without x-auth', async () => { + delete utils.headers['x-auth'] + const response = await utils.GET('internal/transactions/forging') + + expect(response.status).toBe(403) }) }) - describe('GET /networkState', () => { + describe('GET /network/state', () => { it('should be ok', async () => { - const response = await sendGET('networkState') + const response = await utils.GET('internal/network/state') expect(response.status).toBe(200) expect(response.data).toBeObject() - expect(response.data).toHaveProperty('success') - expect(response.data.success).toBeTruthy() + expect(response.data).toHaveProperty('data') + }) + + it('should return 403 without x-auth', async () => { + delete utils.headers['x-auth'] + const response = await utils.GET('internal/network/state') + + expect(response.status).toBe(403) }) }) }) diff --git a/packages/core-p2p/__tests__/utils/check-dns.test.js b/packages/core-p2p/__tests__/utils/check-dns.test.js index 2811f04cb4..68f389f5da 100644 --- a/packages/core-p2p/__tests__/utils/check-dns.test.js +++ b/packages/core-p2p/__tests__/utils/check-dns.test.js @@ -1,5 +1,3 @@ -'use strict' - const app = require('../__support__/setup') let checker diff --git a/packages/core-p2p/__tests__/utils/check-ntp.test.js b/packages/core-p2p/__tests__/utils/check-ntp.test.js index ec7e8ecd9f..5cee0056a0 100644 --- a/packages/core-p2p/__tests__/utils/check-ntp.test.js +++ b/packages/core-p2p/__tests__/utils/check-ntp.test.js @@ -1,5 +1,3 @@ -'use strict' - const app = require('../__support__/setup') let checker @@ -17,10 +15,7 @@ beforeEach(() => { }) describe('Check NTP', () => { - const hosts = [ - 'pool.ntp.org', - 'time.google.com' - ] + const hosts = ['pool.ntp.org', 'time.google.com'] const host = hosts[0] it('should be a function', () => { @@ -36,24 +31,11 @@ describe('Check NTP', () => { expect(response.time.t).toBeNumber() }) - xit('should try to connect to hosts randomly', () => { - }) - - describe('when a host is not avaible', () => { - xit('logs the error', () => { - }) - }) - - describe('when a host times out', () => { - xit('logs the error', () => { - }) - }) - describe('when none of the host could be reached', () => { it('produces an error', async () => { try { await checker(['notime.unknown.not']) - expect().fail('An error should have been thrown') + throw new Error('An error should have been thrown') } catch (error) { expect(error.message).toMatch(/ntp.*connect/i) } diff --git a/packages/core-p2p/__tests__/utils/is-myself.test.js b/packages/core-p2p/__tests__/utils/is-myself.test.js index ef589c85e2..cc9e941dab 100644 --- a/packages/core-p2p/__tests__/utils/is-myself.test.js +++ b/packages/core-p2p/__tests__/utils/is-myself.test.js @@ -1,7 +1,5 @@ -'use strict' - -const isMyself = require('../../lib/utils/is-myself') const os = require('os') +const isMyself = require('../../lib/utils/is-myself') describe('isMyself', () => { it('should be a function', () => { @@ -9,14 +7,14 @@ describe('isMyself', () => { }) it('should be ok for localhost addresses', () => { - expect(isMyself('127.0.0.1')).toBeTruthy() - expect(isMyself('::1')).toBeTruthy() - expect(isMyself('192.167.22.1')).toBeFalsy() + expect(isMyself('127.0.0.1')).toBeTrue() + + expect(isMyself('192.167.22.1')).toBeFalse() }) it('should be ok for LAN addresses', () => { const interfaces = os.networkInterfaces() - let addresses = [] + const addresses = [] // getting local addresses Object.keys(interfaces).forEach(ifname => { @@ -24,7 +22,7 @@ describe('isMyself', () => { }) addresses.forEach(ipAddress => { - expect(isMyself(ipAddress)).toBeTruthy() + expect(isMyself(ipAddress)).toBeTrue() }) }) }) diff --git a/packages/core-p2p/__tests__/utils/is-whitelist.test.js b/packages/core-p2p/__tests__/utils/is-whitelist.test.js index 123483f98a..4d16aa68f8 100644 --- a/packages/core-p2p/__tests__/utils/is-whitelist.test.js +++ b/packages/core-p2p/__tests__/utils/is-whitelist.test.js @@ -1,12 +1,6 @@ -'use strict' - const isWhitelist = require('../../lib/utils/is-whitelist') -const whitelisted = [ - '127.0.0.1', - '::ffff:127.0.0.1', - '192.168.*' -] +const whitelisted = ['127.0.0.1', '::ffff:127.0.0.1'] describe('isWhitelist', () => { it('should be a function', () => { @@ -14,18 +8,14 @@ describe('isWhitelist', () => { }) it('should be ok for 127.0.0.1', () => { - expect(isWhitelist(whitelisted, '127.0.0.1')).toBeTruthy() + expect(isWhitelist(whitelisted, '127.0.0.1')).toBeTrue() }) it('should be ok for ::ffff:127.0.0.1', () => { - expect(isWhitelist(whitelisted, '::ffff:127.0.0.1')).toBeTruthy() - }) - - it('should be ok for 192.168.0.10', () => { - expect(isWhitelist(whitelisted, '192.168.0.10')).toBeTruthy() + expect(isWhitelist(whitelisted, '::ffff:127.0.0.1')).toBeTrue() }) it('should not be ok', () => { - expect(isWhitelist(whitelisted, 'dummy')).toBeFalsy() + expect(isWhitelist(whitelisted, 'dummy')).toBeFalse() }) }) diff --git a/packages/core-p2p/jest.config.js b/packages/core-p2p/jest.config.js index d58c9e94c1..9b709ac547 100644 --- a/packages/core-p2p/jest.config.js +++ b/packages/core-p2p/jest.config.js @@ -1,22 +1,12 @@ -'use strict' - module.exports = { testEnvironment: 'node', bail: false, verbose: false, - testMatch: [ - '**/__tests__/**/*.test.js' - ], - moduleFileExtensions: [ - 'js', - 'json' - ], + testMatch: ['**/__tests__/**/*.test.js'], + moduleFileExtensions: ['js', 'json'], collectCoverage: false, coverageDirectory: '/.coverage', - collectCoverageFrom: [ - 'lib/**/*.js', - '!**/node_modules/**' - ], + collectCoverageFrom: ['lib/**/*.js', '!**/node_modules/**'], watchman: false, - setupTestFrameworkScriptFile: 'jest-extended' + setupTestFrameworkScriptFile: 'jest-extended', } diff --git a/packages/core-p2p/jsdoc.json b/packages/core-p2p/jsdoc.json index 23276f74ea..f3ea8aab33 100644 --- a/packages/core-p2p/jsdoc.json +++ b/packages/core-p2p/jsdoc.json @@ -7,9 +7,7 @@ "includePattern": ".js$", "excludePattern": "(node_modules/|docs)" }, - "plugins": [ - "plugins/markdown" - ], + "plugins": ["plugins/markdown"], "opts": { "template": "../../node_modules/docdash", "encoding": "utf8", diff --git a/packages/core-p2p/lib/court/guard.js b/packages/core-p2p/lib/court/guard.js new file mode 100644 index 0000000000..8656efd516 --- /dev/null +++ b/packages/core-p2p/lib/court/guard.js @@ -0,0 +1,315 @@ +const app = require('@arkecosystem/core-container') +const dayjs = require('dayjs-ext') +const head = require('lodash/head') +const prettyMs = require('pretty-ms') +const semver = require('semver') +const sumBy = require('lodash/sumBy') + +const config = app.resolvePlugin('config') +const logger = app.resolvePlugin('logger') + +const isMyself = require('../utils/is-myself') +const offences = require('./offences') + +class Guard { + /** + * Create a new guard instance. + */ + constructor() { + this.suspensions = {} + } + + /** + * Initialise a new guard. + * @param {Monitor} monitor + */ + init(monitor) { + this.monitor = monitor + + return this + } + + /** + * Get a list of all suspended peers. + * @return {Object} + */ + all() { + return this.suspensions + } + + /** + * Get the suspended peer for the give IP. + * @return {Object} + */ + get(ip) { + return this.suspensions[ip] + } + + /** + * Suspends a peer unless whitelisted. + * @param {Peer} peer + */ + suspend(peer) { + if (config.peers.whiteList && config.peers.whiteList.includes(peer.ip)) { + return + } + + if (peer.offences.length > 0) { + if (dayjs().isAfter(head(peer.offences).until)) { + peer.offences = [] + } + } + + const offence = this.__determineOffence(peer) + + peer.offences.push(offence) + + this.suspensions[peer.ip] = { + peer, + until: offence.until, + reason: offence.reason, + } + + this.monitor.removePeer(peer) + } + + /** + * Remove a suspended peer. + * @param {Peer} peer + * @return {void} + */ + async unsuspend(peer) { + if (!this.suspensions[peer.ip]) { + return + } + + // Don't unsuspend critical offenders before the ban is expired. + if (peer.offences.some(offence => offence.critical)) { + if (dayjs().isBefore(this.suspensions[peer.ip].until)) { + return + } + } + + delete this.suspensions[peer.ip] + delete peer.nextSuspensionReminder + + await this.monitor.acceptNewPeer(peer) + } + + /** + * Reset suspended peers + * @return {void} + */ + async resetSuspendedPeers() { + logger.info('Clearing suspended peers.') + await Promise.all( + Object.values(this.suspensions).map(suspension => + this.unsuspend(suspension.peer), + ), + ) + } + + /** + * Determine if peer is suspended or not. + * @param {Peer} peer + * @return {Boolean} + */ + isSuspended(peer) { + const suspendedPeer = this.get(peer.ip) + + if (suspendedPeer && dayjs().isBefore(suspendedPeer.until)) { + const nextSuspensionReminder = suspendedPeer.nextSuspensionReminder + + if (!nextSuspensionReminder || dayjs().isAfter(nextSuspensionReminder)) { + const untilDiff = suspendedPeer.until.diff(dayjs()) + + logger.debug( + `${peer.ip} still suspended for ${prettyMs(untilDiff, { + verbose: true, + })} because of "${suspendedPeer.reason}".`, + ) + + suspendedPeer.nextSuspensionReminder = dayjs().add(5, 'm') + } + + return true + } + + if (suspendedPeer) { + delete this.suspensions[peer.ip] + } + + return false + } + + /** + * Determine if the peer is whitelisted. + * @param {Peer} peer + * @return {Boolean} + */ + isWhitelisted(peer) { + return config.peers.whiteList.includes(peer.ip) + } + + /** + * Determine if the peer is blacklisted. + * @param {Peer} peer + * @return {Boolean} + */ + isBlacklisted(peer) { + return config.peers.blackList.includes(peer.ip) + } + + /** + * Determine if the peer is within the version constraints. + * @param {Peer} peer + * @return {Boolean} + */ + isValidVersion(peer) { + const version = peer.version || (peer.headers && peer.headers.version) + return semver.satisfies(version, config.peers.minimumVersion) + } + + /** + * Determine if the peer is on the right network. + * @param {Peer} peer + * @return {Boolean} + */ + isValidNetwork(peer) { + const nethash = peer.nethash || (peer.headers && peer.headers.nethash) + return nethash === config.network.nethash + } + + /** + * Determine if the peer has a valid port. + * @param {Peer} peer + * @return {Boolean} + */ + isValidPort(peer) { + return peer.port === app.resolveOptions('p2p').port + } + + /** + * Determine if the peer is localhost. + * @param {Peer} peer + * @return {Boolean} + */ + isMyself(peer) { + return isMyself(peer.ip) + } + + /** + * Decide if the given peer is a repeat offender. + * @param {Object} peer + * @return {Boolean} + */ + isRepeatOffender(peer) { + return sumBy(peer.offences, 'weight') >= 150 + } + + /** + * Decide for how long the peer should be banned. + * @param {Peer} peer + * @return {dayjs} + */ + __determineOffence(peer) { + if (this.isBlacklisted(peer)) { + return this.__determinePunishment(peer, offences.BLACKLISTED) + } + + try { + const state = app.resolve('state') + + if (state.forkedBlock && peer.ip === state.forkedBlock.ip) { + return this.__determinePunishment(peer, offences.FORK) + } + } catch (error) { + logger.warn( + `The state storage is not ready, skipped fork check for ${peer.ip}.`, + ) + } + + if (peer.commonBlocks === false) { + delete peer.commonBlocks + + return this.__determinePunishment(peer, offences.NO_COMMON_BLOCKS) + } + + if (peer.commonId === false) { + delete peer.commonId + + return this.__determinePunishment(peer, offences.NO_COMMON_ID) + } + + // NOTE: We check this extra because a response can still succeed if + // it returns any codes that are not 4xx or 5xx. + if (peer.status === 503) { + return this.__determinePunishment(peer, offences.BLOCKCHAIN_NOT_READY) + } + + if (peer.status === 429) { + return this.__determinePunishment(peer, offences.TOO_MANY_REQUESTS) + } + + if (peer.status && peer.status !== 200) { + return this.__determinePunishment(peer, offences.INVALID_STATUS) + } + + if (peer.delay === -1) { + return this.__determinePunishment(peer, offences.TIMEOUT) + } + + if (peer.delay > 2000) { + return this.__determinePunishment(peer, offences.HIGH_LATENCY) + } + + if (!this.isValidNetwork(peer)) { + return this.__determinePunishment(peer, offences.INVALID_NETWORK) + } + + if (!this.isValidVersion(peer)) { + return this.__determinePunishment(peer, offences.INVALID_VERSION) + } + + // NOTE: Suspending this peer only means that we no longer + // will download blocks from him but he can still download blocks from us. + const heightDifference = Math.abs( + this.monitor.getNetworkHeight() - peer.state.height, + ) + + if (heightDifference >= 153) { + return this.__determinePunishment(peer, offences.INVALID_HEIGHT) + } + + return this.__determinePunishment(peer, offences.UNKNOWN) + } + + /** + * Compile the information about the punishment the peer will face. + * @param {Object} peer + * @param {Object} offence + * @return {Object} + */ + __determinePunishment(peer, offence) { + if (this.isRepeatOffender(peer)) { + offence = offences.REPEAT_OFFENDER + } + + const until = dayjs().add(offence.number, offence.period) + const untilDiff = until.diff(dayjs()) + + logger.debug( + `Suspended ${peer.ip} for ${prettyMs(untilDiff, { + verbose: true, + })} because of "${offence.reason}"`, + ) + + return { + until, + reason: offence.reason, + weight: offence.weight, + } + } +} + +module.exports = new Guard() diff --git a/packages/core-p2p/lib/court/index.js b/packages/core-p2p/lib/court/index.js new file mode 100644 index 0000000000..1fb69f49f6 --- /dev/null +++ b/packages/core-p2p/lib/court/index.js @@ -0,0 +1,3 @@ +module.exports = { + guard: require('./guard'), +} diff --git a/packages/core-p2p/lib/court/offences.js b/packages/core-p2p/lib/court/offences.js new file mode 100644 index 0000000000..ca48eff938 --- /dev/null +++ b/packages/core-p2p/lib/court/offences.js @@ -0,0 +1,89 @@ +module.exports = { + BLACKLISTED: { + number: 12, + period: 'hours', + reason: 'Blacklisted', + weight: 10, + }, + NO_COMMON_BLOCKS: { + number: 5, + period: 'minutes', + reason: 'No Common Blocks', + weight: 1, + critical: true, + }, + NO_COMMON_ID: { + number: 5, + period: 'minutes', + reason: 'No Common Id', + weight: 1, + critical: true, + }, + INVALID_VERSION: { + number: 6, + period: 'hours', + reason: 'Invalid Version', + weight: 7, + }, + INVALID_HEIGHT: { + number: 10, + period: 'minutes', + reason: 'Node is not at height', + weight: 5, + }, + INVALID_NETWORK: { + number: 5, + period: 'minutes', + reason: 'Invalid Network', + weight: 5, + }, + INVALID_STATUS: { + number: 5, + period: 'minutes', + reason: 'Invalid Response Status', + weight: 3, + }, + TIMEOUT: { + number: 2, + period: 'minutes', + reason: 'Timeout', + weight: 2, + }, + HIGH_LATENCY: { + number: 1, + period: 'minutes', + reason: 'High Latency', + weight: 1, + }, + BLOCKCHAIN_NOT_READY: { + number: 30, + period: 'seconds', + reason: 'Blockchain not ready', + weight: 0, + }, + TOO_MANY_REQUESTS: { + number: 60, + period: 'seconds', + reason: 'Rate limit exceeded', + weight: 0, + }, + UNKNOWN: { + number: 30, + period: 'minutes', + reason: 'Unknown', + weight: 5, + }, + REPEAT_OFFENDER: { + number: 1, + period: 'day', + reason: 'Repeat Offender', + weight: 100, + }, + FORK: { + number: 1, + period: 'day', + reason: 'Fork', + weight: 150, + critical: true, + }, +} diff --git a/packages/core-p2p/lib/defaults.js b/packages/core-p2p/lib/defaults.js index e6720ca626..211e99f2d6 100644 --- a/packages/core-p2p/lib/defaults.js +++ b/packages/core-p2p/lib/defaults.js @@ -1,9 +1,7 @@ -'use strict' - module.exports = { + host: process.env.ARK_P2P_HOST || '0.0.0.0', port: process.env.ARK_P2P_PORT || 4002, - remoteinterface: true, - suspendMinutes: 60, + remoteInterface: false, dns: [ // Google '8.8.8.8', @@ -13,14 +11,19 @@ module.exports = { '1.0.0.1', // OpenDNS '208.67.222.222', - '208.67.220.220' + '208.67.220.220', ], - ntp: [ - 'pool.ntp.org', - 'time.google.com' - ], - whitelist: [ - '127.0.0.1', - '::ffff:127.0.0.1' - ] + ntp: ['pool.ntp.org', 'time.google.com'], + whitelist: ['127.0.0.1', '::ffff:127.0.0.1'], + // @see https://github.com/wraithgar/hapi-rate-limit + rateLimit: { + enabled: true, + pathLimit: false, + userLimit: 20, + userCache: { + expiresIn: 1000, + }, + ipWhitelist: ['127.0.0.1', '::ffff:127.0.0.1'], + }, + maxPeersBroadcast: 20, } diff --git a/packages/core-p2p/lib/guard.js b/packages/core-p2p/lib/guard.js deleted file mode 100644 index e32065068b..0000000000 --- a/packages/core-p2p/lib/guard.js +++ /dev/null @@ -1,131 +0,0 @@ -'use strict' - -const moment = require('moment') -const semver = require('semver') -const container = require('@arkecosystem/core-container') -const logger = container.resolvePlugin('logger') -const isMyself = require('./utils/is-myself') - -class Guard { - /** - * Create a new guard instance. - */ - constructor () { - this.suspensions = {} - } - - /** - * Initialise a new guard. - * @param {Monitor} monitor - */ - init (monitor) { - this.monitor = monitor - this.config = monitor.config.peers - - return this - } - - /** - * Get a list of all suspended peers. - * @return {Object} - */ - all () { - return this.suspensions - } - - /** - * Get the suspended peer for the give IP. - * @return {Object} - */ - get (ip) { - return this.suspensions[ip] - } - - /** - * Suspends a peer unless whitelisted. - * @param {Peer} peer - */ - suspend (peer) { - if (this.config.whiteList && this.config.whiteList.includes(peer.ip)) { - return - } - - const until = moment().add(this.monitor.manager.config.suspendMinutes, 'minutes') - - this.suspensions[peer.ip] = { - peer, - until, - untilHuman: until.format('h [hrs], m [min]') - } - - delete this.monitor.peers[peer.ip] - - logger.debug(`Suspended ${peer.ip} for ` + this.get(peer.ip).untilHuman) - } - - /** - * Determine if peer is suspended or not. - * @param {Peer} peer - * @return {Boolean} - */ - isSuspended (peer) { - const suspendedPeer = this.get(peer.ip) - - if (suspendedPeer && moment().isBefore(suspendedPeer.until)) { - logger.debug(`${peer.ip} still suspended for ` + suspendedPeer.untilHuman) - - return true - } else if (suspendedPeer) { - delete this.suspensions[peer.ip] - } - - return false - } - - /** - * Determine if the peer is whitelisted. - * @param {Peer} peer - * @return {Boolean} - */ - isWhitelisted (peer) { - return this.config.whiteList.includes(peer.ip) - } - - /** - * Determine if the peer is blacklisted. - * @param {Peer} peer - * @return {Boolean} - */ - isBlacklisted (peer) { - return this.config.blackList.includes(peer.ip) - } - - /** - * Determine if the peer is within the version constraints. - * @param {Peer} peer - * @return {Boolean} - */ - isValidVersion (peer) { - return semver.satisfies(peer.version, this.config.minimumVersion) - } - - /** - * Determine if the peer has a valid port. - * @param {Peer} peer - * @return {Boolean} - */ - isValidPort (peer) { - return peer.port === container.resolveOptions('p2p').port - } - - /** - * Determine if the peer is localhost. - * @param {Peer} peer - * @return {Boolean} - */ - isMyself (peer) { - return isMyself(peer.ip) - } -} - -module.exports = new Guard() diff --git a/packages/core-p2p/lib/index.js b/packages/core-p2p/lib/index.js index ac92d3fa2b..bb7eda1474 100644 --- a/packages/core-p2p/lib/index.js +++ b/packages/core-p2p/lib/index.js @@ -1,6 +1,5 @@ -'use strict' - -const PeerManager = require('./manager') +const monitor = require('./monitor') +const startServer = require('./server') /** * The struct used by the plugin container. @@ -10,14 +9,21 @@ exports.plugin = { pkg: require('../package.json'), defaults: require('./defaults'), alias: 'p2p', - async register (container, options) { + async register(container, options) { container.resolvePlugin('logger').info('Starting P2P Interface') - return (new PeerManager(options)).start() + monitor.server = await startServer(monitor, options) + + await monitor.start(options) + + return monitor }, - async deregister (container, options) { + async deregister(container, options) { container.resolvePlugin('logger').info('Stopping P2P Interface') - return container.resolvePlugin('p2p').stop() - } + const p2p = container.resolvePlugin('p2p') + p2p.dumpPeers() + + return p2p.server.stop() + }, } diff --git a/packages/core-p2p/lib/manager.js b/packages/core-p2p/lib/manager.js deleted file mode 100755 index 81f85524e9..0000000000 --- a/packages/core-p2p/lib/manager.js +++ /dev/null @@ -1,174 +0,0 @@ -'use strict' - -const logger = require('@arkecosystem/core-container').resolvePlugin('logger') - -const checkDNS = require('./utils/check-dns') -const checkNTP = require('./utils/check-ntp') -const Monitor = require('./monitor') -const startServer = require('./server') - -module.exports = class PeerManager { - /** - * @constructor - * @param {Object} config - */ - constructor (config) { - this.config = config - this.monitor = new Monitor(this) - } - - /** - * Start P2P interface. - * @param {Boolean} networkStart - */ - async start () { - await this.__checkDNSConnectivity() - await this.__checkNTPConnectivity() - - this.api = await startServer(this, this.config) - - await this.monitor.start(this.config.networkStart) - - return this - } - - /** - * Shutdown P2P interface. - */ - async stop () { - return this.api.stop() - } - - /** - * Update network status. - * @return {Promise} - */ - async updateNetworkStatus () { - await this.monitor.updateNetworkStatus() - } - - /** - * Download blocks from a random peer. - * @param {Number} fromBlockHeight - * @return {Object[]} - */ - downloadBlocks (fromBlockHeight) { - return this.monitor.downloadBlocks(fromBlockHeight) - } - - /** - * Broadcast block to all peers. - * @param {Block} block - */ - async broadcastBlock (block) { - await this.monitor.broadcastBlock(block) - } - - /** - * Broadcast transactions to peers. - * @param {Transaction[]} transactions - */ - broadcastTransactions (transactions) { - return this.monitor.broadcastTransactions(transactions) - } - - /** - * Accept a new peer to the node. - * @param {Peer} peer - * @return {Promise} - */ - acceptNewPeer (peer) { - return this.monitor.acceptNewPeer(peer) - } - - /** - * ban an existing peer. - * @param {Peer} peer - * @return {Promise} - */ - banPeer (ip) { - return this.monitor.banPeer(ip) - } - - /** - * Get peers. - * @return {Peer[]} - */ - getPeers () { - return this.monitor.getPeers() - } - - /** - * Get the peer for the given IP address. - * @return {Peer} - */ - getPeer (ip) { - return this.monitor.getPeer(ip) - } - - /** - * Get a random peer. - * @return {Peer} - */ - getRandomPeer () { - return this.monitor.getRandomPeer() - } - - /** - * Get a list of all suspended peers. - * @return {Object} - */ - getSuspendedPeers () { - return this.monitor.getSuspendedPeers() - } - - /** - * Get the peer monitor. - * @return {Object} - */ - getMonitor () { - return this.monitor - } - - /** - * Get network height. - * @return {Number} - */ - getNetworkHeight () { - return this.monitor.getNetworkHeight() - } - - async getNetworkState () { - return this.monitor.getNetworkState() - } - - /** - * Check if the node can connect to any DNS host. - * @return {void} - */ - async __checkDNSConnectivity () { - try { - const host = await checkDNS(this.config.dns) - - logger.info(`Your network connectivity has been verified by ${host}`) - } catch (error) { - logger.error(error.message) - } - } - - /** - * Check if the node can connect to any NTP host. - * @return {void} - */ - async __checkNTPConnectivity () { - try { - const { host, time } = await checkNTP(this.config.ntp) - - logger.info(`Your NTP connectivity has been verified by ${host}`) - - logger.info('Local clock is off by ' + parseInt(time.t) + 'ms from NTP :alarm_clock:') - } catch (error) { - logger.error(error.message) - } - } -} diff --git a/packages/core-p2p/lib/monitor.js b/packages/core-p2p/lib/monitor.js index 08d3298383..28686cebe3 100755 --- a/packages/core-p2p/lib/monitor.js +++ b/packages/core-p2p/lib/monitor.js @@ -1,191 +1,335 @@ -'use strict' +/* eslint no-restricted-globals: "off" */ const prettyMs = require('pretty-ms') -const moment = require('moment') +const fs = require('fs') +const dayjs = require('dayjs-ext') const delay = require('delay') +const flatten = require('lodash/flatten') +const groupBy = require('lodash/groupBy') +const sample = require('lodash/sample') +const shuffle = require('lodash/shuffle') +const take = require('lodash/take') +const pluralize = require('pluralize') const { slots } = require('@arkecosystem/crypto') -const container = require('@arkecosystem/core-container') -const config = container.resolvePlugin('config') -const logger = container.resolvePlugin('logger') -const emitter = container.resolvePlugin('event-emitter') +const app = require('@arkecosystem/core-container') + +const config = app.resolvePlugin('config') +const logger = app.resolvePlugin('logger') +const emitter = app.resolvePlugin('event-emitter') const Peer = require('./peer') -const guard = require('./guard') +const { guard } = require('./court') const networkState = require('./utils/network-state') -module.exports = class Monitor { +const checkDNS = require('./utils/check-dns') +const checkNTP = require('./utils/check-ntp') + +class Monitor { /** * @constructor - * @param {PeerManager} manager * @throws {Error} If no seed peers */ - constructor (manager) { - this.manager = manager - this.config = config + constructor() { this.peers = {} - this.guard = guard.init(this) - this.startForgers = moment().add(this.config.peers.coldStart || 30, 'seconds') + this.coldStartPeriod = dayjs().add(config.peers.coldStart || 30, 'seconds') + + // Holds temporary peers which are in the process of being accepted. Prevents that + // peers who are not accepted yet, but send multiple requests in a short timeframe will + // get processed multiple times in `acceptNewPeer`. + this.pendingPeers = {} } /** * Method to run on startup. - * @param {Boolean} networkStart + * @param {Object} options */ - async start (networkStart = false) { + async start(options) { + this.config = options + + await this.__checkDNSConnectivity(options.dns) + await this.__checkNTPConnectivity(options.ntp) + + this.guard = guard.init(this) + this.__filterPeers() - if (!networkStart) { - await this.updateNetworkStatus() + if (this.config.skipDiscovery) { + logger.warn( + 'Skipped peer discovery because the relay is in skip-discovery mode.', + ) + } else { + await this.updateNetworkStatus(options.networkStart) + + for (const [version, peers] of Object.entries( + groupBy(this.peers, 'version'), + )) { + logger.info( + `Discovered ${pluralize( + 'peer', + peers.length, + true, + )} with v${version}.`, + ) + } + + if (config.network.name !== 'mainnet') { + for (const [hashid, peers] of Object.entries( + groupBy(this.peers, 'hashid'), + )) { + logger.info( + `Discovered ${pluralize( + 'peer', + peers.length, + true, + )} on commit ${hashid}.`, + ) + } + } } + + return this } /** * Update network status (currently only peers are updated). + * @param {Boolean} networkStart * @return {Promise} */ - async updateNetworkStatus (fast = false) { + async updateNetworkStatus(networkStart) { + if (process.env.NODE_ENV === 'test') { + return + } + + if (networkStart) { + logger.warn( + 'Skipped peer discovery because the relay is in genesis-start mode.', + ) + return + } + + if (this.config.disableDiscovery) { + logger.warn( + 'Skipped peer discovery because the relay is in non-discovery mode.', + ) + return + } + try { - // TODO: for tests that involve peers we need to sync them if (process.env.ARK_ENV !== 'test') { await this.discoverPeers() await this.cleanPeers() - } - if (Object.keys(this.peers).length < this.config.peers.list.length - 1 && process.env.ARK_ENV !== 'test') { - this.config.peers.list - .forEach(peer => (this.peers[peer.ip] = new Peer(peer.ip, peer.port)), this) + if (!this.hasMinimumPeers()) { + this.__addPeers(config.peers.list) + + logger.info("Couldn't find enough peers, trying again in 5 seconds.") - return this.updateNetworkStatus() + await delay(5000) + + return this.updateNetworkStatus() + } } } catch (error) { logger.error(`Network Status: ${error.message}`) - this.config.peers.list.forEach(peer => (this.peers[peer.ip] = new Peer(peer.ip, peer.port)), this) + this.__addPeers(config.peers.list) + + logger.info('Failed to discover peers, trying again in 5 seconds.') + + if (process.env.NODE_ENV !== 'test') { + await delay(5000) + } return this.updateNetworkStatus() } } + /** + * Updates the network status if not enough peers are available. + * NOTE: This is usually only necessary for nodes without incoming requests, + * since the available peers are depleting over time due to suspensions. + * @return {void} + */ + async updateNetworkStatusIfNotEnoughPeers() { + if (!this.hasMinimumPeers() && process.env.ARK_ENV !== 'test') { + await this.updateNetworkStatus(this.config.networkStart) + } + } + + /** + * Returns if the minimum amount of peers are available. + * @return {Boolean} + */ + hasMinimumPeers() { + return Object.keys(this.peers).length >= config.peers.minimumNetworkReach + } + /** * Accept and store a valid peer. * @param {Peer} peer * @throws {Error} If invalid peer */ - async acceptNewPeer (peer) { - if (this.guard.isSuspended(peer) || this.guard.isMyself(peer) || process.env.ARK_ENV === 'test') { + async acceptNewPeer(peer) { + if (this.config.disableDiscovery && !this.pendingPeers[peer.ip]) { + logger.warn( + `Rejected ${peer.ip} because the relay is in non-discovery mode.`, + ) return } - if (this.guard.isBlacklisted(peer.ip)) { - logger.debug(`Rejected peer ${peer.ip} as it is blacklisted`) + if ( + this.guard.isSuspended(peer) || + this.guard.isMyself(peer) || + this.pendingPeers[peer.ip] || + process.env.ARK_ENV === 'test' + ) { + return + } - this.guard.suspend(peer) + const newPeer = new Peer(peer.ip, peer.port) + newPeer.setHeaders(peer) - return + if (this.guard.isBlacklisted(peer)) { + logger.debug(`Rejected peer ${peer.ip} as it is blacklisted`) + + return this.guard.suspend(newPeer) } if (!this.guard.isValidVersion(peer) && !this.guard.isWhitelisted(peer)) { - logger.debug(`Rejected peer ${peer.ip} as it doesn't meet the minimum version requirements. Expected: ${this.config.peers.minimumVersion} - Received: ${peer.version}`) + logger.debug( + `Rejected peer ${ + peer.ip + } as it doesn't meet the minimum version requirements. Expected: ${ + config.peers.minimumVersion + } - Received: ${peer.version}`, + ) + + return this.guard.suspend(newPeer) + } - this.guard.suspend(peer) + if (!this.guard.isValidNetwork(peer)) { + logger.debug( + `Rejected peer ${peer.ip} as it isn't on the same network. Expected: ${ + config.network.nethash + } - Received: ${peer.nethash}`, + ) - return + return this.guard.suspend(newPeer) } if (this.getPeer(peer.ip)) { return } - if (peer.nethash !== this.config.network.nethash) { - throw new Error('Request is made on the wrong network') - } - - const newPeer = new Peer(peer.ip, peer.port) - try { + this.pendingPeers[peer.ip] = true + await newPeer.ping(1500) this.peers[peer.ip] = newPeer + logger.debug(`Accepted new peer ${newPeer.ip}:${newPeer.port}`) emitter.emit('peer.added', newPeer) } catch (error) { - logger.debug(`Could not accept new peer '${newPeer.ip}:${newPeer.port}' - ${error}`) + logger.debug( + `Could not accept new peer '${newPeer.ip}:${newPeer.port}' - ${error}`, + ) this.guard.suspend(newPeer) - // we don't throw since we answer unreacheable peer - // TODO: in next version, only accept to answer to sound peers that have properly registered - // hence we will throw an error + } finally { + delete this.pendingPeers[peer.ip] } } + /** + * Remove peer from monitor. + * @param {Peer} peer + */ + removePeer(peer) { + delete this.peers[peer.ip] + } + /** * Clear peers which aren't responding. * @param {Boolean} fast + * @param {Boolean} tracker + * @param {Boolean} forcePing */ - async cleanPeers (fast = false, tracker = true) { - let keys = Object.keys(this.peers) + async cleanPeers(fast = false, tracker = true, forcePing = false) { + const keys = Object.keys(this.peers) let count = 0 let unresponsivePeers = 0 - const pingDelay = fast ? 1500 : this.config.peers.globalTimeout + const pingDelay = fast ? 1500 : config.peers.globalTimeout const max = keys.length logger.info(`Checking ${max} peers :telescope:`) - await Promise.all(keys.map(async (ip) => { - try { - await this.getPeer(ip).ping(pingDelay) - - if (tracker) { - logger.printTracker('Peers Discovery', ++count, max) - } - } catch (error) { - unresponsivePeers++ + await Promise.all( + keys.map(async ip => { + const peer = this.getPeer(ip) + try { + await peer.ping(pingDelay, forcePing) + + if (tracker) { + logger.printTracker('Peers Discovery', ++count, max) + } + } catch (error) { + unresponsivePeers++ - const formattedDelay = prettyMs(pingDelay, { verbose: true }) - logger.debug(`Removed peer ${ip} because it didn't respond within ${formattedDelay}.`) - emitter.emit('peer.removed', this.getPeer(ip)) + const formattedDelay = prettyMs(pingDelay, { verbose: true }) + logger.debug( + `Removed peer ${ip} because it didn't respond within ${formattedDelay}.`, + ) + emitter.emit('peer.removed', peer) - delete this.peers[ip] + this.removePeer(peer) - return null - } - })) + return null + } + }), + ) if (tracker) { logger.stopTracker('Peers Discovery', max, max) - logger.info(`${max - unresponsivePeers} of ${max} peers on the network are responsive`) - logger.info(`Median Network Height: ${this.getNetworkHeight()}`) + logger.info( + `${max - + unresponsivePeers} of ${max} peers on the network are responsive`, + ) + logger.info( + `Median Network Height: ${this.getNetworkHeight().toLocaleString()}`, + ) logger.info(`Network PBFT status: ${this.getPBFTForgingStatus()}`) } } /** - * ban an existing peer. + * Suspend an existing peer. * @param {Peer} peer - * @return {Promise} + * @return {void} */ - banPeer (ip) { - // TODO make a couple of tests on peer to understand the issue with this peer and decide how long to ban it + suspendPeer(ip) { const peer = this.peers[ip] - if (peer) { - if (this.guard.isSuspended(peer)) { - this.guard.suspensions[ip].until = moment(this.guard.suspensions[ip].until).add(1, 'day') - } else { - this.guard.suspend(peer) - } - - logger.debug(`Banned peer ${ip} for ${this.guard.get(ip).untilHuman}`) + if (peer && !this.guard.isSuspended(peer)) { + this.guard.suspend(peer) } } + /** + * Get a list of all suspended peers. + * @return {void} + */ + getSuspendedPeers() { + return this.guard.all() + } + /** * Get all available peers. * @return {Peer[]} */ - getPeers () { + getPeers() { return Object.values(this.peers) } @@ -194,14 +338,16 @@ module.exports = class Monitor { * @param {String} ip * @return {Peer} */ - getPeer (ip) { + getPeer(ip) { return this.peers[ip] } - async peerHasCommonBlocks (peer, blockIds) { + async peerHasCommonBlocks(peer, blockIds) { if (!this.guard.isMyself(peer) && !(await peer.hasCommonBlocks(blockIds))) { logger.error(`Could not get common block for ${peer.ip}`) + peer.commonBlocks = false + this.guard.suspend(peer) return false @@ -215,35 +361,36 @@ module.exports = class Monitor { * @param {(Number|undefined)} acceptableDelay * @return {Peer} */ - getRandomPeer (acceptableDelay, downloadSize) { - let keys = Object.keys(this.peers) - keys = keys.filter((key) => { - const peer = this.getPeer(key) - if (peer.ban < new Date().getTime()) { - return true - } + getRandomPeer(acceptableDelay, downloadSize, failedAttempts) { + failedAttempts = failedAttempts === undefined ? 0 : failedAttempts - if (acceptableDelay && peer.delay < acceptableDelay) { - return true - } + const peers = this.getPeers().filter(peer => { + if (peer.ban < new Date().getTime()) { + return true + } - if (downloadSize && peer.downloadSize !== downloadSize) { - return true - } + if (acceptableDelay && peer.delay < acceptableDelay) { + return true + } - return false - }) + if (downloadSize && peer.downloadSize !== downloadSize) { + return true + } - const random = keys[keys.length * Math.random() << 0] - const randomPeer = this.getPeer(random) + return false + }) + const randomPeer = sample(peers) if (!randomPeer) { - // logger.error(this.peers) + failedAttempts++ - // FIXME: this method doesn't exist - // this.manager.checkOnline() + if (failedAttempts > 10) { + throw new Error('Failed to find random peer') + } else if (failedAttempts > 5) { + return this.getRandomPeer(null, downloadSize, failedAttempts) + } - return this.getRandomPeer() + return this.getRandomPeer(acceptableDelay, downloadSize, failedAttempts) } return randomPeer @@ -253,7 +400,7 @@ module.exports = class Monitor { * Get a random, available peer which can be used for downloading blocks. * @return {Peer} */ - async getRandomDownloadBlocksPeer (minHeight) { + async getRandomDownloadBlocksPeer(minHeight) { const randomPeer = this.getRandomPeer(null, 100) const recentBlockIds = await this.__getRecentBlockIds() @@ -268,13 +415,17 @@ module.exports = class Monitor { * Populate list of available peers from random peers. * @return {Peer[]} */ - async discoverPeers () { + async discoverPeers() { try { - const list = await this.getRandomPeer().getPeers() - - list.forEach(peer => { - if (peer.status === 'OK' && !this.getPeer(peer.ip) && !this.guard.isMyself(peer)) { - this.peers[peer.ip] = new Peer(peer.ip, peer.port) + const peers = await this.getRandomPeer().getPeers() + + peers.forEach(peer => { + if ( + Peer.isOk(peer) && + !this.getPeer(peer.ip) && + !this.guard.isMyself(peer) + ) { + this.__addPeer(peer) } }) @@ -283,32 +434,40 @@ module.exports = class Monitor { return this.discoverPeers() } } + + /** + * Check if we have any peers. + * @return {bool} + */ + hasPeers() { + return !!this.getPeers().length + } + /** * Get the median network height. * @return {Number} */ - getNetworkHeight () { - const median = this.getPeers() + getNetworkHeight() { + const medians = this.getPeers() .filter(peer => peer.state.height) .map(peer => peer.state.height) .sort() - return median[~~(median.length / 2)] + return medians[Math.floor(medians.length / 2)] || 0 } /** * Get the PBFT Forging status. * @return {Number} */ - getPBFTForgingStatus () { + getPBFTForgingStatus() { const height = this.getNetworkHeight() const slot = slots.getSlotNumber() - const heights = {} let allowedToForge = 0 let syncedPeers = 0 - for (let peer of this.getPeers()) { + for (const peer of this.getPeers()) { if (peer.state) { if (peer.state.currentSlot === slot) { syncedPeers++ @@ -317,22 +476,46 @@ module.exports = class Monitor { allowedToForge++ } } - - heights[peer.state.height] = heights[peer.state.height] ? heights[peer.state.height] + 1 : 1 } } - console.log(heights) const pbft = allowedToForge / syncedPeers + return isNaN(pbft) ? 0 : pbft } - async getNetworkState () { + async getNetworkState() { if (!this.__isColdStartActive()) { - await this.cleanPeers(true, false) + await this.cleanPeers(true, false, true) + } + + return networkState(this, app.resolvePlugin('blockchain').getLastBlock()) + } + + /** + * Refresh all peers after a fork. Peers with no common blocks are + * suspended. + * @return {void} + */ + async refreshPeersAfterFork() { + logger.info(`Refreshing ${this.getPeers().length} peers after fork.`) + + // Reset all peers, except peers banned because of causing a fork. + await this.guard.resetSuspendedPeers() + + // Ban peer who caused the fork + const forkedBlock = app.resolve('state').forkedBlock + if (forkedBlock) { + this.suspendPeer(forkedBlock.ip) } - return networkState(this, container.resolvePlugin('blockchain').getLastBlock()) + const recentBlockIds = await this.__getRecentBlockIds() + + await Promise.all( + this.getPeers().map(peer => + this.peerHasCommonBlocks(peer, recentBlockIds), + ), + ) } /** @@ -340,20 +523,31 @@ module.exports = class Monitor { * @param {Number} fromBlockHeight * @return {Object[]} */ - async downloadBlocks (fromBlockHeight) { - const randomPeer = await this.getRandomDownloadBlocksPeer(fromBlockHeight) + async downloadBlocks(fromBlockHeight) { + let randomPeer try { - logger.info(`Downloading blocks from height ${fromBlockHeight.toLocaleString()} via ${randomPeer.ip}`) + randomPeer = await this.getRandomDownloadBlocksPeer(fromBlockHeight) + } catch (error) { + logger.error(`Could not download blocks: ${error.message}`) - await randomPeer.ping() + return [] + } + try { + logger.info( + `Downloading blocks from height ${fromBlockHeight.toLocaleString()} via ${ + randomPeer.ip + }`, + ) const blocks = await randomPeer.downloadBlocks(fromBlockHeight) - blocks.forEach(block => (block.ip = randomPeer.ip)) + blocks.forEach(block => { + block.ip = randomPeer.ip + }) return blocks } catch (error) { - logger.error(`Block download: ${error.message}`) + logger.error(`Could not download blocks: ${error.message}`) return this.downloadBlocks(fromBlockHeight) } @@ -364,11 +558,13 @@ module.exports = class Monitor { * @param {Block} block * @return {Promise} */ - async broadcastBlock (block) { - const blockchain = container.resolvePlugin('blockchain') + async broadcastBlock(block) { + const blockchain = app.resolvePlugin('blockchain') if (!blockchain) { - logger.info(`Skipping broadcast of block ${block.data.height.toLocaleString()} as blockchain is not ready`) + logger.info( + `Skipping broadcast of block ${block.data.height.toLocaleString()} as blockchain is not ready`, + ) return } @@ -398,44 +594,218 @@ module.exports = class Monitor { peers = peers.filter(p => Math.random() < proba) } - logger.info(`Broadcasting block ${block.data.height.toLocaleString()} to ${peers.length} peers`) + logger.info( + `Broadcasting block ${block.data.height.toLocaleString()} to ${pluralize( + 'peer', + peers.length, + true, + )}`, + ) - await Promise.all(peers.map(peer => peer.postBlock(block.toBroadcastV1()))) + await Promise.all(peers.map(peer => peer.postBlock(block.toJson()))) } /** - * Placeholder method to broadcast transactions to peers. + * Broadcast transactions to a fixed number of random peers. * @param {Transaction[]} transactions */ - async broadcastTransactions (transactions) { - const peers = this.getPeers() - logger.debug(`Broadcasting ${transactions.length} transactions to ${peers.length} peers`) + async broadcastTransactions(transactions) { + const maxPeersBroadcast = app.resolveOptions('p2p').maxPeersBroadcast + const peers = take(shuffle(this.getPeers()), maxPeersBroadcast) + + logger.debug( + `Broadcasting ${pluralize( + 'transaction', + transactions.length, + true, + )} to ${pluralize('peer', peers.length, true)}`, + ) + + transactions = transactions.map(tx => tx.toJson()) + return Promise.all(peers.map(peer => peer.postTransactions(transactions))) + } - const transactionsV1 = [] - transactions.forEach(transaction => transactionsV1.push(transaction.toBroadcastV1())) + /** + * Update all peers based on height and last block id. + * + * Grouping peers by height and then by common id results in one of the following + * scenarios: + * + * 1) Same height, same common id + * 2) Same height, mixed common id + * 3) Mixed height, same common id + * 4) Mixed height, mixed common id + * + * Scenario 1: Do nothing. + * Scenario 2-4: + * - If own height is ahead of majority do nothing for now. + * - Pick most common id from peers with most common height and calculate quota, + * depending on which the node rolls back or waits. + * + * NOTE: Only called when the network is consecutively missing blocks `p2pUpdateCounter` times. + * @return {String} + */ + async updatePeersOnMissingBlocks() { + // First ping all peers to get updated heights and remove unresponsive ones. + if (!this.__isColdStartActive()) { + await this.cleanPeers(true, false) + } - return Promise.all(peers.map(peer => peer.postTransactions(transactionsV1))) + const peersGroupedByHeight = groupBy(this.getPeers(), 'state.height') + const commonHeightGroups = Object.values(peersGroupedByHeight).sort( + (a, b) => b.length - a.length, + ) + const peersMostCommonHeight = commonHeightGroups[0] + const groupedByCommonId = groupBy(peersMostCommonHeight, 'state.header.id') + const commonIdGroupCount = Object.keys(groupedByCommonId).length + let state = '' + + if (commonHeightGroups.length === 1 && commonIdGroupCount === 1) { + // No need to do anything. + return state + } + + const lastBlock = app.resolve('state').getLastBlock() + + // Do nothing if majority of peers are lagging behind + if (commonHeightGroups.length > 1) { + if (lastBlock.data.height > peersMostCommonHeight[0].state.height) { + logger.info( + `${pluralize( + 'peer', + peersMostCommonHeight.length, + true, + )} are at height ${peersMostCommonHeight[0].state.height.toLocaleString()} and lagging behind last height ${lastBlock.data.height.toLocaleString()}. :zzz:`, + ) + return state + } + } + + // Sort common id groups by length DESC + const commonIdGroups = Object.values(groupedByCommonId).sort( + (a, b) => b.length - a.length, + ) + + // Peers are sitting on the same height, but there might not be enough + // quorum to move on, because of different last blocks. + if (commonIdGroupCount > 1) { + const chosenPeers = commonIdGroups[0] + const restGroups = commonIdGroups.slice(1) + + if (restGroups.some(group => group.length === chosenPeers.length)) { + logger.warning( + 'Peers are evenly split at same height with different block ids. :zap:', + ) + } + + logger.info( + `Detected peers at the same height ${peersMostCommonHeight[0].state.height.toLocaleString()} with different block ids: ${JSON.stringify( + Object.keys(groupedByCommonId).map( + k => `${k}: ${groupedByCommonId[k].length}`, + ), + null, + 4, + )}`, + ) + + const badLastBlock = + chosenPeers[0].state.height === lastBlock.data.height && + chosenPeers[0].state.header.id !== lastBlock.data.id + const quota = chosenPeers.length / flatten(commonIdGroups).length + if (badLastBlock && quota >= 0.66) { + // Rollback if last block is bad and quota high + logger.info( + `Last block id ${ + lastBlock.data.id + } is bad. Going to rollback. :repeat:`, + ) + state = 'rollback' + } else if (quota < 0.66) { + // or quota too low TODO: find better number + logger.info( + `Common id quota '${quota}' is too low. Going to rollback. :repeat:`, + ) + state = 'rollback' + } + + if (state === 'rollback') { + // Ban all rest peers + const peersToBan = flatten(restGroups) + peersToBan.forEach(peer => { + peer.commonId = false + this.suspendPeer(peer.ip) + }) + + logger.debug( + `Banned ${pluralize( + 'peer', + peersToBan.length, + true, + )} at height '${peersMostCommonHeight[0].state.height.toLocaleString()}' which do not have common id '${ + chosenPeers[0].state.header.id + }'.`, + ) + } else { + logger.info(`But got enough common id quota: ${quota} :sparkles:`) + } + } else { + // Under certain circumstances the headers can be missing (i.e. seed peers when starting up) + const commonHeader = peersMostCommonHeight[0].state.header + logger.info( + `All peers at most common height ${peersMostCommonHeight[0].state.height.toLocaleString()} share the same block id${ + commonHeader ? ` '${commonHeader.id}'` : '' + }. :pray:`, + ) + } + + return state } /** - * Filter the initial seed list. + * Dump the list of active peers. * @return {void} */ - __filterPeers () { - if (!this.config.peers.list) { - logger.error('No seed peers defined in peers.json :interrobang:') + dumpPeers() { + const peers = Object.values(this.peers).map(peer => ({ + ip: peer.ip, + port: peer.port, + version: peer.version, + })) - process.exit(1) + try { + fs.writeFileSync( + `${process.env.ARK_PATH_CONFIG}/peers_backup.json`, + JSON.stringify(peers, null, 2), + ) + } catch (err) { + logger.error(`Failed to dump the peer list because of "${err.message}"`) } + } - const filteredPeers = this.config.peers.list - .filter(peer => (!this.guard.isMyself(peer) || !this.guard.isValidPort(peer))) + /** + * Filter the initial seed list. + * @return {void} + */ + __filterPeers() { + if (!config.peers.list) { + app.forceExit('No seed peers defined in peers.json :interrobang:') + } - // if (!filteredPeers.length) { - // logger.error('No external peers found in peers.json :interrobang:') + let peers = config.peers.list.map(peer => { + peer.version = app.getVersion() + return peer + }) - // process.exit(1) - // } + if (config.peers_backup) { + peers = { ...peers, ...config.peers_backup } + } + + const filteredPeers = Object.values(peers).filter( + peer => + !this.guard.isMyself(peer) || + !this.guard.isValidPort(peer) || + !this.guard.isValidVersion(peer), + ) for (const peer of filteredPeers) { this.peers[peer.ip] = new Peer(peer.ip, peer.port) @@ -446,15 +816,86 @@ module.exports = class Monitor { * Get last 10 block IDs from database. * @return {[]String} */ - async __getRecentBlockIds () { - return container.resolvePlugin('database').getRecentBlockIds() + async __getRecentBlockIds() { + return app.resolvePlugin('database').getRecentBlockIds() } /** - * Determines if coldstart is still active. We need this for the network to start, so we dont forge, while + * Determines if coldstart is still active. + * We need this for the network to start, so we dont forge, while * not all peers are up, or the network is not active */ - __isColdStartActive () { - return this.startForgers > moment() + __isColdStartActive() { + return this.coldStartPeriod.isAfter(dayjs()) + } + + /** + * Check if the node can connect to any DNS host. + * @return {void} + */ + async __checkDNSConnectivity(options) { + try { + const host = await checkDNS(options) + + logger.info(`Your network connectivity has been verified by ${host}`) + } catch (error) { + logger.error(error.message) + } + } + + /** + * Check if the node can connect to any NTP host. + * @return {void} + */ + async __checkNTPConnectivity(options) { + try { + const { host, time } = await checkNTP(options) + + logger.info(`Your NTP connectivity has been verified by ${host}`) + + logger.info( + `Local clock is off by ${parseInt(time.t)}ms from NTP :alarm_clock:`, + ) + } catch (error) { + logger.error(error.message) + } + } + + /** + * Add a new peer after it passes a few checks. + * @param {Peer} peer + * @return {void} + */ + __addPeer(peer) { + if (this.guard.isBlacklisted(peer)) { + return + } + + if (!this.guard.isValidVersion(peer)) { + return + } + + if (!this.guard.isValidNetwork(peer)) { + return + } + + if (!this.guard.isValidPort(peer)) { + return + } + + this.peers[peer.ip] = new Peer(peer.ip, peer.port) + } + + /** + * Add new peers after they pass a few checks. + * @param {Peer[]} peers + * @return {void} + */ + __addPeers(peers) { + for (const peer of peers) { + this.__addPeer(peer) + } } } + +module.exports = new Monitor() diff --git a/packages/core-p2p/lib/peer.js b/packages/core-p2p/lib/peer.js index 367f12f35d..083be6aee7 100755 --- a/packages/core-p2p/lib/peer.js +++ b/packages/core-p2p/lib/peer.js @@ -1,9 +1,11 @@ -'use strict' - const axios = require('axios') -const container = require('@arkecosystem/core-container') -const logger = container.resolvePlugin('logger') -const config = container.resolvePlugin('config') +const chunk = require('lodash/chunk') +const util = require('util') +const dayjs = require('dayjs-ext') +const app = require('@arkecosystem/core-container') + +const logger = app.resolvePlugin('logger') +const config = app.resolvePlugin('config') module.exports = class Peer { /** @@ -11,34 +13,64 @@ module.exports = class Peer { * @param {String} ip * @param {Number} port */ - constructor (ip, port) { + constructor(ip, port) { this.ip = ip this.port = port this.ban = new Date().getTime() - this.url = (port % 443 === 0 ? 'https://' : 'http://') + `${ip}:${port}` + this.url = `${port % 443 === 0 ? 'https://' : 'http://'}${ip}:${port}` this.state = {} + this.offences = [] + this.lastPinged = null this.headers = { - version: container.resolveOptions('blockchain').version, - port: container.resolveOptions('p2p').port, - nethash: config.network.nethash + version: app.getVersion(), + port: app.resolveOptions('p2p').port, + nethash: config.network.nethash, + height: null, + 'Content-Type': 'application/json', + } + + if (config.network.name !== 'mainnet') { + this.headers.hashid = app.getHashid() } } + /** + * Set the given headers for the peer. + * @param {Object} headers + * @return {void} + */ + setHeaders(headers) { + ;['nethash', 'os', 'version'].forEach(key => { + this[key] = headers[key] + }) + } + /** * Get information to broadcast. * @return {Object} */ - toBroadcastInfo () { - return { + toBroadcastInfo() { + const data = { ip: this.ip, - port: this.port, + port: +this.port, + nethash: this.nethash, version: this.version, os: this.os, status: this.status, height: this.state.height, - delay: this.delay + delay: this.delay, + } + + if (config.network.name !== 'mainnet') { + data.hashid = this.hashid || 'unknown' } + + return data + } + + static isOk(peer) { + return peer.status === 200 || peer.status === 'OK' } /** @@ -46,21 +78,15 @@ module.exports = class Peer { * @param {Block} block * @return {(Object|undefined)} */ - async postBlock (block) { - try { - const response = await axios.post(`${this.url}/peer/blocks`, { block }, { + async postBlock(block) { + return this.__post( + '/peer/blocks', + { block }, + { headers: this.headers, - timeout: 5000 - }) - - this.__parseHeaders(response) - - return response.data - } catch (error) { - // logger.debug('Peer unresponsive', this.url + '/peer/blocks/', error.code) - - this.status = error.code - } + timeout: 5000, + }, + ) } /** @@ -68,32 +94,35 @@ module.exports = class Peer { * @param {Transaction[]} transactions * @return {(Object|undefined)} */ - async postTransactions (transactions) { + async postTransactions(transactions) { try { - const response = await axios.post(`${this.url}/peer/transactions`, { - transactions, - isBroadCasted: true - }, { - headers: this.headers, - timeout: 8000 - }) - - this.__parseHeaders(response) - - return response.data - } catch (error) { - this.status = error.code + const response = await this.__post( + '/peer/transactions', + { + transactions, + }, + { + headers: this.headers, + timeout: 8000, + }, + ) + + return response + } catch (err) { + throw err } } - async getTransactionsFromIds (ids) { + async getTransactionsFromIds(ids) { // useless since there is a bug on v1 - const response = await this.__get(`/peer/transactionsFromIds?ids=${ids.join(',')}`) + const response = await this.__get( + `/peer/transactionsFromIds?ids=${ids.join(',')}`, + ) return response.success ? response.transactions : [] } - async getTransactionsFromBlock (blockId) { + async getTransactionsFromBlock(blockId) { const response = await this.__get(`/api/transactions?blockId=${blockId}`) return response.success ? response.transactions : [] @@ -104,53 +133,78 @@ module.exports = class Peer { * @param {Number} fromBlockHeight * @return {(Object[]|undefined)} */ - async downloadBlocks (fromBlockHeight) { + async downloadBlocks(fromBlockHeight) { try { - const { data } = await axios.get(`${this.url}/peer/blocks`, { + const response = await axios.get(`${this.url}/peer/blocks`, { params: { lastBlockHeight: fromBlockHeight }, headers: this.headers, - timeout: 60000 + timeout: 10000, }) - const size = data.blocks.length + this.__parseHeaders(response) + + const { blocks } = response.data + const size = blocks.length if (size === 100 || size === 400) { this.downloadSize = size } - return data.blocks + return blocks } catch (error) { - logger.debug(`Cannot download blocks from peer ${this.url} - ${JSON.stringify(error)}`) + logger.debug( + `Cannot download blocks from peer ${this.url} - ${util.inspect(error, { + depth: 1, + })}`, + ) - this.ban = new Date().getTime() + (Math.floor(Math.random() * 40) + 20) * 60000 + this.ban = + new Date().getTime() + (Math.floor(Math.random() * 40) + 20) * 60000 throw error } } /** - * Perform ping request on peer. + * Perform ping request on this peer if it has not been + * recently pinged. * @param {Number} [delay=5000] + * @param {Boolean} force * @return {Object} * @throws {Error} If fail to get peer status. */ - async ping (delay) { - const body = await this.__get('/peer/status', delay || config.peers.globalTimeout) + async ping(delay, force = false) { + if (this.recentlyPinged() && !force) { + return + } - if (body) { - this.state = body + const body = await this.__get( + '/peer/status', + delay || config.peers.globalTimeout, + ) - return body + if (!body) { + throw new Error(`Peer ${this.ip} is unresponsive`) } - throw new Error(`Peer ${this.ip} is unresponsive`) + this.lastPinged = dayjs() + this.state = body + return body + } + + /** + * Returns true if this peer was pinged the past 2 minutes. + * @return {Boolean} + */ + recentlyPinged() { + return !!this.lastPinged && dayjs().diff(this.lastPinged, 'm') < 2 } /** * Refresh peer list. It removes blacklisted peers from the fetch * @return {Object[]} */ - async getPeers () { + async getPeers() { logger.info(`Fetching a fresh peer list from ${this.url}`) await this.ping(2000) @@ -165,7 +219,7 @@ module.exports = class Peer { * @param {[]String} ids * @return {Boolean} */ - async hasCommonBlocks (ids) { + async hasCommonBlocks(ids) { try { let url = `/peer/blocks/common?ids=${ids.join(',')}` if (ids.length === 1) { @@ -175,7 +229,9 @@ module.exports = class Peer { return body && body.success && body.common } catch (error) { - logger.error(`Could not determine common blocks with ${this.ip}: ${error}`) + logger.error( + `Could not determine common blocks with ${this.ip}: ${error}`, + ) } return false @@ -187,13 +243,13 @@ module.exports = class Peer { * @param {Number} [timeout=10000] * @return {(Object|undefined)} */ - async __get (endpoint, timeout) { + async __get(endpoint, timeout) { const temp = new Date().getTime() try { const response = await axios.get(`${this.url}${endpoint}`, { headers: this.headers, - timeout: timeout || config.peers.globalTimeout + timeout: timeout || config.peers.globalTimeout, }) this.delay = new Date().getTime() - temp @@ -202,7 +258,44 @@ module.exports = class Peer { return response.data } catch (error) { - this.status = error.code + this.delay = -1 + + logger.debug( + `Request to ${this.url}${endpoint} failed because of "${ + error.message + }"`, + ) + + if (error.response) { + this.__parseHeaders(error.response) + } + } + } + + /** + * Perform POST request. + * @param {String} endpoint + * @param {Object} body + * @param {Object} headers + * @return {(Object|undefined)} + */ + async __post(endpoint, body, headers) { + try { + const response = await axios.post(`${this.url}${endpoint}`, body, headers) + + this.__parseHeaders(response) + + return response.data + } catch (error) { + logger.debug( + `Request to ${this.url}${endpoint} failed because of "${ + error.message + }"`, + ) + + if (error.response) { + this.__parseHeaders(error.response) + } } } @@ -211,10 +304,16 @@ module.exports = class Peer { * @param {Object} response * @return {Object} */ - __parseHeaders (response) { - ;['nethash', 'os', 'version'].forEach(key => (this[key] = response.headers[key])) + __parseHeaders(response) { + ;['nethash', 'os', 'version', 'hashid'].forEach(key => { + this[key] = response.headers[key] || this[key] + }) + + if (response.headers.height) { + this.state.height = +response.headers.height + } - this.status = 'OK' + this.status = response.status return response } diff --git a/packages/core-p2p/lib/server/index.js b/packages/core-p2p/lib/server/index.js index 6014d1a2ed..57c031ae08 100755 --- a/packages/core-p2p/lib/server/index.js +++ b/packages/core-p2p/lib/server/index.js @@ -1,7 +1,8 @@ -'use strict' - -const logger = require('@arkecosystem/core-container').resolvePlugin('logger') -const Hapi = require('hapi') +const { + createServer, + mountServer, + plugins, +} = require('@arkecosystem/core-http-utils') /** * Create a new hapi.js server. @@ -9,51 +10,101 @@ const Hapi = require('hapi') * @return {Hapi.Server} */ module.exports = async (p2p, config) => { - const server = new Hapi.Server({ + const server = await createServer({ host: config.host, - port: config.port + port: config.port, + }) + + // TODO: enable after mainnet migration + // await server.register({ plugin: plugins.contentType }) + + await server.register({ + plugin: require('hapi-rate-limit'), + options: config.rateLimit, }) - server.app.p2p = p2p + await server.register({ + plugin: require('./plugins/validate-headers'), + }) await server.register({ plugin: require('./plugins/accept-request'), options: { - whitelist: config.whitelist - } + whitelist: config.whitelist, + }, + }) + + await server.register({ + plugin: require('./plugins/set-headers'), + }) + + await server.register({ + plugin: require('./plugins/blockchain-ready'), + options: { + routes: [ + '/peer/height', + '/peer/blocks/common', + '/peer/status', + '/peer/blocks', + '/peer/transactions', + '/peer/getTransactionsFromIds', + '/internal/round', + '/internal/blocks', + '/internal/forgingTransactions', + '/internal/networkState', + '/internal/syncCheck', + '/internal/usernames', + '/remote/blockchain/{event}', + ], + }, + }) + + await server.register({ + plugin: plugins.corsHeaders, + }) + + await server.register({ + plugin: plugins.transactionPayload, + options: { + routes: [ + { + method: 'POST', + path: '/peer/transactions', + }, + ], + }, }) // await server.register({ - // plugin: require('./plugins/throttle') + // plugin: require('./plugins/transaction-pool-ready'), + // options: { + // routes: [ + // '/peer/transactions' + // ] + // } // }) await server.register({ - plugin: require('./plugins/set-headers') + plugin: require('./versions/config'), + routes: { prefix: '/config' }, + }) + + await server.register({ + plugin: require('./versions/1'), + routes: { prefix: '/peer' }, }) await server.register({ plugin: require('./versions/internal'), - routes: { prefix: '/internal' } + routes: { prefix: '/internal' }, }) - if (config.remoteinterface) { + if (config.remoteInterface) { await server.register({ plugin: require('./versions/remote'), - routes: { prefix: '/remote' } + routes: { prefix: '/remote' }, }) } - await server.register({ plugin: require('./versions/1') }) - - try { - await server.start() - - logger.info(`P2P API available and listening on ${server.info.uri}`) - - return server - } catch (err) { - logger.error(err) - - process.exit(1) - } + return mountServer('P2P API', server) } diff --git a/packages/core-p2p/lib/server/plugins/accept-request.js b/packages/core-p2p/lib/server/plugins/accept-request.js index ee3ec38f5d..da727acc62 100644 --- a/packages/core-p2p/lib/server/plugins/accept-request.js +++ b/packages/core-p2p/lib/server/plugins/accept-request.js @@ -1,7 +1,7 @@ -'use strict' - +const Boom = require('boom') const requestIp = require('request-ip') -const isWhitelist = require('../../utils/is-whitelist') +const isWhitelisted = require('../../utils/is-whitelist') +const monitor = require('../../monitor') /** * The register method used by hapi.js. @@ -14,33 +14,47 @@ const register = async (server, options) => { server.ext({ type: 'onRequest', - async method (request, h) { + async method(request, h) { const remoteAddress = requestIp.getClientIp(request) - if ((request.path.startsWith('/internal') || request.path.startsWith('/remote')) && !isWhitelist(options.whitelist, remoteAddress)) { - return h.response({ - code: 'ResourceNotFound', - message: `${request.path} does not exist` - }).code(400).takeover() + if (request.path.startsWith('/config')) { + return h.continue + } + + if ( + request.headers['x-auth'] === 'forger' || + request.path.startsWith('/remote') + ) { + return isWhitelisted(options.whitelist, remoteAddress) + ? h.continue + : Boom.forbidden() + } + + // Only forger requests are internal + if (request.path.startsWith('/internal')) { + return Boom.forbidden() + } + + if (!monitor.guard) { + return Boom.serverUnavailable('Peer Monitor not ready') } if (request.path.startsWith('/peer')) { const peer = { ip: remoteAddress } - requiredHeaders.forEach(key => (peer[key] = request.headers[key])) + requiredHeaders.forEach(key => { + peer[key] = request.headers[key] + }) try { - await server.app.p2p.acceptNewPeer(peer) + await monitor.acceptNewPeer(peer) } catch (error) { - return h.response({ - success: false, - message: error.message - }).code(500).takeover() + return Boom.badImplementation(error.message) } } return h.continue - } + }, }) } @@ -49,7 +63,7 @@ const register = async (server, options) => { * @type {Object} */ exports.plugin = { - name: 'core-p2p-accept-request', + name: 'accept-request', version: '0.1.0', - register + register, } diff --git a/packages/core-p2p/lib/server/plugins/blockchain-ready.js b/packages/core-p2p/lib/server/plugins/blockchain-ready.js new file mode 100644 index 0000000000..d4b07d2014 --- /dev/null +++ b/packages/core-p2p/lib/server/plugins/blockchain-ready.js @@ -0,0 +1,35 @@ +const Boom = require('boom') +const app = require('@arkecosystem/core-container') + +/** + * The register method used by hapi.js. + * @param {Hapi.Server} server + * @param {Object} options + * @return {void} + */ +const register = async (server, options) => { + server.ext({ + type: 'onRequest', + async method(request, h) { + if (!options.routes.includes(request.path)) { + return h.continue + } + + if (!app.resolvePlugin('blockchain')) { + return Boom.serverUnavailable('Blockchain not ready') + } + + return h.continue + }, + }) +} + +/** + * The struct used by hapi.js. + * @type {Object} + */ +exports.plugin = { + name: 'blockchain-ready', + version: '0.1.0', + register, +} diff --git a/packages/core-p2p/lib/server/plugins/set-headers.js b/packages/core-p2p/lib/server/plugins/set-headers.js index 9aed654682..c1645d193d 100644 --- a/packages/core-p2p/lib/server/plugins/set-headers.js +++ b/packages/core-p2p/lib/server/plugins/set-headers.js @@ -1,7 +1,6 @@ -'use strict' +const app = require('@arkecosystem/core-container') -const container = require('@arkecosystem/core-container') -const config = container.resolvePlugin('config') +const config = app.resolvePlugin('config') /** * The register method used by hapi.js. @@ -12,24 +11,48 @@ const config = container.resolvePlugin('config') const register = async (server, options) => { const headers = { nethash: config.network.nethash, - version: container.resolveOptions('blockchain').version, - port: container.resolveOptions('p2p').port, - os: require('os').platform() + version: app.getVersion(), + port: app.resolveOptions('p2p').port, + os: require('os').platform(), + height: null, } - const requiredHeaders = ['nethash', 'version', 'port', 'os'] + const requiredHeaders = ['nethash', 'version', 'port', 'os', 'height'] + + if (config.network.name !== 'mainnet') { + headers.hashid = app.getHashid() + requiredHeaders.push('hashid') + } server.ext({ type: 'onPreResponse', - async method (request, h) { - if (request.response.isBoom) { - requiredHeaders.forEach((key) => (request.response.output.headers[key] = headers[key])) + async method(request, h) { + const blockchain = app.resolvePlugin('blockchain') + if (blockchain) { + const lastBlock = blockchain.getLastBlock() + if (lastBlock) { + headers.height = lastBlock.data.height + } + } + + const response = request.response + if (response.isBoom) { + if (response.data) { + // Deleting the property beforehand makes it appear last in the + // response body. + delete response.output.payload.error + response.output.payload.error = response.data + } + + requiredHeaders.forEach(key => { + response.output.headers[key] = headers[key] + }) } else { - requiredHeaders.forEach((key) => request.response.header(key, headers[key])) + requiredHeaders.forEach(key => response.header(key, headers[key])) } return h.continue - } + }, }) } @@ -38,7 +61,7 @@ const register = async (server, options) => { * @type {Object} */ exports.plugin = { - name: 'core-p2p-set-headers', + name: 'set-headers', version: '0.1.0', - register + register, } diff --git a/packages/core-p2p/lib/server/plugins/throttle/bucket.js b/packages/core-p2p/lib/server/plugins/throttle/bucket.js deleted file mode 100644 index e71869a0a9..0000000000 --- a/packages/core-p2p/lib/server/plugins/throttle/bucket.js +++ /dev/null @@ -1,82 +0,0 @@ -const logger = require('@arkecosystem/core-container').resolvePlugin('logger') -const { RateLimiter } = require('limiter') - -class Bucket { - /** - * Create a new bucket instance. - */ - constructor () { - this.limiters = {} - this.limits = {} - } - - /** - * Associate a rate limiter with the given IP. - * - * @param {String} ip - * @param {Number} limit - */ - add (ip, limit) { - this.limiters[ip] = new RateLimiter(limit, 'minute', true) - this.limits[ip] = limit - } - - /** - * Get the rate limiter that is associated with the given IP. - * - * @param {String} ip - * @return {RateLimiter} - */ - get (ip) { - return this.limiters[ip] - } - - /** - * Check if a rate limiter is associated with the given IP. - * - * @param {String} ip - * @return {Boolean} - */ - has (ip) { - return this.limiters.hasOwnProperty(ip) - } - - /** - * Remove the rate limiter associated with the given IP. - * - * @param {String} ip - * @return {void} - */ - remove (ip) { - delete this.limiters[ip] - } - - /** - * Decrement the number of tokens by the given amount. - * - * @param {String} ip - * @param {Number} amount - * @return {void} - */ - decrement (ip, amount = 1) { - this.get(ip).removeTokens(amount, (err, remaining) => { - if (err) { - logger.debug(err.message) - } - - this.limits[ip] = remaining - }) - } - - /** - * Get the remaining number of tokens. - * - * @param {String} ip - * @return {Number} - */ - remaining (ip) { - return this.limits[ip] - } -} - -module.exports = new Bucket() diff --git a/packages/core-p2p/lib/server/plugins/throttle/index.js b/packages/core-p2p/lib/server/plugins/throttle/index.js deleted file mode 100644 index 0d48ecb2f6..0000000000 --- a/packages/core-p2p/lib/server/plugins/throttle/index.js +++ /dev/null @@ -1,58 +0,0 @@ -'use strict' - -const logger = require('@arkecosystem/core-container').resolvePlugin('logger') -const requestIp = require('request-ip') -const bucket = require('./bucket') -const isWhitelist = require('../../../utils/is-whitelist') - -/** - * The register method used by hapi.js. - * @param {Hapi.Server} server - * @param {Object} options - * @return {void} - */ -const register = async (server, options) => { - const isKnown = value => { - return server.app.p2p - .getPeers() - .find(peer => (peer.ip === value)) - } - - server.ext({ - type: 'onRequest', - async method (request, h) { - const remoteAddress = requestIp.getClientIp(request) - - if (isWhitelist(['127.*'], remoteAddress)) { - return h.continue - } - - if (!bucket.has(remoteAddress)) { - bucket.add(remoteAddress, isKnown(remoteAddress) ? 2000 : 1) - } - - bucket.decrement(remoteAddress) - - if (bucket.remaining(remoteAddress) <= 0) { - logger.debug(`${remoteAddress} has exceeded the maximum number of requests per minute.`) - - return h.response({ - success: false, - message: 'You have exceeded the maximum number of requests per minute.' - }).code(500).takeover() - } - - return h.continue - } - }) -} - -/** - * The struct used by hapi.js. - * @type {Object} - */ -exports.plugin = { - name: 'core-p2p-throttle', - version: '0.1.0', - register -} diff --git a/packages/core-p2p/lib/server/plugins/transaction-pool-ready.js b/packages/core-p2p/lib/server/plugins/transaction-pool-ready.js new file mode 100644 index 0000000000..120c03507d --- /dev/null +++ b/packages/core-p2p/lib/server/plugins/transaction-pool-ready.js @@ -0,0 +1,35 @@ +const Boom = require('boom') +const app = require('@arkecosystem/core-container') + +/** + * The register method used by hapi.js. + * @param {Hapi.Server} server + * @param {Object} options + * @return {void} + */ +const register = async (server, options) => { + server.ext({ + type: 'onRequest', + async method(request, h) { + if (!options.routes.includes(request.path)) { + return h.continue + } + + if (!app.resolvePlugin('transactionPool')) { + return Boom.serverUnavailable('Transaction Pool not ready') + } + + return h.continue + }, + }) +} + +/** + * The struct used by hapi.js. + * @type {Object} + */ +exports.plugin = { + name: 'transaction-pool-ready', + version: '0.1.0', + register, +} diff --git a/packages/core-p2p/lib/server/plugins/validate-headers.js b/packages/core-p2p/lib/server/plugins/validate-headers.js new file mode 100644 index 0000000000..6a71dce04e --- /dev/null +++ b/packages/core-p2p/lib/server/plugins/validate-headers.js @@ -0,0 +1,84 @@ +const ip = require('ip') +const AJV = require('ajv') + +/** + * The register method used by hapi.js. + * @param {Hapi.Server} server + * @param {Object} options + * @return {void} + */ +const register = async (server, options) => { + const ajv = new AJV() + + ajv.addFormat('ip', { + type: 'string', + validate: value => ip.isV4Format(value) || ip.isV6Format(value), + }) + + server.ext({ + type: 'onRequest', + async method(request, h) { + if (request.path.startsWith('/config')) { + return h.continue + } + + if (request.headers.port) { + request.headers.port = +request.headers.port + } + + const errors = ajv.validate( + { + type: 'object', + properties: { + ip: { + type: 'string', + format: 'ip', + }, + port: { + type: 'integer', + minimum: 1, + maximum: 65535, + }, + os: { + type: 'string', + maxLength: 64, + }, + nethash: { + type: 'string', + maxLength: 64, + }, + version: { + type: 'string', + maxLength: 11, + }, + }, + required: ['version', 'nethash', 'port'], + }, + request.headers, + ) + ? null + : ajv.errors + + if (errors) { + return h + .response({ + error: errors[0].message, + success: false, + }) + .takeover() + } + + return h.continue + }, + }) +} + +/** + * The struct used by hapi.js. + * @type {Object} + */ +exports.plugin = { + name: 'validate-headers', + version: '0.1.0', + register, +} diff --git a/packages/core-p2p/lib/server/versions/1/handlers.js b/packages/core-p2p/lib/server/versions/1/handlers.js index ab855701cd..6a7e12fbbf 100644 --- a/packages/core-p2p/lib/server/versions/1/handlers.js +++ b/packages/core-p2p/lib/server/versions/1/handlers.js @@ -1,15 +1,19 @@ -'use strict' +/* eslint no-restricted-globals: "off" */ -const container = require('@arkecosystem/core-container') +const app = require('@arkecosystem/core-container') const { TransactionGuard } = require('@arkecosystem/core-transaction-pool') -const { Block } = require('@arkecosystem/crypto').models -const logger = container.resolvePlugin('logger') -const requestIp = require('request-ip') -const transactionPool = container.resolvePlugin('transactionPool') const { slots, crypto } = require('@arkecosystem/crypto') -const { Transaction } = require('@arkecosystem/crypto').models +const { Block, Transaction } = require('@arkecosystem/crypto').models +const Joi = require('@arkecosystem/crypto').validator.engine.joi + +const requestIp = require('request-ip') +const pluralize = require('pluralize') + +const transactionPool = app.resolvePlugin('transactionPool') +const config = app.resolvePlugin('config') +const logger = app.resolvePlugin('logger') -const schema = require('./schema') +const monitor = require('../../../monitor') /** * @type {Object} @@ -20,27 +24,24 @@ exports.getPeers = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { + async handler(request, h) { try { - const peers = request.server.app.p2p.getPeers() + const peers = monitor + .getPeers() .map(peer => peer.toBroadcastInfo()) .sort((a, b) => a.delay - b.delay) return { success: true, - peers + peers, } } catch (error) { - return h.response({ success: false, message: error.message }).code(500).takeover() + return h + .response({ success: false, message: error.message }) + .code(500) + .takeover() } }, - config: { - plugins: { - 'hapi-ajv': { - querySchema: schema.getPeers - } - } - } } /** @@ -52,62 +53,55 @@ exports.getHeight = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - handler (request, h) { - const lastBlock = container.resolvePlugin('blockchain').getLastBlock() + handler(request, h) { + const lastBlock = app.resolvePlugin('blockchain').getLastBlock() return { success: true, height: lastBlock.data.height, - id: lastBlock.data.id + id: lastBlock.data.id, } }, - config: { - plugins: { - 'hapi-ajv': { - querySchema: schema.getHeight - } - } - } } /** * @type {Object} */ -exports.getCommonBlock = { +exports.getCommonBlocks = { /** * @param {Hapi.Request} request * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { + async handler(request, h) { if (!request.query.ids) { return { - success: false + success: false, } } - const blockchain = container.resolvePlugin('blockchain') - const ids = request.query.ids.split(',').slice(0, 9).filter(id => id.match(/^\d+$/)) + const blockchain = app.resolvePlugin('blockchain') + + const ids = request.query.ids + .split(',') + .slice(0, 9) + .filter(id => id.match(/^\d+$/)) try { - const commonBlock = await blockchain.database.getCommonBlock(ids) + const commonBlocks = await blockchain.database.getCommonBlocks(ids) return { success: true, - common: commonBlock.length ? commonBlock[0] : null, - lastBlockHeight: blockchain.getLastBlock().data.height + common: commonBlocks.length ? commonBlocks[0] : null, + lastBlockHeight: blockchain.getLastBlock().data.height, } } catch (error) { - return h.response({ success: false, message: error.message }).code(500).takeover() + return h + .response({ success: false, message: error.message }) + .code(500) + .takeover() } }, - config: { - plugins: { - 'hapi-ajv': { - querySchema: schema.getCommonBlock - } - } - } } /** @@ -119,33 +113,45 @@ exports.getTransactionsFromIds = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { + async handler(request, h) { try { - const transactionIds = request.query.ids.split(',').slice(0, 100).filter(id => id.match('[0-9a-fA-F]{32}')) - const rows = await container.resolvePlugin('database').getTransactionsFromIds(transactionIds) + const blockchain = app.resolvePlugin('blockchain') + const maxTransactions = config.getConstants(blockchain.getLastHeight()) + .block.maxTransactions + + const transactionIds = request.query.ids + .split(',') + .slice(0, maxTransactions) + .filter(id => id.match('[0-9a-fA-F]{32}')) + + const rows = await app + .resolvePlugin('database') + .getTransactionsFromIds(transactionIds) // TODO: v1 compatibility patch. Add transformer and refactor later on const transactions = await rows.map(row => { - let transaction = Transaction.deserialize(row.serialized.toString('hex')) + const transaction = Transaction.deserialize( + row.serialized.toString('hex'), + ) transaction.blockId = row.block_id transaction.senderId = crypto.getAddress(transaction.senderPublicKey) return transaction }) - const returnTrx = transactionIds.map((transaction, i) => (transactionIds[i] = transactions.find(tx2 => tx2.id === transactionIds[i]))) + transactionIds.forEach((transaction, i) => { + transactionIds[i] = transactions.find( + tx2 => tx2.id === transactionIds[i], + ) + }) - return { success: true, transactions: returnTrx } + return { success: true, transactions: transactionIds } } catch (error) { - return h.response({ success: false, message: error.message }).code(500).takeover() + return h + .response({ success: false, message: error.message }) + .code(500) + .takeover() } }, - config: { - plugins: { - 'hapi-ajv': { - querySchema: schema.getTransactionsFromIds - } - } - } } /** @@ -157,16 +163,9 @@ exports.getTransactions = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - handler (request, h) { + handler(request, h) { return { success: true, transactions: [] } }, - config: { - plugins: { - 'hapi-ajv': { - querySchema: schema.getTransactions - } - } - } } /** @@ -178,37 +177,17 @@ exports.getStatus = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - handler (request, h) { - const blockchain = container.resolvePlugin('blockchain') - - let lastBlock = null - - if (blockchain) { - lastBlock = blockchain.getLastBlock() - } - - if (!lastBlock) { - return { - success: false, - message: 'Node is not ready' - } - } + handler(request, h) { + const lastBlock = app.resolvePlugin('blockchain').getLastBlock() return { success: true, - height: lastBlock.data.height, + height: lastBlock ? lastBlock.data.height : 0, forgingAllowed: slots.isForgingAllowed(), currentSlot: slots.getSlotNumber(), - header: lastBlock.getHeader() + header: lastBlock ? lastBlock.getHeader() : {}, } }, - config: { - plugins: { - 'hapi-ajv': { - querySchema: schema.getStatus - } - } - } } /** @@ -220,12 +199,8 @@ exports.postBlock = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const blockchain = container.resolvePlugin('blockchain') - - if (!blockchain) { - return { success: false } - } + async handler(request, h) { + const blockchain = app.resolvePlugin('blockchain') try { if (!request.payload || !request.payload.block) { @@ -234,19 +209,22 @@ exports.postBlock = { const block = request.payload.block - if (blockchain.pingBlock(block)) return {success: true} + if (blockchain.pingBlock(block)) return { success: true } // already got it? const lastDownloadedBlock = blockchain.getLastDownloadedBlock() // Are we ready to get it? - if (lastDownloadedBlock && lastDownloadedBlock.data.height + 1 !== block.height) { + if ( + lastDownloadedBlock && + lastDownloadedBlock.data.height + 1 !== block.height + ) { return { success: true } } const b = new Block(block) if (!b.verification.verified) { - throw new Error('invalid block received') + return { success: false } } blockchain.pushPingBlock(b.data) @@ -255,30 +233,41 @@ exports.postBlock = { // let missingIds = [] let transactions = [] // if (transactionPool) { - // transactions = block.transactionIds.map(async id => await transactionPool.getTransaction(id) || id) + // transactions = block.transactionIds + // .map(async id => await transactionPool.getTransaction(id) || id) // missingIds = transactions.filter(tx => !tx.id) // } else { // missingIds = block.transactionIds.slice(0) // } // if (missingIds.length > 0) { - let peer = await request.server.app.p2p.getPeer(requestIp.getClientIp(request)) - // only for test because it can be used for DDOS attack - if (!peer && process.env.NODE_ENV === 'test_p2p') { - peer = await request.server.app.p2p.getRandomPeer() - } + let peer = await monitor.getPeer(requestIp.getClientIp(request)) + // only for test because it can be used for DDOS attack + if (!peer && process.env.NODE_ENV === 'test_p2p') { + peer = await monitor.getRandomPeer() + } - if (!peer) return { success: false } + if (!peer) { + return { success: false } + } - transactions = await peer.getTransactionsFromIds(block.transactionIds) - // issue on v1, using /api/ instead of /peer/ - if (transactions.length < block.transactionIds.length) transactions = await peer.getTransactionsFromBlock(block.id) + transactions = await peer.getTransactionsFromIds(block.transactionIds) + // issue on v1, using /api/ instead of /peer/ + if (transactions.length < block.transactionIds.length) { + transactions = await peer.getTransactionsFromBlock(block.id) + } - // reorder them correctly - block.transactions = block.transactionIds.map(id => transactions.find(tx => tx.id === id)) - logger.debug(`Found missing transactions: ${block.transactions.map(tx => tx.id)}`) + // reorder them correctly + block.transactions = block.transactionIds.map(id => + transactions.find(tx => tx.id === id), + ) + logger.debug( + `Found missing transactions: ${block.transactions.map(tx => tx.id)}`, + ) - if (block.transactions.length !== block.numberOfTransactions) return { success: false } + if (block.transactions.length !== block.numberOfTransactions) { + return { success: false } } + } // } else return { success: false } block.ip = requestIp.getClientIp(request) @@ -290,13 +279,6 @@ exports.postBlock = { return { success: false } } }, - config: { - plugins: { - 'hapi-ajv': { - payloadSchema: schema.postBlock - } - } - } } /** @@ -308,61 +290,50 @@ exports.postTransactions = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - if (!request.payload || !request.payload.transactions || !transactionPool) { + async handler(request, h) { + if (!transactionPool) { return { success: false, - transactionIds: [] + message: 'Transaction pool not available', } } - const blockchain = container.resolvePlugin('blockchain') - if (!blockchain) { - return { success: false } - } - - /** - * Here we will make sure we memorize the transactions for future requests - * and decide which transactions are valid or invalid in order to prevent - * duplication and race conditions caused by concurrent requests. - */ - const { valid, invalid } = transactionPool.memory.memorize(request.payload.transactions) - const guard = new TransactionGuard(transactionPool) - guard.invalid = invalid - await guard.validate(valid) - - // TODO: Review throttling of v1 - if (guard.hasAny('accept')) { - logger.info(`Accepted ${guard.accept.length} transactions from ${request.payload.transactions.length} received`) - logger.verbose(`Accepted transactions: ${guard.accept.map(tx => tx.id)}`) + const result = await guard.validate(request.payload.transactions) - await transactionPool.addTransactions(guard.accept) - - transactionPool.memory - .forget(guard.getIds('accept')) - .forget(guard.getIds('excess')) + if (result.invalid.length > 0) { + return { + success: false, + message: 'Transactions list is not conform', + error: 'Transactions list is not conform', + } } - if (!request.payload.isBroadCasted && guard.hasAny('broadcast')) { - await container + if (result.broadcast.length > 0) { + app .resolvePlugin('p2p') - .broadcastTransactions(guard.broadcast) + .broadcastTransactions(guard.getBroadcastTransactions()) } return { success: true, - transactionIds: guard.getIds('accept') + transactionIds: result.accept, } }, - config: { - plugins: { - 'hapi-ajv': { - payloadSchema: schema.postTransactions - } - } - } + options: { + cors: { + additionalHeaders: ['nethash', 'port', 'version'], + }, + validate: { + payload: { + transactions: Joi.arkTransactions() + .min(1) + .max(app.resolveOptions('transactionPool').maxTransactionsPerRequest) + .options({ stripUnknown: true }), + }, + }, + }, } /** @@ -374,24 +345,36 @@ exports.getBlocks = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { + async handler(request, h) { try { - const blocks = await container.resolvePlugin('database').getBlocks(parseInt(request.query.lastBlockHeight) + 1, 400) + const database = app.resolvePlugin('database') + const blockchain = app.resolvePlugin('blockchain') - logger.info(`${requestIp.getClientIp(request)} has downloaded ${blocks.length} blocks from height ${request.query.lastBlockHeight}`) + const reqBlockHeight = parseInt(request.query.lastBlockHeight) + 1 + let blocks = [] + + if (!request.query.lastBlockHeight || isNaN(reqBlockHeight)) { + blocks.push(blockchain.getLastBlock()) + } else { + blocks = await database.getBlocks(reqBlockHeight, 400) + } + + logger.info( + `${requestIp.getClientIp(request)} has downloaded ${pluralize( + 'block', + blocks.length, + true, + )} from height ${(!isNaN(reqBlockHeight) + ? reqBlockHeight + : blocks[0].data.height + ).toLocaleString()}`, + ) return { success: true, blocks: blocks || [] } } catch (error) { logger.error(error.stack) - return h.response({ success: false, error: error }).code(500) + return h.response({ success: false, error }).code(500) } }, - config: { - plugins: { - 'hapi-ajv': { - querySchema: schema.getBlocks - } - } - } } diff --git a/packages/core-p2p/lib/server/versions/1/index.js b/packages/core-p2p/lib/server/versions/1/index.js index df1af2d8b9..fba71d7016 100644 --- a/packages/core-p2p/lib/server/versions/1/index.js +++ b/packages/core-p2p/lib/server/versions/1/index.js @@ -1,5 +1,3 @@ -'use strict' - const handlers = require('./handlers') /** @@ -10,15 +8,19 @@ const handlers = require('./handlers') */ const register = async (server, options) => { server.route([ - { method: 'GET', path: '/peer/list', ...handlers.getPeers }, - { method: 'GET', path: '/peer/blocks', ...handlers.getBlocks }, - { method: 'GET', path: '/peer/transactionsFromIds', ...handlers.getTransactionsFromIds }, - { method: 'GET', path: '/peer/height', ...handlers.getHeight }, - { method: 'GET', path: '/peer/transactions', ...handlers.getTransactions }, - { method: 'GET', path: '/peer/blocks/common', ...handlers.getCommonBlock }, - { method: 'GET', path: '/peer/status', ...handlers.getStatus }, - { method: 'POST', path: '/peer/blocks', ...handlers.postBlock }, - { method: 'POST', path: '/peer/transactions', ...handlers.postTransactions } + { method: 'GET', path: '/list', ...handlers.getPeers }, + { method: 'GET', path: '/blocks', ...handlers.getBlocks }, + { + method: 'GET', + path: '/transactionsFromIds', + ...handlers.getTransactionsFromIds, + }, + { method: 'GET', path: '/height', ...handlers.getHeight }, + { method: 'GET', path: '/transactions', ...handlers.getTransactions }, + { method: 'GET', path: '/blocks/common', ...handlers.getCommonBlocks }, + { method: 'GET', path: '/status', ...handlers.getStatus }, + { method: 'POST', path: '/blocks', ...handlers.postBlock }, + { method: 'POST', path: '/transactions', ...handlers.postTransactions }, ]) } @@ -27,7 +29,7 @@ const register = async (server, options) => { * @type {Object} */ exports.plugin = { - name: 'ARK P2P API - v1', + name: 'Ark P2P API - v1', version: '0.1.0', - register + register, } diff --git a/packages/core-p2p/lib/server/versions/1/schema.js b/packages/core-p2p/lib/server/versions/1/schema.js index 419e64a98e..c209cd37d3 100644 --- a/packages/core-p2p/lib/server/versions/1/schema.js +++ b/packages/core-p2p/lib/server/versions/1/schema.js @@ -1,5 +1,3 @@ -'use strict' - /** * @type {Object} */ @@ -8,100 +6,100 @@ module.exports = { type: 'object', properties: { success: { - type: 'boolean' + type: 'boolean', }, height: { type: 'integer', - minimum: 0 + minimum: 0, }, currentSlot: { type: 'integer', - minimum: 0 + minimum: 0, }, forgingAllowed: { - type: 'boolean' + type: 'boolean', }, header: { - type: 'object' - } + type: 'object', + }, }, - required: ['success', 'height', 'header', 'currentSlot', 'forgingAllowed'] + required: ['success', 'height', 'header', 'currentSlot', 'forgingAllowed'], }, getHeight: { type: 'object', properties: { success: { - type: 'boolean' + type: 'boolean', }, height: { type: 'integer', - minimum: 0 + minimum: 0, }, header: { - type: 'object' - } + type: 'object', + }, }, - required: ['success', 'height', 'header'] + required: ['success', 'height', 'header'], }, postTransactions: { - type: 'object' + type: 'object', }, getTransactions: { type: 'object', properties: { success: { - type: 'boolean' + type: 'boolean', }, transactions: { type: 'array', - uniqueItems: true - } + uniqueItems: true, + }, }, - required: ['transactions'] + required: ['transactions'], }, getTransactionsFromIds: { - type: 'object' + type: 'object', }, getBlocks: { type: 'object', properties: { success: { - type: 'boolean' + type: 'boolean', }, blocks: { - type: 'array' - } + type: 'array', + }, }, - required: ['blocks'] + required: ['blocks'], }, postBlock: { type: 'object', properties: { success: { - type: 'boolean' + type: 'boolean', }, blockId: { - type: 'string' - } + type: 'string', + }, }, - required: ['success', 'blockId'] + required: ['success', 'blockId'], }, getBlock: { - type: 'object' + type: 'object', }, - getCommonBlock: { - type: 'object' + getCommonBlocks: { + type: 'object', }, getPeers: { type: 'object', properties: { success: { - type: 'boolean' + type: 'boolean', }, peers: { - type: 'array' - } + type: 'array', + }, }, - required: ['peers'] - } + required: ['peers'], + }, } diff --git a/packages/core-p2p/lib/server/versions/config/handlers/index.js b/packages/core-p2p/lib/server/versions/config/handlers/index.js new file mode 100644 index 0000000000..d3b615198c --- /dev/null +++ b/packages/core-p2p/lib/server/versions/config/handlers/index.js @@ -0,0 +1,61 @@ +const app = require('@arkecosystem/core-container') + +const config = app.resolvePlugin('config') +const transform = require('../transformers/plugins') + +exports.config = { + async handler(request, h) { + return { + data: { + version: app.getVersion(), + network: { + version: config.network.pubKeyHash, + nethash: config.network.nethash, + explorer: config.network.client.explorer, + token: { + name: config.network.client.token, + symbol: config.network.client.symbol, + }, + }, + plugins: transform(config), + }, + } + }, + config: { + cors: true, + }, +} + +exports.network = { + handler(request, h) { + return { + data: require(`${process.env.ARK_PATH_CONFIG}/network.json`), + } + }, +} + +exports.genesisBlock = { + handler(request, h) { + return { + data: require(`${process.env.ARK_PATH_CONFIG}/genesisBlock.json`), + } + }, +} + +exports.peers = { + handler(request, h) { + return { + data: require(`${process.env.ARK_PATH_CONFIG}/peers.json`), + } + }, +} + +exports.delegates = { + handler(request, h) { + const data = require(`${process.env.ARK_PATH_CONFIG}/delegates.json`) + data.secrets = [] + delete data.bip38 + + return { data } + }, +} diff --git a/packages/core-p2p/lib/server/versions/config/index.js b/packages/core-p2p/lib/server/versions/config/index.js new file mode 100644 index 0000000000..367713700d --- /dev/null +++ b/packages/core-p2p/lib/server/versions/config/index.js @@ -0,0 +1,26 @@ +const handlers = require('./handlers') +/** + * Register v1 routes. + * @param {Hapi.Server} server + * @param {Object} options + * @return {void} + */ +const register = async (server, options) => { + server.route([ + { method: 'GET', path: '/', ...handlers.config }, + { method: 'GET', path: '/network', ...handlers.network }, + { method: 'GET', path: '/genesis-block', ...handlers.genesisBlock }, + { method: 'GET', path: '/peers', ...handlers.peers }, + { method: 'GET', path: '/delegates', ...handlers.delegates }, + ]) +} + +/** + * The struct used by hapi.js. + * @type {Object} + */ +exports.plugin = { + name: 'Ark P2P - Config API', + version: '0.1.0', + register, +} diff --git a/packages/core-p2p/lib/server/versions/config/transformers/plugins.js b/packages/core-p2p/lib/server/versions/config/transformers/plugins.js new file mode 100644 index 0000000000..e5d7fe93f2 --- /dev/null +++ b/packages/core-p2p/lib/server/versions/config/transformers/plugins.js @@ -0,0 +1,35 @@ +/** + * Turns a "config" object into readable object. + * @param {Object} model + * @return {Object} + */ +module.exports = config => { + const allowed = [ + '@arkecosystem/core-api', + '@arkecosystem/core-graphql', + '@arkecosystem/core-json-rpc', + '@arkecosystem/core-webhooks', + ] + + const result = {} + + for (const [name, options] of Object.entries(config.plugins)) { + if (allowed.includes(name)) { + if (options.server) { + result[name] = { + enabled: !!options.server.enabled, + port: +options.server.port, + } + + continue + } + + result[name] = { + enabled: !!options.enabled, + port: +options.port, + } + } + } + + return result +} diff --git a/packages/core-p2p/lib/server/versions/internal/handlers.js b/packages/core-p2p/lib/server/versions/internal/handlers.js deleted file mode 100644 index 09132e0a56..0000000000 --- a/packages/core-p2p/lib/server/versions/internal/handlers.js +++ /dev/null @@ -1,203 +0,0 @@ -'use strict' - -const container = require('@arkecosystem/core-container') -const config = container.resolvePlugin('config') -const requestIp = require('request-ip') -const logger = container.resolvePlugin('logger') - -const { slots } = require('@arkecosystem/crypto') -const { Transaction } = require('@arkecosystem/crypto').models - -/** - * @type {Object} - */ -exports.postVerifyTransaction = { - /** - * @param {Hapi.Request} request - * @param {Hapi.Toolkit} h - * @return {Hapi.Response} - */ - async handler (request, h) { - const transaction = new Transaction(Transaction.deserialize(request.payload.transaction)) - const result = await container.resolvePlugin('database').verifyTransaction(transaction) - - return { success: result } - } -} - -/** - * @type {Object} - */ -exports.postInternalBlock = { - /** - * @param {Hapi.Request} request - * @param {Hapi.Toolkit} h - * @return {Hapi.Response} - */ - handler: (request, h) => { - const block = request.payload - block.ip = requestIp.getClientIp(request) - container.resolvePlugin('blockchain').queueBlock(block) - - return { success: true } - } -} - -/** - * @type {Object} - */ -exports.getRound = { - /** - * @param {Hapi.Request} request - * @param {Hapi.Toolkit} h - * @return {Hapi.Response} - */ - async handler (request, h) { - try { - const blockchain = container.resolvePlugin('blockchain') - - const lastBlock = blockchain.getLastBlock() - - const height = lastBlock.data.height + 1 - const maxActive = config.getConstants(height).activeDelegates - const blockTime = config.getConstants(height).blocktime - const reward = config.getConstants(height).reward - const delegates = await blockchain.database.getActiveDelegates(height) - const timestamp = slots.getTime() - - return { - success: true, - round: { - current: parseInt(height / maxActive), - reward: reward, - timestamp: timestamp, - delegates: delegates, - currentForger: delegates[parseInt(timestamp / blockTime) % maxActive], - nextForger: delegates[(parseInt(timestamp / blockTime) + 1) % maxActive], - lastBlock: lastBlock.data, - canForge: parseInt(1 + lastBlock.data.timestamp / blockTime) * blockTime < timestamp - 1 - } - } - } catch (error) { - return h.response({ - success: false, - message: error.message - }).code(500).takeover() - } - } -} - -/** - * @type {Object} - */ -exports.getTransactionsForForging = { - /** - * @param {Hapi.Request} request - * @param {Hapi.Toolkit} h - * @return {Hapi.Response} - */ - async handler (request, h) { - const blockchain = container.resolvePlugin('blockchain') - - const height = blockchain.getLastBlock().data.height - const blockSize = config.getConstants(height).block.maxTransactions - - try { - return { - success: true, - data: await blockchain.getUnconfirmedTransactions(blockSize, true) - } - } catch (error) { - return h.response({ - success: false, - message: error.message - }).code(500).takeover() - } - } -} - -/** - * @type {Object} - */ -exports.getNetworkState = { - /** - * @param {Hapi.Request} request - * @param {Hapi.Toolkit} h - * @return {Hapi.Response} - */ - async handler (request, h) { - const blockchain = container.resolvePlugin('blockchain') - - if (!blockchain) { - return { success: true, error: 'Blockchain not ready' } - } - try { - return { - success: true, - networkState: await blockchain.p2p.getNetworkState() - } - } catch (error) { - return h.response({ - success: false, - message: error.message - }).code(500).takeover() - } - } -} - -/** - * @type {Object} - */ -exports.checkBlockchainSynced = { - /** - * @param {Hapi.Request} request - * @param {Hapi.Toolkit} h - * @return {Hapi.Response} - */ - async handler (request, h) { - const blockchain = container.resolvePlugin('blockchain') - - if (!blockchain) { - return { success: true, error: 'Blockchain not ready' } - } - - try { - logger.debug('Blockchain sync check WAKEUP requested by forger :bed:') - blockchain.dispatch('WAKEUP') - - return { - success: true - } - } catch (error) { - return h.response({ - success: false, - message: error.message - }).code(500).takeover() - } - } -} - -/** - * @type {Object} - */ -exports.getUsernames = { - /** - * @param {Hapi.Request} request - * @param {Hapi.Toolkit} h - * @return {Hapi.Response} - */ - async handler (request, h) { - const blockchain = container.resolvePlugin('blockchain') - const walletManager = container.resolvePlugin('database').walletManager - - const lastBlock = blockchain.getLastBlock() - const delegates = await blockchain.database.getActiveDelegates(lastBlock.data.height + 1) - - const data = {} - for (const delegate of delegates) { - data[delegate.publicKey] = walletManager.getWalletByPublicKey(delegate.publicKey).username - } - - return { success: true, data } - } -} diff --git a/packages/core-p2p/lib/server/versions/internal/handlers/blockchain.js b/packages/core-p2p/lib/server/versions/internal/handlers/blockchain.js new file mode 100644 index 0000000000..0a51720ea0 --- /dev/null +++ b/packages/core-p2p/lib/server/versions/internal/handlers/blockchain.js @@ -0,0 +1,21 @@ +const app = require('@arkecosystem/core-container') + +const logger = app.resolvePlugin('logger') + +/** + * @type {Object} + */ +exports.sync = { + /** + * @param {Hapi.Request} request + * @param {Hapi.Toolkit} h + * @return {Hapi.Response} + */ + async handler(request, h) { + logger.debug('Blockchain sync check WAKEUP requested by forger :bed:') + + app.resolvePlugin('blockchain').forceWakeup() + + return h.response(null).code(204) + }, +} diff --git a/packages/core-p2p/lib/server/versions/internal/handlers/blocks.js b/packages/core-p2p/lib/server/versions/internal/handlers/blocks.js new file mode 100644 index 0000000000..11daf8ffb1 --- /dev/null +++ b/packages/core-p2p/lib/server/versions/internal/handlers/blocks.js @@ -0,0 +1,24 @@ +const app = require('@arkecosystem/core-container') +const requestIp = require('request-ip') +const schema = require('../schemas/blocks') + +/** + * @type {Object} + */ +exports.store = { + /** + * @param {Hapi.Request} request + * @param {Hapi.Toolkit} h + * @return {Hapi.Response} + */ + handler: (request, h) => { + request.payload.block.ip = requestIp.getClientIp(request) + + app.resolvePlugin('blockchain').queueBlock(request.payload.block) + + return h.response(null).code(204) + }, + options: { + validate: schema.store, + }, +} diff --git a/packages/core-p2p/lib/server/versions/internal/handlers/network.js b/packages/core-p2p/lib/server/versions/internal/handlers/network.js new file mode 100644 index 0000000000..eb7ffbf7e7 --- /dev/null +++ b/packages/core-p2p/lib/server/versions/internal/handlers/network.js @@ -0,0 +1,17 @@ +const monitor = require('../../../../monitor') + +/** + * @type {Object} + */ +exports.state = { + /** + * @param {Hapi.Request} request + * @param {Hapi.Toolkit} h + * @return {Hapi.Response} + */ + async handler(request, h) { + return { + data: await monitor.getNetworkState(), + } + }, +} diff --git a/packages/core-p2p/lib/server/versions/internal/handlers/rounds.js b/packages/core-p2p/lib/server/versions/internal/handlers/rounds.js new file mode 100644 index 0000000000..88a2f8b064 --- /dev/null +++ b/packages/core-p2p/lib/server/versions/internal/handlers/rounds.js @@ -0,0 +1,45 @@ +const app = require('@arkecosystem/core-container') + +const config = app.resolvePlugin('config') + +const { slots } = require('@arkecosystem/crypto') + +/** + * @type {Object} + */ +exports.current = { + /** + * @param {Hapi.Request} request + * @param {Hapi.Toolkit} h + * @return {Hapi.Response} + */ + async handler(request, h) { + const database = app.resolvePlugin('database') + const blockchain = app.resolvePlugin('blockchain') + + const lastBlock = blockchain.getLastBlock() + + const height = lastBlock.data.height + 1 + const maxActive = config.getConstants(height).activeDelegates + const blockTime = config.getConstants(height).blocktime + const reward = config.getConstants(height).reward + const delegates = await database.getActiveDelegates(height) + const timestamp = slots.getTime() + + return { + data: { + current: parseInt(height / maxActive), + reward, + timestamp, + delegates, + currentForger: delegates[parseInt(timestamp / blockTime) % maxActive], + nextForger: + delegates[(parseInt(timestamp / blockTime) + 1) % maxActive], + lastBlock: lastBlock.data, + canForge: + parseInt(1 + lastBlock.data.timestamp / blockTime) * blockTime + < timestamp - 1, + }, + } + }, +} diff --git a/packages/core-p2p/lib/server/versions/internal/handlers/transactions.js b/packages/core-p2p/lib/server/versions/internal/handlers/transactions.js new file mode 100644 index 0000000000..914e44f6db --- /dev/null +++ b/packages/core-p2p/lib/server/versions/internal/handlers/transactions.js @@ -0,0 +1,55 @@ +const app = require('@arkecosystem/core-container') + +const config = app.resolvePlugin('config') + +const { Transaction } = require('@arkecosystem/crypto').models + +const schema = require('../schemas/transactions') + +/** + * @type {Object} + */ +exports.verify = { + /** + * @param {Hapi.Request} request + * @param {Hapi.Toolkit} h + * @return {Hapi.Response} + */ + async handler(request, h) { + const transaction = new Transaction( + Transaction.deserialize(request.payload.transaction), + ) + + return { + data: { + valid: await app + .resolvePlugin('database') + .verifyTransaction(transaction), + }, + } + }, + options: { + validate: schema.verify, + }, +} + +/** + * @type {Object} + */ +exports.forging = { + /** + * @param {Hapi.Request} request + * @param {Hapi.Toolkit} h + * @return {Hapi.Response} + */ + handler(request, h) { + const blockchain = app.resolvePlugin('blockchain') + + const height = blockchain.getLastBlock().data.height + const maxTransactions = config.getConstants(height).block.maxTransactions + + return { + data: blockchain.getUnconfirmedTransactions(maxTransactions, true), + } + }, +} diff --git a/packages/core-p2p/lib/server/versions/internal/handlers/utils.js b/packages/core-p2p/lib/server/versions/internal/handlers/utils.js new file mode 100644 index 0000000000..6dd2f91854 --- /dev/null +++ b/packages/core-p2p/lib/server/versions/internal/handlers/utils.js @@ -0,0 +1,54 @@ +const app = require('@arkecosystem/core-container') + +const emitter = app.resolvePlugin('event-emitter') + +const schema = require('../schemas/utils') + +/** + * @type {Object} + */ +exports.usernames = { + /** + * @param {Hapi.Request} request + * @param {Hapi.Toolkit} h + * @return {Hapi.Response} + */ + async handler(request, h) { + const blockchain = app.resolvePlugin('blockchain') + const walletManager = app.resolvePlugin('database').walletManager + + const lastBlock = blockchain.getLastBlock() + const delegates = await blockchain.database.getActiveDelegates( + lastBlock ? lastBlock.data.height + 1 : 1, + ) + + const data = {} + for (const delegate of delegates) { + data[delegate.publicKey] = walletManager.findByPublicKey( + delegate.publicKey, + ).username + } + + return { data } + }, +} + +/** + * Emit the given event and payload to the local host. + * @type {Object} + */ +exports.emitEvent = { + /** + * @param {Hapi.Request} request + * @param {Hapi.Toolkit} h + * @return {Hapi.Response} + */ + handler: (request, h) => { + emitter.emit(request.payload.event, request.payload.body) + + return h.response(null).code(204) + }, + options: { + validate: schema.emitEvent, + }, +} diff --git a/packages/core-p2p/lib/server/versions/internal/index.js b/packages/core-p2p/lib/server/versions/internal/index.js index 6f4e7b8757..c0539958ca 100644 --- a/packages/core-p2p/lib/server/versions/internal/index.js +++ b/packages/core-p2p/lib/server/versions/internal/index.js @@ -1,6 +1,9 @@ -'use strict' - -const handlers = require('./handlers') +const blockchain = require('./handlers/blockchain') +const blocks = require('./handlers/blocks') +const network = require('./handlers/network') +const rounds = require('./handlers/rounds') +const transactions = require('./handlers/transactions') +const utils = require('./handlers/utils') /** * Register internal routes. @@ -10,13 +13,19 @@ const handlers = require('./handlers') */ const register = async (server, options) => { server.route([ - { method: 'GET', path: '/round', ...handlers.getRound }, - { method: 'POST', path: '/block', ...handlers.postInternalBlock }, - { method: 'POST', path: '/verifyTransaction', ...handlers.postVerifyTransaction }, - { method: 'GET', path: '/forgingTransactions', ...handlers.getTransactionsForForging }, - { method: 'GET', path: '/networkState', ...handlers.getNetworkState }, - { method: 'GET', path: '/syncCheck', ...handlers.checkBlockchainSynced }, - { method: 'GET', path: '/usernames', ...handlers.getUsernames } + { method: 'GET', path: '/network/state', ...network.state }, + + { method: 'GET', path: '/blockchain/sync', ...blockchain.sync }, + + { method: 'POST', path: '/blocks', ...blocks.store }, + + { method: 'GET', path: '/rounds/current', ...rounds.current }, + + { method: 'POST', path: '/transactions/verify', ...transactions.verify }, + { method: 'GET', path: '/transactions/forging', ...transactions.forging }, + + { method: 'GET', path: '/utils/usernames', ...utils.usernames }, + { method: 'POST', path: '/utils/events', ...utils.emitEvent }, ]) } @@ -25,7 +34,7 @@ const register = async (server, options) => { * @type {Object} */ exports.plugin = { - name: 'ARK P2P API - Internal', + name: 'Ark P2P API - Internal', version: '0.1.0', - register + register, } diff --git a/packages/core-p2p/lib/server/versions/internal/schemas/blocks.js b/packages/core-p2p/lib/server/versions/internal/schemas/blocks.js new file mode 100644 index 0000000000..b6c56ac379 --- /dev/null +++ b/packages/core-p2p/lib/server/versions/internal/schemas/blocks.js @@ -0,0 +1,10 @@ +const Joi = require('@arkecosystem/crypto').validator.engine.joi + +/** + * @type {Object} + */ +exports.store = { + payload: { + block: Joi.arkBlock().options({ stripUnknown: true }), + }, +} diff --git a/packages/core-p2p/lib/server/versions/internal/schemas/transactions.js b/packages/core-p2p/lib/server/versions/internal/schemas/transactions.js new file mode 100644 index 0000000000..4f638ae050 --- /dev/null +++ b/packages/core-p2p/lib/server/versions/internal/schemas/transactions.js @@ -0,0 +1,10 @@ +const Joi = require('joi') + +/** + * @type {Object} + */ +exports.verify = { + payload: { + transaction: Joi.string().hex(), + }, +} diff --git a/packages/core-p2p/lib/server/versions/internal/schemas/utils.js b/packages/core-p2p/lib/server/versions/internal/schemas/utils.js new file mode 100644 index 0000000000..6ea9d91398 --- /dev/null +++ b/packages/core-p2p/lib/server/versions/internal/schemas/utils.js @@ -0,0 +1,11 @@ +const Joi = require('joi') + +/** + * @type {Object} + */ +exports.emitEvent = { + payload: { + event: Joi.string(), + body: Joi.any(), + }, +} diff --git a/packages/core-p2p/lib/server/versions/remote/handlers.js b/packages/core-p2p/lib/server/versions/remote/handlers.js deleted file mode 100644 index 22368f0461..0000000000 --- a/packages/core-p2p/lib/server/versions/remote/handlers.js +++ /dev/null @@ -1,37 +0,0 @@ -'use strict' - -const container = require('@arkecosystem/core-container') - -/** - * Respond with a blockchain event. - * @type {Object} - */ -exports.sendBlockchainEvent = { - /** - * @param {Hapi.Request} request - * @param {Hapi.Toolkit} h - * @return {Hapi.Response} - */ - handler: (request, h) => { - const blockchain = container.resolvePlugin('blockchain') - - if (!blockchain[request.params.event]) { - return h.response({ - success: false, - event: request.params.event, - message: 'No such event' - }).code(500) - } - - const event = blockchain[request.params.event] - - request.query.param - ? event(request.query.paramrequest.params.param) - : event() - - return { - success: true, - event: request.params.event - } - } -} diff --git a/packages/core-p2p/lib/server/versions/remote/handlers/blockchain.js b/packages/core-p2p/lib/server/versions/remote/handlers/blockchain.js new file mode 100644 index 0000000000..30a2e5eb93 --- /dev/null +++ b/packages/core-p2p/lib/server/versions/remote/handlers/blockchain.js @@ -0,0 +1,26 @@ +const app = require('@arkecosystem/core-container') +const schema = require('../schemas/blockchain') + +/** + * Respond with a blockchain event. + * @type {Object} + */ +exports.emitEvent = { + /** + * @param {Hapi.Request} request + * @param {Hapi.Toolkit} h + * @return {Hapi.Response} + */ + handler: (request, h) => { + const event = app.resolvePlugin('blockchain').events[ + request.params.event + ] + + request.query.param ? event(request.query.params) : event() + + return h.response(null).code(204) + }, + options: { + validate: schema.emitEvent, + }, +} diff --git a/packages/core-p2p/lib/server/versions/remote/index.js b/packages/core-p2p/lib/server/versions/remote/index.js index 4ed47aa1dc..b81de5091a 100644 --- a/packages/core-p2p/lib/server/versions/remote/index.js +++ b/packages/core-p2p/lib/server/versions/remote/index.js @@ -1,6 +1,4 @@ -'use strict' - -const handlers = require('./handlers') +const blockchain = require('./handlers/blockchain') /** * Register remote routes. @@ -10,7 +8,7 @@ const handlers = require('./handlers') */ const register = async (server, options) => { server.route([ - { method: 'GET', path: '/blockchain/{event}', ...handlers.sendBlockchainEvent } + { method: 'GET', path: '/blockchain/{event}', ...blockchain.emitEvent }, ]) } @@ -19,7 +17,7 @@ const register = async (server, options) => { * @type {Object} */ exports.plugin = { - name: 'ARK P2P API - Remote', + name: 'Ark P2P - Remote API', version: '0.1.0', - register + register, } diff --git a/packages/core-p2p/lib/server/versions/remote/schemas/blockchain.js b/packages/core-p2p/lib/server/versions/remote/schemas/blockchain.js new file mode 100644 index 0000000000..ffada1bce9 --- /dev/null +++ b/packages/core-p2p/lib/server/versions/remote/schemas/blockchain.js @@ -0,0 +1,10 @@ +const Joi = require('joi') + +/** + * @type {Object} + */ +exports.emitEvent = { + params: { + event: Joi.string(), + }, +} diff --git a/packages/core-p2p/lib/utils/check-dns.js b/packages/core-p2p/lib/utils/check-dns.js index 1f19411f8f..9f1b7b3641 100644 --- a/packages/core-p2p/lib/utils/check-dns.js +++ b/packages/core-p2p/lib/utils/check-dns.js @@ -1,9 +1,11 @@ +/* eslint no-await-in-loop: "off" */ + const util = require('util') const dns = require('dns') const shuffle = require('lodash/shuffle') const logger = require('@arkecosystem/core-container').resolvePlugin('logger') -module.exports = async (hosts) => { +module.exports = async hosts => { hosts = shuffle(hosts) const lookupService = util.promisify(dns.lookupService) @@ -18,5 +20,9 @@ module.exports = async (hosts) => { } } - Promise.reject(new Error('Please check your network connectivity, couldn\'t connect to any host.')) + return Promise.reject( + new Error( + "Please check your network connectivity, couldn't connect to any host.", + ), + ) } diff --git a/packages/core-p2p/lib/utils/check-ntp.js b/packages/core-p2p/lib/utils/check-ntp.js index 824299d72d..17363969ff 100644 --- a/packages/core-p2p/lib/utils/check-ntp.js +++ b/packages/core-p2p/lib/utils/check-ntp.js @@ -1,3 +1,5 @@ +/* eslint no-await-in-loop: "off" */ + const Sntp = require('sntp') const shuffle = require('lodash/shuffle') const logger = require('@arkecosystem/core-container').resolvePlugin('logger') @@ -12,21 +14,22 @@ module.exports = (hosts, timeout = 1000) => { hosts = shuffle(hosts) return new Promise(async (resolve, reject) => { - for (let i = hosts.length - 1; i >= 0; i--) { + for (const host of hosts) { try { - const time = await Sntp.time({ host: hosts[i], timeout }) + const time = await Sntp.time({ host, timeout }) - // @see https://github.com/hueniverse/sntp/issues/26 - if (time.errno) { - logger.error(`Host ${hosts[i]} responsed with: ${time.message}`) - } else { - return resolve({ time, host: hosts[i] }) - } + return time.errno + ? logger.error(`Host ${host} responsed with: ${time.message}`) + : resolve({ time, host }) } catch (err) { - logger.error(`Host ${hosts[i]} responsed with: ${err.message}`) + logger.error(`Host ${host} responsed with: ${err.message}`) } } - reject(new Error('Please check your NTP connectivity, couldn\'t connect to any host.')) + reject( + new Error( + "Please check your NTP connectivity, couldn't connect to any host.", + ), + ) }) } diff --git a/packages/core-p2p/lib/utils/is-myself.js b/packages/core-p2p/lib/utils/is-myself.js index b7cab7815c..da828c07a4 100644 --- a/packages/core-p2p/lib/utils/is-myself.js +++ b/packages/core-p2p/lib/utils/is-myself.js @@ -1,3 +1,5 @@ +/* eslint max-len: "off" */ + const os = require('os') /** @@ -8,7 +10,7 @@ const os = require('os') module.exports = ipAddress => { const interfaces = os.networkInterfaces() - return Object.keys(interfaces).some(ifname => { - return interfaces[ifname].some(iface => iface.address === ipAddress) - }) + return Object.keys(interfaces).some(ifname => + interfaces[ifname].some(iface => iface.address === ipAddress), + ) } diff --git a/packages/core-p2p/lib/utils/is-whitelist.js b/packages/core-p2p/lib/utils/is-whitelist.js index f11fe48a9d..c4a760d4e0 100644 --- a/packages/core-p2p/lib/utils/is-whitelist.js +++ b/packages/core-p2p/lib/utils/is-whitelist.js @@ -1,5 +1,3 @@ -'use strict' - const mm = require('micromatch') /** diff --git a/packages/core-p2p/lib/utils/network-state.js b/packages/core-p2p/lib/utils/network-state.js index 88267cee8a..1f3b65d62d 100644 --- a/packages/core-p2p/lib/utils/network-state.js +++ b/packages/core-p2p/lib/utils/network-state.js @@ -1,54 +1,73 @@ -'use strict' -const container = require('@arkecosystem/core-container') -const config = container.resolvePlugin('config') +const app = require('@arkecosystem/core-container') + +const config = app.resolvePlugin('config') const { slots } = require('@arkecosystem/crypto') /** * Returns current network state. Peers are update before the call - * @param {Monitor} p2pMonitor + * @param {Monitor} monitor * @private {Block} lastBlock * @returns {Object} JSON response for the forger to assess if allowed to forge or not */ -module.exports = (p2pMonitor, lastBlock) => { - const peers = p2pMonitor.getPeers() +module.exports = (monitor, lastBlock) => { + const createStateObject = ( + quorum, + minimumNetworkReach, + coldStart, + overHeightBlockHeader, + ) => ({ + quorum, + nodeHeight: lastBlock.data.height, + lastBlockId: lastBlock.data.id, + overHeightBlockHeader, + minimumNetworkReach, + coldStart, + }) + + const peers = monitor.getPeers() const minimumNetworkReach = config.peers.minimumNetworkReach || 20 const currentSlot = slots.getSlotNumber() let quorum = 0 - let noquorum = 0 + let noQuorum = 0 let overHeightQuorum = 0 let overHeightBlockHeader = null - if (p2pMonitor.__isColdStartActive()) { - return {quorum: 0, nodeHeight: lastBlock.data.height, lastBlockId: lastBlock.data.id, overHeightBlockHeader: overHeightBlockHeader, minimumNetworkReach: true, coldStart: true} + if (monitor.__isColdStartActive()) { + return createStateObject(0, true, true, overHeightBlockHeader) } if (process.env.ARK_ENV === 'test') { - return {quorum: 1, nodeHeight: lastBlock.data.height, lastBlockId: lastBlock.data.id, overHeightBlockHeader: overHeightBlockHeader, minimumNetworkReach: true, coldStart: false} + return createStateObject(1, true, false, overHeightBlockHeader) } if (peers.length < minimumNetworkReach) { - return {quorum: 0, nodeHeight: lastBlock.data.height, lastBlockId: lastBlock.data.id, overHeightBlockHeader: overHeightBlockHeader, minimumNetworkReach: false, coldStart: false} + return createStateObject(0, false, false, overHeightBlockHeader) } for (const peer of peers) { if (peer.state.height === lastBlock.data.height) { - if (peer.state.header.id === lastBlock.data.id && peer.state.currentSlot === currentSlot && peer.state.forgingAllowed) { - quorum = quorum + 1 + if ( + peer.state.header.id === lastBlock.data.id + && peer.state.currentSlot === currentSlot + && peer.state.forgingAllowed + ) { + quorum += 1 } else { - noquorum = noquorum + 1 + noQuorum += 1 } } else if (peer.state.height > lastBlock.data.height) { - noquorum = noquorum + 1 - overHeightQuorum = overHeightQuorum + 1 + noQuorum += 1 + overHeightQuorum += 1 overHeightBlockHeader = peer.state.header - } else if (lastBlock.data.height - peer.state.height < 3) { // suppose the max network elasticity accross 3 blocks - noquorum = noquorum + 1 + } else if (lastBlock.data.height - peer.state.height < 3) { + // suppose the max network elasticity accross 3 blocks + noQuorum += 1 } } - const calculatedQuorum = quorum / (quorum + noquorum) + const calculatedQuorum = quorum / (quorum + noQuorum) - return {quorum: calculatedQuorum, nodeHeight: lastBlock.data.height, lastBlockId: lastBlock.data.id, overHeightBlockHeader: overHeightBlockHeader, minimumNetworkReach: true, coldStart: false} + return createStateObject(calculatedQuorum, true, false, overHeightBlockHeader) } diff --git a/packages/core-p2p/package.json b/packages/core-p2p/package.json index 6be122bbc6..d152b6c190 100644 --- a/packages/core-p2p/package.json +++ b/packages/core-p2p/package.json @@ -1,7 +1,7 @@ { "name": "@arkecosystem/core-p2p", - "description": "P2P API for ARK Core", - "version": "0.1.1", + "description": "P2P API for Ark Core", + "version": "0.2.0", "contributors": [ "François-Xavier Thoorens ", "Kristjan Košič ", @@ -11,35 +11,50 @@ "license": "MIT", "main": "lib/index.js", "scripts": { - "build:docs": "../../node_modules/.bin/jsdoc -c jsdoc.json", "test": "cross-env ARK_ENV=test jest --runInBand --detectOpenHandles", - "test:coverage": "cross-env ARK_ENV=test jest --coverage --runInBand --detectOpenHandles", - "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand --watch", + "test:coverage": "cross-env ARK_ENV=test jest --coverage --coveragePathIgnorePatterns='/(defaults.js|index.js)$' --runInBand --detectOpenHandles", + "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand", "test:watch": "cross-env ARK_ENV=test jest --runInBand --watch", "test:watch:all": "cross-env ARK_ENV=test jest --runInBand --watchAll", "lint": "eslint ./ --fix", - "depcheck": "depcheck ./" + "depcheck": "depcheck ./ --ignores=lodash,lodash.*" }, "dependencies": { - "@arkecosystem/core-container": "^0.1.1", - "@arkecosystem/core-transaction-pool": "^0.1.1", - "@arkecosystem/crypto": "^0.1.1", + "@arkecosystem/core-container": "~0.2", + "@arkecosystem/core-http-utils": "~0.2", + "@arkecosystem/core-transaction-pool": "~0.2", + "@arkecosystem/crypto": "~0.2", + "ajv": "^6.5.5", "axios": "^0.18.0", - "delay": "^3.0.0", - "hapi": "^17.5.0", - "limiter": "^1.1.3", - "lodash": "^4.17.10", + "boom": "^7.3.0", + "dayjs-ext": "^2.2.0", + "delay": "^4.1.0", + "hapi-rate-limit": "^2.1.4", + "ip": "^1.1.5", + "joi": "^14.3.0", + "lodash.chunk": "^4.2.0", + "lodash.flatten": "^4.4.0", + "lodash.groupby": "^4.6.0", + "lodash.head": "^4.0.1", + "lodash.sample": "^4.2.1", + "lodash.shuffle": "^4.2.0", + "lodash.sumby": "^4.6.0", + "lodash.take": "^4.1.1", "micromatch": "^3.1.10", - "moment": "^2.22.2", - "pretty-ms": "^3.2.0", - "request-ip": "^2.0.2", - "semver": "^5.5.0", - "sntp": "^3.0.1" + "pluralize": "^7.0.0", + "pretty-ms": "^4.0.0", + "request-ip": "^2.1.3", + "semver": "^5.6.0", + "sntp": "^3.0.2" + }, + "devDependencies": { + "@arkecosystem/core-test-utils": "~0.2", + "axios-mock-adapter": "^1.15.0" }, "publishConfig": { "access": "public" }, - "devDependencies": { - "axios-mock-adapter": "^1.15.0" + "engines": { + "node": ">=10.x" } } diff --git a/packages/core-snapshots-cli/CHANGELOG.md b/packages/core-snapshots-cli/CHANGELOG.md new file mode 100644 index 0000000000..6842caf9df --- /dev/null +++ b/packages/core-snapshots-cli/CHANGELOG.md @@ -0,0 +1,14 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +## Unreleased + +## 0.1.0 - 2018-12-03 + +### Added + +- initial release diff --git a/packages/core-snapshots-cli/LICENSE b/packages/core-snapshots-cli/LICENSE new file mode 100644 index 0000000000..d6dd75272f --- /dev/null +++ b/packages/core-snapshots-cli/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) Ark Ecosystem + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/core-snapshots-cli/README.md b/packages/core-snapshots-cli/README.md new file mode 100644 index 0000000000..d6036047e2 --- /dev/null +++ b/packages/core-snapshots-cli/README.md @@ -0,0 +1,22 @@ +# Ark Core - Snapshots CLI + +

+ +

+ +## Documentation + +You can find installation instructions and detailed instructions on how to use this package at the [dedicated documentation site](https://docs.ark.io/guidebook/core/plugins/core-snapshots-cli.html). + +## Security + +If you discover a security vulnerability within this package, please send an e-mail to security@ark.io. All security vulnerabilities will be promptly addressed. + +## Credits + +- [Kristjan Košič](https://github.com/kristjank) +- [All Contributors](../../../../contributors) + +## License + +[MIT](LICENSE) © [ArkEcosystem](https://ark.io) diff --git a/packages/core-snapshots-cli/__tests__/.gitkeep b/packages/core-snapshots-cli/__tests__/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/core-snapshots-cli/bin/snapshot b/packages/core-snapshots-cli/bin/snapshot new file mode 100755 index 0000000000..7a5fa62ec7 --- /dev/null +++ b/packages/core-snapshots-cli/bin/snapshot @@ -0,0 +1,72 @@ +#!/usr/bin/env node + +const cli = require('commander') +const util = require('../lib/utils') +const app = require('@arkecosystem/core-container') + +cli.version(require('../package.json').version) + +const registerCommand = (name, description) => { + return cli + .command(name) + .description(description) + .option('-d, --data ', 'data directory', '~/.ark') + .option('-c, --config ', 'network config', '~/.ark/config') + .option('-t, --token ', 'token name', 'ark') + .option('-n, --network ', 'token network') + .option('--skip-compression', 'skip gzip compression', false) + .option('--trace', 'dumps generated queries and settings to console', false) +} + +registerCommand('create', 'create a full snapshot of the database') + .option('-b, --blocks ', 'blocks to append to, correlates to folder name') + .option('-s, --start ', 'start network height to export', -1) + .option('-e, --end ', 'end network height to export', -1) + .option('--codec ', 'codec name, default is msg-lite binary') + .action(async (options) => { + await util.setUpLite(options) + await require('../lib/commands/create')(options) + }) + +registerCommand('import', 'import data from specified snapshot') + .option('-b, --blocks ', 'blocks to import, corelates to folder name') + .option('--codec ', 'codec name, default is msg-lite binary') + .option('--truncate', 'empty all tables before running import', false) + .option('--skip-restart-round', 'skip revert to current round', false) + .option('--signature-verify', 'signature verification', false) + .action(async (options) => { + await util.setUpLite(options) + await require('../lib/commands/import')(options) + }) + +registerCommand('verify', 'check validity of specified snapshot') + .option('-b, --blocks ', 'blocks to verify, corelates to folder name') + .option('--codec ', 'codec name, default is msg-lite binary') + .option('--signature-verify', 'signature verification', false) + .action(async (options) => { + await util.setUpLite(options) + await require('../lib/commands/verify')(options) + }) + +registerCommand('rollback', 'rollback chain to specified height') + .option('-b, --block-height ', 'block network height number to rollback', -1) + .action(async (options) => { + await util.setUpLite(options) + require('../lib/commands/rollback')(options) + }) + +registerCommand('truncate', 'truncate blockchain database') + .action(async (options) => { + await util.setUpLite(options) + require('../lib/commands/truncate')(options) + }) + +cli + .command('*') + .action(env => { + cli.help() + process.exit(0) + }) + +app.silentShutdown = true +cli.parse(process.argv) diff --git a/packages/core-snapshots-cli/jest.config.js b/packages/core-snapshots-cli/jest.config.js new file mode 100644 index 0000000000..57770a97bb --- /dev/null +++ b/packages/core-snapshots-cli/jest.config.js @@ -0,0 +1,12 @@ +module.exports = { + testEnvironment: 'node', + bail: false, + verbose: true, + testMatch: ['**/__tests__/**/*.test.js'], + moduleFileExtensions: ['js', 'json'], + collectCoverage: false, + coverageDirectory: '/.coverage', + collectCoverageFrom: ['lib/**/*.js', '!**/node_modules/**'], + watchman: false, + setupTestFrameworkScriptFile: 'jest-extended', +} diff --git a/packages/client/jsdoc.json b/packages/core-snapshots-cli/jsdoc.json similarity index 90% rename from packages/client/jsdoc.json rename to packages/core-snapshots-cli/jsdoc.json index 23276f74ea..f3ea8aab33 100644 --- a/packages/client/jsdoc.json +++ b/packages/core-snapshots-cli/jsdoc.json @@ -7,9 +7,7 @@ "includePattern": ".js$", "excludePattern": "(node_modules/|docs)" }, - "plugins": [ - "plugins/markdown" - ], + "plugins": ["plugins/markdown"], "opts": { "template": "../../node_modules/docdash", "encoding": "utf8", diff --git a/packages/core-snapshots-cli/lib/commands/create.js b/packages/core-snapshots-cli/lib/commands/create.js new file mode 100644 index 0000000000..81a107e800 --- /dev/null +++ b/packages/core-snapshots-cli/lib/commands/create.js @@ -0,0 +1,24 @@ +const fs = require('fs-extra') +const app = require('@arkecosystem/core-container') + +const logger = app.resolvePlugin('logger') +const snapshotManager = app.resolvePlugin('snapshots') + +const utils = require('../utils') + +module.exports = async options => { + if (options.filename && !fs.existsSync(utils.getPath(options.filename))) { + logger.error( + `Appending not possible. Existing snapshot ${ + options.filename + } not found. Exiting...`, + ) + throw new Error( + `Appending not possible. Existing snapshot ${ + options.filename + } not found. Exiting...`, + ) + } else { + await snapshotManager.exportData(options) + } +} diff --git a/packages/core-snapshots-cli/lib/commands/import.js b/packages/core-snapshots-cli/lib/commands/import.js new file mode 100644 index 0000000000..bcb9f267ac --- /dev/null +++ b/packages/core-snapshots-cli/lib/commands/import.js @@ -0,0 +1,29 @@ +const app = require('@arkecosystem/core-container') + +const snapshotManager = app.resolvePlugin('snapshots') +const emitter = app.resolvePlugin('event-emitter') +const _cliProgress = require('cli-progress') + +module.exports = async options => { + const progressBar = new _cliProgress.Bar( + { + format: + '{bar} {percentage}% | ETA: {eta}s | {value}/{total} | Duration: {duration}s', + }, + _cliProgress.Presets.shades_classic, + ) + + emitter.on('start', data => { + progressBar.start(data.count, 1) + }) + + emitter.on('progress', data => { + progressBar.update(data.value) + }) + + emitter.on('complete', data => { + progressBar.stop() + }) + + await snapshotManager.importData(options) +} diff --git a/packages/core-snapshots-cli/lib/commands/rollback.js b/packages/core-snapshots-cli/lib/commands/rollback.js new file mode 100644 index 0000000000..0b4b675765 --- /dev/null +++ b/packages/core-snapshots-cli/lib/commands/rollback.js @@ -0,0 +1,19 @@ +const app = require('@arkecosystem/core-container') + +const logger = app.resolvePlugin('logger') +const snapshotManager = app.resolvePlugin('snapshots') + +module.exports = async options => { + if (options.blockHeight === -1) { + logger.warn( + 'Rollback height is not specified. Rolling back to last completed round.', + ) + } + logger.info( + `Starting the process of blockchain rollback to block height of ${ + options.blockHeight.toLocaleString() + }`, + ) + + await snapshotManager.rollbackChain(options.blockHeight) +} diff --git a/packages/core-snapshots-cli/lib/commands/truncate.js b/packages/core-snapshots-cli/lib/commands/truncate.js new file mode 100644 index 0000000000..c6edc37b0a --- /dev/null +++ b/packages/core-snapshots-cli/lib/commands/truncate.js @@ -0,0 +1,7 @@ +const app = require('@arkecosystem/core-container') + +const snapshotManager = app.resolvePlugin('snapshots') + +module.exports = async options => { + await snapshotManager.truncateChain() +} diff --git a/packages/core-snapshots-cli/lib/commands/verify.js b/packages/core-snapshots-cli/lib/commands/verify.js new file mode 100644 index 0000000000..8d3c100f8b --- /dev/null +++ b/packages/core-snapshots-cli/lib/commands/verify.js @@ -0,0 +1,23 @@ +const fs = require('fs-extra') +const app = require('@arkecosystem/core-container') + +const logger = app.resolvePlugin('logger') +const snapshotManager = app.resolvePlugin('snapshots') + +module.exports = async options => { + if ( + options.filename + && !fs.existsSync( + `${process.env.ARK_PATH_DATA}/snapshots/${process.env.ARK_NETWORK_NAME}/${ + options.filename + }`, + ) + ) { + logger.error(`Verify not possible. Snapshot ${options.filename} not found.`) + logger.info( + 'Use -f parameter with just the filename and not the full path.', + ) + } else { + await snapshotManager.verifyData(options) + } +} diff --git a/packages/core-snapshots-cli/lib/utils/index.js b/packages/core-snapshots-cli/lib/utils/index.js new file mode 100644 index 0000000000..95c3504077 --- /dev/null +++ b/packages/core-snapshots-cli/lib/utils/index.js @@ -0,0 +1,18 @@ +const app = require('@arkecosystem/core-container') + +exports.setUpLite = async options => { + process.env.ARK_SKIP_BLOCKCHAIN = true + await app.setUp('2.0.0', options, { + include: [ + '@arkecosystem/core-config', + '@arkecosystem/core-logger', + '@arkecosystem/core-logger-winston', + '@arkecosystem/core-event-emitter', + '@arkecosystem/core-snapshots', + ], + }) + + return app +} + +exports.tearDown = async () => app.tearDown() diff --git a/packages/core-snapshots-cli/package.json b/packages/core-snapshots-cli/package.json new file mode 100644 index 0000000000..528cba7899 --- /dev/null +++ b/packages/core-snapshots-cli/package.json @@ -0,0 +1,50 @@ +{ + "name": "@arkecosystem/core-snapshots-cli", + "description": "Provides live cli interface to the core-snapshots module for ARK Core", + "version": "0.1.0", + "contributors": [ + "Kristjan Košič " + ], + "license": "MIT", + "bin": { + "ark:snapshot": "./bin/snapshot" + }, + "scripts": { + "start": "./bin/snapshot", + "debug": "node --inspect-brk ./bin/snapshot", + "create:mainnet": "./bin/snapshot create --config ../core/lib/config/mainnet --network mainnet", + "create:devnet": "./bin/snapshot create --config ../core/lib/config/devnet --network devnet", + "create:testnet": "./bin/snapshot create --config ../core/lib/config/testnet --network testnet", + "import:mainnet": "./bin/snapshot import --config ../core/lib/config/mainnet --network mainnet", + "import:devnet": "./bin/snapshot import --config ../core/lib/config/devnet --network devnet", + "import:testnet": "./bin/snapshot import --config ../core/lib/config/testnet --network testnet", + "verify:mainnet": "./bin/snapshot verify --config ../core/lib/config/mainnet --network mainnet", + "verify:devnet": "./bin/snapshot verify --config ../core/lib/config/devnet --network devnet", + "verify:testnet": "./bin/snapshot verify --config ../core/lib/config/testnet --network testnet", + "rollback:mainnet": "./bin/snapshot rollback --config ../core/lib/config/mainnet --network mainnet", + "rollback:devnet": "./bin/snapshot rollback --config ../core/lib/config/devnet --network devnet", + "rollback:testnet": "./bin/snapshot rollback --config ../core/lib/config/testnet --network testnet", + "truncate:mainnet": "./bin/snapshot truncate --config ../core/lib/config/mainnet --network mainnet", + "truncate:devnet": "./bin/snapshot truncate --config ../core/lib/config/devnet --network devnet", + "truncate:testnet": "./bin/snapshot truncate --config ../core/lib/config/testnet --network testnet", + "test": "cross-env ARK_ENV=test jest --runInBand --detectOpenHandles", + "test:coverage": "cross-env ARK_ENV=test jest --coverage --runInBand --detectOpenHandles", + "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand --watch", + "test:watch": "cross-env ARK_ENV=test jest --runInBand --watch", + "test:watch:all": "cross-env ARK_ENV=test jest --runInBand --watchAll", + "lint": "eslint ./ --fix", + "depcheck": "depcheck ./ --ignores=commander" + }, + "dependencies": { + "@arkecosystem/core-container": "~0.2", + "cli-progress": "^2.1.0", + "commander": "^2.19.0", + "fs-extra": "^7.0.1" + }, + "publishConfig": { + "access": "public" + }, + "engines": { + "node": ">=10.x" + } +} diff --git a/packages/core-snapshots/CHANGELOG.md b/packages/core-snapshots/CHANGELOG.md new file mode 100644 index 0000000000..6842caf9df --- /dev/null +++ b/packages/core-snapshots/CHANGELOG.md @@ -0,0 +1,14 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +## Unreleased + +## 0.1.0 - 2018-12-03 + +### Added + +- initial release diff --git a/packages/core-snapshots/LICENSE b/packages/core-snapshots/LICENSE new file mode 100644 index 0000000000..d6dd75272f --- /dev/null +++ b/packages/core-snapshots/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) Ark Ecosystem + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/core-snapshots/README.md b/packages/core-snapshots/README.md new file mode 100644 index 0000000000..a5e03644b1 --- /dev/null +++ b/packages/core-snapshots/README.md @@ -0,0 +1,22 @@ +# Ark Core - Snapshots + +

+ +

+ +## Documentation + +You can find installation instructions and detailed instructions on how to use this package at the [dedicated documentation site](https://docs.ark.io/guidebook/core/plugins/core-snapshots.html). + +## Security + +If you discover a security vulnerability within this package, please send an e-mail to security@ark.io. All security vulnerabilities will be promptly addressed. + +## Credits + +- [Kristjan Košič](https://github.com/kristjank) +- [All Contributors](../../../../contributors) + +## License + +[MIT](LICENSE) © [ArkEcosystem](https://ark.io) diff --git a/packages/core-snapshots/__tests__/.gitkeep b/packages/core-snapshots/__tests__/.gitkeep new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/core-snapshots/__tests__/fixtures/blocks.js b/packages/core-snapshots/__tests__/fixtures/blocks.js new file mode 100644 index 0000000000..320544a270 --- /dev/null +++ b/packages/core-snapshots/__tests__/fixtures/blocks.js @@ -0,0 +1,184 @@ +/* eslint camelcase: "off" */ + +exports.blocks = [ + { + id: '13114381566690093367', + version: 0, + timestamp: 0, + previous_block: null, + height: 1, + number_of_transactions: 52, + total_amount: '12500000000000000', + total_fee: '0', + reward: '0', + payload_length: 11395, + payload_hash: + '2a44f340d76ffc3df204c5f38cd355b7496c9065a1ade2ef92071436bd72e867', + generator_public_key: + '03d3fdad9c5b25bf8880e6b519eb3611a5c0b31adebc8455f0e096175b28321aff', + block_signature: + '3044022035694a9b99a9236655c658eb07fc3b02ce5edcc24b76424a7287c54ed3822b0602203621e92defb360490610f763d85e94c2db2807a4bd7756cc8a6a585463ef7bae', + }, + { + id: '15735126799781289065', + version: 0, + timestamp: 45020906, + previous_block: '13114381566690093367', + height: 2, + number_of_transactions: 0, + total_amount: '0', + total_fee: '0', + reward: '0', + payload_length: 0, + payload_hash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generator_public_key: + '02637b15aa50fa95018609a6d7b52b025de807a41b79b164626cee87dd6f61a662', + block_signature: + '304402204020c837df631582fa32c5b160761dd38afc0c65149782773d1277d696dd4596022029d7de41039b7a55ceec37bfd27dec92c1cf4c93e6fc737e74b76fb9f1fb320a', + }, + { + id: '4438392404769884042', + version: 0, + timestamp: 45020914, + previous_block: '15735126799781289065', + height: 3, + number_of_transactions: 0, + total_amount: '0', + total_fee: '0', + reward: '0', + payload_length: 0, + payload_hash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generator_public_key: + '02e9ef70986ab6de9dbd5e1f430018bb8dea671d30c1e34af5146a48f2b73d551d', + block_signature: + '30440220153d88f4017960e6cd920a72c516c68c484d31324bd0e89101218a9da621eed3022055cdd5907d2b9fafd761e0c652c4c63cb8bc2ae5c424189066d44f6068957c13', + }, + { + id: '5712353664969387846', + version: 0, + timestamp: 45020922, + previous_block: '4438392404769884042', + height: 4, + number_of_transactions: 0, + total_amount: '0', + total_fee: '0', + reward: '0', + payload_length: 0, + payload_hash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generator_public_key: + '02951227bb3bc5309aeb96460dbdf945746012810bb4020f35c20feae4eea7e5d4', + block_signature: + '304502210083e2060bcbd7d03ee0d02fcf93ff4a5b18e38003b46d9772b8cab50adfbfd765022001c5941bce33e82bcae8cf00ad666fbbdd812df48dc5bdb2f03afa57d33eb90c', + }, + { + id: '570772616607779515', + version: 0, + timestamp: 45020930, + previous_block: '5712353664969387846', + height: 5, + number_of_transactions: 0, + total_amount: '0', + total_fee: '0', + reward: '0', + payload_length: 0, + payload_hash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generator_public_key: + '022eedf9f1cdae0cfaae635fe415b6a8f1912bc89bc3880ec41135d62cbbebd3d3', + block_signature: + '304402207e05134a7fc5fc1327035f7d86589acdb178f0085ca31eab8f5e46efaa2a5930022006756f0ce06d37a9dcaec3194fcacdbdc3a7773862e61635b93126556a088501', + }, + { + id: '746870545888859312', + version: 0, + timestamp: 45020938, + previous_block: '570772616607779515', + height: 6, + number_of_transactions: 0, + total_amount: '0', + total_fee: '0', + reward: '0', + payload_length: 0, + payload_hash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generator_public_key: + '02ac8d84d81648154f79ba64fbf64cd6ee60f385b2aa52e8eb72bc1374bf55a68c', + block_signature: + '30450221008f5618edd4a4991fc04a57637179d4360ec9f6cc5c044b1bb133c4bf9e9309c002203aaec695288cc935f9003c9013843e6ef26248eb6c937190dbd1dfb09a49a36f', + }, + { + id: '5917444039795114220', + version: 0, + timestamp: 45020946, + previous_block: '746870545888859312', + height: 7, + number_of_transactions: 0, + total_amount: '0', + total_fee: '0', + reward: '0', + payload_length: 0, + payload_hash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generator_public_key: + '027b320c5429334ecf846122492d12b898a756bf1347aa61f7bf1dcd706315a9fb', + block_signature: + '3045022100ab5667e66222b7293f0d8d1d1e443cb87529accd86337d3bcbe99f265011479802205d8c904988542bca99a40b0125c335e21ef4beebb829cb100273528082551a2a', + }, + { + id: '8140188225603335547', + version: 0, + timestamp: 45020960, + previous_block: '5917444039795114220', + height: 8, + number_of_transactions: 0, + total_amount: '0', + total_fee: '0', + reward: '0', + payload_length: 0, + payload_hash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generator_public_key: + '021b0f58eca7f123428a8647ffe0644a9454c510f066d3864c27d8c7ad8f5a8aa4', + block_signature: + '30440220670ea1a0acd5af3f01f6e30cfc6bfcbf66592fd0b75933dc9edf2fd06deb5c7502207ae623c982a09e6ee515e06c0e959584e3fb4b5d924c5fe686f9983e729c7057', + }, + { + id: '4508559087330535525', + version: 0, + timestamp: 45020970, + previous_block: '8140188225603335547', + height: 9, + number_of_transactions: 0, + total_amount: '0', + total_fee: '0', + reward: '0', + payload_length: 0, + payload_hash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generator_public_key: + '027f997ab2d8874c8f06d12ef78d39e309ed887a1141d2ba0f50aec8abffaffcde', + block_signature: + '3045022100ceeee0d244d67b087b272a17a9a073622f1472574dbdc0d9c36423645896a4d302206f297a1282b421022489b7de7c162e293906950628d2397729139eba840bee01', + }, + { + id: '13552594290532998422', + version: 0, + timestamp: 45020978, + previous_block: '4508559087330535525', + height: 10, + number_of_transactions: 0, + total_amount: '0', + total_fee: '0', + reward: '0', + payload_length: 0, + payload_hash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generator_public_key: + '03f89a2f86fe683dbbe4856a43c4c326fb2938ae2647fd334ad33261c7c2dee265', + block_signature: + '3044022015d943e2d858f3431434f4c128926c3d78322465a9526312193ff480f76a5f9a022071ea02f6073233bf2ce4be7aa264adc5a5255be1a0b48d5d96af3202670da222', + }, +] diff --git a/packages/core-snapshots/__tests__/fixtures/transactions.js b/packages/core-snapshots/__tests__/fixtures/transactions.js new file mode 100644 index 0000000000..706ff0e3c8 --- /dev/null +++ b/packages/core-snapshots/__tests__/fixtures/transactions.js @@ -0,0 +1,212 @@ +/* eslint camelcase: "off" */ + +exports.transactions = [ + { + id: '3e3817fd0c35bc36674f3874c2953fa3e35877cbcdb44a08bdc6083dbd39d572', + version: 1, + block_id: '13114381566690093367', + sequence: 0, + timestamp: 0, + sender_public_key: + '0208e6835a8f020cfad439c059b89addc1ce21f8cab0af6e6957e22d3720bff8a4', + recipient_id: 'D6Z26L69gdk9qYmTv5uzk3uGepigtHY4ax', + type: 0, + vendor_field_hex: null, + amount: '12500000000000000', + fee: '0', + serializedHex: + 'ff011e00000000000208e6835a8f020cfad439c059b89addc1ce21f8cab0af6e6957e22d3720bff8a40000000000000000000040b10baf682c00000000001e0f7e658ba40c1cb9bb72db528281abfa59164cd1304402203a3f0f80aad4e0561ae975f241f72a074245f1205d676d290d6e5630ed4c027502207b31fee68e64007c380a4b6baccd4db9b496daef5f7894676586e1347ac30a3b', + }, + { + id: '4041e3a8e3760e40e7b3d0269935b7894df156dbdd08092a9dfab32a00dc0572', + version: 1, + block_id: '13114381566690093367', + sequence: 29, + timestamp: 0, + sender_public_key: + '0212a11582a28f178b906edbf8e8c447ce1ba86041ee731e595ae4d39ef034c2ad', + recipient_id: null, + type: 2, + vendor_field_hex: null, + amount: '0', + fee: '0', + serializedHex: + 'ff011e02000000000212a11582a28f178b906edbf8e8c447ce1ba86041ee731e595ae4d39ef034c2ad0000000000000000000a67656e657369735f33303044022065af2653051345aef10cebf5f98210f228af00768b094eb0f82a5a0765180ca202203c87461e7e40f17273be4638f604b01cae72c47ffe8815917d0dae6f6195709b', + }, + { + id: 'ffc28e2cddf4494fa4bdebd90e5b8fa41253c1faa02a95eca0d7ba6bd04ca616', + version: 1, + block_id: '13114381566690093367', + sequence: 30, + timestamp: 0, + sender_public_key: + '027b320c5429334ecf846122492d12b898a756bf1347aa61f7bf1dcd706315a9fb', + recipient_id: null, + type: 2, + vendor_field_hex: null, + amount: '0', + fee: '0', + serializedHex: + 'ff011e0200000000027b320c5429334ecf846122492d12b898a756bf1347aa61f7bf1dcd706315a9fb0000000000000000000a67656e657369735f333130450221009c0682b562cb4405cea7e522d7b98b628af4b33c1bfbea354d67351a0d3a066402204e1c060c533c8a8896dbfd5e6219e2a0e7d96c9d40cbbb23bbdf8bc6c0450bb8', + }, + { + id: '7590a188ae48a4deec150be19947638b0fcf273141dc1580385060e6e4c28caf', + version: 1, + block_id: '14911599679969610348', + sequence: 22, + timestamp: 45021290, + sender_public_key: + '03a3c6fd74a23fbe1e02f08d9c626ebb255b48de7ba8c283ee27c9303be81a2933', + recipient_id: 'DTKn3J3pMjtPLJxZtjvqR5T6DefPzjgGdf', + type: 3, + vendor_field_hex: null, + amount: '0', + fee: '100000000', + serializedHex: + 'ff011e0366f8ae0203a3c6fd74a23fbe1e02f08d9c626ebb255b48de7ba8c283ee27c9303be81a293300e1f5050000000000010103a3c6fd74a23fbe1e02f08d9c626ebb255b48de7ba8c283ee27c9303be81a29333044022007dcaa3b9416ea1197a4ef0ca75cda80e50f9b0f58b0f9bcc2e1e00533bd1c9302205ecb2d51c2b8f3373020b4d613f402541a3357cc96a1541f1bf47cbcef762f9a', + }, + { + id: '781397490f2acab13721556ff8d97aaed1156f707c14dcb511e59963c66467c9', + version: 1, + block_id: '14911599679969610348', + sequence: 23, + timestamp: 45021290, + sender_public_key: + '0346e1a1b5cb0720e863e8cf8a91dc8ed827e09fb4a4812f9f4d51f606e5359516', + recipient_id: 'D5L5zXgvqtg7qoGimt5vYhFuf5Ued6iWVr', + type: 3, + vendor_field_hex: null, + amount: '0', + fee: '100000000', + serializedHex: + 'ff011e0366f8ae020346e1a1b5cb0720e863e8cf8a91dc8ed827e09fb4a4812f9f4d51f606e535951600e1f505000000000001010346e1a1b5cb0720e863e8cf8a91dc8ed827e09fb4a4812f9f4d51f606e53595163044022044fb38232294c0457a3ba75cd9da2be4d37c9ebc64eb85d7d890d8b213f8c6ad02207fab96c1a422389e284da5aecd777a7db9ea8250f300328a40295da6f780f46d', + }, + { + id: 'cb173dc8c269b907a0840f77a778ec67503c9e8f01cb448c86480e685cd46bbf', + version: 1, + block_id: '7029786768310419534', + sequence: 0, + timestamp: 45021298, + sender_public_key: + '02257c58004e5ae23716d1c44beea0cca7f5b522a692df367bae9015a4f15c1670', + recipient_id: 'D8vKwaX6ksU3mWg7tJDm7v1dbxy4cMo4dh', + type: 3, + vendor_field_hex: null, + amount: '0', + fee: '100000000', + serializedHex: + 'ff011e0367f8ae0202257c58004e5ae23716d1c44beea0cca7f5b522a692df367bae9015a4f15c167000e1f5050000000000010102257c58004e5ae23716d1c44beea0cca7f5b522a692df367bae9015a4f15c167030440220587ce5f588142845777cf2ebe653e3fc522bf62535d2e73fb29b4a8c36a5a84f02205f0d2041198a01f9e7e65972762f2dddd2b7f3df37dcde6037248e91544f1e51', + }, + { + id: '2fb72fc1f33c9ac479902c74861e95fb93880a9fa6ccc2efe38c7dcf5f0721cc', + version: 1, + block_id: '17044958519703434496', + sequence: 4, + timestamp: 45021218, + sender_public_key: + '03d3fdad9c5b25bf8880e6b519eb3611a5c0b31adebc8455f0e096175b28321aff', + recipient_id: 'D5pVkhZbSb4UNXvfmF6j7zdau8yGxfKwSv', + type: 0, + vendor_field_hex: null, + amount: '400000000', + fee: '10000000', + serializedHex: + 'ff011e0017f8ae0203d3fdad9c5b25bf8880e6b519eb3611a5c0b31adebc8455f0e096175b28321aff8096980000000000000084d71700000000000000001e077399dbb7a117a4956017b154c0be9cc98ac3bf30450221008e1ae52f2ff48b2fb3d647f828f5ef765127dbe4b66a06a07a00e73ae15a7c6402201302bf455f3f1e6a8541e61ed2f7b3ad9007fef1674b7859199d27e014ab9a31', + }, + { + id: '30baf8c7d428d64b5ac9696d76d229fce56077b557fd4e9633fc385676d36e18', + version: 1, + block_id: '17044958519703434496', + sequence: 5, + timestamp: 45021218, + sender_public_key: + '03d3fdad9c5b25bf8880e6b519eb3611a5c0b31adebc8455f0e096175b28321aff', + recipient_id: 'D7u9gSS3KsykEoRys7DxsRNwHjpYoG8mqS', + type: 0, + vendor_field_hex: null, + amount: '4500000000', + fee: '10000000', + serializedHex: + 'ff011e0019f8ae0203d3fdad9c5b25bf8880e6b519eb3611a5c0b31adebc8455f0e096175b28321aff809698000000000000008d380c01000000000000001e1e452d07ec1ca63b73aa33c4cb96a17026e1dbd83045022100df0948af0c8b81b0e9b1768c7e2cdfe0c52ac3560441186e2d3d08ca317367a002205888dfce34be3794d736dfa9897f366fd0b6d4595aea02eaa97898a9c8c575e4', + }, + { + id: '3246edce737a748021213d52ae14d14b73e8025c46c5a06a32fe6b314941a885', + version: 1, + block_id: '17044958519703434496', + sequence: 6, + timestamp: 45021218, + sender_public_key: + '03d3fdad9c5b25bf8880e6b519eb3611a5c0b31adebc8455f0e096175b28321aff', + recipient_id: 'DSQhC4JyfWaxsZKzF9Kfq5knVifCZA5jLK', + type: 0, + vendor_field_hex: null, + amount: '2300000000', + fee: '10000000', + serializedHex: + 'ff011e0018f8ae0203d3fdad9c5b25bf8880e6b519eb3611a5c0b31adebc8455f0e096175b28321aff8096980000000000000037178900000000000000001ee94dce82a20f9e89f88b93933678e7da3bace92a3044022065deb0b2a580825d3204b04990d43b7ccf065876e4c34cf7125920f7b61187a702207cb76e6b2c06fc81c571e6b878bb6584814847dcdf583ea451848f94ce8c2fea', + }, + { + id: '3314b72bced9456955f06d85b29951c9d3cd976154cd4b08c528d5993b3b3a01', + version: 1, + block_id: '17044958519703434496', + sequence: 7, + timestamp: 45021218, + sender_public_key: + '03d3fdad9c5b25bf8880e6b519eb3611a5c0b31adebc8455f0e096175b28321aff', + recipient_id: 'DFjnYr6USjvtaz9VZv7agd144W77WUiWtN', + type: 0, + vendor_field_hex: null, + amount: '1900000000', + fee: '10000000', + serializedHex: + 'ff011e0018f8ae0203d3fdad9c5b25bf8880e6b519eb3611a5c0b31adebc8455f0e096175b28321aff80969800000000000000b33f7100000000000000001e7440cca101de7e748b6dd53f78aa90d7e97f555d3044022038a76be2094b1fb3341ad74f8a1954aafce1c7a1cbf894c814eaaf2ac111708a02205df57912d98935cf9901451b4c7926c1a54db93f7534863f52e8b03551ef63d0', + }, + { + id: '362ea02651f336167da9e4a7fae1de7591ebee680ed53426ac553d57de351a32', + version: 1, + block_id: '17044958519703434496', + sequence: 8, + timestamp: 45021218, + sender_public_key: + '03d3fdad9c5b25bf8880e6b519eb3611a5c0b31adebc8455f0e096175b28321aff', + recipient_id: 'DHaJZBGNrWLzbWbVTc5TnHMJXKeT6comq9', + type: 0, + vendor_field_hex: null, + amount: '2000000000', + fee: '10000000', + serializedHex: + 'ff011e0018f8ae0203d3fdad9c5b25bf8880e6b519eb3611a5c0b31adebc8455f0e096175b28321aff8096980000000000000094357700000000000000001e8865f053b768370ab3f8335d625b14fa5d5bdf3e3044022016862ef508260e749e88f66c08d34212786742e78cd62315b965394b0a63580102202e1496c03e4d8534d281cd549ebcdc92b32689d9d66f1f5c78920e1b5b14bd3b', + }, + { + id: '3fd3df05b8a2ed82c4bd149a313d6747af66d5db878de0b50cb1b9819ee0a029', + version: 1, + block_id: '17044958519703434496', + sequence: 9, + timestamp: 45021218, + sender_public_key: + '03d3fdad9c5b25bf8880e6b519eb3611a5c0b31adebc8455f0e096175b28321aff', + recipient_id: 'DQUtJHQToFo9Kbgm6R9afGamvXptDzc2mi', + type: 0, + vendor_field_hex: null, + amount: '3000000000', + fee: '10000000', + serializedHex: + 'ff011e0018f8ae0203d3fdad9c5b25bf8880e6b519eb3611a5c0b31adebc8455f0e096175b28321aff809698000000000000005ed0b200000000000000001ed4287dabba34a279f51e0aa6292671893e75d3103045022100958c0ca8a7027b37dc6ad000566f9fe1593943f4219bafa62d878301cbe5060c02201e890ca5ccdd2fc9fda33ba7bf021f7f492d2a875a6942b97711d03feabf7327', + }, + { + id: '420103ba4c64f615032eb4a8e83f39242904afa4e66a6c74e4d409aecc14766d', + version: 1, + block_id: '17044958519703434496', + sequence: 10, + timestamp: 45021218, + sender_public_key: + '03d3fdad9c5b25bf8880e6b519eb3611a5c0b31adebc8455f0e096175b28321aff', + recipient_id: 'DGKgCQ1srb8HZyr47RqQqMvGZ4cDyr4eMo', + type: 0, + vendor_field_hex: null, + amount: '4600000000', + fee: '10000000', + serializedHex: + 'ff011e0019f8ae0203d3fdad9c5b25bf8880e6b519eb3611a5c0b31adebc8455f0e096175b28321aff809698000000000000006e2e1201000000000000001e7aa9a3a05f7730f1e9dc8d0636a1f1514a4e3f8e304502210087cf1800256e95a18031ee4119be2aa3be5933b1cbbd494aa497b414335d3b5002201fa0cfab949cf8c73e99d34e2a97ae305af0b77d6edc4fff034a6ed29c325001', + }, +] diff --git a/packages/core-snapshots/__tests__/transport/codec/ark/ark.test.js b/packages/core-snapshots/__tests__/transport/codec/ark/ark.test.js new file mode 100644 index 0000000000..408e5d479d --- /dev/null +++ b/packages/core-snapshots/__tests__/transport/codec/ark/ark.test.js @@ -0,0 +1,103 @@ +const pick = require('lodash/pick') +const msgpack = require('msgpack-lite') + +const { blocks } = require('../../../fixtures/blocks') +const { transactions } = require('../../../fixtures/transactions') +const codec = require('../../../../lib/transport/codec').get('ark') + +beforeAll(async () => { + transactions.forEach(transaction => { + transaction.serialized = transaction.serializedHex + }) +}) + +describe('Ark codec testing', () => { + test('Encode/Decode single block', () => { + console.time('singleblock') + const encoded = msgpack.encode(blocks[1], { codec: codec.blocks }) + const decoded = msgpack.decode(encoded, { codec: codec.blocks }) + + // removing helper property + delete decoded.previous_block_hex + + expect(decoded).toEqual(blocks[1]) + console.timeEnd('singleblock') + }) + + test('Encode/Decode blocks', () => { + console.time('blocks') + for (const [index, block] of blocks.entries()) { + // TODO: skipping genesis for now - wrong id calculation + if (index === 0) { + continue + } + + const encoded = msgpack.encode(block, { codec: codec.blocks }) + const decoded = msgpack.decode(encoded, { codec: codec.blocks }) + + // removing helper property + delete decoded.previous_block_hex + + expect(block).toEqual(decoded) + } + console.timeEnd('blocks') + }) + + test('Encode/Decode transfer transactions', () => { + console.time('transactions ark transfer') + const properties = [ + 'id', + 'version', + 'block_id', + 'sequence', + 'sender_public_key', + 'recipient_id', + 'type', + 'vendor_field_hex', + 'amount', + 'fee', + 'serialized', + ] + const transferTransactions = transactions.filter(trx => trx.type === 0) + for (let i = 0; i < 100; i++) { + for (const transaction of transferTransactions) { + const encoded = msgpack.encode(transaction, { + codec: codec.transactions, + }) + const decoded = msgpack.decode(encoded, { codec: codec.transactions }) + + const source = pick(transaction, properties) + const dest = pick(decoded, properties) + expect(dest).toEqual(source) + } + } + console.timeEnd('transactions ark transfer') + }) + + test('Encode/Decode transactions other than transfer', () => { + console.time('transactions') + const properties = [ + 'id', + 'version', + 'block_id', + 'sequence', + 'sender_public_key', + 'type', + 'vendor_field_hex', + 'amount', + 'fee', + 'serialized', + ] + + const otherTransactions = transactions.filter(trx => trx.type > 0) + for (const transaction of otherTransactions) { + const encoded = msgpack.encode(transaction, { codec: codec.transactions }) + const decoded = msgpack.decode(encoded, { codec: codec.transactions }) + + const source = pick(transaction, properties) + const dest = pick(decoded, properties) + expect(dest).toEqual(source) + } + console.timeEnd('transactions') + }) +}) diff --git a/packages/core-snapshots/__tests__/transport/codec/lite/lite.test.js b/packages/core-snapshots/__tests__/transport/codec/lite/lite.test.js new file mode 100644 index 0000000000..cce3f9f27f --- /dev/null +++ b/packages/core-snapshots/__tests__/transport/codec/lite/lite.test.js @@ -0,0 +1,72 @@ +const msgpack = require('msgpack-lite') +const { blocks } = require('../../../fixtures/blocks') +const { transactions } = require('../../../fixtures/transactions') +const codec = require('../../../../lib/transport/codec').get('lite') + +beforeAll(async () => { + transactions.forEach(transaction => { + transaction.serialized = Buffer.from(transaction.serializedHex, 'hex') + }) +}) + +describe('Lite codec testing', () => { + test('Encode/Decode single block', () => { + console.time('singleblock') + const encoded = msgpack.encode(blocks[1], { codec: codec.blocks }) + const decoded = msgpack.decode(encoded, { codec: codec.blocks }) + + // removing helper property + delete decoded.previous_block_hex + + expect(decoded).toEqual(blocks[1]) + console.timeEnd('singleblock') + }) + + test('Encode/Decode blocks', () => { + console.time('blocks') + for (const [index, block] of blocks.entries()) { + // TODO: skipping genesis for now - wrong id calculation + if (index === 0) { + continue + } + + const encoded = msgpack.encode(block, { codec: codec.blocks }) + const decoded = msgpack.decode(encoded, { codec: codec.blocks }) + + // removing helper property + delete decoded.previous_block_hex + + expect(block).toEqual(decoded) + } + console.timeEnd('blocks') + }) + + test('Encode/Decode transactions - all types', () => { + console.time('transactions') + for (const transaction of transactions) { + delete transaction.serializedHex + + const encoded = msgpack.encode(transaction, { codec: codec.transactions }) + const decoded = msgpack.decode(encoded, { codec: codec.transactions }) + + expect(decoded).toEqual(transaction) + } + console.timeEnd('transactions') + }) + + test('Encode/Decode transfer transactions', () => { + console.time('transactions lite transfer') + const transferTransactions = transactions.filter(trx => trx.type === 0) + for (let i = 0; i < 100; i++) { + for (const transaction of transferTransactions) { + const encoded = msgpack.encode(transaction, { + codec: codec.transactions, + }) + const decoded = msgpack.decode(encoded, { codec: codec.transactions }) + + expect(decoded).toEqual(transaction) + } + } + console.timeEnd('transactions lite transfer') + }) +}) diff --git a/packages/core-snapshots/jest.config.js b/packages/core-snapshots/jest.config.js new file mode 100644 index 0000000000..57770a97bb --- /dev/null +++ b/packages/core-snapshots/jest.config.js @@ -0,0 +1,12 @@ +module.exports = { + testEnvironment: 'node', + bail: false, + verbose: true, + testMatch: ['**/__tests__/**/*.test.js'], + moduleFileExtensions: ['js', 'json'], + collectCoverage: false, + coverageDirectory: '/.coverage', + collectCoverageFrom: ['lib/**/*.js', '!**/node_modules/**'], + watchman: false, + setupTestFrameworkScriptFile: 'jest-extended', +} diff --git a/packages/core-snapshots/jsdoc.json b/packages/core-snapshots/jsdoc.json new file mode 100644 index 0000000000..f3ea8aab33 --- /dev/null +++ b/packages/core-snapshots/jsdoc.json @@ -0,0 +1,22 @@ +{ + "tags": { + "allowUnknownTags": false + }, + "source": { + "include": "./lib", + "includePattern": ".js$", + "excludePattern": "(node_modules/|docs)" + }, + "plugins": ["plugins/markdown"], + "opts": { + "template": "../../node_modules/docdash", + "encoding": "utf8", + "destination": "docs/", + "recurse": true, + "verbose": true + }, + "templates": { + "cleverLinks": false, + "monospaceLinks": false + } +} diff --git a/packages/core-snapshots/lib/db/index.js b/packages/core-snapshots/lib/db/index.js new file mode 100644 index 0000000000..cefd17da4b --- /dev/null +++ b/packages/core-snapshots/lib/db/index.js @@ -0,0 +1,153 @@ +/* eslint no-await-in-loop: "off" */ + +const promise = require('bluebird') +const { migrations } = require('@arkecosystem/core-database-postgres') +const app = require('@arkecosystem/core-container') + +const logger = app.resolvePlugin('logger') +const queries = require('./queries') +const { rawQuery } = require('./utils') +const columns = require('./utils/column-set') + +class Database { + async make(database) { + if (database) { + this.db = database.db + this.pgp = database.pgp + this.__createColumnSets() + this.isSharedConnection = true + logger.info( + 'Snapshots: reusing core-database-postgres connection from running core', + ) + return this + } + + try { + const pgp = require('pg-promise')({ promiseLib: promise }) + this.pgp = pgp + const options = app.resolveOptions('database').connection + options.idleTimeoutMillis = 100 + this.db = pgp(options) + this.__createColumnSets() + await this.__runMigrations() + logger.info('Snapshots: Database connected') + this.isSharedConnection = false + return this + } catch (error) { + app.forceExit('Error while connecting to postgres', error) + } + } + + async getLastBlock() { + return this.db.oneOrNone(queries.blocks.latest) + } + + async getBlockByHeight(height) { + return this.db.oneOrNone(queries.blocks.findByHeight, { height }) + } + + async truncateChain() { + const tables = ['wallets', 'rounds', 'transactions', 'blocks'] + logger.info('Truncating tables: wallets, rounds, transactions, blocks') + try { + for (const table of tables) { + await this.db.none(queries.truncate(table)) + } + + return this.getLastBlock() + } catch (error) { + app.forceExit('Truncate chain error', error) + } + } + + async rollbackChain(height) { + const config = app.resolvePlugin('config') + const maxDelegates = config.getConstants(height).activeDelegates + const currentRound = Math.floor(height / maxDelegates) + const lastBlockHeight = currentRound * maxDelegates + const lastRemainingBlock = await this.getBlockByHeight(lastBlockHeight) + + try { + if (lastRemainingBlock) { + await Promise.all([ + this.db.none(queries.truncate('wallets')), + this.db.none(queries.transactions.deleteFromTimestamp, { + timestamp: lastRemainingBlock.timestamp, + }), + this.db.none(queries.blocks.deleteFromHeight, { + height: lastRemainingBlock.height, + }), + this.db.none(queries.rounds.deleteFromRound, { round: currentRound }), + ]) + } + } catch (error) { + logger.error(error) + } + + return this.getLastBlock() + } + + async getExportQueries(startHeight, endHeight) { + const startBlock = await this.getBlockByHeight(startHeight) + const endBlock = await this.getBlockByHeight(endHeight) + + if (!startBlock || !endBlock) { + app.forceExit( + 'Wrong input height parameters for building export queries. Blocks at height not found in db.', + ) + } + return { + blocks: rawQuery(this.pgp, queries.blocks.heightRange, { + start: startBlock.height, + end: endBlock.height, + }), + transactions: rawQuery(this.pgp, queries.transactions.timestampRange, { + start: startBlock.timestamp, + end: endBlock.timestamp, + }), + } + } + + getTransactionsBackupQuery(startTimestamp) { + return rawQuery(this.pgp, queries.transactions.timestampHigher, { + start: startTimestamp, + }) + } + + getColumnSet(tableName) { + switch (tableName) { + case 'blocks': + return this.blocksColumnSet + case 'transactions': + return this.transactionsColumnSet + default: + throw new Error('Invalid table name') + } + } + + close() { + if (!this.isSharedConnection) { + logger.debug('Closing snapshots-cli database connection') + this.db.$pool.end() + this.pgp.end() + } + } + + __createColumnSets() { + this.blocksColumnSet = new this.pgp.helpers.ColumnSet(columns.blocks, { + table: 'blocks', + }) + this.transactionsColumnSet = new this.pgp.helpers.ColumnSet( + columns.transactions, + { table: 'transactions' }, + ) + } + + async __runMigrations() { + for (const migration of migrations) { + await this.db.none(migration) + } + } +} + +module.exports = new Database() diff --git a/packages/core-snapshots/lib/db/queries/blocks/delete-from-height.sql b/packages/core-snapshots/lib/db/queries/blocks/delete-from-height.sql new file mode 100644 index 0000000000..cab9ba9c19 --- /dev/null +++ b/packages/core-snapshots/lib/db/queries/blocks/delete-from-height.sql @@ -0,0 +1,2 @@ +DELETE FROM blocks +WHERE height > ${height} diff --git a/packages/core-snapshots/lib/db/queries/blocks/find-by-height.sql b/packages/core-snapshots/lib/db/queries/blocks/find-by-height.sql new file mode 100644 index 0000000000..25ad1738ce --- /dev/null +++ b/packages/core-snapshots/lib/db/queries/blocks/find-by-height.sql @@ -0,0 +1,3 @@ +SELECT * +FROM blocks +WHERE height = ${height} diff --git a/packages/core-snapshots/lib/db/queries/blocks/height-range.sql b/packages/core-snapshots/lib/db/queries/blocks/height-range.sql new file mode 100644 index 0000000000..16eaa7cb2a --- /dev/null +++ b/packages/core-snapshots/lib/db/queries/blocks/height-range.sql @@ -0,0 +1,20 @@ +SELECT + id, + version, + timestamp, + previous_block, + height, + number_of_transactions, + total_amount, + total_fee, + reward, + payload_length, + payload_hash, + generator_public_key, + block_signature +FROM + blocks +WHERE + height BETWEEN ${start} AND ${end} +ORDER BY + height diff --git a/packages/core-snapshots/lib/db/queries/blocks/latest.sql b/packages/core-snapshots/lib/db/queries/blocks/latest.sql new file mode 100644 index 0000000000..daa603cba0 --- /dev/null +++ b/packages/core-snapshots/lib/db/queries/blocks/latest.sql @@ -0,0 +1,3 @@ +SELECT * +FROM blocks +ORDER BY height DESC LIMIT 1 diff --git a/packages/core-snapshots/lib/db/queries/index.js b/packages/core-snapshots/lib/db/queries/index.js new file mode 100644 index 0000000000..32c8c718ac --- /dev/null +++ b/packages/core-snapshots/lib/db/queries/index.js @@ -0,0 +1,31 @@ +const { loadQueryFile } = require('../utils') + +module.exports = { + blocks: { + heightRange: loadQueryFile(__dirname, './blocks/height-range.sql'), + latest: loadQueryFile(__dirname, './blocks/latest.sql'), + findByHeight: loadQueryFile(__dirname, './blocks/find-by-height.sql'), + deleteFromHeight: loadQueryFile( + __dirname, + './blocks/delete-from-height.sql', + ), + }, + transactions: { + timestampRange: loadQueryFile( + __dirname, + './transactions/timestamp-range.sql', + ), + timestampHigher: loadQueryFile( + __dirname, + './transactions/timestamp-higher.sql', + ), + deleteFromTimestamp: loadQueryFile( + __dirname, + './transactions/delete-from-timestamp.sql', + ), + }, + rounds: { + deleteFromRound: loadQueryFile(__dirname, './rounds/delete-from-round.sql'), + }, + truncate: table => `TRUNCATE TABLE ${table} RESTART IDENTITY`, +} diff --git a/packages/core-snapshots/lib/db/queries/rounds/delete-from-round.sql b/packages/core-snapshots/lib/db/queries/rounds/delete-from-round.sql new file mode 100644 index 0000000000..d0037a8835 --- /dev/null +++ b/packages/core-snapshots/lib/db/queries/rounds/delete-from-round.sql @@ -0,0 +1,2 @@ +DELETE FROM rounds +WHERE round > ${round} diff --git a/packages/core-snapshots/lib/db/queries/transactions/delete-from-timestamp.sql b/packages/core-snapshots/lib/db/queries/transactions/delete-from-timestamp.sql new file mode 100644 index 0000000000..012bc3cd45 --- /dev/null +++ b/packages/core-snapshots/lib/db/queries/transactions/delete-from-timestamp.sql @@ -0,0 +1,2 @@ +DELETE FROM transactions +WHERE timestamp > ${timestamp} diff --git a/packages/core-snapshots/lib/db/queries/transactions/timestamp-higher.sql b/packages/core-snapshots/lib/db/queries/transactions/timestamp-higher.sql new file mode 100644 index 0000000000..07d33817da --- /dev/null +++ b/packages/core-snapshots/lib/db/queries/transactions/timestamp-higher.sql @@ -0,0 +1,2 @@ +SELECT id, sequence, serialized FROM transactions +WHERE timestamp > ${start} diff --git a/packages/core-snapshots/lib/db/queries/transactions/timestamp-range.sql b/packages/core-snapshots/lib/db/queries/transactions/timestamp-range.sql new file mode 100644 index 0000000000..49552472ce --- /dev/null +++ b/packages/core-snapshots/lib/db/queries/transactions/timestamp-range.sql @@ -0,0 +1,19 @@ +SELECT + id, + version, + block_id, + sequence, + timestamp, + sender_public_key, + recipient_id, + type, + vendor_field_hex, + amount, + fee, + serialized +FROM + transactions +WHERE + timestamp BETWEEN ${start} AND ${end} +ORDER BY + timestamp diff --git a/packages/core-snapshots/lib/db/utils/column-set.js b/packages/core-snapshots/lib/db/utils/column-set.js new file mode 100644 index 0000000000..a97d0ece8d --- /dev/null +++ b/packages/core-snapshots/lib/db/utils/column-set.js @@ -0,0 +1,34 @@ +/* Column sets. + * If you modify the order you must adapt the sql files export orders also + */ +module.exports = { + blocks: [ + 'id', + 'version', + 'timestamp', + 'previous_block', + 'height', + 'number_of_transactions', + 'total_amount', + 'total_fee', + 'reward', + 'payload_length', + 'payload_hash', + 'generator_public_key', + 'block_signature', + ], + transactions: [ + 'id', + 'version', + 'block_id', + 'sequence', + 'timestamp', + 'sender_public_key', + 'recipient_id', + 'type', + 'vendor_field_hex', + 'amount', + 'fee', + 'serialized', + ], +} diff --git a/packages/core-snapshots/lib/db/utils/index.js b/packages/core-snapshots/lib/db/utils/index.js new file mode 100644 index 0000000000..914fc8e62a --- /dev/null +++ b/packages/core-snapshots/lib/db/utils/index.js @@ -0,0 +1,29 @@ +const QueryFile = require('pg-promise').QueryFile +const path = require('path') + +const app = require('@arkecosystem/core-container') + +const logger = app.resolvePlugin('logger') + +module.exports = { + loadQueryFile: (directory, file) => { + const fullPath = path.join(directory, file) + + const options = { + minify: true, + params: { + schema: 'public', + }, + } + + const query = new QueryFile(fullPath, options) + + if (query.error) { + logger.error(query.error) + } + + return query + }, + + rawQuery: (pgp, queryFile, parameters) => pgp.as.format(queryFile, parameters), +} diff --git a/packages/core-snapshots/lib/defaults.js b/packages/core-snapshots/lib/defaults.js new file mode 100644 index 0000000000..2487bacbf5 --- /dev/null +++ b/packages/core-snapshots/lib/defaults.js @@ -0,0 +1,4 @@ +module.exports = { + codec: 'lite', + chunkSize: 50000, +} diff --git a/packages/core-snapshots/lib/index.js b/packages/core-snapshots/lib/index.js new file mode 100644 index 0000000000..e15ccc6638 --- /dev/null +++ b/packages/core-snapshots/lib/index.js @@ -0,0 +1,16 @@ +const SnapshotManager = require('./manager') + +/** + * The struct used by the plugin container. + * @type {Object} + */ +exports.plugin = { + pkg: require('../package.json'), + defaults: require('./defaults'), + alias: 'snapshots', + async register(container, options) { + const manager = new SnapshotManager(options) + + return manager.make(container.resolvePlugin('database')) + }, +} diff --git a/packages/core-snapshots/lib/manager.js b/packages/core-snapshots/lib/manager.js new file mode 100644 index 0000000000..e2efd62c2f --- /dev/null +++ b/packages/core-snapshots/lib/manager.js @@ -0,0 +1,184 @@ +/* eslint max-len: "off" */ + +const pick = require('lodash/pick') +const app = require('@arkecosystem/core-container') + +const logger = app.resolvePlugin('logger') +const database = require('./db') +const utils = require('./utils') +const { + exportTable, + importTable, + verifyTable, + backupTransactionsToJSON, +} = require('./transport') + +module.exports = class SnapshotManager { + constructor(options) { + this.options = options + } + + async make(connection) { + this.database = await database.make(connection) + + return this + } + + async exportData(options) { + const params = await this.__init(options, true) + + if (params.skipExportWhenNoChange) { + logger.info( + `Skipping export of snapshot, because ${ + params.meta.folder + } is already up to date.`, + ) + return + } + + const metaInfo = { + blocks: await exportTable('blocks', params), + transactions: await exportTable('transactions', params), + folder: params.meta.folder, + codec: options.codec, + skipCompression: params.meta.skipCompression, + } + + this.database.close() + utils.writeMetaFile(metaInfo) + } + + async importData(options) { + const params = await this.__init(options) + + if (params.truncate) { + params.lastBlock = await this.database.truncateChain() + } + + await importTable('blocks', params) + await importTable('transactions', params) + + const lastBlock = await this.database.getLastBlock() + logger.info( + `Import from folder ${ + params.meta.folder + } completed. Last block in database: ${lastBlock.height.toLocaleString()} :+1:`, + ) + if (!params.skipRestartRound) { + const newLastBlock = await this.database.rollbackChain(lastBlock.height) + logger.info( + `Rolling back chain to last finished round with last block height ${ + newLastBlock.height.toLocaleString() + }`, + ) + } + + this.database.close() + } + + async verifyData(options) { + const params = await this.__init(options) + + await Promise.all([ + verifyTable('blocks', params), + verifyTable('transactions', params), + ]) + } + + async truncateChain() { + await this.database.truncateChain() + + this.database.close() + } + + async rollbackChain(height) { + const lastBlock = await this.database.getLastBlock() + const config = app.resolvePlugin('config') + const maxDelegates = config.getConstants(lastBlock.height).activeDelegates + + const rollBackHeight = height === -1 ? lastBlock.height : height + if (rollBackHeight >= lastBlock.height || rollBackHeight < 1) { + app.forceExit( + `Specified rollback block height: ${ + rollBackHeight.toLocaleString() + } is not valid. Current database height: ${ + lastBlock.height.toLocaleString() + }. Exiting.`, + ) + } + + if (height) { + const rollBackBlock = await this.database.getBlockByHeight(rollBackHeight) + const qTransactionBackup = await this.database.getTransactionsBackupQuery( + rollBackBlock.timestamp, + ) + await backupTransactionsToJSON( + `rollbackTransactionBackup.${+height + 1}.${lastBlock.height}.json`, + qTransactionBackup, + this.database, + ) + } + + const newLastBlock = await this.database.rollbackChain(rollBackHeight) + logger.info( + `Rolling back chain to last finished round ${ + (newLastBlock.height / maxDelegates).toLocaleString() + } with last block height ${newLastBlock.height.toLocaleString()}`, + ) + + this.database.close() + } + + /** + * Inits the process and creates json with needed paramaters for functions + * @param {JSONObject} from commander or util function {blocks, codec, truncate, signatureVerify, skipRestartRound, start, end} + * @return {JSONObject} with merged parameters, adding {lastBlock, database, meta {startHeight, endHeight, folder}, queries {blocks, transactions}} + */ + async __init(options, exportAction = false) { + const params = pick(options, [ + 'truncate', + 'signatureVerify', + 'blocks', + 'codec', + 'skipRestartRound', + 'start', + 'end', + 'skipCompression', + ]) + + const lastBlock = await this.database.getLastBlock() + params.lastBlock = lastBlock + params.codec = params.codec || this.options.codec + params.chunkSize = this.options.chunkSize || 50000 + + if (exportAction) { + if (!lastBlock) { + app.forceExit('Database is empty. Export not possible.') + } + params.meta = utils.setSnapshotInfo(params, lastBlock) + params.queries = await this.database.getExportQueries( + params.meta.startHeight, + params.meta.endHeight, + ) + + if (params.blocks) { + if (options.blocks === params.meta.folder) { + params.skipExportWhenNoChange = true + return params + } + const sourceSnapshotParams = utils.readMetaJSON(params.blocks) + params.meta.skipCompression = sourceSnapshotParams.skipCompression + params.meta.startHeight = sourceSnapshotParams.blocks.startHeight + utils.copySnapshot(options.blocks, params.meta.folder, params.codec) + } + } else { + params.meta = utils.getSnapshotInfo(options.blocks) + } + if (options.trace) { + console.info(params.meta) + console.info(params.queries) + } + params.database = this.database + return params + } +} diff --git a/packages/core-snapshots/lib/transport/codec/ark-codec.js b/packages/core-snapshots/lib/transport/codec/ark-codec.js new file mode 100644 index 0000000000..4a6e6ca312 --- /dev/null +++ b/packages/core-snapshots/lib/transport/codec/ark-codec.js @@ -0,0 +1,22 @@ +const msgpack = require('msgpack-lite') +const arkEncoders = require('./ark') + +class ArkCodec { + get blocks() { + const codec = msgpack.createCodec() + codec.addExtPacker(0x3f, Object, arkEncoders.blockEncode) + codec.addExtUnpacker(0x3f, arkEncoders.blockDecode) + + return codec + } + + get transactions() { + const codec = msgpack.createCodec() + codec.addExtPacker(0x4f, Object, arkEncoders.transactionEncode) + codec.addExtUnpacker(0x4f, arkEncoders.transactionDecode) + + return codec + } +} + +module.exports = new ArkCodec() diff --git a/packages/core-snapshots/lib/transport/codec/ark/index.js b/packages/core-snapshots/lib/transport/codec/ark/index.js new file mode 100644 index 0000000000..c7fbfeeccb --- /dev/null +++ b/packages/core-snapshots/lib/transport/codec/ark/index.js @@ -0,0 +1,53 @@ +/* eslint camelcase: "off" */ + +const { camelizeKeys, decamelizeKeys } = require('xcase') +const msgpack = require('msgpack-lite') +const { Block, Transaction } = require('@arkecosystem/crypto').models + +module.exports = { + blockEncode: blockRecord => { + const data = camelizeKeys(blockRecord) + return Block.serialize(data, true) + }, + + blockDecode: bufferData => { + const blockData = Block.deserialize(bufferData.toString('hex'), true) + blockData.id = Block.getIdFromSerialized(bufferData) + + blockData.totalAmount = blockData.totalAmount.toFixed() + blockData.totalFee = blockData.totalFee.toFixed() + blockData.reward = blockData.reward.toFixed() + + return decamelizeKeys(blockData) + }, + + transactionEncode: transaction => + msgpack.encode([ + transaction.id, + transaction.block_id, + transaction.sequence, + transaction.serialized, + ]), + + transactionDecode: bufferData => { + const [id, blockId, sequence, serialized] = msgpack.decode(bufferData) + let transaction = {} + transaction = Transaction.deserialize(serialized.toString('hex')) + + transaction.id = id + transaction.block_id = blockId + transaction.sequence = sequence + transaction.amount = transaction.amount.toFixed() + transaction.fee = transaction.fee.toFixed() + transaction.vendorFieldHex = transaction.vendorFieldHex + ? transaction.vendorFieldHex + : null + transaction.recipientId = transaction.recipientId + ? transaction.recipientId + : null + transaction = decamelizeKeys(transaction) + + transaction.serialized = serialized + return transaction + }, +} diff --git a/packages/core-snapshots/lib/transport/codec/index.js b/packages/core-snapshots/lib/transport/codec/index.js new file mode 100644 index 0000000000..e309b3fc00 --- /dev/null +++ b/packages/core-snapshots/lib/transport/codec/index.js @@ -0,0 +1,14 @@ +module.exports = { + get(codec) { + switch (codec) { + case 'ark': + return require('./ark-codec') + case 'lite': + return require('./lite-codec') + case 'msgpack': + return null + default: + return require('./lite-codec') + } + }, +} diff --git a/packages/core-snapshots/lib/transport/codec/lite-codec.js b/packages/core-snapshots/lib/transport/codec/lite-codec.js new file mode 100644 index 0000000000..b9b909b3d5 --- /dev/null +++ b/packages/core-snapshots/lib/transport/codec/lite-codec.js @@ -0,0 +1,22 @@ +const msgpack = require('msgpack-lite') +const liteEncoder = require('./lite') + +class LiteCodec { + get blocks() { + const codec = msgpack.createCodec() + codec.addExtPacker(0x3f, Object, liteEncoder.blockEncode) + codec.addExtUnpacker(0x3f, liteEncoder.blockDecode) + + return codec + } + + get transactions() { + const codec = msgpack.createCodec() + codec.addExtPacker(0x4f, Object, liteEncoder.transactionEncode) + codec.addExtUnpacker(0x4f, liteEncoder.transactionDecode) + + return codec + } +} + +module.exports = new LiteCodec() diff --git a/packages/core-snapshots/lib/transport/codec/lite/index.js b/packages/core-snapshots/lib/transport/codec/lite/index.js new file mode 100644 index 0000000000..77663b1560 --- /dev/null +++ b/packages/core-snapshots/lib/transport/codec/lite/index.js @@ -0,0 +1,32 @@ +const msgpack = require('msgpack-lite') +const columns = require('../../../db/utils/column-set') + +module.exports = { + blockEncode: block => { + const values = Object.values(block) + return msgpack.encode(values) + }, + + blockDecode: bufferData => { + const values = msgpack.decode(bufferData) + const block = {} + columns.blocks.forEach((column, i) => { + block[column] = values[i] + }) + return block + }, + + transactionEncode: transactionRecord => { + const values = Object.values(transactionRecord) + return msgpack.encode(values) + }, + + transactionDecode: bufferData => { + const values = msgpack.decode(bufferData) + const transaction = {} + columns.transactions.forEach((column, i) => { + transaction[column] = values[i] + }) + return transaction + }, +} diff --git a/packages/core-snapshots/lib/transport/index.js b/packages/core-snapshots/lib/transport/index.js new file mode 100644 index 0000000000..623d5d3c45 --- /dev/null +++ b/packages/core-snapshots/lib/transport/index.js @@ -0,0 +1,193 @@ +/* eslint max-len: "off" */ + +const fs = require('fs-extra') +const QueryStream = require('pg-query-stream') +const JSONStream = require('JSONStream') +const msgpack = require('msgpack-lite') +const pluralize = require('pluralize') +const zlib = require('zlib') + +const app = require('@arkecosystem/core-container') + +const logger = app.resolvePlugin('logger') +const emitter = app.resolvePlugin('event-emitter') +const utils = require('../utils') +const { verifyData, canImportRecord } = require('./verification') +const codecs = require('./codec') + +module.exports = { + exportTable: async (table, options) => { + const snapFileName = utils.getPath( + table, + options.meta.folder, + options.codec, + ) + const codec = codecs.get(options.codec) + const gzip = zlib.createGzip() + await fs.ensureFile(snapFileName) + + logger.info( + `Starting to export table ${table} to folder ${ + options.meta.folder + }, codec: ${ + options.codec + }, append:${!!options.blocks}, skipCompression: ${ + options.meta.skipCompression + }`, + ) + try { + const snapshotWriteStream = fs.createWriteStream( + snapFileName, + options.blocks ? { flags: 'a' } : {}, + ) + const encodeStream = msgpack.createEncodeStream( + codec ? { codec: codec[table] } : {}, + ) + const qs = new QueryStream(options.queries[table]) + + const data = await options.database.db.stream(qs, s => { + if (options.meta.skipCompression) { + return s.pipe(encodeStream).pipe(snapshotWriteStream) + } + + return s + .pipe(encodeStream) + .pipe(gzip) + .pipe(snapshotWriteStream) + }) + logger.info( + `Snapshot: ${table} done. ==> Total rows processed: ${ + data.processed + }, duration: ${data.duration} ms`, + ) + + return { + count: utils.calcRecordCount(table, data.processed, options.blocks), + startHeight: utils.calcStartHeight( + table, + options.meta.startHeight, + options.blocks, + ), + endHeight: options.meta.endHeight, + } + } catch (error) { + app.forceExit('Error while exporting data via query stream', error) + } + }, + + importTable: async (table, options) => { + const sourceFile = utils.getPath(table, options.meta.folder, options.codec) + const codec = codecs.get(options.codec) + const gunzip = zlib.createGunzip() + const decodeStream = msgpack.createDecodeStream( + codec ? { codec: codec[table] } : {}, + ) + logger.info( + `Starting to import table ${table} from ${sourceFile}, codec: ${ + options.codec + }, skipCompression: ${options.meta.skipCompression}`, + ) + + const readStream = options.meta.skipCompression + ? fs.createReadStream(sourceFile).pipe(decodeStream) + : fs + .createReadStream(sourceFile) + .pipe(gunzip) + .pipe(decodeStream) + + let values = [] + let prevData = null + let counter = 0 + const saveData = async data => { + if (data && data.length > 0) { + const insert = options.database.pgp.helpers.insert( + data, + options.database.getColumnSet(table), + ) + emitter.emit('progress', { value: counter, table }) + values = [] + return options.database.db.none(insert) + } + } + + emitter.emit('start', { count: options.meta[table].count }) + for await (const record of readStream) { + counter++ + if (!verifyData(table, record, prevData, options.signatureVerification)) { + app.forceExit( + `Error verifying data. Payload ${JSON.stringify(record, null, 2)}`, + ) + } + if (canImportRecord(table, record, options.lastBlock)) { + values.push(record) + } + + if (values.length % options.chunkSize === 0) { + await saveData(values) + } + prevData = record + } + + if (values.length > 0) { + await saveData(values) + } + emitter.emit('complete') + }, + + verifyTable: async (table, options) => { + const sourceFile = utils.getPath(table, options.meta.folder, options.codec) + const codec = codecs.get(options.codec) + const gunzip = zlib.createGunzip() + const decodeStream = msgpack.createDecodeStream( + codec ? { codec: codec[table] } : {}, + ) + const readStream = options.meta.skipCompression + ? fs.createReadStream(sourceFile).pipe(decodeStream) + : fs + .createReadStream(sourceFile) + .pipe(gunzip) + .pipe(decodeStream) + + logger.info(`Starting to verify snapshot file ${sourceFile}`) + let prevData = null + + decodeStream.on('data', data => { + if (!verifyData(table, data, prevData, options.signatureVerification)) { + app.forceExit( + `Error verifying data. Payload ${JSON.stringify(data, null, 2)}`, + ) + } + prevData = data + }) + + readStream.on('finish', () => { + logger.info(`Snapshot file ${sourceFile} succesfully verified :+1:`) + }) + }, + + backupTransactionsToJSON: async (snapFileName, query, database) => { + const transactionBackupPath = utils.getFilePath( + snapFileName, + 'rollbackTransactions', + ) + await fs.ensureFile(transactionBackupPath) + const snapshotWriteStream = fs.createWriteStream(transactionBackupPath) + const qs = new QueryStream(query) + + try { + const data = await database.db.stream(qs, s => + s.pipe(JSONStream.stringify()).pipe(snapshotWriteStream), + ) + logger.info( + `${pluralize( + 'transaction', + data.processed, + true, + )} from rollbacked blocks safely exported to file ${snapFileName}`, + ) + return data + } catch (error) { + app.forceExit('Error while exporting data via query stream', error) + } + }, +} diff --git a/packages/core-snapshots/lib/transport/verification.js b/packages/core-snapshots/lib/transport/verification.js new file mode 100644 index 0000000000..9e7159e7e1 --- /dev/null +++ b/packages/core-snapshots/lib/transport/verification.js @@ -0,0 +1,99 @@ +const { camelizeKeys } = require('xcase') +const createHash = require('create-hash') +const { crypto } = require('@arkecosystem/crypto') +const { Block, Transaction } = require('@arkecosystem/crypto').models +const app = require('@arkecosystem/core-container') + +const logger = app.resolvePlugin('logger') + +module.exports = { + verifyData: (context, data, prevData, signatureVerification) => { + const verifyTransaction = () => { + if (!signatureVerification) { + return true + } + + const transaction = new Transaction( + Buffer.from(data.serialized).toString('hex'), + ) + return transaction.verified + } + + const isBlockChained = () => { + if (!prevData) { + return true + } + // genesis payload different as block.serialize stores + // block.previous_block with 00000 instead of null + // it fails on height 2 - chain check + // hardcoding for now + // TODO: check to improve ser/deser for genesis, add mainnet + if ( + data.height === 2 && + data.previous_block === '13114381566690093367' && + prevData.id === '12760288562212273414' + ) { + return true + } + return ( + data.height - prevData.height === 1 && + data.previous_block === prevData.id + ) + } + + const verifyBlock = () => { + if (!isBlockChained(data)) { + logger.error( + `Blocks are not chained. Current block: ${JSON.stringify( + data, + )}, previous block: ${JSON.stringify(prevData)}`, + ) + return false + } + + // TODO: manually calculate block ID and compare to existing + if (signatureVerification) { + const bytes = Block.serialize(camelizeKeys(data), false) + const hash = createHash('sha256') + .update(bytes) + .digest() + + const signatureVerify = crypto.verifyHash( + hash, + data.block_signature, + data.generator_public_key, + ) + if (!signatureVerify) { + logger.error(`Failed to verify signature: ${JSON.stringify(data)}`) + } + return signatureVerify + } + + return true + } + + switch (context) { + case 'blocks': + return verifyBlock() + case 'transactions': + return verifyTransaction() + default: + return false + } + }, + + canImportRecord: (context, data, lastBlock) => { + if (!lastBlock) { + // empty db + return true + } + switch (context) { + case 'blocks': + return data.height > lastBlock.height + case 'transactions': + return data.timestamp > lastBlock.timestamp + default: + return false + } + }, +} diff --git a/packages/core-snapshots/lib/utils/index.js b/packages/core-snapshots/lib/utils/index.js new file mode 100644 index 0000000000..0e9e75987e --- /dev/null +++ b/packages/core-snapshots/lib/utils/index.js @@ -0,0 +1,108 @@ +const fs = require('fs-extra') +const app = require('@arkecosystem/core-container') + +exports.getPath = (table, folder, codec) => { + const filename = `${table}.${codec}` + return this.getFilePath(filename, folder) +} + +exports.writeMetaFile = snapshotInfo => { + const path = `${process.env.ARK_PATH_DATA}/snapshots/${ + process.env.ARK_NETWORK_NAME + }/${snapshotInfo.folder}/meta.json` + fs.writeFileSync(path, JSON.stringify(snapshotInfo, 'utf8')) +} + +exports.getFilePath = (filename, folder) => `${process.env.ARK_PATH_DATA}/snapshots/${ + process.env.ARK_NETWORK_NAME +}/${folder}/${filename}` + +exports.copySnapshot = (sourceFolder, destFolder, codec) => { + const logger = app.resolvePlugin('logger') + logger.info( + `Copying snapshot from ${sourceFolder} to a new file ${destFolder} for appending of data`, + ) + + const paths = { + source: { + blocks: this.getPath('blocks', sourceFolder, codec), + transactions: this.getPath('transactions', sourceFolder, codec), + }, + dest: { + blocks: this.getPath('blocks', destFolder, codec), + transactions: this.getPath('transactions', destFolder, codec), + }, + } + + fs.ensureFileSync(paths.dest.blocks) + fs.ensureFileSync(paths.dest.transactions) + + if ( + !fs.existsSync(paths.source.blocks) + || !fs.existsSync(paths.source.transactions) + ) { + app.forceExit( + `Unable to copy snapshot from ${sourceFolder} as it doesn't exist :bomb:`, + ) + } + + fs.copyFileSync(paths.source.blocks, paths.dest.blocks) + fs.copyFileSync(paths.source.transactions, paths.dest.transactions) +} + +exports.calcRecordCount = (table, currentCount, sourceFolder) => { + if (sourceFolder) { + const snapshotInfo = this.readMetaJSON(sourceFolder) + return +snapshotInfo[table].count + currentCount + } + + return currentCount +} + +exports.calcStartHeight = (table, currentHeight, sourceFolder) => { + if (sourceFolder) { + const snapshotInfo = this.readMetaJSON(sourceFolder) + return +snapshotInfo[table].startHeight + } + + return currentHeight +} + +exports.getSnapshotInfo = folder => { + const snapshotInfo = this.readMetaJSON(folder) + return { + startHeight: +snapshotInfo.blocks.startHeight, + endHeight: +snapshotInfo.blocks.endHeight, + folder: snapshotInfo.folder, + blocks: snapshotInfo.blocks, + transactions: snapshotInfo.transactions, + skipCompression: snapshotInfo.skipCompression, + } +} + +exports.readMetaJSON = folder => { + const metaFileInfo = this.getFilePath('meta.json', folder) + if (!fs.existsSync(metaFileInfo)) { + app.forceExit('Meta file meta.json not found. Exiting :bomb:') + } + + return fs.readJSONSync(metaFileInfo) +} + +exports.setSnapshotInfo = (options, lastBlock) => { + const meta = { + startHeight: options.start !== -1 ? options.start : 1, + endHeight: options.end !== -1 ? options.end : lastBlock.height, + codec: options.codec, + skipCompression: options.skipCompression || false, + } + meta.folder = `${meta.startHeight}-${meta.endHeight}` + + if (options.blocks) { + const oldMeta = this.getSnapshotInfo(options.blocks) + meta.startHeight = oldMeta.endHeight + 1 + meta.folder = `${oldMeta.startHeight}-${meta.endHeight}` + } + + return meta +} diff --git a/packages/core-snapshots/package.json b/packages/core-snapshots/package.json new file mode 100644 index 0000000000..7945b9dbe9 --- /dev/null +++ b/packages/core-snapshots/package.json @@ -0,0 +1,40 @@ +{ + "name": "@arkecosystem/core-snapshots", + "description": "Provides live local streamed snapshots functionality for ARK Core", + "version": "0.1.0", + "contributors": [ + "Kristjan Košič " + ], + "license": "MIT", + "main": "lib/index.js", + "scripts": { + "test": "cross-env ARK_ENV=test jest --runInBand --detectOpenHandles", + "test:coverage": "cross-env ARK_ENV=test jest --coverage --runInBand --detectOpenHandles", + "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand --watch", + "test:watch": "cross-env ARK_ENV=test jest --runInBand --watch", + "test:watch:all": "cross-env ARK_ENV=test jest --runInBand --watchAll", + "lint": "eslint ./ --fix", + "depcheck": "depcheck ./ --ignores=lodash,lodash.*" + }, + "dependencies": { + "@arkecosystem/core-container": "~0.2", + "@arkecosystem/core-database-postgres": "~0.2", + "@arkecosystem/crypto": "~0.2", + "JSONStream": "^1.3.5", + "bluebird": "^3.5.3", + "create-hash": "^1.2.0", + "fs-extra": "^7.0.1", + "lodash.pick": "^4.4.0", + "msgpack-lite": "^0.1.26", + "pg-promise": "^8.5.2", + "pg-query-stream": "^1.1.2", + "pluralize": "^7.0.0", + "xcase": "^2.0.1" + }, + "publishConfig": { + "access": "public" + }, + "engines": { + "node": ">=10.x" + } +} diff --git a/packages/core-test-utils/CHANGELOG.md b/packages/core-test-utils/CHANGELOG.md index 127cc35e42..b3c465c0bf 100644 --- a/packages/core-test-utils/CHANGELOG.md +++ b/packages/core-test-utils/CHANGELOG.md @@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Unreleased -## 0.0.1 - 2018-05-31 +## 0.2.0 - 2018-12-03 + +### Changed + +- Better default configuration +- Dropped node.js 9 as minimum requirement in favour of node.js 10 + +## 0.1.1 - 2018-06-14 + ### Added + - initial release diff --git a/packages/core-test-utils/README.md b/packages/core-test-utils/README.md index 901709455a..87bf721009 100644 --- a/packages/core-test-utils/README.md +++ b/packages/core-test-utils/README.md @@ -1,12 +1,12 @@ -![ARK Core](https://i.imgur.com/1aP6F2o.png) +# Ark Core - Test Utilities -# ARK Core - Test Utilities +

+ +

-## Installation +## Documentation -```bash -yarn add @arkecosystem/core-test-utils -``` +You can find installation instructions and detailed instructions on how to use this package at the [dedicated documentation site](https://docs.ark.io/guidebook/core/plugins/core-test-utils.html). ## Security diff --git a/packages/core-test-utils/__tests__/generators/transactions.test.js b/packages/core-test-utils/__tests__/generators/transactions.test.js index fdddad9e10..d23ed06426 100644 --- a/packages/core-test-utils/__tests__/generators/transactions.test.js +++ b/packages/core-test-utils/__tests__/generators/transactions.test.js @@ -1,6 +1,4 @@ -'use strict' - -const generateTransactions = require('../../lib/generators/transactions') +const generateTransactions = require('../../lib/generators/transactions/transaction') const { TRANSACTION_TYPES } = require('../../../crypto/lib/constants') describe('generateTransactions', () => { @@ -14,7 +12,7 @@ describe('generateTransactions', () => { 'devnet', TRANSACTION_TYPES.TRANSFER, undefined, - devnetAddress + devnetAddress, ) for (let i = 0; i < transactions.length; i++) { diff --git a/packages/core-test-utils/__tests__/generators/transactions/delegate.test.js b/packages/core-test-utils/__tests__/generators/transactions/delegate.test.js index 3b2aaf849e..eea6b56245 100644 --- a/packages/core-test-utils/__tests__/generators/transactions/delegate.test.js +++ b/packages/core-test-utils/__tests__/generators/transactions/delegate.test.js @@ -1,5 +1,3 @@ -'use strict' - const createDelegate = require('../../../lib/generators/transactions/delegate') const { TRANSACTION_TYPES } = require('../../../../crypto/lib/constants') @@ -9,11 +7,7 @@ describe('Delegate transaction', () => { }) const quantity = 4 - const transactions = createDelegate( - undefined, - undefined, - quantity - ) + const transactions = createDelegate(undefined, undefined, quantity) it('should return an array', () => { expect(transactions).toBeArrayOfSize(quantity) @@ -21,7 +15,9 @@ describe('Delegate transaction', () => { it('should return an array of 4 delegate objects', () => { for (let i = 0; i < transactions.length; i++) { - expect(transactions[i]).toMatchObject({type: TRANSACTION_TYPES.DELEGATE_REGISTRATION}) + expect(transactions[i]).toMatchObject({ + type: TRANSACTION_TYPES.DELEGATE_REGISTRATION, + }) } }) }) diff --git a/packages/core-test-utils/__tests__/generators/transactions/signature.test.js b/packages/core-test-utils/__tests__/generators/transactions/signature.test.js index 3452203e55..d01f3ce0b7 100644 --- a/packages/core-test-utils/__tests__/generators/transactions/signature.test.js +++ b/packages/core-test-utils/__tests__/generators/transactions/signature.test.js @@ -1,5 +1,3 @@ -'use strict' - const createSignature = require('../../../lib/generators/transactions/signature') const { TRANSACTION_TYPES } = require('../../../../crypto/lib/constants') @@ -9,11 +7,7 @@ describe('Signature transaction', () => { }) const quantity = 4 - const transactions = createSignature( - undefined, - undefined, - quantity - ) + const transactions = createSignature(undefined, undefined, quantity) it('should return an array', () => { expect(transactions).toBeArrayOfSize(quantity) @@ -21,7 +15,9 @@ describe('Signature transaction', () => { it('should return an array of 4 signature objects', () => { for (let i = 0; i < transactions.length; i++) { - expect(transactions[i]).toMatchObject({type: TRANSACTION_TYPES.SECOND_SIGNATURE}) + expect(transactions[i]).toMatchObject({ + type: TRANSACTION_TYPES.SECOND_SIGNATURE, + }) } }) }) diff --git a/packages/core-test-utils/__tests__/generators/transactions/transfer.test.js b/packages/core-test-utils/__tests__/generators/transactions/transfer.test.js index 4aacee8cc7..ac35369fcb 100644 --- a/packages/core-test-utils/__tests__/generators/transactions/transfer.test.js +++ b/packages/core-test-utils/__tests__/generators/transactions/transfer.test.js @@ -1,21 +1,22 @@ -'use strict' - +const { + Bignum, + constants: { ARKTOSHI, TRANSACTION_TYPES }, +} = require('@arkecosystem/crypto') const createTransfer = require('../../../lib/generators/transactions/transfer') -const { TRANSACTION_TYPES } = require('../../../../crypto/lib/constants') describe('Transfer transaction', () => { it('should be a function', () => { expect(createTransfer).toBeFunction() }) - const amount = 20 + const amount = new Bignum(20 * ARKTOSHI) const quantity = 4 const transactions = createTransfer( undefined, undefined, undefined, amount, - quantity + quantity, ) it('should return an array', () => { @@ -24,13 +25,15 @@ describe('Transfer transaction', () => { it('should return an array of 4 transfer objects', () => { for (let i = 0; i < transactions.length; i++) { - expect(transactions[i]).toMatchObject({ type: TRANSACTION_TYPES.TRANSFER }) + expect(transactions[i]).toMatchObject({ + type: TRANSACTION_TYPES.TRANSFER, + }) } }) it('should return an array sending 20 ark', () => { for (let i = 0; i < transactions.length; i++) { - expect(transactions[i]).toMatchObject({ amount: amount * Math.pow(10, 8) }) + expect(transactions[i]).toMatchObject({ amount }) } }) }) diff --git a/packages/core-test-utils/__tests__/generators/transactions/vote.test.js b/packages/core-test-utils/__tests__/generators/transactions/vote.test.js index 776b445da3..92b2d4a29b 100644 --- a/packages/core-test-utils/__tests__/generators/transactions/vote.test.js +++ b/packages/core-test-utils/__tests__/generators/transactions/vote.test.js @@ -1,5 +1,3 @@ -'use strict' - const createVote = require('../../../lib/generators/transactions/vote') const { TRANSACTION_TYPES } = require('../../../../crypto/lib/constants') @@ -9,11 +7,7 @@ describe('Vote transaction', () => { }) const quantity = 4 - const transactions = createVote( - undefined, - undefined, - quantity - ) + const transactions = createVote(undefined, undefined, undefined, quantity) it('should return an array', () => { expect(transactions).toBeArrayOfSize(quantity) @@ -21,7 +15,7 @@ describe('Vote transaction', () => { it('should return an array of 4 vote objects', () => { for (let i = 0; i < transactions.length; i++) { - expect(transactions[i]).toMatchObject({type: TRANSACTION_TYPES.VOTE}) + expect(transactions[i]).toMatchObject({ type: TRANSACTION_TYPES.VOTE }) } }) }) diff --git a/packages/core-test-utils/__tests__/matchers/blockchain/dispatch.test.js b/packages/core-test-utils/__tests__/matchers/blockchain/dispatch.test.js index f322cee9d9..083ba1d9ad 100644 --- a/packages/core-test-utils/__tests__/matchers/blockchain/dispatch.test.js +++ b/packages/core-test-utils/__tests__/matchers/blockchain/dispatch.test.js @@ -1,12 +1,10 @@ -expect.extend({ - toDispatch: require('../../../lib/matchers/blockchain/dispatch') -}) +require('../../../lib/matchers/blockchain/dispatch') describe('.toDispatch', () => { const blockchain = { - dispatch (event) { + dispatch(event) { return event - } + }, } test('passes when the dispatch method is called with the argument', () => { @@ -15,6 +13,9 @@ describe('.toDispatch', () => { test('fails when the dispatch method is not called with the argument', () => { expect(() => {}).not.toDispatch(blockchain, 'FAKE-EVENT') - expect(() => blockchain.dispatch('OTHER-EVENT')).not.toDispatch(blockchain, 'EVENT') + expect(() => blockchain.dispatch('OTHER-EVENT')).not.toDispatch( + blockchain, + 'EVENT', + ) }) }) diff --git a/packages/core-test-utils/__tests__/matchers/blockchain/execute-on-entry.test.js b/packages/core-test-utils/__tests__/matchers/blockchain/execute-on-entry.test.js index 7aa39db3ee..2b2bfbc49f 100644 --- a/packages/core-test-utils/__tests__/matchers/blockchain/execute-on-entry.test.js +++ b/packages/core-test-utils/__tests__/matchers/blockchain/execute-on-entry.test.js @@ -1,8 +1,6 @@ const Machine = require('xstate').Machine -expect.extend({ - toExecuteOnEntry: require('../../../lib/matchers/blockchain/execute-on-entry') -}) +require('../../../lib/matchers/blockchain/execute-on-entry') describe('.toExecuteOnEntry', () => { const machine = Machine({ @@ -11,15 +9,15 @@ describe('.toExecuteOnEntry', () => { a: { onEntry: ['action-a'], on: { - START: 'b' - } + START: 'b', + }, }, b: { on: { - END: 'a' - } - } - } + END: 'a', + }, + }, + }, }) test('passes when the state machine executes all the actions when enters a state', () => { @@ -29,6 +27,9 @@ describe('.toExecuteOnEntry', () => { test('fails when the state machine does not execute all the actions when enters a state', () => { expect(machine).not.toExecuteOnEntry({ state: 'a', actions: ['no-action'] }) expect(machine).not.toExecuteOnEntry({ state: 'b', actions: ['action-a'] }) - expect(machine).not.toExecuteOnEntry({ state: 'a', actions: ['action-a', 'no-action'] }) + expect(machine).not.toExecuteOnEntry({ + state: 'a', + actions: ['action-a', 'no-action'], + }) }) }) diff --git a/packages/core-test-utils/__tests__/matchers/blockchain/transition.test.js b/packages/core-test-utils/__tests__/matchers/blockchain/transition.test.js index 4a9a541f9c..3b232152ae 100644 --- a/packages/core-test-utils/__tests__/matchers/blockchain/transition.test.js +++ b/packages/core-test-utils/__tests__/matchers/blockchain/transition.test.js @@ -1,8 +1,6 @@ const Machine = require('xstate').Machine -expect.extend({ - toTransition: require('../../../lib/matchers/blockchain/transition') -}) +require('../../../lib/matchers/blockchain/transition') describe('.toTransition', () => { const machine = Machine({ @@ -11,28 +9,28 @@ describe('.toTransition', () => { a: { on: { START: 'b', - SUB: 'c' - } + SUB: 'c', + }, }, b: { on: { - END: 'a' - } + END: 'a', + }, }, c: { on: { - END: 'a' + END: 'a', }, initial: 'c-1', states: { 'c-1': { on: { - BACK: 'b' - } - } - } - } - } + BACK: 'b', + }, + }, + }, + }, + }, }) test('passes when the state machine transitions from one state to other on an event', () => { diff --git a/packages/core-test-utils/__tests__/matchers/fields/address.test.js b/packages/core-test-utils/__tests__/matchers/fields/address.test.js index fecb1b789b..1a50b11775 100644 --- a/packages/core-test-utils/__tests__/matchers/fields/address.test.js +++ b/packages/core-test-utils/__tests__/matchers/fields/address.test.js @@ -1,6 +1,4 @@ -expect.extend({ - toBeArkAddress: require('../../../lib/matchers/fields/address') -}) +require('../../../lib/matchers/fields/address') describe('.toBeArkAddress', () => { test('passes when given a valid address', () => { diff --git a/packages/core-test-utils/__tests__/matchers/fields/public-key.test.js b/packages/core-test-utils/__tests__/matchers/fields/public-key.test.js index b87cddfab5..d2d2187d4d 100644 --- a/packages/core-test-utils/__tests__/matchers/fields/public-key.test.js +++ b/packages/core-test-utils/__tests__/matchers/fields/public-key.test.js @@ -1,9 +1,9 @@ -expect.extend({ - toBeArkPublicKey: require('../../../lib/matchers/fields/public-key') -}) +require('../../../lib/matchers/fields/public-key') describe('.toBeArkPublicKey', () => { test('passes when given a valid public key', () => { - expect('022cca9529ec97a772156c152a00aad155ee6708243e65c9d211a589cb5d43234d').toBeArkPublicKey() + expect( + '022cca9529ec97a772156c152a00aad155ee6708243e65c9d211a589cb5d43234d', + ).toBeArkPublicKey() }) }) diff --git a/packages/core-test-utils/__tests__/matchers/models/delegate.test.js b/packages/core-test-utils/__tests__/matchers/models/delegate.test.js index 420f5bebcb..1f24e73a62 100644 --- a/packages/core-test-utils/__tests__/matchers/models/delegate.test.js +++ b/packages/core-test-utils/__tests__/matchers/models/delegate.test.js @@ -1,11 +1,10 @@ -expect.extend({ - toBeDelegate: require('../../../lib/matchers/models/delegate') -}) +require('../../../lib/matchers/models/delegate') const delegate = { username: 'arkxdev', address: 'DQ7VAW7u171hwDW75R1BqfHbA9yiKRCBSh', - publicKey: '0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0' + publicKey: + '0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0', } describe('.toBeDelegate', () => { diff --git a/packages/core-test-utils/__tests__/matchers/models/transaction.test.js b/packages/core-test-utils/__tests__/matchers/models/transaction.test.js index ebc148e3e5..47904003e6 100644 --- a/packages/core-test-utils/__tests__/matchers/models/transaction.test.js +++ b/packages/core-test-utils/__tests__/matchers/models/transaction.test.js @@ -1,21 +1,21 @@ -expect.extend({ - toBeTransaction: require('../../../lib/matchers/models/transaction') -}) +require('../../../lib/matchers/models/transaction') const transaction = { version: 1, network: 23, type: 0, timestamp: 35672738, - senderPublicKey: '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', + senderPublicKey: + '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', fee: 10000000, vendorFieldHex: '5449443a2030', amount: 200000000, expiration: 0, recipientId: 'AFzQCx5YpGg5vKMBg4xbuYbqkhvMkKfKe5', - signature: '304502210096ec6e27176fa694638d6fff35d7a551b2ed8c479a7e03264026eea41a05edd702206c071c97d1c6cc3bfec64dfff808cb0d5dfe857803428efb80bf7717b85cb619', + signature: + '304502210096ec6e27176fa694638d6fff35d7a551b2ed8c479a7e03264026eea41a05edd702206c071c97d1c6cc3bfec64dfff808cb0d5dfe857803428efb80bf7717b85cb619', vendorField: 'TID: 0', - id: 'a5e9e6039675563959a783fa672c0ffe65369168a1ecffa3c89bf82961d8dbad' + id: 'a5e9e6039675563959a783fa672c0ffe65369168a1ecffa3c89bf82961d8dbad', } describe('.toBeTransaction', () => { diff --git a/packages/core-test-utils/__tests__/matchers/models/wallet.test.js b/packages/core-test-utils/__tests__/matchers/models/wallet.test.js index d911188319..e5d62d951d 100644 --- a/packages/core-test-utils/__tests__/matchers/models/wallet.test.js +++ b/packages/core-test-utils/__tests__/matchers/models/wallet.test.js @@ -1,10 +1,9 @@ -expect.extend({ - toBeWallet: require('../../../lib/matchers/models/wallet') -}) +require('../../../lib/matchers/models/wallet') const wallet = { address: 'DQ7VAW7u171hwDW75R1BqfHbA9yiKRCBSh', - publicKey: '0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0' + publicKey: + '0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0', } describe('.toBeWallet', () => { diff --git a/packages/core-test-utils/__tests__/matchers/transactions/types/delegate-resignation.test.js b/packages/core-test-utils/__tests__/matchers/transactions/types/delegate-resignation.test.js index f5bd9afc96..efcff5d174 100644 --- a/packages/core-test-utils/__tests__/matchers/transactions/types/delegate-resignation.test.js +++ b/packages/core-test-utils/__tests__/matchers/transactions/types/delegate-resignation.test.js @@ -1,8 +1,6 @@ const { DELEGATE_RESIGNATION } = require('@arkecosystem/crypto').constants -expect.extend({ - toBeDelegateResignationType: require('../../../../lib/matchers/transactions/types/delegate-resignation') -}) +require('../../../../lib/matchers/transactions/types/delegate-resignation') describe('.toBeDelegateResignationType', () => { test('passes when given a valid transaction', () => { diff --git a/packages/core-test-utils/__tests__/matchers/transactions/types/delegate.test.js b/packages/core-test-utils/__tests__/matchers/transactions/types/delegate.test.js index 85b104afd8..f7197b342a 100644 --- a/packages/core-test-utils/__tests__/matchers/transactions/types/delegate.test.js +++ b/packages/core-test-utils/__tests__/matchers/transactions/types/delegate.test.js @@ -1,8 +1,6 @@ const { DELEGATE } = require('@arkecosystem/crypto').constants -expect.extend({ - toBeDelegateType: require('../../../../lib/matchers/transactions/types/delegate') -}) +require('../../../../lib/matchers/transactions/types/delegate') describe('.toBeDelegateType', () => { test('passes when given a valid transaction', () => { diff --git a/packages/core-test-utils/__tests__/matchers/transactions/types/ipfs.test.js b/packages/core-test-utils/__tests__/matchers/transactions/types/ipfs.test.js index 5e57d55d3b..18aa10968a 100644 --- a/packages/core-test-utils/__tests__/matchers/transactions/types/ipfs.test.js +++ b/packages/core-test-utils/__tests__/matchers/transactions/types/ipfs.test.js @@ -1,8 +1,6 @@ const { IPFS } = require('@arkecosystem/crypto').constants -expect.extend({ - toBeIpfsType: require('../../../../lib/matchers/transactions/types/ipfs') -}) +require('../../../../lib/matchers/transactions/types/ipfs') describe('.toBeIpfsType', () => { test('passes when given a valid transaction', () => { diff --git a/packages/core-test-utils/__tests__/matchers/transactions/types/multi-payment.test.js b/packages/core-test-utils/__tests__/matchers/transactions/types/multi-payment.test.js index 00694586ff..4596198e0f 100644 --- a/packages/core-test-utils/__tests__/matchers/transactions/types/multi-payment.test.js +++ b/packages/core-test-utils/__tests__/matchers/transactions/types/multi-payment.test.js @@ -1,8 +1,6 @@ const { MULTI_PAYMENT } = require('@arkecosystem/crypto').constants -expect.extend({ - toBeMultiPaymentType: require('../../../../lib/matchers/transactions/types/multi-payment') -}) +require('../../../../lib/matchers/transactions/types/multi-payment') describe('.toBeMultiPaymentType', () => { test('passes when given a valid transaction', () => { diff --git a/packages/core-test-utils/__tests__/matchers/transactions/types/multi-signature.test.js b/packages/core-test-utils/__tests__/matchers/transactions/types/multi-signature.test.js index fda2f8d3c7..0a8de16b79 100644 --- a/packages/core-test-utils/__tests__/matchers/transactions/types/multi-signature.test.js +++ b/packages/core-test-utils/__tests__/matchers/transactions/types/multi-signature.test.js @@ -1,8 +1,6 @@ const { MULTI_SIGNATURE } = require('@arkecosystem/crypto').constants -expect.extend({ - toBeMultiSignatureType: require('../../../../lib/matchers/transactions/types/multi-signature') -}) +require('../../../../lib/matchers/transactions/types/multi-signature') describe('.toBeMultiSignatureType', () => { test('passes when given a valid transaction', () => { diff --git a/packages/core-test-utils/__tests__/matchers/transactions/types/second-signature.test.js b/packages/core-test-utils/__tests__/matchers/transactions/types/second-signature.test.js index 0e7c573d47..d9311fb667 100644 --- a/packages/core-test-utils/__tests__/matchers/transactions/types/second-signature.test.js +++ b/packages/core-test-utils/__tests__/matchers/transactions/types/second-signature.test.js @@ -1,8 +1,6 @@ const { SECOND_SIGNATURE } = require('@arkecosystem/crypto').constants -expect.extend({ - toBeSecondSignatureType: require('../../../../lib/matchers/transactions/types/second-signature') -}) +require('../../../../lib/matchers/transactions/types/second-signature') describe('.toBeSecondSignatureType', () => { test('passes when given a valid transaction', () => { diff --git a/packages/core-test-utils/__tests__/matchers/transactions/types/timelock-transfer.test.js b/packages/core-test-utils/__tests__/matchers/transactions/types/timelock-transfer.test.js index 3def0ad483..72b4c0808d 100644 --- a/packages/core-test-utils/__tests__/matchers/transactions/types/timelock-transfer.test.js +++ b/packages/core-test-utils/__tests__/matchers/transactions/types/timelock-transfer.test.js @@ -1,12 +1,12 @@ -const { TIMELOCK_TRANSFER } = require('@arkecosystem/crypto').constants +const { TRANSACTION_TYPES } = require('@arkecosystem/crypto').constants -expect.extend({ - toBeTimelockTransferType: require('../../../../lib/matchers/transactions/types/timelock-transfer') -}) +require('../../../../lib/matchers/transactions/types/timelock-transfer') describe('.toBeTimelockTransferType', () => { test('passes when given a valid transaction', () => { - expect({ type: TIMELOCK_TRANSFER }).toBeTimelockTransferType() + expect({ + type: TRANSACTION_TYPES.TIMELOCK_TRANSFER, + }).toBeTimelockTransferType() }) test('fails when given an invalid transaction', () => { diff --git a/packages/core-test-utils/__tests__/matchers/transactions/types/transfer.test.js b/packages/core-test-utils/__tests__/matchers/transactions/types/transfer.test.js index 0cc5748a6a..cc82600fb9 100644 --- a/packages/core-test-utils/__tests__/matchers/transactions/types/transfer.test.js +++ b/packages/core-test-utils/__tests__/matchers/transactions/types/transfer.test.js @@ -1,8 +1,6 @@ const { TRANSFER } = require('@arkecosystem/crypto').constants -expect.extend({ - toBeTransferType: require('../../../../lib/matchers/transactions/types/transfer') -}) +require('../../../../lib/matchers/transactions/types/transfer') describe('.toBeTransferType', () => { test('passes when given a valid transaction', () => { diff --git a/packages/core-test-utils/__tests__/matchers/transactions/types/vote.test.js b/packages/core-test-utils/__tests__/matchers/transactions/types/vote.test.js index 6b25b61ba5..935b5f8914 100644 --- a/packages/core-test-utils/__tests__/matchers/transactions/types/vote.test.js +++ b/packages/core-test-utils/__tests__/matchers/transactions/types/vote.test.js @@ -1,8 +1,6 @@ const { vote } = require('@arkecosystem/crypto').constants -expect.extend({ - toBeVoteType: require('../../../../lib/matchers/transactions/types/vote') -}) +require('../../../../lib/matchers/transactions/types/vote') describe('.toBeVoteType', () => { test('passes when given a valid transaction', () => { diff --git a/packages/core-test-utils/__tests__/matchers/transactions/valid-second-signature.test.js b/packages/core-test-utils/__tests__/matchers/transactions/valid-second-signature.test.js index ab8950145e..508f6080f7 100644 --- a/packages/core-test-utils/__tests__/matchers/transactions/valid-second-signature.test.js +++ b/packages/core-test-utils/__tests__/matchers/transactions/valid-second-signature.test.js @@ -1,39 +1,26 @@ const { NetworkManager } = require('@arkecosystem/crypto') +const { Transaction } = require('@arkecosystem/crypto').models +const genTransfer = require('../../../lib/generators/transactions/transfer') +const genWallets = require('../../../lib/generators/wallets') -expect.extend({ - toHaveValidSecondSignature: require('../../../lib/matchers/transactions/valid-second-signature') -}) +require('../../../lib/matchers/transactions/valid-second-signature') -const transaction = { - version: 1, - network: 30, - type: 0, - timestamp: 35632190, - senderPublicKey: '0310c283aac7b35b4ae6fab201d36e8322c3408331149982e16013a5bcb917081c', - fee: 10000000, - amount: 10000000, - expiration: 0, - recipientId: 'DFyDKsyvR4x9D9zrfEaPmeJxSniT5N5qY8', - signature: '3045022100ead721ae139c0a18a7be2077453337f8305e02a474a3e4e35eb22bcf59ce474c02207ea591ac68b5cfee068ac605efb000c7e1e7479abc7f6ee7ece21f3a5c629800', - secondSignature: '3044022006bd359a6820353e5e2f28adc0569f79ee7ed2918ee169bb149ca582f613fa760220502f39db1f9568edeb05df08d570a21a8204cb66f993f7cea6554a3298c548be', - signSignature: '3044022006bd359a6820353e5e2f28adc0569f79ee7ed2918ee169bb149ca582f613fa760220502f39db1f9568edeb05df08d570a21a8204cb66f993f7cea6554a3298c548be', - id: 'e665f6634fdbbbc562f79b92c8f0acd621081680c247cb4a6fc987bf456ea554' -} +const wallets = genWallets('testnet', 2) +const transaction = genTransfer('testnet', wallets.map(w => w.passphrase))[0] -describe.skip('.toHaveValidSecondSignature', () => { +describe('.toHaveValidSecondSignature', () => { test('passes when given a valid transaction', () => { expect(transaction).toHaveValidSecondSignature({ - publicKey: transaction.senderPublicKey, - network: NetworkManager.findByName('devnet') + publicKey: wallets[1].publicKey, }) }) test('fails when given an invalid transaction', () => { transaction.secondSignature = 'invalid' + transaction.signSignature = 'invalid' expect(transaction).not.toHaveValidSecondSignature({ - publicKey: transaction.senderPublicKey, - network: NetworkManager.findByName('devnet') + publicKey: wallets[1].publicKey, }) }) }) diff --git a/packages/core-test-utils/__tests__/matchers/transactions/valid.test.js b/packages/core-test-utils/__tests__/matchers/transactions/valid.test.js index 5f90cb8522..da97b83cd8 100644 --- a/packages/core-test-utils/__tests__/matchers/transactions/valid.test.js +++ b/packages/core-test-utils/__tests__/matchers/transactions/valid.test.js @@ -1,21 +1,21 @@ -expect.extend({ - toBeValidTransaction: require('../../../lib/matchers/transactions/valid') -}) +require('../../../lib/matchers/transactions/valid') const transaction = { version: 1, network: 23, type: 0, timestamp: 35672738, - senderPublicKey: '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', + senderPublicKey: + '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', fee: 10000000, vendorFieldHex: '5449443a2030', amount: 200000000, expiration: 0, recipientId: 'AFzQCx5YpGg5vKMBg4xbuYbqkhvMkKfKe5', - signature: '304502210096ec6e27176fa694638d6fff35d7a551b2ed8c479a7e03264026eea41a05edd702206c071c97d1c6cc3bfec64dfff808cb0d5dfe857803428efb80bf7717b85cb619', + signature: + '304502210096ec6e27176fa694638d6fff35d7a551b2ed8c479a7e03264026eea41a05edd702206c071c97d1c6cc3bfec64dfff808cb0d5dfe857803428efb80bf7717b85cb619', vendorField: 'TID: 0', - id: 'a5e9e6039675563959a783fa672c0ffe65369168a1ecffa3c89bf82961d8dbad' + id: 'a5e9e6039675563959a783fa672c0ffe65369168a1ecffa3c89bf82961d8dbad', } describe('.toBeValidTransaction', () => { diff --git a/packages/core-test-utils/config/index.js b/packages/core-test-utils/config/index.js index 71fdd31757..e171379977 100644 --- a/packages/core-test-utils/config/index.js +++ b/packages/core-test-utils/config/index.js @@ -1,5 +1,4 @@ -'use strict' - module.exports = { - passphrase: 'prison tobacco acquire stone dignity palace note decade they current lesson robot' + passphrase: + 'prison tobacco acquire stone dignity palace note decade they current lesson robot', } diff --git a/packages/core-api/__tests__/__support__/config/delegates.json b/packages/core-test-utils/config/testnet/delegates.json similarity index 99% rename from packages/core-api/__tests__/__support__/config/delegates.json rename to packages/core-test-utils/config/testnet/delegates.json index e90b8cae7b..5af0f71488 100644 --- a/packages/core-api/__tests__/__support__/config/delegates.json +++ b/packages/core-test-utils/config/testnet/delegates.json @@ -52,4 +52,4 @@ "agree grain record shift fossil summer hunt mutual net vast behind pilot", "decide rhythm oyster lady they merry betray jelly coyote solve episode then" ] -} \ No newline at end of file +} diff --git a/packages/core-test-utils/config/testnet/genesisBlock.json b/packages/core-test-utils/config/testnet/genesisBlock.json new file mode 100644 index 0000000000..317cd8ed94 --- /dev/null +++ b/packages/core-test-utils/config/testnet/genesisBlock.json @@ -0,0 +1,2312 @@ +{ + "version": 0, + "totalAmount": 12500000000000000, + "totalFee": 0, + "reward": 0, + "payloadHash": "d9acd04bde4234a81addb8482333b4ac906bed7be5a9970ce8ada428bd083192", + "timestamp": 0, + "numberOfTransactions": 153, + "payloadLength": 35960, + "previousBlock": null, + "generatorPublicKey": "03b47f6b6719c76bad46a302d9cff7be9b1c2b2a20602a0d880f139b5b8901f068", + "transactions": [ + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402205fcb0677e06bde7aac3dc776665615f4b93ef8c3ed0fddecef9900e74fcb00f302206958a0c9868ea1b1f3d151bdfa92da1ce24de0b1fcd91933e64fb7971e92f48d", + "id": "db1aa687737858cc9199bfa336f9b1c035915c30aaee60b1e0f8afadfdb946bd", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100ffff4e9ba62e5e3beb37deee052824da83c4030925bce09f190151652d0669b8022056a432e56a2e1b026d4b54f6c34ce88a0c9cebdccc730659c03449fe878c66f8", + "id": "0762007f825f02979a883396839d6f7425d5ab18f4b8c266bebe60212c793c6d", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022001a6326e5d1eb06d0ba1fa39446bd6d56ea45f0c269ebbce5dfc6a649277cfcc02203b252d3a6ef2b22349d9d0a9110ce28a199c39dc8b911edfa82c297a02009d07", + "id": "3c39aca95ad807ce19c0325e3059d7b1cf967751c6929035214a4ef320fb8154", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304502210084d855eddfe616cf1dc238b19226c7959c2fc4027ae2e8aea6fd8e9eb8928e6b0220440f980e40c1c56348782fd69d49a96944df7ee5b68d18028600e0e7501d4000", + "id": "9fdf6ae86f7c005b3b7dc1b9fb6411219407ecaa93adff85fdb61710f5121638", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402205438b8b9058bbde5d30794e7681e400e52b5fbd22324c5b6b521f97bc8b8aabc022000fe04d7afbd2e668b1d4576988ed596dc92251e33efebc081e2cba14ad5a898", + "id": "1d7c68087c875d7ce555b2c3e71e1d91a1ad62d0c2497efe3cab91415e634041", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100b2e634a95b011a68489870f003e4bac4a4f0578bfdc6b9f645c934016c2c0463022022cd4ebf276dd627d98be4b697bae2df10b86d94e984da2eb7e011b08d6dffd2", + "id": "0c993e115ba26981b0be9d22e7c4a13b0f106e0cb472f9d34eabfc8e414dd528", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100f965e5c280acb22d1cde405223fe9a6fcb765844adbc5321b17a268924e1f597022043d31b1edc5fe0cf60a960d84e3528472cdf34560c9463979043a409f37e7f29", + "id": "c279f2eb1f9e6e7d4b0ba7a98233a0f1a2536231976c99f56f64b248eb06a0c1", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "30440220715463c316a75959dbfb6a59a013fbf914bef1ff739ac8000d49dabbf5118df9022019345ae1c34173dc214bae82f3cfbf438092f0fd2d277acafe3e9deb644b1a3b", + "id": "7e2fc9ecf23e909a3d0fbecd615445a0eed8c2cef18e01b1492d63f616f5d87d", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100fdd8aff26dceeb5abb6e5e8a8f468c8ac1997a587225298e3d8135d57dadf4dc022072ab80a81b301a162ed5cfa67d213d5a3980185088632f5f592351aff8aa0e9c", + "id": "511c0e1076104743f98932f8e7720bdb3f1539134edadd331914fd9ece1ebede", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "30440220635e04ce278870f17fcd1883aa26c568e63dfbdd302add39aa30fd3637c79c2c02206fdd9e7b1f4d238a97d26ef1758927e2d39f121687490f2bd79831e36afdd43b", + "id": "0768d5016c53d884e3d68a09d1bab0d730b7067c71ef4ca1c4d61b3815f5ff66", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402200b1dac57ca6565ac31afb99686f2e0f0e8dc219b9860b295ca5444a1663cecfb02205787393561fe407449af4aaf2f621db9e4d3f11c7438666cd694d495c0a0c41f", + "id": "1aeb50080ea118165e5041f7a897974c2ed1ebde08add85dc78cc7cf73566a91", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304502210098dea25eccf31ce6f874a9528578805aaf07be8b41f1571865793f9e3e6e3c97022033ae9c73dad44c01fe6362665fccf63bb1a0ae8e26f77a1cf60b67dc96b05343", + "id": "254f0f4fa277cc651a746d6ac371eb27afc3ea155ba060552dd26b8e83d17b72", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402207f4bf346aac501e766156818089fb16905a9bdca69ff6d5a55ba918a08afc7ab02200ec2c25cc4bb30e2c176d55630d8e2679b899c14ab4ba43c3d62955dd940425b", + "id": "e5ebb02e8e8a6708e22ee5ef99fe1dd8b6eea1095be6b772aa21bf63cf7ade5a", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100a0bbc15bdad648bb9b439f1d34b12b853442d1cfd4ce7f569905082801fa58e8022036b4e73edf7ab7226f8007233f77b1d497cb6b4736f02721bf1b399312ebe114", + "id": "8a686b21477b64dfd85f08f8598a0f121ca1c7d65ccaca9e42326c75fb5f3abb", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402205d77dfcde527dcc6669bcb01c27b92c1a6399e35ebac9e69415645f596ab1d2802204179497bfd952f44d5f9e295b2a3219a290a4a82841c084a18553b7712e26415", + "id": "21175347e2acfabc09a7593aae0682e39fe7152199a90561c11125f525211243", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100cf77c16df9185727ff717b71a94f8b29ceeae1e5bb3a28da8cef9df5bc63b7c202207bca394ce9ebd344a548e5a5697f672dedbef640dc1f9105f7c063287bcd1840", + "id": "ce1d9b7377551f36568127f5b635b5443f5a58abba6566b50a8d4d7b53c8a874", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100eb8daebb5484f3b0a738c9344fb28298c596f9486963f8fe36e2501ee6876f2a0220559df66986dc9a9a8e76982ef85f907c62745757990c69f0b17b6ae5a7ca4719", + "id": "b56702f5eddad0d8dbbb33b6b1ca3e07e4740def9c5dd2aaed9a70b90a4e31b7", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100d088e9bcd78978f2d67e7c7bccecfb73ddd0d1a2dad5b039390812320355722d02207affe83d815f04f6b11abf98eebe0488bfb87f8cd6513d44b829008ed1c15ceb", + "id": "a73c053c42e83a83498cf58e5b077b31443e265ddf8228081cb17a36bba366ae", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100db16a8e9682f07efb607bc7c75b654646ff449761ed146ab9358e69d29fadd7f0220436554ad78db0e04ae5b573258e2c8067848e89b55a6e8e1e25011a43882a643", + "id": "2dccb8b44ad2e598673628fd9d74e336b467a0c941d5e257dceb85c8e0a0000c", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100b03738eccce8ad0b8ac0a656119c2cdd202089c5650d8e1486bd13eb9c3158980220059079900c7fdc16e799c50dccc074726fbf0068044462faabdf1e73f9f9bc38", + "id": "b2cce30021d139f97925807da796722bf4d5459442523823388c259ca5ad73db", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100becb49fe5edd6806d5ba6eddbbb34ca8eaf3a12dba123d1610b2b120ca8bd017022072972992ee0ca0f319ae754a2a5a10d715a08b23f8239f9d6d59774f790543ea", + "id": "9e4841f43ab355be7a4f93b09f3d82c17065fbe25387dd6c5eb4e2692ea05b0b", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402207f1a3fe8c5aa7a77a58ed35c34f128b5df6fba89aa918af35eff432be7d1f8e00220460d4f2a457e1a477974157e33bf2974de6588d56e59729ae980720e9794827a", + "id": "2c7ca823be21724a4876de632dded3b9afca45df357819ed028488128d85d29e", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022067266dfe9d8f2550b590e1eae2f73d28c6b80fecb24c3eb1b4539bc864b3b4f4022031e5122145c35874c0c48673d088e76fb3e11c308ffe9d5dee6431d3441d627e", + "id": "a91119f04e2201184761f7fdcb26e4aa81c7e1076cb11a58a422d351241d4e4a", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100b970ec89927de0cb7805e614a742d42c2967db5a9c68d0892956dc89d68ca7d1022067fa30265dd2e1a2985980be2bf876748a7a8c7f3cde0382265b601fa658dc17", + "id": "94955e6bac6269fbd19e92d2292ac947225fc6f68c6216001b528596a961040c", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402203671b82ddf8a824b8e5aac8bc28be4aef1c00aca1097d14ec1a55003d7a3f28d02203aacb6e7517e916478432b81399828ba7425183ce0fc43feb361bcf345fb0519", + "id": "df563ee9822bd3d7aada600d4800952743ec64fafdc7697428d7a19a60745885", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100b77653317c93eb20ee19c71e64a7f9ecb985351bfb1fe351ac65a5738cb37ae202203d540395e1d55f87caaaa867afbfbaf98c553be0b4c7d1748418a76b0c258c89", + "id": "d21b6341e2b4be5ffdc3dd8fbcdf2c576ba02e2ef4ab5eab0e4bfc9da4e9e442", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022046239e39062a58925099b005888355b8cd6700af66972bf509a10123f9abdec60220202321ea74e56177606fc079d19c29851d832e6d00c93985ffbec3dba6f0d675", + "id": "df6bc7a17ad34f8e9faaa2646e8e5dd8bca35affba352537184f690e200e17b6", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402204eeab87f7ecc2097b85606b986177964f3ae777535f6fc0cf08a55fec587d87602203779d59903b8de63511e4ed0a7967bd85e9cb1fc9d84bbc5091e3caa87d8bd52", + "id": "5f0d5f0dff464d0ad587da5bc93e600a8e2657d359d0a1224bdd4ccc3b6f376a", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402200a2b9d0f61066fa00a2a2882379aa8ee60e949bdc2a85103bbbb69ce3eafccd9022057364f349faceb3047fa95ada210c64fc4a81978d66925b37d3dbc21ede885af", + "id": "1b39e3702576e6ad7775e34d53e43210549d52a56b3f246031e6ba4121a66bf0", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304502210099e568d3d0c1b48410e0b85c74d04234dacfb2fdf2b1d4b51fca1cfb3445347a02207a2509645aae54560762a37422b66ba4b3ee1c42de35d58c36d2f9d8fdea11b4", + "id": "0f21e53dbb1edb1cfb4c31bb675aa4672b452a03ec363a2b3300a9dda49e3be3", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022026cc5f2b588a86241badca73cd9c1686916d516b8c6c397c66a9d5bb6b5d4cd402204ab5a8c8589ee954bda4a116999d2a0e4ab0e3e96f0c7fe131d7c57b9a1ede43", + "id": "410826c255a23a78ac5c3aa10dd48132693bc955845af16c20d9c6f69b05dfe9", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402205fedd8d3b5c8d69cdd7db5ca8e9e7c5004f6ba751e45eb1b85b26d9e89800a2402202be56bb2cd824bccf325b6b11432bf6d0ddb5ec97fcc121839ac2ebf884c7173", + "id": "ddb57d8270b2b6c876191c1e1c5974388b9fb3ae0980cb2245d8a7c426237f47", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022053cd42ad147eea33801b2b57388b33f633b4bfe2ad902190e12480522250d07802203066dc0d0c2ffacc4c74cca1e0187fbea1cef7e78a78666d2ec7e4e87ef546eb", + "id": "29e1aedf98935c369946c8dadb2d6784f9ab5ce8d73b9b4de2466c7757e2557b", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100c10448b87e7176735c8ddfc8fb3c4d5d55c2d71d18b7ce3ab321209ec299fd41022013517a09e4b366ab386698286ec7bb20410bdfb7f6674fab25a739259083b297", + "id": "4cf04852529b5525f22cc540790e36e61ed36045ad1b5b788f61ebe42637391e", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402204cc1588b204ebc0c20f44a31ce53d15ab5e4d1f9c103c02dd4e4eaa1c33630b40220194b6e427b6def0783461cd8d765f97b105d048942be468be2ee9b0a2785d2ac", + "id": "35c6bc3f0799d9c79efc6515f232c58be0d03a3a797d066cba879eef4afaae2c", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100be44f7ea12e2ee89245fb474643ec6c2c75afa00276826a4ecd6fca4cad5ff30022071a2c083b353a821345e4bbf74d98db0760b8721856572572cc3436ebdb8f08c", + "id": "45f75a349f3b4d73434c0f2ac9c291d5d07278b79e6eaa0d38d6e005f66c4783", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402202090f506e8f18fde70b87a3fd6c470a23e9e262f20ec6268dd59b6362e51a29202202b838c598b33c6317c998dc179fad2b660b8a72bfaf8223d7cc82414ab4c6af4", + "id": "a8d9034d1091a4dbe595647ad5f64ca8b243e7842301aee48f7eaf8b8ae98119", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100be59b689a48e198267305f1ae7e116f69f7c360857ea0b1fa81db122278cad69022033436d24ec0103674522f0c559e2357f8696bd498deccad2e0f66b2cf7469538", + "id": "061cb438ba1216cfd5a0f268ce18e6f280557bc944d9aed3655e2bc5f08bdf51", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402203b5d2aa7c4554d6d2dd6723043350df0199e6e7bbd9f21a1a20dbba8c63918cc022014a78064c5f9c5e2f43d3be36de2b5e2f17e9af557bb6c75e8d82d9f725d0188", + "id": "239f0640ddc3170a737ef349c07cb82b2493d207421b6f71b6b3dab856f16088", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022005eb29ad4cf79fd4f6898de19459e15cc816acb0975e53530a202e69c29d0d4a0220686cf6e0c14779d6d68dcb9d16358c0e859094d2eec8083598b7bb5869478bf2", + "id": "25d8eef755cfee7cab0d7f9fbbea0fad6d5f906c432d997ae8ef1c49d23735f5", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100b93096a287d59545fa3a08593dfc740d9d47f3cfa3c4bd3c8ff8ef53d3a2e957022027eda62e47220774cf799f46916195e5a8b30015c56ceff4f4a1c10a918e3675", + "id": "aac25996e3be809ee88996b6b4063e2097d6306e77a067de8ebc8d7076a28d43", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022017282aa4fac7b18e834abc3ca37b2f60cf989c26b12e2f2398a66cb907015a760220428218d39db812a22cc138acc7d5d4d2d5713f0546751c02d2c3fabecca0e724", + "id": "b040f86b75750b49c83ca7eb8f2a458f16b44789796ff306c5f942ca5f19164d", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402205970d53cb0921a62bbef540dc33189b2313f3574e44f046097067e6991d63b1102200a356c87642cc781df661a1fee21cce354a144463d37053280e000e1b75da7a5", + "id": "25ce96f951d7b7d886ef487331125b3413f655f9c5ee7fb4691a728c3cbce18f", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100aab0201c9d9a9641c11605d32353685cbaa051ecc276da1e6a3b309be9f20cf7022067aecbc7329bdf1770974e317a1243815511efa8c7af7801217a83c96d86eb0e", + "id": "285143b8b19cbde7c680b0f62ef51293e8f315c823ffbd97608c38c02045d831", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100dc7752f6f8acaa3a1ee2ed1bed306ee04556b3866db92a1e770c4b970c7a932e02202d137b312342f9d0708704833b26b6611d0464c87df97049ad8b616483e9d1f8", + "id": "87b06fccbb63809e976b3405cccec2eeaa3694d5510203f04c0e60bb6c2c0020", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402205ccad5c77ea339f5e3f2b7900b4b1c409d3c8204273e89b6401314fb61f0d224022026a63fef86356de64fe571ff8488a951dcacab56e980fc044ef9f43b9d37439c", + "id": "5597ed52e4123756bea9307c09c916ff9d0f9fbce8d2e9a3a2ff719a87ad0966", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402207c91153f820f34228bec62772e0d78876bd3277912eacd866fe35b5c86a316c80220104529c6f786cb387ec1e3d5826271c837f0d0a6d0fa5731b9a5c6663cce7108", + "id": "d46fde78608fcc668246cc35336210b3c167ba55c82e91b0fd99df7e36872130", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100acc0cf119c18861d3683bb3b0f6e209f2d62acfdd958f86dfbd35137ada814320220448f6f8adcd46204629b45a4a06f5dc7ccb4dbc2a1d702e107d91053847adf2f", + "id": "aa92faf5d80459b4e058dc8a8212608b589925052e22148384835ab687a4e875", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022055b6bbde5fa886db3cf1224a59f1fb43e850e2d9237db593368e1043698fe2c30220067dd20195e794af4152f1ff9e3ae4261698a86c54803ba1890bf176d97844d4", + "id": "432e67db0d5fc8c66376aa96c7324e5a1e6d00a415a9c8898b5e3bf25d8b083d", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "30450221009d6f38067264df8497d6888e4a8c316ec58ceba8a54c39ccb0ce261d114fbbab02200fae3f2f950f5c5e3387679f8ca341ec70cd90d0e32a30112f03cfb12cd9fc23", + "id": "9321e1b08faa544f592ad8dc7b60ff1cf845efcd28fedf8b445be3bda60434cb", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245100000000000, + "fee": 0, + "recipientId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402200aed5a4102bdafda00fda575294f149b393a798c510af8ba877b8c2d7ec8051e022004f7487c4f728c633aee5baa62ab0017f4b91cf2f494eb1c4cc9addc3e9155da", + "id": "0bbc9340798a18a81109bdfdbee9c9003f20a586dd9f80a39507c84588c1b4b1", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_9", + "publicKey": "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647" + } + }, + "signature": "30440220072124721ba7c997f7c29ad3d4819515fae7a67be2bc395cb73f114eb8d4abe60220523ac295e114de30ce8a4300f4670db91ad2abe1268460e6ad3463fbe9834b84", + "id": "d2e70f9d2de57240571905aa81db0b6883e27a83be2422530722d76b56e63ecd", + "senderId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_18", + "publicKey": "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a" + } + }, + "signature": "304402204b93b06e08e71e3317f9426a1d3d450d6293fdbf5a6b3043fce27b3ce65431e20220683609720ea1d7d921238ca8b5098d3d9c0caab7b1e26efe42a6aebbc095471a", + "id": "8695bcb906f5fd81d858794f7d90447aadaa38418d312e33115a81e856b34d12", + "senderId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_47", + "publicKey": "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd" + } + }, + "signature": "30450221009711559a43005c808113a1e9a01b1665495ff4bf30d635f7d98c752ead4cc3fc02207879e2a939914effe2b5c80cd515c4b3ff77a071b707c85c4444481878803db9", + "id": "55853d2d2a98def00c5ab842866a44d1db91678a07b6dd63d062508db28a00a5", + "senderId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_5", + "publicKey": "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565" + } + }, + "signature": "3044022025ba51a588253524557547ec492d71bd485fe5b291e60eef681c39eaf8ee781702202bf24c3d295c7a2c9aed97a79fb835506797dcfe7e7a2853e2578e7773c7e134", + "id": "553298aadf692c9c5d0334c307dd4ac0e277a49ed165c97ce1362f8ec639ee3f", + "senderId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_19", + "publicKey": "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb" + } + }, + "signature": "3044022041291ba10ad30fb9ebcb0e13902e92d85e2c3e98493b6d369d7d1e70e8474e31022009083444460c415eab6b4beed9e0206eb0733bad5d2a476af4db4f5b5e74b835", + "id": "90af927db7b258538c8e21116b5a31418c88ecc163628b2b65fac92a5a949b14", + "senderId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_42", + "publicKey": "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d" + } + }, + "signature": "304402205d4111c87874e696b8f4b8897d0dfe68fabe4ad5c5769026c6ecdd04f09a1e2f02207b9c8a2a16b50164215eb1efea6d5d9f4e693cbb7eec8535e526cf8ba68bb796", + "id": "8a920ebf5255a102d0c9c5fd720e0d36a6a3539991a2267442facf1fea2d0b86", + "senderId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_10", + "publicKey": "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd" + } + }, + "signature": "3045022100f15ff048872020d9efc561b8c837f542d54d43b9b071f7a6cc09643c6d4180f002207d0e82153a30b66f43fc4cb4b9b3093bb3d5dfd70f96928c8780c838b1448c19", + "id": "30738f376aa40fb3c8d8849a5dc698786aeb1409fa801c18729f8da624631391", + "senderId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_20", + "publicKey": "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751" + } + }, + "signature": "3045022100babb7410d09215def98078bbab6b5e5690c2ebf54960d94527226ed3925877320220342576d1d8fd2d2fe3b6974cab48a2e16b4813f022b341b32f88e13f572bf060", + "id": "ccbe1c27eadc1b3b33f3f87f645be4f756021ee3d4c96f4f094e1f82d5728a3a", + "senderId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_49", + "publicKey": "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374" + } + }, + "signature": "3044022032f2c350cc1319f5838d6880e91b49ae0438fb3a626ed9ab5e27ce8788e3347c02202cca18567c8491e0feea8a5f078e28605029346c509fac0c0a192e934f8c5326", + "id": "f99af0fbb4d65c2c3f2c1c558f0c0c0eac2724942802fcde02fa6da1d3a9000c", + "senderId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_3", + "publicKey": "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17" + } + }, + "signature": "3045022100f0cb5d885ddf3bd4a58837f9b86486da4171652a5eb39228dfd0ff9d34d9c7c602202dc6e3d268d745a7e8633311a337ec097382342049672880c7c2215cf58e5da2", + "id": "2dca03aed08533585d8bc609da5deb9f17ac9be5a8352769d7ae63d0db16ff59", + "senderId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_21", + "publicKey": "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a" + } + }, + "signature": "3045022100999f19fbdc9a12eebbb8c748a4cfc6c91b2233f333a09cddfd49dfeab6aaf38602203d8dc9d1551d400572a88ee812f51f897f8b35508713b789b2c1bf6dd0e88945", + "id": "5d7e51d57b5914ec201ab65a019ecdf651c4f267cbffe403fd2170bb95145f9d", + "senderId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_41", + "publicKey": "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f" + } + }, + "signature": "3045022100e86e648add940a1e637e32ea9187497c281b843da09597e62d0c927d7f43235102200479f64ae63abb55e338f9ce1073a5c46907f7a2a82ea6f9bd9bc29811683515", + "id": "eaeed4133da26612c53550b6572722d8c3380d0a2344da1bd270eed1ea91fdf3", + "senderId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_11", + "publicKey": "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904" + } + }, + "signature": "3045022100bc3b2ebc58a92bf38672206e8311e7ef0e54912abce7338155b11e7d191b0b5d0220765a568c1fa4665c0ace6b4bd3b7ba0f8329e2f25af7a3cc0d78b2ea398084c3", + "id": "bb91e78e43c59a19ac06c015d8a7ef09d7c5b274c9f98505e5a978027354b71c", + "senderId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_22", + "publicKey": "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a" + } + }, + "signature": "3045022100aae4868ab75a33e4e77f9bf6c53b920c5e7c523a7cfe271d1afc472655f3d6a60220499f1bcb79bc0fa830dfa939898db5c9fa8571a2788c8de0da7e550bfc818bcc", + "id": "a6e687647dde9c1db68690090afc4fcf11833dd35fff3186b6b709a1e7d24260", + "senderId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_46", + "publicKey": "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c" + } + }, + "signature": "3045022100c0cf1fc54705c13f70fde39c55a1703a4c612b8a919379cd5b1ada464c7cc8de022074ee62490a184010ad2418d3177ff2ab03d02d2589000176312b90422b1bd64b", + "id": "70262b0eec3ab5a60a736eb8a628cb600eae7522464a49791c0bf26e82318ec6", + "senderId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_6", + "publicKey": "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc" + } + }, + "signature": "3044022045db446b109215c6d3dfb0ee5869154a8a7624376c3760eec4fadc75a29033cf022003e524d64f3ccd0c6de4ca80a7327e2c47ffd16b3ad042bd25a02f5f64500ab7", + "id": "56048c449694964bee3d367609a7bc46c8da20f66878c09c01dcc53c3abd932e", + "senderId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_23", + "publicKey": "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a" + } + }, + "signature": "3045022100f8f69f2957781ed02d64983744c8e51fae613ebe5bbb330d4f509bdcf4fc6b6602205568ad1fd840e01ec26a24ac9a0ff093e978172da55d494138d018a45eb67893", + "id": "e15dfc4e18106480083b3c6211349fd9c803e334e9ba5eb62cca19ae3f57d8e7", + "senderId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_40", + "publicKey": "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689" + } + }, + "signature": "3044022021eeb9e1db8915a9adb99db72972cd17fc7b5b377fc532ac2c9deffcb2707edf022068b9e08f45bbebad89295f520ad40d7786fe64059d45df95551576e3acb736d1", + "id": "2bd0f888ccdeeca24a0134e3c1bf729582d284f32ee000d97f1417f1349a6594", + "senderId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_12", + "publicKey": "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12" + } + }, + "signature": "3044022040a9d0975f747df19792211546410d7c735aff2d26f367d1bf9233ffd1d993d702206890c66d4d0eb5de37df088c082d8fbd8da043817b48a76bd5d70f1e3f6b6529", + "id": "f75ac5ccd243e09fc9da2b3842a0654ca860d2dba5bb73866693a8a918937994", + "senderId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_24", + "publicKey": "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95" + } + }, + "signature": "30440220550c0ab565ab2de649ca7a2aaf2975453a1e4ab8b0d392d69663c0c9b6b80b7b022039047d4d1bf4e9b167a95adcde0a5a8631aeca060dfd426da28a10d968fb3a64", + "id": "aa2ed932faf4832848356beaf87e5381ee56a1a84fb485ba975acb28f8fcf5df", + "senderId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_50", + "publicKey": "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1" + } + }, + "signature": "3044022038df37ef25928d1a04516e982c99f49cbdc193603f814b48ab3802153bdd352002204c918915a3cbfa305c5f898ae4bcdd75394b57460f85c80daa0999751d466c08", + "id": "d30a726e1bb8d199d8f44700bc999c9a0a1a8be86e4be6a15764ecd424f9db1b", + "senderId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_2", + "publicKey": "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d" + } + }, + "signature": "3044022028dd44b9609b0b599c15a257757fd068f9014e33947c77776a6fcbe71879271b02200b46fd8eb0827da6de13f5efd63b17f29e8ba4600e4a690ec31eb08bf2d9af33", + "id": "1410b8b5f15c05528013378251bf5da30e04c8a6b7ac0f729b527664cfbdfbc4", + "senderId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_25", + "publicKey": "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964" + } + }, + "signature": "3044022038edfe34f7b89b4e69ea8b94e3335063b60deaee28246932147f53b2525924a402205b89f5e3d956aa49f24f81e2ba3447c19bd5c026568b3bef73a7a7d5160ad661", + "id": "58d14b74b71586e18f0499a50004ec2e0cc2e5b56aa53f4cf57084030ff90fa3", + "senderId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_39", + "publicKey": "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5" + } + }, + "signature": "3045022100bc1e477994bf4cbcdb5cbe2bd92c7d955a03adfe562f8e3bf04d2f62965e9f78022045512772d8453314361161b2bd2a39aa0a7fbb897a5a83f4c7ab54ced615b42c", + "id": "3ee53b3f1455ef0ddb52afe08854c9d87f42c7313babd3e05bb3ca4f94c495ef", + "senderId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_13", + "publicKey": "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f" + } + }, + "signature": "3044022052fe00e8e9f05b1d890f6910beab0627c823eb2d5875b4b9813a33aed11edfb6022034a723b827ce0e73bfdc0f535b244ffc983f8d549ee72b4d432de90d658db72e", + "id": "4a3d204c2916c93360d7bb11390e355bc1a930e3cf503965a45253d65bfe928b", + "senderId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_1", + "publicKey": "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37" + } + }, + "signature": "3044022013b2798a4ab4d741850abac10d962360cd4ab6a47dfac7c1c806d6f9c3d810cc02202742414ad8a04ce679b445fcd040fb877bbfed3d2692b873dec8cb46c01c8c4c", + "id": "7d0c5a44a7517f6ad7a1253db45d58e85aa1c735a282a32f45d28efdb7869d7e", + "senderId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_45", + "publicKey": "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b" + } + }, + "signature": "304402202c372b7b9679a8fe66f952a1d47d4327968d6e98770b215ada2fed6a8d87ed5502205a797fb511cfba557255dd37e028fb40981b7b65ad2ce8fe0e559a46eb274bf8", + "id": "70bfe97ae7452dc752ab4de0e2a0e81bd18bef07392c56e7a101257683d4d932", + "senderId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_7", + "publicKey": "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0" + } + }, + "signature": "3044022058851712200f7386d6b3c188444f9c8f05788667649ec17c71b9e514206eb105022061e6a4bc4cd11599792e03298f95509893d56af54d51e9f639981045e754b974", + "id": "f6f90ff09dee5be7d8f3d58d217772df7a95865bf8609d7d5b0b673e9a5bc953", + "senderId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_27", + "publicKey": "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d" + } + }, + "signature": "304402204878d69a166e60e0a779c31fbc48c67b70d2e4aed1d63c60beb9f070963e2894022078c46b6687f23493a4c2ed39709a183a0f7352568cc9cc2c1f0d7bf0d809a4a4", + "id": "f68809e407d20a50029fe460d411c866b79c7e09c076dada768a38d81f184aa3", + "senderId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_38", + "publicKey": "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294" + } + }, + "signature": "3045022100d5576393a1dea704cf79a5d0bc2757a3a5e66e1055103b52157fca05fc5693ec0220522832ce0e31b779decef83ac8ce764930de927df9ae1d6f6f99a3312d99c90c", + "id": "2ec6c6f33f00431ef063fbb8a79fb90eadb13a79bf46e6e1df36dd9434314df0", + "senderId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_14", + "publicKey": "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24" + } + }, + "signature": "3044022008a7d0bfe9c4c150566ddf701d08e84b4a5f84b07e3b1c91dde1cefa16d2a3c202200b787e898c0b2c68f4343e74f18ae7363f62b5f4ef2962386932aee09a9fa0d4", + "id": "e37b3efbf034bea4c852be7d7013978f8999eacc39549ceea775de197e14e8da", + "senderId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_28", + "publicKey": "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28" + } + }, + "signature": "3044022023b6fbfa5f4482a4dcc34411846696052b1592786ca87243b7d3344fc9fe9954022035402fbca22691de2497552c743f0f68c7591edd1bd7954ab7639548fcd558a3", + "id": "08268f5e6c15cf146523ca928f24aca65b162f363593d927c66144ee5df297cc", + "senderId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_48", + "publicKey": "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b" + } + }, + "signature": "3045022100b3cad169f29a3a95995b87e1b50b35583c1bff91d69cfa236f58ce452491c579022026775f4ef50b50ecf6d78b530b4633711394983456e6a45ec227b652c86e3014", + "id": "ad94ee2ae94813a638b93909930c7cc631c364b6c8528b2dcd6fa8f69260cc2d", + "senderId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_4", + "publicKey": "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93" + } + }, + "signature": "3044022007ac9ff2f272f3fda4947393b8688586cc8b2958ff5dc7931ac8f82c697bb76802202a66c28852bbff86ef17ac7f51e7eee52e611e825d91a9846f531ab3c3115c81", + "id": "76fb1984da9ef90fd7d588756163c97e00d3e4d6e9dfe78d9e3d3cb6d71ddd38", + "senderId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_29", + "publicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252" + } + }, + "signature": "304402204416e428688ad29928303fb2b00a26996cf79753fe70fb91c1f4635c644ba859022068ac5eab7d05f87c40ba36bd9dc149607c196778120c061698d7ab64aaade7ac", + "id": "0f442a91857061e87dd193b0b9f17a71719ca7e3da62841a63568713fc12b5e7", + "senderId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_37", + "publicKey": "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4" + } + }, + "signature": "304402206a248caa5949024202f297c38cee18845e344c5f140be74349787097d3b0a33c02207ac84336e02592bb5e00dcd0c490d30eb856b34177ab9ac03410d82a355a7b0d", + "id": "eed30a45c350fdffc5877458f7fe29f28dc4bf81aa1a197d003c9433148b71aa", + "senderId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_15", + "publicKey": "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca" + } + }, + "signature": "3045022100c99336ce666cb4a6db3727a61c04c14d8746365f72280d9984441b7d2b568b5402201759e4f417f683743e1d4a14f8a7a215009321cdfa29834b2dbdbe54ee22c1d9", + "id": "ecfba14a58f9d79782c4f905646df28bf566e3e7d1f17b39df6fe6b52c11de59", + "senderId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_30", + "publicKey": "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883" + } + }, + "signature": "3044022070de7b4d4ce64bd605c9d008142544c2b113cc84df07ed1982e0adf3cf69f4520220211b01710a6533a270dc2814c7f968adf27eb6dbf437e7a72960b013b9651a0c", + "id": "36ce5323859a92f302f77f27bd08ee3485d720f55842ccba353a47ea96a964c2", + "senderId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_44", + "publicKey": "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c" + } + }, + "signature": "3045022100a7c271633ecbf3c6641c7db36913b5fa0ea521f400a4848edf024648f3d7128002206a271f8a88644062b64d856407af9567c0b2937d4a3d89a3b3d07edbd3a0f177", + "id": "e120452e7c56a9327b2be7dfd3dcecae193f2e2e772903008b03cdf00146ebd1", + "senderId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_8", + "publicKey": "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564" + } + }, + "signature": "304402200394b6545015bcf2d0f291de57a4197cb6ef57b2ad5fa37f05e8a220913ba83502204d0d2f2206edba54ada5b8e5afd194ba83dd1bf15f744258409595251dbe3ff0", + "id": "7d15eee8e4e3be3d2c44acd51b87a816bdb593565d4ac358dab24ae9c8a5bae2", + "senderId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_31", + "publicKey": "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2" + } + }, + "signature": "3045022100989eb331951a13152aa03583efc765499e836c6fbafcafec4302b243ada8de5002203876fc4cf7fdeee4a095667e55a2fef84e5a7053e807b4d8e029883f0d578019", + "id": "baa686d521f95d265e7099cfd9ef14e0a9a92254dd94c16ce50c460bd013c588", + "senderId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_36", + "publicKey": "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e" + } + }, + "signature": "304402202be177dddfad323302565a866d38a3e7939e0234b16e7dc02075cf258502eba302200928a139ec1a82b4609fcc1bd6d1d027ad050e93fcd2eff94181936d2d43e39c", + "id": "9fcf7ec6fe98ed94710e212226d8b90df7e7467d66dd4c5c9d48474388be3099", + "senderId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_16", + "publicKey": "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9" + } + }, + "signature": "304402207b4f8c09a728acedf3b6ba0632e12d01670c683215053e49dde8598954d85a9a02202a7d7930baa17c2134b314e47dd6c334c828f78e573a2bf92fcbc1146d630541", + "id": "c35e4b1e7a2435664fc0939251c2052633ebf4b51fb22d15e71bfcab85b26de9", + "senderId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_32", + "publicKey": "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055" + } + }, + "signature": "30440220127d27312345e015c681adb799c1a87d16fb0caaabd5020b39257d567816b91c022018b2388f6d2d9afb3714d84ed102b3ea61159772786033c855947613c7ce7b5b", + "id": "0d682a3a9c252a674043bee5240e456dae2685d76fbd3bdeda6ff50f0c442fff", + "senderId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_51", + "publicKey": "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a" + } + }, + "signature": "304402203d0ee691830e4d001553bf4e49b6d9669b3c959376f391410551c8adc679dac902203ba6e275bf6d543efd19d20428649f802d9396bb0967114a1f09c24827be1da7", + "id": "ec2373b0d609ae72fb400ffdfbffc59670ebbf1c15f59c0ac22a4030dae700e3", + "senderId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_26", + "publicKey": "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983" + } + }, + "signature": "3045022100f2cf77b0510f589b5aaaf2b0027ffbce6ce8d4873cdc67dc8900865d156de3be02203c22e30945618683182f3d3873e6b3657e0900b062f866bab2705cd593669e79", + "id": "3cb2f0f7d05a515d4c5c873cbe96e33b1dfba1b7718e4548de7f9da54933b652", + "senderId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_33", + "publicKey": "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe" + } + }, + "signature": "304402201e328159172d543d2225c247c6b728800c52eb724f67c0e919f6b7215e6bd7f2022075fc02fe0b14a1499c5602d87ca2c99d6e789beaceed2b9702060dece872d14a", + "id": "2fd77e744399c9632cc8f106c39237f201dafda976f1040235359f99eea3b832", + "senderId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_35", + "publicKey": "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e" + } + }, + "signature": "3044022063903d82e8bd15a6741a298b9a6007d0dc3626acfe2f072c3b624ccbf91ce3360220486ba4cc5591d8aa31b77dfde025b61691dbaad0feabe13e840d26e40010c5df", + "id": "5baf9e318c9e4cb0513a21eaea27e51c849f95fddc963207fb07aa2fd2b9f9d4", + "senderId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_17", + "publicKey": "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357" + } + }, + "signature": "3045022100efc1bc16e0b646da48f84822543b62ef5253bfa98bed6613f2d6d4634076e61802200ef243f9dbac7633a8819ce45e2a85d0eacfdc9a33a92bd3a03e90cbd312b823", + "id": "b4a959ad75f81b7fdbb957c90a3a63a6c5589e7819e2c455733a3a2b4b034634", + "senderId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_34", + "publicKey": "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80" + } + }, + "signature": "3044022012e52a479648990bfc1ed12bf901cad865708ff45962c3724ea67967be4f9d0102201901525ed8dd090af6a2637c123afb304e9fd178794addcb88d916227e66887d", + "id": "6439f2308efe31ac52ad06ef1caa45b9abf6c589118b7997da6a287325ca36e7", + "senderId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_43", + "publicKey": "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e" + } + }, + "signature": "3045022100a0874d1582ce210081f7ab30e7f951dfb9ce8f512d237f8a8cbd5d85569ef3b902200f0053c05de3d6e5ada4e4cf1403a836779d653573c2f374055645cc954c4c4a", + "id": "b0733072e98d3d6afe977e32f3dd118c15e79212232417743ffb551dc2a2ba55", + "senderId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW", + "senderPublicKey": "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357", + "timestamp": 0, + "asset": { + "votes": [ + "+03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357" + ] + }, + "signature": "30440220158ed59156e0eef2d2b94a296451dffe079be701b3d74f0443ef43bc266b334202205a2c39f57abfcd279d568608b90884b3ebe107316aa7552eca35c743b318a47c", + "id": "ea294b610e51efb3ceb4229f27bf773e87f41d21b6bb1f3bf68629ffd652c2d3", + "senderId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7", + "senderPublicKey": "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80", + "timestamp": 0, + "asset": { + "votes": [ + "+030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80" + ] + }, + "signature": "3045022100898da9f693a458a6875344c6c4cb73069c4075904c75595ffbc665967d84b07002200f168aaf3ab1b52dfa74599394387dc4cf627a447fbc5a91000e9d251cdb20c0", + "id": "3639b5dc6d19d46d8254d941bf7ace0f3da8a7cf8a56361921b260820c7239cd", + "senderId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1", + "senderPublicKey": "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e", + "timestamp": 0, + "asset": { + "votes": [ + "+032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e" + ] + }, + "signature": "3044022055ed9a8b55ccb3bd0945a710269b6f243f1dbfaa28467d3218a17565eb0c962d02207d31561478f16d93a20f5454ad565dea24e8dda4ddc464cb011f4b6b360c4e81", + "id": "fe24509580cde0c2e2f49defedd3a0f7572d2f78f90b51a253b0d8cebd74c20d", + "senderId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof", + "senderPublicKey": "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055", + "timestamp": 0, + "asset": { + "votes": [ + "+0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055" + ] + }, + "signature": "30440220092f367f833d677e8d0609ad1df65f389c2c35d1501c71c245c2982e6a832268022018e67445f525613d6cb6ac0c9683bd0f55bd40d9c929165649414f083c9041f9", + "id": "6a76553db794ebf4d5f60a7d7d71cfe29f4dbcaad9610106fbc578cdc7167cd4", + "senderId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy", + "senderPublicKey": "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2", + "timestamp": 0, + "asset": { + "votes": [ + "+03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2" + ] + }, + "signature": "304402203dc028b5013c36b03f97b111a8d7c05d0cd8e505b0b0d18747c0656c9b5cfe8102205e9ce8a78d1183b3e9880c69635d04218d94d17808bcc3f92e7af53195c23daf", + "id": "0f9d7e7708918b77afbdfffb63eef8fe87ba36e0131c88b44c1a7f81750cc025", + "senderId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9", + "senderPublicKey": "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e", + "timestamp": 0, + "asset": { + "votes": [ + "+0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e" + ] + }, + "signature": "3045022100a80ddd7c3adaf0e97ab938773fc78a716f3054d7e03afc1ddfcb5005badbd2810220231c0dabe2262149f994c939f9dc90d46b9bd7ca96b19aad6788cd3571e4f71a", + "id": "0ac77b2637fb25be42b3b60d1651bbbd788aeaba933a08ec4a417c7b4c54e087", + "senderId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT", + "senderPublicKey": "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883", + "timestamp": 0, + "asset": { + "votes": [ + "+02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883" + ] + }, + "signature": "30440220772c9cd8b96f74fcddc429d57d466eca6fc40fc211845f59eeb78cb027e116c5022004cda291587eb118d622de21333d2a5783969794b5b0101ad8b1044c7d8058af", + "id": "4b0dda465564d53981c0e36d73caec888e3523633eaa80dfb99a9c81b2604c7d", + "senderId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU", + "senderPublicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252", + "timestamp": 0, + "asset": { + "votes": [ + "+0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252" + ] + }, + "signature": "30440220406d54714b6425ae4553ea8bec75f31fe52e9b1a9b6f6897151253ab7f637d3b022040a2df4b69840f4d9b0b67658c75efdae8d8269780d4cc50d055fa63922dbb9a", + "id": "c7db9d36d97ff0168d0d670ec695e1dc786dfb93f4081586870c8793b50e5f17", + "senderId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK", + "senderPublicKey": "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4", + "timestamp": 0, + "asset": { + "votes": [ + "+030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4" + ] + }, + "signature": "3044022018b7e51118ec83c985fa4eb3d7f0cf0655753bcbde7e82bac521665fb1c0ffaf02204e2ace460b2542db8c77e41d05d5e02fa5514b746a0a1e947256925846ed19f1", + "id": "c41f4cffcdd523f1718154d5bd5f4f0bec0376076b5f8dd340337e9edb4821ae", + "senderId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW", + "senderPublicKey": "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28", + "timestamp": 0, + "asset": { + "votes": [ + "+03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28" + ] + }, + "signature": "304502210088dbe249503da43c157485bfd4f2c95babfe4d0b8bbefe44afa52529b824a79e022045239b6a374fd9aca52c27171ee66b4863c956ae4085c9760d863b1902596c1a", + "id": "b1736ec6a1ea4c6d4eb278430a8ee214c88daefe296ba98530e692f8b7a7434c", + "senderId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej", + "senderPublicKey": "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d", + "timestamp": 0, + "asset": { + "votes": [ + "+02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d" + ] + }, + "signature": "3045022100fcdf750a775e728a31691a1b38908a7f990b579da510959cc2c63442f5ffde760220316ebb051d9fecb2486771dd39921fb12675b6d46b2441dd1db3c42fad0a59b0", + "id": "069271456015c2ff842771775993b8afc3404bc070572eeeb0f2fd72d58e18dc", + "senderId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U", + "senderPublicKey": "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294", + "timestamp": 0, + "asset": { + "votes": [ + "+0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294" + ] + }, + "signature": "3044022034ce8f77ea9d0f5cf3a9135d7b72d0ba3b96ac6d7eaa3670e9956aef2c9a83cb0220626d1f269128f673a23f9993ce00ba78a08103e697298be29a4c8ee94f204e3a", + "id": "9a99bba8340e7ad4e05d8424a0977ebbde428d31ee066c9828bd06b42bb42a72", + "senderId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2", + "senderPublicKey": "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983", + "timestamp": 0, + "asset": { + "votes": [ + "+02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983" + ] + }, + "signature": "3044022039ae1155f8b87a61c38b25cbbf30da6ecf6cfcc12b25c2e7fe576373754a41eb0220061a66a893129fbad5d48cdd19cf48b1a0d133dd2f3ecdc60ee7b87277e1f81d", + "id": "6c2c8926420ac269b50fa30127e0e791afb2131aff5821ca7aa80d38a0182048", + "senderId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf", + "senderPublicKey": "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964", + "timestamp": 0, + "asset": { + "votes": [ + "+02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964" + ] + }, + "signature": "3045022100d0dac2b7691aa059b1048d7925a0c5d5099f6e9b0f2e321e6d4f128ab1b3272b02207e8c4f643f8f9d1c3f81f0cce6a698df2da2ab71d5b01042766bbe0f46f4a775", + "id": "9259193c5de72276ed7a99f9d507dd6ea9856411fda521074fb41a556294fdf7", + "senderId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9", + "senderPublicKey": "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5", + "timestamp": 0, + "asset": { + "votes": [ + "+03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5" + ] + }, + "signature": "3045022100d5496fec447367ab6b53956a8c40cd8566e050ebb3b92d2c0b2a9d09bef36c7402205e32367605372375801f7b9db39aaafb46ee763b1494f0aca144fb91f3415752", + "id": "2a41e5946ab0773ca2334bba9d3510184bdd258f1c651ff8ec95b7b64a01dc2e", + "senderId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW", + "senderPublicKey": "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95", + "timestamp": 0, + "asset": { + "votes": [ + "+039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95" + ] + }, + "signature": "304502210099249695dc38826e04c8fcffd2570b98c43dec4788cc6a19737ed0872f17ec3302205301f645d803ad5df4ab1a700446e28c7cd76153607f6a2d68ae9168d46f3fe9", + "id": "e5c09b0fb2c24c57a4dcef0078953093800329ab4dc8e16a9d9f68215b5acd3d", + "senderId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU", + "senderPublicKey": "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a", + "timestamp": 0, + "asset": { + "votes": [ + "+034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a" + ] + }, + "signature": "3045022100f983b03e319aaa6c6ab6381e3ef8c0c035d6e3cc2139cedf70fd4e385393e38a0220286f73577765eb3e89e362785ad8a6de572bebf41bbc1f515b0ea93e41801eb3", + "id": "00b2c0455ef6f508d65f11bb49e3cfe1e6062d5fd153cafdfdfd2ccbf9c646e5", + "senderId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr", + "senderPublicKey": "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689", + "timestamp": 0, + "asset": { + "votes": [ + "+022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689" + ] + }, + "signature": "30440220103862ec51621ca27a0ec6b2817848e8824d2d09dbf7e6aac2f45aeea5d2dc9102205e8cce78b5cd7148aa4d406dc7b491dd7758047200e10cfe1e5fde5c56107ac5", + "id": "e25439ad11cb8db3d49ccb3b8b608c1bcb24cb29b2e5ea15101cce3e475224eb", + "senderId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ", + "senderPublicKey": "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a", + "timestamp": 0, + "asset": { + "votes": [ + "+03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a" + ] + }, + "signature": "304502210099241ced4a0fd1eb02f5cdcc880ae5f48eb3c7e490d4520c20124ecbf403893602204729dc6cacf3e87c97ca57c1be54d1e80791bf31ef022135e68fc06c950f6994", + "id": "1474f50815c6c7df41ab652414806d61abe15bee0d41f32d772f4e2793badce4", + "senderId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX", + "senderPublicKey": "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a", + "timestamp": 0, + "asset": { + "votes": [ + "+0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a" + ] + }, + "signature": "3045022100eccf81d44992c49a5ee37c6fc2ccc4b6bee9aa44888513b3e18e79452ede3156022056b0ddf079d2918d72e8781d3af009c87e6058563591dfd6ee0117b7df5534b2", + "id": "b394e2a8b5c2d20a72ed288408b8f0d48aed922edbee6e16c1c5b0e67517214c", + "senderId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf", + "senderPublicKey": "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f", + "timestamp": 0, + "asset": { + "votes": [ + "+03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f" + ] + }, + "signature": "3045022100bdb87894846eccc5a5473edaee1e6dca5f3469963e22f06123b6bde195aede0e02203d0c6833e87c5e60f4597ce624d4c2502a0562b4e54d943f82a4889e3cd69532", + "id": "6a399099bac6c74fa5e956512ef8b3a39f6f946d5d6996f192c2f1dd5ba172dc", + "senderId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv", + "senderPublicKey": "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751", + "timestamp": 0, + "asset": { + "votes": [ + "+02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751" + ] + }, + "signature": "304402200785771ccf1a6a40b51183a190d4cb4ce76b9ffd4c2c736d7724e6c667113d020220649ecfe73017d8dda96a7914793470ee7e582693e4866df123b1032194c163b1", + "id": "f20a831a6bae0a85470e308fb66517e70db479657459f6bb39f2cd1783c565e6", + "senderId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv", + "senderPublicKey": "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb", + "timestamp": 0, + "asset": { + "votes": [ + "+0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb" + ] + }, + "signature": "3044022020b79e1f07bcb17cae9485b9f44e9f583ca235da4ddd363b905fafb884347f71022015a20481b43720ddb3b1e3ca64b1f47e59b5cc2016a62f43327ca14533384dd4", + "id": "7a1285be87dca9718bece5b84266c1bf6801a39cc111d534e660aef9e6d26929", + "senderId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg", + "senderPublicKey": "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d", + "timestamp": 0, + "asset": { + "votes": [ + "+0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d" + ] + }, + "signature": "3045022100b1615d16763c46d42ca2aae967f04c1c07c119b5af7a378c262ba85515a8d35002202cf7df91676cd137943720e93f06c11907412a6bdc5ef2157cf536a203cf83a3", + "id": "76fb5a1de90f245b1eeb79cb11c7bea7c8b738add0fb8cd95191186a944b0229", + "senderId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri", + "senderPublicKey": "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a", + "timestamp": 0, + "asset": { + "votes": [ + "+02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a" + ] + }, + "signature": "3045022100e3c7b5d6a72acde4d22e8c1c6cd864c549deba89683f4b84320407d6c380827c02202da57df0ab7cd381b776bdf85802aed371e7cea7269a84f911b1d8e9956badee", + "id": "8da75c8100e6248ab37cc92f72ed9facec3067f4f82f03db8bb8063791463fb3", + "senderId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t", + "senderPublicKey": "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe", + "timestamp": 0, + "asset": { + "votes": [ + "+03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe" + ] + }, + "signature": "304402205779b5d8acbfedfc105fedb6fcbd4636713ed27605faa9bd988598072640a958022042d8a8b3d7910c7c385f3707a317c5d445d56da250f8d127c71df2d9d4c5d86e", + "id": "fd26e265be88289828d0ce7ffc5faeb9849e1f4cb37a8f1dd5d6fcc436d910b7", + "senderId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf", + "senderPublicKey": "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e", + "timestamp": 0, + "asset": { + "votes": [ + "+034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e" + ] + }, + "signature": "3045022100e18a89fe1fe0a8acaca2b6461314e784ffebbe7374f6aafdb06934e83985ccbf022027314b21a4a25b477bd7cc070b4e00ef8f3d69f3f1af028b96571dc245924c00", + "id": "41d92e128e6b8367cbf8fd111e5263d52e1abad553653f975dd60d7f7c5b637b", + "senderId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9", + "senderPublicKey": "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9", + "timestamp": 0, + "asset": { + "votes": [ + "+02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9" + ] + }, + "signature": "304402201c614c84dbae26f87973c9e2b38df883fe0c8c469080e31fe32a4c4946d50b67022075b8fb498fb1384aa6be785845da02813185ccf095597b5782618033828af4d5", + "id": "1e4a1f8aab6fbf8682c2b35e0d04e9e007ae717ce3f4a82894747e5807e3c759", + "senderId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV", + "senderPublicKey": "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca", + "timestamp": 0, + "asset": { + "votes": [ + "+02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca" + ] + }, + "signature": "3045022100b1ee6becc59d594776a40e5b3caec82390d273b703ecb0d7caece44953141449022016543cc29a28882845118afab6e51296cd216bc662260c28e5efd9597b6025b1", + "id": "2ce068bfccb3f967f4004e9a1e81614a738e55e45c80114c0af30a085f71a2e9", + "senderId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ", + "senderPublicKey": "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c", + "timestamp": 0, + "asset": { + "votes": [ + "+022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c" + ] + }, + "signature": "3044022036698a329d7f5f751f91ce02bc188a7527a377d01583b70427cfce64def945ec022079afafea10aa32394a1e42a80577de3869856656221d5f259e05fb44f01668b8", + "id": "3478d1ad3655e10fcc864f191972322c866616866bb1dbf66d7b66b31cd95de6", + "senderId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA", + "senderPublicKey": "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24", + "timestamp": 0, + "asset": { + "votes": [ + "+03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24" + ] + }, + "signature": "3044022035fa7be80cf881eefefc12b11de04ffb2e2e92815cf05074afef54a3c5b2eccb022041f3347f59db0b3caadefcbfbc5ae275d3fe3e2a52fe1504b23628d4b79a43bf", + "id": "8adfd8e73e96188ed9fdec459d88db1fb041a2b25b3f64830476aec661ae5010", + "senderId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm", + "senderPublicKey": "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f", + "timestamp": 0, + "asset": { + "votes": [ + "+021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f" + ] + }, + "signature": "30440220630da8a73979bd3988b7f84fe9e83a429cf3239f54c140c3dbcc407140513fc002203664ad54ed9f199f2683479b988bd97ad8fffb2c2d5dfdbdb10858aca4abfaca", + "id": "e306328ffefcd9e3809e7390a358199a62cf8ef037d57af1f5c7b54d728d427e", + "senderId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1", + "senderPublicKey": "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b", + "timestamp": 0, + "asset": { + "votes": [ + "+02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b" + ] + }, + "signature": "304402206f1df93f299ffedacc25aa201807df47d32c43369315cf9db280963c357be56302206a66acd553710f49bbb7b803a2bcb71128c8e617ffce66b37b7c968817349247", + "id": "dc69bc8f78502ba34655ed062987788939189709a4112760cd8807245d7461f5", + "senderId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8", + "senderPublicKey": "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12", + "timestamp": 0, + "asset": { + "votes": [ + "+03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12" + ] + }, + "signature": "30440220629e696a10e04d4fbc10a5ac443bf9bd40dd5d89d4b214224abe47d7ab5600340220643f361a24d9916e2c5aaec7bd7d8a6a0d3ffc5fc0b62c3ac4906eb799a862fa", + "id": "c3f49fb80c40f7779b32ba23616f5573a6ba58fc60c4629c2252933038dd89f0", + "senderId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2", + "senderPublicKey": "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904", + "timestamp": 0, + "asset": { + "votes": [ + "+0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904" + ] + }, + "signature": "30440220660f9604896dad2a97820b0d7524f0bce5a8b5766f150517d5061fd02bddf768022055e87c25891d4480e66e5d1a71e42cd5a4bef3ab2b2651cd72d44f30a4b32309", + "id": "8e8ac1b1a586e86867abbf25d63387bb6dfb793c691f0b06333c1581a9a568b3", + "senderId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT", + "senderPublicKey": "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c", + "timestamp": 0, + "asset": { + "votes": [ + "+034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c" + ] + }, + "signature": "304402202e2ad64129f61ef1156c4c7e80ab862d4823d62dac502685f53028536ddfb41a02201a3ec777fdfe8fae9f7cd5251fac322c1b6a2a4d41b3ec456daed474986d4872", + "id": "ff73565c373f2cefebf86c72dda3a6a6205750eb03b69178cb83378620715e1d", + "senderId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q", + "senderPublicKey": "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd", + "timestamp": 0, + "asset": { + "votes": [ + "+02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd" + ] + }, + "signature": "304402202e5c78cf21a088db10e1e1f64d98d84c8d3294fde7bc322d4af06bfe99d4c2e302207e7912a16a37b641a9f8c7c722f2b0d699917ca73e4d0f21584b717fb7f02f13", + "id": "3822273b496f2e253081cedf382e4f9937713fabb83449e1f892377cf536e68a", + "senderId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo", + "senderPublicKey": "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647", + "timestamp": 0, + "asset": { + "votes": [ + "+0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647" + ] + }, + "signature": "3045022100a65ce45164c9bc3e018e26703370c9deb2933ee3b4e814619043cc37c4a39c4802205ae4931ac9e8dffd714c3b601fe248a49c0185c8367887205f497d951c52eb54", + "id": "430d6db0b87c25dce4ce14ac907c13bcc6efa5d95135f05aa4ba7596ea9d400c", + "senderId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN", + "senderPublicKey": "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd", + "timestamp": 0, + "asset": { + "votes": [ + "+036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd" + ] + }, + "signature": "3045022100f3cdd7f688ad2d7b6a5b9cc7e793cb8a6e6e07d3327bc67add64691a53fd2911022026ae1adc8f4fcfc01bcca3efc83019026755b443a504265ad1f46f69d1f5951c", + "id": "dda86ecc0332e6c4eed1c0a5af7424374089b85dd274a300fed51b86e2655587", + "senderId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj", + "senderPublicKey": "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564", + "timestamp": 0, + "asset": { + "votes": [ + "+03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564" + ] + }, + "signature": "3045022100d419072a752acd55792257c96099fb14c56c29112a00535d39bca96fbd7951c902201abdf4db247dc956d79f4543c389823fbd1a9337f95d30df39603a3b52486bfb", + "id": "0998e9a055c53bf6697ee76af94c7a830c1364016d78fce889a21bc38ed70cd5", + "senderId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN", + "senderPublicKey": "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0", + "timestamp": 0, + "asset": { + "votes": [ + "+022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0" + ] + }, + "signature": "3045022100ba1e0ab761326d2a53cbda2a4a5135033c94d8166864d2ad3ceb963b4a0c046402207d755ecf4ada9fa2a598fd75e73a59d30cb83e01f510020b48b6bf162dc60b27", + "id": "be13743deb8486a575d1fb564d2b07d797ac77148d35793c9aca43c0d47aad61", + "senderId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA", + "senderPublicKey": "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b", + "timestamp": 0, + "asset": { + "votes": [ + "+03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b" + ] + }, + "signature": "3044022038a491e2e13ac32025209d00aec1af31b73a8b6ee77ad9b8bb80a34f5df59dfc02200ce82c89fe9f88bd5af236ceeaa80f9954e3fb4af7bc884c447505751d49c134", + "id": "f1d3d44cc289837de9623cba8891a1ed1cde8918473a91e2daead29975afad22", + "senderId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx", + "senderPublicKey": "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc", + "timestamp": 0, + "asset": { + "votes": [ + "+0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc" + ] + }, + "signature": "304402202ae599ce389cd030b8ab48ef53113458b9ba8bf9c9ed09c662eba2849bf540f802202ed63f8af492dd0b67d1b451170a989418a42466a3a7ffe89c4c5a18337e8fb9", + "id": "65ab302a44ea7550891eabc3b4a8d5ecbcb80784c4666195d5d0b7e33394300d", + "senderId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK", + "senderPublicKey": "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565", + "timestamp": 0, + "asset": { + "votes": [ + "+026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565" + ] + }, + "signature": "304502210088a3a4e82d307c238e01ce154b57631d4429e0b591e828ec36839a783736e842022042c6e1d719781e2edca3dbfe84ad13b9e490821a47ccadfcff379decb9c873c0", + "id": "d26a7ea56f398634a81086bb15c2f0c863c71b8bd728304d324d8245a8fb6c73", + "senderId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz", + "senderPublicKey": "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374", + "timestamp": 0, + "asset": { + "votes": [ + "+032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374" + ] + }, + "signature": "3045022100ae5805541f085a50076835422b2581d3b7a128a05b4f068ad7e3c14cd02799b802205f4bb40e06f90e02282ae74c0aba97923e601fd78234b9585468c4fb73f47893", + "id": "02504eae7ff4963c081219523bc48d7a07de4c29fdc1622224547f9a7c133abf", + "senderId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp", + "senderPublicKey": "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93", + "timestamp": 0, + "asset": { + "votes": [ + "+03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93" + ] + }, + "signature": "3044022078d38cabd8f427ef381d0aa6a0b98c6a590cb18f47acc1d80b429a1c1959b0ab022022a70d4d93d650ca3121dde6065e80cd90d1e2e91cb90f0d0b2eadde609e0d75", + "id": "addb8c1baa833baa52a5b51d8a86f8524bde826b5c9f0a99e57070e6323e1dfc", + "senderId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv", + "senderPublicKey": "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17", + "timestamp": 0, + "asset": { + "votes": [ + "+038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17" + ] + }, + "signature": "3044022076dd065e3fba825b77884a179d0231d7fc9e7d3a02e34bc6565fab81a84e559e02200a880c028e690a9d6f2c4c6576b1bf3e913817c834da8ec6afdbadfae78d341d", + "id": "72f31f9a829b93045ef2e860b24c33b9be6a2621c26914acd42121215c1d517e", + "senderId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P", + "senderPublicKey": "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1", + "timestamp": 0, + "asset": { + "votes": [ + "+030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1" + ] + }, + "signature": "304402205261d9d8ded6364fda8b10bd477982be84990cb010f9214d52c492676814e1f40220489f441ffe2478d361a12ab96caa59da495fe62d61d0e2255aa5ec4ed789afb8", + "id": "1f17b4ba072d205761ed3f786491eaf684ed3601b69082e487e568aa74a319e8", + "senderId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd", + "senderPublicKey": "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d", + "timestamp": 0, + "asset": { + "votes": [ + "+02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d" + ] + }, + "signature": "3044022040219da41054a3eebd3122df7f09a62a4e8b4fdc287ae77221f2217b42f291ad02202b9a70c54bb546a604eafadcc086ef6b6570f57542374d87de02ad7f61fe51a4", + "id": "5fa837023159d6a3d6cf7c5b2ed6fe05ff7df19300226b2f0be5a48a06993780", + "senderId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo", + "senderPublicKey": "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37", + "timestamp": 0, + "asset": { + "votes": [ + "+03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37" + ] + }, + "signature": "3045022100ded426768f114f459485ba6ae293c9649b340cf2dcb15e8e887fbb5fed6f7e0b0220752297022de6e93ff64bb9e07b4efef8e946cd2872f84d9e1cb3165ff5c342cb", + "id": "0a16dc31514629a36d7237968ada6a95d6cbec027b7d26e1e0f0d7d4febe9494", + "senderId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD", + "senderPublicKey": "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a", + "timestamp": 0, + "asset": { + "votes": [ + "+02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a" + ] + }, + "signature": "304402203aa292e7aedcd62bb5a79c2521b666b8e1886b57923d98f51911b0461cfdb5db0220539657d5c1dcb78c2c86376da87cc0db428e03c53da3f4f64ebe7115998f00b6", + "id": "8816f8d8c257ea0c951deba911266394b0f2614df023f8b4ffd9da43d36efd9d", + "senderId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD" + } + ], + "height": 1, + "id": "17184958558311101492", + "blockSignature": "304402202fe5de5697fa25d3d3c0cb24617ac02ddfb1c915ee9194a89f8392f948c6076402200d07c5244642fe36afa53fb2d048735f1adfa623e8fa4760487e5f72e17d253b" +} diff --git a/packages/core-test-utils/config/testnet/peers.json b/packages/core-test-utils/config/testnet/peers.json new file mode 100644 index 0000000000..fe44230ea3 --- /dev/null +++ b/packages/core-test-utils/config/testnet/peers.json @@ -0,0 +1,14 @@ +{ + "minimumVersion": ">=2.0.0", + "minimumNetworkReach": 5, + "globalTimeout": 5000, + "coldStart": 30, + "whiteList": [], + "blackList": [], + "list": [ + { + "ip": "0.0.0.99", + "port": 4000 + } + ] +} diff --git a/packages/core-test-utils/config/testnet/plugins.js b/packages/core-test-utils/config/testnet/plugins.js new file mode 100644 index 0000000000..2dd60a3832 --- /dev/null +++ b/packages/core-test-utils/config/testnet/plugins.js @@ -0,0 +1,74 @@ +module.exports = { + '@arkecosystem/core-event-emitter': {}, + '@arkecosystem/core-config': {}, + '@arkecosystem/core-logger-winston': { + transports: { + console: { + options: { + level: process.env.ARK_LOG_LEVEL || 'debug', + }, + }, + dailyRotate: { + options: { + level: process.env.ARK_LOG_LEVEL || 'debug', + }, + }, + }, + }, + '@arkecosystem/core-database-postgres': { + connection: { + host: process.env.ARK_DB_HOST || 'localhost', + port: process.env.ARK_DB_PORT || 5432, + database: process.env.ARK_DB_DATABASE || 'ark_development', + user: process.env.ARK_DB_USERNAME || 'ark', + password: process.env.ARK_DB_PASSWORD || 'password', + }, + }, + '@arkecosystem/core-transaction-pool-mem': { + enabled: !process.env.ARK_TRANSACTION_POOL_DISABLED, + maxTransactionsPerSender: + process.env.ARK_TRANSACTION_POOL_MAX_PER_SENDER || 300, + allowedSenders: [], + // 100+ years in the future to avoid our hardcoded transactions used in the + // tests to expire immediately + maxTransactionAge: 4036608000, + }, + '@arkecosystem/core-p2p': { + host: process.env.ARK_P2P_HOST || '0.0.0.0', + port: process.env.ARK_P2P_PORT || 4000, + whitelist: ['127.0.0.1', '::ffff:127.0.0.1'], + }, + '@arkecosystem/core-blockchain': { + fastRebuild: false, + }, + '@arkecosystem/core-api': { + enabled: !process.env.ARK_API_DISABLED, + host: process.env.ARK_API_HOST || '0.0.0.0', + port: process.env.ARK_API_PORT || 4003, + whitelist: ['*'], + }, + '@arkecosystem/core-webhooks': { + enabled: process.env.ARK_WEBHOOKS_ENABLED, + server: { + enabled: process.env.ARK_WEBHOOKS_API_ENABLED, + host: process.env.ARK_WEBHOOKS_HOST || '0.0.0.0', + port: process.env.ARK_WEBHOOKS_PORT || 4004, + whitelist: ['127.0.0.1', '::ffff:127.0.0.1'], + }, + }, + '@arkecosystem/core-graphql': { + enabled: process.env.ARK_GRAPHQL_ENABLED, + host: process.env.ARK_GRAPHQL_HOST || '0.0.0.0', + port: process.env.ARK_GRAPHQL_PORT || 4005, + }, + '@arkecosystem/core-forger': { + hosts: [`http://127.0.0.1:${process.env.ARK_P2P_PORT || 4000}`], + }, + '@arkecosystem/core-json-rpc': { + enabled: process.env.ARK_JSON_RPC_ENABLED, + host: process.env.ARK_JSON_RPC_HOST || '0.0.0.0', + port: process.env.ARK_JSON_RPC_PORT || 8080, + allowRemote: false, + whitelist: ['127.0.0.1', '::ffff:127.0.0.1'], + }, +} diff --git a/packages/core-test-utils/fixtures/testnet/blocks.101-155.js b/packages/core-test-utils/fixtures/testnet/blocks.101-155.js new file mode 100644 index 0000000000..eed2da2090 --- /dev/null +++ b/packages/core-test-utils/fixtures/testnet/blocks.101-155.js @@ -0,0 +1,1047 @@ +module.exports = [ + { + id: '16380709717848284005', + version: 0, + timestamp: 46584522, + height: 101, + reward: '0', + previousBlock: '6161515163793239359', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f', + blockSignature: + '304402204d1e50daa970881aa600a19e4f785fe3f74ffedede6134889c86bb7df5f3103a02206e623a242ffb5297ae09185f1f46cbcc9e49b0324bc0aac0bb30e4b0dff7b20f', + createdAt: '2018-09-11T17:08:42.241Z', + }, + { + id: '15490212522027991751', + version: 0, + timestamp: 46584530, + height: 102, + reward: '0', + previousBlock: '16380709717848284005', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2', + blockSignature: + '304402204ca739a7c99d035d01cb27a18e2989110196490f4d2e17293a6bc5f9d5240afd02200e49f9901aa1dc129866b98290958baf0fdbca41f3c9114f864228089859dffd', + createdAt: '2018-09-11T17:08:50.564Z', + }, + { + id: '7619316577889665171', + version: 0, + timestamp: 46584538, + height: 103, + reward: '0', + previousBlock: '15490212522027991751', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d', + blockSignature: + '3045022100cab8276fe2cebafefb6fcd0f895b9cadf5e38829d14ea8e0f1b1365e9481dc7202205395c196242699efd143548d9cf783607e7e4772bf572c3564ab8bb7c0a3e7cd', + createdAt: '2018-09-11T17:08:58.400Z', + }, + { + id: '14306710738176000705', + version: 0, + timestamp: 46584546, + height: 104, + reward: '0', + previousBlock: '7619316577889665171', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0', + blockSignature: + '304402202702687d7607151039ebddeb69715ec72effe5458a7f02004ee84124c8482b480220625a2d2fd5214d820464f960240e3f98b45174cab5c2d043025c1d61509f8e38', + createdAt: '2018-09-11T17:09:06.414Z', + }, + { + id: '16285816300440069381', + version: 0, + timestamp: 46584554, + height: 105, + reward: '0', + previousBlock: '14306710738176000705', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb', + blockSignature: + '304402202b45aaa43e3b0801389f4ed4bca834ef83d7f1160a25d7063bb5434fa07a1384022054e14371cfcb448dd46cecd84981b33a35a9aca892f4aab4c8495c6ffbbaeaf6', + createdAt: '2018-09-11T17:09:14.346Z', + }, + { + id: '16505099800747927529', + version: 0, + timestamp: 46584562, + height: 106, + reward: '0', + previousBlock: '16285816300440069381', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252', + blockSignature: + '3045022100b1d9bd1a77eb5d9ddd94a45b5f83168438d6f09ab7da068eeaee457aed79e6c502207a5423a3c7e3cae99d4b656e7c62ac2672030fde9ccd618c3ccc2388c203bdcd', + createdAt: '2018-09-11T17:09:22.407Z', + }, + { + id: '16506832204032304009', + version: 0, + timestamp: 46584570, + height: 107, + reward: '0', + previousBlock: '16505099800747927529', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95', + blockSignature: + '3045022100f25903940fae22d28d95c7232d5220ef5ce599abdd773bea1b6942e1c331f0b50220726a691c87a99645fc3eb756a3914aa2b0cd36cf48c48f76f2f266132e3d3dff', + createdAt: '2018-09-11T17:09:30.531Z', + }, + { + id: '9467089070361350584', + version: 0, + timestamp: 46584578, + height: 108, + reward: '0', + previousBlock: '16506832204032304009', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2', + blockSignature: + '304402205d1b9fe34514316e70682743dd35e328d3b8424747e3951b93f6c7373442b67c022064fce5e5569a7a7a8a4cb7f914c5eb217bd71e9254a5934f05802705d3b0205f', + createdAt: '2018-09-11T17:09:38.454Z', + }, + { + id: '8391119528927829411', + version: 0, + timestamp: 46584586, + height: 109, + reward: '0', + previousBlock: '9467089070361350584', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a', + blockSignature: + '30440220617749a2d215693ac015b19285cda89ac7b9c5d383f2a416d2e975d66084dbb5022058baac9686c5096e7f77172d3e66f036bfd43564c8388365437f874efd68f146', + createdAt: '2018-09-11T17:09:46.375Z', + }, + { + id: '16820242876782994066', + version: 0, + timestamp: 46584594, + height: 110, + reward: '0', + previousBlock: '8391119528927829411', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93', + blockSignature: + '304402206c0a3dd633fd14dfafaa3b4b35d196485dc0b0c9ef8006ed5ae412510170d28a02203b0caef052c8c0b25fae1af1661bb06c2a212dfabaf87a6689528e897b0938a5', + createdAt: '2018-09-11T17:09:54.417Z', + }, + { + id: '17811063050605622774', + version: 0, + timestamp: 46584602, + height: 111, + reward: '0', + previousBlock: '16820242876782994066', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751', + blockSignature: + '304502210091c76111ecfb88d30071d4c850a63899cfebfb0ab03d3dd9e2b14bf921fd444e02204c48b0a02acb3fdf9d76d6ede553c1b98580145135801e27c803b38fce79de95', + createdAt: '2018-09-11T17:10:02.366Z', + }, + { + id: '17705208927947214042', + version: 0, + timestamp: 46584610, + height: 112, + reward: '0', + previousBlock: '17811063050605622774', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca', + blockSignature: + '3044022066f31a536c2bc098c6ee7f74591b6564cd619d2f00734b2a5a5491cde33f9a740220085c9e8a5b1457215f33a23d4b94f671c1f0f5f8127682b5713d1a44633ab598', + createdAt: '2018-09-11T17:10:10.335Z', + }, + { + id: '3794170631479398111', + version: 0, + timestamp: 46584618, + height: 113, + reward: '0', + previousBlock: '17705208927947214042', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28', + blockSignature: + '304402204ccdf577d8cbec4ef62ce2ef68752915de0344093e27057ab05895aa8871e73a02202f27f5d537e0a21911e574c21bc1b80936ea98a5d0b49c693dd42fec41f6401f', + createdAt: '2018-09-11T17:10:18.285Z', + }, + { + id: '2000919467344312301', + version: 0, + timestamp: 46584626, + height: 114, + reward: '0', + previousBlock: '3794170631479398111', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e', + blockSignature: + '30440220479043956e097c3bafad3529b8335eadf295e0c9fd71e2a9ab04c151247743cd02201ebf345c07fc9c7be440ed0989a84b841a2bdaa032c2adee34534be2a67d6ac8', + createdAt: '2018-09-11T17:10:26.304Z', + }, + { + id: '17040727982508304752', + version: 0, + timestamp: 46584634, + height: 115, + reward: '0', + previousBlock: '2000919467344312301', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294', + blockSignature: + '304402202fa24bd38c39d4884fee63b739b1650358804a1fc703290133c5cc6b6269c39f0220105daf68cb3745f788c01cbd9d3e365e8ed9168e73974d168ae4968689ccd813', + createdAt: '2018-09-11T17:10:34.422Z', + }, + { + id: '9164793200684835761', + version: 0, + timestamp: 46584642, + height: 116, + reward: '0', + previousBlock: '17040727982508304752', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f', + blockSignature: + '3045022100e5b85d062e3fb760fb05e45ae32f8bdca3cf44541f3b2609011e99a5dd39595d022069af2fd27969ff7ade169d59e2384e10d59f316c3660beb7417e83bf5544e2be', + createdAt: '2018-09-11T17:10:42.265Z', + }, + { + id: '9702240278422456718', + version: 0, + timestamp: 46584650, + height: 117, + reward: '0', + previousBlock: '9164793200684835761', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1', + blockSignature: + '3045022100e3aec30648fb8443d1330d8934c116b7e063885e7ce4589b3a9a356b9788efd9022050f042f95dd7462bf6a01cf1c08193903f08c6fd0ba3b8b109a5f94ca2f044ee', + createdAt: '2018-09-11T17:10:50.387Z', + }, + { + id: '2372729513640015242', + version: 0, + timestamp: 46584658, + height: 118, + reward: '0', + previousBlock: '9702240278422456718', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689', + blockSignature: + '3045022100ecb8acd0440f7e7f4b4220c4e3e6a70d61c4e04d05a87642767f466facb6250302207707505aaa1863ec12966b183b421688e5d5195b51b21b2979246796b249b5b0', + createdAt: '2018-09-11T17:10:58.441Z', + }, + { + id: '3675127542764096771', + version: 0, + timestamp: 46584666, + height: 119, + reward: '0', + previousBlock: '2372729513640015242', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564', + blockSignature: + '30440220406326a74f91b99f9a3979de11e29ebd39df74e20d0dc5bcd666a9720b9121af02207103c201be49d9b93bdf286679fbc852410df35d3e1242b53d4115645f107914', + createdAt: '2018-09-11T17:11:06.309Z', + }, + { + id: '5358667162203289341', + version: 0, + timestamp: 46584674, + height: 120, + reward: '0', + previousBlock: '3675127542764096771', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd', + blockSignature: + '3045022100f1aa88f80f0ca725337174df11b6c38d1019c6920154c7884fcc2d853f7c2b6f02206ff94a9cfc11455e8a1d277ea3f705505fbaded49b3a53a297b062b4eeda670e', + createdAt: '2018-09-11T17:11:14.247Z', + }, + { + id: '18004288728431909564', + version: 0, + timestamp: 46584682, + height: 121, + reward: '0', + previousBlock: '5358667162203289341', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565', + blockSignature: + '304402200f52bafe85aa27cceac9de07660146a417745b3764ef3d8edc5566efd2a2137602200d589d6af456297a6c1e0af569f60c7c87bc33ca788fca0afc7aeaf5b937b42c', + createdAt: '2018-09-11T17:11:22.473Z', + }, + { + id: '6595564574956816872', + version: 0, + timestamp: 46584690, + height: 122, + reward: '0', + previousBlock: '18004288728431909564', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e', + blockSignature: + '3045022100eaf2e2a97742659b160ff43d5fecd82f8de7ce8e498d6692189a45225484e47a022011749a641345e689a26905037abe4cb19bd5cc1ead4b1d962a5df139f26c2d7c', + createdAt: '2018-09-11T17:11:30.413Z', + }, + { + id: '10066431236273363611', + version: 0, + timestamp: 46584698, + height: 123, + reward: '0', + previousBlock: '6595564574956816872', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964', + blockSignature: + '3044022027996c930ee580299cf4e506d913ee97ec3e33efe6a5311222a8e173cd8576b5022024601fd7cdbb0e0e6c34283a04dd66c11d4dd55518bf72f254d8bb5e0e808495', + createdAt: '2018-09-11T17:11:38.340Z', + }, + { + id: '4889016410282212954', + version: 0, + timestamp: 46584706, + height: 124, + reward: '0', + previousBlock: '10066431236273363611', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd', + blockSignature: + '3045022100cbb02b436b77d7d52e559b9e38e514188327fe6fd2a33285a6e46c0244b5adca02201cd4a6460a7fb29326625d68b31b6067de4739176066056fcd15339948c7847e', + createdAt: '2018-09-11T17:11:46.316Z', + }, + { + id: '1479697744155789665', + version: 0, + timestamp: 46584714, + height: 125, + reward: '0', + previousBlock: '4889016410282212954', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a', + blockSignature: + '3045022100caae762a80796c84e0d58e137b01494fe3520721b306917a3cfcd3bc6ddd19a5022026a294ad3d974a9b4e9eeae88967a79432ca559ca8f0273fd245469554e9de8e', + createdAt: '2018-09-11T17:11:54.512Z', + }, + { + id: '3211613713464451417', + version: 0, + timestamp: 46584722, + height: 126, + reward: '0', + previousBlock: '1479697744155789665', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d', + blockSignature: + '304402202d1b567d6c0141dfb2d7a55eadca8077be71337f351a4525f2ccf7a06314874a02204db6782f98f2827a7bad420a40b2a4bd00a7713e8f02a8b407d8f11bb32aee44', + createdAt: '2018-09-11T17:12:02.313Z', + }, + { + id: '14953374716924761457', + version: 0, + timestamp: 46584730, + height: 127, + reward: '0', + previousBlock: '3211613713464451417', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9', + blockSignature: + '3045022100efca475f4241c545a6e3f59547e0b4843999468ef803e940d00accc84886df5a022035536116d39f2ca3f0651cdc97b6304e66cef55c20dc07e5d3620fce85ece5fe', + createdAt: '2018-09-11T17:12:10.410Z', + }, + { + id: '3086909897235569982', + version: 0, + timestamp: 46584738, + height: 128, + reward: '0', + previousBlock: '14953374716924761457', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b', + blockSignature: + '3045022100a7d81f46a37cda7f99da390156371e7acdec498de689cc22395abef28285450f022001d1c2aabb1023b12074172d60c1c86deb7b324c3bf29e8c8c74a1597006c2d9', + createdAt: '2018-09-11T17:12:18.323Z', + }, + { + id: '11858031216720080832', + version: 0, + timestamp: 46584746, + height: 129, + reward: '0', + previousBlock: '3086909897235569982', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d', + blockSignature: + '3045022100a46abcfe70ca5e95daee7fc4120e75009501e15b7f63cac47e30aac256f2c4d102201c8c0b6e7f7f86459dfcde1fa58b7ee7503bace7a9d3681dfb169180b93c67d5', + createdAt: '2018-09-11T17:12:26.281Z', + }, + { + id: '10670801688829958309', + version: 0, + timestamp: 46584754, + height: 130, + reward: '0', + previousBlock: '11858031216720080832', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5', + blockSignature: + '3045022100d6c6fa51b3394aeac44552369cf4f26331435dc839c8ba7690ae551f55edf05102207bbbef4210e7b27c760957d2d72515e5561bb7478d1f6fba0ab5c616d5beb95c', + createdAt: '2018-09-11T17:12:34.345Z', + }, + { + id: '17447880863052605705', + version: 0, + timestamp: 46584762, + height: 131, + reward: '0', + previousBlock: '10670801688829958309', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80', + blockSignature: + '304402202df02cdcedadb9c34c5303ccb1ec572774a37d6649d869641499831c4455658e02200a92d9d63e6b8c3dfc6c97ca536cadb5d9100e0f834ba4bb252ecc1dda404b78', + createdAt: '2018-09-11T17:12:42.409Z', + }, + { + id: '14743301194148498313', + version: 0, + timestamp: 46584770, + height: 132, + reward: '0', + previousBlock: '17447880863052605705', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883', + blockSignature: + '3045022100f68768e22ec1b31f693ee723218cf382bd552903ea81d0ce5263582785039dab02201e89eb48a668b34c96d08f34ce84aa171aee87f860f4303b80c0bbeac2cdfe43', + createdAt: '2018-09-11T17:12:50.302Z', + }, + { + id: '16518342502287211733', + version: 0, + timestamp: 46584778, + height: 133, + reward: '0', + previousBlock: '14743301194148498313', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c', + blockSignature: + '3045022100f0732f4d73a509abe0fcf7ad950bed566a6387b51f77c3013647acd7058e5343022063ebff98016117241ddaa962eb17dd1ead55dd13323cb89bfbcd35294b5086a8', + createdAt: '2018-09-11T17:12:58.314Z', + }, + { + id: '3353127138299058636', + version: 0, + timestamp: 46584786, + height: 134, + reward: '0', + previousBlock: '16518342502287211733', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983', + blockSignature: + '3045022100fbe535970ab538c2e595c29d61e5efc288032bd663d4abf635c789b6a131632602207cca6065f02369324aad13744baedcd7a382243cff5d14beb66b72f58d43dd9a', + createdAt: '2018-09-11T17:13:06.404Z', + }, + { + id: '13175423574809505282', + version: 0, + timestamp: 46584794, + height: 135, + reward: '0', + previousBlock: '3353127138299058636', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904', + blockSignature: + '304402200896963614fba6bc8973e8c8be928c967e79c51f424ac42fc8ed7a77dc9211ec02205193a9cf0f0de3aa649d233c4fe23d33047beefdab31c73d28c3c906b17a3a10', + createdAt: '2018-09-11T17:13:14.314Z', + }, + { + id: '3055219214450264731', + version: 0, + timestamp: 46584802, + height: 136, + reward: '0', + previousBlock: '13175423574809505282', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a', + blockSignature: + '304402204f32800096d690cc2619fd971dce261c95c785647d8a577a231de9556dfb87ab0220227c64529eca59adbf5c744a13248b51bab87759543dfeb2bcd12cba79d5dec7', + createdAt: '2018-09-11T17:13:22.356Z', + }, + { + id: '2571351432366343511', + version: 0, + timestamp: 46584810, + height: 137, + reward: '0', + previousBlock: '3055219214450264731', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a', + blockSignature: + '304402200c238364bb210d0193429add99316ae42bdba0b5b8335480ea5c018ceae23b7802204fd755e41d4110a84837de79769c2cd95aefbe3dc3a8da18361119f01d176ea0', + createdAt: '2018-09-11T17:13:30.363Z', + }, + { + id: '6241265622100638768', + version: 0, + timestamp: 46584818, + height: 138, + reward: '0', + previousBlock: '2571351432366343511', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b', + blockSignature: + '3045022100b9fa19345ed45ac93c0eb6f6b939ec78b73eda64946da8a2f25c0618265df1ba0220147bca759e832db436f7240bde45938d1f43b65e8e11d46c0c7e4e499fd5153f', + createdAt: '2018-09-11T17:13:38.346Z', + }, + { + id: '18124529744536436230', + version: 0, + timestamp: 46584826, + height: 139, + reward: '0', + previousBlock: '6241265622100638768', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e', + blockSignature: + '3044022064c5588cc5cbed09662f7850cb610d940e8ebc54ae2607ea47f5a03c6d0b419b022040a2765191b7b2df155cf560d1841390e399919ac02b15782893c9c76bb79d40', + createdAt: '2018-09-11T17:13:46.397Z', + }, + { + id: '10444106797405289101', + version: 0, + timestamp: 46584834, + height: 140, + reward: '0', + previousBlock: '18124529744536436230', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17', + blockSignature: + '304402206a5e1d6d97dcf9ee1b6c37bfcd297f5e531a67890a36e3b73ba91861614ff4e00220637bfac65bc7c5156a06af632eab4dbeb76ba26a4cdb35d967d0e869138fd0fd', + createdAt: '2018-09-11T17:13:54.389Z', + }, + { + id: '9550675986057608428', + version: 0, + timestamp: 46584842, + height: 141, + reward: '0', + previousBlock: '10444106797405289101', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374', + blockSignature: + '3045022100cf7c530e0df3a6d78f5329e21c2c54febd6a6e040260df5c2f740dbc7bf497b8022021f498737f154a979ce29812e58bab3e04abc3e18296f75ee3c56dfa8e5de574', + createdAt: '2018-09-11T17:14:02.315Z', + }, + { + id: '14001735896815839031', + version: 0, + timestamp: 46584850, + height: 142, + reward: '0', + previousBlock: '9550675986057608428', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c', + blockSignature: + '3045022100873e93f03cdaa3ca9cee3d93075af754a5599bb54652b5bde42600811bbff21202206a8d479d2c3a7ed95575034321621acdfd377fd805c7d265945dec6962e180f5', + createdAt: '2018-09-11T17:14:10.260Z', + }, + { + id: '10633857440088301351', + version: 0, + timestamp: 46584858, + height: 143, + reward: '0', + previousBlock: '14001735896815839031', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f', + blockSignature: + '3044022067a82ec75db9a587e6f8890baa93037b647c6093e42de0cdf6703a3198bee78f02201b1083c9bd74488d37bbec3ff3f1b3e9c684d4e0e1dd3fe60ee2547d228eed3c', + createdAt: '2018-09-11T17:14:18.337Z', + }, + { + id: '10947047468505212355', + version: 0, + timestamp: 46584866, + height: 144, + reward: '0', + previousBlock: '10633857440088301351', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24', + blockSignature: + '3043022055bf8dea517e636fa46f0826706996307b49d0935891e58eec9d363bdade8fbe021f433b6ea919156f75084b4a502185d3000e91d378aae8ffabfebed7a8c5ca0d', + createdAt: '2018-09-11T17:14:26.275Z', + }, + { + id: '7416108013584846374', + version: 0, + timestamp: 46584874, + height: 145, + reward: '0', + previousBlock: '10947047468505212355', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12', + blockSignature: + '304402207500b2890ff54361434c2abf11f5aa587bd528d78756f40cc072a4b5260ec817022066558ab1b5d969992880d64c9e4f0966775b373c33903c03eca61220ff64d1fb', + createdAt: '2018-09-11T17:14:34.388Z', + }, + { + id: '4808775828130615656', + version: 0, + timestamp: 46584882, + height: 146, + reward: '0', + previousBlock: '7416108013584846374', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', + blockSignature: + '3044022039efce2d80b670403fbb0f3a2011cff6e207178cc4f46cb0c6267f89528586f102205a6658c235e31de7781be8d248f12568699f17c72408946aa0c7bde43ece1688', + createdAt: '2018-09-11T17:14:42.542Z', + }, + { + id: '6351137783535009353', + version: 0, + timestamp: 46584890, + height: 147, + reward: '0', + previousBlock: '4808775828130615656', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37', + blockSignature: + '3045022100996f089968b240a3e72321b1a7f6f32d210c28aebbcf3978842a9a5d7beddf2d02201ae019ab437bdfddb416c234ca4364eda1658cf31c4da9bf2ac5c2c9a4c1b5bb', + createdAt: '2018-09-11T17:14:50.391Z', + }, + { + id: '12627548292318554118', + version: 0, + timestamp: 46584898, + height: 148, + reward: '0', + previousBlock: '6351137783535009353', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647', + blockSignature: + '304502210085c920053b6aa11fdcfc54ac7d2b73799e9c0a5a5a853115ed4186d5b420d14f0220127e87b4911deddeaf4a88af43cc6a2ae41a36a3109ed9942c3c88940d052154', + createdAt: '2018-09-11T17:14:58.246Z', + }, + { + id: '2084097592015010038', + version: 0, + timestamp: 46584906, + height: 149, + reward: '0', + previousBlock: '12627548292318554118', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055', + blockSignature: + '3045022100d0fe7aa7bd1b5ec46fcf82eff1a23f632e2fd8658df8a2cfaabb4bbb89a5bc63022041a11d99c92dfcb51108888e3b1fd80b4d169b605f1f177758a8dc875567b3ae', + createdAt: '2018-09-11T17:15:06.428Z', + }, + { + id: '289908998694171445', + version: 0, + timestamp: 46584914, + height: 150, + reward: '0', + previousBlock: '2084097592015010038', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe', + blockSignature: + '304502210095e6c2904ea13151400e946d07c2d993be0c5f25f85e7325bd0607f952d3f450022034fd2236a2973559844ce3ac2dda58f0d0a17a3f8df6d46627a15809ec2c1ec3', + createdAt: '2018-09-11T17:15:14.427Z', + }, + { + id: '8005210879399134536', + version: 0, + timestamp: 46584922, + height: 151, + reward: '0', + previousBlock: '289908998694171445', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4', + blockSignature: + '3045022100a6adbabb46d2a78ff68ecd4249460e42a60c5194f85fefe3997300af70c36e460220654d30777cd3f362067d6be444c3fc6c28610f32cda43414ae27dd945b7cb6f2', + createdAt: '2018-09-11T17:15:22.323Z', + }, + { + id: '16154614440238332956', + version: 0, + timestamp: 46584930, + height: 152, + reward: '0', + previousBlock: '8005210879399134536', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc', + blockSignature: + '304402207087465aa8fcd2ead5bb853c57d09f1722c140ebe8bd6f8eba3018f95dea98070220617a9722465e67d9e7ecb52f7a124daf7fb7edb0dbe1a3d817c20bbbe5bc3cb6', + createdAt: '2018-09-11T17:15:30.312Z', + }, + { + id: '4655700423809570268', + version: 0, + timestamp: 46584938, + height: 153, + reward: '0', + previousBlock: '16154614440238332956', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a', + blockSignature: + '3045022100d7441a6c9193dde35da5240454733a724ec0eff34c820a5c0d34308ab798e3c902200de18c320188f0c0f1844b3ec0f2eb3ced452410ddc04913610a8bc33c12c14d', + createdAt: '2018-09-11T17:15:38.549Z', + }, + { + id: '1945298362228106487', + version: 0, + timestamp: 46584946, + height: 154, + reward: '0', + previousBlock: '4655700423809570268', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252', + blockSignature: + '304402200dffa8d365fdca32e75598ca5ee84750f2dd606e3dc20a1da18cbb84cf80262402206ce23e4fa379fe1c9bce8810ddbaf700d04a27bf5249e8ffe99323be9ecd9989', + createdAt: '2018-09-11T17:15:46.313Z', + }, + { + id: '8368457960814709674', + version: 0, + timestamp: 46584954, + height: 155, + reward: '0', + previousBlock: '1945298362228106487', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d', + blockSignature: + '3045022100b7e6c2c4797d307ea7e66a7bd6b0008bfe871ad77dc525e13b3bf0da9ebb06d6022052c11d46e8238f1979dee6d3e4b6ccb1ad3be7c38a59632d21bae58e045ebb0c', + createdAt: '2018-09-11T17:15:54.342Z', + }, +] diff --git a/packages/core-test-utils/fixtures/testnet/blocks.2-100.js b/packages/core-test-utils/fixtures/testnet/blocks.2-100.js new file mode 100644 index 0000000000..456dd8436c --- /dev/null +++ b/packages/core-test-utils/fixtures/testnet/blocks.2-100.js @@ -0,0 +1,1883 @@ +module.exports = [ + { + id: '17882607875259085966', + version: 0, + timestamp: 46583330, + height: 2, + reward: '0', + previousBlock: '17184958558311101492', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565', + blockSignature: + '3045022100e7385c6ea42bd950f7f6ab8c8619cf2f66a41d8f8f185b0bc99af032cb25f30d02200b6210176a6cedfdcbe483167fd91c21d740e0e4011d24d679c601fdd46b0de9', + createdAt: '2018-09-11T16:48:50.550Z', + }, + { + id: '7242383292164246617', + version: 0, + timestamp: 46583338, + height: 3, + reward: '0', + previousBlock: '17882607875259085966', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17', + blockSignature: + '304402204087bb1d2c82b9178b02b9b3f285de260cdf0778643064fe6c7aef27321d49520220594c57009c1fca543350126d277c6adeb674c00685a464c3e4bf0d634dc37e39', + createdAt: '2018-09-11T16:48:58.431Z', + }, + { + id: '6799129462450431489', + version: 0, + timestamp: 46583346, + height: 4, + reward: '0', + previousBlock: '7242383292164246617', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95', + blockSignature: + '304402201edab51a52d06b8c2e30fe334699239db1ff198172c11600b62fa063b7f74ef9022047649d94df2342707c1aeefc635260c6b3f642735588f4e04965c01db820df44', + createdAt: '2018-09-11T16:49:06.496Z', + }, + { + id: '12118504647305813914', + version: 0, + timestamp: 46583354, + height: 5, + reward: '0', + previousBlock: '6799129462450431489', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24', + blockSignature: + '3045022100e5a098f4a5b83c3550eeebfd65b04099b70f6cc1eb66a1f0e9cc8f516d6d229b02200610a07cd2fa908b7dbc19743f73f26623f7e9c36d46020bc1605653cb211bce', + createdAt: '2018-09-11T16:49:14.403Z', + }, + { + id: '15175173194595918016', + version: 0, + timestamp: 46583362, + height: 6, + reward: '0', + previousBlock: '12118504647305813914', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294', + blockSignature: + '304402201b82f934764e43f7ff45091e014ca3bd6c10d4300553818b63b6e80719625d6002207e4af15383c836835a5f61f79b8f50ff104cbd339bf92283107759a007c2a93f', + createdAt: '2018-09-11T16:49:22.314Z', + }, + { + id: '4904019637861251674', + version: 0, + timestamp: 46583370, + height: 7, + reward: '0', + previousBlock: '15175173194595918016', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883', + blockSignature: + '3044022056993f85cd7876109aa724f3c665323be14584c83457483c07ea36d6c7b75ebc02200c710bd09883471452fec45570bf6f5bbb06266feef3f8f2a9921cb4d8e13a37', + createdAt: '2018-09-11T16:49:30.295Z', + }, + { + id: '7856584295950436953', + version: 0, + timestamp: 46583378, + height: 8, + reward: '0', + previousBlock: '4904019637861251674', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e', + blockSignature: + '3045022100e45ec5b032e7762711c3727f30004fffe631605e9c323d1cd278b079714a9e30022002eea2c2c5234079e52326a69944c5f064f329ca163cbd6ef6a1272ec70f8524', + createdAt: '2018-09-11T16:49:38.366Z', + }, + { + id: '9519090140760236724', + version: 0, + timestamp: 46583386, + height: 9, + reward: '0', + previousBlock: '7856584295950436953', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', + blockSignature: + '304402200cc7bb74b97d8fcabf46f638ae3272143fdf6aa752df7ec5a3f850c976dfd2580220344cf0dea89111b7a455d95266b541753c40e7560d65af256d7bc3c97971e10a', + createdAt: '2018-09-11T16:49:46.409Z', + }, + { + id: '16953205951793869073', + version: 0, + timestamp: 46583394, + height: 10, + reward: '0', + previousBlock: '9519090140760236724', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d', + blockSignature: + '3045022100ba9cf471fad1103fa05c92038dd7f930edcfe526dfb4a68160ce068aa30e207802207b4ba0383953948c1fc7ec9125e8845cc3dd1df5f25727c9165e85c35c81d3c6', + createdAt: '2018-09-11T16:49:54.277Z', + }, + { + id: '8196750727867107014', + version: 0, + timestamp: 46583402, + height: 11, + reward: '0', + previousBlock: '16953205951793869073', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c', + blockSignature: + '304402200f93d59646c5e0bbc5b1d59bc9630bdee2669646c21d4ddf4db80c0b8afc1c0302200aaa36850b010ef9395f0a1f63652d236ef0265794953816e714a659f0a77283', + createdAt: '2018-09-11T16:50:02.246Z', + }, + { + id: '11789312660453212991', + version: 0, + timestamp: 46583410, + height: 12, + reward: '0', + previousBlock: '8196750727867107014', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd', + blockSignature: + '3045022100bac34bc173c7b473db162b72e2b3a14c51d6b1e9132530e759d6312a16241d6f022027328c6c69907bd67dcd23163fbbb5a5fff817d2beb62f67f1b61e2c202405db', + createdAt: '2018-09-11T16:50:10.268Z', + }, + { + id: '883541050685133383', + version: 0, + timestamp: 46583418, + height: 13, + reward: '0', + previousBlock: '11789312660453212991', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80', + blockSignature: + '30450221008574bfed61362c0a89a27e168d2ea83c9221e60e65d45471063d9ee295342dc502203d07ae5cdc6f04c6cb32e9569c3d57a2918a20ecb7b1e821075764518a269257', + createdAt: '2018-09-11T16:50:18.367Z', + }, + { + id: '2576147034160793253', + version: 0, + timestamp: 46583426, + height: 14, + reward: '0', + previousBlock: '883541050685133383', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37', + blockSignature: + '30440220125c9e17f524e4153853449c9f86961751f3225c1f3fbe4c0bb8eb3e66d9a3d802202d7cef058d1b3f5ce7ac7840d23aaefa595228ecff9aa30be41c6b809c5e7997', + createdAt: '2018-09-11T16:50:26.340Z', + }, + { + id: '15862421549550122994', + version: 0, + timestamp: 46583434, + height: 15, + reward: '0', + previousBlock: '2576147034160793253', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a', + blockSignature: + '30440220224f65b1190ab981691879b3d6861e11703b5fe78bceb36f5f51a8170228634b02203a8262131cd75cd2f6d56db8f5f5e370fcb635c84ca7a4b319d534a85476e543', + createdAt: '2018-09-11T16:50:34.426Z', + }, + { + id: '4688274543361472830', + version: 0, + timestamp: 46583442, + height: 16, + reward: '0', + previousBlock: '15862421549550122994', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a', + blockSignature: + '304402201a3aa0ebb176ff0ccc8c876142cada83cf8c12dc8a45de36eaf139c7d4d78e05022064b5f4b4da27a1e625236db9dcec89788fb417c88a928e193dcf816ad71117db', + createdAt: '2018-09-11T16:50:42.534Z', + }, + { + id: '5883773764321361785', + version: 0, + timestamp: 46583450, + height: 17, + reward: '0', + previousBlock: '4688274543361472830', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe', + blockSignature: + '3045022100f7ed8590c1c31e40b41d44c9321fb03d2864ef6f651ce518bec5a0eda5343bb302205bc757186589556a30d53abb9469c387011b49634494108b688d75bf63f07761', + createdAt: '2018-09-11T16:50:50.441Z', + }, + { + id: '7698647406843990550', + version: 0, + timestamp: 46583458, + height: 18, + reward: '0', + previousBlock: '5883773764321361785', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d', + blockSignature: + '304402201519d3e2c7d9221d8efcb532bccad9e5ac538751e7a43fb0bee7e736361483c802205b0e58959f9047c1a5de8af79d89a43828f85457653cbf732e164bdeef429c7b', + createdAt: '2018-09-11T16:50:58.430Z', + }, + { + id: '17299323387642470917', + version: 0, + timestamp: 46583466, + height: 19, + reward: '0', + previousBlock: '7698647406843990550', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28', + blockSignature: + '304402201bc616ef4dce8261b202df53a00555452d3dbe67be0a1959d06b269a189f0b7a02202d742310a55b693694f3f47ccd143629199ffe62ad0636d2fad52b8fad077249', + createdAt: '2018-09-11T16:51:06.342Z', + }, + { + id: '13814549369794209203', + version: 0, + timestamp: 46583474, + height: 20, + reward: '0', + previousBlock: '17299323387642470917', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983', + blockSignature: + '3045022100efc8192c34bcc4ac7bd74ea784a3a590eb9293e8923ff5cbb3eea74589c6a62d02206359a30fa492e1725655333b769ab6543fed69ba3ba6a5066a26cced31bf4192', + createdAt: '2018-09-11T16:51:14.337Z', + }, + { + id: '2277077266570141420', + version: 0, + timestamp: 46583482, + height: 21, + reward: '0', + previousBlock: '13814549369794209203', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f', + blockSignature: + '3044022054ad1575cc1ee09284f3f5252f80e1d48a59a9a3db740d8053784699824692ef022060ee4c78ea07e5612d86d74a70f6e1d5a94de5c2ed12a41111630caeee30b081', + createdAt: '2018-09-11T16:51:22.244Z', + }, + { + id: '5168238890100617525', + version: 0, + timestamp: 46583490, + height: 22, + reward: '0', + previousBlock: '2277077266570141420', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd', + blockSignature: + '30450221008ccfb6b5c8cbf8831c82f8a86afa88c2a27eb63d42c0cbd5eb9abe729fda314b02203df3fc50902656cce3bab7d5eb0a46d67be4eaab65fd41b1788b3676301cd005', + createdAt: '2018-09-11T16:51:30.339Z', + }, + { + id: '13736455109678252775', + version: 0, + timestamp: 46583498, + height: 23, + reward: '0', + previousBlock: '5168238890100617525', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb', + blockSignature: + '304402206ea489d925646a1253e78df0c9e761dbb58a173da5c34911301e262bc141127202201072cd4af50e72b5d34ad04708712b658d9ebb22fb00cc86132b0759fe04deba', + createdAt: '2018-09-11T16:51:38.469Z', + }, + { + id: '4282003522259720405', + version: 0, + timestamp: 46583506, + height: 24, + reward: '0', + previousBlock: '13736455109678252775', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c', + blockSignature: + '304402200593032068e5c67d38f4bd6cda8f4f64675f7b4d0bd07c77bf6c401c43c7e98e0220621eb05a51f1e7799af8fb45846fc75aa2e91246ba9db732976511a2bf0b8c0d', + createdAt: '2018-09-11T16:51:46.331Z', + }, + { + id: '11402948775542429021', + version: 0, + timestamp: 46583514, + height: 25, + reward: '0', + previousBlock: '4282003522259720405', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b', + blockSignature: + '3045022100e523b1c3ca604d62cf8bcf7e59b5eb22ad05ee1170619e07ac6bf90c204901bf0220214c72bd57067526672a57ca71147c4de05072311aa0962e1c9ae2e3ee89d413', + createdAt: '2018-09-11T16:51:54.309Z', + }, + { + id: '10423041071728627937', + version: 0, + timestamp: 46583522, + height: 26, + reward: '0', + previousBlock: '11402948775542429021', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a', + blockSignature: + '3045022100934248e71acba0b36fa40872ef2c36c8d807a23108f6d741d53422b48456e63b0220763a120b4eb8a25aa7a3bac5345cdccde50864a1fc6a9334a7c73ec4e548aded', + createdAt: '2018-09-11T16:52:02.508Z', + }, + { + id: '8610162720362054175', + version: 0, + timestamp: 46583530, + height: 27, + reward: '0', + previousBlock: '10423041071728627937', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1', + blockSignature: + '304402203fee457c035eb6df8abd0116a2726f8cf9a14758a5a7719589696cc338eee379022002722dd5064c308d1c875c99f7b6fe2376a7b987b6e4762ef669ff36d86a195c', + createdAt: '2018-09-11T16:52:10.336Z', + }, + { + id: '12492391117174185461', + version: 0, + timestamp: 46583706, + height: 28, + reward: '0', + previousBlock: '8610162720362054175', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc', + blockSignature: + '304502210085a248b96899c9443795857d3ce47f0ca7af2b97b9331e0e2a89ba715f98d79c022022e2839597e282d49ca9afbab66d417d754cc7acfb9e501a9db18506e5bfe1d4', + createdAt: '2018-09-11T16:55:06.505Z', + }, + { + id: '16807996944516641692', + version: 0, + timestamp: 46583714, + height: 29, + reward: '0', + previousBlock: '12492391117174185461', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2', + blockSignature: + '304402204d71ed66ddada97c2c38cac4650b5cd162b3fee65875e943ed41a253aa3d5ac4022013a00da3750cf1760208d78ae3cea524cc02c5909e806643b2907ee98ac2017a', + createdAt: '2018-09-11T16:55:14.296Z', + }, + { + id: '13831680932126032361', + version: 0, + timestamp: 46583722, + height: 30, + reward: '0', + previousBlock: '16807996944516641692', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689', + blockSignature: + '304402204e3aaa4af5776b85fe79120ddd37ebba8389cf18ef56df0b48d7ce6b3897e25b0220146ec521a9d32284eb2cfa9010b3379ba5a65020e25639ad644586ce272d99b8', + createdAt: '2018-09-11T16:55:22.414Z', + }, + { + id: '12836676775100447088', + version: 0, + timestamp: 46583730, + height: 31, + reward: '0', + previousBlock: '13831680932126032361', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751', + blockSignature: + '3044022058ffb2ceae3807c1beb244ba3f45c64f19f774de94b9f496b115da7eb0f877490220760d4d2f6048f7e694aa8cd5460a59fac64d671affec0cfddb2b4062ef3fe023', + createdAt: '2018-09-11T16:55:30.537Z', + }, + { + id: '16288754112931452950', + version: 0, + timestamp: 46583738, + height: 32, + reward: '0', + previousBlock: '12836676775100447088', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565', + blockSignature: + '3045022100c1ab5f864e444ae93537967f1ff485fe491496cef9404a1152d79cdf4244527102201246d40ba8e7038911403da19f6a685e6e0a86703697cc52c79d62d665bc4af0', + createdAt: '2018-09-11T16:55:38.270Z', + }, + { + id: '13854880431048519276', + version: 0, + timestamp: 46583746, + height: 33, + reward: '0', + previousBlock: '16288754112931452950', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17', + blockSignature: + '3045022100ca3177eba7928227e814ec37d9f0f4926add2020aa6b6de5f91e3121a64e4a60022067d2b87d4d7657de5c826985c494db50eb4b9a60ba30b722bf47a4bf708d3286', + createdAt: '2018-09-11T16:55:46.255Z', + }, + { + id: '13840357199384695281', + version: 0, + timestamp: 46583754, + height: 34, + reward: '0', + previousBlock: '13854880431048519276', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95', + blockSignature: + '304402205de0e8135717890ba90b31b60bc47b896dadbe5f9eb1b3eff084e0fb75afa8cf02200a1ddd0121786658972b495a3f812a4cf61afd99df7c10c93cd21ff74e1c361e', + createdAt: '2018-09-11T16:55:54.380Z', + }, + { + id: '11244772664213279648', + version: 0, + timestamp: 46583762, + height: 35, + reward: '0', + previousBlock: '13840357199384695281', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24', + blockSignature: + '3045022100e9d6a88ed3f96c5c33be6487159c3fdbdac0497f4958e7a6956332943482891c02202ecffc19b8d8cafe66c1e32a2e032d8f105ff9a4cd2ad46304b18fa168708d5e', + createdAt: '2018-09-11T16:56:02.434Z', + }, + { + id: '15443428733962171330', + version: 0, + timestamp: 46583770, + height: 36, + reward: '0', + previousBlock: '11244772664213279648', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294', + blockSignature: + '3044022070f7635302affb1ca9f515ddf14d0357e21846a5fd2094c4c27879b93a9c8b9702204e79875847238f560c932354a067167c74823da5a85eb45b7fbdb6a7265f33e1', + createdAt: '2018-09-11T16:56:10.294Z', + }, + { + id: '7454266686990589007', + version: 0, + timestamp: 46583778, + height: 37, + reward: '0', + previousBlock: '15443428733962171330', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883', + blockSignature: + '3044022057258edc364989cda08dc60c7059813db1fcf71004519691301226c08457a3b20220750dbad6b2734e2c66d53a39f9a90bf11d13e7f597440911c120b01803b17b7d', + createdAt: '2018-09-11T16:56:18.498Z', + }, + { + id: '4597925663050872611', + version: 0, + timestamp: 46583786, + height: 38, + reward: '0', + previousBlock: '7454266686990589007', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e', + blockSignature: + '304402202004341ca61b0580246d06c77f1099ea50e264d3bed1005568e0ededa850250b0220472ec5c11c57f6510ef95cd54dcd124e6272569907e2765ee9cf1b237a2dd612', + createdAt: '2018-09-11T16:56:26.323Z', + }, + { + id: '4238729528436398513', + version: 0, + timestamp: 46583794, + height: 39, + reward: '0', + previousBlock: '4597925663050872611', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', + blockSignature: + '3045022100abad03f7fb997fa8fed0830720e0cf1d0c84de4c9315adbc1440896b9b4d0ea302201e190b801e0945a6e7921d407d073a066f4e4b0eeba68cefc44135e08fb08dcc', + createdAt: '2018-09-11T16:56:34.513Z', + }, + { + id: '9197895153416047617', + version: 0, + timestamp: 46583802, + height: 40, + reward: '0', + previousBlock: '4238729528436398513', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d', + blockSignature: + '304402204a0d98b25ecf80f6bcc17474c62cbd1fa61988fb4aad4d7cd5e6eb9f3440446202206ec758d73ad3bc2fd612bb0d6dcc2b7b20f6dadf46afa968b32631aff013bb07', + createdAt: '2018-09-11T16:56:42.416Z', + }, + { + id: '924154762496380167', + version: 0, + timestamp: 46583816, + height: 41, + reward: '0', + previousBlock: '9197895153416047617', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd', + blockSignature: + '3045022100b81be618931cddee9ea14e40a96fa142c7954daf78b43924a9487f94eea71053022032de4cbc65040c40a859f2bd8abe82f6c2683607aac54bd7022129da178ed1c4', + createdAt: '2018-09-11T16:56:56.352Z', + }, + { + id: '15177934353618302368', + version: 0, + timestamp: 46583826, + height: 42, + reward: '0', + previousBlock: '924154762496380167', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80', + blockSignature: + '3045022100e461ebcdf96f5da7847d05de62a12503fee7fb3bcceb0dfdb142bc32c66dbab4022054a8f0b75d0ffdf46e167a44427bc5b931200f5fadbdd06d30002314434344aa', + createdAt: '2018-09-11T16:57:06.383Z', + }, + { + id: '924392217041273716', + version: 0, + timestamp: 46583834, + height: 43, + reward: '0', + previousBlock: '15177934353618302368', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37', + blockSignature: + '3045022100d978d3336898294151c583d7c2b8f4b578a9af41eba08ae399d02b16815c61da02204ce7f53790358a8bf48e9bbc9019de7e6f827fe0a7bf015fb7ded4579b3229b5', + createdAt: '2018-09-11T16:57:14.417Z', + }, + { + id: '16477448205939004004', + version: 0, + timestamp: 46583842, + height: 44, + reward: '0', + previousBlock: '924392217041273716', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a', + blockSignature: + '304402202d10704a95ce21dfb3e11956a29cf692e2d6220a5f7ad1521691e2e3cdd37c9b02205b670adf2e1c2961669f31f70d6dea35aa0cfa13ab04adf36ff80a4f47b60615', + createdAt: '2018-09-11T16:57:22.490Z', + }, + { + id: '12838684505709123370', + version: 0, + timestamp: 46583850, + height: 45, + reward: '0', + previousBlock: '16477448205939004004', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a', + blockSignature: + '3045022100f93f4b968f294e8bbe3d0cfe004a493749e9c8cb9dedc1f72a7bf7a351032e8002201b3564c0d996ec08d80069de99d88ac5d0db3cd6ea5f275ec4099b0e7ff7f88e', + createdAt: '2018-09-11T16:57:30.496Z', + }, + { + id: '5132859035237431345', + version: 0, + timestamp: 46583858, + height: 46, + reward: '0', + previousBlock: '12838684505709123370', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe', + blockSignature: + '3045022100cb32d6cb514ea08308a37a4c0fc9557d4b8380004a61a54cdda3ed8c143327ab022075578c0afa5ceb4c0ac3ca277efb1cede2d332168e7849b4c99e3ae63ee5da05', + createdAt: '2018-09-11T16:57:38.441Z', + }, + { + id: '7963682794246037175', + version: 0, + timestamp: 46583866, + height: 47, + reward: '0', + previousBlock: '5132859035237431345', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d', + blockSignature: + '304402200c65cac8594f02135f9c073e9786b8202f41b3fee67c32a50baf31d7cc90014e02207c4398cb34bcbbeeb25eef195e467a74bd3fa459a7e24e48aea3f8d7e56abe6b', + createdAt: '2018-09-11T16:57:46.440Z', + }, + { + id: '13070232553444551324', + version: 0, + timestamp: 46583874, + height: 48, + reward: '0', + previousBlock: '7963682794246037175', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28', + blockSignature: + '3045022100c7cd9708728c454006f1df0cb1de64c62a82e2df1d94b3fc2d8319fb78e7240d022066ce9e73f7039f949e412d19cb257c1ea818fb84d64d89d63409508ed802eacc', + createdAt: '2018-09-11T16:57:54.296Z', + }, + { + id: '625974805128499213', + version: 0, + timestamp: 46583882, + height: 49, + reward: '0', + previousBlock: '13070232553444551324', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983', + blockSignature: + '3045022100f12e139ee66c5936775bad938e1749117c8882e392c06596b1fc24959695a3c102203b708a0bcd11f51c7739ed22758a6e5235ea510756b285281f8e93a486609e04', + createdAt: '2018-09-11T17:01:38.244Z', + }, + { + id: '15904513475939308775', + version: 0, + timestamp: 46584112, + height: 50, + reward: '0', + previousBlock: '625974805128499213', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc', + blockSignature: + '304402202e0ae3e498efaf903740cedd72790f8d62aa7010ae5aa8e8382353a2d8577e940220714efec6305271e3c8b3f8076cf967ffd4167084bd9567a9f24300a8246bf197', + createdAt: '2018-09-11T17:01:52.512Z', + }, + { + id: '15510607002956264823', + version: 0, + timestamp: 46584122, + height: 51, + reward: '0', + previousBlock: '15904513475939308775', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2', + blockSignature: + '3044022078ec98d6895f1bc2a09623f060fd479bb4f75c37706d6c46c36209d84d54568402202c2a09000caafa25580e5b884fc973453574d80d7ee700517094e05f73f92d70', + createdAt: '2018-09-11T17:02:02.491Z', + }, + { + id: '17227544728161997595', + version: 0, + timestamp: 46584130, + height: 52, + reward: '0', + previousBlock: '15510607002956264823', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689', + blockSignature: + '30450221009a94f6cab02143fd03db3745d714dcafcddbfa28e440bc74a27fcef409d3069902207526c6626410f71224f89b7f7dd5136d92fd06aa0f95d714fd8ca62aa29867b1', + createdAt: '2018-09-11T17:02:10.367Z', + }, + { + id: '8285956439623855556', + version: 0, + timestamp: 46584138, + height: 53, + reward: '0', + previousBlock: '17227544728161997595', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb', + blockSignature: + '30450221008c8be43703dd3b513e2fab89ccbb307be40a2015c060b37f34252cb3c4463d82022071d817add1e17f5097850e905c9963bb87e56055fe69fa8e5f897f8e83dc98b7', + createdAt: '2018-09-11T17:02:18.360Z', + }, + { + id: '6896439417802463255', + version: 0, + timestamp: 46584146, + height: 54, + reward: '0', + previousBlock: '8285956439623855556', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294', + blockSignature: + '3044022041e2d1d9a3215a1cee4e6f24f2d0bf9ab8e9c8aad85306c01de38925b997d6da022004bceb2844ac828ce07d572238910be51fe5e9508f2c8a0c36719db5d954a0c7', + createdAt: '2018-09-11T17:02:26.339Z', + }, + { + id: '2902372601932188608', + version: 0, + timestamp: 46584154, + height: 55, + reward: '0', + previousBlock: '6896439417802463255', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d', + blockSignature: + '3045022100eaf1cd0c296484c50fa507fd8f375891b1acc6c0434cee6f93ce45f40a181ad60220460c1fce332bdf297c4675a806899187cd6c86337d9e2b03ed972c3fe7009b74', + createdAt: '2018-09-11T17:02:34.363Z', + }, + { + id: '10825219670382518509', + version: 0, + timestamp: 46584162, + height: 56, + reward: '0', + previousBlock: '2902372601932188608', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12', + blockSignature: + '304502210087bb4b53db33adb4de3f21412882f30e6e5391466d23a2f6940b2a4493d9123702201d581122e703af1552c3750d4c6a4cff0d82b16647e4edadd0c4e1dfc52291fc', + createdAt: '2018-09-11T17:02:42.403Z', + }, + { + id: '8203927523221479932', + version: 0, + timestamp: 46584170, + height: 57, + reward: '0', + previousBlock: '10825219670382518509', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd', + blockSignature: + '304402203be65a7c74ca18ac8661a447ab209fce85f76d8c87a30db642342d9c41d138a602201667db0713ad5977cd6b42a045707c19147d28dc9c86ef5e6f974ab68c1d3e28', + createdAt: '2018-09-11T17:02:50.411Z', + }, + { + id: '16715427056889121751', + version: 0, + timestamp: 46584178, + height: 58, + reward: '0', + previousBlock: '8203927523221479932', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4', + blockSignature: + '3045022100b35dec76883908f5a91be19b2d31bc55b0486cb9f9350ecd5d565a7614a2df0702203219fb7439379cd1ff82377d8dcfdc6bda6bda99d2cc4c2050925c064f71aba0', + createdAt: '2018-09-11T17:02:58.302Z', + }, + { + id: '16305880676178938140', + version: 0, + timestamp: 46584186, + height: 59, + reward: '0', + previousBlock: '16715427056889121751', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c', + blockSignature: + '3045022100e5896815ae064ca2244dcce1fbc3651527f0d7a8e09bad13fb37a8d5001bf1f302207b3d1b61dee0ff0c9c435a794b65d66d9bdaf982ac20c5eff1f718fbf95351d6', + createdAt: '2018-09-11T17:03:06.354Z', + }, + { + id: '7799778404770723520', + version: 0, + timestamp: 46584194, + height: 60, + reward: '0', + previousBlock: '16305880676178938140', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e', + blockSignature: + '30440220375cd7cde93652b17926414f4ec24dbd4bac9e8ec961d242d475aa1edf0e74240220341048d58153b1055daf632ede7d2fcc9b57a5fafbc9d60495c25f9e7f68f752', + createdAt: '2018-09-11T17:03:14.404Z', + }, + { + id: '5758761688279180444', + version: 0, + timestamp: 46584202, + height: 61, + reward: '0', + previousBlock: '7799778404770723520', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', + blockSignature: + '30450221009c87a22235797fcfa108f318de14ec99d6491545f6161280bab17e225ad381860220682d3a0a367c77915768b8ef7524379644c283cf2297b34d619c03d8d361d2ff', + createdAt: '2018-09-11T17:03:22.394Z', + }, + { + id: '300976438207115612', + version: 0, + timestamp: 46584210, + height: 62, + reward: '0', + previousBlock: '5758761688279180444', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a', + blockSignature: + '3045022100de8fc5c21168063ffae3a319c94de8029d02b4fbec0e6128c2ec8c7b18ade08402201250ffc4ef5ba71f3b8f0d8e9b935c39779066b313f57051d3e51f013831f6ca', + createdAt: '2018-09-11T17:03:30.381Z', + }, + { + id: '2019154568349929038', + version: 0, + timestamp: 46584218, + height: 63, + reward: '0', + previousBlock: '300976438207115612', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e', + blockSignature: + '304402206d927629fde40bc224ba6c044d3b5966193ccc578998dd42cbf2c526871d55c302201f83ed237a60531f7bb02ce26085069839d42f3dafd4b6581095000d01ecefa8', + createdAt: '2018-09-11T17:03:38.403Z', + }, + { + id: '10330603764729699281', + version: 0, + timestamp: 46584226, + height: 64, + reward: '0', + previousBlock: '2019154568349929038', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a', + blockSignature: + '3045022100e7194d853550abc79c507b2f6338c9013d528e0fb031ca345f5c1cbdd153c82302205b556d61d9a91399f6e7128657dbd279ec715bca0d0912ca0cc9ad87da0753a9', + createdAt: '2018-09-11T17:03:46.516Z', + }, + { + id: '16855224566886101894', + version: 0, + timestamp: 46584234, + height: 65, + reward: '0', + previousBlock: '10330603764729699281', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a', + blockSignature: + '304402204ece7e930f42e06e457da426fc59a0dedf29c04d76126e94167b50225c179850022010104fe54b125e341f888656d997ece2092e5bf599877d3a7d295d4ea5e4faf5', + createdAt: '2018-09-11T17:03:54.345Z', + }, + { + id: '3100095040675947327', + version: 0, + timestamp: 46584242, + height: 66, + reward: '0', + previousBlock: '16855224566886101894', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93', + blockSignature: + '3045022100e5623db11c1e683ea406c8f0688fa569481b126a3422c3c3f13e4b5dbafa021f0220172d01bbb12544d17877b99a3548efaffc8fa6692fe4f5b0e8e11bf57ebbc345', + createdAt: '2018-09-11T17:04:02.407Z', + }, + { + id: '9113535137970315837', + version: 0, + timestamp: 46584250, + height: 67, + reward: '0', + previousBlock: '3100095040675947327', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e', + blockSignature: + '3045022100a1110d53b5b0750bc0e4631df4c77d6cb4c7e31bfeb9d3a296b02ea6a5749671022008fe9533a58542903619deeda2a84c9c4542bd837c5920eeb959cee668be0c7e', + createdAt: '2018-09-11T17:04:10.390Z', + }, + { + id: '13522109433438488118', + version: 0, + timestamp: 46584258, + height: 68, + reward: '0', + previousBlock: '9113535137970315837', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0', + blockSignature: + '3045022100a39ab29adf9c2606d634766b2094ff8c069aa0f3fed8e3379554ff083f1e6183022056addd110d11f7d053e14741c67bb0fc573ddc3ded85589b422768a50cede4c0', + createdAt: '2018-09-11T17:04:18.376Z', + }, + { + id: '4836027030925388062', + version: 0, + timestamp: 46584266, + height: 69, + reward: '0', + previousBlock: '13522109433438488118', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751', + blockSignature: + '304402206286621e85e27d2f0c79b7a85da3da5465b0b8737cf506155b702fcbf542ee51022013e5a747e4b34c28dfefe2cb2ed47dc81dc15c04cc9d1aeab8590af4ed6ee3a9', + createdAt: '2018-09-11T17:04:26.540Z', + }, + { + id: '1124208886475980765', + version: 0, + timestamp: 46584274, + height: 70, + reward: '0', + previousBlock: '4836027030925388062', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1', + blockSignature: + '304402204095cf9589d899c6cc10ec0b391a5d3d1a3c94247e91680a6ecdf8c69c2e8519022062386adfd6bd42d825cd903a91882d98bf7dcce7c6d9f5d9a6172c95e9f1b870', + createdAt: '2018-09-11T17:04:34.421Z', + }, + { + id: '2300021073741981330', + version: 0, + timestamp: 46584282, + height: 71, + reward: '0', + previousBlock: '1124208886475980765', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5', + blockSignature: + '3045022100b02997cd91021d9a06dd77079aabb04e01de890176e6544e724e9563552082dc022053adc616e133e010aab3aa138548aa36e554decb899374a6c60c36d8d92525a4', + createdAt: '2018-09-11T17:04:42.337Z', + }, + { + id: '1435082221279493221', + version: 0, + timestamp: 46584290, + height: 72, + reward: '0', + previousBlock: '2300021073741981330', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd', + blockSignature: + '3045022100d3badcd7c113fd44d3ae22b502e45f1e9d15bbf7b5fc8a81aff765cf326199320220126e625a1b021f640cb79e3ea833c733e88d0eafe6c8947f7639f205431eefa8', + createdAt: '2018-09-11T17:04:50.375Z', + }, + { + id: '5781105193399022760', + version: 0, + timestamp: 46584298, + height: 73, + reward: '0', + previousBlock: '1435082221279493221', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37', + blockSignature: + '304402200fd5424d5304c669c1a8455a92490f1aab3005ad435ba4efda443b28ef6fe34902200c38c4b23213b42022ba551cdf6b26b8e29a4239ab88fd939e72f2f096821ea7', + createdAt: '2018-09-11T17:04:58.343Z', + }, + { + id: '7306295778722296358', + version: 0, + timestamp: 46584306, + height: 74, + reward: '0', + previousBlock: '5781105193399022760', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883', + blockSignature: + '304402202d794978935d04f48f1bbca967242b764d0ad19529dbf72fd8f08a14e300e39202205d960169ae3c18f983c2034cf387bd6bbd7cf4c30043179fd8da05c3dfa25e21', + createdAt: '2018-09-11T17:05:06.468Z', + }, + { + id: '11621508727770821942', + version: 0, + timestamp: 46584314, + height: 75, + reward: '0', + previousBlock: '7306295778722296358', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95', + blockSignature: + '3045022100c8395b5aa7a8f70cc5f8af5571efa3ac61906f0ca38ecd929ba1b7ba80ba3ab80220212acf9dd8b793f5b06e6e58a4a9791d37f28f431af88bd7cc53867e453de8e7', + createdAt: '2018-09-11T17:05:14.510Z', + }, + { + id: '3633426813146358866', + version: 0, + timestamp: 46584322, + height: 76, + reward: '0', + previousBlock: '11621508727770821942', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252', + blockSignature: + '304402200430ed30340bdf3dadc437db984547a7159f2fe716b7f607ce793353be2ceefc02201995468fe1cf73e0257f6db115f6de6bef1bee3de01222dd55fcfc243bc96fd4', + createdAt: '2018-09-11T17:05:22.467Z', + }, + { + id: '10585574832161348147', + version: 0, + timestamp: 46584330, + height: 77, + reward: '0', + previousBlock: '3633426813146358866', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b', + blockSignature: + '3045022100a69a370fcf30a8e80b36916fe17c4404c63ff8f5f0f654d662656db662be95a4022061dece06170f0e59a63abb078c5809488b6a3548470a699434fd769eb3e2ae66', + createdAt: '2018-09-11T17:05:30.462Z', + }, + { + id: '16732819090621444724', + version: 0, + timestamp: 46584338, + height: 78, + reward: '0', + previousBlock: '10585574832161348147', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c', + blockSignature: + '30450221008e6bdd7ea4189ea751e02157ab0449651a70405e560b68efb489f36b90b3c20702203d5764e527965e8f0fffa192bd3ccc4fa10649674e9c52cc361accf0d0c53541', + createdAt: '2018-09-11T17:05:38.369Z', + }, + { + id: '13535887590163426042', + version: 0, + timestamp: 46584346, + height: 79, + reward: '0', + previousBlock: '16732819090621444724', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055', + blockSignature: + '3044022052171485017323ec5ee011d4fa110a9e9137b2043ee6d0ec5f6da56bbf713f1102203744e54783bf400353b0221b2454b09ebdbddebe30a3d1c62fd7a1fc4cd5dd7f', + createdAt: '2018-09-11T17:05:46.419Z', + }, + { + id: '7447301067999335250', + version: 0, + timestamp: 46584354, + height: 80, + reward: '0', + previousBlock: '13535887590163426042', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a', + blockSignature: + '3045022100c729ce8b683f619368f91e782009b2319babacdc5ddc6d51fcaaaf76042c09e90220278ff4db42f02241a05bd26e2ad6c1ba71f0396a4c7c66b015756854dc9119e0', + createdAt: '2018-09-11T17:05:54.345Z', + }, + { + id: '9843400248178032761', + version: 0, + timestamp: 46584362, + height: 81, + reward: '0', + previousBlock: '7447301067999335250', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80', + blockSignature: + '3045022100858015fd991a4c318801217c8051572d2f0ac2657ce9676d612f3bdc4ed9a46a0220523af034dd7b11c31843615ec670675782e2e1549a260ada819ae9c453481da7', + createdAt: '2018-09-11T17:06:02.454Z', + }, + { + id: '14466873879302081211', + version: 0, + timestamp: 46584370, + height: 82, + reward: '0', + previousBlock: '9843400248178032761', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d', + blockSignature: + '30440220532e47a63b905269436a28b24c12da027f822ecbeddfb02f10ae9f6f7d05eba60220468a4e4f91c7b613292a937c4e7297590e0e2c66f1cffef628041f77c82b8e92', + createdAt: '2018-09-11T17:06:10.415Z', + }, + { + id: '14557757316112343772', + version: 0, + timestamp: 46584378, + height: 83, + reward: '0', + previousBlock: '14466873879302081211', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d', + blockSignature: + '30440220332a364f25ef135fbf1b6329778e8a0f0484d900b98e2ea883a5d9381a39e50b02204b4b0fb1d2f6aac5f2b61204782f20335d99e71a854fb0b17a5799dd862dbeca', + createdAt: '2018-09-11T17:06:18.358Z', + }, + { + id: '15094374440231126484', + version: 0, + timestamp: 46584386, + height: 84, + reward: '0', + previousBlock: '14557757316112343772', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24', + blockSignature: + '304402207fb74f4b2665307dced45c14025b1583c95d718841c4a320f60b67f749731bb302206716b2733bec550c86db5669ece70790ccbc225dcd2745c8007772b39bd5b9e9', + createdAt: '2018-09-11T17:06:26.235Z', + }, + { + id: '5714424774144793592', + version: 0, + timestamp: 46584394, + height: 85, + reward: '0', + previousBlock: '15094374440231126484', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b', + blockSignature: + '3045022100988030c41476d2e52b6e303e0a3ac6b9c56fe10d33f9dd8396d1c911e14eb2b702200997ac462d60095fd1e157a13986da7b4dd079796806865d63b7278763ae6fbc', + createdAt: '2018-09-11T17:06:34.371Z', + }, + { + id: '464843749694128591', + version: 0, + timestamp: 46584402, + height: 86, + reward: '0', + previousBlock: '5714424774144793592', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565', + blockSignature: + '3045022100e47ede694b10ed629f7da387151154c80f3a8fd434fdc3ca1bfdbf509bc8830e02201f834cf3a0167e33ec1aec83cacb3294046dc93e1a7a847bf043ece5583fd13e', + createdAt: '2018-09-11T17:06:42.321Z', + }, + { + id: '1723867044168113856', + version: 0, + timestamp: 46584410, + height: 87, + reward: '0', + previousBlock: '464843749694128591', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe', + blockSignature: + '3045022100c2b565bf8049d85b8ea0354efb0d94bc620aab6dfb973b09cad100195e6d511802200b7e9fd6a3173eeeeb8d0fa39e646ee099d141601aaf52df6241e11d759f02fb', + createdAt: '2018-09-11T17:06:50.473Z', + }, + { + id: '7628284931710202890', + version: 0, + timestamp: 46584418, + height: 88, + reward: '0', + previousBlock: '1723867044168113856', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a', + blockSignature: + '3044022003d908ed5e60f42501ad80303275096c21c5a41c5f2405511dac6d9e441d7d010220297dfc8f90a868827fc224e4df4fdf53c5c39a8cfaf63b7b904af69882b08475', + createdAt: '2018-09-11T17:06:58.368Z', + }, + { + id: '3531996231287449620', + version: 0, + timestamp: 46584426, + height: 89, + reward: '0', + previousBlock: '7628284931710202890', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564', + blockSignature: + '3045022100c52c316937e914f5adfb68efa31fa4edec3fa742009d59b2b2e02593f8f7728a02203d17f18f07f67d7ca23044b98552030ac547c4b741648ef8bdeee043ae0b34cd', + createdAt: '2018-09-11T17:07:06.264Z', + }, + { + id: '7435167259407493217', + version: 0, + timestamp: 46584434, + height: 90, + reward: '0', + previousBlock: '3531996231287449620', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28', + blockSignature: + '304402204b65ae72b90172be9b257300ddef0342c6817823c006bdb38b257d0b0ef1db8d0220429eaa801b85b63c858ace7f0440ff43c51157141282bca446133cca96159dff', + createdAt: '2018-09-11T17:07:14.284Z', + }, + { + id: '5656841191275027942', + version: 0, + timestamp: 46584442, + height: 91, + reward: '0', + previousBlock: '7435167259407493217', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647', + blockSignature: + '3045022100f500a0d127dd995bf238ebf15450155fa4be6ba59ebda61e2699282dff81c88702205d44d5e6dee2715239b11865bdc2d1482536f5600ce8a4ea5229f04781322045', + createdAt: '2018-09-11T17:07:22.266Z', + }, + { + id: '6646555502142403115', + version: 0, + timestamp: 46584450, + height: 92, + reward: '0', + previousBlock: '5656841191275027942', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f', + blockSignature: + '304402202b22d9186ba9b9c7fc020ca4425d3fa93a8e937683396b84fd22d1085bdb586d02201e7d474fa56e1af239d9e5e5dcb1dd53500194ee58602792bb1e6bd312777a87', + createdAt: '2018-09-11T17:07:30.377Z', + }, + { + id: '8618021774665230437', + version: 0, + timestamp: 46584458, + height: 93, + reward: '0', + previousBlock: '6646555502142403115', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904', + blockSignature: + '3045022100d0daa10ce4872a19b6b4bb3b3d1ed5d41221102e4aa362dfd277b59bb86e560702207316be26ab1213b808ac439dae5d1708290b2d76fba92d55ccd6afeb1523f91b', + createdAt: '2018-09-11T17:07:38.423Z', + }, + { + id: '6558209391920917685', + version: 0, + timestamp: 46584466, + height: 94, + reward: '0', + previousBlock: '8618021774665230437', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964', + blockSignature: + '304402205e134c3b7e2f3766e9c6d021f06e3ab537c589d27694c877aea302900c0a20e3022015813d2f698cce19a4f6d86eb2499a70f5266156f5fde9fc0edc7a8df696ec59', + createdAt: '2018-09-11T17:07:46.451Z', + }, + { + id: '18098650501718304452', + version: 0, + timestamp: 46584474, + height: 95, + reward: '0', + previousBlock: '6558209391920917685', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17', + blockSignature: + '3045022100d890951e03cd628ad22fea648c4e190099a730d66190b59aaa0990f77a0e6db2022075c11de03bb0e0010a51cdaca740636f54a8e74078821a7b30ec8e3ba86f89cb', + createdAt: '2018-09-11T17:07:54.409Z', + }, + { + id: '3612743398896107056', + version: 0, + timestamp: 46584482, + height: 96, + reward: '0', + previousBlock: '18098650501718304452', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca', + blockSignature: + '304402206de9d9ece51e025039379235e3e39ec01f9b1951b9d435c898a11fcc0e31fca10220572172f3d678ffa04f13c8c3857c315e404d3e6e7cb073406713cdf7369a20aa', + createdAt: '2018-09-11T17:08:02.374Z', + }, + { + id: '3590346281108682583', + version: 0, + timestamp: 46584490, + height: 97, + reward: '0', + previousBlock: '3612743398896107056', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc', + blockSignature: + '3045022100ab8b12df4b19fa8a93544fbf452dc68d6804ea6ab8e88edfa58d6d939af109f4022003554d5524d26c12a11f3328dca2045a8c562d90f26f9d28f7647bdabc928936', + createdAt: '2018-09-11T17:08:10.443Z', + }, + { + id: '5940078448948565481', + version: 0, + timestamp: 46584498, + height: 98, + reward: '0', + previousBlock: '3590346281108682583', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9', + blockSignature: + '30450221008f89c040a9f9eefa7e0eda2866318336d14b39ead910e4ddd697312fcbde9f22022040e86e88a39ae0546d240b1000d0962fa5ed9b7da65e13ae06bfa078abb435b6', + createdAt: '2018-09-11T17:08:18.326Z', + }, + { + id: '2958406944863963956', + version: 0, + timestamp: 46584506, + height: 99, + reward: '0', + previousBlock: '5940078448948565481', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374', + blockSignature: + '3044022046573056dca01fc73b635e3e33592c8c180bb0ee676414b11aeb0deac20250d302203ee93fb91ebb50d22314b059cff09c2fc367557b9b0f51fd494e9f0495abe3f3', + createdAt: '2018-09-11T17:08:26.381Z', + }, + { + id: '6161515163793239359', + version: 0, + timestamp: 46584514, + height: 100, + reward: '0', + previousBlock: '2958406944863963956', + numberOfTransactions: 0, + totalAmount: '0', + totalFee: '0', + payloadLength: 0, + payloadHash: + 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + generatorPublicKey: + '02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983', + blockSignature: + '3045022100e32d06b7e3d4ae078cb2cb7093e2502a71732173099cb2881d91b5c4e49459d3022063df0dc42d2c3cd2854cd68881662be767b192c34ad7d4e1a50c00f34750d248', + createdAt: '2018-09-11T17:08:34.469Z', + }, +] diff --git a/packages/core-test-utils/fixtures/testnet/delegates.js b/packages/core-test-utils/fixtures/testnet/delegates.js new file mode 100644 index 0000000000..bdc0fd6ec7 --- /dev/null +++ b/packages/core-test-utils/fixtures/testnet/delegates.js @@ -0,0 +1,28 @@ +const { client, crypto } = require('@arkecosystem/crypto') + +/** + * Get the testnet genesis delegates information + * @return {Array} array of objects like { secret, publicKey, address, balance } + */ + +client.getConfigManager().setFromPreset('ark', 'testnet') + +const delegatesConfig = require('../../config/testnet/delegates.json') +const genesisTransactions = require('../../config/testnet/genesisBlock.json') + .transactions + +module.exports = delegatesConfig.secrets.map(secret => { + const publicKey = crypto.getKeys(secret).publicKey + const address = crypto.getAddress(publicKey) + const balance = genesisTransactions.find( + transaction => + transaction.recipientId === address && transaction.type === 0, + ).amount + return { + secret, + passphrase: secret, // just an alias for delegate secret + publicKey, + address, + balance, + } +}) diff --git a/packages/core-test-utils/fixtures/testnet/passphrases.js b/packages/core-test-utils/fixtures/testnet/passphrases.js new file mode 100644 index 0000000000..e639a9f670 --- /dev/null +++ b/packages/core-test-utils/fixtures/testnet/passphrases.js @@ -0,0 +1 @@ +module.exports = require('../../config/testnet/delegates.json').secrets diff --git a/packages/core-test-utils/jest.config.js b/packages/core-test-utils/jest.config.js index 26f7a25796..57770a97bb 100644 --- a/packages/core-test-utils/jest.config.js +++ b/packages/core-test-utils/jest.config.js @@ -1,22 +1,12 @@ -'use strict' - module.exports = { testEnvironment: 'node', bail: false, verbose: true, - testMatch: [ - '**/__tests__/**/*.test.js' - ], - moduleFileExtensions: [ - 'js', - 'json' - ], + testMatch: ['**/__tests__/**/*.test.js'], + moduleFileExtensions: ['js', 'json'], collectCoverage: false, coverageDirectory: '/.coverage', - collectCoverageFrom: [ - 'lib/**/*.js', - '!**/node_modules/**' - ], + collectCoverageFrom: ['lib/**/*.js', '!**/node_modules/**'], watchman: false, - setupTestFrameworkScriptFile: 'jest-extended' + setupTestFrameworkScriptFile: 'jest-extended', } diff --git a/packages/core-test-utils/lib/generators/transactions.js b/packages/core-test-utils/lib/generators/transactions.js deleted file mode 100644 index 37d5f4daf0..0000000000 --- a/packages/core-test-utils/lib/generators/transactions.js +++ /dev/null @@ -1,53 +0,0 @@ -const ark = require('arkjs') -const assert = require('assert') -const { client, crypto } = require('@arkecosystem/crypto') -const { TRANSACTION_TYPES } = require('@arkecosystem/crypto').constants -const config = require('../../config') -const superheroes = require('superheroes') - -module.exports = (network, type, testWallet, testAddress, amount = 2, quantity = 10) => { - network = network || 'testnet' - type = type || TRANSACTION_TYPES.TRANSFER - amount = amount * Math.pow(10, 8) - - assert.ok(['mainnet', 'devnet', 'testnet'].includes(network), 'Invalid network') - assert.ok([ - TRANSACTION_TYPES.TRANSFER, - TRANSACTION_TYPES.SECOND_SIGNATURE, - TRANSACTION_TYPES.DELEGATE_REGISTRATION, - TRANSACTION_TYPES.VOTE - ].includes(type), 'Invalid transaction type') - - client.getConfigManager().setFromPreset('ark', network) - ark.crypto.setNetworkVersion(client.getConfigManager().config.pubKeyHash) - - const transactions = [] - for (let i = 0; i < quantity; i++) { - const passphrase = testWallet ? testWallet.passphrase : config.passphrase - const address = testAddress || crypto.getAddress(crypto.getKeys(passphrase).publicKey) - - let transaction - if (type === TRANSACTION_TYPES.TRANSFER) { - transaction = ark.transaction.createTransaction( - address, - amount, - `Test Transaction ${i + 1}`, - passphrase - ) - } else if (type === TRANSACTION_TYPES.SECOND_SIGNATURE) { - transaction = ark.signature.createSignature(passphrase, passphrase) - } else if (type === TRANSACTION_TYPES.DELEGATE_REGISTRATION) { - const username = superheroes.random().toLowerCase().replace(/[^a-z0-9]/g, '_') - transaction = ark.delegate.createDelegate(passphrase, username) - } else if (type === TRANSACTION_TYPES.VOTE) { - const publicKey = crypto.getKeys(config.passphrase).publicKey - transaction = ark.vote.createVote(passphrase, [publicKey]) - } else { - break - } - - transactions.push(transaction) - } - - return transactions -} diff --git a/packages/core-test-utils/lib/generators/transactions/delegate.js b/packages/core-test-utils/lib/generators/transactions/delegate.js index 1b2cf6898b..6422903e97 100644 --- a/packages/core-test-utils/lib/generators/transactions/delegate.js +++ b/packages/core-test-utils/lib/generators/transactions/delegate.js @@ -1,13 +1,14 @@ -const generateTransactions = require('../transactions') +const generateTransactions = require('./transaction') const { TRANSACTION_TYPES } = require('../../../../crypto/lib/constants') -module.exports = (network, testWallet, quantity = 10) => { - return generateTransactions( +module.exports = (network, passphrase, quantity = 10, getStruct = false, fee) => + generateTransactions( network, TRANSACTION_TYPES.DELEGATE_REGISTRATION, - testWallet, + passphrase, undefined, undefined, - quantity + quantity, + getStruct, + fee, ) -} diff --git a/packages/core-test-utils/lib/generators/transactions/index.js b/packages/core-test-utils/lib/generators/transactions/index.js index 423ae7364a..ae4b4ced1b 100644 --- a/packages/core-test-utils/lib/generators/transactions/index.js +++ b/packages/core-test-utils/lib/generators/transactions/index.js @@ -2,5 +2,5 @@ module.exports = { transfer: require('./transfer'), delegate: require('./delegate'), signature: require('./signature'), - vote: require('./vote') + vote: require('./vote'), } diff --git a/packages/core-test-utils/lib/generators/transactions/signature.js b/packages/core-test-utils/lib/generators/transactions/signature.js index a8c2290e19..6909b81dc0 100644 --- a/packages/core-test-utils/lib/generators/transactions/signature.js +++ b/packages/core-test-utils/lib/generators/transactions/signature.js @@ -1,13 +1,14 @@ -const generateTransactions = require('../transactions') +const generateTransactions = require('./transaction') const { TRANSACTION_TYPES } = require('../../../../crypto/lib/constants') -module.exports = (network, testWallet, quantity = 10) => { - return generateTransactions( +module.exports = (network, passphrase, quantity = 10, getStruct = false, fee) => + generateTransactions( network, TRANSACTION_TYPES.SECOND_SIGNATURE, - testWallet, + passphrase, undefined, undefined, - quantity + quantity, + getStruct, + fee, ) -} diff --git a/packages/core-test-utils/lib/generators/transactions/transaction.js b/packages/core-test-utils/lib/generators/transactions/transaction.js new file mode 100644 index 0000000000..488ab1aac3 --- /dev/null +++ b/packages/core-test-utils/lib/generators/transactions/transaction.js @@ -0,0 +1,100 @@ +const superheroes = require('superheroes') +const { client, crypto } = require('@arkecosystem/crypto') +const { + TRANSFER, + SECOND_SIGNATURE, + DELEGATE_REGISTRATION, + VOTE, +} = require('@arkecosystem/crypto').constants.TRANSACTION_TYPES +const defaultPassphrase = require('../../../fixtures/testnet/passphrases')[0] + +module.exports = ( + network, + type, + passphrase, + addressOrPublicKey, + amount = 2, + quantity = 10, + getStruct = false, + fee, +) => { + network = network || 'testnet' + type = type || TRANSFER + passphrase = passphrase || defaultPassphrase + + if (!['mainnet', 'devnet', 'testnet'].includes(network)) { + throw new Error('Invalid network') + } + + if ( + ![TRANSFER, SECOND_SIGNATURE, DELEGATE_REGISTRATION, VOTE].includes(type) + ) { + throw new Error('Invalid transaction type') + } + + let secondPassphrase + if (Array.isArray(passphrase)) { + secondPassphrase = passphrase[1] + passphrase = passphrase[0] + } + + client.getConfigManager().setFromPreset('ark', network) + + const transactions = [] + for (let i = 0; i < quantity; i++) { + let builder = client.getBuilder() + switch (type) { + case TRANSFER: { + if (!addressOrPublicKey) { + addressOrPublicKey = crypto.getAddress( + crypto.getKeys(passphrase).publicKey, + ) + } + builder = builder + .transfer() + .recipientId(addressOrPublicKey) + .amount(amount) + .vendorField(`Test Transaction ${i + 1}`) + break + } + case SECOND_SIGNATURE: { + builder = builder.secondSignature().signatureAsset(passphrase) + break + } + case DELEGATE_REGISTRATION: { + const username = superheroes + .random() + .toLowerCase() + .replace(/[^a-z0-9]/g, '_') + .substring(0, 20) + builder = builder.delegateRegistration().usernameAsset(username) + break + } + case VOTE: { + if (!addressOrPublicKey) { + addressOrPublicKey = crypto.getKeys(passphrase).publicKey + } + builder = builder.vote().votesAsset([`+${addressOrPublicKey}`]) + break + } + default: { + throw new Error('Invalid transaction type') + } + } + + if (fee) { + builder = builder.fee(fee) + } + + builder = builder.sign(passphrase) + + if (secondPassphrase) { + builder = builder.secondSign(secondPassphrase) + } + const transaction = getStruct ? builder.getStruct() : builder.build() + + transactions.push(transaction) + } + + return transactions +} diff --git a/packages/core-test-utils/lib/generators/transactions/transfer.js b/packages/core-test-utils/lib/generators/transactions/transfer.js index 258004573e..2eeb9c82d4 100644 --- a/packages/core-test-utils/lib/generators/transactions/transfer.js +++ b/packages/core-test-utils/lib/generators/transactions/transfer.js @@ -1,13 +1,22 @@ -const generateTransactions = require('../transactions') +const generateTransactions = require('./transaction') const { TRANSACTION_TYPES } = require('../../../../crypto/lib/constants') -module.exports = (network, testWallet, testAddress, amount = 2, quantity = 10) => { - return generateTransactions( +module.exports = ( + network, + passphrase, + address, + amount = 2, + quantity = 10, + getStruct = false, + fee, +) => + generateTransactions( network, TRANSACTION_TYPES.TRANSFER, - testWallet, - testAddress, + passphrase, + address, amount, - quantity + quantity, + getStruct, + fee, ) -} diff --git a/packages/core-test-utils/lib/generators/transactions/vote.js b/packages/core-test-utils/lib/generators/transactions/vote.js index bf6bf91faa..754f7e1c90 100644 --- a/packages/core-test-utils/lib/generators/transactions/vote.js +++ b/packages/core-test-utils/lib/generators/transactions/vote.js @@ -1,13 +1,21 @@ -const generateTransactions = require('../transactions') +const generateTransactions = require('./transaction') const { TRANSACTION_TYPES } = require('../../../../crypto/lib/constants') -module.exports = (network, testWallet, quantity = 10) => { - return generateTransactions( +module.exports = ( + network, + passphrase, + publicKey, + quantity = 10, + getStruct = false, + fee, +) => + generateTransactions( network, TRANSACTION_TYPES.VOTE, - testWallet, + passphrase, + publicKey, undefined, - undefined, - quantity + quantity, + getStruct, + fee, ) -} diff --git a/packages/core-test-utils/lib/generators/wallets.js b/packages/core-test-utils/lib/generators/wallets.js index c114a21bfb..d01b1c2f3b 100644 --- a/packages/core-test-utils/lib/generators/wallets.js +++ b/packages/core-test-utils/lib/generators/wallets.js @@ -1,20 +1,21 @@ -const assert = require('assert') const bip39 = require('bip39') const { client, crypto } = require('@arkecosystem/crypto') module.exports = (network, quantity = 10) => { - network = network || 'devnet' - assert.true(['mainnet', 'devnet'].includes(network), 'Invalid network') + network = network || 'testnet' + if (!['testnet', 'mainnet', 'devnet'].includes(network)) { + throw new Error('Invalid network') + } client.getConfigManager().setFromPreset('ark', network) - let wallets = {} - + const wallets = [] for (let i = 0; i < quantity; i++) { - const passphrase = bip39.generateMnemonic() - const address = crypto.getAddress(crypto.getKeys(passphrase).publicKey) + const passphrase = bip39.generateMnemonic() + const publicKey = crypto.getKeys(passphrase).publicKey + const address = crypto.getAddress(publicKey) - wallets[address] = passphrase + wallets.push({ address, passphrase, publicKey }) } return wallets diff --git a/packages/core-test-utils/lib/helpers/api.js b/packages/core-test-utils/lib/helpers/api.js new file mode 100644 index 0000000000..7afa616b39 --- /dev/null +++ b/packages/core-test-utils/lib/helpers/api.js @@ -0,0 +1,57 @@ +class ApiHelpers { + async request(server, method, url, headers, params = {}) { + // Build URL params from _params_ object for GET / DELETE requests + const getParams = Object.entries(params) + .map(([key, val]) => `${key}=${val}`) + .join('&') + + // Injecting the request into Hapi server instead of using axios + const injectOptions = { + method, + url: ['GET', 'DELETE'].includes(method) ? `${url}?${getParams}` : url, + headers, + payload: ['GET', 'DELETE'].includes(method) ? {} : params, + } + + const response = await server.inject(injectOptions) + const data = typeof response.result === 'string' + ? JSON.parse(response.result) + : response.result + Object.assign(response, { data, status: response.statusCode }) + return response + } + + expectJson(response) { + expect(response.data).toBeObject() + } + + expectStatus(response, code) { + expect(response.status).toBe(code) + } + + expectResource(response) { + expect(response.data.data).toBeObject() + } + + expectCollection(response) { + expect(Array.isArray(response.data.data)).toBe(true) + } + + expectSuccessful(response, statusCode = 200) { + this.expectStatus(response, statusCode) + this.expectJson(response) + } + + expectError(response, statusCode = 404) { + this.expectStatus(response, statusCode) + this.expectJson(response) + expect(response.data.statusCode).toBeNumber() + expect(response.data.error).toBeString() + expect(response.data.message).toBeString() + } +} + +/** + * @type {Helpers} + */ +module.exports = new ApiHelpers() diff --git a/packages/core-test-utils/lib/helpers/blockchain.js b/packages/core-test-utils/lib/helpers/blockchain.js new file mode 100644 index 0000000000..a07b748da0 --- /dev/null +++ b/packages/core-test-utils/lib/helpers/blockchain.js @@ -0,0 +1,18 @@ +module.exports = { + resetBlockchain: async () => { + // Resets everything so that it can be used in beforeAll to start clean a test suite + // Now resets: blocks (remove blocks other than genesis), transaction pool + // TODO: reset rounds, transactions in db... + const app = require('@arkecosystem/core-container') + + // reset to block height 1 + const blockchain = app.resolvePlugin('blockchain') + const height = blockchain.getLastBlock().data.height + if (height) { + await blockchain.removeBlocks(height - 1) + } + + const transactionPool = app.resolvePlugin('transactionPool') + transactionPool.flush() + }, +} diff --git a/packages/core-test-utils/lib/helpers/container.js b/packages/core-test-utils/lib/helpers/container.js new file mode 100644 index 0000000000..e373f6c005 --- /dev/null +++ b/packages/core-test-utils/lib/helpers/container.js @@ -0,0 +1,18 @@ +const path = require('path') +const app = require('@arkecosystem/core-container') + +module.exports = { + setUp: async options => + app.setUp( + '2.0.0', + { + data: options.data || '~/.ark', + config: options.config + ? options.config + : path.resolve(__dirname, '../../config/testnet'), + token: options.token || 'ark', + network: options.network || 'testnet', + }, + options, + ), +} diff --git a/packages/core-test-utils/lib/index.js b/packages/core-test-utils/lib/index.js deleted file mode 100644 index 0bf335cefd..0000000000 --- a/packages/core-test-utils/lib/index.js +++ /dev/null @@ -1,17 +0,0 @@ -const { red } = require('chalk') -const matchers = require('./matchers') - -const jestExpect = global.expect - -if (jestExpect !== undefined) { - jestExpect.extend(matchers) -} else { - /* eslint-disable no-console */ - console.error(red('Unable to find Jest\'s global expect.')) - /* eslint-enable no-console */ -} - -module.exports = { - generateTransactions: require('./generators/transactions'), - generateWallets: require('./generators/wallets') -} diff --git a/packages/core-test-utils/lib/matchers/api/block.js b/packages/core-test-utils/lib/matchers/api/block.js new file mode 100644 index 0000000000..84a667aba2 --- /dev/null +++ b/packages/core-test-utils/lib/matchers/api/block.js @@ -0,0 +1,53 @@ +const isEqual = require('lodash/isEqual') +const sortBy = require('lodash/sortBy') + +function isValidBlock(block) { + const allowedKeys = sortBy([ + 'blockSignature', + 'createdAt', + 'generatorPublicKey', + 'height', + 'id', + 'numberOfTransactions', + 'payloadHash', + 'payloadLength', + 'previousBlock', + 'reward', + 'timestamp', + 'totalAmount', + 'totalFee', + 'transactions', + 'updatedAt', + 'version', + ]) + const actualKeys = Object.keys(block).filter(key => allowedKeys.includes(key)) + + return isEqual(sortBy(actualKeys), allowedKeys) +} + +const toBeValidBlock = (actual, expected) => ({ + message: () => `Expected ${JSON.stringify(actual)} to be a valid block`, + pass: isValidBlock(actual), +}) + +const toBeValidArrayOfBlocks = (actual, expected) => { + const message = () => + `Expected ${JSON.stringify(actual)} to be a valid array of blocks` + + if (!Array.isArray(actual)) { + return { message, pass: false } + } + + actual.forEach(peer => { + if (!isValidBlock(peer)) { + return { message, pass: false } + } + }) + + return { message, pass: true } +} + +expect.extend({ + toBeValidBlock, + toBeValidArrayOfBlocks, +}) diff --git a/packages/core-test-utils/lib/matchers/api/peer.js b/packages/core-test-utils/lib/matchers/api/peer.js new file mode 100644 index 0000000000..1f3ba6a26c --- /dev/null +++ b/packages/core-test-utils/lib/matchers/api/peer.js @@ -0,0 +1,36 @@ +const isEqual = require('lodash/isEqual') +const sortBy = require('lodash/sortBy') + +function isValidPeer(peer) { + const allowedKeys = sortBy(['ip', 'port']) + const actualKeys = Object.keys(peer).filter(key => allowedKeys.includes(key)) + + return isEqual(sortBy(actualKeys), allowedKeys) +} + +const toBeValidPeer = (actual, expected) => ({ + message: () => `Expected ${JSON.stringify(actual)} to be a valid peer`, + pass: isValidPeer(actual), +}) + +const toBeValidArrayOfPeers = (actual, expected) => { + const message = () => + `Expected ${JSON.stringify(actual)} to be a valid array of peers` + + if (!Array.isArray(actual)) { + return { message, pass: false } + } + + actual.forEach(peer => { + if (!isValidPeer(peer)) { + return { message, pass: false } + } + }) + + return { message, pass: true } +} + +expect.extend({ + toBeValidPeer, + toBeValidArrayOfPeers, +}) diff --git a/packages/core-test-utils/lib/matchers/api/response.js b/packages/core-test-utils/lib/matchers/api/response.js new file mode 100644 index 0000000000..d74d52f0a9 --- /dev/null +++ b/packages/core-test-utils/lib/matchers/api/response.js @@ -0,0 +1,32 @@ +const toBeSuccessfulResponse = (actual, expected) => ({ + message: () => `Expected ${JSON.stringify({ + data: actual.data, + status: actual.status, + headers: actual.headers, + })} to be a successful response`, + pass: actual.status === 200 && typeof actual.data === 'object', +}) + +const toBePaginated = (actual, expected) => ({ + message: () => `Expected ${JSON.stringify({ + data: actual.data, + status: actual.status, + headers: actual.headers, + })} to be a paginated response`, + pass: + actual.data.meta + && [ + 'pageCount', + 'totalCount', + 'next', + 'previous', + 'self', + 'first', + 'last', + ].every(property => Object.keys(actual.data.meta).includes(property)), +}) + +expect.extend({ + toBeSuccessfulResponse, + toBePaginated, +}) diff --git a/packages/core-test-utils/lib/matchers/api/transaction.js b/packages/core-test-utils/lib/matchers/api/transaction.js index e0cb4b62fa..14a300ada3 100644 --- a/packages/core-test-utils/lib/matchers/api/transaction.js +++ b/packages/core-test-utils/lib/matchers/api/transaction.js @@ -1,14 +1,32 @@ -'use strict' +const isEqual = require('lodash/isEqual') +const sortBy = require('lodash/sortBy') -const { isEqual, sortBy } = require('lodash') - -module.exports = (actual, expected) => { +const toBeApiTransaction = (actual, expected) => { // TODO based on type - const allowedKeys = sortBy(['id', 'blockid', 'type', 'timestamp', 'amount', 'fee', 'senderId', 'senderPublicKey', 'signature', 'asset', 'confirmations']) - const actualKeys = Object.keys(actual).filter(key => allowedKeys.includes(key)) + const allowedKeys = sortBy([ + 'id', + 'blockid', + 'type', + 'timestamp', + 'amount', + 'fee', + 'senderId', + 'senderPublicKey', + 'signature', + 'asset', + 'confirmations', + ]) + const actualKeys = Object.keys(actual).filter(key => + allowedKeys.includes(key), + ) return { - message: () => `Expected ${JSON.stringify(actual)} to be a valid transaction`, - pass: isEqual(sortBy(actualKeys), allowedKeys) + message: () => + `Expected ${JSON.stringify(actual)} to be a valid transaction`, + pass: isEqual(sortBy(actualKeys), allowedKeys), } } + +expect.extend({ + toBeApiTransaction, +}) diff --git a/packages/core-test-utils/lib/matchers/blockchain/dispatch.js b/packages/core-test-utils/lib/matchers/blockchain/dispatch.js index f9918670d7..b90735d508 100644 --- a/packages/core-test-utils/lib/matchers/blockchain/dispatch.js +++ b/packages/core-test-utils/lib/matchers/blockchain/dispatch.js @@ -1,6 +1,4 @@ -'use strict' - -module.exports = (received, dispatcher, arg) => { +const toDispatch = (received, dispatcher, arg) => { const mock = jest.fn() dispatcher.dispatch = mock @@ -13,6 +11,10 @@ module.exports = (received, dispatcher, arg) => { // FIXME isNot is necessary to write the right message // @see https://facebook.github.io/jest/docs/en/expect.html#expectextendmatchers message: () => `Expected "${arg}" to ${this.isNot ? 'not' : ''} be dispatched`, - pass + pass, } } + +expect.extend({ + toDispatch, +}) diff --git a/packages/core-test-utils/lib/matchers/blockchain/execute-on-entry.js b/packages/core-test-utils/lib/matchers/blockchain/execute-on-entry.js index c7a962ca02..229b73e70d 100644 --- a/packages/core-test-utils/lib/matchers/blockchain/execute-on-entry.js +++ b/packages/core-test-utils/lib/matchers/blockchain/execute-on-entry.js @@ -1,15 +1,14 @@ -'use strict' - const { isEqual, get } = require('lodash') -module.exports = (machine, transition) => { +const toExecuteOnEntry = (machine, transition) => { let path = transition.state - // For nested states, but only works 1 level depth + // For nested states, but only works 1 level deep if (transition.state.indexOf('.') !== -1) { const slugs = path.split('.') path = `${slugs[0]}.states.${slugs[1]}` } + const state = get(machine.states, path) const actions = transition.actions.map(action => `"${action}"`).join(', ') @@ -17,7 +16,13 @@ module.exports = (machine, transition) => { return { // FIXME isNot is necessary to write the right message // @see https://facebook.github.io/jest/docs/en/expect.html#expectextendmatchers - message: () => `Expected machine to ${this.isNot ? 'not ' : ''}call actions ${actions} on state "${transition.state}"`, - pass: isEqual(state.onEntry, transition.actions) + message: () => `Expected machine to ${ + this.isNot ? 'not ' : '' + } call actions ${actions} on state "${transition.state}"`, + pass: isEqual(state.onEntry.map(action => action.type), transition.actions), } } + +expect.extend({ + toExecuteOnEntry, +}) diff --git a/packages/core-test-utils/lib/matchers/blockchain/transition.js b/packages/core-test-utils/lib/matchers/blockchain/transition.js index a068fa64cd..42838566cd 100644 --- a/packages/core-test-utils/lib/matchers/blockchain/transition.js +++ b/packages/core-test-utils/lib/matchers/blockchain/transition.js @@ -1,14 +1,18 @@ -'use strict' - const { matchesState } = require('xstate') -module.exports = (machine, transition) => { +const toTransition = (machine, transition) => { const state = machine.transition(transition.from, transition.on) return { // FIXME isNot is necessary to write the right message // @see https://facebook.github.io/jest/docs/en/expect.html#expectextendmatchers - message: () => `Expected machine to ${this.isNot ? 'not' : ''} transition to "${transition.to}" from "${transition.from}" on "${transition.on}"`, - pass: matchesState(transition.to, state.value) + message: () => `Expected machine to ${this.isNot ? 'not' : ''} transition to "${ + transition.to + }" from "${transition.from}" on "${transition.on}"`, + pass: matchesState(transition.to, state.value), } } + +expect.extend({ + toTransition, +}) diff --git a/packages/core-test-utils/lib/matchers/fields/address.js b/packages/core-test-utils/lib/matchers/fields/address.js index c97db09213..3d10fdf6ef 100644 --- a/packages/core-test-utils/lib/matchers/fields/address.js +++ b/packages/core-test-utils/lib/matchers/fields/address.js @@ -1,5 +1,3 @@ -'use strict' - const { crypto } = require('@arkecosystem/crypto') /** @@ -8,9 +6,11 @@ const { crypto } = require('@arkecosystem/crypto') * @param {String} argument * @return {Boolean} */ -module.exports = (received, argument) => { - return { - message: () => 'Expected value to be a valid address', - pass: crypto.validateAddress(received, argument) - } -} +const toBeArkAddress = (received, argument) => ({ + message: () => 'Expected value to be a valid address', + pass: crypto.validateAddress(received, argument), +}) + +expect.extend({ + toBeArkAddress, +}) diff --git a/packages/core-test-utils/lib/matchers/fields/public-key.js b/packages/core-test-utils/lib/matchers/fields/public-key.js index f61c0c2544..4429791035 100644 --- a/packages/core-test-utils/lib/matchers/fields/public-key.js +++ b/packages/core-test-utils/lib/matchers/fields/public-key.js @@ -1,10 +1,10 @@ -'use strict' - const { crypto } = require('@arkecosystem/crypto') -module.exports = (received) => { - return { - message: () => 'Expected value to be a valid public key', - pass: crypto.validatePublicKey(received) - } -} +const toBeArkPublicKey = received => ({ + message: () => 'Expected value to be a valid public key', + pass: crypto.validatePublicKey(received), +}) + +expect.extend({ + toBeArkPublicKey, +}) diff --git a/packages/core-test-utils/lib/matchers/index.js b/packages/core-test-utils/lib/matchers/index.js index 149a4e948d..a5187e10f3 100644 --- a/packages/core-test-utils/lib/matchers/index.js +++ b/packages/core-test-utils/lib/matchers/index.js @@ -1,27 +1,26 @@ -module.exports = { - toBeArkAddress: require('./fields/address'), - toBeArkPublicKey: require('./fields/public-key'), +// TODO put together similar matchers (for example all 'types' matchers) +// so that we can require() a collection of coherent matchers - toBeApiTransaction: require('./api/transaction'), - - toBeDelegate: require('./models/delegate'), - toBeTransaction: require('./models/transaction'), - toBeWallet: require('./models/wallet'), - - toBeValidTransaction: require('./transactions/valid'), - toHaveValidSecondSignature: require('./transactions/valid-second-signature'), - - toBeDelegateResignationType: require('./transactions/types/delegate-resignation'), - toBeDelegateType: require('./transactions/types/delegate'), - toBeIpfsType: require('./transactions/types/ipfs'), - toBeMultiPaymentType: require('./transactions/types/multi-payment'), - toBeMultiSignatureType: require('./transactions/types/multi-signature'), - toBeSecondSignatureType: require('./transactions/types/second-signature'), - toBeTimelockTransferType: require('./transactions/types/timelock-transfer'), - toBeTransferType: require('./transactions/types/transfer'), - toBeVoteType: require('./transactions/types/vote'), - - toDispatch: require('./blockchain/dispatch'), - toExecuteOnEntry: require('./blockchain/execute-on-entry'), - toTransition: require('./blockchain/transition') -} +require('./fields/address') +require('./fields/public-key') +require('./api/transaction') +require('./api/response') +require('./api/peer') +require('./api/block') +require('./models/delegate') +require('./models/transaction') +require('./models/wallet') +require('./transactions/valid') +require('./transactions/valid-second-signature') +require('./transactions/types/delegate-resignation') +require('./transactions/types/delegate') +require('./transactions/types/ipfs') +require('./transactions/types/multi-payment') +require('./transactions/types/multi-signature') +require('./transactions/types/second-signature') +require('./transactions/types/timelock-transfer') +require('./transactions/types/transfer') +require('./transactions/types/vote') +require('./blockchain/dispatch') +require('./blockchain/execute-on-entry') +require('./blockchain/transition') diff --git a/packages/core-test-utils/lib/matchers/models/delegate.js b/packages/core-test-utils/lib/matchers/models/delegate.js index d505268b23..c1cf6d0212 100644 --- a/packages/core-test-utils/lib/matchers/models/delegate.js +++ b/packages/core-test-utils/lib/matchers/models/delegate.js @@ -1,10 +1,15 @@ -'use strict' +const isEqual = require('lodash/isEqual') +const sortBy = require('lodash/sortBy') -const { isEqual, sortBy } = require('lodash') +const toBeDelegate = actual => ({ + message: () => 'Expected value to be a valid delegate', + pass: isEqual(sortBy(Object.keys(actual)), [ + 'address', + 'publicKey', + 'username', + ]), +}) -module.exports = (actual) => { - return { - message: () => 'Expected value to be a valid delegate', - pass: isEqual(sortBy(Object.keys(actual)), ['address', 'publicKey', 'username']) - } -} +expect.extend({ + toBeDelegate, +}) diff --git a/packages/core-test-utils/lib/matchers/models/transaction.js b/packages/core-test-utils/lib/matchers/models/transaction.js index 63edba13da..62ff70141e 100644 --- a/packages/core-test-utils/lib/matchers/models/transaction.js +++ b/packages/core-test-utils/lib/matchers/models/transaction.js @@ -1,14 +1,26 @@ -'use strict' +const isEqual = require('lodash/isEqual') +const sortBy = require('lodash/sortBy') -const { isEqual, sortBy } = require('lodash') - -module.exports = (actual) => { +const toBeTransaction = actual => { // TODO based on type - const allowedKeys = sortBy(['id', 'type', 'amount', 'fee', 'timestamp', 'signature']) - const actualKeys = Object.keys(actual).filter(key => allowedKeys.includes(key)) + const allowedKeys = sortBy([ + 'id', + 'type', + 'amount', + 'fee', + 'timestamp', + 'signature', + ]) + const actualKeys = Object.keys(actual).filter(key => + allowedKeys.includes(key), + ) return { message: () => 'Expected value to be a valid transaction', - pass: isEqual(sortBy(actualKeys), allowedKeys) + pass: isEqual(sortBy(actualKeys), allowedKeys), } } + +expect.extend({ + toBeTransaction, +}) diff --git a/packages/core-test-utils/lib/matchers/models/wallet.js b/packages/core-test-utils/lib/matchers/models/wallet.js index 4026497b7e..855249fdc2 100644 --- a/packages/core-test-utils/lib/matchers/models/wallet.js +++ b/packages/core-test-utils/lib/matchers/models/wallet.js @@ -1,10 +1,11 @@ -'use strict' +const isEqual = require('lodash/isEqual') +const sortBy = require('lodash/sortBy') -const { isEqual, sortBy } = require('lodash') +const toBeWallet = actual => ({ + message: () => 'Expected value to be a valid wallet', + pass: isEqual(sortBy(Object.keys(actual)), ['address', 'publicKey']), +}) -module.exports = (actual) => { - return { - message: () => 'Expected value to be a valid wallet', - pass: isEqual(sortBy(Object.keys(actual)), ['address', 'publicKey']) - } -} +expect.extend({ + toBeWallet, +}) diff --git a/packages/core-test-utils/lib/matchers/transactions/types/delegate-resignation.js b/packages/core-test-utils/lib/matchers/transactions/types/delegate-resignation.js index 94c0b5a9f9..04de841350 100644 --- a/packages/core-test-utils/lib/matchers/transactions/types/delegate-resignation.js +++ b/packages/core-test-utils/lib/matchers/transactions/types/delegate-resignation.js @@ -1,10 +1,10 @@ -'use strict' - const { DELEGATE_RESIGNATION } = require('@arkecosystem/crypto').constants -module.exports = (received) => { - return { - message: () => 'Expected value to be a valid DELEGATE_RESIGNATION transaction.', - pass: received.type === DELEGATE_RESIGNATION - } -} +const toBeDelegateResignationType = received => ({ + message: () => 'Expected value to be a valid DELEGATE_RESIGNATION transaction.', + pass: received.type === DELEGATE_RESIGNATION, +}) + +expect.extend({ + toBeDelegateResignationType, +}) diff --git a/packages/core-test-utils/lib/matchers/transactions/types/delegate.js b/packages/core-test-utils/lib/matchers/transactions/types/delegate.js index 5dfde546f3..ba3032cb75 100644 --- a/packages/core-test-utils/lib/matchers/transactions/types/delegate.js +++ b/packages/core-test-utils/lib/matchers/transactions/types/delegate.js @@ -1,10 +1,10 @@ -'use strict' - const { DELEGATE } = require('@arkecosystem/crypto').constants -module.exports = (received) => { - return { - message: () => 'Expected value to be a valid DELEGATE transaction.', - pass: received.type === DELEGATE - } -} +const toBeDelegateType = received => ({ + message: () => 'Expected value to be a valid DELEGATE transaction.', + pass: received.type === DELEGATE, +}) + +expect.extend({ + toBeDelegateType, +}) diff --git a/packages/core-test-utils/lib/matchers/transactions/types/ipfs.js b/packages/core-test-utils/lib/matchers/transactions/types/ipfs.js index 68063aa7ec..613d83b4ef 100644 --- a/packages/core-test-utils/lib/matchers/transactions/types/ipfs.js +++ b/packages/core-test-utils/lib/matchers/transactions/types/ipfs.js @@ -1,10 +1,10 @@ -'use strict' - const { IPFS } = require('@arkecosystem/crypto').constants -module.exports = (received) => { - return { - message: () => 'Expected value to be a valid IPFS transaction.', - pass: received.type === IPFS - } -} +const toBeIpfsType = received => ({ + message: () => 'Expected value to be a valid IPFS transaction.', + pass: received.type === IPFS, +}) + +expect.extend({ + toBeIpfsType, +}) diff --git a/packages/core-test-utils/lib/matchers/transactions/types/multi-payment.js b/packages/core-test-utils/lib/matchers/transactions/types/multi-payment.js index df68055eca..ce6bf3fd68 100644 --- a/packages/core-test-utils/lib/matchers/transactions/types/multi-payment.js +++ b/packages/core-test-utils/lib/matchers/transactions/types/multi-payment.js @@ -1,10 +1,10 @@ -'use strict' - const { MULTI_PAYMENT } = require('@arkecosystem/crypto').constants -module.exports = (received) => { - return { - message: () => 'Expected value to be a valid MULTI_PAYMENT transaction.', - pass: received.type === MULTI_PAYMENT - } -} +const toBeMultiPaymentType = received => ({ + message: () => 'Expected value to be a valid MULTI_PAYMENT transaction.', + pass: received.type === MULTI_PAYMENT, +}) + +expect.extend({ + toBeMultiPaymentType, +}) diff --git a/packages/core-test-utils/lib/matchers/transactions/types/multi-signature.js b/packages/core-test-utils/lib/matchers/transactions/types/multi-signature.js index bca4425e0e..e52b95799a 100644 --- a/packages/core-test-utils/lib/matchers/transactions/types/multi-signature.js +++ b/packages/core-test-utils/lib/matchers/transactions/types/multi-signature.js @@ -1,10 +1,10 @@ -'use strict' - const { MULTI_SIGNATURE } = require('@arkecosystem/crypto').constants -module.exports = (received) => { - return { - message: () => 'Expected value to be a valid MULTI_SIGNATURE transaction.', - pass: received.type === MULTI_SIGNATURE - } -} +const toBeMultiSignatureType = received => ({ + message: () => 'Expected value to be a valid MULTI_SIGNATURE transaction.', + pass: received.type === MULTI_SIGNATURE, +}) + +expect.extend({ + toBeMultiSignatureType, +}) diff --git a/packages/core-test-utils/lib/matchers/transactions/types/second-signature.js b/packages/core-test-utils/lib/matchers/transactions/types/second-signature.js index 1503f7a8d2..7b0d591989 100644 --- a/packages/core-test-utils/lib/matchers/transactions/types/second-signature.js +++ b/packages/core-test-utils/lib/matchers/transactions/types/second-signature.js @@ -1,10 +1,10 @@ -'use strict' - const { SECOND_SIGNATURE } = require('@arkecosystem/crypto').constants -module.exports = (received) => { - return { - message: () => 'Expected value to be a valid SECOND_SIGNATURE transaction.', - pass: received.type === SECOND_SIGNATURE - } -} +const toBeSecondSignatureType = received => ({ + message: () => 'Expected value to be a valid SECOND_SIGNATURE transaction.', + pass: received.type === SECOND_SIGNATURE, +}) + +expect.extend({ + toBeSecondSignatureType, +}) diff --git a/packages/core-test-utils/lib/matchers/transactions/types/timelock-transfer.js b/packages/core-test-utils/lib/matchers/transactions/types/timelock-transfer.js index 001a28b850..9140a4346b 100644 --- a/packages/core-test-utils/lib/matchers/transactions/types/timelock-transfer.js +++ b/packages/core-test-utils/lib/matchers/transactions/types/timelock-transfer.js @@ -1,10 +1,10 @@ -'use strict' +const { TRANSACTION_TYPES } = require('@arkecosystem/crypto').constants -const { TIMELOCK_TRANSFER } = require('@arkecosystem/crypto').constants +const toBeTimelockTransferType = received => ({ + message: () => 'Expected value to be a valid TIMELOCK_TRANSFER transaction.', + pass: received.type === TRANSACTION_TYPES.TIMELOCK_TRANSFER, +}) -module.exports = (received) => { - return { - message: () => 'Expected value to be a valid TIMELOCK_TRANSFER transaction.', - pass: received.type === TIMELOCK_TRANSFER - } -} +expect.extend({ + toBeTimelockTransferType, +}) diff --git a/packages/core-test-utils/lib/matchers/transactions/types/transfer.js b/packages/core-test-utils/lib/matchers/transactions/types/transfer.js index 8192947003..a2a814a9ca 100644 --- a/packages/core-test-utils/lib/matchers/transactions/types/transfer.js +++ b/packages/core-test-utils/lib/matchers/transactions/types/transfer.js @@ -1,10 +1,10 @@ -'use strict' - const { TRANSFER } = require('@arkecosystem/crypto').constants -module.exports = (received) => { - return { - message: () => 'Expected value to be a valid TRANSFER transaction.', - pass: received.type === TRANSFER - } -} +const toBeTransferType = received => ({ + message: () => 'Expected value to be a valid TRANSFER transaction.', + pass: received.type === TRANSFER, +}) + +expect.extend({ + toBeTransferType, +}) diff --git a/packages/core-test-utils/lib/matchers/transactions/types/vote.js b/packages/core-test-utils/lib/matchers/transactions/types/vote.js index a2f098a346..08e813d4ae 100644 --- a/packages/core-test-utils/lib/matchers/transactions/types/vote.js +++ b/packages/core-test-utils/lib/matchers/transactions/types/vote.js @@ -1,10 +1,10 @@ -'use strict' - const { VOTE } = require('@arkecosystem/crypto').constants -module.exports = (received) => { - return { - message: () => 'Expected value to be a valid VOTE transaction.', - pass: received.type === VOTE - } -} +const toBeVoteType = received => ({ + message: () => 'Expected value to be a valid VOTE transaction.', + pass: received.type === VOTE, +}) + +expect.extend({ + toBeVoteType, +}) diff --git a/packages/core-test-utils/lib/matchers/transactions/valid-second-signature.js b/packages/core-test-utils/lib/matchers/transactions/valid-second-signature.js index ab9df40850..df3e4bcc2d 100644 --- a/packages/core-test-utils/lib/matchers/transactions/valid-second-signature.js +++ b/packages/core-test-utils/lib/matchers/transactions/valid-second-signature.js @@ -1,10 +1,16 @@ -'use strict' - const { crypto } = require('@arkecosystem/crypto') -module.exports = (actual, expected) => { +const toHaveValidSecondSignature = (actual, expected) => { + let verified + try { + verified = crypto.verifySecondSignature(actual, expected.publicKey) + } catch (e) {} // eslint-disable-line no-empty return { message: () => 'Expected value to have a valid second signature', - pass: crypto.verifySecondSignature(actual, expected.publicKey, expected.network) + pass: !!verified, } } + +expect.extend({ + toHaveValidSecondSignature, +}) diff --git a/packages/core-test-utils/lib/matchers/transactions/valid.js b/packages/core-test-utils/lib/matchers/transactions/valid.js index 52974357b2..ed752caa82 100644 --- a/packages/core-test-utils/lib/matchers/transactions/valid.js +++ b/packages/core-test-utils/lib/matchers/transactions/valid.js @@ -1,10 +1,10 @@ -'use strict' - const { crypto } = require('@arkecosystem/crypto') -module.exports = (transaction, network) => { - return { - message: () => 'Expected value to be a valid transaction', - pass: crypto.verify(transaction, network) - } -} +const toBeValidTransaction = (transaction, network) => ({ + message: () => 'Expected value to be a valid transaction', + pass: crypto.verify(transaction, network), +}) + +expect.extend({ + toBeValidTransaction, +}) diff --git a/packages/core-test-utils/package.json b/packages/core-test-utils/package.json index 0840d48a5d..3a97a6a942 100644 --- a/packages/core-test-utils/package.json +++ b/packages/core-test-utils/package.json @@ -1,7 +1,7 @@ { "name": "@arkecosystem/core-test-utils", - "description": "Test Utilities for ARK Core", - "version": "0.1.1", + "description": "Test Utilities for Ark Core", + "version": "0.2.0", "contributors": [ "Brian Faust " ], @@ -9,23 +9,29 @@ "main": "lib/index.js", "scripts": { "test": "cross-env ARK_ENV=test jest --runInBand --detectOpenHandles", - "test:coverage": "cross-env ARK_ENV=test jest --coverage --runInBand --detectOpenHandles", - "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand --watch", + "test:coverage": "cross-env ARK_ENV=test jest --coverage --coveragePathIgnorePatterns='/(defaults.js|index.js)$' --runInBand --detectOpenHandles", + "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand", "test:watch": "cross-env ARK_ENV=test jest --runInBand --watch", "test:watch:all": "cross-env ARK_ENV=test jest --runInBand --watchAll", "lint": "eslint ./ --fix", - "depcheck": "depcheck ./" + "depcheck": "depcheck ./ --ignores=lodash,lodash.*" }, "dependencies": { - "@arkecosystem/crypto": "^0.1.1", - "arkjs": "^0.2.1", + "@arkecosystem/core-container": "~0.2", + "@arkecosystem/crypto": "~0.2", "bip39": "^2.5.0", - "chalk": "^2.4.1", - "lodash": "^4.17.10", - "superheroes": "^1.0.0", - "xstate": "^3.3.3" + "lodash.get": "^4.4.2", + "lodash.isequal": "^4.5.0", + "lodash.sortby": "^4.7.0", + "lodash.take": "^4.1.1", + "lodash.uniqby": "^4.7.0", + "superheroes": "^2.0.0", + "xstate": "^4.1.2" }, "publishConfig": { "access": "public" + }, + "engines": { + "node": ">=10.x" } } diff --git a/packages/core-tester-cli/.gitignore b/packages/core-tester-cli/.gitignore new file mode 100644 index 0000000000..5dc9198e84 --- /dev/null +++ b/packages/core-tester-cli/.gitignore @@ -0,0 +1 @@ +test-wallets \ No newline at end of file diff --git a/packages/core-tester-cli/CHANGELOG.md b/packages/core-tester-cli/CHANGELOG.md index 127cc35e42..dd6949dd30 100644 --- a/packages/core-tester-cli/CHANGELOG.md +++ b/packages/core-tester-cli/CHANGELOG.md @@ -7,6 +7,31 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Unreleased -## 0.0.1 - 2018-05-31 +## 0.2.0 - 2018-12-03 + +### Added + +- Option for `smartBridge` values +- Default values for ports +- Multi Signature support +- Vote support +- Flood option + +### Changed + +- Moved from modules to classes to reduce duplication +- Use the v2 API for any API calls +- Handle duplicate transaction IDs +- Dropped node.js 9 as minimum requirement in favour of node.js 10 +- Use human-readable values as input for amounts and fees + +### Fixed + +- Undefined passphrases for the `overridingPassphrase` option in transfers +- Display of human-readable numbers + +## 0.1.1 - 2018-06-14 + ### Added + - initial release diff --git a/packages/core-tester-cli/README.md b/packages/core-tester-cli/README.md index 2042d240e5..878f26dd44 100644 --- a/packages/core-tester-cli/README.md +++ b/packages/core-tester-cli/README.md @@ -1,12 +1,12 @@ -![ARK Core](https://i.imgur.com/1aP6F2o.png) +# Ark Core - Tester CLI -# ARK Core - Tester CLI +

+ +

-## Installation +## Documentation -```bash -yarn add @arkecosystem/core-tester-cli -``` +You can find installation instructions and detailed instructions on how to use this package at the [dedicated documentation site](https://docs.ark.io/guidebook/core/plugins/core-tester-cli.html). ## Security diff --git a/packages/core-tester-cli/__tests__/__fixtures__/delegates-page-1.json b/packages/core-tester-cli/__tests__/__fixtures__/delegates-page-1.json new file mode 100644 index 0000000000..00b929e29f --- /dev/null +++ b/packages/core-tester-cli/__tests__/__fixtures__/delegates-page-1.json @@ -0,0 +1,90 @@ +{ + "meta": { + "count": 3, + "pageCount": 2, + "totalCount": 6, + "next": "/api/v2/delegates?page=2", + "previous": null, + "self": "/api/v2/delegates?page=1&limit=100", + "first": "/api/v2/delegates?page=1&limit=100", + "last": "/api/v2/delegates?page=2&limit=100" + }, + "data": [ + { + "username": "arkx", + "address": "DNjuJEDQkhrJ7cA9FZ2iVXt5anYiM8Jtc9", + "publicKey": "03bbfb43ecb5a54a1e227bb37b5812b5321213838d376e2b455b6af78442621dec", + "votes": 43424464264923, + "rank": 1, + "blocks": { + "produced": 15605, + "missed": 709, + "last": { + "id": "9508080167740922063", + "timestamp": { + "epoch": 52479984, + "unix": 1542581184, + "human": "2018-11-18T22:46:24Z" + } + } + }, + "production": { + "approval": 0.34, + "productivity": 95.65 + }, + "forged": { + "fees": 74694705072, + "rewards": 3078200000000, + "total": 3152894705072 + } + }, + { + "username": "obiwan", + "address": "D71HuRcEGH8q15hZnaqZ1oSfgZjqYscgav", + "publicKey": "03a2f2ce2aebd426d353bf3abf2c00a85e3122070bbeaa04b73eba2a6119dbc620", + "votes": 7827580000000, + "rank": 2, + "blocks": { + "produced": 15104, + "missed": 493, + "last": { + "id": "6408769526029163610", + "timestamp": { + "epoch": 52479946, + "unix": 1542581146, + "human": "2018-11-18T22:45:46Z" + } + } + }, + "production": { + "approval": 0.06, + "productivity": 96.84 + }, + "forged": { + "fees": 50980000000, + "rewards": 2986600000000, + "total": 3037580000000 + } + }, + { + "username": "yo", + "address": "DTFWtjocUWuiwqxcPh2Qi6SWU9CJKvPpsD", + "publicKey": "02e345079aca0567db96ec0ba3acf859b7cfd15134a855671f9c0fe8b1173767bd", + "votes": 6343253260000, + "rank": 3, + "blocks": { + "produced": 4165, + "missed": 785 + }, + "production": { + "approval": 0.05, + "productivity": 84.14 + }, + "forged": { + "fees": 3550000000, + "rewards": 833000000000, + "total": 836550000000 + } + } + ] +} diff --git a/packages/core-tester-cli/__tests__/__fixtures__/delegates-page-2.json b/packages/core-tester-cli/__tests__/__fixtures__/delegates-page-2.json new file mode 100644 index 0000000000..ac81fa58f2 --- /dev/null +++ b/packages/core-tester-cli/__tests__/__fixtures__/delegates-page-2.json @@ -0,0 +1,82 @@ +{ + "meta": { + "count": 3, + "pageCount": 2, + "totalCount": 6, + "next": null, + "previous": "/api/v2/delegates?page=1", + "self": "/api/v2/delegates?page=2&limit=100", + "first": "/api/v2/delegates?page=1&limit=100", + "last": "/api/v2/delegates?page=2&limit=100" + }, + "data": [ + { + "username": "cam", + "address": "DACFobAjNEKsc1CtPSMyp5uA4wp6uC3fgC", + "publicKey": "032cfbb18f4e49952c6d6475e8adc6d0cba00b81ef6606cc4927b78c6c50558beb", + "votes": 6070791889600, + "rank": 4, + "blocks": { + "produced": 1551, + "missed": 180, + "last": { + "id": "3658545612136752676", + "timestamp": { + "epoch": 52479330, + "unix": 1542580530, + "human": "2018-11-18T22:35:30Z" + } + } + }, + "production": { + "approval": 0.05, + "productivity": 89.6 + }, + "forged": { + "fees": 5060000000, + "rewards": 310200000000, + "total": 315260000000 + } + }, + { + "username": "arklabs", + "address": "D9z1ZUcCUHHeiFLEtYhwk6z8kmbCCHTRFd", + "publicKey": "0394685435d7331d178effe91d6b101ce7c4a6e03d2a96cfd5be1fffb0ae156e58", + "votes": 4500000000000, + "rank": 5, + "blocks": { + "produced": 14572, + "missed": 772 + }, + "production": { + "approval": 0.04, + "productivity": 94.97 + }, + "forged": { + "fees": 29670020960, + "rewards": 2884000000000, + "total": 2913670020960 + } + }, + { + "username": "jeremig", + "address": "D7h9uZHJAA37j9UnSs9zbhkEv6QtKGrSGL", + "publicKey": "02c6a267650795a4f4bd95e32a65aa5aa8e384d218e8be7b1f9c3a5f21661e85db", + "votes": 4013860773791, + "rank": 6, + "blocks": { + "produced": 2650, + "missed": 950 + }, + "production": { + "approval": 0.03, + "productivity": 73.61 + }, + "forged": { + "fees": 3000000000, + "rewards": 530000000000, + "total": 533000000000 + } + } + ] +} diff --git a/packages/core-tester-cli/__tests__/__fixtures__/transaction-1.json b/packages/core-tester-cli/__tests__/__fixtures__/transaction-1.json new file mode 100644 index 0000000000..3304cc29cd --- /dev/null +++ b/packages/core-tester-cli/__tests__/__fixtures__/transaction-1.json @@ -0,0 +1,17 @@ +{ + "id": "02c0061df475cceb6e80bc2c5ae1719960bbc214fbf662620cc2491f0f06e51b", + "blockId": "2099984314112825055", + "type": 0, + "amount": 2543518349, + "fee": 10000000, + "sender": "DGuuCwJYoEheBAC4PZTBSBasaDHxg2e6j7", + "recipient": "D7seWn8JLVwX4nHd9hh2Lf7gvZNiRJ7qLk", + "signature": "3044022065386285cb4dbcd042ac370e1a9f3034b7cdf68d9b97e8e4b0cb219087cbf79f02202e0fd295f3633c1c0503b892643fe212a22a1d290036227e0e9ba61ac2ba6677", + "vendorField": "darkzen reward", + "confirmations": 13, + "timestamp": { + "epoch": 52481490, + "unix": 1542582690, + "human": "2018-11-18T23:11:30Z" + } +} diff --git a/packages/core-tester-cli/__tests__/__fixtures__/transaction-response-1.json b/packages/core-tester-cli/__tests__/__fixtures__/transaction-response-1.json new file mode 100644 index 0000000000..f0fe3da998 --- /dev/null +++ b/packages/core-tester-cli/__tests__/__fixtures__/transaction-response-1.json @@ -0,0 +1,10 @@ +{ + "accept": [ + "4743f493f3f0e119b8330ea95de500e9823e51802ca3391ece96c326634e183a" + ], + "excess": [], + "invalid": [], + "broadcast": [ + "4743f493f3f0e119b8330ea95de500e9823e51802ca3391ece96c326634e183a" + ] +} diff --git a/packages/core-tester-cli/__tests__/__fixtures__/voters-page-1.json b/packages/core-tester-cli/__tests__/__fixtures__/voters-page-1.json new file mode 100644 index 0000000000..264578c79b --- /dev/null +++ b/packages/core-tester-cli/__tests__/__fixtures__/voters-page-1.json @@ -0,0 +1,38 @@ +{ + "meta": { + "count": 3, + "pageCount": 2, + "totalCount": 6, + "next": "/api/v2/delegates/03bbfb43ecb5a54a1e227bb37b5812b5321213838d376e2b455b6af78442621dec/voters?page=2&limit=100", + "previous": null, + "self": "/api/v2/delegates/03bbfb43ecb5a54a1e227bb37b5812b5321213838d376e2b455b6af78442621dec/voters?page=1&limit=100", + "first": "/api/v2/delegates/03bbfb43ecb5a54a1e227bb37b5812b5321213838d376e2b455b6af78442621dec/voters?page=1&limit=100", + "last": "/api/v2/delegates/03bbfb43ecb5a54a1e227bb37b5812b5321213838d376e2b455b6af78442621dec/voters?page=2&limit=100" + }, + "data": [ + { + "address": "D598HVxTLLyjnpvpj1voo5CePGYxpw9kvy", + "publicKey": "033c0b8ca9e01cacd539cb512ac8d576a37c287fea8fd769fc3cad46889e5a708c", + "username": null, + "secondPublicKey": null, + "balance": 100000000, + "isDelegate": false + }, + { + "address": "D59atbRCJ5UijDPMHj9opgU3gxbffzFRLe", + "publicKey": "026554b83729a2f2928f47fb7f0ce55cf462c7828792f9216bce60851eda938d98", + "username": null, + "secondPublicKey": null, + "balance": 100000000, + "isDelegate": false + }, + { + "address": "D59r2xBatFUjRY9BMwjuUdXNBSCraVGKWh", + "publicKey": "03e6c5aa5835eec16fc48a913f2c9622c69b2ed7eb828b5b892509934031e985e5", + "username": null, + "secondPublicKey": null, + "balance": 100000000, + "isDelegate": false + } + ] +} diff --git a/packages/core-tester-cli/__tests__/__fixtures__/voters-page-2.json b/packages/core-tester-cli/__tests__/__fixtures__/voters-page-2.json new file mode 100644 index 0000000000..114b36ccdf --- /dev/null +++ b/packages/core-tester-cli/__tests__/__fixtures__/voters-page-2.json @@ -0,0 +1,38 @@ +{ + "meta": { + "count": 3, + "pageCount": 2, + "totalCount": 6, + "next": null, + "previous": "/api/v2/delegates/03bbfb43ecb5a54a1e227bb37b5812b5321213838d376e2b455b6af78442621dec/voters?page=1&limit=100", + "self": "/api/v2/delegates/03bbfb43ecb5a54a1e227bb37b5812b5321213838d376e2b455b6af78442621dec/voters?page=2&limit=100", + "first": "/api/v2/delegates/03bbfb43ecb5a54a1e227bb37b5812b5321213838d376e2b455b6af78442621dec/voters?page=1&limit=100", + "last": "/api/v2/delegates/03bbfb43ecb5a54a1e227bb37b5812b5321213838d376e2b455b6af78442621dec/voters?page=2&limit=100" + }, + "data": [ + { + "address": "D5A1b37Yr291pxwomH2gHZeekoks2tLwhk", + "publicKey": "023f3312ca84373adf6a219eb4bc70545263338810afc33331a86634d3d80ae72d", + "username": null, + "secondPublicKey": null, + "balance": 100000000, + "isDelegate": false + }, + { + "address": "D5a3upUoaEfLUkwCVkspJNQJq4UCR1ytth", + "publicKey": "03bf5acdc2a8dfd0f46a6353dc39fcc1ee896232f3a470e196dfbc4c9f7cbf6318", + "username": null, + "secondPublicKey": null, + "balance": 100000000, + "isDelegate": false + }, + { + "address": "D5a9L47PQEKk9JCnYzhSoXFf9wAn1k8Y3E", + "publicKey": "02cf021ef0687ca93a102244b88b733cec0851875993b040aaaa72a95eb3927f6d", + "username": null, + "secondPublicKey": null, + "balance": 100000000, + "isDelegate": false + } + ] +} diff --git a/packages/core-tester-cli/__tests__/__fixtures__/wallet-1.json b/packages/core-tester-cli/__tests__/__fixtures__/wallet-1.json new file mode 100644 index 0000000000..cf8846d5d8 --- /dev/null +++ b/packages/core-tester-cli/__tests__/__fixtures__/wallet-1.json @@ -0,0 +1,8 @@ +{ + "address": "DNjuJEDQkhrJ7cA9FZ2iVXt5anYiM8Jtc9", + "publicKey": "03bbfb43ecb5a54a1e227bb37b5812b5321213838d376e2b455b6af78442621dec", + "username": "arkx", + "secondPublicKey": null, + "balance": 42159020792234, + "isDelegate": true +} diff --git a/packages/core-tester-cli/__tests__/commands/command.test.js b/packages/core-tester-cli/__tests__/commands/command.test.js new file mode 100644 index 0000000000..4c7333fb14 --- /dev/null +++ b/packages/core-tester-cli/__tests__/commands/command.test.js @@ -0,0 +1,433 @@ +const clipboardy = require('clipboardy') +const axios = require('axios') +const MockAdapter = require('axios-mock-adapter') +const fill = require('lodash/fill') +const Command = require('../../lib/commands/command') +const logger = require('../../lib/utils/logger') + +const mockAxios = new MockAdapter(axios) + +let command +beforeEach(() => { + command = new Command() + mockAxios.reset() +}) + +describe('Command Base', () => { + describe('Init', () => { + it('should be a function', () => { + expect(Command.init).toBeFunction() + }) + it('init w/ option', async () => { + mockAxios + .onGet('http://test_baseUrl:1234/api/v2/node/configuration') + .reply(200, { data: { constants: {} } }) + mockAxios + .onGet('http://test_baseUrl:4321/config') + .reply(200, { data: { network: {} } }) + command = await Command.init({ + baseUrl: 'http://test_baseUrl', + apiPort: 1234, + p2pPort: 4321, + passphrase: 'test_passphrase', + secondPassphrase: 'test_secondPassphrase', + }) + expect(command.config).toContainEntries([ + ['baseUrl', 'http://test_baseUrl'], + ['apiPort', 1234], + ['p2pPort', 4321], + ['passphrase', 'test_passphrase'], + ['secondPassphrase', 'test_secondPassphrase'], + ]) + }) + }) + + describe('Copy to Clipboard', () => { + it('should be a function', () => { + expect(command.copyToClipboard).toBeFunction() + }) + + it('should contain the copied content', () => { + command.copyToClipboard([ + { + key: 'value', + serialized: '00', + }, + ]) + + expect(JSON.parse(clipboardy.readSync())).toEqual([ + { + key: 'value', + serialized: '00', + }, + ]) + }) + }) + + describe('Run', () => { + it('should be a function', () => { + expect(command.run).toBeFunction() + }) + it('throw expception', () => { + expect(command.run).toThrowWithMessage( + Error, + 'Method [run] not implemented!', + ) + }) + }) + + describe('Generate Wallets', () => { + it('should be a function', () => { + expect(command.generateWallets).toBeFunction() + }) + it('generate wallets', () => { + command.config = { + network: { + version: 1, + }, + } + const wallets = command.generateWallets(10) + expect(wallets).toBeArrayOfSize(10) + wallets.forEach(wallet => { + expect(wallet).toContainAllKeys(['address', 'keys', 'passphrase']) + }) + }) + }) + + describe('getDelegates', () => { + it('should be a function', () => { + expect(command.getDelegates).toBeFunction() + }) + it('should get delegates', async () => { + const delegatePage1Fixture = require('../__fixtures__/delegates-page-1.json') + const delegatePage2Fixture = require('../__fixtures__/delegates-page-2.json') + command.config = { + baseUrl: 'http://baseUrl', + apiPort: 1234, + } + mockAxios + .onGet('http://baseUrl:1234/api/v2/delegates?page=1') + .reply(200, delegatePage1Fixture) + mockAxios + .onGet('http://baseUrl:1234/api/v2/delegates?page=2') + .reply(200, delegatePage2Fixture) + + expect(await command.getDelegates()).toIncludeSameMembers([ + ...delegatePage1Fixture.data, + ...delegatePage2Fixture.data, + ]) + }) + }) + + describe('getTransactionDelaySeconds', () => { + it('should be a function', () => { + expect(command.getTransactionDelaySeconds).toBeFunction() + }) + it('should delay correct', () => { + command.config = { + constants: { + blocktime: 8, + block: { + maxTransactions: 10, + }, + }, + } + + // 1 Block + expect(command.getTransactionDelaySeconds(fill(Array(5), true))).toBe(20) + expect(command.getTransactionDelaySeconds(fill(Array(10), true))).toBe(20) + // 2 Block + expect(command.getTransactionDelaySeconds(fill(Array(15), true))).toBe(40) + // 10 Block + expect(command.getTransactionDelaySeconds(fill(Array(100), true))).toBe( + 200, + ) + }) + }) + + describe('getTransaction', () => { + it('should be a function', () => { + expect(command.getTransaction).toBeFunction() + }) + it('should get transaction', async () => { + const transactionFixture = require('../__fixtures__/transaction-1.json') + command.config = { + baseUrl: 'http://baseUrl', + apiPort: 1234, + } + mockAxios + .onGet( + `http://baseUrl:1234/api/v2/transactions/${transactionFixture.id}`, + ) + .reply(200, { + data: transactionFixture, + }) + + expect(await command.getTransaction(transactionFixture.id)).toEqual( + transactionFixture, + ) + }) + }) + + describe('getVoters', () => { + it('should be a function', () => { + expect(command.getVoters).toBeFunction() + }) + it('should get voters', async () => { + const voterPage1Fixture = require('../__fixtures__/voters-page-1.json') + const voterPage2Fixture = require('../__fixtures__/voters-page-2.json') + command.config = { + baseUrl: 'http://baseUrl', + apiPort: 1234, + } + mockAxios + .onGet('http://baseUrl:1234/api/v2/delegates/1/voters?page=1') + .reply(200, voterPage1Fixture) + mockAxios + .onGet('http://baseUrl:1234/api/v2/delegates/1/voters?page=2') + .reply(200, voterPage2Fixture) + + expect(await command.getVoters(1)).toIncludeSameMembers([ + ...voterPage1Fixture.data, + ...voterPage2Fixture.data, + ]) + }) + }) + + describe('getWalletBalance', () => { + it('should be a function', () => { + expect(command.getWalletBalance).toBeFunction() + }) + it('should get transaction', async () => { + const walletFixture = require('../__fixtures__/wallet-1.json') + command.config = { + baseUrl: 'http://baseUrl', + apiPort: 1234, + } + mockAxios + .onGet(`http://baseUrl:1234/api/v2/wallets/${walletFixture.address}`) + .reply(200, { + data: walletFixture, + }) + + expect( + (await command.getWalletBalance(walletFixture.address)).toNumber(), + ).toBe(walletFixture.balance) + }) + }) + + describe('getWallet', () => { + it('should be a function', () => { + expect(command.getWallet).toBeFunction() + }) + it('should get transaction', async () => { + const walletFixture = require('../__fixtures__/wallet-1.json') + command.config = { + baseUrl: 'http://baseUrl', + apiPort: 1234, + } + mockAxios + .onGet(`http://baseUrl:1234/api/v2/wallets/${walletFixture.address}`) + .reply(200, { + data: walletFixture, + }) + + expect(await command.getWallet(walletFixture.address)).toEqual( + walletFixture, + ) + }) + }) + + describe('static parseFee', () => { + it('should be a function', () => { + expect(Command.parseFee).toBeFunction() + }) + it('should give arktoshi', () => { + expect(Command.parseFee(0.1).toString()).toBe('10000000') + expect(Command.parseFee(1).toString()).toBe('100000000') + expect(Command.parseFee(10).toString()).toBe('1000000000') + expect(Command.parseFee('0.1').toString()).toBe('10000000') + expect(Command.parseFee('1').toString()).toBe('100000000') + expect(Command.parseFee('10').toString()).toBe('1000000000') + expect(Command.parseFee('0.001-0.005').toNumber()).toBeWithin( + 100000, + 500000, + ) + }) + }) + + describe('sendTransactions', () => { + it('should be a function', () => { + expect(command.sendTransactions).toBeFunction() + }) + it('should send and wait', async () => { + const responseFixture = require('../__fixtures__/transaction-response-1.json') + const loggerInfo = logger.info + logger.info = jest.fn() + command.getTransactionDelaySeconds = jest.fn(() => 1) + command.config = { + baseUrl: 'http://baseUrl', + apiPort: 1234, + } + mockAxios.onPost(`http://baseUrl:1234/api/v2/transactions`).reply(200, { + data: responseFixture, + }) + + const start = new Date().getTime() + const response = await command.sendTransactions([], 'test') + const end = new Date().getTime() + + expect(response).toEqual(responseFixture) + expect(command.getTransactionDelaySeconds).toHaveBeenCalledTimes(1) + expect(Math.round((end - start) / 1000)).toBeGreaterThanOrEqual(1) + expect(logger.info).toHaveBeenCalledWith( + 'Waiting 1 seconds to apply test transactions', + ) + logger.info = loggerInfo + }) + }) + + describe('postTransactions', () => { + it('should be a function', () => { + expect(command.postTransactions).toBeFunction() + }) + it('should send transaction', async () => { + const responseFixture = require('../__fixtures__/transaction-response-1.json') + command.config = { + baseUrl: 'http://baseUrl', + apiPort: 1234, + } + mockAxios.onPost(`http://baseUrl:1234/api/v2/transactions`).reply(200, { + data: responseFixture, + }) + + expect(await command.postTransactions([])).toEqual(responseFixture) + }) + }) + + describe('__applyConfig', () => { + it('should be a function', () => { + expect(command.__applyConfig).toBeFunction() + }) + it('should sets constant', () => { + command.options = { + baseUrl: 'http://baseUrl///', + apiPort: 1234, + p2pPort: 4321, + passphrase: 'test_passphrase', + secondPassphrase: 'test_secondPassphrase', + } + + command.__applyConfig() + + expect(command.config.baseUrl).toBe('http://baseUrl') + expect(command.config.apiPort).toBe(1234) + expect(command.config.p2pPort).toBe(4321) + expect(command.config.passphrase).toBe('test_passphrase') + expect(command.config.secondPassphrase).toBe('test_secondPassphrase') + }) + }) + + describe('__loadConstants', () => { + it('should be a function', () => { + expect(command.__loadConstants).toBeFunction() + }) + it('should sets constant', async () => { + command.config = { + baseUrl: 'http://baseUrl', + apiPort: 1234, + } + mockAxios + .onGet('http://baseUrl:1234/api/v2/node/configuration') + .reply(200, { + data: { + constants: { + testConstant: true, + testConstant2: 'test', + }, + }, + }) + + await command.__loadConstants() + + expect(command.config.constants).toContainAllEntries([ + ['testConstant', true], + ['testConstant2', 'test'], + ]) + }) + }) + + describe('__loadNetworkConfig', () => { + it('should be a function', () => { + expect(command.__loadNetworkConfig).toBeFunction() + }) + it('should sets constant', async () => { + command.config = { + baseUrl: 'http://baseUrl', + p2pPort: 4321, + } + mockAxios.onGet('http://baseUrl:4321/config').reply(200, { + data: { + network: { + testConfig: true, + testConfig2: 'test', + }, + }, + }) + + await command.__loadNetworkConfig() + + expect(command.config.network).toContainAllEntries([ + ['testConfig', true], + ['testConfig2', 'test'], + ]) + }) + }) + + describe('static __arkToArktoshi', () => { + it('should be a function', () => { + expect(Command.__arkToArktoshi).toBeFunction() + }) + it('should give arktoshi', () => { + expect(Command.__arkToArktoshi(0.00000001).toString()).toBe('1') + expect(Command.__arkToArktoshi(0.1).toString()).toBe('10000000') + expect(Command.__arkToArktoshi(1).toString()).toBe('100000000') + expect(Command.__arkToArktoshi(10).toString()).toBe('1000000000') + }) + }) + + describe('static __arktoshiToArk', () => { + it('should be a function', () => { + expect(Command.__arktoshiToArk).toBeFunction() + }) + it('should give ark', () => { + expect(Command.__arktoshiToArk(1)).toBe('0.00000001 DѦ') + expect(Command.__arktoshiToArk(10000000)).toBe('0.1 DѦ') + expect(Command.__arktoshiToArk(100000000)).toBe('1 DѦ') + expect(Command.__arktoshiToArk(1000000000)).toBe('10 DѦ') + }) + }) + + describe('__problemSendingTransactions', () => { + it('should be a function', () => { + expect(command.__problemSendingTransactions).toBeFunction() + }) + it('should log message and exit', () => { + const processExit = process.exit + const loggerError = logger.error + process.exit = jest.fn() + logger.error = jest.fn() + const message = '__problemSendingTransactions message' + command.__problemSendingTransactions({ + message, + }) + expect(logger.error).toHaveBeenCalledTimes(1) + expect(logger.error).toHaveBeenCalledWith( + `There was a problem sending transactions: ${message}`, + ) + expect(process.exit).toHaveBeenCalledTimes(1) + process.exit = processExit + logger.error = loggerError + }) + }) +}) diff --git a/packages/core-tester-cli/__tests__/commands/delegate-registration.test.js b/packages/core-tester-cli/__tests__/commands/delegate-registration.test.js index 508818214f..d21c8e25b0 100644 --- a/packages/core-tester-cli/__tests__/commands/delegate-registration.test.js +++ b/packages/core-tester-cli/__tests__/commands/delegate-registration.test.js @@ -1,9 +1,70 @@ -'use strict' +const axios = require('axios') +const MockAdapter = require('axios-mock-adapter') +const superheroes = require('superheroes') +const DelegateRegistrationCommand = require('../../lib/commands/delegate-registration') -const vote = require('../../lib/commands/delegate-registration') +const mockAxios = new MockAdapter(axios) + +const defaultOpts = { + skipTesting: true, + skipValidation: true, +} +beforeEach(() => { + // Just passthru. We'll test the Command class logic in its own test file more thoroughly + mockAxios + .onGet('http://localhost:4003/api/v2/node/configuration') + .reply(200, { data: { constants: {} } }) + mockAxios + .onGet('http://localhost:4000/config') + .reply(200, { data: { network: {} } }) + jest.spyOn(axios, 'get') + jest.spyOn(axios, 'post') +}) + +afterEach(() => { + mockAxios.reset() +}) describe('Commands - Delegate Registration', () => { it('should be a function', () => { - expect(vote).toBeFunction() + expect(DelegateRegistrationCommand).toBeFunction() + }) + + it('should register as delegate', async () => { + const opts = { + ...defaultOpts, + delegateFee: 1, + number: 1, + } + const command = await DelegateRegistrationCommand.init(opts) + const expectedDelegateName = 'mr_bojangles' + // call to delegates/{publicKey}/voters returns zero delegates + mockAxios.onGet(/http:\/\/localhost:4003\/api\/v2\/delegates/).reply(200, { + meta: { pageCount: 1 }, + data: [], + }) + jest + .spyOn(superheroes, 'random') + .mockImplementation(() => expectedDelegateName) + + await command.run() + + expect(axios.post).toHaveBeenNthCalledWith( + 2, + 'http://localhost:4003/api/v2/transactions', + { + transactions: [ + expect.objectContaining({ + fee: DelegateRegistrationCommand.__arkToArktoshi(opts.delegateFee), + asset: { + delegate: { + username: expectedDelegateName, + }, + }, + }), + ], + }, + expect.any(Object), + ) }) }) diff --git a/packages/core-tester-cli/__tests__/commands/multi-signature.test.js b/packages/core-tester-cli/__tests__/commands/multi-signature.test.js index a93f8266c0..e2825db958 100644 --- a/packages/core-tester-cli/__tests__/commands/multi-signature.test.js +++ b/packages/core-tester-cli/__tests__/commands/multi-signature.test.js @@ -1,5 +1,3 @@ -'use strict' - const vote = require('../../lib/commands/multi-signature') describe('Commands - Multi-signature', () => { diff --git a/packages/core-tester-cli/__tests__/commands/second-signature.test.js b/packages/core-tester-cli/__tests__/commands/second-signature.test.js index f6cd0c0f01..f4753b9c94 100644 --- a/packages/core-tester-cli/__tests__/commands/second-signature.test.js +++ b/packages/core-tester-cli/__tests__/commands/second-signature.test.js @@ -1,9 +1,63 @@ -'use strict' +const axios = require('axios') +const MockAdapter = require('axios-mock-adapter') +const SecondSignatureCommand = require('../../lib/commands/second-signature') -const vote = require('../../lib/commands/second-signature') +const mockAxios = new MockAdapter(axios) + +const defaultOpts = { + skipTesting: true, + skipValidation: true, +} +beforeEach(() => { + // Just passthru. We'll test the Command class logic in its own test file more thoroughly + mockAxios + .onGet('http://localhost:4003/api/v2/node/configuration') + .reply(200, { data: { constants: {} } }) + mockAxios + .onGet('http://localhost:4000/config') + .reply(200, { data: { network: {} } }) + jest.spyOn(axios, 'get') + jest.spyOn(axios, 'post') +}) + +afterEach(() => { + mockAxios.reset() +}) describe('Commands - Second signature', () => { it('should be a function', () => { - expect(vote).toBeFunction() + expect(SecondSignatureCommand).toBeFunction() + }) + + it('should apply second signature', async () => { + const opts = { + ...defaultOpts, + signatureFee: 1, + number: 1, + } + const command = await SecondSignatureCommand.init(opts) + mockAxios + .onPost('http://localhost:4003/api/v2/transactions') + .reply(200, { data: {} }) + + await command.run() + + expect(axios.post).toHaveBeenNthCalledWith( + 2, + 'http://localhost:4003/api/v2/transactions', + { + transactions: [ + expect.objectContaining({ + fee: SecondSignatureCommand.__arkToArktoshi(opts.signatureFee), + asset: { + signature: { + publicKey: expect.any(String), + }, + }, + }), + ], + }, + expect.any(Object), + ) }) }) diff --git a/packages/core-tester-cli/__tests__/commands/transfer.test.js b/packages/core-tester-cli/__tests__/commands/transfer.test.js index 3f6ba2a58b..233b81fff3 100644 --- a/packages/core-tester-cli/__tests__/commands/transfer.test.js +++ b/packages/core-tester-cli/__tests__/commands/transfer.test.js @@ -1,9 +1,150 @@ -'use strict' +const axios = require('axios') +const MockAdapter = require('axios-mock-adapter') +const TransferCommand = require('../../lib/commands/transfer') -const vote = require('../../lib/commands/transfer') +const mockAxios = new MockAdapter(axios) + +const defaultOpts = { + skipTesting: true, + skipValidation: true, +} +beforeEach(() => { + // Just passthru. We'll test the Command class logic in its own test file more thoroughly + mockAxios + .onGet('http://localhost:4003/api/v2/node/configuration') + .reply(200, { data: { constants: {} } }) + mockAxios + .onGet('http://localhost:4000/config') + .reply(200, { data: { network: {} } }) + jest.spyOn(axios, 'get') + jest.spyOn(axios, 'post') +}) + +afterEach(() => { + mockAxios.reset() +}) + +afterAll(() => mockAxios.restore()) describe('Commands - Transfer', () => { it('should be a function', () => { - expect(vote).toBeFunction() + expect(TransferCommand).toBeFunction() + }) + + it('should postTransactions using custom smartBridge value', async () => { + const expectedRecipientId = 'DFyUhQW52sNB5PZdS7VD9HknwYrSNHPQDq' + const expectedTransactionAmount = 2 + const expectedFee = 0.1 + const opts = { + ...defaultOpts, + amount: expectedTransactionAmount, + transferFee: expectedFee, + number: 1, + smartBridge: 'foo bar', + recipient: expectedRecipientId, + } + const command = await TransferCommand.init(opts) + mockAxios + .onPost('http://localhost:4003/api/v2/transactions') + .reply(200, { data: {} }) + let expectedTransactions = [] + jest.spyOn(axios, 'post').mockImplementation((uri, { transactions }) => { + expectedTransactions = transactions + }) + + await command.run() + + expect(expectedTransactions).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + vendorField: 'foo bar', + amount: TransferCommand.__arkToArktoshi(expectedTransactionAmount), + fee: TransferCommand.__arkToArktoshi(expectedFee), + recipientId: expectedRecipientId, + }), + ]), + ) + }) + + it('should generate n transactions', async () => { + const expectedTxCount = 5 + const opts = { + ...defaultOpts, + amount: TransferCommand.__arkToArktoshi(2), + transferFee: TransferCommand.__arkToArktoshi(0.1), + number: expectedTxCount, + } + const command = await TransferCommand.init(opts) + mockAxios + .onPost('http://localhost:4003/api/v2/transactions') + .reply(200, { data: {} }) + let expectedTransactions = [] + jest.spyOn(axios, 'post').mockImplementation((uri, { transactions }) => { + expectedTransactions = transactions + }) + + await command.run() + + expect(expectedTransactions).toHaveLength(expectedTxCount) + for (const t of expectedTransactions) { + expect(t.vendorField).toMatch(/Transaction \d/) + expect(t.amount).toBeDefined() + expect(t.fee).toBeDefined() + } + }) + + it('should send n transactions to specified recipient', async () => { + const expectedTxCount = 10 + const expectedRecipientId = 'DFyUhQW52sNB5PZdS7VD9HknwYrSNHPQDq' + const opts = { + ...defaultOpts, + amount: TransferCommand.__arkToArktoshi(2), + transferFee: TransferCommand.__arkToArktoshi(0.1), + number: expectedTxCount, + recipient: expectedRecipientId, + } + const command = await TransferCommand.init(opts) + mockAxios + .onPost('http://localhost:4003/api/v2/transactions') + .reply(200, { data: {} }) + let expectedTransactions = [] + jest.spyOn(axios, 'post').mockImplementation((uri, { transactions }) => { + expectedTransactions = transactions + }) + + await command.run() + + expect(expectedTransactions).toHaveLength(expectedTxCount) + for (const t of expectedTransactions) { + expect(t.recipientId).toEqual(expectedRecipientId) + } + }) + + it('should sign with 2nd passphrase if specified', async () => { + const expectedTransactionAmount = TransferCommand.__arkToArktoshi(2) + const expectedFee = TransferCommand.__arkToArktoshi(0.1) + const opts = { + ...defaultOpts, + amount: expectedTransactionAmount, + transferFee: expectedFee, + number: 1, + secondPassphrase: 'she sells sea shells down by the sea shore', + } + const command = await TransferCommand.init(opts) + mockAxios + .onPost('http://localhost:4003/api/v2/transactions') + .reply(200, { data: {} }) + let expectedTransactions = [] + jest.spyOn(axios, 'post').mockImplementation((uri, { transactions }) => { + expectedTransactions = transactions + }) + + await command.run() + + expect(expectedTransactions).toHaveLength(1) + for (const t of expectedTransactions) { + expect(t.secondSignature).toBeDefined() + expect(t.signSignature).toEqual(t.secondSignature) + } }) }) diff --git a/packages/core-tester-cli/__tests__/commands/vote.test.js b/packages/core-tester-cli/__tests__/commands/vote.test.js index 2f2ad1f6e0..601afdde1a 100644 --- a/packages/core-tester-cli/__tests__/commands/vote.test.js +++ b/packages/core-tester-cli/__tests__/commands/vote.test.js @@ -1,9 +1,106 @@ -'use strict' +const axios = require('axios') +const MockAdapter = require('axios-mock-adapter') +const VoteCommand = require('../../lib/commands/vote') -const vote = require('../../lib/commands/vote') +const mockAxios = new MockAdapter(axios) + +const defaultOpts = { + skipTesting: true, + skipValidation: true, +} +beforeEach(() => { + // Just passthru. We'll test the Command class logic in its own test file more thoroughly + mockAxios + .onGet('http://localhost:4003/api/v2/node/configuration') + .reply(200, { data: { constants: {} } }) + mockAxios + .onGet('http://localhost:4000/config') + .reply(200, { data: { network: {} } }) + jest.spyOn(axios, 'get') + jest.spyOn(axios, 'post') +}) + +afterEach(() => { + mockAxios.reset() +}) + +afterAll(() => mockAxios.restore()) describe('Commands - Vote', () => { it('should be a function', () => { - expect(vote).toBeFunction() + expect(VoteCommand).toBeFunction() + }) + + it('should vote for specified delegate', async () => { + const expectedDelegate = '03f294777f7376e970b2bd4805b4a90c8449b5935d530bdb566d02800ac44a4c00' + const opts = { + ...defaultOpts, + number: 1, + voteFee: 1, + delegate: expectedDelegate, + } + const command = await VoteCommand.init(opts) + mockAxios.onGet(/http:\/\/localhost:4003\/api\/v2\/delegates.*/).reply(200) + mockAxios + .onPost('http://localhost:4003/api/v2/transactions') + .reply(200, { data: {} }) + + await command.run() + + expect(axios.post).toHaveBeenNthCalledWith( + 2, + 'http://localhost:4003/api/v2/transactions', + { + transactions: [ + expect.objectContaining({ + fee: VoteCommand.__arkToArktoshi(opts.voteFee), + asset: { + votes: [`+${expectedDelegate}`], + }, + }), + ], + }, + expect.any(Object), + ) + }) + + it('should vote random delegate if non specified', async () => { + const expectedDelegate = '03f294777f7376e970b2bd4805b4a90c8449b5935d530bdb566d02800ac44a4c00' + const opts = { + ...defaultOpts, + number: 1, + voteFee: 1, + delegate: null, + } + const command = await VoteCommand.init(opts) + mockAxios + .onPost('http://localhost:4003/api/v2/transactions') + .reply(200, { data: {} }) + mockAxios + .onGet(/http:\/\/localhost:4003\/api\/v2\/delegates\/.*/) + .reply(200) // call to delegates/{publicKey}/voters + // call to /delegates + mockAxios.onGet(/http:\/\/localhost:4003\/api\/v2\/delegates/).reply(200, { + meta: { pageCount: 1 }, + data: [{ publicKey: expectedDelegate }], + }) + + await command.run() + + expect(axios.post).toHaveBeenNthCalledWith( + 2, + 'http://localhost:4003/api/v2/transactions', + { + transactions: [ + expect.objectContaining({ + fee: VoteCommand.__arkToArktoshi(opts.voteFee), + asset: { + votes: [`+${expectedDelegate}`], + }, + }), + ], + }, + expect.any(Object), + ) }) }) diff --git a/packages/core-tester-cli/__tests__/config/index.test.js b/packages/core-tester-cli/__tests__/config/index.test.js index f8be6f1fdd..213eb37ca4 100644 --- a/packages/core-tester-cli/__tests__/config/index.test.js +++ b/packages/core-tester-cli/__tests__/config/index.test.js @@ -1,5 +1,3 @@ -'use strict' - const config = require('../../lib/config') describe('Config', () => { @@ -9,17 +7,12 @@ describe('Config', () => { it('should have specific data', () => { expect(config).toEqual({ - baseUrlApi: 'http://localhost:4003', - baseUrlP2P: 'http://localhost:4000', - passphrase: 'prison tobacco acquire stone dignity palace note decade they current lesson robot', - secondPassPhrase: '', - publicKeyHash: 23, - requestHeaders: { - nethash: 'd9acd04bde4234a81addb8482333b4ac906bed7be5a9970ce8ada428bd083192', - version: '1.0.1', - port: 4000 - }, - transactionWaitDelay: 15 + apiPort: 4003, + p2pPort: 4000, + baseUrl: 'http://localhost', + passphrase: + 'prison tobacco acquire stone dignity palace note decade they current lesson robot', + secondPassphrase: '', }) }) }) diff --git a/packages/core-tester-cli/__tests__/utils/copy-to-clipboard.test.js b/packages/core-tester-cli/__tests__/utils/copy-to-clipboard.test.js deleted file mode 100644 index 5ec23038cd..0000000000 --- a/packages/core-tester-cli/__tests__/utils/copy-to-clipboard.test.js +++ /dev/null @@ -1,20 +0,0 @@ -'use strict' - -const clipboardy = require('clipboardy') -const copyToClipboard = require('../../lib/utils/copy-to-clipboard') - -describe('Utils - Copy to Clipboard', () => { - it('should be a function', () => { - expect(copyToClipboard).toBeFunction() - }) - - it('should contain the copied content', () => { - copyToClipboard([{ - key: 'value' - }]) - - expect(JSON.parse(clipboardy.readSync())).toEqual([{ - key: 'value' - }]) - }) -}) diff --git a/packages/core-tester-cli/__tests__/utils/generate-wallets.test.js b/packages/core-tester-cli/__tests__/utils/generate-wallets.test.js deleted file mode 100644 index 09de812b25..0000000000 --- a/packages/core-tester-cli/__tests__/utils/generate-wallets.test.js +++ /dev/null @@ -1,44 +0,0 @@ -'use strict' - -const generateWallets = require('../../lib/utils/generate-wallets') -const arkjs = require('arkjs') - -describe('Utils - Generate Wallets', () => { - it('should be a function', () => { - expect(generateWallets).toBeFunction() - }) - - it('should generate 4 wallets', () => { - const wallets = generateWallets(4) - - expect(wallets.length).toBe(4) - }) - - it('should have wallet with passphrase, keys and address', () => { - const wallet = generateWallets(1)[0] - - expect(wallet).toContainAllKeys([ - 'address', - 'keys', - 'passphrase' - ]) - }) - - it('should give a wallet with a valid address', () => { - const wallet = generateWallets(1)[0] - - expect(arkjs.crypto.validateAddress(wallet.address)).toBeTruthy() - }) - - it('should give a wallet with a valid passphrase', () => { - const wallet = generateWallets(1)[0] - const keys = arkjs.crypto.getKeys(wallet.passphrase) - - expect(keys).toContainKeys([ - 'publicKey', - 'privateKey' - ]) - expect(wallet.passphrase.split(' ').length).toBe(12) - expect(arkjs.crypto.getAddress(keys.publicKey)).toBeTruthy() - }) -}) diff --git a/packages/core-tester-cli/bin/tester b/packages/core-tester-cli/bin/tester index 280e3178ae..a5a791af5b 100755 --- a/packages/core-tester-cli/bin/tester +++ b/packages/core-tester-cli/bin/tester @@ -8,51 +8,69 @@ const registerCommand = (name, description) => { return app .command(name) .description(description) - .option('-n, --number ', 'number of transactions', 10) - .option('-a, --amount ', 'transaction amount', 200000000) - .option('--transfer-fee ', 'transfer fee', 10000000) - .option('--base-api ', 'base api url') - .option('--base-p2p ', 'base p2p url') + .option('-n, --number ', 'number of wallets', 10) + .option('-a, --amount ', 'initial wallet token amount', 2) + .option('--transfer-fee ', 'transfer fee', 0.1) + .option('--base-url ', 'base api url') + .option('--api-port ', 'base api port', 4003) + .option('--p2p-port ', 'base p2p port', 4002) + .option('-p, --passphrase ', 'passphrase of initial wallet') + .option('-s, --second-passphrase ', 'second passphrase of initial wallet') .option('--skip-validation', 'skip transaction validations', false) - .option('--recipient ', 'recipient address') .option('-c, --copy', 'copy the transactions to the clipboard', false) } registerCommand('transfer', 'send multiple transactions') + .option('--flood-attempts ', 'flood node with same transactions', 0) + .option('--recipient ', 'recipient address') .option('--skip-second-run', 'skip second sending of transactions', false) - .option('-f, --flood-attempts ', 'flood node with same transactions', 0) - .action(async (options) => require('../lib/commands/transfer')(options)) + .option('--smart-bridge ', 'smart-bridge value to use') + .action(async (options) => { + const command = await require('../lib/commands/transfer').init(options) + await command.run() + }) registerCommand('second-signature', 'create wallets with second signature') - .option('--signature-fee ', 'second signature fee', 500000000) - .action(async (options) => require('../lib/commands/second-signature')(options)) + .option('--signature-fee ', 'second signature fee', 5) + .action(async (options) => { + const command = await require('../lib/commands/second-signature').init(options) + await command.run() + }) -registerCommand('delegate', 'create multiple delegates') - .option('--delegate-fee ', 'delegate registration fee', 2500000000) - .action(async (options) => require('../lib/commands/delegate-registration')(options)) +registerCommand('delegate-registration', 'create multiple delegates') + .option('--delegate-fee ', 'delegate registration fee', 25) + .action(async (options) => { + const command = await require('../lib/commands/delegate-registration').init(options) + await command.run() + }) registerCommand('vote', 'create multiple votes for a delegate') - .option('--vote-fee ', 'vote fee', 100000000) + .option('--vote-fee ', 'vote fee', 1) .option('-d, --delegate ', 'delegate public key') - .option('-q, --quantity ', 'quantity of delegates to vote for if `-d` is omitted', 1) - .action(async (options) => require('../lib/commands/vote')(options)) + .action(async (options) => { + const command = await require('../lib/commands/vote').init(options) + await command.run() + }) -app - .command('multi-signatures') - .description('create multiple multisig wallets') - .option('--multisig-fee ', 'multisig fee', 500000000) - .option('-n, --number ', 'number of multisig wallets', 10) - .option('-m, --min ', 'minimum number of signatures per transaction') +registerCommand('multi-signature', 'create multiple multisig wallets') + .option('--multisig-fee ', 'multisig fee', 5) + .option('-m, --min ', 'minimum number of signatures per transaction', 2) .option('-l, --lifetime ', 'lifetime of transaction', 72) - .option('-q, --quantity ', 'number of signatures per wallet', 2) - .option('-c, --copy', 'copy the transactions to the clipboard', false) - .action(async (options) => require('../lib/commands/multi-signature')(options)) + .option('-q, --quantity ', 'number of signatures per wallet', 3) + .option('--skip-tests', 'skip transaction tests', false) + .action(async (options) => { + const command = await require('../lib/commands/multi-signature').init(options) + await command.run() + }) app .command('*') .action(env => { app.help() - process.exit(0) }) app.parse(process.argv) + +if (app.args.length === 0) { + app.help() +} diff --git a/packages/core-tester-cli/jest.config.js b/packages/core-tester-cli/jest.config.js index 26f7a25796..57770a97bb 100644 --- a/packages/core-tester-cli/jest.config.js +++ b/packages/core-tester-cli/jest.config.js @@ -1,22 +1,12 @@ -'use strict' - module.exports = { testEnvironment: 'node', bail: false, verbose: true, - testMatch: [ - '**/__tests__/**/*.test.js' - ], - moduleFileExtensions: [ - 'js', - 'json' - ], + testMatch: ['**/__tests__/**/*.test.js'], + moduleFileExtensions: ['js', 'json'], collectCoverage: false, coverageDirectory: '/.coverage', - collectCoverageFrom: [ - 'lib/**/*.js', - '!**/node_modules/**' - ], + collectCoverageFrom: ['lib/**/*.js', '!**/node_modules/**'], watchman: false, - setupTestFrameworkScriptFile: 'jest-extended' + setupTestFrameworkScriptFile: 'jest-extended', } diff --git a/packages/core-tester-cli/lib/commands/command.js b/packages/core-tester-cli/lib/commands/command.js new file mode 100644 index 0000000000..1d3d9adf98 --- /dev/null +++ b/packages/core-tester-cli/lib/commands/command.js @@ -0,0 +1,352 @@ +const { Bignum, crypto, formatArktoshi } = require('@arkecosystem/crypto') +const { bignumify } = require('@arkecosystem/core-utils') +const bip39 = require('bip39') +const clipboardy = require('clipboardy') +const delay = require('delay') +const fs = require('fs') +const path = require('path') +const pluralize = require('pluralize') +const config = require('../config') +const { logger, paginate, request } = require('../utils') + +module.exports = class Command { + /** + * Init new instance of command. + * @param {Object} options + * @return {*} + */ + static async init(options) { + const command = new this() + command.options = options + command.__applyConfig() + await command.__loadConstants() + await command.__loadNetworkConfig() + + return command + } + + /** + * Run command. + * @param {Object} options Used to pass options to TransferCommand + * @throws Method [run] not implemented! + */ + run(options) { + throw new Error('Method [run] not implemented!') + } + + /** + * Copy transactions to clipboard. + * @param {Object[]} transactions + * @return {void} + */ + copyToClipboard(transactions) { + for (const transaction of transactions) { + transaction.serialized = transaction.serialized.toString('hex') + } + + clipboardy.writeSync(JSON.stringify(transactions)) + logger.info(`Copied ${pluralize('transaction', transactions.length, true)}`) + } + + /** + * Generate wallets based on quantity. + * @param {Number} [quantity] + * @return {Object[]} + */ + generateWallets(quantity) { + if (!quantity) { + quantity = this.options.number + } + + const wallets = [] + for (let i = 0; i < quantity; i++) { + const passphrase = bip39.generateMnemonic() + const keys = crypto.getKeys(passphrase) + const address = crypto.getAddress( + keys.publicKey, + this.config.network.version, + ) + + wallets.push({ address, keys, passphrase }) + } + + const testWalletsPath = path.resolve(__dirname, '../../test-wallets') + fs.appendFileSync( + testWalletsPath, + `${new Date().toLocaleDateString()} ${'-'.repeat(70)}\n`, + ) + for (const wallet of wallets) { + fs.appendFileSync( + testWalletsPath, + `${wallet.address}: ${wallet.passphrase}\n`, + ) + } + + return wallets + } + + /** + * Get delegate API response. + * @return {Object[]} + * @throws 'Could not get delegates' + */ + async getDelegates() { + try { + const delegates = await paginate(this.config, '/api/v2/delegates') + + return delegates + } catch (error) { + const message = error.response + ? error.response.data.message + : error.message + throw new Error(`Could not get delegates: ${message}`) + } + } + + /** + * Determine how long to wait for transactions to process. + * @param {Object[]} transactions + * @return {Number} + */ + getTransactionDelaySeconds(transactions) { + const waitPerBlock = Math.round(this.config.constants.blocktime / 10) * 20 + + return ( + waitPerBlock * + Math.ceil( + transactions.length / this.config.constants.block.maxTransactions, + ) + ) + } + + /** + * Get transaction from API by ID. + * @param {String} id + * @return {(Object|null)} + */ + async getTransaction(id) { + try { + const response = await request(this.config).get( + `/api/v2/transactions/${id}`, + ) + + if (response.data) { + return response.data + } + } catch (error) { + // + } + + return null + } + + /** + * Get delegate voters by public key. + * @param {String} publicKey + * @return {Object[]} + */ + async getVoters(publicKey) { + try { + return paginate(this.config, `/api/v2/delegates/${publicKey}/voters`) + } catch (error) { + const message = error.response + ? error.response.data.message + : error.message + throw new Error(`Could not get voters for '${publicKey}': ${message}`) + } + } + + /** + * Get wallet balance by address. + * @param {String} address + * @return {Bignum} + */ + async getWalletBalance(address) { + try { + return bignumify((await this.getWallet(address)).balance) + } catch (error) { + // + } + + return Bignum.ZERO + } + + /** + * Get wallet by address. + * @param {String} address + * @return {Object} + */ + async getWallet(address) { + try { + const response = await request(this.config).get( + `/api/v2/wallets/${address}`, + ) + + if (response.data) { + return response.data + } + + return null + } catch (error) { + const message = error.response + ? error.response.data.message + : error.message + throw new Error(`Could not get wallet for '${address}': ${message}`) + } + } + + /** + * Parse fee based on input. + * @param {(String|Number)} fee + * @return {Bignum} + */ + static parseFee(fee) { + if (typeof fee === 'string' && fee.indexOf('-') !== -1) { + const feeRange = fee.split('-').map( + f => + +bignumify(f) + .times(1e8) + .toFixed(), + ) + if (feeRange[1] < feeRange[0]) { + return feeRange[0] + } + + return bignumify( + Math.floor( + Math.random() * (feeRange[1] - feeRange[0] + 1) + feeRange[0], + ), + ) + } + + return bignumify(fee).times(1e8) + } + + /** + * Send transactions to API and wait for response. + * @param {Object[]} transactions + * @param {String} [transactionType] + * @param {Boolean} [wait=true] + * @return {Object} + */ + async sendTransactions(transactions, transactionType, wait = true) { + const response = await this.postTransactions(transactions) + + if (wait) { + const delaySeconds = this.getTransactionDelaySeconds(transactions) + transactionType = `${ + transactionType ? `${transactionType} ` : '' + }transactions` + logger.info(`Waiting ${delaySeconds} seconds to apply ${transactionType}`) + await delay(delaySeconds * 1000) + } + + return response + } + + /** + * Send transactions to API. + * @param {Object[]} transactions + * @return {Object} + */ + async postTransactions(transactions) { + try { + const response = await request(this.config).post('/api/v2/transactions', { + transactions, + }) + return response.data + } catch (error) { + const message = error.response + ? error.response.data.message + : error.message + throw new Error(`Could not post transactions: ${message}`) + } + } + + /** + * Apply options to config. + * @return {void} + */ + __applyConfig() { + this.config = { ...config } + if (this.options.baseUrl) { + this.config.baseUrl = this.options.baseUrl.replace(/\/+$/, '') + } + + if (this.options.apiPort) { + this.config.apiPort = this.options.apiPort + } + + if (this.options.p2pPort) { + this.config.p2pPort = this.options.p2pPort + } + + if (this.options.passphrase) { + this.config.passphrase = this.options.passphrase + } + + if (this.options.secondPassphrase) { + this.config.secondPassphrase = this.options.secondPassphrase + } + } + + /** + * Load constants from API and apply to config. + * @return {void} + */ + async __loadConstants() { + try { + this.config.constants = (await request(this.config).get( + '/api/v2/node/configuration', + )).data.constants + } catch (error) { + logger.error('Failed to get constants: ', error.message) + process.exit(1) + } + } + + /** + * Load network from API and apply to config. + * @return {void} + */ + async __loadNetworkConfig() { + try { + this.config.network = (await request(this.config).get( + '/config', + true, + )).data.network + } catch (error) { + logger.error('Failed to get network config: ', error.message) + process.exit(1) + } + } + + /** + * Convert ARK to Arktoshi. + * @param {Number} ark + * @return {Bignum} + */ + static __arkToArktoshi(ark) { + return bignumify(ark * 1e8) + } + + /** + * Convert Arktoshi to ARK. + * @param {Bignum} arktoshi + * @return {String} + */ + static __arktoshiToArk(arktoshi) { + return formatArktoshi(arktoshi) + } + + /** + * Quit command and output error when problem sending transactions. + * @param {Error} error + * @return {void} + */ + __problemSendingTransactions(error) { + const message = error.response ? error.response.data.message : error.message + logger.error(`There was a problem sending transactions: ${message}`) + process.exit(1) + } +} diff --git a/packages/core-tester-cli/lib/commands/delegate-registration.js b/packages/core-tester-cli/lib/commands/delegate-registration.js index 285b88413c..72135756f5 100644 --- a/packages/core-tester-cli/lib/commands/delegate-registration.js +++ b/packages/core-tester-cli/lib/commands/delegate-registration.js @@ -1,78 +1,111 @@ -'use strict' - -const ark = require('arkjs') -const delay = require('delay') -const utils = require('../utils') -const config = require('../config') -const logger = utils.logger +const { client } = require('@arkecosystem/crypto') +const pluralize = require('pluralize') const superheroes = require('superheroes') -const transferCommand = require('./transfer') - -module.exports = async (options) => { - utils.applyConfigOptions(options) - - const wallets = utils.generateWallets(options.number) - await transferCommand(options, wallets, 50, true) - - const delegates = await utils.getDelegates() - - logger.info(`Sending ${options.number} delegate registration transactions`) - if (!options.skipValidation) { - logger.info(`Starting delegate count: ${delegates.length}`) - } - - const transactions = [] - const usedDelegateNames = delegates.map(delegate => delegate.username) - wallets.forEach((wallet, i) => { - wallet.username = superheroes.random() - - while (usedDelegateNames.includes(wallet.username)) { - wallet.username = superheroes.random() - } - - wallet.username = wallet.username.toLowerCase().replace(/ /g, '_') - usedDelegateNames.push(wallet.username) - - const transaction = ark.delegate.createDelegate( - wallet.passphrase, - wallet.username, - config.secondPassphrase, - utils.parseFee(options.delegateFee) +const { logger } = require('../utils') +const Command = require('./command') +const Transfer = require('./transfer') + +module.exports = class DelegateRegistrationCommand extends Command { + /** + * Run delegate-registration command. + * @return {void} + */ + async run() { + const wallets = this.generateWallets() + + const transfer = await Transfer.init(this.options) + await transfer.run({ + wallets, + amount: this.options.amount || 25, + skipTesting: true, + }) + + const delegates = await this.getDelegates() + + logger.info( + `Sending ${this.options.number} delegate registration ${pluralize( + 'transaction', + this.options.number, + )}`, ) - transactions.push(transaction) - - logger.info(`${i} ==> ${transaction.id}, ${wallet.address} (fee: ${transaction.fee}, username: ${wallet.username})`) - }) - - if (options.copy) { - utils.copyToClipboard(transactions) - process.exit() // eslint-disable-line no-unreachable - } - - const expectedDelegates = delegates.length + wallets.length - if (!options.skipValidation) { - logger.info(`Expected end delegate count: ${expectedDelegates}`) - } - - try { - await utils.postTransactions(transactions) + if (!this.options.skipValidation) { + logger.info(`Starting delegate count: ${delegates.length}`) + } - if (options.skipValidation) { + const transactions = [] + const usedDelegateNames = delegates.map(delegate => delegate.username) + + wallets.forEach((wallet, i) => { + while (!wallet.username || usedDelegateNames.includes(wallet.username)) { + wallet.username = superheroes.random() + } + + wallet.username = wallet.username.toLowerCase().replace(/ /g, '_') + usedDelegateNames.push(wallet.username) + + const transaction = client + .getBuilder() + .delegateRegistration() + .fee(Command.parseFee(this.options.delegateFee)) + .usernameAsset(wallet.username) + .network(this.config.network.version) + .sign(wallet.passphrase) + .secondSign(this.config.secondPassphrase) + .build() + + transactions.push(transaction) + + logger.info( + `${i} ==> ${transaction.id}, ${ + wallet.address + } (fee: ${Command.__arktoshiToArk(transaction.fee)}, username: ${ + wallet.username + })`, + ) + }) + + if (this.options.copy) { + this.copyToClipboard(transactions) return } - const delaySeconds = await utils.getTransactionDelay(transactions) - logger.info(`Waiting ${delaySeconds} seconds to apply delegate transactions`) - await delay(delaySeconds * 1000) - - const delegates = await utils.getDelegates() - logger.info(`All transactions have been sent! Total delegates: ${delegates.length}`) + const expectedDelegates = delegates.length + wallets.length + if (!this.options.skipValidation) { + logger.info(`Expected end delegate count: ${expectedDelegates}`) + } - if (delegates.length !== expectedDelegates) { - logger.error(`Delegate count incorrect. '${delegates.length}' but should be '${expectedDelegates}'`) + try { + await this.sendTransactions( + transactions, + 'delegate', + !this.options.skipValidation, + ) + + if (this.options.skipValidation) { + return + } + + const targetDelegates = await this.getDelegates() + logger.info( + `All transactions have been sent! Total delegates: ${ + targetDelegates.length + }`, + ) + + if (targetDelegates.length !== expectedDelegates) { + logger.error( + `Delegate count incorrect. '${ + targetDelegates.length + }' but should be '${expectedDelegates}'`, + ) + } + } catch (error) { + logger.error( + `There was a problem sending transactions: ${ + error.response ? error.response.data.message : error + }`, + ) } - } catch (error) { - logger.error(`There was a problem sending transactions: ${error.response ? error.response.data.message : error}`) } } diff --git a/packages/core-tester-cli/lib/commands/multi-signature.js b/packages/core-tester-cli/lib/commands/multi-signature.js index dc242f3e87..c7475c7329 100644 --- a/packages/core-tester-cli/lib/commands/multi-signature.js +++ b/packages/core-tester-cli/lib/commands/multi-signature.js @@ -1,384 +1,433 @@ -'use strict' +/* eslint no-await-in-loop: "off" */ + +const { client } = require('@arkecosystem/crypto') +const pluralize = require('pluralize') +const take = require('lodash/take') +const { logger } = require('../utils') +const Command = require('./command') +const Transfer = require('./transfer') + +module.exports = class MultiSignatureCommand extends Command { + /** + * Run multi-signature command. + * @return {void} + */ + async run() { + const approvalWallets = this.generateWallets(this.options.quantity) + const publicKeys = approvalWallets.map( + wallet => `+${wallet.keys.publicKey}`, + ) + const min = this.options.min + ? Math.min(this.options.min, publicKeys.length) + : publicKeys.length + + const testCosts = this.options.skipTests ? 1 : 2 + const wallets = this.generateWallets() + + const transfer = await Transfer.init(this.options) + await transfer.run({ + wallets, + amount: (publicKeys.length + 1) * 5 + testCosts, + skipTesting: true, + }) + + const transactions = this.generateTransactions( + wallets, + approvalWallets, + publicKeys, + min, + ) -const ark = require('arkjs') -const delay = require('delay') -const utils = require('../utils') -const logger = utils.logger -const transferCommand = require('./transfer') + if (this.options.copy) { + this.copyToClipboard(transactions) -module.exports = async (options) => { - const copyTransactions = options.copy - options.copy = false + return // eslint-disable-line no-unreachable + } - // Wallets for extra signatures - const approvalWallets = utils.generateWallets(options.quantity) - await transferCommand(options, approvalWallets, 20, true) + try { + const response = await this.sendTransactions( + transactions, + 'multi-signature', + !this.options.skipValidation, + ) - const publicKeys = approvalWallets.map(wallet => `+${wallet.keys.publicKey}`) + if (!this.options.skipValidation) { + let hasUnprocessed = false + for (const transaction of transactions) { + if (!response.accept.includes(transaction.id)) { + hasUnprocessed = true + logger.error( + `Multi-signature transaction '${ + transaction.id + }' was not processed`, + ) + } + } + if (hasUnprocessed) { + process.exit(1) + } - const min = options.min ? Math.min(options.min, publicKeys.length) : publicKeys.length + for (const transaction of transactions) { + const tx = await this.getTransaction(transaction.id) + if (!tx) { + logger.error( + `Transaction '${transaction.id}' should be on the blockchain`, + ) + } + } + } + } catch (error) { + const message = error.response + ? error.response.data.message + : error.message + logger.error( + `There was a problem sending multi-signature transactions: ${message}`, + ) + process.exit(1) + } - // Wallets with multi-signature - const multiSignatureWallets = utils.generateWallets(options.number) - await transferCommand(options, multiSignatureWallets, (publicKeys.length * 5) + 10, true) + if (this.options.skipTests || this.options.skipValidation) { + return + } - let transactions = [] - multiSignatureWallets.forEach((wallet, i) => { - const transaction = ark.multisignature.createMultisignature( - wallet.passphrase, - null, + await this.__testSendWithSignatures(transfer, wallets, approvalWallets) + await this.__testSendWithMinSignatures( + transfer, + wallets, + approvalWallets, + min, + ) + await this.__testSendWithBelowMinSignatures( + transfer, + wallets, + approvalWallets, + min, + ) + await this.__testSendWithoutSignatures(transfer, wallets) + await this.__testSendWithEmptySignatures(transfer, wallets) + await this.__testNewMultiSignatureRegistration( + wallets, + approvalWallets, publicKeys, - options.lifetime, min, - options.multisigFee ) - transaction.signatures = [] - for (let i = approvalWallets.length - 1; i >= 0; i--) { - const approverSignature = ark.multisignature.signTransaction( - transaction, - approvalWallets[i].passphrase - ) - transaction.signatures.push(approverSignature) - } - transactions.push(transaction) - - logger.info(`${i} ==> ${transaction.id}, ${wallet.address}`) - }) - - if (copyTransactions) { - utils.copyToClipboard(transactions) - process.exit() // eslint-disable-line no-unreachable } - try { - const response = await utils.postTransactions(transactions) - let hasUnprocessed = false - for (const transaction of transactions) { - if (!response.data.accept.includes(transaction.id)) { - hasUnprocessed = true - logger.error(`Multi-signature transaction '${transaction.id}' was not processed`) + /** + * Generate batch of transactions based on wallets + * @param {Object[]} wallets + * @param {Object[]} [approvalWallets=[]] + * @param {String[]} [publicKeys=[]] + * @param {Number} [min=2] + * @param {Boolean} [log=true] + * @return {Object[]} + */ + generateTransactions( + wallets, + approvalWallets = [], + publicKeys = [], + min = 2, + log = true, + ) { + const transactions = [] + wallets.forEach((wallet, i) => { + const builder = client.getBuilder().multiSignature() + + builder + .fee(Command.parseFee(this.options.multisigFee)) + .multiSignatureAsset({ + lifetime: this.options.lifetime, + keysgroup: publicKeys, + min, + }) + .network(this.config.network.version) + .sign(wallet.passphrase) + + if (wallet.secondPassphrase || this.config.secondPassphrase) { + builder.secondSign( + wallet.secondPassphrase || this.config.secondPassphrase, + ) } - } - if (hasUnprocessed) { - process.exit(1) - } - - const delaySeconds = await utils.getTransactionDelay(transactions) - logger.info(`Waiting ${delaySeconds} seconds to apply multi-signature transactions`) - await delay(delaySeconds * 1000) - for (const transaction of transactions) { - const tx = await utils.getTransaction(transaction.id) - if (!tx) { - logger.error(`Transaction '${transaction.id}' should be on the blockchain`) + if (approvalWallets) { + for (let j = approvalWallets.length - 1; j >= 0; j--) { + builder.multiSignatureSign(approvalWallets[j].passphrase) + } } - } - } catch (error) { - const message = error.response ? error.response.data.message : error.message - logger.error(`There was a problem sending multi-signature transactions: ${message}`) - process.exit(1) - } - await __testSendWithSignatures(multiSignatureWallets, approvalWallets) - await __testSendWithMinSignatures(multiSignatureWallets, approvalWallets, min) - await __testSendWithBelowMinSignatures(multiSignatureWallets, approvalWallets, min) - await __testSendWithoutSignatures(multiSignatureWallets) - await __testSendWithEmptySignatures(multiSignatureWallets) - await __testNewMultiSignatureRegistration(multiSignatureWallets, options) -} + const transaction = builder.build() + transactions.push(transaction) -/** - * Send transactions with approver signatures. - * @return {void} - */ -async function __testSendWithSignatures (multiSignatureWallets, approvalWallets) { - logger.info('Sending transactions with signatures') - - const transactions = [] - multiSignatureWallets.forEach((wallet, i) => { - const transaction = ark.transaction.createTransaction( - wallet.address, - 2, - `TID - with sigs: ${i}`, - wallet.passphrase - ) - transaction.signatures = [] - for (let j = approvalWallets.length - 1; j >= 0; j--) { - const approverSignature = ark.multisignature.signTransaction( - transaction, - approvalWallets[j].passphrase - ) - transaction.signatures.push(approverSignature) - } - transactions.push(transaction) + if (log) { + logger.info( + `${i} ==> ${transaction.id}, ${ + wallet.address + } (fee: ${Command.__arktoshiToArk(transaction.fee)})`, + ) + } + }) - logger.info(`${i} ==> ${transaction.id}, ${wallet.address}`) - }) + return transactions + } - try { - await utils.postTransactions(transactions) - const delaySeconds = await utils.getTransactionDelay(transactions) - logger.info(`Waiting ${delaySeconds} seconds to apply transactions`) - await delay(delaySeconds * 1000) + /** + * Send transactions with approver signatures. + * @param {TransferCommand} transfer + * @param {Object[]} wallets + * @param {Object[]} [approvalWallets=[]] + * @return {void} + */ + async __testSendWithSignatures(transfer, wallets, approvalWallets = []) { + logger.info('Sending transactions with signatures') + + const transactions = transfer.generateTransactions( + Command.__arkToArktoshi(2), + wallets, + approvalWallets, + ) - for (const transaction of transactions) { - const tx = await utils.getTransaction(transaction.id) - if (!tx) { - logger.error(`Transaction '${transactions.id}' should be on the blockchain`) + try { + await this.sendTransactions(transactions) + for (const transaction of transactions) { + const tx = await this.getTransaction(transaction.id) + if (!tx) { + logger.error( + `Transaction '${transaction.id}' should be on the blockchain`, + ) + } } + } catch (error) { + this.__problemSendingTransactions(error) } - } catch (error) { - const message = error.response ? error.response.data.message : error.message - logger.error(`There was a problem sending transactions: ${message}`) - process.exit(1) } -} -/** - * Send transactions with min approver signatures. - * @return {void} - */ -async function __testSendWithMinSignatures (multiSignatureWallets, approvalWallets, min) { - logger.info(`Sending transactions with ${min} (min) of ${approvalWallets.length} signatures`) - - const transactions = [] - multiSignatureWallets.forEach((wallet, i) => { - const transaction = ark.transaction.createTransaction( - wallet.address, - 2, - `TID - with ${min} sigs: ${i}`, - wallet.passphrase + /** + * Send transactions with min approver signatures. + * @param {TransferCommand} transfer + * @param {Object[]} wallets + * @param {Object[]} [approvalWallets=[]] + * @param {Number} [min=2] + * @return {void} + */ + async __testSendWithMinSignatures( + transfer, + wallets, + approvalWallets = [], + min = 2, + ) { + logger.info( + `Sending transactions with ${min} (min) of ${pluralize( + 'signature', + approvalWallets.length, + true, + )}`, ) - transaction.signatures = [] - for (let j = approvalWallets.length - 1; j >= 0; j--) { - const approverSignature = ark.multisignature.signTransaction( - transaction, - approvalWallets[j].passphrase - ) - transaction.signatures.push(approverSignature) - if (transaction.signatures.length === min) { - break - } - } - transactions.push(transaction) - - logger.info(`${i} ==> ${transaction.id}, ${wallet.address}`) - }) - try { - await utils.postTransactions(transactions) - const delaySeconds = await utils.getTransactionDelay(transactions) - logger.info(`Waiting ${delaySeconds} seconds to apply transactions`) - await delay(delaySeconds * 1000) + const transactions = transfer.generateTransactions( + Command.__arkToArktoshi(2), + wallets, + take(approvalWallets, min), + ) - for (const transaction of transactions) { - const tx = await utils.getTransaction(transaction.id) - if (!tx) { - logger.error(`Transaction '${transactions.id}' should be on the blockchain`) + try { + await this.sendTransactions(transactions) + for (const transaction of transactions) { + const tx = await this.getTransaction(transaction.id) + if (!tx) { + logger.error( + `Transaction '${transaction.id}' should be on the blockchain`, + ) + } } + } catch (error) { + this.__problemSendingTransactions(error) } - } catch (error) { - const message = error.response ? error.response.data.message : error.message - logger.error(`There was a problem sending transactions: ${message}`) - process.exit(1) } -} -/** - * Send transactions with below min approver signatures. - * @return {void} - */ -async function __testSendWithBelowMinSignatures (multiSignatureWallets, approvalWallets, min) { - const max = min - 1 - logger.info(`Sending transactions with ${max} (below min) of ${approvalWallets.length} signatures`) - - const transactions = [] - multiSignatureWallets.forEach((wallet, i) => { - const transaction = ark.transaction.createTransaction( - wallet.address, - 2, - `TID - with ${max} sigs: ${i}`, - wallet.passphrase + /** + * Send transactions with below min approver signatures. + * @param {TransferCommand} transfer + * @param {Object[]} wallets + * @param {Object[]} [approvalWallets=[]] + * @param {Number} [min=2] + * @return {void} + */ + async __testSendWithBelowMinSignatures( + transfer, + wallets, + approvalWallets = [], + min = 2, + ) { + const max = min - 1 + logger.info( + `Sending transactions with ${max} (below min) of ${pluralize( + 'signature', + approvalWallets.length, + true, + )}`, ) - transaction.signatures = [] - for (let j = approvalWallets.length - 1; j >= 0; j--) { - const approverSignature = ark.multisignature.signTransaction( - transaction, - approvalWallets[j].passphrase - ) - transaction.signatures.push(approverSignature) - if (transaction.signatures.length === max) { - break - } - } - transactions.push(transaction) - - logger.info(`${i} ==> ${transaction.id}, ${wallet.address}`) - }) - try { - await utils.postTransactions(transactions) - const delaySeconds = await utils.getTransactionDelay(transactions) - logger.info(`Waiting ${delaySeconds} seconds to apply transactions`) - await delay(delaySeconds * 1000) + const transactions = transfer.generateTransactions( + Command.__arkToArktoshi(2), + wallets, + take(approvalWallets, max), + ) - for (const transaction of transactions) { - try { - const tx = await utils.getTransaction(transaction.id) - if (tx) { - logger.error(`Transaction '${transactions.id}' should not be on the blockchain`) + try { + await this.sendTransactions(transactions) + for (const transaction of transactions) { + try { + const tx = await this.getTransaction(transaction.id) + if (tx) { + logger.error( + `Transaction '${transaction.id}' should not be on the blockchain`, + ) + } + } catch (error) { + const message = error.response + ? error.response.data.message + : error.message + if (message !== 'Transaction not found') { + logger.error( + `Failed to check transaction '${transaction.id}': ${message}`, + ) + } } - } catch (error) { - } + } catch (error) { + this.__problemSendingTransactions(error) } - } catch (error) { - const message = error.response ? error.response.data.message : error.message - logger.error(`There was a problem sending transactions: ${message}`) - process.exit(1) } -} -/** - * Send transactions without approver signatures. - * @return {void} - */ -async function __testSendWithoutSignatures (multiSignatureWallets) { - logger.info('Sending transactions without signatures') - - const transactions = [] - multiSignatureWallets.forEach((wallet, i) => { - const transaction = ark.transaction.createTransaction( - wallet.address, - 2, - `TID - without sigs: ${i}`, - wallet.passphrase + /** + * Send transactions without approver signatures. + * @param {TransferCommand} transfer + * @param {Object[]} wallets + * @return {void} + */ + async __testSendWithoutSignatures(transfer, wallets) { + logger.info('Sending transactions without signatures') + + const transactions = transfer.generateTransactions( + Command.__arkToArktoshi(2), + wallets, ) - transactions.push(transaction) - logger.info(`${i} ==> ${transaction.id}, ${wallet.address}`) - }) - - try { - await utils.postTransactions(transactions) - const delaySeconds = await utils.getTransactionDelay(transactions) - logger.info(`Waiting ${delaySeconds} seconds to apply transactions`) - await delay(delaySeconds * 1000) - - for (const transaction of transactions) { - try { - const tx = await utils.getTransaction(transaction.id) - if (tx) { - logger.error(`Transaction '${transactions.id}' should not be on the blockchain`) + try { + await this.sendTransactions(transactions) + for (const transaction of transactions) { + try { + const tx = await this.getTransaction(transaction.id) + if (tx) { + logger.error( + `Transaction '${transaction.id}' should not be on the blockchain`, + ) + } + } catch (error) { + const message = error.response + ? error.response.data.message + : error.message + if (message !== 'Transaction not found') { + logger.error( + `Failed to check transaction '${transaction.id}': ${message}`, + ) + } } - } catch (error) { - } + } catch (error) { + this.__problemSendingTransactions(error) } - } catch (error) { - const message = error.response ? error.response.data.message : error.message - logger.error(`There was a problem sending transactions: ${message}`) - process.exit(1) } -} -/** - * Send transactions with empty approver signatures. - * @return {void} - */ -async function __testSendWithEmptySignatures (multiSignatureWallets) { - logger.info('Sending transactions with empty signatures') - - const transactions = [] - multiSignatureWallets.forEach((wallet, i) => { - const transaction = ark.transaction.createTransaction( - wallet.address, - 2, - `TID - without sigs: ${i}`, - wallet.passphrase + /** + * Send transactions with empty approver signatures. + * @param {TransferCommand} transfer + * @param {Object[]} wallets + * @return {void} + */ + async __testSendWithEmptySignatures(transfer, wallets) { + logger.info('Sending transactions with empty signatures') + + const transactions = transfer.generateTransactions( + Command.__arkToArktoshi(2), + wallets, ) - transaction.signatures = [] - transactions.push(transaction) - - logger.info(`${i} ==> ${transaction.id}, ${wallet.address}`) - }) - - try { - await utils.postTransactions(transactions) - const delaySeconds = await utils.getTransactionDelay(transactions) - logger.info(`Waiting ${delaySeconds} seconds to apply transactions`) - await delay(delaySeconds * 1000) - for (const transaction of transactions) { - try { - const tx = await utils.getTransaction(transaction.id) - if (tx) { - logger.error(`Transaction '${transactions.id}' should not be on the blockchain`) - } - } catch (error) { + transaction.data.signatures = [] + } + try { + await this.sendTransactions(transactions) + for (const transaction of transactions) { + try { + const tx = await this.getTransaction(transaction.id) + if (tx) { + logger.error( + `Transaction '${transaction.id}' should not be on the blockchain`, + ) + } + } catch (error) { + const message = error.response + ? error.response.data.message + : error.message + if (message !== 'Transaction not found') { + logger.error( + `Failed to check transaction '${transaction.id}': ${message}`, + ) + } + } } + } catch (error) { + this.__problemSendingTransactions(error) } - } catch (error) { - const message = error.response ? error.response.data.message : error.message - logger.error(`There was a problem sending transactions: ${message}`) - process.exit(1) } -} -/** - * Send transactions to re-register multi-signature wallets. - * @return {void} - */ -async function __testNewMultiSignatureRegistration (multiSignatureWallets, options) { - logger.info('Sending transactions to re-register multi-signature') - - const transactions = [] - const approvalWallets = utils.generateWallets(options.quantity) - const publicKeys = approvalWallets.map(wallet => `+${wallet.keys.publicKey}`) - const min = options.min ? Math.min(options.min, publicKeys.length) : publicKeys.length - - multiSignatureWallets.forEach((wallet, i) => { - const transaction = ark.multisignature.createMultisignature( - wallet.passphrase, - null, + /** + * Send transactions to re-register multi-signature wallets. + * @param {Object[]} wallets + * @param {Object[]} [approvalWallets=[]] + * @param {Object[]} [publicKeys=[]] + * @param {Number} [min=2] + * @return {void} + */ + async __testNewMultiSignatureRegistration( + wallets, + approvalWallets = [], + publicKeys = [], + min = 2, + ) { + logger.info('Sending transactions to re-register multi-signature') + + const transactions = this.generateTransactions( + wallets, + approvalWallets, publicKeys, - options.lifetime, min, - options.multisigFee ) - transaction.signatures = [] - for (let i = approvalWallets.length - 1; i >= 0; i--) { - const approverSignature = ark.multisignature.signTransaction( - transaction, - approvalWallets[i].passphrase - ) - transaction.signatures.push(approverSignature) - } - transactions.push(transaction) - logger.info(`${i} ==> ${transaction.id}, ${wallet.address}`) - }) - - try { - await utils.postTransactions(transactions) - const delaySeconds = await utils.getTransactionDelay(transactions) - logger.info(`Waiting ${delaySeconds} seconds to apply transactions`) - await delay(delaySeconds * 1000) - - for (const transaction of transactions) { - try { - const tx = await utils.getTransaction(transaction.id) - if (tx) { - logger.error(`Transaction '${transactions.id}' should not be on the blockchain`) + try { + await this.sendTransactions(transactions) + for (const transaction of transactions) { + try { + const tx = await this.getTransaction(transaction.id) + if (tx) { + logger.error( + `Transaction '${transaction.id}' should not be on the blockchain`, + ) + } + } catch (error) { + const message = error.response + ? error.response.data.message + : error.message + if (message !== 'Transaction not found') { + logger.error( + `Failed to check transaction '${transaction.id}': ${message}`, + ) + } } - } catch (error) { - } + } catch (error) { + this.__problemSendingTransactions(error) } - } catch (error) { - const message = error.response ? error.response.data.message : error.message - logger.error(`There was a problem sending transactions: ${message}`) - process.exit(1) } } diff --git a/packages/core-tester-cli/lib/commands/second-signature.js b/packages/core-tester-cli/lib/commands/second-signature.js index 47c8408f27..264ac809d8 100644 --- a/packages/core-tester-cli/lib/commands/second-signature.js +++ b/packages/core-tester-cli/lib/commands/second-signature.js @@ -1,61 +1,89 @@ -'use strict' +/* eslint no-await-in-loop: "off" */ -const ark = require('arkjs') -const config = require('../config') -const delay = require('delay') -const utils = require('../utils') -const logger = utils.logger -const transferCommand = require('./transfer') +const { client } = require('@arkecosystem/crypto') +const pluralize = require('pluralize') +const { logger } = require('../utils') +const Command = require('./command') +const Transfer = require('./transfer') -module.exports = async (options) => { - utils.applyConfigOptions(options) +module.exports = class DelegateRegistrationCommand extends Command { + /** + * Run second-signature command. + * @return {void} + */ + async run() { + const wallets = this.generateWallets() - const wallets = utils.generateWallets(options.number) - await transferCommand(options, wallets, 50, true) + const transfer = await Transfer.init(this.options) + await transfer.run({ + wallets, + amount: this.options.amount || 5, + skipTesting: true, + }) - logger.info(`Sending ${options.number} second signature transactions`) - - const transactions = [] - wallets.forEach((wallet, i) => { - wallet.secondPassphrase = config.secondPassphrase || wallet.passphrase - - const transaction = ark.signature.createSignature( - wallet.passphrase, - wallet.secondPassphrase, - utils.parseFee(options.signatureFee) + logger.info( + `Sending ${this.options.number} second signature ${pluralize( + 'transaction', + this.options.number, + )}`, ) - wallet.publicKey = transaction.senderPublicKey - wallet.secondPublicKey = transaction.asset.signature.publicKey - transactions.push(transaction) - - logger.info(`${i} ==> ${transaction.id}, ${wallet.address} (fee: ${transaction.fee})`) - }) + const transactions = [] + wallets.forEach((wallet, i) => { + wallet.secondPassphrase = + this.config.secondPassphrase || wallet.passphrase + const transaction = client + .getBuilder() + .secondSignature() + .fee(Command.parseFee(this.options.signatureFee)) + .signatureAsset(wallet.secondPassphrase) + .network(this.config.network.version) + .sign(wallet.passphrase) + .build() - if (options.copy) { - utils.copyToClipboard(transactions) - process.exit() // eslint-disable-line no-unreachable - } + wallet.publicKey = transaction.senderPublicKey + wallet.secondPublicKey = transaction.asset.signature.publicKey + transactions.push(transaction) - try { - await utils.postTransactions(transactions) + logger.info( + `${i} ==> ${transaction.id}, ${ + wallet.address + } (fee: ${Command.__arktoshiToArk(transaction.fee)})`, + ) + }) - if (options.skipValidation) { + if (this.options.copy) { + this.copyToClipboard(transactions) return } - const delaySeconds = await utils.getTransactionDelay(transactions) - logger.info(`Waiting ${delaySeconds} seconds to apply signature transactions`) - await delay(delaySeconds * 1000) + try { + await this.sendTransactions( + transactions, + 'second-signature', + !this.options.skipValidation, + ) + + if (this.options.skipValidation) { + return + } - for (const walletObject of wallets) { - const wallet = await utils.getWallet(walletObject.address) + for (const walletObject of wallets) { + const wallet = await this.getWallet(walletObject.address) - if (wallet.secondPublicKey !== walletObject.secondPublicKey || wallet.publicKey !== walletObject.publicKey) { - logger.error(`Invalid second signature for ${walletObject.address}.`) + if ( + wallet.secondPublicKey !== walletObject.secondPublicKey || + wallet.publicKey !== walletObject.publicKey + ) { + logger.error(`Invalid second signature for ${walletObject.address}.`) + } } + } catch (error) { + logger.error( + `There was a problem sending transactions: ${ + error.response ? error.response.data.message : error + }`, + ) } - } catch (error) { - logger.error(`There was a problem sending transactions: ${error.response ? error.response.data.message : error}`) } } diff --git a/packages/core-tester-cli/lib/commands/transfer.js b/packages/core-tester-cli/lib/commands/transfer.js index 107d4ecee8..939b86ff16 100644 --- a/packages/core-tester-cli/lib/commands/transfer.js +++ b/packages/core-tester-cli/lib/commands/transfer.js @@ -1,185 +1,403 @@ -'use strict' +/* eslint no-await-in-loop: "off" */ -const ark = require('arkjs') -const config = require('../config') +const { Bignum, client, crypto } = require('@arkecosystem/crypto') const delay = require('delay') +const pluralize = require('pluralize') const unique = require('lodash/uniq') -const utils = require('../utils') -const logger = utils.logger - -const primaryAddress = ark.crypto.getAddress(ark.crypto.getKeys(config.passphrase).publicKey) -const sendTransactionsWithResults = async (transactions, wallets, transactionAmount, expectedSenderBalance, options, isSubsequentRun) => { - let successfulTest = true - - let postResponse - try { - postResponse = await utils.postTransactions(transactions) - } catch (error) { - if (options.skipValidation) { - return true +const { logger } = require('../utils') +const Command = require('./command') + +module.exports = class TransferCommand extends Command { + /** + * Run transfer command. + * @param {Object} options + * @return {void} + */ + async run(options) { + this.options = { ...this.options, ...options } + + const primaryAddress = crypto.getAddress( + crypto.getKeys(this.config.passphrase).publicKey, + this.config.network.version, + ) + + let wallets = this.options.wallets + if (wallets === undefined) { + wallets = this.generateWallets() } - const message = error.response ? error.response.data.error : error.message - logger.error(`Transaction request failed. Error: ${message}`) - return false - } + logger.info( + `Sending ${wallets.length} transfer ${pluralize( + 'transaction', + wallets.length, + )}`, + ) - if (options.skipValidation) { - return true - } + const walletBalance = await this.getWalletBalance(primaryAddress) - if (!isSubsequentRun && !postResponse.data.accept.length) { - return false - } + if (!this.options.skipValidation) { + logger.info( + `Sender starting balance: ${Command.__arktoshiToArk(walletBalance)}`, + ) + } - if (!isSubsequentRun) { - for (const transaction of transactions) { - if (!postResponse.data.accept.includes(transaction.id)) { - logger.error(`Transaction '${transaction.id}' didn't get approved on the network`) + let totalDeductions = Bignum.ZERO + const transactionAmount = Command.__arkToArktoshi(this.options.amount || 2) - successfulTest = false - } + const transactions = this.generateTransactions( + transactionAmount, + wallets, + null, + true, + ) + for (const transaction of transactions) { + totalDeductions = totalDeductions + .plus(transactionAmount) + .plus(transaction.fee) } - } - for (const key of Object.keys(postResponse.data)) { - if (key === 'success') { - continue + if (this.options.copy) { + this.copyToClipboard(transactions) + return } - const dataLength = postResponse.data[key].length - const uniqueLength = unique(postResponse.data[key]).length - if (dataLength !== uniqueLength) { - logger.error(`Response data for '${key}' has ${dataLength - uniqueLength} duplicate transaction ids`) - successfulTest = false + const expectedSenderBalance = new Bignum(walletBalance).minus( + totalDeductions, + ) + if (!this.options.skipValidation) { + logger.info( + `Sender expected ending balance: ${Command.__arktoshiToArk( + expectedSenderBalance, + )}`, + ) } - } - const delaySeconds = await utils.getTransactionDelay(transactions) - logger.info(`Waiting ${delaySeconds} seconds for node to process and forge transfer transactions`) - await delay(delaySeconds * 1000) + const runOptions = { + primaryAddress, + transactions, + wallets, + transactionAmount, + expectedSenderBalance, + skipValidation: this.options.skipValidation, + } - for (const transaction of transactions) { - const transactionResponse = await utils.getTransaction(transaction.id) - if (transactionResponse && transactionResponse.id !== transaction.id) { - logger.error(`Transaction '${transaction.id}' didn't get applied on the network`) + try { + if (!this.options.floodAttempts) { + const successfulTest = await this.__performRun(runOptions, 1) + if ( + successfulTest && + !this.options.skipSecondRun && + !this.options.skipValidation && + !this.options.skipTesting + ) { + await this.__performRun(runOptions, 2, false, true) + } + } else { + const attempts = this.options.floodAttempts + for (let i = attempts; i > 0; i--) { + await this.__performRun( + runOptions, + attempts - i + 1, + i !== 1, + i !== attempts, + ) + } + } + } catch (error) { + const message = error.response ? error.response.data.message : error + logger.error(`There was a problem sending transactions: ${message}`) + } - successfulTest = false + if (this.options.skipValidation) { + return } + + await this.__testVendorField(wallets) + await this.__testEmptyVendorField(wallets) } - const walletBalance = await utils.getWalletBalance(primaryAddress) - if (walletBalance !== expectedSenderBalance) { - successfulTest = false - logger.error(`Sender balance incorrect: '${walletBalance}' but should be '${expectedSenderBalance}'`) + /** + * Generate batch of transactions based on wallets. + * @param {Bignum} transactionAmount + * @param {Object[]} wallets + * @param {Object[]} [approvalWallets=[]] + * @param {Boolean} [overridePassphrase=false] + * @param {String} [vendorField] + * @param {Boolean} [log=true] + * @return {Object[]} + */ + generateTransactions( + transactionAmount, + wallets, + approvalWallets = [], + overridePassphrase = false, + vendorField, + log = true, + ) { + vendorField = vendorField || this.options.smartBridge + const transactions = [] + wallets.forEach((wallet, i) => { + const builder = client.getBuilder().transfer() + // noinspection JSCheckFunctionSignatures + builder + .fee(Command.parseFee(this.options.transferFee)) + .recipientId(this.options.recipient || wallet.address) + .network(this.config.network.version) + .amount(transactionAmount) + .vendorField( + vendorField === undefined ? `Transaction ${i + 1}` : vendorField, + ) + .sign(overridePassphrase ? this.config.passphrase : wallet.passphrase) + + if (wallet.secondPassphrase || this.config.secondPassphrase) { + builder.secondSign( + wallet.secondPassphrase || this.config.secondPassphrase, + ) + } + + if (approvalWallets) { + for (let j = approvalWallets.length - 1; j >= 0; j--) { + builder.multiSignatureSign(approvalWallets[j].passphrase) + } + } + + const transaction = builder.build() + transactions.push(transaction) + + if (log) { + logger.info( + `${i} ==> ${transaction.id}, ${ + transaction.recipientId + } (fee: ${Command.__arktoshiToArk(transaction.fee)})`, + ) + } + }) + + return transactions } - wallets.forEach(async wallet => { - const balance = await utils.getWalletBalance(wallet.address) + /** + * Perform a run of transactions. + * @param {Object} runOptions + * @param {Number} [runNumber=1] + * @param {Boolean} [skipWait=false] + * @param {Boolean} [isSubsequentRun=false] + * @return {Boolean} + */ + async __performRun( + runOptions, + runNumber = 1, + skipWait = false, + isSubsequentRun = false, + ) { + if (skipWait) { + runOptions.skipValidation = true + this.__sendTransactionsWithResults(runOptions, isSubsequentRun) - if (balance !== transactionAmount) { - successfulTest = false - logger.error(`Incorrect destination balance for ${wallet.address}. Should be '${transactionAmount}' but is '${balance}'`) + return } - }) - return successfulTest -} + if (await this.__sendTransactionsWithResults(runOptions, isSubsequentRun)) { + logger.info( + `All transactions have been received and forged for run ${runNumber}!`, + ) -module.exports = async (options, wallets, arkPerTransaction, skipTestingAgain) => { - utils.applyConfigOptions(options) + return true + } - if (wallets === undefined) { - wallets = utils.generateWallets(options.number) - } - const walletBalance = await utils.getWalletBalance(primaryAddress) + logger.error(`Test failed on run ${runNumber}`) - logger.info(`Sending ${options.number} transfer transactions`) - if (!options.skipValidation) { - logger.info(`Sender starting balance: ${walletBalance}`) + return false } - const transactions = [] - let totalDeductions = 0 - let transactionAmount = (arkPerTransaction || 2) * Math.pow(10, 8) + /** + * Send transactions and validate results. + * @param {Object} runOptions + * @param {Boolean} isSubsequentRun + * @return {Boolean} + */ + async __sendTransactionsWithResults(runOptions, isSubsequentRun) { + let successfulTest = true + + let postResponse + try { + postResponse = await this.postTransactions(runOptions.transactions) + } catch (error) { + if (runOptions.skipValidation) { + return true + } - if (!arkPerTransaction && options.amount) { - transactionAmount = options.amount - } + const message = error.response ? error.response.data.error : error.message + logger.error(`Transaction request failed: ${message}`) - for (const id in wallets) { - const wallet = wallets[id] - const transaction = ark.transaction.createTransaction( - options.recipient || wallet.address, - transactionAmount, - `TID: ${id}`, - config.passphrase, - wallet.secondPassphrase || config.secondPassphrase, - config.publicKeyHash, - utils.parseFee(options.transferFee) - ) - transactions.push(transaction) - totalDeductions += transactionAmount + transaction.fee + return false + } - logger.info(`${id} ==> ${transaction.id}, ${options.recipient || wallet.address} (fee: ${transaction.fee})`) - } + if (runOptions.skipValidation) { + return true + } - if (options.copy) { - utils.copyToClipboard(transactions) - process.exit() // eslint-disable-line no-unreachable - } + if (!isSubsequentRun && !postResponse.accept.length) { + return false + } - const expectedSenderBalance = walletBalance - totalDeductions - if (!options.skipValidation) { - logger.info(`Sender expected ending balance: ${expectedSenderBalance}`) - } + if (!isSubsequentRun) { + for (const transaction of runOptions.transactions) { + if (!postResponse.accept.includes(transaction.id)) { + logger.error( + `Transaction '${ + transaction.id + }' didn't get approved on the network`, + ) + + successfulTest = false + } + } + } - const performRun = async (run, skipWait, isSubsequentRun) => { - if (skipWait) { - sendTransactionsWithResults( - transactions, - wallets, - transactionAmount, - expectedSenderBalance, - Object.assign({skipValidation: true}, options), - isSubsequentRun + for (const key of Object.keys(postResponse)) { + if (key === 'success') { + continue + } + + const dataLength = postResponse[key].length + const uniqueLength = unique(postResponse[key]).length + if (dataLength !== uniqueLength) { + logger.error( + `Response data for '${key}' has ${dataLength - + uniqueLength} duplicate transaction ids`, + ) + successfulTest = false + } + } + + const delaySeconds = this.getTransactionDelaySeconds( + runOptions.transactions, + ) + logger.info( + `Waiting ${delaySeconds} seconds to apply transfer transactions`, + ) + await delay(delaySeconds * 1000) + + for (const transaction of runOptions.transactions) { + const transactionResponse = await this.getTransaction(transaction.id) + if (transactionResponse && transactionResponse.id !== transaction.id) { + logger.error( + `Transaction '${transaction.id}' didn't get applied on the network`, + ) + + successfulTest = false + } + } + + if (runOptions.primaryAddress && runOptions.expectedSenderBalance) { + const walletBalance = await this.getWalletBalance( + runOptions.primaryAddress, ) + if (!walletBalance.isEqualTo(runOptions.expectedSenderBalance)) { + successfulTest = false + logger.error( + `Sender balance incorrect: '${Command.__arktoshiToArk( + walletBalance, + )}' but should be '${Command.__arktoshiToArk( + runOptions.expectedSenderBalance, + )}'`, + ) + } + } - return + for (const wallet of runOptions.wallets) { + const balance = await this.getWalletBalance(wallet.address) + if (!balance.isEqualTo(runOptions.transactionAmount)) { + successfulTest = false + logger.error( + `Incorrect destination balance for ${ + wallet.address + }. Should be '${Command.__arktoshiToArk( + runOptions.transactionAmount, + )}' but is '${Command.__arktoshiToArk(balance)}'`, + ) + } } - let successfulTest = await sendTransactionsWithResults( - transactions, + return successfulTest + } + + /** + * Test vendor field is set correctly on blockchain. + * @param {Object[]} wallets + * @return {void} + */ + async __testVendorField(wallets) { + logger.info('Testing VendorField value is set correctly') + + const transactions = this.generateTransactions( + Command.__arkToArktoshi(2), wallets, - transactionAmount, - expectedSenderBalance, - options, - isSubsequentRun + null, + null, + 'Testing VendorField', ) - if (!successfulTest) { - logger.error(`Test failed on run ${run}`) - } else { - logger.info(`All transactions have been received and forged for run ${run}!`) + try { + await this.sendTransactions(transactions) + + for (const transaction of transactions) { + const tx = await this.getTransaction(transaction.id) + if (!tx) { + logger.error( + `Transaction '${transaction.id}' should be on the blockchain`, + ) + } + if (tx.vendorField !== 'Testing VendorField') { + logger.error( + `Transaction '${ + transaction.id + }' does not have correct vendorField value`, + ) + } + } + } catch (error) { + this.__problemSendingTransactions(error) } } - try { - if (!options.floodAttempts) { - const successfulTest = await performRun(1) + /** + * Test empty vendor field is set correctly on blockchain. + * @param {Object[]} wallets + * @return {void} + */ + async __testEmptyVendorField(wallets) { + logger.info('Testing empty VendorField value') - if (successfulTest && !options.skipSecondRun && !options.skipValidation && !skipTestingAgain) { - await performRun(2, true, true) - } - } else { - let i = 0 - for (; i < options.floodAttempts; i++) { - performRun(i + 1, true, (i > 0)) - } + const transactions = this.generateTransactions( + Command.__arkToArktoshi(2), + wallets, + null, + null, + null, + ) - await performRun(i + 1, false, (i > 0)) + try { + await this.sendTransactions(transactions) + + for (const transaction of transactions) { + const tx = await this.getTransaction(transaction.id) + if (!tx) { + logger.error( + `Transaction '${transaction.id}' should be on the blockchain`, + ) + } + if (tx.vendorField) { + logger.error( + `Transaction '${ + transaction.id + }' should not have vendorField value '${tx.vendorField}'`, + ) + } + } + } catch (error) { + this.__problemSendingTransactions(error) } - } catch (error) { - logger.error(`There was a problem sending transactions: ${error.response ? error.response.data.message : error}`) } } diff --git a/packages/core-tester-cli/lib/commands/vote.js b/packages/core-tester-cli/lib/commands/vote.js index d49b04a8bb..638d016ae9 100644 --- a/packages/core-tester-cli/lib/commands/vote.js +++ b/packages/core-tester-cli/lib/commands/vote.js @@ -1,74 +1,102 @@ -'use strict' - -const ark = require('arkjs') -const delay = require('delay') +const { client } = require('@arkecosystem/crypto') +const pluralize = require('pluralize') const sample = require('lodash/sample') -const utils = require('../utils') -const config = require('../config') -const logger = utils.logger -const transferCommand = require('./transfer') +const { logger } = require('../utils') +const Command = require('./command') +const Transfer = require('./transfer') -module.exports = async (options) => { - utils.applyConfigOptions(options) +module.exports = class VoteCommand extends Command { + /** + * Run vote command. + * @return {void} + */ + async run() { + const wallets = this.generateWallets() - const wallets = utils.generateWallets(options.quantity) - await transferCommand(options, wallets, 2, true) + const transfer = await Transfer.init(this.options) + await transfer.run({ + wallets, + amount: 2, + skipTesting: true, + }) - if (!options.delegate) { - const delegates = await utils.getDelegates() - if (!delegates.length) { - logger.error('Could not find any delegates to vote for') - process.exit(1) + let delegate = this.options.delegate + if (!delegate) { + try { + delegate = sample(await this.getDelegates()).publicKey + } catch (error) { + logger.error(error) + return + } } - options.delegate = sample(delegates).publicKey - } - let voters = await utils.getVoters(options.delegate) - - logger.info(`Sending ${options.quantity} vote transactions`) - - const transactions = [] - wallets.forEach((wallet, i) => { - const transaction = ark.vote.createVote( - wallet.passphrase, - [`+${options.delegate}`], - config.secondPassphrase, - utils.parseFee(options.voteFee) + const voters = await this.getVoters(delegate) + logger.info( + `Sending ${this.options.number} vote ${pluralize( + 'transaction', + this.options.number, + )}`, ) - transactions.push(transaction) - logger.info(`${i} ==> ${transaction.id}, ${wallet.address} (fee: ${transaction.fee})`) - }) + const transactions = [] + wallets.forEach((wallet, i) => { + const transaction = client + .getBuilder() + .vote() + .fee(Command.parseFee(this.options.voteFee)) + .votesAsset([`+${delegate}`]) + .network(this.config.network.version) + .sign(wallet.passphrase) + .secondSign(this.config.secondPassphrase) + .build() - if (options.copy) { - utils.copyToClipboard(transactions) - process.exit() // eslint-disable-line no-unreachable - } + transactions.push(transaction) - const expectedVoters = voters.length + wallets.length - if (!options.skipValidation) { - logger.info(`Expected end voters: ${expectedVoters}`) - } - try { - await utils.postTransactions(transactions) + logger.info( + `${i} ==> ${transaction.id}, ${ + wallet.address + } (fee: ${Command.__arktoshiToArk(transaction.fee)})`, + ) + }) - if (options.skipValidation) { + if (this.options.copy) { + this.copyToClipboard(transactions) return } - const delaySeconds = await utils.getTransactionDelay(transactions) - logger.info(`Waiting ${delaySeconds} seconds to apply vote transactions`) - await delay(delaySeconds * 1000) + const expectedVoterCount = voters.length + wallets.length + if (!this.options.skipValidation) { + logger.info(`Expected end voters: ${expectedVoterCount}`) + } + + try { + await this.sendTransactions( + transactions, + 'vote', + !this.options.skipValidation, + ) + + if (this.options.skipValidation) { + return + } - let voters = 0 - voters += (await utils.getVoters(options.delegate)).length + const voterCount = (await this.getVoters(delegate)).length - logger.info(`All transactions have been sent! Total voters: ${voters}`) + logger.info( + `All transactions have been sent! Total voters: ${voterCount}`, + ) - if (voters !== expectedVoters) { - logger.error(`Delegate voter count incorrect. '${voters}' but should be '${expectedVoters}'`) + if (voterCount !== expectedVoterCount) { + logger.error( + `Delegate voter count incorrect. '${voterCount}' but should be '${expectedVoterCount}'`, + ) + } + } catch (error) { + logger.error( + `There was a problem sending transactions: ${ + error.response ? error.response.data.message : error + }`, + ) } - } catch (error) { - logger.error(`There was a problem sending transactions: ${error.response ? error.response.data.message : error}`) } } diff --git a/packages/core-tester-cli/lib/config/index.js b/packages/core-tester-cli/lib/config/index.js index 81380b1d97..92eb0eb0e2 100644 --- a/packages/core-tester-cli/lib/config/index.js +++ b/packages/core-tester-cli/lib/config/index.js @@ -1,19 +1,10 @@ -'use strict' - const config = { - baseUrlApi: 'http://localhost:4003', - baseUrlP2P: 'http://localhost:4000', - passphrase: 'prison tobacco acquire stone dignity palace note decade they current lesson robot', - secondPassPhrase: '', - publicKeyHash: 23, - requestHeaders: { - nethash: 'd9acd04bde4234a81addb8482333b4ac906bed7be5a9970ce8ada428bd083192', - version: '1.0.1', - port: 4000 - }, - transactionWaitDelay: 15 + apiPort: 4003, + p2pPort: 4000, + baseUrl: 'http://localhost', + passphrase: + 'prison tobacco acquire stone dignity palace note decade they current lesson robot', + secondPassphrase: '', } -require('arkjs').crypto.setNetworkVersion(config.publicKeyHash) - -module.exports = config +module.exports = Object.freeze(config) diff --git a/packages/core-tester-cli/lib/utils/apply-config-options.js b/packages/core-tester-cli/lib/utils/apply-config-options.js deleted file mode 100644 index 3eb70626e4..0000000000 --- a/packages/core-tester-cli/lib/utils/apply-config-options.js +++ /dev/null @@ -1,11 +0,0 @@ -const config = require('../config') - -module.exports = (options) => { - if (options.baseApi) { - config.baseUrlApi = options.baseApi - } - - if (options.baseP2p) { - config.baseUrlP2P = options.baseP2p - } -} diff --git a/packages/core-tester-cli/lib/utils/copy-to-clipboard.js b/packages/core-tester-cli/lib/utils/copy-to-clipboard.js deleted file mode 100644 index bdeeddf8c8..0000000000 --- a/packages/core-tester-cli/lib/utils/copy-to-clipboard.js +++ /dev/null @@ -1,8 +0,0 @@ -const clipboardy = require('clipboardy') -const logger = require('./logger') - -module.exports = (transactions) => { - clipboardy.writeSync(JSON.stringify(transactions)) - - logger.info(`Copied ${transactions.length} transactions`) -} diff --git a/packages/core-tester-cli/lib/utils/generate-wallets.js b/packages/core-tester-cli/lib/utils/generate-wallets.js deleted file mode 100644 index d4565ff48d..0000000000 --- a/packages/core-tester-cli/lib/utils/generate-wallets.js +++ /dev/null @@ -1,16 +0,0 @@ -const bip39 = require('bip39') -const { crypto } = require('arkjs') - -module.exports = (quantity = 1) => { - let wallets = [] - - for (let i = 0; i < quantity; i++) { - const passphrase = bip39.generateMnemonic() - const keys = crypto.getKeys(passphrase) - const address = crypto.getAddress(keys.publicKey) - - wallets.push({ address, keys, passphrase }) - } - - return wallets -} diff --git a/packages/core-tester-cli/lib/utils/get-constants.js b/packages/core-tester-cli/lib/utils/get-constants.js deleted file mode 100644 index 637bd7ae72..0000000000 --- a/packages/core-tester-cli/lib/utils/get-constants.js +++ /dev/null @@ -1,11 +0,0 @@ -const request = require('./request') -const logger = require('./logger') - -module.exports = async () => { - try { - return (await request.get('/api/v2/node/configuration')).data.data.constants - } catch (error) { - logger.error(`Failed to get constants: ${error.message}`) - return {} - } -} diff --git a/packages/core-tester-cli/lib/utils/get-delegates.js b/packages/core-tester-cli/lib/utils/get-delegates.js deleted file mode 100644 index 491bcbec87..0000000000 --- a/packages/core-tester-cli/lib/utils/get-delegates.js +++ /dev/null @@ -1,12 +0,0 @@ -const paginate = require('./paginate') - -module.exports = async (publicKey) => { - try { - const delegates = await paginate('/api/v2/delegates') - - return delegates - } catch (error) { - } - - return [] -} diff --git a/packages/core-tester-cli/lib/utils/get-transaction-delay.js b/packages/core-tester-cli/lib/utils/get-transaction-delay.js deleted file mode 100644 index 7d527ea626..0000000000 --- a/packages/core-tester-cli/lib/utils/get-transaction-delay.js +++ /dev/null @@ -1,9 +0,0 @@ -const config = require('../config') -const getConstants = require('./get-constants') - -module.exports = async (transactions) => { - const constants = await getConstants() - const waitPerBlock = (Math.round(constants.blocktime / 10) * 10) - - return Math.max(config.transactionWaitDelay, waitPerBlock * (transactions.length / constants.block.maxTransactions)) -} diff --git a/packages/core-tester-cli/lib/utils/get-transaction.js b/packages/core-tester-cli/lib/utils/get-transaction.js deleted file mode 100644 index 7bfda3eaa0..0000000000 --- a/packages/core-tester-cli/lib/utils/get-transaction.js +++ /dev/null @@ -1,11 +0,0 @@ -const request = require('./request') - -module.exports = async (id) => { - const response = (await request.get(`/api/v2/transactions/${id}`)).data - - if (response.data) { - return response.data - } - - return null -} diff --git a/packages/core-tester-cli/lib/utils/get-voters.js b/packages/core-tester-cli/lib/utils/get-voters.js deleted file mode 100644 index 8d42942246..0000000000 --- a/packages/core-tester-cli/lib/utils/get-voters.js +++ /dev/null @@ -1,12 +0,0 @@ -const paginate = require('./paginate') - -module.exports = async (publicKey) => { - try { - const voters = await paginate(`/api/v2/delegates/${publicKey}/voters`) - - return voters - } catch (error) { - } - - return [] -} diff --git a/packages/core-tester-cli/lib/utils/get-wallet-balance.js b/packages/core-tester-cli/lib/utils/get-wallet-balance.js deleted file mode 100644 index 3e81b192cc..0000000000 --- a/packages/core-tester-cli/lib/utils/get-wallet-balance.js +++ /dev/null @@ -1,11 +0,0 @@ -const getWallet = require('./get-wallet') - -module.exports = async (address) => { - const wallet = await getWallet(address) - - if (wallet) { - return +wallet.balance - } - - return null -} diff --git a/packages/core-tester-cli/lib/utils/get-wallet.js b/packages/core-tester-cli/lib/utils/get-wallet.js deleted file mode 100644 index 93f1545e01..0000000000 --- a/packages/core-tester-cli/lib/utils/get-wallet.js +++ /dev/null @@ -1,16 +0,0 @@ -const request = require('./request') - -module.exports = async (address) => { - let response - try { - response = (await request.get(`/api/v2/wallets/${address}`)).data - } catch (error) { - return null - } - - if (response.data) { - return response.data - } - - return null -} diff --git a/packages/core-tester-cli/lib/utils/index.js b/packages/core-tester-cli/lib/utils/index.js index d875cf85c1..6305859902 100644 --- a/packages/core-tester-cli/lib/utils/index.js +++ b/packages/core-tester-cli/lib/utils/index.js @@ -1,16 +1,5 @@ module.exports = { - applyConfigOptions: require('./apply-config-options'), - copyToClipboard: require('./copy-to-clipboard'), - generateWallets: require('./generate-wallets'), - getConstants: require('./get-constants'), - getDelegates: require('./get-delegates'), - getTransaction: require('./get-transaction'), - getTransactionDelay: require('./get-transaction-delay'), - getVoters: require('./get-voters'), - getWallet: require('./get-wallet'), - getWalletBalance: require('./get-wallet-balance'), logger: require('./logger'), - parseFee: require('./parse-fee'), - postTransactions: require('./post-transactions'), - request: require('./request') + paginate: require('./paginate'), + request: require('./request'), } diff --git a/packages/core-tester-cli/lib/utils/logger.js b/packages/core-tester-cli/lib/utils/logger.js index 181397255a..1659945fe0 100644 --- a/packages/core-tester-cli/lib/utils/logger.js +++ b/packages/core-tester-cli/lib/utils/logger.js @@ -1,10 +1,7 @@ const pino = require('pino') -const pretty = pino.pretty({ - formatter: (data, util) => `${util.prefix}: ${util.asColoredText(data, data.msg)}` -}) -pretty.pipe(process.stdout) module.exports = pino({ name: 'ark-tester-cli', - safe: true -}, pretty) + safe: true, + prettyPrint: true, +}) diff --git a/packages/core-tester-cli/lib/utils/paginate.js b/packages/core-tester-cli/lib/utils/paginate.js index 2171e5f90b..671fb7cb7b 100644 --- a/packages/core-tester-cli/lib/utils/paginate.js +++ b/packages/core-tester-cli/lib/utils/paginate.js @@ -1,15 +1,19 @@ +/* eslint no-await-in-loop: "off" */ + const request = require('./request') -module.exports = async (endpoint, limit) => { +module.exports = async (config, endpoint, limit) => { const data = [] let page = 1 let maxPages = null while (maxPages === null || page <= maxPages) { - let response = (await request.get(`${endpoint}?page=${page}`)).data - if (response.data) { + const response = await request(config).get(`${endpoint}?page=${page}`) + if (response) { page++ maxPages = response.meta.pageCount data.push(...response.data) + } else { + break } } diff --git a/packages/core-tester-cli/lib/utils/parse-fee.js b/packages/core-tester-cli/lib/utils/parse-fee.js deleted file mode 100644 index 2cf3ec0433..0000000000 --- a/packages/core-tester-cli/lib/utils/parse-fee.js +++ /dev/null @@ -1,16 +0,0 @@ -const randomFee = (min, max) => { - return Math.floor(Math.random() * (max - min + 1) + min) -} - -module.exports = (fee) => { - if (typeof fee === 'string' && fee.indexOf('-') !== -1) { - const feeRange = fee.split('-').map(f => parseInt(f)) - if (feeRange[1] < feeRange[0]) { - return feeRange[0] - } - - return randomFee(feeRange[0], feeRange[1]) - } - - return parseInt(fee) -} diff --git a/packages/core-tester-cli/lib/utils/post-transactions.js b/packages/core-tester-cli/lib/utils/post-transactions.js deleted file mode 100644 index a0bf975c0b..0000000000 --- a/packages/core-tester-cli/lib/utils/post-transactions.js +++ /dev/null @@ -1,13 +0,0 @@ -const request = require('./request') - -module.exports = async (transactions) => { - let response = null - - try { - response = (await request.post('/api/v2/transactions', {transactions})).data - } catch (error) { - throw error - } - - return response -} diff --git a/packages/core-tester-cli/lib/utils/request.js b/packages/core-tester-cli/lib/utils/request.js index 3a3826074d..a8b4e2455d 100644 --- a/packages/core-tester-cli/lib/utils/request.js +++ b/packages/core-tester-cli/lib/utils/request.js @@ -1,19 +1,28 @@ const axios = require('axios') -const config = require('../config') -module.exports = { - get: (endpoint, isTransport) => { - const baseUrl = isTransport ? config.baseUrlP2P : config.baseUrlApi +module.exports = config => { + const headers = {} + if (config && config.network) { + headers.nethash = config.network.nethash + headers.version = '2.0.0' + headers.port = config.p2pPort + headers['Content-Type'] = 'application/json' + } + + return { + get: async (endpoint, isP2P) => { + const baseUrl = `${config.baseUrl}:${ + isP2P ? config.p2pPort : config.apiPort + }` - return axios.get(baseUrl + endpoint, { - headers: config.requestHeaders - }) - }, - post: (endpoint, data, isTransport) => { - const baseUrl = isTransport ? config.baseUrlP2P : config.baseUrlApi + return (await axios.get(baseUrl + endpoint, { headers })).data + }, + post: async (endpoint, data, isP2P) => { + const baseUrl = `${config.baseUrl}:${ + isP2P ? config.p2pPort : config.apiPort + }` - return axios.post(baseUrl + endpoint, data, { - headers: config.requestHeaders - }) + return (await axios.post(baseUrl + endpoint, data, { headers })).data + }, } } diff --git a/packages/core-tester-cli/package.json b/packages/core-tester-cli/package.json index 3b9317f8bc..de74c8058d 100644 --- a/packages/core-tester-cli/package.json +++ b/packages/core-tester-cli/package.json @@ -1,7 +1,7 @@ { "name": "@arkecosystem/core-tester-cli", - "description": "Tester CLI for ARK Core", - "version": "0.1.1", + "description": "Tester CLI for Ark Core", + "version": "0.2.0", "contributors": [ "Brian Faust ", "Alex Barnsley " @@ -14,25 +14,34 @@ "scripts": { "start": "./bin/tester", "test": "cross-env ARK_ENV=test jest --runInBand --detectOpenHandles", - "test:coverage": "cross-env ARK_ENV=test jest --coverage --runInBand --detectOpenHandles", - "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand --watch", + "test:coverage": "cross-env ARK_ENV=test jest --coverage --coveragePathIgnorePatterns='/(defaults.js|index.js)$' --runInBand --detectOpenHandles", + "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand", "test:watch": "cross-env ARK_ENV=test jest --runInBand --watch", "test:watch:all": "cross-env ARK_ENV=test jest --runInBand --watchAll", "lint": "eslint ./ --fix", - "depcheck": "depcheck ./ --ignores=commander" + "depcheck": "depcheck ./ --ignores=commander,pino-pretty,lodash,lodash.*" }, "dependencies": { - "arkjs": "https://github.com/ArkEcosystem/ark-js#master", + "@arkecosystem/core-utils": "~0.2", + "@arkecosystem/crypto": "~0.2", "axios": "^0.18.0", "bip39": "^2.5.0", "clipboardy": "^1.2.3", - "commander": "^2.15.1", - "delay": "^2.0.0", - "lodash": "^4.2.1", - "pino": "^4.16.1", - "superheroes": "^1.0.0" + "commander": "^2.19.0", + "delay": "^4.1.0", + "lodash.fill": "^3.4.0", + "pino": "^5.9.0", + "pino-pretty": "^2.3.0", + "pluralize": "^7.0.0", + "superheroes": "^2.0.0" + }, + "devDependencies": { + "axios-mock-adapter": "^1.15.0" }, "publishConfig": { "access": "public" + }, + "engines": { + "node": ">=10.x" } } diff --git a/packages/core-transaction-pool-mem/.gitattributes b/packages/core-transaction-pool-mem/.gitattributes new file mode 100644 index 0000000000..60cc52db63 --- /dev/null +++ b/packages/core-transaction-pool-mem/.gitattributes @@ -0,0 +1,11 @@ +# Path-based git attributes +# https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html + +# Ignore all test and documentation with "export-ignore". +/.editorconfig export-ignore +/.gitattributes export-ignore +/.gitignore export-ignore +/.travis.yml export-ignore +/__tests__ export-ignore +/docs export-ignore +/README.md export-ignore diff --git a/packages/core-transaction-pool-mem/CHANGELOG.md b/packages/core-transaction-pool-mem/CHANGELOG.md new file mode 100644 index 0000000000..365ba5960e --- /dev/null +++ b/packages/core-transaction-pool-mem/CHANGELOG.md @@ -0,0 +1,33 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +## Unreleased + +## 0.2.0 - 2018-12-03 + +### Added + +- Get transactions from mem pool ordered by fee + +### Changed + +- Test flushing wallets +- Reduce nondeterminism in the transactions expiration tests +- Dropped node.js 9 as minimum requirement in favour of node.js 10 +- Lazy sort transactions to improve performance +- Don't always purge expired transactions when checking for existence to improve performance + +### Fixed + +- Ensure the SQL database exists +- Sorting of transactions by fee + +## 0.1.0 - 2018-10-12 + +### Added + +- initial release diff --git a/packages/core-transaction-pool-mem/LICENSE b/packages/core-transaction-pool-mem/LICENSE new file mode 100644 index 0000000000..d6dd75272f --- /dev/null +++ b/packages/core-transaction-pool-mem/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) Ark Ecosystem + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/core-transaction-pool-redis/README.md b/packages/core-transaction-pool-mem/README.md similarity index 51% rename from packages/core-transaction-pool-redis/README.md rename to packages/core-transaction-pool-mem/README.md index 57ec424cdf..4b6a9771e7 100644 --- a/packages/core-transaction-pool-redis/README.md +++ b/packages/core-transaction-pool-mem/README.md @@ -1,29 +1,12 @@ -![ARK Core](https://i.imgur.com/1aP6F2o.png) +# Ark Core - Transaction Pool - Memory -# ARK Core - Transaction Pool Redis +

+ +

-## Installation +## Documentation -```bash -yarn add @arkecosystem/core-transaction-pool-redis -``` - -## Configuration - -### Defaults - -```js -module.exports = { - enabled: true, - key: 'ark', - maxTransactionsPerSender: 100, - allowedSenders: [], - redis: { - host: process.env.ARK_REDIS_HOST || 'localhost', - port: process.env.ARK_REDIS_PORT || 6379 - } -} -``` +You can find installation instructions and detailed instructions on how to use this package at the [dedicated documentation site](https://docs.ark.io/guidebook/core/plugins/core-transaction-pool-mem.html). ## Security @@ -34,6 +17,7 @@ If you discover a security vulnerability within this package, please send an e-m - [Kristjan Košič](https://github.com/kristjank) - [Brian Faust](https://github.com/faustbrian) - [Alex Barnsley](https://github.com/alexbarnsley) +- [Vasil Dimov](https://github.com/vasild) - [All Contributors](../../../../contributors) ## License diff --git a/packages/core-transaction-pool-mem/__tests__/__fixtures__/transactions.js b/packages/core-transaction-pool-mem/__tests__/__fixtures__/transactions.js new file mode 100644 index 0000000000..be17190b65 --- /dev/null +++ b/packages/core-transaction-pool-mem/__tests__/__fixtures__/transactions.js @@ -0,0 +1,210 @@ +const ark = require('@arkecosystem/crypto') + +const { slots } = ark +const { Transaction } = ark.models + +exports.dummy1 = new Transaction({ + version: 1, + network: 23, + type: 0, + timestamp: 35672738, + senderPublicKey: + '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', + fee: 10000000, + vendorFieldHex: '5449443a2030', + amount: 200000000, + expiration: 0, + recipientId: 'AFzQCx5YpGg5vKMBg4xbuYbqkhvMkKfKe5', + signature: + '304502210096ec6e27176fa694638d6fff35d7a551b2ed8c479a7e03264026eea41a05edd702206c071c97d1c6cc3bfec64dfff808cb0d5dfe857803428efb80bf7717b85cb619', + vendorField: 'TID: 0', + id: 'a5e9e6039675563959a783fa672c0ffe65369168a1ecffa3c89bf82961d8dbad', +}) + +exports.dummy2 = new Transaction({ + version: 1, + network: 30, + type: 0, + timestamp: 35632190, + senderPublicKey: + '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', + fee: 10000000, + amount: 10000000, + expiration: 0, + recipientId: 'DFyDKsyvR4x9D9zrfEaPmeJxSniT5N5qY8', + signature: + '3045022100ead721ae139c0a18a7be2077453337f8305e02a474a3e4e35eb22bcf59ce474c02207ea591ac68b5cfee068ac605efb000c7e1e7479abc7f6ee7ece21f3a5c629800', + secondSignature: + '3044022006bd359a6820353e5e2f28adc0569f79ee7ed2918ee169bb149ca582f613fa760220502f39db1f9568edeb05df08d570a21a8204cb66f993f7cea6554a3298c548be', + signSignature: + '3044022006bd359a6820353e5e2f28adc0569f79ee7ed2918ee169bb149ca582f613fa760220502f39db1f9568edeb05df08d570a21a8204cb66f993f7cea6554a3298c548be', + id: 'e665f6634fdbbbc562f79b92c8f0acd621081680c247cb4a6fc987bf456ea554', +}) + +exports.dummy3 = new Transaction({ + version: 1, + type: 0, + amount: 200000000, + fee: 10000000, + recipientId: 'ANqvJEMZcmUpcKBC8xiP1TntVkJeuZ3Lw3', + timestamp: 37346710, + asset: {}, + vendorField: 'TID: 0', + senderPublicKey: + '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', + signature: + '304402203f4d2b11b6f05538b16e2ab314c3c158885d8ceb95f3c0237d00fb350ea1b8e7022052eb7a2cd35c0d91ac14a8cba32b14a744ef26fc7d4c63b66d55f3ade0d6c305', + id: 'b163572af7598e35b4ea51e92cd1b59c8d653a50fc21358a7690777cc793cc50', +}) + +exports.dummy4 = new Transaction({ + version: 1, + type: 0, + amount: 200000000, + fee: 10000000, + recipientId: 'AJ5eV59hu4xrbRCpoP3of7fEYWUteSVa8k', + timestamp: 37346710, + asset: {}, + vendorField: 'TID: 1', + senderPublicKey: + '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', + signature: + '30450221008e04e622578bb6ac55097c9af3b7ffb553b659900f58056dae6ff2d57b0630000220071f416401431ba375f3f1a345b5f98deddd2198f072af4746a78417f8ece47d', + id: '03ebe9fd182e2ac19244a80717428b5ded0c2e7692f7f503f1acea0ea285ded9', +}) + +exports.dummy5 = new Transaction({ + version: 1, + type: 0, + amount: 200000000, + fee: 10000000, + recipientId: 'ASvC1E9hMLfANTi63S2gUMvr7rVZYJBj3u', + timestamp: 37346710, + asset: {}, + vendorField: 'TID: 2', + senderPublicKey: + '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', + signature: + '304502210095e699ae51090076180ead5623059ad0e607f08cf2a56b6a214817ec08610fd6022041ab05fe8acffdf0e4ed265d062411b2d3e47cf0f76b22793aee6ba12b17042c', + id: 'b1b89654cabf06fd2db8aa0b3659efcbf7430d1223bae0d8a23f6fad0983b032', +}) + +exports.dummy6 = new Transaction({ + version: 1, + type: 0, + amount: 200000000, + fee: 10000000, + recipientId: 'Ac8utEr7XRebWRvArSBnbVoxbq6bXftAmL', + timestamp: 37346710, + asset: {}, + vendorField: 'TID: 3', + senderPublicKey: + '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', + signature: + '304402203388ae5ba8f6248545593e7b4401900ca47dc5d694f5c36c8e1dafa67f1e214a02204a5e0cb620f0229cd0059675c8e2e3d835621eb682dc77f993acf5345a2f2bc7', + id: '937cb5431352100d60b5a6e9d5bb487c1276c1dee7ab75a238ca98daca35d236', +}) + +exports.dummy7 = new Transaction({ + version: 1, + type: 0, + amount: 200000000, + fee: 10000000, + recipientId: 'ANWEaVfvAh3VTyZNYcuFESUum1XBmAvAdj', + timestamp: 37346710, + asset: {}, + vendorField: 'TID: 4', + senderPublicKey: + '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', + signature: + '304502210093b9cf39802eff75d1f16c5f1de5a4326c77c73153e9cb87cfeb81f00b59a06402200b5375046043f0839bcdc2c3f972728241fb04fdacf3a669b12f2ec47c962d23', + id: 'd14ebba264bc6056acc5593c5c6d5566ae7bbd688556386e9e70ab33eb6e3e9c', +}) + +exports.dummy8 = new Transaction({ + version: 1, + type: 0, + amount: 200000000, + fee: 10000000, + recipientId: 'ALsZS24Dn4HYXwed5kAC5fKyB9BFzdmcSx', + timestamp: 37346710, + asset: {}, + vendorField: 'TID: 5', + senderPublicKey: + '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', + signature: + '30450221008425a7283e921d956a86db10bb34666deea9c13fa204420c4a85e2482399cce50220476bfdddc0743a0e05730e1b056a5a1d1030a963241ceced24da41ade6e6d2c9', + id: '7cf2325af89cdd7ac0b75e45a98ef1a30e8ee83842afeec27f22e695bf01f0ce', +}) + +exports.dummy9 = new Transaction({ + version: 1, + type: 0, + amount: 200000000, + fee: 10000000, + recipientId: 'ANuaLhRuBJhTcHao7kTfDcfsewLQGr7x5G', + timestamp: 37346710, + asset: {}, + vendorField: 'TID: 6', + senderPublicKey: + '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', + signature: + '3045022100f6571a7da13e81053e3cf39262b0dba7c476e589ae0c30ea7fb46bdff22dbd05022015c528cf9e8aacd986bb20b81420bf8eb7fd235a51f37193a8488f060a884267', + id: '6cc8e7d4ea99198dee4bed393e77828da8302619b27064933c0487c9dbb48e78', +}) + +exports.dummy10 = new Transaction({ + version: 1, + network: 30, + type: 0, + timestamp: slots.getTime(), + senderPublicKey: + '0310c283aac7b35b4ae6fab201d36e8322c3408331149982e16013a5bcb917081c', + fee: 10000000, + amount: 20000000, + recipientId: 'DFyDKsyvR4x9D9zrfEaPmeJxSniT5N5qY8', + signature: + '3045022100ead721ae139c0a18a7be2077453337f8305e02a474a3e4e35eb22bcf59ce474c02207ea591ac68b5cfee068ac605efb000c7e1e7479abc7f6ee7ece21f3a5c629800', + secondSignature: + '3044022006bd359a6820353e5e2f28adc0569f79ee7ed2918ee169bb149ca582f613fa760220502f39db1f9568edeb05df08d570a21a8204cb66f993f7cea6554a3298c548be', + signSignature: + '3044022006bd359a6820353e5e2f28adc0569f79ee7ed2918ee169bb149ca582f613fa760220502f39db1f9568edeb05df08d570a21a8204cb66f993f7cea6554a3298c548be', + vendorField: 'Expiring transaction 2', +}) + +exports.dummyExp1 = new Transaction({ + version: 1, + network: 23, + type: 0, + timestamp: slots.getTime(), + senderPublicKey: + '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', + fee: 20000000, + vendorFieldHex: '5449443a2030', + amount: 200000000, + expiration: slots.getTime() + 5, + recipientId: 'AFzQCx5YpGg5vKMBg4xbuYbqkhvMkKfKe5', + signature: + '304502210096ec6e27176fa694638d6fff35d7a551b2ed8c479a7e03264026eea41a05edd702206c071c97d1c6cc3bfec64dfff808cb0d5dfe857803428efb80bf7717b85cb619', + vendorField: 'Expiring transaction 1', +}) + +exports.dummyExp2 = new Transaction({ + version: 1, + network: 30, + type: 0, + timestamp: slots.getTime(), + senderPublicKey: + '0310c283aac7b35b4ae6fab201d36e8322c3408331149982e16013a5bcb917081c', + fee: 10000000, + amount: 20000000, + expiration: slots.getTime() + 5, + recipientId: 'DFyDKsyvR4x9D9zrfEaPmeJxSniT5N5qY8', + signature: + '3045022100ead721ae139c0a18a7be2077453337f8305e02a474a3e4e35eb22bcf59ce474c02207ea591ac68b5cfee068ac605efb000c7e1e7479abc7f6ee7ece21f3a5c629800', + secondSignature: + '3044022006bd359a6820353e5e2f28adc0569f79ee7ed2918ee169bb149ca582f613fa760220502f39db1f9568edeb05df08d570a21a8204cb66f993f7cea6554a3298c548be', + signSignature: + '3044022006bd359a6820353e5e2f28adc0569f79ee7ed2918ee169bb149ca582f613fa760220502f39db1f9568edeb05df08d570a21a8204cb66f993f7cea6554a3298c548be', + vendorField: 'Expiring transaction 2', +}) diff --git a/packages/core-transaction-pool-mem/__tests__/__support__/setup.js b/packages/core-transaction-pool-mem/__tests__/__support__/setup.js new file mode 100644 index 0000000000..3d93a41015 --- /dev/null +++ b/packages/core-transaction-pool-mem/__tests__/__support__/setup.js @@ -0,0 +1,15 @@ +const app = require('@arkecosystem/core-container') +const appHelper = require('@arkecosystem/core-test-utils/lib/helpers/container') + +jest.setTimeout(30000) + +exports.setUp = async () => { + await appHelper.setUp({ + exit: '@arkecosystem/core-blockchain', + exclude: ['@arkecosystem/core-transaction-pool-mem'], + }) +} + +exports.tearDown = async () => { + await app.tearDown() +} diff --git a/packages/core-transaction-pool-mem/__tests__/connection.test.js b/packages/core-transaction-pool-mem/__tests__/connection.test.js new file mode 100644 index 0000000000..c5149e72fe --- /dev/null +++ b/packages/core-transaction-pool-mem/__tests__/connection.test.js @@ -0,0 +1,722 @@ +/* eslint max-len: "off" */ + +const { bignumify } = require('@arkecosystem/core-utils') +const container = require('@arkecosystem/core-container') +const crypto = require('@arkecosystem/crypto') +const delay = require('delay') +const delegatesSecrets = require('@arkecosystem/core-test-utils/fixtures/testnet/passphrases') +const generateTransfer = require('@arkecosystem/core-test-utils/lib/generators/transactions/transfer') +const randomSeed = require('random-seed') +const mockData = require('./__fixtures__/transactions') +const app = require('./__support__/setup') + +const ARKTOSHI = crypto.constants.ARKTOSHI +const TRANSACTION_TYPES = crypto.constants.TRANSACTION_TYPES +const Transaction = crypto.models.Transaction +const slots = crypto.slots + +let config +let defaultConfig +let database +let connection + +beforeAll(async () => { + await app.setUp() + + config = container.resolvePlugin('config') + defaultConfig = require('../lib/defaults') + database = container.resolvePlugin('database') + + const Connection = require('../lib/connection.js') + connection = new Connection(defaultConfig) + await connection.make() + // 100+ years in the future to avoid our hardcoded transactions used in these + // tests to expire + connection.options.maxTransactionAge = 4036608000 +}) + +afterAll(async () => { + connection.disconnect() + await app.tearDown() +}) + +afterEach(() => { + connection.flush() +}) + +describe('Connection', () => { + it('should be an object', () => { + expect(connection).toBeObject() + }) + + describe('getPoolSize', () => { + it('should be a function', () => { + expect(connection.getPoolSize).toBeFunction() + }) + + it('should return 0 if no transactions were added', () => { + expect(connection.getPoolSize()).toBe(0) + }) + + it('should return 2 if transactions were added', () => { + expect(connection.getPoolSize()).toBe(0) + + connection.addTransaction(mockData.dummy1) + + expect(connection.getPoolSize()).toBe(1) + + connection.addTransaction(mockData.dummy2) + + expect(connection.getPoolSize()).toBe(2) + }) + }) + + describe('getSenderSize', () => { + it('should be a function', () => { + expect(connection.getSenderSize).toBeFunction() + }) + + it('should return 0 if no transactions were added', () => { + expect(connection.getSenderSize('undefined')).toBe(0) + }) + + it('should return 2 if transactions were added', () => { + const senderPublicKey = mockData.dummy1.senderPublicKey + + expect(connection.getSenderSize(senderPublicKey)).toBe(0) + + connection.addTransaction(mockData.dummy1) + + expect(connection.getSenderSize(senderPublicKey)).toBe(1) + + connection.addTransaction(mockData.dummy2) + + expect(connection.getSenderSize(senderPublicKey)).toBe(2) + }) + }) + + describe('addTransaction', () => { + it('should be a function', () => { + expect(connection.addTransaction).toBeFunction() + }) + + it('should add the transaction to the pool', () => { + expect(connection.getPoolSize()).toBe(0) + + connection.addTransaction(mockData.dummy1) + + // Test adding already existent transaction + connection.addTransaction(mockData.dummy1) + + expect(connection.getPoolSize()).toBe(1) + }) + }) + + describe('addTransactions', () => { + it('should be a function', () => { + expect(connection.addTransactions).toBeFunction() + }) + + it('should add the transactions to the pool', () => { + expect(connection.getPoolSize()).toBe(0) + + connection.addTransactions([mockData.dummy1, mockData.dummy2]) + + expect(connection.getPoolSize()).toBe(2) + }) + + it('should not add not-appliable transactions', () => { + // This should be skipped due to insufficient funds + const highFeeTransaction = new Transaction(mockData.dummy3) + highFeeTransaction.fee = bignumify(1e9 * ARKTOSHI) + // changing public key as fixture transactions have the same one + highFeeTransaction.senderPublicKey = + '000000000000000000000000000000000000000420000000000000000000000000' + + const transactions = [ + mockData.dummy1, + mockData.dummy2, + highFeeTransaction, + mockData.dummy4, + mockData.dummy5, + mockData.dummy6, + ] + + // Ensure no cold wallet + database.walletManager.findByPublicKey( + '000000000000000000000000000000000000000420000000000000000000000000', + ) + + const { added, notAdded } = connection.addTransactions(transactions) + expect(notAdded[0].message).toEqual( + `["[PoolWalletManager] Can't apply transaction id:b163572af7598e35b4ea51e92cd1b59c8d653a50fc21358a7690777cc793cc50 from sender:AHkZLLjUdjjjJzNe1zCXqHh27bUhzg8GZw","Insufficient balance in the wallet"]`, + ) + expect(connection.getPoolSize()).toBe(5) + }) + }) + + describe('addTransactions with expiration', () => { + it('should add the transactions to the pool and they should expire', async () => { + expect(connection.getPoolSize()).toBe(0) + + const expireAfterSeconds = 3 + const expiration = slots.getTime() + expireAfterSeconds + + const transactions = [] + + transactions.push(new Transaction(mockData.dummyExp1)) + transactions[transactions.length - 1].expiration = expiration + + transactions.push(new Transaction(mockData.dummy1)) + // transactions[transactions.length - 1].type = + // TRANSACTION_TYPES.TIMELOCK_TRANSFER + + // Workaround: Increase balance of sender wallet to succeed + const insufficientBalanceTx = new Transaction(mockData.dummyExp2) + transactions.push(insufficientBalanceTx) + insufficientBalanceTx.expiration = expiration + + const wallet = connection.walletManager.findByPublicKey( + insufficientBalanceTx.senderPublicKey, + ) + + wallet.balance = wallet.balance.plus(insufficientBalanceTx.amount * 2) + + transactions.push(mockData.dummy2) + + // Ensure no cold wallets + transactions.forEach(tx => + database.walletManager.findByPublicKey(tx.senderPublicKey), + ) + + const { added, notAdded } = connection.addTransactions(transactions) + expect(added).toHaveLength(4) + expect(notAdded).toBeEmpty() + + expect(connection.getPoolSize()).toBe(4) + await delay((expireAfterSeconds + 1) * 1000) + expect(connection.getPoolSize()).toBe(2) + + transactions.forEach(t => connection.removeTransactionById(t.id)) + }) + }) + + describe('removeTransaction', () => { + it('should be a function', () => { + expect(connection.removeTransaction).toBeFunction() + }) + + it('should remove the specified transaction from the pool', () => { + connection.addTransaction(mockData.dummy1) + + expect(connection.getPoolSize()).toBe(1) + + connection.removeTransaction(mockData.dummy1) + + expect(connection.getPoolSize()).toBe(0) + }) + }) + + describe('removeTransactionById', () => { + it('should be a function', () => { + expect(connection.removeTransactionById).toBeFunction() + }) + + it('should remove the specified transaction from the pool (by id)', () => { + connection.addTransaction(mockData.dummy1) + + expect(connection.getPoolSize()).toBe(1) + + connection.removeTransactionById(mockData.dummy1.id) + + expect(connection.getPoolSize()).toBe(0) + }) + + it('should do nothing when asked to delete a non-existent transaction', () => { + connection.addTransaction(mockData.dummy1) + + connection.removeTransactionById('nonexistenttransactionid') + + expect(connection.getPoolSize()).toBe(1) + }) + }) + + describe('removeTransactionsForSender', () => { + it('should be a function', () => { + expect(connection.removeTransactionsForSender).toBeFunction() + }) + + it('should remove the senders transactions from the pool', () => { + connection.addTransaction(mockData.dummy1) + connection.addTransaction(mockData.dummy2) + connection.addTransaction(mockData.dummy3) + connection.addTransaction(mockData.dummy4) + connection.addTransaction(mockData.dummy5) + connection.addTransaction(mockData.dummy6) + + // dummy10 is the only cold wallet + database.walletManager.findByPublicKey( + mockData.dummy10.data.senderPublicKey, + ) + + connection.addTransaction(mockData.dummy10) + + expect(connection.getPoolSize()).toBe(7) + + connection.removeTransactionsForSender(mockData.dummy1.senderPublicKey) + + expect(connection.getPoolSize()).toBe(1) + }) + }) + + describe('transactionExists', () => { + it('should be a function', () => { + expect(connection.transactionExists).toBeFunction() + }) + + it('should return true if transaction is IN pool', () => { + connection.addTransactions([mockData.dummy1, mockData.dummy2]) + + expect(connection.transactionExists(mockData.dummy1.id)).toBeTrue() + expect(connection.transactionExists(mockData.dummy2.id)).toBeTrue() + }) + + it('should return false if transaction is NOT pool', () => { + expect(connection.transactionExists(mockData.dummy1.id)).toBeFalse() + expect(connection.transactionExists(mockData.dummy2.id)).toBeFalse() + }) + }) + + describe('hasExceededMaxTransactions', () => { + it('should be a function', () => { + expect(connection.hasExceededMaxTransactions).toBeFunction() + }) + + it('should be true if exceeded', () => { + connection.options.maxTransactionsPerSender = 5 + connection.options.allowedSenders = [] + connection.addTransaction(mockData.dummy3) + connection.addTransaction(mockData.dummy4) + connection.addTransaction(mockData.dummy5) + connection.addTransaction(mockData.dummy6) + connection.addTransaction(mockData.dummy7) + connection.addTransaction(mockData.dummy8) + connection.addTransaction(mockData.dummy9) + + expect(connection.getPoolSize()).toBe(7) + const exceeded = connection.hasExceededMaxTransactions(mockData.dummy3) + expect(exceeded).toBeTrue() + }) + + it('should be falsy if not exceeded', () => { + connection.options.maxTransactionsPerSender = 7 + connection.options.allowedSenders = [] + + connection.addTransaction(mockData.dummy4) + connection.addTransaction(mockData.dummy5) + connection.addTransaction(mockData.dummy6) + + expect(connection.getPoolSize()).toBe(3) + const exceeded = connection.hasExceededMaxTransactions(mockData.dummy3) + expect(exceeded).toBeFalse() + }) + + it('should be allowed to exceed if whitelisted', () => { + connection.flush() + connection.options.maxTransactionsPerSender = 5 + connection.options.allowedSenders = [ + '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', + 'ghjk', + ] + connection.addTransaction(mockData.dummy3) + connection.addTransaction(mockData.dummy4) + connection.addTransaction(mockData.dummy5) + connection.addTransaction(mockData.dummy6) + connection.addTransaction(mockData.dummy7) + connection.addTransaction(mockData.dummy8) + connection.addTransaction(mockData.dummy9) + + expect(connection.getPoolSize()).toBe(7) + const exceeded = connection.hasExceededMaxTransactions(mockData.dummy3) + expect(exceeded).toBeFalse() + }) + }) + + describe('getTransaction', () => { + it('should be a function', () => { + expect(connection.getTransaction).toBeFunction() + }) + + it('should return the specified transaction', () => { + connection.addTransaction(mockData.dummy1) + + const poolTransaction = connection.getTransaction(mockData.dummy1.id) + expect(poolTransaction).toBeObject() + expect(poolTransaction.id).toBe(mockData.dummy1.id) + }) + + it('should return undefined for nonexisting transaction', () => { + const poolTransaction = connection.getTransaction('non existing id') + expect(poolTransaction).toBeFalsy() + }) + }) + + describe('getTransactions', () => { + it('should be a function', () => { + expect(connection.getTransactions).toBeFunction() + }) + + it('should return transactions within the specified range', () => { + const transactions = [mockData.dummy1, mockData.dummy2] + + connection.addTransactions(transactions) + + if (transactions[1].fee > transactions[0].fee) { + transactions.reverse() + } + + for (const i of [0, 1]) { + const retrieved = connection + .getTransactions(i, 1) + .map(serializedTx => Transaction.fromBytes(serializedTx)) + + expect(retrieved.length).toBe(1) + expect(retrieved[0]).toBeObject() + expect(retrieved[0].id).toBe(transactions[i].id) + } + }) + }) + + describe('getTransactionIdsForForging', () => { + it('should be a function', () => { + expect(connection.getTransactionIdsForForging).toBeFunction() + }) + + it('should return an array of transactions ids', () => { + connection.addTransaction(mockData.dummy1) + connection.addTransaction(mockData.dummy2) + connection.addTransaction(mockData.dummy3) + connection.addTransaction(mockData.dummy4) + connection.addTransaction(mockData.dummy5) + connection.addTransaction(mockData.dummy6) + + const transactionIds = connection.getTransactionIdsForForging(0, 6) + + expect(transactionIds).toBeArray() + expect(transactionIds[0]).toBe(mockData.dummy1.id) + expect(transactionIds[1]).toBe(mockData.dummy2.id) + expect(transactionIds[2]).toBe(mockData.dummy3.id) + expect(transactionIds[3]).toBe(mockData.dummy4.id) + expect(transactionIds[4]).toBe(mockData.dummy5.id) + expect(transactionIds[5]).toBe(mockData.dummy6.id) + }) + }) + + describe('getTransactionsForForging', () => { + it('should be a function', () => { + expect(connection.getTransactionsForForging).toBeFunction() + }) + }) + + describe('flush', () => { + it('should be a function', () => { + expect(connection.flush).toBeFunction() + }) + + it('should flush the pool', () => { + connection.addTransaction(mockData.dummy1) + + expect(connection.getPoolSize()).toBe(1) + + connection.flush() + + expect(connection.getPoolSize()).toBe(0) + }) + }) + + describe('senderHasTransactionsOfType', () => { + it('should be a function', () => { + expect(connection.senderHasTransactionsOfType).toBeFunction() + }) + + it('should be false for non-existent sender', () => { + connection.addTransaction(mockData.dummy1) + + expect( + connection.senderHasTransactionsOfType( + 'nonexistent', + TRANSACTION_TYPES.VOTE, + ), + ).toBeFalse() + }) + + it('should be false for existent sender with no votes', () => { + const tx = mockData.dummy1 + + connection.addTransaction(tx) + + expect( + connection.senderHasTransactionsOfType( + tx.senderPublicKey, + TRANSACTION_TYPES.VOTE, + ), + ).toBeFalse() + }) + + it('should be true for existent sender with votes', () => { + const tx = mockData.dummy1 + + // Prevent 'wallet has already voted' error + connection.walletManager.findByPublicKey(tx.senderPublicKey).vote = '' + + const voteTx = new Transaction(tx) + voteTx.id = + '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef' + voteTx.type = TRANSACTION_TYPES.VOTE + voteTx.amount = 0 + voteTx.asset = { votes: [`+${tx.senderPublicKey}`] } + + const transactions = [tx, voteTx, mockData.dummy2] + + connection.addTransactions(transactions) + + expect( + connection.senderHasTransactionsOfType( + tx.senderPublicKey, + TRANSACTION_TYPES.VOTE, + ), + ).toBeTrue() + }) + }) + + describe('shutdown and start', () => { + it('save and restore transactions', () => { + expect(connection.getPoolSize()).toBe(0) + + const transactions = [mockData.dummy1, mockData.dummy4] + + connection.addTransactions(transactions) + + expect(connection.getPoolSize()).toBe(2) + + connection.disconnect() + + connection.make() + + expect(connection.getPoolSize()).toBe(2) + + transactions.forEach(t => + expect(connection.getTransaction(t.id).serialized.toLowerCase()).toBe( + t.serialized.toLowerCase(), + ), + ) + + connection.flush() + }) + + it('remove forged when starting', async () => { + expect(connection.getPoolSize()).toBe(0) + + const block = await database.getLastBlock() + + // XXX This accesses directly block.transactions which is not even + // documented in packages/crypto/lib/models/block.js + const forgedTransaction = block.transactions[0] + + // Workaround: Add tx to exceptions so it gets applied, because the fee is 0. + config.network.exceptions.transactions = [forgedTransaction.id] + + // For some reason all genesis transactions fail signature verification, so + // they are not loaded from the local storage and this fails otherwise. + const original = database.getForgedTransactionsId + database.getForgedTransactionsIds = jest.fn(() => [forgedTransaction.id]) + + expect(forgedTransaction instanceof Transaction).toBeTrue() + + const transactions = [mockData.dummy1, forgedTransaction, mockData.dummy4] + + connection.addTransactions(transactions) + + expect(connection.getPoolSize()).toBe(3) + + connection.disconnect() + + await connection.make() + + expect(connection.getPoolSize()).toBe(2) + + transactions.splice(1, 1) + + transactions.forEach(t => + expect(connection.getTransaction(t.id).serialized.toLowerCase()).toBe( + t.serialized.toLowerCase(), + ), + ) + + connection.flush() + + database.getForgedTransactionsIds = original + }) + }) + + describe('stress', () => { + const fakeTransactionId = i => + `id${String(i)}aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` + + it('multiple additions and retrievals', () => { + // Abstract number which decides how many iterations are run by the test. + // Increase it to run more iterations. + const testSize = connection.options.syncInterval * 2 + + for (let i = 0; i < testSize; i++) { + const transaction = new Transaction(mockData.dummy1) + transaction.id = fakeTransactionId(i) + connection.addTransaction(transaction) + + if (i % 27 === 0) { + connection.removeTransaction(transaction) + } + } + + for (let i = 0; i < testSize * 2; i++) { + connection.getPoolSize() + for (const sender of ['nonexistent', mockData.dummy1.senderPublicKey]) { + connection.getSenderSize(sender) + connection.hasExceededMaxTransactions(sender) + } + connection.getTransaction(fakeTransactionId(i)) + connection.getTransactions(0, i) + } + + for (let i = 0; i < testSize; i++) { + const transaction = new Transaction(mockData.dummy1) + transaction.id = fakeTransactionId(i) + connection.removeTransaction(transaction) + } + }) + + it('delete + add after sync', () => { + for (let i = 0; i < connection.options.syncInterval; i++) { + const transaction = new Transaction(mockData.dummy1) + transaction.id = fakeTransactionId(i) + connection.addTransaction(transaction) + } + + const transaction = new Transaction(mockData.dummy1) + transaction.id = fakeTransactionId(0) + connection.removeTransaction(transaction) + connection.addTransaction(transaction) + }) + + it('add many then get first few', () => { + const nAdd = 2000 + + // We use a predictable random number calculator in order to get + // a deterministic test. + const rand = randomSeed.create(0) + + const allTransactions = [] + for (let i = 0; i < nAdd; i++) { + const transaction = new Transaction(mockData.dummy1) + transaction.id = fakeTransactionId(i) + transaction.fee = bignumify( + rand.intBetween(0.002 * ARKTOSHI, 2 * ARKTOSHI), + ) + transaction.serialized = Transaction.serialize(transaction).toString( + 'hex', + ) + allTransactions.push(transaction) + } + + // console.time(`time to add ${nAdd}`) + connection.addTransactions(allTransactions) + // console.timeEnd(`time to add ${nAdd}`) + + const nGet = 150 + + const topFeesExpected = allTransactions + .map(t => t.fee) + .sort((a, b) => b - a) + .slice(0, nGet) + .map(f => f.toString()) + + // console.time(`time to get first ${nGet}`) + const topTransactionsSerialized = connection.getTransactions(0, nGet) + // console.timeEnd(`time to get first ${nGet}`) + + const topFeesReceived = topTransactionsSerialized.map(e => + new Transaction(e).fee.toString(), + ) + + expect(topFeesReceived).toEqual(topFeesExpected) + }) + }) + + describe('purgeSendersWithInvalidTransactions', () => { + it('should be a function', () => { + expect(connection.purgeSendersWithInvalidTransactions).toBeFunction() + }) + + it('should purge transactions from sender when invalid', async () => { + const transfersA = generateTransfer( + 'testnet', + delegatesSecrets[0], + mockData.dummy1.recipientId, + 1, + 5, + ) + + const transfersB = generateTransfer( + 'testnet', + delegatesSecrets[1], + mockData.dummy1.recipientId, + 1, + 1, + ) + + const block = { + transactions: [...transfersA, ...transfersB], + } + + block.transactions.forEach(tx => connection.addTransaction(tx)) + + expect(connection.getPoolSize()).toBe(6) + + // Last tx has a unique sender + block.transactions[5].verified = false + + connection.purgeSendersWithInvalidTransactions(block) + expect(connection.getPoolSize()).toBe(5) + + // The remaining tx all have the same sender + block.transactions[0].verified = false + + connection.purgeSendersWithInvalidTransactions(block) + expect(connection.getPoolSize()).toBe(0) + }) + }) + + describe('purgeBlock', () => { + it('should be a function', () => { + expect(connection.purgeBlock).toBeFunction() + }) + + it('should purge transactions from block', async () => { + const transactions = generateTransfer( + 'testnet', + delegatesSecrets[0], + mockData.dummy1.recipientId, + 1, + 5, + ) + const block = { transactions } + + block.transactions.forEach(tx => connection.addTransaction(tx)) + + expect(connection.getPoolSize()).toBe(5) + + connection.purgeBlock(block) + expect(connection.getPoolSize()).toBe(0) + }) + }) +}) diff --git a/packages/core-transaction-pool-mem/jest.config.js b/packages/core-transaction-pool-mem/jest.config.js new file mode 100644 index 0000000000..57770a97bb --- /dev/null +++ b/packages/core-transaction-pool-mem/jest.config.js @@ -0,0 +1,12 @@ +module.exports = { + testEnvironment: 'node', + bail: false, + verbose: true, + testMatch: ['**/__tests__/**/*.test.js'], + moduleFileExtensions: ['js', 'json'], + collectCoverage: false, + coverageDirectory: '/.coverage', + collectCoverageFrom: ['lib/**/*.js', '!**/node_modules/**'], + watchman: false, + setupTestFrameworkScriptFile: 'jest-extended', +} diff --git a/packages/core-transaction-pool-mem/jsdoc.json b/packages/core-transaction-pool-mem/jsdoc.json new file mode 100644 index 0000000000..f3ea8aab33 --- /dev/null +++ b/packages/core-transaction-pool-mem/jsdoc.json @@ -0,0 +1,22 @@ +{ + "tags": { + "allowUnknownTags": false + }, + "source": { + "include": "./lib", + "includePattern": ".js$", + "excludePattern": "(node_modules/|docs)" + }, + "plugins": ["plugins/markdown"], + "opts": { + "template": "../../node_modules/docdash", + "encoding": "utf8", + "destination": "docs/", + "recurse": true, + "verbose": true + }, + "templates": { + "cleverLinks": false, + "monospaceLinks": false + } +} diff --git a/packages/core-transaction-pool-mem/lib/connection.js b/packages/core-transaction-pool-mem/lib/connection.js new file mode 100644 index 0000000000..26025a7b97 --- /dev/null +++ b/packages/core-transaction-pool-mem/lib/connection.js @@ -0,0 +1,417 @@ +/* eslint no-constant-condition: "off" */ +/* eslint no-await-in-loop: "off" */ + +const { + TransactionPoolInterface, +} = require('@arkecosystem/core-transaction-pool') + +const assert = require('assert') +const app = require('@arkecosystem/core-container') +const Mem = require('./mem') +const MemPoolTransaction = require('./mem-pool-transaction') +const Storage = require('./storage') + +const database = app.resolvePlugin('database') +const emitter = app.resolvePlugin('event-emitter') +const logger = app.resolvePlugin('logger') + +/** + * Transaction pool. It uses a hybrid storage - caching the data + * in memory and occasionally saving it to a persistent, on-disk storage (SQLite), + * every N modifications, and also during shutdown. The operations that only read + * data (everything other than add or remove transaction) are served from the + * in-memory storage. + */ +class TransactionPool extends TransactionPoolInterface { + /** + * Make the transaction pool instance. Load all transactions in the pool from + * the on-disk database, saved there from a previous run. + * @return {TransactionPool} + */ + async make() { + this.mem = new Mem() + this.storage = new Storage(this.options.storage) + this.loggedAllowedSenders = [] + + const all = this.storage.loadAll() + all.forEach(t => this.mem.add(t, this.options.maxTransactionAge, true)) + + this.__purgeExpired() + + // Remove transactions that were forged while we were offline. + const allIds = all.map( + memPoolTransaction => memPoolTransaction.transaction.id, + ) + + const forgedIds = await database.getForgedTransactionsIds(allIds) + + forgedIds.forEach(id => this.removeTransactionById(id)) + + return this + } + + /** + * Disconnect from transaction pool. + * @return {void} + */ + disconnect() { + this.__syncToPersistentStorage() + this.storage.close() + } + + /** + * Get the number of transactions in the pool. + * @return {Number} + */ + getPoolSize() { + this.__purgeExpired() + + return this.mem.getSize() + } + + /** + * Get the number of transactions in the pool from a specific sender + * @param {String} senderPublicKey + * @returns {Number} + */ + getSenderSize(senderPublicKey) { + this.__purgeExpired() + + return this.mem.getBySender(senderPublicKey).size + } + + /** + * Add a transaction to the pool. + * @param {Transaction} transaction + * @return {Object} The success property indicates wether the transaction was successfully added + * and applied to the pool or not. In case it was not successful, the type and message + * property yield information about the error. + */ + addTransaction(transaction) { + if (this.transactionExists(transaction.id)) { + logger.debug( + 'Transaction pool: ignoring attempt to add a transaction that is already ' + + `in the pool, id: ${transaction.id}`, + ) + + return this.__createError( + transaction, + 'ERR_ALREADY_IN_POOL', + 'Already in pool', + ) + } + + const poolSize = this.mem.getSize() + + if (this.options.maxTransactionsInPool <= poolSize) { + // The pool can't accommodate more transactions. Either decline the newcomer or remove + // an existing transaction from the pool in order to free up space. + const all = this.mem.getTransactionsOrderedByFee() + const lowest = all[all.length - 1].transaction + + if (lowest.fee.isLessThan(transaction.fee)) { + this.walletManager.revertTransactionForSender(lowest) + this.mem.remove(lowest.id, lowest.senderPublicKey) + } else { + return this.__createError( + transaction, + 'ERR_POOL_FULL', + `Pool is full (has ${poolSize} transactions) and this transaction's fee ` + + `${transaction.fee.toFixed()} is not higher than the lowest fee already in pool ` + + `${lowest.fee.toFixed()}`, + ) + } + } + + this.mem.add( + new MemPoolTransaction(transaction), + this.options.maxTransactionAge, + ) + + // Apply transaction to pool wallet manager. + const senderWallet = this.walletManager.findByPublicKey( + transaction.senderPublicKey, + ) + + const errors = [] + if (this.walletManager.canApply(transaction, errors)) { + senderWallet.applyTransactionToSender(transaction) + } else { + // Remove tx again from the pool + this.mem.remove(transaction.id) + + return this.__createError( + transaction, + 'ERR_APPLY', + JSON.stringify(errors), + ) + } + + this.__syncToPersistentStorageIfNecessary() + return { success: true } + } + + /** + * Add many transactions to the pool. + * @param {Array} transactions, already transformed and verified + * by transaction guard - must have serialized field + * @return {Object} like + * { + * added: [ ... successfully added transactions ... ], + * notAdded: [ { transaction: Transaction, type: String, message: String }, ... ] + * } + */ + addTransactions(transactions) { + const added = [] + const notAdded = [] + + for (const t of transactions) { + const result = this.addTransaction(t) + + if (result.success) { + added.push(t) + } else { + notAdded.push(result) + } + } + + return { added, notAdded } + } + + /** + * Remove a transaction from the pool by transaction object. + * @param {Transaction} transaction + * @return {void} + */ + removeTransaction(transaction) { + this.removeTransactionById(transaction.id, transaction.senderPublicKey) + } + + /** + * Remove a transaction from the pool by id. + * @param {String} id + * @param {String} senderPublicKey + * @return {void} + */ + removeTransactionById(id, senderPublicKey = undefined) { + this.mem.remove(id, senderPublicKey) + + this.__syncToPersistentStorageIfNecessary() + } + + /** + * Check whether sender of transaction has exceeded max transactions in queue. + * @param {Transaction} transaction + * @return {Boolean} true if exceeded + */ + hasExceededMaxTransactions(transaction) { + this.__purgeExpired() + + if (this.options.allowedSenders.includes(transaction.senderPublicKey)) { + if (!this.loggedAllowedSenders.includes(transaction.senderPublicKey)) { + logger.debug( + `Transaction pool: allowing sender public key: ${ + transaction.senderPublicKey + } (listed in options.allowedSenders), thus skipping throttling.`, + ) + this.loggedAllowedSenders.push(transaction.senderPublicKey) + } + + return false + } + + const count = this.mem.getBySender(transaction.senderPublicKey).size + + return !(count <= this.options.maxTransactionsPerSender) + } + + /** + * Get a transaction by transaction id. + * @param {String} id + * @return {(Transaction|undefined)} + */ + getTransaction(id) { + this.__purgeExpired() + + return this.mem.getTransactionById(id) + } + + /** + * Get all transactions that are ready to be forged. + * @param {Number} blockSize + * @return {(Array|void)} + */ + getTransactionsForForging(blockSize) { + return this.getTransactions(0, blockSize) + } + + /** + * Get all transactions within the specified range [start, start + size), ordered by fee. + * @param {Number} start + * @param {Number} size + * @return {(Array|void)} array of serialized transaction hex strings + */ + getTransactions(start, size) { + return this.getTransactionsData(start, size, 'serialized') + } + + /** + * Get all transactions within the specified range [start, start + size). + * @param {Number} start + * @param {Number} size + * @return {Array} array of transactions IDs in the specified range + */ + getTransactionIdsForForging(start, size) { + return this.getTransactionsData(start, size, 'id') + } + + /** + * Get data from all transactions within the specified range [start, start + size). + * Transactions are ordered by fee (highest fee first) or by + * insertion time, if fees equal (earliest transaction first). + * @param {Number} start + * @param {Number} size + * @param {String} property + * @return {Array} array of transaction[property] + */ + getTransactionsData(start, size, property) { + this.__purgeExpired() + + const data = [] + + let i = 0 + for (const memPoolTransaction of this.mem.getTransactionsOrderedByFee()) { + if (i >= start + size) { + break + } + + if (i >= start) { + assert.notStrictEqual( + memPoolTransaction.transaction[property], + undefined, + ) + data.push(memPoolTransaction.transaction[property]) + } + + i++ + } + + return data + } + + /** + * Flush the pool (delete all transactions from it). + * @return {void} + */ + flush() { + this.mem.flush() + + this.storage.deleteAll() + } + + /** + * Remove all transactions from the transaction pool belonging to specific sender. + * @param {String} senderPublicKey + * @return {void} + */ + removeTransactionsForSender(senderPublicKey) { + this.mem + .getBySender(senderPublicKey) + .forEach(e => this.removeTransactionById(e.transaction.id)) + } + + /** + * Checks if a transaction exists in the pool. + * @param {String} transactionId + * @return {Boolean} + */ + transactionExists(transactionId) { + if (!this.mem.transactionExists(transactionId)) { + // If it does not exist then no need to purge expired transactions because + // we know it will not exist after purge too. + return false + } + + this.__purgeExpired() + + return this.mem.transactionExists(transactionId) + } + + /** + * Check whether a given sender has any transactions of the specified type + * in the pool. + * @param {String} senderPublicKey public key of the sender + * @param {Number} transactionType transaction type, must be one of + * TRANSACTION_TYPES.* and is compared against transaction.type. + * @return {Boolean} true if exist + */ + senderHasTransactionsOfType(senderPublicKey, transactionType) { + this.__purgeExpired() + + for (const memPoolTransaction of this.mem.getBySender(senderPublicKey)) { + if (memPoolTransaction.transaction.type === transactionType) { + return true + } + } + + return false + } + + /** + * Remove all transactions from the pool that have expired. + * @return {void} + */ + __purgeExpired() { + for (const transaction of this.mem.getExpired( + this.options.maxTransactionAge, + )) { + emitter.emit('transaction.expired', transaction.data) + + this.walletManager.revertTransactionForSender(transaction) + + this.mem.remove(transaction.id, transaction.senderPublicKey) + + this.__syncToPersistentStorageIfNecessary() + } + } + + /** + * Sync the in-memory storage to the persistent (on-disk) storage if too + * many changes have been accumulated in-memory. + * @return {void} + */ + __syncToPersistentStorageIfNecessary() { + if (this.options.syncInterval <= this.mem.getNumberOfDirty()) { + this.__syncToPersistentStorage() + } + } + + /** + * Sync the in-memory storage to the persistent (on-disk) storage. + */ + __syncToPersistentStorage() { + const added = this.mem.getDirtyAddedAndForget() + this.storage.bulkAdd(added) + + const removed = this.mem.getDirtyRemovedAndForget() + this.storage.bulkRemoveById(removed) + } + + /** + * Create an error object which the TransactionGuard understands. + * @param {Transaction} transaction + * @param {String} type + * @param {String} message + * @return {Object} + */ + __createError(transaction, type, message) { + return { + transaction, + type, + message, + success: false, + } + } +} + +module.exports = TransactionPool diff --git a/packages/core-transaction-pool-mem/lib/defaults.js b/packages/core-transaction-pool-mem/lib/defaults.js new file mode 100644 index 0000000000..15aa270672 --- /dev/null +++ b/packages/core-transaction-pool-mem/lib/defaults.js @@ -0,0 +1,18 @@ +module.exports = { + enabled: !process.env.ARK_TRANSACTION_POOL_DISABLED, + syncInterval: 512, + storage: `${process.env.ARK_PATH_DATA}/database/transaction-pool-${ + process.env.ARK_NETWORK_NAME + }.sqlite`, + // When the pool contains that many transactions, then a new transaction is + // only accepted if its fee is higher than the transaction with the lowest + // fee in the pool. In this case the transaction with the lowest fee is removed + // from the pool in order to accommodate the new one. + maxTransactionsInPool: process.env.ARK_MAX_TRANSACTIONS_IN_POOL || 100000, + maxTransactionsPerSender: + process.env.ARK_TRANSACTION_POOL_MAX_PER_SENDER || 300, + allowedSenders: [], + maxTransactionsPerRequest: + process.env.ARK_TRANSACTION_POOL_MAX_PER_REQUEST || 40, + maxTransactionAge: 2700, +} diff --git a/packages/core-transaction-pool-mem/lib/index.js b/packages/core-transaction-pool-mem/lib/index.js new file mode 100644 index 0000000000..bb7f10efdd --- /dev/null +++ b/packages/core-transaction-pool-mem/lib/index.js @@ -0,0 +1,29 @@ +const Connection = require('./connection') + +/** + * The struct used by the plugin container. + * @type {Object} + */ +exports.plugin = { + pkg: require('../package.json'), + defaults: require('./defaults'), + alias: 'transactionPool', + extends: '@arkecosystem/core-transaction-pool', + async register(container, options) { + container.resolvePlugin('logger').info('Connecting to transaction pool') + + const transactionPoolManager = container.resolvePlugin( + 'transactionPoolManager', + ) + await transactionPoolManager.makeConnection(new Connection(options)) + + return transactionPoolManager.connection() + }, + async deregister(container, options) { + container + .resolvePlugin('logger') + .info('Disconnecting from transaction pool') + + return container.resolvePlugin('transactionPool').disconnect() + }, +} diff --git a/packages/core-transaction-pool-mem/lib/mem-pool-transaction.js b/packages/core-transaction-pool-mem/lib/mem-pool-transaction.js new file mode 100644 index 0000000000..c52b2afff1 --- /dev/null +++ b/packages/core-transaction-pool-mem/lib/mem-pool-transaction.js @@ -0,0 +1,64 @@ +const assert = require('assert') +const crypto = require('@arkecosystem/crypto') + +const TRANSACTION_TYPES = crypto.constants.TRANSACTION_TYPES +const Transaction = crypto.models.Transaction + +/** + * A mem pool transaction. + * A normal transaction + * + a sequence number used to order by insertion time + * + a get-expiration-time method used to remove old transactions from the pool + */ +module.exports = class MemPoolTransaction { + /** + * Construct a MemPoolTransaction object. + * @param {Transaction} transaction base transaction object + * @param {Number} sequence insertion order sequence or undefined; + * if this is undefined at creation time, + * then it is assigned later using the + * setter method below + */ + constructor(transaction, sequence) { + assert(transaction instanceof Transaction) + this._transaction = transaction + + if (sequence !== undefined) { + assert(Number.isInteger(sequence)) + this._sequence = sequence + } + } + + get transaction() { + return this._transaction + } + + get sequence() { + return this._sequence + } + + set sequence(seq) { + assert.strictEqual(this._sequence, undefined) + this._sequence = seq + } + + /** + * Derive the transaction expiration time in number of seconds since + * the genesis block. + * @param {Number} maxTransactionAge maximum age (in seconds) of a transaction + * @return {Number} expiration time or null if the transaction does not expire + */ + expireAt(maxTransactionAge) { + const t = this._transaction + + if (t.expiration > 0) { + return t.expiration + } + + if (t.type !== TRANSACTION_TYPES.TIMELOCK_TRANSFER) { + return t.timestamp + maxTransactionAge + } + + return null + } +} diff --git a/packages/core-transaction-pool-mem/lib/mem.js b/packages/core-transaction-pool-mem/lib/mem.js new file mode 100644 index 0000000000..ba8935dbfa --- /dev/null +++ b/packages/core-transaction-pool-mem/lib/mem.js @@ -0,0 +1,316 @@ +const assert = require('assert') +const { slots } = require('@arkecosystem/crypto') + +class Mem { + /** + * Create the in-memory transaction pool structures. + */ + constructor() { + /** + * A monotonically increasing number, assigned to each new transaction and + * then incremented. + * Used to: + * - keep insertion order. + */ + this.sequence = 0 + + /** + * An array of MemPoolTransaction sorted by fee (the transaction with the + * highest fee is first). If the fee is equal, they are sorted by insertion + * order. + * Used to: + * - get the transactions with the highest fee + * - get the number of all transactions in the pool + */ + this.all = [] + + /** + * A boolean flag indicating whether `this.all` is indeed sorted or + * temporarily left unsorted. We use lazy sorting of `this.all`: + * - insertion just appends at the end (O(1)) + flag it as unsorted + * - deletion removes by using splice() (O(n)) + flag it as unsorted + * - lookup sorts if it is not sorted (O(n*log(n)) + flag it as sorted + */ + this.allIsSorted = true + + /** + * A map of (key=transaction id, value=MemPoolTransaction). + * Used to: + * - get a transaction, given its ID + */ + this.byId = {} + + /** + * A map of (key=sender public key, value=Set of MemPoolTransaction). + * Used to: + * - get all transactions from a given sender + * - get the number of all transactions from a given sender. + */ + this.bySender = {} + + /** + * An array of MemPoolTransaction, sorted by expiration (earliest date + * comes first). This array may not contain all transactions that are + * in the pool, transactions that are without expiration are not included. + * Used to: + * - find all transactions that have expired (have an expiration date + * earlier than a given date) - they are at the beginning of the array. + */ + this.byExpiration = [] + this.byExpirationIsSorted = true + + /** + * List of dirty transactions ids (that are not saved in the on-disk + * database yet). Used to delay and group operations to the on-disk database. + */ + this.dirty = { + added: new Set(), + removed: new Set(), + } + } + + /** + * Add a transaction. + * @param {MemPoolTransaction} memPoolTransaction transaction to add + * @param {Number} maxTransactionAge maximum age of a transaction in seconds + * @param {Boolean} thisIsDBLoad if true, then this is the initial + * loading from the database and we do + * not need to schedule the transaction + * that is being added for saving to disk + */ + add(memPoolTransaction, maxTransactionAge, thisIsDBLoad = false) { + const transaction = memPoolTransaction.transaction + + assert.strictEqual(this.byId[transaction.id], undefined) + + if (thisIsDBLoad) { + // Sequence is provided from outside, make sure we avoid duplicates + // later when we start using our this.sequence. + assert.strictEqual(typeof memPoolTransaction.sequence, 'number') + this.sequence = Math.max(this.sequence, memPoolTransaction.sequence) + 1 + } else { + // Sequence should only be set during DB load (when sequences come + // from the database). In other scenarios sequence is not set and we + // set it here. + memPoolTransaction.sequence = this.sequence++ + } + + this.all.push(memPoolTransaction) + this.allIsSorted = false + + this.byId[transaction.id] = memPoolTransaction + + const sender = transaction.senderPublicKey + if (this.bySender[sender] === undefined) { + // First transaction from this sender, create a new Set. + this.bySender[sender] = new Set([memPoolTransaction]) + } else { + // Append to existing transaction ids for this sender. + this.bySender[sender].add(memPoolTransaction) + } + + if (memPoolTransaction.expireAt(maxTransactionAge) !== null) { + this.byExpiration.push(memPoolTransaction) + this.byExpirationIsSorted = false + } + + if (!thisIsDBLoad) { + if (this.dirty.removed.has(transaction.id)) { + // If the transaction has been already in the pool and has been removed + // and the removal has not propagated to disk yet, just wipe it from the + // list of removed transactions, so that the old copy stays on disk. + this.dirty.removed.delete(transaction.id) + } else { + this.dirty.added.add(transaction.id) + } + } + } + + /** + * Remove a transaction. + * @param {String} id id of the transaction to remove + * @param {String} senderPublicKey public key of the sender, could be undefined + */ + remove(id, senderPublicKey) { + if (this.byId[id] === undefined) { + // Not found, not in pool + return + } + + if (senderPublicKey === undefined) { + senderPublicKey = this.byId[id].transaction.senderPublicKey + } + + const memPoolTransaction = this.byId[id] + + // XXX worst case: O(n) + let i = this.byExpiration.findIndex(e => e.transaction.id === id) + if (i !== -1) { + this.byExpiration.splice(i, 1) + } + + this.bySender[senderPublicKey].delete(memPoolTransaction) + if (this.bySender[senderPublicKey].size === 0) { + delete this.bySender[senderPublicKey] + } + + delete this.byId[id] + + i = this.all.findIndex(e => e.transaction.id === id) + assert.notStrictEqual(i, -1) + this.all.splice(i, 1) + this.allIsSorted = false + + if (this.dirty.added.has(id)) { + // This transaction has been added and deleted without data being synced + // to disk in between, so it will never touch the disk, just remove it + // from the added list. + this.dirty.added.delete(id) + } else { + this.dirty.removed.add(id) + } + } + + /** + * Get the number of transactions. + * @return Number + */ + getSize() { + return this.all.length + } + + /** + * Get all transactions from a given sender. + * @param {String} senderPublicKey public key of the sender + * @return {Set of MemPoolTransaction} all transactions for the given sender, could be empty Set + */ + getBySender(senderPublicKey) { + const memPoolTransactions = this.bySender[senderPublicKey] + if (memPoolTransactions !== undefined) { + return memPoolTransactions + } + return new Set() + } + + /** + * Get a transaction, given its id. + * @param {String} id transaction id + * @return {Transaction|undefined} + */ + getTransactionById(id) { + if (this.byId[id] === undefined) { + return undefined + } + return this.byId[id].transaction + } + + /** + * Get an array of all transactions ordered by fee. + * Transactions are ordered by fee (highest fee first) or by + * insertion time, if fees equal (earliest transaction first). + * @return {Array of MemPoolTransaction} transactions + */ + getTransactionsOrderedByFee() { + if (!this.allIsSorted) { + this.all.sort((a, b) => { + if (a.transaction.fee.isGreaterThan(b.transaction.fee)) { + return -1 + } + if (a.transaction.fee.isLessThan(b.transaction.fee)) { + return 1 + } + return a.sequence - b.sequence + }) + this.allIsSorted = true + } + + return this.all + } + + /** + * Check if a transaction with a given id exists. + * @param {String} id transaction id + * @return {Boolean} true if exists + */ + transactionExists(id) { + return this.byId[id] !== undefined + } + + /** + * Get the expired transactions. + * @param {Number} maxTransactionAge maximum age of a transaction in seconds + * @return {Array of Transaction} expired transactions + */ + getExpired(maxTransactionAge) { + if (!this.byExpirationIsSorted) { + this.byExpiration.sort( + (a, b) => a.expireAt(maxTransactionAge) - b.expireAt(maxTransactionAge), + ) + this.byExpirationIsSorted = true + } + + const now = slots.getTime() + + const transactions = [] + + for (const memPoolTransaction of this.byExpiration) { + if (memPoolTransaction.expireAt(maxTransactionAge) <= now) { + transactions.push(memPoolTransaction.transaction) + } else { + break + } + } + + return transactions + } + + /** + * Remove all transactions. + */ + flush() { + this.all = [] + this.allIsSorted = true + this.byId = {} + this.bySender = {} + this.byExpiration = [] + this.byExpirationIsSorted = true + this.dirty.added.clear() + this.dirty.removed.clear() + } + + /** + * Get the number of dirty transactions (added or removed, but those additions or + * removals have not been applied to the persistent storage). + * @return {Number} number of dirty transactions + */ + getNumberOfDirty() { + return this.dirty.added.size + this.dirty.removed.size + } + + /** + * Get the dirty transactions that were added and forget they are dirty. + * In other words, get the transactions that were added since the last + * call to this method (or to the flush() method). + * @return {Array of MemPoolTransaction} + */ + getDirtyAddedAndForget() { + const added = [] + this.dirty.added.forEach(id => added.push(this.byId[id])) + this.dirty.added.clear() + return added + } + + /** + * Get the ids of dirty transactions that were removed and forget them completely. + * In other words, get the transactions that were removed since the last + * call to this method (or to the flush() method). + * @return {Array of String} transaction ids + */ + getDirtyRemovedAndForget() { + const removed = Array.from(this.dirty.removed) + this.dirty.removed.clear() + return removed + } +} + +module.exports = Mem diff --git a/packages/core-transaction-pool-mem/lib/storage.js b/packages/core-transaction-pool-mem/lib/storage.js new file mode 100644 index 0000000000..40ce9595ed --- /dev/null +++ b/packages/core-transaction-pool-mem/lib/storage.js @@ -0,0 +1,121 @@ +const BetterSqlite3 = require('better-sqlite3') +const fs = require('fs-extra') +const { Transaction } = require('@arkecosystem/crypto').models +const MemPoolTransaction = require('./mem-pool-transaction') + +/** + * A permanent storage (on-disk), supporting some basic functionalities required + * by the transaction pool. + */ +class Storage { + /** + * Construct the storage. + * @param {String} file + */ + constructor(file) { + this.table = 'pool' + + fs.ensureFileSync(file) + + this.db = new BetterSqlite3(file) + + this.db.exec(` + PRAGMA journal_mode=WAL; + CREATE TABLE IF NOT EXISTS ${this.table} ( + "sequence" INTEGER PRIMARY KEY, + "id" VARCHAR(64) UNIQUE, + "serialized" BLOB NOT NULL + ); + `) + } + + /** + * Close the storage. + */ + close() { + this.db.close() + this.db = null + } + + /** + * Add a bunch of new entries to the storage. + * @param {Array of MemPoolTransaction} data new entries to be added + */ + bulkAdd(data) { + if (data.length === 0) { + return + } + + const insertStatement = this.db.prepare( + `INSERT INTO ${this.table} ` + + '(sequence, id, serialized) VALUES ' + + '(:sequence, :id, :serialized);', + ) + + try { + this.db.prepare('BEGIN;').run() + + data.forEach(d => + insertStatement.run({ + sequence: d.sequence, + id: d.transaction.id, + serialized: Buffer.from(d.transaction.serialized, 'hex'), + }), + ) + + this.db.prepare('COMMIT;').run() + } finally { + if (this.db.inTransaction) { + this.db.prepare('ROLLBACK;').run() + } + } + } + + /** + * Remove a bunch of entries, given their ids. + * @param {Array of String} ids ids of the elements to be removed + */ + bulkRemoveById(ids) { + if (ids.length === 0) { + return + } + + const deleteStatement = this.db.prepare( + `DELETE FROM ${this.table} WHERE id = :id;`, + ) + + this.db.prepare('BEGIN;').run() + + ids.forEach(id => deleteStatement.run({ id })) + + this.db.prepare('COMMIT;').run() + } + + /** + * Load all entries. + * @return {Array of MemPoolTransaction} + */ + loadAll() { + const rows = this.db + .prepare( + `SELECT sequence, lower(HEX(serialized)) AS serialized FROM ${ + this.table + };`, + ) + .all() + + return rows + .map(r => ({ tx: new Transaction(r.serialized), ...r })) + .filter(r => r.tx.verified) + .map(r => new MemPoolTransaction(r.tx, r.sequence)) + } + + /** + * Delete all entries. + */ + deleteAll() { + this.db.exec(`DELETE FROM ${this.table};`) + } +} + +module.exports = Storage diff --git a/packages/core-transaction-pool-mem/package.json b/packages/core-transaction-pool-mem/package.json new file mode 100644 index 0000000000..27de168b34 --- /dev/null +++ b/packages/core-transaction-pool-mem/package.json @@ -0,0 +1,41 @@ +{ + "name": "@arkecosystem/core-transaction-pool-mem", + "description": "Transaction Pool - Memory implementation for Ark Core", + "version": "0.2.0", + "contributors": [ + "Kristjan Košič ", + "Brian Faust ", + "Alex Barnsley ", + "Vasil Dimov " + ], + "license": "MIT", + "main": "lib/index.js", + "scripts": { + "test": "cross-env ARK_ENV=test jest --runInBand --forceExit --detectOpenHandles", + "test:coverage": "cross-env ARK_ENV=test jest --runInBand --coverage --coveragePathIgnorePatterns='/(defaults.js|index.js)$' --forceExit", + "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand", + "test:watch": "cross-env ARK_ENV=test jest --runInBand --watch", + "test:watch:all": "cross-env ARK_ENV=test jest --runInBand --watchAll", + "lint": "eslint ./ --fix", + "depcheck": "depcheck ./" + }, + "dependencies": { + "@arkecosystem/core-container": "~0.2", + "@arkecosystem/core-transaction-pool": "~0.2", + "@arkecosystem/crypto": "~0.2", + "better-sqlite3": "^5.0.1", + "delay": "^4.1.0", + "fs-extra": "^7.0.1" + }, + "devDependencies": { + "@arkecosystem/core-test-utils": "~0.2", + "@arkecosystem/core-utils": "~0.2", + "random-seed": "^0.3.0" + }, + "publishConfig": { + "access": "public" + }, + "engines": { + "node": ">=10.x" + } +} diff --git a/packages/core-transaction-pool-redis/CHANGELOG.md b/packages/core-transaction-pool-redis/CHANGELOG.md deleted file mode 100644 index 21aae20925..0000000000 --- a/packages/core-transaction-pool-redis/CHANGELOG.md +++ /dev/null @@ -1,17 +0,0 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) -and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). - -## Unreleased -## 0.0.1 - 2018-07-27 -- Adding new methods to the pool for size, sender size, sender accept -- GetForgingTransactions and AcceptChainedBlock moved out of specific implementation to the parent plugin: core-transaction-pool -- Handling Duplicates on parent level before entering guard -- Additional tests - -## 0.0.1 - 2018-05-31 -### Added -- initial release diff --git a/packages/core-transaction-pool-redis/__tests__/__fixtures__/transactions.js b/packages/core-transaction-pool-redis/__tests__/__fixtures__/transactions.js deleted file mode 100644 index bd59a86b74..0000000000 --- a/packages/core-transaction-pool-redis/__tests__/__fixtures__/transactions.js +++ /dev/null @@ -1,179 +0,0 @@ -const ark = require('@arkecosystem/crypto') -const { slots } = ark -const { Transaction } = ark.models - -exports.dummy1 = new Transaction({ - version: 1, - network: 23, - type: 0, - timestamp: 35672738, - senderPublicKey: '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', - fee: 10000000, - vendorFieldHex: '5449443a2030', - amount: 200000000, - expiration: 0, - recipientId: 'AFzQCx5YpGg5vKMBg4xbuYbqkhvMkKfKe5', - signature: '304502210096ec6e27176fa694638d6fff35d7a551b2ed8c479a7e03264026eea41a05edd702206c071c97d1c6cc3bfec64dfff808cb0d5dfe857803428efb80bf7717b85cb619', - vendorField: 'TID: 0', - id: 'a5e9e6039675563959a783fa672c0ffe65369168a1ecffa3c89bf82961d8dbad' -}) - -exports.dummy2 = new Transaction({ - version: 1, - network: 30, - type: 0, - timestamp: 35632190, - senderPublicKey: '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', - fee: 10000000, - amount: 10000000, - expiration: 0, - recipientId: 'DFyDKsyvR4x9D9zrfEaPmeJxSniT5N5qY8', - signature: '3045022100ead721ae139c0a18a7be2077453337f8305e02a474a3e4e35eb22bcf59ce474c02207ea591ac68b5cfee068ac605efb000c7e1e7479abc7f6ee7ece21f3a5c629800', - secondSignature: '3044022006bd359a6820353e5e2f28adc0569f79ee7ed2918ee169bb149ca582f613fa760220502f39db1f9568edeb05df08d570a21a8204cb66f993f7cea6554a3298c548be', - signSignature: '3044022006bd359a6820353e5e2f28adc0569f79ee7ed2918ee169bb149ca582f613fa760220502f39db1f9568edeb05df08d570a21a8204cb66f993f7cea6554a3298c548be', - id: 'e665f6634fdbbbc562f79b92c8f0acd621081680c247cb4a6fc987bf456ea554' -}) - -exports.dummy3 = new Transaction({ - version: 1, - type: 0, - amount: 200000000, - fee: 10000000, - recipientId: 'ANqvJEMZcmUpcKBC8xiP1TntVkJeuZ3Lw3', - timestamp: 37346710, - asset: {}, - vendorField: 'TID: 0', - senderPublicKey: '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', - signature: '304402203f4d2b11b6f05538b16e2ab314c3c158885d8ceb95f3c0237d00fb350ea1b8e7022052eb7a2cd35c0d91ac14a8cba32b14a744ef26fc7d4c63b66d55f3ade0d6c305', - id: 'b163572af7598e35b4ea51e92cd1b59c8d653a50fc21358a7690777cc793cc50' -}) - -exports.dummy4 = new Transaction({ - version: 1, - type: 0, - amount: 200000000, - fee: 10000000, - recipientId: 'AJ5eV59hu4xrbRCpoP3of7fEYWUteSVa8k', - timestamp: 37346710, - asset: {}, - vendorField: 'TID: 1', - senderPublicKey: '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', - signature: '30450221008e04e622578bb6ac55097c9af3b7ffb553b659900f58056dae6ff2d57b0630000220071f416401431ba375f3f1a345b5f98deddd2198f072af4746a78417f8ece47d', - id: '03ebe9fd182e2ac19244a80717428b5ded0c2e7692f7f503f1acea0ea285ded9' -}) - -exports.dummy5 = new Transaction({ - version: 1, - type: 0, - amount: 200000000, - fee: 10000000, - recipientId: 'ASvC1E9hMLfANTi63S2gUMvr7rVZYJBj3u', - timestamp: 37346710, - asset: {}, - vendorField: 'TID: 2', - senderPublicKey: '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', - signature: '304502210095e699ae51090076180ead5623059ad0e607f08cf2a56b6a214817ec08610fd6022041ab05fe8acffdf0e4ed265d062411b2d3e47cf0f76b22793aee6ba12b17042c', - id: 'b1b89654cabf06fd2db8aa0b3659efcbf7430d1223bae0d8a23f6fad0983b032' -}) - -exports.dummy6 = new Transaction({ - version: 1, - type: 0, - amount: 200000000, - fee: 10000000, - recipientId: 'Ac8utEr7XRebWRvArSBnbVoxbq6bXftAmL', - timestamp: 37346710, - asset: {}, - vendorField: 'TID: 3', - senderPublicKey: '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', - signature: '304402203388ae5ba8f6248545593e7b4401900ca47dc5d694f5c36c8e1dafa67f1e214a02204a5e0cb620f0229cd0059675c8e2e3d835621eb682dc77f993acf5345a2f2bc7', - id: '937cb5431352100d60b5a6e9d5bb487c1276c1dee7ab75a238ca98daca35d236' -}) - -exports.dummy7 = new Transaction({ - version: 1, - type: 0, - amount: 200000000, - fee: 10000000, - recipientId: 'ANWEaVfvAh3VTyZNYcuFESUum1XBmAvAdj', - timestamp: 37346710, - asset: {}, - vendorField: 'TID: 4', - senderPublicKey: '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', - signature: '304502210093b9cf39802eff75d1f16c5f1de5a4326c77c73153e9cb87cfeb81f00b59a06402200b5375046043f0839bcdc2c3f972728241fb04fdacf3a669b12f2ec47c962d23', - id: 'd14ebba264bc6056acc5593c5c6d5566ae7bbd688556386e9e70ab33eb6e3e9c' -}) - -exports.dummy8 = new Transaction({ - version: 1, - type: 0, - amount: 200000000, - fee: 10000000, - recipientId: 'ALsZS24Dn4HYXwed5kAC5fKyB9BFzdmcSx', - timestamp: 37346710, - asset: {}, - vendorField: 'TID: 5', - senderPublicKey: '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', - signature: '30450221008425a7283e921d956a86db10bb34666deea9c13fa204420c4a85e2482399cce50220476bfdddc0743a0e05730e1b056a5a1d1030a963241ceced24da41ade6e6d2c9', - id: '7cf2325af89cdd7ac0b75e45a98ef1a30e8ee83842afeec27f22e695bf01f0ce' -}) - -exports.dummy9 = new Transaction({ - version: 1, - type: 0, - amount: 200000000, - fee: 10000000, - recipientId: 'ANuaLhRuBJhTcHao7kTfDcfsewLQGr7x5G', - timestamp: 37346710, - asset: {}, - vendorField: 'TID: 6', - senderPublicKey: '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', - signature: '3045022100f6571a7da13e81053e3cf39262b0dba7c476e589ae0c30ea7fb46bdff22dbd05022015c528cf9e8aacd986bb20b81420bf8eb7fd235a51f37193a8488f060a884267', - id: '6cc8e7d4ea99198dee4bed393e77828da8302619b27064933c0487c9dbb48e78' -}) - -exports.dummy10 = new Transaction({ - version: 1, - network: 30, - type: 0, - timestamp: slots.getTime(), - senderPublicKey: '0310c283aac7b35b4ae6fab201d36e8322c3408331149982e16013a5bcb917081c', - fee: 10000000, - amount: 20000000, - recipientId: 'DFyDKsyvR4x9D9zrfEaPmeJxSniT5N5qY8', - signature: '3045022100ead721ae139c0a18a7be2077453337f8305e02a474a3e4e35eb22bcf59ce474c02207ea591ac68b5cfee068ac605efb000c7e1e7479abc7f6ee7ece21f3a5c629800', - secondSignature: '3044022006bd359a6820353e5e2f28adc0569f79ee7ed2918ee169bb149ca582f613fa760220502f39db1f9568edeb05df08d570a21a8204cb66f993f7cea6554a3298c548be', - signSignature: '3044022006bd359a6820353e5e2f28adc0569f79ee7ed2918ee169bb149ca582f613fa760220502f39db1f9568edeb05df08d570a21a8204cb66f993f7cea6554a3298c548be', - vendorField: 'Expiring transaction 2' -}) - -exports.dummyExp1 = new Transaction({ - version: 1, - network: 23, - type: 0, - timestamp: slots.getTime(), - senderPublicKey: '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', - fee: 20000000, - vendorFieldHex: '5449443a2030', - amount: 200000000, - expiration: (slots.getTime() + 5), - recipientId: 'AFzQCx5YpGg5vKMBg4xbuYbqkhvMkKfKe5', - signature: '304502210096ec6e27176fa694638d6fff35d7a551b2ed8c479a7e03264026eea41a05edd702206c071c97d1c6cc3bfec64dfff808cb0d5dfe857803428efb80bf7717b85cb619', - vendorField: 'Expiring transaction 1' -}) - -exports.dummyExp2 = new Transaction({ - version: 1, - network: 30, - type: 0, - timestamp: slots.getTime(), - senderPublicKey: '0310c283aac7b35b4ae6fab201d36e8322c3408331149982e16013a5bcb917081c', - fee: 10000000, - amount: 20000000, - expiration: (slots.getTime() + 5), - recipientId: 'DFyDKsyvR4x9D9zrfEaPmeJxSniT5N5qY8', - signature: '3045022100ead721ae139c0a18a7be2077453337f8305e02a474a3e4e35eb22bcf59ce474c02207ea591ac68b5cfee068ac605efb000c7e1e7479abc7f6ee7ece21f3a5c629800', - secondSignature: '3044022006bd359a6820353e5e2f28adc0569f79ee7ed2918ee169bb149ca582f613fa760220502f39db1f9568edeb05df08d570a21a8204cb66f993f7cea6554a3298c548be', - signSignature: '3044022006bd359a6820353e5e2f28adc0569f79ee7ed2918ee169bb149ca582f613fa760220502f39db1f9568edeb05df08d570a21a8204cb66f993f7cea6554a3298c548be', - vendorField: 'Expiring transaction 2' -}) diff --git a/packages/core-transaction-pool-redis/__tests__/__support__/config.js b/packages/core-transaction-pool-redis/__tests__/__support__/config.js deleted file mode 100644 index 00b32e7291..0000000000 --- a/packages/core-transaction-pool-redis/__tests__/__support__/config.js +++ /dev/null @@ -1,12 +0,0 @@ -'use strict' - -module.exports = { - enabled: true, - key: 'ark_test', - maxTransactionsPerSender: 100, - allowedSenders: ['03dde379eb1da857f523c3b3560eb4bb7b99897df2054bd9774f49dd0371ee99b7'], - redis: { - host: process.env.ARK_REDIS_HOST || 'localhost', - port: process.env.ARK_REDIS_PORT || 6379 - } -} diff --git a/packages/core-transaction-pool-redis/__tests__/__support__/setup.js b/packages/core-transaction-pool-redis/__tests__/__support__/setup.js deleted file mode 100644 index 479ecd9dc7..0000000000 --- a/packages/core-transaction-pool-redis/__tests__/__support__/setup.js +++ /dev/null @@ -1,25 +0,0 @@ -'use strict'; - -const path = require('path') -const container = require('@arkecosystem/core-container') - -jest.setTimeout(30000) - -exports.setUp = async () => { - await container.setUp({ - data: '~/.ark', - config: path.resolve(__dirname, '../../../core/lib/config/testnet'), - token: 'ark', - network: 'testnet' - }, { - exit: '@arkecosystem/core-blockchain', - exclude: [ - '@arkecosystem/core-transaction-pool-redis', - '@arkecosystem/core-p2p' - ] - }) -} - -exports.tearDown = async () => { - await container.tearDown() -} diff --git a/packages/core-transaction-pool-redis/__tests__/connection.test.js b/packages/core-transaction-pool-redis/__tests__/connection.test.js deleted file mode 100644 index 3f065a8f28..0000000000 --- a/packages/core-transaction-pool-redis/__tests__/connection.test.js +++ /dev/null @@ -1,366 +0,0 @@ -'use strict' - -const app = require('./__support__/setup') -const delay = require('delay') -const mockData = require('./__fixtures__/transactions') -const { Transaction } = require('@arkecosystem/crypto').models -const defaultConfig = require('../lib/defaults') - -let connection - -beforeAll(async () => { - await app.setUp() - - const RedisConnection = require('../lib/connection.js') - connection = new RedisConnection(defaultConfig) - connection = await connection.make() -}) - -afterAll(async () => { - await connection.disconnect() - await app.tearDown() -}) - -afterEach(async () => { - await connection.flush() -}) - -describe('Connection', () => { - it('should be an object', () => { - expect(connection).toBeObject() - }) - - describe('getPoolSize', () => { - it('should be a function', () => { - expect(connection.getPoolSize).toBeFunction() - }) - - it('should return 0 if no transactions were added', async () => { - await expect(connection.getPoolSize()).resolves.toBe(0) - }) - - it('should return 2 if transactions were added', async () => { - await expect(connection.getPoolSize()).resolves.toBe(0) - - await connection.addTransaction(mockData.dummy1) - - await expect(connection.getPoolSize()).resolves.toBe(1) - }) - }) - - describe('getSenderSize', () => { - it('should be a function', () => { - expect(connection.getSenderSize).toBeFunction() - }) - - it('should return 0 if no transactions were added', async () => { - await expect(connection.getSenderSize('undefined')).resolves.toBe(0) - }) - - it('should return 2 if transactions were added', async () => { - await expect(connection.getSenderSize(mockData.dummy1.senderPublicKey)).resolves.toBe(0) - - await connection.addTransaction(mockData.dummy1) - await connection.addTransaction(mockData.dummy2) - - await expect(connection.getSenderSize(mockData.dummy1.senderPublicKey)).resolves.toBe(2) - }) - }) - - describe('addTransaction', () => { - it('should be a function', () => { - expect(connection.addTransaction).toBeFunction() - }) - - it('should add the transaction to the pool', async () => { - await expect(connection.getPoolSize()).resolves.toBe(0) - - await connection.addTransaction(mockData.dummy1) - - await expect(connection.getPoolSize()).resolves.toBe(1) - }) - }) - - describe('addTransactions', () => { - it('should be a function', () => { - expect(connection.addTransactions).toBeFunction() - }) - - it('should add the transactions to the pool', async () => { - await expect(connection.getPoolSize()).resolves.toBe(0) - - connection.addTransactions = jest.fn(async (transactions) => { - for (let i = 0; i < transactions.length; i++) { - await connection.addTransaction(transactions[i]) - } - }) - - await connection.addTransactions([mockData.dummy1, mockData.dummy2]) - - await expect(connection.getPoolSize()).resolves.toBe(2) - }) - }) - - describe('addTransactions with expiration', () => { - it('should add the transactions to the pool and they should expire', async () => { - await expect(connection.getPoolSize()).resolves.toBe(0) - - connection.addTransactions = jest.fn(async (transactions) => { - for (let i = 0; i < transactions.length; i++) { - await connection.addTransaction(transactions[i]) - } - }) - - const trx1 = new Transaction(mockData.dummyExp1) - const trx2 = new Transaction(mockData.dummyExp2) - - await connection.addTransactions([trx1, trx2]) - - await expect(connection.getPoolSize()).resolves.toBe(2) - await delay(7000) - await expect(connection.getPoolSize()).resolves.toBe(0) - }) - }) - - describe('removeTransaction', () => { - it('should be a function', () => { - expect(connection.removeTransaction).toBeFunction() - }) - - it('should remove the specified transaction from the pool', async () => { - await connection.addTransaction(mockData.dummy1) - - await expect(connection.getPoolSize()).resolves.toBe(1) - - await connection.removeTransaction(mockData.dummy1) - - await expect(connection.getPoolSize()).resolves.toBe(0) - }) - }) - - describe('removeTransactionById', () => { - it('should be a function', () => { - expect(connection.removeTransactionById).toBeFunction() - }) - - it('should remove the specified transaction from the pool (by id)', async () => { - await connection.addTransaction(mockData.dummy1) - - await expect(connection.getPoolSize()).resolves.toBe(1) - - await connection.removeTransactionById(mockData.dummy1.id) - - await expect(connection.getPoolSize()).resolves.toBe(0) - }) - }) - - describe('removeTransactions', () => { - it('should be a function', () => { - expect(connection.removeTransactions).toBeFunction() - }) - - it('should remove the specified transactions from the pool', async () => { - await connection.addTransaction(mockData.dummy1) - await connection.addTransaction(mockData.dummy2) - - await expect(connection.getPoolSize()).resolves.toBe(2) - - await connection.removeTransactions([mockData.dummy1, mockData.dummy2]) - - await expect(connection.getPoolSize()).resolves.toBe(0) - }) - }) - - describe('removeTransactionsForSender', () => { - it('should be a function', () => { - expect(connection.removeTransactionsForSender).toBeFunction() - }) - - it('should remove the senders transactions from the pool', async () => { - await connection.addTransaction(mockData.dummy1) - await connection.addTransaction(mockData.dummy2) - await connection.addTransaction(mockData.dummy3) - await connection.addTransaction(mockData.dummy4) - await connection.addTransaction(mockData.dummy5) - await connection.addTransaction(mockData.dummy6) - await connection.addTransaction(mockData.dummy10) - - await expect(connection.getPoolSize()).resolves.toBe(7) - - await connection.removeTransactionsForSender(mockData.dummy1.senderPublicKey) - - await expect(connection.getPoolSize()).resolves.toBe(1) - }) - }) - - describe('transactionExists', () => { - it('should be a function', () => { - expect(connection.transactionExists).toBeFunction() - }) - - it('should return true if transaction is IN pool', async () => { - const trx1 = new Transaction(mockData.dummy1) - const trx2 = new Transaction(mockData.dummy1) - await connection.addTransactions([trx1, trx2]) - - await delay(500) - - const res1 = await connection.transactionExists(trx1.id) - expect(res1).toBe(true) - - const res2 = await connection.transactionExists(trx2.id) - expect(res2).toBe(true) - }) - - it('should return false if transaction is NOT pool', async () => { - const trx1 = new Transaction(mockData.dummy1) - const trx2 = new Transaction(mockData.dummy1) - - const res1 = await connection.transactionExists(trx1.id) - expect(res1).toBe(false) - - const res2 = await connection.transactionExists(trx2.id) - expect(res2).toBe(false) - }) - }) - - describe('hasExceededMaxTransactions', () => { - it('should be a function', () => { - expect(connection.hasExceededMaxTransactions).toBeFunction() - }) - - it('should be truthy if exceeded', async () => { - connection.options.maxTransactionsPerSender = 5 - connection.options.allowedSenders = [] - await connection.addTransaction(mockData.dummy3) - await connection.addTransaction(mockData.dummy4) - await connection.addTransaction(mockData.dummy5) - await connection.addTransaction(mockData.dummy6) - await connection.addTransaction(mockData.dummy7) - await connection.addTransaction(mockData.dummy8) - await connection.addTransaction(mockData.dummy9) - - await expect(connection.getPoolSize()).resolves.toBe(7) - const exceeded = await connection.hasExceededMaxTransactions(mockData.dummy3) - await expect(exceeded).toBeTruthy() - }) - - it('should be falsy if not exceeded', async () => { - connection.options.maxTransactionsPerSender = 7 - connection.options.allowedSenders = [] - - await connection.addTransaction(mockData.dummy4) - await connection.addTransaction(mockData.dummy5) - await connection.addTransaction(mockData.dummy6) - - await expect(connection.getPoolSize()).resolves.toBe(3) - const exceeded = await connection.hasExceededMaxTransactions(mockData.dummy3) - await expect(exceeded).toBeFalsy() - }) - - it('should be allowed to exceed if whitelisted', async () => { - await connection.flush() - connection.options.maxTransactionsPerSender = 5 - connection.options.allowedSenders = ['03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', 'ghjk'] - await connection.addTransaction(mockData.dummy3) - await connection.addTransaction(mockData.dummy4) - await connection.addTransaction(mockData.dummy5) - await connection.addTransaction(mockData.dummy6) - await connection.addTransaction(mockData.dummy7) - await connection.addTransaction(mockData.dummy8) - await connection.addTransaction(mockData.dummy9) - - await expect(connection.getPoolSize()).resolves.toBe(7) - const exceeded = await connection.hasExceededMaxTransactions(mockData.dummy3) - await expect(exceeded).toBeFalsy() - }) - }) - - describe('getTransaction', () => { - it('should be a function', () => { - expect(connection.getTransaction).toBeFunction() - }) - - it('should return the specified transaction', async () => { - await connection.addTransaction(mockData.dummy1) - - const poolTransaction = await connection.getTransaction(mockData.dummy1.id) - await expect(poolTransaction).toBeObject() - await expect(poolTransaction.id).toBe(mockData.dummy1.id) - }) - - it('should return undefined for nonexisting transaction', async () => { - const poolTransaction = await connection.getTransaction('non existing id') - await expect(poolTransaction).toBeFalsy() - }) - }) - - describe('getTransactions', () => { - it('should be a function', () => { - expect(connection.getTransactions).toBeFunction() - }) - - it('should return transactions within the specified range', async () => { - await connection.addTransaction(mockData.dummy1) - await connection.addTransaction(mockData.dummy2) - - let transactions = await connection.getTransactions(0, 1) - transactions = transactions.map(serializedTx => Transaction.fromBytes(serializedTx)) - - await expect(transactions[0]).toBeObject() - await expect(transactions[0].id).toBe(mockData.dummy1.id) - }) - }) - - describe('getTransactionsForForging', () => { - it('should be a function', () => { - expect(connection.getTransactionsForForging).toBeFunction() - }) - - it('should return an array of transactions', async () => { - await connection.addTransaction(mockData.dummy1) - await connection.addTransaction(mockData.dummy2) - await connection.addTransaction(mockData.dummy3) - await connection.addTransaction(mockData.dummy4) - await connection.addTransaction(mockData.dummy5) - await connection.addTransaction(mockData.dummy6) - - let transactions = await connection.getTransactionsForForging(0, 6) - transactions = transactions.map(serializedTx => Transaction.fromBytes(serializedTx)) - - await expect(transactions[0]).toBeObject() - await expect(transactions[0].id).toBe(mockData.dummy1.id) - await expect(transactions[1].id).toBe(mockData.dummy2.id) - await expect(transactions[2].id).toBe(mockData.dummy3.id) - await expect(transactions[3].id).toBe(mockData.dummy4.id) - await expect(transactions[4].id).toBe(mockData.dummy5.id) - await expect(transactions[5].id).toBe(mockData.dummy6.id) - }) - }) - - describe('flush', () => { - it('should be a function', () => { - expect(connection.flush).toBeFunction() - }) - - it('should flush the pool', async () => { - await connection.addTransaction(mockData.dummy1) - - await expect(connection.getPoolSize()).resolves.toBe(1) - - await connection.flush() - - await expect(connection.getPoolSize()).resolves.toBe(0) - }) - }) - - describe('__isReady', () => { - it('should be a function', () => { - expect(connection.__isReady).toBeFunction() - }) - - it('should be truthy if connected', async () => { - expect(connection.__isReady()).toBeTruthy() - }) - }) -}) diff --git a/packages/core-transaction-pool-redis/jest.config.js b/packages/core-transaction-pool-redis/jest.config.js deleted file mode 100644 index 26f7a25796..0000000000 --- a/packages/core-transaction-pool-redis/jest.config.js +++ /dev/null @@ -1,22 +0,0 @@ -'use strict' - -module.exports = { - testEnvironment: 'node', - bail: false, - verbose: true, - testMatch: [ - '**/__tests__/**/*.test.js' - ], - moduleFileExtensions: [ - 'js', - 'json' - ], - collectCoverage: false, - coverageDirectory: '/.coverage', - collectCoverageFrom: [ - 'lib/**/*.js', - '!**/node_modules/**' - ], - watchman: false, - setupTestFrameworkScriptFile: 'jest-extended' -} diff --git a/packages/core-transaction-pool-redis/lib/connection.js b/packages/core-transaction-pool-redis/lib/connection.js deleted file mode 100644 index be92e3dadd..0000000000 --- a/packages/core-transaction-pool-redis/lib/connection.js +++ /dev/null @@ -1,363 +0,0 @@ -'use strict' - -const { TransactionPoolInterface } = require('@arkecosystem/core-transaction-pool') -const Redis = require('ioredis') -const container = require('@arkecosystem/core-container') -const logger = container.resolvePlugin('logger') -const emitter = container.resolvePlugin('event-emitter') -const ark = require('@arkecosystem/crypto') -const { Transaction } = ark.models - -module.exports = class TransactionPool extends TransactionPoolInterface { - /** - * Make the transaction pool instance. - * @return {TransactionPool} - */ - make () { - if (!this.options.enabled) { - logger.warn('Redis transaction pool disabled - please enable if run in production') - - return this - } - - this.keyPrefix = this.options.key - this.pool = new Redis(this.options.redis) - this.subscription = new Redis(this.options.redis) - - this.pool.on('connect', () => { - logger.info('Redis connection established') - - this.pool.config('set', 'notify-keyspace-events', 'Ex') - - this.subscription.subscribe('__keyevent@0__:expired') - }) - - this.pool.on('error', () => { - logger.error('Could not connect to Redis. If you do not wish to use the transaction pool, please disable it and restart, otherwise fix the issue.') - process.exit(1) - }) - - this.subscription.on('message', async (channel, message) => { - logger.debug(`Received expiration message ${message} from channel ${channel}`) - if (message.split(':')[0] === this.keyPrefix) { - const transactionId = message.split(':')[2] - const transaction = await this.getTransaction(transactionId) - - emitter.emit('transaction.expired', transaction.data) - - this.walletManager.revertTransaction(transaction) - await this.removeTransaction(transaction) - } - }) - - return this - } - - /** - * Disconnect from Redis. - * @return {void} - */ - async disconnect () { - try { - if (this.pool) { - await this.pool.disconnect() - } - } catch (error) { - logger.warn('Connection already closed') - } - try { - if (this.subscription) { - await this.subscription.disconnect() - } - } catch (error) { - logger.warn('Connection already closed') - } - } - - /** - * Get the number of transactions in the pool. - * @return {Number} - */ - async getPoolSize () { - return this.__isReady() ? this.pool.llen(this.__getRedisOrderKey()) : 0 - } - - /** - * Get the number of transaction in the pool from specific sender - * @param {String} senderPublicKey - * @returns {Number} - */ - async getSenderSize (senderPublicKey) { - return this.pool.llen(this.__getRedisSenderPublicKey(senderPublicKey)) - } - - /** - * Add a transaction to the pool. - * @param {(Transaction|void)} transaction - */ - async addTransaction (transaction) { - if (!this.__isReady()) { - return - } - - if (!(transaction instanceof Transaction)) { - logger.warn(`Discarded Transaction ${transaction} - Invalid object.`) - return - } - - if (await this.transactionExists(transaction.id)) { - logger.debug(`Duplicated Transaction ${transaction.id} - Transaction already in pool.`) - return - } - - try { - const res = await this.pool.hmset(this.__getRedisTransactionKey(transaction.id), - 'serialized', transaction.serialized.toString('hex'), - 'senderPublicKey', transaction.senderPublicKey - ) - - if (res === 0) { - throw new Error('Transaction not added to the pool - await this.pool.hmset failed') - } - await this.pool.rpush(this.__getRedisOrderKey(), transaction.id) - await this.pool.rpush(this.__getRedisSenderPublicKey(transaction.senderPublicKey), transaction.id) - - if (transaction.expiration > 0) { - await this.pool.setex(this.__getRedisExpirationKey(transaction.id), transaction.expiration - transaction.timestamp, transaction.id) - } - } catch (error) { - logger.error('Could not add transaction to Redis', error, error.stack) - - this.walletManager.revertTransaction(transaction) - } - } - - /** - * Add many transaction to the pool. - * @param {Array} transactions, already transformed and verified by transaction guard - must have serialized field - */ - addTransactions (transactions) { - if (!this.__isReady()) { - return - } - - transactions.forEach(transaction => { - this.addTransaction(transaction) - }) - } - - /** - * Remove a transaction from the pool by transaction object. - * @param {Transaction} transaction - * @return {void} - */ - async removeTransaction (transaction) { - if (!this.__isReady()) { - return - } - - if (await this.transactionExists(transaction.id)) { - await this.pool.lrem(this.__getRedisOrderKey(), 0, transaction.id) - await this.pool.lrem(this.__getRedisSenderPublicKey(transaction.senderPublicKey), 0, transaction.id) - await this.pool.del([this.__getRedisExpirationKey(transaction.id), this.__getRedisTransactionKey(transaction.id)]) - } - } - - /** - * Remove a transaction from the pool by id. - * @param {Number} id - * @return {void} - */ - async removeTransactionById (id) { - if (!this.__isReady()) { - return - } - - if (await this.transactionExists(id)) { - const senderPublicKey = await this.pool.hget(this.__getRedisTransactionKey(id), 'senderPublicKey') - - await this.pool.lrem(this.__getRedisSenderPublicKey(senderPublicKey), 0, id) - await this.pool.lrem(this.__getRedisOrderKey(), 0, id) - await this.pool.del(this.__getRedisExpirationKey(id)) - await this.pool.del(this.__getRedisTransactionKey(id)) - } - } - - /** - * Remove multiple transactions from the pool. - * @param {Array} transactions - * @return {void} - */ - async removeTransactions (transactions) { - if (!this.__isReady()) { - return - } - - try { - for (let transaction of transactions) { - await this.removeTransaction(transaction) - } - } catch (error) { - logger.error('Could not remove transactions from Redis: ', error.stack) - } - } - - /** - * Check whether sender of transaction has exceeded max transactions in queue. - * @param {String} transaction - * @return {(Boolean|void)} - */ - async hasExceededMaxTransactions (transaction) { - if (!this.__isReady()) { - return - } - - if (this.options.allowedSenders.includes(transaction.senderPublicKey)) { - logger.debug(`Transaction pool allowing ${transaction.senderPublicKey} senderPublicKey, thus skipping throttling.`) - return false - } - - const count = await this.pool.llen(this.__getRedisSenderPublicKey(transaction.senderPublicKey)) - return count ? count >= this.options.maxTransactionsPerSender : false - } - - /** - * Get a transaction by transaction id. - * @param {Number} id - * @return {(Transaction|String|void)} - */ - async getTransaction (id) { - if (!this.__isReady()) { - return - } - - const serialized = await this.pool.hget(this.__getRedisTransactionKey(id), 'serialized') - if (serialized) { - return Transaction.fromBytes(serialized) - } - - return undefined - } - - /** - * Get all transactions within the specified range. - * @param {Number} start - * @param {Number} size - * @return {(Array|void)} - */ - async getTransactions (start, size) { - if (!this.__isReady()) { - return - } - - try { - const transactionIds = await this.pool.lrange(this.__getRedisOrderKey(), start, start + size - 1) - - let transactions = [] - for (const id of transactionIds) { - const serializedTransaction = await this.pool.hmget(this.__getRedisTransactionKey(id), 'serialized') - serializedTransaction ? transactions.push(serializedTransaction[0]) : await this.removeTransactionById(id) - } - - return transactions - } catch (error) { - logger.error('Could not get transactions from Redis: ', error, error.stack) - } - } - - /** - * Get all transactions within the specified range. - * @param {Number} start - * @param {Number} size - * @return {(Array|void)} array of transactions IDs in specified range - */ - async getTransactionsIds (start, size) { - if (!this.__isReady()) { - return - } - - try { - const transactionIds = await this.pool.lrange(this.__getRedisOrderKey(), start, start + size - 1) - - return transactionIds - } catch (error) { - logger.error('Could not get transactions IDs from Redis: ', error, error.stack) - } - } - - /** - * Flush the pool. - * @return {void} - */ - async flush () { - const keys = await this.pool.keys(`${this.keyPrefix}:*`) - - keys.forEach(key => this.pool.del(key)) - } - - /** - * Remove all transactions from transaction pool belonging to specific sender - * @param {String} senderPublicKey - * @return {void} - */ - async removeTransactionsForSender (senderPublicKey) { - const senderTransactionIds = await this.pool.lrange(this.__getRedisSenderPublicKey(senderPublicKey), 0, -1) - - for (let id of senderTransactionIds) { - await this.removeTransactionById(id) - } - } - - /** - * Checks if transaction exists in the pool - * @param {transactionId} - * @return {Boolean} - */ - async transactionExists (transactionId) { - const exists = await this.pool.hexists(this.__getRedisTransactionKey(transactionId), 'serialized') - return (exists > 0) - } - - /** - * Get the Redis key for the given transaction. - * @param {Number} id - * @return {String} - */ - __getRedisTransactionKey (id) { - return `${this.keyPrefix}:transactions:${id}` - } - - /** - * Get the Redis key for the order of transactions. - * @return {String} - */ - __getRedisOrderKey () { - return `${this.keyPrefix}:order` - } - - /** - * Get the Redis key for the transactions expiration - * @param {String} publicKey - * @return {String} - */ - __getRedisExpirationKey (transactionId) { - return `${this.keyPrefix}:expiration:${transactionId}` - } - - /** - * Get the Redis key for searching/counting transactions related to and public key - * @param {String} senderPublicKey - * @return {String} - */ - __getRedisSenderPublicKey (senderPublicKey) { - return `${this.keyPrefix}:senderPublicKey:${senderPublicKey}` - } - - /** - * Determine if the pool and subscription are connected. - * @return {Boolean} - */ - __isReady () { - return this.pool && this.pool.status === 'ready' - } -} diff --git a/packages/core-transaction-pool-redis/lib/defaults.js b/packages/core-transaction-pool-redis/lib/defaults.js deleted file mode 100644 index dd8d68ffb3..0000000000 --- a/packages/core-transaction-pool-redis/lib/defaults.js +++ /dev/null @@ -1,12 +0,0 @@ -'use strict' - -module.exports = { - enabled: !process.env.ARK_TRANSACTION_POOL_DISABLED, - key: 'ark', - maxTransactionsPerSender: process.env.ARK_TRANSACTION_POOL_MAX_PER_SENDER || 100, - allowedSenders: [], - redis: { - host: process.env.ARK_REDIS_HOST || 'localhost', - port: process.env.ARK_REDIS_PORT || 6379 - } -} diff --git a/packages/core-transaction-pool-redis/lib/index.js b/packages/core-transaction-pool-redis/lib/index.js deleted file mode 100644 index 3e8d2711fc..0000000000 --- a/packages/core-transaction-pool-redis/lib/index.js +++ /dev/null @@ -1,26 +0,0 @@ -'use strict' - -const RedisConnection = require('./connection') - -/** - * The struct used by the plugin container. - * @type {Object} - */ -exports.plugin = { - pkg: require('../package.json'), - defaults: require('./defaults'), - alias: 'transactionPool', - async register (container, options) { - container.resolvePlugin('logger').info('Connecting to transaction pool') - - const transactionPoolManager = container.resolvePlugin('transactionPoolManager') - await transactionPoolManager.makeConnection(new RedisConnection(options)) - - return transactionPoolManager.connection() - }, - async deregister (container, options) { - container.resolvePlugin('logger').info('Disconnecting from transaction pool') - - return container.resolvePlugin('transactionPool').disconnect() - } -} diff --git a/packages/core-transaction-pool-redis/package.json b/packages/core-transaction-pool-redis/package.json deleted file mode 100644 index 878fbeefcc..0000000000 --- a/packages/core-transaction-pool-redis/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "@arkecosystem/core-transaction-pool-redis", - "description": "Transaction Pool - Redis Implementation for ARK Core", - "version": "0.1.1", - "contributors": [ - "Kristjan Košič ", - "Brian Faust ", - "Alex Barnsley " - ], - "license": "MIT", - "main": "lib/index.js", - "scripts": { - "build:docs": "../../node_modules/.bin/jsdoc -c jsdoc.json", - "test": "cross-env ARK_ENV=test jest --runInBand --detectOpenHandles", - "test:coverage": "cross-env ARK_ENV=test jest --coverage --runInBand --detectOpenHandles", - "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand --watch", - "test:watch": "cross-env ARK_ENV=test jest --runInBand --watch", - "test:watch:all": "cross-env ARK_ENV=test jest --runInBand --watchAll", - "lint": "eslint ./ --fix", - "depcheck": "depcheck ./" - }, - "dependencies": { - "@arkecosystem/core-container": "^0.1.1", - "@arkecosystem/core-transaction-pool": "^0.1.1", - "@arkecosystem/crypto": "^0.1.1", - "delay": "^3.0.0", - "ioredis": "^3.2.2" - }, - "publishConfig": { - "access": "public" - } -} diff --git a/packages/core-transaction-pool/CHANGELOG.md b/packages/core-transaction-pool/CHANGELOG.md index 10266a880d..e5ba2581be 100644 --- a/packages/core-transaction-pool/CHANGELOG.md +++ b/packages/core-transaction-pool/CHANGELOG.md @@ -6,20 +6,52 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). ## Unreleased -## 0.0.1 - 2018-07-27 -- Splitting guard methods into more smaller units -- Handling duplicates also on incomming payload level (before entering and checking with pool) -- Fix on applychained block - to use correct wallet and update from blockchain wallet only if necesary + +## 0.2.0 - 2018-12-03 + +### Added + - Delete pool wallet if no ballance or no transactions in pool - Additional tests implemented -- Broadcasting only valid transactions further (verified, and wallet manager applied) - -## 0.0.1 - 2018-07-20 - Pool wallet manager implementation to guard the pool -- GetForgingTransactions moved to Transaction Pool - Blocking of sender if not in conditions or whitelisted +- Limit votes to 1 per wallet in pool via guard +- Return error feedback from the guard +- Handle dynamic fees +- Better transaction ping +- Broadcasting on launch of relay +- Cap the number of transactions the pool can hold + +### Changed + +- Splitting guard methods into more smaller units +- GetForgingTransactions moved to Transaction Pool +- Broadcasting only valid transactions further (verified, and wallet manager applied) - Guard updated with wallet manager +- Handle numbers as `BigNumber` instances +- Dropped node.js 9 as minimum requirement in favour of node.js 10 +- Adjusted timeouts & lifetimes +- No longer add transactions that do not meet the fee requirements to the pool (BTC/ETH behaviour) +- No longer decline transactions that exceed the static fees +- Simplified the broadcasting logic +- Broadcast transactions when the pool is full + +### Fixed + +- Handling duplicates also on incomming payload level (before entering and checking with pool) +- Fix on applychained block - to use correct wallet and update from blockchain wallet only if necesary +- Call getTransactionIdsForForging() properly +- Properly log the transaction audit +- Properly determine valid transactions based on their type +- Handle unexpected errors in the guard +- Revert transactions with non-matching dynamic fees +- Revert excess transactions +- Reject transactions that have a timestamp from the future +- Remove invalid transactions from pool when receiving a bad block +- Handling of cold wallets while applying transactions + +## 0.1.1 - 2018-06-14 -## 0.0.1 - 2018-05-31 ### Added + - initial release diff --git a/packages/core-transaction-pool/README.md b/packages/core-transaction-pool/README.md index ce21022787..876e25757b 100644 --- a/packages/core-transaction-pool/README.md +++ b/packages/core-transaction-pool/README.md @@ -1,12 +1,12 @@ -![ARK Core](https://i.imgur.com/1aP6F2o.png) +# Ark Core - Transaction Pool - Interface -# ARK Core - Transaction Pool Interface +

+ +

-## Installation +## Documentation -```bash -yarn add @arkecosystem/core-transaction-pool -``` +You can find installation instructions and detailed instructions on how to use this package at the [dedicated documentation site](https://docs.ark.io/guidebook/core/plugins/core-transaction-pool.html). ## Security diff --git a/packages/core-transaction-pool/__tests__/__fixtures__/transactions.js b/packages/core-transaction-pool/__tests__/__fixtures__/transactions.js index d2fb4afaf7..33c59c7cbc 100644 --- a/packages/core-transaction-pool/__tests__/__fixtures__/transactions.js +++ b/packages/core-transaction-pool/__tests__/__fixtures__/transactions.js @@ -5,15 +5,17 @@ exports.dummy1 = new Transaction({ network: 23, type: 0, timestamp: 35672738, - senderPublicKey: '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', + senderPublicKey: + '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', fee: 10000000, vendorFieldHex: '5449443a2030', amount: 200000000, expiration: 0, recipientId: 'AFzQCx5YpGg5vKMBg4xbuYbqkhvMkKfKe5', - signature: '304502210096ec6e27176fa694638d6fff35d7a551b2ed8c479a7e03264026eea41a05edd702206c071c97d1c6cc3bfec64dfff808cb0d5dfe857803428efb80bf7717b85cb619', + signature: + '304502210096ec6e27176fa694638d6fff35d7a551b2ed8c479a7e03264026eea41a05edd702206c071c97d1c6cc3bfec64dfff808cb0d5dfe857803428efb80bf7717b85cb619', vendorField: 'TID: 0', - id: 'a5e9e6039675563959a783fa672c0ffe65369168a1ecffa3c89bf82961d8dbad' + id: 'a5e9e6039675563959a783fa672c0ffe65369168a1ecffa3c89bf82961d8dbad', }) exports.dummy2 = new Transaction({ @@ -21,13 +23,62 @@ exports.dummy2 = new Transaction({ network: 30, type: 0, timestamp: 35632190, - senderPublicKey: '0310c283aac7b35b4ae6fab201d36e8322c3408331149982e16013a5bcb917081c', + senderPublicKey: + '0310c283aac7b35b4ae6fab201d36e8322c3408331149982e16013a5bcb917081c', fee: 10000000, amount: 10000000, expiration: 0, recipientId: 'DFyDKsyvR4x9D9zrfEaPmeJxSniT5N5qY8', - signature: '3045022100ead721ae139c0a18a7be2077453337f8305e02a474a3e4e35eb22bcf59ce474c02207ea591ac68b5cfee068ac605efb000c7e1e7479abc7f6ee7ece21f3a5c629800', - secondSignature: '3044022006bd359a6820353e5e2f28adc0569f79ee7ed2918ee169bb149ca582f613fa760220502f39db1f9568edeb05df08d570a21a8204cb66f993f7cea6554a3298c548be', - signSignature: '3044022006bd359a6820353e5e2f28adc0569f79ee7ed2918ee169bb149ca582f613fa760220502f39db1f9568edeb05df08d570a21a8204cb66f993f7cea6554a3298c548be', - id: 'e665f6634fdbbbc562f79b92c8f0acd621081680c247cb4a6fc987bf456ea554' + signature: + '3045022100ead721ae139c0a18a7be2077453337f8305e02a474a3e4e35eb22bcf59ce474c02207ea591ac68b5cfee068ac605efb000c7e1e7479abc7f6ee7ece21f3a5c629800', + secondSignature: + '3044022006bd359a6820353e5e2f28adc0569f79ee7ed2918ee169bb149ca582f613fa760220502f39db1f9568edeb05df08d570a21a8204cb66f993f7cea6554a3298c548be', + signSignature: + '3044022006bd359a6820353e5e2f28adc0569f79ee7ed2918ee169bb149ca582f613fa760220502f39db1f9568edeb05df08d570a21a8204cb66f993f7cea6554a3298c548be', + id: 'e665f6634fdbbbc562f79b92c8f0acd621081680c247cb4a6fc987bf456ea554', +}) + +exports.dynamicFeeNormalDummy1 = new Transaction({ + type: 0, + amount: 200000000, + fee: 270000, + recipientId: 'AcjGpvDJEQdBVwspYsAs16B8Rv66zo7gyd', + timestamp: 45947670, + asset: {}, + vendorField: 'TID: 0', + senderPublicKey: + '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', + signature: + '304402201ecbac2760492934873a13fdc7287958f464f4ee95fc13d4370a6a7c4351b2e902200ff75120a1663ab65eeb7a1795ad7c855363a0b61028751fcc2e7848b262df44', + id: 'b6d993f3294b2aee7c077cd15c2c54912427412fb4be291a559c93f51cf7e4cd', +}) + +exports.dynamicFeeLowDummy2 = new Transaction({ + type: 0, + amount: 200000000, + fee: 100, + recipientId: 'AabMvWPVKbdTHRcGBpATq9TEMiMD5xeJh9', + timestamp: 45947828, + asset: {}, + vendorField: 'TID: 0', + senderPublicKey: + '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', + signature: + '3045022100a8754cee4492f30efa61825f39cda1a0de44b3d8e909b6c7e9055d7bc923b6d402200fab8abb348b4f5c7aaf10a9bb5451021e0e0e1fbb2f995555740b6d4ef8ccfe', + id: 'f7c7f073735d6900b4d12c70f75d7d1ad5ba41715d2254f50bf057580e05f7ec', +}) + +exports.dynamicFeeZero = new Transaction({ + type: 0, + amount: 200000000, + fee: 0, + recipientId: 'AVnRZSvrAeeSJZN3oSBxEF6mvvVpuKUXL5', + timestamp: 45948315, + asset: {}, + vendorField: 'TID: 0', + senderPublicKey: + '03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357', + signature: + '304402206119b9bfd045b0faa89436e4e487ff3e33aac310cea93f6e2870067ef42cc7e402204ccfc4756432901723fb70d98863adcf26f6e9ea963ba6f4063a886f44b82cb7', + id: '9966cc7fa7c646ab5771335809acb4a98c0c13c9045fa7976a1065f3a77c1721', }) diff --git a/packages/core-transaction-pool/__tests__/__support__/setup.js b/packages/core-transaction-pool/__tests__/__support__/setup.js index 6e151d71ba..b59568908d 100644 --- a/packages/core-transaction-pool/__tests__/__support__/setup.js +++ b/packages/core-transaction-pool/__tests__/__support__/setup.js @@ -1,22 +1,16 @@ -'use strict'; +const app = require('@arkecosystem/core-container') +const appHelper = require('@arkecosystem/core-test-utils/lib/helpers/container') -const path = require('path') -const container = require('@arkecosystem/core-container') +jest.setTimeout(60000) exports.setUp = async () => { - await container.setUp({ - data: '~/.ark', - config: path.resolve(__dirname, '../../../core/lib/config/testnet'), - token: 'ark', - network: 'testnet' - }, { + await appHelper.setUp({ exit: '@arkecosystem/core-blockchain', - exclude: ['@arkecosystem/core-p2p'] }) - return container + return app } exports.tearDown = async () => { - await container.tearDown() + await app.tearDown() } diff --git a/packages/core-transaction-pool/__tests__/dynamic-fee.test.js b/packages/core-transaction-pool/__tests__/dynamic-fee.test.js new file mode 100644 index 0000000000..64a23d2602 --- /dev/null +++ b/packages/core-transaction-pool/__tests__/dynamic-fee.test.js @@ -0,0 +1,97 @@ +const app = require('./__support__/setup') +const mockData = require('./__fixtures__/transactions') + +let dynamicFeeMatch +let blockchain +let container + +beforeAll(async () => { + container = await app.setUp() + await container.resolvePlugin('blockchain').start() + + dynamicFeeMatch = require('../lib/utils/dynamicfee-matcher') +}) + +afterAll(async () => { + await app.tearDown() +}) + +describe('static fees', () => { + beforeAll(() => { + blockchain = container.resolvePlugin('blockchain') + blockchain.getLastBlock = jest.fn(plugin => ({ + data: { + height: 20, + }, + })) + const h = blockchain.getLastBlock().data.height + container.resolvePlugin('config').getConstants(h).fees.dynamic = false + }) + + it('should be a function', () => { + expect(dynamicFeeMatch).toBeFunction() + }) + + it('should accept transactions matching the static fee for broadcast', () => { + expect(dynamicFeeMatch(mockData.dummy1).broadcast).toBeTrue() + expect(dynamicFeeMatch(mockData.dummy2).broadcast).toBeTrue() + }) + + it('should accept transactions matching the static fee to enter pool', () => { + expect(dynamicFeeMatch(mockData.dummy1).enterPool).toBeTrue() + expect(dynamicFeeMatch(mockData.dummy2).enterPool).toBeTrue() + }) + + it('should not broadcast transactions with a fee other than the static fee', () => { + expect( + dynamicFeeMatch(mockData.dynamicFeeNormalDummy1).broadcast, + ).toBeFalse() + expect(dynamicFeeMatch(mockData.dynamicFeeZero).broadcast).toBeFalse() + }) + + it('should not allow transactions with a fee other than the static fee to enter the pool', () => { + expect( + dynamicFeeMatch(mockData.dynamicFeeNormalDummy1).enterPool, + ).toBeFalse() + expect(dynamicFeeMatch(mockData.dynamicFeeZero).enterPool).toBeFalse() + }) +}) + +describe('dynamic fees', () => { + beforeAll(() => { + blockchain = container.resolvePlugin('blockchain') + blockchain.getLastBlock = jest.fn(plugin => ({ + data: { + height: 20, + }, + })) + const h = blockchain.getLastBlock().data.height + container.resolvePlugin('config').getConstants(h).fees.dynamic = true + }) + + it('should broadcast transactions with high enough fee', () => { + expect(dynamicFeeMatch(mockData.dummy1).broadcast).toBeTrue() + expect(dynamicFeeMatch(mockData.dummy2).broadcast).toBeTrue() + expect( + dynamicFeeMatch(mockData.dynamicFeeNormalDummy1).broadcast, + ).toBeTrue() + }) + + it('should accept transactions with high enough fee to enter the pool', () => { + expect(dynamicFeeMatch(mockData.dummy1).enterPool).toBeTrue() + expect(dynamicFeeMatch(mockData.dummy2).enterPool).toBeTrue() + expect( + dynamicFeeMatch(mockData.dynamicFeeNormalDummy1).enterPool, + ).toBeTrue() + }) + + it('should not broadcast transactions with too low fee', () => { + expect(dynamicFeeMatch(mockData.dynamicFeeLowDummy2).broadcast).toBeFalse() + expect(dynamicFeeMatch(mockData.dynamicFeeZero).broadcast).toBeFalse() + }) + + it('should not allow transactions with too low fee to enter the pool', () => { + expect(dynamicFeeMatch(mockData.dynamicFeeLowDummy2).enterPool).toBeFalse() + expect(dynamicFeeMatch(mockData.dynamicFeeZero).enterPool).toBeFalse() + }) +}) diff --git a/packages/core-transaction-pool/__tests__/guard.test.js b/packages/core-transaction-pool/__tests__/guard.test.js index 1ec2c9c248..d9c0fea430 100644 --- a/packages/core-transaction-pool/__tests__/guard.test.js +++ b/packages/core-transaction-pool/__tests__/guard.test.js @@ -1,11 +1,26 @@ -'use strict' - +/* eslint import/no-extraneous-dependencies: "off" */ +/* eslint no-await-in-loop: "off" */ +const Guard = require('@arkecosystem/core-transaction-pool/lib/guard') +const { slots, crypto } = require('@arkecosystem/crypto') +const bip39 = require('bip39') +const delegates = require('@arkecosystem/core-test-utils/fixtures/testnet/delegates') +const generateVote = require('@arkecosystem/core-test-utils/lib/generators/transactions/vote') +const generateSignature = require('@arkecosystem/core-test-utils/lib/generators/transactions/signature') +const generateDelegateReg = require('@arkecosystem/core-test-utils/lib/generators/transactions/delegate') +const generateTransfers = require('@arkecosystem/core-test-utils/lib/generators/transactions/transfer') +const generateWallets = require('@arkecosystem/core-test-utils/lib/generators/wallets') const app = require('./__support__/setup') +let container let guard +let transactionPool +let poolInterface beforeAll(async () => { - await app.setUp() + container = await app.setUp() + + transactionPool = container.resolvePlugin('transactionPool') + transactionPool.make() }) afterAll(async () => { @@ -13,8 +28,8 @@ afterAll(async () => { }) beforeEach(() => { - const poolInterface = new (require('../lib/interface'))({}) - guard = new (require('../lib/guard'))(poolInterface) + transactionPool.flush() + guard = new Guard(transactionPool) }) describe('Transaction Guard', () => { @@ -26,167 +41,679 @@ describe('Transaction Guard', () => { it('should be a function', () => { expect(guard.validate).toBeFunction() }) - }) - describe('getIds', () => { - it('should be a function', () => { - expect(guard.getIds).toBeFunction() - }) - - it('should be ok', () => { - guard.transactions = [{ id: 1 }] - guard.accept = [{ id: 2 }] - guard.excess = [{ id: 3 }] - guard.invalid = [{ id: 4 }] - guard.broadcast = [{ id: 5 }] - - expect(guard.getIds()).toEqual({ - transactions: [1], - accept: [2], - excess: [3], - invalid: [4], - broadcast: [5] - }) + it.each([false, true])( + 'should not apply transactions for chained transfers involving cold wallets', + async inverseOrder => { + /* The logic here is we can't have a chained transfer A => B => C if B is a cold wallet. + A => B needs to be first confirmed (forged), then B can transfer to C + */ + + const arktoshi = 10 ** 8 + const delegate = inverseOrder ? delegates[8] : delegates[9] // don't re-use the same delegate (need clean balance) + const delegateWallet = transactionPool.walletManager.findByAddress( + delegate.address, + ) + + const wallets = generateWallets('testnet', 2) + const poolWallets = wallets.map(w => + transactionPool.walletManager.findByAddress(w.address), + ) + + expect(+delegateWallet.balance).toBe(+delegate.balance) + poolWallets.forEach(w => { + expect(+w.balance).toBe(0) + }) + + const transfer0 = { + // transfer from delegate to wallet 0 + from: delegate, + to: wallets[0], + amount: 100 * arktoshi, + } + const transfer1 = { + // transfer from wallet 0 to wallet 1 + from: wallets[0], + to: wallets[1], + amount: 55 * arktoshi, + } + const transfers = [transfer0, transfer1] + if (inverseOrder) { + transfers.reverse() + } + + for (const t of transfers) { + const transfer = generateTransfers( + 'testnet', + t.from.passphrase, + t.to.address, + t.amount, + 1, + )[0] + + await guard.validate([transfer]) + } + + // apply again transfer from 0 to 1 + const transfer = generateTransfers( + 'testnet', + transfer1.from.passphrase, + transfer1.to.address, + transfer1.amount, + 1, + )[0] + + await guard.validate([transfer]) + + const expectedError = { + message: + '["Cold wallet is not allowed to send until receiving transaction is confirmed."]', + type: 'ERR_APPLY', + } + expect(guard.errors[transfer.id]).toContainEqual(expectedError) + + // check final balances + expect(+delegateWallet.balance).toBe( + delegate.balance - (100 + 0.1) * arktoshi, + ) + expect(+poolWallets[0].balance).toBe(0) + expect(+poolWallets[1].balance).toBe(0) + }, + ) + + it('should not apply the tx to the balance of the sender & recipient with dyn fee < min fee', async () => { + const delegate0 = delegates[14] + const { publicKey } = crypto.getKeys(bip39.generateMnemonic()) + const newAddress = crypto.getAddress(publicKey) + + const delegateWallet = transactionPool.walletManager.findByPublicKey( + delegate0.publicKey, + ) + const newWallet = transactionPool.walletManager.findByPublicKey(publicKey) + + expect(+delegateWallet.balance).toBe(+delegate0.balance) + expect(+newWallet.balance).toBe(0) + + const amount1 = 123 * 10 ** 8 + const fee = 10 + const transfers = generateTransfers( + 'testnet', + delegate0.secret, + newAddress, + amount1, + 1, + false, + fee, + ) + + await guard.validate(transfers) + + expect(+delegateWallet.balance).toBe(+delegate0.balance) + expect(+newWallet.balance).toBe(0) }) - it('should be ok using a type', () => { - guard.excess = [{ id: 3 }] - - expect(guard.getIds('excess')).toEqual([3]) + it('should update the balance of the sender & recipient with dyn fee > min fee', async () => { + const delegate1 = delegates[1] + const { publicKey } = crypto.getKeys(bip39.generateMnemonic()) + const newAddress = crypto.getAddress(publicKey) + + const delegateWallet = transactionPool.walletManager.findByPublicKey( + delegate1.publicKey, + ) + const newWallet = transactionPool.walletManager.findByPublicKey(publicKey) + + expect(+delegateWallet.balance).toBe(+delegate1.balance) + expect(+newWallet.balance).toBe(0) + + const amount1 = +delegateWallet.balance / 2 + const fee = 0.1 * 10 ** 8 + const transfers = generateTransfers( + 'testnet', + delegate1.secret, + newAddress, + amount1, + 1, + false, + fee, + ) + + await guard.validate(transfers) + expect(guard.errors).toEqual({}) + + // simulate forged transaction + newWallet.applyTransactionToRecipient(transfers[0]) + + expect(+delegateWallet.balance).toBe(+delegate1.balance - amount1 - fee) + expect(+newWallet.balance).toBe(amount1) }) - }) - describe('getTransactions', () => { - it('should be a function', () => { - expect(guard.getTransactions).toBeFunction() - }) - - it('should be ok', () => { - guard.transactions = [{ id: 1 }] - guard.accept = [{ id: 2 }] - guard.excess = [{ id: 3 }] - guard.invalid = [{ id: 4 }] - guard.broadcast = [{ id: 5 }] - - expect(guard.getTransactions()).toEqual({ - transactions: [{ id: 1 }], - accept: [{ id: 2 }], - excess: [{ id: 3 }], - invalid: [{ id: 4 }], - broadcast: [{ id: 5 }] + it('should update the balance of the sender & recipient with multiple transactions type', async () => { + const delegate2 = delegates[2] + const newWalletPassphrase = bip39.generateMnemonic() + const { publicKey } = crypto.getKeys(newWalletPassphrase) + const newAddress = crypto.getAddress(publicKey) + + const delegateWallet = transactionPool.walletManager.findByPublicKey( + delegate2.publicKey, + ) + const newWallet = transactionPool.walletManager.findByPublicKey(publicKey) + + expect(+delegateWallet.balance).toBe(+delegate2.balance) + expect(+newWallet.balance).toBe(0) + expect(guard.errors).toEqual({}) + + const amount1 = +delegateWallet.balance / 2 + const fee = 0.1 * 10 ** 8 + const voteFee = 10 ** 8 + const delegateRegFee = 25 * 10 ** 8 + const signatureFee = 5 * 10 ** 8 + const transfers = generateTransfers( + 'testnet', + delegate2.secret, + newAddress, + amount1, + 1, + false, + fee, + ) + const votes = generateVote( + 'testnet', + newWalletPassphrase, + delegate2.publicKey, + 1, + ) + const delegateRegs = generateDelegateReg( + 'testnet', + newWalletPassphrase, + 1, + ) + const signatures = generateSignature('testnet', newWalletPassphrase, 1) + + // Index wallets to not encounter cold wallet error + const allTransactions = [ + ...transfers, + ...votes, + ...delegateRegs, + ...signatures, + ] + + allTransactions.forEach(transaction => { + container + .resolvePlugin('database') + .walletManager.findByPublicKey(transaction.senderPublicKey) }) + + // first validate the 1st transfer so that new wallet is updated with the amount + await guard.validate(transfers) + + // simulate forged transaction + newWallet.applyTransactionToRecipient(transfers[0]) + + expect(guard.errors).toEqual({}) + expect(+newWallet.balance).toBe(amount1) + + // reset guard, if not the 1st transaction will still be in this.accept and mess up + guard = new Guard(transactionPool) + + await guard.validate([votes[0], delegateRegs[0], signatures[0]]) + + expect(guard.errors).toEqual({}) + expect(+delegateWallet.balance).toBe(+delegate2.balance - amount1 - fee) + expect(+newWallet.balance).toBe( + amount1 - voteFee - delegateRegFee - signatureFee, + ) }) - it('should be ok using a type', () => { - guard.excess = [{ id: 3 }] + it('should not accept transaction in excess', async () => { + const delegate3 = delegates[3] + const newWalletPassphrase = bip39.generateMnemonic() + const { publicKey } = crypto.getKeys(newWalletPassphrase) + const newAddress = crypto.getAddress(publicKey) + + const delegateWallet = transactionPool.walletManager.findByPublicKey( + delegate3.publicKey, + ) + const newWallet = transactionPool.walletManager.findByPublicKey(publicKey) + + // Make sure it is not considered a cold wallet + container.resolvePlugin('database').walletManager.reindex(newWallet) + + expect(+delegateWallet.balance).toBe(+delegate3.balance) + expect(+newWallet.balance).toBe(0) + + // first, transfer coins to new wallet so that we can test from it then + const amount1 = 1000 * 10 ** 8 + const fee = 0.1 * 10 ** 8 + const transfers1 = generateTransfers( + 'testnet', + delegate3.secret, + newAddress, + amount1, + 1, + ) + await guard.validate(transfers1) + + // simulate forged transaction + newWallet.applyTransactionToRecipient(transfers1[0]) + + expect(+delegateWallet.balance).toBe(+delegate3.balance - amount1 - fee) + expect(+newWallet.balance).toBe(amount1) + + // transfer almost everything from new wallet so that we don't have enough for any other transaction + const amount2 = 999 * 10 ** 8 + const transfers2 = generateTransfers( + 'testnet', + newWalletPassphrase, + delegate3.address, + amount2, + 1, + ) + await guard.validate(transfers2) + + // simulate forged transaction + delegateWallet.applyTransactionToRecipient(transfers2[0]) + + expect(+newWallet.balance).toBe(amount1 - amount2 - fee) + + // now try to validate any other transaction - should not be accepted because in excess + const transferAmount = 0.5 * 10 ** 8 + const transferDynFee = 0.5 * 10 ** 8 + const allTransactions = [ + generateTransfers( + 'testnet', + newWalletPassphrase, + delegate3.address, + transferAmount, + 1, + false, + transferDynFee, + ), + generateSignature('testnet', newWalletPassphrase, 1), + generateVote('testnet', newWalletPassphrase, delegate3.publicKey, 1), + generateDelegateReg('testnet', newWalletPassphrase, 1), + ] + + for (const transaction of allTransactions) { + await guard.validate(transaction) // eslint-disable-line no-await-in-loop + + const errorExpected = [ + { + message: `["[PoolWalletManager] Can't apply transaction id:${ + transaction[0].id + } from sender:${ + newWallet.address + }","Insufficient balance in the wallet"]`, + type: 'ERR_APPLY', + }, + ] + expect(guard.errors[transaction[0].id]).toEqual(errorExpected) + + expect(+delegateWallet.balance).toBe( + +delegate3.balance - amount1 - fee + amount2, + ) + expect(+newWallet.balance).toBe(amount1 - amount2 - fee) + } + }) - expect(guard.getTransactions('excess')).toEqual([{ id: 3 }]) + it('should not validate 2 double spending transactions', async () => { + const amount = 245098000000000 - 5098000000000 // a bit less than the delegates' balance + const transactions = generateTransfers( + 'testnet', + delegates[0].secret, + delegates[1].address, + amount, + 2, + true, + ) + + const result = await guard.validate(transactions) + + expect(result.errors[transactions[1].id]).toEqual([ + { + message: `["[PoolWalletManager] Can't apply transaction id:${ + transactions[1].id + } from sender:${ + delegates[0].address + }","Insufficient balance in the wallet"]`, + type: 'ERR_APPLY', + }, + ]) }) + + it.each([3, 5, 8])( + 'should validate emptying wallet with %i transactions', + async txNumber => { + // use txNumber so that we use a different delegate for each test case + const sender = delegates[txNumber] + const senderWallet = transactionPool.walletManager.findByPublicKey( + sender.publicKey, + ) + const receivers = generateWallets('testnet', 2) + const amountPlusFee = Math.floor(senderWallet.balance / txNumber) + const lastAmountPlusFee = + senderWallet.balance - (txNumber - 1) * amountPlusFee + const transferFee = 10000000 + + const transactions = generateTransfers( + 'testnet', + sender.secret, + receivers[0].address, + amountPlusFee - transferFee, + txNumber - 1, + true, + ) + const lastTransaction = generateTransfers( + 'testnet', + sender.secret, + receivers[1].address, + lastAmountPlusFee - transferFee, + 1, + true, + ) + // we change the receiver in lastTransaction to prevent having 2 exact + // same transactions with same id (if not, could be same as transactions[0]) + + const result = await guard.validate( + transactions.concat(lastTransaction), + ) + + expect(result.errors).toEqual(null) + }, + ) + + it.each([3, 5, 8])( + 'should not validate emptying wallet with %i transactions when the last one is 1 arktoshi too much', + async txNumber => { + // use txNumber + 1 so that we don't use the same delegates as the above test + const sender = delegates[txNumber + 1] + const receivers = generateWallets('testnet', 2) + const amountPlusFee = Math.floor(sender.balance / txNumber) + const lastAmountPlusFee = + sender.balance - (txNumber - 1) * amountPlusFee + 1 + const transferFee = 10000000 + + const transactions = generateTransfers( + 'testnet', + sender.secret, + receivers[0].address, + amountPlusFee - transferFee, + txNumber - 1, + true, + ) + const lastTransaction = generateTransfers( + 'testnet', + sender.secret, + receivers[1].address, + lastAmountPlusFee - transferFee, + 1, + true, + ) + // we change the receiver in lastTransaction to prevent having 2 + // exact same transactions with same id (if not, could be same as transactions[0]) + + const allTransactions = transactions.concat(lastTransaction) + + const result = await guard.validate(allTransactions) + + expect(Object.keys(result.errors).length).toBe(1) + expect(result.errors[lastTransaction[0].id]).toEqual([ + { + message: `["[PoolWalletManager] Can't apply transaction id:${ + lastTransaction[0].id + } from sender:${ + sender.address + }","Insufficient balance in the wallet"]`, + type: 'ERR_APPLY', + }, + ]) + }, + ) }) - describe('has', () => { + describe('__filterAndTransformTransactions', () => { it('should be a function', () => { - expect(guard.has).toBeFunction() + expect(guard.__filterAndTransformTransactions).toBeFunction() }) - it('should be ok', () => { - guard.excess = [{ id: 1 }, { id: 2 }] + it('should reject duplicate transactions', () => { + const transactionExists = guard.pool.transactionExists + guard.pool.transactionExists = jest.fn(() => true) + + const tx = { id: '1' } + guard.__filterAndTransformTransactions([tx]) - expect(guard.has('excess', 2)).toBeTruthy() + expect(guard.errors[tx.id]).toEqual([ + { + message: `Duplicate transaction ${tx.id}`, + type: 'ERR_DUPLICATE', + }, + ]) + + guard.pool.transactionExists = transactionExists }) - it('should not be ok', () => { - guard.excess = [{ id: 1 }, { id: 2 }] + it('should reject blocked senders', () => { + const transactionExists = guard.pool.transactionExists + guard.pool.transactionExists = jest.fn(() => false) + const isSenderBlocked = guard.pool.isSenderBlocked + guard.pool.isSenderBlocked = jest.fn(() => true) + + const tx = { id: '1', senderPublicKey: 'affe' } + guard.__filterAndTransformTransactions([tx]) + + expect(guard.errors[tx.id]).toEqual([ + { + message: `Transaction ${tx.id} rejected. Sender ${ + tx.senderPublicKey + } is blocked.`, + type: 'ERR_SENDER_BLOCKED', + }, + ]) + + guard.pool.isSenderBlocked = isSenderBlocked + guard.pool.transactionExists = transactionExists + }) - expect(guard.has('excess', 1)).toBeFalsy() + it('should reject transactions from the future', () => { + const now = 47157042 // seconds since genesis block + const transactionExists = guard.pool.transactionExists + guard.pool.transactionExists = jest.fn(() => false) + const getTime = slots.getTime + slots.getTime = jest.fn(() => now) + + const secondsInFuture = 3601 + const tx = { + id: '1', + senderPublicKey: 'affe', + timestamp: slots.getTime() + secondsInFuture, + } + guard.__filterAndTransformTransactions([tx]) + + expect(guard.errors[tx.id]).toEqual([ + { + message: `Transaction ${ + tx.id + } is ${secondsInFuture} seconds in the future`, + type: 'ERR_FROM_FUTURE', + }, + ]) + + slots.getTime = getTime + guard.pool.transactionExists = transactionExists }) }) - describe('hasAtLeast', () => { + describe('__validateTransaction', () => { it('should be a function', () => { - expect(guard.hasAtLeast).toBeFunction() + expect(guard.__validateTransaction).toBeFunction() }) + }) - it('should be ok', () => { - guard.excess = [{ id: 1 }, { id: 2 }] - - expect(guard.hasAtLeast('excess', 2)).toBeTruthy() + describe('__removeForgedTransactions', () => { + it('should be a function', () => { + expect(guard.__removeForgedTransactions).toBeFunction() }) - it('should not be ok', () => { - guard.excess = [{ id: 1 }] + it('should remove forged transactions', async () => { + const database = container.resolvePlugin('database') + const getForgedTransactionsIds = database.getForgedTransactionsIds + + const transfers = generateTransfers( + 'testnet', + delegates[0].secret, + delegates[0].senderPublicKey, + 1, + 4, + ) + + transfers.forEach(tx => { + guard.accept.set(tx.id, tx) + guard.broadcast.set(tx.id, tx) + }) + + const forgedTx = transfers[2] + database.getForgedTransactionsIds = jest.fn(() => [forgedTx.id]) + + await guard.__removeForgedTransactions() + + expect(guard.accept.size).toBe(3) + expect(guard.broadcast.size).toBe(3) - expect(guard.hasAtLeast('excess', 2)).toBeFalsy() + expect(guard.errors[forgedTx.id]).toHaveLength(1) + expect(guard.errors[forgedTx.id][0].type).toEqual('ERR_FORGED') + + database.getForgedTransactionsIds = getForgedTransactionsIds }) }) - describe('hasAny', () => { + describe('__addTransactionsToPool', () => { it('should be a function', () => { - expect(guard.hasAny).toBeFunction() + expect(guard.__addTransactionsToPool).toBeFunction() }) - it('should be ok', () => { - guard.excess = [{ id: 1 }] + it('should add transactions to the pool', () => { + const transfers = generateTransfers( + 'testnet', + delegates[0].secret, + delegates[0].senderPublicKey, + 1, + 4, + ) + + transfers.forEach(tx => { + guard.accept.set(tx.id, tx) + guard.broadcast.set(tx.id, tx) + }) - expect(guard.hasAny('excess')).toBeTruthy() - }) + expect(guard.errors).toEqual({}) - it('should not be ok', () => { - guard.excess = [] + guard.__addTransactionsToPool() - expect(guard.hasAny('excess')).toBeFalsy() + expect(guard.errors).toEqual({}) + expect(guard.accept.size).toBe(4) + expect(guard.broadcast.size).toBe(4) }) - }) - describe('__transformAndFilterTransations', () => { - it('should be a function', () => { - expect(guard.__transformAndFilterTransations).toBeFunction() - }) - }) + it('should raise ERR_ALREADY_IN_POOL when adding existing transactions', () => { + const transfers = generateTransfers( + 'testnet', + delegates[0].secret, + delegates[0].senderPublicKey, + 1, + 4, + ) + + transfers.forEach(tx => { + guard.accept.set(tx.id, tx) + guard.broadcast.set(tx.id, tx) + }) - describe('__determineValidTransactions', () => { - it('should be a function', () => { - expect(guard.__determineValidTransactions).toBeFunction() + expect(guard.errors).toEqual({}) + + guard.__addTransactionsToPool() + + expect(guard.errors).toEqual({}) + expect(guard.accept.size).toBe(4) + expect(guard.broadcast.size).toBe(4) + + // Adding again invokes ERR_ALREADY_IN_POOL + guard.__addTransactionsToPool() + + expect(guard.accept.size).toBe(0) + expect(guard.broadcast.size).toBe(0) + + for (const transfer of transfers) { + expect(guard.errors[transfer.id]).toHaveLength(1) + expect(guard.errors[transfer.id][0].type).toEqual('ERR_ALREADY_IN_POOL') + } }) - }) - describe('__determineFeeMatchingTransactions', () => { - it('should be a function', () => { - expect(guard.__determineFeeMatchingTransactions).toBeFunction() + it('should raise ERR_POOL_FULL when attempting to add transactions to a full pool', () => { + const poolSize = transactionPool.options.maxTransactionsInPool + transactionPool.options.maxTransactionsInPool = 3 + + const transfers = generateTransfers( + 'testnet', + delegates[0].secret, + delegates[0].senderPublicKey, + 1, + 4, + ) + + transfers.forEach(tx => { + guard.accept.set(tx.id, tx) + guard.broadcast.set(tx.id, tx) + }) + + guard.__addTransactionsToPool() + + expect(guard.accept.size).toBe(3) + expect(guard.broadcast.size).toBe(4) + + expect(guard.errors[transfers[3].id]).toHaveLength(1) + expect(guard.errors[transfers[3].id][0].type).toEqual('ERR_POOL_FULL') + + transactionPool.options.maxTransactionsInPool = poolSize }) }) - describe('__determineExcessTransactions', () => { + describe('__pushError', () => { it('should be a function', () => { - expect(guard.__determineExcessTransactions).toBeFunction() + expect(guard.__pushError).toBeFunction() }) - }) - describe('__reset', () => { - it('should be a function', () => { - expect(guard.__reset).toBeFunction() + it('should have error for transaction', () => { + expect(guard.errors).toBeEmpty() + + guard.__pushError({ id: 1 }, 'ERR_INVALID', 'Invalid.') + + expect(guard.errors).toBeObject() + expect(guard.errors['1']).toBeArray() + expect(guard.errors['1']).toHaveLength(1) + expect(guard.errors['1']).toEqual([ + { message: 'Invalid.', type: 'ERR_INVALID' }, + ]) + + expect(guard.invalid.size).toEqual(1) + expect(guard.invalid.entries().next().value[1]).toEqual({ id: 1 }) }) - it('should be ok', () => { - guard.transactions = [{ id: 1 }] - guard.accept = [{ id: 2 }] - guard.excess = [{ id: 3 }] - guard.invalid = [{ id: 4 }] - guard.broadcast = [{ id: 5 }] + it('should have multiple errors for transaction', () => { + expect(guard.errors).toBeEmpty() - expect(guard.transactions).not.toBeEmpty() - expect(guard.accept).not.toBeEmpty() - expect(guard.excess).not.toBeEmpty() - expect(guard.invalid).not.toBeEmpty() - expect(guard.broadcast).not.toBeEmpty() + guard.__pushError({ id: 1 }, 'ERR_INVALID', 'Invalid 1.') + guard.__pushError({ id: 1 }, 'ERR_INVALID', 'Invalid 2.') - guard.__reset() + expect(guard.errors).toBeObject() + expect(guard.errors['1']).toBeArray() + expect(guard.errors['1']).toHaveLength(2) + expect(guard.errors['1']).toEqual([ + { message: 'Invalid 1.', type: 'ERR_INVALID' }, + { message: 'Invalid 2.', type: 'ERR_INVALID' }, + ]) - expect(guard.transactions).toBeEmpty() - expect(guard.accept).toBeEmpty() - expect(guard.excess).toBeEmpty() - expect(guard.invalid).toBeEmpty() - expect(guard.broadcast).toBeEmpty() + expect(guard.invalid.size).toEqual(1) + expect(guard.invalid.entries().next().value[1]).toEqual({ id: 1 }) }) }) }) diff --git a/packages/core-transaction-pool/__tests__/interface.test.js b/packages/core-transaction-pool/__tests__/interface.test.js index a315c50074..d04fce3498 100644 --- a/packages/core-transaction-pool/__tests__/interface.test.js +++ b/packages/core-transaction-pool/__tests__/interface.test.js @@ -1,7 +1,5 @@ -'use strict' - +const dayjs = require('dayjs-ext') const app = require('./__support__/setup') -const moment = require('moment') let poolInterface @@ -32,8 +30,10 @@ describe('Transaction Pool Interface', () => { expect(poolInterface.getPoolSize).toBeFunction() }) - it('should throw an exception', async () => { - await expect(poolInterface.getPoolSize()).rejects.toThrowError('Method [getPoolSize] not implemented!') + it('should throw an exception', () => { + expect(poolInterface.getPoolSize).toThrow( + 'Method [getPoolSize] not implemented!', + ) }) }) @@ -43,7 +43,9 @@ describe('Transaction Pool Interface', () => { }) it('should throw an exception', async () => { - await expect(poolInterface.getSenderSize()).rejects.toThrowError('Method [getSenderSize] not implemented!') + expect(poolInterface.getSenderSize).toThrow( + 'Method [getSenderSize] not implemented!', + ) }) }) @@ -53,7 +55,9 @@ describe('Transaction Pool Interface', () => { }) it('should throw an exception', async () => { - await expect(poolInterface.addTransaction()).rejects.toThrowError('Method [addTransaction] not implemented!') + expect(poolInterface.addTransaction).toThrow( + 'Method [addTransaction] not implemented!', + ) }) }) @@ -63,17 +67,9 @@ describe('Transaction Pool Interface', () => { }) it('should throw an exception', async () => { - await expect(poolInterface.removeTransaction()).rejects.toThrowError('Method [removeTransaction] not implemented!') - }) - }) - - describe('removeTransactions', () => { - it('should be a function', () => { - expect(poolInterface.removeTransactions).toBeFunction() - }) - - it('should throw an exception', async () => { - await expect(poolInterface.removeTransactions()).rejects.toThrowError('Method [removeTransactions] not implemented!') + expect(poolInterface.removeTransaction).toThrow( + 'Method [removeTransaction] not implemented!', + ) }) }) @@ -83,7 +79,9 @@ describe('Transaction Pool Interface', () => { }) it('should throw an exception', async () => { - await expect(poolInterface.getTransaction()).rejects.toThrowError('Method [getTransaction] not implemented!') + expect(poolInterface.getTransaction).toThrow( + 'Method [getTransaction] not implemented!', + ) }) }) @@ -93,7 +91,9 @@ describe('Transaction Pool Interface', () => { }) it('should throw an exception', async () => { - await expect(poolInterface.getTransactions()).rejects.toThrowError('Method [getTransactions] not implemented!') + expect(poolInterface.getTransactions).toThrow( + 'Method [getTransactions] not implemented!', + ) }) }) @@ -101,6 +101,24 @@ describe('Transaction Pool Interface', () => { it('should be a function', () => { expect(poolInterface.getTransactionsForForging).toBeFunction() }) + + it('should throw an exception', () => { + expect(poolInterface.getTransactionsForForging).toThrow( + 'Method [getTransactionsForForging] not implemented!', + ) + }) + }) + + describe('getTransactionIdsForForging', () => { + it('should be a function', () => { + expect(poolInterface.getTransactionIdsForForging).toBeFunction() + }) + + it('should throw an exception', () => { + expect(poolInterface.getTransactionIdsForForging).toThrow( + 'Method [getTransactionIdsForForging] not implemented!', + ) + }) }) describe('hasExceededMaxTransactions', () => { @@ -109,7 +127,21 @@ describe('Transaction Pool Interface', () => { }) it('should throw an exception', async () => { - await expect(poolInterface.hasExceededMaxTransactions()).rejects.toThrowError('Method [hasExceededMaxTransactions] not implemented!') + expect(poolInterface.hasExceededMaxTransactions).toThrow( + 'Method [hasExceededMaxTransactions] not implemented!', + ) + }) + }) + + describe('senderHasTransactionsOfType', () => { + it('should be a function', () => { + expect(poolInterface.senderHasTransactionsOfType).toBeFunction() + }) + + it('should throw an exception', async () => { + expect(poolInterface.senderHasTransactionsOfType).toThrow( + 'Method [senderHasTransactionsOfType] not implemented!', + ) }) }) @@ -119,7 +151,9 @@ describe('Transaction Pool Interface', () => { }) it('should throw an exception', async () => { - await expect(poolInterface.transactionExists()).rejects.toThrowError('Method [transactionExists] not implemented!') + expect(poolInterface.transactionExists).toThrow( + 'Method [transactionExists] not implemented!', + ) }) }) @@ -129,7 +163,9 @@ describe('Transaction Pool Interface', () => { }) it('should throw an exception', async () => { - await expect(poolInterface.removeTransactionsForSender()).rejects.toThrowError('Method [removeTransactionsForSender] not implemented!') + expect(poolInterface.removeTransactionsForSender).toThrow( + 'Method [removeTransactionsForSender] not implemented!', + ) }) }) @@ -140,11 +176,11 @@ describe('Transaction Pool Interface', () => { it('should return true', async () => { poolInterface.blockSender('keykeykey') - expect(poolInterface.isSenderBlocked('keykeykey')).toBeTruthy() + expect(poolInterface.isSenderBlocked('keykeykey')).toBeTrue() }) it('should return false', async () => { - expect(poolInterface.isSenderBlocked('keykeykey2')).toBeFalsy() + expect(poolInterface.isSenderBlocked('keykeykey2')).toBeFalse() }) }) @@ -154,34 +190,12 @@ describe('Transaction Pool Interface', () => { }) it('should block sender for specified time', async () => { - const time = moment() + const time = dayjs() const blockedTime = poolInterface.blockSender('keykeykey') - const duration = moment.duration(blockedTime.diff(time)) - - expect(poolInterface.isSenderBlocked('keykeykey')).toBeTruthy() - expect(parseInt(duration.asHours())).toEqual(1) - }) - }) - - describe('getTransactionsIds', () => { - it('should be a function', () => { - expect(poolInterface.getTransactionsIds).toBeFunction() - }) - - it('should throw an exception', async () => { - await expect(poolInterface.getTransactionsIds()).rejects.toThrowError('Method [getTransactionsIds] not implemented!') - }) - }) - - describe('getTransactionsForForging', () => { - it('should be a function', () => { - expect(poolInterface.getTransactionsForForging).toBeFunction() - }) - }) + const duration = blockedTime.diff(time) / 1000 / 60 / 60 - describe('removeForgedAndGetPending', () => { - it('should be a function', () => { - expect(poolInterface.removeForgedAndGetPending).toBeFunction() + expect(poolInterface.isSenderBlocked('keykeykey')).toBeTrue() + expect(parseInt(duration)).toEqual(1) }) }) diff --git a/packages/core-transaction-pool/__tests__/manager.test.js b/packages/core-transaction-pool/__tests__/manager.test.js index 679050dcb2..f5c08e64aa 100644 --- a/packages/core-transaction-pool/__tests__/manager.test.js +++ b/packages/core-transaction-pool/__tests__/manager.test.js @@ -1,9 +1,7 @@ -'use strict' - const transactionPoolManager = require('../lib/manager') class FakeDriver { - make () { + make() { return this } } @@ -27,7 +25,9 @@ describe('Transaction Pool Manager', () => { it('should return the drive-connection for a different name', async () => { await transactionPoolManager.makeConnection(new FakeDriver(), 'testing') - expect(transactionPoolManager.connection('testing')).toBeInstanceOf(FakeDriver) + expect(transactionPoolManager.connection('testing')).toBeInstanceOf( + FakeDriver, + ) }) }) diff --git a/packages/core-transaction-pool/__tests__/pool-wallet-manager.test.js b/packages/core-transaction-pool/__tests__/pool-wallet-manager.test.js new file mode 100644 index 0000000000..85f9271df7 --- /dev/null +++ b/packages/core-transaction-pool/__tests__/pool-wallet-manager.test.js @@ -0,0 +1,218 @@ +const { crypto } = require('@arkecosystem/crypto') +const { Block } = require('@arkecosystem/crypto').models +const bip39 = require('bip39') +const delegates = require('@arkecosystem/core-test-utils/fixtures/testnet/delegates') +const generateTransfer = require('@arkecosystem/core-test-utils/lib/generators/transactions/transfer') +const generateWallets = require('@arkecosystem/core-test-utils/lib/generators/wallets') +const blocks2to100 = require('@arkecosystem/core-test-utils/fixtures/testnet/blocks.2-100') +const app = require('./__support__/setup') + +const arktoshi = 10 ** 8 +let container +let poolWalletManager +let blockchain + +beforeAll(async () => { + container = await app.setUp() + poolWalletManager = new (require('../lib/pool-wallet-manager'))() + blockchain = container.resolvePlugin('blockchain') +}) + +afterAll(async () => { + await app.tearDown() +}) + +describe('applyPoolTransactionToSender', () => { + describe('update the balance', () => { + it('should only update the balance of the sender', async () => { + const delegate0 = delegates[0] + const { publicKey } = crypto.getKeys(bip39.generateMnemonic()) + const newAddress = crypto.getAddress(publicKey) + + const delegateWallet = poolWalletManager.findByAddress(delegate0.address) + const newWallet = poolWalletManager.findByAddress(newAddress) + + expect(+delegateWallet.balance).toBe(+delegate0.balance) + expect(+newWallet.balance).toBe(0) + + const amount1 = 123 * 10 ** 8 + const transfer = generateTransfer( + 'testnet', + delegate0.secret, + newAddress, + amount1, + 1, + )[0] + + delegateWallet.applyTransactionToSender(transfer) + + expect(+delegateWallet.balance).toBe( + +delegate0.balance - amount1 - 0.1 * 10 ** 8, + ) + expect(newWallet.balance.isZero()).toBeTrue() + }) + + it('should only update the balance of the sender with dyn fees', async () => { + const delegate0 = delegates[1] + const { publicKey } = crypto.getKeys(bip39.generateMnemonic()) + const newAddress = crypto.getAddress(publicKey) + + const delegateWallet = poolWalletManager.findByAddress(delegate0.address) + const newWallet = poolWalletManager.findByAddress(newAddress) + + expect(+delegateWallet.balance).toBe(+delegate0.balance) + expect(+newWallet.balance).toBe(0) + + const amount1 = 123 * 10 ** 8 + const fee = 10 + const transfer = generateTransfer( + 'testnet', + delegate0.secret, + newAddress, + amount1, + 1, + false, + fee, + )[0] + + delegateWallet.applyTransactionToSender(transfer) + + expect(+delegateWallet.balance).toBe(+delegate0.balance - amount1 - fee) + expect(newWallet.balance.isZero()).toBeTrue() + }) + + it('should not apply chained transfers', async () => { + const delegate = delegates[7] + const delegateWallet = poolWalletManager.findByPublicKey( + delegate.publicKey, + ) + + const wallets = generateWallets('testnet', 4) + const poolWallets = wallets.map(w => + poolWalletManager.findByAddress(w.address), + ) + + expect(+delegateWallet.balance).toBe(+delegate.balance) + poolWallets.forEach(w => { + expect(+w.balance).toBe(0) + }) + + const transfers = [ + { + // transfer from delegate to wallet 0 + from: delegate, + to: wallets[0], + amount: 100 * arktoshi, + }, + { + // transfer from wallet 0 to delegatej + from: wallets[0], + to: delegate, + amount: 55 * arktoshi, + }, + ] + + transfers.forEach(t => { + const transfer = generateTransfer( + 'testnet', + t.from.passphrase, + t.to.address, + t.amount, + 1, + )[0] + + // This is normally refused because it's a cold wallet, but since we want + // to test if chained transfers are refused, pretent it is not a cold wallet. + container + .resolvePlugin('database') + .walletManager.findByPublicKey(transfer.senderPublicKey) + + const errors = [] + if (poolWalletManager.canApply(transfer, errors)) { + poolWalletManager + .findByPublicKey(transfer.senderPublicKey) + .applyTransactionToSender(transfer) + + expect(t.from).toBe(delegate) + } else { + expect(t.from).toBe(wallets[0]) + expect(JSON.stringify(errors)).toEqual( + `["[PoolWalletManager] Can't apply transaction id:${ + transfer.id + } from sender:${ + t.from.address + }","Insufficient balance in the wallet"]`, + ) + } + + container + .resolvePlugin('database') + .walletManager.forgetByPublicKey(transfer.publicKey) + }) + + expect(+delegateWallet.balance).toBe( + delegate.balance - (100 + 0.1) * arktoshi, + ) + expect(poolWallets[0].balance.isZero()).toBeTrue() + }) + }) +}) + +describe('Apply transactions and block rewards to wallets on new block', () => { + const __resetToHeight1 = async () => + blockchain.removeBlocks(blockchain.getLastHeight() - 1) + + beforeEach(__resetToHeight1) + afterEach(__resetToHeight1) + + it.each([2 * arktoshi, 0])( + 'should apply forged block reward %i to delegate wallet', + async reward => { + const forgingDelegate = delegates[reward ? 2 : 3] // use different delegate to have clean initial balance + const generatorPublicKey = forgingDelegate.publicKey + + const wallet = generateWallets('testnet', 1)[0] + const transferAmount = 1234 + const transferDelegate = delegates[4] + const transfer = generateTransfer( + 'testnet', + transferDelegate.passphrase, + wallet.address, + transferAmount, + 1, + true, + )[0] + + const totalFee = 0.1 * arktoshi + const blockWithReward = Object.assign({}, blocks2to100[0], { + reward, + generatorPublicKey, + transactions: [transfer], + numberOfTransactions: 1, + totalFee, + }) + const blockWithRewardVerified = new Block(blockWithReward) + blockWithRewardVerified.verification.verified = true + + await blockchain.processBlock(blockWithRewardVerified, () => null) + + const delegateWallet = poolWalletManager.findByPublicKey( + generatorPublicKey, + ) + + const poolWallet = poolWalletManager.findByAddress(wallet.address) + expect(+poolWallet.balance).toBe(transferAmount) + + const transferDelegateWallet = poolWalletManager.findByAddress( + transferDelegate.address, + ) + expect(+transferDelegateWallet.balance).toBe( + +transferDelegate.balance - transferAmount - totalFee, + ) + + expect(+delegateWallet.balance).toBe( + +forgingDelegate.balance + reward + totalFee, + ) // balance increased by reward + fee + }, + ) +}) diff --git a/packages/core-transaction-pool/jest.config.js b/packages/core-transaction-pool/jest.config.js index d58c9e94c1..4db45c2003 100644 --- a/packages/core-transaction-pool/jest.config.js +++ b/packages/core-transaction-pool/jest.config.js @@ -1,22 +1,13 @@ -'use strict' - module.exports = { testEnvironment: 'node', bail: false, - verbose: false, - testMatch: [ - '**/__tests__/**/*.test.js' - ], - moduleFileExtensions: [ - 'js', - 'json' - ], + verbose: true, + silent: true, + testMatch: ['**/__tests__/**/*.test.js'], + moduleFileExtensions: ['js', 'json'], collectCoverage: false, coverageDirectory: '/.coverage', - collectCoverageFrom: [ - 'lib/**/*.js', - '!**/node_modules/**' - ], + collectCoverageFrom: ['lib/**/*.js', '!**/node_modules/**'], watchman: false, - setupTestFrameworkScriptFile: 'jest-extended' + setupTestFrameworkScriptFile: 'jest-extended', } diff --git a/packages/core-transaction-pool/jsdoc.json b/packages/core-transaction-pool/jsdoc.json index 23276f74ea..f3ea8aab33 100644 --- a/packages/core-transaction-pool/jsdoc.json +++ b/packages/core-transaction-pool/jsdoc.json @@ -7,9 +7,7 @@ "includePattern": ".js$", "excludePattern": "(node_modules/|docs)" }, - "plugins": [ - "plugins/markdown" - ], + "plugins": ["plugins/markdown"], "opts": { "template": "../../node_modules/docdash", "encoding": "utf8", diff --git a/packages/core-transaction-pool/lib/guard.js b/packages/core-transaction-pool/lib/guard.js index b408e1c8a1..8102adf1d4 100644 --- a/packages/core-transaction-pool/lib/guard.js +++ b/packages/core-transaction-pool/lib/guard.js @@ -1,11 +1,18 @@ -const Promise = require('bluebird') -const container = require('@arkecosystem/core-container') -const { Transaction } = require('@arkecosystem/crypto').models -const { TRANSACTION_TYPES } = require('@arkecosystem/crypto').constants +/* eslint max-len: "off" */ + +const app = require('@arkecosystem/core-container') +const crypto = require('@arkecosystem/crypto') +const pluralize = require('pluralize') + +const { + configManager, + constants: { TRANSACTION_TYPES }, + models: { Transaction }, + slots, +} = crypto +const isRecipientOnActiveNetwork = require('./utils/is-on-active-network') + const dynamicFeeMatch = require('./utils/dynamicfee-matcher') -const helpers = require('./utils/validation-helpers') -const database = container.resolvePlugin('database') -const _ = require('lodash') module.exports = class TransactionGuard { /** @@ -13,209 +20,321 @@ module.exports = class TransactionGuard { * @param {TransactionPoolInterface} pool * @return {void} */ - constructor (pool) { + constructor(pool) { this.pool = pool - this.__reset() + this.transactions = [] + this.excess = [] + this.accept = new Map() + this.broadcast = new Map() + this.invalid = new Map() + this.errors = {} } /** - * Validate the specified transactions. - * ORDER of called functions is important + * Validate the specified transactions and accepted transactions to the pool. * @param {Array} transactions - * @return {void} + * @return Object { + * accept: array of transaction ids that qualify for entering the pool + * broadcast: array of of transaction ids that qualify for broadcasting + * invalid: array of invalid transaction ids + * excess: array of transaction ids that exceed sender's quota in the pool + * errors: Object with + * keys=transaction id (for each element in invalid[]), + * value=[ { type, message }, ... ] + * } */ - async validate (transactions) { - await this.__transformAndFilterTransations(_.uniqBy(transactions, 'id')) + async validate(transactionsJson) { + this.pool.loggedAllowedSenders = [] - await this.__removeForgedTransactions() + // Cache transactions + this.transactions = this.__cacheTransactions(transactionsJson) - await this.__determineValidTransactions() + if (this.transactions.length > 0) { + // Filter transactions and create Transaction instances from accepted ones + this.__filterAndTransformTransactions(this.transactions) - await this.__determineExcessTransactions() + // Remove already forged tx... Not optimal here + await this.__removeForgedTransactions() - this.__determineFeeMatchingTransactions() - } + // Add transactions to the pool + this.__addTransactionsToPool() - /** - * Get a list of transaction ids. - * @param {String} type - * @return {Object} - */ - getIds (type = null) { - if (type) { - return this[type].map(transaction => transaction.id) + this.__printStats() } return { - transactions: this.transactions.map(transaction => transaction.id), - accept: this.accept.map(transaction => transaction.id), - excess: this.excess.map(transaction => transaction.id), - invalid: this.invalid.map(transaction => transaction.id), - broadcast: this.broadcast.map(transaction => transaction.id) - } - } - - /** - * Get a list of transaction objects. - * @param {String} type - * @return {Object} - */ - getTransactions (type = null) { - if (type) { - return this[type] - } - - return { - transactions: this.transactions, - accept: this.accept, + accept: Array.from(this.accept.keys()), + broadcast: Array.from(this.broadcast.keys()), + invalid: Array.from(this.invalid.keys()), excess: this.excess, - invalid: this.invalid, - broadcast: this.broadcast + errors: Object.keys(this.errors).length > 0 ? this.errors : null, } } /** - * Check if there are N transactions of the specified type. - * @param {String} type - * @param {Number} count - * @return {Boolean} + * Cache the given transactions and return which got added. Already cached + * transactions are not returned. + * @return {Array} */ - has (type, count) { - return this.hasAny(type) === count - } + __cacheTransactions(transactions) { + const { added, notAdded } = app + .resolve('state') + .cacheTransactions(transactions) - /** - * Check if there are at least N transactions of the specified type. - * @param {String} type - * @param {Number} count - * @return {Boolean} - */ - hasAtLeast (type, count) { - return this.hasAny(type) >= count + notAdded.forEach(transaction => { + if (!this.errors[transaction.id]) { + this.__pushError(transaction, 'ERR_DUPLICATE', 'Already in cache.') + } + }) + + return added } /** - * Check if there are any transactions of the specified type. - * @param {String} type - * @return {Boolean} + * Get broadcast transactions. + * @return {Array} */ - hasAny (type) { - return this[type].length + getBroadcastTransactions() { + return Array.from(this.broadcast.values()) } /** - * Transforms and filters incomming transactions. - * It skips duplicates and not valid crypto transactions - * It skips blocked senders + * Transforms and filters incoming transactions. + * It skips: + * - transactions already in the pool + * - transactions from blocked senders + * - transactions from the future + * - dynamic fee mismatch + * - transactions based on type specific restrictions + * - not valid crypto transactions * @param {Array} transactions * @return {void} */ - async __transformAndFilterTransations (transactions) { - this.transactions = [] + __filterAndTransformTransactions(transactions) { + transactions.forEach(transaction => { + const exists = this.pool.transactionExists(transaction.id) - await Promise.each(transactions, async (transaction) => { - const exists = await this.pool.transactionExists(transaction.id) + if (exists) { + this.__pushError( + transaction, + 'ERR_DUPLICATE', + `Duplicate transaction ${transaction.id}`, + ) + } else if (this.pool.isSenderBlocked(transaction.senderPublicKey)) { + this.__pushError( + transaction, + 'ERR_SENDER_BLOCKED', + `Transaction ${transaction.id} rejected. Sender ${ + transaction.senderPublicKey + } is blocked.`, + ) + } else if (this.pool.hasExceededMaxTransactions(transaction)) { + this.excess.push(transaction.id) + } else if (this.__validateTransaction(transaction)) { + try { + const trx = new Transaction(transaction) + if (trx.verified) { + const dynamicFee = dynamicFeeMatch(trx) + if (dynamicFee.enterPool) { + this.accept.set(trx.id, trx) + } else { + this.__pushError( + transaction, + 'ERR_LOW_FEE', + 'Too low fee to be accepted in the pool', + ) + } - if (!exists && !this.pool.isSenderBlocked(transaction.senderPublicKey)) { - const trx = new Transaction(transaction) - - if (trx.verified) { - this.transactions.push(new Transaction(transaction)) + if (dynamicFee.broadcast) { + this.broadcast.set(trx.id, trx) + } else { + this.__pushError( + transaction, + 'ERR_LOW_FEE', + 'Too low fee for broadcast', + ) + } + } else { + this.__pushError( + transaction, + 'ERR_BAD_DATA', + "Transaction didn't pass the verification process.", + ) + } + } catch (error) { + this.__pushError(transaction, 'ERR_UNKNOWN', error.message) } } }) } /** - * Skipping already forged transactions - * @return {void} + * Determines valid transactions by checking rules, according to: + * - transaction timestamp + * - wallet balance + * - transaction type specifics: + * - if recipient is on the same network + * - if sender already has another transaction of the same type, for types that + * - only allow one transaction at a time in the pool (e.g. vote) */ - async __removeForgedTransactions () { - const transactionIds = this.transactions.map(transaction => transaction.id) - const forgedIdsSet = new Set(await database.getForgedTransactionsIds(transactionIds)) + __validateTransaction(transaction) { + const now = slots.getTime() + if (transaction.timestamp > now + 3600) { + const secondsInFuture = transaction.timestamp - now + this.__pushError( + transaction, + 'ERR_FROM_FUTURE', + `Transaction ${ + transaction.id + } is ${secondsInFuture} seconds in the future`, + ) + return false + } + + const errors = [] + if (!this.pool.walletManager.canApply(transaction, errors)) { + this.__pushError(transaction, 'ERR_APPLY', JSON.stringify(errors)) + return false + } - this.transactions = this.transactions.filter(transaction => { - if (forgedIdsSet.has(transaction.id)) { - this.invalid.push(transaction) + switch (transaction.type) { + case TRANSACTION_TYPES.TRANSFER: + if (!isRecipientOnActiveNetwork(transaction)) { + this.__pushError( + transaction, + 'ERR_INVALID_RECIPIENT', + `Recipient ${ + transaction.recipientId + } is not on the same network: ${configManager.get('pubKeyHash')}`, + ) + return false + } + break + case TRANSACTION_TYPES.SECOND_SIGNATURE: + case TRANSACTION_TYPES.DELEGATE_REGISTRATION: + case TRANSACTION_TYPES.VOTE: + if ( + this.pool.senderHasTransactionsOfType( + transaction.senderPublicKey, + transaction.type, + ) + ) { + this.__pushError( + transaction, + 'ERR_PENDING', + `Sender ${ + transaction.senderPublicKey + } already has a transaction of type ` + + `'${TRANSACTION_TYPES.toString(transaction.type)}' in the pool`, + ) + return false + } + break + case TRANSACTION_TYPES.MULTI_SIGNATURE: + case TRANSACTION_TYPES.IPFS: + case TRANSACTION_TYPES.TIMELOCK_TRANSFER: + case TRANSACTION_TYPES.MULTI_PAYMENT: + case TRANSACTION_TYPES.DELEGATE_RESIGNATION: + default: + this.__pushError( + transaction, + 'ERR_UNSUPPORTED', + 'Invalidating transaction of unsupported type ' + + `'${TRANSACTION_TYPES.toString(transaction.type)}'`, + ) return false - } + } - return true - }) + return true } /** - * Determines valid transactions by checking rules, according to: - * - if recipient is on the same network - * - if sender has enough funds - * Transaction that can be broadcasted are confirmed here + * Remove already forged transactions. + * @return {void} */ - async __determineValidTransactions () { - await Promise.each(this.transactions, async (transaction) => { - if (transaction.type === TRANSACTION_TYPES.TRANSFER) { - if (!helpers.isRecipientOnActiveNetwork(transaction)) { - this.invalid.push(transaction) + async __removeForgedTransactions() { + const database = app.resolvePlugin('database') - return - } - } + const forgedIdsSet = await database.getForgedTransactionsIds([ + ...new Set([...this.accept.keys(), ...this.broadcast.keys()]), + ]) - try { - await this.pool.walletManager.applyPoolTransaction(transaction) - } catch (error) { - this.invalid.push(transaction) - return - } + app.resolve('state').removeCachedTransactionIds(forgedIdsSet) + + forgedIdsSet.forEach(id => { + this.__pushError(this.accept.get(id), 'ERR_FORGED', 'Already forged.') - this.broadcast.push(transaction) + this.accept.delete(id) + this.broadcast.delete(id) }) } /** - * Determine exccess transactions + * Add accepted transactions to the pool and filter rejected ones. + * @return {void} */ - async __determineExcessTransactions () { - for (let transaction of this.broadcast) { - const hasExceeded = await this.pool.hasExceededMaxTransactions(transaction) - - if (hasExceeded) { - this.excess.push(transaction) - } else { - /** - * We need to check this again after checking it in "__transformAndFilterTransations" - * because the state of the transaction pool could have changed since then - * if concurrent requests are occurring via API. - */ - const exists = await this.pool.transactionExists(transaction.id) - - if (exists) { - this.invalid.push(transaction) - } else { - this.accept.push(transaction) - } + __addTransactionsToPool() { + // Add transactions to the transaction pool + const { added, notAdded } = this.pool.addTransactions( + Array.from(this.accept.values()), + ) + + // Exclude transactions which were refused from the pool + notAdded.forEach(item => { + this.accept.delete(item.transaction.id) + + // The transaction should still be broadcasted if the pool is full + if (item.type !== 'ERR_POOL_FULL') { + this.broadcast.delete(item.transaction.id) } - } + + this.__pushError(item.transaction, item.type, item.message) + }) } /** - * Determine any transactions that do not match the accepted fee by delegate or max fee set by sender - * Matched transactions stay in this.transaction, fee not accepted by node/delegate are still broadcasted. + * Adds a transaction to the errors object. The transaction id is mapped to an + * array of errors. There may be multiple errors associated with a transaction in + * which case __pushError is called multiple times. + * @param {Transaction} transaction + * @param {String} type + * @param {String} message * @return {void} */ - __determineFeeMatchingTransactions () { - this.accept = this.accept.filter(transaction => dynamicFeeMatch(transaction)) + __pushError(transaction, type, message) { + if (!this.errors[transaction.id]) { + this.errors[transaction.id] = [] + } + + this.errors[transaction.id].push({ type, message }) + + this.invalid.set(transaction.id, transaction) } /** - * Reset all indices. + * Print compact transaction stats. * @return {void} */ - __reset () { - this.transactions = [] - this.accept = [] - this.excess = [] - this.invalid = [] - this.broadcast = [] + __printStats() { + const properties = ['accept', 'broadcast', 'excess', 'invalid'] + const stats = properties + .map( + prop => + `${prop}: ${ + this[prop] instanceof Array ? this[prop].length : this[prop].size + }`, + ) + .join(' ') + + app + .resolvePlugin('logger') + .info( + `Received ${pluralize( + 'transaction', + this.transactions.length, + true, + )} (${stats}).`, + ) } } diff --git a/packages/core-transaction-pool/lib/index.js b/packages/core-transaction-pool/lib/index.js index 732b9cee14..6e24a61e41 100644 --- a/packages/core-transaction-pool/lib/index.js +++ b/packages/core-transaction-pool/lib/index.js @@ -1,5 +1,3 @@ -'use strict' - const transactionPoolManager = require('./manager') /** @@ -9,9 +7,9 @@ const transactionPoolManager = require('./manager') exports.plugin = { pkg: require('../package.json'), alias: 'transactionPoolManager', - async register (container, options) { + async register(container, options) { return transactionPoolManager - } + }, } /** diff --git a/packages/core-transaction-pool/lib/interface.js b/packages/core-transaction-pool/lib/interface.js index 453d2d4a40..bbfcafaad3 100644 --- a/packages/core-transaction-pool/lib/interface.js +++ b/packages/core-transaction-pool/lib/interface.js @@ -1,30 +1,21 @@ -'use strict' +const app = require('@arkecosystem/core-container') -const Promise = require('bluebird') +const logger = app.resolvePlugin('logger') -const container = require('@arkecosystem/core-container') -const logger = container.resolvePlugin('logger') -const database = container.resolvePlugin('database') - -const ark = require('@arkecosystem/crypto') -const { slots } = ark -const { TRANSACTION_TYPES } = ark.constants - -const memory = require('./memory') +const dayjs = require('dayjs-ext') const PoolWalletManager = require('./pool-wallet-manager') -const helpers = require('./utils/validation-helpers') -const moment = require('moment') -const uniq = require('lodash/uniq') + +const database = app.resolvePlugin('database') +const dynamicFeeMatch = require('./utils/dynamicfee-matcher') module.exports = class TransactionPoolInterface { /** * Create a new transaction pool instance. * @param {Object} options */ - constructor (options) { + constructor(options) { this.options = options this.walletManager = new PoolWalletManager() - this.memory = memory this.blockedByPublicKey = {} } @@ -33,15 +24,23 @@ module.exports = class TransactionPoolInterface { * Get a driver instance. * @return {TransactionPoolInterface} */ - driver () { + driver() { return this.driver } + /** + * Disconnect from transaction pool. + * @return {void} + */ + disconnect() { + throw new Error('Method [disconnect] not implemented!') + } + /** * Get the number of transactions in the pool. * @return {Number} */ - async getPoolSize () { + getPoolSize() { throw new Error('Method [getPoolSize] not implemented!') } @@ -50,7 +49,7 @@ module.exports = class TransactionPoolInterface { * @param {String} senderPublicKey * @return {Number} */ - async getSenderSize (senderPublicKey) { + getSenderSize(senderPublicKey) { throw new Error('Method [getSenderSize] not implemented!') } @@ -58,7 +57,7 @@ module.exports = class TransactionPoolInterface { * Add a transaction to the pool. * @param {Transaction} transaction */ - async addTransaction (transaction) { + addTransaction(transaction) { throw new Error('Method [addTransaction] not implemented!') } @@ -67,7 +66,7 @@ module.exports = class TransactionPoolInterface { * @param {Transaction} transaction * @return {void} */ - async removeTransaction (transaction) { + removeTransaction(transaction) { throw new Error('Method [removeTransaction] not implemented!') } @@ -76,17 +75,17 @@ module.exports = class TransactionPoolInterface { * @param {Number} id * @return {void} */ - async removeTransactionById (id) { + removeTransactionById(id) { throw new Error('Method [removeTransactionById] not implemented!') } /** - * Remove multiple transactions from the pool. - * @param {Array} transactions - * @return {void} + * Get all transactions that are ready to be forged. + * @param {Number} blockSize + * @return {(Array|void)} */ - async removeTransactions (transactions) { - throw new Error('Method [removeTransactions] not implemented!') + getTransactionsForForging(blockSize) { + throw new Error('Method [getTransactionsForForging] not implemented!') } /** @@ -94,7 +93,7 @@ module.exports = class TransactionPoolInterface { * @param {Number} id * @return {(Transaction|String)} */ - async getTransaction (id) { + getTransaction(id) { throw new Error('Method [getTransaction] not implemented!') } @@ -104,18 +103,18 @@ module.exports = class TransactionPoolInterface { * @param {Number} size * @return {Array} */ - async getTransactions (start, size) { + getTransactions(start, size) { throw new Error('Method [getTransactions] not implemented!') } /** - * Get all transactions IDs within the specified range. + * Get all cleans transactions IDs within the specified range from transaction pool. * @param {Number} start * @param {Number} size * @return {Array} */ - async getTransactionsIds (start, size) { - throw new Error('Method [getTransactionsIds] not implemented!') + getTransactionIdsForForging(start, size) { + throw new Error('Method [getTransactionIdsForForging] not implemented!') } /** @@ -123,16 +122,15 @@ module.exports = class TransactionPoolInterface { * @param {String} senderPublicKey * @return {void} */ - async removeTransactionsForSender (senderPublicKey) { + removeTransactionsForSender(senderPublicKey) { throw new Error('Method [removeTransactionsForSender] not implemented!') } /** * Add many transaction to the pool. Method called from blockchain, upon receiving payload. * @param {Array} transactions - * @param {Boolean} isBroadcast */ - async addTransactions (transactions, isBroadcast) { + addTransactions(transactions) { throw new Error('Method [addTransactions] not implemented!') } @@ -141,7 +139,7 @@ module.exports = class TransactionPoolInterface { * @param {String} transaction * @return {(Boolean|void)} */ - async hasExceededMaxTransactions (transaction) { + hasExceededMaxTransactions(transaction) { throw new Error('Method [hasExceededMaxTransactions] not implemented!') } @@ -150,7 +148,7 @@ module.exports = class TransactionPoolInterface { * @param {Transaction} transaction * @return {Boolean} */ - async transactionExists (transaction) { + transactionExists(transaction) { throw new Error('Method [transactionExists] not implemented!') } @@ -159,12 +157,12 @@ module.exports = class TransactionPoolInterface { * @param {String} senderPublicKey * @return {Boolean} */ - isSenderBlocked (senderPublicKey) { + isSenderBlocked(senderPublicKey) { if (!this.blockedByPublicKey[senderPublicKey]) { return false } - if (this.blockedByPublicKey[senderPublicKey] < moment()) { + if (this.blockedByPublicKey[senderPublicKey] < dayjs()) { delete this.blockedByPublicKey[senderPublicKey] return false } @@ -177,161 +175,171 @@ module.exports = class TransactionPoolInterface { * @param {String} senderPublicKey * @return {Time} blockReleaseTime */ - blockSender (senderPublicKey) { - const blockReleaseTime = moment().add(1, 'hours') + blockSender(senderPublicKey) { + const blockReleaseTime = dayjs().add(1, 'hours') this.blockedByPublicKey[senderPublicKey] = blockReleaseTime - logger.warn(`Sender ${senderPublicKey} blocked until ${this.blockedByPublicKey[senderPublicKey]} :stopwatch:`) + logger.warn( + `Sender ${senderPublicKey} blocked until ${ + this.blockedByPublicKey[senderPublicKey] + } :stopwatch:`, + ) return blockReleaseTime } /** - * Get all transactions that are ready to be forged. - * @param {Number} start - * @param {Number} size - * @return {(Array|void)} + * Processes recently accepted block by the blockchain. + * It removes block transaction from the pool and adjusts + * pool wallets for non existing transactions. + * + * @param {Object} block + * @return {void} */ - async getTransactionsForForging (start, size) { - try { - let transactionIds = await this.getTransactionsIds(start, size) - transactionIds = await this.removeForgedAndGetPending(transactionIds) - transactionIds = uniq(transactionIds) - - let transactions = [] - for (const id of transactionIds) { - const transaction = await this.getTransaction(id) - - if (!transaction) { - continue - } - - if (!helpers.canApplyToBlockchain(transaction)) { - await this.removeTransaction(transaction) - - logger.debug(`Unsufficient funds for transaction ${id}. Possible double spending attack :bomb:`) + acceptChainedBlock(block) { + for (const transaction of block.transactions) { + const exists = this.transactionExists(transaction.id) + const senderPublicKey = transaction.senderPublicKey - await this.purgeByPublicKey(transaction.senderPublicKey) - this.blockSender(transaction.senderPublicKey) + const senderWallet = this.walletManager.exists(senderPublicKey) + ? this.walletManager.findByPublicKey(senderPublicKey) + : false - continue - } + const recipientWallet = this.walletManager.exists(transaction.recipientId) + ? this.walletManager.findByAddress(transaction.recipientId) + : false - if (transaction.type === TRANSACTION_TYPES.TIMELOCK_TRANSFER) { // timelock is defined - const actions = { - 0: () => { // timestamp lock defined - if (transaction.timelock <= slots.getTime()) { - logger.debug(`Timelock for ${id} released - timestamp: ${transaction.timelock} :unlock:`) - transactions.push(transaction.serialized.toString('hex')) - } - }, - 1: () => { // block height time lock - if (transaction.timelock <= container.resolvePlugin('blockchain').getLastBlock().data.height) { - logger.debug(`Timelock for ${id} released - block height: ${transaction.timelock} :unlock:`) - transactions.push(transaction.serialized.toString('hex')) - } - } - } - actions[transaction.timelockType]() - } else { - transactions.push(transaction.serialized.toString('hex')) - } + if (recipientWallet) { + recipientWallet.applyTransactionToRecipient(transaction) } - return transactions - } catch (error) { - logger.error('Could not get transactions for forging from Redis: ', error, error.stack) - } - } - - /** - * Removes any transactions in the pool that have already been forged. - * @param {Array} transactionIds - * @return {Array} IDs of pending transactions that have yet to be forged. - */ - async removeForgedAndGetPending (transactionIds) { - const forgedIdsSet = new Set(await database.getForgedTransactionsIds(transactionIds)) - - await Promise.each(forgedIdsSet, async (transactionId) => { - await this.removeTransactionById(transactionId) - }) - - return transactionIds.filter(id => !forgedIdsSet.has(id)) - } + if (exists) { + this.removeTransaction(transaction) + } else if (senderWallet) { + const errors = [] + if (senderWallet.canApply(transaction, errors)) { + senderWallet.applyTransactionToSender(transaction) + } else { + this.purgeByPublicKey(transaction.senderPublicKey) + this.blockSender(transaction.senderPublicKey) - /** - * Processes recently accepted block by the blockchain. - * It removes block transaction from the pool and adjusts pool wallets for non existing transactions - * - * @param {Object} block - * @return {void} - */ - async acceptChainedBlock (block) { - for (const transaction of block.transactions) { - const exists = await this.transactionExists(transaction.id) - if (!exists) { - const senderWallet = this.walletManager.exists(transaction.senderPublicKey) ? this.walletManager.getWalletByPublicKey(transaction.senderPublicKey) : false - // if wallet in pool we try to apply transaction - if (senderWallet || this.walletManager.exists(transaction.recipientId)) { - try { - await this.walletManager.applyPoolTransaction(transaction) - } catch (error) { - logger.error(`AcceptChainedBlock in pool: ${error}`) - await this.purgeByPublicKey(transaction.senderPublicKey) - this.blockSender(transaction.senderPublicKey) - } - - if (senderWallet.balance === 0) { - this.walletManager.deleteWallet(transaction.senderPublicKey) - } + logger.error( + `CanApply transaction test failed on acceptChainedBlock() in transaction pool for transaction id:${ + transaction.id + } due to ${JSON.stringify( + errors, + )}. Possible double spending attack :bomb:`, + ) } - } else { - await this.removeTransaction(transaction) } - if (await this.getSenderSize(transaction.senderPublicKey) === 0) { - this.walletManager.deleteWallet(transaction.senderPublicKey) + if ( + senderWallet.balance === 0 && + this.getSenderSize(senderPublicKey) === 0 + ) { + this.walletManager.deleteWallet(senderPublicKey) } } - this.walletManager.applyPoolBlock(block) + // if delegate in poll wallet manager - apply rewards and fees + if (this.walletManager.exists(block.data.generatorPublicKey)) { + const delegateWallet = this.walletManager.findByPublicKey( + block.data.generatorPublicKey, + ) + const increase = block.data.reward.plus(block.data.totalFee) + delegateWallet.balance = delegateWallet.balance.plus(increase) + } + + app + .resolve('state') + .removeCachedTransactionIds(block.transactions.map(tx => tx.id)) } /** * Rebuild pool manager wallets * Removes all the wallets from pool manager and applies transaction from pool - if any - * It waits for the node to sync, and then check the transactions in pool and validates them and apply to the pool manager + * It waits for the node to sync, and then check the transactions in pool + * and validates them and apply to the pool manager. * @return {void} */ - async buildWallets () { - this.walletManager.purgeAll() - const poolTransactions = await this.getTransactionsIds(0, 0) + async buildWallets() { + this.walletManager.reset() + const poolTransactionIds = await this.getTransactionIdsForForging( + 0, + this.getPoolSize(), + ) - const unconfirmedTransactions = await this.removeForgedAndGetPending(poolTransactions) - - await Promise.each(unconfirmedTransactions, async (transactionId) => { - const transaction = await this.getTransaction(transactionId) + app.resolve('state').removeCachedTransactionIds(poolTransactionIds) + poolTransactionIds.forEach(transactionId => { + const transaction = this.getTransaction(transactionId) if (!transaction) { return } - try { - await this.walletManager.applyPoolTransaction(transaction) - } catch (error) { - logger.error('BuildWallets from pool:', error) - await this.purgeByPublicKey(transaction.senderPublicKey) + const senderWallet = this.walletManager.findByPublicKey( + transaction.senderPublicKey, + ) + const errors = [] + if (senderWallet && senderWallet.canApply(transaction, errors)) { + senderWallet.applyTransactionToSender(transaction) + } else { + logger.error('BuildWallets from pool:', errors) + this.purgeByPublicKey(transaction.senderPublicKey) } }) logger.info('Transaction Pool Manager build wallets complete') } - async purgeByPublicKey (senderPublicKey) { + purgeByPublicKey(senderPublicKey) { logger.debug(`Purging sender: ${senderPublicKey} from pool wallet manager`) - await this.removeTransactionsForSender(senderPublicKey) + this.removeTransactionsForSender(senderPublicKey) this.walletManager.deleteWallet(senderPublicKey) } + + /** + * Purges all transactions from senders with at least one + * invalid transaction. + * @param {Block} block + */ + purgeSendersWithInvalidTransactions(block) { + const publicKeys = new Set( + block.transactions + .filter(tx => !tx.verified) + .map(tx => tx.senderPublicKey), + ) + + publicKeys.forEach(publicKey => this.purgeByPublicKey(publicKey)) + } + + /** + * Purges all transactions from the block. + * Purges if transaction exists. It assumes that if trx exists that also wallet exists in pool + * @param {Block} block + */ + purgeBlock(block) { + block.transactions.forEach(tx => { + if (this.transactionExists(tx.id)) { + this.removeTransaction(tx) + this.walletManager + .findByPublicKey(tx.senderPublicKey) + .revertTransactionForSender(tx) + } + }) + } + + /** + * Check whether a given sender has any transactions of the specified type + * in the pool. + * @param {String} senderPublicKey public key of the sender + * @param {Number} transactionType transaction type, must be one of + * TRANSACTION_TYPES.* and is compared against transaction.type. + * @return {Boolean} true if exist + */ + senderHasTransactionsOfType(senderPublicKey, transactionType) { + throw new Error('Method [senderHasTransactionsOfType] not implemented!') + } } diff --git a/packages/core-transaction-pool/lib/manager.js b/packages/core-transaction-pool/lib/manager.js index 3585fc9c12..8431331910 100644 --- a/packages/core-transaction-pool/lib/manager.js +++ b/packages/core-transaction-pool/lib/manager.js @@ -1,11 +1,9 @@ -'use strict' - class TransactionPoolManager { /** * Create a new transaction pool manager instance. * @constructor */ - constructor () { + constructor() { this.connections = {} } @@ -14,7 +12,7 @@ class TransactionPoolManager { * @param {String} name * @return {TransactionPoolInterface} */ - connection (name = 'default') { + connection(name = 'default') { return this.connections[name] } @@ -24,7 +22,7 @@ class TransactionPoolManager { * @param {String} name * @return {void} */ - async makeConnection (connection, name = 'default') { + async makeConnection(connection, name = 'default') { this.connections[name] = await connection.make() } } diff --git a/packages/core-transaction-pool/lib/memory.js b/packages/core-transaction-pool/lib/memory.js deleted file mode 100644 index 8e958fe1ca..0000000000 --- a/packages/core-transaction-pool/lib/memory.js +++ /dev/null @@ -1,54 +0,0 @@ -'use strict' - -const without = require('lodash/without') - -/** - * We use this to store transaction IDs in memory to allow us filtering out - * duplicate transactions before hitting the validator which in certain - * cases can result in a race condition which in turn results in duplication - * of transactions during that process and after all in the transaction pool. - */ -class Memory { - /** - * Create a new Memory instance. - */ - constructor () { - this.memory = [] - } - - /** - * Memorize the given transactions. - * @param {Array} transactions - * @return {Object} - */ - memorize (transactions) { - const valid = transactions.filter(t => !this.__includes(t.id)) - const invalid = transactions.filter(t => this.__includes(t.id)) - - this.memory = this.memory.concat(transactions.map(t => t.id)) - - return { valid, invalid } - } - - /** - * Forget the given transactions. - * @param {Array} transactions - * @return {Memory} - */ - forget (transactions) { - this.memory = without(this.memory, transactions) - - return this - } - - /** - * Determine if the given transaction is memorized. - * @param {Object} transaction - * @return {Boolean} - */ - __includes (transaction) { - return this.memory.includes(transaction) - } -} - -module.exports = new Memory() diff --git a/packages/core-transaction-pool/lib/pool-wallet-manager.js b/packages/core-transaction-pool/lib/pool-wallet-manager.js index 8aa73d8e1e..53b8e4c274 100644 --- a/packages/core-transaction-pool/lib/pool-wallet-manager.js +++ b/packages/core-transaction-pool/lib/pool-wallet-manager.js @@ -1,10 +1,10 @@ -'use strict' -const container = require('@arkecosystem/core-container') +const app = require('@arkecosystem/core-container') const { Wallet } = require('@arkecosystem/crypto').models const { WalletManager } = require('@arkecosystem/core-database') -const logger = container.resolvePlugin('logger') -const database = container.resolvePlugin('database') -const config = container.resolvePlugin('config') + +const logger = app.resolvePlugin('logger') +const database = app.resolvePlugin('database') +const config = app.resolvePlugin('config') const { crypto } = require('@arkecosystem/crypto') const { TRANSACTION_TYPES } = require('@arkecosystem/crypto').constants @@ -13,29 +13,29 @@ module.exports = class PoolWalletManager extends WalletManager { * Create a new pool wallet manager instance. * @constructor */ - constructor () { + constructor() { super() this.emitEvents = false } /** - * Get a wallet by the given address. If wallet is not found it is copied from blockchain wallet manager - * Method overrides base class method from WalletManager. + * Get a wallet by the given address. If wallet is not found it is copied from blockchain + * wallet manager. Method overrides base class method from WalletManager. * WARNING: call only upon guard apply, as if wallet not found it gets it from blockchain. * For existing key checks use function exists(key) * @param {String} address * @return {(Wallet|null)} */ - getWalletByAddress (address) { - if (!this.walletsByAddress[address]) { - const blockchainWallet = database.walletManager.getWalletByAddress(address) + findByAddress(address) { + if (!this.byAddress[address]) { + const blockchainWallet = database.walletManager.findByAddress(address) const wallet = Object.assign(new Wallet(address), blockchainWallet) // do not modify this.reindex(wallet) } - return this.walletsByAddress[address] + return this.byAddress[address] } /** @@ -44,99 +44,109 @@ module.exports = class PoolWalletManager extends WalletManager { * @param {String} key can be publicKey or address of wallet * @return {Boolean} true if exists */ - exists (key) { - if (this.walletsByPublicKey[key]) { + exists(key) { + if (this.byPublicKey[key]) { return true } - if (this.walletsByAddress[key]) { + if (this.byAddress[key]) { return true } return false } + deleteWallet(publicKey) { + this.forgetByPublicKey(publicKey) + this.forgetByAddress( + crypto.getAddress(publicKey, config.network.pubKeyHash), + ) + } + /** - * Empty the pool manager wallets - * @return {void} + * Checks if the transaction can be applied. + * @param {Object|Transaction} transaction + * @param {Array} errors The errors are written into the array. + * @return {Boolean} */ - purgeAll () { - Object.keys(this.walletsByPublicKey).forEach(publicKey => { - delete this.walletsByPublicKey[publicKey] - }) - - Object.keys(this.walletsByAddress).forEach(address => { - delete this.walletsByAddress[address] - }) - - Object.keys(this.walletsByUsername).forEach(username => { - delete this.walletsByUsername[username] - }) - } + canApply(transaction, errors) { + // Edge case if sender is unknown and has no balance. + // NOTE: Check is performed against the database wallet manager. + if (!database.walletManager.byPublicKey[transaction.senderPublicKey]) { + const senderAddress = crypto.getAddress( + transaction.senderPublicKey, + config.network.pubKeyHash, + ) + + if ( + database.walletManager.findByAddress(senderAddress).balance.isZero() + ) { + errors.push( + 'Cold wallet is not allowed to send until receiving transaction is confirmed.', + ) + return false + } + } - deleteWallet (publicKey) { - delete this.walletsByPublicKey[publicKey] + const sender = this.findByPublicKey(transaction.senderPublicKey) + const { type, asset } = transaction + + if ( + type === TRANSACTION_TYPES.DELEGATE_REGISTRATION && + database.walletManager.byUsername[asset.delegate.username.toLowerCase()] + ) { + logger.error( + `[PoolWalletManager] Can't apply transaction ${ + transaction.id + }: delegate name already taken. Data: ${JSON.stringify(transaction)}`, + ) + + errors.push( + `Can't apply transaction ${ + transaction.id + }: delegate name already taken.`, + ) + // NOTE: We use the vote public key, because vote transactions have the same sender and recipient. + } else if ( + type === TRANSACTION_TYPES.VOTE && + !database.walletManager.__isDelegate(asset.votes[0].slice(1)) + ) { + logger.error( + `[PoolWalletManager] Can't apply vote transaction: delegate ${ + asset.votes[0] + } does not exist. Data: ${JSON.stringify(transaction)}`, + ) + + errors.push( + `Can't apply transaction ${transaction.id}: delegate ${ + asset.votes[0] + } does not exist.`, + ) + } else if (this.__isException(transaction)) { + logger.warn( + `Transaction forcibly applied because it has been added as an exception: ${transaction}`, + ) + } else if (!sender.canApply(transaction, errors)) { + const message = `[PoolWalletManager] Can't apply transaction id:${ + transaction.id + } from sender:${sender.address}` + logger.error(`${message} due to ${JSON.stringify(errors)}`) + errors.unshift(message) + } - delete this.walletsByAddress[crypto.getAddress(publicKey, config.network.pubKeyHash)] + return errors.length === 0 } /** - * Apply the given transaction to a wallet. A combination of pool wallet and blockchain wallet manager is used. + * Remove the given transaction from a sender only. * @param {Transaction} transaction * @return {Transaction} */ - async applyPoolTransaction (transaction) { /* eslint padded-blocks: "off" */ + revertTransactionForSender(transaction) { const { data } = transaction - const { type, asset, recipientId, senderPublicKey } = data - - const sender = this.getWalletByPublicKey(senderPublicKey) - let recipient = recipientId ? this.getWalletByAddress(recipientId) : null - - if (!recipient && recipientId) { // cold wallet - recipient = new Wallet(recipientId) - this.walletsByAddress[recipientId] = recipient - - } else if (type === TRANSACTION_TYPES.DELEGATE_REGISTRATION && database.walletManager.walletsByPublicKey[asset.delegate.username.toLowerCase()]) { - - logger.error(`PoolWalletManager: Delegate transaction sent by ${sender.address}`, JSON.stringify(data)) - throw new Error(`PoolWalletManager: Can't apply transaction ${data.id}: delegate name already taken`) - - // NOTE: We use the vote public key, because vote transactions have the same sender and recipient - } else if (type === TRANSACTION_TYPES.VOTE && !database.walletManager.walletsByPublicKey[asset.votes[0].slice(1)]) { - - logger.error(`PoolWalletManager: Vote transaction sent by ${sender.address}`, JSON.stringify(data)) - throw new Error(`PoolWalletManager: Can't apply transaction ${data.id}: voted/unvoted delegate does not exist`) + const sender = this.findByPublicKey(data.senderPublicKey) // Should exist - } else if (config.network.exceptions[data.id]) { + sender.revertTransactionForSender(data) - logger.warn('Transaction forcibly applied because it has been added as an exception:', data) - - } else if (!sender.canApply(data)) { - - logger.error(`PoolWalletManager: Can't apply transaction for ${sender.address}`, JSON.stringify(data)) - logger.debug('PoolWalletManager: Audit', JSON.stringify(sender.auditApply(data), null, 2)) - throw new Error(`PoolWalletManager: Can't apply transaction ${data.id}`) - } - - sender.applyTransactionToSender(data) - - if (recipient && type === TRANSACTION_TYPES.TRANSFER) { - recipient.applyTransactionToRecipient(data) - } - - return transaction - } - - /** - * Apply the given block to a delegate in the pool wallet manager. - * We apply only the block reward and fees, as transaction are already be applied - * when entering the pool. Applying only if delegate wallet is in pool wallet manager - * @param {block} - */ - applyPoolBlock (block) { - // if delegate in poll wallet manager - apply rewards - if (this.exists(block.data.generatorPublicKey)) { - const delegateWallet = this.getWalletByPublicKey(block.data.generatorPublicKey) - delegateWallet.applyBlock(block.data) - } + return data } } diff --git a/packages/core-transaction-pool/lib/utils/dynamicfee-matcher.js b/packages/core-transaction-pool/lib/utils/dynamicfee-matcher.js index d55783173f..de8b708dd9 100644 --- a/packages/core-transaction-pool/lib/utils/dynamicfee-matcher.js +++ b/packages/core-transaction-pool/lib/utils/dynamicfee-matcher.js @@ -1,39 +1,95 @@ -const container = require('@arkecosystem/core-container') -const { feeManager, dynamicFeeManager } = require('@arkecosystem/crypto') -const config = container.resolvePlugin('config') +const app = require('@arkecosystem/core-container') +const { + feeManager, + dynamicFeeManager, + formatArktoshi, +} = require('@arkecosystem/crypto') /** - * Determine if transaction matches the accepted fee by delegate or max fee set by sender + * Determine if a transaction's fee meets the minimum requirements for broadcasting + * and for entering the transaction pool. * @param {Transaction} Transaction - transaction to check - * @return {Boolean} matches T/F + * @return {Object} { broadcast: Boolean, enterPool: Boolean } */ -module.exports = (transaction) => { - const staticFee = feeManager.getForTransaction(transaction) - const blockchain = container.resolvePlugin('blockchain') - const feeConstants = config.getConstants(blockchain.getLastBlock().data.height).fees - if (!feeConstants.dynamic && transaction.fee !== staticFee) { - // logger.debug(`Received transaction fee '${transaction.fee}' for '${transaction.id}' does not match static fee of '${staticFee}'`) - return false - } +module.exports = transaction => { + const config = app.resolvePlugin('config') + const logger = app.resolvePlugin('logger') + + const fee = +transaction.fee.toFixed() + const id = transaction.id - if (feeConstants.dynamic) { - const dynamicFee = dynamicFeeManager.calculateFee(config.delegates.dynamicFees.feeMultiplier, transaction) + const blockchain = app.resolvePlugin('blockchain') + const fees = config.getConstants(blockchain.getLastBlock().data.height).fees - if (transaction.fee < config.delegates.dynamicFees.minAcceptableFee) { - // logger.debug(`Fee not accepted - transaction fee of '${transaction.fee}' for '${transaction.id}' is below delegate minimum fee of '${config.delegates.dynamicFees.minAcceptableFee}'`) - return false + let broadcast + let enterPool + + if (fees.dynamic) { + const minFeeBroadcast = dynamicFeeManager.calculateFee( + fees.dynamicFees.minFeeBroadcast, + transaction, + ) + if (fee >= minFeeBroadcast) { + broadcast = true + logger.debug( + `Transaction ${id} eligible for broadcast - fee of ${formatArktoshi( + fee, + )} is ${ + fee === minFeeBroadcast ? 'equal to' : 'greater than' + } minimum fee (${formatArktoshi(minFeeBroadcast)})`, + ) + } else { + broadcast = false + logger.debug( + `Transaction ${id} not eligible for broadcast - fee of ${formatArktoshi( + fee, + )} is smaller than minimum fee (${formatArktoshi(minFeeBroadcast)})`, + ) } - if (dynamicFee > transaction.fee) { - // logger.debug(`Fee not accepted - calculated delegate fee of '${dynamicFee}' is above maximum transcation fee of '${transaction.fee}' for '${transaction.id}'`) - return false + const minFeePool = dynamicFeeManager.calculateFee( + fees.dynamicFees.minFeePool, + transaction, + ) + if (fee >= minFeePool) { + enterPool = true + logger.debug( + `Transaction ${id} eligible to enter pool - fee of ${formatArktoshi( + fee, + )} is ${ + fee === minFeePool ? 'equal to' : 'greater than' + } minimum fee (${formatArktoshi(minFeePool)})`, + ) + } else { + enterPool = false + logger.debug( + `Transaction ${id} not eligible to enter pool - fee of ${formatArktoshi( + fee, + )} is smaller than minimum fee (${formatArktoshi(minFeePool)})`, + ) } + } else { + // Static fees + const staticFee = feeManager.getForTransaction(transaction) - if (transaction.fee > staticFee) { - // logger.debug(`Fee not accepted - transaction fee of '${transaction.fee}' for '${transaction.id}' is above static fee of '${feeManager.get(transaction.type)}'`) - return false + if (fee === staticFee) { + broadcast = true + enterPool = true + logger.debug( + `Transaction ${id} eligible for broadcast and to enter pool - fee of ${formatArktoshi( + fee, + )} is equal to static fee (${formatArktoshi(staticFee)})`, + ) + } else { + broadcast = false + enterPool = false + logger.debug( + `Transaction ${id} not eligible for broadcast and not eligible to enter pool - fee of ${formatArktoshi( + fee, + )} does not match static fee (${formatArktoshi(staticFee)})`, + ) } - // logger.debug(`Transaction accepted with fee of '${transaction.fee}' for '${transaction.id}' - calculated fee for transaction is '${dynamicFee}'`) } - return true + + return { broadcast, enterPool } } diff --git a/packages/core-transaction-pool/lib/utils/is-on-active-network.js b/packages/core-transaction-pool/lib/utils/is-on-active-network.js new file mode 100644 index 0000000000..f65baaf211 --- /dev/null +++ b/packages/core-transaction-pool/lib/utils/is-on-active-network.js @@ -0,0 +1,26 @@ +const app = require('@arkecosystem/core-container') +const bs58check = require('bs58check') +const { configManager } = require('@arkecosystem/crypto') + +const logger = app.resolvePlugin('logger') + +/** + * Checks if transaction recipient is on the same network as blockchain + * @param {Transaction} + * @return {Boolean} + */ +module.exports = transaction => { + const recipientPrefix = bs58check.decode(transaction.recipientId).readUInt8(0) + + if (recipientPrefix === configManager.get('pubKeyHash')) { + return true + } + + logger.error( + `Recipient ${ + transaction.recipientId + } is not on the same network: ${configManager.get('pubKeyHash')}`, + ) + + return false +} diff --git a/packages/core-transaction-pool/lib/utils/validation-helpers.js b/packages/core-transaction-pool/lib/utils/validation-helpers.js deleted file mode 100644 index 4b41e85e2e..0000000000 --- a/packages/core-transaction-pool/lib/utils/validation-helpers.js +++ /dev/null @@ -1,37 +0,0 @@ -'use strict' -const container = require('@arkecosystem/core-container') -const bs58check = require('bs58check') -const { configManager } = require('@arkecosystem/crypto') -const logger = container.resolvePlugin('logger') -const database = container.resolvePlugin('database') - -module.exports = { - /** - * Gets the blockchain wallet and checks if transaction can be applied - before returning it to forger. - * @param {Transaction} - * @return {Boolean} - */ - canApplyToBlockchain: transaction => { - return database - .walletManager - .getWalletByPublicKey(transaction.senderPublicKey) - .canApply(transaction) - }, - - /** - * Checks if transaction recipient is on the same network as blockchain - * @param {Transaction} - * @return {Boolean} - */ - isRecipientOnActiveNetwork: transaction => { - const recipientPrefix = bs58check.decode(transaction.recipientId).readUInt8(0) - - if (recipientPrefix === configManager.get('pubKeyHash')) { - return true - } - - logger.error(`Recipient ${transaction.recipientId} in not on the same network: ${configManager.get('pubKeyHash')}`) - - return false - } -} diff --git a/packages/core-transaction-pool/package.json b/packages/core-transaction-pool/package.json index b0231ca5a7..758c854cf7 100644 --- a/packages/core-transaction-pool/package.json +++ b/packages/core-transaction-pool/package.json @@ -1,7 +1,7 @@ { "name": "@arkecosystem/core-transaction-pool", - "description": "Transaction Pool Manager for ARK Core", - "version": "0.1.1", + "description": "Transaction Pool Manager for Ark Core", + "version": "0.2.0", "contributors": [ "Kristjan Košič ", "Brian Faust ", @@ -10,25 +10,30 @@ "license": "MIT", "main": "lib/index.js", "scripts": { - "build:docs": "../../node_modules/.bin/jsdoc -c jsdoc.json", "test": "cross-env ARK_ENV=test jest --runInBand --detectOpenHandles", - "test:coverage": "cross-env ARK_ENV=test jest --coverage --runInBand --detectOpenHandles", - "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand --watch", + "test:coverage": "cross-env ARK_ENV=test jest --coverage --coveragePathIgnorePatterns='/(defaults.js|index.js)$' --runInBand --detectOpenHandles", + "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand", "test:watch": "cross-env ARK_ENV=test jest --runInBand --watch", "test:watch:all": "cross-env ARK_ENV=test jest --runInBand --watchAll", "lint": "eslint ./ --fix", - "depcheck": "depcheck ./" + "depcheck": "depcheck ./ --ignores=@arkecosystem/core-transaction-pool" }, "dependencies": { - "@arkecosystem/core-container": "^0.1.1", - "@arkecosystem/core-database": "^0.1.1", - "@arkecosystem/crypto": "^0.1.1", - "bluebird": "^3.5.1", - "bs58check": "^2.1.1", - "lodash": "^4.17.10", - "moment": "^2.22.2" + "@arkecosystem/core-container": "~0.2", + "@arkecosystem/core-database": "~0.2", + "@arkecosystem/crypto": "~0.2", + "bs58check": "^2.1.2", + "dayjs-ext": "^2.2.0", + "pluralize": "^7.0.0" + }, + "devDependencies": { + "@arkecosystem/core-test-utils": "~0.2", + "bip39": "^2.5.0" }, "publishConfig": { "access": "public" + }, + "engines": { + "node": ">=10.x" } } diff --git a/packages/core-utils/.gitattributes b/packages/core-utils/.gitattributes new file mode 100644 index 0000000000..60cc52db63 --- /dev/null +++ b/packages/core-utils/.gitattributes @@ -0,0 +1,11 @@ +# Path-based git attributes +# https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html + +# Ignore all test and documentation with "export-ignore". +/.editorconfig export-ignore +/.gitattributes export-ignore +/.gitignore export-ignore +/.travis.yml export-ignore +/__tests__ export-ignore +/docs export-ignore +/README.md export-ignore diff --git a/packages/core-utils/CHANGELOG.md b/packages/core-utils/CHANGELOG.md new file mode 100644 index 0000000000..0664a2186a --- /dev/null +++ b/packages/core-utils/CHANGELOG.md @@ -0,0 +1,29 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +## Unreleased + +## 0.2.0 - 2018-12-03 + +### Added + +- Tests for timestamp formatting +- Helper to create tables in the CLI + +### Changelog + +- Dropped node.js 9 as minimum requirement in favour of node.js 10 + +### Fixed + +- Properly calculate delegate approval + +## 0.1.0 - 2018-10-08 + +### Added + +- initial release diff --git a/packages/core-utils/LICENSE b/packages/core-utils/LICENSE new file mode 100644 index 0000000000..d6dd75272f --- /dev/null +++ b/packages/core-utils/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) Ark Ecosystem + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/validation/README.md b/packages/core-utils/README.md similarity index 53% rename from packages/validation/README.md rename to packages/core-utils/README.md index 4d249fad7f..1e9057172b 100644 --- a/packages/validation/README.md +++ b/packages/core-utils/README.md @@ -1,12 +1,12 @@ -![ARK Core](banner.png) +# Ark Core - Utilities -# ARK Core - Validation +

+ +

-## Installation +## Documentation -```bash -yarn add @arkecosystem/validation -``` +You can find installation instructions and detailed instructions on how to use this package at the [dedicated documentation site](https://docs.ark.io/guidebook/core/plugins/core-utils.html). ## Security @@ -15,7 +15,6 @@ If you discover a security vulnerability within this package, please send an e-m ## Credits - [Brian Faust](https://github.com/faustbrian) -- [Alex Barnsley](https://github.com/alexbarnsley) - [All Contributors](../../../../contributors) ## License diff --git a/packages/core-utils/__tests__/delegate-calculator.test.js b/packages/core-utils/__tests__/delegate-calculator.test.js new file mode 100644 index 0000000000..0d4b7c0641 --- /dev/null +++ b/packages/core-utils/__tests__/delegate-calculator.test.js @@ -0,0 +1,84 @@ +const { Bignum } = require('@arkecosystem/crypto') +const { Wallet } = require('@arkecosystem/crypto').models +const app = require('@arkecosystem/core-container') +const delegateCalculator = require('../lib/delegate-calculator') + +let delegate + +beforeEach(() => { + delegate = new Wallet('D61xc3yoBQDitwjqUspMPx1ooET6r1XLt7') + Object.entries({ + producedBlocks: 0, + missedBlocks: 0, + }).forEach((key, value) => { + delegate[key] = value + }) +}) + +describe('Delegate Calculator', () => { + describe('calculateApproval', () => { + it('should be a function', () => { + expect(delegateCalculator.calculateApproval).toBeFunction() + }) + + it('should calculate correctly', () => { + delegate.voteBalance = new Bignum(10000 * 1e8) + + app.resolvePlugin = jest.fn(plugin => { + if (plugin === 'config') { + return { + getConstants: () => ({ + height: 1, + reward: 2 * 1e8, + }), + genesisBlock: { + totalAmount: 1000000 * 1e8, + }, + } + } + }) + + expect(delegateCalculator.calculateApproval(delegate, 1)).toBe(1) + }) + + it('should calculate correctly with 2 decimals', () => { + delegate.voteBalance = new Bignum(16500 * 1e8) + + app.resolvePlugin = jest.fn(plugin => { + if (plugin === 'config') { + return { + getConstants: () => ({ + height: 1, + reward: 2 * 1e8, + }), + genesisBlock: { + totalAmount: 1000000 * 1e8, + }, + } + } + }) + + expect(delegateCalculator.calculateApproval(delegate, 1)).toBe(1.65) + }) + }) + + describe('calculateProductivity', () => { + it('should be a function', () => { + expect(delegateCalculator.calculateProductivity).toBeFunction() + }) + + it('should calculate correctly for a value above 0', () => { + delegate.missedBlocks = 10 + delegate.producedBlocks = 100 + + expect(delegateCalculator.calculateProductivity(delegate)).toBe(90.91) + }) + + it('should calculate correctly for a value of 0', () => { + delegate.missedBlocks = 0 + delegate.producedBlocks = 0 + + expect(delegateCalculator.calculateProductivity(delegate)).toBe(0.0) + }) + }) +}) diff --git a/packages/core-utils/__tests__/format-timestamp.test.js b/packages/core-utils/__tests__/format-timestamp.test.js new file mode 100644 index 0000000000..b6bd1c0e16 --- /dev/null +++ b/packages/core-utils/__tests__/format-timestamp.test.js @@ -0,0 +1,30 @@ +const app = require('@arkecosystem/core-container') +const formatTimestamp = require('../lib/format-timestamp') + +app.resolvePlugin = jest.fn(plugin => { + if (plugin === 'config') { + return { + getConstants: () => ({ + epoch: '2017-03-21T13:00:00.000Z', + }), + } + } +}) + +describe('Format Timestamp', () => { + it('should be a function', () => { + expect(formatTimestamp).toBeFunction() + }) + + it('should compute the correct epoch value', () => { + expect(formatTimestamp(100).epoch).toBe(100) + }) + + it('should compute the correct unix value', () => { + expect(formatTimestamp(100).unix).toBe(1490101300) + }) + + it('should compute the correct human value', () => { + expect(formatTimestamp(100).human).toBe('2017-03-21T13:01:40.000Z') + }) +}) diff --git a/packages/core-utils/__tests__/round-calculator.test.js b/packages/core-utils/__tests__/round-calculator.test.js new file mode 100644 index 0000000000..b1f4a69a1a --- /dev/null +++ b/packages/core-utils/__tests__/round-calculator.test.js @@ -0,0 +1,44 @@ +const app = require('@arkecosystem/core-container') +const roundCalculator = require('../lib/round-calculator') + +app.resolvePlugin = jest.fn(plugin => { + if (plugin === 'config') { + return { + getConstants: () => ({ + activeDelegates: 51, + }), + } + } +}) + +describe('Round calculator', () => { + describe('calculateRound', () => { + it('should be a function', () => { + expect(roundCalculator.calculateRound).toBeFunction() + }) + + it('should calculate the round when nextRound is the same', () => { + const { round, nextRound } = roundCalculator.calculateRound(1) + expect(round).toBe(1) + expect(nextRound).toBe(1) + }) + + it('should calculate the round when nextRound is not the same', () => { + const { round, nextRound } = roundCalculator.calculateRound(51) + expect(round).toBe(1) + expect(nextRound).toBe(2) + }) + }) + + describe('isNewRound', () => { + it('should be a function', () => { + expect(roundCalculator.isNewRound).toBeFunction() + }) + + it('should determine the beginning of a new round', () => { + expect(roundCalculator.isNewRound(1)).toBeTrue() + expect(roundCalculator.isNewRound(2)).toBeFalse() + expect(roundCalculator.isNewRound(52)).toBeTrue() + }) + }) +}) diff --git a/packages/core-utils/jest.config.js b/packages/core-utils/jest.config.js new file mode 100644 index 0000000000..57770a97bb --- /dev/null +++ b/packages/core-utils/jest.config.js @@ -0,0 +1,12 @@ +module.exports = { + testEnvironment: 'node', + bail: false, + verbose: true, + testMatch: ['**/__tests__/**/*.test.js'], + moduleFileExtensions: ['js', 'json'], + collectCoverage: false, + coverageDirectory: '/.coverage', + collectCoverageFrom: ['lib/**/*.js', '!**/node_modules/**'], + watchman: false, + setupTestFrameworkScriptFile: 'jest-extended', +} diff --git a/packages/core-utils/jsdoc.json b/packages/core-utils/jsdoc.json new file mode 100644 index 0000000000..f3ea8aab33 --- /dev/null +++ b/packages/core-utils/jsdoc.json @@ -0,0 +1,22 @@ +{ + "tags": { + "allowUnknownTags": false + }, + "source": { + "include": "./lib", + "includePattern": ".js$", + "excludePattern": "(node_modules/|docs)" + }, + "plugins": ["plugins/markdown"], + "opts": { + "template": "../../node_modules/docdash", + "encoding": "utf8", + "destination": "docs/", + "recurse": true, + "verbose": true + }, + "templates": { + "cleverLinks": false, + "monospaceLinks": false + } +} diff --git a/packages/core-utils/lib/bignumify.js b/packages/core-utils/lib/bignumify.js new file mode 100644 index 0000000000..f3eeb2c986 --- /dev/null +++ b/packages/core-utils/lib/bignumify.js @@ -0,0 +1,3 @@ +const { Bignum } = require('@arkecosystem/crypto') + +module.exports = value => new Bignum(value) diff --git a/packages/core-utils/lib/create-table.js b/packages/core-utils/lib/create-table.js new file mode 100644 index 0000000000..bae1f3d4b5 --- /dev/null +++ b/packages/core-utils/lib/create-table.js @@ -0,0 +1,11 @@ +const Table = require('cli-table3') + +module.exports = (opts, data) => { + const table = new Table(opts) + + for (const item of data) { + table.push(item) + } + + return table.toString() +} diff --git a/packages/core-utils/lib/delegate-calculator.js b/packages/core-utils/lib/delegate-calculator.js new file mode 100644 index 0000000000..30313899ae --- /dev/null +++ b/packages/core-utils/lib/delegate-calculator.js @@ -0,0 +1,49 @@ +const app = require('@arkecosystem/core-container') + +let { Bignum } = require('@arkecosystem/crypto') + +Bignum = Bignum.clone({ DECIMAL_PLACES: 2 }) + +/** + * Calculate the approval for the given delegate. + * @param {Delegate} delegate + * @param {Number} height + * @return {Number} Approval, with 2 decimals + */ +exports.calculateApproval = (delegate, height) => { + const config = app.resolvePlugin('config') + + if (!height) { + height = app.resolvePlugin('blockchain').getLastBlock().data.height + } + + const constants = config.getConstants(height) + const totalSupply = new Bignum(config.genesisBlock.totalAmount).plus( + (height - constants.height) * constants.reward, + ) + const voteBalance = new Bignum(delegate.voteBalance) + + return +voteBalance + .times(100) + .dividedBy(totalSupply) + .toFixed(2) +} + +/** + * Calculate the productivity of the given delegate. + * @param {Delegate} delegate + * @return {Number} Productivity, with 2 decimals + */ +exports.calculateProductivity = delegate => { + const missedBlocks = +delegate.missedBlocks + const producedBlocks = +delegate.producedBlocks + + if (!missedBlocks && !producedBlocks) { + return +(0).toFixed(2) + } + + return +( + 100 + - missedBlocks / ((producedBlocks + missedBlocks) / 100) + ).toFixed(2) +} diff --git a/packages/core-utils/lib/format-timestamp.js b/packages/core-utils/lib/format-timestamp.js new file mode 100644 index 0000000000..4d3d6c0596 --- /dev/null +++ b/packages/core-utils/lib/format-timestamp.js @@ -0,0 +1,18 @@ +const dayjs = require('dayjs-ext') +const app = require('@arkecosystem/core-container') + +/** + * Format the given epoch based timestamp into human and unix. + * @param {Number} epochStamp + * @return {Object} + */ +module.exports = epochStamp => { + const constants = app.resolvePlugin('config').getConstants(1) + const timestamp = dayjs(constants.epoch).add(epochStamp, 'seconds') + + return { + epoch: epochStamp, + unix: timestamp.unix(), + human: timestamp.toISOString(), + } +} diff --git a/packages/core-utils/lib/index.js b/packages/core-utils/lib/index.js new file mode 100644 index 0000000000..0960e647e7 --- /dev/null +++ b/packages/core-utils/lib/index.js @@ -0,0 +1,7 @@ +module.exports = { + bignumify: require('./bignumify'), + createTable: require('./create-table'), + delegateCalculator: require('./delegate-calculator'), + formatTimestamp: require('./format-timestamp'), + roundCalculator: require('./round-calculator'), +} diff --git a/packages/core-utils/lib/round-calculator.js b/packages/core-utils/lib/round-calculator.js new file mode 100644 index 0000000000..e6cec2f09a --- /dev/null +++ b/packages/core-utils/lib/round-calculator.js @@ -0,0 +1,29 @@ +const app = require('@arkecosystem/core-container') + +/** + * Calculate the round and nextRound based on the height and active delegates. + * @param {Number} height + * @param {Number} maxDelegates + * @return {Object} + */ +exports.calculateRound = (height, maxDelegates = undefined) => { + const config = app.resolvePlugin('config') + maxDelegates = maxDelegates || config.getConstants(height).activeDelegates + + const round = Math.floor((height - 1) / maxDelegates) + 1 + const nextRound = Math.floor(height / maxDelegates) + 1 + + return { round, nextRound, maxDelegates } +} + +/** + * Detect if height is the beginning of a new round. + * @param {Number} height + * @return {boolean} true if new round, false if not + */ +exports.isNewRound = height => { + const config = app.resolvePlugin('config') + const maxDelegates = config.getConstants(height).activeDelegates + + return height % maxDelegates === 1 +} diff --git a/packages/validation/package.json b/packages/core-utils/package.json similarity index 51% rename from packages/validation/package.json rename to packages/core-utils/package.json index aa5797ab84..c30366bf03 100644 --- a/packages/validation/package.json +++ b/packages/core-utils/package.json @@ -1,30 +1,31 @@ { - "name": "@arkecosystem/validation", - "description": "Validation for ARK Core", - "version": "0.1.1", + "name": "@arkecosystem/core-utils", + "description": "Utilities for Ark Core", + "version": "0.2.0", "contributors": [ - "Brian Faust ", - "Alex Barnsley " + "Brian Faust " ], "license": "MIT", "main": "lib/index.js", "scripts": { - "build:docs": "../../node_modules/.bin/jsdoc -c jsdoc.json", "test": "cross-env ARK_ENV=test jest --runInBand --detectOpenHandles", - "test:coverage": "cross-env ARK_ENV=test jest --coverage --runInBand --detectOpenHandles", - "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand --watch", + "test:coverage": "cross-env ARK_ENV=test jest --coverage --coveragePathIgnorePatterns='/(defaults.js|index.js)$' --runInBand --detectOpenHandles", + "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand", "test:watch": "cross-env ARK_ENV=test jest --runInBand --watch", "test:watch:all": "cross-env ARK_ENV=test jest --runInBand --watchAll", "lint": "eslint ./ --fix", "depcheck": "depcheck ./" }, "dependencies": { - "joi": "^13.3.0" + "@arkecosystem/core-container": "~0.2", + "@arkecosystem/crypto": "~0.2", + "cli-table3": "^0.5.1", + "dayjs-ext": "^2.2.0" }, "publishConfig": { "access": "public" }, - "devDependencies": { - "@arkecosystem/crypto": "^0.1.1" + "engines": { + "node": ">=10.x" } } diff --git a/packages/core-vote-report/.gitattributes b/packages/core-vote-report/.gitattributes new file mode 100644 index 0000000000..60cc52db63 --- /dev/null +++ b/packages/core-vote-report/.gitattributes @@ -0,0 +1,11 @@ +# Path-based git attributes +# https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html + +# Ignore all test and documentation with "export-ignore". +/.editorconfig export-ignore +/.gitattributes export-ignore +/.gitignore export-ignore +/.travis.yml export-ignore +/__tests__ export-ignore +/docs export-ignore +/README.md export-ignore diff --git a/packages/core-vote-report/CHANGELOG.md b/packages/core-vote-report/CHANGELOG.md new file mode 100644 index 0000000000..6842caf9df --- /dev/null +++ b/packages/core-vote-report/CHANGELOG.md @@ -0,0 +1,14 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +## Unreleased + +## 0.1.0 - 2018-12-03 + +### Added + +- initial release diff --git a/packages/core-vote-report/LICENSE b/packages/core-vote-report/LICENSE new file mode 100644 index 0000000000..d6dd75272f --- /dev/null +++ b/packages/core-vote-report/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) Ark Ecosystem + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/core-vote-report/README.md b/packages/core-vote-report/README.md new file mode 100644 index 0000000000..f4b8319277 --- /dev/null +++ b/packages/core-vote-report/README.md @@ -0,0 +1,22 @@ +# Ark Core - Vote Report + +

+ +

+ +## Documentation + +You can find installation instructions and detailed instructions on how to use this package at the [dedicated documentation site](https://docs.ark.io/guidebook/core/plugins/core-vote-report.html). + +## Security + +If you discover a security vulnerability within this package, please send an e-mail to security@ark.io. All security vulnerabilities will be promptly addressed. + +## Credits + +- [Brian Faust](https://github.com/faustbrian) +- [All Contributors](../../../../contributors) + +## License + +[MIT](LICENSE) © [ArkEcosystem](https://ark.io) diff --git a/packages/core-vote-report/jest.config.js b/packages/core-vote-report/jest.config.js new file mode 100644 index 0000000000..57770a97bb --- /dev/null +++ b/packages/core-vote-report/jest.config.js @@ -0,0 +1,12 @@ +module.exports = { + testEnvironment: 'node', + bail: false, + verbose: true, + testMatch: ['**/__tests__/**/*.test.js'], + moduleFileExtensions: ['js', 'json'], + collectCoverage: false, + coverageDirectory: '/.coverage', + collectCoverageFrom: ['lib/**/*.js', '!**/node_modules/**'], + watchman: false, + setupTestFrameworkScriptFile: 'jest-extended', +} diff --git a/packages/core-vote-report/jsdoc.json b/packages/core-vote-report/jsdoc.json new file mode 100644 index 0000000000..f3ea8aab33 --- /dev/null +++ b/packages/core-vote-report/jsdoc.json @@ -0,0 +1,22 @@ +{ + "tags": { + "allowUnknownTags": false + }, + "source": { + "include": "./lib", + "includePattern": ".js$", + "excludePattern": "(node_modules/|docs)" + }, + "plugins": ["plugins/markdown"], + "opts": { + "template": "../../node_modules/docdash", + "encoding": "utf8", + "destination": "docs/", + "recurse": true, + "verbose": true + }, + "templates": { + "cleverLinks": false, + "monospaceLinks": false + } +} diff --git a/packages/core-vote-report/lib/defaults.js b/packages/core-vote-report/lib/defaults.js new file mode 100644 index 0000000000..3fc1848f6a --- /dev/null +++ b/packages/core-vote-report/lib/defaults.js @@ -0,0 +1,5 @@ +module.exports = { + host: process.env.ARK_VOTE_REPORT_HOST || '0.0.0.0', + port: process.env.ARK_VOTE_REPORT_PORT || 4006, + delegateRows: process.env.ARK_VOTE_REPORT_DELEGATE_ROWS || 80, +} diff --git a/packages/core-vote-report/lib/handler.js b/packages/core-vote-report/lib/handler.js new file mode 100644 index 0000000000..133b2e3a5a --- /dev/null +++ b/packages/core-vote-report/lib/handler.js @@ -0,0 +1,101 @@ +const sumBy = require('lodash/sumBy') +const { configManager } = require('@arkecosystem/crypto') +const { bignumify, delegateCalculator } = require('@arkecosystem/core-utils') +const app = require('@arkecosystem/core-container') + +const config = app.resolvePlugin('config') +const blockchain = app.resolvePlugin('blockchain') +const database = app.resolvePlugin('database') + +const formatDelegates = delegates => + delegates.map(delegate => { + const voters = database.walletManager + .allByPublicKey() + .filter( + wallet => + wallet.vote === delegate.publicKey && wallet.balance > 0.1 * 1e8, + ) + + const approval = Number( + delegateCalculator.calculateApproval(delegate), + ).toLocaleString(undefined, { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + }) + + const rank = delegate.rate.toLocaleString(undefined, { + minimumIntegerDigits: 2, + }) + + const votes = Number(delegate.voteBalance.div(1e8)).toLocaleString( + undefined, + { maximumFractionDigits: 0 }, + ) + const voterCount = voters.length.toLocaleString(undefined, { + maximumFractionDigits: 0, + }) + + return { + rank, + username: delegate.username.padEnd(25), + approval: approval.padEnd(4), + votes: votes.padStart(10), + voterCount: voterCount.padStart(5), + } + }) + +module.exports = (request, h) => { + const lastBlock = blockchain.getLastBlock() + const constants = config.getConstants(lastBlock.data.height) + const delegateRows = app.resolveOptions('vote-report').delegateRows + + const rewards = bignumify(constants.reward).times( + lastBlock.data.height - constants.height, + ) + + const supply = +bignumify(config.genesisBlock.totalAmount) + .plus(rewards) + .toFixed() + + const active = database.walletManager + .allByUsername() + .sort((a, b) => a.rate - b.rate) + .slice(0, constants.activeDelegates) + + const standby = database.walletManager + .allByUsername() + .sort((a, b) => a.rate - b.rate) + .slice(constants.activeDelegates + 1, delegateRows) + + const voters = database.walletManager + .allByPublicKey() + .filter(wallet => wallet.vote && wallet.balance > 0.1 * 1e8) + + const totalVotes = sumBy(voters, wallet => +wallet.balance.toFixed()) + const percentage = (totalVotes * 100) / supply + + const client = configManager.get('client') + + return h + .view('index', { + client, + voteHeader: `Vote ${client.token}`.padStart(10), + activeDelegatesCount: constants.activeDelegates, + activeDelegates: formatDelegates(active), + standbyDelegates: formatDelegates(standby), + voters: voters.length.toLocaleString(undefined, { + maximumFractionDigits: 0, + }), + supply: (supply / 1e8).toLocaleString(undefined, { + maximumFractionDigits: 0, + }), + totalVotes: (totalVotes / 1e8).toLocaleString(undefined, { + maximumFractionDigits: 0, + }), + percentage: percentage.toLocaleString(undefined, { + minimumFractionDigits: 2, + maximumFractionDigits: 2, + }), + }) + .type('text/plain') +} diff --git a/packages/core-vote-report/lib/index.js b/packages/core-vote-report/lib/index.js new file mode 100644 index 0000000000..bb3c13089c --- /dev/null +++ b/packages/core-vote-report/lib/index.js @@ -0,0 +1,11 @@ +exports.plugin = { + pkg: require('../package.json'), + defaults: require('./defaults'), + alias: 'vote-report', + async register(container, options) { + return require('./server')(options) + }, + async deregister(container, options) { + return container.resolvePlugin('vote-report').stop() + }, +} diff --git a/packages/core-vote-report/lib/server.js b/packages/core-vote-report/lib/server.js new file mode 100644 index 0000000000..053ed03fa7 --- /dev/null +++ b/packages/core-vote-report/lib/server.js @@ -0,0 +1,25 @@ +const Handlebars = require('handlebars') +const { createServer, mountServer } = require('@arkecosystem/core-http-utils') + +module.exports = async config => { + const server = await createServer( + { + host: config.host, + port: config.port, + }, + instance => + instance.views({ + engines: { html: Handlebars }, + relativeTo: __dirname, + path: 'templates', + }), + ) + + server.route({ + method: 'GET', + path: '/', + handler: require('./handler'), + }) + + return mountServer('Vote Report', server) +} diff --git a/packages/core-vote-report/lib/templates/index.html b/packages/core-vote-report/lib/templates/index.html new file mode 100644 index 0000000000..2215808eff --- /dev/null +++ b/packages/core-vote-report/lib/templates/index.html @@ -0,0 +1,18 @@ +Top {{activeDelegatesCount}} Delegates Stats + +=> Total Votes : {{percentage}}% ({{totalVotes}} / {{supply}}) +=> Total Voters : {{voters}} (only voters with more than 0.1 {{client.symbol}}) + +=================================================================== +| Rank | Delegate | Vote % | {{voteHeader}} | Voters | +=================================================================== +{{#each activeDelegates}} +| {{rank}} | {{username}} | {{approval}} | {{votes}} | {{voterCount}} | +{{/each}} +=================================================================== +{{#if standbyDelegates}} +{{#each standbyDelegates}} +| {{rank}} | {{username}} | {{approval}} | {{votes}} | {{voterCount}} | +{{/each}} +=================================================================== +{{/if}} diff --git a/packages/core-vote-report/package.json b/packages/core-vote-report/package.json new file mode 100644 index 0000000000..f473916b81 --- /dev/null +++ b/packages/core-vote-report/package.json @@ -0,0 +1,34 @@ +{ + "name": "@arkecosystem/core-vote-report", + "description": "Vote Report for Ark Core", + "version": "0.2.0", + "contributors": [ + "Brian Faust " + ], + "license": "MIT", + "main": "lib/index.js", + "scripts": { + "test": "cross-env ARK_ENV=test jest --runInBand --detectOpenHandles", + "test:coverage": "cross-env ARK_ENV=test jest --coverage --coveragePathIgnorePatterns='/(defaults.js|index.js)$' --runInBand --detectOpenHandles", + "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand", + "test:watch": "cross-env ARK_ENV=test jest --runInBand --watch", + "test:watch:all": "cross-env ARK_ENV=test jest --runInBand --watchAll", + "lint": "eslint ./ --fix", + "depcheck": "depcheck ./ --ignores=lodash,lodash.*" + }, + "dependencies": { + "@arkecosystem/core-container": "~0.2", + "@arkecosystem/core-http-utils": "~0.2", + "@arkecosystem/core-utils": "~0.2", + "@arkecosystem/crypto": "~0.2", + "handlebars": "^4.0.12", + "lodash.clonedeepwith": "^4.5.0", + "lodash.sumby": "^4.6.0" + }, + "publishConfig": { + "access": "public" + }, + "engines": { + "node": ">=10.x" + } +} diff --git a/packages/core-webhooks/CHANGELOG.md b/packages/core-webhooks/CHANGELOG.md index 127cc35e42..b98550ed95 100644 --- a/packages/core-webhooks/CHANGELOG.md +++ b/packages/core-webhooks/CHANGELOG.md @@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Unreleased -## 0.0.1 - 2018-05-31 +## 0.2.0 - 2018-12-03 + +### Changed + +- Instantly execute webhook jobs instead of queueing a job +- Dropped node.js 9 as minimum requirement in favour of node.js 10 + +### Fixed + +- Properly listen for all events +- Properly check for enabled webhooks + +## 0.1.1 - 2018-06-14 + ### Added + - initial release diff --git a/packages/core-webhooks/README.md b/packages/core-webhooks/README.md index c087519bd7..5794bd4144 100644 --- a/packages/core-webhooks/README.md +++ b/packages/core-webhooks/README.md @@ -1,41 +1,12 @@ -![ARK Core](https://i.imgur.com/1aP6F2o.png) - -# ARK Core - Webhooks - -## Installation - -```bash -yarn add @arkecosystem/core-webhooks -``` - -## Configuration - -```js -module.exports = { - enabled: !process.env.ARK_WEBHOOKS_DISABLED, - database: { - dialect: 'sqlite', - storage: `${process.env.ARK_PATH_DATA}/database/webhooks.sqlite`, - logging: process.env.ARK_DB_LOGGING - }, - redis: { - host: process.env.ARK_REDIS_HOST || 'localhost', - port: process.env.ARK_REDIS_PORT || 6379 - }, - server: { - enabled: process.env.ARK_WEBHOOKS_API_ENABLED, - host: process.env.ARK_WEBHOOKS_HOST || '0.0.0.0', - port: process.env.ARK_WEBHOOKS_PORT || 4004, - whitelist: ['127.0.0.1', '::ffff:127.0.0.1', '192.168.*'], - pagination: { - limit: 100, - include: [ - '/api/webhooks' - ] - } - } -} -``` +# Ark Core - Webhooks + +

+ +

+ +## Documentation + +You can find installation instructions and detailed instructions on how to use this package at the [dedicated documentation site](https://docs.ark.io/guidebook/core/plugins/core-webhooks.html). ## Security diff --git a/packages/core-webhooks/__tests__/__support__/setup.js b/packages/core-webhooks/__tests__/__support__/setup.js index 578141185f..d43ef14109 100644 --- a/packages/core-webhooks/__tests__/__support__/setup.js +++ b/packages/core-webhooks/__tests__/__support__/setup.js @@ -1,48 +1,33 @@ -'use strict' - -const path = require('path') -const container = require('@arkecosystem/core-container') +const app = require('@arkecosystem/core-container') +const appHelper = require('@arkecosystem/core-test-utils/lib/helpers/container') jest.setTimeout(60000) exports.setUp = async () => { process.env.ARK_WEBHOOKS_ENABLED = true - await container.setUp({ - data: '~/.ark', - config: path.resolve(__dirname, '../../../core/lib/config/testnet'), - token: 'ark', - network: 'testnet' - }, { + await appHelper.setUp({ exclude: [ - '@arkecosystem/core-blockchain', '@arkecosystem/core-api', '@arkecosystem/core-graphql', - '@arkecosystem/core-forger' - ] + '@arkecosystem/core-forger', + ], }) - await require('../../lib/manager').setUp({ - redis: { - host: process.env.ARK_REDIS_HOST || 'localhost', - port: process.env.ARK_REDIS_PORT || 6379 - } - }) + await require('../../lib/manager').setUp({}) await require('../../lib/server')({ enabled: false, host: process.env.ARK_WEBHOOKS_HOST || '0.0.0.0', port: process.env.ARK_WEBHOOKS_PORT || 4004, - whitelist: ['127.0.0.1', '::ffff:127.0.0.1', '192.168.*'], + whitelist: ['127.0.0.1', '::ffff:127.0.0.1'], pagination: { limit: 100, - include: [ - '/api/webhooks' - ] - } + include: ['/api/webhooks'], + }, }) } exports.tearDown = async () => { - await container.tearDown() + await app.tearDown() } diff --git a/packages/core-webhooks/__tests__/conditions/between.test.js b/packages/core-webhooks/__tests__/conditions/between.test.js new file mode 100644 index 0000000000..3543590539 --- /dev/null +++ b/packages/core-webhooks/__tests__/conditions/between.test.js @@ -0,0 +1,21 @@ +const condition = require('../../lib/conditions/between') + +describe('Conditions - between', () => { + it('should be true', () => { + expect( + condition(1.5, { + min: 1, + max: 2, + }), + ).toBeTrue() + }) + + it('should be false', () => { + expect( + condition(3, { + min: 1, + max: 2, + }), + ).toBeFalse() + }) +}) diff --git a/packages/core-webhooks/__tests__/conditions/contains.test.js b/packages/core-webhooks/__tests__/conditions/contains.test.js new file mode 100644 index 0000000000..5de1ef8bb7 --- /dev/null +++ b/packages/core-webhooks/__tests__/conditions/contains.test.js @@ -0,0 +1,11 @@ +const condition = require('../../lib/conditions/contains') + +describe('Conditions - contains', () => { + it('should be true', () => { + expect(condition('Hello World', 'Hello')).toBeTrue() + }) + + it('should be false', () => { + expect(condition('Hello World', 'invalid')).toBeFalse() + }) +}) diff --git a/packages/core-webhooks/__tests__/conditions/eq.test.js b/packages/core-webhooks/__tests__/conditions/eq.test.js new file mode 100644 index 0000000000..fc637ce423 --- /dev/null +++ b/packages/core-webhooks/__tests__/conditions/eq.test.js @@ -0,0 +1,11 @@ +const condition = require('../../lib/conditions/eq') + +describe('Conditions - equal', () => { + it('should be true', () => { + expect(condition(1, 1)).toBeTrue() + }) + + it('should be false', () => { + expect(condition(1, 2)).toBeFalse() + }) +}) diff --git a/packages/core-webhooks/__tests__/conditions/falsy.test.js b/packages/core-webhooks/__tests__/conditions/falsy.test.js new file mode 100644 index 0000000000..1458dc3833 --- /dev/null +++ b/packages/core-webhooks/__tests__/conditions/falsy.test.js @@ -0,0 +1,11 @@ +const condition = require('../../lib/conditions/falsy') + +describe('Conditions - falsy', () => { + it('should be true', () => { + expect(condition(false)).toBeTrue() + }) + + it('should be false', () => { + expect(condition(true)).toBeFalse() + }) +}) diff --git a/packages/core-webhooks/__tests__/conditions/gt.test.js b/packages/core-webhooks/__tests__/conditions/gt.test.js new file mode 100644 index 0000000000..681b9e6114 --- /dev/null +++ b/packages/core-webhooks/__tests__/conditions/gt.test.js @@ -0,0 +1,11 @@ +const condition = require('../../lib/conditions/gt') + +describe('Conditions - greater than', () => { + it('should be true', () => { + expect(condition(2, 1)).toBeTrue() + }) + + it('should be false', () => { + expect(condition(1, 2)).toBeFalse() + }) +}) diff --git a/packages/core-webhooks/__tests__/conditions/gte.test.js b/packages/core-webhooks/__tests__/conditions/gte.test.js new file mode 100644 index 0000000000..f80a98f970 --- /dev/null +++ b/packages/core-webhooks/__tests__/conditions/gte.test.js @@ -0,0 +1,12 @@ +const condition = require('../../lib/conditions/gte') + +describe('Conditions - greater than or equal', () => { + it('should be true', () => { + expect(condition(2, 1)).toBeTrue() + expect(condition(2, 2)).toBeTrue() + }) + + it('should be false', () => { + expect(condition(1, 2)).toBeFalse() + }) +}) diff --git a/packages/core-webhooks/__tests__/conditions/lt.test.js b/packages/core-webhooks/__tests__/conditions/lt.test.js new file mode 100644 index 0000000000..f269dd2bba --- /dev/null +++ b/packages/core-webhooks/__tests__/conditions/lt.test.js @@ -0,0 +1,11 @@ +const condition = require('../../lib/conditions/lt') + +describe('Conditions - less than', () => { + it('should be true', () => { + expect(condition(1, 2)).toBeTrue() + }) + + it('should be false', () => { + expect(condition(2, 1)).toBeFalse() + }) +}) diff --git a/packages/core-webhooks/__tests__/conditions/lte.test.js b/packages/core-webhooks/__tests__/conditions/lte.test.js new file mode 100644 index 0000000000..1fdc49b256 --- /dev/null +++ b/packages/core-webhooks/__tests__/conditions/lte.test.js @@ -0,0 +1,12 @@ +const condition = require('../../lib/conditions/lte') + +describe('Conditions - less than or equal', () => { + it('should be true', () => { + expect(condition(1, 2)).toBeTrue() + expect(condition(1, 1)).toBeTrue() + }) + + it('should be false', () => { + expect(condition(2, 1)).toBeFalse() + }) +}) diff --git a/packages/core-webhooks/__tests__/conditions/ne.test.js b/packages/core-webhooks/__tests__/conditions/ne.test.js new file mode 100644 index 0000000000..b220b168fb --- /dev/null +++ b/packages/core-webhooks/__tests__/conditions/ne.test.js @@ -0,0 +1,11 @@ +const condition = require('../../lib/conditions/ne') + +describe('Conditions - not equal', () => { + it('should be true', () => { + expect(condition(1, 2)).toBeTrue() + }) + + it('should be false', () => { + expect(condition(1, 1)).toBeFalse() + }) +}) diff --git a/packages/core-webhooks/__tests__/conditions/not-between.test.js b/packages/core-webhooks/__tests__/conditions/not-between.test.js new file mode 100644 index 0000000000..f275d4a62b --- /dev/null +++ b/packages/core-webhooks/__tests__/conditions/not-between.test.js @@ -0,0 +1,21 @@ +const condition = require('../../lib/conditions/not-between') + +describe('Conditions - not-between', () => { + it('should be true', () => { + expect( + condition(3, { + min: 1, + max: 2, + }), + ).toBeTrue() + }) + + it('should be false', () => { + expect( + condition(1.5, { + min: 1, + max: 2, + }), + ).toBeFalse() + }) +}) diff --git a/packages/core-webhooks/__tests__/conditions/regexp.test.js b/packages/core-webhooks/__tests__/conditions/regexp.test.js new file mode 100644 index 0000000000..6cbee84c35 --- /dev/null +++ b/packages/core-webhooks/__tests__/conditions/regexp.test.js @@ -0,0 +1,11 @@ +const condition = require('../../lib/conditions/regexp') + +describe('Conditions - regexp', () => { + it('should be true', () => { + expect(condition('hello world!', 'hello')).toBeTrue() + }) + + it('should be false', () => { + expect(condition(123, 'w+')).toBeFalse() + }) +}) diff --git a/packages/core-webhooks/__tests__/conditions/truthy.test.js b/packages/core-webhooks/__tests__/conditions/truthy.test.js new file mode 100644 index 0000000000..a67dd0224c --- /dev/null +++ b/packages/core-webhooks/__tests__/conditions/truthy.test.js @@ -0,0 +1,11 @@ +const condition = require('../../lib/conditions/truthy') + +describe('Conditions - truthy', () => { + it('should be true', () => { + expect(condition(true)).toBeTrue() + }) + + it('should be false', () => { + expect(condition(false)).toBeFalse() + }) +}) diff --git a/packages/core-webhooks/__tests__/api/handler.test.js b/packages/core-webhooks/__tests__/server/handler.test.js similarity index 51% rename from packages/core-webhooks/__tests__/api/handler.test.js rename to packages/core-webhooks/__tests__/server/handler.test.js index b19c6d3458..08a03130bf 100644 --- a/packages/core-webhooks/__tests__/api/handler.test.js +++ b/packages/core-webhooks/__tests__/server/handler.test.js @@ -1,5 +1,3 @@ -'use strict' - const app = require('../__support__/setup') const utils = require('./utils') @@ -15,19 +13,22 @@ const postData = { event: 'block.forged', target: 'https://httpbin.org/post', enabled: true, - conditions: [{ - key: 'generatorPublicKey', - condition: 'eq', - value: 'test-generator' - }, { - key: 'fee', - condition: 'gte', - value: '123' - }] + conditions: [ + { + key: 'generatorPublicKey', + condition: 'eq', + value: 'test-generator', + }, + { + key: 'fee', + condition: 'gte', + value: '123', + }, + ], } -function createWebhook () { - return utils.request('POST', 'webhooks', postData) +function createWebhook(data = null) { + return utils.request('POST', 'webhooks', data || postData) } describe('API 2.0 - Webhooks', () => { @@ -40,23 +41,48 @@ describe('API 2.0 - Webhooks', () => { }) describe('POST /webhooks', () => { - it('should POST a new webhook', async () => { + it('should POST a new webhook with a simple condition', async () => { const response = await createWebhook() utils.expectSuccessful(response, 201) utils.expectResource(response) }) + + it('should POST a new webhook with a complex condition', async () => { + const response = await createWebhook({ + event: 'block.forged', + target: 'https://httpbin.org/post', + enabled: true, + conditions: [ + { + key: 'fee', + condition: 'between', + value: { + min: 1, + max: 2, + }, + }, + ], + }) + utils.expectSuccessful(response, 201) + utils.expectResource(response) + }) }) describe('GET /webhooks/{id}', () => { it('should GET a webhook by the given id', async () => { const webhook = await createWebhook() - const response = await utils.request('GET', `webhooks/${webhook.data.data.id}`) + const response = await utils.request( + 'GET', + `webhooks/${webhook.data.data.id}`, + ) utils.expectSuccessful(response) utils.expectResource(response) const { data } = response.data - const webhookData = Object.assign(webhook.data.data, { token: data.token.substring(0, 32) }) + const webhookData = Object.assign(webhook.data.data, { + token: data.token.substring(0, 32), + }) expect(data).toEqual(webhookData) }) }) @@ -65,7 +91,11 @@ describe('API 2.0 - Webhooks', () => { it('should PUT a webhook by the given id', async () => { const webhook = await createWebhook() - const response = await utils.request('PUT', `webhooks/${webhook.data.data.id}`, postData) + const response = await utils.request( + 'PUT', + `webhooks/${webhook.data.data.id}`, + postData, + ) utils.expectStatus(response, 204) }) }) @@ -74,7 +104,10 @@ describe('API 2.0 - Webhooks', () => { it('should DELETE a webhook by the given id', async () => { const webhook = await createWebhook() - const response = await utils.request('DELETE', `webhooks/${webhook.data.data.id}`) + const response = await utils.request( + 'DELETE', + `webhooks/${webhook.data.data.id}`, + ) utils.expectStatus(response, 204) }) }) diff --git a/packages/core-webhooks/__tests__/api/utils.js b/packages/core-webhooks/__tests__/server/utils.js similarity index 80% rename from packages/core-webhooks/__tests__/api/utils.js rename to packages/core-webhooks/__tests__/server/utils.js index 4ea4b0ad57..b558d5826f 100644 --- a/packages/core-webhooks/__tests__/api/utils.js +++ b/packages/core-webhooks/__tests__/server/utils.js @@ -1,9 +1,7 @@ -'use strict' - const axios = require('axios') class Helpers { - request (method, path, params = {}) { + request(method, path, params = {}) { const url = `http://localhost:4004/api/${path}` const request = axios[method.toLowerCase()] @@ -12,22 +10,23 @@ class Helpers { : request(url, params) } - expectJson (response) { + expectJson(response) { expect(response.data).toBeObject() } - expectStatus (response, code) { + expectStatus(response, code) { expect(response.status).toBe(code) } - expectResource (response) { + + expectResource(response) { expect(response.data.data).toBeObject() } - expectCollection (response) { + expectCollection(response) { expect(Array.isArray(response.data.data)).toBe(true) } - expectPaginator (response, firstPage = true) { + expectPaginator(response, firstPage = true) { expect(response.data.meta).toBeObject() expect(response.data.meta).toHaveProperty('count') expect(response.data.meta).toHaveProperty('pageCount') @@ -39,12 +38,12 @@ class Helpers { expect(response.data.meta).toHaveProperty('last') } - expectSuccessful (response, statusCode = 200) { + expectSuccessful(response, statusCode = 200) { this.expectStatus(response, statusCode) this.expectJson(response) } - expectError (response, statusCode = 404) { + expectError(response, statusCode = 404) { this.expectStatus(response, statusCode) this.expectJson(response) expect(response.data.statusCode).toBeInteger() diff --git a/packages/core-webhooks/jest.config.js b/packages/core-webhooks/jest.config.js index 6707392d08..57770a97bb 100644 --- a/packages/core-webhooks/jest.config.js +++ b/packages/core-webhooks/jest.config.js @@ -1,21 +1,12 @@ -'use strict' module.exports = { testEnvironment: 'node', bail: false, verbose: true, - testMatch: [ - '**/__tests__/**/*.test.js' - ], - moduleFileExtensions: [ - 'js', - 'json' - ], + testMatch: ['**/__tests__/**/*.test.js'], + moduleFileExtensions: ['js', 'json'], collectCoverage: false, coverageDirectory: '/.coverage', - collectCoverageFrom: [ - 'lib/**/*.js', - '!**/node_modules/**' - ], + collectCoverageFrom: ['lib/**/*.js', '!**/node_modules/**'], watchman: false, - setupTestFrameworkScriptFile: 'jest-extended' + setupTestFrameworkScriptFile: 'jest-extended', } diff --git a/packages/core-webhooks/jsdoc.json b/packages/core-webhooks/jsdoc.json index 23276f74ea..f3ea8aab33 100644 --- a/packages/core-webhooks/jsdoc.json +++ b/packages/core-webhooks/jsdoc.json @@ -7,9 +7,7 @@ "includePattern": ".js$", "excludePattern": "(node_modules/|docs)" }, - "plugins": [ - "plugins/markdown" - ], + "plugins": ["plugins/markdown"], "opts": { "template": "../../node_modules/docdash", "encoding": "utf8", diff --git a/packages/core-webhooks/lib/conditions/between.js b/packages/core-webhooks/lib/conditions/between.js index f112ddcef8..ec8371b8e3 100644 --- a/packages/core-webhooks/lib/conditions/between.js +++ b/packages/core-webhooks/lib/conditions/between.js @@ -1,10 +1,7 @@ -'use strict' - /** * Check if the given value is between min and max. - * @param {Number} input - * @param {Number} min - * @param {Number} max + * @param {*} actual + * @param {*} expected * @return {Boolean} */ -module.exports = (input, min, max) => (input > min && input < max) +module.exports = (actual, expected) => actual > expected.min && actual < expected.max diff --git a/packages/core-webhooks/lib/conditions/contains.js b/packages/core-webhooks/lib/conditions/contains.js index cd1651eeea..bda6d138ae 100644 --- a/packages/core-webhooks/lib/conditions/contains.js +++ b/packages/core-webhooks/lib/conditions/contains.js @@ -1,9 +1,7 @@ -'use strict' - /** * Check if A contains B. - * @param {*} a - * @param {*} b + * @param {*} actual + * @param {*} expected * @return {Boolean} */ -module.exports = (a, b) => (a.includes(b)) +module.exports = (actual, expected) => actual.includes(expected) diff --git a/packages/core-webhooks/lib/conditions/eq.js b/packages/core-webhooks/lib/conditions/eq.js index 1177a81fe9..d528558f50 100644 --- a/packages/core-webhooks/lib/conditions/eq.js +++ b/packages/core-webhooks/lib/conditions/eq.js @@ -1,9 +1,7 @@ -'use strict' - /** * Check if A equals B. - * @param {*} a - * @param {*} b + * @param {Number} actual + * @param {Number} expected * @return {Boolean} */ -module.exports = (a, b) => (a === b) +module.exports = (actual, expected) => actual === expected diff --git a/packages/core-webhooks/lib/conditions/falsy.js b/packages/core-webhooks/lib/conditions/falsy.js index d205056a93..8cf3018961 100644 --- a/packages/core-webhooks/lib/conditions/falsy.js +++ b/packages/core-webhooks/lib/conditions/falsy.js @@ -1,8 +1,6 @@ -'use strict' - /** * Check if the given value is false. - * @param {*} value + * @param {*} actual * @return {Boolean} */ -module.exports = (value) => (value === false) +module.exports = actual => actual === false diff --git a/packages/core-webhooks/lib/conditions/gt.js b/packages/core-webhooks/lib/conditions/gt.js index 1792c2fab8..cedc3d2f02 100644 --- a/packages/core-webhooks/lib/conditions/gt.js +++ b/packages/core-webhooks/lib/conditions/gt.js @@ -1,9 +1,7 @@ -'use strict' - /** * Check if A is greater than B. - * @param {Number} a - * @param {Number} b + * @param {Number} actual + * @param {Number} expected * @return {Boolean} */ -module.exports = (a, b) => (a > b) +module.exports = (actual, expected) => actual > expected diff --git a/packages/core-webhooks/lib/conditions/gte.js b/packages/core-webhooks/lib/conditions/gte.js index e9a976d4c2..9b37bd9524 100644 --- a/packages/core-webhooks/lib/conditions/gte.js +++ b/packages/core-webhooks/lib/conditions/gte.js @@ -1,9 +1,7 @@ -'use strict' - /** * Check if A is greater than or equal to B. - * @param {Number} a - * @param {Number} b + * @param {Number} actual + * @param {Number} expected * @return {Boolean} */ -module.exports = (a, b) => (a >= b) +module.exports = (actual, expected) => actual >= expected diff --git a/packages/core-webhooks/lib/conditions/lt.js b/packages/core-webhooks/lib/conditions/lt.js index 946a595440..0fade24ca2 100644 --- a/packages/core-webhooks/lib/conditions/lt.js +++ b/packages/core-webhooks/lib/conditions/lt.js @@ -1,9 +1,7 @@ -'use strict' - /** * Check if A is lesser than B. - * @param {Number} a - * @param {Number} b + * @param {Number} actual + * @param {Number} expected * @return {Boolean} */ -module.exports = (a, b) => (a < b) +module.exports = (actual, expected) => actual < expected diff --git a/packages/core-webhooks/lib/conditions/lte.js b/packages/core-webhooks/lib/conditions/lte.js index 08c914d11c..3ed5e2d525 100644 --- a/packages/core-webhooks/lib/conditions/lte.js +++ b/packages/core-webhooks/lib/conditions/lte.js @@ -1,9 +1,7 @@ -'use strict' - /** * Check if A is lesser than or equal to B. - * @param {*} a - * @param {*} b + * @param {Number} actual + * @param {Number} expected * @return {Boolean} */ -module.exports = (a, b) => (a <= b) +module.exports = (actual, expected) => actual <= expected diff --git a/packages/core-webhooks/lib/conditions/ne.js b/packages/core-webhooks/lib/conditions/ne.js index 5b3f1a627e..e19b931d00 100644 --- a/packages/core-webhooks/lib/conditions/ne.js +++ b/packages/core-webhooks/lib/conditions/ne.js @@ -1,9 +1,7 @@ -'use strict' - /** * Check if A does not equal B. - * @param {*} a - * @param {*} b + * @param {Number} actual + * @param {Number} expected * @return {Boolean} */ -module.exports = (a, b) => (a !== b) +module.exports = (actual, expected) => actual !== expected diff --git a/packages/core-webhooks/lib/conditions/not-between.js b/packages/core-webhooks/lib/conditions/not-between.js index 602564615e..8e81b2e587 100644 --- a/packages/core-webhooks/lib/conditions/not-between.js +++ b/packages/core-webhooks/lib/conditions/not-between.js @@ -1,12 +1,9 @@ -'use strict' - const between = require('./between') /** * Check if the given value is not between min and max. - * @param {Number} input - * @param {Number} min - * @param {Number} max + * @param {Number} actual + * @param {Number} expected * @return {Boolean} */ -module.exports = (input, min, max) => (!between(input, min, max)) +module.exports = (actual, expected) => !between(actual, expected) diff --git a/packages/core-webhooks/lib/conditions/regexp.js b/packages/core-webhooks/lib/conditions/regexp.js index 19e9260afd..8abc454110 100644 --- a/packages/core-webhooks/lib/conditions/regexp.js +++ b/packages/core-webhooks/lib/conditions/regexp.js @@ -1,9 +1,7 @@ -'use strict' - /** * Check if the given value matches. - * @param {*} input - * @param {String} pattern + * @param {*} actual + * @param {String} expected * @return {Boolean} */ -module.exports = (input, pattern) => (new RegExp(pattern).test(input)) +module.exports = (actual, expected) => new RegExp(expected).test(actual) diff --git a/packages/core-webhooks/lib/conditions/truthy.js b/packages/core-webhooks/lib/conditions/truthy.js index 72a65c8027..1ac9e49daf 100644 --- a/packages/core-webhooks/lib/conditions/truthy.js +++ b/packages/core-webhooks/lib/conditions/truthy.js @@ -1,8 +1,6 @@ -'use strict' - /** * Check if the given value is true. - * @param {*} value + * @param {*} actual * @return {Boolean} */ -module.exports = (value) => (value === true) +module.exports = actual => actual === true diff --git a/packages/core-webhooks/lib/database/index.js b/packages/core-webhooks/lib/database/index.js index 0da060b331..d640fa54cd 100644 --- a/packages/core-webhooks/lib/database/index.js +++ b/packages/core-webhooks/lib/database/index.js @@ -1,11 +1,10 @@ -'use strict' - const Sequelize = require('sequelize') + const Op = Sequelize.Op const Umzug = require('umzug') const path = require('path') const fs = require('fs-extra') -const logger = require('@arkecosystem/core-container').resolvePlugin('logger') +const app = require('@arkecosystem/core-container') class Database { /** @@ -13,7 +12,7 @@ class Database { * @param {Object} config * @return {void} */ - async setUp (config) { + async setUp(config) { if (this.connection) { throw new Error('Webhooks database already initialised') } @@ -24,7 +23,7 @@ class Database { this.connection = new Sequelize({ ...config, - ...{ operatorsAliases: Op } + ...{ operatorsAliases: Op }, }) try { @@ -32,9 +31,7 @@ class Database { await this.__runMigrations() await this.__registerModels() } catch (error) { - logger.error('Unable to connect to the database', error.stack) - // TODO no exit here? - process.exit(1) + app.forceExit('Unable to connect to the database!', error) } } @@ -43,7 +40,7 @@ class Database { * @param {Object} params * @return {Object} */ - paginate (params) { + paginate(params) { return this.model.findAndCountAll(params) } @@ -52,7 +49,7 @@ class Database { * @param {Number} id * @return {Object} */ - findById (id) { + findById(id) { return this.model.findById(id) } @@ -61,8 +58,8 @@ class Database { * @param {String} event * @return {Array} */ - findByEvent (event) { - return this.model.findAll({ where: {event} }) + findByEvent(event) { + return this.model.findAll({ where: { event } }) } /** @@ -70,7 +67,7 @@ class Database { * @param {Object} data * @return {Object} */ - create (data) { + create(data) { return this.model.create(data) } @@ -80,7 +77,7 @@ class Database { * @param {Object} data * @return {Boolean} */ - async update (id, data) { + async update(id, data) { try { const webhook = await this.model.findById(id) @@ -97,9 +94,9 @@ class Database { * @param {Number} id * @return {Boolean} */ - async destroy (id) { + async destroy(id) { try { - const webhook = this.model.findById(id) + const webhook = await this.model.findById(id) webhook.destroy() @@ -113,19 +110,16 @@ class Database { * Run all migrations. * @return {Boolean} */ - __runMigrations () { + __runMigrations() { const umzug = new Umzug({ storage: 'sequelize', storageOptions: { - sequelize: this.connection + sequelize: this.connection, }, migrations: { - params: [ - this.connection.getQueryInterface(), - Sequelize - ], - path: path.join(__dirname, 'migrations') - } + params: [this.connection.getQueryInterface(), Sequelize], + path: path.join(__dirname, 'migrations'), + }, }) return umzug.up() @@ -135,8 +129,8 @@ class Database { * Register all models. * @return {void} */ - __registerModels () { - this.model = this.connection['import']('./model') + __registerModels() { + this.model = this.connection.import('./model') } } diff --git a/packages/core-webhooks/lib/database/migrations/20180305163843-create-webhook.js b/packages/core-webhooks/lib/database/migrations/20180305163843-create-webhook.js index ecc10e001e..b48e612516 100644 --- a/packages/core-webhooks/lib/database/migrations/20180305163843-create-webhook.js +++ b/packages/core-webhooks/lib/database/migrations/20180305163843-create-webhook.js @@ -1,5 +1,3 @@ -'use strict' - /** * The webhooks migration. * @type {Object} @@ -11,30 +9,30 @@ module.exports = { * @param {Sequelize} Sequelize * @return {void} */ - async up (queryInterface, Sequelize) { + async up(queryInterface, Sequelize) { await queryInterface.createTable('webhooks', { id: { allowNull: false, autoIncrement: true, primaryKey: true, - type: Sequelize.INTEGER + type: Sequelize.INTEGER, }, event: Sequelize.STRING, target: Sequelize.STRING, conditions: Sequelize.JSON, token: { unique: true, - type: Sequelize.STRING + type: Sequelize.STRING, }, enabled: Sequelize.BOOLEAN, createdAt: { allowNull: false, - type: Sequelize.DATE + type: Sequelize.DATE, }, updatedAt: { allowNull: false, - type: Sequelize.DATE - } + type: Sequelize.DATE, + }, }) queryInterface.addIndex('webhooks', ['event']) @@ -45,7 +43,7 @@ module.exports = { * @param {Sequelize} Sequelize * @return {void} */ - async down (queryInterface, Sequelize) { + async down(queryInterface, Sequelize) { return queryInterface.dropTable('webhooks') - } + }, } diff --git a/packages/core-webhooks/lib/database/model.js b/packages/core-webhooks/lib/database/model.js index d1dab74d74..eeebd70a6d 100644 --- a/packages/core-webhooks/lib/database/model.js +++ b/packages/core-webhooks/lib/database/model.js @@ -1,5 +1,3 @@ -'use strict' - /** * Define the webhook model. * @param {Sequelize} sequelize @@ -7,22 +5,26 @@ * @return {Sequelize.Model} */ module.exports = (sequelize, DataTypes) => { - const Webhook = sequelize.define('webhook', { - id: { - allowNull: false, - autoIncrement: true, - primaryKey: true, - type: DataTypes.INTEGER - }, - event: DataTypes.STRING, - target: DataTypes.STRING, - conditions: DataTypes.JSON, - token: { - unique: true, - type: DataTypes.STRING + const Webhook = sequelize.define( + 'webhook', + { + id: { + allowNull: false, + autoIncrement: true, + primaryKey: true, + type: DataTypes.INTEGER, + }, + event: DataTypes.STRING, + target: DataTypes.STRING, + conditions: DataTypes.JSON, + token: { + unique: true, + type: DataTypes.STRING, + }, + enabled: DataTypes.BOOLEAN, }, - enabled: DataTypes.BOOLEAN - }, {}) + {}, + ) return Webhook } diff --git a/packages/core-webhooks/lib/defaults.js b/packages/core-webhooks/lib/defaults.js index 182079c95d..df0167a8f5 100644 --- a/packages/core-webhooks/lib/defaults.js +++ b/packages/core-webhooks/lib/defaults.js @@ -1,26 +1,18 @@ -'use strict' - module.exports = { enabled: process.env.ARK_WEBHOOKS_ENABLED, database: { dialect: 'sqlite', storage: `${process.env.ARK_PATH_DATA}/database/webhooks.sqlite`, - logging: process.env.ARK_DB_LOGGING - }, - redis: { - host: process.env.ARK_REDIS_HOST || 'localhost', - port: process.env.ARK_REDIS_PORT || 6379 + logging: process.env.ARK_DB_LOGGING, }, server: { enabled: process.env.ARK_WEBHOOKS_API_ENABLED, host: process.env.ARK_WEBHOOKS_HOST || '0.0.0.0', port: process.env.ARK_WEBHOOKS_PORT || 4004, - whitelist: ['127.0.0.1', '::ffff:127.0.0.1', '192.168.*'], + whitelist: ['127.0.0.1', '::ffff:127.0.0.1'], pagination: { limit: 100, - include: [ - '/api/webhooks' - ] - } - } + include: ['/api/webhooks'], + }, + }, } diff --git a/packages/core-webhooks/lib/index.js b/packages/core-webhooks/lib/index.js index 93e00825b1..c705495116 100644 --- a/packages/core-webhooks/lib/index.js +++ b/packages/core-webhooks/lib/index.js @@ -1,5 +1,3 @@ -'use strict' - const webhookManager = require('./manager') const database = require('./database') @@ -11,7 +9,7 @@ exports.plugin = { pkg: require('../package.json'), defaults: require('./defaults'), alias: 'webhooks', - async register (container, options) { + async register(container, options) { const logger = container.resolvePlugin('logger') if (!options.enabled) { @@ -30,11 +28,11 @@ exports.plugin = { logger.info('Webhooks API server is disabled :grey_exclamation:') }, - async deregister (container, options) { + async deregister(container, options) { if (options.server.enabled) { container.resolvePlugin('logger').info('Stopping Webhook API') return container.resolvePlugin('webhooks').stop() } - } + }, } diff --git a/packages/core-webhooks/lib/manager.js b/packages/core-webhooks/lib/manager.js index 7a59b763a4..4594d683cc 100644 --- a/packages/core-webhooks/lib/manager.js +++ b/packages/core-webhooks/lib/manager.js @@ -1,61 +1,55 @@ -'use strict' +/* eslint no-await-in-loop: "off" */ const axios = require('axios') -const Bull = require('bull') -const map = require('lodash/map') -const container = require('@arkecosystem/core-container') -const logger = container.resolvePlugin('logger') +const app = require('@arkecosystem/core-container') + +const logger = app.resolvePlugin('logger') const database = require('./database') -const emitter = container.resolvePlugin('event-emitter') + +const emitter = app.resolvePlugin('event-emitter') class WebhookManager { /** - * Set up the webhook container. + * Set up the webhook app. * @param {Object} config * @return {void} */ - async setUp (config) { + async setUp(config) { this.config = config - await this.__registerQueue() - - map(this.config.events, 'name').forEach(event => { + for (const event of app.resolvePlugin('blockchain').getEvents()) { emitter.on(event, async payload => { const webhooks = await database.findByEvent(event) - this - .getMatchingWebhooks(webhooks, payload) - .forEach(webhook => this.queue.add({ webhook, payload })) - }) - }) - - this.queue.process(async (job) => { - try { - const response = await axios.post(job.data.webhook.target, { - timestamp: +new Date(), - data: job.data.payload, - event: job.data.webhook.event - }, { - headers: { - Authorization: job.data.webhook.token + for (const webhook of this.getMatchingWebhooks(webhooks, payload)) { + try { + const response = await axios.post( + webhook.target, + { + timestamp: +new Date(), + data: payload, + event: webhook.event, + }, + { + headers: { + Authorization: webhook.token, + }, + }, + ) + + logger.debug( + `Webhooks Job ${webhook.id} completed! Event [${ + webhook.event + }] has been transmitted to [${ + webhook.target + }] with a status of [${response.status}].`, + ) + } catch (error) { + logger.error(`Webhooks Job ${webhook.id} failed: ${error.message}`) } - }) - - return { - status: response.status, - headers: response.headers, - data: response.data } - } catch (error) { - logger.error(`Job ${job.id} failed: ${error.message}`) - } - }) - - this.queue.on('completed', (job, result) => { - logger.debug(`Webhooks Job ${job.id} completed! Event [${job.data.webhook.event}] has been transmitted to [${job.data.webhook.target}] with a status of [${result.status}].`) - - job.remove() - }) + }) + } } /** @@ -64,45 +58,33 @@ class WebhookManager { * @param {Object} payload * @return {Array} */ - getMatchingWebhooks (webhooks, payload) { + getMatchingWebhooks(webhooks, payload) { const matches = [] - webhooks.forEach(webhook => { + for (const webhook of webhooks) { + if (!webhook.enabled) { + continue + } + if (!webhook.conditions) { - webhooks.push(webhook) + matches.push(webhook) + + continue } - for (let condition of webhook.conditions) { + for (const condition of webhook.conditions) { const satisfies = require(`./conditions/${condition.condition}`) if (!satisfies(payload[condition.key], condition.value)) { - break + continue } matches.push(webhook) } - }) + } return matches } - - /** - * Get all webhook events. - * @return {Array} - */ - getEvents () { - return this.config.events - } - - /** - * Create a new redis queue instance. - * @return {void} - */ - __registerQueue () { - this.queue = new Bull('webhooks', { - redis: this.config.redis - }) - } } module.exports = new WebhookManager() diff --git a/packages/core-webhooks/lib/server/handler.js b/packages/core-webhooks/lib/server/handler.js index ddac724d59..ae31a1d454 100644 --- a/packages/core-webhooks/lib/server/handler.js +++ b/packages/core-webhooks/lib/server/handler.js @@ -1,5 +1,3 @@ -'use strict' - const database = require('../database') const utils = require('./utils') const schema = require('./schema') @@ -13,11 +11,11 @@ exports.index = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { + async handler(request, h) { const webhooks = await database.paginate(utils.paginate(request)) return utils.toPagination(request, webhooks, 'webhook') - } + }, } /** @@ -29,23 +27,27 @@ exports.store = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { - const token = require('crypto').randomBytes(32).toString('hex') + async handler(request, h) { + const token = require('crypto') + .randomBytes(32) + .toString('hex') request.payload.token = token.substring(0, 32) const webhook = await database.create(request.payload) webhook.token = token - return h.response(utils.respondWithResource(request, webhook, 'webhook')).code(201) + return h + .response(utils.respondWithResource(request, webhook, 'webhook')) + .code(201) }, options: { plugins: { pagination: { - enabled: false - } + enabled: false, + }, }, - validate: schema.store - } + validate: schema.store, + }, } /** @@ -57,15 +59,15 @@ exports.show = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { + async handler(request, h) { const webhook = await database.findById(request.params.id) delete webhook.token return utils.respondWithResource(request, webhook, 'webhook') }, options: { - validate: schema.show - } + validate: schema.show, + }, } /** @@ -77,14 +79,14 @@ exports.update = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { + async handler(request, h) { await database.update(request.params.id, request.payload) return h.response(null).code(204) }, options: { - validate: schema.update - } + validate: schema.update, + }, } /** @@ -96,12 +98,12 @@ exports.destroy = { * @param {Hapi.Toolkit} h * @return {Hapi.Response} */ - async handler (request, h) { + async handler(request, h) { await database.destroy(request.params.id, request.payload) return h.response(null).code(204) }, options: { - validate: schema.destroy - } + validate: schema.destroy, + }, } diff --git a/packages/core-webhooks/lib/server/index.js b/packages/core-webhooks/lib/server/index.js index 1aad890f13..244e2d992c 100644 --- a/packages/core-webhooks/lib/server/index.js +++ b/packages/core-webhooks/lib/server/index.js @@ -1,72 +1,62 @@ -'use strict' - -const Hapi = require('hapi') -const logger = require('@arkecosystem/core-container').resolvePlugin('logger') +const { + createServer, + mountServer, + plugins, +} = require('@arkecosystem/core-http-utils') /** * Creates a new hapi.js server. * @param {Object} config * @return {Hapi.Server} */ -module.exports = async (config) => { - const baseConfig = { +module.exports = async config => { + const server = await createServer({ host: config.host, port: config.port, routes: { cors: true, validate: { - async failAction (request, h, err) { - throw err - } - } - } - } - - const server = new Hapi.Server(baseConfig) + async failAction(request, h, err) { + throw err + }, + }, + }, + }) await server.register({ - plugin: require('./plugins/whitelist'), + plugin: plugins.whitelist, options: { - whitelist: config.whitelist - } + whitelist: config.whitelist, + name: 'Webhook API', + }, }) await server.register({ plugin: require('hapi-pagination'), options: { meta: { - baseUri: '' + baseUri: '', }, query: { limit: { - default: config.pagination.limit - } + default: config.pagination.limit, + }, }, results: { - name: 'data' + name: 'data', }, routes: { include: config.pagination.include, - exclude: ['*'] - } - } + exclude: ['*'], + }, + }, }) await server.register({ plugin: require('./routes'), routes: { prefix: '/api' }, - options: config + options: config, }) - try { - await server.start() - - logger.info(`Webhook API available and listening on ${server.info.uri}`) - - return server - } catch (error) { - logger.error(error.stack) - // TODO no exit here? - process.exit(1) - } + return mountServer('Webhook API', server) } diff --git a/packages/core-webhooks/lib/server/plugins/whitelist.js b/packages/core-webhooks/lib/server/plugins/whitelist.js deleted file mode 100644 index 927fab8491..0000000000 --- a/packages/core-webhooks/lib/server/plugins/whitelist.js +++ /dev/null @@ -1,43 +0,0 @@ -'use strict' - -const Boom = require('boom') -const requestIp = require('request-ip') -const mm = require('micromatch') -const container = require('@arkecosystem/core-container') - -/** - * The register method used by hapi.js. - * @param {Hapi.Server} server - * @param {Object} options - * @return {void} - */ -const register = async (server, options) => { - server.ext({ - type: 'onRequest', - async method (request, h) { - const remoteAddress = requestIp.getClientIp(request) - - for (let i = 0; i < options.whitelist.length; i++) { - if (mm.isMatch(remoteAddress, options.whitelist[i])) { - return h.continue - } - } - - container - .resolvePlugin('logger') - .warn(`${remoteAddress} tried to access the Webhooks API without being whitelisted :warning:`) - - return Boom.forbidden() - } - }) -} - -/** - * The struct used by hapi.js. - * @type {Object} - */ -exports.plugin = { - name: 'core-webhooks-whitelist', - version: '0.1.0', - register -} diff --git a/packages/core-webhooks/lib/server/routes.js b/packages/core-webhooks/lib/server/routes.js index a4761bc3be..6f7fe33535 100644 --- a/packages/core-webhooks/lib/server/routes.js +++ b/packages/core-webhooks/lib/server/routes.js @@ -1,5 +1,3 @@ -'use strict' - /** * Register webhook routes. * @param {Hapi.Server} server @@ -9,27 +7,33 @@ const register = async (server, options) => { const handler = require('./handler') - server.route([{ - method: 'GET', - path: '/webhooks', - ...handler.index - }, { - method: 'POST', - path: '/webhooks', - ...handler.store - }, { - method: 'GET', - path: '/webhooks/{id}', - ...handler.show - }, { - method: 'PUT', - path: '/webhooks/{id}', - ...handler.update - }, { - method: 'DELETE', - path: '/webhooks/{id}', - ...handler.destroy - }]) + server.route([ + { + method: 'GET', + path: '/webhooks', + ...handler.index, + }, + { + method: 'POST', + path: '/webhooks', + ...handler.store, + }, + { + method: 'GET', + path: '/webhooks/{id}', + ...handler.show, + }, + { + method: 'PUT', + path: '/webhooks/{id}', + ...handler.update, + }, + { + method: 'DELETE', + path: '/webhooks/{id}', + ...handler.destroy, + }, + ]) } /** @@ -37,7 +41,7 @@ const register = async (server, options) => { * @type {Object} */ exports.plugin = { - name: 'ARK Webhooks API', + name: 'Ark Webhooks API', version: '0.1.0', - register + register, } diff --git a/packages/core-webhooks/lib/server/schema.js b/packages/core-webhooks/lib/server/schema.js index 87319204f8..7dc51fe561 100644 --- a/packages/core-webhooks/lib/server/schema.js +++ b/packages/core-webhooks/lib/server/schema.js @@ -1,10 +1,18 @@ -'use strict' - const Joi = require('joi') const conditions = [ - 'between', 'contains', 'eq', 'falsy', 'gt', 'gte', - 'lt', 'lte', 'ne', 'not-between', 'regexp', 'truthy' + 'between', + 'contains', + 'eq', + 'falsy', + 'gt', + 'gte', + 'lt', + 'lte', + 'ne', + 'not-between', + 'regexp', + 'truthy', ] /** @@ -12,9 +20,13 @@ const conditions = [ */ exports.index = { query: { - page: Joi.number().integer(), - limit: Joi.number().integer() - } + page: Joi.number() + .integer() + .positive(), + limit: Joi.number() + .integer() + .positive(), + }, } /** @@ -22,8 +34,8 @@ exports.index = { */ exports.show = { params: { - id: Joi.string() - } + id: Joi.string(), + }, } /** @@ -32,30 +44,39 @@ exports.show = { exports.store = { payload: { event: Joi.string().required(), - target: Joi.string().required().uri(), + target: Joi.string() + .required() + .uri(), enabled: Joi.boolean().default(true), - conditions: Joi.array().items(Joi.object({ - key: Joi.string(), - value: Joi.string(), - condition: Joi.string().valid(conditions) - })) - } + conditions: Joi.array().items( + Joi.object({ + key: Joi.string(), + value: Joi.any(), + condition: Joi.string().valid(conditions), + }), + ), + }, } /** * @return {Object} */ exports.update = { + params: { + id: Joi.string(), + }, payload: { event: Joi.string(), target: Joi.string().uri(), enabled: Joi.boolean(), - conditions: Joi.array().items(Joi.object({ - key: Joi.string(), - value: Joi.string(), - condition: Joi.string().valid(conditions) - })) - } + conditions: Joi.array().items( + Joi.object({ + key: Joi.string(), + value: Joi.any(), + condition: Joi.string().valid(conditions), + }), + ), + }, } /** @@ -63,6 +84,6 @@ exports.update = { */ exports.destroy = { params: { - id: Joi.string() - } + id: Joi.string(), + }, } diff --git a/packages/core-webhooks/lib/server/transformer.js b/packages/core-webhooks/lib/server/transformer.js index 1a99378e2f..f3a50a77ee 100644 --- a/packages/core-webhooks/lib/server/transformer.js +++ b/packages/core-webhooks/lib/server/transformer.js @@ -1,17 +1,13 @@ -'use strict' - /** * Turns a "webhooks" object into a generic object. * @param {Object} model * @return {Object} */ -module.exports = (model) => { - return { - id: model.id, - event: model.event, - target: model.target, - token: model.token, - enabled: model.enabled, - conditions: model.conditions - } -} +module.exports = model => ({ + id: model.id, + event: model.event, + target: model.target, + token: model.token, + enabled: model.enabled, + conditions: model.conditions, +}) diff --git a/packages/core-webhooks/lib/server/utils.js b/packages/core-webhooks/lib/server/utils.js index 8f23b445b8..ad6a5a4ee6 100644 --- a/packages/core-webhooks/lib/server/utils.js +++ b/packages/core-webhooks/lib/server/utils.js @@ -1,4 +1,4 @@ -'use strict' +/* eslint max-len: "off" */ const Boom = require('boom') @@ -8,9 +8,7 @@ const Boom = require('boom') * @param {Object} data * @return {Object} */ -const transformResource = (request, data) => { - return require('./transformer')(data) -} +const transformResource = (request, data) => require('./transformer')(data) /** * Transform the given data into a collection. @@ -19,21 +17,18 @@ const transformResource = (request, data) => { * @param {Object} transformer * @return {Array} */ -const transformCollection = (request, data, transformer) => { - return data.map((d) => transformResource(request, d, transformer)) -} +const transformCollection = (request, data, transformer) => + data.map(d => transformResource(request, d, transformer)) /** * Create a pagination object for the request. * @param {Hapi.Request} request * @return {Object} */ -const paginate = (request) => { - return { - offset: (request.query.page - 1) * request.query.limit, - limit: request.query.limit - } -} +const paginate = request => ({ + offset: (request.query.page - 1) * request.query.limit, + limit: request.query.limit, +}) /** * Respond with a resource. @@ -42,11 +37,10 @@ const paginate = (request) => { * @param {String} transformer * @return {Hapi.Response} */ -const respondWithResource = (request, data, transformer) => { - return data +const respondWithResource = (request, data, transformer) => + data ? { data: transformResource(request, data, transformer) } : Boom.notFound() -} /** * Respond with a collection. @@ -55,9 +49,9 @@ const respondWithResource = (request, data, transformer) => { * @param {String} transformer * @return {Object} */ -const respondWithCollection = (request, data, transformer) => { - return { data: transformCollection(request, data, transformer) } -} +const respondWithCollection = (request, data, transformer) => ({ + data: transformCollection(request, data, transformer), +}) /** * Alias of "transformResource". @@ -66,9 +60,8 @@ const respondWithCollection = (request, data, transformer) => { * @param {String} transformer * @return {Hapi.Response} */ -const toResource = (request, data, transformer) => { - return transformResource(request, data, transformer) -} +const toResource = (request, data, transformer) => + transformResource(request, data, transformer) /** * Alias of "transformCollection". @@ -77,9 +70,8 @@ const toResource = (request, data, transformer) => { * @param {String} transformer * @return {Hapi.Response} */ -const toCollection = (request, data, transformer) => { - return transformCollection(request, data, transformer) -} +const toCollection = (request, data, transformer) => + transformCollection(request, data, transformer) /** * Transform the given data into a pagination. @@ -88,12 +80,10 @@ const toCollection = (request, data, transformer) => { * @param {String} transformer * @return {Hapi.Response} */ -const toPagination = (request, data, transformer) => { - return { - results: transformCollection(request, data.rows, transformer), - totalCount: data.count - } -} +const toPagination = (request, data, transformer) => ({ + results: transformCollection(request, data.rows, transformer), + totalCount: data.count, +}) /** * @type {Object} @@ -106,5 +96,5 @@ module.exports = { respondWithCollection, toResource, toCollection, - toPagination + toPagination, } diff --git a/packages/core-webhooks/package.json b/packages/core-webhooks/package.json index 72cca09ba9..eff2619ea6 100644 --- a/packages/core-webhooks/package.json +++ b/packages/core-webhooks/package.json @@ -1,38 +1,40 @@ { "name": "@arkecosystem/core-webhooks", - "description": "Webhooks for ARK Core", - "version": "0.1.1", + "description": "Webhooks for Ark Core", + "version": "0.2.0", "contributors": [ "Brian Faust " ], "license": "MIT", "main": "lib/index.js", "scripts": { - "build:docs": "../../node_modules/.bin/jsdoc -c jsdoc.json", "test": "cross-env ARK_ENV=test jest --runInBand --detectOpenHandles", - "test:coverage": "cross-env ARK_ENV=test jest --coverage --runInBand --detectOpenHandles", - "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand --watch", + "test:coverage": "cross-env ARK_ENV=test jest --coverage --coveragePathIgnorePatterns='/(defaults.js|index.js)$' --runInBand --detectOpenHandles", + "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand", "test:watch": "cross-env ARK_ENV=test jest --runInBand --watch", "test:watch:all": "cross-env ARK_ENV=test jest --runInBand --watchAll", "lint": "eslint ./ --fix", - "depcheck": "depcheck ./" + "depcheck": "depcheck ./ --ignores=sqlite3" }, "dependencies": { - "@arkecosystem/core-container": "^0.1.1", + "@arkecosystem/core-container": "~0.2", + "@arkecosystem/core-http-utils": "~0.2", "axios": "^0.18.0", - "boom": "^7.2.0", - "bull": "^3.4.2", - "fs-extra": "^6.0.1", - "hapi": "^17.5.0", - "hapi-pagination": "^2.0.0", - "joi": "^13.3.0", - "lodash": "^4.17.10", - "micromatch": "^3.1.10", - "request-ip": "^2.0.2", - "sequelize": "^4.37.8", - "umzug": "^2.1.0" + "boom": "^7.3.0", + "fs-extra": "^7.0.1", + "hapi-pagination": "^2.0.1", + "joi": "^14.3.0", + "sequelize": "^4.41.2", + "sqlite3": "^4.0.4", + "umzug": "^2.2.0" + }, + "devDependencies": { + "@arkecosystem/core-test-utils": "~0.2" }, "publishConfig": { "access": "public" + }, + "engines": { + "node": ">=10.x" } } diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index 127cc35e42..8a435fc4f7 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Unreleased -## 0.0.1 - 2018-05-31 +## 2.0.0 - 2018-12-03 + +### Changed + +- Dropped node.js 9 as minimum requirement in favour of node.js 10 + +## 0.1.1 - 2018-06-14 + ### Added + - initial release diff --git a/packages/core/README.md b/packages/core/README.md index 4aad3a7cce..b8eaebfc97 100644 --- a/packages/core/README.md +++ b/packages/core/README.md @@ -1,12 +1,12 @@ -![ARK Core](https://i.imgur.com/1aP6F2o.png) +# Ark Core - Core -# ARK Core +

+ +

-## Installation +## Documentation -```bash -yarn add @arkecosystem/core -``` +You can find installation instructions and detailed instructions on how to use this package at the [dedicated documentation site](https://docs.ark.io/guidebook/core/plugins/core.html). ## Security diff --git a/packages/core/bin/ark b/packages/core/bin/ark index d1a70a4abe..b7557fd986 100755 --- a/packages/core/bin/ark +++ b/packages/core/bin/ark @@ -4,8 +4,9 @@ const app = require('commander') const bip38 = require('bip38') const fs = require('fs') const wif = require('wif') +const version = require('../package.json').version -app.version(require('../package.json').version) +app.version(version) app .command('start') @@ -17,7 +18,9 @@ app .option('-b, --bip38 ', 'forger bip38') .option('-p, --password ', 'forger password') .option('--network-start', 'force genesis network start', false) - .action(async (options) => require('../lib/start-relay-and-forger')(options)) + .option('--disable-discovery', 'disable any peer discovery') + .option('--skip-discovery', 'skip the initial peer discovery') + .action(async (options) => require('../lib/start-relay-and-forger')(options, version)) app .command('relay') @@ -26,7 +29,11 @@ app .option('-c, --config ', 'network config', '~/.ark/config') .option('-t, --token ', 'token name', 'ark') .option('-n, --network ', 'token network') - .action(async (options) => require('../lib/start-relay')(options)) + .option('-r, --remote ', 'remote peer for config') + .option('--network-start', 'force genesis network start', false) + .option('--disable-discovery', 'disable any peer discovery') + .option('--skip-discovery', 'skip the initial peer discovery') + .action(async (options) => require('../lib/start-relay')(options, version)) app .command('forger') @@ -37,17 +44,7 @@ app .option('-n, --network ', 'token network') .option('-b, --bip38 ', 'forger bip38') .option('-p, --password ', 'forger password') - .option('--network-start', 'force genesis network start', false) - .action(async (options) => require('../lib/start-forger')(options)) - -app - .command('snapshot') - .description('take a snapshot of the database') - .option('-d, --data ', 'data directory', '~/.ark') - .option('-c, --config ', 'network config', '~/.ark/config') - .option('-t, --token ', 'token name', 'ark') - .option('-n, --network ', 'token network') - .action(async (options) => require('../lib/snapshot')(options)) + .action(async (options) => require('../lib/start-forger')(options, version)) app .command('forger-plain') @@ -64,7 +61,7 @@ app const delegates = require(delegatesConfig) delegates.secrets = [options.secret] delete delegates.bip38 - + fs.writeFileSync(delegatesConfig, JSON.stringify(delegates, null, 2)) }) @@ -86,7 +83,7 @@ app configManager.setFromPreset(options.token, options.network) const keys = crypto.getKeys(options.secret) - const decoded = wif.decode(keys.toWIF()) + const decoded = wif.decode(crypto.keysToWIF(keys)) const delegates = require(delegatesConfig) delegates.bip38 = bip38.encrypt(decoded.privateKey, decoded.compressed, options.password) diff --git a/packages/core/lib/config/devnet/delegates.json b/packages/core/lib/config/devnet/delegates.json index 591d409c22..096f5472e1 100644 --- a/packages/core/lib/config/devnet/delegates.json +++ b/packages/core/lib/config/devnet/delegates.json @@ -1,7 +1,3 @@ { - "dynamicFees": { - "feeMultiplier": 1000, - "minAcceptableFee": 30000 - }, - "secrets": ["this is top secret"] + "secrets": [] } diff --git a/packages/core/lib/config/devnet/peers.json b/packages/core/lib/config/devnet/peers.json index af2037161d..1e766742fc 100644 --- a/packages/core/lib/config/devnet/peers.json +++ b/packages/core/lib/config/devnet/peers.json @@ -1,5 +1,5 @@ { - "minimumVersion": ">=1.1.1", + "minimumVersion": ">=2.0.0", "minimumNetworkReach": 5, "globalTimeout": 5000, "coldStart": 5, @@ -28,6 +28,6 @@ } ], "sources": [ - "https://raw.githubusercontent.com/ArkEcosystem/ARK-Peers/master/devnet.json" + "https://raw.githubusercontent.com/ArkEcosystem/peers/master/devnet.json" ] } diff --git a/packages/core/lib/config/devnet/plugins.js b/packages/core/lib/config/devnet/plugins.js index fc71f45a71..fd4c38865e 100644 --- a/packages/core/lib/config/devnet/plugins.js +++ b/packages/core/lib/config/devnet/plugins.js @@ -1,100 +1,73 @@ module.exports = { '@arkecosystem/core-event-emitter': {}, '@arkecosystem/core-config': {}, - '@arkecosystem/core-logger': {}, '@arkecosystem/core-logger-winston': { transports: { console: { options: { - colorize: true, - level: process.env.ARK_LOG_LEVEL || 'debug' - } + level: process.env.ARK_LOG_LEVEL || 'debug', + }, }, dailyRotate: { options: { - filename: process.env.ARK_LOG_FILE || `${process.env.ARK_PATH_DATA}/logs/core/${process.env.ARK_NETWORK_NAME}/%DATE%.log`, - datePattern: 'YYYY-MM-DD', level: process.env.ARK_LOG_LEVEL || 'debug', - zippedArchive: true - } - } - } - }, - '@arkecosystem/core-database': { - snapshots: `${process.env.ARK_PATH_DATA}/snapshots/${process.env.ARK_NETWORK_NAME}` + }, + }, + }, }, - '@arkecosystem/core-database-sequelize': { - // dialect: 'sqlite', - // storage: process.env.ARK_DB_STORAGE || `${process.env.ARK_PATH_DATA}/database/${process.env.ARK_NETWORK_NAME}10.sqlite`, - host: process.env.ARK_DB_HOST || 'localhost', - dialect: process.env.ARK_DB_DIALECT || 'postgres', - username: process.env.ARK_DB_USERNAME || 'ark', - password: process.env.ARK_DB_PASSWORD || 'password', - database: process.env.ARK_DB_DATABASE || 'ark_devnet', - logging: process.env.ARK_DB_LOGGING, - redis: { - host: process.env.ARK_REDIS_HOST || 'localhost', - port: process.env.ARK_REDIS_PORT || 6379 - } + '@arkecosystem/core-database-postgres': { + connection: { + host: process.env.ARK_DB_HOST || 'localhost', + port: process.env.ARK_DB_PORT || 5432, + database: + process.env.ARK_DB_DATABASE || `ark_${process.env.ARK_NETWORK_NAME}`, + user: process.env.ARK_DB_USERNAME || 'ark', + password: process.env.ARK_DB_PASSWORD || 'password', + }, }, - '@arkecosystem/core-transaction-pool': {}, - '@arkecosystem/core-transaction-pool-redis': { + '@arkecosystem/core-transaction-pool-mem': { enabled: !process.env.ARK_TRANSACTION_POOL_DISABLED, - key: 'ark', - maxTransactionsPerSender: process.env.ARK_TRANSACTION_POOL_MAX_PER_SENDER || 100, - whitelist: [], - redis: { - host: process.env.ARK_REDIS_HOST || 'localhost', - port: process.env.ARK_REDIS_PORT || 6379 - } + maxTransactionsPerSender: + process.env.ARK_TRANSACTION_POOL_MAX_PER_SENDER || 300, + allowedSenders: [], }, '@arkecosystem/core-p2p': { host: process.env.ARK_P2P_HOST || '0.0.0.0', port: process.env.ARK_P2P_PORT || 4002, - whitelist: ['127.0.0.1', '::ffff:127.0.0.1', '192.168.*'] + whitelist: ['127.0.0.1', '::ffff:127.0.0.1'], }, '@arkecosystem/core-blockchain': { - fastRebuild: false + fastRebuild: false, }, '@arkecosystem/core-api': { enabled: !process.env.ARK_API_DISABLED, host: process.env.ARK_API_HOST || '0.0.0.0', port: process.env.ARK_API_PORT || 4003, - whitelist: ['*'] + whitelist: ['*'], }, '@arkecosystem/core-webhooks': { enabled: process.env.ARK_WEBHOOKS_ENABLED, - database: { - dialect: 'sqlite', - storage: `${process.env.ARK_PATH_DATA}/database/${process.env.ARK_NETWORK_NAME}/webhooks.sqlite`, - logging: process.env.ARK_DB_LOGGING - }, - redis: { - host: process.env.ARK_REDIS_HOST || 'localhost', - port: process.env.ARK_REDIS_PORT || 6379 - }, server: { enabled: process.env.ARK_WEBHOOKS_API_ENABLED, host: process.env.ARK_WEBHOOKS_HOST || '0.0.0.0', port: process.env.ARK_WEBHOOKS_PORT || 4004, - whitelist: ['127.0.0.1', '::ffff:127.0.0.1', '192.168.*'] - } + whitelist: ['127.0.0.1', '::ffff:127.0.0.1'], + }, }, '@arkecosystem/core-graphql': { enabled: process.env.ARK_GRAPHQL_ENABLED, host: process.env.ARK_GRAPHQL_HOST || '0.0.0.0', port: process.env.ARK_GRAPHQL_PORT || 4005, - path: '/graphql', - graphiql: true }, '@arkecosystem/core-forger': { - hosts: ['http://127.0.0.1:4002'] + hosts: [`http://127.0.0.1:${process.env.ARK_P2P_PORT || 4002}`], }, '@arkecosystem/core-json-rpc': { enabled: process.env.ARK_JSON_RPC_ENABLED, host: process.env.ARK_JSON_RPC_HOST || '0.0.0.0', port: process.env.ARK_JSON_RPC_PORT || 8080, - allowRemote: true, - whitelist: ['127.0.0.1', '::ffff:127.0.0.1', '192.168.*'] - } + allowRemote: false, + whitelist: ['127.0.0.1', '::ffff:127.0.0.1'], + }, + '@arkecosystem/core-snapshots': {}, } diff --git a/packages/core/lib/config/mainnet/delegates.json b/packages/core/lib/config/mainnet/delegates.json new file mode 100644 index 0000000000..096f5472e1 --- /dev/null +++ b/packages/core/lib/config/mainnet/delegates.json @@ -0,0 +1,3 @@ +{ + "secrets": [] +} diff --git a/packages/core/lib/config/mainnet/genesisBlock.json b/packages/core/lib/config/mainnet/genesisBlock.json index 8c7a9c9c5c..bfc4226214 100644 --- a/packages/core/lib/config/mainnet/genesisBlock.json +++ b/packages/core/lib/config/mainnet/genesisBlock.json @@ -9,16674 +9,18167 @@ "payloadLength": 313052, "previousBlock": null, "generatorPublicKey": "03a4d147a417376742f9ab78c7c3891574d19376aa62e7bbddceaf12e096e79fe0", - "transactions": [{ - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AU9BgcsCBDCkzPyY9EZXqiwukYq4Kor4oX", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ed57f27cabdb01f5398b30e63e3372735ee428e17e95de675c37586b6d1a5c12022062a0040ed189a4adac6c3d105e05180f7c74e8c68ca9912b3c60286c2226f3fa", - "id": "44d9d0a3093232b9368a24af90577741df8340b93732db23b90d44f6590d3e42", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AeLpRK8rFVtBeyBVqBtdQpWDfLzaiNujKr", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022018618cfd5dd1024c0dd7677fdbddcaa6977b57f832eca130583d36480dfa452302202c067556fd93899fb0d18ea28e6f0276a778099cdde3d97d3bb8733dff965a59", - "id": "512f1aa00538b24a3ba55d65519d34cea83d753f5b2cebfd7004d5c0eaa7177a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "ARagsXvdeTHYghaQgJkwbdSkPLZ73qdMkR", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022021e056a123b4a6c30e3f30dd68ff56f4cc1a994222cf27ff5b48434947e45f300220424cbc671a54a019cc655d02b2313a324702908a4a05c86bac4ac83029bb01ef", - "id": "8bb3997878a6a359f1418cf25f31c84f660e5e6897ebd6d07549ff6a4374a44d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AT9xWcPQ8hGYuXZ8aWE57VJFohyX1TTLkH", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fd0ab0bee79152978d8d5835e2d244fa159e4957f48d602c65e35e2383c0d14a022036380dac439784075befef7f7b14734f9ed782e4be5ac7f2f4c49985b08fdce9", - "id": "30cb724924823c689058c25243d1c213b9cdb8c157eff26ee9c89fc1e705fedd", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "ATjjXXcGPTum6wogPVGb9pmimpSo4EDDEv", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202e4a8dbbc11c3628f7aa9ef92825d84cb662a20e0af724d80475bcaf64416007022063e859ef5e9f9dcb294956e14d0680bad69641d1c254ef0ccc733f25b7814573", - "id": "69e5ced4fddc54dc4b688150e8bbb5bd3cb056252708e0d03401819490bc6125", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AW58iWw1ATvzGHu338WqMYvgUhmvMMsRjF", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b1a8dfbf6c37a984acb364311e22336c367c5c76741a29dae4d5f894a496738202203e93441406fe1b23ab6d8807179c2cfe9e4c33bfbc455cc30733b5237af35d60", - "id": "62a85a7d3c9c31eafba7b39b102ff4594c5dce17e5c9ed38ef897ae0970ea613", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AFxqVbsVuDfnfyd9ciRAuGq6waR5GqiC5R", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ff14b9189e4f4d6199737c9b9b00d7572b2e9a5e1d1280b0bcb02b51b233668d02207a9df93b66088faf216bdbd60f438974dd5000cd1dee92a5a391294d717fde00", - "id": "c7b221db20709d99cf25d4a5b75aedc2644c963be994f040c9582c8ca84524d5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AJjkVwkhsvsX6dVKhVxpmhRvz4CyXLEvQ3", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100aa43dec0f44ed1ae07fcca1bd4ed5075954cfe0a0bc6ae88f0a2640c9961cd1502205c750b5c957bb92e7dc032bdf01fdd2765cffa5dcdfdaec7201b8a2fd17e56b1", - "id": "647143b65234e1dd78f258cb32ba64008a1d23baea7739c02db82e60ce9147bd", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AMG1Y3LP4kZJMAtoPhsnVkpsMTJ8nnCDr3", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203519061e2b618b44181bee15f4ae561f710c6601995ee5e38149726366b3d14302200d0414c012b86429eae098b474acfa1c9f29ac4ef06d500eda8a9294c1ce14c8", - "id": "02dc2d050528586dbb9ec9dfe8a4118a21bcb3244d14e61a8cf41337925972a0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AVFkEkCmEg7cuCXoVrfvtH6mKz6XC9XnvV", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210088d431420331051cc29ee00cfe3851ac4fed969c9592a81dd0492c0dac83d0ec02200f2efd316f7506abc7c60ad6151b00977206aeacc5a3a538df94fbbb88a1bd70", - "id": "1a3522ccc27e223953d3978b891e4adc219ab41216b06eb956b138c8dd532243", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "ANstQM4LaxfsuKtFMd8vqdGte3CL9s2vMA", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b6e401941a798a09d5179752ac67c39af596f95d28aaded45a79cc8b8689bfa5022079ada29c01231e3fc2ad96050204047a7d0a9b56c56f609532bdb3d92b152e91", - "id": "574fbbd0c1f28cc923b03cd00bc9f6867fe246a645e3b261b6b9b6b041491c13", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AJqbav8MPPAe3zdzo1f471gaciQbx1SRe3", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201e4f4718c13b10300c478ea28fc4a6444f626fcd1fbe6d45f80504abd8f1e5ac022078c0fa5bd5701dc989ee3432a561e659d7a07c22e6a9eb198745d162a3eef958", - "id": "e1d3f456bc81aa88b5b9f790c383384fd24593ab4dd50b308a77a843e0de346a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AbfnTeGFiRM3m8eHcMsrqNvrpUCoCnuSzH", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fb740effa4f878b5afd3bf8202cedaa7bc4c76b5a9ec0e1791824008b08c04ab0220340e130184ea186b9c7acf058b9cb62c77fea9cbd954d5e5f0d883da8136d15c", - "id": "85c540e0e42f449a14541c4ab66a667a64a18ffb1dfc2213a143441c6d21069a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AXArbuCVSiRuYBkzCAajboxCfNiw8AyQX1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022073143336b15ab2a51da194873e14a2e08da329a325e570d3d525c764a8e546b402207055a169c2cf9b1da89bdd40b1e9a19c579865cc19e2f5e868343f594ebd87de", - "id": "0d00b60f1a26a05d52432e517e59a6e42b1597ba16547f25d5b4cc5a4d821c03", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "Aa5rKoVusA5xiyh8Git1tJUWZE48ScbCR8", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ea59db1db3462c4d08ed19920dd694e707181f63dedb48ad62991935f3f5da10022005d5981a84a82f8b7a881e50a07ffac814fa62d1052d43583de50e0ed62498a6", - "id": "bffa21418f3668024901a65e57f484ad45202ac71196e857d30b61c2a300ab6a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AbrgipEvLp1ZHNJ1GcWWAsCLNgSgDG6Lxh", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203e5fc71ee49506af5218a4d6dd3870493081984f16234dc53339e6dd411d774302200293cee5f33cc54c22c766f420a0658107339905c6d6b745e88d49be6154be18", - "id": "77456d6e6fe11bd3fb7ec636e115dd6cd105cfbc97f2c9af37513f9f74737c97", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AWLoVgSScNNB2kecswuhbY9tcrtv9kf2iC", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210089cb088a883d07418a6be847f45d2fdb1c8c09cc506b5ead7df7df3f54cb503202201b323319c4e8ae723c46886fc51ba311a722e25a0ed87a130ca57e9d6e725dd8", - "id": "79c7c34636d6bef31813438d5db5c2b02bd8a7964ec1654a2e24cc24563f5695", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AbyacFxcWS1JsokdRCx8bFsWP8f48XftmS", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100bc987030f590b970eade8df22b44f13deb89a652837b3cdbd9274a27b9d97f9802204ad6718c262ab2eba80202503ef5cc9704c13b3ebce7e2e5e80489e783e34540", - "id": "8e40e07b53f46d8b42c90b18383ae19d5af69ff657c13f5f6550890eb65939e3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AYTEu82arYgRyvTgi7dbYwjodV7ignYucz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e30c20254d8518201f0a46ec347352159ae81ab2d1a47d582dfb20bbbfbfdb7c0220300c012e88a107f9268e7593f2adebcf7ab72f2d240aad37b58b139d02067f40", - "id": "23241fac8b9f633b6749f0b7788ffaf9ac8997168c55718d7c20eb688856cfbd", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AYLTbdiYWHvPvJo5Lh42MEVS4Fnepg5vgc", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207c919607f7d4b17b0dd54cd82843f4b4da3f5c5ea92f07a1794f0fd666f065f402207245dbc1d97ed651e14849c84579f11bee9dad72ec7b73dcf0b3d79cb7d68eaa", - "id": "5c78d1808a47333800b9604fc1ab2352bd847ea5fccb9f834825fee74e5aabe0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AGdHR2UZ3MJuaXWejKGoAycztyN8BFQnNG", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f6f1153d93d37483e21cbad1b6c07bebf95a8d13dca45e8c51008a69be736dd602200f81dbda9b257e6c12314bc3a20c5b1c8ba86e0deecde76bd1606f79e836e008", - "id": "fe843047a6d408de46081217cea6f5f197f6c2aba86bbacab00240f147002501", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AVi8PFHr5jFBFGWSissPFDFXUPABuBgxSa", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022002a5daa6a6ac2cba5804e8bdc21769310f76fc6501c61147f9a5d97ff35737ac02202c6886b09e65cd90b3fb5ab5c906bf98512ff823f21cba66ee684c3e55e2058a", - "id": "eba8ca8a4c458bd3e15aa956a15e4b8cdf9336bf7d1050e9ab44bc83482005cb", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AVoTzMjHaaWKDuA26ysXGU681N6Q2PQre6", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203e6a954d0044affbfb9bf8097fb12fd030fa4d7b9f921a797ddbdac7d64d357002202404106e049c35fba4483451e9522ae46e201c916d50bf6971e5ffe7bc1f0155", - "id": "3c8b8785bb4213cb8df30aee1b061fa2ef0a515b59f05abbb0fc7e1c36f2052d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "APXkAdLbLiLJDC9Ls68Y9a5ws3PcgmUDAo", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022022b5f2321cc614962cb4fd9a1eefd128986d39285b59f6e418e459139b07528f022050988e49f7d25d9a44765514d50765a0f43a47b306df56def037be36d9c97d01", - "id": "ab8a92d54c08815a6dcb5561c0dfa0e93b8552eea75e3feac096f5a5e4eff784", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AGZhXHXFUdvd7W4aWs1fYJe6XFUYeSWrd4", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a66c0a231cf6f09d6ba27d7a835a4458edac26f7efce8fe1c6b58f80f88cd00e02207f92221ca0873e10a6415e62cdeb4da836cd16336715cc861784762d387a1749", - "id": "ea59d2aca71b241d063cc41061adab57d97369fe0e9e3bda651ada6c712665d2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "Ad8UiXMZPecuNGwCXZTmF8Mysn1TchVVTf", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100af001967b21b5715f68047911026eb0cef51d14a8e0563e1633b2bf213c191cd02204b85d55c4b13255b488a661dba416f7208237dc12c114040fe54692f76a7fd57", - "id": "b8b63cd15f19ef5671309e8d571482537d88af6226248c2fa0e5bfc3750606ed", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "APQgLh8MaztT1XuWVKb6d4FKM9HMmdmDVB", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206bf4937703d0b2fc171b86ed8596ba5ec58e9282e3cc4ac269192ce670478a4002205cd8f627869c5071fb99db462c47655eafdeb1b991beb75bc48f62a56915c137", - "id": "e1a4a5601e46dca9c9e2a5a67655bf976764efe72e82d2cae07c043e46e29928", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "ANUfH6C3Jjp46pDUxWgeV6WUbWCagaVxM1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100acc09397ff3c0b38214df5bead49d458931197b22e28426826d0173594a75a0702202d22e93e84748b52edfc2e420ddbc6887b9cfae3f7b7b3d7781886f085b9618d", - "id": "e47687f406ffdc59012079854958532ae22512e2021990c0c11cede226c64d58", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AXuVpX3tAewNp5YVWvXWv3etxjrMDgaZdK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100df1255aec444d8ce3ac9cd459669412376eb92d281ec0153c7a525b43b2cd7ca022078e22a0c52eace076baf1d89bfd03771ed1b45dfea105451cb9490371be6908b", - "id": "a9301a31302384e0428be63ca0731b93ebd2a2c18534b2ce771525c4a0c1a708", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AdCa1oGLMRQqygEBGGq1AEtSV44CJ5Kbdo", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220181358f06e1a2f2d43538dd72e7ec33ab64a39c92a512f2cb08e08fa32c3e2cc02203fddae5a4c9545093c9668c95688ec07b9b7ab1be27eb3efdf0c0acc41b2bc61", - "id": "f10ea8612fdb470c754f6ba5271d0b30c52c12d3a89ddffec0151cbc90e8d6fe", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "Actv8ebcwNsbfx8MM5k2AeJidJuLL7PotT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b2c5014c3967c971f57c995bad2385f5d3cdbef34d43304d17be215984f986de0220080cdd2e5a643d7dc8fa9c299c5456d554a2d46713ce3a8901abd94455dd5929", - "id": "2a992486b31f723a33458ca055b878e51f1c13359cc4bda87509fc124d57c6ec", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "ANeLRbMxkSguPMq9CJeMgr8xZxwZ9mbqbx", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009fddcf0b5071d43e7cfae4f9241011718d324ae16692ee674d668f09434041bd022050fd7c97e4206c2e07ef98032ed731593ec0cd8209a9debec36f39b153b752c5", - "id": "3e6debb349d1059af502804311bcb2cd37368d67b33845f9b50e4ba296d0aadc", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AR5z28tRUnvaBWC14KSBpvNJDgsVCNtagq", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220747d72aa2180e80d190ae4940dbffcad648ab743d551ee70ef221439357aa14a0220334be2dd1a004d188539af503467b37dceab37ec55ae5a035801746fa356412b", - "id": "7b97374ee88b881af118a757167c49ee0ae60b0ce88e377a200b015f87441b19", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AKeDRRgG4TdDo4Z2iCzaBZS2UcvjWKMSrC", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205882a3aa05216dc8495784c9b842e3066f331014c8b55644804deccc10d696e602200fae518daafe7c9599a3e9a4d1ab8388fd3e5751af5e946c00a0d5d7c062f82e", - "id": "0d1a17ff619a2dfd5b1d2abe09600fd1a9ae1f373ebffb70bba1dacf7a15947a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AbkDPAUDsfQJgvHn5g8AisDm9XqLAtFFai", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022016ea5da49920aec7c20e293270fc5aeb99a7a8e6020daee092ed11cf48b01a3002205d10abf6cd111443e4ed7ae84a9f29791c5441cf99dac64af09611d6dff00dca", - "id": "4888da0a60c337f287a6526c9fc86be8bd85460ac1e48aa39b5d2f5c4a4018f9", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AZvjdJSG5V4WnNjPaRbDNfLD72j3rYWqbs", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202d089f163508a18c061fc42c70a79583a0081d9afb49dfa36b7f881cf73a48ab022021dfa71c41e3b7303297dcfcf63a180094f0ec58953f52e8b8c424251514f7f6", - "id": "be67562ccb6fc1d6a04791726fbcc111067d5d54076425b91380bc9442b31ea0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AbAeJ4YJU5rxuNtXpDn3E4W5E8UNHyc26a", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022015b2f957cf3fe5f690786bdec5831efe41b59ea82a357bc520500c77ab20d9cf02201ac6773a21d83bf1f0b744576b620838ad984e6954965db199fea922ca5680ec", - "id": "2101c235de152ed1a0bde3f57593362d73149e1cb1e5b4df855718c392ac245c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AY5GwZtG9sFvDzMKAQfAD1Q8EHDh4bW718", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200ad645598de2adfa46f68a9c0b849457306a8744627c9d5a085238bcf51599fa022035823c617d15fc35bf7910a88ca45e47c9b3d2aa6c9146f6c1db2b92de0d3ecb", - "id": "f9aa1c9331948314027579cf07368180d49b452bb747f153c0f25c39328d955c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AP8agRcU4WmsYhC72pBqyfLwaDU6NYKUL6", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207b203b7f10f7fcd1c29379603c765d37d9c1eadb787885211729b63606fe7b3502202862e0cdc7af6f3f2ae8d48ce56b9a76bd38ef3320bb82f21bef96c6d793eee9", - "id": "f6445a905a38bf0454327fc4cd9976bbd971994b48a55906ed3c123efc0f5370", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AaFxHxsjYyYCsZtpQwwYGvYESogJ2SHxe5", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206f4c7616b756110ad060c31c2e4402219f77bd266bbf2c0bdcb4e8969cf59cb4022028355a38d68cf842b88b67ca9d9e261ca5adf017e84b2b5bf04e7adb6062285d", - "id": "4ccaadad7365662dcda0d68a13a18ee08174e2b0ce3638de5d45586cefe1fec7", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AHmBqWJgxZfaC2azkyASdrbCxF6csE7Qxx", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220088ea11151b787f4aac1c5bed478a83ed2b31a013942ee76f6c8b5a45dd1fb3d022068d99ce4db49d383fe1987682a459620153e616de651b45f092839b7afa4b29a", - "id": "600b4e8a38b45624d23f8f6a11424cd20a9ed956fa970cd317b126221c2c870b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AZengw5WND4WLC8JKz6xUDFwLz3yCKPpTC", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022001c34abe513df6f732d459e995d5ab3ac6ce064213ba79f502472fbd23d2a41b0220799e96bdbe031aa06aa9fd14cb25b49b71244298cc04f5835fd3c947bcacdb61", - "id": "fca76de221fc1f70b642f30c4e5ea024f5ff886fbbe2f51f4ac7fac4bce94629", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AeLV4NUMsPJW1nvHquBWPFVKCWirs1pshf", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d37946b7e677220e9333aa5d428e8b82a8553d2b3e0c1adbd8551a75112b54ee0220465fdfad076cdde91b5642305ee4c237c4093dcc210b9445c374660b1a11ae40", - "id": "6680f73be6c0d1f96e187440bf3575eed655477e15d8f1da85388453f5c9390a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AJrXd5u3y6FH5HktH2jgkLQHjgD9ZztMtk", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a97bd4beb5444b5c2dea233a7dfc11c5ccb705a88799a7386f188a159477ef56022011875cadccf32228d693ebf24b6a1acbd574b615dabb2763e4a29b75591dc75e", - "id": "0520f4b24257ba8ad735613737ac0f0f2bd593ab5c52edcac746f4bbc8c635e2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "Ad6y8ae35QWkrtiLBpiXRR5Cj2KK2u3EGX", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b6065b0dab807b36139d101154d5e16c145fcd9ee807c06e46ba60e172efedcd022030e641f2c5ee29da508ceab6649593a6cb872d89d4661b3fb2b79f48b20c4ec9", - "id": "04e36364fb8007bfe7f85914c22cbe4bad262c12631ec4f339858d82213adc7c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AQaKx7UU8857b4tJij1jb7aURUzd3GDyKt", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220540f725157e6fa9e1d5a7e495504b5007d9d554ad8f0c275e0e45a04028cf27f0220660a555068c7402672443beffc2bcaef8a85f06f9ed38ab558ede7a21e265bac", - "id": "3dbb56502f32939958b41aeaf84e9cbd4483a85b23ab32f979a3c1f0d683db10", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AGb36aHfdxvqbMqoDCnm6wVkKKtqkE3zAh", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022063d7b93cfedf0daa9255bb1ab9a3955367c5bc8941b386f548fb01db85507bb902200cdde437236daa8fc1b396fd7de9294a9cdcbfdbd22df347bd635bd66581704d", - "id": "1c99e21a5232ccecf47da6b530eba9ceef87f02baa91cb333fcb3b8ca18edccb", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "ARDkQVS4DbJnErrptyWSWdJD8gtaPEyRH8", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c1b92b570f6abf42650414541ddf44693c61835816883bc2de0c4e7997926640022015e109e9f622844d8930a8e497ea2af2fae7089a4a110ff2d3c6fca46b19a70e", - "id": "fda4e22bce9444a6bc7d952c0cab822a5408ff74a19aa8e6d47b61513e061bd3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AW91q3n1QYTn3caBm7KR35zexcJU7PgMtZ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009010a3346835bd198bd011a5a3cac7ef94685c96acd668ee92be386e9b267fe2022078a272a9552454e80ff83dd2a01b3621fce5818d71fbd6430e0848ba85cd2c32", - "id": "52cb2975b2dec5cd21beac470055a254a84169e51b1a72387757a340509a5049", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AYaYHEKaJvLLWX2NgM8VXk15zSDxV8vCgn", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100894832a480b4ce89972badf315ba89a21f9c200cf83dc402dfac475107197852022036158362b58228e69defeeed4035e9491f20e38b8435a4b8afd86718906ec42e", - "id": "1b693cf3a23efe80385fb0f8f2b7e1ec123af4f5b99795a154f7dd1aca505950", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 0, - "fee": 0, - "recipientId": "AGNMmJ5upuU38ucaG3TUsG1ESaQDExSMo4", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e2d35dbf837de046e351c2bdc8a7061edca5af3cf01d8c47ed468225a85f688e02202cd057264c2d6f17a4b0ab9d054de7e6db6349eb1ffa2beecda58960ce80b4d8", - "id": "509e2950f47ac036f4ca1545f3f3e4dee77db3756682175d292558b920948579", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 128537390, - "fee": 0, - "recipientId": "AapqpT6xF7q1Enu44UkL75c76uNuWmRWkB", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ba8eec5c24356ccc89437cfb53440d3db1929fdae0133a4744a4fc61ee1c768502202775dca5d3ac6c2c3b6d5b72e58a975cbdbdfeacf31f26d46486a420fa12bf9b", - "id": "6300b6f026c1e1657f7d7328bcbe58e5e1c6a8e56eb5f1cb1402bd1225786c90", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1470150572, - "fee": 0, - "recipientId": "ARc9Qz4v9wNbneBSNk5s4M1RKXwoMzLiug", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220084a67416a41da67ff634eab70f88443a7f3d531976c84b310a07cb0a6ced39102201f26c0d886785aaac15d5efc79b9545bf8da36ec4b4a491a2d33a937a97bb9d0", - "id": "33c5449bf830f309809f67aee50bafdfbabc3fe284aed0d5a84059baec213843", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1939749374, - "fee": 0, - "recipientId": "AcE7Xh9FTaMB9pUKQgST1BHfXnpmganLAN", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a3515ef9744947b6b3cfcc3c6bbc6ccc05b7c158ecb639b0a46b0c5d38132b3b02202d2c20ebd19a0f60da85961a6dfcdcc905858e11556a0fbe3f37a36ea286703d", - "id": "5359b1e1068625f47432ba3a1ac12fda7411225f9be163d7248c25a92080c496", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2223350287, - "fee": 0, - "recipientId": "AcGWNuiBErRUP9MeXGW3yUQrhQTNKh4keP", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207d9fc26887b0a6ebc7877d0f96cd49fb6f51e09c5f7086c8030740bd19c7f8200220229ac976a89a3f1b061d7f833c916fc76da131629d0373e20f6a10680128c246", - "id": "68e9ebe8e03c06a773223752296acaacc47503411398d75ce9aea8d1809900a1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2635948642, - "fee": 0, - "recipientId": "ASHDLexaM8z53tcrddDC9qNrG48KiykCFj", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220390fd742fd9ad375f06b2dd4be9fd28976facd9ab58a3b497f9c53627c54903e02207a13f2cf4b2e35b512d9f25344d7cbaffa7533a841b444be4131ef3ccbb9a707", - "id": "140dad637fb5e85d9bb48885be2ce2caf63599982325fceef875f5438dba6379", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3319628053, - "fee": 0, - "recipientId": "AKoFbGWi8ZpD1FKLtWbs4PFdR4H5L9mNqj", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fbaf95f5cf4ed909feefc9b0d3d82a27c6281837320174fb9c1cc65c6dfc4b3c0220571f50b5ba6c1b9effff224d5ea08a1dd79753d07487694897f5b053cc7bac56", - "id": "fc4460c527373e2cae1ef706aeb846d0d011f5fe3a15d5b29727ec6d4a65b378", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3500000000, - "fee": 0, - "recipientId": "AcT6rrsUh2T23TXVgfXxXLQKmpRbECs4N4", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ce9a0287b36c323e4dfbd845a2d0bd30cfeadbaaa4314c5055d3f4194d05aa1402207aeba8bf92955383a8bb95ce75628a258c5ce379e3bb482787b66db194bc24c6", - "id": "255952a161258cd10a8e70bb03be46b8005101f05ad0ad453e50bf8b5f1c39c1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3500000000, - "fee": 0, - "recipientId": "AYxobqMdZyUFvvX9o3ihE4iMnZWCzQBhgs", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a8ba213f88717697168ef6647a89ea7d7d1a7bb56c8b82a27f4019cb351f13b502207afb90964461534dff853f2bd8a55e36fe6660de37b0864f65e4220c45cff2b5", - "id": "4a761497352e5687757421e2cad81fd7881c45395fafd33fa5d4266d98d3b40e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3606920711, - "fee": 0, - "recipientId": "AMepHWLBpbShRDbwLcEJhyHRatqGAMDa6r", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a35fee7952af116cb4ec7b4881f9fe5056371287ee26034206d964171c76f05d022053b2d4cf6bd03c89db073a25270ce48fda9b1c98a6cf19136291b912040d8917", - "id": "5cbe722d6e53c668c603db420a577c8a88f2c57c838141d7b0d336ecf4d67541", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 4373745201, - "fee": 0, - "recipientId": "AXZCfAqHYyFUpYxYgNyw6W9XVngp25rGkq", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d430485cd384e4a58efddc72ce62e203a5ce80eb29699fb293b7d378521c932d02201e0d8cd73d3c98ca4973fe45ca2d161443f045125c971304864f9dc4e7d47645", - "id": "4f29a835860ea8533c479ecaac35bf14af9c12689a4d40ad8f4b07e55efe9a91", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 4410451715, - "fee": 0, - "recipientId": "ATyCrCUvZN7hJfkYWbCXgKfEZp7PB7ez6V", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e90a709462f9654e698f131cee2fe1ae82852e12909909c32bb4ad8883e5e764022065c75a2511725d489a625ce0f4321119c43d2df7831fa748d788c879cea94eca", - "id": "16f6d59d7b48c528332ba917f7710f5af66dcc647a0c129165da7508aa93e826", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 4410479871, - "fee": 0, - "recipientId": "ASrrGt6HcDBYe6hTqX2p4cD1AjNfiC3vnv", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f42315460ff894d560857f7b863e22b8e9b14bde5a86ccd34c4189e37e83a8ed022036ad285ab692485715db059896f7d394382dc6ae8386627d6bfde5771a01279e", - "id": "6497901d7e0d33d9ebc7b510100ada1146f9be06e960528d789c4d62f1198855", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 5445780417, - "fee": 0, - "recipientId": "APRgb6yUmpvtaCyPmLuSzXPucgPiJ6FRpJ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100cef35ed420e2dc8c5f0de5911474f0b22c0b5f0eebf9cfb453f6832892b47fe502207f52c64e0bcb8fabcfd641a8c0a680d6f6a80ce47df726e276f620131f681c70", - "id": "1ba4319ef107661772377dc6587a13c08493dc0a02499eea9f69de567fce243c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 5549484283, - "fee": 0, - "recipientId": "AQqQZPw1ZNhRqmbYfVisYc6muRF1TrUk32", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100aad3e80ae4d92622e819f38872ef85c0edb22300dfbc3fe8ec67ce570c0fa45a022076ce462d4b9cc5ae6340eae28219b1949ca4e5d70eb01fb70c92d759513402b6", - "id": "ddd800bcdce22996cf22036b8de5903e7f5719c5aa9142e4aea0a79b25837df7", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 5618558679, - "fee": 0, - "recipientId": "AXd5pgP55H9Xd9i6ErnzM3mWpZ8hZpYaCN", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b5860683085463cbb8f828e4749c08b31e1c8a0cb5c5be8166414c7d38da33100220053a0efa7541a6a63cdb752bf3ca7eff289d4314c01c1215ee86dddd27d0c68d", - "id": "12bc04a7470e5929cadeaaa4f1ac786861eaecac4f6792b38b5bd6a8596b6395", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 5677245896, - "fee": 0, - "recipientId": "AKURdwRzPFAS4XhPUtBAqKrTrLu9LPqFbj", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fcef07fa5b582bf19686f0df769c110a74e2503fa653475b82f7f5e6faa3be0b0220647b219bd0b2163b6fa363b62bdfef06f2df6006325b878455f806dfd44c09e1", - "id": "2436864a65bb862ba864aaf5e6334bba91a7674a032abd2ad9f2a3895d08309b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 6558699223, - "fee": 0, - "recipientId": "AaNyZo6YitELcMW9SyWXiG1FVTUmrK39Zc", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022078ce2baec0753ba02c05dff2efe59dbb628cd279307c7bd7d884776f2c15f35f022007f3cfe57778813c908496b147ada7c6d3531111cee9fb56053d09099a4b878d", - "id": "64277b25a02735c525a4f11417772288ac3e71f0fd75c8e00d6f40e6a2af8cb6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 6900000000, - "fee": 0, - "recipientId": "AY3adwSjUDSKysWv8Ym4UaGYeqDx9V5a1v", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200cd7794247be234bb63d915a2c777372a89d0762c3c5299178bccec15b6be0ce022048130b001b7d24136435c148838e1caa6b176b98a0fa052314e408f26f81db35", - "id": "644fdeb9e3e870bf0e6558234075ecd9be5addff36f9fec81c28aa7c8ff57a86", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 7350752858, - "fee": 0, - "recipientId": "AY9k6pyVCWzkCNdnfges2yjGJVJyhLdYw3", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220216dd68a632f1f0846cfb628921df1ff06772d478185d05c20986ba09efacc8a02207ea5c3932b37e98b491041ad0169554e3145e06a03088ca5c4e92a6fb184c6d4", - "id": "00cdc908312961a8350276e109985ee2dc325a984d92d8ad64d60dafae5e1ef6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 7350752858, - "fee": 0, - "recipientId": "AV6aU7fieAyQQhMpjAdiUPF8w1SMujpVo5", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f9e222aee99a87a56193fc9661fcb15754e43c41d3a37a1104c063b8e754d37202200c31da497f5e8e84069c9265d816d5ea8c80591836ea68ce94b4cfad308c619a", - "id": "71788c698bc0997546b1c9c2da21cdc2f391a3a295193c61582cb5788571c5c4", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 8174205069, - "fee": 0, - "recipientId": "AWhKaR8aPiTxfMaMypQqt2LtfDEUGpB1kz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ce4bac79228cd04ad09239a51a423a4c0e3e0aa48feecb5de9d3ad9402b6678b02205acaba891280ef0fe4c1ea18ed56d6c0693f5a0d31ae9fd00e266e3dddb0c5d5", - "id": "586cf12649c475cf490b6f7ad6bda018032da30e87bd257ebe2b222391e932ff", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 8335753741, - "fee": 0, - "recipientId": "AW1BDJsPkEV6AUfZtk5js9RKqHYfjEnuBH", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009c055053f467f1571cc395463e23f7225580fbf5814d17756a7a421eb812c709022011f5a333a164b685998de4fbd5625c55a35c4a35e31643f8653b74f84d488836", - "id": "dba64b2e7c7f94a2afc083b73fe947c069070b534e442cd5958361ef4b22880d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 8793099579, - "fee": 0, - "recipientId": "AH2QuDHZFX3rkLFkFTBrRshjz9VAaDVu2z", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022075820ff7058679540c808d1fceea1033fef3c80fdbdc1f7409ad40e9ee22249b02207a60b839bb427497387c71965871304b2418afcc7aef71495b3bed16bbb87445", - "id": "fd79cc4dced6ab4862faf2c0b5cde19b3ecda72ac2453558001cee1e5f90af09", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 8930739717, - "fee": 0, - "recipientId": "ATiYQXzewAtwbKtNb8n5uoRpATXvASGu9C", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022043721eada610fccc21dfcc12eca7604854d55ff996a1aee8ef1b6ed6dcfc9c7c02205c1b63a8dc3317a90c41366477b12e6bbb4b26aaf1951546b956b2a019849633", - "id": "4b309d61a46af825c19faec1e116c949e0e4958bed87afe0ef3c81336e269169", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 9285850665, - "fee": 0, - "recipientId": "AL2DsLKiUjXFKBbByaLP1RsdUMeNyj8Pre", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207310e88bc29ed44d42c60cc2bfd8cd0cf41751a7c44a72d47f0ef597a312efc0022074f06ab9ddb0dd66b6095f8324a65d8e57841db18df7569427e3001222bfffd1", - "id": "fc59c5754fa17a47bb34b642ee71b99fff47e1cca8d877788490a6401c1f969b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 10062477006, - "fee": 0, - "recipientId": "AQjGegCDm4ig1o2hAmxBwWYAta74ZvS8f8", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022035956acc21b16b19f446509f805fcda6ec6aa5bb09803e9367e3459b05de6a630220310de9e98092f88787e9ccc503bf67439dcb47e4516eeac015ca5064c6c8230e", - "id": "96db83cae120bcee57cc27436207abb76202272b558e5fd7579fcda5f5f9f61d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 10090126421, - "fee": 0, - "recipientId": "AXhCBxMufzWdxQoGQi3ZPS1SQokqHr7SQ2", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202cda06e19276c0d76680c0fd5177c8e143da4863cd47f2ab4a9f9634abf0b28402205e278ca769cdafefbe74862d94df273382ba379ac0efd90c306d817951d75703", - "id": "f5a2f41b66cb6ddcbc7d68cefea3f5b884f18c2e981eeb8731280dad92d781e9", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 10400000000, - "fee": 0, - "recipientId": "AbDSp8xeAfoUR6mauGYE5P3JTDXXnWYmjJ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220684bdff8dbcd3dbee5bd9d98d630db30d6e285f82f06349cd4c85500d4e20fe4022049809890d215e9041fedaa8996dcacf2b59cfa949ba44d5b19bfc0aa3d993f77", - "id": "6bcee0de136de52f7fa27f7641d3fd661bdc17069f874c189b09593936b9511a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 10469786602, - "fee": 0, - "recipientId": "ATQACwzUT92xq8ftk83nm9gc8cDELLk1wt", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203261caf9bd95edc131e4c18f7c0fd985d477314f70b85fea340501934f6968f602202c0c225421471e7ca9ba8e1bf3fa38ee5ab35187ceb5f272c6eaa36b2fcfa127", - "id": "8a8a7657c453a4eceeba12235add5d02a27dcfbd27a82238e586e673ba2d8dc2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 10792241696, - "fee": 0, - "recipientId": "AaD6oZFiPZaWDgAz3NGdjASA4Lcw1n1yFB", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f80771b2256f6e642bb27369d356716861ac83bc0d779870055e53a362bed01402201c5e896aeedc8acbe608ec78f14b87c623069b627d5470d835f07db98dd3394b", - "id": "194ee2091f2dfe779eaa985ae67489ef6f4caef181911050d2d3615292eb9345", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 10860889308, - "fee": 0, - "recipientId": "AQr31AJnzbHCTxtVgbguzDEL5VLHUqpjhb", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ffaa693ebc94e479852ec7d47a90b96f82eebaf2c00b73adfee062ec8f764851022039b50274a148a43a23f7744c30cb00a370ebbd5d39a2e8aff5d91465f3b3a95e", - "id": "177f350bb7801ca83c881fa56256c9f9d63dd8b78d508e67ee74d8455852eae8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 11300031743, - "fee": 0, - "recipientId": "AKgJL6ko3BvdJXKdRDuZ4f9kAdvmNRiq34", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d2012faa0994f60a9e9ab7049c703e223de18e4b89fc71b2204fe73b17af9708022024c5294f0424a68afc1d2975f7d300e35a4440b937f49684ceeeeb64277cc0cd", - "id": "b513d351901d269acf8389af328ed20dd0146542f83b80cb4c3ba8f8a0fb9bce", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 12028504677, - "fee": 0, - "recipientId": "APg3XHNRy3pxHmg9jnbb6iSqq67dEyeup6", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022018b80f68abdc7e6940dca597bb8d24c3a6150c3b6cedfa85f13f3e73aeefb720022047f45325bb01e0d6b9f300a80b0b5b15d5f9f453b646dd84371cc23ed63186b6", - "id": "e19f84fd9f142d50860f6725a79d8c1a14b90e19301ca793ba4a1d13bed8ab22", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 12416758078, - "fee": 0, - "recipientId": "AJZA2GSpqAAjxCBsQS6ASjryGwFvEDz4wY", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022012701d828ce4db33b2f03f4dc42720189cb3e0aa82f48ff8e0284b3a4deaa0b902207a1685bd283e1c51c42002a8041c31ee518307c4b86c7f22c78acdd863cbb4a7", - "id": "3c75b71a126df25c97986d07402e8b153919ed29dd8e86ef7b5d232dc4c27141", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 13626793145, - "fee": 0, - "recipientId": "AHUzDz27ouUBRnBB8MVYEAjaEkjzfYxAZy", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207dccfdaccd0afa9d7fe39da6737f1fa1588cfaa83011f9913e46f9e0bc2d60f5022030b46c49b11c5513d7041963c76394f6a643f60fc9f76af2549ea72758d0d33e", - "id": "ff635c6f6988222c2dfe24ebecd0ce33f5c9310dda198657343c16d9c2c73163", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 13900000000, - "fee": 0, - "recipientId": "Aezpc3WQ487fMYKeoH5CxF3X1BQpG3Z1Tv", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ee21909eedef0a8e7c587263c5a6d8430dc487a1b96ed2d5c662e69c9cc6cc610220341bac16dd02f854fc19f9f3af37489c0b4f4035bf309bc6ef81f22997a3b814", - "id": "06f9cae8f3f46a0f3fe4f1b53efe34cc8c502bd1fbbb2fd15d52d8d0cef3846d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 13900000000, - "fee": 0, - "recipientId": "AUhaVctz4y38gYtk8kAH5iiHsUZJyiV9QK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100cc8a312b243e021212b170071f32ce4174013460e275166c9f17020e769de2c202206b71d09fdc88f4ac32677c19ccaa21408045e1756ac5d7ab4b94352dd21ed038", - "id": "e5a8d56567089b515a7878383ea67dea1690fb4624e8870f566848a28fd2467e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 14407475602, - "fee": 0, - "recipientId": "AN5fzWHTJm6LuJjU2iLqKyS2HGrz7n1awJ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f6203ac00161224464cc3c4ec7df00bf57446cbc9b19d96b4895df4a550bc126022059ec4181988c1f19ae9e790098d17bafffb2668d11b4aa2dd6581abf4516de0a", - "id": "817ab520c018dbf31f24790d8ca23e5f5c1f6e598cf204c58427289dd9c7299a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 14554490659, - "fee": 0, - "recipientId": "AWQzdRCybJwnWsJcB4Ux1ZWCcudmuZj29L", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f61c81d36b176998d3c00b6490c0ecc79726693b04f7f32bdd0522076602e99e02204d8bffead0b7adc26cb5245c5a8de9db29909a4982bc1d371db83e69e005864f", - "id": "397f2509d05348aa49de4a15f4d3adec5379ef12521541ba3388d2c73d45ed35", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 14561654186, - "fee": 0, - "recipientId": "AdBh5du8W41f6JXJxFVmHE5x97cRG9kojq", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b15dbd1e14d3a4ec461cf52edf840144bb0094e09e2a9d1b91f9a9669f6b929f022038ae77df2e975e856a57f656bd04f4fd8b08b11166503de53affdf50da0891f5", - "id": "39d14c1d51ac1509fc9dab4be8b3b40f540c12b11392fc7fb45ed208f0696ca7", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 14701505716, - "fee": 0, - "recipientId": "AaoM7ppRsH58K2ABYH1YxSyBKW7z3FrDpY", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022049720a06d232f1232cd8f09e17128721f32bac33a8b210baa322ff6bd813f5520220402aa73d01e414a5953260b79946172ecb53e02326c9baef65c0d6a80e71afe4", - "id": "6d93427a7be1230f2faed5c635893d0f7e376b9bf13fec2ebbd7d6d314bc7e7c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15000000000, - "fee": 0, - "recipientId": "AM16EJe7VJpQtFPkoYLyatgNDJmaoNW1EK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ab3dded9d9a320de89ad11a137ec45cdc6caa558b1ed312c2cfab6a5e73028df022050adffc944953f798ddb791b9f233e1503856f6c16867e06cb91fc18f503685b", - "id": "a9e8e4e49962cffc045abba3b6eaaa77f2955daa6c3b2bb62497f861e26c5b04", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15000000000, - "fee": 0, - "recipientId": "AUPFE3QxTSpq61H8T5pumPcZNBtxbPSCvr", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100bc62bb643a1344403854746bbae7bffc44228db69528c485a1bac9b44051160302207628f7a3ca9b230a77dfa13714572f0f28d421356288fce43d695753077173a2", - "id": "c4ced95ee40260f04bb935b7709c4a19c969b77311dcc75537165c30f43793a4", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15000000000, - "fee": 0, - "recipientId": "ALeKWmZh3XGjdgSboRyFU5p1k1BQpuriwt", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203abcccd1b15a9857f111db5dfbc65135ae361ff3548a94cdcf9d18f38f1ccc4d022064f4dfbb1a13e532ea2d629ba4a4d5cc85622c18e6f5fea4c5cca9de6e8aeca9", - "id": "110689874c1ab40dd0cdb8af84630a1b89074c4f751e662105017f5e351e1841", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15000000000, - "fee": 0, - "recipientId": "Ac9tpzJ5h72V7rCobsaLxeC2Y4aHmki9EK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200a67c0321177682ad46b56c287807a6c6fb3c68cb35e7fea4325c26b1ff3c3b0022038d12784c4b342b950f43dfc5592d57703c33e331e867a33fc0bf5d6243406e3", - "id": "3293e055b85c9c3a34f2099261032891a326cbd39541a80dab24cc4c5efff8c8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15000000000, - "fee": 0, - "recipientId": "AZ8hMVpGVT1hyHt8nonk5ip8fKFCST7KZ8", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e1d4503779cf4c4e9e90579b2de7eea38a344ae1d1a5be81961309118b13ee7202207b977b82d13e913e0f4f9f37ac713b8deb3ea5b752cd3495af4a00a99c62f853", - "id": "b1d086b1b1bdfb25160c121232d62f2246e0f2125f557f7657439def1a5b473b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15000000000, - "fee": 0, - "recipientId": "AXxBftbe7ARvVnaLTpXyY6bSWSnL1b7iQw", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022057b0ec2903cf6d7741db49ae7ed7e6243e2bda73f878c5ff93e78b9e9941169402201c199cf06a81408eaafa26c8dc6195f243fbfd193076df3ee362e502b555ba8c", - "id": "5555d7f9855671019c47805a4aa14c3054fd4aef01fa161cb7d7e3fc79388b0a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15000000000, - "fee": 0, - "recipientId": "AcB6nKH6ueGiN1ygXurgkdXUVTNGPrAiVA", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b9a86d98d13a708b647d00ca9a28732af3707ed3ea34b173e66a20340666eb9802204de9b88e185c87055b454f146b8472d6513883ff065ebb251c155e59ac56ce28", - "id": "3922852d56b26b389bb1cbcfaf3235d2721a9e65e72185946dcbb46e09de2889", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15000000000, - "fee": 0, - "recipientId": "AZJByMD3mzvS1ux4emnxrJbYAf2mEsS8bu", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e7c70ded41dc8ff70b306e5fe5a01fcbf38057d2a38875e9618deecbd5e1bef40220031687e7a7286f4856e056fb86a600c5fe06cfd05d1373ad451a8e33c3d7ffb6", - "id": "dd619abb201619f8e6361f54aff5d95ab8a45f1b75c866e86a68b4319094bb01", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15000000000, - "fee": 0, - "recipientId": "ARVv9D5LedrdyjyuLPM45ALNowdWZCu9Ww", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022029337e12c30c5a1f3ea0b17a53dcc263bbb88343f140765e5dd5b7661cb7249802206c50a6520a2b47313a614d9d657199b5bd22f6a58c10374bde951078ab66bdf4", - "id": "271e64895989fc542cee02a54399c1e8dfab53f596658a095d7f3818f9d147c6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15000000000, - "fee": 0, - "recipientId": "AJ6Swgm7ABDGZd7vdBuAv3xHL64MGSFZ1d", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220640d9872265a1f6b0649c593e9850bb77023c1122e0483e03924cc44d8421cab022063368396d31392bd0fce5b5aeb2d0a745a4462ee3b47bea7499a8bfdbab3e218", - "id": "b1c51b691bd763cf532b060f04238af305a3965f2755d3b8295c1145c2c78acd", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15000000000, - "fee": 0, - "recipientId": "AbiXRAWJQvtxiEMzVZm45Jj7dTYF6amMx8", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008a0d3a40ba64688ce776449872561a1887d272b885ed9dc77464f5e0e9044ae5022062db52bcbf422b12bebdaffbf4f207f0240b803478764aade7c5440b0efdf413", - "id": "4616809d23f8caeac00a90f33547db0d3c31b6d21dc0c6d1223a2f2b6f8acb9b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15000000000, - "fee": 0, - "recipientId": "AQd294jzG4M7snWPK4chtyrKDTGBN3xU37", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220073c9db4fff5e1b5d59f7b36a29d250ccd0c352d8e30f42d641c0aecb9fcbb780220304f3f1237fbfdd6feb055a4d193a2a24f3d78d36891f86c752059704cb87d84", - "id": "8356eea142b2f8dc858aaf9ab5038dbfc8f71f6a6fae25eb0f9a1e7b0c9c02b8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15000000000, - "fee": 0, - "recipientId": "AJ4WmzahkzX1mzQGQ2ASfXUwVNsTr2nK8c", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100beb99fe85584c1db0e164c49ad211ef99e09b62fecb4ab5bd388b82f3069a3b602206657572320712fa459da101ea422229843f65f7c63cd0f2ec86d49aec3895cb4", - "id": "d3e6dae3d4d3bcad431182bcac5dff365e0ef615c1bc44be29776b9b62eaa847", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15000000000, - "fee": 0, - "recipientId": "ANZyNXsDsx8pCWwodv4VBp5vQotCgFSLpQ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c1b2099ba3d7dcc366b013be5a09fce01599bb707d25c8ca4b8112c1fa65eb1a02203468b56d9ed1247cf21bfa67fd83307eb6c78741f51f24d5722033249193300d", - "id": "eb1c6fbc04b75fdb056432946f90715f02c4a1f3cbba7a1da1e11cf923d9c26f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15000000000, - "fee": 0, - "recipientId": "AGZ466UoZ8rmMwYqCobkJieDn5WnmuNJBT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220115463a85eedde299e2181968838add9326a9f5f11a066e2de1063372d96d2b102203299c9a0998b75353b474a383f6a8ee5636964ded2265284924a1810dc8a2e6b", - "id": "42362155399528b008cb1945e8271cda6ab8232ac38c1a9f1ba092722162d5ef", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15000000000, - "fee": 0, - "recipientId": "AQK3Ew5GGnHTyrFyt4fZRY6xobNoiWAa9S", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220232b18ce1bb8fec9f105de89b07be45b4851032fd57adb11227c7b408fe4910002204fc98352522425910dedc1a10876da390acdf2737a3efeef36afc0b77c26c114", - "id": "01899d20bf6bb2163d05c2dfb1800fc9abfd8fda8c708b313dd38c44eed60e27", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15000000000, - "fee": 0, - "recipientId": "AKLLCyWEnnsXPLxQ1S91J76WXL2YsgCxo8", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009b8269539e07b9055f9cab99b49218c0535124d99a366cba09a674a31371e82902203b6b6cf090facfbda718b53f181e046bab31040ed1a6bcdc702c519b2fec40df", - "id": "053d16a85becee53a301904de426d478499b1de157a9f15db98f91c4783173f1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15000000000, - "fee": 0, - "recipientId": "AZ36zcRJmdUJ64NvN1M2T9pzv7dLAWtp6U", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008a664c0db5cdf291bb0da5dd05b22a539f8b538286650c2f7dc91def82ecf204022035033583b9bf16e4b0e3db65b4125c567e0591a8c69b5739ee158b55f8c842c9", - "id": "968c02469edccfcc11797a12463cef24aa7ae281aa648854fbff46b6634b5279", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15000000000, - "fee": 0, - "recipientId": "AYhCgzBpHXC9kgRCu9FUyRpjtqvfqNSr4o", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f207cdc66a586a04eb9e7a5c777c4ea37434b73dde96b05a0c7ac666064d69c7022058eb07e5f8adac444c5eb113d25d09da6fa42e9f7a3a5ae778f479c953039610", - "id": "67b0005a47824abec015c2799d99ddb2036bbf932a36cf05db7575fbaee92098", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15155129039, - "fee": 0, - "recipientId": "AN5x6WfeFwtvyqDvpaN6C1MusAvSCzZU45", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f2577c3278f2aae85a9cbce9b581c9c094d2f33b2e8173ff6b4091a12008da9a0220753f0064d21a0b871807911194832c3c255060f3a6dd7730fcd6538de884392b", - "id": "c2f08ecf56771833549e92030bc839761e353fd88330cd7e414f9e5e33869b99", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15155129039, - "fee": 0, - "recipientId": "AcgtP5SQDHp9gjDwe4KPVVE83JLGwWGvUG", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210096dd68b49e599249c0d35342a8375ef543fa62670c6f67602e2415db4b788cb302202cc2edc7b1b318c4c127acc7fdcf34c7a5385d078a683cb6f10593272091a6a0", - "id": "887cc5bf0335496a821123b14efb9b9e989645f90911c1f7fdb9f44924c89f52", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15155129039, - "fee": 0, - "recipientId": "AU61SM9NBrBfiCVyJ3wYMZ73GhvGPcQhkj", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022017fa1b374e87bb1dcc55ed07a0dbd64efa5a148d5b1f3604b6890dc43ff6022402204a0e788d401f1223b27b4c2e0cc5631cbc92d1301827a53bd2d7a7ca411d41dd", - "id": "3dc4b91d426b88fff8d78258c20991afa63c247572ba06ea469ae2a4887a4aa6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15155129039, - "fee": 0, - "recipientId": "AJN82CKCtJ912F93y6mHEmbWS7ny1He3c3", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022042cced4fe76ea745f6e41b70a696a800c2172eaecb24c77845b35355f882dde402200e7a5e5cdcb4411a92bae306df4c01a3ff8ee5d53b6972518dbb1f50f768ee0c", - "id": "445db40bc02d41ea28aba75cc2069cb212793b0c202fe5346feb1ae304288c35", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15458231620, - "fee": 0, - "recipientId": "AebPWjx5BvurHauVa1Qj6nJD1h6h7hrnAm", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100eb671a7f10f305a65bf38632f205cc28f850d304e24d49cdcd19d7ceecd20b830220658bee7489d4555361f2d330fd31f59e146c489070c2522dbfb2009a3ccc5209", - "id": "0a6de5b1e8dfbccd33051fa1bcdba56d8f8ba2beef3c5ff7310620695ed8f7ed", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15912885491, - "fee": 0, - "recipientId": "AZTp75YcToEXwnZU51Meb5etPteCx72DCp", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100831c7fabcbfc8e4f0d7d093d2f80f4dc964bbbb7139d1f438ee539cb3e5266ab02207a4c930391f10a571b7047df2059de1aafc255da9225425cc09f6008e8b93889", - "id": "6b144c56b46f2d418538d2af9ba9890847b3073cb6f0d91c0dd4406402361cb8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15912885491, - "fee": 0, - "recipientId": "ANFaKygQ8EoZFiyvWi2SaRT8WbfwXpW21R", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205d825095fba54447404abf0c7721ebde7ec9d1bafc56bd4673eaa2146dd0c24d022029586e4fd33e94280ce99760eeeb4f12c51e2b068df63cdadc090dc5de09a741", - "id": "74f7c9d800d11facf0e9fd059069e0a05eaddefddc35e684c77f8bc9c6502d45", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15912885491, - "fee": 0, - "recipientId": "AVbpuFDTAyRmt1BRakzWTJyuokTRpBbeqo", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f70e2674210db0cd7ab970fd8b58cb86da605ff850284058d8d6803668950ff902202669e91f8004f9ad85b19312539eb5b1a393d9ed101659980656fca3a7f2b978", - "id": "d828823d3b2287d38edca76dd4e83a88557b2b8da43475cd6197ce16c906834d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 16670641943, - "fee": 0, - "recipientId": "AG31y1h83VJt7MUvv4zu3ergGFqfpUpNkw", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022050e9976c6dade3e5c5e365ff0f4ffb1990ff83e6613015559439c18e62395ab20220083ae7dd6567213a1ea0d762c24af46f8845080bd554f57e675b501c30c11ebb", - "id": "85df60d54bca2146dc642dd2a2bde7ec60c2b00ab7868b3487c3e4cfec742385", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 17079830426, - "fee": 0, - "recipientId": "ANaUP88ggMTde3BhtTXvm8N3UwSLADG54e", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207e0f782747a7020e5f2b0c72ce0bf366bf43ce2b8016c937d376adfd583aadfd02204607186b59392cf5d7899a8f020fb7298d974dadac28f3beebe82cc58b2843d3", - "id": "4a78a7be1bb24b6b44a6d8d20a5be158edb30f7e33028703a01488194439628e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 17300000000, - "fee": 0, - "recipientId": "ARUNkZzsiJa8YECfHbTxiCGv9vrFLZcdKN", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d143d7c5f2d41212209c85a3f762dff3321fbf3e766b6746a9483e5136f62ab402203117b6c3c8fdeb69dd8779319c3652ee0390e3ff8771cab0fcf18512e885fd18", - "id": "ebc1f86a8dfcb7ae369e124628a80298b868939e410a2bb5262c467b43a21b3e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 17300000000, - "fee": 0, - "recipientId": "AepyttoE4qxeaX3Q6tmhvJmhWR4e59UgNN", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220100a5efb6722cb9e96ebd5bc5af40854bc765e7b68c5d42b56d7b92e48c32ecf0220428e3ef95633e89d1b125fbc8c75ffeaf093971b70c553722232e464965ac6ae", - "id": "3b6bb91064213ed8006dfbb57a7aa9fc9b92acd1ff152625bb13c84d4a1c9fdf", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 17300000000, - "fee": 0, - "recipientId": "AK1DoQ2TzXwZFpqRuuLRkuMLtxvnwYA6BN", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206d8e23fd7873b9b3b176c2f81ca68bb8f6a39e86f48e01afd58f1d72b2f370170220160f43117a81dea41d0bd16bca567744b30a0df789d4cdecf1b4969f0de5a16d", - "id": "f77518bfec4286fd33fb36f0c6bfddd86fb51a4394034d80f12616b9c839eca7", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 17300000000, - "fee": 0, - "recipientId": "Af2dxbRzquQbsEDdc6YyK38EYoa86bLaS7", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022072d8f98d2aa1dc1ea479aca3d4b3232de3619674c0b484b4f821394ffb91663802201ef857234756b2c4dc090b32375a399c9b9981c616d4106ce35f18b55e7883a2", - "id": "c05281457bb1438b3a8dd85840f6aa8a4e87089f8f41e3243ca146f1ca406836", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 17300000000, - "fee": 0, - "recipientId": "AdgRuyVNXHvKYyqfTqHNN6FL8nQhFuybe9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203fcc0e870991a56bb59b4d5e3a8be7efa5a07361a34c19802e4b7310bf2a79660220281eee0aa154c8ceb369173ba099b1cf0a46117576dd77d9d30e0bbe7cdc55b3", - "id": "bd02783756ed0a83080748833bd610847e7a54be76c138b07b417bbd09589040", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 17300000000, - "fee": 0, - "recipientId": "AJZcbQZWg6yk2nZvxpuenxNEg5vdNfP7d5", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204f2170f03f42e1a6013ee9ab7f585e420480fc72309e219aa536de5a1eeaeeb602207b5c6838c72cb39c48357df2419b569982eda8275bc4662c066faa7b390dc4cd", - "id": "3742052eb3b87c2e55476c66c85fb7d6f71206ef8c3c94c737a382576f142746", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 17428398395, - "fee": 0, - "recipientId": "APGnKfbcBc7pKjbSWd4dqYbC6zAS9UQn6u", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a9b09e31f0cdae58a7f91e18a967e12436dcbb5dc3e56304e4803d942cbbad7002204d398385e1776bb0ed9f1cf6325cdccfb8bdb64a78287e4d96d18d5754bab1cd", - "id": "f7bbbad0d7ef708f2df7af6116907e8b89d34348d1786d22687f6e680e70b918", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 17428398395, - "fee": 0, - "recipientId": "AMBQecZh541er6XkgwPgZxk7fNLWUDwjXZ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f78352db270ad2e970789ced7fb13b976f20d45905cf4374d9ecb7a7b89a072d0220634c8330932815d3c89aad1f22d74f4305f9a0209279c3b5b5e849a573b763ac", - "id": "849ada089f0422ce85f82cf22cb73ea146af98d1166ecaaab0f772873f854bed", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 17428398395, - "fee": 0, - "recipientId": "AZHYssEeVUGz2WkDiWWkjefoSRcmNtKcxj", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206cbf14e3cb952df65c1688fd79bb6dd657325b21dc9831ea4545617bd15acfe902202e828910f28cc99a91b1e28c8000b53c5389fdec3920c502ab7c2116c11d111c", - "id": "de2af52762d16398e677a58eab98730dd6ea3fa036b148fe8c701da96501938f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 17428398395, - "fee": 0, - "recipientId": "AefDEneWp8sNsesZ4aQkGk91vKWCpMm23n", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022023939f4888ab00f3e2c258fcb8671a70a8b1c25a2eb52d610e1efd91ca5f813902206bf4c893b636139551282d0274f6155df35e46688974c5d9225dc1e3c7ba2230", - "id": "dfe1495aae4a5c62976804ff5ecf1e993416996f4cba9bf1df0ab0795ef5005b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 17428398395, - "fee": 0, - "recipientId": "AciqQathcu91PZkK7wiKqRp61Cddop7YwY", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201b8ecb50cb16def362f572efe3385be176d0ffcac0aefe6f9f378d5e899e445d022062907eb7d5381840cfcd021a1c9283dc4047a61e76df88e9cecd7852ea63e3e4", - "id": "e86a19a03fadada17fa359e563c25ebec320915ce818f28bbdb3dbe7a15545e7", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 17432660696, - "fee": 0, - "recipientId": "AJTnGpoECgBAwkcWJFgxNAqq6BNNwQP1hm", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022045f5da273f2e2f227b3d422d418e3cbf3816958282d21131f3ec2844c9cd76920220591b8a380ee924fd2550a1e52a425fe3c7f185448347c119d2f0d515e15135ee", - "id": "aedb2f45e57c01965371534c52adbb99629ba581c788f7597da354fd72a0b885", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 18380568436, - "fee": 0, - "recipientId": "AUWioz7GLb9wrTXGMLVMGa6X4HytaUz1mt", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202dbb34ce6baa94e4996bf50310955636c5082e96db5314804af02e4c446846810220333215217bd86424975be8033217fb1d74b5897ba9cbcac196efa9006765ea6a", - "id": "bc0efb1b00e63694849e719ee3552176f4dbeaeb943910ad34b681b8250c0280", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 18726879545, - "fee": 0, - "recipientId": "AXJ2kuVeuwa2MMtc9XQqe5VBfxKgt8ZAsy", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210097fe86ad5302cdc3a189eb42fc873abb875e7f3c4f47b4b5e581e04be5a37a0902206e8a1fa9cdf78cd7d69d0e12059709f4c2301fc6235585db9dd8d638e01a3a3d", - "id": "a4cbe3e424ff70728cfce9f31324b8115012bc47293d480f62b05228969396dd", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 18826504375, - "fee": 0, - "recipientId": "AaPfmEsY8yCH9UhUdHaWr29UCruPbQC8EK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fc0dabf71ef6e74f376b5c646ceaaeb09f65c47322096e0d130e69463bd0a32f02202b52c16528b3106348834e75e68137fff3908755171c8ef89ae44e480da6d774", - "id": "79e4c62a158b1d95852406021ecc176c2eae643012071320c741c472be24ef25", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 19758347933, - "fee": 0, - "recipientId": "ASWwdLfs6zYsAnQB2MEVq2KVhbtsuuWELk", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100af87163f52e7bd36dd86f728b18360df16d9d9f499acb1709a0e365080ead6730220016e4040fe172f041da4ea90eae432d28f8fe4f49326ff7178f087eeafd52945", - "id": "b60e9a8a4229478192e1bf5df84df85e009a8517b5add54ea0e779550571515f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 20185909534, - "fee": 0, - "recipientId": "AXYVmQKznY2qtzpryr19zTSjTbSkfHd8aH", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022062ddc327d35dc5a02d06d6a91f9303fc340829d731a2ff8c71e868482c99d70402206c4bafa555098c358b0b5e68823b103401ecad4a05a65e5a49176ba0e435d09d", - "id": "60d339709c06fce066b14b06536b0afe9d7d8f0cd346da5763240fa937d2b7e6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 20235049486, - "fee": 0, - "recipientId": "AeR3975uH4kfYydrwgLQgo5pWkmJUww2nm", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204e06a134e0545f41c5f3a6f7f54881ae07c5e7791d23a7c9786c3015fa5fd4a60220422553d947eee3af1faf66e6e80119511651d5a2589d39c34d7cee4daba94ca3", - "id": "8242c9f18a6fa8535be6511f8b75cf6cbbc8da6cb962f8f9a0beeb697a95ecf0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 20301994953, - "fee": 0, - "recipientId": "APSfK5XyawPuumG2me4ovkwDPKCSx257gW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220789829516e896e6f204699d632176feb9a721d69bc3b72392ed1a1a7b787efea02203f736d9ffcf9ff0b899d7ea648d1b74e1e938a4fe26cf3c8c6f556b0fb4a4bb7", - "id": "e0ea1ebc9da7c1a67fcee0b06203e7df1bc6ad83444f4dfff4fc37ae58f41c2d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 20800000000, - "fee": 0, - "recipientId": "ARwCmALF48ZWiY9cCBWqhCV6PkFbp2Bre9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210098dcf23f4386de84fc4d75258d22469d2bd67017fea3417396393437d831628b022064427eb68be7fbfb7d034c682b2e5a3c0a740594da40843dafd4fc8fe1593528", - "id": "9c76e2b23ef60016ec4e1e54fae90bdf727172be152125e41fce7a69fb04f73d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 20800000000, - "fee": 0, - "recipientId": "AUGQoqoSkCGdT9gYPNsuFumhksQBDjFLeS", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022071580d7f06e5a33fe8e140208441455af5cd013853c94fd983c457e34685960b02201d7c1134e7c3e408b2dfdd61916e8b1fcbce9fa3e5539ddbb00ec47c424bc510", - "id": "8f444d8c999f8cb2a73f6b48be6f497b0230b4956ce62bc3c2c646367ae79d79", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 20800000000, - "fee": 0, - "recipientId": "AQayPyz6AWMwY8RPTCPeVhxkr8hNuez3Qi", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022045fc1b2a0389840a6e8495f0bab89579c2927936bbdc1237f56b2159ddbb152802207f2216ae4e65f848f96a5da8db61a64c7b0ff16a973783d1a6dc93afbabade13", - "id": "805e65bf89a54b7bf5043f510d74c9bc89a8fbdea7fa741a68bf4427bab5caa6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 20800000000, - "fee": 0, - "recipientId": "AGahFaiYodwt82Qi12rt5j29p2C2MeTLBh", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100897790cf4bd81566f48c2ade97bed334735704f19a67f8f9ca75f53c60756ad30220468cf778cb00ad16e4921c2377a06c2ea762f87ca41fc55e7864fe1cf18b841d", - "id": "133692fccaea85c45398542c5d4c8ac7971d4882764b60daf649f81a3204c49f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 20800000000, - "fee": 0, - "recipientId": "AUPkqi1hRw1Xk95PU9DmKn489PztyNjRYh", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200fd59320b0f0962b330c012ce0ebb55791d59ac26ceefbe0f89b140ffab7e5ea02201ace6578816b4751dc693f4894e04c25ca654e9f962d7f7ea710cf55a759df13", - "id": "faf85b52fd458c9be80059cd065cb328853cd66ebe35bc2f0c76160e271cdbbe", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 20800000000, - "fee": 0, - "recipientId": "APuwwoc1Btsz33vZNtuQDHNznD8G8CHcNY", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206633a9f528e3430e1ac997eb95252c483c94308a97462f9d8d8b6175e04efc9802204cec670befc7b7e2445aea1ad7af8d300a0fdcfe5f8e185df47bf5bf2918b210", - "id": "886bf5c983e9f90993a7fbb5a50064a6c9b32db2408d09561951578a12db73c1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 21622003904, - "fee": 0, - "recipientId": "AavfBaCqpww1LarHdp74ayFp3TSVZ9QHdu", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206329d87b5ab1bf32142a5688d09638ee7b80b79109350e42fca433dd4de0170702206d27e82dedb5ec747f7e16eae5c35408ad6600c0a847c130c615c7cf2875ecac", - "id": "3ac9d7d0173837c2079cfe16d4079d1f960ccbd320ecdfba026819239c4659a2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 21819296752, - "fee": 0, - "recipientId": "ARfsXLuowXfLk3pWNrJprdbn7F25hwMRYi", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207289896d987705b7a0be5edcbe197f61cdf28efe3a0844bcfd70f1f1e36f3bfe02203e49e3d9e01428c39a8e5966851fe94d7b798b4c3c6690be3a098f1ecd16db17", - "id": "ccfc33a398e393b8abcdc28d431fb5a3b4753b15544d58864d7a405b828ce957", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 22277220240, - "fee": 0, - "recipientId": "AGaMNkFFH7n6bXwKbXXEdfuDCN2JC4JMEY", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204e619395ae8cfc6dadcea3a709bb27a014c8836092bfea565ba8fa40c5fcb42002200b46a3a4503971b4238fd849b15a40a927945babd50e7107e205d9fb40bd4110", - "id": "ee656950500341fe56fbcb6b720b120a5e6ad4eb5eb75a2b89651b0526cbb782", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 22426664055, - "fee": 0, - "recipientId": "AYL4yJL3TfEafvWh5abik9mjrNGDS2N5ZT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b94073a33031731ec6ca84bebbb2e63e45d4d0c509b885684b7315d769b7cb7b02202e0662f659c239b2a69583fde44eb38e8650eaf91a9edfce4e9c602106fb33df", - "id": "b5e89bf8f85d527e891b8ca3ee0f2a2e24a1daf63e50e0ade2d791aa52e03b06", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 22493303746, - "fee": 0, - "recipientId": "Ac4V3AcXoBTb3gDXkBofGd996DySEZ8w68", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100bb49539eec3c2ddd506812379d6d9a126f3cb252fce6e918d72920dc389db7f40220135ab2cb8c335ac8e2b7fb563f9b3cf5ed4a3189e4ff9008871b21765def468d", - "id": "f418f20dd6f1c0826b102833e01fee05ac5eccfd3c69e70c6d9694c9885fef2b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 22606906279, - "fee": 0, - "recipientId": "ATksXZghzmn9RkctvKrpwPEctjEFG2s6Fv", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206ca341544ec2f0047a0f1001838d1aa42c0d94b49257034e037258bf09d34a2e022021c6958774ed74bbc8ad0fc4fefcbbf3711bfa0c0b47369fad575001fd3d7df6", - "id": "42e3bda812617277293b0efb08d308dc5494e47c5823d088e1c0520d2082ff57", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 22720508834, - "fee": 0, - "recipientId": "AKy9y4KXZ7XhtWmiodsb3mJSE2HH3H2VtS", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207d201e258c9244f724e94f5764513a16a42dc2aeddd50da09db88b6fac5919350220437202432b51c67ed7538ae1af5ee3445093d5fe85ab500923b23c866a4e12d9", - "id": "54a8922aceaf439f3efc4ebbcddcc60adfff7170351c57fb38a3a23ef2b6e1ee", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 22720508834, - "fee": 0, - "recipientId": "AdQTTtT1HGKsAuGzs1mgqBnwXHtMVCp6MJ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100df406f87bf59816e855ba7749af423879a850e20863ea5bf5e0ff96972aaefce02201a50f1f35dedc824860e5785dbcd6b49eb09510df251b5be71d4ec1fca16e546", - "id": "7f97907d31a72371925ee8ddd94f6c9460f2d7bd837533245c2aa41b9fbcab20", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 23338898720, - "fee": 0, - "recipientId": "AJeeb4cmTjh2oKsSUt6b1Cted554SrkCuE", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201500734913f9fad425d61e07ed00838e1c1e8171020c25dced36849b81be9da402200cf05fe867256dfb7467009a78e47ffc001eb80835413b4c558a465cc08c048b", - "id": "888fe214344f8d288fd0107747d8bcfc1cdd1baf596c75a1aa493b2e086861fe", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 23976819323, - "fee": 0, - "recipientId": "AXtJWNWJctDDFkwuYC3J8CNBGNJorqs5KS", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220678d7e0489942b5faae8fd0cf73542706f700bb4a9ae7a7037f1f13a64b74401022073f32ad4ca5b3a8ecbf843d645876656ff46382057586a85909c8454261d829e", - "id": "d7c0a0b53885f500999c7efde8b6f2dddd186247bf94f0f9b4a1864630d90dc5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 24200000000, - "fee": 0, - "recipientId": "AYet9i4fohv9fYye39z6TVkTkdAeb7g2Gm", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204382461f91941863a5256166d0202c684e4fb1ba39ac43eb7cb432c8b0a90a0002205ad3056fdf794935c28e94bab65673c01e51154624cf695331687f0a3974b420", - "id": "a14fddbb3784cf2bf6491f244fc9830559bc8b3fd355decee085db44c9953b5f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 24200000000, - "fee": 0, - "recipientId": "AS3b7yzfnNX97TLzWm4ez9GiAfkbzs8WTa", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022075bfdbe554fb74d09142042bcde603b6390903a8baa2eae9995193f87bcabad2022048a005a2d88496da6de06cf027ec78de4563267a8de12c0f258580d1e2d44638", - "id": "74b83c00431943cdf0a97d5f801eed6045c1f57e10d0c07c5437954b4b811efe", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 24748325720, - "fee": 0, - "recipientId": "AGUdj5MtJ4HnmcAFtdd8GscPBGwRC4hzYK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008600ceac976e10082007b40015e56d19d6924f888e6e620ddf8ae114bc877b5502207cc0afad875ec422d817fbcd6a067ffce41c013d6d971083b52389ee567726d5", - "id": "a64ef1a8982ad70a13440e5a901066ae8bbab1b1015113bd53a48c14e886d2b9", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 24859867470, - "fee": 0, - "recipientId": "AVu5QHc9C727s3wXJACZyvFRc9XJSiHkHs", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ee316c58495cc4729ad60d451d129d7a4f98574e764f8cf5bda95050e1a8c79a02204ba8d962c6128d528dfeebe64156e7ea6aed5b4c98f468265d5886066c350711", - "id": "81e9ca6c942e14621b6c0de8ca5deb8200114cc8dff364ad52e541663095090e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 25052610401, - "fee": 0, - "recipientId": "ANmAMut1Egf7zK4DBHbaki6tv7dzgsEzBt", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205f1aa6c3bc84dc585915658e7e03bdca6b05307a86df928cac71cb523be7510b02206cdad96a72947eab1a24acd55869a8888c12252583e3319ce11ad2de65f64857", - "id": "ea5534e532dfed08d41e0c0668e5b1d3e1aaf70831ff61c6afc65562580a40bc", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 25157514204, - "fee": 0, - "recipientId": "AUncJXmGFQDzHE2XWPWEqitaQg5Azw7Rux", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220354217fb3a9f69b30e0c74b86c3474260e276e4553c0dccbaffa5d2eb1101c5702200b9dfcb85de1773d239fa99288959577030eba8f3908a4cf2611d52c5f5e58dd", - "id": "bb609aaa336872e1a90049e64e08b329ba0e9b1b155b39555660f13e900cc5e6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 25248444979, - "fee": 0, - "recipientId": "AZ5MTXTuHnMtZsgpZJ2zM9B8gWojkpen4A", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100892b7674c9045e60026206aed6c6d8ca9fea571c02fb63a3d852e26de4d9aa1002200f4c29438eb6a7ec035105771370937732a0e076fb1bae458d42f6b864784d0a", - "id": "9e7cc0e06c0f91878772d1f3b3ef00fa270da3087442baaba6e2ecdfb1e788b3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 25763719365, - "fee": 0, - "recipientId": "APxxDqpuPch7PfMZ7611osF5bZYEyx5UMB", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100dafcc214d6f27318979493288f12f50e61a1398bc4276ff9e559dc2d00a2e61b02206b173725cbca509a7d26ae49ab1b063540c8d75843c887ca1e0139029a26d395", - "id": "b838f9fefc43e5780733198956cb88817b6b57ada2f8b9351ddeb38a1b1b4a13", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 25763719365, - "fee": 0, - "recipientId": "AJdxs7TGgcizNuXVMYgd9JaXpuyKe6fF5g", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008402e0f1908c2a7a75474b3262ec6a6b492cb8d63d9ac0fefd5e7935f91cd0bf02202e6225f7b03abe5f580bc1c7d7a2a33070fb139fa22122fa075a70d912fc7749", - "id": "e93052fe6fe08457995307ee8c843d5293f0d62d3a644b4613af01057f7b4182", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 25763719365, - "fee": 0, - "recipientId": "ARjehcSFYaDpcuEnZ1iPquKMnq7i3sW8Yd", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201b094974dd39f06be93b8fc08eac96a942eba37a5ee4aed9b38b4c4d5e85414502203470bb9167f1a5121ae1909a3336caab615fd947a9ba464ef4cdc0ec5efd6182", - "id": "f9b86470f90ca95e6ec3dba7dcf43a638992d501595dc2b311354b01420267f8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 25763719365, - "fee": 0, - "recipientId": "Aar18iMBogeroCZw8S4ELPzeLDuvXoRdH8", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f884dc287f4e68750c622c5cbcfa02efd10ef032e95e3dd5163fe0709f331f7002200b8fb3fb1c0a21467618f265d012a2d0094d62b6b95c5a36e77b1129d295033e", - "id": "7dce050a4abc7ae6ada53d03e78ee7e42774ea2dab60a084cc2f2b2a3f77cd4e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 26000000000, - "fee": 0, - "recipientId": "AXbPyMxJTmQ2iN7qoswFQoxAfZWW3wZj6t", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c343b8c44441d845cd4a56ace540f15ea2445b00a22a350a70f4694052480f2602203110b618b42594b5d8e148f53cf613b55d2eb83685120e40eb9b8f2ca2ee36ed", - "id": "78688e06570c4b2ee4017450f89cf8531cfe1ec31a5422887e84ba2a6a21427e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 26000000000, - "fee": 0, - "recipientId": "AJbQvAY7LCed3KXVa1qxJiySXMKWRrLZ5X", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022045b6f2b658a709eb8b9ec4f9d15839cfe270ee0be5f96e6550a6395e0f887c2c02201194477e971ebaa8b7b8dc4f281f2cf1157960905618602c060b35ccc29d8c0f", - "id": "1604c3e03314a5a83519482df25366aa40aa3bcb3738d7eeb42c177bd1a38b08", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 27559966014, - "fee": 0, - "recipientId": "AXBwNDce45Bw5upoPTup7NUmdhn8NP6D12", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c3d6ccd2349a07f0a94d99292863b4c40fd1fdcb541dd15554131b6f03b5c427022028e5387876964b386a74c01ce79c9435ae71b6690bc65284f6a88b6e313498ad", - "id": "cb5a0d3fd3c4edc2414b8036df50caf75b9b8c25b1bb4b645b368291c8506cda", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 27700000000, - "fee": 0, - "recipientId": "ASXb7xv6zz5N3JVKzhvfLrmZHGGVETBvSw", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ca228022c4c0932b3b548d1c3262894183c12f65c56981b54365360acd175db4022037711473cdbfec5110a4f4467d2f4f847cf8e1424a70bd31ed391c11440e4cbf", - "id": "1d466dc4a218dce9c63f753870cdd645e994c9af33ae0777596bece6fd95bdb5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 27700000000, - "fee": 0, - "recipientId": "AJMMbNCj4gMpfne8rg9QezvdBF9zxPfysh", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202ddc599782c761e60e98b40880fe924a162495a916e30b4fb7e119b5a0ed0a8f02207429cbe9b1e529682b78c2e30e8269673845621d809b9b0393b7386e396e0378", - "id": "a0c287269d928a06bad77dc7366afe8579308331b10f2fc67b0c249edd5652ba", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 27700000000, - "fee": 0, - "recipientId": "ATj3133FZRJqKK49nScR4yZ87S6BAWdtZm", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220690493de80d6ae99cf3108b18cbb9ba0b18d9c283f65d9dcb8158df40623e6df0220376c3e63badab403ed5bfbb298622a9449b8f40aa93f797b4678fb03a0615570", - "id": "7ea9ac0687d6c936dc61a9c6a8c131412cb973869a7073b7a679508d91243917", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 27700000000, - "fee": 0, - "recipientId": "APunbT9dgTkTpqpUAqxHHW1GvQ6pNzaTHL", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100bc128ca47b50617210c4efe3991eea82f3cfeeafce7e3ee464acc43c6962fb4b0220434e20c12c72b9e6f1cca4b0f79f5f8023cf054bddbc4e654cd195bed26ad923", - "id": "7fd55eb9e7a1576beb9060840cc704c3db6c2022c904d6ed4f6fd42bd2b94b96", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 27989653191, - "fee": 0, - "recipientId": "APTFQ7bZpw8n13J5v5sbgZ96YpgqbdYsNj", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022045ff469954bab872b82b892d9cc5422ab3284fbcb4976af1fe34abb3882fb18b02204ec503dd4f4491143fcd84a875b6ec8fa7aca68b2e8f6240cf5cefbc281538be", - "id": "6941d8c3cb4a3690680b6af7656f683e3f4d7dc77a8ffed8ca64af9ec501134c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 28721448453, - "fee": 0, - "recipientId": "APjsYt53nwje4wv8sBUJkuJPgHYfkJrvbr", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a5fb78077c9bd963201b4b73f26d1f57f9ff804d0e56080d7d5b11365b97218602205fcb7dd7009b4fc091cb21d8fb32c3b20ba8feee9eb95f19038caebaaa1b3de9", - "id": "653f5e251e1fa91014fc5d5fdb5160f1aab6408bb8e62baeaa69733a9d11b847", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 28730083421, - "fee": 0, - "recipientId": "ANPpsAJ5zUvsFSH89FpiuKn3HSE3F8MrvD", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203d66184dab85d76f32d99f406814204822417081b933227d247eb99aa5ca69420220470e38f361a771362db029ef353e384f002982dc5a40bcfd846c0db84d413576", - "id": "24df83ccb61485f2694a460efbb8ab77b38d0587adc4e48855ba4c496195a2e5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 29339140141, - "fee": 0, - "recipientId": "AWwHvryaqeQv7SsZVysNaG2xHQD65romAU", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022037e16fba790a42b0e56a0e7b353fb740eb499278cc8b9e638209ba06885e27f7022039d8876608f1afc24e7a27400844b4855e6f6b05f7fd2eb45f682760efcd5442", - "id": "54ec066a0475f3d3bb34b431aa58747a246a1e8513c6d295669f0738ad5208e2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 29885914464, - "fee": 0, - "recipientId": "AKWZFvNtkFcyp9qCd1qoaA1XHTCo6yumHz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203dc53e2d991bc80bfe7ef58bb5836b1016fac072bb04dd8ea307c675fb5fa86702201e4ca6d94cd78e647c9f1796bfe6855852a1b08d24033e31861cf4769da707e7", - "id": "882cb0fe98bfb862e7c1b0c89fa209cc1611691a92290ead9bd049b38fc69dfb", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30000000000, - "fee": 0, - "recipientId": "ANPjQL9f5qA6hiVgntKsdre4hRnt4kVXqb", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220641e29b2546a81aa442e6b13f7c6ca49cb3fd6ea836a3dcff16f9b8ac88b30d602206804d133dd4ab791569c95cb6db82d9e9ae9e8774ebb14be8de6a9ba15308bbf", - "id": "a1e0e700abedc3d7ad878be06f16cd2d565074462d81a731976a57411d1c4d35", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30000000000, - "fee": 0, - "recipientId": "AbGe4yigaf5FgBd791PKMeRkysFeRdNUJ6", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ac923911201411e738cc3d738b588fcefc6809d1cabe40042fd145624958f32c02201f3f39bdb47e5ed315cb3d88efd53d7f7582370261ec2956d1eadcfa33e1d560", - "id": "99992456df9d1108f11876975230e1f47bbce3defecb092aefcde7d015863426", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30000000000, - "fee": 0, - "recipientId": "AGWNji5TSq8tXMXK2JftSbUuytzkkUszKX", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202ed1f7fadf1c77665beac7333f23ea2afe3968219944d538a894fd5763f7cd320220637dbe52b04f82ca4f340695b9b77e939d6abefbfc10bd928781abdfe0770b59", - "id": "f11dcbbd114f6d70f1b90c5a54bc4dbabebe788ae0aab1473b9464d48686f0c6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30000000000, - "fee": 0, - "recipientId": "AZTfaXxi8ZEvtpvZnEbdJZaajFXqCf1B16", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ba7d814fe5391cedaf1eae38c14557e7f7842b0bb618a2043aebf040c10c23dc022002780b3165d68dad87c0dbfe646ca1e11852cc09e8f57443787b3fb4ac636b1a", - "id": "1ac2891f76ab45cce0d5297e9d896deb831ae644968c4b7aacd3c22ac3e2cc80", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30000000000, - "fee": 0, - "recipientId": "AbEXWz7aphvULaWnTs2LMt8PTnuvFM1tcQ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e5b9e4859b7541fd99124fae2704d5ccb01d9fd424168d931dd8ce7feae9e55b02205faed9d0716e2abea81cf4748db0189c7cf802706087f0570add7399eb51465d", - "id": "53ef0aaa67a4d02eebff7a550715542501d59849dff9ecd83b1be58956403276", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30000000000, - "fee": 0, - "recipientId": "ATHcSoKCMZzo4KW8ukygbkeJjQ3Hhdm1oC", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100cda20fa0f3a07fdce9d0b17acbd67703863c40311ded26bca2411ab6ea2f03b002200fd03ec6c9c62e33aecec9f704b7bc5a409cb727cbe2b43e7a9ff7ac894b7e85", - "id": "6038460b4fb005389c6df2e4e1513468063fe6ef332af5471e7e47390e09f7ba", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30000000000, - "fee": 0, - "recipientId": "AKrAqqmZ4SfjPqd9UqtbMoecpHR9tCgmWh", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204d13a7b0c8f6267c5134f40c9c03af1e75eced936834f100607ec8785b58b9fc02205f99a3e0133114f48a42f0eab3e1cf9546b2e71799244e31f12470eef16a5af7", - "id": "4727130dec5138ce4720b7c347fdba334c80d638549992d58e62d8ac6bac5e56", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30000000000, - "fee": 0, - "recipientId": "AJNdz4hjGwRxrt8CJSBzsqzTHgyBUmEkp9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e0218eb720635af56f74b4c3f531ab1146764cf082d9c934978c3cbf52a3c65e022041f23226a14f86a8893cee1ef08bbc8521df699ceb6e3925dee5ed947b06d70c", - "id": "9ae2cae32a3895d6fa5f6b7f6b36b21416a6fe14c4782e386d5ebc0831d9985b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30000000000, - "fee": 0, - "recipientId": "ANWw5vn73Hjh6pLHztyWjYvMiNxYynkbKn", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009a7f5002efea36c366ec5b7afe37b22e12a72d59b2ff43626ecbedeca83a14e802206ea4127d8d15eb80c28905d5047c16128a23ec64e9f25262345de8066e0a31d5", - "id": "3735e0e88737e8ab56057b4383d091ca5f0779177d5aa95da30cf0d8a81aa96f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30000000000, - "fee": 0, - "recipientId": "AcgKpQ3zVCN4St8seZaob41Brk7zpBbyF4", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220455306c09b4bcf68b3d503c3399d266ccfcd7355014e1edfb600e17ec67e4141022055e7128f5c2caa7b564a08b0dce9492448aaad0e4cd093b603e61d245b27fc28", - "id": "d4c0238a3d04e69ca8e2ee8ec3b8da3a41679ae8d131a1012c2cb300c4a437b7", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30000000000, - "fee": 0, - "recipientId": "AdT9uerGBa6ivvJ75gGJaDYjXyPXfGwJBF", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022063f7821d3d906617f9d60474e54259e408ee9f88c724ce5b40455eee8701042202203d0ca800bfc80788ed4888351174f6e1524b7ea63a41f222d770f305f97a35f6", - "id": "aa97fc714c3d8c6b5f5fb76c351b81e4e0fcd263b90597a72e94d55cffc14f2d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30000000000, - "fee": 0, - "recipientId": "AQ96VLizRnB1RtTb4voazDaMLB3VYKhoiW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203c248de6577db8045e71f536de61b935a3c6a2dfbf9ab80f92d810a31fa34b9f02202484f612bc171400b2b0471b6f5820be3ba8291031740e2cde5547948bd25f65", - "id": "371d63607d0af6c067a50dfeb58e56737e2636f4b0b0ff98aecaa44507a73f16", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30000000000, - "fee": 0, - "recipientId": "AZEYQFFZ31ybrZ7gcnt7YtJb11o72HcVCE", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202cad95342229afd4cff162e4f6166020be810f803ae87247e609ac6b476be6650220643568fb6eab880dcef52e35a6ae597da18d849ab7f77e4847216817dbdf2066", - "id": "8d4bcd6bbe8c0d21408c5c956e963c7edbe906e8d51618d15946356ed05f84d3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30000000000, - "fee": 0, - "recipientId": "AQrgHm3rfWGVXDhoPBSz4vXRYSJnezg5VE", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204abad6d12a702ad5bfe5d86738bb12e5fb77ccd3dc963f385f9fbc60369406f602207e473b2bbcd7176b9d1b8d3ac9429b651c8afa5e4f1394d97114923017734b2f", - "id": "c16763bfed71cf294553f0f3d6b3b0b3ca6d133d73d09c4b918b6e5cee11a895", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30000000000, - "fee": 0, - "recipientId": "ANBMsW2NRR5QUp8yhQNJc8BW6yrL7iRW8W", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220344f021c3a169186dd6ae0cdb48330b6224da92758de49503fff882d1b71b2c7022048f81b28b9a8ff3c07a1879fb2b3f0f31489f9409061df4cab21bc8403053f34", - "id": "3a359c2cc190a82229e1366b45d4c882bca83958d84063bbdf513d69f8da9bfd", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30000000000, - "fee": 0, - "recipientId": "AWHBi3iRAFasvWqRPrhBHYXvayzn6VNans", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210095a887589f959790c4c01da0adca893b9f288a8fc6ef32de25d19a4501f2fa770220267683c7e421d85c5d368c0416c0f067110ad2b39085a57b396300df68446827", - "id": "3deed8497e891cd9c8c52cb779542e4e0c14bc1434418558e20cb2d2e7a26f4b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30000000000, - "fee": 0, - "recipientId": "AKNx6tMWjp3wkCVmMKc6Lf7evoVQaVW2RR", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008a303a51a8eac6a3b47ac696cd9d561133dd3b08392060a20baced5d3d7659e5022032c11371eb5e80d42325caa9933e9cb218c03b17584bc20c8aae6045687c1a45", - "id": "8fe4b99d4943a9107010ec38e159f8208e1242087efa376d7345cfc8798fcf57", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30000000000, - "fee": 0, - "recipientId": "AX9teDU5aZqYBJUiGXFmkxFoVARFHpSZv1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009c77ca7fd50bbbe8244d6cf87d31fee1502d9cd53bc2719b4977b163601656cc022049cc61fe0848c5cc67bcd401339da0edf6490d59766f1eae6acf071f59d11bff", - "id": "960f6fd34b2aee0ec704559f85cb7889acfc8c5a3b635593d4660a5c4e84077e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30000000000, - "fee": 0, - "recipientId": "AbB54oR2UpH7Jh9beZbHAMU7i5FAZVqEPL", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205ac4b25ffcee117effac747f983502385778170bf4d9397aa36f0b68b660817502204d73b9266257237d35a1de1afed230c6512c7edb749e92cf978679aa9525e131", - "id": "a841cd49a92d5ecb39a5439a958d9d1d02622188a73b71800b45631d15ed14b9", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30000000000, - "fee": 0, - "recipientId": "AdDxYew7tm1TmxC6ASHJhzS1qgtoVKLEPc", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fa7ad99b7c0c61a861d253948568f93ed985cd832ccc49bd68b5fff69d7d0a3202205d3b4717783ed8db230108f8802644ca9b63e5edc60652d743e3792574cd0a18", - "id": "1eae0aa7ebb5ec9e7e421e704ead21748c4d211d899006b8e0c4df6c0dd54018", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30000000000, - "fee": 0, - "recipientId": "AXsSBj89cjVAu5Sc9gLiDDwoRhASaVPWpA", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201a00e76784ec8a63958aec45ea6677c6af0bed2c0fc698ddf5a62911459af0ea02200efae75686a8e3615b62fcb698148229837f5ff32c2cbc2d289447124bb2b5bd", - "id": "193e570b80302b146e5c034c941e1817f34979f322c1c8fe47bef69c8b129b94", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30000000000, - "fee": 0, - "recipientId": "AKUncjgDtuG8pJk7YQrFkwBxujN8SLp1By", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203f9a8eb03c96849a9327c877eae8bc07d3c8e469ef3ecb7bc92f3b10ff76e77d02206b2d2396c5f18be1a68689649acc583c7a827eddf3064d16ebb095a3cb6d4be6", - "id": "4aea1fd822d1a22ae2edefbf779ca2ffb6f8b49a0971e2f43addf9607933d513", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30000000000, - "fee": 0, - "recipientId": "AVbcaqopSmsUjmXDvW288cGUTYq9YSmWRR", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c26e6789b1f61fc93d15a669de8c5a8dd420f68fb8e2424bb5c40c4a15fd1abd022007007a2055610948879608dbfeb831ffdac2535e26614453bd029b93820c648c", - "id": "de983ec6b437575acf2c16bb9da752f6a901ece688be7bad75e24591baab23c1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30000000000, - "fee": 0, - "recipientId": "ANhuDMbZ8GPX6MNLNrn1wC13yKTKL4PjL3", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022057f327c74d0539fb43790a2315867fba5f2e8a3f1faa261852c146bcd26e570302206d543cb594a980b408f5bd8fa2c45251e7d4eb005b2e55950cebf36c92c4438a", - "id": "a869df9fc61b6e1693527a3981d465f6f46d96a318a09d9a92c9888145e88a7d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30000000000, - "fee": 0, - "recipientId": "ALg7ozgLSN9wLUGu94LwMhPhFzyWBxQobR", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a609672480799e9034457b36d6c8f78c1cb253af8a055ac82117e30a3582f96f02207616bc3a6de1cca1762a3dac65dd48022da00e6800c39b44ae53e0d26a322fd1", - "id": "7f7b0295b52a45c399379f18ee56ab09638718fb9346c5bc1963d11cef412afc", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30000000000, - "fee": 0, - "recipientId": "AcF5LeL5ooyt1wja5Mj52gU8X92TVtG318", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022019f8c0dc34957e29ad1e55901f0ab865b38a7e0e018ed69b8793253a5d207e8002205901d7f3d081664da8469ed8e6bd59b3041ac1a8455f629f5508b50dfc2f62ca", - "id": "dae4406da93d88d9398fb59cdb154503104687b2e3a0754b169d17807a634900", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30000000000, - "fee": 0, - "recipientId": "AZ3qjcSmk3vacEiV3GdcK3x18hAut72yAE", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100dc74c59b710ef47a0568517dfe242dd8df2bd1305155600e7b0d39113b34a9e602207abe3ef33953e3aee86dd4f1c8909edf6ccbb2a3eb181a0221665dc07e1e0023", - "id": "0d3cb578f886acc03177c1708528692590db30c8ca270b5032b5fcd86ed75033", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30000000000, - "fee": 0, - "recipientId": "AYdMCtcQjbEAUKWLb7f5NEkkBx9SmTJzcU", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100af1a06c135f43cd0c67c499d1ce310170ead6e61b87f5d673a3d1eee424ae1cb022065b02e0dba32c5f235d9a707cf279a8178d5e5b0baa34572327c9dab785500aa", - "id": "ca2382312af236ea7f5ecec7f860db5ca528b71a4030736eb824db55ea976167", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30000000000, - "fee": 0, - "recipientId": "AGRJC9bwD6npvCuYBZywtho8dBD3RAzikr", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d060d1ae9b22357dd0fb6062abc88eb2ae7e47eebb7af7bc21440495acd3803202207e33d96cfb29e5cc40e45b53eca85b5891ee1b4122ef041e579df50464b8b053", - "id": "40a6b024984183f0809d08d199fb2d7c1742995adea05f1fe51a2fdbbd969842", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30310258076, - "fee": 0, - "recipientId": "AU2s8RgEdGWJYXjSSh8M5zkoJjdguh41Tk", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100be9cd07b90814b2f4cb2a868f08dea6eddc297e79ad7d48c3a1230d078454edb02200171f1277e17ab3978a16fa260903bcad9e66b8667e632cc856d09ea9359a898", - "id": "8d3fe39309daed03ed0e02d4b1808d54a18b71108ad3316898a9109981f0b840", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30644619264, - "fee": 0, - "recipientId": "AQFEMBFnxk8j3ShwNErwoqSK977DidXAAK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100929d3ed3bf40d9aab26360d553f1016f7fad051af511b4111b45ba22571d2b4a02204600751a7a3dd8d0b9e5ae93b6c014facf6191b52a64963a893ce4ad6d74cb36", - "id": "49b13cd9ea10a35ee422e6cca7044ca7a4e4201f397cbb8fd8627d1ef641ca5c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30990774050, - "fee": 0, - "recipientId": "ASVZwCuU1a7qgUKSdiZzRkuRHJpLp9Fp4F", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c352876accf4af2e7395b682bb88e69b896166e3ba25ecb62de62dec09891c5102204bf978db3488674cedc28d875a218309195f3cf7fd2ff1e35b28ed9dadd60995", - "id": "dba6677347d67b9a1030a3f883d978a72c40870414b9dd9a6fafd888195d96cb", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 31371117110, - "fee": 0, - "recipientId": "AXnjrqJujCyYt9rMC5E6NmnbuoN8N8LtR8", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205a2ed6c565adbcea14620c4872181c55dd5df09cfdb0ea96242a6a8a16fd446e022019cd448d1b41aa454ac2cfc476eb4d8d95b3283489fed359d7228d87f97f4192", - "id": "f03293bcc0c837c7d0741081cd123574c51a55f7e58f430aab867047ed0ddf0a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 31808712368, - "fee": 0, - "recipientId": "AWecYiRcWfVFEqdU9Ph6j7F7YwZp2kuowr", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220126963651521701323eb3bc6d78d7bf598d7b12896138f91d0daaaa0cb2a37d4022027009cf91eb481191fb7058204489db792fe49cc2925f2ded59e06f7740f2cfa", - "id": "4b77e88f7746845ee2b045357fb2f1cdc9d23608c50a5587c6414b3a0c4df8a7", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 31825770981, - "fee": 0, - "recipientId": "APATpfYkUfDEhUnoq2icXy7ECqSumPRK4C", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d20fa45969cdf4217de7c8977675794023ceb702d0986785fc7d14200a836c2202201db190f80f13322618d3d5c27d07b36f78c0a876428550ba1fe3cc6e5a2be8dd", - "id": "d6dd825e9819c4bfa896bb33b25ccd26c0d6fdf07dd60567c8048b57a6046cb0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 32300000000, - "fee": 0, - "recipientId": "AWcBdMSL6DFzxf4zcbouKnXqT3xnsaxi4c", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a69a449089437fb0878f351b9abb5770b9e84041516b1fa92deb06dc648627a302200b30af92639075735109ddd39d1247a57e9ee7cccba8760f0e18da868f264d84", - "id": "b3971af4cbd2bf84c9766dfd4124993189e2e445bf5c0dff235aa49f4942a2fb", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 32490327633, - "fee": 0, - "recipientId": "AWq1wsJLPzAY4uiVTvH14F14YNZ2PozaUQ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f05a79d7bcd98a58c56630a91eaa25f14e80fd07bc9c70277ded30bf32dcdcf9022067761b7133837da252a7f12c54a5e59596a5bae74292751f4f71722d1d0aa3d6", - "id": "bb073805ed067d4e2efb8882453433f52d0fd6f44235299416f012d73688ec4f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 32583527433, - "fee": 0, - "recipientId": "APruVpipmehKJWeienqh2jbAdVC9o3x2Yn", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c421a27e857b78d81cfd6d12a5b5feb0fea128bfc43a7dd874c014040c91a29f02201df13abe3451a8039bef22d2e801cc09bc6f4d42f85bf4e62caaeb34131a5e7d", - "id": "439c60dc29d33a9d2e800a5b4ba1c1d195f580fbc46c4183cd4dfe1eaaf9dd27", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 32900000000, - "fee": 0, - "recipientId": "ANiKA7nwrdSW432oB4Xufeb4MyyTk9QeLb", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207a79a82616ea4c83b9bbfd52f8a53ea0ee6ea8bcbbad23a0aae1b74e5eb133390220179678e1b59b8e435fd19e68541d890136f85656f31ad1513169df3b947ea481", - "id": "e645add44af4985a0c44d63a7d33d6bbc87d8d0ded51a9074d8796a2af61a720", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 32900000000, - "fee": 0, - "recipientId": "AQvTNyqxVEHLVZfpVFttfMankBSGLyAfWh", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100cfc612e6c035e4ba731bc662abd91c151c0256379c975b2b0b301e4990f99c36022028380c0fcec416d7cae09ff6ad936087ecb43f162e7edb98b6773891003a494e", - "id": "d17aada75d6a2e7566d34ea4d19a4f044e7ec8a77954de872911f5e603d0ce2b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 32900000000, - "fee": 0, - "recipientId": "AYnzEccw2MrcTUT4yXRp7sHQGe6G7x7UkD", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100bc272d36bad69aef950ac0551b96dd488bc9a83cb4025fac78c57ca286d42a30022003e275f6f1f923c61d6c3a45141274ca2b32f396d9f15a37ecdf8e6299df9254", - "id": "685f94850350f66b039fd33e550f0c2d1114c9f2fd7b7f0f723f9a8dae08f4be", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 33114472223, - "fee": 0, - "recipientId": "AVzMmzLTmugSxbwqWPqxxSQA4QtXVcz5Le", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220699428272cbe81ce84c5556bdb47e05285e8f2a533c5e1f0fafdfb2ff47fe92802204b0c4c4ae35dedca243f3a322e82bba73d80802f01d8d584ce5abb75154db06a", - "id": "1a1efccbdf78b25765e859d14e2d623afb1fc2acffc1fcd8d2679c0aa1fb697a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 33341283885, - "fee": 0, - "recipientId": "AY5Q9bdBx2NnXsQ4L6Zw5XShNR5gL6ExPu", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220398e0ab17a01dee9508b61e2a42fdccd6f0e26ad76168dd5f78b3bf8ed5d0a5502202fe39e30d85935a83060a11be934999874065d837f18e65ce96041b502a4388b", - "id": "eae73dbe65e5699583a3db3933114222b264c45ef69c6ad26dfa517fbb028665", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 33341283885, - "fee": 0, - "recipientId": "Ac2vcL7D9SLoQKwm5K8G6bbFQWgAXNbN9o", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206826a73682fbfebf2b6e78341e339ca1265bbdc3a2a70ea36edecb3d50adb2d9022064a2a77effebcea2f7e8fa6de6249b1e205e518e0efeca9000826f5a493d46ed", - "id": "16158b459a0c1b2953d98feb4d5b43df41ded0f72f3d8f7b159d47f5fddb1c2e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 33341283885, - "fee": 0, - "recipientId": "AYNtaJsLCbs88Dqv2Cc9SUEhRn3gMi6y7B", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009c00f35dfbde9a28230439c618354b5bb60defa091c8795c455f8a3519dff48c02204dbaa156e94921647d58d271e1e94cbff2fbca92263f225b46fbafbd65aa67b5", - "id": "7c0a5ab8ab2aa880dc4688437645dc9d825e030fdac4df2a25d5a8e97f4b5c70", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 33412512992, - "fee": 0, - "recipientId": "ALa8NaNCRdYYfS5sx81qzvoFEVsA7H4VQw", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ed45f09cf19eb0819dce65b619923909e116fe75588a96d6d2e792857a1a887e022050ce6e62dd65fa58e4bae5d09c191290c669eaecbca5dc38813d1b043f8f565c", - "id": "bab26302a9ea1d99d9ae0a90ed17f44c66f1174dc8ff11f7e7b79ed7b2b49492", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 34492604732, - "fee": 0, - "recipientId": "AUJRMxuAJjUFEbS7sed3otS7K4R89caZx1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009e20c799169e14bee9d76da2ca433b8d98295f8593bcedbced345a3ce189b4e602205fef5c8b8225b20744c385f1bd2994a0a824849e2b65592fd5246d625cb6a28c", - "id": "6cb0b2faa48c09b48dfa6dd0391d3309be705c4704d55f72d8a39347da0cc6cf", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 34600000000, - "fee": 0, - "recipientId": "AHWoDbD86gdtvHfgRyKtxo7jHS92hLAnPL", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022043bac64f1f5a5b986fae5cf88d182ca4698d667a0989fb2b89e731282487021f02206b8d22d28a13bce3d61e513c6aa2ab9ed8aba0370ea38305c86df90796cca026", - "id": "fdb9291d29c3ba236ff008224764227942056a4d28f9c12c7ca7e22b4c4c9f56", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 34600000000, - "fee": 0, - "recipientId": "AbJv6ehN7bETURRPJtTgJ5LfJcmjnVCjjY", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e01a874648848f53e3c58f382b04c4d8372dfe14d5e715a0aafa483c4c1593e0022024d196708b95991b30f9a735aa5bdc951ce80455fd30b32265fb1ae8e20c4376", - "id": "f10183e8291eec17c2308b2731b25e0378a2753ac11024c6b967c04138491900", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 34600000000, - "fee": 0, - "recipientId": "AMGy7FcNBntN6FY9ouWS62dEmiNW5SNDSs", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100bc4ceeb3be6f423d167c08e8609e5224a43fe2692675c4cccb7ef35d9b5e286502205b9639e02cabb93e9d1262b8291022e87c8fb26e104ad46f38ba1ee4eecd8b16", - "id": "e72f27cd791fe40da52aa33d4534c6cb4061080e57a1f00ac5c0ca2e0f8e0adb", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 34600000000, - "fee": 0, - "recipientId": "ATgMvSP8FjG7mtDN84NKvxCJkHP63S2EMp", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206556edbb04478bf8492500e284ba73afa570a1ede51add1d0798e70f349e728802202846f2751bc43dd0c0541327e1f20e5e97149b2bb29ebf75d2c17890fdc751d4", - "id": "21d1a6e3205127c1c2008279631cde827bf82ef542a9706f255f0a52b0aea1f3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 34600000000, - "fee": 0, - "recipientId": "AHs1p6BVoscsszE917Zhvd9BPWrQbaUqcq", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a3e2779d7b46931554138df6b0cef64b7f087541eff83c07358e497e136ea23b02200477eb4b805e61433a164c1d0dac248aa2301bb20f774477bcb81c455b5ea709", - "id": "6e804117d3933b6731b936984bcd33a42319d096d5ee8d5784e1686658c72af9", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 34600000000, - "fee": 0, - "recipientId": "AHqN9DLFs6S26HcG3zNL93VfofkFSoMXQL", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022058b2c046dc42102008402d2aa1cedd8417f39663048e943227682186c8a5861b022062914b3c529429ed2e0612cf2dbf0e66baebd5ce3ee70679ec723862d8bbbed4", - "id": "d0d692c0b8ea05ba6adf6848c94c642a824840fe2b541e16c7fdc0acb8ab280d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 34600000000, - "fee": 0, - "recipientId": "AaAewYY6LEDiXVmMcsoZTbkvq2X1DQKoCF", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fd56b02b4933f9ad0f998c48d4305fc64c047d80fde18883c4c38561d787023702207f6c412361e281154d0868530a6bbe3261040d367087c401b9ad8a7915ff6a17", - "id": "72b77c936dfc9f4f38a825d79ae0360a351753a8aa7e89286edacece4ccd59fb", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 34600000000, - "fee": 0, - "recipientId": "Ac5rmbW5oQnjn51KeQeYPi8k8cB34kZFUY", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210084307422d072f2c09c3ba15404fe9bcd44932e92eb2ed608c60d707b960b69700220186c1250f67c8805c39661d121b8051aa983e0962cb34e046372641830dc7dea", - "id": "7fe1f32c8cb0217b9ef57edc5cf687a7fb07c1b1b82a6e9d6422e1ceec2643ae", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 34600000000, - "fee": 0, - "recipientId": "AR4BUMG1TKCcZi7rWMaNQ6HQkp6wikmknF", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f32acf1ce8f09eeef89d9b42c32b76dfc95da77375d96d22eabbaf837a318fbc0220059b6de004ce6fa0a2ce3f41ed053cd0d8f735888707bcb6f5163e6c05e762e3", - "id": "28148ffe3c46ac548cf5ca10fd40575acafc8cbd43f01e97cde9b5d385974b29", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 34600000000, - "fee": 0, - "recipientId": "AZDhZu4Bxs1Y4SgLc24PansSLP6gXZ29to", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f4963f319382de0ba03c3c0856b9a667a00c82a90de308f00581299aa649b30d02205f7023de13f3958320606b1db434cf40c5294759c01a21691070c90bc2b02bcd", - "id": "d7b7d4815d3617e96fc2f47bbd7424a8b841e2dd5acfa42fd96ac52cd91d2e90", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 34600000000, - "fee": 0, - "recipientId": "AVG7PZt7mWxsbHEuJHF8xjqDLCxhPXsH6V", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a6698eead4fc3e21e659f6705356bf1c1cbf11865a735ea83e60eac5488ce1c8022002c23b6bfe049f8a0e9dae2f7eddc50558b51898459bcb2310b4376ef29f1a21", - "id": "e0d87972b7727a514955e01278aa1803bd33f18170554c410d0c851f7c0e7340", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 34600000000, - "fee": 0, - "recipientId": "AWiJZUDjG9KKM5QnKhz1Gnb1C3WQB23Xyc", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220563392e63a4df3c65909808b2a4b69371e082af2e6f0a9d2c3fe8131b87d514902201657b05f6789b16a5cc4f83dacfd0479f222bbfe17ac97374f19238259566c81", - "id": "34aec54141d983219b001b20901745720f3c38d32cfc736b82697e11bd0848aa", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 34600000000, - "fee": 0, - "recipientId": "AXDoHhX3gwTapS24HEU72dgjsc8TFEre1w", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204d7f9490bb14995339dd36f4f36a34fcf37726f1ff6a821731a2e788e62c9e1f02204804a2d78f61b94ca546c21285de091fcb3779c2af7aeb7e62c483556c221849", - "id": "152802a6a0822b0d9082c0bfd4109dce3dde9efb491cbf09d76e071911f62083", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 34600000000, - "fee": 0, - "recipientId": "AQ1n5gCzkyT9DfgJVBEMdApdKsBhXS2ZjE", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206b5c708a8413bb94024010c291633528f6dcf3f86d06112312239bed0e488b5d022068113fcfc5dc3f522005841ea7972f92c75f57ac19f58fd186371d7548ed8ce0", - "id": "b0a303fff3f8d312ee52989778d5473173c0010bfffecf773d89e3db1a3c316c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 34600000000, - "fee": 0, - "recipientId": "AdJ7BZneub7qzyB8qPHg1FS3ViisAfXP55", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204e09b911019131814eff411b87aec770b43f90b15dee330ef901ae18f57178f90220381febfa6e3cb1e869ca682c3efce6c5c07f5002a234475a1724a7a3fbc6788b", - "id": "05e2795800c06da22617f5ecb702c5c178c610a9c1ccc8dfc8a5310f80c169c3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 34600000000, - "fee": 0, - "recipientId": "AXMgtmxcMTMTZkMWJJyZgFNuaP4jco9RZL", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100db75661cda0f02805787729e123ea7fd914448e56b5de0598c187d193a1fdc3002202823a45c4a674e70468185ca667f45fd2769c4a763c915e4e4c0975a672950a7", - "id": "e7f397170f9ec10b9e1605974c37d1ab68794956b6687c03e96ecae5057d12e0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 34600000000, - "fee": 0, - "recipientId": "AQFYCZf3XpzZyjo4BtAQ7PzD72Xhp7y7vb", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d3cc40176b487dafeffa3c068dec44b0e94e079d015811c0866e3eb96a77a2d6022051d678f7e7410d3b27a9c86e2829d31277462b37381eca23febd1d195b21cd1f", - "id": "56806a7b8d18fff61d209e977234bbafe94329804f06ce5dacb626c91e5efb7f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 34600000000, - "fee": 0, - "recipientId": "AZqUtuBczriacfQkM1iWaiobSGX4GN8KwP", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009897cfdf79fd8c69a0508292f557dd46b4ee751be8e158d0bce8338c73fd86b2022044dc1e89fc5eaa374c0703862cddec760a8f692718768b221ca561116af6eccd", - "id": "c9e886dbe8d9344cde99eceec3f927ad6f8ac08525b18daa8d2a72ddc2a0bddb", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 34600000000, - "fee": 0, - "recipientId": "AW8RbZZiYe8FbDGNS77MGWEE16Zu8AxxLz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207bc3c68c391fe49ed8c7f06d35db75a739ab9c8d97cefd2e108f7b9bc5f164bb022040ffe76e6f3bcc39f993df7405860880ece802b28e56336a17b40a91701587ce", - "id": "53f0027d4810bd37571d6a25fe9a212890210ec4ee42f700394ccd8a1672c8a2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 34856796789, - "fee": 0, - "recipientId": "AXk9foYqX2ExUBK9Rtdirj2XTZ2vReCmox", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022049aa0eb602199bde5b2163a99fb098af4687a8ce249923d7007f5155a4219764022076e659cb2877771720de2d695b7df6c981221010217e885f42fa7d0c09d329cd", - "id": "fc2c5586c3e6aa5bc6d08272c06caebce5592b9f9bea2657707c3ced4c008aaa", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 34856796789, - "fee": 0, - "recipientId": "AYJyrRtDNZPw3srKy34buKUFJ8vwCxAuzc", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220125967fe3764625cc68030e8111c0499a0c5102195f94aa38499802de03f267a02206a97bb532d9da550410499a3952ab4a6e01939ab247c17227792e67fc25fba03", - "id": "b4cfd3f8d50c8bec11bf73e8bda2e8c78de932ee460911e0b8ff69c49ed03a08", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 36400000000, - "fee": 0, - "recipientId": "AJtBjGqiABsp5bUduT6YaK9L9E4EVZXhjH", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210087a0a6cfd2e046140baf9899ee9734ebfdfeb5fa86da06d6b354a7035ae3bfd602207de557dfade43b2b1f79b57c19133df0c0c0f6fe5b72f6b34fd0a5b5de987a8f", - "id": "379d4537f2de2f2cd6d9dcdad6c922ff45d538571712ceb2eca4ebfb676d06e7", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 36400000000, - "fee": 0, - "recipientId": "ASE9D8yvqKef22qP7gAqKyxYqvNymPPm9a", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100dbdf2e7a976583aa29d4bf6e0d46f3919aa5bf281af7d2a655db076cd73aa1a702203d2a6c322152f63bcfa2db3f535f40b397bdccbd69a13557430bad54c3410cdf", - "id": "0fcf2fa0265d5c4bbdb6a0a0bde602f3342fa59c479af9c761e8032876ca7a34", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 37488839577, - "fee": 0, - "recipientId": "AT2FkCcRYAttXPz47FGpdgURLmza1cDctK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207cc3222d47958a7db0ccf22b6a82724ab14774498c3015c1efe72a4eaa81f0c002204c6d395c17568ee5f5831170da2ed918f5bdb637d2bec9711173b444b09a250b", - "id": "8a905c558371ad7a59243e489fd76d5ca42e522c8a04d3d8908a73445d6ecea9", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 37771522137, - "fee": 0, - "recipientId": "ARZQdfzNT9Bd7ym6p7VF4KTjnD1XyoBFdx", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205c90fa2f53194d4d662c53420e4ff1408aac499327e46ab09c5bdb4bcb367eaf02200c71e40ed64aaf058061a224a54d21d1da4719816a4ad90a73b2d86a2795d3f6", - "id": "0f8a2e414407bed22c8866f8f3ad446bd932f24089c15c3122677c7f5ddbf4af", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 38100000000, - "fee": 0, - "recipientId": "AQpo8EbxDh5FA4zATjVRzEFfLcnmUnzMAv", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201de54ef50c50d19a8c86aaaccd7ce55790faf0a58031f608f50929b0ea79e8550220533214087b327632aad01474d1abd56f24793bcddd2366f7cc8346cb75b72985", - "id": "079d07f46a09bde98d55c78ecb6c5205e5209ab32d27c4307dc5448552a25bbb", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 38645579049, - "fee": 0, - "recipientId": "AarTZVSMDRD4k2YPRRs4vNpARZMEa6MtHL", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e437c1b3391179c2c73f309351525aca426a52a050f84cb92463fb37c0f0da65022075660f2e0dfe215911ca518b55954cccd0e184f2d87eb3b7f4500a3e782a7b4b", - "id": "a16879ce73bbfd163115c767c3ffaba4dcf8d1cd2bbdacece77ef15c1a777ab8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 39403335501, - "fee": 0, - "recipientId": "AZdt1o9xiUGNbKtxX4GUjA2Qf8rrepeY8J", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022100c6415f478336f7eb59ada8084bb4656eff9e22a97670afaa4b7aeab9cdd38d40021f62e0546fdb8b200a526c79c67c1240fbd528f6cb332804713109b921b4a458", - "id": "6da4c777b0511056f1d5420621dd8b70b8ca6ab5fdc1a6df342938513e01b2c6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 39470224178, - "fee": 0, - "recipientId": "AV7fCGPQZi7tcKaKYDKf9yGJRiaTpicRTK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e0bbe7320e5972688505a4793e0e9cab39914b53a9ec5fba0ea6e179cd8f94340220737cb6e960f6c2af403f8a80b7a553b6baab74e517f3bf9de245621b1ca9cfac", - "id": "bd2280fa9b6d30ec1530bd9e5601de25f3dd3e0344472a2b4cc7c32818e8037d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 39620933325, - "fee": 0, - "recipientId": "APLS8VURVhTsQ8gYRh69cNbUCETjL89jik", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220548e77cba610645e3b5caa5fe0de930be30662ae976b837252b3fde06bd2f93202201bc93d5dd1710ed48d95cae56f0842df1acbf6da100d4d4d4a56a43b84a504df", - "id": "6bda585f91fe13005e7c2ae9e317e55486f3e6cd0d83d0a64636c409ee8962b3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 39676127823, - "fee": 0, - "recipientId": "APfd2W7pvN7889NjkxygPYuaeAg1XNvKSo", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f99b2ab861887bd456fe83981eb9bf17c655bd9fb3db399c57735001b8913c6102206166bff4926c83511798121ddbbe68e37ce8ef14baf47009c55385110bd470e0", - "id": "46aee861d13cbfa1e058f518e14f1accab43bc628b5aa1e5fcc5f28b38219a03", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 39676127823, - "fee": 0, - "recipientId": "AaLnoAq8B6ZQ9gWMNSc6EHa1PKKkNrPVFV", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b9dd2cd37c9f1838e81325c4ec8d738c9554cd658df1588bdfd568d4ef92e1a9022026e3e132290b7c040220c7a6acd09aa98f4f10cc203f632fe8beadb4f9e1b036", - "id": "d40b29ae4603902272be5e09112e1e5291d49ef8a05ac9e756974c92ae50a677", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 40208679058, - "fee": 0, - "recipientId": "AXVNkc31rXQchNorSwfpweu54jjPCuJkWu", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022078da406531b60613184867d8ab424d2de871bba0651bdfeb0fd90f57c50db48b02205ce247f5c318340534a0ab4abcf37102c09072085b78649b7dbfdc166e79151a", - "id": "d3c4f8396ff1a4ee221b03282321bb8e45ce23efb00d61b8e1f9c76039d2c744", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 41600000000, - "fee": 0, - "recipientId": "Ab2j8GC1y4QtgT7hYv7pA2g1tiiC4W2Hmb", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fab3f4e4d7b764645b4dc54ac55b3856fe95e32f5be4e1bcfa105823a9cb5ed20220053d7c446db556eba9cf85d8e6229360a28dc0cbf46d894481e29269e96ad74e", - "id": "cc6a17753f16a9bc0bfd922b5c39e54e2e8bd6c3daf60f0cb84752af997bcea0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 41600000000, - "fee": 0, - "recipientId": "Abbn712o4ZVx9WVhC3vy36KuW8nRQrKR7i", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022027d1dbc4e47f15a2acbf82f28391d94205ce0ca67fc6bcd88aa0661afb4cae550220717bc9f5525ea5f38d8a17ec4b265b56a58f0caa523071e584d5bc1505b9f525", - "id": "79fc75d4fef939b3967e65fac8103cbdb9dd6b7e60c08323d735611d4f4a1db4", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 41600000000, - "fee": 0, - "recipientId": "ANMGxQS3nccdwd4E9VCkUPx7kqCoNgTPBv", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203360d6ca61b6a128e399878bcff373b8ffbec4812df391d118eb972f8fa51cd8022057eadf2624d266fe0a054b103302832345189074c05502f9d9efd4969fb6678a", - "id": "000e2a9426529b65db56224bb9ada512a48395bdc14d22eefcc64ea1342b8e45", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 41600000000, - "fee": 0, - "recipientId": "AWPKFKMqjSFjMzzimsKMgQhyzJF9JBbu6s", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c8f1def0dd762083c23c58977202e0fb138ac22f987ecfc71f915425e3492827022054d427bbadc47b5aba27f3856cb00960a9c07ede09e438ab29928e3ed0096e26", - "id": "617a1168653fd2b8c17ca88d0186949cb8a155ffce2a20727b9940254b82f2e9", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 41600000000, - "fee": 0, - "recipientId": "AcQR4ymd1ezhUe82AuXZdWTooroxdt1cWF", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207f92c3391e8c66ee21f1f7a12b056e04056603ab6364055295e5bb9eca0862f5022058b6be51c4ae062433934609bf3d0b3f7c8e5aac5af9d72c0ab375abc89a6167", - "id": "948c73321a84c807cd7381d595361e64dfef9b87e957da57ff809f666b76f0e6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 41600000000, - "fee": 0, - "recipientId": "AQ4Bp3zg3oCoS1Kb2grC3DMVtkRCzzgsgz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022057a78d857515ab4028b94cf3bc3cc0bf378213f226fd1160d18c17f298dcd5830220574d2d14ec7972b165c138bbca3f01dd51b34499d2ea5516381572ae3a08ac84", - "id": "4b1cbd8fbd593f29f8fa05b2aaa44c0e0130748b17f09b0c43d65d3e643a4c3c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 41600000000, - "fee": 0, - "recipientId": "AHgivfsrR3CX3xQFoCQmui2DAvUZY2CNyZ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a76da3d4c56cf815cd0fc51160e7a78408c144bfce412d19ee1cc58665e8e44f0220348632438eb2902e6af28bf0a5c074dad45e9060a44b011eae325fa52a70177e", - "id": "dcb2ea9333efa45f3d66d4a3fc489ddc3853f998a902785da39f4ea2ca1520af", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 41600000000, - "fee": 0, - "recipientId": "APcJ3M8vmMQD7gU5ADj2sDgcf1N6FhJ1P8", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b530f23d6cfaf93c26ab19c19b06d4424bde9d28d9a26383603706e15a9c2273022064b7a2879828a23310603e34907761104bb7f3a3df81bfce674ff11ae2fbb664", - "id": "69a05ee826cc2ba50c2c034cb980ae47812567b7307814444b72b8e70f98b43e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 42131258728, - "fee": 0, - "recipientId": "AUHWHwFyrqGvBcNXUjvUwM3hadXg8Ao29t", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100bdc6bbfd224056cce2382d92e4a81821720bff470853dbb0afd886afd149cc4e02204b98db8db62174711cd168c11900262a210fbdcf3a9a6f37095e174b54ef5891", - "id": "31ef234dacbdde03bd42a16ec10113e15d07ec0a7b7be5ba53c0cea80667fec8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 42255389394, - "fee": 0, - "recipientId": "Ab71JZB8rZ8kpYVn85Tm5Ra2MPP9dP9zrg", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204adf5271946845e06db2bd764012260c81fe65fd53cc5153d197bfe49ec4c6b6022064637659ab09da617552f820fa155c0c8e927f6da4e64041ce1d1dc982dee5b5", - "id": "160d40dc3bf0931f17ba61708817191e818b5e3342c23de337ae4e90c865a371", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 42416655243, - "fee": 0, - "recipientId": "AQjvy3Lr3AnW7QzeEtDzaL2XvAZGNmA6od", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008d073a33310126298b08ecca7abf4f9af03086b76a62975c13e335e77880ce4d02200e928de4e5726b37f282d9e483ddcb7d4fed27c73cfc0261d8bff9f382606768", - "id": "cb63ced56cddfa2952302fe8878c721bf74dae1ccb014309d602caa2b1cd3787", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 42700000000, - "fee": 0, - "recipientId": "AbKA7AXhr2Hz4N3o4uLgxCVw9q445xygRs", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022061a00c4b115ae2f72d6c7a66d6bbc6bff9843239b65de88a214036c98bf2ecd9022059f612d1060bea12812fda983962c7909793151b0c33b57ea1c0b87cb979e588", - "id": "7e741a32b14ce1d4364ae4f93ba123042d430dbd76be81b0705a69921a07596e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 42700000000, - "fee": 0, - "recipientId": "AKRPP27m6RocDmDwUeSn9FPMZAdq7XZKeb", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204976b03c753c921b6ffcaf08b742e53f3944dd99f7604e9491128c2cd5bb06070220735eec837093c4b48d14dd6d91d02a0433e86ab5156070361245cf7204b7648a", - "id": "5aa56c54f898b59c422a478990d978382aa5ae7168e87afb3a693db7e5c4d897", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 43300000000, - "fee": 0, - "recipientId": "AboW3NE4S2atxnDiB5fE4FNq6ewXQX1jNM", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200bd507090d4afe13d3cfda6d6a3b8cd84d07f501c1d0b4dcab622d836f6f2baa0220597014fae0b01e2f26bd560804a8d2980df2695a0b277945140c2f7f3641d072", - "id": "d8768e339e6bfdc242cf3c395d3b0f11d4b4796977179cabb06c2ec3a758c301", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 43300000000, - "fee": 0, - "recipientId": "AYSgtUb1hE3WTkw7pQ2U1AxYmTXB6hSdAY", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220548744d15a0172cad94e4a2da25632d1074c78de9b5ab01299ce319b7e9554eb0220252400f1bce65a39a0060a64a5cb44aeda15fe33e01ca7b3524f2dd41ef517e5", - "id": "af598dc5b1ec4ca254f60e4abfdddda7a400afd42eca30863b7565899fb73396", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 43300000000, - "fee": 0, - "recipientId": "AJDZqWaKSug4kPadzqKYDzm4MHGxhhUYiE", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210083e24d007dfe080315146299f74d8129fcadabd3feefee65133cb26b4a7205f102202b0378b31f5810c7aeb96d4c1784d1cb098a36df52f8f8e10d16fc41370f7c69", - "id": "1c2e9b68f93e64f431c95d1aa03edfe301d01d5e5061bf303ca3510462f7dec0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 43300000000, - "fee": 0, - "recipientId": "ALDJhQh5YLMeT2TNf1viyoqJFDTdVxBpdr", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205a6741a4f2d76c61a93c300c5dc9542ffe7822c1d2eaf4d63e7f5dacaf7405d40220675355e51b2da2eebad0e1409be2b674415ed903fbda6257dde37e1851ce4fcc", - "id": "4522f2e824f76a2ca38b8f9bcb589d32394eeeeb44521c27a7d29b410d27ba2b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 43300000000, - "fee": 0, - "recipientId": "ANZed5qKqwcaj9Vy1emaYETWUeTVTuZE6q", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022002d24d963c7d96285437680fa90647d6380df7fa3f84fc3b26ebe80d6d5b4ab70220292fd00bed98449c72e246a94a5265324c16bb8357d4d5863cbd9bf95d7ce1c8", - "id": "72ceb8e73f321a870319b090a0840e83bd8257d86500ad1c23fd3df4e9f76288", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 43768613037, - "fee": 0, - "recipientId": "AVpuvWkhYahCaRt3HP27X42W5sLQp1par8", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202bf9aaf14081129fade556087d9c51d31b2ca79f316df943834364dc655e13a502200fee586bf2a8edf195f939b9b850bbec71eea69a04f4bacd592e38dd69c21910", - "id": "4f0a3f9b10798151efb56686d7920dd3447d824d0ff85e805923f6e429f35dbd", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 44117933985, - "fee": 0, - "recipientId": "ARKK5gYqzp8ZBQu6Lb2XCrhyFN7DW2u71y", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100982ecaaa74b2b64bc24eafeaa49951093212380f9784b4cdba3f39b4c6d80e84022054da5701fc8b6222fd56ce68c1c36f125b588e1b4a18fa2512674497c553d807", - "id": "f75cdbe651257ba7454fae6d967686c399a041698c666c25db6f31641a7dc9e3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 44286661880, - "fee": 0, - "recipientId": "AN87Bx6HtTjA6NpajYfTLrqSwKHzx5d5hW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fd9e1fad2be125b433ad14c77655b8f461db35bdcd68e2cc776c22c887908e46022013e50085edbe22d2feda04815b035ff06fc6a744822150ef8ea7f67c893f0c66", - "id": "9a01c2222033973b17d6014c970e033280053eedac7c1fa9092b2d104a72caa1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 44333481457, - "fee": 0, - "recipientId": "ASbW8T3Xx3bDZQYGincxMhgspZFZNrobJD", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009fcdb37789a54a1ca4134fa8a5931cb5ecff33a6928695d68a903d088fb086b502200e7c474cbb7d1f6245c569d3f2fd7468a7993bde91bccd9802c59ce0d2b56ddf", - "id": "48de47db070de621b582c945d2eee43674ce2ec38b48d7fa80294d20e857cdf8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 44556079374, - "fee": 0, - "recipientId": "ALBVdpLvZofQPLdHungdurd4iF2vHtoFbS", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210098e6b691e6c5c75fe5288d2a5cf0cd0b79694a03e782d9aa982a6df7fe206db202206df4cfb87cc5fe8fc61c5b95c16c947e98671390dbac8b74d5d9acc02fd6513f", - "id": "bb34fd7dc178bbc4ccf41b5ffe7a9b8d8bae117f006006bc710d76f36a83d5f2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 44571697840, - "fee": 0, - "recipientId": "AHXaXhX5ybwNZ7VDkJzJMSD81J6m225xNS", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ef3571ee051193e032dbee17d7b1baf58ea08de031521582416e7965407babe9022055b390e25f42ac5240921d89210f4a9c7176bb922941cc85f92b9dc7e12a1491", - "id": "6834021b254515836168aaaba7bad2ea5ba943f2f6ebab2ed65873342886e147", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 45000000000, - "fee": 0, - "recipientId": "AatvqNHtaZ3bEbegvVZKPoXUebZkNQgJG8", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100bdd197b4f1265984c8298d2780746f2e9c3bc375a2e316108fde2334d025e06702201c836e38d63e67910c20791d9fc4813de475b83ef954778ed5a309aa7691ba3f", - "id": "f3fba4cd40e1f99acd6f5fddf5d7fea6758053db2c37e0408976a4294068bc92", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 45000000000, - "fee": 0, - "recipientId": "AYzwRwPZiXuvP33QBjKC8aGyhtbQJad56t", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f87ba4784290c46da18275953842aa98133bc70d7b4e71d8ca12282f6c3aface02200ea514cffdaaed678ee27e9915546bd78735363976da8036347a99353373c981", - "id": "e81faed2cca7cbb2f9d059b2092adee98010bdd0be99cbd5a2fa3dd6cbfa2b50", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 45000000000, - "fee": 0, - "recipientId": "AFrMQ99PEVFX2fF6FHiczGKjXwetkGxYCy", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210089b572936a6429869c1824ff5c093f32519eda2f184c25e488044564fd4f773d0220300200b1497d89248eb06940f0ad30972666dac7971767e1e3d72290a2017457", - "id": "d50bbb062053072e469d59ac609cfa67f1b42db5bf94f50f00002a89253b09bd", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 45000000000, - "fee": 0, - "recipientId": "AZ5xjWNo8XA6xCbWvVeR5gWKF8Yh51ccpY", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201c7336f68570529c6964cb333047edffb7208a41b20946e3f1e33a6fd8c2808102200df8378a745cfebe85881fe2145d8b6dc54bf002e7232e966f10f852f2ac4e92", - "id": "0e671acd9b32bb08daec418f01e9a2b92533928190485a2444ce5ed10798903c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 45000000000, - "fee": 0, - "recipientId": "AUR1TuACuFHerTUB6nkvzfr8LYKw4D1DeA", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205f37144ad23e3cb508c39225b2aa5316c64a64c4dbd8d9f683c931f986862e1302202a6891bc8c03f50f697d5229fe5d9e968c731f54ee2661b4d87c4178be3bc2bc", - "id": "1e0c135240fec675f246e042f8d3677621cf69715a0f8ce8c0480c8c7e276d94", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 45000000000, - "fee": 0, - "recipientId": "AJhTg2R2MWsrzWfn2VMSa7YgthV9ciSAaz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b8c307b1cd5f04e3190470d66972ab3887286424834389efa4c0f14b29d5dbad022053bacfe7cb19002963ce7999a9b324e7b5beee348b827cdd071514c4f3a94fce", - "id": "625634fef958d669ba75d5feedd43da8930ee4f33cc192ae99803f9643d9d44d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 45000000000, - "fee": 0, - "recipientId": "AawK835dZLs9E5C9KXLsFEVmK6re5E2fwp", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f97b2eb6908446bebde6634b3b79d43eab3d425f02660216f1c2c753195d6aab02201c428ab520196041a462194e906afe6bb49ef7e4fd97955dd44bf4b2cb3c498d", - "id": "71ed3ebc697935d79efb1b1b0ec2f45a67a0e784c57fbff3965ce8ac73a8cdf3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 45000000000, - "fee": 0, - "recipientId": "ALyaoK69C8NT8yiKJdx2bPnPpggTkuJdFG", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f69603b3b32ed21e6b90d70b8053aea3c45c1c2e2c204bd5261246b97f43da2f022040756dae02033d7959f870bd1e05145f017aa7f9e8d8bde5ea9db4458eca7e14", - "id": "a38b475f390abd826db23697d8f3a11229ef4ff5e5d9a5486dfc2475cf9b2594", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 45000000000, - "fee": 0, - "recipientId": "AdrWr45gkfS17raTKgACtMwC1oeem29fLn", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022058cdcaabd8201113db1e2babddf080db1958c9072b1039fa245c7dd83e92caa7022070ad9408de0f11f8a39cb43d2533a8b6bf079c7237250288e4eb96dedc3806b1", - "id": "f0865d7b5fbb45687410d8abd0e4a491320fcd2803a80edc40d3a300ae0eb05f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 45000000000, - "fee": 0, - "recipientId": "ATLyQaK3RtKHa6eGCPZRkVrKjEMcKM2NNE", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022005e5bdc9a2eaf86059bc4d631765da8da416e108e6d2e07f2aae071e14fcf87d0220085c0961f9ca20cf2e40278cb27e3cc0de609d080599d4547905dc37bdbc60ed", - "id": "89fe6d2b213226f45a138ea256496d79ad5144353b0f5bd95315c34324674ce4", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 45000000000, - "fee": 0, - "recipientId": "AdMty9JNMNJ4eSoUZqwnE1pzRBZQW85Dmr", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201aeb9867943ae98594b74f68a44e2194eda83b52a7c01850f2da145af34554e80220615f683129fc5e3b109067e5bbae547d6c80581c2653b7bedd7d986bc19384c4", - "id": "6550d4dff8ecc93472441bde8d4b87b174719d14b9778f9f25e826cb58d57d08", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 45000000000, - "fee": 0, - "recipientId": "APEkkUCURK2SFA1rXq6nrqYyPVW13rsxtq", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022056e356a79e482348494a82271fa5c6ea1f1ff3857fc2429d248eb5c4ab859734022000b20a70ff281ae78a4ad63af9646c92e11b23a0108c6d646e0b2680f7a8cb53", - "id": "2640992456466adfef85dc33db1f0ad1bf731209a988ce0c3af7b9e2f0a15e36", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 45000000000, - "fee": 0, - "recipientId": "AYiQeJcxPMdGqdvKVHzLQvmAPcgK1JNuwX", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022072936a9c44c3c78e1da607c23346ae71a7dd55294a9f1dccc7ca7b995075b96e022022ceeb6db9237674388251c1acce2a1a6eb5665aeb8a42b9772853ab68284e90", - "id": "e288716799ad69535338745567163e9607bd2500e78f2fc1dd90b4deaa64cf7a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 45000000000, - "fee": 0, - "recipientId": "AQAeWRKR5mR124KMqCH44BciU6otGmbofj", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fb9aabdf5f55bfe910272ad8ce308f03f5db3dafd8c9d2a9007e784e0ba8b12e02203843f7b9e84f7a2a37a23843605dc6e1943b3ec3be0a7330d075024be0338f8c", - "id": "b7a4725339a9517ce667d69b50279c93c53e432ac8029cf1d1990033ce446479", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 45000000000, - "fee": 0, - "recipientId": "AYHJ3GQkHzy9f3ndLg3CsEBvqSrAr9WicB", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a609c9f810820be67db6b2ad25e582721da81ae29b1fbe95acc1e6ec9eae4f5502206cfd243d311190870177ddced286a50f7df71e3ed12bcf2544ccb61184441675", - "id": "6e68a86ad3f141ce115341c4167a0b8c8039671f7b8d593a9007c299a1742ab8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 45000000000, - "fee": 0, - "recipientId": "ATsDqjHX5hGuURrPfnDNmQ3jpB4q2aMcmK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fd13b731e92673d5ae20fbe28c9dafd55b4de120a8b8654b9db323c4ffce89bc02207df49ea18df0e5fd24e72ade2bfc2ea417f53d5a268364eda48a8af850a972fa", - "id": "f6432660a1f9291b952bcc0518abca3f0fc2a48cb553922f94ab82d5127d83de", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 45000000000, - "fee": 0, - "recipientId": "AbWMPtepNQdtZKbNFfkbEvBki3gLxgzpWZ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203fc4e5dcf19aec5c7cd014ec4aade1a177bcf1e8ba4c1ed8ba6636e6091d62fb02201935e26746309781e360a48577ef5ffcd82d41c6540943448d1bdfe44c804b7a", - "id": "1c67042ad2c0ea1436ffca3f18bdb68e192dad5cc1af9506db9187880bfcff58", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 45000000000, - "fee": 0, - "recipientId": "AcA3ke2piEk5tUbLcaaeU25tZckcYaVRo5", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220057351f830067dd2f2a6c554307d64f2cb01c4a41b4bcb56d92bd02353f2a00302205562002faae96f1915237f5ce1574cba8bb17f2cbe4cebcc4eb25f21b39018d7", - "id": "8abc18519bc37580a21b2b5d36bfe15eb4d6f63610fca4db2dee20f6a25417b2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 45000000000, - "fee": 0, - "recipientId": "AWMJezaNhsvRxDPMtEqNdYHt6iAMMCRroQ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206f1e30ed77982601cd7186278023615f0f9c19984ea459629a7d4ebcc4f31e9402207109ecb76a21e88e3dde1c9b1c996195def546b3e6c5affb44838c2fd6342a0e", - "id": "5977367c87cc269564188bb26cd03226dc5d182f7191ec3dc7948f6f21f71d13", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 46006407173, - "fee": 0, - "recipientId": "AMjF2vBKEdDs292kBAsPB2HpAYzCqwUmEC", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b58f5b2879ce4eb45501c18fc605821dc979e3e7efa7f204c85f5ff02b6623b602206f2b4c40f9e7ba54dab669024d3a5a53bbf35ad4bb815c3811a565e6d5325691", - "id": "faa89d3d52bebd59d0abe61d555e187c1b8c98c3446bc566a036a217c6fe5c7a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 46288347832, - "fee": 0, - "recipientId": "ATsdHdM4ZWFUXSmAS1MxvTJn4wEt75fyBu", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100cdad60bffc4d6b6e137f894becf8b7d67d2084a47df750d40590a133e02cd68d02205c99a8012fb42099ea7f26c45181a47e53a02602093a0fda29681ae77dd9e6e6", - "id": "87c1e1fdb88c4e153d3e3e85a767b0e76a29f7da8a88d299b79451abcead9365", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 46416322043, - "fee": 0, - "recipientId": "AZsbKy8LmWUf44H8XqGkbGA3mVdyoNsPc4", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ea15ca497460bb9d9ef34b644d107abf984cb3ca26e6c31b16509d7b9346119002206b732e6eaf0a6d14f43ed5d889726a5998d5a190895d4aeeb355cbc2c48ae2d2", - "id": "8aa8e83047ae4bc31b0775949ec3e9a393888ce39b463d91be26a9e5393fe7fc", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 46947045881, - "fee": 0, - "recipientId": "AG7uDVNphx9PerxNvELAPrHREsnDC4zNyN", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220697f3cf632d4a4e8a3a424be3e15cf7e9b8af40f484dbd862fa32fd0e7bded8e0220061d59d40d3f63cb496b1b1030cdbfc87a9e06e71c63fb9b05764fac08df8dd0", - "id": "e351f47deb7122873b04a91a6051db3812abc8fbe84c907533e6f68a224ad68f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 47400000000, - "fee": 0, - "recipientId": "AGkeeXQM5NjSMk5FwGs4wsVET2TojDJRgh", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210092e1610b6e99829aa9a149a92fb3117ea73ee1f0c7c2b7cea099b55769870de6022017ec1216d66d1c8f7546d9c5e2db23b95f033313d2aa8e1e4f9762cc74036dc4", - "id": "4d07eac2ace1a2cd2579dcd8b0de07d6dde9c3145a2d09ab7580f8ded1531def", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 47400000000, - "fee": 0, - "recipientId": "AHGo9dHkARtM2E2kqb8oVi9VMGZduFNFGT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b022f6e3c9b494d8c11e12c2014cb078876469c3ce2cf74ce1d2448cb7f813190220012990c9b719f8e80e69108a6e9e0501d7094cf47a0daa1df32f08c2cf29130b", - "id": "143256c98cf7c47331065de6db5e8e328680aa78a35a9b7c4038055a6a416961", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 47400000000, - "fee": 0, - "recipientId": "AVZugZBjYSTPC9ik4rB6RknCnjzWPBdP84", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205d010fa7f4e16cdd80da7f18052eb197794173f661abd51d5b8d3a377a88d853022021f3f75f96a21cd8e3c694b1635a286febb72427c1d7983d52d6dc20a79c3576", - "id": "058cd4a632a73218954a3b9dd18a5b21395ea99bffe9504be2c111e7b5df1628", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 47400000000, - "fee": 0, - "recipientId": "AVp8x3mBHzs7fpvPfpUyeE8WMPdtX5CK63", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c0b5dd428920c1f5148e1282ff66c13b845990b6bb31f497381dd060e8c6c0d50220756750f9565df70437787347c15c60cb5d71677b21c9ce6a7c8bb5e9b786b4df", - "id": "6a3a8a2adc4c7c5cee98d56b69f581b32dddf7da323eddec1bcff013841bded5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 47400000000, - "fee": 0, - "recipientId": "AbgCof5QkxSrpZNJGYsiepZuAEwPxhxT2T", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022063f69a740c7ea719eb624fcb71fee6b497a159b101f0f3b8f06e90791b7f508b0220710ebc92317ab726b2824684d51ae758059efa7c16b7ec78d38d45a4e7d6124e", - "id": "e5458cc7aff8e0bd8e2804a68822a783c48db482295997d53939305186376ea0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 47400000000, - "fee": 0, - "recipientId": "AJZtruVwKAPj1rv3ahcF3Z9GTXGcN9oc7K", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204849a42fc02fb6473c4a79a0c2c9ad9facda13ad294495b9b2786b38745b7f3c022070dbe71e4555efe7fa244a3cca10bf07744bbd0ff280b83676a2a2e188f44825", - "id": "3ee0be7406fb23f3ba38c0eb96698b168c043afeaa6fd918949e0ec7c90cc3d6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 47400000000, - "fee": 0, - "recipientId": "AJgvboi25qWyEgoZrqqWo39kPGaPVbrbki", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203c936c24a2e3490bfa4743b369ed09f12ed8dccefa55836551ba3c666febb58a0220586eac237dc31060f71bd86a893b78a578b76f2970b8f57ff31c31132b9f1008", - "id": "14de30e7e1bfc74127cca71e59bfc74a03b9b2f714837b4812a7e149cfef20d8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 47400000000, - "fee": 0, - "recipientId": "AU5SUAATEwfHjAtQDkGFXVPL8Vh4k6sNtN", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022049a821648ea42ce2c2d1d02c5c97d7a8964060bdf2e4028954528dd843faa00e02203e800a96beedff49f634ed9da667ff419bc8c9c582bccd0297c31006683056a6", - "id": "f41fed485ef003ccbd228edaec88d8087731e0005616a600dcdf94c67e72f0a6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 47400000000, - "fee": 0, - "recipientId": "AT6sBJKYptsn7csAsQSzrKuHeDNv7GkTSv", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200b60f4bf416eef8e104234eaeb92ebe80647bd5afa15953cb446fa06da0b169c02204dad39f650f29de7c6867453c4121a868a2e24b12443d5c7722c4b2465443015", - "id": "17a5a7826eb0676195d33e12b63705cf50846a4db052199cc330156a67607c55", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 48367953807, - "fee": 0, - "recipientId": "APcpfWW8rMcGe9gmiFmZZ6qfeYBtwneDP8", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100879fa90ae6b2d4c759e4ce307f0a1cd87980bce956d431fda9003f00ceffa6a4022054c7765423a5f512d1631d3ffa077d717d943298e5fb8cde08908a0a7c9b8267", - "id": "4a6b80c0f1feff81fd4450558c0da1528879ac2db42362ac7fe3b65f4fa52201", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 48500000000, - "fee": 0, - "recipientId": "ALKpxaTevuYjZYSXvTYav47Nj8jQaWSNqf", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201c5a1709172473523d605e4a21c02f3350df6bd9cc3c0951f20e8e2d13151f95022047b2993d4fe88e1e7d079de95f342202c45813aa0f1a6d17289b71022c03d512", - "id": "fc415685bb6fd5876d5ad3c492ce4696004aefe8995874b6b1f1dd0d5571ec52", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 48500000000, - "fee": 0, - "recipientId": "AH2ZufhZhdDsHWsY6qBbrdp9AwH1rF1kes", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207d9dba6ca6da8f7e49f6d2654d0a02cf36beaee6da12fe5e5470582e4d9ea28102202de0debfc82f03488b867493316c18949aba7ce6788b8e6b583b26f7d9335792", - "id": "22a3ad155d12e9679a0af1d5e8384417828eec2b9fc36cbae2785464b12b372d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 48500000000, - "fee": 0, - "recipientId": "AG2RijifYGo36FXJN2Noxq6hM1JEvX4Xxh", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100cc3629e0cfb25047f615976b40ebaec5d3048f34eec4739e4dfbff8537122a9d022034f893414c942792e86a25e64494c4fa92e72d2252236a2506d26ec1e6d64d41", - "id": "ce7f905a90772e79f6e7b54ecbff92625073fae404abce4af59244ac361b411a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 48500000000, - "fee": 0, - "recipientId": "AZcoh7wHpN3Ex7ijGMrdMRTF77i4sMEgiP", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ce4ea4644dce81416d60ad4de4ce33c7c389b6c6cb53f06cc3bd2c5f60a08e7302200dce4ca71921b485fc37eec0326bceae9c7345af73e16036a195d024c97644e5", - "id": "46016076914aa928d354260f80e77a6cee67c75a0fc754eb8c84c0278c8c5562", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 48500000000, - "fee": 0, - "recipientId": "AYnAUcC8xE7EXKouH467mTCiubcpbgQj1A", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201697eb4f8560bb074f208bc71be81f1308a275967f9af4931066f61c9f56912602204bd8f4577f71c2f5133295cf6d9f9cc54deb0d8c370fd8e1c100cbc8a192ec62", - "id": "37b6ab528f70a015c24f1d9532cee172e1ac7e24167b199de6afe74bec419b9e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 48500000000, - "fee": 0, - "recipientId": "AUYW8cN8SXecVeBLmTZrr4XGPL4MEbGz4o", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206a44108ed5a88f05d1de5932518d0c4f473ff9b85952ec7f168b7f013ccea9ac02205c0cdb66e19f9c4766eeae55d554af8e18954f88c008621eeaf4bbaada341df4", - "id": "9b7ce4722d40f509d67a01d676ea46ab007b7c3250e70cf450c0d4152c861356", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 48500000000, - "fee": 0, - "recipientId": "AHoMsGebVZJMkwd722t3SNQtz8kxbsK2j3", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a6ccd3bc952f8e17fe373625a22692d035ce466241cdb96e5412246c4288bd6602200c55d0122b0e09a7b98df0940538ab3308937637b03640ece423228eaf724964", - "id": "abb9425699d86129a675ebe33f6021ccfe0423fb2ee919030cd44856e29ae0d1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 48500000000, - "fee": 0, - "recipientId": "ARRMnpJsXLabK1nWxQqm3R1WKiY9ZyZxtn", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008b4c4f04e3234f263978b73e510bff42e7eecbccc61bdddc82c906434bd2665f022061480eeade9e85307b62121241c7dfad53168a851d5a3e141c460bac0c78fb80", - "id": "6c644f623c504fd6449dec1ece024fa5026b86d13896bd6466912ae6f8487011", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 48500000000, - "fee": 0, - "recipientId": "AV6ffXNFhte61rxqLoCuWVTs3ufuJ7Z8jW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200db348a71ec10ef1fe1498daf3c292411ce01e1f524cfbdbee6f2a9e86959ef002204bbbbf2e508f461a134a6acc333ab4c817c9e2c791baca36d1f235a30320b11d", - "id": "cdc3bf330b78fc143c82058b0674465da2b2e840270869d05a42c2d3eac7ac7b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 48500000000, - "fee": 0, - "recipientId": "APhVjG9pJj2YpG3A7rh9gApT2oFf1HHdbA", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009609b469e7ced5253be188cc3ccf069e155894e715ca8ce9b402c024ae62577a02204b6887fa2ff4881d0e539d66ddd8649783bf4aea3cae68aa5bacb0cdd1e5a106", - "id": "bafdf9d4628983cf25b0f411f0c957ebe6565d01dc043d5f79877d6503749b62", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 48500000000, - "fee": 0, - "recipientId": "AVa7ZKfPSMcnZn5b43m9Z17dLYAkKPepSC", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fbc0bd9719f34d1e39ab2c3eba2ae9b20434d4ed9550d745eba0a176c45abfae0220261f68db9cdbbd41ab3df574ffa1a7e5d07d94917bf3455f0348f2a8c86f33a4", - "id": "cae63006ef7dbc6d4bbb8c0f8b2f0c1821292a53c3720046d2f3e5aa9b18df74", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 48500000000, - "fee": 0, - "recipientId": "APJyeTaF5E619fNpruHNDppitroDorHt5a", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203a37ab7e59a3bebbcf9b1d55aa629f5eda60d60330c43ba2ba1c23c43783ac7702202e75368241dbcdf204a3d9e415f8fe755fd8e60c8c45454de3104e9212a9a56a", - "id": "22399be7427eedf993b9bda222c461f4daac136d9ae48988f073bd31d34d9c45", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 48500000000, - "fee": 0, - "recipientId": "AbWDXPoVRcHmUQ3KW4ZWeuD2mrPYfhodtr", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b245491f63892ba07fa18e5c6f0d3dd50c141bf978094934d32aca1efd8c6bbe0220625ad4d01d27ecc58c643353396093c12c9ee5f617e8a7bab48f590b4e0e92d9", - "id": "e7b6647114488172d1c18263e301818829f4ad9185cae8bed3622cfcc2c001d2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 48500000000, - "fee": 0, - "recipientId": "AUeBAB7qtntRpSt6GtXZXcVNeVkhuS2RRm", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206013142ca9cf760ad5f77a3f946e8cd39a254ba8d4b2424489e01897edd3cabc022050457ebaa39e2b84e773ffee063526ead54194a86281dc21492e3fb0188ece93", - "id": "b9d8c7f12cd758e451a70df541351b3f19dd2f2c5516f7a62629e04227d1d4e8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 48500000000, - "fee": 0, - "recipientId": "AMKTHeQDsTHWw3QeSRLAW2kWQnBrfrqKHV", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f6fae8c2f2fe7da5e0690c8b030e7ce4d7f49ed238d182c0bcd554e3c8daf1660220065e1ec76e1db8fc24fc360e04ed3a04782c04e29a9248597aa0974a67825937", - "id": "afaa4c75e302dfef1e9d36c63929decf4dfd7d8d1e8ec8f980bfb6459767ff76", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 48500000000, - "fee": 0, - "recipientId": "AJT7v8APQuYDV3uDJWsAFGBze9XDKpXdNt", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022043653b6aacf91675ba1ea798f0ef37e7fb265811ae4a52130959e57d4d90091f02202b046afa7f108d0d1e2a377246e9aa295531e053c359385c1406eae8ca9dc4ab", - "id": "3917c81dff0713611f02f1427a92b63d26058577ec5f16eade5bc5f313f8861a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 48500000000, - "fee": 0, - "recipientId": "AGuBeT5rVgCETkMTTAUc94Yzx788X9fiqH", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f17d6e2720d978efea176cbc85f9e5c472882df3f6886172c5fc94b8c207b1f5022049fd7c95a425608177ca111b78b6666829d6644a03c324d033de3d003f2a70dc", - "id": "6094c25254da89c6e8d08fb7c97e255448331fd054f3aeb2a7a239f4cab5c43b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 48500000000, - "fee": 0, - "recipientId": "AVvE9v9QyJvBPZK2kgMDwJxDMu1UEYvYRx", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022019dbbb234bdb03d4652206e72bf2294f4d5e18112b86e1e52e29d0419369e55f02202be9a176cec5b00ad3cb40900080100b8c3b15a0827ae5132e4004f22f820895", - "id": "06df438d747a1cad820cde398e0198333f4389c12faeba195c0abb7fd4d92350", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 49717819332, - "fee": 0, - "recipientId": "AKFLHqUXHQSV8qchdjbm1jUYPptVatZyQy", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100929159e14809ac7f07724a097962ed91909fae24bf045e51c74f5f212e2a4654022053ad7d90be5cd253e8fe175267b45453d5af2738f6478d611869ec5e4b124e46", - "id": "c57dfb4a2801c1ad9868dd2e14eca2115928f013ee8713e068ab670171e66abd", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 50011925828, - "fee": 0, - "recipientId": "AYTJNTk88MySw2YRJxb24XQrHr8fYe3SFf", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207a665bd64a6becf19aaaa99468984ce4e5e74cdea92ab4ff565d8d202319ba7c02201aad01d9484f0ec40e02fac399570338ff66cb5b8a84748ba1cffa0bef41fd3a", - "id": "89079a73bd4806bcf928c52bec954e11ec3de186a4caf4d1bc8f21a430373c88", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 51012164344, - "fee": 0, - "recipientId": "ASm2ZsSj9W7jmYCDdLi8Eh9RwLQALkH1T9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100cecb5a11966ec1d395eb2eead1ebf4d9c41f7a2e65d94bece07d8175fdb20125022062b79536de24c87d93ace4791643d62e2af941cba4aa457b776bc12524cdc0dd", - "id": "199a36b4f6be8326483599431afdc07c424c761826e5dc915103ab677d97112f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 51523164985, - "fee": 0, - "recipientId": "AYXPcxBW4EiZ3hav9w8qPnYCfMC7UiHUFc", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205006932929f7e0fcdfa814063682fa9576cd197d2ba944a52244d8ac573701620220540b8abb5d72775ef6fa039984fe4fb068fcbb11622715947e0bf43b00dcda85", - "id": "5af79acec8a2ca26ae1ef4a4bb4c36c9d756f4627407b9831dc1aefce88d41d1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 51527438731, - "fee": 0, - "recipientId": "AN8fTyWTGzGMWndi86xLuPZ6sx5RqDU3V8", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c86ad1039fbbf4dbf38750f6933eb94de081730aa4bbbab2e69fbf6bffd86994022065cb206c7a6da6a2cc49564fbdbfd861c2d7a43ae574a9152ca743ccef38883a", - "id": "0e875f8909e934d95123c4e39b0dff610726bf4cc793ff32ac3ab87607a869c0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 51527438731, - "fee": 0, - "recipientId": "AcoxZHkmsepyWCs2K77TaAAuKXzYFRhQCF", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a556f84c6f3ab557c61a3f103d5a19f967a624bc247905e6433206d17b05979702202bda3ea0fe77b2217dfef8a79921a4169a421451eb08f31350667e8253eacce2", - "id": "baf5b1d34f909d2ef94d82896e8354fb10d59464743e95174fdaf41f5816d986", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 52000000000, - "fee": 0, - "recipientId": "ANx31923yoBut3ToXoPugKPnzgRhRGELPX", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008e91db1c38a78379d51739c8e7c5bba7c7e10423f90d975a83ae8fcd5073e08a022025c8927e171c351598b0ef39f93c2bc2eb2bc86eccd43b5b8c9f6bca681edc97", - "id": "6e86383cbfbcf26c0268180644f7a946325559b282acd1b4166d1edc55271951", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 52000000000, - "fee": 0, - "recipientId": "AN1XZJrPk8cm7Vwf1ZTrKrZtCCLZgkyrJ1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205e39a2dfce53486be7370d92d65ccbf412e079c07e0405d68fecab4f1e17371e0220438de48ce7ef76a2bb2b65bb9e2013eb1790f1c9b26d2037138ba4796315611e", - "id": "6cd2b5fb62f45dfcff3337b52bc1f4750761e88df28c5d02acfecea7cd0164d0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 52000000000, - "fee": 0, - "recipientId": "ATGUpBz7YkxB86G86796U5yTEgyK5u4rJk", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202a418c3135e189187865442f8ffd4cfcd5469eb1858ceb9add3bd0810ea37a4a02204744e68ce981a9d4bbc54c992382dacd14b47458873da4488e3995f206b09db1", - "id": "722201637e0a6c263a9a2094f2ca0adda2d8b69f44a6f15e4d29a53a93cb2985", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 52000000000, - "fee": 0, - "recipientId": "AGyRgpaEFZ2ZnNHL9Kr5bpMGkv5LUWebQb", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207f5ce9d7c0055100d09575738ccde05ba74dfe3db8bdf4d8a30d0bcd6b99592b02205a0f50872db6a29e0f0bab2c687c44077f9be26558b022dd74b3e2275cb6b853", - "id": "33f843ae2198e8310d2055803607fac2d24907bf8f8daa2f7290967e81672e14", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 52000000000, - "fee": 0, - "recipientId": "AT3g4LwnJfZoN4vuFLtMJY9Wxq2uMtLuxT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022059078b6b0dcb5203a2c3ba3a46bef4d723a63ecd6fd3a2e3ad29f67b50fcac1c02206994e842c8011c3de756e762b831e9b1aa12d8df872d5838ff98d53aeec95e2d", - "id": "f5ed89f77f37b64aae398ba0e89fb520081aac2ef2ffb2aec87c42bf29a719a4", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 52285195184, - "fee": 0, - "recipientId": "AdJLdk5Vkejk95ah4j3ZRcEWu34E1Q7wVN", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022056d42be934431202be893e9d5e6d640d2d9f5acab7aac3bc40017654ee6688a902201f407d488855a6208aeaf3068f109a0b5de4abdfc4233e8bfbbb89ca3e33847d", - "id": "4912aebc2a0e8081a4761cdf85238d17a27277193389698d25200c3259116728", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 52325513889, - "fee": 0, - "recipientId": "AJE5ptbRLg4SGn7DQcaLChpuzjEo66WTDg", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fa8e197adcd0a62c4e79017cea097a9e22a2301be0ab22fb3b5466846bb78575022044a063dd5987a6e91f6ebc4858754ca6f7e7fefcf53bbd3e1e08e20c3f7e14db", - "id": "58aee6b0df8cea2a4fb9ec25402b3440a8e5076890a8cba8a9ccef0ca5b52148", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 52512522119, - "fee": 0, - "recipientId": "AR57nJGjbRknsTMoDJVPnKjeH7H8pQ4J3e", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fb7872a819b54bbc0b30dcf4d8c3e413c84278d631628dca3a6805ec1231e210022002c76cc1e9b7672ad3f0a1db859e4b36564f7f815e494c5f9b1d601b6081e8db", - "id": "3f54c13b225a0c71692660cc5cc0910fedd163ff1aada08cff0b6216df414f4f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 54692496501, - "fee": 0, - "recipientId": "AH1HPESny9sMqiJz1ySzoonvcgVLPNTVY8", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204b168552ce3f30befaf9a566986b6c17f67471fa0cc2ea308acf7e580586d58f022017a5a0173699a7a5440f82dabea25270637d7167372d9aa71ec62b09e4c1860e", - "id": "b1ac5258577f86365c9c532150696897e0f5b304fc755657e4166b7f784adf79", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 56071540498, - "fee": 0, - "recipientId": "AY4gFPmvcG2GfTcVE25mqeDmnDQMPcWndc", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203b1848de0b3be4cccfef6ff105581675c01006ec69da4492815ed63c194338f30220377f301d3fffb2a88f7ed13d42e2231cc5984f63775f082e3c85e02b37c1743d", - "id": "e1154407af38c6fbb875feb1badaeb5cd8262821b3b1b1a441cf506aaec41d4c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 57049922288, - "fee": 0, - "recipientId": "AQbcTN3TDRc57j6fpwAvLjxsc9FeAJThp5", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100dbc5ba06661abfcadade917512e640a45ba57ff29ca7fd7ef728405e87f8f0cf022016d0bd3ef6c0a88d161096520dcf4673dc2cb8fc96ca7e61095ea5e67465c8b5", - "id": "3fd968cf660e948f9fe340334684579db327ab1d6281ee05a840dd1deb0e4b7f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 57589490347, - "fee": 0, - "recipientId": "AZDQwckNFvu5RL2gP6x5SfNFtzSk91tPTQ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e3824a2385b1f4133877047b7d5e702d269c82e64bf96196f526a063047d97120220327dfbafefca990f871ed25bcbad0bb7308279930468676e84c54d701890ee15", - "id": "d1d7712844a3898546271abe9b6c0d139b3d322f436d26d7805caa0a34e1f8e3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 58900000000, - "fee": 0, - "recipientId": "AZe1BULQ52K9W8Pm2oz7WnS8EFsHSmtcGa", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100cef7f753f6cbce6fc6513cbbeffb4fed56e32f0f6632d87f4471d59841a8af2c022036f7202c8e437be380ecedf8f1930d38fada608900e93d33334ea8815c4ada2b", - "id": "00acf4f97b4d6baf38f7a16619a7bfb62d93a96cd30f5bb081fa15099dbaadfa", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 60000000000, - "fee": 0, - "recipientId": "AFuQS4a6wysBSmZJpMXq4xDNAetJJBAFsQ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d8865a56a63f070cbf21dc8e48685ecd862077ee52ccd2c8cd8f40be72c3c4d3022057b11b12e968dd5e87df9da6928c6028a131b59bda09ee07a204dfbb9a055844", - "id": "d3ac3ea41460fd549c79fe3badd7a80ba4d467869b62b6b4bb342d8db1570efe", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 60000000000, - "fee": 0, - "recipientId": "AeWauSzsoZ2FXZwP7GFX92pPLyJMSkSKph", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204531943ac76998e7bb5987455c901b6174d603114ebf915775590c8315653896022001eaa07b36c01e93b07c66aa139cf299ebf25ae16431eb85611dfb9cea9c09a1", - "id": "c6719c892816ee2bdd2c113614cbbd92a59de7b54b3a4c17de68c0da22256d3e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 60000000000, - "fee": 0, - "recipientId": "AMmqT7w7oXLazLwQcSV7WHnYx9S7KSXixq", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200e9b8f5aa7d2471eb1981ce5482230a2c2fd1bbcc6db017f6a1ddee9e4e90eb202201ec640c890050eac7108f74d40f010d1e7d5f9bb05f2fd17eb5d8fe385080342", - "id": "7d269a6a5a9c507c1637707448d5fa61324f9394471fde06b0b53bbd51b0cac3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 60000000000, - "fee": 0, - "recipientId": "AXdGv5eEBNGK5UTcRaFHbW3FwEiXifcegt", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fd07c0502e712b804344fdc118b52e2bd1f9082c52aaa6a87141f4e46d42107c0220718a1a7d58f887e544c92404b49824154352139fbe33eddb5a7dd5e4ef88d7ad", - "id": "f0425c83dd9d9eaae6158673566fc41a1d4dce9304fc82703c97463b4f93db7c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 60000000000, - "fee": 0, - "recipientId": "AYA5LBnUiYXCraG1jz6XxGe1FbViiJbj7n", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022036479d87611d110554a7fc93c08cc78094a769674379c3630c8a77498626c1b302203712a96621cb8133a43789b7f4c64dc6dec8de903de7c7275582c1fba30007ba", - "id": "2b65f2d5ba1c79f39c61a99642af209df57514ea158bcdd790c637d6287175bd", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 60000000000, - "fee": 0, - "recipientId": "AVf5Nefkn7H2m5ccTY2Gss783w4B2XHrZH", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b3ed017b9c924a513e4175d1ae026e1f6e0cf5062d8abf944a1d456c9b99a3e902206e81a45c621846a3b3975fdbc63e842926e2f0736a8cab98e382fb2027309e09", - "id": "afc6dc49249582cb59fd0ef44d5ef26d40d7a4faf6cec4edea6410396511a57a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 60000000000, - "fee": 0, - "recipientId": "AZmiLVom6XmmQjch8mPaZjzbiZt7xEJ4Ux", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022001981eb483fc7c992ee3b6491fee84e92940df9fe96655b36a451771563a94f002201d0494084a12cf4de2441081cae004067d1d43f802c7c661bd75d0c8882a6d9b", - "id": "c177aef927d06946f2c80cdb33855fc233d0b20a5bc0b70a72d3e1f6076e4e4c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 60000000000, - "fee": 0, - "recipientId": "AUs83fWgyxfn3vFcpr5DLhiNeCrRcrY8YL", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022025c7b0874fc7eba0e23e003d5172490a564e3eed0a504861ce0346e2782a28400220165dc08dcf6720694b67de43258f127630a4d4cddbec8a2f66ec1ddf853d454c", - "id": "6e6193eb69cb0ba573c5545757078fab69cd407c3ab4499ab75985fbf378634b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 60000000000, - "fee": 0, - "recipientId": "Ac2vFD8sqzixk7MaK7JwEYoe2QXEPna1e3", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ee6a0aead5de861b29caaf1c876304bd9792e917a5ceeb1164b69aee6293727002201edad412f00a6efa6148a6a62d7148466f4d24ef343e406b5291688a4270b92b", - "id": "ab0da3b48e067dfbdd94c6bbcac4f3e468946a508735dae2c7cae0ce051e2087", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 60000000000, - "fee": 0, - "recipientId": "AbJSiFHgiy1Gc9dnpnSUgRQVu7cmKUTJFo", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022007df858f6b336a855e06e11bde5f75b4584aa8941a8d61ed54b91ab8a76670ac02205fd2ca83ba0694a6a5ff2e552330616ac9896c319a319dc9998f5c6b57edda65", - "id": "6cbc50accd6cdccae73f205c0bddb4c944bdba76323c5100ba6331f89d16f952", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 60000000000, - "fee": 0, - "recipientId": "AaSvUFxNvGZcvxk9ncd7wnqtMw69qTF2NG", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200ecadd5dc516c178c2d80b3b52caf05720883e07c0b28bef1e0a20f27c0607900220178af5fb06c3327e6b5c6767c848bb2be60e311ed477bd64a56caa6e66dfa13b", - "id": "d1bc92a487e9202d245e42abfb7e37f60e08d0a78a3126624dd0e0783c2a9238", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 60000000000, - "fee": 0, - "recipientId": "ANFpv6FWVyodGiMNwfqBvfNo3tt59q2uwW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022064edc033b3ff422b695196c4a6d3a0bb6b321e467a2771632816d92ad05af9ca02203afca6079f18210a50218dc05956311a77b04c9b5c9f7c960f0f796c436c92fd", - "id": "a3429a6656e132eed4dbb74b2ed17238caf2790187166ecf4af877aa2a7087f5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 60000000000, - "fee": 0, - "recipientId": "Ab9vTWogfBcwA3d9BVdHLZ7RVasLqZ7qwg", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100923954a62e4ab7684af8694637e66839fcff5fc11d54de68b4fa82f7974b313202202d89f173b1c62ab26c6f9210a8cf5b7d12538124c7366c6c1914f8990bdcb272", - "id": "6cb18de69128b7a4c91bfce46d17227f1103f50f0061a9228e2488c58d26d18a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 60000000000, - "fee": 0, - "recipientId": "AGonR6i4nHcvrHN95rsmg25YTgqRm7TBox", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f906a1d22b886f4198c8e6e8729d55f15fbd10761b445f92a2b7748ad4ed0295022018b9fe3b0e95e59d612119d349472090f1a78be9057c754dc17a0c23610247cb", - "id": "4c650df3dca440c5d3f2f17f89fe1000e114a60df15a51190134eac8feb777e0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 60000000000, - "fee": 0, - "recipientId": "AZp6btpTxvxPCWdsJGUqZJCrZMYrS6cCk7", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c8211a6578d9f11108a1fd950260f2e30c15c854c5cbe33af0d6ee329a81bfef02201fa7a8226fee5217097353f9b00c39cd6901e8cd2471cd3d3a34daa56958dc5e", - "id": "9ef08f0bd8beda3e82d6c39147005bdf9590f6df478e87716c5c69942f6e34f5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 60000000000, - "fee": 0, - "recipientId": "AQT6VvbyD8BaVSBtkq2rQJf7ZFxpQMrGFF", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f989f104e83e5091791929078b408a0e6c56d86bb8c9caed517293bb377a92aa02201bd438311e99fac1e31bd4c031ebcb9fe7f05de8a330713be4bd25f5effc2e0e", - "id": "30e10c01d2e0a376ce6deb42cedf146f8a849f9ead0170286e7ae6f5ec14af92", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 60000000000, - "fee": 0, - "recipientId": "AJRzekFXBecN23nD3H17GCvU5ykTqZ9Qu1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100cf8ca12989b34d74df49b7f7db16c5d29d5c94e387890a6dc714628ec737f7c802207eda53f3c1d3f43b62598b1b6efc8de7a4b46ffc069750a90ef294b5a5d49fe8", - "id": "167ef310bcb21341cc2b7c32b1ded135a3223f5322eb438751a5081fd8a61c1e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 60000000000, - "fee": 0, - "recipientId": "ANVX8UQEt8MkJokm35rGPiQbkMD6Kc7KSt", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220723a3f4869ece9ec362b11c309a824ef17ff8287d3a6e2f1046db473bcc0faaa02201618ea49f81bf73c60ee427956afaa75826bf94788d73319c8810ef2c4538427", - "id": "b3734997009c33befcf1d9d3aad7917aed5eed0c4c7de9730ecba54a72db099c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 60600000000, - "fee": 0, - "recipientId": "AVFpsz7LiwhRJmCAq63uMCFBXhXYaMNAq8", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206c018a247cc32e4807e6fdc62fc83cab278d50ec7a4f0f67e26094387793cf7b022014782a31c92672ce921fe86b3b8cf36452e40b360830f47459c3fd8b26cbe5c5", - "id": "072dafcb1b3e774663b9c7be4c1c2054f7c9357e3708b5d61dde8104101026de", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 60600000000, - "fee": 0, - "recipientId": "AZ7M9chTUSjuxSUkWVDyQhAbEDVXbP2ZvA", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207ce6a75041112fe7cc42d42ee0e35cddbcae0f33ba051c425b5d3afc235b691e02206092e7c04965993b38e860019c498968baef52f05160e492c5bcfda86a868e33", - "id": "d728112b0c69a9c9f5a3c1800347aa8f87de5ba5407fb16fed5e1079f9a48ac2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 60600000000, - "fee": 0, - "recipientId": "ALMaBHtP4Ki4epwJut68XMDxYVRXTwhPuU", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022050f867d1d89a62e65a88c9861c6fa93971ea08bd0564d9864a51517244196866022032ba4ba30dcf55cd08834085ddcdd425eceb7cc784f4459e62c11e70f29eed21", - "id": "996aade098c28e002949de9eba9dd663f3d9a29a8042dc516142bd56c91f1b8a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 60600000000, - "fee": 0, - "recipientId": "Aapmg3eAWSv4bWzPYMNUWMx2cULimBsKDT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a76f37bb0e4c4eb508597231f437289107f7f9fd266c31c653c2e10c45d59cfd02202bcf4f912212e7d409bf2a425d73fd9697836a63019a064e6ce2ce8f174987d4", - "id": "544531e7295c7333e4e770a010b73b7584d06751a7d05388f3a523080299f929", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 60600000000, - "fee": 0, - "recipientId": "AZHUEDRF7B1wHT4qcg66t6f6AZpmAwnQzP", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022037ff7edd4d48a58cb2d3aca7cf2b4a6f047b5e0ecf930c6624deec7e6e7ca22102202a038b5e27f88d596acc94687529c4700fffa41e907a34118e4867c012083b2f", - "id": "ce8ac13ef4d89b3c3e9cb359a4e5ecd8ece85313dd6ed08e247995fa12ae92af", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 60600000000, - "fee": 0, - "recipientId": "ALMjKKEK2z3hLUY3XubSxkAhzdpU5i8jsL", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203589acf0d84cf3f231ae931522af87cd17ba02138f1b5fbaf71b1ee6f530451702204881f4bef7736594e5cb28e5fdac8bfadb467fc853c58ca7f59e55e7a7b121bf", - "id": "2988196f5d08ebe98c6bb9de0830e0675c85fbafb60a2ab7168a633360c112d1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 60620516154, - "fee": 0, - "recipientId": "AWFzsKF4dALGbqzQgR81VbFBDdTSUJCBNU", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210083abf4d927d402f0aec00e8c37e661e8be625b8ba47b3fe3d604500c358f88d30220645351b976be790dfeec71082328756d3610e33e57cb8b396657c69fff96feb5", - "id": "a68385459023327d26fa0e745c0891a34789bc3db0392294cee99cf1ddc1b190", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 62300000000, - "fee": 0, - "recipientId": "AGikMwhSBsgXuwCUZsv3EAkxeYSsHCRany", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022014e9a28ad7815e15bef49340133ef40a0ec92d8dfa80c125eb0c26e3d47ca96a02204a8ee6d3f847fadd1ccbf50e54d4a1f220ad28125f82cc1e653069761e953331", - "id": "71a75c1380f47a79f47847fcf615e733c9b8e4d44511490729cbc2cf7cb04b3a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 62614203690, - "fee": 0, - "recipientId": "Acu59K3HbqucEtsNMMLzogU4tFJxmuJkCc", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202448a56483a3ce4580734e2734c1cda29fec792689854f77a3bd2aeeb4b395be02206b17cca51c241b725a9f41d7a7d15e308f0f94f33480fbdea4f4ca2c99d01482", - "id": "d71afbccce8620d94b04bc74c40038eca31034383a296570c0b3181b00433bd0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 62821647096, - "fee": 0, - "recipientId": "AGg3tZ3u4gE8mSM68gmeEiQnjARwUpT2n9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022011162de5da032f0a5e15596ee983ac470d62876eb2e8348cd015eccfa0b9831102207c6b60bae672fd6e593b3f5040733dde21c7ed75741a85faff759d97f8a5e27b", - "id": "ec44a065625a762aed0e093f485104dd5cca3e4d73fae79d6ead07ee6bc4704a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 63651541963, - "fee": 0, - "recipientId": "AQEsgEhmEBzGLwtXeDzYacpgHFdmZzgxBD", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210099bf9fcf91b0efffd75888770663c351f6e8158fbaec8ea99fe43382e31ad5230220575000d242528aa103ac912daf6117cb4ffabdd867fccdcf847b46d6e46c0a12", - "id": "130c08efd433f91433f3170cd7bc85b484d2c3e3c53134c0d955932726bc5338", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 64100000000, - "fee": 0, - "recipientId": "AL3BcBwg6R2PZ9pmnYe6wzeY9xr2E4Rhdi", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220684f309ec0d8e34d82365c29e7ea21a08e4d044bf5a96e17f692ea4320ad12210220155cd1bce15cfb31d60d097fadfd6aec6bdd14f65c079039d9432ec9c7ab91ce", - "id": "22372757608284b2b88a6c068c4dc994ca37684d765c14f5be0bdb48ad50e968", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 64100000000, - "fee": 0, - "recipientId": "AbpU1DmufxiTYMDQrbKjeKumxoVPwKyczD", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202f40051c81e2bf95bff6cc78fcf9cab2b999d48ebd9b6524b593c95441902d9e0220347c380e7fbbdbe5dd4ea8492a5deb17835b48ac22f388c2b519fd4103fff0fc", - "id": "8726a184e737d57567c17b077a424fb7ac9fe5b0cc9acf509e3af87baf5167e4", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 64700000000, - "fee": 0, - "recipientId": "AR51dQ3b2iPD7kxY6Jr2f8nvG9V1Tp4bXn", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e701b0a5ae50d35cc985776be08a2af2a1189df4a7dd2bbaaf7b182ff5fe5ebd0220123def90996bfddd4c0769746130d4e13a8150d75e32770b6fc2024cad56e80a", - "id": "9f890472facb44d3f0fc91cc3100f33ff80a0ca419d6654479c0ad2e1867401e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 66023125672, - "fee": 0, - "recipientId": "ALMVkKVthbGLSyCAu99UXPTcJUCgycJCio", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204c190c4ae5a7885bdefb89112f08f782934fcd60fa2fcc0ffb5a57fc25589f0702206c086bd249bceabc559d1bce46a35687963c7af245e982b83bcb4679d27f048b", - "id": "f0db655b4c6a0cce96585893a9ae0b5834629b471c8a10bae2d03ba7b59a86a2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 66682567770, - "fee": 0, - "recipientId": "ALVWWv96ePvZpsr2LJiYkgczjp5HFh2vS6", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d4223e4d6d86f362b5d9bbcf4887e3b4a7905504509d7cba066761e5ab4f2eee022053f2f8f1e12ea2c979c1ff532d2529577ee1d5128e4863e4b88081fe4223074f", - "id": "e49671791471089e19114260ecf0d0410571a828831fc693900129992cbdcd32", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 66985670351, - "fee": 0, - "recipientId": "AK5aMpBxSFkveYCPLK7655BNCYxE2oDWTj", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022030059d3cb8c99259e250803496094fcbdf5c644a54be5de71ed67579c50dfe7c0220551dc20a9ea8fab2756d945ba96b6df226f786f1517ba500808990535517540a", - "id": "1ab441b67ca4f041fd0b4de0ee084f47808fc41327afbf0db652ec6e8eb0293d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 67500000000, - "fee": 0, - "recipientId": "AZiCsJNur5AHuBmzXFm8hrvzMtxaXeBmTP", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100819f9e25f210711c95d4f5bfda34f90c4cac0d2ee7fc788867059cc8437153a302202f94cd63aa4e59b051dc69a1acf46cd905be00b8547d377f705f6f63b3a61119", - "id": "373da2f2c548fb4f41d36f7b39aed883804bc453846bf42ad223c7dc22f65903", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 67922251265, - "fee": 0, - "recipientId": "AaVsZhcJWbpsrwHFYQ6Ms7dwRamLQGbiEQ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fadc2d82b1e12c7ade65115d3d2a80c59be0570cdcecba6b6d46500de0b1723f022027b16d7f88841422575354d423d0cde46edd1ff3dbfe77cec29aa3cce7ddb61b", - "id": "b6cebe893f177fac2b32bb805b3a8b6ef79dcf42d7e7e1e367da46fec3c6e659", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 68047923959, - "fee": 0, - "recipientId": "AcfGpnqyxHTTCg9qGGDNoJZxp9gP3RZJEs", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220056ebdfcf97cd26c4f1ddb8d2dc2eda872aa41c72122dbf4b1fb7dfe6a13a566022066e8ea897d1845fe11262d60550d930d4ec0be1408c874ae05b6705838499ee4", - "id": "636db58a8c9e586a4eb157c7b2be73af3edae8b5ff48248933970e06cc14ed67", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 69300000000, - "fee": 0, - "recipientId": "AdReKteT3KZV3nxYeaUwbxuvNu4Tbux8QV", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220045e674e2020858cb6db65016b0721094b18d69d5c40b21e420eaca23c7e5e530220581f3f511f5ac357d3dd730ebf0e6084d62a9aeb356d1317463799444ed3a327", - "id": "194bef1b8604a0d86e0dce346149d9a67dec990def05321fa4ca2f5d857a3b45", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 69300000000, - "fee": 0, - "recipientId": "ATBhoLR6mCACu9T9iHcvPmXBbeabR9o2Af", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fe79b98c6ac6eea23af36c1cbea5f5ce104ab7e8cadad9905bc86c36555e552f022050dc6c3a5334e5efaed6f072a584319c51dfda211522d9424561e0d48bf5d7d7", - "id": "bc5c5cbfbacf7ca885544dd956d82dd4a99d3d9a9b922124556711c35aeaef1f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 69300000000, - "fee": 0, - "recipientId": "AULwd36ELPQHp3MBCVjQPGsG5vLbWDwsX5", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220730f890799382a99a6082648a97e89117ee5ea2cf79405ddbf726c8732a48a9a02204791eb8cad7f9b987dbd4865a507c87d446b502f4faa5b469ef938be043e034f", - "id": "8de5f8c57d06f1a26d57f2b30e1a6de70c1f4181b5c7a5ac46d4d77d4aa0d1d0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 69300000000, - "fee": 0, - "recipientId": "ASWtE77ekytMEB82Snx3iZeyECBwcyYAGU", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009e5a8e6261a7c50f8cc6afeaaf51cf433a55a2ef85545823811c2bbca752046402204d879e4ff9709ac18288c75ff6b2d0bf210d4466a7c46d82d688727b3a49eaa9", - "id": "a0d0bd4e4470ad7708a1b6a8d8c26c5ac9de239b8e15a581cf2a29699648f944", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 69300000000, - "fee": 0, - "recipientId": "AMWKeZaKAZgtvX3McGVZGVCjR519mjdxod", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e910ea19a113d2fe010320fba9848358135d3989f92c328a59d9611e1382a2c902205e83c177d11dd68147d97a9536fb8657b18121c69e3257034a101c7c928d4cc9", - "id": "622e1654011fa90a79be805a43dcd875b0d649c5e5d455285c2103430f5329f7", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 69300000000, - "fee": 0, - "recipientId": "AMP3grMYVWSxx5g7KdRf84PjvT3f9NDiZ4", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100acbdeee8bdd4dc28809d30dfeff20965f48211675bddf7bed7a105a6e04092e202202c61fa35cc87ab1b02a8530b0021a8d05d2d20f34520637c9e17f60e603ac2b1", - "id": "9ade4fb6bd9dec55103ea68751040bb6cadbdb7f7518442327d72599dff0ec36", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 69300000000, - "fee": 0, - "recipientId": "APyUPnRwawq7LHHQbuLVwEVvviUS9gYvqf", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210082e9e6dc9eccb3d40725cd5434128ebb94f56d47bb864d879a79cf6a6d7d92e6022020e76a058819f2d1afb709d1262835bd3571112422f885d1bb5dab06900a41dc", - "id": "961478ef66c79ff2bfe8f9c1f7f530c1111e998ab0f36386ae9b5d6a27fe2875", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 69300000000, - "fee": 0, - "recipientId": "AaygtE13tPoD7HTNBJiJQ2McDRxVaWdJYw", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ef82c8eb76122d5557befd50e52d7c297ba3ec741cfc050fee3a1ca10d3bd01a02205b199789061011b890a09029642750b784f53a174082d8e113a43083fce2cd24", - "id": "5291bc37168adc5497986964e7f44a553aa5007143cb056be070857b285cdb0a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 69300000000, - "fee": 0, - "recipientId": "AamfrghtYBbWkQtRV7vohTfrJCPv8Sg15f", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220757f338c7cfd2ba9342a5246b2c20ab46c2fab13d8b8475f748ae596d721afd702207dd4f45e4a0562765392b4041a812f3caba35985ec8b0a27f59af91063ca0ff4", - "id": "49f82d3d4360a92c509afd96a16e76adb8cee98b82b17c9ef0d8403a7d933b8b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 71253891180, - "fee": 0, - "recipientId": "AHcjnPJA9tdupQcjcJMLtD6nnWJ9e6KFQs", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009ac53ee5d6f50ae5eb6021aae45b59f77ff49b259a42bb7b072d1c9506c0063602203238177cd22e6d418db707699b4051639c4c530283d13a02c8c9ebef4fe9b4e9", - "id": "04069fc9bc169922314401d138568a956bfe70d8f3658a5fc456c33ca10ad67f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 71429604399, - "fee": 0, - "recipientId": "AYFJQE3EPeSkuxEa4PubKaS4eVitUtZkiR", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200add47cd5990fcd49c559868724063fc58cbdffe8c79aa958a7ecbc75a603bf7022017f022de0655cd62e383d4b7d9d4a4a074b8222ae7c1bd6cf26716c1292bb3ad", - "id": "06ed48da4f8bfc579c4ef2298b43745eb77529889ece543daaaf68ff2bdbb9b3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 71590501751, - "fee": 0, - "recipientId": "AMP1K45yauAQU1c2NqwuUu6ekCmBqtaPoP", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022014db9f5d0e46fd745c970ca39b54ce13f245ddff480e7abd19b318c262f3b951022062ca17464681bdfc5381876ebeb66740f14ea227007c34a4dfb1fe0946c6e2ce", - "id": "34598c7779c1aff18a82cfb53f52f7cd9baf51bf2fd9eb2d8088f38e9de615e2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 71600000000, - "fee": 0, - "recipientId": "AQRhAZwfV8rwCvsb4WM1bVTbenugJn3c8r", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206b2f68e67bc4218888b389cadfca07d954a4388635974d1c4872819d9fb4305402201dfaa7ca2e83c0694ab80505ac5282ca28ae45970161acb774b38d87efaaff22", - "id": "e9a1f1079b09dbc72a80b56de6c65f7414455d7d569c6ef55540286c6e6cebce", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 72653688612, - "fee": 0, - "recipientId": "ATBxkNfkzM8NBxdCsJ44RdABoATkD98qdR", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ca29827b5530b9846ee5a9084d75a067fbd9a932073e731af57c460bc403b5210220487342cde09bc5c339223b575a8a4c325098202707c68d09e0ed48bffdf72f1e", - "id": "11ecc7e569168d579cb6273ce6d27f58f29fd4db7c2897082d6e49cc6a9bbf8d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 72700000000, - "fee": 0, - "recipientId": "AW5d3EEDJBQnKFHkPJnKPTinSivnBzUYkB", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204e68f134e251d796c0c4044c61881a7e49f260d17aef7fd2f4d54010d9fdf52d02203dd02402d012f4d91946dcb449f95d61d874e02ca02ef4bc2c36f7d4eb5b4547", - "id": "f38d068010566f2d81f972525779b84f6e8693880ef6251b6a63153a2e98d9ad", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 72700000000, - "fee": 0, - "recipientId": "AMYvEFsHMcctwEmRrghWE46Jj9kWbFPA3A", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a593780b9925611723664234d85ffde90f314afb68d45e4a0fccb00d40c1bef302200ddaf8f1677d988f24302a388e71d069149437822d9c7d2330fa037f96770110", - "id": "b1d8f7741c54407d505bcefc467f1daab79772ff77e71bbd0ef7f8708ae43582", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 72700000000, - "fee": 0, - "recipientId": "AR44YGUBeJXZDQcbUebK7Ds8fVHy7DHjgW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207ac0a6b2a5468d60e9f0290e5ceca35b896db702038309ffae2a410ba25f2b6902205d3643b2569c0b185f2bce2a1539f5a1cb92438a1e6efe3512080712fbf4774b", - "id": "1bb883cf35619f46d4839ebaff381c9ae4e00c3d4cbe981acd00bd98a1c4ab91", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 72700000000, - "fee": 0, - "recipientId": "AM3F4yHDLbzGGqJ9uMCjnPCv8xzoJ872sp", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d6ac3a85f45bd763fa1fa8850dc8fc12978155982c3dbc250a5514d2e4f6081502200d08e59cbb1dd6bd22a7ca8375ae7bde3dc2499367482483b84b5dbf2df4a0f7", - "id": "e46dc48c6353759f1bfd73f83112c808d8a2ebbb687fcd177002f7facc3da944", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 73796297519, - "fee": 0, - "recipientId": "AGcoFdESM7NdWm1HodtJyDU32BHyShDqat", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022071e03ef704b56aef2dc368d7ca2642275dba4b81eb085aef6b8c1fe48307006602200a4354795dd801e4752ca441187d98f25609ac9b58a0ab79d2bdad3659db6ff8", - "id": "71e2650406959057c6503cf336a99c7be97b592eb47e383b03a334bfc3cd5bcd", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 74014667709, - "fee": 0, - "recipientId": "ATkzTWGZPHNhEKCToyULmtTaxSJYNiZRYz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210096a5bada156e5b921023bc5d2e79b9cb6058c2a6b722674c3bc04ff45e2c2d0f02202a804f965b55887303c2f15ef22bdfa0f70639141ab4db6b982832b76e5111d8", - "id": "ebab1e0dc5d5a02577ba83b3bcb0641722dfd2f08acde9ff14e7f4d5c5415ecf", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 74124099984, - "fee": 0, - "recipientId": "APpwmia2SFKQmhNZq9zxav8aidP5vBBptx", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a4a58e349be3f5d8da0b00d71bc150261f2538a2031e06fc8dcf0df8afcb6865022003308a299af829c6bcad2f9bd36c2648d96eb3a3bb8b0c33e687b33099cd1fb3", - "id": "0dc2b86a4ea26f04660150949d00091900028bb6fef863392f2bb3110e77b498", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 75000000000, - "fee": 0, - "recipientId": "AWshU1zde3iSo4691GzJ1ibHDCqA8n7mGW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207a0ed602d07dca8bbf2b4d9458a0dc70fd92c192c2bd05cc455dab5977be3d48022044f872dff762af785e654198f8342b6083e66e9c0181a16c3c21a1f2423b982a", - "id": "2df19ff6e35c5a76a99a062d893432c27fbc7e98e6d4df4ded66109311b58744", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 75000000000, - "fee": 0, - "recipientId": "AVWUFjyvKxXZLYexXDWLiJLuLXZ49Ymb5f", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210093a55677a758062eeb56a99d5994dbd886a2bdd33f76287fb9dee7ce6f25322302202ce4a80a24aa3b75d0b8dce030b04985f3b625252ee8411223735ed013535f1a", - "id": "40dc85e19386d391e0da2c9d50cec7dbdef55e9777f8e0952e26ee7c9a2523e8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 75000000000, - "fee": 0, - "recipientId": "AL9X3YsJksdtUqAMS2yojWG3rThNH3rXqc", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022007d901327f63e75971e3a5a023ff97c2513cea96dbd4f4d2969fc33fcecf3c8d0220606584131bc5a786e15e7a7fb7e8dd752cffb73c578b5933a62d6ea6072c4ad0", - "id": "9d0d26d7fe267421fc7db3b7cdeb2b877696d056dfdbbd4dbc4fffbd052c5584", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 75000000000, - "fee": 0, - "recipientId": "ATE6aerp28bsHn4g9uhKk4ncJiGtKpuSNe", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204faead30048606f6b057ddbd4ee76da47657a853cb8b644e588c29d375c9f2ac02207785f0ecd77c1af9f8f0f68c5cc3d344e4176fbf911037ec8df681e72f5d5f09", - "id": "7f2a17f9a14b1c84cf539431573a00a63d9059051a58ee50a3ae575effc08bd5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 75000000000, - "fee": 0, - "recipientId": "ARc6St2Vj9T6PU8JPMtUn7RBb3DuM9uE8p", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100de6a748d2991d40d71bbdaa2de5cfd9cfef49c4bb9965174e0bdccc58cd7e0f5022027ed0e384fdaa03164d3e0f317f475d6f7728e1747afe8ba829a47edd3f39b59", - "id": "ff8a36e128dfadbdfd48159c0b65c608702425d36f3dbbe0db0657a80cae66de", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 75000000000, - "fee": 0, - "recipientId": "AHfcau8pKsQVGWzFCWSXDyoXGGkTKvuXsK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b1a48ab2f689a43aeb5e2b8d59f6e777ef945685301e64dcee3325bb9b3ef46202204b125c359a5d00bc54f0c0d0d3580a9841c73cf8e2ae19fe3e9666587a83a143", - "id": "64e0e887e60dfe4cf3c0a0a00ce3c89c5dbf6d76607e6c1bec2c8e65611492d6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 75000000000, - "fee": 0, - "recipientId": "AaSGhysJYBesZiFSf4zHj986A11DRvYtca", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ed44ab5a22710c41eaf06885e3b3801bc9234987085adae32f7277d1c31dbd51022022a855e38b1e57ad064a4004f37597ed6d31deaa6378e06dcbee180075ac0fbc", - "id": "c2742c309400d0bc0e4cd6b4a183cf9c58d2a8d00ad67564e6243e5019ce79a4", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 75000000000, - "fee": 0, - "recipientId": "AS3gXToMKTMydG7jNvxUMNxygvUc7okXXw", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d8b5a57241bd6982060e2a5260a6d6a9ad076c10e9a6b863503686b5b1d9ff0002200933f2e858f279ac24011d5008fe4a6ab99efab3ec795954a5b86c121fc09a90", - "id": "27fb7f36d8e0e19ff8caf5f74033b5912eec9611c439561f1d3edc37537c569a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 75000000000, - "fee": 0, - "recipientId": "ATS6jWiztxiZw8EFr2VU158ZiJev6bYfiF", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c434b9605d6bebe5950ae910388235326b701d218a72f630a523386a3d085fac02203ba1a9016a6738f0d6078d89d7e481aef5fb7e1c698262a345453f8978211ef0", - "id": "e78b60e89f9757af6f2193efd826c7f4e43cf55e992abb49a49fc6efd8488ffb", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 75435988442, - "fee": 0, - "recipientId": "AHZ3K294SDAyoNfoBX7ofAvxNr3u6bt2Tb", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b700ec2b35d2a4a0a36802e503a75794557148e37121ea7983bd3bfad456d19202204fc34d8b6fcfd513b1e7d74dbcde9963eb606b234897f1d8fcd1024d236a7118", - "id": "c331e66c718f09ab4d637cd139a5e0a9620b0aa268b8548b51f82113a6f91961", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 75912885491, - "fee": 0, - "recipientId": "AL8QkKgRswzkHyPfaYuknd8F98onyYfsw7", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b2b7083ee6801b455e14c24c1f739e1f19f39d429054e86c77475d82c54be2470220128182d6a3c7b36eb456a5e2438b9cf7579b981feef78a31fd71e63200ca1959", - "id": "9f74b82aa9272226bff1637d566a3e3ce213957f053eb6fb167ddc9d1b8833d2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 76800000000, - "fee": 0, - "recipientId": "AcHCwqRbb4vneRguSP6SXqFq9RzUt8CCto", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203e95f92a3a0ff1cca53e0acfd410a6204074cc52135671a1cb1ab193e7e42b1402202cb648ac7bcefe13152483a85f5cb54a1f2dcbbbdef70fda2e9744d210692614", - "id": "1758ed13f7ab2c65bf54bebfff06763f6955bec8836c1bb84b9277960aaf3cf3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 77291158098, - "fee": 0, - "recipientId": "ALikhBgeXghUsmNXXwXD37SPJJKP9YKFQZ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022037329d395aa796dec8db0f41eebeec510fdce6cbcbd5bf429bd308392def4c6102200f20bb5f7d5849d26ee324ebe881ac7fabbf3c4e7fe5e93605c0f7615810f50e", - "id": "144e1c573644f0461ed333bd72feca9b94c7233763ef21f196cc869937bb5de7", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 77900000000, - "fee": 0, - "recipientId": "AG755Z2rSmeXi4nXc2Dp5xjEnV3h9DSePY", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022072dad4689c20a7daec81141e12e12b48ccd71072cd2c6350321523515830f97302201e442d4448f5a0fb02e73deff73b0f798262beeae00d47c8f8a4ad94e041a4a3", - "id": "50259feb79aaba9640ac99629d6dd7cc84a43c14529be5549267c3fa219e071e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 77900000000, - "fee": 0, - "recipientId": "AX6JKGAGAURGfwYoy8r6BqCsiHibZQFtSH", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100894bcf3faf2ced40b12da116be0cebcccbdc17d822fecf2d52be9dad273dda8102207de8bca9554c27b1a37e7679c1b8ea4bd75b1b47697b9535789d5386f2a69289", - "id": "c6a38a970ca5a17e2632b958bf0f035c4760e2320fe5991c19dcce0fbc2ab0b8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 77900000000, - "fee": 0, - "recipientId": "APkL2ZzBb5Smjhv8f9ugVgS8iRJP48pZEs", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009f0a965cdca67e25a459cae3674e261d235b631393a521c95118260a50ef817b0220667fc3de471fea7ebe7d92776f8d0358bf1cb6e480c1964f45d104ee9ebc815c", - "id": "b11d02a6be882a82b57e34d0876feb673843ef6baafba06421adffbf34512108", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 77900000000, - "fee": 0, - "recipientId": "AaSzFFxYD6brxjKMaz6PsLM8Mgy611VWXU", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203968e6322e183b266a578d5f6599b707c74b8d35dfd2722b1e43abe8850434af02207e4a7783ba60cd39d8503769f886d7f699b673cc1811879f37c97e000aee180a", - "id": "8a51fa7f53ee7372961dbbc9dae868c1111748d769488e36cb21c575ef3e9475", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 78500000000, - "fee": 0, - "recipientId": "AavMxN9AF7pJ1yV2qmWjYeihGZN4QBVSTo", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f4b220829fbee7eaf190752898c3bc55359ab757413f2acb3d8f3f3c154e9206022076632671be2f123a47cc6b18b1f4ce8c5fa6697247a7b4a4da6e87e9c3810585", - "id": "becf405f252fa1c2c16031dc31feb20317838c2995476064f11fae9e7b3f23db", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 78806671001, - "fee": 0, - "recipientId": "AHTeBUJSraRKMDkpYmE2kzCTdEMTw2iS8v", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d1db2ff69f14e7066d9e3a8e9d9325f9c9c840ca2f3cb4499b72d615cbc47763022067e19df7ea14b245626624b76b408827093fe02036142966ad7c91c2a847bd83", - "id": "98e5b97afe377508e7c517db5d694167a9380169c78903aa92c557d673b7895c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 79513639585, - "fee": 0, - "recipientId": "ANg37TzJQgskwThhQ526R6EukJff7jWXZD", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e68c3dee5a9eb77645c958a81f8b3684485ab7ef7108eb29c95239d618ae6cbb0220779e760390ec7ef1700cc84b80361dc80c23df1bdc8fae6e2686e20f489342df", - "id": "e6fc80f568069d7ab3bb599d99e81f02ee2e8d85b449e37b2456f996f729f727", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 80575550021, - "fee": 0, - "recipientId": "AUwoiLFPxQimPnE8Bnp7Z9GVLGwNMn777R", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204d6e44f453221389ffcc58e8bc98a9a2691483f2e0713c1c0ebb38ca87236593022041a360781403cb8f434b221177060f206b3bc7bb184e011eb1e5066f1ea8d70f", - "id": "75dd1bd25d4413d6d4d5c2d9853d9c03283a2606365b1f0458d1f05d2923d4e2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 80648439946, - "fee": 0, - "recipientId": "AWojAkunWdVit59t4Pr29yGWAdhCrMzeNf", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022030ee47eac2cb2b80f4e22f407d8eee4c29733efd0e11daf7a3937bee384e44be02205695c43c6ed886a5db961b87b6008ff171ebc5add97e0318680528940ed0f007", - "id": "52f8f83b4a2346b02e454ecb7dbd9fac6a8d4c3f2596eccc5cc5c1444844a0e1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 80880602287, - "fee": 0, - "recipientId": "AdTfUqtiB3NJuhhw2T2xPYHiMJYGJLFXBT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e5957017f40d2b9a0a7f10722697b00e49c16e791e1debccb1c2a072e3d063c202205c19ad3b770b138245321ff7dc299ed5f411f3d9fe727f22b54d1165f0447b8a", - "id": "f8900c94b8fd4e9c80d07fccee69881edfd4c525f7d624f076522bf677c50c56", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 81355763706, - "fee": 0, - "recipientId": "AP2TBQe9NmoirGTja8cbSuH6158GFprhoS", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206a6476bd2d646155d0bab7dc4f952a8856c7789a6512718ae6d8b7736ae1ba1802205fc63cac9eb495ef7e2426a64668b771a694826c943023891f0f46f5ea8d4741", - "id": "ff059b0e5477e3417d2e3ed156d6cc48dcd62cbd7ab13e30c5120f80900d8e73", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 81837696809, - "fee": 0, - "recipientId": "Ab5x44ac1h97exN5QJsXY81WfMTAJx9YyW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022014c66256aef1f3094558a0890efc5a0f22a25dbcc1ff52c6f618a1ba519eb5cf02207a79ccc6cc6e562604c2d8e11eb041c27ff824a2682de9f399906e5360bfabc5", - "id": "4caf5c2aa360f7f94a872c50e41028b7c83540dc65ed63fe8c982fcf0472c0b8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 81837696809, - "fee": 0, - "recipientId": "ATpmYfefxVXdB6raUbujbqqj3bx5kVoDfB", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022073d07498a3e0ff75e0786796c973e8700139fe9222319fed425e96b03c78dad5022012fbc2aa62a479c88197a3656ec4488756356cb4d568ecf65fce5e8a15f5c5c0", - "id": "5e3146ffca3c3c29e76ffe1bbf28dacecf88566d393117d870feee892111cda9", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 83100000000, - "fee": 0, - "recipientId": "Acp2FNSe4DwXdMvJxBn6iLGGMZnvmtaR7X", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100cc65894c33488bd85d10eb2104a142710a36d8f4899c8198dd50db51ba7bc6c10220527d3192c1357d324ffb84a70fd02b848328fef04d26537255c4f8790283f138", - "id": "d584d07fac0668f426731192de3967134dc574c6fedf27d98118df0c796c2dc7", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 83353209713, - "fee": 0, - "recipientId": "AJHws2iLF46S5j8JYEwSHnSvcJsfGmXuY1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207934233bc6857a2ec4440fb1d3d80c30f3e71b86c59438fedc0cb8f773e6d15b02202f6915682768af0db3aaaeca4e8154acdda3446ba816d4086636af89ed8726b3", - "id": "f16ba7a15ee70202fde2f172673374204a3beab555954cb8edb829214d4d1f9c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 83989725133, - "fee": 0, - "recipientId": "APwVRmToNQFy3vq4wiEHfi8F1vYfwGXMxe", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f04bd60b6b64559d86587bf3c83f6407c20b0ba82b91db0d79a284222d5ccabb02204bac2bdc4e1b328c668aa33cac6f435b666cd6e3f907b91463b3f5b03678d799", - "id": "6cc3b4a346d67a46d101749766f64a6332dae291d148b969d042cc8d178085e4", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 84900000000, - "fee": 0, - "recipientId": "ALaNWEzy9zhCVGrJw28wSV91ES1fhWZpQb", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c27e16af3bac0ad147ffd8a884565fced7a6a609fea72d2b3e23a54cbf83e77b02205a8ad93c4da3473bec4315ea1917af5734413171b22df8d1f1cc14b1f0071f0f", - "id": "d7b32ba893728ea38b48d632302f22e87dab2c04a01cfd809413b7991afbc70a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 84900000000, - "fee": 0, - "recipientId": "AGNzHhBmg7JkSgae3DKbhj45cJvd3at1ht", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f0dfcdf262541ad079d15430a8057ca753ae9ad4030811913110356b177afc19022031c0156405f2ca3262c121a648242b65f40e6b9e02f981af090bf5fd83d77234", - "id": "d3173641dc8035ce4e2bcfb9d20ad323b3b525d9cab25a86f8c3ecd6cddb1c07", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 86600000000, - "fee": 0, - "recipientId": "AbcfAjLyDM9xKnnKyPq1esgwrpPffzuhpK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100868c42ee9b8707f4c5fe317090e9d4bf3ee8fa023fef5a2dd1ab6e5613b58c5d02201898a17c6bc802c3bf03522db36e4d23a4fd74e780e83aac72043f51dde78074", - "id": "8c0b5fb020e1c904661cc97dddcb5ab0a946d6b4f8e74e4ec22dd225ecbc29ce", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 86600000000, - "fee": 0, - "recipientId": "AKFXsYK3u5Yys3gaQVtQnARgQYr7K2qi7Y", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202298b4575ccaa0e90fc62851eeb490411cf463a7f81205b530d9abba7151376502205b1834247d0e24b428d211069e86d0fe7498dce5545c21fcbc669a04738440f9", - "id": "83b38ef3992d3ab5884eb9b7bdfd37d7f937134f238e0810aa807ec6c78bbd34", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 86600000000, - "fee": 0, - "recipientId": "AHiUknBbPYinqfG6pGkgJnLWXyH5SdiAwu", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022068147f79aeecf424c969d66138b8cfeb1a543bc833d0c1dcaea2b361ca67088202205af3b0111769ab1ad9a03f98c25b3df6db75e352c973cd6ac2a5adb9a528af23", - "id": "8fcf8c21aaa30f9a9cbe2e8f17ec58e811e52a7cb71ddd76a824560dd5ed26c2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 86600000000, - "fee": 0, - "recipientId": "AGpULTAeC1WWDY8PFZjkzrbhwUqnksCTKA", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ef2a3557376455e0d25cf3c951db49394f7b211503b42b57a239be0eb76b41a402203406584ba5c6b3f1c791f1bd54781c27cdc2e4f794b1c187e3ba05d8710559bf", - "id": "7c09fc8b85c9a9b231aaa24e4ba3149f2da51dba3693bdda7ef1dc584b6e2094", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 86600000000, - "fee": 0, - "recipientId": "AWhFiapndC1wvpb8o2cxWak84oFu4NBRMo", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009a5bed09102a91a9355bec42813eb86645d93ef79c7eb0b26db2bd155008678902207b8ce7fb53a59078b53581a81ded88b791737d1caa5554c16a05a9c4ce15034d", - "id": "0288e9d30d96bde32799db384292c36aef36840fe738d86431cf001180e171c1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 86600000000, - "fee": 0, - "recipientId": "AJUmYRUYf6hksjU2eWExtQZuxf7ZCACSzt", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100dfea58e5ce12a20be120decac2941a279eef12189d7a5491856278c7d18edd8e02202aba95df77908c8f46353fb1c4bdbbb1d68ad510dfdb082fb7c7f74e3f4f573f", - "id": "eba13a92a631ea574f1e478f8d5612d3af6ce7f6d610b669a7b46b30d878cc7d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 86600000000, - "fee": 0, - "recipientId": "AY87NwPwRs4tYVYHznKKoqDWLqCUHrErYg", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210098df44bd72c80c3ee825909494f2a973484d1b9d806e8b2d6359fd89afe5714b022002b29eea85c6bac9267d37d0ddc0f74a89c5833cc15f5b8cb5afc98355b6eb4a", - "id": "74d30f27ca09703402c3f09089ee5c4cb8548625974a0416f5efcff722984606", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 86600000000, - "fee": 0, - "recipientId": "ASmTzH5eR9V2nkrU7E8J7G8Mu8RTiQstJe", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008f15851112cd2825da273a761843bfe8d772c88da8e8108835f18758758e3bb7022040497db4055ffa5c14c2a2f3fb000cdbeddd5a8fab8a9066e55b2beddb34a790", - "id": "850b70f669c62b31665190b27391ec3dff00222e4e86757e04bb35cc01076357", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 86600000000, - "fee": 0, - "recipientId": "AQqd4UCBGeKi4kJZyjoqPB62W7Gqqi41YL", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022065e858357c4f598f1cf4c26e20e52b245fe92c2c58fb66c986106800e106d02e0220071dfa1c61fac54e79288d6b59f7b15c7271269e7cfb4c93a76bd0a7c6858011", - "id": "dc1dcfabdef49122d646d50d52fe9b558803df411c765ccf04fc4d86cc084d9e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 87141991973, - "fee": 0, - "recipientId": "AR8hYbKPJYajTNZ9pnpHjWrm7CFqSFaGHL", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c68c155894dc39eff0136d6aa9d7046964f2abbff63548e669298b937a2554dd0220669383cedd736fc3524a286ca3480001e17e6fdabe616b0290d151bed94361b5", - "id": "1697ab9993ff077aecedf05e5897d1366435f757709d0d4b8ba163cfbe64192f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 88300000000, - "fee": 0, - "recipientId": "Acd1WttVcq32Xv7agoi1KnoQZ3uhS3xx5D", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a6e73937fdb2867650c86e5ab5afe66407d79f38ccd10e9af6e6b9210852bd96022064e9f36604a80e8ebd292143d6dbb4dcde5fa48567c1389ab448a87b57a7edd3", - "id": "129f59b0d566a5081114b4a4a287e8d352baa05b6ecdf8efff73fd0661d92da5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 89405066332, - "fee": 0, - "recipientId": "AGzvuwhRjpXsCiF1acJxFnnXgNrMd8ekWe", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205dd8167fcd2a31bff75cb1a6a98adc1490bdd1c8a073929aa05bb56ef3cd199b02202d18b11bbb36c91fde4ae756b4cf7dba8197433c8723835ba91b1f4424a40a32", - "id": "87618b8944a3032bb912cbece834559d1f043e7d7255705c6abda7bda031f445", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 89514072770, - "fee": 0, - "recipientId": "Acn1izrpJYNCFrqFwFQhKXgXHHyxpGAVTw", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207a5fdefe87c639533e3a5ab01f52624f4d1b468ab88eedab0e523cac50513e1e0220388fe25747ea2764ca18cecd4ef8c3ddfdfd2a689effe830b22f336d1db292be", - "id": "2eb0bcffeb0067aa69f8438afdf76f91969faed45f26cd0c641fc0b11695145a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 90000000000, - "fee": 0, - "recipientId": "AG1bTaALP6A4Lh7Z3pDDehv8saCFpf3RZQ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204f0e2ff8ab6eb771ce67474134ca7a8b59f5d0fb421730fdd306803a548f867d022029256ce0d0c018660a1c3a9f38a7c627a07247a73b2058ae52a000fc06781267", - "id": "591c06ac993f8d1454caf4553330213b9fa246c7b8e761077768907b7f136dd4", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 90000000000, - "fee": 0, - "recipientId": "Aaq9zxgsq5heY5uGvHWpUanFsLp1aFYtzs", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c537c102f6d3e77742203961dd7718f4441db6f9c73e6dc17c139c7639707592022049a206a019ec362981d3377b6172d499de98a4e603b2c6b6772e676f3161ce7d", - "id": "c66078f962373fe9663a4a89460d2cb8694aee100ef510c511376b64a6129d14", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 90000000000, - "fee": 0, - "recipientId": "APdt2CLhn79TsuFb148bXN4yRWDtxXByi9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100be4c6dd3e6266e8f3c488f7a70e43547b289a8a838af519fc0e3718270133a7d02202b438a20931ed53c67c4122f3bc8543c5f51fbfdd918e87e2da4d0aaa9becaca", - "id": "fd445aafceecef71b3bf57c4f047fda3759aaa279f5bd7108a5ef27538b11002", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 90000000000, - "fee": 0, - "recipientId": "AcAs2VGLLA3CTwB4zzHBnbzrUpFU94qpo4", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c21d6ea2c66bc26ddbcb250dcfe904c10684eaf8a30aef233aec5b64d3ec9687022011396be43ba72cd7cf2f5001e619fc4856d972745d012194b3d951834562f802", - "id": "0963c73ce61593cb65e2faaba4c803783a37198d3b93ea54323d3d52615d45b7", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 90000000000, - "fee": 0, - "recipientId": "AHvDiW6VVXRHhGLkMpuR8ZX5auBZPHK4AB", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e333d51da7708efc3ab80ad3e510482ddfd87f2193b1d61939d38d5092fc5be402207bce382e3990b99c53e0c8e5dc3af4f948a7f511e514684e0f59c37aa0ec54a2", - "id": "f2d908530b25ea4f3cbce6547e4aaf248e18fe149f190d598f775fe26458e60e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 90100000000, - "fee": 0, - "recipientId": "AJ43cE4rT2RoUAv3LfkDzYYG6podChvrUQ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f4b85a3222ca9638fc1b8c5a64e4e23aec2cc4ccd8d957cd1ad0747cd430fe910220716428e2f6d7289bea53eb029006d1a1472cdf4661c0e55eb9b04ebcfde5958f", - "id": "a533655b53cfeff54fa341c2d9cb376e71c70f2b7625f798a66e6e1e0ca1c505", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 90882035337, - "fee": 0, - "recipientId": "ARQiX23neMcAX7SPfyauwbixNhfWF9DF7c", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022018c324014c8bdd445bd2025fe527f52cc668886705b068837b9d86cc079ff215022075646fa0b7eee5be5355c1630eacc5bf4b98b1653db006d1cbfd41e07c156218", - "id": "4111147e598f03fce985dfef561a5205500865a7adaf07ebef15a8035b070726", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 91944813749, - "fee": 0, - "recipientId": "AZRqkB1K4ybcsZXL5ZV6sYfcqYD2bRYwzW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220794d5cfc737927e6e6e2a628298466bda26bebacc349fa3b75cae81c636bdfcb0220463b4ef0055b4bad1150add80f192999486d91c4ccfdb07da77bc9100844271c", - "id": "8e3e472a029d3c34d9360a92e08f71ecadbe5c2290fcd295d691b35444510626", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 92749389717, - "fee": 0, - "recipientId": "AXiaU4ksGV7AZHLSPPMM5Ey1wbEwEXoV2m", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203436a912a9c53191957842d0d04401a5b33b3255bafecea63ffb703fe36bc4a402204bdd3dc39ea956d43a909b9e5ad8c71909bb5291238ef2b0ff7bfea8cecce5c1", - "id": "6d4a7e3b265f562969594ee5ada3abf8a1a3028a324803a7d8566b294ace73f6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 93006402914, - "fee": 0, - "recipientId": "AXZLHoMLqpEVAfeP1qcdtprba9GBoK8rU1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022074f4c6f3bc573b7e6ad33da49b2f429d8bd93d2947c8befb2eef024e24b885ff022035902bcc93a8f39dad93fa36d0c378378517d50ed2bfe1b910d8b6bf2712b3c6", - "id": "69adc07393e5f7e41408f665571ccdf56ed41e8414002df3a5ee78f83d4e51a3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 94906857132, - "fee": 0, - "recipientId": "AGwRjNYG47ycvkzKjM5f6QrzcHoU8MNRHT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f31598c11e21ad6c472aca50ae8c9e762bf7b9dfb720bf81e4edeb0c94a0863302207172d053daf3cca142027b29c62cf8ad23f2bcfe856d9ae9bee82f2398bfcd38", - "id": "c311c2d17e5882af306b820209a4cccc28f382dc7861e8e59d39b7a5e023502e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 95300000000, - "fee": 0, - "recipientId": "AY26UuQoCQTQA3Yaqf5Khwf1dWK79AkfuQ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205a0874f7f7aef5aa5eb650196cf1ee1739a3c0d3be23fcefb43cb63efee96f3602203aa0715dd7b00a84926f6e7081840adc97f9dc8dff542373b614bb9a20912074", - "id": "493a1e157bbab8a11059fd93f54cb3015076628ab11b09a1f6768b233d8c1454", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 95300000000, - "fee": 0, - "recipientId": "AFwj9n5ARhWX6oWNbTEeR9bbX3o7xBikXD", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220483099ced6fd44669d578eab70d4630660597f0df1a0fb734a62c72cb2581cf202206636e3f8066fc4857d558eeb5a3502b3aa2dc25b2f51f3d44aba967650479988", - "id": "a3273ca38ac6a49f276e658b11155fcd151f5745ce220bbf63373cc8971d784b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 95300000000, - "fee": 0, - "recipientId": "AU54w4okTRtFbFa19MC79VBL9B3QW45trR", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022055aefacb9cb4500f4573d6ab8e50e724970b2640b8a01cf071c4f0bd7076ca6a0220474772c7c8f44a38f98a1fd4be1cdd65120bbd3c2404c91f21fe5331f2f429c1", - "id": "de221e24f05801bb0c5681342127472e05e716852392d8d60733811779a0a142", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 95300000000, - "fee": 0, - "recipientId": "Adap1889XDiKC1bMLuLrSKzsabXmTuBXjR", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220083115c84effaa090c3b79b7e7036a9bf2d9dc8e5818aad77446445f17ac8e41022016a2dc3addd3d82605c5b20e27f89019dba0af6bb91cbb609f4f3be89f463b4b", - "id": "97aaec895cc684d562baab61c97def9a651cddd63b1b8fdea8ca846a86eb595e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 95559787156, - "fee": 0, - "recipientId": "AayAdq2K47PQiS7jMknrMwmQZujeEp5Fic", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200993e9038199932d4f9ea36724f89ac970875ce335ec578abd5792c24c4cce170220048ac8441077ce7e8eebb2fb0d22d4216f0ada9a0f8a3bff22e713f2d20b2875", - "id": "28103dfb6b5efe7dd7f5f880df2b3b910a96c4ba733c7bec80040aaf73b9a754", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 95612193593, - "fee": 0, - "recipientId": "AWgoLa9CgxHtUPAHqFvMpxvvFFK2iyBxUK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b71039017534404cadacb04535b1da38415411d5a2f6f5b511131c6a7d48843e02203504cabf89ca95390944620ed9398261da2a0a825e38d26ed5ce0c94bf58469c", - "id": "2a4c8eb73ba5fda2120f2ab91c7806ac9b603ca1a2b2d8301d676fda113ac29c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 97000000000, - "fee": 0, - "recipientId": "AbD1qLeYWasvZH4PX4j2h9bXFXJxAdhAuy", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203d888caf166966ca8a3559a40b6e8a7ac840048ef9469dc143bb1f9be26acbf302201d256b315dcbca537eaddc86c56850354726e67148088e38ea6763c8f774e2eb", - "id": "0725b2165c79199d1cb3087ce9f6989d0781c38bb4fd3bb054e9f42cf577532d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 97000000000, - "fee": 0, - "recipientId": "AWffb5DY3ceB9DcHknBsLSmZ7bQCX9BgZa", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200a3142e959218f0b3b7daf341222c3d2ceb5be21817e5c97bac96f964823faa70220086698050a3d8030bb6a1f01d4000297561b0a6204d58f8e4795b58a6b1448bc", - "id": "50f6375cdb90d9bf764f1544c5c85daaac335148e7c5b9706fad6564711eb832", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 97000000000, - "fee": 0, - "recipientId": "AJyxXb67KmdzRibbRSp55tC1NHcSXzNQmn", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201bc4e3f5e8bae4e7bd81da4e8d4d3e8a1f9c607c36e39e442235b133e3c350dc02200cdab848881bcfd15adf3f38afba7582753e9824cded8a96c35de855ed394c6d", - "id": "41cff0cb50f6902d42cc455467415829d66bc857002b904b63b959fdcf028215", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 97000000000, - "fee": 0, - "recipientId": "AYo5WNLUCNSRKkvxxMs5hHCNxme7xQ12ZK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205958c081b5336400e4a7a834a33cb8b5b05b81cfd7fd435b6f2c2109850db75d02205ac3c51a116db91e925e26da94efb2143e3e457669ebed1bd7464c9b1306099b", - "id": "ec651028a9b2b6924dd11472761295fad83f3738d2b1ca5867b32a867e17d946", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 97000000000, - "fee": 0, - "recipientId": "AZFKF8mKcoFVz6nG2zvbFxQXfumsXK5a2J", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ffabd89a120c2ed7c03c125c1da112043f5dd98cc99f205ae87488f422278b87022054bc18f5d6c732e8a2132086bb9961d9b3313bbfde4f428cca2f61db934275cf", - "id": "6dc4ec6abe9f5b39e3624841432e9c9af338edc2d4214468029d204d15bd50af", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 97000000000, - "fee": 0, - "recipientId": "Acye9MMv7bbhsBoN1T7TuiCKwPFprnoJgk", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f2dcee2429c1d6ed797c1d8825890474a4770f5f18774575308946bafb3b4c2502201ad6bd91169df28bb2fa6c827e8cecf0696d87136de193bcacae2068d0af83e4", - "id": "ddd07d35e2e0d2b1eb9d1fe7297051c22da9762283b767b6f8377d12959328fa", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 97000000000, - "fee": 0, - "recipientId": "ARWYVBZxnuxnp8JQp96fSZHZEw3Ea2Zd3X", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022007e6b2cbc4a6bf18e2b310325e1d7a56e0d455cd9afc6b7bffe419a9e70b710b02205faf2e91e740f331c04ca133da2e6408fa7f3ae4e5328b8ed6befabc8f7adef5", - "id": "52d56ac56c6e2363f94d1a953a908ba3d841bd193c4af65799f652044c66bde2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 97000000000, - "fee": 0, - "recipientId": "AdPV4RprkYHnm1YajzZYcQ7QjVLwyP9HrS", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203827a7141256877ba780e3b36875bb9af64f7f4fb3d9bbd4e9705d25dada25a7022027a1c9324c162cdc510aa1130099435d7d5569737249c3458f496577482a297b", - "id": "7cd4765b692240de26ec4341109869564754a541571ac191a1ecc960220cdc6f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 97000000000, - "fee": 0, - "recipientId": "AGNE5beBRiKtzAGxCGHPUEzSTbYNmB4x65", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220639fd4f4f25e365b6cdb6ba4cd631a93cd826376a07ad941aff9c83eacb438b3022060a52e0cfa6f7b4b0048d30deff592b185a7132439031c9f84aa5eab945413e6", - "id": "aff7235b112fbaeb9bd31ed8ddd827a95d735d74cfdbec373727031a6e752d07", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 97297237832, - "fee": 0, - "recipientId": "AWxt9gGVbxQ7cX7o9DBniXLA3FNnAzo5Yc", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100dda67cc7adf9bf59523c49e3862a569502c02b69d4183681ba73fca12720e14f02202744c8bed417d5bb28499eb7bd3d353041c32d86247d9152090925395642f2eb", - "id": "08977af886121fdadc51a53156c4d920998d236560d5ba5518eae27b0cb75460", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 97764047435, - "fee": 0, - "recipientId": "AXduXps2TeHn7AvTiJW6m9qqNCtrPAXD3H", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022033d10a0876ec4a4dc66e809ab4a852ad48cc688c68891ca5934b78550420e7ae02201798c11a5dcd1c21f873f0bb299a86d363895ea0e6d4e7a1137327498fa69256", - "id": "9d74cfa57b58e0470fdb88a9eb944096e1c749a4196820575b99e948c125caca", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 98045028617, - "fee": 0, - "recipientId": "AWYjUa8Y5UdaZKtit3Va899xqZDdXxsRaS", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c60266fade798d0a234c8e8d8fbdfe5f73fb015a29f2497acf95e78f1fb5e192022034c1a2debfaaf6068d46e70e42eb606082438aa53eeb75ae1d84f84b6cde0353", - "id": "828319edbb770b68aa5aa91afd76c02f76308f17f4a1c36523fb2817d1bc1e28", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 98100000000, - "fee": 0, - "recipientId": "AUzivjaUXHG8ivXWuj6evpdL2TjszQmVWs", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022008f1b85ead0a3a3328f43200c0c532a2a539715fbf4856e084dea1e7498a096402201e0daee01c06927dde071f5f5cc7e6fe1eeab7291cf4f7a0f330833c535d2deb", - "id": "fa1085f0ac80d410ef9530aba0af26ae0d652677f5e90195bf2184be93dfdf71", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 99262036541, - "fee": 0, - "recipientId": "ANGen8SGYqiBR8TFgtawL57qxbNZRN1hrt", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207557798214dc6bd35d8dc197714dc93287dbd45edd7ed832991635e5f20cf9a202207ca660d57db42578e31b0622648439ddf0219a862579b1c933d5987b76ce53c5", - "id": "f46f63e2877adbb32ffac6af90c5cbc79dc19ca5592a0579d395739d249a22a1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 100000000000, - "fee": 0, - "recipientId": "APSNQNbPQabUiMqxLxjhEyTkeh27nWQDu8", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009b295629afb30454c67ebce29203ec8b3f684f194fddb167bc4ef9d3739a300902202da7e99a48430663805db9cef9cc32915ad694ee75b5573a5be7d7d7d688afa4", - "id": "423abfb5a05784af1225894bc22e224dac42d421e90bb4227c945c35ccb9aa54", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 100000000000, - "fee": 0, - "recipientId": "Acj8SdBVCKnaCUFAydJ2Ggk6E7cfiRP1kJ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009d471ec487447ee43e43ecca799d7d1eab2528d75a1f98a35d9f1c777ebbfcf5022020d40ea9d1d3903bf5ee4e2f67f97b7d62fdfeba622ca8e72e67622c9dbdf8ee", - "id": "0977be517acbf17a25ebbe3c2568a91667b5bbc05c6deea85d61b2f1154440b9", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 100000000000, - "fee": 0, - "recipientId": "ATz8duPjUnEL5oXZeD59rLCmtvHEcbui6i", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200de765be6c4d07836d73dc78eafed1a80fd2e91e3217e7bd104b6b084b09d78802207b244d85ea74fb2248bbd4c265a9e88a5b6a55ac6126f1545f839d2c41204f95", - "id": "106903e0f03337c08dc2d9af7c17263b53376474f56134b76357113a4e92b3e9", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 100000000000, - "fee": 0, - "recipientId": "AUxTza9YeaMXKqgU2FXp6mr6kGyRNFACRF", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220697444d31def970f5a73bafad9d3c0865cfa82a8f200d95913a6953314b7b49102207f70b0f71f2177add874eafa7ddbac1c3f5162f1f410320b06cd9f312fa5cddb", - "id": "e2b78d5f015620390fc6dc0bb39dfe1473461281c1f2de2dc47668959cb705fe", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 100000000000, - "fee": 0, - "recipientId": "AdbbGesHxgSbb5S9BFVvvmgrLbz6vMwtti", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ff6e1f7efbd6cf34bd7e27dde486d29e6429d28f0407a2cb86b9d3b2430cf22802200f64f32c92f87a8591e674426c34e43534c3afae30c62f08b6492f53554e99f3", - "id": "900cc87a9f10d54378456a777b72168fa9a8e44d256d8c46c362a1e068b8a3ec", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 100000000000, - "fee": 0, - "recipientId": "ARRdKZqLoEz3BqkspqPFnjDMXUWHiK7rUf", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008ac2f93dca4a6e81886d0cd48cd8d05fe612364e9382f45eadce42e3051cb0da0220349b5ef16d0dd502d887fbd2caa4d666cf0080f55a6c8bb92b99819e15cb148b", - "id": "48bdcc189c2fe7e1796fe78cb49f18b99187feae93e80d3e014d30101c067f84", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 100000000000, - "fee": 0, - "recipientId": "AM14wbgpGVFcR6EeyFrZ98iBSGQdKGwoNR", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f56b28811f377035b6f5ef6597f622a8f45d0ab7ba46d9cf8b73367dc2ba72c4022021bc53a68673a43fbc49c98b19708527f61269f16bfa15571a74b468dde373e2", - "id": "1c0411c1f4e0cccf85034f50469939ef994740903f65ec5c51d3ea04a0d776d8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 100000000000, - "fee": 0, - "recipientId": "APwycJtjaT8LaXEwN6DmyanzBWMGLCDffz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022030e5363191d9681297a0b85fda62a95ed499f3b6ec18f7dfe115371456367bb5022018807046a5e802ed222f7b2f87e583942782a7a3f3241592f9d7bed5d5d88784", - "id": "f0825d84e64b56bf8f388530cd18cdd4909be54d364ff9703db24cdacece080b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 100000000000, - "fee": 0, - "recipientId": "AFwTR2Q1TyWgpYvnUD5AKZ3KtEhTZnjSen", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220767d49d3c2497cac443b78c806287b68deffea0b7bbbeb171335997b40a10d7c02201a7e30b1d7ac9115d98589b3b54c16e19e7466b8ccc4394b488cb2637315af0e", - "id": "0dd5220da9ca8ff958bbc8a4040a0502d8ee757ddde806625c00f4a7cdcdddda", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 100000000000, - "fee": 0, - "recipientId": "AWWbW4iYXRvXzXAG4DVNw13kxGyZXkXJZe", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e00353541efedb21d3bd42e33963056ec65f0a79880f8a3a5f991103d8f64b3d02202f324a1de8c96fa2fbc41d9c3cd544e3e25bd84de68013c38696115a497a12cb", - "id": "3fe581b3aa87b6cffddcb98d27f62ef83138e2e78fcf3feea8a44db4575f89d1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 100000000000, - "fee": 0, - "recipientId": "AZcPTCo5A8M36wCFvDvPz3H2cBBJo9p8iq", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100cc27cbdedfcb771e9d222bb6cb13a71d7aec8e36fd433ea04942633c5d5e84a20220564dacdf36c5d0abaacfb62c445c8fd1d046a794339f38a05b8f40ab1d338d2c", - "id": "7682c2fa3c74fc40d917290a665ca4412fe74b737cd464c908850ee631af679e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 100000000000, - "fee": 0, - "recipientId": "ARoVFy8w9CsSBazrXnigzRZVrrsVhUzfLs", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022072790cfc15458125cf1fe54e85d58955797d3f4409f99fe74d3405742fa72bda022013075f4dd0ec2054b42eabc9d41d4cbec07d885bf1650f75ef3936826dc2d1b4", - "id": "f20634bad0858d0e9b1fae15b9608e8b6c0eb8715adba0977e0f17cc20dbee99", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 100000000000, - "fee": 0, - "recipientId": "AaerL99dZfwZL7yghV9k8Ri5Hhpi9YPsYp", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e67003e1c964db17bf2bbb00e6a4c60ca12e46753d36785b13041a136bef4ebf02207846bf567a2bd72bee3289a321e58da645d3a64dd9030d0f52028de50efac7b8", - "id": "8aae4664984ac30d28b171541c9a41dccabe558089b073d8236171c40456c4a0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 100000000000, - "fee": 0, - "recipientId": "AYA1abqExAqcWxP4qHaMNN6MdwSVAzz23e", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205e46b3935995f1edd2797f8a4ecd5181cf16893d4f955747824e0cbd7effae40022012f11701804587a5c2d9bdd8295fbf67524bce5a26ac6758bb7d43ba6975ecd0", - "id": "fb4d5ab6087839d6bea3c4b93d91a5654cb556023c0c2648e3ddc47268b29447", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 100023851656, - "fee": 0, - "recipientId": "AG825v123YvZQuL4vbe7wNxvdyTewt9gGm", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009d37379a461696e7b42faf48419ac770ead1768095ff38997eee98fc01bccc3802203272ec96815df48dc692ff686952e04053d60f14c0cddd821f0bfca775034b27", - "id": "aca358d024faa5f4fa68b7943ccace6bbc5a9ba2bfcc614445b7a1b4e96be417", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 100749519793, - "fee": 0, - "recipientId": "AStWDeuQ3NTP619nCiyxbYbnyHTnR6cxb3", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022046f3e87a0851d6feaae6224127051c783d08efc892aa52118f89dab6f11f02310220030a37ce70dcc5b4554397934d67ea888f49c7ad825a337a5540f8fae99cca44", - "id": "b92dcea5e20cb9348374898f686f4d2e2b6ecfaceefd6a0ca637bc61c6a2bf46", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 100933159396, - "fee": 0, - "recipientId": "ANV8jYBCQdPscN31ES2NDFQ5Xe87zUrFzX", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022000ac1e8b3e471505f8476f98ea31920128876a804d22ee446af4ddf210442cfd02203032930c4d6d6646d3d4140ff89c48b4e58374770f6be9169d04c1099a39d216", - "id": "c57cb34e723d065e12f74b33c2ba5bcde69763ef191505ba9cb38af0a769360c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 101680182605, - "fee": 0, - "recipientId": "AUQroQ4if3dKyFwgv6ESDM8MHyJDe8MVLP", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022025f1efed2ab491fe87764de2cca46aeebe3e31e558210001798d86c831dd69fc022059dd3257cbb318ab88d7f21baa2cf56a975582d578a3c67cc188ce46793a2d2b", - "id": "f1d975e6feb911d060c7ee86cebf9f56ea0d3001d8d1e9813d24c0fd1791aeb4", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 101830636768, - "fee": 0, - "recipientId": "AR58rt33ihFKG56DXMVdKoidzNm4C8kCnF", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a8e1e2102f75026fdf1cdf3bd8a737a673315d48ccf8b28730235ac9f78dd2ed02205d5a50aefab9c7817d6769a64c83b19b96df69769a735a3051c9888eb4844ce7", - "id": "84ada517a25f66b23c3127830b7d77948fab1c1fd2e643f4166384c1a6af9bfe", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 102744627447, - "fee": 0, - "recipientId": "AY7JH5b3GdHv1ZcbFXW3c19ovA5k3jYtDc", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100dc91d5af8df4ce928414162c63d64452bc1a05ecf20fca159cc374deab7401ea0220749733c55f0532b454f3d401d41bc3bb79fec7fef8b439f54c34c17fd5865a1d", - "id": "edbb728bb5f8ccf9384ccd41be5689507179d05d60f72188c419d5163d76b6cd", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 103054877463, - "fee": 0, - "recipientId": "AHRjCLd18MVx4MevXGsygteD41pjjEmae5", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220223d32f9daa36a1d0c96c35d6825922ac18fd23cf9e69f640f707c27a49f9a4802206e4132f40a65ceabff49666671a7f8d1d22848e06ff91c31a42cb6cc38f0d9b9", - "id": "63a23da52548b2b0f932340589409d453f3d46656f78dea4d8688d926013f84d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 103054877463, - "fee": 0, - "recipientId": "AYwziM1FFZdiYJFpLjSDBQUnJD5gQG3T6U", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ef3d526e72b7021dfdaf9b7706c88ad8bd985f453754a116254d13b888e127140220259eebf0c8aa21adee9b573ceb4bc1b4597c72cf6a18cf1617cf645eb169dd4d", - "id": "915baba7089f762e6ff2398ad391de54f7285f0b155a277d88e5a9bd049139b8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 103054877463, - "fee": 0, - "recipientId": "AFygDabDnSBm2M1iDWofGNHPa6ZeCEeqj4", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009fb6a8eeca7df3b18fa9d1db1a1a4c1c63fb36dc5f71396c9f6d21070e7fe8d90220426ff00438c59643cf1ccd01575832f0a375d1217c43cd816538f3968c643fb1", - "id": "886d32c7624d952ff3db788984073b74e5dc6bc027ef926d1139b0a512dc3f2b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 103054877463, - "fee": 0, - "recipientId": "AMimZDyN8vdDp96CHVLtWkhtvmERvTmnnT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fd942aca86527ff6011d230a0ad9626468d361b91f44ad22e32c0774627b0cf90220410fe8a28dec6354408b5da8bb3b77f5f5a4e2b491dabf5177876a8b29928c97", - "id": "b7f7c997bc93d99f92b458affba8081b15e2349f35176e2100ad38bd859bcdf0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 103054877463, - "fee": 0, - "recipientId": "APdPdgkVCNJqQz1xP4qqzRY6K2tjybdH6V", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100bdb4e44659fffbe283616db6d45315d3abd1e4e559bbf323629b9efc4ed81b080220069b6e53fd81cea49c8136ba9ae23e00258ab6a2d30130d1b31784a21b669a96", - "id": "ffaa043601b679834ce66deff3b7ff00046acd8bb3f573ac6610165ef087879a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 103900000000, - "fee": 0, - "recipientId": "AZiQBaR5TwSH34NXrdrvErMX3aiYZWFxo8", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c87c4c23d0a4432c99df14afd1c88bdda73f3a156ad89a247ea662080b7214dd022055506cba670851b036bb39e638986879199b28312fdf356a685bdd1b17003708", - "id": "146b10f76eab1b6783af1c108c35df9bafa3c6ba25b72ac6597d9fc57c7cb215", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 103900000000, - "fee": 0, - "recipientId": "AZo1U1VRipZ4aWx8LYfEXmyEBcFTs2St36", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022040317a8ac4fe1308c10fdb2ccf695db0d4374cc57ce5b012e7d37766a7619ec70220014d508f6dda12b5b9ff095e6d53fa77bdaeeb04713de273725d09b55ca22251", - "id": "549b4107541aaa18058574d381323196285df6645476b9dd4e4f791ea4c49106", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 103900000000, - "fee": 0, - "recipientId": "Af4CtTPXJ4Wkgrsw1zsvmCoEUS1AksAyEk", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203e6c4eb1fa7b5311f04bc7cdc38445b9b737592b9eaf0df143998cf5ce66eeec02204ee48dfa39a93b9afb978afdb4b2de537dbbeaf1c82e31059d344be867378cbd", - "id": "3fe8bb50ef8e7f6346f7447e934e9cf8e51d981ab151698ac258cdf03c72b8ac", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 103900000000, - "fee": 0, - "recipientId": "AV1MipTPz9KkjJKqSfagNiQkpCDACG6A45", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009c3986801d041cc233bbd394cac166ddcb2c55482aca48a85a59c130c55cd8d50220164eb74f9ef23f5a6307756fe57ff385258a9fbdeecb5525802f79cf5dee8956", - "id": "54fc495250ae8a95f231553ba952f8ff502aba015ad586f03f68bd6fceaa7606", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 103900000000, - "fee": 0, - "recipientId": "AdFF3NRiwLpVuypouVth7HKk5Ca4xejtmq", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100efce8d12b523214f79402697597729647211ba94ef27ae2743af9d6ff0985da602202b75b8e0a0a655a8863b39940726b51b31566f98ddb51b2b17735a7970596edf", - "id": "436256751f2e97b12d0a99f725a71aaa4b4ace4644b4087298592e0a5cafda7d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 104570390367, - "fee": 0, - "recipientId": "AXowRmmMSAB7GFCy8XPpNLu7E23B7DmkPa", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e0b952d2bfc38186a4ca9ca51607f44ef64a3a0e58836171f1668f0f47fc10b5022071d9e89774682c5cb84897d5c406aab779527e759ddfac473c900add865e420c", - "id": "ef7a402d8c58133af24b24b5ec33821e0b443e680144a20b9ae83ac85ea2d16b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 104811009865, - "fee": 0, - "recipientId": "AJNitjA6dbbiz5vDaQkaKSXaNiktVFmopp", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100aef19847d686fa0e802b7eccdf3e302fd9bc3aacc87f6ed76ee2ef0d5abd0c570220248a00f81756031ad2b87a6bb367e7e6cedc11b4412ee3998db66972edd35166", - "id": "1d956208a3979f3224a4dd347109102afae6463b060bd94957440442904988fd", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 105000000000, - "fee": 0, - "recipientId": "ALrkZgaD6BBZCLx1FaUvcFRL9BkTsjXa6P", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100eb10d7c5fd4b9c27aae44cccefec7315600dbabf3cbb180fc66e996ea2856783022037c60b02b33ac06604cc39077d11372ade6e1a66aa89f99c43b6fd0f0fcd8ee3", - "id": "1d10aadc7d67af4ea389a2f0163fc174f261d71ca6c80c2b326b674858948ed2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 105000000000, - "fee": 0, - "recipientId": "AZnonaWAZjaGFbku3DLoeGwgg8PCy41sMj", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210091235be3645f78fa9d77d45882767b7280e779f3532defcdf0b71eeebc73bf63022050c9631aedf3c42231ed1fb9f385763c370ff1c9faa6c14ce07d14500fab3d0f", - "id": "a65fe81748277af637a844a6a21b8cd57f4d1dcbe6aa58a553a94cfcf0ee2650", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 105000000000, - "fee": 0, - "recipientId": "AbCoHPSKn16NSKL58h81seENSohU6xAT9w", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204ee2fa79681c3c86b4107e239596087b33a0fb6108e2bfe286598618945c859902203a32f45dd2538f1e49eea075fbda05db26f5c9cfb2b3d1f4aa85117bf4a92149", - "id": "306de8162df8007e47f95095c1386c4f838d32bd6072ea1e740e27720649058d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 105000000000, - "fee": 0, - "recipientId": "AMng2ZJC3Gh2ykVUAGUeKB2q16WnaqK9hF", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204d0818688736ad3bb25e21e4af2716b2038a3691e2cc7f27bda2df761df4c1c802201c2fd04143b52f2b5e5bc1d3f8c17cb038b90eebd5282ac3877012a874f8fa95", - "id": "1a64cc2367fc2d05a9fc862cbb99be77166117d5ba2ec25907126561b2d9e1ed", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 105381567713, - "fee": 0, - "recipientId": "ANzYwcwGfMg15SgWMkGuYPxjePuXLtvuEG", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220750181471cd14e07434ff8f59022127b7ebb36b643aaa1851142144fd6d0bfaf0220268280752dd52b66eda35bb6384e6148135461ae865154b175b36162860d71d6", - "id": "e4f2db2efffd43d8a99a2df742cc93ba40d3e97cc4e9cb421f9ad3c85a1d5e19", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 105714987355, - "fee": 0, - "recipientId": "AcJFXLL7uS4i8x6Jg2hZQftgirzmFt2X1t", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200c0d4ba6f603d8dc3b535fb8b442fd1c92c2d7deca82c1aff622981874563b0b022043f3c8a59e042b847b1359f1a28a34b44fccaa042c41947a1565ec2d7e719167", - "id": "a85f33a959089b825b8453138de87a63137c1fc61ab1038f3e8202d761133c31", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 106221504166, - "fee": 0, - "recipientId": "APk1d1oci5TiANq2XcdQjy8C8iLwmtTf1G", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206afbd9bc04c90409a31228c58e89f493ce384d7dd97a0b97412a4725d7358ccc022067b1f28540632ad989bd7458fdcd23e5897615e9d9017289850277034114888a", - "id": "b9cf7363f5730e0b1ac4ce9114ef5eee22797016bb718354940fcb53cab874b2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 107239514002, - "fee": 0, - "recipientId": "AGLvTbXCtBAdCD7bvAi8PBSSvRexEv1upC", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200ddf53eb746d313d24df80c2edb7a3d01b533a9691d05d4c863afe390ee5a82402204de5576afd6f9a54ad7f106cdc71691acbe16e206914e9da123709f9ab78ef85", - "id": "84b3f5981b62693819aaed660e3eed3e5f13042449234ab73a5870e760a45c7d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 107692346948, - "fee": 0, - "recipientId": "AR8jXLCoRWnnkaD78YxajVcFsTv7eVutRb", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022077094180476f993bcc0da365d9f9667c8724c5d07402689ece5f870af7e63b2f02200faa17f80991d65bc3e8a2593eb2ccbd7b12fda29dc3fb856ae0d222bd56113d", - "id": "dd832724781a028d0427b13d14813c82d8e949fa488e9885c872f1d7e6176642", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 109100000000, - "fee": 0, - "recipientId": "Ae8ZPCEgJEUMkR8oD1Pp9eDocsGE2MRtiZ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022040ea35b1906200719f7b79139f0bc3dcfd2d1f34b19c3e75a4fdd1e3ca84b60b022008522e9eb7dde5ec65fecddb318added37afed341c66d4c3f938cdb539bab0c3", - "id": "ae1127f0c65bc53762bb7b5e79c3dd2f0da85fb201afc5bb1577b1fcf371c31c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 109100000000, - "fee": 0, - "recipientId": "ASoz5DXAEBaQy8H5KrYWH6bzYkJ3zHVSsx", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b4b63ea88288f994776b80c78ecb41793cf70fbf72e3038acf73099c5677be9d02200358cad66ae2d98a08c43be0c73fe88a6ee869be49d0012e394db3d14659c43c", - "id": "f2d28d17f885481487547831f316bcf701a1be0d2263403740dc0516293384c3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 109100000000, - "fee": 0, - "recipientId": "AaPUG2PrNDy6UVUBkSwPuKvKh2DSZdnDqe", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008d7f47c01e28bec5afbf49a5cbfd68f4a911a4e840b624e13abfa4209c2e67c102201fcb385bc4fd9b55c687e5a253b2f181a658b7fc462d8830e63deee0c82967d7", - "id": "0974483b28113dc2ba87c4e8caa564f71b5a4dd10167252e66124b02fbddd7d9", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 109100000000, - "fee": 0, - "recipientId": "Aek4aTvvdA3hUVUjhgkDtPQF5E2iBuAVP5", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a05c9fc68f17c57f5adfc88c3bef13e616149a53b65a6a97c95d8f750a3251ad02203cd2aeed88591b244df1c05342d79fc7a5c0da989d5b024bb4c72582b28333ea", - "id": "cb54ba7a6a747c5d20e66648e3a7d12c6e5193d0ec1daba2dbae6b8bda726165", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 110800000000, - "fee": 0, - "recipientId": "AL32Ure9XiVh6emxgHdLQPRbLbr5otNqDc", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b8d1cd4c228ea834d371edd3ee9c59053d831c124edc7588cb358aaf0639f93102200cbfb5d6f0cb5498709897a24af743cc1a80a66a948d411c9d71ef18394872ee", - "id": "4683c51754c198ccaefd949f1becfa8dc36383bdf4f43b9a5ac3df0e848cbb01", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 111541749725, - "fee": 0, - "recipientId": "Af3iDQ3qYG53LHVXgGbQFXkffa2pyjdEFj", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c57f7ddf68a0d08feb91bc9d67e9b246bdff6d8fc3dc07e3524cde453ad60bb9022007a08e49417b03c201aae30e9c6b12360c1e5e92b7ea5e72cc3b257d48578f54", - "id": "df3260c10be2b53c385cbe025e84be776d6f9cc5bbced87a110ba3fee4ada362", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 112600000000, - "fee": 0, - "recipientId": "AU1k68nmfcpAkTkday2TZFoKuttD6eh7JL", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3043022004abba6942eb051d80c8faea823133159c8207251f82bae328b0227b77f92097021f1580e0ff6214cbec6d97059469e5f498b39c25873c889870d0450b1b892be5", - "id": "c4b480f9254eb4290b7acc61e2e85bd2131785e482f6e617b8c3a6084773760b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 112600000000, - "fee": 0, - "recipientId": "AS3SgCu4BQ4VxfdJyu4HKNVHZGTQBP6bTB", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100bd132234f55b6c486d34b3fb5b1b52558d45938ffbe0a02e2ee06ba9fe7673e802200f61ad1ae7b20468c496c0526bf726546eae7907387f72f85245e0c7fd9888a5", - "id": "66b7e7ae47d5663ceef394c8cec8ddd1851bb4034c5ad133c1b4f6d2b18b43a1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 112600000000, - "fee": 0, - "recipientId": "AWepJMLX9wD9nm8RqagQasNfypVX8n2wLF", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201dbf3a7b09b8a4e71db49504e3cd5bf8864a877218bffab4dbce5a50b199cd1e0220452ebc9b95206fea3629f11abc6a40a6be3c0738bf496ab2215c7033bba185a3", - "id": "a94b2af091d991840007d2644ece123f0f42d18276237f163935d2df2e075685", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 112600000000, - "fee": 0, - "recipientId": "AXBWn3Kf2yEy16mYKrwnTQsRFL3geunAxh", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220663a6cd1bef053f3376b19778d7256d08a34a8d8177e9fc36b3460cacea75c4602205b50dbdf88972c8868d15934c2a466f7cc6b82234002cd08391ffd13d173107b", - "id": "068b774d4990385eca9fb6e1ac6726cf6eaf99fd3687b35271fe407b33e9a784", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 112600000000, - "fee": 0, - "recipientId": "AYtpgFgBb7FJL88VBShq1GtBLoGnYBzLe2", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201d96f2acded9f3d609618ce34f387c2bc46402e7e14c7bca2592aae1e00562800220593d7ee4b3f97caff848c38b497140312855d9df2f007b8432c69b43182462e8", - "id": "df619578c2c85a4e2a3f9f41c7afd5992439c5a60f8d17eb3ec7a9ce8b23c96a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 114624967068, - "fee": 0, - "recipientId": "APR5muHZocUvsHqfXt3Y3QDuYLHHgiRnov", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fa7873fc955e0c2de2a6591ecf38fd0252b4b25f83c92b6eca220dca2c593e7b022007b86133cb60ece69909502ae21d7a5a0fffba04ae88522ffe15bebeba2882b0", - "id": "877ce4b295db21844c7dfdbaaa08571c2a376400d60cdabc9af1eac7fa2b591e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 115000000000, - "fee": 0, - "recipientId": "AQVCqqgTRUDR5NMaBBDNxgdpwxkZbtqGxs", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202927f829fea3a19b90b2144407b9a268daa489ab146c08106be90c4273220b960220220f2de203a334b320f9852c527e55b8f595d3175e6b78c2650c27487bcde63d", - "id": "0674ef83667bbf5c4dddc21c122777e76af7abb6ff73337b7c1f87231573e3ea", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 116000000000, - "fee": 0, - "recipientId": "AWEHZFuvK2sucehMNho7bFgs5Kct9MX9cM", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022023e9e21d3126edf7419081dc3d8ca781cf08b4f7a6250536859c4161d848799802207e4a553cc1b629c4727b4c3fef627e8fb592e839c80997dbfe631a08313f84b9", - "id": "aaacbb16a6a80d35c49796dd24c5ec944fa8e78323f7df908fee895a651b59a1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 116329005231, - "fee": 0, - "recipientId": "AMuZTwvJTd24XdckcZAi7Qiy3pMoitZLHV", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220523323f28caa94c93362d327129e8d3c4088f9c577a77e9c905464c5ebd04b1b0220705fe7ff0d17f52e3370d10be916af09ef1883614c76eec9899adca018888445", - "id": "7301a48380a2745cfefa1cdf1a2ecc9edbf70e619ef97440092bf80e8c392440", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 116897017953, - "fee": 0, - "recipientId": "AdFmnvX2noJxbAqXZvKKCRV8xewsq2L8mU", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a61b9e09531ab70652d5a188994c291247b3be964960448ba1fd0d21668d7f2302204d856caa8fa3ff06e8b91c69f5dcabc7c60e57d8b342205ce03233682b109c06", - "id": "55242c764f2a4cd791545e8b71cf09b205b99663760874500a814a942070939e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 118387830724, - "fee": 0, - "recipientId": "AGsD1iKAnYqa7q41f987DzMS9kVmuvMB4p", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b982e36000e67d68c16636c2f869d138f69612e2a2452584831d807bfd7e2b69022061eebe290b68359322fda287642ca41864a581bf666b74f998796b7abf418c54", - "id": "9c19c864bedeae508eadfb014a1716c8f6af01bffa05bde44a35e9400fb441ac", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 120000000000, - "fee": 0, - "recipientId": "AbToFt8MRXR3BmKcC6EpnEPWaNUMQzr1hz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d94cf00a4b6aef15f3243dcb3d68afbad70558b3928f096622eba887da94af4e02202d306ded93a5b9e21cfa7ed9db16dae8b78ce51586f4c6be5dd0ff69c379fdcc", - "id": "fa35c7b607c02653d4c3856476100bdb65b0af57df0864b0173da3fd370d1bf7", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 120000000000, - "fee": 0, - "recipientId": "AHWWoXDCa9RSeB5d9BCS2krPh6TzxUa9b5", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100af2fbcda194d173772c91a90ecea2ba0ae32aa24dd7a119a5cec4b92dd348a93022073dace8e3c3fb62051bccda308c1e80650e39ddf6db74cfbb1ff554fe5dfe773", - "id": "d96cef527759049343a6ceb34e973a6e873cd89ffdc0750dc94a9b8b11602c38", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 120000000000, - "fee": 0, - "recipientId": "ATqYMZ7zmQy5f3DFrPKaMZjiPVpGAjCWae", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220176a3dafb595afac283608fecb966d35be5f4ea746ee54a61cc837732b368f3d02201df396e59e4947dac9c31c0f6e3596fa366b3d6a1b537a04a3d39bd5b2705911", - "id": "942882235103abaf544d21ea54b7cd466fb9f0eccf13db858af4cf254444cc0f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 120100000000, - "fee": 0, - "recipientId": "AeEasb3UFnht7FJiYqFi7csnAavnTwxUHG", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30430220608fd2db9a7ab9160e8071694506c793a63ef0b3a70970488358a661e80e11eb021f6ac85f5fb747484f5cfc189b8cb75e2ae8a013b9f9f2f37b96ccd1a5e21f01", - "id": "5b51d62552fa2d44563a09c0e6b1e30610ace3fb9721fa24499cc19d6252f8a3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 121200000000, - "fee": 0, - "recipientId": "AR979mGe91DMX9dUPsKvEHhru5hc2aMqn2", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d97b547f60feb499b52f9b613366eeaba66f8f2675d7e1faba52dee39e3142810220617a00281f0c066eba13a80da45ace50b6d94766a50d0b975563c2e1617cb1cf", - "id": "03676f15ae81acf829753f2b3ac30cee6d4749a508ae32cf104124b9a4f612c6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 121200000000, - "fee": 0, - "recipientId": "Ad6npQratXMq87v27PgmpKfK9aMvmWTjSs", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022065eeb3aeec85e090ec09e772ed5d036d0e7521f09db0310e75622c0bb8e96c87022061e5b3ed0e12e3077522abcc5d15cb07a2d261d6fec0e59622700ec4466c89ec", - "id": "1e2ea66e2f12b91bb85d384b483f8a81c349adab4dfd2d20fb1d26346e4ceed3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 121200000000, - "fee": 0, - "recipientId": "AMeyqtTonCYWt1mPJwd1K2FpnHcPjCVznH", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b0d13c6cfd44a8e186e659c23a2af522cec69a41b8e28ea6a6131bd12795216402200a0a212cda71ddcc26629b53d7f1d6e455b99e8fe4bc8f4e3ddc29839316a82d", - "id": "2f27ad44ec7b4c1b612fb27a23a4d77e9309461f72c5613c1ccf60db7601e833", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 121200000000, - "fee": 0, - "recipientId": "ALvhge1cucXrjdpnMozCDaWM3C6gm2Xm33", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022059d6b72bf48d119e8e18924861ccd754aee7e71d7d3010daeba835d2b33daf8e02203f0dfc75e84aba60c389eeaa7b8cb704c5768e58d0c3e066004ca01b2015120e", - "id": "b46a24fae79c4b7b18b368b357785eed4efa908b0170fc0c955365d9a8764b31", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 121200000000, - "fee": 0, - "recipientId": "Ac427bp1DynWsNGXCCYwWXseyUCYMWr2CA", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100df366d759e02b5345ca59b52de2bcab1906b78729c65ded10fe89c6e0daed4c602205821d77a90716e943ddf58c31392f902c7777e3dbe69bdec5198bb2796c17a4b", - "id": "f5c95f62953e9c219850a8ae44c468d3a61fabcaac19446d99aefdf72714f32e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 121200000000, - "fee": 0, - "recipientId": "ALHBQuNjrFx3i3PgCz1QdkWgAEwX8zQ7zy", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200c9fa69d5adfc7f6c1a6dda8dbcaed58135738eb7e20975bf457cf288a4412fc02207be43c5bbf745b851bec3b076291f3800c54388da527b24853363b0c8144f0da", - "id": "190f5a757ecd8332701afd35805f0ab1ade99cd1aa3a9169b0fb9f48148e6cae", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 121200000000, - "fee": 0, - "recipientId": "ASn5uzMgJxu2bu54HGiKE8D64ZpkhXrPcX", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100bfc41e8af18b4505ef221990a17ae16c2be5e9ad554785523fbcbfd5393f006f022017978893e82ae7232da47b6ef37334bfa255c94cc19e9dcc8de51659b4bc47b9", - "id": "2e80037c72f52d9caa96bc27fa934e662be2497852c6162a50ea01b2487c5b4f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 121200000000, - "fee": 0, - "recipientId": "AYmpwBT59ZpMKJCUcsKxjCUBYfGb3i4r7P", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200b5a383750451bbfd892a9c444c41a029efe9fdddb40acf604851b6cd623ba320220129abddee1f38206fe9b688715471242f10ddfe99fff3717bbb0e17b5a43c071", - "id": "388d78941ad3978004c95a6507737c08e6b2840f1de9e054c215a1c800827c16", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 121200000000, - "fee": 0, - "recipientId": "APaWSMFzp9gNr2RRqwdGzMdKrf5rwa3dNV", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c69b404bda50b119d33763cdb23e3b69bdcc387668458dd33253955247763c5802204fc1cd9a805cca13f1c62bc706393a2f2e839a696afadcf528ca93177aaba237", - "id": "1b24b82d490655834aeacee9d6af2ec815bead657ff6405bd6cb29ab19faf737", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 121200000000, - "fee": 0, - "recipientId": "ANo6dapr6rCMDTKjwRzZgWUtQgbbQ1Nnz4", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fd106e25de0bd3b3c1e6cd3dd1f6b49968e482fb015f00556ed60a3853c2d576022050e02fdee6b72fa4c6027c17f8485e395391b9a342a6e212b064c0cc27a47aec", - "id": "96834d445ffb6224915b81236804f1a6f4e5231553b4019d5b9a9806afa632ed", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 121200000000, - "fee": 0, - "recipientId": "AWA6TybTgFiesGDtCasa68Jt15QP2Auvju", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203bc67263cf58ec7b90c524dd694b06184f705dc7a206b1e1a1a8fa1dd29cbaf1022049410d87332f9108ec487dcc2d4fcaf52ed36867b05e4b4f14deb94006e94802", - "id": "176a70f81ae2c02db9e422651bfb9fe7430639d86144b94a4f28585533403cca", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 121200000000, - "fee": 0, - "recipientId": "Ac97FP6Zt5mUcz8hRWRy8QgNRsPCxs7BaL", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202d1d32121b5e7ec0fcabcf04ddf8da303b4e3b5ffb55ab9ec037509f6d4df29902201526e223d63a19013b7e44fe44879ecaea07baf2c45ddf13c1234ed9c5163475", - "id": "7b50f54fb15fb3cb7c7c2e5b1ca1d241c37d3c10db990db87534ce366ea94d3f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 121200000000, - "fee": 0, - "recipientId": "AJEX11r4ECKF3r14KxNMwzLT29omPCtGHA", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022035208eb90354b15269c5b1a97197ef357799111600bbd313afacce965838eae10220036a346f41e67380824086cbda241e058dab979994c171be6b9f633ef4c0300a", - "id": "35242f8882db3e61b508761316879c32fcee9a5677bbbf23c76c731cd68b2cd8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 121200000000, - "fee": 0, - "recipientId": "AQ8PPGdBYLGPAiUjpo64YAWCyPzsUEEBvM", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022025cbb2d13fbc38c3de8cd8f134c41eccee79f133e78c83091888e4e1460f998402201abaf01c324594b4a3e2ebacf46c80ae6609ccb8dbc915304d0bb907a08a7869", - "id": "0889d189eb144fca050638e158ba32932733b39352998d2cc9307b4cfd5ce2fb", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 121200000000, - "fee": 0, - "recipientId": "AKhaX5DPoz59va7cMYhcUsBEGLw73S7524", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205c29cd985cc57d5dfb9cc47619030cc11860ade66201f73db301a411dcf8769802205329981e063b8f671cf6584bdf65f6d9ee12d304d4b167399d913e1e3fa3a8db", - "id": "2edd2baac328384231be9165095f0553378679aea26eba5b149e3a54303f5fae", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 121200000000, - "fee": 0, - "recipientId": "AN3u3wzJPUEbKkjRTW7JGnZwHj2U8ir1s6", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e2cb4fb8a510d122ff54873ae69f3ed0e05e5218f16caf3e10c719a46c1f493e02201c2a6640e6904f68a9ef5375bf4d3e0a568a558a088d68087071f09f34206d61", - "id": "85d4a553ed41bc54fd93c81ec5021a23088be6f50aba0055270e382acefd98cf", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 121200000000, - "fee": 0, - "recipientId": "AVL35iLjeDYJFrV3YK5kPHHijJcHbzGqv7", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200acc365ced6b1cbff5d6d586f373ca5f9a193a20de02ed784c2ed0969bd33a27022033ed50bc892f08d837f3e38ec8c3d4b2cff4ad2ba148712667870d7615047b80", - "id": "122ae3a92b89b6c5cb1234075b7e5415c0b284c4ccdb66a480cdc47a6f45591b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 121200000000, - "fee": 0, - "recipientId": "AYxAEgAvXoifkzMsN9P8nmDGaErUnGz6vE", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022079f8b805e20edaa4f0ee8e1a1136ced571a1a964c49f678ea4ac945c77aa40ad02205f03efae06c98fe37f8beb0e730a0f0b6cb5473c70fe0f5f03a33e71699b4816", - "id": "9d1bb9a20498867f18e4cd28d56b1b6d0330c78da178d3ec2a9ea776d657300f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 121482157847, - "fee": 0, - "recipientId": "AXdk1YaWraKLT1he2N3LW4aBaZLyAiyiMW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022036f7275a99c91e73aceb5d904bdd1aff19007fe45aa3c1d926170e9883134730022074df6932914e893362a8f6473bf32e1eca016efe823a02bb9fa3d9ab7f64c6a0", - "id": "6676dc925e0257740d79d42f4963e30cf1451dfe23c282732f9b2a0917e7fda0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 122958047810, - "fee": 0, - "recipientId": "ALHwE12mF1DbBNZCTxcPRB6x1om2bRnQxG", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201484a2b3a9bf798e204b01eeed2d235e3dfb11f9710bcaa5c78eb984c5a4cb2102200cdb0f5f44d445cd495f20b75707927abb3115b84fa1c95e12879f36e5d962c2", - "id": "50e3e17e80a61446fb6a9dd016d3ecd76d22014721416802fbb8ec212f732255", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 123284431502, - "fee": 0, - "recipientId": "APMwQmexasWJwpAyLZoDFYWFSGUamtNK1J", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220310d6c899dba99be0221deed8077220becb9da79118276ec3cab9226988e9b72022048bb5ea38ced208e1cb6d065248a390ecafcfc6aefd19b8f439c515132768603", - "id": "817ab6d80dd709d55baf1d885b47d8f83dbfe0009f8777dff77500745797fa3a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 123492648017, - "fee": 0, - "recipientId": "Ac33gzmvjrrbo75WJ6WVuuMYchi2oSG2cZ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022011862523ab035e2600fc17663721256caeb4b54de512cbb7f22064bfeb6f306b0220586576a37ee87ce14575e8e440aae35c6b370bf8ebbb3d220337395e4da3a127", - "id": "fc0ba615203b330acb7946235f7f4bf01739cf6847e07be0d23d5218ac106d03", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 123626298069, - "fee": 0, - "recipientId": "AePe8p3H3wqiUUJ7N63aR4tSiSkxnA8Li9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022023c78ea21b06e95bbe80641f27a39ded89ec17a2ee2c8f5be89135ac4098a464022058ee31b7830ed287622216e2c47c34c6fb1929b72917b3f95de4c3e1cab45083", - "id": "5776ccefa14dca3370b26abed21365f1ffe65228a6bf5b25631cd39c461d14ca", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 124700000000, - "fee": 0, - "recipientId": "ALL3T4hBL5Hy6N1ekevdHuK7c8SCoiKmSy", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100da7c3cc5cd62b428639c066eaf88fcf3fcd60b69b3a6988d1059868aced0a0b602204a2f5da3d7958c04d3edfd60bed8ce37a862ca10238c5175d49f8d994f4d0462", - "id": "b44e7fe2d2a0491576054ce4b6df112eb422691517c896ec9000e642d057eee6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 124700000000, - "fee": 0, - "recipientId": "AcM8Mm1xZLsaQ3C1UrpKBGETTWL42n74o3", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022051d19bcc61978325c50456ad68fcba62f75356d48611b6922b7b3386ecd1febe02204e16018952ec4bd29530eca80eb7d1485b279595524a69c77a199b7795bf52b5", - "id": "dd34a901ab4d46ed7f9e4b0d9e4ef54e36e412d1e0169c63fd5e6479c9f49eac", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 124700000000, - "fee": 0, - "recipientId": "AG9kM2jLaRKeTdRiDBnmHKFvEodwxkyns7", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ed04ff01b76d87858b06a9b4ac1fbbf452f237f3c89291ccc2dabf2ca2eae7650220307fbb2d586cf040baedd8a96b0745e7c5bff914ec9a36c6a9ecc1db28edb430", - "id": "f69027b2324e43c68a23e9a62a24689315571342b63651380d620e0d747cd561", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 124700000000, - "fee": 0, - "recipientId": "AbJe8Q4PeWXGd2hurMguwVe3BLaDHfWRcR", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206c292d5bc621a09520136d3763e2ea99994c92164f083317ac7d4d84ad67c9a7022064fce43058f8d19cdca3d633fcc34429086211c6947d4deedec92a96f5d72e7e", - "id": "d6b27e61b96f4a4e503454f052fbf313559f9317694aaf0e3b17f9c12a84ffcc", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 124700000000, - "fee": 0, - "recipientId": "AKm4VdRbpqQRxNUatCuHz6SaRGTatMGUsD", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100dec71fb87031a989bc6dc3f048ee308dbc97ec349a45861efae3459b04424b2d02207a5e5f4a089bd56368ce0cf6a83db247e9a8b215c0aed867dc83141ddd81894d", - "id": "f3cc88247afdfd0a8cab61e339840363c7353287cb76043acaa613f1ee5e8555", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 125174485431, - "fee": 0, - "recipientId": "AUYnvSaH7v8kU891WuBGDA8XraJnqfPft7", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210086f778878fc1586963bd8994419927a9a1f6c88f899c5f4f19840b2c42dc559c02207bde1d3bcc0f1faf3143b3845f6671a90792bb2e3ea1b041ac9d80a5daa02615", - "id": "2801d176b91ba63de86b0332a26346bc1e4c7a8a3a967473e18c09e559965121", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 129540204214, - "fee": 0, - "recipientId": "AbnX6Wyoz3d1LLBdY4pkYmRXvkv7qq57Nw", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200d2330b9edc3faf556ae66e1c689237bb630dea023ccaf3037dd706e7a9e34b702203ff844c9710095e75fab94dee0d6f15a2c233a4c05e37a593008ff36bffbbea4", - "id": "0a1e802ba4d8543ca30911f77fc551ef666486b36678ef2132ecbfee416331e9", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 130000000000, - "fee": 0, - "recipientId": "AYxWmuZJwzYkjUarmquFoHjG64ityMAwTm", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a55652d4a247e1e536a05ac2233c5cedcbeccf6e8b8e701af2bdb07b42a72fee022058737e0837e904be3c969f81e9622890bf7593604e8ef6ee19aa592ecaed0088", - "id": "3efe48cfa53baaacd2e25059d104d656493d9fd13eb2e8acb508db55db7417dd", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 130000000000, - "fee": 0, - "recipientId": "AFyuiPD8r62cdnrrAb8PHdiom3ZgUZsFQb", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009f3ec0907177655f8d54eb4eba7f2c96a3e86f239a914401174b45319c482c99022051c830003a1111109f2f726fb888107ec30c5faca8f54a34a078c4831e62ca0b", - "id": "7a58e80d25d0d063bfa357729ce25b66b833107b74beb953899a4724e981d47b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 130884887397, - "fee": 0, - "recipientId": "AGDxH1FYXf3XrL6nJ9qhwmGeri3M8hg7dM", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201cbd29a31f62bb30c95fda9d78c8d860fcac3939f39fb7b5638257d429bbc69702206cec558ca827f47711b6b0685b37a571487840d013dae31e95dcaccc31c0d82d", - "id": "218113406ee93b29cc9cd8ebd40d51df6eb6b37dab860641087fb2990dda7d88", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 132401763390, - "fee": 0, - "recipientId": "AdFxLwoJ8JVWW3zpPWkvcpTjbVtawPhh1L", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202cd5cd7114a86e5ea04746d2a44b1daf598749885f03cb8b69dbcb95e8f7591e0220062c9951b5f1476594c34f7bf9a47bb637ea83e843e46bc070ef8f80fd20112b", - "id": "21589db4eafcfe26a65312b727f705ba20dd4403d8ee7fc09dfe4722005251a9", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 133300000000, - "fee": 0, - "recipientId": "AVzze8R7jrAugNCcUDpS6gvtH3jLTBApfK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e575b4d782d64bfd7b3a5208a9b0b36baae254418f704ff71a519be9e33f4504022011766b87c099d21616072efcb5916ae72965886276837b08e8737ec00d20f691", - "id": "f0d6338a6ae19444416bd44a0a194c4dd6043950bd0488187c2ae522f0c9cec5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 133300000000, - "fee": 0, - "recipientId": "AHiw6LhXUDksaQkQ5YEys4bR3KQUpShuhK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220336d5cd425f12d9aba380a3112d53d3d7c8f64adb9ecef94f69e6b42afec87db0220521a58fd1b62eb89abaf64b5ba8e79493ff4b146fb9877ade991119b4d5096f1", - "id": "01968fa393539a33b61a61e9b27f6c666dfc9a75618c5515d4fc0ae3e5e2f7bc", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 133400000000, - "fee": 0, - "recipientId": "Ac9Z3Yq7xJeE2Vt5QcRPDmuaTS1FtypjyC", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c041ef867527f600f1c23510313ea3765322127147262b2137a7fd6ff8e8ea6002205d20cf3486dc1e2604b447f5cf48b4f1463c0fb8e2a5136d4ef43e5017355bbe", - "id": "fd69e79e125889c7e18e4ee6f3b9b6a6833185dc560cb07a24f76523911d9e87", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 133400000000, - "fee": 0, - "recipientId": "AeWazLDW2wcTR5tDFoThm96tZFVKvyg3Xw", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210094396bc42de431678812ed874f45e95dca0c9a28a3e67a48530f271fe1366c6202201aab946ee2c25becde260943d413a6b70e800ab2ec02bacfe6cff415c439a7eb", - "id": "99cbdf7999737e6e3ab6f3db168106e630e99e78c7c7f6610acc9cb77d9b74f1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 133400000000, - "fee": 0, - "recipientId": "AYKHBz1zZ1dQjpfBu7jJforx7wqX3MSw45", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022066f06afd81dd1ae22a41c79ae0f8592333f9a1f40d0dc09a91fc81556179ef6802201c0fb882cd5d81ef77ba6b1bca9ce4a52143fe2cfe9c06d0c4d1b6737d27b42c", - "id": "ac75980be3c16d88e18006a739c0405ba62ff7e4573297509c22799f36648090", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 133400000000, - "fee": 0, - "recipientId": "AGytj4HN26YqbqoYy8bVyAkHr5DBKqck5S", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022000cb76109a01edf4df270e3a942744877f14f08c462e21f48a97e8b401d7e0e00220497ef0efaa27f2b0f98ded7c797f897411629d2500eb9541e8450e2ec4a85b75", - "id": "dcb55ec4448b657e784ffce0a845657369bdcd31ea3118c6852f3a267858dbf5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 133400000000, - "fee": 0, - "recipientId": "AKv5bQtqcrS1NwWM744ApRXLGzxq8th83Q", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022000f10c1b56695f77a65301a9c63d16f2c6a984a921b4c43a1087e41362db454502203ee4bb6a6f6fec5cd685966c65e032b9dff460102e35423f16d677a98d4d9a77", - "id": "da79fa8dda0f553b25b8cf289fa917a8f2b3154d16754749c0beb2c0fd541909", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 133400000000, - "fee": 0, - "recipientId": "AW3MKtfA8qu3WyuWf3WzZsXyNJj4T9t9d9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009e8e61957950103cb3dfc4dad5e18efe80e1f1e4974d1c1c079122ec080087cf0220209c4741057ef4819de778e3353b58a0a9fbd45013775606e3eaf16f91b4c22e", - "id": "880ffeb2284de4b16dd38499fc6fd15320071d08a0d19b1837a1973284b44795", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 133400000000, - "fee": 0, - "recipientId": "Abe1tPmDJ7a34syYde7XCkdUfAGjPmhNyD", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206ee7dc450b5b1e60271ca2172e1e1c26b23d6b9e163bb8ef819e4d7a2cc3937402200b5b7687c82a928ce9856cc9d452ca71e762053135ebd791bf09e1ecf2f1d94f", - "id": "436a0eb389e7ebb2ffb7215e10fcfb90b707f9a3fe08b46b4a08e53919106bfa", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 133400000000, - "fee": 0, - "recipientId": "AaCJwF1eVDGA3Jy6MmQ8emMB5LKkPFhqPF", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c319ac615e8d54a36c919e40e7a6a77e534abbd952abded7533e11a1bcfbac2902203e9a945df2c06505823ea920839528d37fe946ec8cba4c75e1c2bc035d1e0624", - "id": "65451621e425a1118c592029a9b6f47f4635937da9640edbbe2aa7e1531b032e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 133400000000, - "fee": 0, - "recipientId": "AXYh1dUhBWumWF3Saj7F8UH46TqKoUR4oq", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210099fbf3734fcf70371ee259534f82e2ef84a37b9000b254f7bef53e812afee3a202201c0aed05b097804fc2e6103c996b323cd0d1a634d2bf08560d1473cb19c98583", - "id": "0e8d05444ae15dbb7cbfaf6ea4d03733dfdcad333267f9e7e7ed18f5975bc168", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 133400000000, - "fee": 0, - "recipientId": "AFzhTRcF1mdD8bswGM4kjyiAbvHFZ3utDf", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a40e1a906abb1198a9e6749f139169488103f6a089384414c228a375c3697c28022045e6829b51d7f3f0ffb9e6f27132aabb8c13c5612d9cf98b2bc65736d3bb7d6a", - "id": "53b7a5d15d2e6c5d4b977280ec050e8bde87040748e5b25901459f139c9afe46", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 133400000000, - "fee": 0, - "recipientId": "AHj3b7vTcrvS81U3xpWT62G6C4jVBpXB9z", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a226e5b1d830f56939fd2b860c004c54e6f49260ff1400d21509c2e1f6c7404d02201997e86e6cb516c88bf6ffc7ee6cafb855783954fb8e131bd65561fbbea8246b", - "id": "7bf54e1e48b45d11b86e06636fbc78f412d46ae1e71b2dd24dc3474aa6290dee", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 133400000000, - "fee": 0, - "recipientId": "AUjtjkgdiyEpuByP1uajKuT2HSeb68iq2K", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220415974bfe952d18dc3a26a966b9d7c63993568f834a3bed5c4bd08784331230b022029b654a8a4b0da40821d6a63dcf40fb325b58579041008ce1593aa8f1b785d09", - "id": "cc3fd2a9da7d622e24a186044bbe5479ce94cf75be168d9e2ce5a950853648b1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 134701272086, - "fee": 0, - "recipientId": "AGyWeMScLefasU8tiewWRkHBeqvSeaAGii", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e75d0bf3d62eea3631a95d6bf61055b0006c0ca0f92007b3b178e4ae82bcf5de022065d1c1c26883926792929c9945fd6fe6cd1054ca716113d146598c669f8b7db9", - "id": "2b80ef415bf5e28b1cc9b5fdd407c3005c498e6ed0d779defb5386f12a145b05", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 135000000000, - "fee": 0, - "recipientId": "ANZr3b2hPsGwTtVgNxpvMkyZZ6Vg9UZkrx", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220774c16ee61fb32555f68f77aa42d26f4df6689af47415876105fcc44049d00f0022026855b61fc8975aa07b518e0b4043f63f6e4e10936b25266754dd50f4d63c014", - "id": "70a85c890f419243809d0fefe37b7e6a03f73d859c8cda6f59cd34d1b7d67a5d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 135100000000, - "fee": 0, - "recipientId": "AHY7L1v8LzmNke19ArEgzN3tocigVaAzLX", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204ea6f57c6dad7869ddae0d8bd270a4f3ac278bf5887bdcf587ff4f083013e322022032a61c4901116e5714560a5ade681f74b41cb9947426384ac2db55df4004131c", - "id": "a5bb75d5aa8aad7955555060d8d43eaf3ddf39c0b7e43235466870752a8fc283", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 137900000000, - "fee": 0, - "recipientId": "ANAL6hHrK34Jy7v3YWGodsJcb3Egau8UcW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d12c766b40589e3c976e03c5a0ed64a8e44c32d3f0b1366051dd37bd9c6043520220455b383091894c83178c0ff07a45108abf5d442fa44d2dee6adc8b8cf884e018", - "id": "95fb3162c8f7beb2ab5f6fb61666094226db627b460f0d5ed45a76483064e6d0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 138600000000, - "fee": 0, - "recipientId": "AUArTLyiUVrf9h8N5fM4gtv3yeaT7sD7pt", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e4f07b7c14b4136b62ba30d4dbb23ef7c34d0b5aa574b528fc71975134700fee022018350059d6011c7c4310aae232b683b8bdfec4f366cb952c8a71573080eeeb73", - "id": "cce0cd6d09ba3eddc5acde554e079cda7dd1a370a2ad2136bee3da660a7bb6b0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 140300000000, - "fee": 0, - "recipientId": "AKbaSMZ36bgW2jL63Z2RYe221JvEKBJRpK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201e1e2cec556612a736da0487ae900c979093566cb9d461ee5f97c1cb8913521d022059f3e13018c3779000de42972f514a49cd359f1681a8f389d203483c95defd9e", - "id": "77de4c98b0eb2024ba7df54f734d9e0d86efe0250eb4c38921be96039a92273d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 140332554565, - "fee": 0, - "recipientId": "AS4JC75Lv8avQHSDT8aRu4qWLLzy7B8YnJ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220220c567e49b35270e9ad3f4618ce46a1d9b86d8bac6f51f77a561414b1c589b10220287e615bbcf9366ae1cc249f5652cffe72e61bc76dd6221bfb0b9751b359ed63", - "id": "b45e18990b9f754737ea2442fb4ce19f020f9ff1ac5bc083d69e5e24810d0e34", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 140332554565, - "fee": 0, - "recipientId": "AU1Bz7CJhiNYneNYEuBCXPY9WQBwCxCFSQ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022030a79416ae581e874e3f85ad8fac4d2c0ac39d7287c92e807452122a4b18977702205b3d6fc1ccddb6741330366926fd70ed89f160eef85bd2dc161e73984bf7c1e7", - "id": "627b1183a9f109a94542d761904f247ee43527810bb5b32c70c6089121223f1b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 141913175258, - "fee": 0, - "recipientId": "AWSYgoRKRpXfXbA3WpJ8eegTky4SdT6dYi", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d8aa4af8d9f52b9b1bac3b38217220c0aee778de34fa652dbc9d2df182540c840220687ddcebd64e8b0b02aa4e18ba738aba219e0a66157d373e840ffdcb4e3d5093", - "id": "fe7f90ba3d98988a846a2f943017bd03c475625ec021bdf13799f8cf7ed70b89", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 142400383746, - "fee": 0, - "recipientId": "AHomeJ2mZdS2HdBnfpznUGWKMdnGE2ZyBi", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ebc13c20a25aebab60d043e3983faeac70aea83008e8531afcd3b3aa986395e002207e37320b8a5085c0fcabdc8da57c7f67482b46847251beb21ced9096858d67a2", - "id": "73f0d8477a0a9691839f121b8a28b86f9c3a0283e60b5dcb57a74256ddc19c1e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 142597922946, - "fee": 0, - "recipientId": "AbCmk7JqsA2oNHjSxs33hwEwm7i9ZGfNTc", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ff68a3af0a8400a3f5bc2fa933df079aeae3cd8a33df0e6d06883b8bae604f3902200618c92f102ae967f90b5ab0bf2f17d561501fa6b0e42069cf958f58f10131b9", - "id": "1b8a6a9805b7c3a9185eb8692d93bf0130f0c090decfab0f25f33748465c34fd", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 143671138618, - "fee": 0, - "recipientId": "AKpcMURctYwUa7NFWwQbHMPShAmGvZxTDk", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203de99b3f8f7fb93625f52d07e75e9735674757e5728a0833e282e21887c399ff0220665f3516be9e94ea507964890dd5d1de7d0829143401ef78439503742444cb45", - "id": "ef58d87117fe3cfb73ed87681ef9df9144ef889a2027ad85f341809548a7d69b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 144747007068, - "fee": 0, - "recipientId": "ATw5aBDeZzzxdz1VhJH7zjYUS5c5m3wWcz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022016e3810651bdd50d22b4240aaeaed98bc01b383990a18711671e27fc1c2bfe35022027628ae55345065e5f4e21b462408a9845cfe2b3d9666506017fda87ac6f7e07", - "id": "d068d9b75cf07209d53076886c817de5d449938fe3fcafd31828ea400f4fd44e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 145130623474, - "fee": 0, - "recipientId": "AeReN9UHpbqNqA1zRP3My3iQYYw4vBQ85h", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022076fa46b96abcb0ac7b0b0b9b5c8870269edaa7b4a3ae4fe75585837c73c1194d022004e5e214749129ecef9fcbafd06325ec4645816366431199253fe349af14bf86", - "id": "a784b1ea1393c00ac0c8e58fa19b9e137f1e8611a4e8f81f65660dd36b4f3882", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 145500000000, - "fee": 0, - "recipientId": "AVgLdwCZLBUVRr84tPzwgCPLcdDRRTvkMd", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206d398c5a3c63f66e37216a297e442d8eb490c67bf99cc0a98c5680d9ddbe2933022048170d0c7dbe5ef0a30baee4c669579c1c414fc12cca94af65adcd40e90e2d39", - "id": "0d36bc9b909f51dd5bed75e5022f632bdf8707268e74aba53f8d7400849b49a4", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 145500000000, - "fee": 0, - "recipientId": "AVroDA7WnnpRhsAy9187e7mRs3c9p5ADoF", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201e8248c25c74669b3074a5efbdab29b715d4d796bf1b139917634cd27b72b1280220184b4d05880cabc910f372c43c13fe5f3db2540174993467dadd0bcab4c84873", - "id": "6277e6f92b5b75671e07fd26b28a16a82038447cd9ae5dbc4a8a525ea2969204", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 145500000000, - "fee": 0, - "recipientId": "AdQNZMDMYsqUhuZ3F5Yy5FvUsdRDSupxEP", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009b106d35d40c34def24a3af078288ce38a5c42374086bf13c1d43a354abd4ece02203797da879995e88f71e7a0d04b65ab17f80d073d0cd015bec58f1f4a5bac25a6", - "id": "a76db685b5fc59e38d3e25f7c43cadca9f35dbb079c8b5b73bc8da3066b501cc", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 145500000000, - "fee": 0, - "recipientId": "AbWS5yJ1gwx1GhpaTYDQvJSy3bCFbA2vpo", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204e1ff4b27c8fb80dc2427f493822b570600fab317cec5a5cb53a58e10769b6b202206a7dc2cdb7785ae00ab6240db3da4abcff95042a33f5c620e42af976925f2c73", - "id": "560771be8dc4d0c21922a7a57b7fb66a9b20803ac8051150cadb54816086eff4", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 145500000000, - "fee": 0, - "recipientId": "AXfFia87jEauZWU6DJHRbECKk44EXSQmbY", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d1ff7a6ec56fbd8fa592c687ba088f198d0752abc667ef957dd2c2e40d9589c70220218d36c822d70d25b1fe3c0ecc1efe85671b09d16765a93cd12c20b45f1fa6df", - "id": "63d81828f4c3e1455eb6a1aa99ef36b241b5fa9dd7c5cf86c92dc8781df88b92", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 145500000000, - "fee": 0, - "recipientId": "AJCWEe6hRQRiCC1gLdS2TUSbEwUPHxMJcn", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205b1550775c4cf879ec7500f8eb3880a3ec9173db41a7e8e249db14dad79a0d9902200cd06919a283c00dca6cbc647f1f09398dc377c8a4819db6ec20458c55a4affa", - "id": "ec03b808b1f705553a333f882008acb5330f3fbfb87eeb64b7879f4e3e9e013c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 145500000000, - "fee": 0, - "recipientId": "AM3Tdmm7PajytJqccZvjBmK2aNzfkmVNay", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100cb1a88bc254deed2de2aaaa7165c62d8ac24599cb716cf294fa7650d731c7cb8022040c5516b3945d87eb5bc4101ad5fd8e28c04a86a2475617d43611793c2e7619f", - "id": "58ea9d0e7a38ac86f105406e615eb08a288053f6be10db870a126b4d5b1a7558", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 145500000000, - "fee": 0, - "recipientId": "AY1tE8UrGCykVngKVmmjZfes21arcLLyzn", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d0b69b396392afd07b737fc4aab7262c5e693a61b4869afe53696e1d72c159d502200de0cb71068602b2552baec25e1d3421c4d59526c01a99bc3475abec5f63bd1c", - "id": "2f2c0ef7895193de3e7405dfda9ded41aebf2aa0143a3870f879800ff3af4a6a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 145500000000, - "fee": 0, - "recipientId": "APAFtJderG8gJDUr6avxr4thm5a2hrYk6q", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008d43e939b9b3789b1673ff939519fbcdbfcb6746688d1309318b2bd12f839c8e022009e186c21fb9d2963e2c01d863058aee90c9eed7349d3243c900d606cd7f5163", - "id": "d9e039153b8d06ab7b1e3fe64eca9bb917bd7a7c848eeaeda9f8d2b28d24d5e4", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 145500000000, - "fee": 0, - "recipientId": "AMFSfB5sy97Dr17fqAF64G93pxkSn6mGqH", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022005a7f2529d9264b887d323228132518980dc91ea2d0cd5bfed098b8f05b31acd0220676c8d86fe6be5a7fc90ef3ac2db26674377c33188b694e5106c36850fcdd5d3", - "id": "1f7ff73bd0c0b6c42a73499dc8948ffc23a5affa758ca17425d60d03f0e3c412", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 145500000000, - "fee": 0, - "recipientId": "AQ5kzJMSeEEr14YkwoTTGpjj8odwQj121R", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ba6df9e0ac6c1db0a889bcd3c30460b2d5460ddffb7867652dd4e0fb296d9bb70220039f2b0799cf13b3f9e5f4f950afb53c12c72ae1e6ccc15b6c86aaba0febd322", - "id": "39afbf86f83389014c2d00c1b56c215278a7d12f631a10e24615b4c69aab3dac", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 146600000000, - "fee": 0, - "recipientId": "AY3P1mc5878sCMkCFmJdEBhMXjzZivm4rd", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c563a228728d67c90cc13501efe0dafd97919ecec25afc4e56c48c9289f0d85a02205c91587eb8001188c7e291e0c851feed13f6960d1828b7fdc6303fa49eb08b41", - "id": "a1ab69f665a37b685d9219b051428f1e9930a4e8bd908623085b1cc5a85a7a37", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 146647519521, - "fee": 0, - "recipientId": "AVwxCqG9GamW79Xb96S7ipWUpxLgR3shoe", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009d426ec91319147e8ce9d95e7f4a2bb2ef20ac1a93c4b9a79e0a45b555aac9840220470cc4cd8993fe92f3e41ac71027ea68d6dc5e873a4f5f4042d2f6e03fea61f2", - "id": "6b19fd28e4fac7c60537e63d10d0bfeb1ac28eb768db7c05a0eacb22ed0c945a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 146868042106, - "fee": 0, - "recipientId": "AUALn8exeu8kXARs5HVxay2r8pmSmxMVdq", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022038a92d978af95b79d68342d7da3d86e0de7ec10fe793b87e15e889f962f78bfd02207095fdc539244f346eb46a50d00a5a692b0687ff1d6d4597ebc7f2f92c7b3aeb", - "id": "d3d03e03d5bba603521e8be851fbb870e25dee280cf5a1f6fc7a025d84314a10", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 146868042106, - "fee": 0, - "recipientId": "AUDTxFyejQZcR5bNSXBkoQocuoquYfChG9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c460859d8d9d4a18b8c336b5345adf8023234c90a0d2f86836a39ac3b1baacc9022068265214028204e47325d2f157d27c6ac20c0f43276d6df706d4492687b13e23", - "id": "04f2135cee1a37d6854cd0d10c8db0bcc83fd8176833428f8e5cb4b891aeaee5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 146868042106, - "fee": 0, - "recipientId": "ATxUGRxnCNHpafcsTQAimxEygTJEb3syCy", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008b9f09ada3004e0b966f2a208bb2c938b797b1973e1e8c2b53b7ad4b0860939f02206f08c4caaf1ed0102430c9b2f382f58e6e0337ef8c11ec6ca0894263b99086e1", - "id": "7c156161c977de562a5613d8b6b955144a56ebdd9efceee9e8981ea639e144fa", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 147015057164, - "fee": 0, - "recipientId": "AJeAvhsxGTJQKtd7RHBfmNtCy9fPUZYNVV", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100eba3c97cbd1002056427991b7c33c21336783809f814936183ff030378ed3c5002203c6dd00bfab286353f3565d3bc7be98975a9c8f412c409bf182892043e350719", - "id": "4511231384b91d494dd617db65cf90e99d7be45a761010761b39b2e07cf0a896", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 147015057164, - "fee": 0, - "recipientId": "AeyAvcAptKRxirAwuyLei1YLUMZap6RSCe", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e30b9369318e1cad7ec287448f11e9df997d10d4ccfa1cb14c5bc16f042969550220716c4d0772ffa77db00d076cea094ea196e1bad98aab377b20e87aea6e7b8b34", - "id": "a033da0ff01712d4b8e724846bc0f524a3931a0e268cbe798a006361a6b5a2e2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 147015057164, - "fee": 0, - "recipientId": "ASHqJXYyyKCVuhjs761cz5bLm6wy8nbSgn", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203c354c4d829f755371122ce7249619b2df5a86e74830f1809e977fb80875e5610220713491f7571edf18f009dd7d0a1d4ddd94ba8c53fdc7a1e53596dcbeaff40315", - "id": "86c30a20741f5fc1738e4f0180b64b585f0adb966d414ac45316a879fd5e7fe2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 147165816371, - "fee": 0, - "recipientId": "AVpQfwASwF3WSC5CM7HErLYvYBkpzkTmUu", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220030a63d6cd68e0fcac0e2eca89c14eb6a8832d52efa56e6d1a5b772805d1ea480220091c1fc5904423e14a6137f02d153573765905e76d1c4db66e945ec7851763b7", - "id": "93ea7b1a7e4a623e75cb4245a2ff78894c9f63c9ae4438a2b614350b9f65f1cd", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 147695811297, - "fee": 0, - "recipientId": "AevPmhwSCevsJkXhDcKvaRNQwnG32ygbC5", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d748dcbdd417e023f4e3976a7625d8c7f2ad45644e768bc5923210b70b8e535102203ecf2b3f03c5caabde8ab41047155bb14ef36073bcab9a76b1fde86baa8eb21b", - "id": "6cf7722a4793a9f5134e80853eb954b8772ec20f9e7732b109c7489b722f7c0e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 147792818385, - "fee": 0, - "recipientId": "AYdQPyMPRyP2jpp813PpvKn18rew13EJTk", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c946a710663b006a6065a032f29ae1eb13ecb2864ee79e7443e795a7d566714d02207dde19f663673b881bb01ddcffdc1bb88481b42c7b78058ef722238c3acea288", - "id": "5ced9e0a7ae04dbe285c3087898108f56f6ac791e3650a11c9b6d05c3279f0e8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 147794072165, - "fee": 0, - "recipientId": "Ab2sMHQxXcEFT347HyvsSdXqTwBWcYkiNo", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008f73302141cdd6646a1b0c2be14aeb4e40bed6eeea5ae720ba24d482f45ce1fe02203213e8ed9fd98004e859de842345e8a3856b9a1920608fa050211ea76dfd7cf3", - "id": "ef80b356e77a8b3e18c21b11b6ac09b3f89b7b99f33aa12fa53b4d2ee3f380b5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 148338192678, - "fee": 0, - "recipientId": "AVS2aoVuzEnY74iWsgzfzmMNQfSRc5KTzq", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c6b3c68949296e1794246ebbc64bd06f9f5d099c5a4498030442a6eb8a78d6f202205f0be315dfac6b7647a33934a04df6c40a2e40dd8a17303f0b20bb09c6bec6b9", - "id": "e38e2053c5110aed17e4a7654650a3061ca5441c3a5fd8d159e2140b20d26f33", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 148900000000, - "fee": 0, - "recipientId": "AeNApTdu2Kf7vphV4H2ZTbopitfEchc2eb", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201255ca8ef4fb94fb2a0f9eb089f9f1d48971adcc9bd153835e7df739109fd6d7022022a497a0b8ebc793d25e3348fd884f32cea85189bdae2f66799a3818c15e6936", - "id": "5e76229c1016f43b961ab11b51d4be7598434be225f68ca4347df5106c68b0b5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 149442810367, - "fee": 0, - "recipientId": "Ae9cyMJ32RatQDd1iPd5pftvBjFpRyghhJ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210099179595efa579206006e9b6689f62d222f67a4ce4565508d7dea57e3325c917022009425c7807f05f46406a05f02a8cd70dbb6cd20f7ee172749a54eb21f9fdfab5", - "id": "578b56b6076f8b418eb1df12980143f0ff841890cbdf447b7d1d5320785cd0fc", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 150899497250, - "fee": 0, - "recipientId": "AZGVDCCTnVz5zye3hsckws1AZkgnUdEwLj", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022056e8422f6cc77310114d7e7aab0eba13fbca2cc242a04594af17c8938d7a55c302205d8a258dcb617f878e4b25c84f08d69f77c5575e7c6840028059706635f5bd5e", - "id": "c543394aca3a02fea18e06f89d12e6f170269787be922539139bf72ba173caa8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 151036016000, - "fee": 0, - "recipientId": "APuhkVvG7u6itm8bUEfqDBpw8vTqTZMpdE", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008db754d788749079dadc57c9bec350c02487e095df746ae3e196c566b62edfa50220089ecf52f504b54a6d5ec5da34b0eef3bc5f151d8a65598c07da8cf61dc2524f", - "id": "2a5b77ad3a7559a3b066e6845f41c73b368032bf9c125825f6ecfe7f84a48f78", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 151200000000, - "fee": 0, - "recipientId": "AVJ6FhpMSHC7sywQDJujkwM9yv75tyzjrj", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202a8ffe7a80afccaff07d8d972d11e8af2396f9912171e3fd7ee869a30262739b02205b9785b72fd0ff1d1028c44d29d9423cf3a22a3e5c6514f86697742777868398", - "id": "e1e3ac19ac46f91d4be3977a0e95de5cb136219a984b03b1782243d0b5f2757d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 152400000000, - "fee": 0, - "recipientId": "AKMDyKrWkSbpU3q6oTxuoS7nr6G5US5Ppm", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b12f5c4a7c7e0366f303803b62486f0d6685eb60a873fdb9f15d508c8796af2f02207d28afc1bda7c2af2c650a7cdafcdd6111f950cc10d403fa95132e0bf5669661", - "id": "188f9c090bca5ec2214a0c41ef741aa5b7f3a947cd2cc6ffd51375c837bcf9b7", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 152400000000, - "fee": 0, - "recipientId": "AR5yuVPejTDoeHhfbAAYBMCoMPWfT64wS5", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207530f550343588e92edebc0c239f9d9215362cdba07fc9fb0a9a0ab5a3185baf02203a151c01fd5ee65b3b90915d6bc0d49a756a687e6e409ae21dc64f18cdf61c8f", - "id": "b5b6f86c2a8dcba704275301e6f78c80fc63a7c3f1e6f80a11e4c1f35e738e2d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 153500000000, - "fee": 0, - "recipientId": "ALhmTEX4c8Cu6j3LmvMy9QRScP4qd5uS1X", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009582b66e2d7e23ee2cd95f4a35683e67370dd60f84bdd4bf13a70b0e950255ce022027d4f0e29103bbe2c7626378b5d92f9976ef5637d4e30201f41762f6b58abcfd", - "id": "d337a4d55a6f848c4b56a1d8b4267ec04379b7ca49d51c4ff12bb4c91dfe07eb", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 153600000000, - "fee": 0, - "recipientId": "APL1n3DRcNdNvtGEAVXrZeF8aE3kSje39B", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022026c5e59f6f0389d02d8303807aa6b56a1677759397bf1131fa923da22cc0ff3102200c206cdad36b67bbfafcdc42bc5af3a43865c4dbcde49216cd6acffb1193a86c", - "id": "f855d660cd350500dd7c352d9e1e298f7faa93fe3b99d54fc5179caa3233e9f3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 154067041808, - "fee": 0, - "recipientId": "ANe5pi2srBMSp2Hsdi4dvEQkmRw6QRufWE", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b6021389172baf3c7416f95ce39a517a755f44e213c7fc174dc47c2a9f67aa14022002f08e8c6e0109219b258fec7dfbe25e18c5d563a99cb751219955a68ada0e0a", - "id": "300260d69932d0fee55a854007a7c8e16da8ba9a531fef306df009c500e42901", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 157600000000, - "fee": 0, - "recipientId": "ALUZm656LEa4TqfwdtkjP3XFidv8hdFG9y", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220564681998c47b9747919eec5e8d497815a14002b497a43789007d5fcfd1fa37d02205b6097bfe9e3c44dd8a7bd9d610a55d72c674cca6f89e29b37847ce57eb06ec4", - "id": "2c1eb9434e82279b5ba0aafea3b7813e4f024f3386126e65cbbdcaac3e1de27e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 157600000000, - "fee": 0, - "recipientId": "AWtwaGELZxRTxu6znTh3JaxMJWyUf5yg2b", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a87d31acee7834af08c83ca70917065c1a5a413a74d7c4443e316f24a8526ada022077ddd8c1add111bba68f01695dc922f680b83fa3db1edf0e9750a0e041a3c5d0", - "id": "b724ce6e1fd1bc009fd05da5523c735a21300fbe1a4fc1da52cf2c6ab9d66ba6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 157600000000, - "fee": 0, - "recipientId": "AH8dy4DPGzSnyMmfXmJrtyWhUkZoqsscWC", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022000f7c8a6f8a8b0bdda54992f15a566dd1c9c9d5d48f03b0205104ccef6397312022052ba2904b07535406df11778a86256ea7893b6e41c91a7889aa4e4f4e93ce7fa", - "id": "a7d0234ea7c0595d44d473619c7464781cfbd6b3be2edc583b624cb9210ae7f4", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 157600000000, - "fee": 0, - "recipientId": "APovNoMU6T9i1yvfXczPauvFA79FFPP3Ns", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e8a6834b4380b17f340853bda75c96ee9c553ba2b570402c28261504ac6f11e8022072c7c130180e042c97a660bf1f6f2b17625dc24acc16e03c4b54bfc767ba4e02", - "id": "86f6394cec011bda87c30b080e27320137e936adb8e67a9f9fde6afc84582c7e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 157613342003, - "fee": 0, - "recipientId": "AZd59X8LMYSdKgz6zz64jKxhs6YHUcE2Dc", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022021513ab40baf4bd11223c976ec339be0374e8a96ee60c90e499202e2e14916150220229b9355d285561da1b1cb33ad210df305e961ac485e3ce51db39faeac96475a", - "id": "a3b4066f32a764dd0cc8c357a401e91c30be8b7913851aaf8815c61f1fde18ed", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 159675898944, - "fee": 0, - "recipientId": "Ae4moTG7YCQ4yvzW7NV86aZVA1SL5jZGUy", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220799233668ec57eb2ca1b0c18b433e788ef25df88edd97bdfbc5919e1184efdb3022074a3d4fac5a531fee1ba3a6c6378d5fd080acd163e8e7f983969b1059376e9b1", - "id": "2d900441744993dfaa79989178ee5ed78cbf8dc5a67ed945b2558b0531c23653", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 160600000000, - "fee": 0, - "recipientId": "AeR1SNtu15o3UocwDDh8kBeov2RWeVYzve", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c3ca5aaa9b76d2d4f4916b9268fdedd5f8c75427bb980e7437e5e50e4028560d02207f145bba9763452fd5cf86013c35ff8a71aaeebd0966e2a6e218e7dcfbd43dda", - "id": "4f732a783e8fd503af9584c2116f4d2d9cdb0763c1629f202646dbaa79445be3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 161600000000, - "fee": 0, - "recipientId": "AP8RQXpVHCYEjNaQzHPZLYEARWeMzYAnUH", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100dea089096a8ef631cd271361fd564a626f541409e3e166082890f5c3d39a5db1022057eaa7c8ca2fc37cac5129c8994f26b231dada2607cf7f3e026bc5b22c9ab89d", - "id": "99aad499192c22c4bcbe71b8c133bef61eb16efb59b9281323e04c6c4b925860", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 161657213879, - "fee": 0, - "recipientId": "AdLtfyiktPxNa8Wf3uEgGiPHHRvBwb6BVS", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022074316c70b4b377bf7ede11dfd7e246e947479c62c6343c8370db0f0f5ba9e19702202487a7a8e86ee4970e3bfa3c42edebfab845b42f98c454db3bd0310c085acb07", - "id": "70a2af7bb1dc6807071d4c2ecc193a16ea4adaa872ff14de76d40e5d07c3498c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 162022981403, - "fee": 0, - "recipientId": "AW6FnNuwQGBcJ9nujbPDx7CBjukP2tK8KN", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c29213cead6a57f15622d66bb90dbfd8e9f46bbdbc186c752113d264e930486a022006f20912f179934ca1f2f94e0fd43ba5b415666d9949c11f0092de3553f648e7", - "id": "5c75d116edc4dcc35d0ba18d7ad56aa45dac0d9404fbf9f52e857fe8e8f34406", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 166527964751, - "fee": 0, - "recipientId": "ARkk3RAAeZSrA6Q2NiQYi1F5J27yW8Fz66", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220297e1206fd771d82406755d928bc86097eb8126f245e500f9c3f425d5b30fb1f02204b2258bcb30b1a11cde8cd76c81ee20482f870715cfb861c62c1512bc2737344", - "id": "4f3aa1ae966a9f4ea2bffb9e340bd522f3ee33479be4fea1f63d5a7b5eb47c0b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 168221932329, - "fee": 0, - "recipientId": "AN7y5f2nixsdifEkZTcgpnXWBzpiuCkcQQ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e460a99b932fe2c9b28720352ea943683be7120993e9dc4bd82bb336167c597502205a46ceac87e8dd5179eb40194229be169446ccdf085089e657b200089bcec557", - "id": "6bd4850be884fccb495c347ca9a9ee5b46be31fc1a0404c03cec0608912be6e6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 168973133925, - "fee": 0, - "recipientId": "AQ6ziotXeWnocAnwzz7V2idW8uxz5V1pka", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100bfeb6d49f03a89820a6dd1e82d238aca795866ca245be3f43e869dd1ae5bf9f20220580a0224b2b99b38564cee5b3470f88aa7c7106068e2bde76fd8ad1d8ec0ed98", - "id": "81e4e95e91247b73cd9e2dc3be2a84efb9fb428f04b184f63df43d3c1a9de40d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 169700000000, - "fee": 0, - "recipientId": "AKDpBAVgjd4cYXd7dP6khrK2Q5GyuyQfoi", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202619a5fef5f87ca49dadda59139f17bc7f388f09340914c5e0b997c1f0492b9d022031a12aabd0dca56193409dbf39fa3e9ee332d3e47fa4656252e161ea90563c6c", - "id": "6c86bd9ad81ff5305fa35d8eec25872292bf417ed456a801bb2301cfd9d5e79d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 169700000000, - "fee": 0, - "recipientId": "Ac6zKra111cp2QccMk6zDNYwyWrYsjY4zo", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203677d3e5102ea36a2a7693d8a47c86b3f182aaf7c4c8cb4118efb17eed87b6f002206a17cdfc67917a0c18faedec37baec1be75245eaccb45dc7fdf8ce4cf49b1e5a", - "id": "df692fe1270c264c2cad4bee6383428d2038d6b82d29b805d367690097136575", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 169700000000, - "fee": 0, - "recipientId": "AZbfRSargxVS9qk4cBB2BfVCiqir8bsrKS", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100bba6694b9e169a8b77a512b9c09079d99586551db4f5848a059b18d7500ec4e60220438d0b0f1d75a0621a6a06375ba8a3f75dfcc542d7d13f08175f9878b5feb409", - "id": "c0ca1a1626b404ec63d0a50fff867e2e9f9a1edaa744840c39a58c979862e33e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 169700000000, - "fee": 0, - "recipientId": "ANeUUTh74UcDqZhgxEwMe1SX2CP44MkfZX", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022072f2156f00911ae5b22ed9bb3701c89ee4ac9ede3f3b4451911e1e284e21f3ec022001918a7e52c65cf762ace735e980547e60abc3d00df59cf16770faaedc05e1a6", - "id": "b119402b26404e9bbba26df0e59cfbf8d50d41d28d428202fb0b293e19c30830", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 169700000000, - "fee": 0, - "recipientId": "AdVL1oAWGLDP5vKax1kfA9izMrZGkaStAj", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206d1a108b0dbbdb2c78252fc7ad9a91ebd9a525fc5d6a0c13f94d64a1e6f8ffe002203c04d2e0f607398933e30df73e93a40db9ddc41abef1980e954654a6bfdbce12", - "id": "ffce74f355622c5a278ee320d0d9eae789d9a8a81440815bd919179a5a0b2633", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 169700000000, - "fee": 0, - "recipientId": "AFpTaoXGqbwVG2HhaWJK5Vky8QMXCGNxAh", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206dd92556e443b03c0d88cbb88f562223e8def85b3c4e5ac40cefd0dc958ae157022012b06f7fbd4551ada6d470d25bfcd38cf8cc711c9af94ac56e4415f4f099f528", - "id": "ea0ed0b1bcb706d1e0b05b818a91691221010f7fece97113227de6a2851dac02", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 169700000000, - "fee": 0, - "recipientId": "ATzVyx4Et7ie5KLrjEUm4iULw9Lm77vgkt", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f42364a66c031a8584365c68b926931d1ffcd6edfa8a4a859a9e07ff248a507902201731c3bddd83d1f64f8514f5914b0bba1f385c6ca410241a0c313c5b8b614b1b", - "id": "6aec2e00bf4ff94b4374f83df59e85d0b6a5d05fa5520b021d02c74e9b582e26", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 169700000000, - "fee": 0, - "recipientId": "AUeaN1Nvksrkynuxe2KFQcDnE6U8dHFPdD", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206facc2f5e57cb6ffe15840f80384f3d386125e186234a6825accb2c8fae4dc940220456e79a2aa1c1302dd8d9437d815582b5cf6e2dcf9e7bb18f5036a1a1c77aa80", - "id": "965f90cc474b98cae2de4369455e85d1d10b71d5f6218bf8029eacbd8ac70324", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 169700000000, - "fee": 0, - "recipientId": "AbFmTF7BXLzyHYPsbzhH73fcUSzYrLcZeL", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022025a0f243b8cedb3282616eac1cd44a0f15f0d908c75cbe5cc9b0be8b46c4e72d02207463d2e7f585be69268fcdb655d3d23c6f3b50c376b2683d7e2f86cc7a5e1aed", - "id": "c1d0407270d31a4e5a569d340e0e71f3e7771dee306d0c229c2c4badced51dee", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 169700000000, - "fee": 0, - "recipientId": "AXvyLRRSRYxX8HsQHwLgDJNwwxQ6MPyuhz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a149e9edfd55fbd717c71c7150b9546a47072537b1021c7fc4e23703b4322c93022033f23dbec845e796d00102b8570fabea477c75c88b574611bc46e3aa94afdd73", - "id": "d7fccd7b5b4da68f0deaad41f9f132f5891a82295259510d2a4c8f5c1f2fb22e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 169938227241, - "fee": 0, - "recipientId": "AKLvGM1T9FCVstMPjWTC9ytw5UjyZJ9xMT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d361a2adb15f3e5b20238eb382fedf6a502ce30044b065b9169f4bd223d30fb902205e6004454fb61b7562e86ff5dec410db6765e29128e23285a6dd2b34fd437791", - "id": "a59e761db39ffcf16d170da0745cb36b5fa9d13c103592cfc28e1083ceacd886", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 170449652084, - "fee": 0, - "recipientId": "ALwMf5fAPMJhW3iwjxMydBBNr8EgZcTkrr", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200d97423751ff5c67b4a4bf29412b80ee84ec48c34a9412addeba4bc0a6278372022010398454bef83c100bfcbcd6920bef23951cc1534611f143c9dfc07a247d60e5", - "id": "d0dc0ac9dcbaea7ddeabf7fc94171d286fccc49fd07668e417b672e96b49f362", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 172000000000, - "fee": 0, - "recipientId": "AbpQwBzBGHQa2NdEpPbg8p1N5j1u9KUMkL", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203599ccae223b04921b15fb6dbf2282c0847656785d0fc12874e739520462d8b602207d431393872a4a6c5e9a7014e99c5d5dc6ce17ed2d21745661b36c34096a96c8", - "id": "245622a915732fb38c48597bce7bb1b91a4ae08bfc629ab7108f13f17804a962", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 172479663865, - "fee": 0, - "recipientId": "Adu9KbxhD6etHEMnjkf6n7diLWdjEGzwiw", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220702ff0e19a0dcc3fb0e62185a5cf1c094b6b67e3be700252e02ece19e3a53e3502205f45c8b0ab6d45cacc2572799244c5304b832f068e0cee10dbfefc14384e98d8", - "id": "3e2a032b3ea825987a4f374298f036806e3d032d7047ffb77f3c74c62d1bb8e9", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 172700000000, - "fee": 0, - "recipientId": "AT5ziEWMZjWzBjjKbgFVwa9XsXvgLF7E6x", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203072cc3eb52d630364deff654fedbc54d5a05feaac0e34e0b56acdd843c5d57502201e8f8c94205b700683610b373a3014b04fc0c064ecf7e48115febe1dd26e6c07", - "id": "760939c2cc34d8b911d94e7c5d33e577b4b521695ef1283793e47e9550cad9fb", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 174283983946, - "fee": 0, - "recipientId": "AUnkYxRkpMJZ9jKzRQMN9p5VGDmYhk6bZQ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100bf56948136cd8aabd99228cfe5b668e3c31ee9ba51904413885a0c28de5785b00220529937211a9e16896a45ce426309e06db74d3cf0014316d6472088d843ccb6ab", - "id": "1440feb6aeb77c3ceb720c4cc1aff6c3ca840ad482b13ca6fc44943f26bd41d1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 174283983946, - "fee": 0, - "recipientId": "AYP5kYDXLi1c6wrL6AbUX3S2JUEZPVLyug", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220564b80aa83110cfcf4c05976c11cb0bf022aea5539ccfc7285e6bb7024ea92a6022054cd14b6b69a9a7aced496951201a2b39b665282a053686b6095aa8f9af74be9", - "id": "2350844dac54c1d2b56608babd879cd5d1b986f4d0c3b32f587e0d270f9faac5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 174996809637, - "fee": 0, - "recipientId": "AZ8ijDkmLBLemmH1AVPQZz1ucfK7hmpLaG", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e3e8f38a1b850c94c87b33bb095221210280b1f9da1d2ec58669063f7b9302c902206b3b20dc5e9fac39ab48f418d4119751c52692aa353361c20839b564ae2d86d0", - "id": "af897d4026d8b58fc97ad3e0a4f555c1ec2d38954a590611780229514b07aac6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 175000000000, - "fee": 0, - "recipientId": "AQyWsH3NpyMMepkGbMJmqBqZehhQoDnzgu", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a9dadb4e5df8e5b324a66eca8e5a2abbe608886ceb3058c3b28d2c4eaaff255602205bd59390dd1b2b0019a5d928913d9379cad4adebd2b686d61b91733acc1629e9", - "id": "169028e76183f099c5c6937c4b0f33d085a4dc67b0cfdd5e70ef985a7640cc46", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 175000000000, - "fee": 0, - "recipientId": "ARaVs5XoWqrTdQrfXSSr2PTFWpz8ex6Tpd", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3043021f2f2ee4045f6a3a4072212a905fb674ac22021fbe4f627ab06254c9d8996a6302206011608f1e33f52c6e310bb6f5990fb97b40e3621266d832b5ff3336998c75d8", - "id": "b29913407f911e50a89ee33658efe0bdd856c17654f022df7dff3ba66037456a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 175000000000, - "fee": 0, - "recipientId": "AaAYd5qhdUN5Suq6wnJyLFgvVMbz7tAXhe", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100dbe0cac3b1a67b51c05c4dcf60cdd40898c0d797c9e82ead41c3d253ff5936aa02206a1367f167e42d0272eb4a2aacde2f6392b845324131d83e4060743e981a2982", - "id": "8c1d279a9c3e6fa01cdd41be4de0389ca0628a81e9f54738b3521a38cad15199", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 176418068596, - "fee": 0, - "recipientId": "ALemeBL1Rt6JgL6Z8CJysKDckba33SxDJg", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210087e1ac43a27da39206017ddb7b7d65c9104eb079587244283e27156769a6669a022002838c9763c2b4c53926175830c64dde70709773dd9ec5fc82880f8afcc57ac4", - "id": "d1e866be9ca942556ce9e7b7e86fc181cb4b2507a254e213837cc9549af568ea", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 178300000000, - "fee": 0, - "recipientId": "AK7bbYXM4Gkyscxp9sVecVn12z3oniuEfm", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204c1db106bfbc3cfb05d07cd96f73e94a858a3b48d98e6ecd569c70e6bd381b0d02202db38c2a3f4796f90719ac11132e0bccbf90f3c4df55a423a8102cdc2617dbf6", - "id": "dcfa805aa6fa5e3b48e2977f881e0b5e958fcd6d8f5e954d2ffcc19ec604b548", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 178300000000, - "fee": 0, - "recipientId": "AeBnLajb2S3ggu919PuDkcHKvQUyHogQ8e", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e22d2b3fa99c81cc47c253d98cf068c6e6d4392cea6b98046a6f9bf96f08cc2902206b95a356720f6ad9a1fc35a0ad4a20dd52ff5554e917b83a47323564f6a59eea", - "id": "b7f38f5e6054fac0d79bfad045c9d6320b25c5daafc7981cf20e97a86d0c960c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 178500479084, - "fee": 0, - "recipientId": "AQdLeqJwgo6Tq6K9ydgN79wyaFt5gzKFde", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fa25b2247f33f524a63be9001bc7bdcc5bec69b58672a2716c818bd6628e2dde02203b4fe9e4e3ee61142c081368f69b7aa585bff6a006d89be99f11c6812f8adefd", - "id": "f31cb0587377be839be6a8c831a618f305cf2aa81524fa8b7db848d1a890ff0a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 178900000000, - "fee": 0, - "recipientId": "AbZg4v2npAwLZfgjLAX3fj6ygRRXiT4uJ7", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205069080158b4cdea2222990a79074e3b604f8fa3c9fe3c64a6ef43c28e17235502200ae19cfc468e9a6be38f7d32418a8fdbd9645926cdbc41f69983b814a2370268", - "id": "741fa2cda9837f82593d70443034a0fffcce8513f05a6808230b4dbc222a517d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 180659436535, - "fee": 0, - "recipientId": "Ac9dEA2bwQW99JBREyPDyhEotZ7YQRH6ra", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ca9bd24ddc2d0da487f016603fcbec17be8c090360e57b8e8cfc33609bf72d080220033a502c201ddc296b9ffe5a6c8a439a56ae3b3e7c21907467f22b5c84afec74", - "id": "d777a58efef6dd5addf4b41c7d606d5087d2c04da46cc3de40df6b253179322c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 180700000000, - "fee": 0, - "recipientId": "AN1yL23GyoHGo9sa9k34ivBDsbJ9xNTso4", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202c19e9171610eea55add6b8ce88e6dd2df3cebcb2c7408750e2d439462053b9502202a0ac408178498ac59f3efef9fbe11595c6354e192d93384b40016ce4032d73b", - "id": "9baa8ef575418b7c21c114677123bdf2994083fdb026f71f3160e42749a3d896", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 180700000000, - "fee": 0, - "recipientId": "AQvopcUU3ynU28hy9qrgjNgAfNJUXxxh6d", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f192ccea6e18a7c7085772ac499c17747e47086e3e3f8091062a5024f6e1d77402207312fda88382fe4897d0f36660b431290e6cc28d09da713929cffaf9f6a49924", - "id": "bdb82c07d56940e5aa3ed4738521380d13c46dfcc2c41a08a552870b9b2f26c3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 181302136380, - "fee": 0, - "recipientId": "APytrs52Z9zEQFbTTsVseTAc2ah2w3Rz6E", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206333d9530c4bb019d2fa8505536bba29d34255860b173bbce1f3c04dd5dfaae502202f71f8001cd13550442493273dfb28a76be302bb4958fa2c00c1da0752c5584b", - "id": "c8e21ed6c8a7b2de81d217a948f55842dd2d9f3ee5c5355e333357d7345a0276", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 181861548464, - "fee": 0, - "recipientId": "AK3N2csioKfWiKcdFiM5Jz8bh6pQurd8B6", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205db6e528d94b20b8a25c31994a01ed5b2735bfa1bc5cf2e8a44d44b666ca11b8022056eccb3b38df08cd32a6d10abd316caf075582233a4e3f33cb73dbd143ee2905", - "id": "70ade5cda886880e03b60be04919c3623a511b655e98dca632b59c49c861a285", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 183741686918, - "fee": 0, - "recipientId": "Ad5ZbazVtWzjZJ7PPep5xcd6BrKXujAVRs", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022046b4f82debedc188166749d7eac5367ea18d2c56ec136943dfea7081d2a52af402207f6b27161c1b32de2738e9d55225e411d74872db44109b4ebd740abf1f3751d8", - "id": "d7f3e67bcfcf0e9be5368f8c3a0d23f48271465c61a3d345054c5be9aa01249d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 187700000000, - "fee": 0, - "recipientId": "APaeLc9yFj2Kr4c6TzDvSEhtv9yuyYt15r", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201f2ec1b7426bca1a40df431b64b458e41c3da447c9110f04752b17f27e19922802200f450da9a7053e18de7d92f27b373bbeb5e8d83d9ab97e521e7b2b97d70a56bc", - "id": "2d55f798fc91fdbbf8e8cadb68372e3562b7c14b5c8cc9c15e9835c442f37133", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 187862979565, - "fee": 0, - "recipientId": "AeK3nfKry9sXXTKdf1TpGxukzwjEbFsYzB", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022049d80b6b0f5e5592a925a105fa49d3824cf6ade3e1f82c6e08458fc6d1b4e1ea0220084e937408e7f66e690d2170723464652d7fc5e49b5a50d46edd4daeec028806", - "id": "90e496cfb4d6231cf2e764ba08e6d236086ee2b0126d754e96e1f046990b4741", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 189637269418, - "fee": 0, - "recipientId": "AURDY45qCCokzgcLMHFgMQedxx3fAAvrmS", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022070499c504fec7c112ea30ad8064083d50c86fc7bab9c35b906d3f5dc574a63c50220295bfade3e5b109dbd370a713f8166eede8aa42754b532dcfebb2e1208ee064f", - "id": "a344917af836c95bd810bbdb119bfa4505d53e314f7d8064b947a95765acc668", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 190000000000, - "fee": 0, - "recipientId": "AbQgQntyhfSarnTh8cFN7o5voAyDvbyZFa", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100bfd6cec5bf192f270babc3b0ba8435d592bdd369e3624c9c6c3b1a01b5f2b6820220191aa370fb41dc7e0f1c4ac848290419702e467f73dba7eb5e63f31028585fbe", - "id": "5174fb0eb29a8303387005b4518977b8386e811e228754863418ea5dae98953a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 191010602651, - "fee": 0, - "recipientId": "AQXAihgHkyTH2GaA5q7txsuGN8Wm1fRCsh", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f63d5da7c7ccdabaeee4c6d4d7a6a280feb33e4c0309291d9d32e689be6d83b6022013a07a743b78fb4a3fdc0c405279a72a1514baebb9dd166b9364c46eb934c3f5", - "id": "0b931be5bc7475ba3080a14a864bbde1f78e8dc0e9097c7d6541ac32990f55fc", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 192343079840, - "fee": 0, - "recipientId": "AJVL5Lh8fjMSrzDMTXxsBt8bjjEfMp6eFb", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100bf093f56441607b038305a26408c77428d3f41f0be77f1ad8a990b8837902eb702203c3badb9b7c845cd4c84261403de3ea42e644f11cc5536878828ff3536e91c0c", - "id": "e47fbbeb7f8b522d4a60ae7731df51df96a687adbea76a3d216c8671106e9c81", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 194167513244, - "fee": 0, - "recipientId": "AR8J56ZfnBCzB5Lvx5VyMbjKnfvN1ue8KT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fa1e878c673805908d682901f13bf1f0ce133822ba183e9c00425bcc1d43e8bd022043c553f199195ec42da2c5ffead7abcf0aa9046dcb8a5009f0b04d64f3611c8a", - "id": "2da708e273f79eae2ccfc37fb5ce48fa46f664f90715e7109b4b03d4f336820a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 195295588810, - "fee": 0, - "recipientId": "ARRpaRQ3t4LQdiJSN2ZMsuShCn4RqV6uq3", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202b4e543a3ac721ced2a4cde390f1b7e31d5efdc3d036d9e6a525c5a093ca7768022030c034a23ef72c1f335fb32fcc0e068ad14ddb0973302f8895f46060acac864c", - "id": "1cafd9c19b66bf9168a643075f84b1a78d80c909e2d6fcd13ebe51335ce45d83", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 196578368156, - "fee": 0, - "recipientId": "AXnet9aeWZ6SUKqHqHaZfCZNuTvQcdS9YR", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fde0862fac2154078b283cf6d5d95e9913b5b19ba708cc17f6287832216e54e502201f71dce1c39e215b9d5a3c971ff5a6e8ebbfa6fb79a7135ceddd490216fed391", - "id": "4a3e46a8378334a550bd54172491a19a8832ff1c4e909b68f54a9acd22fa9e0f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 197344240463, - "fee": 0, - "recipientId": "AV9rVNEKtxumKAuw7ZRui27Xqm5oDQTcGu", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fdadaef2d3b1c8eab520b7a5738db35eb35c224e2fdd0d215911454d74b09da302207d468b503cea3e7106c55f2b4e3081036c6ee71b0d22f3c7ef7c6ace38c2c1c5", - "id": "7a263c4f547c159bfeea9542f083060435453a72ef8251375930a6ce50788e35", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 199700000000, - "fee": 0, - "recipientId": "AGJDGWF7ZdcFg3py7fg5DXVLv7u835YEu4", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200d2557315c3ed28f6e9006adff24c8c7653482ae2c5a46536dffcd2de17187c7022021bb54089176340c71544b27388cd2836274b5fa4578af87a8bcebf8509160de", - "id": "73ee85253599b0a5c6795e002a0369b02caafe3d471e3ae50bf06257d9242ea6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 200000000000, - "fee": 0, - "recipientId": "AVQp4XzGX7xezNvAs7zK9THH52sHQ5cVMF", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f4497eb3cf8dab8dcc034e86323ed133378045e5be031e8a0aa7e146df51185102205b4e2fd28d73d1c6b0363163f3d43f455e909c5d1e91ab351f1c54a0c1180c56", - "id": "ab4b8af4e3bba9782ddd6e1cf423572c08018b97c1edb458ead90e71d84196ef", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 201600000000, - "fee": 0, - "recipientId": "Aa5mSdp95Q3UYCfq14hyqoFAb17nbvwtce", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a859f753c037cf28dd0adf78f00b25edfb1824a361dacaa6e638c1a026072f4002202f3fc4d70a9a783cb18cdf15cbcb44152c33c4b1bd3258a8d40b080fb677b93c", - "id": "f8f09ffcd58da0f41474741a12846a993315794679c3689f683e2caef0222616", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 202607842389, - "fee": 0, - "recipientId": "AZ1X4tRmPioTYsF7M9G6LptiwUC3FiTcSR", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d687ac1127083d06605b4f903c9052cc4d0d4b32a6721e2bf5802d7363dba00e022072fa83d6653c638db9f2f011a61c7277e3feda10551d6455be11f7ea8282e625", - "id": "9fbf5160fb1d3e8c0b218e2332a1fd4ec0bac96c346fafcf8430cad2aa7dfbea", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 202700000000, - "fee": 0, - "recipientId": "Ab9yCa4xAXYPMhDVQn4pq9sPaNPf87oPn6", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203b4ad209e97f90c9042d145d904fb43b7415dee167bc23704e29d1b1e6f57a7602207cd6aa93c337139424cc160791262310216b131fe347e6261f29c30fc470991a", - "id": "f553a38a56e7591467c16af7ad8b3b33661f70cc6e7ef38b7193ca30d7433e80", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 203859765516, - "fee": 0, - "recipientId": "AdAVt1aKEhoTSpoThdzoBc551Pd8TvcnTK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200ee9a0e9d21b09cf8456a7af712aff5576bbb7487afec2277c6ce857ea32044202202c7c723a32c2eb349c27cc9b53aba8c41eee9c668e606e8d1f39a4f4c51725cc", - "id": "fc7712497be31254a03197aa586d121307aee0db828ea22ae5f64efafd4a7d2d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 205000000000, - "fee": 0, - "recipientId": "ARpbHrGteAtmcuq4ogVhDHGYa5bNX43vuc", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100be97fc5e92f8dbe342499e2dfeb861e2a3034d90db0ed46263c492c02821842602203c072ccfcfc88cf36e9e2bb05f4bb6bad6055c6b5f409d46a686e2594d92b2f7", - "id": "3fa38602a65a4cbd8289112ad9d2dcc38682688422da1399192e9becb3713419", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 206040822146, - "fee": 0, - "recipientId": "ANiKFTez41cCVTDCeQMGDah3CZcQE3QtqM", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b2d3c8ff809e06ce7f18e8578c098a05f17ef5725f5493455fbdafb0a18c64d50220278ebca469d1ec78d436a6876bf69caf7c43b61de58bf725768e20e5467b214f", - "id": "fb110b753cecae568ea684ea89219ecc435e4c0b36c4732f39429b96c4324d42", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 210000000000, - "fee": 0, - "recipientId": "AMEiCa1gAAMQkkNBLq6U8XU6eojD9NDLhK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100858d68292d61d3ee9765bd761c669b387362768926892d13e20de085dab00b34022063217ca008673f5d910d52e76172ae3d5cd89c5397722555fa02ef904046b3f0", - "id": "5e160385a766397e2e8073acf3c6e61ebc1e5531c051511e2305e1f9a99c9074", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 210742589495, - "fee": 0, - "recipientId": "ASa6Ptm7PRBFEabEA3xSAaTzkXAATsgWYH", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201f7e5d2a2b1eb413415147c5b0531be4acc9657a258b0642674a9222c9e111aa02200a6b12557e8b15c93363cbd2f16c5da5b347808b81ff0787b509a5df402bdcb2", - "id": "7e416a3161f32a1c8fc7a50ddaee0005af24af5d71634ed412a850b272773300", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 213596124973, - "fee": 0, - "recipientId": "AW2WdVA4pT25G6Mg4Y8v4zVzwMqf4aSzVY", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f483231b8fa37f29b442b23f5cde12bd0a3c5aa9685b0474c9d8b49e29bba09202202909c7cfd49d450ac8230e0830b501c30d4bde12daf911c0123c2986a6cd940b", - "id": "c40a53464e01b2d155f20f7bee18aeff16912e6d0bf62ce7af98242c7d17129c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 214366548708, - "fee": 0, - "recipientId": "AY4zDyuA2GRwYA19o9MfJWHkYX5y284Qef", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220433e6ed95528685139036657dda5bd0d00835bf887ff48b50f2ab8fee55c862f0220454511b151d642bf325c1b76e4f87c10e2edcd6888db2ae93b80dc002c64fc26", - "id": "d11284b0b9371d544a9164d028d01780bd65f8c855c147788bf9863670756898", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 218074902818, - "fee": 0, - "recipientId": "AcGLR6W5eVw7Z4nUNxAKAsPbff7W3g27LL", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022059ae53f97ead4bcffcd1918d7441d2af25e3e82b8177543cf2ed491506ea4452022040e8491b7acda16b0cbe26376c7c363c31e007fe6d530d0a7b59a2e0fa8bd2c2", - "id": "492487dd0ac90a5e56db964bf01399a2e68a6ae90ae7df983d28bb7a016fd3ce", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 218233858158, - "fee": 0, - "recipientId": "Ady9TkKQPteVBFnEgsB1jReC31ChZPQTrM", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022044026bad7aac5170ffb87b2fab2d9e042093d05707d14e8cecb33de925fd04b70220181f5fdf565a57905911e0de52b99de3fb686768d269bd825e660a7136e88baf", - "id": "fe4a120e7ab4c9029ce22ff565bb6a3b1c94b271d356fdfb5ebff146b521e983", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 220000000000, - "fee": 0, - "recipientId": "Ac4TAJqrvBq4ts5VZBhHdH1NG9t12T5iG3", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207afeefd18cfef28ca2d575ce09186d5e73dc9b26164ce2f236b3191c0f96279202202716438a52ea4a50fc87bcf18b2053506f19cbc8063c6115d878c5f6392effbe", - "id": "97b34b6492aacfd46d6cc9abc808fe0a24753ddb97bbf6f6fecb926097faf36b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 220522585745, - "fee": 0, - "recipientId": "AVQxWb8vskpGUtBHGyWtZSdM9gGK4oWGAr", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022029c9ca7067178a57095b53e99b9ef5bf510797b677eff8270dd269c44d52af190220773c8cd4647f9bd75fa8d67164990b3dd5c4e872564438d5125be7c08224858c", - "id": "8bf8a19bc12cd56778d9ceed54b0f85bf35d93074acfc79360c845b3afc49701", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 223213787338, - "fee": 0, - "recipientId": "AdYX3f5TQrDG1E59vtT67yfUkePMA4kdLs", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ca26254fdba9aff2aac672c8f81d6501c7ed05f2310408211593616c79dd1d7f02205601d25d8967f49a12d32334a65c2a5135bffa6b00ae0b8409c20012db15c977", - "id": "01729bd3f0c4cf81b3c5ee92c11104e3ba3bdaf5ca1cff75468b1909b0702c0d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 223400000000, - "fee": 0, - "recipientId": "AW1Hn4dANHJAbEYZeEjY72kHziwS82vgnU", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206554e7abc84d48a0446916b7dedfe2ca80b81ee68fac6a1306e20f21fff13277022069ce2552631634c4ea0d8715b01b78b2a6a5ae0ae27adedee6fa6e943845a33d", - "id": "489622fac2962052e7aebeee1e4a4b2474432b88164ee70863fc4597ccb0f27e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 224600000000, - "fee": 0, - "recipientId": "ASHHaaJMGmaBdgYzLBnCf3QRzmBfiCLwCZ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f52a3a95b11ff46babb1a698a31a2c15543cd1e4edc0222b7f6593bf9e1d4a8402207aca0fc68e3096119766e390f2d20d2e48d308520f2700a4a1a8400fc9472407", - "id": "83ac0a39f01b70bd420881285a9cc7b4a99fe52f1329da58561a10bb7f933c4e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 225135109888, - "fee": 0, - "recipientId": "AShwN32PRrdnpqBNruVJBba54zvBxQT1fZ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205855eb9048241c2c794ceb57f89f4cfe6c6e7db7b75819eb2d6b613ddf830f3102205e55a04f4d782a61e969ad9cfcb8926990001650282849122773fcc25efd49a8", - "id": "83093ca92b08910d1701846610d091403f0caa583c539c555c676b6a31fc62e0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 225186625152, - "fee": 0, - "recipientId": "AU8vV51b4PJZb9fWwHgVUrgz4Qq9ybsM6o", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202ceb7829288662087ca7db79218ddb0d576cbcd112fc065bc5121d2726f7195c02202deb812e71c09a4e21095b881ba24d55a7cc135cc9dd739e66b22149d669269b", - "id": "2cac15432180f5f1a0459c96a42fa93dad5626ac6f3abba1b79116c9c785734e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 225944551562, - "fee": 0, - "recipientId": "AMw99hBqtW5JzU69NFnqdHmP7hezSHEJwd", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202ecfd14378b25946c8f865df0a638300d26e6f82c4c557e47acc3ae5fdee98590220047e32bd8b1cefe6ac337acee1671d0c83b6c4966bab9de30615c36f5b78afdb", - "id": "c62a1fc478ea0e2bf3e784ed5a79e7073e62911ee9d078dbbbe888fbdb69f4ca", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 226088941627, - "fee": 0, - "recipientId": "AYijkoBCzzshgn3N89mw6tVHfFVDEoHhTj", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008a560bec818d7a518488d631663ef9db1051402d2e9f24b7e45ed008de328adb0220783be0fe7394775314a1ac063e286a47d8f0d5a03bedef6fba927a08f16991ee", - "id": "b5ee7b65892cbd18ce165ec3039e9f103163b4775c19774223c7a039706c7be1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 226432949161, - "fee": 0, - "recipientId": "AQg79cKKYsHB27WksW9k5Zj4gfCgd6y334", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201b6566d5b7fef4e562a28df76b1cf240b1ab6d8e404fceeb6a73e8eeac2c410e02206fc6d1f95cc2f73268bc8c8a16c018f1e3d8841b5d1689a0ab9a994eca88c35c", - "id": "7f3c2b6326ae39f356f638e7ae2a62c6743f9a0ef5d96bf5579d4ab633945d3e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 226920728780, - "fee": 0, - "recipientId": "ASvcE2iGk6NjtGzsCdhtyEmYTZq8vzA4ro", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d491f759be71c566db0c613b002abe362d5773c394c4c334b2be2c594339cf1202207af821eab08a548cf1ac494066c9f5c44f1e012a2f802388cda6dd1d3e929136", - "id": "d5f945780826ed328ed99545019e5a71b6758320802accc0e27063a882bc410a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 227205088343, - "fee": 0, - "recipientId": "AHAD2pRZH6sqxHbhGYjAWWBbrUryGgLXNb", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fda316ddaeb730b7d40cef2c6b67b1ab4309013e1fc2dfad9c7338cdbddd99d8022068dbecf8adbe1f3772ec3ada57f712d621c6dbc05586a7d07657f515ceaf8301", - "id": "c90e06437de6b21fefbc7ad2740019ed8a21d3d2f8cf4dec41c9ca50fecf9878", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 227326935581, - "fee": 0, - "recipientId": "AMzGgQHh5MHzFzpMV2RnP2ZEaDxh648gYr", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022100df2e8ea17c584cd5c2b98d8f482073b0283a0e08dfff592d802b136397f482ae021f3b7a55fa8f7e6cf81dc6366730081f9350c929a64c00d57b278e8e927a6639", - "id": "4ff0f93c6049358eabbc1fc17d2085b198fb2f853898c31e4e86897921bf0739", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 227395512019, - "fee": 0, - "recipientId": "AadNd7r4Sxm8nRqRXauh8e93JieVxHr6SE", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100cb986908cda1d4cde6fc3d3d1d677cd884b44cae1f8baf1ff29c60ce9ec230f302206c17455c3a4a0cbac75aaf7827e3a2b6e04904114b580e6b2e34e1830824afe0", - "id": "8198e7da0ccb9bdddc19850d2b12b7f142e5bae867e699865c6e07f380249de3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 228227511241, - "fee": 0, - "recipientId": "ASyPsMFeWujywouFojtZHAmk8MhB3ZYMyr", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008f58884d3e390ffce7e7dd713c9f3c0522a03f995ab5e78310ad81e490dcb80c02206ef0c5569957702d9260aa8b1ddfe7460737fbae69f7685cad4615e497b027e0", - "id": "76cb4cb4da799f5652caa816f58da0851a83281f7412938263b9d93535026bff", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 229694826743, - "fee": 0, - "recipientId": "AQejgdtXnkygMaN4iYGsceURNvrnGLN96D", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022043a8989908833bb50b5a74aa77ba1172f4126ba24fcfbb7502a8b3adbf7f9bf602205227d5352082b42dc8ff3a6971d5c04cae58f7c84f44b9804a42d7d424e076fd", - "id": "5f4e06198e65476fd625fe07b5876e9e9fc27cec66fe4e48faef7c89bd79fd57", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 231352203905, - "fee": 0, - "recipientId": "ALr1QRnTAnsQXCKVoc5nHjA78uVSDNGArL", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202b798a36b794fa8ec3a75ad0edea4d6376cd39df6c0d263025c4b09b606acad80220371266d010a2cfd2a22e5e46322647528cca9eec61f6e17aedbb64ee19854b3a", - "id": "cefa0126ac7ae644b539f9004f2cd71b5e4520af416d93e4541c5ca8a84f75ce", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 232283790318, - "fee": 0, - "recipientId": "AeZPqVdexqu7VGES4UMMGdnySdKTRapfPi", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022015972edfca96fef8811354524dad92eb10b6f891d80fd0daed0b692e60f65b2b022052ca9bcd9a6963826ca5ed308c0268c94a0136d236245c522859091d405d9599", - "id": "e36e0129a20398b9ec6d8190e2ef349e4e3ae61e0e1a09085f153523f57bc3a8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 234568404307, - "fee": 0, - "recipientId": "ATAva6NSSHp4tfH7N9toWikSqd6YYKBBLk", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c2dd0fc577d306894f4464c70fe39c83e85c80f31003102a5ed878f6095ec21702202c64b5a075465f7c3014c9255ce0cbdf593b2158d6cdbd8e91f1b44ce9e3803d", - "id": "7d7fe67913bdd7317ac7b930a9cb90e7649f05125ebdf1e8691e4ed32a482af9", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 235000000000, - "fee": 0, - "recipientId": "ANMT9kqisqY2KKLx3VMokjLCynqMxQGUaS", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a8e13b798bd778badc34d9280e1d2ab9414c813f938384c0a86550e826cd8b8402205950252bc1efb41ff5b354dbff2ca5a8ebd5d4d815d9b5b3c39f2c787b881a48", - "id": "14b33a1754dd1dd5f243301dd176910255ab19ddaab5f6655f18790b9d2d8331", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 235931714746, - "fee": 0, - "recipientId": "ANpWLmDRAqDejcZ7GCdcKChmRGoMZCNJS6", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b99bd138ec399c08edd91e0219e9bd049ab7a80e32c813501d80442f436d2d19022056341b7bf689ddaf371c88ade20a7952815bdd784dc2ae64d30b2ad311e79e39", - "id": "6953ea52c0b42bd950b6a53eb1e0b4e6af5c13d0836a30288726a0cbbeb34f56", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 235942815916, - "fee": 0, - "recipientId": "AcqrcF2KJgjenxBxXoK5vtWo5ELqwfkbhX", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210094dd527f0c312b8ec349fa10aad1c7dfea7cd7dcc9c4c9196fc5a571c05d85cd0220595c9587b8bdefd34389e98cd78ef8b4bd9f1912700f0d3d713afbff6f5280f0", - "id": "6572a91980977673ed2d3c74edea33493e87d2855e060e3ee17a015e35331159", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 237605753191, - "fee": 0, - "recipientId": "APNyAxuJpws9bQ9agQN9J1hKE2kMoBpv1c", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ec9cc4a71bdfe43a491208b81c164c1a7dba990eaa9232235a6f26eac2bac7b002202ace026d4bceaab43df36c3a7dc38d859e00337e0a278550fc11d3f7ec2455d9", - "id": "45c45d469ad237b9eb967bf033998866e4671c955498a39bcc4ff652d7366e69", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 237874783089, - "fee": 0, - "recipientId": "AUn658PgseDk5iLkcAHwEMAYy7SLz7aByk", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022010c2a04ea0859438a7c8baec0c633a993afb4f2fa74b09fd3cdc36bd2a74cc36022074a2b5210fa27262bb40d9a5d6eaafcdd7791bb62bc678c3dec55d8a0e196b2d", - "id": "5809e7da60df4b7f9c8f359c859c43fae0d319b9ba0ba7e8dc2228d96cc8f651", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 238708836916, - "fee": 0, - "recipientId": "AS62XXxC49oGLwGiaFyMXCxCamuATfHSHo", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206e893e194882b8be5aa96582595ca69b55ea0ea9a7799789d0e3a79d003ea77c022034edefdf0793575f1f2139b925e7cd1e87c831ef0e2a11f923440ccbb62aec8e", - "id": "745488ac65b21596e11eb41d380bd595a4270fb691819b5c0437e3b9b0f5f52d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 239265443070, - "fee": 0, - "recipientId": "AUdHvFwv2fF2DBpYqbnh8fakj2Wc1HFDW9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203fadb40ba73bed4b275b2dcf2d205b496404c65e896468fdb66946792fad929902201ce6b87ca0ca7013dc22177e6915c06fddabeaba1f818098b63cc0918c33c9cc", - "id": "7d94f1bdecf28119468bad192f7ed5ef12f67800246f071a312bd23e8d8f2d9e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 240950563055, - "fee": 0, - "recipientId": "ALE7xUp2tVw4XqoA9gK1d2UADbZ5XbNPv4", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f2d3dbadcc28cb3aaa43b29caa35493ed229e7feb032985420d6cdae580e8355022005ad1413bc7dde581e08d60a2faa4faabcb8cb1d4e822cbe23f47922e737d7de", - "id": "8b057bffb3bfa183445d801a220a07a2c66e7e4e1aadc440265615fec4336442", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 245331115580, - "fee": 0, - "recipientId": "ALRhEXxjx8RxjBMbFJMZfRPVKYgTeABue1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c10b2b4f807ffc5f82391479dfbe6d1e455e16f6adb0c150bc92200c8fcbd9a30220033b3a351010143a22272ca5b48d73180b209b9d9f2367fff8ccd5dd899e642c", - "id": "09dd0da5b96f36e27e7d67779d3cdf266ccc2efdbe5c9ab88c20b5082942d4b7", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 245368130406, - "fee": 0, - "recipientId": "AR8zWTBs1pw55kwS3Wq58uvhhwPjtTYNyr", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220076a552745173a93750265a34cb80633d8d613dd72565420ccabe9d56f27c44002200509f4e62d51dd15d11fada0edf71e02af8397fe5e5bad521bf28bf9acf80655", - "id": "39c6bf781edd4da283148bb6f34d1152cee2fc98cec7464932a82bf380df151c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 250593911397, - "fee": 0, - "recipientId": "AGnxrUgmVmqqRNyo8nVVnFuSwiABeiMjXp", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a01fa1cd2c20a5012c88ed1a0756a1f643a62c78fcfc4f69a7c983e76932ebd202205ecc72be31c8732feee7ed2f79ada18b52b9d773f26fda89825d5364ffb0653a", - "id": "abe6f922e8ab5509fb29fbe11356a182a5b7feb4e91d0ffabe3969708b5d221c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 253760909613, - "fee": 0, - "recipientId": "AchFpiHbXRyCxc1ZY6z638QtmJnDi7hozK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008e32159083784acaf47a4a5bc2fae2f25b42f27ccfd4d1f0bb2e6263f902ae8b0220068d23c7a19fcf30456fe8117678b6f16d14765256e034764f7be575c53579a3", - "id": "99b8b895b70466c7984edfdf0f05dc35ad4b52b3a620bed624cb11fd68a588c0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 254454616560, - "fee": 0, - "recipientId": "AXt9rWvbGupykENfpxW88mnD9zdxTDvWXQ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022071ecea689811557ce917a64653771c2660ff29f9a5a903405a74f5f7e6884a0c022034acca7a4460d555b186d371be5c90de69ee6cd2e562b874fa37323dc9b7479a", - "id": "189b47b1a4ef03306276ad9e7afa6de0a26711fbdfb2bcb6527f679ca1afc192", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 254606167851, - "fee": 0, - "recipientId": "AaPyrCLTj12R3oc3iW2mWAwFBy6iu6VbwB", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b4927d09c6bbbc5e300e8e12107822350358939d92916affee3f5bd8147bf845022052635047282fc85c9fb4f115bd03f9fdfe42636668f1da00073827ee72835b4a", - "id": "bb4f8ad248ea6a382f7b492587bd4ac14bd1f06554261b9e2d187aac784930a6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 254687439215, - "fee": 0, - "recipientId": "ASddgAZdbm4jQAWaT1q6Y2zQWRqEkJFEX9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e7ba05a49b3b569d7f55ba5dc0309db7d775c5f1b5ad068f426cecf7e6973bfd022073aa72abef5c92119acbd30f5434b066d2e9c3f68d0a8d44f61c6ac60d76d9a3", - "id": "3aed748d0979d80a807df6e530f480a05485d147925f971b26e7c7826e854fe0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 257637193659, - "fee": 0, - "recipientId": "ASsSVAcmoUukQd71zZdmXu6nXzmG3gsKVk", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100823c1f1dd6b34885aaa0e0ad4fb4ce4362343dd5a328bbf0d670261a6b90d4a802205a54410b7ec114c84c47ca4de5390e78411fb580f966a790266ef570425ee935", - "id": "00dc859d0b95f33615098b9026cecae7a86f1aa61dc2402725bf41ed589fb563", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 257700000000, - "fee": 0, - "recipientId": "AdeWwxiobp9H6WiabttYQp5H3kkNrHXQ4h", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022052cfe09b5968829e0742892f8bf957072e13528e293879aaecd0c0c5c37273b5022021eb5fb8c940be0b569c6c90921ce4a5e6e20df8662d50d94f05b03429317e66", - "id": "b55d6a965744191be648d34aed3eafea6346102c9c078ac7e6ad16b3aa9528da", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 258336704622, - "fee": 0, - "recipientId": "AZeA4DJAW5qBbSdGavdC1CikwiW5usc19G", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3043021f791bd82b7e0414daa7a8a9567d935795438cf7e23c4ce95ec0c634ddf8bea102205eda1bf6bbb5f7f374460fefca7e8001e4a37d1d2615e776c347a3094ecb88a7", - "id": "5ab82d277db94a82df64931ca7c39d4708fe488152263dd47abc95f889fea4c3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 263400000000, - "fee": 0, - "recipientId": "AQ1qa5TMsSF4RWU6fBZCQCFxcEpzmtkGEM", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204fea12280fe69879e6dcd4eb86c2590293a9647627db7709ac6848690e3d9c3602201fd4810e4209edae71a9dcbd3b58daa95ee072bff610b035a8c642770d70de4b", - "id": "0985c36709c6452d9520cc9a2742c2388949c62c811f51add27bb59e0092f144", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 263517383725, - "fee": 0, - "recipientId": "AVLiBtEcZGEyUzME7mkjwn9whygssd6iio", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210083285814a6b94481dfac21296003cc4f343d4d7c8bc7a7a0e5345d4aa48eac1902207915c6bedd8a3a10812da78de0368acae101cbe093685d18fdcddc98b76053d7", - "id": "af50dd79f9d422fcbd301e204ba6a1e27f7b52bad2ef1183ff20e434049c2ea3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 264706758253, - "fee": 0, - "recipientId": "ANTb8pDUmSQHBQK47P3JSU5pTWYDnAuGGW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204175f6fc6e5b7e7b453dc121a8af4df6dfc4c55028d11c3ddf71b9d81f4e7e0402207723e4e6a7ca838f645fbab78af16c493d384a06e70b32909fc4cf915817d5e3", - "id": "0ed931759cb9de29db6d266868b504864389c2d1cf3a81f5d4a5efa54ae82a7a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 266600000000, - "fee": 0, - "recipientId": "AYpgKvx4aBst2hD5gaRYv21FtiELyaehMa", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210095cfda172969672c538a02e9befc1343f837d4fb1f3bb9570312f03e2dbfafd602202297f4fd1f28d1c63614a75d47c4cbf3f60ec5f77eadf12769d4de7a39290277", - "id": "2ad61362f35c9510c43e14c3968ae3ab8a1f0b1ebe69dbba2b0bdb094805d55a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 266600000000, - "fee": 0, - "recipientId": "AFsy81B8AvNKkxpneNm4WaPXsXezYLRVwV", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220632892e9de2b0f3e915e2af3a869e834b065a33d239888e4d9cc86068e9a8d9202201cf798edd4f1785b50425d3cf0e85b2cf41117479e4d0d354a00908ac809d711", - "id": "2e7d5d559b6bac5a49af20ad2e745daff3651fcd782d3a681e1935c2fec8793a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 267156888910, - "fee": 0, - "recipientId": "AWxBnbH6FrttJsempdhhoNqzzdynnue2Kr", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204ba5295df2c4e3d4b1c098c7ecdedc98ec316f115399ecca37ac08606010a4bc022057819841af1ce0f3c979c9b3ef0f6de3493e21b10040dab878cf753849c25b0a", - "id": "0caf79acb11be4d8712ca28485afcee25efc113aea6eee515d490a9235608e28", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 268215057163, - "fee": 0, - "recipientId": "AKU81Sra3nx1y9FcCJYxuuHQjZ81rjHavg", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022020e417bdf510dbae5780ddc943a9b2fbdc1a79d2225a3e491a223f3e6a8fda2f022021b6e95132010bfd534af5d9404295e9ab497f6f00798ee15d7a6b5ef49257b1", - "id": "fc18ebde76c5d15ef00d628b4e987f77c4ec85d4fe24dfb56d7c3a20fd8abe27", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 269700000000, - "fee": 0, - "recipientId": "AXHDNRmJ36baawXLcS8ipDHgrunCeRN471", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220580727096e40273d96f9f2c52109eb4810c2cc10797bc59228f1abb8fb42af22022062043d9bef15d4e1239a42735bc3cccf08a15c6b1e51058d3c0ea590418e269e", - "id": "fe60d828232ea75e7df9a6008cb7b1b3ad2e5d8e72f638350f6f40420b36bec5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 271217304301, - "fee": 0, - "recipientId": "AegyGSE9AKWNiYeiBPA7p7f5MDBbsQobNw", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220587cb825e6b40631e4b8262b05b170e219c6a42c723ba1fed4f6cc6b472474120220784a7ff6e72b544cd8807dfdabb9f00f3782322bef851bba6995ff4b2b826710", - "id": "fb0dfdcec943df0624049563fc6c04fdbdfe413bbeef620e7a27ac06af71f0bf", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 273312359613, - "fee": 0, - "recipientId": "AdG4rV1nutJ2VmGfKDvH1usesnFgxdokd1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220367368621c5adcf56ee4cda123934cc5fc9ac54332b0bcaeaa0b413a0d65a71402201971cf564a643d39c915a8328da5d3cfa36901b373ad69b8a72a21345946948a", - "id": "5a71a47bab2f7cab9e01e4694cfbfb67b77c411d4488555101f187dc88ca3372", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 275823348504, - "fee": 0, - "recipientId": "AQHWx36dxxzBjq7t4HD7sCMtBMBSjCBceS", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022020167d72b49f9c4b420066171449eedbd8313fcd5384f06881d19c1648c1b4d902205d0d2bbf805276426751a1a45daf52516d058a1776f43963c583cece69fe20c6", - "id": "a5b96fda073ea900e23c4c85cee5b79f0ebead350d4353d1697874abeb377ec4", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 275919189541, - "fee": 0, - "recipientId": "AdmQcPaXYhe7cJcD9C1Ghk6BKbfS9VqFQq", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008d577572afc4ed0362d6ec5c4a5c9b31abba6d2267c51a69c7d5f7349f8760b902203e73555f377d34d71c77786defe682711866f02f4be29787552bc25e1a277082", - "id": "99e450025bb676e306e237e05dde8a6f2d49913794ed927d9699c78a5e363409", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 279247094098, - "fee": 0, - "recipientId": "AT5ANRumUi7WBhCSVs35yfkbUg186x96fe", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100967b5bfbba242e8efe50f90f6880afe77a1e065e471a7885060af61baed6736d02202dfc5b008abb3466e78cc24315b51af9058ed24e2f77eb6e57c80b3a85ce250e", - "id": "ca2358076d0c35255bc017cc7a85023f41551867e9ef28287ff6d5da2d50833e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 280000000000, - "fee": 0, - "recipientId": "AQN9znPRTre9TCbGYmriMAc8Z2m8H8xrL1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022032247fec35acb98d299336331d44cd915e19b15857c36ed9f5bbe6dca7c2d9ea0220350197b5c1a25d9e0dad1d00d223596aff07e8a0da480661a19e27342a26dee3", - "id": "fa5d6719a86996e3661842604a1448e78e5b9d6a91e6c137a4ca6af765b9ca19", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 280803102800, - "fee": 0, - "recipientId": "ANfCguzStf32kWL6HueDisbWajTw8acRWs", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022014dc24aa9c13fa450a824e24a25ffb06005807c86b04aad84c4fd502e257647f02206479aaebb822b9c1e0ebc8d28acb759c7e5b09a3eaaadd48409dcca0c7045c0c", - "id": "08fc563e818b09004b5ce2e4c7c5eed2890146f62deebcafec6d5a2e4ad7f0bd", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 280988036090, - "fee": 0, - "recipientId": "AQypxoNmusR1UsP1u69SFbjb3R9YH7mszw", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d63d05d551bd6c9610dad7ecec2332de5675540eaa9c7989a00b4622d238ded3022071a021dbd0a3e69cf9cdc1ac0d949f803cb5137e08ddf476fe606a774f6f1127", - "id": "52cb8cbb5a802ca5d4f20438a0cf60ce155421404f9b8184952571a2382745c4", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 281336687456, - "fee": 0, - "recipientId": "AZx5ahPCDgGR7tdGeZUTv6oV4vfmKvPeJs", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201f040daf2812c5bca3ca29ea83bf0d24212707eec898547a76d6f00a114d1c330220179b38aa34cde2de80c519e0ac5beb23be3e14389d5e12b530fcc8769779f9ea", - "id": "b3e6422692e6b305050f7dcc3d23c3ea9efead66f14327c7ed41f02e1471039f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 289471840817, - "fee": 0, - "recipientId": "ALApc6GgN5sAA5MdRfws9MS3PxcP14Vk3i", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220284ba45d70676f0e34c9f8401d06c0d5807a6e84d021ebb52266730491ac5c0d022014d14816d1e86ca5568ea8c78e54def350ab3817f4fefe4404362042cdd12ef6", - "id": "899123718c97ccfc2af2a5bc4b50d97012d46c2d1403c60b51d54ae30e3e7da0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 290500000000, - "fee": 0, - "recipientId": "AVd1HMGBkguKeBduZoN7JD25mVv91G3diR", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220623a9ce997e94680b7fda4412921890ddb91de2dc833c76331026df41d4bc93f0220159e4f175d888472f3eb4318344b7fbde4140cac5b43dade415445a5c848c24e", - "id": "b2fd759ed4885ab57848dcb86ccc2026f47bae0cac4fe119183550435dc21d90", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 293042430719, - "fee": 0, - "recipientId": "ATdJXNdCCBdPaD9pTzZE1uHubNd4EixaoA", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220333ccf40d7686d7ede92e901701f2e4fb65206b40bf1f71abc85815e6eecce1e02204c30a9f447bb751fa78c08ac0eea0dd9bf22950cef4a8ae85ae101970a963362", - "id": "69d303c8dbbec71c451201ea88e64455da3260bcf9eb866a784b13128ae3e6d6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 294030114327, - "fee": 0, - "recipientId": "AaobgufVyjG5QYYUCHfdD62yqfKnheoiK7", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207badea2403c148d9573e4b8551e91ff258250cc339647cfc7c09492c64d57602022058a84d0ca29a3e2a9d469bb5e31460c3fc55a968a296337dda894b1f324a3406", - "id": "e1fc93b662aa17857ec8282b16af5accb50862272ac7e804c9a599072e13a7b4", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 297800000000, - "fee": 0, - "recipientId": "AavHyFGe2JQE9ZwkWVHZeZF4otbj8q8aKp", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210092332a9a11c56d75f25b407f22b3b910d469d888b30ddeb12ab843b37f5eccb2022008048a684ee0765e703fff4452d81e85eee5060c7730ce7959e66ca4c442414d", - "id": "e908984cbe697b713493d9e3f6a8e928932c5352d5f3eb262d7840cc04e8741e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 301300000000, - "fee": 0, - "recipientId": "AMwtequWhiTWPMH7R4PUf6wzEUVoQf41sE", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220284be66d3840c7c5a748d244c17b9255e2977142e43263139e36d89e1b204d9502206d9ebc18bd3f19ce852d2b4e8371baed5853cfe7a57d550fb89332f3cebed29d", - "id": "caa7b788cd2a9c62b6f83c5e549fdfecaafd76dc531f1f29689cf3490bcbdbc2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 301947752203, - "fee": 0, - "recipientId": "ATFJPWAy75j6jXHzYPCG1JbWYMm6XvAdiK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b5fb6d53b4dd98f55f120f556a6bb569291942b574a0977ffb82009a8422d8cd02205203575ca53fc5636a40e6f931e429ff63e2bb55931177732a04a0ce0431d431", - "id": "6f0fd1a8e7236b0e2ea0353de6aace7a1a9e52b2268a2e21a7d70ba50df685b8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 302851017757, - "fee": 0, - "recipientId": "AGrNFNUrFmtbDEtGmdmcXY4PmdcGt52xtD", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207085b431cd0a8ef985dc12b3b01b7e45ad8b3c0aade162cc21054fda777114b202205df8eb5b1e36a571083b0c89af506f917d5bb80859852a0435fa7af5ecef1994", - "id": "640cabc266bc124bb7575b0d0d54826bb4298f6dcf86728552a7c85cfb9d5c42", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 304323259134, - "fee": 0, - "recipientId": "AcmxYd8QHTF89awqRBCtJFsC1aPvwfnLqx", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c4a2d7ce45f32daeefaadb4b12d0f3022f207f68019a82d76fa41fae5f50461d022015bed2ebd307241f334322ac81eacac8b517a6b4942ee9dfa866ccc85cd3c4be", - "id": "88585b0976182c15633b99af07e08efd91f2e2ade96f6bcac9a87289b7b2f7bb", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 304700000000, - "fee": 0, - "recipientId": "AcjeSyWdbJbP7Y4xXZpPuGLuNtTL1EVmKx", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022040412540fd1740a5bf25c9edee8e55b8697f4862b476d93c57b7397b5265c14e0220394c3e19b2a9ffff36ff404e4ac60a77b695cd3641bdb119a0fe2d9a74ca5b19", - "id": "09b69e99fa28ffce86e2333899a9053e7cb915d4a6eef962c9b19fce83c42229", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 308731620043, - "fee": 0, - "recipientId": "ATXdja19fpLfnjPbpuusYqtSs2xGK1yYy7", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f16422eb334f756c50c1af8e4df9897a0341dd5b222fb7e24838978006d1b0b802206eb59fb05242d6208812e4601aeb2a0a64408ac03aa42ccfd6e4d2176cab3821", - "id": "71036c6537b211efc0da3ded963361c03c47b5002a0729cb8bd94c9171514900", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 309164632390, - "fee": 0, - "recipientId": "ARftmK1C8xzd6QJk4xNvvnLUHNNHr5oWD2", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d9ae4512d715c87e98370acc74818cb15f4a3575eadbe764e15a6aa4beff9ec10220042de90d3d51992d850581e2f717c40d7e00d85a07d5418856b8b4d28a6da8ed", - "id": "aeff6d588a242455a1226b253a08412327b1936cb47d911cffc5b0e1d4e01876", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 313315057164, - "fee": 0, - "recipientId": "AVziGRo9W9A4ngqrkof2wpHyrDDeBDiKiN", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022077e882d387450d847cc5ccf18042ef7c0c9a15b9f01ed523ab2dd90f3debec66022000b0525cdb09ce49c7ffb1588002e56e20f95798e2ed979e7f34cfb7c95aea6c", - "id": "c9fc04b7d64a5f6cc60fade0d91d344ecd925187f0e2b5591cb1e0748c293508", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 315100000000, - "fee": 0, - "recipientId": "ANPQroio7mrAH6hSrETf9nhoBvhz9UfrnY", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022004011cfce82a2b867330e93ac537230402fae45ebd6c28029c20a9a179fd588e02203c1d4518c47a0f86f33d93ddd32f6f97d297c74ce4a3a22464695aa14e144311", - "id": "b50c52e231192da85a6249b53545fcc91f17e03db263ba9ba9830f6e2198a36b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 323400000000, - "fee": 0, - "recipientId": "AbnhZAGRAWZQNfj3NSwWacXCcXsoDg1UDZ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022043e245c68837fc34dbf6a6f1806a5ded6a173f97a935aed9fe532ec5df5a045402202f5a8bb2ae72c7995e2fcaf1acbb9615b2d0f3567b2bd9db01af6e02c33c1a96", - "id": "5475983134ca085d94e93c8ad7847d8ec2d124c0606e7f65dc7360582927e28b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 333412838852, - "fee": 0, - "recipientId": "AHFC64BTXc4kKdmn2jw8Tb8487uxsbK65j", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f1d1ec1e2e7af629ab53f68441a83f4107ff97e7d21ae0db068cff630a2ad887022030152a4a06f8a0d390d7957995be0a5134f1fbf58693f4ccfb4815abefd9ba45", - "id": "178b974b999420ffc3f16c4b96a2886660174655e77f83e1277d1cc139c42445", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 334419127093, - "fee": 0, - "recipientId": "AbEtCb6JAawzHj3iDF1CnEBWpjdShoRes7", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100934d8a30fa7fad31b7e59d5befa251d41a9b476f381394569b6c670388b88ea702201789741ebd7614767df9f43b73a8ebc1ff546e9747ffd22cb1c2f7060891622f", - "id": "5889c1d56044d500f6abd85ba7e02e2fd69dae5740a88a6321acbf5620f0ed6b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 338228944448, - "fee": 0, - "recipientId": "ANm2X2bmWfVavS68Wf6zmisgvyKzmsYWEk", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100dad3e59166de998a91e9439ee044e318dd82040d8c20ab971d6ba12fe5057384022048f7c14d431001b88b2ce5abecba8fec190d38a1dad0886b1213c2bfe649b96f", - "id": "3255e17ccac83b9df7d9d34bd09ae2a6b6664423c632046b5ace6267e591fa0f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 338641901001, - "fee": 0, - "recipientId": "AR9nWb2Y4rZzrsCTpHCDBsjeTB2cSqxgLr", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100842b25c4dcaa3f85e3cffcb5412650e3d16f65600c6f76b3ffda4d3064649ce802204b6e0ff006c7045ec16bc1f2ddec0c778a192bf5f65203f1c9330dbd25e0317e", - "id": "11d040dd27672f77a6dd8088f2a40c0d095d714ff505582422eb9c280f65ca7f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 339243683819, - "fee": 0, - "recipientId": "APkQyY3hE8TTfDdYFxVX9BXfAhKvgLMFFC", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008d5444e7ab774e40da05ae30917882abef70cd94d28114658515c122bd33b32c022022e8c524d76b82f9241dcb8d49759dcb8e11efdbb2bc8f41ad1340b0ace8ef3e", - "id": "05c45393976a5e5daa2ad7386d12587d3f8096e6e99875b8aad24b6b87fec4c2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 340662911557, - "fee": 0, - "recipientId": "ATynVRNrhhRBWx9xLuwzqRMatJEebrNag5", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ab90a2e21ac0cb5269f1e3f662e29d54fba5e57b867fbe8c716a2212c9c2fa06022032daff32ee5c0167d8f1716462077882e411473116cbd3a23289832ddc414a6d", - "id": "863339c27a73d2b35fb206638b23c1048f35854c4d8ef4e0d2c2c9f664a38be3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 340892990675, - "fee": 0, - "recipientId": "AdDGwzuSnwbTgS5zCn9G2tjgbRSVwtwXgq", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205c4da9c7896032a24fb33f087f28cbd4ee68a1af5f242ad4cc246ce189c57fc70220754cda9f04dddd1db8a420374a314b3398d2b20c8a13ca69490c9c48af950917", - "id": "6b0fd1ad749e8923efea2a678bd5fa503cad05c1290b85d87336a46641148a1d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 341600000000, - "fee": 0, - "recipientId": "AZXZtF8s1rtY2x7qZ4fup9iXsGdwLgCy5o", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022029cb43b5e7381c8692a5e474af506b4443735f56198d2c03d8bac38edbfc46de0220736670e57d73f4d8ee09c27ddf435b1ddbe206fde50b3cf2362115b11ea8da9f", - "id": "79bd2a6949472941f09c7872534dd18cc5cc7d55d8ce9276f0859cc872f1f56f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 342836625893, - "fee": 0, - "recipientId": "AbSRLLJkexPZCWdhznU1YnBs6UmsvAsg8R", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220615218597c85309c9eb5db6cd1d0657998553494a8ceb6140102d9d6955bcd4f02205264ce22077d58684a39bec2dd60d2b90780ebcef424fa29720244d19907dc6b", - "id": "ebce164ccef6fb06922b26611a1d4c755ac5393812f1b6e6725f5a09eacf9607", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 348484491500, - "fee": 0, - "recipientId": "AVv22GuhDy6QAq5EbWmvqPpyNK327dDKpX", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210091c2b8ace2dc7f2d4bbda72cb5d52cae4b6413f823dfb4722d7a6b78d93d07df022046b2f87bdc34fb337175fbaa95d17ecd967a2b3bf2e158759b50edc1be0ab51c", - "id": "74c1b29f70e726c862c8db61964d259aabdc5fc1e5ec4a14caae3338c474b092", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 349954995610, - "fee": 0, - "recipientId": "AZKSX4x6Wrun1sKFcm5tUMQTyEDKHSGvEt", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204db55e406f565efc50329b609813b5361fa8829413c65dfbdb81eb62d45d4dc702206eef0b82a59c4ae156d53b5174d667b2239934b2f4ce6e3a433ffcf133dfac8d", - "id": "b4f3fff5b12a05df38f253328d0212e80e1b86f9f783d1845676a395fb46b72a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 350000000000, - "fee": 0, - "recipientId": "AXUuekRSD7Z8aAqRz5oEra8tjAhn5Jvvrr", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100875b2ed22d8bc7cef1683d8aa8b5f5bf4696859e2770afc120fc5fb9fcaea1c702202771caf3c8ca619fa15f339dfe2c1106d066804689421836b19d9a5d1fdb5cd9", - "id": "15a1e1313a9a1df3686417a2eed1cae978664b8413e79fea6b38925a286b4411", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 350000000000, - "fee": 0, - "recipientId": "AWnx5rbjMA3BNCXQ2JDXw9jjtdJtqG9gvU", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220723a306d9e64fb999de916be02dd0a12c45a33da542fb93eb5be5a73a39c7df0022063a52580d99354654e80fcd43440c0df1dd932c939eb672308bfa4ea705ff901", - "id": "6a717fdc8c6b1052bc7f70a2a18ffa4bf14f78b8d252825c90424d920f13a24f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 350918258935, - "fee": 0, - "recipientId": "AGUqJi6qb2E4F51wdxxdtomHGdTgDMYhkm", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a2ed646787d44f8f362242ce96426f32fa938967c409f3d1f748b713aab0a2c9022019adfe63d28f5b634ef60f843021e42514baa766c465a45840d73bedc00001f5", - "id": "a4b4f4cb2902f4d9a0489fe35641c04bf8911b064d9cd29b80cb0a1274ed64d5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 351177075272, - "fee": 0, - "recipientId": "AMQLH7k26GetQAX3q4shwWaDooL9cDcW9F", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e6ec5c6fcc7b88f4325f2e449d139e6889e8eea625463b9cb120b8921c26a902022049986b8ca2d95d0f3b461601b3411cc7e694271a2496ce84088899242a9212d4", - "id": "6f0898653b2de3e94b56625e6d6248bfe50f2e120b0a6425a311f6a47e7a3b26", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 352101061907, - "fee": 0, - "recipientId": "AKGkMr8fTn7d5Wcu3AAyjbVM338JWubiHm", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207b22f8fc7e97f5669baeefa2e72d9d30dce95e4ece077da817c391460050de28022045ecc963840f840ebf144a32ca3f47827a3f8665ccca7653a718d273a29c6a52", - "id": "35b48f395bb80488b5b9542206cac08dc7bb6e1c4ac2f07fceeaa028a615b2df", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 353468821454, - "fee": 0, - "recipientId": "ALkHY1xQK74faXu6C3Pejk1xSuAFqCFdhz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022077fe72a93d8d27611229b8f74ec4dcdd4fce7c4c3379d44237814ed7e5b81bf00220679f8baa1992972284470f22d085907bcaf41b5cbdeaf9ae886be71187e38c0a", - "id": "ac919bd687999aa984250568b6c43e8cedd7d1a639aed32a816f8e1588cd901a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 356573668788, - "fee": 0, - "recipientId": "AaEfJQu8y267hp5fQSyJtzR4iJSor7q5xH", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f101ca42eae873277eae594351e634addb1ecd245c28fab5a3b6ad97add0800f02204a262f763608d06ae684f5147b1ccf82bc9538bd82937de72cd1d8593c9e9804", - "id": "51f08208e82c1ea12099b608bc6cb3fdec272ae383c10cc18cca09d3a6906ad9", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 357292915405, - "fee": 0, - "recipientId": "Ab7CQLYGsWUEwHRY86hEPRXaABtMRfj4vp", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022048b11cb528691c8397aa0c8b01d4824ab9ab37b2ffbfd5c93ea7632be5414abf02205d868c12d097942225f488ae41bb9a0b83fb7e12fe163eabbec26a50a5751d17", - "id": "cbb6e663289d0af21a30738d8456ad4bf347fc60052eca55937598ddcd1f8127", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 357640325222, - "fee": 0, - "recipientId": "AQzZvHDiVUfrPTs3PhNi6xXaCmWwPJ9rW3", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c6744c0afeb8b450b915b4131c6a5318073f20cc7828f31f05b5fe7a51d40413022075e0848a80f03df23205e31438c4f7fdb16aa36060e87838f5ea4098ae5e92c5", - "id": "aae37ca7a805749e82bc2ccb0f812c0c80c5731d4b0258a6a44b394985f4e213", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 359722188329, - "fee": 0, - "recipientId": "AH45YgpupuJgJaKfNqpxrbusmyxxzAsSiZ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205685e59ae6d20fe9242cf689a3a6d7741215b7d473405716b61eaa15c4ae156f02201251a4a0cb27f4f5501c5b5feb891c730a795620d7092d7906b4d853e830ffaf", - "id": "bcf73615f4b48a7ea0a5570da0b75b6edbe053808301a5d3c0465da8a1c8a992", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 361053804649, - "fee": 0, - "recipientId": "ALGxVP1rkTWWUpEZyhTvzT8YJprKADx6jA", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100850f4683c8641e83b64d7076b43922e70569769b224813ab0513c88e51470eb302200ba35068526155c1413020bf4c18f2b4b8cc32f5e16877a9e10aa32dae1907cd", - "id": "afd3ee65410f9d76132c8cecbc796bfd54a530327ba33af33dc0e9a07760c1fd", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 363315727061, - "fee": 0, - "recipientId": "AMQ8ezFU9gvYfyxxk7VETnXmK6kpt1Looc", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201689314194023cd9e64eef30f0051279da6253ab7b487de47d5ce3b81487f2830220148ffa133c7bca9cf6d1d743105be8b3912af8426d7e0309b969c2e2d6334674", - "id": "a9bcd03694c114a041220271fd5f01274c7ae365a6b0f85d89b364a104a20e29", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 364303311651, - "fee": 0, - "recipientId": "Aeg4n5zYvShKUmhuXe7CmzvEJqFBTv3jVs", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100899497a5fba8b821e22acd35d5027771d09baf69899acf626c47d63ee4ac74fe0220481eab02c6e999522954a7da743125b5162b56620a93d6132195675464f64c8d", - "id": "e7ac9b3742d019488f8d93c3418e19fa8bf556bc232ff0af88cc300e631329ca", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 364467189703, - "fee": 0, - "recipientId": "AUSKfmvgiPu3LSAfY6Kfyo4zR1VgL2twcL", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022055af734911a3bfe58f44351b3ae7c15653ea3738911cb6d9872c62471eb3716d022032d62b6716655c8a6e9109fada3a82a3b4a20809ab6c0166ee79327529e92ac0", - "id": "635946b171c00b3f9c0983e4a43582187bd2a3016349a6760732e434bdfcd697", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 365586352150, - "fee": 0, - "recipientId": "ANV7tExbU5ZgSDJGYyDtDmfg3Z8SVZ6rvf", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220493d2343b10c305a73614abd14c038561f4ae878c6d9957a171c0616f149187f022042548385875006c2cb45faaf5322f455b178d256075a007913ac11be84fd68b7", - "id": "ebba2ab5afa6f21355ca4f77d4b79e55d08b88c0b8b35afb69749ac61f0b031d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 366287950968, - "fee": 0, - "recipientId": "AcM4tvSTkSHsvjLM2MtBEkMX53ErPpFEbo", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207f9c913da5d2500b202003576ef1c2f478ee3218ac7d90ec443b94b64e96012f0220537e1b8af0d427a41400ba6008a463d00006c5f722bbc6b65e1d83d524863ec4", - "id": "a6fa7609921c11ea4658cea3ee0626f1a87d0ae21324780ce17721ed0d21f539", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 369653766955, - "fee": 0, - "recipientId": "AMfKrnGPBwckMBZff3rR4wFGfeztHUXEXk", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202e4e5c658ba2857c9b0d56b5babd7bcb848bece7b38820f4407827132032d59d0220713d1203f84e049caebf326b1eb3424b91643f407ee34494d1614ecc7b06c7dd", - "id": "ac8c772db29278a0bd50fa5e4b0a016fa8bb80b35b20bbb538ead6f53218cfff", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 373149442409, - "fee": 0, - "recipientId": "AVHXn563x7mzNDVN32MCf8Jngc7UKgGoY2", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022009b8fc1be1c3fde84bf3099e79c2356bea23ae042a0f76bb1d07b34fd4e90b410220704e5c4ced7376c4c7135004c0f07ae545ea1b5a0e72355caf0aae0150c865af", - "id": "36ab40ef3b10937488dd8593e7726d4c965a5baa8b2839f06620cd6392c146aa", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 373746668966, - "fee": 0, - "recipientId": "AUc2gugBPs87YHajno9jVS2niPspZLydtb", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d83d24ca3f90fbf5791169619436bc87c015f58140ea0c72a4c68df3996ea50c02201a061ded755126c92713e464bdcfd652cd4f7530aa1c5a56f1c56e366b388236", - "id": "f46f2c84bfb139e6bd22eaafd4b8c18a0547635dc798b91a3bc40567ddedb41a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 373774406219, - "fee": 0, - "recipientId": "AasYFcLgSztcGK66vSat1rgHSpFSxbgMML", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100dd07f53bb0e76df7d4dae83990242fb5db90a9c53c1d93855620b03eacf5d95902207957e7389be539c14ff9a17b9b0cd4418ebb14e80a74e3e56b555062e209e333", - "id": "19b48281b3104b5c29a0858d05fb08e8c324437fbeba15fdf68756842b3434e2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 374988724940, - "fee": 0, - "recipientId": "AbNopZKDikntAR9jguVZBChPeVmrp363ey", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220238b5a7da45bc180902e8b2c49d8552306a721f6a7f7f435eea329e0fb6952af022028e04e87bb64fb457a3cde60771481e71aec7fc8c2522cb05918e6677242ef67", - "id": "3e5fa869674d84582bf5a2cd3a2d18a52af64b80c188ddc9b15d6dc4b129c67a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 395360944311, - "fee": 0, - "recipientId": "Abk1pu25HhKdUVPwwkGqp1zqhYMTHEU2bR", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008e3454257b6c3f1b6bcaf812b5f3551ecaf4cf7118fca5367d4cdd4155208650022038add348b1a48125de8a37d8724e497e140b69234cff0a3923e70fc305c8d58a", - "id": "e0aec5537bfbb10983ad3268b4059a8b08fecd76a16db4a871d76e3f9d82c6a8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 396243735944, - "fee": 0, - "recipientId": "AFrHJuVb2HT4c4tWqYEvWgiY6CuymhkNFs", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ef46b5c739f79696c0b0a9a8f735cec91a0dc546accc233ff32f7e5cbf38b40902200dfdc24247a4f60f3e791fba193d9e9d16d83131184028e248a50ea4cb2a7272", - "id": "f2205ba50118bfce10259a754db70528268ee9112d16da6e2bd7dac30d06418c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 396752660012, - "fee": 0, - "recipientId": "AdWC72U5LSwghdenW8DKXWHYuULfUDrCP3", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008a55e63ad2b9b3d0baa2b6a2f80606f38d02abaac071387077ccba86f315a80c022013c555cafa7277020701df0004f2b695e34253ed7cbcd6f2a9e0e66593390577", - "id": "61c5f683b3a21404863121a1833c43e94f7f97acfc4100198f24e8dce6e5fd7a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 398860671270, - "fee": 0, - "recipientId": "AHV54m6LqZG8A1YdPKzvJdBfdoV48VzNmt", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220281ea4f34930789c6890fcae28d56ae12d1877038a112355f45a8586a7f7108a02204b0ceb0a989c686b91d84d42cbb5c8de0657c2988d9acfda7911f6fb37a4d0d4", - "id": "8aa2f2aec071acb8418bea239baeabcf9e22a4ec3059777df5f2f379f0dde30d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 399900000000, - "fee": 0, - "recipientId": "AMDpfwcmvCFW1jZYJz5Vk16pytx8zwqf4M", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202512aac371fad98ace991a2c0b3c736cb12b18da8206f5308dab02b71043c1df022031d2c0fee93eadf08de6f04abbd6795f15467d0d9264bd22c67bcaab93a40307", - "id": "9147058ff25475d0975386208f9d0d4cc8c60bbdf77737a09dde4bc168638db9", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 406030861383, - "fee": 0, - "recipientId": "Ad8LXbyPdTSYMHvcCZiQzaUtsd8VkLRdUk", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201df9dcb7dfcd79218826fc4777d0216f5020377bf2c1ab94e3818f17a03a6ec3022052324948abd06924e123c5e5042f9b388bcfd0f127b962f4450b166207f6b4d8", - "id": "7dd69f0c7424458dc39d3500fda4e8b1e5faebb079d6917f908c88192e03602c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 410054755558, - "fee": 0, - "recipientId": "AejLSizWdJowzJq3o2DZstQmyZNdqGGzJK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b53a8ca2840af4fafdfd607ba7a2673d1a3a70c4c3001cdfd03998e1d85049bb02206d11131b4410a8214be0bb9035664caa24e5ac6788ad7201442e151ca4e75b2e", - "id": "84fd6c750dbc8697bf563b042b5590d7d543e0f14b07cc3af1de3a89ceeca224", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 411430774232, - "fee": 0, - "recipientId": "AQwJBgy1TXokikH7XvqpyWtgAexhvnEX4e", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022005de47c592104b12833c0de59912e4f98001ab5e263af9d085828237f378a73f022074efe6b3260b7fc941691a426dd73e567eae101b680e360652e9c1539dc26c1e", - "id": "4594cf80dd9c58f780619f1c5b07ded414855e984bfe92f9c8b5e253703eeac4", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 414435446144, - "fee": 0, - "recipientId": "ALcuF8EWQZo6wHdhEab3SPG6NNnUhxmtrS", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100be8dacfc1c3bf51ff37c4db4df096642aee830e9c54b03da3a2cb1093150099a02206694dc3b9cfb53ef9c9af478bb5663979bcf740cedd5c36dc892ae50ac2b5c38", - "id": "3683470aee128d9e3198d1367815a49543180de9e5b6a354c6cace53386b998f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 414495122050, - "fee": 0, - "recipientId": "ASCzbyDxfQipaZCjC6VR5hbGG9YYgsaAwd", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b9aef4b9f36b7c0fefd1a5fef061047e327f54935080c118cbf913f607e42d1c02206edd5cbb8feae8309a3ea4e53ce4a86f9d91a084d453cfb51dcbff13522ce002", - "id": "198ee58a22c79eb720667aa9d17e249be4e2eb3114c7206ab0a73b7c9127ccfb", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 421404948418, - "fee": 0, - "recipientId": "AcZ8qLedqB3pqDv59QMLD5zLCMLEPsZiyA", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203294398344f0e3863dcb9709bf6bf915ff4c678a681edf48f03ed605ef990aeb0220247299f0e0a0abf1595d9801220e2be6ae9baffd4611aa62683697dbfb051f92", - "id": "83fbac69f11ce4a4d5993f8b7c60a4d1da9738f85e0d2e6905d49f41f62f22ab", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 422404168409, - "fee": 0, - "recipientId": "ALEAsaG5tcombmn4ewk6CtCZcT8jxS5LfA", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022044a875f285cb908df1025a9246529b88c88320c3d2c5b212721a67afba69304e022035b80eec3f0b523df1d8b235f9c9ad05c569e33f6ed4b7d72127ac88a8e04a51", - "id": "f01d3a9212807fcad775b20db523002d72db87387a2c0c0e6d6e43a96f76e10c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 425000000000, - "fee": 0, - "recipientId": "AaFVVK4bHWAULm3enE5jFuW8w1tGDVAtPP", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e4c2fc79977dd2c8202b0b9b710c1d345266b58a583911b8d7dab80cf6a9efa8022043b02b4273d62a6bfb357060314f977c8688fa2c9fd9655f1225d76e5f210598", - "id": "a9d807156e0201c2e6b62cbcd86df7e744c113443547394481215613463aa517", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 428842921747, - "fee": 0, - "recipientId": "ARTND7EwNVQyRRcHmxRMXD4vDxMsuvWHe2", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206d2758d81dfb99fe616979b5241ddc7054c2ba0661db8534b27f5a15a6e42f52022075af3ca1a436a580397f182ffe8dc07734eb4b2a67bda747135546f8fd3462f1", - "id": "30cc3a106ccd48d7a88c1f6d948d5701670c7541ea85d7472bc0a8e66899a9a6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 429330120346, - "fee": 0, - "recipientId": "AUnowRvHGnZnpPYWQhjnP5GRh8waH9oaoW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220396919ca6596b28199114e6bed458f8b3fcd53d1bc01b9c55a3e8c393f2694480220072f26bdc63d2ca9bd7c3c4a4ad1e246676055338077894de505da12f2b81a8d", - "id": "b673418ffcaa8a343b85cc02856e8d1aa2167c9e80228b738ac3d9487a56adf1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 429900000000, - "fee": 0, - "recipientId": "AVtEhnUNTLMG1ABGW8MxoprpQpcnjVMMs5", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a4775a3edb88c12d3117057cb71c556f460bada4d578d14d52f6f16f52dbe1e502206f0793cf3cba1bbfb17195e79343b6652414cd85a1ad47a6e76819f58a41e794", - "id": "91d608f9137abb9d4f30446786eca2f74cd9173b0cf9e47f3a917b400bea2d78", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 430758143690, - "fee": 0, - "recipientId": "AcsmQm5EH94A8bmxVhBX5azqRZ5HxSFurH", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ffcdd344a83d815b35399377593e907593848c590e4f6b690f90c8d87970f7d20220098ae996ee30c244bfbe04fea6f0940488dace06119d2af396b7d08dd925a328", - "id": "9693698248b30da4d32f3bb74a94185545a22511a32789b6e7c6a62c22300d15", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 431169218840, - "fee": 0, - "recipientId": "AaNpyjWJC1SzuYNtPd5eJrfdNGD6syTzLe", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a19b4cae750b166dc50c3e22bd12dfc5f490b58cd13c139412b61dc7acc7149502200418a034b9a2b6fa26b12276e5bba9f79a15ddf3307b51ac1d3b35316087a080", - "id": "074cbdd2b8b306c0883d1e6d0a468376c98f00274da7467af05095edb852a044", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 433300000000, - "fee": 0, - "recipientId": "AS31C6KTNhEc6P3pHgpZYg6L6xduuqvSXW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200369f8d253aed3996199457e932c7f1b95d12cfbac50abf255e04a331eb6b30302200c9643963f4b856e9ddb9572797944164f4a2991e2073ddd0a9c0853da0b969a", - "id": "bed6b1d63572f48b674a38739a4f33608fffd9267989b21144f3fa1de1f6d39f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 434358663505, - "fee": 0, - "recipientId": "AMKqjbsJKvsiRyzBwc3htV5V2sqrwkXpzK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022026566e29b8b649d199aa887ab842f5b815df66865cc04f5e1d3a26378c3a39450220284f908cca59b861fcb512612c0e66a0ddd855d4472d0fe6a96d113963dd0ed5", - "id": "73c577979ee440ffcda796ac338ecc04d7a462b69c17336ddcbf05dafeff9e9d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 441082175858, - "fee": 0, - "recipientId": "AJCDjQNpuuEN2byRdGY9xf2qRBCeASsCv9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203e7de0ac5c2dca5bb3b367f2006e33648f0b99fe5321af1cf06923f5638376e702207b223a41226368a7fbf51a26ede9ce708c86dadf563446aadc82eee78a142f29", - "id": "295bc81dc9d3e434b8b4cd76bf32878432742128e94b10f133b6f8596e4ae65e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 442296547242, - "fee": 0, - "recipientId": "AeeJpSnh6sHMH9QFnaS8iNQUxHX5kxZwa1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205a6753a13b5dba6748e93d9ff8c9e0b243916edebc82d50f26dfa4023c5a1c97022015cff0083bd455c998ba99ad3836fe8f569dea1b16e46f3cb0a1789a9015abc1", - "id": "db2bd8f694e5d5d7193469bc9af661d54ccdc1bf5f8dd1672648edabcec5585a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 444900000000, - "fee": 0, - "recipientId": "AYBuKPH9GghfWpVeoXmHheJ3hFEHHsPLL6", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022076e35e14f992269d3388839ceb60bf32ec1b02a0ef6e63ddab97fce76cebe95702203cc902cf0c383317ee84a5b6fe7ad1a5d0e507d3dfb9a5e1cb6b72bed9c2e013", - "id": "05b8f0519ee71468c7b25ee5d7e80360de95b6e2076886f3c1407f0b1b2c9f35", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 454296574143, - "fee": 0, - "recipientId": "ANdCnCPbZcMmb5DcuxKiC4Cun8XfNpk9LH", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e4072324402b907461e4bcfcf4b064dad72e9099acd171f27d208a9a018c2c4d022011b20091c75c4dc05d32e8c40b202c910a32a6fd18da1b531ddb4f5dc677a0f5", - "id": "9c35f16fe5a213937cb9d260efb89e114bc59310f3843280f6f858626257cbe0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 454410176686, - "fee": 0, - "recipientId": "ASDxEzhr4QLiKvE8gx8NyBNpNJBiY93bBN", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100be0f72e16ac306667849e550bfa53a55f77446ba1b3e85190a28c789d80e2dda022021706b1b73b64cd7d98e85c79e9787cae57efdaddf31c60e9d13c6530432d09a", - "id": "68038c71701292ed7e30371c8f58c74de6926a9eecd9833f205e85817b4880c7", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 458329154329, - "fee": 0, - "recipientId": "Af4KkTdudJhshRqyQknHmieMTzgN1baKGk", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200d98f84a03352a7404824fbf2565597e3407f554602a05db8c9e94842121de5a02201500a98f7224e8e716c2719d8981995c6a9cb0c38b456842b8b219c6034819b4", - "id": "13437129b6e18a12d3acdb01c9e113c21bdd85e2058aa56a460af7f3c8423501", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 461698156433, - "fee": 0, - "recipientId": "AJJ7HZHTZGmkLjGLBiWJ2ni47EVVmsPAcW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100eb4bc75f85eb983bd0b2a1d73ebbaf29c0163ba020b3fb85781ce3c1a97d6a49022071bb413f07e6c7b13f6f8c82dc9d023da2ef6f262883aadbaae6def1dbe5cc1d", - "id": "2e52fe4e3801a2a567ab73693da5448d5f0bfde55a2f0d6f4052075820ecae65", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 462363719366, - "fee": 0, - "recipientId": "AVsMnuEh8yCdQjAtc81NZzRsxJJDVjf9Ka", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ffd9156e78730c609974cc6a31a597d827cde890c7e5de46bc54cb10d7b1d51d02200303b539a531b513eb059a15ed6a5b08f9299e634348e3228ba323cee42d16bb", - "id": "5ce506c37e536cf8d7da0c3d2208bf27e461c5b261b9eae156808812fa14a6ee", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 462789386912, - "fee": 0, - "recipientId": "AVmGqru9A4Zpn3kd7goY1kJ3h37nAaxkN1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022039e8e2eff6ee9b7df8d20d070143f244f3a29b4c673932576e2d1d514d31d7af02202a79c76be0c59c0d27af4a7c5e45da0ac00944eaee1eb9aaffb3768eb3986095", - "id": "a3875b9ae99d76e48778e0b37392498715806214a2cfca46307c828e0d160ba5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 464492402483, - "fee": 0, - "recipientId": "Acb9QU2CSwSXNcbZARBwyqBSSsQRubqjHq", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202e6eaaf793a04b8fd064315af7d6cc5b911f86faf21346fa2a6e013bdb2191d3022038a043a4914bc834a47c6c903cddf4dba4eef84885201b9c4a637cfdd9552f55", - "id": "7f81ee0bb3fe048921ccb934a4476c15a339019cd8bd3de40685062281d9373b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 466008654301, - "fee": 0, - "recipientId": "AQ2bpZffieDKR6TFatkS3vZwDLyvDpA6Jk", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220516e15a8cd6382b7e0b93ee04ce1ceff0621dbb17ec2f79158a1dfce7d3829e902201383e9cbe11f387f87cd8e1701a0d974c61ea92f75090620065125f1b283ceaa", - "id": "838d54e1f7681e910380bc08a02aefa3bd47d347c10c9f17030cc1bbdbc9067a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 468845108203, - "fee": 0, - "recipientId": "AbBz7xmNnHkkdww8fBK7x4EcEi26V5sqr6", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009364c19fed0bfc1c4566e19fe01e83bace4233e7f7bbb25ab08971ef5c2e00500220118bc321de72db6de795781e1ccfe1c587b89362be1a8f9ff43d9ec1e2411633", - "id": "de57689682daa61b89193fc451040ae47b6335ef07f363e86bb37ff0b28f75d1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 477386564720, - "fee": 0, - "recipientId": "AT3dyR6SqoMafVWKsMvL9h3iBvsU2Q7S63", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b8e109b247b4d83739b36d32ad9e54f11979bbb54ec0629da72f65274e468d7302203b1370fce9d9e950120e102ebce751b2381d2319353e5c0313c6c84e5f24fff6", - "id": "8ec9dac6224398952f9c801261fa4a901ec3e823bc47301201c8e1d377b77bd1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 477386564720, - "fee": 0, - "recipientId": "Aeb22zZXfmhNvEjUH6H3ZT64fJCEqR62iJ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009fea8a4720368c5228f554d16026c0286bc036d49f5de51abfa2689d27e54346022061f2f0b0165159567388103419fce40a4b296079369bff483df251fcb9427764", - "id": "a47039058f275732366634483cc82c01a7ceddcfb6fe448f4e60eab614ae0e64", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 477600000000, - "fee": 0, - "recipientId": "AWhmJrkMyrJsdGjVaz2LoqAboibJFdpeKg", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202f3417cab05063c88942c5011311b5d19f7c05bbffc67e6ae090388803a8639502200a05fb48af403296455264ca2a3a3f6d4b1cc89706877be3335fc5c490c88692", - "id": "b6c19da13c34a12fb2a06d6a081b172074f07641024f3021b2105864e31faa49", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 486438883282, - "fee": 0, - "recipientId": "ANVReFpTPz83WVcVZocHwuNwJLuGW8Hg5n", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100bc6894303b0552ad18f66494029308976efe651de9f707a0187059e33106431302203f70460a4113ba5b089efc2d85e885832a349a9860bd05563c55f5d5923bbca5", - "id": "2644a2b4e0c87b2b0fb23f8da21f0c085ea8aae031436e846d45d77699ad1c28", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 486986935045, - "fee": 0, - "recipientId": "APoqq5cehPy8xdqgY5nPMFtupDK8HcCWFD", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e1ac0a3e424f949cdafbabed541a5fe658eacf781e059b22460f1ccceeac7554022050119d98a70c087621994890f55d3d8a79e889b02cc186f8be1ef04ca4ede1fc", - "id": "0bb8b3edd973b8b51a57550b49252f708528319de548f0b89a77aaf8f567a685", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 499452432600, - "fee": 0, - "recipientId": "AaVHPBJGnHGAyDsXqcXMkgnTXrP2VA8zXd", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202040b29b5ae655905a4be13aa5160fcc682c0c3df0768ef4c15142e0b6d79f45022070a5b44807bfe60f84455ad05957fdee06cf677a99279b25c33eab56b33bba80", - "id": "a8a4acb7cd42fb523baa102fa6dfe72371a2686c99d18e8f26d83cd65ce69e62", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 506413677424, - "fee": 0, - "recipientId": "AViKTbBER3QdyjPYvu6aEikJG6jyMZeBMH", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220575b7844c2c7dfe981396bdba8d577ed88738a16e4307c522077255c5db8225502206ff9da12d3b9a67eebfb1234918c19e92b1d94f75983c5ffc8b5598d0992a40d", - "id": "a424e155f169f58f922458c89352fc80a71a214a9b7f5d7edf53b833b7e9bb3c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 507369287698, - "fee": 0, - "recipientId": "AN4SVH6wMd1J2UinEszD1m6rNd2Qf67s6p", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202fc2e97188ea29acbbb5cb669a91834399df4e95258f843e5f508b2ae92bdbaa02201503b9313688be4f868f27960bd4ec9d3e26b49d09455e7261f811a8f4bb9f64", - "id": "362dce6072bbf7ddabf9cefee0b27fb43eae636f5d4a0d2f777319764ae643b9", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 509141981427, - "fee": 0, - "recipientId": "Abjr6LJqKumLBkGwWdCmqQU6ySWNTvYs83", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210088070a6fcbbe069be1a6a7b9de2ac4baf72f01078d69e8b3203bc85bc87e68e802200993087e55d13928a55f3a543cb91e780fe082d1a571da71ad6e4edd4ae63af3", - "id": "980d85c7519a5bf12e66c830e13372ce93d7918dea83f61bf88aaf57e5d44e6f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 515274387317, - "fee": 0, - "recipientId": "AKsTx2HPyBzhbNiEuUTjaBefkXsbWBmAzj", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206799aa5ca25023037fc2046c9976c29eee3253c6110d6d68da3b38a011f85ae20220498f5755684e9f2525f2080ebbec2c1306b18dbcbb1ef40d9006f17b3e12c30b", - "id": "0b85faa2155edb7516010b7b78fab8170527f6f51a144eda464f9bf148a2997f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 516873898330, - "fee": 0, - "recipientId": "AWP1xqsXMMgBDfRpvJZum4fywFLtRvT5Uz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205a98023efaa4e52f9936bfc80e4f8d4230a2c907a7723a7766a7ec0eed9992fc02202266a5cb028f371ab13c03ac11ec40a711c0473834a595da18591c2293622f15", - "id": "bbf1e033954f8086c4ba041a94635ae3ed8e0a34fdb0ecb699aa1a62edf9dac7", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 522000000000, - "fee": 0, - "recipientId": "AZydcTLh6qTuJzSkt2i7j7neaaMxN57bqL", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022049014a7b3c815b9989d7c4da1275d9381d5ea1bf94fa0197e2f1cce3093f9001022018b6744495c6da6cec8820e4d28edac409e2f4a9383ea42f918a792c89fda18d", - "id": "253a6707bd401ebd1b7d1465bf5857db4aba9e8ad438b8d97d121a7bf3a6e7c5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 522851951837, - "fee": 0, - "recipientId": "AZ1BHFwiQLgXfnbiW8poyzX44z9fg6R7Pu", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e6ea691fcf6ceb3735eeca8e83cd6be8664b9c42bd31aa0317fda910b154e65002206556f64d1821aec7395eadb7d2aae1a5a95e7a063b62ca6dcb6176d3ae8190df", - "id": "a01d46e24b46904aa9a2163d3950c53af19460ac839238d03c7304ac83b33820", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 526711619581, - "fee": 0, - "recipientId": "AUsWkvkAVgvaFhj9VTX4U96FyGFh5KbdZU", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f4e1b32ed7f1c7831444c0b2452e8d329dc9a0a439da676a5a56d0ef2b8c266902201bf1c1a13f4ecd6289b91e866e73b727ce735baa4128f0825acbd976e147ea32", - "id": "c22131de3dff92e746993d7a01636fa1ca2dd20e01d4db0708271aae6a63bb49", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 528376108643, - "fee": 0, - "recipientId": "AUuTNzGAj9F1aNpcKDJfuDzHYj2ndYLihD", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200ffbe2910b4d88d818dbc798913af9ddc106e423242640cc712e0d55c1a4a1d602206262f13fc3fd933e9f92f1455ebe280d33727501dfca60f8dc1bf85bfeb51ce0", - "id": "b487b250cc3f98368b60ec6c5fabd510e1a8483cc03bcd74d4931ef792080712", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 531321344927, - "fee": 0, - "recipientId": "ARtGz4V9e3wzW3iRtpYo4DbREDAvCwAg2k", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203776cd4346a82b61c46c2ae9fe7e7b5e412b84727183646992b4764249881c59022025e092b1d5180fb4cf23717ba0de4444e52067414da0bf474752763cdbefb8c2", - "id": "fe48867e9156b1ada766c579bce19e3d01f92164d9c265902b7a6c20159d520e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 536606958259, - "fee": 0, - "recipientId": "AWFff1CkyqJWtugHuYYE8WWzBP8w9qwuhL", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220024c4fee1e8ac337e575ed098a4ecfe070ada692085295894459b7b7a3b86c37022034f2e22c2438ebf949955ee0e865b528a781da86b942321eb3725178a2f8173c", - "id": "f1fcd6c5c6b3c83d0bd5accfcb929061d8804a863015cb094100ed09c90b0076", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 538220305472, - "fee": 0, - "recipientId": "AMF2nM6FEMBBfv7qWc9tW1TWv93dxWbXjn", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220315cf7c033bfeda43ab267511e88fbe392380aede5ab0087e7295bc4b20b0abd02202524f858f7d42cc1c5fa6866221d7463abc1b94d0185067ff0b3dd57a182984e", - "id": "8e26b02745f1f5ced11fa24895b0bd773a2db5370126c1e92235f1b123570548", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 539888138573, - "fee": 0, - "recipientId": "AUoii6QU9zwWhRJzLZMF71E6dffv7c9f1P", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022045f6e18076dffb721463d1e34eaf47a3bdd0d1d0e87d19d9e0a2ece49c9ad71f02206a0b723c4937c7861579b098763ddb8c533a7308dced9baf55d943b17e8b6237", - "id": "b56baa4d48dda93fd85fcfed035b4ee474f64469e28eede0b2369b4ffe17a542", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 540008433875, - "fee": 0, - "recipientId": "AKpuB5YvWrEzgxGqs9RSGr9oT9WQLCyxaF", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022066b1533fde6b296e7cc40d4764676bed7e9e088489e2482d9d7151f845f1c7c3022041502f6705fed4575514296bb157a9c5ad601758992acb22be436badfbb66f21", - "id": "85882091ee2b032360bfc72a9502434cda2fb938f5362225d68c4f77c3a47600", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 540816219226, - "fee": 0, - "recipientId": "AGGeFX427aMiLYXk3n6u1c4hup1X2STgdV", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220276e0d0e57371d2e5d6d9dcdcc8f9f1267bc27f640e95eb88b8024716e019743022034bd26c909f2653ca8af6298aca77609e8eb367e16f4b4507ad280beeae51699", - "id": "d966f146fa457ac9906b6b928bff9807416e8506483774c8948c0398c0481435", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 552260891955, - "fee": 0, - "recipientId": "AQrYk1AbtQ2brZ3dvsbHh8rdErYGJb68pi", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a1ad97eeb99f64d9eae5da29ec69a174058788941b7d7d43348e0e84a8d04cc902202520b1fc1ffc869ab83da821886b904d1e94193dd33210b5fa6cf38a1c9ea9bd", - "id": "ccf83a1e1d918e27052860875f0abf5e55dc14f6933c432eab13264919a60d6a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 553060575959, - "fee": 0, - "recipientId": "ARMwrHG3miRYdVZsGYmeXKQULB6GwMyyad", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200110ca9f26cf5a36a36e2b035b932b98df256209b95465a57eaaf8c2b19c05b6022062f55565484251018cd6e30fe19ae6387d5bff36836dc7b09fcfb5c350efa4c4", - "id": "f8aecfe8e66cf62d917c2c231855f9d4a7a479e918464658a98d4cf5dc03edc7", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 559276526635, - "fee": 0, - "recipientId": "AUbZ5CjroZETpDU9rmQtJdVU1ZSBHhxWNk", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200c8f7e1cf87873f2035f917f692cb58ffb2e8a5ecd68a13f25e8ad08b3309eb002201b7d7b59ee7e63221343a44e4a04642118e38acd08ca658ec01bf620040f7ec9", - "id": "d94bfd69197aa074ae9ede3c8abf9fe3a67b49bf498d3c620c364197be028b16", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 564299912400, - "fee": 0, - "recipientId": "AcMseyJzDq5Rsh2RYqJsGXYncjQinXDtvX", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a5edcdabd03e64a2e29f5bbf6427db67691f39b54ac517fe46fcf26b3515db9a022074d62771c4396e6252d56581e6413ed4b24891272bc7c8fb2a3ae01d2b7d6161", - "id": "a2f8f856798ed3ea34daac7d04f99409ceb4b58e897f8a4a8f05e1706926c64c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 566286551662, - "fee": 0, - "recipientId": "AQFkoubX26ch8tFBy7dm9yG98LLqV7cMCo", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206e638a8e03710eb44c0d7e8ac09b1b38366156bc8c46e1a0ee2f88424b86c5b40220247f979fe46dce7faff11bff26d3fd1bcd510747dc857b9cce2c354fc8d31043", - "id": "392e37377917bbe974e3c8ce837d0ecf52f41f1bbb7ec2e0056d0b09fd44620a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 567899118315, - "fee": 0, - "recipientId": "AYMj9jGadgkv3uWMpRr9f8P9poV9HPqr8c", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100937f17e1cd7f010b860f1f87e21802ee7c72e826564e9eea6b942b862e56f0ef02201673df293e24e84c2528bc70bca4ebfa5f73102beb49bbf999ec169527e2a3e7", - "id": "efb581f15c255041206ec351d3ee4f0b20792e6f99b29da27f9f588d1a5fb34a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 567899118315, - "fee": 0, - "recipientId": "AGpjXT2iG15ACjpwGGnZuZ1rcEB8WuwLGn", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b12dd8dfdfad12e59a4bd1b13e589a882674f1d9ddfd7f91286e10def66a8e9e022054bd93d1ea02976eb99f7d2b12c3df7b4d10db3cd77bc02810332c24a2e26227", - "id": "4aa30ef712b9518114abbcfbcbc962414af90b4618d22288fcc6c9b8cedf4453", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 568012720859, - "fee": 0, - "recipientId": "AGM85ysEstriQdnff6hLY96CNegLmfsTNx", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009b5a8d8225cc5c573f92f1f007c19ee1a702093e08dde891385ed3c19f00258902205e1088df5448c3a8aed0cc80a51b16db6759b80cdcfc318ad0cf70bb1eb19ca3", - "id": "32da511a73a5b2077d70a3299332790197c37351f0f6a10178cf1f777126e6f2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 568126323403, - "fee": 0, - "recipientId": "AWkSJ6mwXFC75PCU2Jq35ddXHyDAWETy8d", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100bcb4517f522f1c416d6ff3a5112dd22b15de6ac76fa7288c3e53859265b71208022046f9365a91793e947578c86fc7ff612c6f34d468dd6ea61f35b7b4467ca7f87e", - "id": "6de463003b0a10c7372a8ba2490533ae3a485d916b93986d2049980bf3771e8d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 572950085963, - "fee": 0, - "recipientId": "AXQXmHt4c1EcpxFAqkC9Cy7J1ui7FJaTUe", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210081b78d77da50f2b94713bb862662883a4e0dbe744ff6d41e14c5448dec5f99ef02203d4ec23476ed4adebfde4e7043cb0fdf6f7a07800d0bc350c4509baa698eb45a", - "id": "2521232eaf12c8a956b5b0177a86b430e4557aa782be3719e3220a6ae1ef77fc", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 584622281689, - "fee": 0, - "recipientId": "AXVz1XQf4pdPdXgyyU4VCFjsRRV3i9VrbW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220296a2e02be62e0a620e5b5b166757a449fe5c45829a0d41efad153710f94d065022075f637f41da115284df9e0a3782e73db04e044935a60a90715555949add9a470", - "id": "1f4180750e1f7c3f5c48fcb94104ab167e677eac601f7414f675c984e8dced44", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 585926998753, - "fee": 0, - "recipientId": "AeWy7BY7i384uzceaAbtxT7k7N1RkQeVK1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220296d7c9a6a71dc7d9803a3c95c67f69fc0aef05e2309dc3038611d28a712f8d5022050fdf931fddfbdfff9a36c4a554a7198c3ac011d462580f103b419b6f9a996db", - "id": "f8ac8625237e4d9d263547e716bbc276f536c7dc5612a9b102195f76744e0d78", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 587913213597, - "fee": 0, - "recipientId": "AKEyZbWJ6qKChGPXrq41cHZk4Jz8xHTqh8", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100993c7c4f1c17412bc3f44f64181821c60a5532272d1f0436aaabda139274900f022010e72f7d9343ead3cc02fba0e111674f31c2cf573994415adeab4d664acbdcbb", - "id": "8691098d97c62a3d45c08b8193b7cdd5416518973eb699d713bd826f5b978fea", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 589063195094, - "fee": 0, - "recipientId": "AeZ5u74dBxufywKh6eKBafLKBnWBX7F39G", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203f7a428270130c3cb5cc77cf307f8f87e3e99da03bd9c673805de883aff6b4f7022062a643143c9be2a68a3c49ba308a96d89920130f4e28bc688a687b05e5554ceb", - "id": "7ef826360e319242f436e15599caff7ab705747e617cbb8a2e0865b3821afe7c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 592519033621, - "fee": 0, - "recipientId": "AJQkUYcMuHxLho6Ag8yLiZjTcjhMXZ9aHB", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c2f173878f73f99e2a044fcca1fe6d6e5f116c30a8153f0ede31f3c1963b19500220081480f6aba6fe8568d84a6ecb26c70a8b6e418c60aad5386148455d9d361b0c", - "id": "af49856b1c3f6a712330fced86bbb90b577150af1568b8fc64b024eee487daa4", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 597999101241, - "fee": 0, - "recipientId": "AGoFy5eoJDS7wWbNpAwyDQbwGcWHF4iAe6", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e0a578e2efa657e551cb1ec1fc7330b08ec8aefcbf4458f720d7ece9b04b655a0220065c046cf75908b41f1d540e33450ecc4506f838818d97240d3c256562bf1daa", - "id": "50a23397ce1b9f9af4bdae64c7658e7a98125d17e803340d310535c11aef57b1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 601400000000, - "fee": 0, - "recipientId": "AYqXPht63UU1HKGMYSTgmgPoZj33zKWAGV", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201d214d26ae57304653dbf4deff3a2f4c2b5c0faa6451821a4aaf0851a66f77070220563a930f4833d36732cc2845a318e4d59cf77c2c7808eab9fa80440b6649c3c7", - "id": "545a75b3f45b8d3ceb447f8a573ad527853ea7cbfcce54c2ded8e8add84b1574", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 603323064588, - "fee": 0, - "recipientId": "APue7kzQNznGLbD361AwVKyfeqk66Gp8pb", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202105a9341411c738f541af56b48370e5c670710f26375dc77c968e3a3d0306ab02204218af14c3f11038101be19628a0d34d7be466f0dbfc41518440498e23742b57", - "id": "ca525d14c00825ad6f0b1f41b8832ab154464f55adbefcdfcaa9158f195633cd", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 604220262324, - "fee": 0, - "recipientId": "AamyoMmKy6vucKTsu13jYFnP4GeBy1RMum", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022032a24879fdefdebcb46b671a4dadf43e6f84af8b4d58646044a13d2dffc19720022052301e1eedcbb6116cc327c27ecf021e0e69345fc8b64d8864de1799356cb052", - "id": "5fc2c74fe023282f5b142ede55e47f0b218daed782c307d3f516b1707afd89ea", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 636515419627, - "fee": 0, - "recipientId": "ALPyErixj2dXaoQf2aFKR5qRWrpQNSpVzW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210088327da183772be9161d481fc69fdfeee11f629481d8b564146f45709347775e02207bdac01a99707e5fd59cfdaaaf9aff15b0171bc5c4fd2a8a97695c5adae6e49f", - "id": "783b96a592c50b102e9e73a1d69279352e842cdd8dc7b967b2728f6f15031ac1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 639468721143, - "fee": 0, - "recipientId": "AWTTo6v3d5AwpVu7Z4zMTdzGt7nStpphgS", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022046efb627b31d7f8834c4cb53547c86b346cc0a0c52b00d8bed26910909cb759e02206c6e2c5b6d5fdbe74e6a05006fcc9f2c1c0b2e3a488dc8f9baae9c1e4f9f2538", - "id": "b5be81aec8875f631918ea7e3471074c1ead97de2eb760b6367d43360f3d7917", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 649700000000, - "fee": 0, - "recipientId": "ARRLBH2goVLrow9EgBstBpS13mjmKzYwNA", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210091648b7427049df79b49484ca0a5881a3b870354a1e74c38e56b83849d49fa43022010008dc0dac24a564eb2d82d51353602ff7d7cc0b01be101aba4e6bd8a3d5bb1", - "id": "f7d43309c24a58b257df1477766aafee1d1f4a41d4ee45a38fb874fa62517e29", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 650982673120, - "fee": 0, - "recipientId": "AeUoiRMhcgcw1BozjW2yesuRNsCaq4WzAt", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e7623c82f69ca00ef2b0f988cdf38f53ef71067be47637c7db4da7f010a33ac60220429410215eaf06057c4f8c7d1da490340b0147a3d72be9ab9b1f4e136451cf98", - "id": "f3c675a4dab04c4a3f7437bf4264e97402d36f43bcfe84f5c2a874c089509cf4", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 655486679871, - "fee": 0, - "recipientId": "AP7kuQYdDVNaxFpBy1RRZCtFJxEfjyafk8", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220157e94b4569a8eb2cf78c543010cfabddffd8fddf12b800c5ae82a6a90605e95022041d4a41672b6f85bb8c2171a033906eea7043a35f377f2c1e07ae09c07906f53", - "id": "8e4a229041acf3eb033f4215adc26faf8bcdfdd1a8f351b1f97bfb96972c48ae", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 667854242368, - "fee": 0, - "recipientId": "AXyLBiVC4v1vyXUwVCZywuGPgzGE6fwjfr", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220117105ef4a93b506305144a883d16778f4d15fb5cc7cdc4624770e1e0976c1e802201ef7dfaf16ccfa96f2e408f78f7026377a65a59d1289608c47fd6c96f9df8730", - "id": "dd2a692bf311ad077ab9e0eb14d321fd4be930012b9ee7439cee939330063ce5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 668477464923, - "fee": 0, - "recipientId": "ARanutQKuQepLjbaHuTGh3yvFVzDbuoWj6", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207bf98de6ba2b128320e753ee96a3740084cdb6aaa13b3452ea9c6dd3afbdb6ec02203a9c6e40cf99cc6694a504c913a3eda844cdcd0e89b594903d27774a78b96ce5", - "id": "a428541fc5455a8e86b42088317a82ec539ec88ee98e2b7016a8aed336046fe0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 669856703512, - "fee": 0, - "recipientId": "ASBZf3gbf2VLdkaFp8rkVRGjnCm89HRfEP", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100dfa8b07f91d5ac3309d0302898299f4695480d247e75cea9c316aead4eda1332022039a19ddb10f1b4b4471a6ae3af7cc70cc9a2fc5ba9f88da5cb14e25c1cef12a1", - "id": "3a0b61cf0227f3a14b973e4d991b3c892ca9c4b40f48c6b48dc0e12a70939126", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 683962013271, - "fee": 0, - "recipientId": "AM6uMWQkzps2vJqMMMMyEuZLNa8a9HetfJ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100aed03caf6374a94b18218b1d6557cc6b24336e14a14932f1c3de017d61d969e3022040ae6f228c81d7ef90a5cd59d57844e7e712c981cfde43b4f7bf5fc590550995", - "id": "1ed84533e28f9b77cf94331c50903a74d10f648d4bb290eff722fafd5ad726b7", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 685060228654, - "fee": 0, - "recipientId": "AMwuubQrccxV551wFW5oTmKWZhvbojTizD", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204618ffb59c02a2106b27c71d14148d1932968b0c31490664911c343e96e5316c0220313e2e7f2387c05e242f162fbd94bbfaa3c991aadd853ebbe19c994095cc2464", - "id": "07c8587383bcb1fa6cc35ac3517ddbb3ccbaee82084ed71682c81a53db7b7995", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 688309516953, - "fee": 0, - "recipientId": "AS3HG6pG4cgtJBHiai6DrZfMdpUyTFPkB1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022019ddc6fe655b187a051a3d7a0575c8f3fe2b6ddaf74c69c8c6dc84a05e67d20b0220568dc2da3b1d3dbd1a712a4dc8e492500b475a08200bc70f62f73559a10d80ed", - "id": "0e1e914e5931d52145327aecf15e302d44dd38bf5c87756af8cb22a0cc1b8177", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 690823753611, - "fee": 0, - "recipientId": "AL5qEAPm6HBApbNTqVE3awEgzr65w8JZA1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e7ab0f12b99f73cdec3b34ee4b52d3987aaef73fab54b7aada17d807428cd0730220383d3191195bd2819afd54dc40bdc165c9271a201ecf57444c6ccea480800d1e", - "id": "cb4091df5629df4208f1132ad20d8beedac84714e5c73e52e8dd025a2d571278", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 690970768669, - "fee": 0, - "recipientId": "AMRtZ94wfCYmF9eAgK8345Hy9unPa1GKWE", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022058163e796f8fac61be71bd7493ca8f729067086b0a850bf233a0f719ff7a4d8f0220126c32a7a178013b1c955dafa8ffc3ff7c785a41f9ed089fe0bdd5283ee2bbe4", - "id": "711bdc5c2a1da2fe4c488397f938dfd9569779581ad321f8f1471b2bc363e195", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 703958360199, - "fee": 0, - "recipientId": "ASCegDxvnqHPGYrUUS3YoX3fMC5B6WqYGx", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fbcb790ad306e8b67dad036b7b02185dd3f40e92cde91c942ebf65976ecd98b6022033e4e5eed3dc65ed5264efff8a3f581107557fe0033fc6ef440e3a1622e4500d", - "id": "15c7116a20f1740fd4fa8c6e93c23b5149be45117d14c9c38c36684517914c32", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 706898356567, - "fee": 0, - "recipientId": "AYSpB9rSgnR9Cp9siWsdPct9dKKxbhBnnL", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022000cf165386c43ac8d18e3304b5eb7d7a58bf1eccdffdefd3f5af84fceb94846c02202cfa34b89f205b55f7a8c90ba72bdb8698ad1abc18a87dd650fd41c348592f53", - "id": "be6736d3f90b290d9761ab4976c11397d23d0300cbb09a3d24f818c850c9fe68", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 716079847081, - "fee": 0, - "recipientId": "AGBi3EnW12LZUDcyybsqxbeqLzdxzxTsEV", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220524fee405d41e04fedacc0e38c031c26ffbbb70cb273e53106382add945918430220549f961152cdbb902d342a57dff174cc6cd7d6b689d5aa49eac318311784b4a1", - "id": "a5a5a47040cb7f878d89cbd7b9e2d4da7f17b686f9f031b9f4ab8485373a467b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 726541178342, - "fee": 0, - "recipientId": "ANkCc7vjQS8g1jo5pKEvYKvrVbPTVmZxx8", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220082613e1f512c2c74044df74ccfa0018f5066c27c1027911669e6a393094f22702204cc71514d9c0c72430d6b24dfa6d8e0ddc3e0d9e9877e5a45af7b66e06c77141", - "id": "bf09ad805c4fbe75d9e1dc6d17b319edf13885f5455094ce30e44c144a496ed2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 727897828829, - "fee": 0, - "recipientId": "AeX8N5GFDN6ZBqf3u3kXNxVHBYsz2jLg8v", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200198881de2264fc3c1921b214379e16bad210f1e3d62b289ec0714e4c47f51b8022013d911c9f57820450630bcb87670ea779e7ffed6bfd700f7be55fdbebfdef0c8", - "id": "83613475e1867eb2a82ecbb92db7506a2e50c0336514c42e48dd3868d5aeb6cc", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 732204904378, - "fee": 0, - "recipientId": "AbzyK6ESfRUtaVWgiw79Qjx23QpEpBQdDY", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022065140a29fa740ed9049d50e848a48398fc0976992611867e87e7fe0afc72e13402202bfab985f83e5ea588c2a15210e1f6751b263eae649c2eccaddffc07746a0a69", - "id": "03dc5b6869f88c387a1e29bc05e963c99e88a3861a8e6b215ea0c87852df252b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 733825657832, - "fee": 0, - "recipientId": "AX2fhE4ybwdvcWwnJKpcwsU2sHZAQqF9h6", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022014e54a8d9f603cd2ffb1b589b11e26c1f74d0aa0c3c457b67fdf614ba46d1b1802200ecc6519cfb098463a51a3a4c8791d8cdfd7d0ba1a7841402c1c61c37df556a0", - "id": "57a89b3732488bdcab397c8c52e9cf56cfc18d316659388d49bd59b9b104be11", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 734634240646, - "fee": 0, - "recipientId": "AJdkWn2xq9mfJ1XbsvMmGWgzg1qXZcpaVr", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022020e7d6b80e23a91b7ac3cf255416b0cd1ee4b8c99e7905f3f074e0389d41658002206e2056d8cd76a1017caf5657c0b2028f85e9769b8dffc3b55667f34e00b10187", - "id": "a6c0f4e9a9df5bd241fbddad25bb116624637bfc4aa4938c2167894d3b422d31", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 734928270761, - "fee": 0, - "recipientId": "AKBTUeWQRdFCE3Cs2tKVXdSSxFnm5m4dZL", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022056a156e3715c7e280dc5ada73fec5140c0d7d58a36a9d5c2d191e141558cf22b02206f1a3b08eb3f4ac221438eb716232c205e5574753ddfe10c215dfab5961af2b4", - "id": "3fee18fd82e1b26fff178afc44338454f947dd5cbfcfb9b26e95786d7a852a36", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 734928270761, - "fee": 0, - "recipientId": "AYcACtdVz7kyrUu1RyfyYmnSxd4TKYCiAH", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009173fbf35ca5887ba7e479349557a88564c45c0f9a2c84555ae04839fc96124d02206c2654536f9ff7f3192f2aa9ef23e612f4488263d77c342b81d0ff9638b59f93", - "id": "50743bc18dbf1b0b06b0b85da7831be155da905b66cb4c55061b2c87329b6857", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 734928270761, - "fee": 0, - "recipientId": "AJPBdGiVCiYb2Zo4ZWs4wQwGpiJxuPT6uC", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022001bc153ee897c9a8088bd7d83db9b0beba950a777c79a3e19168a280c9a58929022028538f8aa4e9932b2a779622b99bdfedc92e16cc05aca8e835ed647a41419872", - "id": "aa2748fd0d2f735f8937046030459798b03ff7ace43ab7a6858a1d63cf38965d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 735075285817, - "fee": 0, - "recipientId": "AXe51e9NEuXQPFhY6faMfWJNAru1ccTJ3a", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022008f25a62cf8b062f8264aabdbdfd46a3b7d8ac5086031e0465afb0f9e30403870220207ae7d8f21ef03284ef94bcfa9d0d370dbc4e5b795b183decdd446f89b26fea", - "id": "0dbe3c763cdab7222f45d7062cf94bdd72a5ed8895fa55b268e2bc7626198c22", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 735075285817, - "fee": 0, - "recipientId": "AHPpn51yRx8UnegXydxpXiivh9xnuyshH9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203f1447733e52b6d8529e108e9a59259656da14f448adbeccd11cdf3770afed200220236c460323b60286ee1667c51bf1d8a61e7c7ccc88c90195241db585e886ee3f", - "id": "8e61c93cec0bc73a53710fd0d35fa0d4dff90a240513d20964782de96f256a86", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 735075285818, - "fee": 0, - "recipientId": "AKST4cpT1s7nnoP9fVYvyWSEvnKLz7vT7U", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205559fddbf5dc0f93eef3713edaad47980b79f81dea309ec15dccfd4e04fb0d76022018c9a630b655ca36b9865b304ac7a256fce6282779092790079d6dc78fc4cbe3", - "id": "6ca20d3c6119bc42cf161f48f4d82c73f005d8e9e5f602df32fa5cc0bcefa9ee", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 735075285818, - "fee": 0, - "recipientId": "AGN9gWA67X1BxSdVNjDwuQrpJKr6waamAs", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100bbb6b489d4f1f55424f74280ab00615213d7c008718567eed1b849a66c9c0ce0022008129948f42b4be5837584c37bcc415d343c336d7a6988f1bc7ef69a698c188b", - "id": "031a5500249e80688c627180ecc8d3cb9cfa38c5ed42ea10d2624ecae5342fc9", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 735075285818, - "fee": 0, - "recipientId": "ATHa3HMBEGDM4BQ3VcH1rAY6FdviPyDg32", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100948cf4bd55210d34820da658b900d4d4dfc4f2b538b9f8281189abf139fec2070220749e0a1a746c346b324aa393796276ea95f449dd11058d1857bba366fd228977", - "id": "ac676439da598343cd82aeaad1f306e6d1fa15d8db51bfaa967de14572af508f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 735075285820, - "fee": 0, - "recipientId": "AdezHrqbRQdooEMbLf5HEQjStMcWtKaUrs", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a0265aa6bcc52dd3ce524eb0902b08a00139f01e8078412acb0d48021bd54100022061fd1f5fd3c0abfdbf11fe56932ed39ae9b25d468f9e9d2fe00a96b96b60e3ce", - "id": "e9d8c9795d3f32cbbd22b6811801dea2d4b99a3b5dd66013d8e1bf75a12fa573", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 743982782620, - "fee": 0, - "recipientId": "AMefnVvdW3xQzRnfy3RqzjpEjUayGp62cz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022046a419c537be06463ceef560a05950552f61b5429f7e2b4a2aa09ea2ad1d3d0f022038881350fc45a81a7c1c0ad407f258b100b87acb496b8ec6e6e62958468c55dc", - "id": "edd887ebf23a14ee72232666b61754f7835b4cfa4034f7294fc9bd9a30ac1f10", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 758597694964, - "fee": 0, - "recipientId": "Ae9YVNX8GAVUiVH4wA3PqeSMGTDTDeUfeC", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022009cc850c616124e30c7a173d679234436dacba9fe466a501b2f645f01a59944d0220042cc6acd2cc25538201006a7a1df425d3ffce08a4408b1f5fdeb73d27d7cfa6", - "id": "ae6f8253bd2b564690008ff3ada0199ae1389457eba14431897332e6588e111a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 762146976638, - "fee": 0, - "recipientId": "AdScYdTwx5YAJSZNXhFfCXGqNpUZfgUAun", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207aecd31e853d981b83f6b4381a7e2d6152afcb06e08f7b001ad88200aee9d33f022018b9af36be0290056ded2c835c80902c824826ec0955e53cea50f4f153fc62e2", - "id": "62c9ac8c0b9bc3590849da10c55d14ed79af7a11aed9c88d4820c043655d8d61", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 764781255703, - "fee": 0, - "recipientId": "AazxWnociyHVd8hBNgCxPqAepYe52psryF", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207fa864ffe01d95a14e23efbb66ea9a22ec47b0cecdb564c8842a6c0f0cceadf4022054ff2c650fbd053bf2b022422e49977f6bc4fe147834dca0198d5c87f39169b7", - "id": "3684f2c7ebac624519c3e3fa1751718e07c66bb695649cf049238506d3866e15", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 767271583336, - "fee": 0, - "recipientId": "AKBgENszA84HHwQg1eKG7t5KnU17WLUkDN", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022015ab4dce082428342f964b9372d37588cfb5be5f916c8c936eca4d7a4457ad440220632c804557c94797efb8d041f94561b3126d0ce2105f1f51f038b49ebe387a8e", - "id": "a7d10521629488ad012d27edb9083ad6dead0b3a401089fe34401af2da0a847d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 772911580976, - "fee": 0, - "recipientId": "Aai89ucFnPch8ZHFvt5NJ6qBZKACJVYTeP", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204335c3aa664c18916e6ca785fd3c89f76b790e77511df34ffdaf5094322dc0a002204506ffc0e8c85e5a68417b78c3c231ce5c48a8a1dc417f1962bf65d6a1b5da7d", - "id": "773b21c1fca3bd52438fb17f97403e5f26aeb20693c591ee9d4e9e3ffa748be1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 772911580976, - "fee": 0, - "recipientId": "AcBCaUbM8cS4sp6s1uXELKv3CESzCD5XX8", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e01f0a0d0194e905f33d5189eb1f46da9ec86cd2520af288d3a88bdb3096d54202200f1285e4b0a6b4d3036e1fb85637725532a39e4cdffd51c324af87d4d30d0a3e", - "id": "2465e6d3f6b17da590b6f53136e4af7f893b9178bdfd0f7b5cee9f7c8ef816f5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 780058983676, - "fee": 0, - "recipientId": "AcuUUQ4hUm4wfob8z2dy2fgzVjMBYBL7CE", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022015bf2469739a014eb0002e02a27cb9873058c6ce26bcc30b491dd1c2a783a285022027942002fec0c30c3f73859f03d0b22d6e6b9aa8f2b4f996fe440ba00920e643", - "id": "1efca8a1ea9b00029fc970c5680d14f2aaff245fa0757ad0f1853d2c2b2e7053", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 783225207027, - "fee": 0, - "recipientId": "Abj2DUoYZAET4WYB73sTyr6udaGA24QSaF", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207d994f0790b2279a417323e51fabe58f9406f3306b21846d986a3f7146bb2dc40220246635f1f8a5d028f72d6117a7a743410fc596e89722121f94f8643dde175495", - "id": "cafe13900519e38c9e814edf229a8a07f9f521ecedfeb8f2812d9c8a94aa7f4f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 792264143054, - "fee": 0, - "recipientId": "AH6gRrXAUiWeyi79vjBvysTKJHCny88jpo", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100bfabfef46710cdcc59a2223e554e3e7cc416890cb9d2aa3ea408724bdd11d08a02205aed7c99e38a0b4ae8991c7daf53da01ba8652434d589aab0122d7c043dff201", - "id": "26c101b6192346f37ee639f28da5b53ff81ecb7ac8802389ea6ae9cc9571fc2d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 795355926543, - "fee": 0, - "recipientId": "AL9EsuL167UcKpjH2Cco6zqiFena8LoURK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220601bcb86301d0406afb27b864ff246c6bbfb8e6668be9bdd87dde634cd44b1f4022070ecc8458fed79816df9f30790a903d99ce41bd765cfc92421cf6070c7e6961a", - "id": "b745abc6ac90e5123dd8235aa5b19cf96e2419a8b7710ba03828a33dc796fb11", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 800000000000, - "fee": 0, - "recipientId": "ALgKXQivLiRjcmchi1vaRBvZDPpYcMNv3K", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009ad6dfefc8a08f6337c0fb9283a07fca5b24dda8145dbb06644284a7f91a0aba0220730b2b1411070cc0f9cb67b09d8d4c897a2dd7fdfd49523ab3b9d4f759c9803c", - "id": "fde379bb0f8057769553fbf9c7e49b62c37f33999696b0a426d6df0f1198d7e9", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 800807608813, - "fee": 0, - "recipientId": "ASNbbDUUV537CWVyJhW4nEBaoqphsfdGoF", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205c5f5fbe87eb844f435035cee3b081a0594c30581165ab0c5ee5eede125c99b702202db7822920671f90a6bc5ef5056b6c91599f7f48b1441ce679e8aa6b0ca53e19", - "id": "0d34c831223debbc92140029644e84dab7664c4af7cb70acd1271b023df5777d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 807327846398, - "fee": 0, - "recipientId": "AaJkUNWfyrzaF8VeoujbCUB96bncRBxJwb", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204b973689c3730f93177aae4292752724a4ae4f313a98f70b8602a63d2fcd7898022061fc16b87f2e06b4f2adb56ea4e15de9ee8858b079b7783c749575c6fc8e647c", - "id": "784dabe70b09163d177db73a00dcdc56ec59620d25ea31e271fe15a479c31f35", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 817711112949, - "fee": 0, - "recipientId": "AY25aryyTvvZUjDtbG53zbpigrenCBXbEd", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e23b475b7f57825c23c18dd4adc239468a8d185f43f5fc35b815f8d9bc04d03d02205e27da5cec444f1fa6941ac1b28c6536b5c4e56c9908099aeedea3af4c8943bc", - "id": "50fd6a37dba73576473f5d47c3a08ae07e39b1c5451d50fdcf5e9d3c1469a521", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 817938318037, - "fee": 0, - "recipientId": "AGTFXFtkqYmcG6wZowdinGwb9K56rWbSjH", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c8908d3537c932ca3d4de3b28d09da5561604463bd531024a992be58de1802ae02202b07302aeb41d0a3fe01a7a519a0b19e14d726918dac560e79d575e5c68412f9", - "id": "9352eb84bca23a8932cba246fca96482c36b3c55cebf9545ab3260968c223b04", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 828092442164, - "fee": 0, - "recipientId": "AHNQc1eUKgSJWr7BiopwP3fCLm72NRGFnu", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022078d3cd96dfe78a40223df2d36967e46708c8ed21dd1e098e5994c9832b2bef1602200ac6d2c0ba0763740046aae684d542a3332ceaa98cd2d62d0217a75c57411e54", - "id": "190407bed322d0dc2626669ba6de2627c6ed18f86d158bdc4e3d24e4e49bbcdf", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 833532097131, - "fee": 0, - "recipientId": "AHSytS1gD6vMjHtcpkQ86V3tTLVbVy4UV7", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a35919ee25620b1cbf5f00d83d28329563805282f1de3c6a14c3f3718d5fb671022003b1c6755cc0d0f7451fc3c16e41cf2b5a771c4596063a2a3458544bf927dfd4", - "id": "c36f7006aa4ada2eda35951c1d8e88194598959783880832ebfe42357baa5661", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 838975285818, - "fee": 0, - "recipientId": "Accz8foPxAgb53QZq55r2J3MHyhFJhWjyN", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d38fbd8b4e808a943dc3ed39967191c50ab52d5049bcb95f8c7896232ad9a25102204ce41e68a375a7a77d12ac92c4eb5a32a87dd2646d481b4dd6a4fd9b28e0a8f4", - "id": "677b8dd3b694d5ca4f4a2d890d99038f0d3529372ca65f21ad0669eb2a703d4b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 843238131545, - "fee": 0, - "recipientId": "AVWJBw2eQiWU9dhYYiPZk6YDKgT8zWuJpr", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100908c7959593e47247fcc045d6c5d14798668266960532130f43c8f03ee9e4e3802205da61bf5c85eaafea399d9a0f6ba0002baa6f011fc6c10d0367197768d5fc7f1", - "id": "442e380e1881f46f13924593a158c58ab704e76686258a9e1b33b645c9f1913e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 861005612452, - "fee": 0, - "recipientId": "APLNgrLNdVJUcAg8n79DRo5d8krXTS9jBP", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210082d6450fb65d0734f8c6d7d7ddab2438055b37ba420a3283b73b7dd236cc855602203663d2b76b2c2e681e78f016bf74a300587259281d73be10a8ae1841db720bbd", - "id": "53462cdbd50f84cc911007ef46be4622b31fecc18415d27f7937b5c36a9c1c38", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 867237104113, - "fee": 0, - "recipientId": "ANnnZMq2TBZhCoQkrXtsuhKYVvX7ii5RKG", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220054a3b0e8eb109670e0fb452e1e58b8b82048aaa531c4238a011ade0f3c7662d0220711ad6eeeaf8888a8774cd572606e7ba0613d737d3255367a96542b95181d5b6", - "id": "e6c1a70720897231182fbac0ff131552e938891ca01be2fcd96afdf3ce2079b1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 868945860370, - "fee": 0, - "recipientId": "AdWni6sVGmYL1iWEeVAt5erYacKrNE6CHY", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022042ef637e7595b772dc0f2c6edd1d1cdf05decd33f67e595c94abc1357baab2c702204e8bd0a77224dd1bf329ead41f7d03ab79b61f3bbb4a607d9b1ec06978fe59c3", - "id": "93ea865c088bdf14d07332d702448dc31dceeed8f265334e3df8b859f06a048b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 871419919728, - "fee": 0, - "recipientId": "ALBGoFokLTX1VeswH5LRBtk3uEUitoYy5U", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022036757f788fe0baf560512809ee624ea8efa84ec50dc22f8c8d14bcf6daaae4c7022011760ffdfd5f5c283ae6561b017036027b62b70a1281bcfb7cf9fee718400800", - "id": "75dd4fc72a01bbd3b6faaf4adf4fdea8c88bb2a6708d15f124005079cb9cfc2f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 875407840383, - "fee": 0, - "recipientId": "AStpm2Vziqqgtm4Tc3xw8poVh9XUBGpode", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206fd3e896284765a4a81713111ed9bfac25e977e14b70b2db0febea67d8e14893022055d0b6b689b94312aa2f360f5930c43341499b6551f74cee2d2469527f5699e8", - "id": "85f1956ed442417404c08f274e8b70f65b139a35ce77b85bea78f9b913e4e4f6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 877995100899, - "fee": 0, - "recipientId": "AYGjRAJcBQokKnpxnEWvxsLYohpa3R22n9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220563f3bacdff499019a348d4c9feb8c965c3aa80385328d1ae7fe2d1abd7b133a022078402ff3128df4b1bd885b3abf5d79c3318d6255ef03f6aa2c4148b323569a7f", - "id": "92ab5e8f2f16a9e0b3e8a127101142184a3f2da044a47bc9ff72da0afdd5c0aa", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 879811609594, - "fee": 0, - "recipientId": "AN3odZjMnK4NY6oHHG5hKPySNbH6DvfcyA", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022076f3867eb0610cfb8c5ce5be956ac5b2c37561fdd58525db87c5c89e26af7c0002203635be4d862d33fdca979630ae2f08f43a8375f35632af2ba59b148045bf1f24", - "id": "ad3ab65ab8c782d704ebcb4f1ad69d54a225ca2e669aaaac22724b946b244508", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 881943327924, - "fee": 0, - "recipientId": "AdEnEMDqFd9FGjuTAdcLgVeSYB4Nroj5qR", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022022e4869dc0dba943de4d58bbad7c4252e5a7e29a4cc415940ec3ec947b4f427d02204dd4c32404556aa475eb6eee346ca5b408e6541d7078cb03af4c8acf72ce87b2", - "id": "7deba86a243c8bcf2c222986ba4fed01192817061e1721c1d42e55b04678c85d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 882010152950, - "fee": 0, - "recipientId": "AUNsfAkq6Pcqeew41Qb7fMMTtsjKMfLuBU", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203abb628561fafe13dcce54fb723168690a9a9e766bd4ec3a250a5b496abdfb33022017a450e3a2f31be397e2696b79535dc956c2faa59ed503ac81d57fd8c3078c23", - "id": "55dd0e380d2c6b884a719461ceb712f3c6ee0518841ba10f81f1f3c3cd044907", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 882090342981, - "fee": 0, - "recipientId": "AYxtKAvHGgKmjAyszFLeeUdrBrcx2T4HMj", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202dbbb29509d4944ae73a2957f94bc821480f99552f77b7b2576b63703832fe9902207c65af1e634a4f3f2140146658865b577d8fd0ab88563d943ac6ab9f5c2082d8", - "id": "ae02e0d07ada325ac33ee462c57bbfe4b175943bad966e7930af9b51a6a83888", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 882090342981, - "fee": 0, - "recipientId": "AQ9dsnRjod2zb1jYmQouSeqMECCjczHTe4", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204ca7df8131d2dbae7148bb7d600fd2ae9504838ae6e08a36ce5038898dface6302203016472420df3880b64e341b28ae44d9ba50a218a1be088692613fa69ab95245", - "id": "ccce88fed70924e2c19f5ce8ccde69f7c74377cbb3f698fb678dd6455cb74ae6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 895174683068, - "fee": 0, - "recipientId": "AX2ZAQGv5aZfuB7uEMrKVBJixqGjaD7QTk", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204000a219545ece7dfcabaf8d2bec29a6ac6d360046298e81f1fa847dc260bec9022004193aacae42218212effa3649334b8e5e865ca8018f4cc10a704e0bf464aac0", - "id": "fe23b603d883fcb3e0f2dcbd203a338e6402e95abd9c2d32ff36352b707ce12c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 895341745634, - "fee": 0, - "recipientId": "AKgTzN7RNMLvv4S8QzRHqvtP5Kx4KFeufC", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210086703eb4f783d915efde3bc0521c44c2c1fa7f09ef0fa0cce1b83c0567e55ea102203402af173407f63130b753f8e503acf6ab9272d4cf540ca2da5f76c5da2704a8", - "id": "e61c6ec80612d5006059f9551b9f34e928aeb6424694f773c56500bf2037e776", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 896791848697, - "fee": 0, - "recipientId": "ARyJArFNkcQUDDpQdLGL47BF4ZVXJ3y3fm", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022053fde5e97462ffe6d69adc37b4923118269fd9d858ecbca3b7ec8f9fd88e1cde022047da7a3a640d20856f1f267e2f06178d1ffefee2177e8a15b2957f24f83cfa0b", - "id": "45eed794987ba92e4d579a7aa21bf890bda28e3028a3139be7a4bae6ef232ac3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 900000000000, - "fee": 0, - "recipientId": "AKJn3FRweuCdDcNkjSGH36vXb5M8ZBjbcT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009e08602bf0177bd5ff9b95c0f173333563073c193eec6574a25b8a4c7453a15b0220778701ddbc1a30c3b0366dd7d7ad654b0066e4db8f8a884a668425c95dc57028", - "id": "5d3beece4057da03840834c3035f4b580872492de87afacbe44d540ed75453be", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 903190511125, - "fee": 0, - "recipientId": "ANN62YesPBDVEsW12iTwfwRaxhgTQGC6B8", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100cd15bb91ab56975fb578938b0ba8ec406c684015cc4a84386d93a1fd5660ab18022017b0b3c53b8d834a2a830676ccfcf346d21610f55e96c25eec771585d6993c87", - "id": "f7b3f239d399a69d954994d12753be50a09d71241516f3bc49dcc6fcdefb7d44", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 912865546892, - "fee": 0, - "recipientId": "ARuGpfJJNMi3BFFbsgS5BeHU2c5ASxcE3x", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008d232047da315e33fe38b625c3bebad7400b03cbbd0b046aa0c38e972d5843f20220261e30aa301f0f4956d1f95cf3e4ffc50f0a6d6dcb2f0175e6e589704eb88023", - "id": "e2c3a809125902671f2e0242d8cbafaed3fcbe90c659a782e9de638bca44ef44", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 913029661747, - "fee": 0, - "recipientId": "ASycZbKLnRNbYdYgek8YJQzvyNFwjcQGAt", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b27e1b308e009e6cdb6ebbe5b5ad0b81140bfb107e13ee7b044cf93d3152fd8802207b01d59ad8c5f909c37114ac86e763ad66c5398601d99fb1338e5944cd8810fb", - "id": "0a2f7813b32d7506cd8f633d7938b81c89d8aea083e830c65790ebaf4c6e7795", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 916154978619, - "fee": 0, - "recipientId": "APepu8ruATApkWtKxJhiU5CPYcFMfH5tfu", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100dba1440e8f6a7a3d4796995d180099e8abef17fff1f9d1c5d8c69cb3132cd1c10220351bb3f699b4dd023ad2ab75172a2c2f4d0854fd554ae437d11b3bd573f8aef8", - "id": "92f849292f6fc6ccb43b4f0feb73d9a875024a8aa9b32e4b4023936a71e2ce95", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 920325036170, - "fee": 0, - "recipientId": "AaDbKSFY6xA2UJgeBSE8r6n8wX65Py1feQ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ded1448f1d4b184b39b787c38e550308b2e458d19ffd23b403c8d8c836cbdce1022002d021095c60fbe111946539cbefa09e5202a7261d44df441cd1996c01e3e2d8", - "id": "879e49379ae26a5f8120f6a4535400fb01357eee8b4aae9322d51e149fb9a227", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 921784408416, - "fee": 0, - "recipientId": "AJGxTV9yTgqZWNiXifF9JM8U2vdPssLyEz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201d722c68e0a469d9bfc0a67bf0de5c63c4a969b2942c30cbab883fccff7e733e02202d9cf49d2fee94fb552e356cc09291a1a0cefd9fa5ca98af311a951433c6b3f0", - "id": "8e0a8082e102ee10405d32ba82988839770f5f8a4736b556ca64ea6b674d90a0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 922643224501, - "fee": 0, - "recipientId": "AbsrMsgKck1shqR8NwDm1ntDApWxGSZW3e", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009cd6e7355be59b5624201572983708b730e673c00b779c20273d94d4c34e9e4802202685f9d0798d3e167b787234885618a79d7f9967adc21786c7b127edaab39687", - "id": "59d8c7f34718a9845f8c670513b377e70b9f988c86007aad583f6318680be534", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 928155414454, - "fee": 0, - "recipientId": "Aaj14mdqcmAtZH7LnQqdWT3qf9BFmyR7hG", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d10065682321cd83ecf696a90d06022a557d0e6f64864be26aca6d3e7958348d02201eb4018574d93c83eb706107bf2108a5f48529782fc2b03a4c55482f49cc4ba7", - "id": "65e3b5466ee3e56a4646686a8bed5a279368eea489d49ef0e093d3c6848a8ddf", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 932790490195, - "fee": 0, - "recipientId": "AdQDEejPjoMpLg8cMDPJV7tyG2zLQmuDjg", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e668f456c6c608cae80c8c429f20cd6b38690f069c232a8d8ecb57def6986579022015f6758e04f379ff651fa51c06ae5b9f64b48203dead52a732f08d88fd5c7ac0", - "id": "f14cf4caeb5874d8bd03184939da80ee11ff146580438247ecb81af6dc116176", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 939660273449, - "fee": 0, - "recipientId": "AdGeDcDSCeYBfS2DA5Dd9VZ5SwvgmAgCz4", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100de0fa78884cbade7879b174697493b0d54e6810a8a5b1e9675b04d5a98668fe30220520492f5cf1c91d22bfe2d63edec163d25a09ab5c74338f20f3dc1ccb3a80e0e", - "id": "e11a97c65477cb5de932daf09eb0f377e14cb233813ddb680ffc030661dcd44b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 940453697923, - "fee": 0, - "recipientId": "AbfshU5wgXcrhfWNDjrkrvN52y3EScpg5V", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206cc11c0bf89c528f9efc84688be77e19339a847328790b7cdd407bfbbebfcdf8022057b0752aab9c9592f2387078df66d2ac5e40e49928df72a53b769b942cc40c1b", - "id": "1442d74ed4130eb43a84c53baa8ae6db3fc088d2ac900423f8b69953aa61a84b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 944039590123, - "fee": 0, - "recipientId": "AKj53MkBzDfkDf1SLXyMf5DnkC7Ra9cqug", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201edebd2222f9e616ed293c9c55f35c7cdfd6f0b4e739a588d912dc9761fe4dba02205b7b844d19d075b195a5cd94799d40c3292ca05f0b3bfdb4736739b7869e9d73", - "id": "8f981304ad1db95e27e2fca8bee4e51a421d0c8a406921d2e8aea3318e45fe9f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 944903185065, - "fee": 0, - "recipientId": "AUTtCwMqXuWDskRBVkdvDjCdMPz21Qqn1B", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220455ff666f653f5e990e60a35c440270b625b844ac3154e4d1a959e490fa11a1502203980c454fd84512adb7659279c031f72b23438cb3d5055238b34966837337856", - "id": "1741b8faaca3c787f7abc73fb5a926f1669b4c7ad363b2ff8db9c04f084b3f07", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 954261371043, - "fee": 0, - "recipientId": "ASdMtEgrbnpJzNg8ZbcA9wec7QcvgXBio7", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202a01b72970b65264a10f17e18db74bff086e4908e01ea391baea9f67528abb4a02200a63fe887e4aff1fcbe7235e72d58a6ca6cef97e3f0d7c89f7792afdba1cd41c", - "id": "cef4106da76091c4ea826c2f1cd235a182f20634765bf8f6183a3c767fe36e55", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 956921007076, - "fee": 0, - "recipientId": "AU3A2mNv21o4SkKrPjjumxAMSx9dNSJkbM", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009fb21352f67025aa234098c53b941d99b9afd9acd26e9a66fa08209561bacba0022067f9ec9f3b46d62bb5c30915f80b0da84b9efa71e6b9f357efc7089827803c40", - "id": "6f0e865e6a5d3b5564ebcc4f2e2c0aa6618418fa561284db9780fef7bf553f5b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 964800000000, - "fee": 0, - "recipientId": "AXUg9JM1fE7XbUPCsDeC3UxXCMv4tx8bgv", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206fc92484602f29f7b50a5ffc503c5d1a231dc0e54802d9aeb373ff327602325002204efccab14943708ca58cbf02824c6d1590dc1090bc0470bbfa7760f14fa629d8", - "id": "a059a31470b9a196a3894a864cd22eb0c92e159e776c7406f20cb92db7a54dc0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 967490707524, - "fee": 0, - "recipientId": "ASvJ5NScpJtLy2WQV6AyBtzh5FzKxP5N4H", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100873f68bcdf9688710966b018209079b9a4ebea3c7b49e281b220391537b5b6a7022033d3d9d2463907307693dcfdc80edf4b864cb92cab31bf89ccc3c260ba72b91b", - "id": "c996d17aeb1aebda108edbd8af91fae13aad80b959a5f6cd1b2f8152cf4e829b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 969700000000, - "fee": 0, - "recipientId": "AQinQgE4vAbgTXaUKCj1QabiQbpsAT8fzD", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022041619c75759c53ae76620fabf4c133b4bc2b8cf890f3c574a4ac706436a6e84e02204386f909f08ca380e03cc52330fa553bae5bc73ff9cfc5dbef030be47a4b934a", - "id": "ae59ee72e6a0f70f2a9ec115af54c17664b2515e5af10f3c66ae0ec5687fe005", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 984780889208, - "fee": 0, - "recipientId": "ATunEsg5YC1zoyYSuRap3zJyWmpzQkz9tT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f8ceeea56b0a689d42103fafd6a58cd236a14183201ede721f666309aa66769302204c345a794bd8c7aa04e3e734bbdac62cb1606cb1375ac66d4a405c9bf515c5fc", - "id": "5711b79607001f91ae6452e19d06b65a23310ffa4ad08acc8a30b24ee67bc3ca", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 993823555585, - "fee": 0, - "recipientId": "AWUKR4R5oo99dRkwRkvTvTJ6ffYBNv7zPF", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100eec0a2a2274589c7b1daa03e60382327c2a429daf422815f969a16a2cbe3bcab02201c2cc1ea66118960117cc6c00d5cbabb878e48783e37086bb7fe0e3ad3acb30a", - "id": "a71624227e6daceb049d5ae4cb83a6a6e9a04659f29e53a1fe30f4746f3dc194", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 998232238139, - "fee": 0, - "recipientId": "Ada2uLW2F4xsEVqmYhvk2y1gnjbQbeEGny", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008bcccaa6dc17a49848a90005e91d25cc5a2f3c50af365fb9e84bbd18f8cf19530220582fbdc99507556d418996f4aec523965f88c88efc5248d779526deff09b1460", - "id": "bd15a7f964c5ccfeeff073d396ccb099886e5bd562af5b66717f93dbb20e9bf5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1000000000000, - "fee": 0, - "recipientId": "AV5UwZD1wxVNcDjjXi4K136dBPjT8BUSMp", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022034080e7de43853b75340e97ad6a2823b8d08290c7050fb0b4e7be311d95067c0022035815502cfbadf9851555f9bf30b82544aacfa1c5eccac34377d86520b83d873", - "id": "494e41b53f142601472c50a49c966c2af768701a283d28dac2b09492b902f9f5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1001660153985, - "fee": 0, - "recipientId": "AKmat4frPHmBjrfwuMCk4uBRTPp2zAznfu", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203cd5409d500d5b5fbf817476f4ea709e7e09cdddcb93ebd2a1dd7cec3f46dd0f022051cb3f390cf2d0d9162d5409aded948a48fa466b25186498de1e35a0d360ea24", - "id": "6a948937670927c06e5c1358667bb2f7611dd7387a405bc429b25f43e4e56827", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1004564574086, - "fee": 0, - "recipientId": "AHnrwSwuuXKTxxL41xgqAwAjHBc7nsYCDU", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d73919bc931145f7dc02745832964a7cf2091a3540eacc25569f6fad1c954fd002202ca78633ac126f1a38818b7712572f0b17887e187dddfcfceaa4c92521b4c80e", - "id": "18f0983e59f657e62c56a4b3257d3a14cbbc405b4066f20d687852162c449a43", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1017708933348, - "fee": 0, - "recipientId": "AJnv4qX1hnuecj66hRM9mgLXfYUdEqWr8p", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022012492f457272b7d233a1324f49e7b1e04fcd80d555d91a05b1392b6559b62dcd0220530e2dab22b207a45dfeed314678a22822eb0118715ef7a87fb7bcdaf97cbb93", - "id": "5caa6ca9681dd44dc6bc566caf1289fa243e6448d9d9c5d19200800341f52dea", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1022309295002, - "fee": 0, - "recipientId": "AaZ88ShGS4izM2RAjdRb1v2XBDjeWNRiCS", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022022def44bc8637552e51371d00a3a39b5cd77cbbbf0166ad4f3431933ac94181f022055884070dc5ca41b51cfe9c8f363b03209c76b97c6dbd02476fe94397c1e4bee", - "id": "c09ea42b2ef6849ce9724fcb6e560e83c211df8c31bba0eb5853c1dbdfc2c9ff", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1024417009424, - "fee": 0, - "recipientId": "AXdzLoCsCHkLrhLGW7SbqQF7ycQMdHj5CW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008b4844b7dd8265790126f46b21ac699ac941d6b9e657ac3efc52ed7c874535e102204c3ac47d179cd180370993b8e7d2e322b584e3848b2d7a0ecb86f8f74169a08f", - "id": "3ad1bc54683cb14a70774636d880c11c2aa3a236ee3af42c524dfec3dbc7bd20", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1026165099001, - "fee": 0, - "recipientId": "Ab5PAShY5CX52trT6YmEB8Xu25t5tM5HjJ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f74a6839a13eb8a3df1b72407585ecddf0893ed4fa3ee32bc30a66f7c49c609a022051dcb39162f3aae1ba1269a4496eb62db24ed3c176e488419bf19250fef3680f", - "id": "fa7af6fc72bd13847f83a7e5b0a9c689315429725a6b6f87101f9f5210a67330", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1027972402698, - "fee": 0, - "recipientId": "AXk5qyz8GftcgVTEzUDhpfWZL52ZJMcN4G", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206a1ff97dae426570695a4585f2e9e5734c742bb8be2981a757890cf99a2d9fe402200f7e67d7241d9fbef45f4c0f51f7c86827649cb337ce8a902f242d6367b48ba7", - "id": "ace052f0c133b5875489f3a7397b48ade06a5ea9465c0860a290b3d34a5f927c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1028958385088, - "fee": 0, - "recipientId": "AK5NYn7AJdvYWy3DyESmvQb2SDf7PxRa5J", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009fb2a2c3952a7df061783e1f6acc7d7ebb1db208f242c9db13e82e0ae515eb8e022078dcba5d7c2487202d4a950b66cb3ba4e4cc8718bac248605405ada6131e617e", - "id": "e1230c88023ca1225588bd7a9dd7ddf53bfc6f93c0610c3dfdccf630f943ac09", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1029105400145, - "fee": 0, - "recipientId": "ARAkS27JzjnmAGTBPMQmKJgSwCgD6SNUDi", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e2fc6163e74ec9cb17eeda9bf171e5b4789200831d5ab73aa00356cb911f884102204a9b214977eedc6106cb9b6c416ee8a14d000e854be082764d65109f88ec2206", - "id": "6c8816c6f0b88e43ad7b4b790bcb539d7be48a61a830b9f4d32ecec9c595552d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1029105400145, - "fee": 0, - "recipientId": "Ac78t9XdQCAVc3aQVwrvB8HTUqSoDqiHAq", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100bb701ab9fe8c4f9dc7b1cefa260c8934b2bc4c2aad31fd607ded1c768526aeb902203b1b477789a7e8a69c02fca7bb5a8d348785a975e097b4e6cea3f2515d68ed82", - "id": "5005846db55b1f7f32d13b95ec2ed595dc8927902d1650fe366356fb6cdaa5fa", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1029518225860, - "fee": 0, - "recipientId": "AWPoYy3qsD94b5k2kbNuvUzZVh9SnQjBsa", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200c1463b83dac90ff2ce43bf2743c30616939b4a9a1c3dbee8ce27ab1015ef3bf02203c474948d5240127b76ea1f19ecbfff55033dcb3257faf741c0d73c0c4fbdf83", - "id": "fa84fe86327ff3ff43663f888df8c167f5567aca4f61c02157a7c4403af4f29a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1030548774634, - "fee": 0, - "recipientId": "AdPywJjNoHDnCzYua5irL8ShvUx9KSHnc5", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202199eca47200eb76742b28d1b0767359f588e9c2e6b19405a40ee32816cae9a402204d9b9980c2cf193f6cc38e6ca8796b0e192b055bec5b0c52eeb31b95da466bdd", - "id": "c65d4ec488a9d907cdbadcb865f4732ee6a0ea2edb8baeafa1e7e76c37237c2a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1031249725970, - "fee": 0, - "recipientId": "ANLRw9k91KW3snAC3NCPhhmzgg9cMgdg6j", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022052dd06e5866b27fe253f1b64dae8d3e1924bdd4666062d7e9384bf77cad2b86102201cea424f053cd156ac65ffbeb703d245b14bb2ba0575aa90d9613a7e8fe4a7c5", - "id": "5c7bcfce2963fff9eb502e79dcef563274a4c409a93334c3937c3019cbf55185", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1039396454147, - "fee": 0, - "recipientId": "AaAUZ1yWFqde5BYXbbUEWFB9FGGpQCcScK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008bf00e9e9954748def806ae413bc38629058e7c2daf5f56c34991b81a61fb7e0022015c587a5adb9e7cc11e4da7f2b6e5f1bc1e8f4f36c99a3fc15fef28390dd2c46", - "id": "7dbbdba5101c67507ff51e5375318d0aa8a9e3f25de019dd16af2fb62077d6d7", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1040719589660, - "fee": 0, - "recipientId": "ALHQ1oorGCEvSPsFNWdYPwRyk3rVvMj2B6", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204a48b4446d976bce24fe26d4e666947e59567c29d55254c4a4d986ed2e0af1cb02203147efd709c8bb850861b19c71997a5780e606889ccabddb70ea4f5beebcffeb", - "id": "b06a6b4aa2f8d71c39b5ab05f1535e521cea4d1a6cd304d56fcb02518e5d37ee", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1041975741930, - "fee": 0, - "recipientId": "AZVgPvHxJNtfVaG2YkJn7zPdFdUtk3jL53", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206c33c5318130b31313a7431a249900519d511ee8f2a43986ee37ca6d534aeca802204b833d1bd726a50e0a76edd62600031e215239c7e823c556e53aa225cf5d0691", - "id": "f9bf139b97f3dee7e627fab2bd00ad2ee7b2ca61ce259c8a9da4c0e33f8e6680", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1049727197915, - "fee": 0, - "recipientId": "AQrP3AzVXbRbps1UzCfjDFoCCnc1f19a5o", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220333ec0cb3e0cdf420ae2a89997b32607a748333fde1bd62becec1e8231b5a98d02201a424700aba7467ea4141d1d847156b83da94c26acb464cef725f4f8ab36f651", - "id": "69baefe519ef9cf9c530931b69908efef4ba290f89a014f2fe7c93f7d4f4d3da", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1078361899572, - "fee": 0, - "recipientId": "AXhwWcy8HhMYLbiWhUKnZPw28o6HfGJjaN", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008ebdc6ea8c2c50965088daffa9b2ec09f1a4548729284ba4aa2e9adf38cb82510220524ce025795ef5cfb044667870375c205818ba4da875e0c3cc4ad6283673d884", - "id": "fbcced1418f85f3aeb54a66bceb7bfee00708ba6eeaa3d5b7aa85cc841a14536", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1102465913669, - "fee": 0, - "recipientId": "ANMuAyS1SD2CfJvuZSi6RQb261gvFSJt1X", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205e2895cfc0f9708d2af9c6008451ffa63461201ccebd7037c81196198f3c25a00220151c81744a95f78670811a8b66995a0f2229be460d5dfd712a7e744f5d56b706", - "id": "9c19d49856030d283b8772771d575a16c5356413501e2acd042835873fc02cbf", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1102759943784, - "fee": 0, - "recipientId": "AVVhvtdbiqHm6zuFnUYbCQCsgfKs7GxJxS", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a5a5702c73261b34e2ebb67471524f509588fa51756b267c861b3cc8737c9b6e02204322f7c837883abeaa450b02e6c51e81c90c5a0d41196f046dbdbe0827e1de63", - "id": "734294bf0236a11b079ee873079c7c4c9f1b85a53750c0cd97fedcb5cdad0074", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1108427216593, - "fee": 0, - "recipientId": "AYnxyQgq1j5i7h7AEd1UcYVWeZhip2BPsy", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e3c2842f21cc80db48cc3a7fda70e84cf3fed43e68ec7486d2b6316bf94e85f2022040fb1c566bb45142bccea742c68cab0d9093a823c43d623ac6038062393cf171", - "id": "81ba05c7bfc196047ec8955ddb0ee07ab51176ed9884beac7e59d49e117e7bae", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1109838235948, - "fee": 0, - "recipientId": "AJvzuyNaWbYyC8UqDu7hPVBLtB4yEm8ovV", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008d0159ed2472012ee33ddf9230004b427c7f696bf22eccb67f3ef6320e657a33022000b1dab519c3bf58067af22ddb3fbd1df9144324ed404f0a3f67d7fb2f64f7af", - "id": "08c1f4dac6b650a1d2e5ca059fabd37ba23a2a8718ae034fa1759e32f0ecfcdf", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1110036076121, - "fee": 0, - "recipientId": "AGvTatnwQJR22A5dDEWXvWpfLCCFNu8tof", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205979870c79c60800f61d96ff866cc18b494945f2c805678b9d55650548562e6e02205a070cc7341571569be79255018a01cbe86a1330c1e2b02ad4aec2ab498910aa", - "id": "9541a811866acc0b84756a38bbf327a40cc96ae00eef7e20a540be4adce3ca69", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1110492080313, - "fee": 0, - "recipientId": "AGfChYyMy3ezANVDo7JBECGJxEYGeefPwV", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220298aa44e674cfaed265a12495d1ecd96299c34f8ee8beacb597ade8a5b22429c02203b640535bff8f890be8292c5ace7085658b1e71ed361a467945f1d6b97f5a223", - "id": "b1887110f49e04d53f26b0182321f2cc049877bc774784dd69a856ebae16d260", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1113211377847, - "fee": 0, - "recipientId": "AWhG1JweDmRpkT4jbojz4d8QshRZnf1AZr", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022060139759d9b0b550c2b108cf60902acd2da2cfbb0747e2782124c478fab51d1202202d51d8bd860b50a5822448e21f35eb97c39deab8cceabff01e30d7865a486fb3", - "id": "dd436734a516d0647539b60be1932d984dec023de8ec0b3d963bb48e2544da62", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1117612928727, - "fee": 0, - "recipientId": "AaTpLPFKjkyMqe1HAzsQvnvVDAPj7pyv6K", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206a305e6563c1eaca84abbe8141f6d16b053e58796933355afd0c004e4b4615f9022022de5f7a2dcb182a421cacb118d5606b3180e54397e535ead5fafb3808640ec5", - "id": "d946b6d8a8a3a305eaed80a1c5c856dba6b732d0a6f2976d2e1830168d242783", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1127012726593, - "fee": 0, - "recipientId": "AdwPm6G4tnxBBgtuB2UCX6kUt8KYv4vm4L", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201527ac126261312ad02383d5481500ac4bd030a800d2d1e8b0eb2e26d5986df90220666b7179f7e9eb56b0a91b43165247d2743083d37f61c773780314fc18d811fd", - "id": "228725e2039844ee5584f099930f5ab6c1c0185f78e69fd5d418c74abe97e512", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1133071775570, - "fee": 0, - "recipientId": "AQsoWhRqcDBKREvizPBDehMYfUMwpfoyts", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207f4c04ab56643d9175bd4c8179c2c3efc5743bb2b1149c38a182583c72b2ba1a02206fc46634fdd5548d2ae01950b9e9696ce6b880dcfc59abedd4c62c3757d0783b", - "id": "71e16485b6b1168dbedc07642c4dcd4295c7d6073b6b12d8c86afddbc392675a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1135911839174, - "fee": 0, - "recipientId": "AUw9RAfTKkMqFky8G7Q3s97cA1NMwsxsK1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d29979af23b1a9156c2a0223a3e5a76ecd62b666452dbc0931590730b0ef15bc02200eff2f5a2cb906c959ee855bf3261db9240d7ddefb5cc52bc1d70d295856ef99", - "id": "dfd87714aef9d4f11ee8a5383fd9cb8a467e3523a3206eaf99ec66d943bb41d6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1135911839174, - "fee": 0, - "recipientId": "AHkybDKEp9psTVmKPvHzqj47z56BY5UcEc", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205d422f18bd80adc6a12a4c8bf2f933fa5a49328137e696e1738f1e5ad0f743e602202522cbfbe59ca0e6d3080cf64011d7eada1505b5984553bcf353b871c2c6513d", - "id": "7500e3531f8b71b5f4b7aa57e9cfd47de4424a8b7eb5dca89e2f2b9e6f5dc34b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1136025441718, - "fee": 0, - "recipientId": "AKwY5JoLghksohAZG7oEG2JmgZuubyPGVp", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100bf6dc08b189c178a9201df3e5c32c3e42b534a09c7f676980d47d6d53335848c0220531edd5c8315583016cefb60ed96217a578c14dfcdc4d6ed703c052cc2c2adf6", - "id": "09bb287a691f3121e58b6f0d862b98e2fc1e6a703594897dada3f2775f8ad9fd", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1136025441718, - "fee": 0, - "recipientId": "AdbutZprjH2HAM17xxtqixENbzXPW9Wys5", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100df1312b79544c50df8309c5c47227587ffd9a46eacee45787cc56e37be4c0c8502206e7679edcba8ed6fe9bb634fdfc96115005803a8c12cc6292445585761069d4c", - "id": "d77a533c624889a76d7135695ab9c70217f78ffea9319af6800249ab846800f1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1136025441718, - "fee": 0, - "recipientId": "AJknkVe3o8zMyMVvhLoeoHsgMowWV2gZj6", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220090cff705808e2057c9375917aa0e29056143e9e30a4a631cf32be7e9d8f7281022001259193a883851281a9978aa198ede0dc910db7215f1da0aa40c6eb749fdbc4", - "id": "f0813945e05653ff3b2f3e0f7be0a392e5183f5805efe5fba11d23386cfa310a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1142768005049, - "fee": 0, - "recipientId": "AKjKD5TuG62qWVFPpeca7JGeg5ZSs87F2t", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008c34f0cc07ecff34844dc8b3c59859eb986e4713d2177923de88beded8a00e4302202dda4d34149b8269f5d62b28e18b3c0eff841acb41c7d19a657f673d8f2ae735", - "id": "f456730f13cabf7d2b355c690cef499f35613b3d9943769770a371d68ceda967", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1143514373646, - "fee": 0, - "recipientId": "AVzbLnDifGM3MgLLXGJokYRRaJtCTSDtJf", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e5ac125df4c653e04fcfa0ac241245873a2ab254eeaecf65b2e55a9974627da5022026cb84adf8e3f7b3b3acfe181df6cc1e4a1d64f06e9aeed4ee3dd2fc809da404", - "id": "7084d48327cb27c550dea563c70084c1b113aac2cfc8eaee8da2d2dfd231e7c4", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1166230353463, - "fee": 0, - "recipientId": "AdFkX9y3WiLxaeEsdHgTBr3fTUHSzEynGF", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100bc010d5be3aa4448bf37dd53b39cde7efd9112922ff340bd4271e6989ef0a6eb02200a155c4869414d9feb7359b3b7abe7a44dfeb329f70dba2f06679ed5f61943bc", - "id": "331e701070f52d72d30610165dfc9aa6c0d7077f7fefbf4daac202ed64563323", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1167544630860, - "fee": 0, - "recipientId": "ASDGBYEPJkRm16xDXW2uBtzegkmtDX7Fs3", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202e7deb619dddea19875e03f43270d03e73f37e48efaff365eda36e2962f676e60220697fe1276d816b0e5b2d6a55f06a0aedc12f76d6f228b07da41213d79d85f2a2", - "id": "4a2f713400914d0d3a66f565c2d1c9cc39a3f19c12543e2ec418110335a0b596", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1172864247614, - "fee": 0, - "recipientId": "AWbSK2Pwu5USnhcQxaraoybLz7XSRRM4JX", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100812581fa24ca31fb48b100b3bd5415e16727dd8be600f0f604c03408010055330220032db4b8659cadee9a1b949add6b4ac8fafaf0fca6774898848f3c417c36a180", - "id": "7dd6f8130f9d3f76512de04ba1c3473ca264e77b0613a2c8a86f3cd791fa659c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1176120457308, - "fee": 0, - "recipientId": "AaRaJMpnL5vKt7ADUsEAbVw3nqnLY6CvMg", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220379c7a758df66f5b8e7879119a902aa415fad87c14d36d7288b8565c90310773022074efd40722d365288b37f2e883b4a9c3aaa8dd211762b496649c63e477bf9e48", - "id": "df44e3d6aea679f21c528cb1e0831f1c2c1a92abf61ba046e05bfe4542b5cad2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1182001059596, - "fee": 0, - "recipientId": "ANZWuhTZmksp11sRpxy1JdT4mymjkdz2ys", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022004f1a606b87c3931b43aa9ad6c39c1b7a4425d7b9463d3fb1165ef64ef3515250220614138bfa85aa722ed98ce55a3a8445c39fdfea6add75b0d780e47f93a45d933", - "id": "fa762596e4127da262c6663483dacf38836d6efa88c818c9bef23d3c8c265cec", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1185739919799, - "fee": 0, - "recipientId": "AV7zqi8PG6BfB3Nud74eC2N3BQA3zi9zCa", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220246839d23affac82057511a02b479902a17d163a2df94b950e8cb7757436cbe402201fd4e87363021f4a3d341f8635d61d38010aba3ea51df5e1a10c9af1613db6c3", - "id": "d3aeecd07fcde727f3e8e8ba0852c7ff5b28adf9da80024cfea7c51f8d2c961d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1187780964457, - "fee": 0, - "recipientId": "ARyuySFRx29xHYMdL7TnKZv3xvBgrWRdep", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201235cf2bb5c1cf1c254fbe24d2337d87d100da46a7f39c211770ebcc937765b802205bbad34509bb0b7f86f8a2807e08be016273cec72bef1ab9bf5457939767832f", - "id": "b7eadc91dfd13958e6a36963095361b289c1c37c68f0aa3fca1ac4f648440ba5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1218554570073, - "fee": 0, - "recipientId": "AGqGgDyDQdj4stacZznPKNDRbdeQ7z4nfz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e43b353214830892288bbb6ac6da9459ccc205692fc81860f5551b4a6fe8f325022040f1567d23489b76539c272293702890658f1acb22ddaa3e43ec2c50ed293d14", - "id": "971db6562dad82beef13c4ec839c0d60866e141b03ec2d4a9d63c67e2fc46992", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1226105576744, - "fee": 0, - "recipientId": "AbumjiTo1eDMprMELVf5RnCwY4jFYxu5js", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205873b0046921b459e29f8227a7d59181a7abee5d75860c5f941c79a9618351dc0220795169efc3aa3651755c0563b623945bb5aa8908196cc2aa0d1fca2e87f4c6fc", - "id": "f22ec22f00452a8c00256018006eb2fd665b84932dff56090d95faffeb895a7f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1241085387065, - "fee": 0, - "recipientId": "AGNRsF3qaggSf4N9i9gpmMuGkHBKnLCYqS", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f6924dec0957658a213b7e04eb24a996018344513ea1a35163b4977bb1db709402205b8d978e83d7c5051c208c33617bf8ab611d63ab376fda7ab8a3ab6917ea0ac2", - "id": "9137dc5ad77a4c7b7946f24e7e150c2622c15b6d1765f3efa552a386dbec4552", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1248321295924, - "fee": 0, - "recipientId": "Ac9WFSBF9MPEjCD1f3G6vWCHtZNT53C538", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c9ff6cd56b1723f0bc7d5e7623bb66ca39e4561b79ed3f6b2e3fc541bd08787e02203b69a4d8b2837be4fc097bdbf174cc41c1b968626d125f497b106c30c6b8f5b7", - "id": "24d7adecccd21860742650572bf854e50a79d8edd7f23af74b7a41311b3d9917", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1251098136462, - "fee": 0, - "recipientId": "AZ8GhCcmNL9HGhLejRShEkbPL4fsDcB6Cw", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210087e8c65ba87f0af0fe5966e9d134ba62000972b7a4c5caba161f634141b2e07002205ec3411d77ffff2f5652d2074f622078dee8b8149b0f14b8dc779164ff03a3df", - "id": "912bb48bb857b0da7007fa875d86644c803c3acc59af672692cb0abe4fd684b3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1254056287561, - "fee": 0, - "recipientId": "ATRX4J1yKRWZwSsNyW2rEHwbgNxaj3SaDG", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009eaceaad92bedbcf6a3137ecef0dd7272072662bf6158c82ee8242dfd6a9265d022032b614fd8ddb333c1b7135197649a09e7cfd3ebee617f4b08753fe5011121330", - "id": "c9eb7cb21ffed293a6dc750757d50b459e5bb98dde6080ba44ea984bb5a3bb81", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1262124265749, - "fee": 0, - "recipientId": "APZXrDufYPZd4M6KK6mU3N9i1o5kypmeFB", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202dd40b2e9929255d731e525e3f2bc1d49dec2151eb3d65a58424d346b6e1ebb7022050c87541ba7b5da3e891df8b9148b9cc7f84d5e3c185172367b76afb8544c34f", - "id": "9c0e58750a4580a5efa8c5dab95ec4948feca82e6750647945584406b2b777c7", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1267980213012, - "fee": 0, - "recipientId": "AW5XkGBc44rDNynQgVwVSCSyUHd8dt2ap9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202fd98a801d3baf19fa8a77e2e0e5b8d684547744e26856719c37f37ed3e5af3202202b3f071b8daf7f5e57ea7ff8c4b54e46dac73204a72f2ceba6e5de7121f0de82", - "id": "b0ac53b52314830e2fecf20cac13d0e3c1c33795c55cc15fe575db1caf5e59a0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1275943681122, - "fee": 0, - "recipientId": "AekYhbhVD1qNL6NmWL1tUZTyopAjEjq1FD", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100bc37876c3e04ed282fdab28d5412486eda4952dd02d7cb625cc642409fa0262d0220263503fb14d31513ba463c6fa2bab58838daca4a19dda7604c7708002d576073", - "id": "17bf45d5a938ff3f0e910d5a75c731196d39553d66152b74cd4f8687241e3c49", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1281318617272, - "fee": 0, - "recipientId": "AY6ZLmZrpunUg3XuQZZBSXQCqhUqwdV7Pg", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022033eb26e2f3bf589d76033dbb4ab8a726bf495a26068e54782aa26f86edc83cb70220639b4a7648c43a4aae0e4d3cca922b7274aabdaf8096cc1f99aecbb93379cf70", - "id": "027298b8d2a4425c3b04df6e1200a87e504f79fa7ddf9f8e1453be427d51b5dc", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1283452028431, - "fee": 0, - "recipientId": "AZUXnt5f7UDcqCTn8GLMqrqxFumWzc6xdV", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022061a17e5dd43b0fe5b0bd9f3a10dc22a004fa2ed372e4668ab3fe162444a4a354022025f7353468432e788a5859f589e4cd840f107b908d496bce9e08a0ae8a48f81c", - "id": "fb90e727a1fb40e9f09caabc1bdf855f85ada79315a103e6201f4b05b9bc1554", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1290283529798, - "fee": 0, - "recipientId": "ASxqjAvYhLchFzgx2jwju4GsUCSQEH3AEP", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ee3204265b27ca699266a811730b567a7cc018f07e789156820f4b55bb5dc5a6022037f1b07874363ebac4373e04aa81cdacc8e462d0c8615dec4945254fd78bfdb3", - "id": "ab1293aa990a9bcf79d2c390946ee548564abe1961227cf01b6ea0e4f99caae8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1305366622447, - "fee": 0, - "recipientId": "AKoaU94wDMKcvDdon237iQ4ygpqVEP13Y3", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100bf1fcb56c3a81f457103bc035df6f52aa8f37b342db0d24b37d31ab09b345d85022033ea972e903998fd0b87d127f49638d31612c25ddbf176a8f28408da823c5382", - "id": "e33edc4c6ae458da431e7b3fa0c62bb9f04b900c071887835f9e7168cfe57076", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1307153045859, - "fee": 0, - "recipientId": "AYbyHKD2741E6HT7dM2YFnqM9mMPS2yYTd", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100eb0c6b3da5ea62ad2fc5d1d80b88627f9f88de9787c2369ad41d035fd4e984db02207b78c129b934570c69db9b52b5c47e7e922c64d9c0f6d05beb8b93507e232e3b", - "id": "b791858333e83013d9a2bc47ee3f32000e2a4b5425093c89e3615af4033bb90f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1332727985890, - "fee": 0, - "recipientId": "AMwPB8oS9vsN2mfaDVXSBZpGPx4cos5Mjt", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200ed8b29399b29160b2317c2eb075647fdff0f477844348d0c2419f6a99eabc5102205753d822e07f472849206cef2b0bd4e55f7584e793eaf40db6b1a1eb478a65b0", - "id": "393c15a74a9b38eafdb1b8bc58171ba17bfc61674792a0443abd4a4706674b0a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1353732126985, - "fee": 0, - "recipientId": "AeWDk3U68wyXzwYKrG1eFngLb1PmjEJ4NU", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f99a88f1106de48bf260252af1d7c94c0b128bf3a1293b39fa6aa3b39e855671022001c6a107ff261eaf289562ddc495ae5431f2c03eaae98e02d31d186b3891044e", - "id": "677d0d56c62618704636b51d569670848fdb4e838c1d127a643ade064730d7ae", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1363961613487, - "fee": 0, - "recipientId": "AYKGjy1QdNyw1QtuYMKEQiLeeim1PsMGse", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022072093aca8550c3ed5c93ee467e06dda194f02c5434da8b51e8ce1f425f4d6a0e02203b3969a7a176fde24aba664534284790c56aa157e3ab8a6144b2f82e14c328b1", - "id": "7f8fdbf6de9d41fca6389436ffbf660e670356a289f9b823a335e0c6f33a5fb2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1368486431867, - "fee": 0, - "recipientId": "ALqNN4gFAQ4i6keQYWt19VGVdf6srRw3fu", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203fa40db925f8076b84cb54c0442f866c882e25b67274df69d2e668d1713fb702022029b2294f08730eecb92ac2080c7f116ffd3b587ce00ff6907d0ac52b544188c3", - "id": "0ac5811bb68f5a2b9e1f9516414ae78b9b19d68c9d45abd95a83b45ee5b8245e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1373148336615, - "fee": 0, - "recipientId": "AWBBsjmyW9q9Eu6Esu738Bmhm2ZGZiwqmZ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200d6fb95c47336c8107cdda4217db3bbb5c7e6068e82d0e78c158f422d44e473b02202b2c57abf8045984d6a695a1e7396507b47c0e735a38bac8b4731217a618b922", - "id": "0d8c957621281c5dc06c45fd28fd69d0ae5bebd809f991f077d061e692470b25", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1414800000000, - "fee": 0, - "recipientId": "AYsi3kyJfxa5LvhTms3yLbVjLDcwZEuQFU", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201f2578fe3f6799f09c4e21ceb01444643676736794accb55e66065b5e2c7823d022057adec3762d37b685973d42c40d03b2c8ec414d3b4d2bb04499816845a358312", - "id": "0cf6ba6998cc228d806efa6663b4e1024aa417a15e46b5f64225dd86b2e1a2ae", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1445037440539, - "fee": 0, - "recipientId": "APNYtJ4DsTAPr7UzmPoQFsdj4GaBT4cDNw", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b55aacdbdafbf73aaa8ffdd77638cd52c2e572f68c82cce5a21182d8edef856402203605dc48ec3545efcc2ae67e9dfbc440a3e3fb89133dc2eac0969c65e9d7ea89", - "id": "a0f5649db4efa028d6eebdee0636a191c1981a80829cf6c2948c0cd3f5c14ff5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1445600000000, - "fee": 0, - "recipientId": "AZ82o4tRxNgRkjzV5GyBDkuaAgnLnUDMTx", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220713958c68f4b3f560c9592fcbda9dc2a6be93678f7e08ade6e96370c4eaa26d402202c862c934e996d1dd75dd49ed7204128b81b54b78b431076c997cf97e7747cfa", - "id": "2fac0236a0c0a9a6bcaf6401293611d1452f338213641627f8db909d47bfd8e8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1454528664622, - "fee": 0, - "recipientId": "AcCh8h1ZmQN5BeJ74rFJKE6hG9KZqbesYT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ca4227b7da265016be665600bc3e7bb20f75d7a65d72c13da8c8d9ab4ce383e2022038ff78d1c5e601365c28d9e6d2e4337a7d9d7d0dbde45c4a4023638fa07e87cd", - "id": "8ae411cae067cb9b9f15fac37ff5e9ecf9642a135de60053c3ecddc38a498f77", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1466807483534, - "fee": 0, - "recipientId": "AFqgu6rcFy6QTXGfN1FxC6sUHY2xCW7uc1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b2f227538d4b7706be16ade8e17139e739a09afe03282f64cc5c545dd1e2dafa02205597c6a4d88ced4a5f1a2773b27b256a9138310ec40c62bde619a99f6b4914f6", - "id": "2f4c8dab500b1105cc9545363586a417fd7946615170bfad8928f68b145e067c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1467651315664, - "fee": 0, - "recipientId": "AHHrxPEi2Kj5VP6W5ZKegVh49PCV5n1jYG", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e97ad561c742835e8d25dfe5e8417892e5b73a5fd29200bd36760092bca344c702202441a37b935457517e87484b64edd8b4d8343eee4e6acfb4a231faf29a079c9e", - "id": "806e0255fad866d11ce328cadcbe4002bd5a496bb152984bb09344e890d566e7", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1468250973203, - "fee": 0, - "recipientId": "AHBAMChcuEmR4GEqhyx8Kwf2uSadixGJ63", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b2484f242f0e10ff6a3c0a6ce4b32c308153788c8d844ea7b8b6f53eb2bc6013022009b277ce199b03c13cee24d7e1f0d0a519f097e783053ed8fb1e85ff174b5533", - "id": "e024d4271d53d17eee174f952a3577ce724d9f9896036a3c2cd3dfe7680b6853", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1468680421064, - "fee": 0, - "recipientId": "ANAjpvQ3YXDaQBdh3uq9UrCzpgdKbyyPec", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220329b1550fb0f30e6e506aa2a818bc28db4f5f83510cffb3e92c5237ed612e3ba02202b595447789bc432db35f5795a9f37a41dcb7c610dd1148fa46748291a08ef74", - "id": "04ca01893a22c45fc969173c7ae1d0b8f319b6ce02a52cd8439fd40bd7092452", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1468680421064, - "fee": 0, - "recipientId": "AZdWJgmHDvj77EmtJeV1WvpBP2iotiGAm1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022022abe78cf54b66aa2968b866a5f2c89b5ba498a10716b87a4f5b1b22294268b002203cc887e61beae4a9b5d1472a25fc5e9e19fa21195710159c19b433b9004fb33b", - "id": "e1a59241b4186c667e2092a767cad17bcd1e348c0e7507e57783ecaddd8b59a8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1469630945593, - "fee": 0, - "recipientId": "AJduNtdjCT13Xmn1HbRG7DA4H4g4Q6BvaV", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210090c7c64fdfd574b1a2e65c070b231e9c99a4fd26d4ab2046d985076c42fc21c90220481c1d8d1458f1dcf7adf39a52fab40a3f3d25830607ce853e20767623fa691c", - "id": "8bfc8aa67c36db1b6c8db6f65fd89687b83bbf8b45223be0984c084d2d507621", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1470003556578, - "fee": 0, - "recipientId": "Ad4QYPyJaqhXRoMKbezNvCREbK5XPa3zhy", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205188ab1d4c98d2f7c02b3825701e03b310655fbc44db5931a89432b666ffcf3f02200e1eb5e6220abf42c61477be919ab32c21626dc74dcd14a48c5d6078ac155cec", - "id": "4029404e82dedf7fa4e8df1e90238546b5fd8009d9cf6457ad8adc7504a1ac00", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1470150571634, - "fee": 0, - "recipientId": "AYF11aoSpagfi9wzfzY5PWdsYw8erLzi5N", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204973fbd8f15de9230d6a4cb6f9f3bdda3dc7e1b66abb0d5eca95ad2ab43b4d750220132d7876e371bffb26b076bcc1b68ac7b8719917b25d9f09c597ec58e37bfda4", - "id": "3112c2354cb4f918d6bab6f765a16084540663423d129abd46a7f98292f6e781", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1470150571635, - "fee": 0, - "recipientId": "Abw8geGxqiRSNtAZubYj6CM7NPeWK7VU8t", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220532893083e7e86ced90c28507bc86376998b7fe227c26d44835905dc2c4c3fe20220784051c6f98e86370580c94789326635a2737a3f1d9cbe553c9af5636e4c7a15", - "id": "508f69085efd61c4ac263c576c0da0e037ca716874a848a3ef14d7cd8fde3487", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1470150571635, - "fee": 0, - "recipientId": "AHbf1KCCkWZZYww8dBFjAbSK4oi44ATaNj", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207409532c4f13e05ccd6236cc3230bd8c4d8b9fb3335023566af2ec6a22ad545302202dbdccf7e42d4aade9dff05a5a16c5c96e9b8050dd5b2437f3471097f8ad4211", - "id": "dc3acba04a593a641812a6390fa5b0e63837447f08914576425715f8887c02a3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1470150571635, - "fee": 0, - "recipientId": "AP3uaTgqBZiPz6TFYNJ8zNNcZiNBidyLEa", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d44633e422ddb30db8bff2241ffec1290600ac1307393452dc7754e7c0928177022024cf31e3fa2a243218375cc5e66c8f0dfa1df07ec5480196884309b54a4068e8", - "id": "9273a1dda6e37f1e98206d1c5c89f5c36d869a7a4e59d1134875cfb923b9fff1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1470150571635, - "fee": 0, - "recipientId": "AGuHXDf1v7Hwfobh3P337B2579DBPpjSVs", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220278be19de5f1b004e82a31fbb872d3bc14f516c26b56dfd10fc69fa5c724252e02203dddd4e05320b906a2a3945e52b412e12760c0be9e64c9286afa2ed1b907a43c", - "id": "6dfe84e6247aee21e6df75a25030ac199eb74a7079b01df62095fe507c0f3b53", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1470738631864, - "fee": 0, - "recipientId": "AHUF2TeEq2KfWsdKJmKkyb2r7rn1ssxVTD", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c5944532bc50d544fbe393d8067585bac4c00239d96d2cec920b16b5e58be22702207e0594792578262ddd6c2ed4f443078a59b17412b835168837f58ea03268e8f2", - "id": "4e4ec69496a82528dd81743b7121fa8f8337d95a8c960e035ca863c9e9e945ed", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1471620722207, - "fee": 0, - "recipientId": "AdDYWwFY9CHymn4k8dbnShiEJZyF1gCTbe", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202febe57e819afd13b956afbf988130d00fc6894a72128595b9d3c5c10b7171ca0220127aeee9f9e67b4ced063e09300edb638be7001c3d823bf4873f2fc07c1a8052", - "id": "c3efc99b197e710b0db3510f26d78676fccff157f80a0043ff70f862b99bb48d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1476719471690, - "fee": 0, - "recipientId": "ARPtgH415JQHtdLmpkyfXm5QvUB9NWWZRY", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f9f6c9667ac8300ab05a51955046d8653cdbf93d28678be87e4892502aff5bf8022045b45cc9ba1a05612867c00cb08e881ceae4dc43e0369cad40789edc8dd3ea66", - "id": "5accfa3b6f5bde03070a900439418bfcf6e333eeaa78a55dd38dda5281f72359", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1501867950683, - "fee": 0, - "recipientId": "AaZMdjLc3oc2VU79SWzjaM8N6QQxD9JXsp", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a4efa1b07b43cdb06620c1ef7cc124505d440620ac4533bfd20d609d038b0018022050a04b85c435ad086578e698d11bcf35256cde10769c69945e144ea5b369a5b8", - "id": "99e166bd676b85006a59c88b96bafd199145e0464e120a72630a18886fe93347", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1521031173923, - "fee": 0, - "recipientId": "AHGrL6VPzSfw2kGfTZWFLN9hJxh11NLvRH", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022009ce1f620f2978fde9d02d346f69178a5339d0d34d229c9303a6bf3b0d390c7d022052bd984b7abf23e6e1f71f6c532a94eb92fa99a1b1a6683249ca16c93610e06e", - "id": "cd80da60be2804c472b529b4e41b3117d2c54b37047fe32363431735f21f4771", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1538544082336, - "fee": 0, - "recipientId": "Adse4g6EQzevtFtxCaymFKNTXfiqT8q3i3", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201e4d2f7d9ee5804329bcb4a16f1a925878dcc4f35d2462bbbc0e5dd63d6c5d86022039db901cb2fd1af4827f7c902cbf9d3758d56abaa3c2673f9a36eef29237bc4a", - "id": "16d0f95017cd07ec7ee5fb6b9a34cc55b4f3a43b7e551a8a2117fb22117cbe13", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1543246790015, - "fee": 0, - "recipientId": "ALreqLXn9X6tcgYfw7LD1WYYk7Pt77kdUd", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e5d85a41b1562fb3238d3e5fee2f4374b794aec61600ecf1eeaf745ec90b699402202b87a4c0574ee646af802ec7f4ccacfa7d6163c70f169b03384bbacde592b398", - "id": "b0078a99ab5fd8889b072e2022171a7eb345aef853d5d097a78b761989a260c6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1544792613177, - "fee": 0, - "recipientId": "AWuvoaPLVWvzGLAdJhSAY4gdLnTB5uEJdi", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a74e828d11fd810da6ce5be317d67c6795cb1bc02ebef637ff8d0f9de8c00412022073c5c9da3fae7a882d34d29ef370cede0e7b3fdef0ee054e72c659b0dbb25b71", - "id": "eb3495c47848de6b51b7d60f0918727bbd598a58625a3e308353dc27cbe2987b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1544843298795, - "fee": 0, - "recipientId": "AGWDijB8AcjiwxYTB6eybHiV9qeaFXPmsq", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201c541b0daa00bdb881cf99ccff32f8c04575e14f55e0987ddaaa9e83079ca420022042d986fda9b4e961d5487e602f78aa3c982bd4e0f9601ce33ca5b0be2cb51332", - "id": "cb64a6bb232fe4a160ef8a96b6f34bc76e8d1f1355edf969e0e1956886384aae", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1551677103335, - "fee": 0, - "recipientId": "ASqxPCEkpFj8ziJ6j4FY8pC3AmMXXT1KtR", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ecf1d28c1dfbc54be58569ec5f273008330340ab70df7629243b096e32357ff502205f9b0ed9cf1b7d7ee02b6e7a06799da79566c831cbbbb663b56b52b56f2f8632", - "id": "18fc455a58a3d42ae22c76540f497b5c1e74887612b6fb6128f6930d466fb6ca", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1557630114327, - "fee": 0, - "recipientId": "AYi6DEzFoDBwrRjj7sT78hXJGayRm3tZMm", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008ce7aae30ea9cb91237a4a646db6408a52917eef521c4575bb94e8a4a95e25b80220356cea901142679c62987b9d6f36b82029860226a46fc3e056c8120588658144", - "id": "e76471ed188cf048233c7114f4cf26d21b24e77b4e4c4e297cdc3e02645ab56b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1590480695140, - "fee": 0, - "recipientId": "AWevRPHEGJfM4rn2BRV435fKi3AAnZZuxP", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3043021f73eefa8d4dda995031746278feb82015905014306cab9766abb3d428d82fde02205852d35a40e3cf3a0113295ae54c76b4465bfbe46b67eaba24b2cb2590ff4b7a", - "id": "03d82bd53b9b6bb359d6773a6ef3fd340664e1946f8bd02cbda99e53fa35ba69", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1591288549068, - "fee": 0, - "recipientId": "AUkNoFqcTkMpPbvSx6FH5HPssnuWeUN1Wy", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f6ed9dac47067252fcf8bdaee46e90445a60b818d130f96755cfef8aed8c03830220139448b9a28051a55cf48f54f3162f7279e13e6a987a15b020d3d96a7e9cc3c9", - "id": "cba7cd24daeb4cbb94a63f729b6f4628bba3c878b09af82c6d81dcee220e8bd2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1598561495493, - "fee": 0, - "recipientId": "AGwteprikJgukHmkfyLepCefswocmkeJts", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203fd3b520f78acab6d4319657c1995b3abde676c85271af58fd8439fa41ac256502204add7191ae8d36d8028151d67956c891f67bf80b1cc3762fdf0871087a2ce8b1", - "id": "296c9e5c6c5f2fb5d7008c3b6d5191a02aa7410fc8efe451f8ced624d60de865", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1603639652925, - "fee": 0, - "recipientId": "AGQZLKtm74nXFBFvQX954zsXpBCVz6Vs6W", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100eae62745fa946e1d39d8f12c6a0f965c2dd95e709a728bd2b4aa800b8174ca0b0220529f3a59374eaf4208b8f6273d90af22dce3d183624fbe50b0ec49fa3dfc1519", - "id": "fca0223018570612e9d70ae707868624c6c7b9b42209077bfa7eedaecb136b86", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1605551439283, - "fee": 0, - "recipientId": "AH5EBGfkjr5UewU4Pkdk4X32FZUacp1wib", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022020d4c8eae1b41ba868e1796068e109d48cc208a5eeb374318c448b2aa21003d70220323a6f9fab9bc56481e8d6ff37be611370aad7957f8b0506688e20084466460d", - "id": "069a53a5dfb9ee6058e1202769e25903a014b12df9e4a815874bb4675e95ab37", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1608266337418, - "fee": 0, - "recipientId": "AXsBCKFEyrq1TmAyBHBFX6Fs2iLfg7qYsB", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200fa692b85aabb7c9cd1c23288ab8c3c51707598b7e4067ffc018f27a2428e37b02204dd58f775a2ce3340d1ece51a2133b628cf79e26df11dc75669c2f44b2e58df7", - "id": "399cd9f4dcfdd54a47fff7d51568cb6525e54332251a623a94c8497b228a88bd", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1612755177084, - "fee": 0, - "recipientId": "AbjtH1c5sw2cPFu9D7cCDNU5dchyWERKV6", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f78f0db05853c6639d8ab877bae34a93f65ec3001b62a313d0790c1f08429b9702200133bc555e10405721c43638af4b77eaa4c57b73c64f786ee40df2f4827d9f7d", - "id": "fcf8f52e8b0a6ea3d181ca56067bb44d93f744e28aedbbcdb8e06ffeef189db0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1615695478227, - "fee": 0, - "recipientId": "ATQZen8h9DzHAt7HgPAwzcWfAC6CaTH4dp", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203b9df7a00baac5b1c3b61b590455967d9a38701ef39fbc4e3e37d1c74631f0c202205625993ab0006b2b2d65b0b28871765a4345a6482cf2aa42d0d1ebc503f6ac93", - "id": "c13207f4ba76d22fe47a1d538019c73ac6652dd7b6351a4222ddc158950e9958", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1632724842016, - "fee": 0, - "recipientId": "AMbioVwHwrkTYHt4zqt1r577Z4Y5tgWwJH", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210084ed4b704b13b31aba705cdfc9df95fa552f0254e97f89371e9488d672aa337d02206ca6ec6c2cda84cc0534d21a4e74d8782f11aaa5690668ab17768bd97abafa9e", - "id": "18ae7a152adcb4616d7f396119eab66060b48e66553a4562737e95244dc2cf8b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1635164836036, - "fee": 0, - "recipientId": "Adkm397wm32bW55AE1kQTGyk1t6NCz7sfP", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c749b79487813d5201670106a0cf10f990e795c5405801c66e3fda6b7bb8515f022012a06e81726ef353b47297609051d850caba385828b5d9a4e044f1e5edb32471", - "id": "e583c7aa0cf2bb4da4d9886b55b893ce1b1052ba6d79ee510e7f58c273c8b1c3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1658329844804, - "fee": 0, - "recipientId": "AGvf9xsh3xgCMSnoCYLembrzthHqGJdwbM", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200a16ffd1d50f85db3ea81de649a38892df46548d4b69ac6ba8e1cb610bca9be6022005f0b9d13821099d92a8fe5662389f439c232e3da0a024dd43cd5eea7ab4fe21", - "id": "aa4d7b90b4c1fbbd4297a23df89b89a84c9c912f03af1a9bb4dcf77dd52b794b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1672675483771, - "fee": 0, - "recipientId": "AMW2gACZ82N8CNgjFL4q5bzC6dRwpave6f", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200fd4245350f29e79b767acd442c893689dbbe3fe5c6d0b1bb40d3d7d8f4e0dbc02200f0d67c711afabfc3d38324236f051384229ab00f1f9a698627567b8f73460c2", - "id": "a8870e6e74479438af8e464c62dcabafbe785b01824e078e1e121bfff01e880f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1738465434518, - "fee": 0, - "recipientId": "AKFT9sF88rSg7rvy3gvMEJJ8LaYsbEsYH7", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fa6c33a957f7b2b26549f37208c4ab1d968161f531cc2c681c863acaaa90627f02203138faffd5b376854a9e6d7080b2850d571f07b1a2c7c58113dfc105c6318f54", - "id": "b416130c8a04526c058e7dd56d79161c989f0cfcd83aaa798e6235ee6fcc3c57", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1742839839455, - "fee": 0, - "recipientId": "AMXgwGKJbUt9NT5qEMwY2dxUVQquQDBrTv", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220537c4ad8333d6c27ae2d4b5e3822242efa493084a984db369f4538f61fd55cb302205a054469d04d99e8d3e57f47ce237178014ea4c7c33c7e05f5bab627901b1e20", - "id": "d5355bc6a2601705af7f537514f45a838246dd11a95c2b33bd3a3bb2461bc89d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1775549503277, - "fee": 0, - "recipientId": "AWGk5PUpJCLBr9GppUnNY9ryL5RhbstthX", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100cd7bf83928c227b964f34cc5d55483743a1ccdf17f778f14bde1bde676a7051d022034e2bb957bdf212377580f3b6a7ac3024179b1aaa0dfe57e9cf76c32f37ecf6d", - "id": "ee657127722958204f85897e7825ffec69af1504e20ade4076b07aefdeb263cf", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1812187469576, - "fee": 0, - "recipientId": "AReskqQAtGi73GHG6tLyGxpyZKAw6kyhko", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f7d097824b01b8a9d290ac4f7c80cc8bd5f32ef07b22768ab289ae39048b2b2902205bff5fcf23fbcdfe1f60cdd017fe790153ee783facc851af6a65b7e2cde0cbfa", - "id": "3641ee56bb7b499407222f68f9b0432c80b7e6a32a8515f8c5c08ee38bcbdf8c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1847900000000, - "fee": 0, - "recipientId": "ALCuA5ST57RnThByiyCGYti1rFFpy2vaPy", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210088f32afedbe40f6ce661f0e828f6815288b96d78409c0067578bc016149d05c0022018dfcd5230d3fca401a478120a60a153c027212107b380c8f428e3991775d067", - "id": "ad9154e66ae59ac9f80f524568452bca4f00455ecfbfc25ab89652ec84f26c08", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1849124693198, - "fee": 0, - "recipientId": "AbpeUAgMG9Zk1XsLfPcNshwumea7mkekBZ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022012c3db569ba5f74749d21752f16fe382493c639d383aa30d9bc85ffbdb3dd1c002200dcce7a238a59263badcb59d57e531933ca1264161aec6f04e44e5c87a6767c1", - "id": "f5615283d55e13b2b690b281bdcc412f9d87493b212d2b6b76d529e54d0a6b32", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1876941234807, - "fee": 0, - "recipientId": "AdBizdK3H7zfp6cnpAsAi9uR2fvJNQSFd9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d595be37c3d0bc9d54b9746e84d92ea5d28f1a39df6c0ead2ab145191f95bb4e022020c5ece72829027083379f47cffe67674d4f4ee5e98f9eab80ad16b2fb44a4e4", - "id": "8bb71be1a515fcfdce9a10be706054e87bfd64cabc0e2ad958569ae7a03068a2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1891934510958, - "fee": 0, - "recipientId": "AKxpcA6iVjFtxKzcW8H1EvQY7nz2qrkGFT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205e4a8eb13b197165a479dd3c0aa6ef0d06a011ab5fc429de4b25021fed9024ab022061c25125f58c392d7d10d9b060edfd3a55df16009b3b50ed6b7825be84e0c375", - "id": "06f4102c8d21139312432f58fc981d0e183a97c6726506f8ea1ea71e5957c4fc", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1895283091114, - "fee": 0, - "recipientId": "AYR4E6VBw7Ut1ygyvwLxbwDYtsLHrq7T7Q", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022012c4b05c360635a515a257733ed66d9f100fd39810beba85b4014c21c068bcd30220090c79f001b853f4e38c3df7f043fc8c7c2c683fd2f2572a01e38d11f4219d88", - "id": "bb54551895feb42ba8c85355084adb36d7dff452ef87dd411558a07356989cae", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1903697975211, - "fee": 0, - "recipientId": "AbT1VtooS3gA8M6KRT4Fy98tFzaTg5N9Gk", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a905b417aa0cd3b7f1b195254e15bbe303e0e59d7e2f7007889e0615bfaf945b02204050e412101f519179944471aaa65e6d32045138a45631fce10b18e31a05748c", - "id": "3f1f30abd5977c35300930eb6a8af9b16f78ee602cbfeabbc3870149d0144c57", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1909607394110, - "fee": 0, - "recipientId": "AZt4XTwHPBLEhr6vkLEYX1b1RKmAN8Yit3", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f5fcda2c42c4756ee68e460366d4ee509299d67559a4ce904dc22adb03d8422c02204be79c434dad458962e524da2e99ab10116c61374ac17bc880dfc5061827bf61", - "id": "8c4192958e2a40b7ac6886d39d6324a17d4c05c9c7e96da6bf6316742f2a7b7f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1911195743126, - "fee": 0, - "recipientId": "ATd8DeNiNgb7R4uiQGyGNLYkq1q7FhikGk", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201e2d7e0d4153794e41d90c9cfdf873867f46da8fb73d4bf5df8250f782d4a4de02204c2c78faf8a805d97119e09e77c132630f7d525bed291fcc40b019e71bc85490", - "id": "cddf63350558f510f3bd2bb86009c71bd39f75d36ea1bb245bf4b3af761f2e1c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1940598754559, - "fee": 0, - "recipientId": "AYeUdkzuGw84sPXgFBdLjfjXtG6SsJ2Rjg", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220621146cc0eb8596f176a16040fa8832112c2fc19b49c5a4a1ba830de141df6b202202f1a8232b2057dd529355fc4aec34ca4825630d203182f02880de2efe342d736", - "id": "00f4cf49905ea8c652b71c522fb8bd19ddecde1d2e8feb1ee2961fcdf7034a04", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1941422708032, - "fee": 0, - "recipientId": "AeVN8SgGb4mUYCjHVCCmWfw8h7WHb8LApw", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203d2d268ff5c91f54eba179cdc53b51726f6eaa3c1dfc3598be7e444c12a5575a02201cd9dd296215e16ebc511146fbda0989c8a41051dcb07d62f9fd4622bfcbf27e", - "id": "fb2a707333b3286f4d44b61db19a2e617bbe3592de77da45695444b62fc0a5fb", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1946861217599, - "fee": 0, - "recipientId": "AGueDNGxUQRDsGUa9aSPw53XKNgNPjUAia", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a8a10c8b659087d985de4bbd6166a9f2c5f8cd46e28be26b2f9babe3a2d063c80220460ce29b3f0327359a4028ad600d25bcb25634f19bd9b3d8e4a3014b2b9636f8", - "id": "e127b243ad79cbf966ab4b1c77b45e6657fbb5f49e4cc3a96406887e2ce4637c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1949845628984, - "fee": 0, - "recipientId": "ARsJyHCQ8YnDZYm8v2sE51e1qtGnK3SdMo", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f82068304b6f191b9452c1160caede73592d36d75a00beb74a9af9f1886715eb02206b38b09daf8e9184cb91130165227fbf05e94b835a7399d4ba07ff8bca6c1179", - "id": "6ed82d8c0071b52aa28e9674e012ba28759081f527a793da1161fc32d058bcc5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1973042309220, - "fee": 0, - "recipientId": "AML7Pg7WEuKaEWAM52rAUfv3RWE8BAbp7i", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204806c034f7027b71d645ab6df4134ce5c2861e479b9ce8a608669221fa1f9991022052ff1460577ba1674b6a15ccc505b53749bd6fdb8f0d1e3dfa596ca91bc956cb", - "id": "5d719b936209fc04fbf9e118b78c688ae6b586d0d9ffac1cf88225f47e2c37e6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1973887957498, - "fee": 0, - "recipientId": "AcSTQCTesrVHnvoAK8r1bwZ9CpDqiPmRK1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201ee8cf1f90aee896e63feb920df725b6897c6d4cf0723198abe4dcb65fd6359702203e5307a6831a54072cf564804482661789e2c78b9c189760ef1b33579de60d56", - "id": "5b82367f3b78997169ed9fcba1e4eefa8054c96b64d2bd30d12f18f2a364444d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1991239524027, - "fee": 0, - "recipientId": "AGhLhXKXAUWDZRS3skaEVMzpcyeqCyE6as", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022019f81fc2e04573a9ec9ffcd4c6504da8d206467a742c8d9cbf96d1980ab77ff2022050b0746effd9c253e61dc8f89b015b4256764292860db88eb9a6832c33812b66", - "id": "b62ecd68c562fa705d41d59b3f871934b7a5594a89354cbce472c9772e100393", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2000000000000, - "fee": 0, - "recipientId": "AVMX3Y79qXSHBk6tUrcLAeKh9C25xtyJVL", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100edcdf6bd19aa85b0c2078804a9a021847592dce74d2dcdddb38a0ece549a080c022057316f1c9f36d89f08ad9020385c16fed5bc088f12e588166fc984e9b0c6fda4", - "id": "4a26a119361e812cb7fa868b10ad2c903dcb681418113abe72c610afd4c1475a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2007149179076, - "fee": 0, - "recipientId": "ARLoK9ABM7bFmaqLMaEBbfTVvsXqyYaeXV", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e924d9016e8ed30d3e06fbea56d70c05b670b6a9d6999a039b93b0d436357b25022015da3def5243cdac0d0baa92e8f695a5018e06da5155d17f7f48dd7814341b3a", - "id": "f40dec591c02dae1e1eb176583476d7a7e291ee5f6be1741b9ba3c0e97013f1a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2020119321574, - "fee": 0, - "recipientId": "AL4youLTt6UXwxXWmqzAxznH2aPEekZCpf", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b4c556e5c648045ac2cb50aea26bfc158506a494c66bfff2d22941ab8a3f6af902206b6560e4d19bbf8b770c2ea0cacca973f94e683b38df2a00d81727d4bc0b41a0", - "id": "394ffc5b4a91e6dd81621246ca0a1070f3b451aaeca3f1ad48c4a4186409079f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2048474511235, - "fee": 0, - "recipientId": "AGsx5dwwQju71REuRJd8iv8AAo6wuo2Hhj", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210083dab3dbab91f91a9f7bbb3fd91b16c5457fe84e918d475cb7e544d09466c8380220504deee2a01460cc9dfe7be2531f92ed2b14a6923bc6bdb02ad1131803fc7b28", - "id": "0c1e0d578f3f6afcdf8d0406ea5478ade1c52d87b31153fcde6c6345cb0db9c2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2058848207492, - "fee": 0, - "recipientId": "ALcc4t52pgbFF1iZ1dntq8oK1TjprrckKT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008ebec56c81cce72ade2152091e9771c0c9b46c411f17c49272b1647466b4d1bb022022bb7763cfb7af70ab4d97d6301db9a96046225be25b50234a5e1bc868e978e4", - "id": "e3e18ce2031b8052143296bee5317ba5013b6df080a1a222fcd41af5a3263398", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2061097549268, - "fee": 0, - "recipientId": "AFpxF8SMNEMaBjhw5NKdydhfU9zeDByEnK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100df0a94e388245d9cc205bd2739d9e17f02964f957707a88a51aaf03d029fb58f02204fe22271ef442b7364541ce62a5d833bdf061d8c6c3d78809a243e26428b2f05", - "id": "a91fab928d30719452a7890dc5d7b4bf323642923ee6e99c7e12aef8eb5ed821", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2061097549268, - "fee": 0, - "recipientId": "AbfyMpZLZXJukJ1jCLkQaDdxU8hRMCroHM", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203b386391a09c598649acf2575dabb917adcb14572a60f1ea8cbdfeeb4557549902200d3e0c146cd9d726ab91b215b817dbe68adc25dd8f506dec264445062dfff1ea", - "id": "0c1c747f9e680eb8199584b1f2a9b3b855db0f700e61ef3041f4b9388bb0c826", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2066612412189, - "fee": 0, - "recipientId": "AMgiiG8wXhd16NBjazW2je1hK9pfanLyMV", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204c5afff450f8735039b04fb34b6324136842b66fce3e1e87fb5cefbd23d1384c02203364cf3f9b63c10e14909c7ba9aa6d442da124bf257c707277a8167a05bf894e", - "id": "142834112cc331aabf1f30dbcec6c6a538c9b47927eb71ffc30083f8322bb224", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2109666070297, - "fee": 0, - "recipientId": "APJ25Fek6dNkA3jEExkyG67UAzrDRvPxf4", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022047b3d2953eb0b6e1834bb77053b207444fdf49669578ae639e062eaccb721c9b02204d142ead55d393dc0557b1d4b417e71cef41ef65623ffb5bde6e56665da2db91", - "id": "439911c5383eb2e090858e43740e9272b7053d4709c455a5fdf21ed46569a591", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2153677032409, - "fee": 0, - "recipientId": "AXtyzwP8X29Ddr5KUy6GuuxWibW2eNypng", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009ce7072f8d3bf7866b357aa36b475f3eb102e31caeae5d8d3c6a39d8f3c39a4a0220636f0f46dbd6a477194025d39f2db234449195b53798fbd03ce3e2ec3c86edb7", - "id": "dc9c7ec06d60f03495f590e1e46a6283db8cf62dcfd2186fc65249f4ddf51074", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2163834169022, - "fee": 0, - "recipientId": "AaJxRN92BCtogWtzRUrHJC8TWqSswRJGA5", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207120a932e96c536e2c2f051546d173f3c58bfc83946fbddb0f991431da9f685a02202ebb91ef9238d05341afd2012ba2bd456a54d2bfc20d22ce3d10d4a618ebc5a7", - "id": "fb426988eabaa074956707a42bdf4adf3a0c10cd719a6c4cd6fb2828fa9b7c53", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2184588569625, - "fee": 0, - "recipientId": "AXKzjecNQcpJvwpm72ZE2DDkf3c6qV9FQz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204dc5f6f772f7843dca653edee6da99c709d3efcb585092d3b563fbb58ef9ee93022011ad3b1c4226208c88fbe189f9a40fc22964d8336fdc290d3051840a20006499", - "id": "7853c4e80e57ad1152b9b7c8f7e8e1f6d5aa849ae1f0b5a3732121ae11b929c3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2191161363601, - "fee": 0, - "recipientId": "ARV6tjuLPdAAJFhTeho2KbZ3caMXNChvwK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e9fa2dd98b2518aaf44488865877488f3413caa3f38d70d690b8693519f96a7f02202959afa89b20dfc55786c82a636edc53260290744beb427150b506b666414da6", - "id": "0e73c449c0116a23ef5abb5993be907794353557601e0a39e96da882a7c948d8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2204931827339, - "fee": 0, - "recipientId": "AaUvDwmuhLvZRwmW8epsDmRQfLh11ufUzH", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009ebbd2c288878988a5f18a448ec7c33adaeecc203084620f2f98b3c74960ae6402204014eecc985db4e8d94b92e94148453480f526521a604c2222b3c04b90fcea17", - "id": "8e95a6db2d145e700e36e08a413e0d0f2a6f23d0640f468be65b73b56469ffde", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2205078842396, - "fee": 0, - "recipientId": "AJuvjPUQHDYkiV5R9QQrAmKQqMsdCiyW9k", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206083b54d4879edb8e02dcd5828e6117ee97624ac9f1381da575ca3654d7da3ad02201effb3b78038dfbb482cc8d60a8096c77fb351387cbeb5b1fe7423d1aac34c67", - "id": "bf0dad6cac85409e568de7d2ec72bf9a649a5a78e2f2d49c2096800e05dff8bc", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2205225857453, - "fee": 0, - "recipientId": "AdeDz2SgSHtNSS49qk89UQoosmM9nSn8yW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022060fb58e2b791d584bb622cbfbb9ae89489a68b63cd292445db2bb82c60031025022065952795086ac1cd075d4b2fb58356579b3000948628d8a0cd91170eff57a83a", - "id": "7acf01f865d9e3b0172fd107b066a11d10e561a233af85c325a1891ab695b94a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2241213029168, - "fee": 0, - "recipientId": "AcRFukzbp9dcnpAfhUR7tKr2T9TP9ysr8E", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c9efa61ad9f4ac61a62a753d773e5f5b07c68348d41f651ce11b4381403dbe9202205397961b89303df542243d52407a2f3d1d1314b7f419818fef1b6a5a172a7b9a", - "id": "68995bfad121ad8d25068bd9f6a1c7442730220b39cc002a41650ff3a38221b4", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2248243233437, - "fee": 0, - "recipientId": "AeZ1HHc1d6eg8P42i6fVcJVKsXw8Eo32hT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022047e447051f960a6d1e554a72640858c8557099de95f891b692f44b15ca6b85d102207a4d3e483e26de4de2de0c337ad2bbb581312cfcb77f806d320d88103a1aa227", - "id": "7eb9c09a76d966babff5fef1db9a160af8885f4545fa1da2cba9baf5b64cebe7", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2262177091195, - "fee": 0, - "recipientId": "AJzzwPzzyDCiDc23uQ2u7AMywkfzaVCcWt", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206772491d6df99e5475ed8609d3a35a646b77fe85b81aa0cbcd5a79ea725a0f6602205b19e267638b99baa4990e16ccdab0ebfbe2a9130618c83c30ff9f8fd750eb2a", - "id": "fd90da851810e57219244396325da5e2064640daf9ba6114102aabff880414ca", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2266868808469, - "fee": 0, - "recipientId": "ALNvcAUuj1GRHaTvDcEj3J2LJrpbigMfTd", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b0e14408162136a3d9a103e113d860643cb583e260bed70db986b548167bdd1d02201e3cd6711b3a5a47b07cc79a2a0fd24d701003ee54bf4e96c34feaae11586bcd", - "id": "997f9a8497ee44bce5675df192fbef70e582563d5a8d6774a10a38c1ffc870e9", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2271096947063, - "fee": 0, - "recipientId": "AKU5SETsMF21C4QNxSAFEuMtucEVZbHrbT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220405439f374319ae7818197cd605c29f981ec33ae5e5d8ff63daa6c28b79a12fd02204afb1feecba0339d1f6858f00f45053c4fe891a041a810df553c0274b8da8837", - "id": "625cabdf0b3e0ec7461e182b037d5050566ed0cfc96daeee199fec7372b428c9", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2272050883436, - "fee": 0, - "recipientId": "Ad3NrB9ak5ASf4k7u8UsMUw62onx7t7c5T", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210093ef0463dc9e57cf30e412631760d1f8c9546fabac8d02a81d4450c1b0225fc7022034d6e9612a01b53cbca18c08c95ded5ecf9e16486772e910e857e32dd7fcc8d6", - "id": "56ec4d726f2f6eb3bdbf96201d7bd4ec0dc76222145e4aab469a5a8031bc0897", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2276774784522, - "fee": 0, - "recipientId": "ASdJV1rBGrv8hr3n6PAzyEstMMaeKRC9r7", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022073089b31090a9893b58f7d356e2ab39709f213bc753efe142dce1028a18fcc85022027516343ec493797a210a0eded5d162f612c19221ee758925bd0bff3b9a38a4d", - "id": "b2f66b94ccca70109adff57f5b0327c01fb8b1cf9266cc5d34e67c1078619b6b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2287751179042, - "fee": 0, - "recipientId": "AQG5AyRdBMK1EiAxjtzumHBKTz5fQziJaQ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203358a1b09882d61785e37ac06243189f37c429a08c245dcb9cd302d67bc23a89022036c0830ea03b7fc64d9d673d83d99d5001a39487d5207983a09a6b2bb45e8b70", - "id": "27f99bcaff31983a34701f2db5614995f09298ec428508c0ef310abca3a17156", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2318734742927, - "fee": 0, - "recipientId": "AHWbM4U2eC5G8GqhEXjKjyjQ14gE2uz8WB", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206f65c7a1ff3c846ba9ecc55cc3485c498ea01d316a456d7044e801dc910edfde022057487ee7c70aa9f4920bd4a32759569e2dda24d493d427c1a1aa2cc92b6f860b", - "id": "726d10604f15f9e5007445f0b8f829d8811952a0b9f81895fa673d45e579a8e4", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2328424475356, - "fee": 0, - "recipientId": "Ad9T3DbNPoF7SnCuhBEMQwHuiKjEXmhTFn", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220725c7b21c8cf49ce86093c81ff5079c5f3ad6a7955529a52354e01c8b93db64502204463fa21a31a3cd7fac42e62f0e304ad7861d71c7eed6114e1c64cd37ade9438", - "id": "66ecd1311f19281f119c8bbbd34d6f32daceb58f2c747c32bac3821d1b22bc36", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2338875909420, - "fee": 0, - "recipientId": "AH5nQnHDEueDsMA1oL4AxTYgPkGgzrPPv4", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210093df608b5fc963f1724fbb3f0e3e3c52c1642b17330988bfa45d7e28b143f7af02203b04d3b802038a17bef863ba2e2e17f1a288ae1764ef61e7410643017643f054", - "id": "1446fe4a270106969f516ddb59b0d145c4df5ef0c58aaea92e16d4e73d4edf17", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2356684778844, - "fee": 0, - "recipientId": "AeNyCDJoThuMtgGCqo36Qj1RxiLzp2wKfX", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c7ae57e20b74727add16c03acabc3f2ee6e8e200651ed2dfdb973f3137cbad9d02201c33c46ac75f9d1183ce4a60bfdaf72021415676828992f5b4bb4a15bf8b06a3", - "id": "8e4d777e325bb6e75f240dc86f0def43fd27a1d7db6efeae8af457fb4a0e5a7c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2366781260994, - "fee": 0, - "recipientId": "AGog6GdAzTgGhYXuifWnrKvK8VAPaEhe3U", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210097204cf3140ccc71aa07a31cc969dd5b532d8ffbbe936581b08914982e823033022063df68f995e5b8f76d391cf7faea9b34fdb2b3b26db5ec42dc94055efafb86b2", - "id": "250af0610058d8455a4efe16382bc4b0cb0d3206cbb288333ac3550ceb44cda9", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2372499252388, - "fee": 0, - "recipientId": "AQRccct6eua3CnzgReDsYVdZhjJEGa55fM", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022048fcfeda36ed20495c633c7b1e671a306df8229e2a7d4a75547c81b8af509742022066b8f68d2adae68654bb0fd01d56c817b45f1d5fe686c1a180fb53f9109ebefb", - "id": "72c59a55be7083859a7fcbf1e4b9d5e3f39013b292c812fc61a83b07d44aca4a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2381643926049, - "fee": 0, - "recipientId": "AGvdP9o1xDU5HB9ZfFEBKTN9Td97rka9GG", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a95fbdf4d29b7d8d00bf352f5c0faae88fd0c6954119c1e7de8624c539efedd702200aaa95e4924771e70dafc892933be295c372f3d7614058f34f6568955e60e3d7", - "id": "c4be55dbb512485ddcfa1a44a64b77f72f6a623ba28a1ed74f7e164759921b69", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2411046937482, - "fee": 0, - "recipientId": "AS4BtWoaap3AVmgxh8cQj3xkcd7dkWfK1J", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d2efa679287190ad29fd7fbe91978ce07dd5819acfc9f08b12e9aca27c5d9fee02207da29d7168e36a88509b6d73344e461635bbb009e1203bff8c6ea31068f8b2c0", - "id": "dca8904b7776d845555706aa639fbaae9e6ae4d6d912c796a41e793dc2030d6f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2421793988476, - "fee": 0, - "recipientId": "AGErCuSAoSpZNQ7ubeV4HSuHrwoxGQoBbq", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c9947449ab96e6ebafcae96a6c080669ce3045f711e0ea1bce651061cb054d7b02204bd9e3e1fa0bbb0923571ddafa6943c69ca2096fd82dde9a0fea4e3eace6bbdf", - "id": "c36be7fc674eef93fff38d284a209599ffab56eace2e569f9f05db0ebbc98e8c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2424820646199, - "fee": 0, - "recipientId": "ANgyLRoKJC7a6RLUJw4nkkrL1Rni5eYs5i", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022040b3f827c57219cac01e956cb5aec623fcee151b57225ac06edf7fbea1d86521022021808f0d44f5a50c7f35a25e40c0034b7831deb627f8c2922ded0b406a00cc63", - "id": "f3f300b5fb8de1f81c863737617f45c4b67f80fbfb7b72cb4a4e0423718df75e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2440155918800, - "fee": 0, - "recipientId": "Ab9oevZRRtixxzvZjVA5jJrjxi1kwWhUN3", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201a6214822f6166833f7fcb539cbbca80debc0e0d01ca91c0f87a64a5dbe993b002205bfc9366366bca57d54bb5c389edff2e0b90728fdcb58ceca89984ba9aa12e66", - "id": "a6fdc2fec0e799ecc73e8310e8285cee66c1420f3edb9d915cdbe7414c23b824", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2471141445854, - "fee": 0, - "recipientId": "AcQgRCArM8s3iCzXmaNa4LFYcPwPUqR4Xw", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022014be56285973e8fa73c89a4de8c1d5f06c30bbdf6d69c9286e19e18d3c00cdca02203a8777b4f3cb0a28cb42af527b3a13d284c8bb5a8c6a97b1f04c5fa3b7d42dec", - "id": "8dd4e91bcad96169a7d3e4a01fcede8898b36e45797a4aaa6c318f1c0ac02889", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2481166956848, - "fee": 0, - "recipientId": "AbKSfhS4rZQXKJjnF1egbDqBh1fnkoDADx", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100bd942f63f791c0cc5f90d50edbbb6837a1445b053c599abd9cb8bf89e933d96e02202e1620e229f7657fd1d87fa97c076b42a5a8a4b5eb6992cd2cf1308a4d2585a2", - "id": "cc51d42bf081b422663bcebf7c9d4676a1ec5fae1e4df76e7ef63bc9184e7c50", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2484636536440, - "fee": 0, - "recipientId": "ANTd31Ts3VHYBkd3BmbAv1FHdrYjVU939o", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202aadc401035be55c7a644fc4204865a0b25c61c8ee7557c35c8d6908ae51748602200eee3eb04aaadda8f210440e269c03868d46fad3f80850c81f7f526471e7090c", - "id": "d5f9faff17330dc56236696dfb08548941a881159948c6aa100136fd416ae834", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2532393949328, - "fee": 0, - "recipientId": "AeZGayWNSzKRkeNxkHJFzHEygeXsh8eytK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022036bd56eef8476da49e4c226f6d5bff50a491a4b0d077f0320df704ec731b3ee9022057b53f23797d0cb167b534f88cb0004961c2ac0ca25adca7a83bb0eebc541cab", - "id": "b6f7fad4820bfd4a97c845918c3f7d39a9cce601db5947b30f0a8cf515346fe3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2576371936586, - "fee": 0, - "recipientId": "AZMvWheiHokcgXW1UBvepmCiSjtLESNoid", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200923d3e46b3595c3f9c728deb6f8f34cb5dc49e32cf5e9668d0d74e31181d5ad02202d6079625ff697cb987da8782d44333768b883c10407af365fb4cc9a5135aba0", - "id": "1768864cee1985d3e4440b710f7cc8dbb7bf095f57f61af22f4fe9c1cef4e1a8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2584344277365, - "fee": 0, - "recipientId": "AUpLiwm2WVWh7Pqeizt33LgjTfLxaeKQZM", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d3cb2ef1d65dfefc87c26a36c625d9c018924faa17876acb422727fafab78c5d022054abdebdb5079c36789fe3f7d97bf736ef5a314555aba0632ec3511f6b72af7c", - "id": "644c4cacbd139ed34ad275cc8e2c5d147a4d3a5e8ceda34f93c7860cbf3285e9", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2592139332838, - "fee": 0, - "recipientId": "AWEVGHr3x1e166sLRYWjub9tMuRmrwv5Rz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100dba9d478044f5f59fe1c85f8528f1e0fcbe8ff1fecd0cffc13d09ea320a180480220086a1fa2d5f23c120b0b8e49753d8e4c9a1772f8b2449700e9987f7679acbdbf", - "id": "27a27a46a268bf1af2f7309c1d6d4594513c1e6188d68216eadb573ebaaec3f0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2596699852052, - "fee": 0, - "recipientId": "AVpBNSkQsqp9VtK1hZtf32ZBszABP6mPxz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201d4b144431415a853dcb795f3ead4eb9947a0780af7303c7f8f1bbe95f0bf470022025539723eedc56622cff150b1f6d65e5ff10ee29a39b5f29b77af51d455616a9", - "id": "d6adcf3c3c7307e26318198bb541bfa38f3b12328b4b71a87eb3a6eb760baad0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2599032418076, - "fee": 0, - "recipientId": "AaQDmLECcNXVzALX99oWP8ed8wrz7E6vQV", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022052078242e033e71cc764c5e6cdb1f240fa434c674d8bbcf5253f17b2e4bdd95e02204a1095961b33110272cf1d944ff3cf147cf784f02cd37794205369f75aefeb09", - "id": "06f66303e2b00608900e64f219579cccaf060f93a50eb1ffb83a6af3374128ca", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2619541018549, - "fee": 0, - "recipientId": "AM1WQJyB6ENVcBM3qumifK1iyGgmxAtfky", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ec33ce506f26896c7cb3f5730859b4da1b52fe9ce4fddca9c17976e7522d82cb022040a6c88430b555f187b83324a99cea223f56be138e5de4d860fcf2a3315e91c7", - "id": "105f4cf709516db516b88e985518ccf82eb4939a886c1b8fe356ca85b2444325", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2625323003381, - "fee": 0, - "recipientId": "AbYapv2W4GTvn1XAQopCFPxHTmGuhZ7wrU", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100cbe7e43ef7a56ddda2308f5cb60204611e24dc16d1cd1c681a4190bb109ce8ac02202b41f1a599c6de7bf37d94b8105c618460729edb0235d3070948a002d408a315", - "id": "706cb7d860d44fd5ca836fa5667d81e60dfb86c0e8190850a1ef042da330e2fa", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2646271028944, - "fee": 0, - "recipientId": "ALGc47qvCBw7dL6y5ruLrpWXdghQSMjRX2", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204756f3e295f5dad6ffe44c0bc09e7a8e215acf01bd7fbe85babbea5e1682971802201cd1a6af8e4d6440405631ffaa0b77333ff31a4068675a4ed9e32e345e812c11", - "id": "a7b9cd14e449f0809494ef6a4e94e257206e3b339196dafa6cce9a5911eeccfd", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2735324506659, - "fee": 0, - "recipientId": "AW9ZtarPjeMUH3abFtVvC2ECNTkMS4w9ZY", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e1b443ca71f70cefd6dfd6cbd2120881c7963e60b9601d6793d46587bf64f8e102205519f08774fb4a7ccec42ee49cf10cc1e60c8bdd4b8f9b0ff3d403cf009022c8", - "id": "26d5fd2ff3c8975785fcbbefd6ad746f51727c273f70f5545e95d3fd683593fe", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2745083256244, - "fee": 0, - "recipientId": "AcWyTqpf7XuNnptSCJ4cTyw2hqc6PhDufV", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e1fe873519ee311dfe7114f754260443d272cb2faabdc67d5e13b3e22dce40b902201b2372a23b827ea4c3b588b9e55da4cb09f9f18f201293591bbba3791f1fe46a", - "id": "3ae55c8fc62086c2ab577dad2cc85e9fd025d8e035ccdd040857f25f3215a29f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2764221209306, - "fee": 0, - "recipientId": "AS2NDZSgogBv8K2PdDNYwWcU8RphnXARQo", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200d7315132954c4ddfb3a09c6204a1dc0be0a415d87b5243093e8ca01c02057f70220377bb5e835854b2a1372aac469e103ff59fb023acb7b05abb259083ac0a695c7", - "id": "41220183a52980e1897442d243a14f13cc5f6e3a9356c1fa229b6999899c152b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2806744646340, - "fee": 0, - "recipientId": "ARsQwGzjkRCscuwe8dQ2MHPHSYqmbY4iSU", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207f71fdb335a27b7d37d9e07677d14e546e91f1bc8be8c5519179853be3f6ca9d0220712a67657afe2b13a1ed42f7d29f662c625b55b577a87d032e5a513d3a33e875", - "id": "5a83436df7e6bcea1e1221846e05315cf36f3c5c4b06d785344e8010e48cb64b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2906876974000, - "fee": 0, - "recipientId": "AT51Pc6EAJKjK4Sgr2tf3i2X7Wp6L1Nmef", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210084c2421ebaf0f1cf5c9ebc09454762d5e6b47291c0b88d8c644cef634c92d4a9022000b3c741497725e2659358254baf0cf87ca742dd189ed5b29160e72e9a7e8d94", - "id": "5ef7d8921886188473d15c50c752fbcb5db7d094efbaa8011b23929409a7e642", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2910898131837, - "fee": 0, - "recipientId": "AST9oifUBT4nv5kiNZwFrkTneZEyUshbti", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100be3ed06ba98f260ce44e0049f1ea20d5efa532ec97e9c286a3dc6611f72048bd0220562050948f72a8747b5e9407033c083ecd60aa78621b0f8d7c57283eacd286f7", - "id": "f04b90545d3dfa0567f8b277d172f32c9cbd9de645036edd4d5e0e74c77267a5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2940154128213, - "fee": 0, - "recipientId": "AMZXd6g2nidHGd1pZFUqZVpJnNrpzqtCKF", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201396009e8dc5376c341ea496e7542c2b96514819dca5aa23ca8dbf8efc1175ae02205a6083d4d66a15d511c672cf521d57ee61ac55bc876f494ea6450d2b7b5f6640", - "id": "46f24f882e0b0a1df1eeb6e2b17ad3a37ec3b9eb413d8aeb2af5827c1a16e286", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2940154128214, - "fee": 0, - "recipientId": "AHwkTdboEC2Nm6NwXoURbTzoNRPmMVXCqc", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205f1d63f3ad6bb0ee39797711bd1939b72f6081abda7a3249ef9d690c4b2de86102206022e684106c6e47c8441c5cb2ca2e583b3e79fc2f8db0d6885ec2590cf88c2a", - "id": "f868bf1d98ad88b9fa263292382355e6e21513a7614bf35e0a413e94602b4f80", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2940301143271, - "fee": 0, - "recipientId": "ASBzgywUJ9UtciVtbYc512CDrgTDhcMYng", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204939d50212d6492e23e7f3ff583044ae1ad7f01b173966b8fa83491e2c94b7ba022033f1a5538b4790cc5cfdf0d52a093bfc9e579b4da08643c3359d3ef0f39bb34f", - "id": "202834102dabee749fb707c8f620ca53d51c5f92aaa4113dc1b86d7989433ed5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2940301143271, - "fee": 0, - "recipientId": "Ab2DLnDBmKqcwBuzhQUa6wWdCrECZ7MpTo", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100eac45b9e454362b7fa3852c5c8ce5d2ca19db0da27428f75543d6ef075c91b4002207a49026e26676748eb003fa34f5244e0d9ad7cd881e90d9adbd158ab322e82cb", - "id": "f608e70123ec8b29777cf6904ff2e530f8c150d8f59aed648866acd8bd250710", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2940301143271, - "fee": 0, - "recipientId": "Ae7NncFsoDvMMmVqiJPiTmibiB1aW8XYk7", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207767c2f983946bed560b7ebb36101222275a8bd64f0c0b4f8b2fa2727f344b0202204222fa85950d3ba68b37be153d77ee9135a12d1f3a4ca7f8bf201d18502aa12f", - "id": "56e775c567f7f7c2c7e728221167d54bdd021f722acfee6aae640ff888c50801", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2940595173385, - "fee": 0, - "recipientId": "AaYk4acmLnvcKiiuYbxQBB71goY5Tn3Dm3", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a0546e807d1390df8e97606cf30028b6145d287a93dfec9f5c7b9672d172afb102207325221156e2b4e32ad04c80691f073e1dc6402b61fe2aa7296cc7d424d584ea", - "id": "89d8e7581c333ef01ce0ded3dc08da5580c358e02444a6c37bb2637b53e747fe", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2941331203166, - "fee": 0, - "recipientId": "AKJdgCXk6ymHHKaVoNhkgwtsS7zeSHg323", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220172d555b9f5ecc5268d9af740ce9aabd35ba38a1e011b0ab05783148bce1f96102205d4491c92d5bef700518e4ba909025b6e0da94ac550af7f33f14a2a47189b72a", - "id": "09b3d72c0f9d6051e30ec2f6dce7512820a02c0d95edeeaffd79dcf90e461fc6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2943241444414, - "fee": 0, - "recipientId": "AeykjWcAMwZ8jf9UkS7NoAEX7W3kJiBWUZ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008260a61c32c694392729d954b56d02ca72468167ebfe0c2ab4f96999606656d10220247bbc53dfc30f0e6c0267e7cff73f44f3794a77512b483b3a16a78f95cfa609", - "id": "524c4e3f8d8c26f3b78ffeec170648af3410bcd1c4ff3dd91b783cd9a2f229ee", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2975619527639, - "fee": 0, - "recipientId": "AGT3E9aU7PuT3qF5dGVQFwAG8zuXTd7uAp", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220051f525cc7336031431dffad29a63ea2aaba824790c6db30ca40d529d77d1ba402200601f5acc9a39b41fda57e49a3d2e4ed473b323336f82b8c39be54cf72611de9", - "id": "dabb12f952a645ab435977dbe2353cdd2609dc6ed1a672394d547f0880d93cc6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2982935509848, - "fee": 0, - "recipientId": "AKU1FaKbLTBfonNqSAUidf6nWS7fyaAs8d", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a399bcad2f889782a418d8c4f43fd50545a9762a5afcc2f1c0a2584b9cd9cd99022033c4e961ea62a4db1bedf6dc894b402dde87328fc5426bf7080f8181b0220316", - "id": "ce7293fefd0f534c30b3c2845c129fd297d3fd3d4ed7c24d3e0ed490801eb0ea", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2985301143271, - "fee": 0, - "recipientId": "ASgKLrpaJGxArbtTNuKHTQNVWyGitGGpZC", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202de43275dc393daad998ce1dc35038299d94e82655584b05bf1ad3d88ed4ad5902206722a7a5753f18a2f280180f411bbe0be380d0fc48d95007ad5381f367ee3be7", - "id": "9a99bf84368d99e4a83fa780867596c6be71a181ab0e4d80b99e843956435c4d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 2991168353049, - "fee": 0, - "recipientId": "AZePtHJzYCXrdG4tF9SBHY6k6R25R8ZBn5", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f5b8cb767a75c487bb2d1bc078baf5e9bc1ffa024177bec52cd34de5c87306f7022024806722c1dfa0212e49d7cc22c1251ed59d4c0fbd9963bca459aa0c0f64f521", - "id": "a36430d45917be491b50a09e86615f3d1a67af148173e7867509d704df2b1367", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3029944047194, - "fee": 0, - "recipientId": "AM8f4MdYwPFB9XKqvki7wt3MNBXK6d1EtU", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022002187664dbc4b4203779ce0717e3efef35f94aa241477a5e326ececf4897e3d0022029c1e31d1591c2c54f242b43bb27575b94561bbb82fd726f3c54738f96c9025c", - "id": "e0c8f8e46c5377741c86b6854281d0056919cbebffdf4d641785826709879a51", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3030774378583, - "fee": 0, - "recipientId": "AJVm2UANQSZBH6WhTLM8ZBqTNDwmYf48GE", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100988c50ea74333df4771619f0cf7396f7569ed020b6d02ec3bc3ab1b2e93e186502206adc99ee4498664293176a09208ca5631fb03147f6fcc330d9dd28102f088e8c", - "id": "90090e44f39b81ebfd82a3c3c68e11c81c22757c91460e309879913aac6e915c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3043211683285, - "fee": 0, - "recipientId": "AJi3yet6WjHiMNx8j41pbwNyoKfZtFbzwE", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f0d5d871e104cb93b22fe9937872219bb52695f3be7508144d260de8fd33cb43022064656b7b33df040d9a49839e45250c44780cca7ee302112a123694fd5ddf2a81", - "id": "71b958d40ddcd3e70236969225049f99b99e012608253a52102926154e8e6eda", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3055154128214, - "fee": 0, - "recipientId": "Ack5VMNG38f4DCpn53a8rXNoijKCpaEEqq", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200fc998d1c31efc5222de1447a8284cd94cde778da61ef0f13ec333196318fabc022049cb07ea8df855b9712d85f334e2c2fda9ba07a5d7065f978b677bd900e0f899", - "id": "2c42da9e75c92d6f66144898ef06ff9fcdc35853a8036788f3a52fa7cbfcf033", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3059124967808, - "fee": 0, - "recipientId": "AaFaBMRCVAF1ZBfJx9wgpZNxxANpJdJSYs", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205fb4f163f5d2276083b58ce3c7a5739f74e751d86050c6d9bb10b2be84c343870220407388a647c4d12beac50154d72dffa01125a3a2ed5f4c26fe20fd385ad27316", - "id": "a05319b6d84c6991ade6f957ebfcd3193aefe5937122e7afb1bb7768eeeb4057", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3131025807748, - "fee": 0, - "recipientId": "AKuqp4G8AA3XWNe8JwMhTdNFsjhrWhQ7ZF", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009c9c994a2e54b52e7dd638337ba112c43bc2150f740f470de9d5b72b852947d10220050af097f8ec27f51f0fbc9d052e5864aee99e7b6082a61e3f1488497febb899", - "id": "e521e3dfa3379d083020dc9c8ab5856bdac23ed0f412e1568d9704ebd73f4114", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3136161306270, - "fee": 0, - "recipientId": "AHWAQFqCmJ5RrKvicKzg4qEvSStWN2f4PF", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c2673236c613f050e22ea59478067f803201b9c88b51a4e0215270ebd6ce17f402206a586fbc5b2e0e5b27edf94bca44e9b136fd35a7be96f5d12c2c3030286a8196", - "id": "08a2b9d852bd06e8a2158c95142c88624887ae9ec667eddd62b02036993c3d48", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3141084221939, - "fee": 0, - "recipientId": "Af4K4T6Y13ZyZi6hQxSuFwWHVRZQEhP1D9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008aa3a5f09a85a7e94a23beef8c95851670ebbaeaa7d251941a92a3f44420951e02204070c008e27d95e14ac9fd50741a889efa464ae4c740cb44791edeeab2815227", - "id": "391d96b95f7d84192a1f319932167a2d2457624222afdb0dba66eb4b3ef9cd69", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3182675621655, - "fee": 0, - "recipientId": "AY36AeEFHXi5uevkukSSY63Qv29xLtBNzj", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c502e26db7ca217fb755fcbe660da9ee6c29047ddbcfa3962e6cee1c15fd213002207ac54ce32e991a0c654e5b3c684d0d2efbee9d2967f4edeb80ad823f4b19f3e6", - "id": "f5c46574a98b4659092e4193d2c05405973cf80be9ef391e824eadf89003f116", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3208001085999, - "fee": 0, - "recipientId": "ARtWsVUYotKEXTXxx1ZxCNvQUrQsnXaGSB", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203d060f9f1a25f865c48d773b58228dd2ccc8061b9903039940c507dcdf895f5c02202bb37da139cd3d4a7cf5f677f1677202e28d0be38468601e829ccce2cb925263", - "id": "8a6dd2571b665a50bdd9aa12e5908b8b7bef290dd7e77365593830c0c3504355", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3234184242541, - "fee": 0, - "recipientId": "Ab3SAMJGK1fTrQAqoio6uxNiQqUPCmrzxj", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210083d0d329a80d6ee339c024b6a8143dc1ccd2a4ef9cc36e2a2290f3edcdb37afe02203a76762e23f40fc99ad1bf9684a19d3e5060ab3de016fe025acdab08546ae83a", - "id": "ab3ddb2107eb42d4b92b1ed42c5c60d6ba432932db57b3f250c5ddef2e5f0b40", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3234331257598, - "fee": 0, - "recipientId": "AYUmyzDXiqHcTnFjtKQC9GHJzFQb76rTjv", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022017b50c51bbc0d381d134b7fa916d7d2e3ff07819c217144c1969a993af614f4402207aa346585c21d6fafd6a31eae748581272ec2ffbcc4cdbf2cd12f258a113340e", - "id": "47d84153cbc76cece88fe01fd661a4fb388a40c05495fd2d4bbe8af7b650e1ee", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3240854690572, - "fee": 0, - "recipientId": "AKdcJzAriRFVftFqfHkrdZ1kYKtSajjVGe", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009956a1473b920fc46270c1b8b7b53ee4be22aad70d53a9e9059305f1a8d3107b022035e82d31b43b221e7a7da617454ad1c27a504ffb107cb4fb9efe88539b886e4e", - "id": "a599896c8dab5a4251366d83c44c108d21f2e82922a01214d24857c5d965c9a4", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3264823516954, - "fee": 0, - "recipientId": "AMnGLCrRYXtxmrnzsx7bDzEx3G2W4igcx5", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100cc08ed2979526f2e9e0876e177871deb20ac16bfb094b240475efa11cdf5642b022005f4dddc0a80d1c9df8eaf04f3fa4dff3c5b349e5b4315d6f037f80ebf95aa74", - "id": "0b33f80be4c0145ab42eb74dcd63c93ef5dd8093b8cc2358182e644f12287634", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3307427638563, - "fee": 0, - "recipientId": "AH66WwUgJHCYvEbX8hTFpuKpx4UwzoaQEz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a243814491855ae7abe45fad6ea7c7e939903f198383b224091a25e22fb357f002206e4849d25af6dc5bb6e002f30ab0cf7f8cd939528fa4780256abe3f9f38f4419", - "id": "af232d8be6ed5cceba703d618a040d13db05286235b2610de8c4cda5668ebe8a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3324317837586, - "fee": 0, - "recipientId": "ALTNeLaT2mvuvMohvSjg8FjYhVDNxbeMEu", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009f8ac3837eb8b6363c0ec7788dbaff01a07d9cf68cccad905a67a8016ebd24ca02207acf56e23a7485fffa201ebbe3c515b99bb4121170da3b0884193416881a23fc", - "id": "577010da36ec3f0cca45de28e26aeef46a3bb7fd932b755609aac454e9626fef", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3332461324329, - "fee": 0, - "recipientId": "ARLUcoV2hyhKCzfy25Lk8Y9VWix6deVAYj", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220724da3de0142e6139d36004f68e5ab4eefe84b786c5c80d0374b319c3be8d6f402207276502244f50eae18d9d8cc7ef1636936809fa9f6d72461a5bbe91db9c8c04f", - "id": "65306f6058181b91b964039ad1c18f711fbe7b7d9f318d33a02bc1acdc7618c6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3333461562845, - "fee": 0, - "recipientId": "AHFojRfYcbsAhEqvKY8MXMsAc8MEkxwZJU", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220179bbffea812db28bea6ddc3e3863b6798af30cf9b2789d5f827201fbca974d302200ded60e75ebf3d9eb1f947bf5dfb216e8206a4882eacdeb7269c728fe47c0bfd", - "id": "705f8aacb1c7cca2391a4d432053872f3dc302d9ec36f1f399377e1b10ab1347", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3337241797612, - "fee": 0, - "recipientId": "AHRETqnSboGYrrjQ87Bnu5ovyKZBvfuS35", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009eefca56858fd766265713c444958cccb5d615b012747c011c6f5f355955c60402207cab37ed16c6f328ead3ef60c35257cfeff84c0e36182125822142f2f4a3c471", - "id": "4f16617510a64b071be9c9aeeda35eea4947d52625610d7c8af2d47dc144632e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3341104284118, - "fee": 0, - "recipientId": "AXNH4NZ1wsrkZ1PPFfSQFucDGwt4sfsGor", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e443d4e4a9d3f91f9fddccb71e70555b5376d5928da292c4466f0fb4bfa7f12c02202b083a62b3e4d139c3bbc09c162259ea43c256fb0cd25870b724cddb4d7b074a", - "id": "7664dfadec3af8d62814ad0baf545d16c8aca1be546758a259a05a2115837cb8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3359667184998, - "fee": 0, - "recipientId": "AXDfDrajcMoF4ssBKAj72AefFrS32A6ErV", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100eee29af59dce2e725f1441b665b737c9bc22090bd4b37a68cb79c29e8a041a28022038b10296b17315ce07bfcecd521104a62a7c1598d07ef17fc397aebfebb094ba", - "id": "388dfda809f3802e4f7ca49ae7da2409e195be0b231c037c0c0ee139227b5e74", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3411370798936, - "fee": 0, - "recipientId": "AMg61zEWGdPqgRcebwuY3nABTXcEf5ursg", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ac107612d5b3790a6640e52d8d5cb277f32c7ce79f3d9881641b8e7b613213010220353d4bd4188fabe59e5d8ac78d4135b57faebcd5e8095c1c7ab8d9c1cdbb6b41", - "id": "a16f6f3d94d84c9e83cf9ab117cc17257632d3b7548fe779f21bd02e0cf3db90", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3431641346204, - "fee": 0, - "recipientId": "AV4uwLo1v4g78ZWWEfZWt3zssgjS3HUUK2", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c6ca22e986389d94fa3da2973a1bcea26492e76c8fc8ecc47d2f754ee21e0e65022031cb3ffe69ddd0d63c0c40b089fd445748c9b0527e71d71970f2c1e987670320", - "id": "71ae8506d64400ce1c01558b7dbf6eadb9b915b8576f8024ba54929f56273d8d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3472495650202, - "fee": 0, - "recipientId": "AREUm684gmTkURsYWAb5XFSWjtUpnkHXM1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a6977f3021aaa15636b427ecff64771bfe698cac3e6ab1fcf1113e927656b44d02203bdb670754598eb986329abbf9afa637afced4dd83415f117ffda3a40d7c2da1", - "id": "e03a176681d276f4c1a44b84923d8ae4458333954e8917c67cea9b412d743ceb", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3485679678910, - "fee": 0, - "recipientId": "AeUU182Jnq996yw8TZRaDAPj4khgpxBjKY", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022006a3492b8a039c733c6860409ad2b6639d288f4638863a10955502162aecfedd02205035b3a64ac33b34cc81b07bdec6d74dfd14b28639df434b97cb55c1eb15a9f0", - "id": "aa9f40571467e5776f3ff8378598356aa77cccd4ae6d20b9911472393a3aaa23", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3485679678910, - "fee": 0, - "recipientId": "AesYuSHWM25csWzyJE5aiXD6yL4Vb6G1Vw", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c4de585a2f48a005b07f3cce3a97ca0ad829250496930b3bd2410b0740b8ae2d02205f46e8dcb4cae8879992e1352a3bfa5c947706c36bb8d288516169b536f3299d", - "id": "0116ede2fa14adc70cf6286d703f9dac6d7d29d2121b62a382a197f2e0c9bcc4", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3528361371925, - "fee": 0, - "recipientId": "AUxFccM7Y1rX9rgzi7ashGogxk3Am2A5px", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220750199ce472faa98d3eee8da3efcc0e4a381473aa1d48ace4731d7dffa78fa1c02203c91c647378029ce9944d5b647776989c67c7b3e153e7f3af0f33e709c9d0954", - "id": "8911fe01cd1cc981963d244e82226027890ff383183acadde7023091ff3ba196", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3531301673068, - "fee": 0, - "recipientId": "AeeJBq15fTimUFojH6XpR4FUAZmDubP43u", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100933a2422b0d1ce2180e046a6071652758838311737a3424a23ace27474eefba602203e72e72184db462d5af7d862d1d2d20b8eda36d9d5df6cd9cd308b6868a7604e", - "id": "62f6c02daf915e73a4440f65838b9bdc7cd4af1cd3361d7e3ece2755643a753c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3535124064554, - "fee": 0, - "recipientId": "ALfWJY9kKj9UQkPG9WpmaD6ty1xzy19MH5", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022056e64e74a7762a00139bc688a97421ff9ef58d1052019cd594855abb279de55d022075b33e73eed827a243c96a46f97bb3ad1c3998407d84a8d557f61f3e93fb08e1", - "id": "785e5330cca5c0a53d97c3746427ad1dd4e72d75e64567ebad677d00bcb3b8b4", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3556280867780, - "fee": 0, - "recipientId": "AccgnHy72MjgSSByZcWQqmeRgMstvJcuYb", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022063057051b56093a07affaed97bdc4c80fcbf7e3e9f1ca81d68347176e39ab60b022054765fcde969a830d58d67dc80f1e2610ced4e6275d3c261b44542add4ff74a2", - "id": "fe4ec15b065062d5662f9d352d1e1885ff2f907f2ba0c6a1528e98bebc2bc32d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3557938075605, - "fee": 0, - "recipientId": "AVEz9XVtNWEBn7DKziwGAYRFUcaXetU2y7", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220603807fb9a4ae361dc3743551f4cec9f78bfc9a5e6bfd00a7576196f8970a1230220586ce37ff801f638feae33e0449cf80c4a389617fbae8712a50e03e45b6e11ce", - "id": "f0fff2d878b1fca856116cebb41cae5a5cc0aff75d6b1c986e302722a81feadd", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3593815899623, - "fee": 0, - "recipientId": "AdWUn8FcTbrtck26543q1oGyaSjZFWu6no", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022045025274c42fbda104625bf2cf9320a01045aee16cacc809074ee6d315cc17f7022036b821e1e26e19cf0a34bb6ba82a3d1e5c164990f1257119677f81e019bb231e", - "id": "e2ecfc0a1f1e5e47ef99d7de7963e51d2af78f5a3671859487a835447cdf9353", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3599965360713, - "fee": 0, - "recipientId": "AGYEkwK8grFmYGrrQkNSsEbQTRxSv1QGBH", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d44a62be1cd41baff04021452b670b11fa4466a50b19624e918c56950c0326d302204734db4e45f8c2fb42f41fc3488cafea5187c051a4b5c21820b864e46336cda5", - "id": "f851283dfdb3e819303fe22d6accb80c935a06112ee8ccd6da917eeda8d9e2d0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3637230969298, - "fee": 0, - "recipientId": "AXtwLLdXbcAhX9j7YadfNoAbEAwmzUDGe3", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202d65e277703ac1505ec5becca2491ae4cc63b47af9e3c9bfd4610601b14e17dd0220659e5031db6fe356fd2297cff629fe3a67f153f05fecc76a37d12ec81c7f77c9", - "id": "737a7570bd435e95df00dd9aea0d8dd9ed6a2d6715919814d240104a31cc29d8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3637230969298, - "fee": 0, - "recipientId": "AFtvTj3CU7Vr2C3bDwNCDXDpbqE5TAR7UD", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008d5661fd7a233b744682e4df941f880b2a499996700246100d94b196db0297e102202c1086cb609d5d24d960307f3adf858268cfa85608ac887b6579f48fdeb2efae", - "id": "8c2a012cf5e9de46fc73d5cf899a51508af66e88951d8d17d9bfeea7b53cbd7e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3675376429087, - "fee": 0, - "recipientId": "AJqdLZvhCLntP4asFsVa7BfxAzvm5vL1TD", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c69c239352a791354a5be8627cfbe1c5d266c11bd6113db1d7a156f33ae5f819022053aaa645c823507cc6bab83b87fda3f3e66bab8e69b4ca2ff29928be6a7b7a16", - "id": "5b19f5b4f515679b9e1dc6a3624a2dd740595f48dd236076fee85848ed65dfa7", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3675376429087, - "fee": 0, - "recipientId": "AKrejHN9mQwjGALapuuf38wjs5TTDZGYPD", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022058f35b0134f4ddca74ab3e3d3494946276c15748ac629b4949c1132bbb754dfd02204d6efde7d964d9f74327077b2f693642b5652fa5dab7de8da16aa5a587c04c1c", - "id": "6388b60ea1d6fca35d97d365f06309d93e211362aecf97d0bf4771dbe192006e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3675376429087, - "fee": 0, - "recipientId": "AXH4SRRS9WQqYW6tr32eDScenDgfmZvn6z", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022078cc3fc5584871fc50c9df131c162cae857088ed96cdaad082aeb2bf73a7237a02202175cbca5a39833cedc9c394e0c896b5eb5c4369748e021b588af40539c80e1b", - "id": "e64991d57370d9e29549f930e3c72ba1d2963fea228c69d07da985f20889992d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3675376429089, - "fee": 0, - "recipientId": "ARuZqMpJcTxfyqs9FYwN5o4vHrH9ofLvnm", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207c4cd8d49f9a5babd6d545162f31da577ec194b1783c1cb7a518ea922c589b78022053d81b6610d827dd8e4ee4be48d6ad9f397c28711d8225981027ac283aea127f", - "id": "bbd93094994a8367c48099c29dc4619dcc5da73cf63caa53b1e529395b6b9a6a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3697295037611, - "fee": 0, - "recipientId": "AZE3bGd41tQLJqtP7kmn1SUQLe4ULUpNtK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b7153b2711d4d93933b0d9de3fc66ce2d459464e57fe7c6d502d8a0ca6c8dd3b022027915527227c59c301929b18c2f04b65d58d6dac510d9f9720689fa3bf8bd180", - "id": "c8cf09babe8f3fdfc44ba66a538154418bcb3c3b4c960ddea6d710e893bd4337", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3706851016327, - "fee": 0, - "recipientId": "AXMnw2SyrKVtEpkos4pYLqLyKS6nzBjWL8", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207b5080ed8fa34486c079d94794804e2bb8fafab6c643507a322fb8f1266d4f9702207d80e5d261ec51e6c371b2fa59926163828d91856d8c0b482bd23a03a991e32b", - "id": "8dc1c97b5fd6cc3002868749b97114243ba2a950e9b2beff032840548a875f13", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3709028616718, - "fee": 0, - "recipientId": "AWjDzWr3whEepeRDHMcLSZzfrYykBc2e2V", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e660c72942d1e4722f23166e5a781f5ec8ff9c264e6841695d9799934a9e859b02201a2e7e073c30e1efdf4b1fd17d3ef33914276e7931cde622c42dd3a90dc3f7e7", - "id": "4e83f8b8b7acfea0f43dfba0f8cdf8a8809eec7717d4519f8ba762e7328bd338", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3822391486252, - "fee": 0, - "recipientId": "ASf6GkdyPRoxAQ9e6wNu1eTcGzdCxTwU4F", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008980846f5d043bab9bc69d533094c47209a08b6604052b9097e97d3fb884828002203dd82abb96ec6873149fc3a1f274b04792c30dbeef84d15d274432f91b53ebc1", - "id": "b25ef9750e5e136d27cd99248823856666cb496d15c45af37ef77850791157ae", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3841576429087, - "fee": 0, - "recipientId": "AdJqCvp1xnvHCJKRBYDm6Pps7Yn1Ly4gnJ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ee2c9b676bb97f604b5cddff9c35cd2995b9ed514d71eec031f606fe249cdd5902203cdadf32092513c27107651f170ec3209e52e2fdbf5d19fbc7d6cc222ae367eb", - "id": "4069a73c1653a4dd78863adc651caf01c46b1ce2c603656fabc4bef4e15cc243", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3912040733393, - "fee": 0, - "recipientId": "AR4SrANMGxGvnQNzBtKo4PMiW6gpfnWvrS", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ac2967b732aa360a24d7f5562b138970d165ff8f5bd6c9e8aa8e45e69ed94b0a0220360bce61f2bbedfb4fb7f12ca83b1d9cc803a1e39512b1fc5fe5667f12ac740b", - "id": "2eedf249fe84cfd6b31f3090424050ae839909a12a3c1e39c777bc2e98897b7a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3918939514059, - "fee": 0, - "recipientId": "APwMLxdB8EHM5XXKG3gfT76Z939dLz1JCz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d3efefdd5f23c7d432cfd10d2519ba3dec0cb225c4df2cac9435db8a71646dbb02202e46cc5d7721e3dd8ea325ca859b01899359a3a36657fba4c93f202ca58ffa89", - "id": "d51629cab0261f943ae8bf7c72d8f33220cfdd1cda45a5f4fa5407919e9af420", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3937230969298, - "fee": 0, - "recipientId": "AU412AFph2KBNp1ZUNbMr6UQP9o5NSf55s", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d38cb807e50f55665d84172ae9f51ad7496e6afbf2128f7d79ff6b245b2dd3bd0220315d0693ad470da6c87599ccaa083645aae0bff6f5ecf9f6c540f2b333e0dae3", - "id": "04de02148852008a6b34df8e5c3ec16c21d4d84acc7176ac5a4f828bc14e16c2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3965251953261, - "fee": 0, - "recipientId": "AGQ6aRNRA165aF71WK26Wd7WBn26d928dC", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100996ac1644a8e8fa34351933824de6c784aec3656fecf58b00ecc73058100037202205b82dd95182ecc1b5933392cb43106c56a93faad5da958145e55cb066d055b66", - "id": "00887bc4d7329a1cd596625f9befcc07758c39b425cbc173f70338a62455f8dd", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3970035705567, - "fee": 0, - "recipientId": "AcvUN694h6sjffQYucMLacGpPuq1ZAupLp", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fb1f077325d32c64f6047e8bcc8c4110e079af9fdc76c171d1f8a0abfb32c43a022063f5bd3195cd0985a836b925f56cec34f3331d1fa0a9f0c0243583b7f785ba01", - "id": "db7c86a83a6e9fba3775696e6d06a5051cbdb20b329cd9877358d8e5bf3e1545", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3991462828751, - "fee": 0, - "recipientId": "Aes2M6fkCxfwRyguG6R7K234a8aB3SiD93", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022059bcfb711cd879f837a28c9ab64e342750b5a3bcda836c1aa232ee472004eab50220609448b1560201f56d821c2bfc180e08de802a8349b0f132c111cc5ee7d0e6da", - "id": "c797c9e6646543db243df8ca6f595651745b1262062762393342dced20eaea82", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 4000000000000, - "fee": 0, - "recipientId": "AcomwPvjAGZoBiCx3u4e7pnHaXxeLnn4MD", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022024236bc5bde500949d5031c98e8b36f823e00fa915cf01773baad25e20eb77b802201dedd50e48b684a7934b341f4e961bcb703cbdaadf3047bc3a63179992c80367", - "id": "65636f924d10c01ba4289d064623dbc2bbb19b7e6f5da944635edc38442aafd6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 4001132109901, - "fee": 0, - "recipientId": "Ac7qjfgoPxS7CvKMsGgPY9qPjy8MRsxtFA", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f4622b4a0e92ef2b2e120d951f547a4bd22afeb383700cf21f66cafda92d752702203d815814d38b4885ecd59e747d6fc0131f3aca76ad6b8f795b8d7d05a13fd8e6", - "id": "4b66a47cd8eccc4247e661526a5010aef5156eeda176cf8e0b1471be657790e7", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 4015989936987, - "fee": 0, - "recipientId": "AaHvdU5zBUEkqUebphZdJuRQx4K7QxGBc5", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f1843d7b8f388f8fc2130ac2f5b5721b98e6e1905974cee0e5bee71f7bb5359002204ee81e364ba06b6ae5fdb9ff4c3772291dabe596664d64cd8fdc7f9041386b9c", - "id": "cf6bac6a58bd66f9820e8b92a2b7a093d3c874d652f81cf3956c11d785133f82", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 4042914071996, - "fee": 0, - "recipientId": "ATBpKuXuUDFEo3uxRDJpZYCYvAuRxedMQP", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022036b9cc8a055c30695316e968334a488c1daaeb796f189549ca5566ca677d4be102205df0433a63bc80d39594ec5aada62412a8776468c5d8996d7c670669f0819070", - "id": "356ddf4e0040d24014d624050eea27429e4ee5002b07977cdf08878e93397531", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 4048316026508, - "fee": 0, - "recipientId": "AWd7KCkz7PAP9K8noozmqggx1qdWNHxoa1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022064ae748e8002a9118a3e4bb16d56dc25a8aa37260cfad3b5ff30bb0fda6031b902204fa1d3f9faece8ab66054c47647ad8a863759f0ce3c3c36edcc1e33162e6bf80", - "id": "d37818308a718d3d8ef3c3f4364a10b354b63af68840195c436dbba2fa18e344", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 4131665330066, - "fee": 0, - "recipientId": "AMuFbxddTGnj41RK9QRCVymbSbdkxrJBoK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204e2de836477641275c567bd1b574bd277216d355bbaef3574821b70ee55affda02200e01aa3604454ef602992243324c66746e0ad04b91dd65f0275bc349f4329faf", - "id": "d9147524e74c26eaca62684a3a6a1876cfe97e71cbb85b95dc5490dcb1ba094d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 4131706645547, - "fee": 0, - "recipientId": "AZ9hZpKCaaJ8c5GyjvNqWVxKoiHj8fUkxj", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220618744db99463616257c71774ccbffbad439cf0cb6283b556a8a7fd98e54da2502206456d52a8c767b60e5de2f3280f852ac049b66dcec4f9e389b8e801ce00aec07", - "id": "265d72b2909c0d5500b9dcd4346f030c32be27ee393d755a4dd017cc66094e4e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 4153588271639, - "fee": 0, - "recipientId": "AK9RL2q4zGWGbLtLViUHHdrzGbY19JyVWp", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f6adccb21f415791105482edc5d6a640964148330fa534d8f7e2e80f24b4fcd70220246d7278626b4b645018240af6d11d558a086e9baa7be5f4c02e47cfcd28043d", - "id": "be1d5b2d28236cb2e1551a702bb633e003582007cef416286b54553d1b09f13a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 4209041086592, - "fee": 0, - "recipientId": "AQqyqd4wPnAceW8SNg2Jwq7kw7oJdbu8jX", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ad4d36816a2710a030966ae3dfd7964a36e3d6600877bc12a5787877117b160802207c3bcb1abf4acadc60182ba7c5f242cac9276382fdfe31f8cc5c1d34128497e6", - "id": "0657d38310031c46d2207d04760de4dd9768f0f88643c189f234cd0f09fcf33a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 4241270774064, - "fee": 0, - "recipientId": "AQ77PDtC953vqib9FNM1QxgHS4c8hTKbY4", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202152e05672aaffa4dd6728794f48c789449778ffee43732fd04a7daf0ea10fa502203d3b1e6d34399f84c96363adbe3e486c4b766e402387b1c88097794f5d681f47", - "id": "faf38dc7c24d054c7b542ca52119cd5325bfa8e48ca24488e259594c72c4b6a9", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 4335474035753, - "fee": 0, - "recipientId": "ARNrAn3AagtTUXwwPgfNMkG42om4y4tjXp", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022049deea24c707fdc7650d34b049bf69911105a2591b93789cef09ccee23386f1a0220693f7fc8a1bf4ed2c42fd89dff05b49ba16efa2b607dc040c99fee81fd94fa8c", - "id": "4321cc2b30fb9c56a2d3dc0e68cb711fb3706c2bdea33bf06f8d1b532bb15ba7", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 4362372912987, - "fee": 0, - "recipientId": "ARqijV9qpJv793nYJpSuzhJJtgGt7F5vMh", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220330da9b78b7aa2553cc5b832e4780c160d6c2c9177a2c07240f7ec4aac39f31b02201b6a1e5f6d7003d1d2428eb6d89c1b4dd896a083fc37e136bb7a030322027d2d", - "id": "ef30241456071ab5739cbc01b77c888de52548ce718d290e17ed78dad3ce9de8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 4395705996499, - "fee": 0, - "recipientId": "AMZueSSbjv5eBjytCubTZy8gkkFov5GQJb", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220201fa8fdb645e5a6d8867dceaac2c15a03323f7df042a1c32d2cc0500451dc9102202980c35218796eabfe7755d019448caca47b7892d756548585cc2f10803ff878", - "id": "b12f8bef995ddc79c9ab8b62294b59ca171e59af53daf5b45173758fef8314b9", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 4410451714906, - "fee": 0, - "recipientId": "AeeTLvBUBeVaWNW6WU4dQ5RaM1XkFvAz7Z", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e82506b38a0e8e95f0bba2735b71ea2d00ec3bdb4a1e11519960933acb202f2402207e93347b0fdc6263d6a0725cafb8a15cf6fd82dca3033a5a9520408b37dfd3e0", - "id": "0f41c6cab1711f15519c238ad3913e0f99f45604f01181bf312450fe142b42f3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 4410451714909, - "fee": 0, - "recipientId": "AeVsSShGJR7KWQg1DHKEqev1PDSDREiDfy", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a53783236e53c4d54ae16e2172b9152cb44d78194a72a404849ea9d36e783d39022030ea460212b5b2ad93542eb7e27806e6b6215f9d005863297e9a55814071bbcd", - "id": "41666cc004f1e16061027115720b89eb3fded76b0032c3db25e90178fa158ace", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 4411611467971, - "fee": 0, - "recipientId": "ASp6DK4Fcrji5LHRFCwx17YPG9wdnXUnq9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220456e45ce3c5fc8ac7ff423250d7ba6248b29edce819edf5e1ff2fad55702e70102203f1a313fe9dd3705f217ca2a2515cc7e26e316ab7bd4228dce7e600a54f2d98f", - "id": "0515f9a1e521fc8e692c197a0467ab01b300ffc3a4780bbbd5faef682ce9514c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 4415891272021, - "fee": 0, - "recipientId": "ANR1PwuJc4o8Wp2qpc6uUk6wWjX5QRhX47", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100cf11b29ca14aca61107d25fac12d9a994c965392dc0ba3e1177c9f91559132ba0220266d7dd8d55b8eabe70e95190c53e9cb606c82b3d4c4f4b578afa933873f6b20", - "id": "ccf658c1b13a22aca678f05fff271fb533459d73fe00e361d1b1b96b64fe2d43", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 4507507351910, - "fee": 0, - "recipientId": "AVF5GuU4tJ9qd6YewAzDbN4sZkzFDNFgUi", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ef1c683d99d3c0228c8af10864c6981991f0cd493262303514d907e1a2dbe46802200c087f8aa3e4f2aff028e14664e5760873d753d7f846eb0fe1e9e30fb885eb13", - "id": "450de1b4d45c627fb948d1badd4cc8a70c89f3436fa5e745b795545b1ef06927", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 4531651714906, - "fee": 0, - "recipientId": "AcKGYwT1xwcWveaQE3dBqqqqTT3nnfpKbg", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c71f196cf735ce57f667d19e98ca7296c9dddf84bfa634318315edae96a67ba5022062cb8e1fec6e86e0f79e50b9b0c52a943a772fda7f5aba0cac56eca7cbe7066a", - "id": "d679cde12bd6e8ee711e0979e8968a1b97d6ceb9fe19634835355733b0a012ea", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 4535436795104, - "fee": 0, - "recipientId": "ANPpeB8JWX4gfskbcev8a6RYXZSSaMs3pv", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b86b575d515ed5ba323eb805882031a307b11d63c65249dbb52d20bac8f41f6702201ecf99a70e608349febe6ff6d33da93336357df5f9255757e9096d1bd1ab0743", - "id": "d496570ca0432b0f7d71fa40c94fbf7f9388cf27d7bfd1c18617e70c96546be5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 4641265354653, - "fee": 0, - "recipientId": "AXyPubrCRRig234zKtDMzzSVrPKoTR2vNt", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220312e3a6206e914414d40c7011162de5061089520ed5dc02ac0f88e20ec1a52e2022069011ece4aa149869d180c118870995de0280b5343791f0152705094f088cc4d", - "id": "afc269e369f0a701457aad91613679e5151e0457bdaa3ca386359882cb3ece67", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 4680692119983, - "fee": 0, - "recipientId": "ASZgEyR6XZQ9RXFoUtuyXY7gqHbC64vkU2", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203c43b599138e87457b214b1e3d1c1e83bb699d06a01b01e6add07df59b4c5b42022079f8d76bcb6bec406e86a5acb5cf2e926af71349801d6ee20ba89287c432dfc1", - "id": "121fc9d4fc8e2cc2f95508394b6eb20ce3593cf6c297fd4e0cc7d48d852719cf", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 4691051871764, - "fee": 0, - "recipientId": "AGa6Frh3DWJMmAsd3Nkn4bGt7n6bFwG8qw", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100808d7e940940c758d49ef8fb12660f15efa0c0cf5ccd391805a490ef877322da022005388d608bf563be295af2d05a993b2b1a87c93ece23ffa0f29c1bb412104b85", - "id": "0ac956b61b69b38a04280abe2c372042dc63a8267b67c4a6f23b7870f88a978e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 4697862065215, - "fee": 0, - "recipientId": "ANQkpXR4MwEdPpgbEdi3BaxF3qQMTGo92w", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220522fa6db9ad2b0d1a899e533b97002774bc90d96495b2493c200eb777a52da32022049690e22275a24280cbc7df79b99c92731c8b9b95261a07ab01e02c295f2ebaa", - "id": "fc6e5363cc3ebcb775be0446dbe8add45d7642f58ab984cba460ab5d966116be", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 4807392369248, - "fee": 0, - "recipientId": "AXYbSuKBYev8pU4TK5GkcwxWXWsqFL1Vvq", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200ad8d8f2a9ecbd9f954853681c27b5a46ac43b0db909544e6b23763932aad2f4022075e36c1e9e5260f5099f0fef9748071fb3e3202c82b0f685f6e56497c0ed929e", - "id": "a0b9708d51039b38e4285f869cc4ee2e29f620f84837bf3147d09e7dbd91295b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 4900011855261, - "fee": 0, - "recipientId": "ALZLdzs2XH7Ma87nS6qnGBvipdXCwXEcom", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022055e239d43d618d29581141d520ea39e940a627d113d417d39b5e8600965ea1fa022013dabd576ca157cf2aacb55588570d6abefa793db90617f9b52b5f8bdc5c0bb9", - "id": "bde6c2c3a29e7d20ef59a478faba012f38555663d3468c12748c1d0d5e70e292", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 4972512330701, - "fee": 0, - "recipientId": "ALT8t2gVWLdEgc516c1QTXbajnsDxTvrMS", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c4bed4d0ee6867797c4c8e3c3a15d169602302dff9d0f60a683881ae0a2cad7b022067e97a1f63f524e3037d8f29471b30007579fc372551e0c8e02f2924d8f5cce2", - "id": "c2f507727122bd6a0d0b78f12a8dcf1169d9f16187877e64bc24daad9679e0d9", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 4977195555049, - "fee": 0, - "recipientId": "AeNTL1HCB6ZBvKLHVMpHnGqVksTDktSCfx", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a0a35c51f045c7b5020d616cedf80411457f899f160d1edc5a326f827b886e4e022009084b2462322f577fb92d07b220eb0d5f2c17e52838faa7ef0dd9a0913a01a5", - "id": "c0d6bb7397e069bf8fa73f3227860c1dc2f262ebb274d8ac79bc70ee5e6c5129", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 5000000000000, - "fee": 0, - "recipientId": "APBJH5q5UPjfekwkaMemUzo32WsAGPLgC7", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220668c6951f67ebbd0aad2929ce9b00210a7d9f669fdcc1de95d713264a0630d420220630ba108e8db883d532c16fa21901ff3fd2a150bb6473d083a859416164fc862", - "id": "595117b36fc9609f6012d0afb10f3c072301bde2b65ee67d4bd5e00b9ea5b456", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 5086720977858, - "fee": 0, - "recipientId": "APiXiBgZ5Vk47zL7r6nXbb1feEcJw37a3Z", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220532e792b6107cc509119c9761433c93ec9ffda5cc5f4ebde8b0add5b84d9960b02200ef235d5bfb86c9083ba1917160fe33ec880f547845b80c456f4a2cd2ebdd380", - "id": "2e02e34a648a1136e0237953a75deb9dc336bfa2851b764d3b419dea851b3688", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 5145527000724, - "fee": 0, - "recipientId": "AQvzCAZgwfEerwR8Wbi2jtLRZe1xckgwnz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022046c8c7d959a7e4a01250674d44fcfae8d2b1a1d1beb302061f98fb3baecbcca30220795103528d96a6b86575d359c68af22b864bc6e1c412e4501bbf80d55690164e", - "id": "29e47540c5c0663a2a8612e77717256275a82a29084a03ec6b0fdc940ca3b792", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 5145527000724, - "fee": 0, - "recipientId": "AUNQekNveCH4o9EGHfuMAc45P46vNAkJWQ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210096a8e326a4c0ae121e4ff4428d3eaf00682d0894367cf354ecd68ac2063fd14b02200f21db687cd6b747dc4da81857fe7decae1dbd7d1e1570c8e609a27b6008d17d", - "id": "fc43db98ac4c5b9f1b3687e91da1f922a1328e4a33b3d5fead709911acf6c810", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 5152228598785, - "fee": 0, - "recipientId": "AbFfKLj8cbZCpD1dFcnx9M1quKbGyvY72S", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200108edd763dc24457372d2be73c2e0bf08c551e81646221bd02c298222bd3f6d0220304c7a242cc0b1c97956e7ffde176e16c89bf6bc024ad2f85edf0b531686b235", - "id": "ca1eaa9b36e044f32ce3d08b3d2a25bf6fa71d52efaddff1fa1712eeadf76413", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 5165668063555, - "fee": 0, - "recipientId": "ASxsKmBbAojE934PbqhJ1mhXXpkdrEMGi2", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220218d87057621c85e71f76523b123fab334c76307c5ac2030c572ded289d211b702206a80d562a887ad92a6ff0f5ce69202578f382e55a79665526ae3a38af5908f46", - "id": "fabd7438e73fef81feade0e11ed6da77e2eb6e0a4962b9f945cd6288139c37e0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 5229284067939, - "fee": 0, - "recipientId": "AV5Ap4mdBEJKpbfUZQYZWxx6Q66yJv25ne", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022039474147574e5fd182277aaab990a51c8254d41ac8d8740b646dc26c2877a2d6022033eaf619263d1b0e415c5badc403f76a4c9851d2de87c35f7ea0c63d35840a77", - "id": "e03816fb6db7a11b0bd2ade86f9a85765e3ab7a94e2906b6c0e30e7d8e0b5fba", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 5292542057888, - "fee": 0, - "recipientId": "Abos1R3ZsDqgNa3T62XQ2gsyE9ogYs6fPi", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ea11ad93fe457b16aa68e3b89751a8556aecc737d0a5472695c8731beed5821c02206fce4f51c29956e7c996ce0b9bfb75702c90983b4a8a59a3fa3dc75c06a20ef2", - "id": "05ec9e7cdfa7944660f3468045a013182795f23b066e02d0706be47cc49fa88a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 5308261029410, - "fee": 0, - "recipientId": "AGqBNsAT7ndLy25CcGrsaRCrXRzwhR3gLY", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b2253589018b40a1f81e3a216adf75f1b6498cb9761023f6bbc0f120c21ff20f022042596e6765c285aa0905e8d173880704cb843b1ebf97de0e92ac285d972bc2a4", - "id": "c0ac0b134286a830d4f2a84e8e391215336a5f1e46ef05ce9a1b7f47da0729d0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 5312153866513, - "fee": 0, - "recipientId": "ANZCH2mAMCUAA9TJByBgt1R9PZp8j2dnsX", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210092551cd132785e29add9309d136a6883834349f2efa084138f259c7b500dc5f102203a39a5ef2dc305e947758bfa72d6d5ebaa3afa3e36cff9b17f3aaaeb0079cb58", - "id": "c646cc3909e6032cd9dbd8df7d5827abfecda82eadc0155d7f2667f33e37207c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 5357843265955, - "fee": 0, - "recipientId": "AQJwwgFQ4F8NxNUqn44d8Kx6rB8AmJFiBN", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210090279d7a8f908e661b3651cddb1f1690868b9906c0744724356747ec26e1d4db02200942dbfcdd9e72db4cf2ca3fb4d20b6b94133a781fa221ebe47d964e8c03f977", - "id": "aa45b2bfbff8221f7b5809e7ec6947f39e57754d1866a25d2b855b8b54080ae4", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 5399929874642, - "fee": 0, - "recipientId": "AeRzn9WbFJkeExpJ1ib9bcqPFGBz6fYha6", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202c2146192848bd5fe02d0968ed6629dc03b5531b945d8e7fd344902c46074a5c0220677a6ade625198cfc73d9e60d9735841111dc5fce252a8ceea6ef5aeea325337", - "id": "d8396e0dc6eff0baaf523bdb9ec0a0f683ea01b2e7b481edab37f679959c72e7", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 5452743873172, - "fee": 0, - "recipientId": "AK3xPfpuLgDxvcUgvHE8G7nzgJ9TikonCM", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100dddf3ac76223dc2e41a5bf9c19b0e4e448e2f90c1e9970c97c4642c13892f68202203e5e2ad64cc817c835b951212e7a65b09e565f47707f030ae39b770694fd6f6f", - "id": "96fa04274bbbb82e73be6c4baff991523c86cb022cc8f4b0ca267e8f2b5fcd29", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 5454583384732, - "fee": 0, - "recipientId": "APrqARoKAGvFvSd2ipxmhWt8LMNoJPxHDX", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205017cfe8817f69a0383d53361483393f92c9275face9004b127e7d3ee4730ecd02201259d5100eb0ed196778b34bdef3e90a59b34dc0d61949d56890c8c1c994e400", - "id": "12514530353f15e198fd07bf42693c050c1bbf92f1094b9060ec2a940f1bae19", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 5534027654283, - "fee": 0, - "recipientId": "AURkidZfCN8uin9FX8ByFwCpCpqAs37uyK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220752c29c7102b3d0967a2a369eb8ee0f8fb09bff978cc00502069626526a6b7150220351f29c9591b208740088abc640391b793dc7fdaa56a084b1a12bde9a3ca8ae6", - "id": "d39878fa44b4eacd96c1dde902d6ac74748525845fde03ae3bd74bcf99f0e14c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 5596708324890, - "fee": 0, - "recipientId": "AW8dQKTqagJnXcRfDyYXiPBJgtY82sjSoG", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100be71df263fcfb94fea34c0ade0751d3f7b3fd25406d995555f2692179b1100ff022000c3c93736cd0bb38fb59f5a4336dae6486c26f643c8cb8fdbff1b06d8f7bf5e", - "id": "5e016277b51da7b156b41d5790536d3f643297f005202b5e504d4ea588451d31", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 5613302182608, - "fee": 0, - "recipientId": "AYoqmnDvAruDtVpKpmJY5XGHVsdtAsfYxu", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220171cc8f28be49906b2b55123b0b5e1dba8a0a5be228aaf517c3b5f03d1202d2d0220559bab26591db1c5348b69ec6b801f607ec8ba8b84030759b6edb6827d3ac0cb", - "id": "9c1b2c56282b48749139ac851a3a991ef9e4ae3926e600cff88a4182cf9b3e19", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 5623070875236, - "fee": 0, - "recipientId": "AGtJTLKoLnx2oVgTpfi9briAHR7SrT97PV", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210080d87159f97654d34b9cd2ccb64b5c3b44824405bf464462184bff3cce93d49c02202e72887f5a73adfc0101cd5e4f0bd019ac66e52c029ed1790890389395c7b16e", - "id": "66ee1e6db3ff2989dea803fa06d2cd01981d1833a98b960c79295b63c653d3dc", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 5648505606296, - "fee": 0, - "recipientId": "AFsy8pLNJnnq1R36WeJmQNrRygxPZ4TBv7", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210087518cb76baf699d909ef78187be4e5918f47d90bcc88b64612201fef8d672b30220668295a8f17296c8992a8dce97ccafb840b1a939660c7793f76c55ba4d5074f8", - "id": "1eda98af243f8de2c3cfe8cfd2b2de565e5e5b8af91998b716edea0da85607c0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 5648906556452, - "fee": 0, - "recipientId": "ASjpXv62BcY7wLgJLkos781E8HhDjfPZ4c", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206f1c839e8b95af5b74909a9febbabc652f35bb9cc6afed4dfb1294fa3a57cabb02200a3e9a2ff90d7d72808c5da906d873984a07576d593343a520279d5d81053904", - "id": "450f9e10debe655d9786b3e3a181b79380207e54a5460e21d27c64cdfe48bd6b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 5667502986102, - "fee": 0, - "recipientId": "AMMB8GyfXAnSjbEQap9UV1KxfiQD4SFhnZ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022041f56e22efaa29c67f715270a3ccf5f1fefd2b2c9a3a3473afdaac2731542df802200d42682d5a7f7d578f3d8065395662cca264afcf6c8941d558a45caf3528380d", - "id": "3eb6c19696d81659c7bbd979cd9d926a6473f86263b262aeb0ee10ea6c71a57c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 5680013606036, - "fee": 0, - "recipientId": "AVgqPjPJ4RjFpw2bqmMkvHGHhTUnvrT7Sm", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022030881e7cfb479dfdfceccfabb2acc03ffe03ad5e515c79fee770be69e107d75e022071b7098cb80f71d6a26cc8aa3b62df4d1dc56ab67cb86541c3a217ec9737554a", - "id": "9571f17bd17068f34b02419e07be1c2e1a2984ead5800a4b666b38ca8b235816", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 5880602286541, - "fee": 0, - "recipientId": "AMjo1KKaWVXTKxgY8f7h95pBGi2wjX9kuW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022077e2def23f7441b5eebf718fcd350c6a5af8207e01f549932dc78c00eea12f2c02202697c2c7aa53ce55a12e88f4d28a9a92afa6d2e0b03da2c81de9cbeea5945c6b", - "id": "1f79270181b53adc2a6d320fdda137a3a2b0a5d76ebfa29623b7399f1bcd1cfc", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 5893686626629, - "fee": 0, - "recipientId": "AGWQjb8AZSSgin8H2HHHHcMNoA4iS1HweV", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205097acaa5ada5c48df6a182a101fd1ad2005a521ed387bda6a3cf48a93951796022001c1d933f2d00539a616151571e013e10a22c25804ca301ddc65652164a2e58d", - "id": "394aa80cac2db93a5aca32bed46ef28feb1c5e49b0fc26cc220bcdb6a255c58a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 6008981564334, - "fee": 0, - "recipientId": "AKX2t7kQ4asoStjoSHQKhGVBuDLfXVwtHk", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207f53f7fae41d09c34b7371af87d33ccfad7b3fd29df5644dea82ed1e45706d620220027cee4f90fa3a0e6037a4a321251a53940df0b8d44564343068187d19e423cd", - "id": "230f86676f4336a0a640ee78f3534633d1af95728a495c47bc0ab4ef1d826604", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 6048199451708, - "fee": 0, - "recipientId": "AQQCMjGnEgsutWWRfL8BbUrsGe1z5HryH4", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220211e94fec0b2a86f27a27009c1ca016d618d6415f2745e444ffe1d601963f2d1022023829c5346a27ab73f3f70cdde7200df4fdff5be708c6f965874fc200d529a18", - "id": "b26eba2e7164c76a09a874efe75237c6ea80369105872855350b1d3227d0249a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 6062051615496, - "fee": 0, - "recipientId": "AdTSi59wjy3uZTv4tnenKL9fFWajaeYsCU", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d5e6a1d7bdc9206e118eb2552e96893ed4af47543c1ac692798bc2085ae43fef022067cf6d3e916ef610dcdf6953c778f24306a989041bfff1ef3f1f599b90f11570", - "id": "6d99eb7d36ba0a942ae8e0c870b31312e6445392c2a05dbaa8734c56c249f1dd", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 6099257525671, - "fee": 0, - "recipientId": "ARPxAfyT51W26UdTgSbfVRdjUpzeiLg3Th", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3043021f4867133c5f9563bd0e953c12c2c7ed084e469b2933da10ba51eda964f3f74d0220527964fd63a3c23a6e140d7d2c142a0297d02786577d91f3a97c863ff1f43f00", - "id": "652889dd48a67aea94b758b01f454c7126398882189dc752bfb11e0a7d06602d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 6114940797408, - "fee": 0, - "recipientId": "Ad2CVhECLL4ekRXmFVrYjGjALmyFmDBV82", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fa235782a7afa225cc198c424876b1271be94a5cbd18b8b11a2d3a6e5b1ea561022006309b82f6241beea5cbc446d902ae570cb18c6847060e45d6287a2d0524302c", - "id": "2be98fdf7807c6d82dc2d8e7263194164b9f55822de204b1fc9258b735cb9003", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 6177278671897, - "fee": 0, - "recipientId": "AUwfer8xFsv4Yk889R3n4oQF1nxAKts1tL", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b8cbb6b32084b8ef479e3dfa560eb6a99fcd8391c26299ec9d7339e98bbf3e9b02201effcbfd175cf6d97ffc072c22d3966ed4b22ff771dfd78f7ae7b03039e00bdb", - "id": "d6c0d6f8ccb456ff951f74e3033b503433185415be2fef77b700b096a1dfc233", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 6233789537763, - "fee": 0, - "recipientId": "AJ8vfPKvPPLJFdqVSQh7BBcZRF5GSTvBQJ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022073c38a4d26f344b6ead47c4ac5f7e6d96a8946d423da13bb14b24c84c69e68c1022071d29be6bfe25b7b4e33b7b6d6757bb435f9ad9d00b1824b81cd5b16f1e4279a", - "id": "277669ed0959b0a322f658dc6cdc807ca4526ef9b7fb07f7b2c55436cffe85ea", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 6249771580151, - "fee": 0, - "recipientId": "AaXTDvrMHd2nW34ENidytBxjtrALaB3uVF", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206c0337c25c9f541d130700ac0475836bff0a69b427ad1a352fa18155212ceebf022022db04421beced42fd6fb6723769f5eb19443f4cee8146a11f2386fa882087b6", - "id": "5de7ff26c18b4b4ad9ccdf0e09a94fad3053d7f61a4d07beaec231083324a602", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 6336348963748, - "fee": 0, - "recipientId": "AGeS6jmsQfmvS95KTbXLCFEKqpwUoEAc5b", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022002d5c9af048e1efd8bc37d2ad0e0aa64781bb3a738bacda828a9d2c3cb7affb302205a3594eaff82c4c46a6386089df34ce45aab71ef0ef1123e623cd64793c5f4d9", - "id": "c13088a3d622fd2925df99c39a4b25eac1632c68b3386f3351d9ede44b4bdf48", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 6347464915470, - "fee": 0, - "recipientId": "ALvAAwn8MHupoymbgiJSCDYiqjQrWTEQ1H", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203d2c5ef313400dde6be26935d2bf2eaa8f7daf90acb6dda71af277fab69b55fd02207280ed0a4f4114db9dbab70b067343a36ca6361e0b00cb9064a39730e9162b76", - "id": "631288a43196ef9f2d5b214a93c261d1453a532d83f3f68a441905899c5e5165", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 6608432032957, - "fee": 0, - "recipientId": "AcbUExwmdGDJgA1GWAjdEvx5VZv5VZT6ck", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e9c9364a47769112d10d48b398c5190e30c124d1c22b6d3bcd751976bd149bf70220297154a4646628b181af186fafc2f2b89c64b2d6b91b472f14353a324663ed63", - "id": "3def7e1baefa19fdfaa298305b4fed13eeda8ee4d8627304754edfa9b656e403", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 6690095694899, - "fee": 0, - "recipientId": "Acj7HFPqsAauRBAmfHqAcPiscUCxdiS7b3", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022034909f75febe76da183cd50b5f7e0745a50b6317d1dd1327eeddab9f42701a9a02202583150e149038dff6694c382b45949ec0d052d1edddfee4cc31da83d7c39311", - "id": "e912a67d2b2f1f5579c60cc12b09898804fd06914fb6b7032add9807c7666bd6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 6816039047765, - "fee": 0, - "recipientId": "AHBdGME8KmcvG63JkaQ1FndwmPWyuBWTgZ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ba60a9d3173dd42720e271a63126cf2b49f83f0846083bc0314d047be29853cc02206d2fe11664db806837fdf975675360c51cf5429a2a32ec88439f4969a40e970c", - "id": "4d1f9302f5b7ceb7682750384d414bf0a5f6b36820de505c8965720f46874df2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 6845037580681, - "fee": 0, - "recipientId": "AXFnbzewz6GyVVXuMhvAm7cyMLZRijpZXZ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210084adf931c399b8330219ecb1e0091fa02e7e400e8f44abffa0011c3d5123a8c702207333080ef7f923e35c53f55fbda2cd3b686fd30606b0d6b92fffafc0990a51e2", - "id": "beaa5d25d2d5156209f7a6bcea44f483080f1a3790f72e2e7405a1b7adaf7d83", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 7198886304127, - "fee": 0, - "recipientId": "AYidBk2SLnvrtgCu9ZYX8thNPweQXKoBgt", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100bbc9400997cc61072e38bcf2a3b4a600275332a5667fcf9ba463935309b6a98f02202fa932ee91e6f940b9d943255e1ec649517302c5a93b54fdf49847ee5c0abcd3", - "id": "3e725df96a6f88901607d832bad39c83e18f7b52e689a3590869c85cc4dff5db", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 7274098215498, - "fee": 0, - "recipientId": "AQiRjkc6LSFBc5JgQHfEtRYTBKzuibCm9d", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a0d5eff67117daa369f3b77839d2053ab16c5b659dac2f3457a75877cf346ad402206ef582d8394a23e3f535385d02ec135d09bf6aba3c1d812228d59052f3cac48e", - "id": "f13e17151b9761aa406da0d987c8790eb0556d93eaeaab95d5d2b91458a951ee", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 7350458828062, - "fee": 0, - "recipientId": "ATWCEtjbAVLDMNCyHmdRMeoiqcHPahb3A5", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206fd243d047585330ab1711f38f4a5d8de5d283df73af280628aec73c56bc13f3022035c0af74cb2df381b3e3ea2056d77859d085da0105c2e85edc6d607a6ed6df57", - "id": "9492b0c5b908ff768932a67731efab51d12491d654ddf6144307949596c4f581", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 7350605843105, - "fee": 0, - "recipientId": "AG61Zuk9tUxhu53EfvBBNzh6aLiHshmbgk", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220289eb9006920d7e06fdf963d3a6b1252528cbc897bec005c20773c2a6fcc1d5d022010e275229dd9e83053e9cf8e931e8d6bf28c8b5a7a40275f6da2d08e68f12445", - "id": "a2e69e4e5391966a019444eb1920d8e6c8793cee7c6778848f14eb8e2a711d7b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 7350752858177, - "fee": 0, - "recipientId": "AJ89PsZmopZgpAEJYiFpN4Nsf37AmqGFEJ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b1d30a5b801388ff04e1afbb0a1a08cef63e0ea4f256826b49438559914965e002204c6311d26e092f282985591802be6819a159e368f86f8bc72b39ded94b3bb93c", - "id": "6372eabeb335296df1f7dd2d62aaa635bcfe1259195ae57967a47b1121d16578", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 7350752858177, - "fee": 0, - "recipientId": "AcxafSyp9wY2zZkqDSfX7uM1ZPsVsBw2mT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100af2d76096e5de9e708de3bd6d68f3144bebc43dfbf09272a9f402870c2581e49022017a11a3726d0930d47a965393455304dee143d0eeb992fba84880474de00a211", - "id": "05418f5b2eaf40ebb39646280a9f1ba7850e96727bfaf4bc4379637ab169e7f6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 7350752858177, - "fee": 0, - "recipientId": "AZXTaxgDD7YqDPJLTkWwKgB6XPZT9L9Ata", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a54c0c0c82ee1943d9fdd66b10a0a6f70f8697bf5c2e5a70b108ce26669a639b0220463b72006b1f45a7403ac406181fbdad7ad4173d4109f20c25c890551851994a", - "id": "d311075ad854a0aabcea25b63cdcdf8f4b81ea41aeecb05e09f64c5e9d9056c3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 7350752858177, - "fee": 0, - "recipientId": "AeX9ZCUY3TgYBmxhT1eA28buQymhzcRkdG", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202bc46f5c4714ddec901a698d0ecb09e4eaedeeb654ca202f55f3af3256774a97022034c060851358a005d60fdc2c88a4706e0cd4252d1ed84f64c42227bea5fa0a5a", - "id": "f5338178edbbfef4715e79399f932057179aa09bca7ec7fbae3c170bffa5bded", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 7350899873234, - "fee": 0, - "recipientId": "ARnH7KwF2dFqZBaVtg89YRNpiFoN9E5s4G", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009a0f64be9d209adf953456872e1bb098c29174f219b4b620287a624663890ed802202894dd9517455c765ef6868b12239246a2b4a862cd9e5c5e53cb7e24b452f5dd", - "id": "833780d0f9ddbdd029d0a4c3fc15248044540cafabd9ea99f39ef268de3e559b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 7350899873234, - "fee": 0, - "recipientId": "AboFjwBTGZYhpHeBSRyX1gRifpmGaba1Ne", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009f02dfcee31f851c53ee9ba7747732b8395dc294e22ce326bba9087ce845939b022067c32661f0ea2f62133dd9367ce19762e8ba976ae5d9fdbdd0b5747880527ef5", - "id": "da390944985838649b7fb34067c7335926531602ab7fd04993f3d3dca8cfa0aa", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 7352075993676, - "fee": 0, - "recipientId": "AHJUzj6eMQ9331gQSJ8VMmxwyTxXgojdUy", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202efe05396510be9de3a85403629b8de370c7e239b9aa7ba8274a3dfe813b7639022019fb6626e456e050efa3b49ff2bbe5d53ff9c7b0f857bb46a60c4574ae9706e3", - "id": "6baf648e78dd4f865452d1b2a10008e9ba53067f5f7b33689715e1012e11b920", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 7467974903126, - "fee": 0, - "recipientId": "ARBHK6526c75WtrSA9twWuFbcvxSQXh1ZB", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100820cd452944f0b765c309ecf5888f897a012290fdfa80ada1d79edc8048b068002200a7b4d0de4d6da32ca4e02527c9630f08e2efcb2b5d9a2ad9fb2ac59f9236058", - "id": "b615051a5fe01170d7972e4cc06eb635e0ac7d8435f7122873308a029d64b029", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 7596490265803, - "fee": 0, - "recipientId": "ATDz1si1NgxYVhwco5FU8rziXikgzMswrL", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203ffe6e56154cd9fec39d3b5ca60ea6b371eb95dac9857a4365b807b329156fdc0220733a0c695b65af96e3f2b8b92661c6a91e1667867580abf25f146ca2362e2545", - "id": "7c77338e20a9478450a35a4ce4a503ae93c1268850c4582deeed42b2ea202600", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 7728600535371, - "fee": 0, - "recipientId": "AUzNXqYNtmcbPUesxouPuLnAqcvxeBv62r", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207dfaa07820dff0518a6781b5637985188caad8c308a6716b0eb5b8e49a399d1a02202a44037fcd6142cd558e01469a283cb7abaa6b63f383eed37425a830a38952b9", - "id": "98b95f131466f769280d7aefbe5cf7fdb7aeefab4dda10d561fd22cefb329e1b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 7863973424054, - "fee": 0, - "recipientId": "AcGpDjv1Ja8gybNf1Kg1y5wfjRvB65nLJ1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022001916ce368bcfc70ab18b04a0972d24a4a798c1bfe1ac82af88af3e57f05109d02207d702327da226d245e3e73db80fda6ab378037e21cd96129b5eda4bdc44f0dd2", - "id": "8da4b1228b425051845def8bf958afddd81be64966832d56ae85f30c09b55298", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 8061487401793, - "fee": 0, - "recipientId": "AYpKBgSEGotwZF3BvgpXWxGKXsawYQEr7U", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b566d3021fa2bd2a9bac9320149fdea4f0aff2e710affebf98a8e4e132270f27022036fcfa529097201dc793d55940b20861d2a359bb14d82e8fd0a1ae17359577ff", - "id": "7f88e5d7f79c63317e0c732c03b451b1ff2714bd5d87900faf43b979e551970b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 8091708746281, - "fee": 0, - "recipientId": "AMgi4FUnRNsseqVpBVQLcHtk2PxkRFkv4M", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202750a5d5fdb30175ba7a0e8a417026664dfde32cff5df156e5d73e25b26b5f0d02202a6ecd37f045c321be0526ce5b854dfebd8a7b29e646fed77e98a126458a62e5", - "id": "834bb22d473469b193464fc80c52058042e14d82d6e3ed85b463cef6da9e68f4", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 8150156945826, - "fee": 0, - "recipientId": "ATuYepEksWdtwk3PTdYEdjytkTKv1L3R19", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a2f40bf9457f828ef8c32f1bcbde320417f0f70eae75ee0492509a44986b97be02206a1fa49f2b1079da0af70eab644a2e161c69774bdcaf10d6b924e3b4b0730a9c", - "id": "2e66f27a9f97ace05f8168b01858118e23cdb033ee68c84ab0c5cad7d9154eb1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 8360754246642, - "fee": 0, - "recipientId": "AbA6wrkyQS5p5iDZF25BXcvuUgfZm3Hy7A", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201477fff0e08a35db8bea53057aa0b8cf323ba63d32e3ad28bed7da6d79007ed102200a5bc18c359443f02793e2673e615dca45013fba0dcf11d9719d80478e8d6e93", - "id": "c087ec57f646b73353792010f5dab487f12111ba61950c3cb4dcf26c51daefe8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 8820462384640, - "fee": 0, - "recipientId": "AZf55Hbr3KnRwHbZn6zoEov7TSkJGhDHWU", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b964e775cf55c8c3c174c1a06ab32919bc940dc74121b06f5f985145c06781550220452aed6f7d901c9ea5ccdc9a3c9538fd5f2fffdc8b4abd1778627f54674319d5", - "id": "206c25241d5f0bf068e1d532c0005957992176629f09a897dd39dada84b7d500", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 8820903429812, - "fee": 0, - "recipientId": "AankYCzRAR2mK7z2fRXmXxzUwJMknRPkDq", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022023e35b79c2cd4429d44e9a152371760a704819b464132b8464313c139e8be78b02202b5fcd45b45515a5fb41a997d93f55c089e65090a1ffbf31f07147445181d5a9", - "id": "62b7ad211b62f4c87e4dcd71d72cc6d9aadc8a4077379d96377e3a8fdf468b78", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 8909427869508, - "fee": 0, - "recipientId": "AP47UoDcZ3XMq3P7VBLpJJnHGjGaD7yGyu", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f5619dd275b2e1857001e6a803b2cc5978b562f947e569bb61c66d57a381075702202087f6b32d421f28c766fde6853ce0aeffb672903a9c065f3520d4111653d5f3", - "id": "8a8001b5fd69483fb8abc89b2c13626c30adcdb94c04a25dcdc1d81a5bc3214e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 8947739735763, - "fee": 0, - "recipientId": "AeBVmaLa8zk43EApXSKPcTudHKRqDBYFWd", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100846c22b8c3b999a50686b0df62755762c8f3d6e856d30ef3e467ea55f0755b9402202611440aa0e7b6c220399b990995b991324b3cf2fe8eee8d3724736edc00be2b", - "id": "e434a3e0a1ca8c488797a9a7e10361b4f0889c8528263f2d5da8de0ce2f923b8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 8987732597729, - "fee": 0, - "recipientId": "AYtFa1PZcaXinZSwvsjoym27aAAKwEAnaX", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100871e75cefa2f4aa5aa3e2602c3a918a98589889bf157f72e7f550085423d3300022058f068d7af9ee807c49abae45edda26876e1205504229609397e42bf26d8b4a4", - "id": "89f718ec38b7ac3e6ed5c353e8d6c6b7c77558357fb317e4ad45f00a593b4d2b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 9019606582562, - "fee": 0, - "recipientId": "AKeLaHxdcSBzMyM5bJUvThFcTHsVxmmatz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210092e17b11d4c617baefc3df8fbb432d34ff142e1eba516f363507e6f7d5dd655902207278a3fc300dabd87c6103e680d0b4f9a9a9daa9a7ddedb372d8a5039a5b8118", - "id": "b1a04d1ff1bb94dc1b0b1902a803f95f29b4cb75577899ec9ec8f0b3d042fa17", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 9073460596513, - "fee": 0, - "recipientId": "ATNoXbqJPxJLUxNrPoGDYXo4TL8dsetmgz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008120ddb52945a8a06d38ed29d2444d99ffe8e2ee7a6626ab6444b3484cfd94f102202f304a833c539fe335c91ec20005231362b5872d37f2f716ef8705857dd44bc0", - "id": "aa0f4fabc4952d57a65943c6d9a4c6ffdeb77ddb984aa4c6e73918028e697816", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 9106661500215, - "fee": 0, - "recipientId": "Aa3rBGChkK7iz2NVnkUx7pkjwgtgaZRpVo", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e61fe14e4167951da3bb22c81a12a387602ca09796354cb5d2dfa34b453e31190220493edba4cce40195451c2ef5c260726dd80a81f9e53a2c0bf8714c9b2cd33b14", - "id": "9db14bae790c26d0073c5cb21b54d8a860d79573f6a24004d5938db55917d20b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 9116425808613, - "fee": 0, - "recipientId": "AbSakR7RXYAEWqBh4btWuVXCG29HTdxCgw", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009d069471d4566b87598efb5d7f4550a511b7ce0d303f8eecae2532ec3cf1664b022072ffdbbde754ca2d1b57600ad8f0bf8db9d0c628a4f761479ea547af329091b6", - "id": "a3ade2de7783875db21cdb97071f1cadba19e2a5258fedea37396443f7dc88b3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 9176679868148, - "fee": 0, - "recipientId": "AKWjaZp5KyKzdCnJq9wQiF8umWCJL33E6B", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f6d4983def05d2a75eda8867eb47c6ec6cef8c4d13d43c85302161685ec7a324022055c69ebb708ede45540d87ac55fb4b240f9a1160a5ba8dd1aa7d49a4587e6572", - "id": "4fae51a3f14bd18dd23869bfaa3fae58c31142644e18d4422ff46f922f68ff1e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 9212629406283, - "fee": 0, - "recipientId": "Acj1Rg3SaJrZbiPsTRN7mfzKwHxh9ZLciN", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204dbd9c143b3e6d1335ccee6965087fe0d875d4d8d9c9d3574e018317508e248302207cc154f6ed0baee54eb44551e9a3d67b89ae5c539568c208b6e6243e881909f8", - "id": "5aa7d5de2c38dcc27f69d679349af0ad153ee494ecaee656a757fbf3cc1bbdf0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 9261801586245, - "fee": 0, - "recipientId": "AJN6KnBY8VxHfiE7YDyAwneXCwDVtdh57q", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ce0a2d090fd6bfd170616d273b648bd862a37d30e5dc365af8e70dc702f0763502205b95aeadb2b0e3e02a68638e5e0ddfdf74ada07ee5630e00b22e58392144f3e6", - "id": "006c9df41217c960f9888779a7fe79f5f7e30dfc06d450379c54aafe01820606", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 9431021629737, - "fee": 0, - "recipientId": "AHpsBCfa32ufzETjsSJj3c3hJNGhjAyq6f", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f26cdb6fece9de8ef933318bb3af05a349e888ee8ab47310aa829d96f2b044d602206f97eab55c51cb15bc25e66da6832db6a4b436eb538aa727a5264fff4ccbfe37", - "id": "f543ab6ff8794636fe7aaa81367bbc5b3c47bdb7f9080df77d3fd09067941b56", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 9456800520174, - "fee": 0, - "recipientId": "AXt8HyD1jBZsYE1c6x2HdD8HoVJsjHuqjL", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100dbb11f95e9145884db5207db7a7a45b4eb04bb4f0c833c2949b2019194f7c7b602202d8c32008367ff0d486a7c584eb23a9feaf533188ad2e38d2a7bcdb912561ac1", - "id": "ddd35a61d78d3ef066178e240dee956ba70f73b0ff41aa59fba2543c01ceee60", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 9529256927883, - "fee": 0, - "recipientId": "AXmh1DXiL4g4JjqJp2RgQdHnycZspLeztT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022039c3d55cd46134f05af871e13604c76aff0e92381980fe2d4e5e61f63efa891a02207b707a5e64a03e5ec1b6cce3372da6da6ca0ebb2e2bab0cda4ee104aac92d0ab", - "id": "ac0915e202a613fe3d133a3b8e0a4b86737e0d06bcca02202d583e5e3ddbbb3f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 9547731294407, - "fee": 0, - "recipientId": "ASjGMDGXLfB9fViy9qPqYGEjgv1jeuwWox", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205e2ad7e24d33353687c030186542c4ecbe2602a35cea56d4e7b241454e785e51022028d425089617605caac7b1827be5cdf18abe4c8235c2a622669c97af32f965ac", - "id": "d31f907d222323d8e5d6034811433ab67dd7dd334e0a5c6bbe24cdd3accdb501", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 9657132907103, - "fee": 0, - "recipientId": "AGFfszsJjBPwUf5ko5gQJaX76xFVoKbh2E", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100cece660ea46f4303e6b76cacb62da21ae4c8a6d11481ffbdf1b071e49d498f4a022034ed3118a40013cfc73123a39ced55c65bdcb01dd8ebccdac9ca689faf8a8514", - "id": "2cf431f04c0124d8149a4493ce3b317257512684868568884658512f5bf02d27", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 9720973358155, - "fee": 0, - "recipientId": "ALxR1nKJXgDfNtEuek1jaiNJG7gNtfZ6qb", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210086691e951494d4808f416e82c1d346653b04f39272cbcafa934b3e643447dbcb0220292d0fd8915227ba07bdc17bb7a7e946f6a50c4c063950fccd47a73433f5b42b", - "id": "f532635980304bfc7afc3ee2873890f529431ecc3217f8bd580f47f1369d0541", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 9861574288956, - "fee": 0, - "recipientId": "AYAYsDGPzVarAcqXrpUE8eYcftN9J2UNtK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d7531a783114009e2775b63dfdf0123ba0bbadd193e284a9076b4e02ad1063dd022041f3c3c3a9dd40d17483c4c01d2615eb89762611a5924718a517aaa0ce09a829", - "id": "cb3f0522a4824486a1277d54d509ea9956aeec80cc2fa77dfdbccdfc7a888a62", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 9967620875688, - "fee": 0, - "recipientId": "AaxB3RG8EhWNB1axLbDrxza3v5E9kphnwn", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c9f22c83fd1327fab869e27902fdce90ed952126e7c43c7e9afae0cd9007591a02202141f6f04a4a4b519fcecbee3afa90cac41a090c31393db048946d780735d33d", - "id": "a47732e4feab4d3817daa01358f6f295d9e4f07ab1e383f08b09ba0cb755af05", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 10271698022691, - "fee": 0, - "recipientId": "AYDYbKKZ22ym3ZpXcyzPWc7bnvZXRZdiem", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205b259b711e8a7cbef4e8b103cdd7af07e6aed38f65d0f91ce15f906dbf6dff7102202a0e181a4c64494bb7a679e0d86b397c644e3139e0ecd8c90e38fb7dbc798811", - "id": "a46b6b26e9c55a9a265845d4109e3e03ea963491b5efa4756e49a6aaea94d91a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 10298404754306, - "fee": 0, - "recipientId": "AcdSagvBLHcUuh1f3GbqhwxDZ9kuNgt9Lw", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201deeb7ffb887271b4ee12f3feb9b5c5ef4ba4c60cb4a1bc6555474cc96e420830220542663416f5fc69b7797d6a4d231041a6d4467d77d1598e19cfc7a64d89632df", - "id": "f9006c06167e9095b7398eeb11f8195d715b04be4689eebe59a5864def4798f0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 10305487746344, - "fee": 0, - "recipientId": "AGVBHkaRr9XWBLZQJDdV1Q9RXcoB67PBeG", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205601083db78190cda32bbc1af11fffcd7f933052794e7d4c95b6292db63c3f2102202bdaf8d58e7cbeab12ce6fa0d34cc70cb02f381273d533db553e15f9b2cd2d08", - "id": "66092335843fe18ab2c4a8d137fe0e341057060964ab4169383b461df9f7f385", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 10318455720429, - "fee": 0, - "recipientId": "AdbuHGsffes9YYyKBp9DzKrcQofg7zuSKQ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200a8c0a7ace259d0393f8c3662af8f8e27a0f261e69fcbe00fe99a095193965ad022034badec2675471d2d846e28aa0f4cc48ec9d1b8f6879f2dfd769300496e0dc78", - "id": "457678f9e0c30fd116dda8f82fa4e479b23a0139d36872bc4b992fcda5fa095e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 10360354001447, - "fee": 0, - "recipientId": "AXkBtARJ9ibkidfLMhzVSRCAuqWBxRaDhj", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204131d85f9493b052192d281fef2a87ecebead69c4e4b72b306c967a2bffd013602201786ecd3284b341843cf434ae92600de4bd044840ea306ef36372da4f8fe7e13", - "id": "eb6590373de4b7155bd45679378a312473be8ceee6c9c4fb86f2ebaea4c1be1d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 10445981844431, - "fee": 0, - "recipientId": "Abu2eNnxLNUKimhqKJg6x2aAcsUJStuCAG", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100eccb27c0cfc2b60f4ebaf647654132c4e7fab649368a77241c55f72dc8ca3025022016463ae4170d699d3cdd336c992057ac3d5c2ace3be998adb189840afd328d20", - "id": "b4b03eee17ce3bfdefba3d60783e5fefbfa99f5e2a3ae36d3a77f42dbba37837", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 10446382135839, - "fee": 0, - "recipientId": "AXBkJGbRzM2rUD6orebcoP3peg2xGbgT7j", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022008bd51d33b28766782018df754e853f8d92672e3ff570d1261fb1cb2f30fc9640220022208c3f0da9cb972e2c1888f1fb720c1e977b7376caff753f23fcad801a5cf", - "id": "818bcbbb73b9470f0e4d0e9606f937ae2281dfec46f55251ac7b77d8ae545bd9", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 10585084115774, - "fee": 0, - "recipientId": "AJXuBCyg1jivEDuJqrJwu9R19C6uNG3rHM", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100887bab7c2e2800b93cc9df58e418ecec30395fb35db6c3598d541295cf4104580220128140bf3e75736d5710c9df703b7f3a9818a6a1caeae847c0ab154645bd68c4", - "id": "95ea9f02ecbd2722503b7ad6754a29b3c743e2e114fdd403fc96b16097a3ff31", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 10792241696323, - "fee": 0, - "recipientId": "ASSd4LMA4BLtskUS3XvPbQYLe84qCJBF5V", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202885acb08d8088274b1a8ab4a28c796f5489b82412344c5ddec9f21389bbb21b0220525fa2842e1e3b91b98a5f8326cdc89d880e543da82be9adff19d923a87b43c6", - "id": "872e270c3eb5dc0d487a040745293ee5373e2622ddc9d34cf3e4ad793f2c6a25", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 11033661805931, - "fee": 0, - "recipientId": "ARo1r6758wTHS1QR8LnhJiyLcudybWPhb7", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100bfa945a5eb00deeb1f4774b9a2d46a44832d38877976f385be3fa88628c00ab5022024546c571207800790fab06037d3292a46d31e9c947acf318a27f67db8e42ead", - "id": "1e03b495436ab9cad5aabd942c84cb315f7c7796a597a56a6aaf9680f1124173", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 12262151610133, - "fee": 0, - "recipientId": "AWFxQB7mKARk8W63fNRpp6kZjVsapdFsDa", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a31f640dc8ff053899dbcad3ba8b4d67b1046db0c9cfd2dbe8c15a1b7fb7d920022003b089de0b92bdb55701c76ab22306636acd88e933f75cf6d077bd4cc7844c5b", - "id": "e550f7a823f274dfb83ffdd148c2d18b573abad654583438af7a702ac6de40f1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 12274908823760, - "fee": 0, - "recipientId": "APcaeU4K9uQXSRLRGEgDM1G8gtiBG5tCYZ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210098a25f2a406512474e48e14d7d009cc8e7349e7b4a51f2ebcd63f4996c2507a502203cda6a22c4fec125995d1163ff1ff725ffe060c6b720f91ae76c20a7217b2e6a", - "id": "736b8f9771bbec8794353162441c1dc30720dab02dda5f17721f3577b0f7b454", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 12417330032449, - "fee": 0, - "recipientId": "AHLhrDJwqQmHnZnhEPBJqfEHYHegt9Y5rd", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100edd8d1aa1c15c0249e1cd88ccd81edae73250b10df8c8a32549632404b5f0c560220441b966469b37869d5415cc7d90205be883870c3895db4c8b5ce2b4a7d0dba17", - "id": "9340ea9bdaa5155914bf58d74b856d532f1710efe6c569ecee144d1c6ec51ceb", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 12465317334603, - "fee": 0, - "recipientId": "ASECaxsSkxVDWry9D5fcygAY5ZuutNBvPG", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201ecaf13c7ce1da00ef9f8e28e95be0d15d26951dff1f742399e5298031337c8c02202d756de469c1f1ea127c4d785d723ca5c7f6991bdb8b8e3a9e7be2498f5c9377", - "id": "6902bbe0e9cb1b9cf2faebf4f96d27c85f4b1aacf9ef7b4dd52aa7d882b4470c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 12637331924100, - "fee": 0, - "recipientId": "AJ8YEJ79noVf2n9dm7WktKLy2yJPqmUWiE", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b4236f3e9b43c0c3f503906f146a6c736e8572264c9da1507de8cca20d7df08902203004c4ded33dd32eec7b97384b8edaec3cf17c8b0f813084703c289e17572cfc", - "id": "695597762e9a98153891ef3ce163835b600d7d6c8d622b15b53f70b1da3ec08e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 13156450295530, - "fee": 0, - "recipientId": "AMnJCV7YZg3aQ9XFH2Wm48wX5Q8KP8yf3s", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220798836f686318188a82f5a0b37e419bd52a94582e4bea79a981bfef94485a06002205539539bda455d85f826a824772f5a068359d2c0af5f8fa94876fa7b6a83f14d", - "id": "dfe1528b1eda46e77923bee940a97c678ac3ccf209e146cee8b4d9e590d652f2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 13231355144718, - "fee": 0, - "recipientId": "AYhj1z71Ajs7gQPb7TQoK1Th2HWne8Dicz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204e4e7921958f482891c6edf82e87d577bc1525ec26a1606239dc3bde80c7e20e022036dfd51919362e104d7cf98a1d2fcad1517261761e780569d60503dd87c85b9c", - "id": "d531efdb301103524d38dd7720408e6692c77d4b2581c46b44e98352952e2990", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 13433119945670, - "fee": 0, - "recipientId": "AJuwxFoWbhWGiSghWDuNLh7B2u6orxYKEr", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e2e10a21a73b7fb49a51c9ce6981401bb7041ee97b929781e9a33c55ba85f8fd022045871513d5cd53061f7b21ba1638ea8502f17cec0eceeb1ef66715712d3a2d92", - "id": "c37d982d2277da42cb03590feed99bf612911df0df4d0819c410d906e28237f5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 13711299443014, - "fee": 0, - "recipientId": "AcFJgpMAH1SCrCRcsgWfXgbQvDiBh7suEd", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206fb5cbaef0ff5662a750ac6a89b6090cb5e54934f86e1852f75b65801397fbb4022052e7eab49c5daabe9b69fe1ced745c2cb722c3c221864f9336584082bdc750dd", - "id": "96f9f1ef9345ec0a80a1d49ac3a366ce130174c328432db08758a69f694ef2e0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 14115873577166, - "fee": 0, - "recipientId": "AZLm98LrEyNEmbfe2AHV1q5V3FZza6x6fB", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202d808872dea296887d825d2939947ac1ef11f72f86dd8d0c6725f280d611ac9002205b08d41e9438076a7689cc07f0d74f3af73158568cda9b0469cdeb4d631c1373", - "id": "60df15ce23bbf98fcfef08bd24668c1951af818540910ec3ad9dcbc5d2600995", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 14159732932194, - "fee": 0, - "recipientId": "AWiJP7L3ZvRPzZyc6mmM9qqNcaYbL9ABxx", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204c66842803665c4bcf29c2043e1d9714e3724a1e1dcd935e1ccefe6228704675022010f26ee2519ced03bd61a8095e0830cab83d159c56928d7f11017c67b8c6247c", - "id": "9d5279ed2f9c0e85a47378bdfd168d29b83e2ee7d6ce8813c3a7b4a68fe50d85", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 14302397057832, - "fee": 0, - "recipientId": "AcRE9hpuKFJtyqCSGDS1QcAFTYCU17t1F1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022019ce5205866f88b78846a07a0862122d34113cd250df8abd884c7202603af10c02206d05348f0438e537108ae858798cc390f104c69047eb00aa47455bd89fff0b22", - "id": "5dced5fe4b20327ae767ec3902dfe102e6764a86f20fcb9fc75c6356cbeb7385", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 14627998187772, - "fee": 0, - "recipientId": "AeDZmqf4hg8HYMvpxJujrVWqCyVUyqZ3Zj", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022050e3a4396de2c6bbbc7cd1120e46a01863b9d961bc19ed42f98a18750e61a8bc02205ba8fd0e08d26df41708ae78280ba08fffe1dbdac48092b464da8b77649a716e", - "id": "816320ee8653dbc97e201b24ab45af6d3c4d182ca9d59b96c60f218803bbe76c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 14701505716353, - "fee": 0, - "recipientId": "AdTzqZEgkihPhhqn7isgQNM7UmJCFjSRaJ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205fceba8d1f594a4c189f6939db2567a740598184cbb2787a82560c7d33939191022054ec9894c1f430554cadace94c584a6c6ea5f907f06f5636de53d01c9937667a", - "id": "bbf0def2ca931ae79bb421b00044e5873840c3b761a24cd6db19161a069d8575", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 14702758612028, - "fee": 0, - "recipientId": "AWSCxEf8ZFBNNMturNTbyrwaHqJHTAz5hF", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220415ce13dfa1e2a0f62c4a1b452747c0818aeb16cf852e7c649a7e061b522295f0220738dd8e58a0bd7b0cb3035295d38aa9c164cf1a023fb69c2512f964ff840c0b1", - "id": "39aa37fb064becdf8f37a9bb1e55d3a1e8a96beb6be1fc1779967690a74dd7b2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 14702828851868, - "fee": 0, - "recipientId": "ALcRivRn5MpE7gjYPfhvdjkT7EidnM6AsT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022041e7c81b713fe8ebc58fe4d9db338b89b3663afdd526ecd31dcb0b6e9a8f8b1d02201eafac17f41fdc7dfa29c748261f9a0e79bcfac5e418a1c144b0d820dcf54ab5", - "id": "19270d05eff4baf154541b1e9acea7f70990c9fad504e043c281d384a856314e", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 14708415424040, - "fee": 0, - "recipientId": "AbVMJrPSe2z7UCqxfebGwvVnCPePzYqqPX", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220429ea8d0eb83bc86a8ecbde1777798182f219eae5aa56de3cae7bbdb4d04e054022051e6769e588884e730ca65b1886452de1d2f7050a9bdf758675f78c0606db368", - "id": "a116b90dd6924989225c4ccee132706146ccc6a508c8c0f2055349c71d01a375", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 14818222131272, - "fee": 0, - "recipientId": "AbmqyXrS3NaqZL1JanAV7pi33cxKHewwQP", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b1d6a14c5c53e2c96d5080df55c593d397771c9d4cdd9c87a35dcb886102e7c202205e2ead847be17b2d5c71b93b7b50acffae974232c1164971145e6bdbf912a85e", - "id": "5b864466691fa06bd64c97204b10e4cc4de6acbc4f9f02d9183e96f53ae9e6e6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 14822705716353, - "fee": 0, - "recipientId": "AMwimBgD3PLbthyD2pw6x5kr7XdAG81u4Z", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100cc44646a784672d659731b5c7aa58da1d4f010845bef874c5dcabd149d2c871702204e067aa1fdfcd05315ff030f488bff4160bc6d4dff149e6d0f248cfe0606e5c1", - "id": "ae29982e256bf9213db1e8944b73f2c98942fc31a4b107c2d5201f67595102f4", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 14895015891637, - "fee": 0, - "recipientId": "AYJiw1a15awqfRNQWXXuDmxpQ3DNjWitzM", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402205f487f6903a7767049c69f2d80637c45ddf757d5cc2b879df4b12e421223e0c702201ff2ad7ab479099433d5cb74b17dd647a0fb0ea38fe72950601d4510910b730b", - "id": "4b00501c8bfb24939da2e8402e40ef56c58a5c61ab6b4eedfc528b1b28f35157", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15082558701296, - "fee": 0, - "recipientId": "AQbJg9r4c5TxoPPMcywzVfLHavxbWCQs5f", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220502e111dd7864a3bf81e5dfa24abe4f74db23747b2ae7017cdae6cccfb72567e02200737316bb0d540184321f56e7e1099d857c56fb50d9156f2fa4356c56b369d6e", - "id": "430dc9734272db7f88762940c12c32b5063b5ce5042e8846a48937d2636e11ee", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15241050976143, - "fee": 0, - "recipientId": "AdYqsVoQVTUto6ALnocgCvnssTbDWnPAbP", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204012639c893ef39e7d67a0ba9fb133a37120007ae3b9d8ab7544cb2bcdda32640220232cc268d227799a8ea63d58697cfe0a2cc9de3123ff825ee7551a894d0b6d3e", - "id": "bab6b296e910810366f4ccba38ef01545ee34cd4386c0c1f806369c8d71579db", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15458231619516, - "fee": 0, - "recipientId": "AcXhb4DBzzmBG2USvxuJY2uEuFnMr7Qfhm", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a2ce8edebcb297f1948498412a60c8b736320ce1ad347043222bf034b21fa69402205e098d716d247f85e9c454b7b53b43489d55a91be9f19d792ef92b303b48e9e9", - "id": "d4a58d3b71902d221cfe3cf915429551c77a0c4d3c73c92a2473c3c151c1f9af", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15525088530753, - "fee": 0, - "recipientId": "AXDwt4SoPBiSvfjSKgZdV4vMTaNCgaFHMK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100eef9c401c97b593bd75fb52828a9df9bbeb82508006ff0d683309a7c1119e6f10220040995de4c4246197bc51ac7abc5094d9ac8ed8b1a8562ba85634bf430d9d866", - "id": "f3e07c51b39f93978aa8b6e4f133400e33ab808f17b3a47825afa75a58bb76a5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15609782909903, - "fee": 0, - "recipientId": "AaT8V4r48jE2MtWySFmdk2gqz3oz5RkXvs", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b46dbd720df1b60f59d8221ba0f7af053d7447acfe378b0763edc899300e035602206723c53b8ec4b41f1c374efe7620b94e62f0894fc90174404fe2d36c190ec396", - "id": "c37f2b2b221265b74534bb17e8791ae000793bea52102905f35c89a5fea5bbf3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 15840600000000, - "fee": 0, - "recipientId": "APpQDTuoqkWQex8ZjLCHxNf7xpYuEdWpJ6", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b6d5bcdb2466f138713b14a398ad38c470affb52f714693f836574106ea1cc3002200bbe4f8923a286f2e677e660c7316a815b444db2b6f46849d73402466b12cd98", - "id": "4c20e8ee483a76470df958bf62ddd99ee14e9a2536be56599145d28afe1700bf", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 16008869346988, - "fee": 0, - "recipientId": "AeRmfbh2GUoEitySmsQRACFRkPQFh6XxCn", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210082cbed89e51bde2a686b62c96c564914f843ca0771b18ee0f57a1266eb181d2402200d87f5c50a8be268afe0210c67a394dc63cfc5bf026db1b58c8950ea185dfd57", - "id": "9ca43cdb29bb7b775d487bc7392be4f6da70b6065cad1ccf40483b0c53e0b23b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 16171656287989, - "fee": 0, - "recipientId": "Aa3E6iHPVW89sPXamzE5CUfAYhEp9arAw4", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c1f8856ceeae2243ebb9a171b36ab449c637536365e033e244a6ec47688922530220565bd9cea70b34e2f7a7fe5ed5b6b4fe2eec554def7c32b400df035c5dd9997f", - "id": "e370cd7fae15dfee56e44b6b602c0bea7819758a9a61fe0cfb5387cffbf5c747", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 16171656287989, - "fee": 0, - "recipientId": "AYHTbw2P8oKpk9JyPFXKuCw6auvVtr1Upn", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009985662bfaf857f58295def71d71bf62109d4e7454eb087bf0af4509896161e102207bce078f3fba1bddb717c318f6eced379c983b9830d4295ae2f6f90ba2fdfe60", - "id": "7874cc7ba980cda4c93a50b415074b3406415f7a84a10efb43db211eb3bbe794", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 16191556704498, - "fee": 0, - "recipientId": "ASUXHuCsmbvLNURKg8bG33iPKid3dvyX7d", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022061886ff0eba8d281f18efe0bcdd9ee543c91a19fa82e539aab7a1bd83cb5839002204f05a0c30ab8083a8fbd9d1e48f376b52aee5c23470c0f9f270e04e88fbf854b", - "id": "ee246b6d6c7fb8aad48fd8dc16e11b86a796a21d24068a87f9822f6fb6db857c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 16746157299652, - "fee": 0, - "recipientId": "ATybACcBV3KhQEuhhJC2CbEUeAX5V9UpGy", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ae2122c8f375f70a1d174ec4d2d0fcd25936177ecb38ba43095d7166fc19da2802206c22f1e50d9e150d40e1d77bf1e81b153c546c3f55444e9073c440f5f9a08467", - "id": "bdaf7fef1b17036b8c7e15f7bd23c975166b368dfcfa840b5e569e5e95b71d49", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 17763076895273, - "fee": 0, - "recipientId": "AGycSD9trbo9XRQh7cFjk68dniLHM7AfBa", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008ca39400df66d8192aaedf44bc2cd791bed8ac3e0e048f3a94da6d56e201b6a702205fa0caa9f2f27a0d5321e06b0e4a68ca30af1813f7e1069d8e70afa378f794cb", - "id": "d5102ff88df36c6c97dd02fb8ef8e178ea72e32556c91a2e36f41d2363cc4e7a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 17882280422877, - "fee": 0, - "recipientId": "AYzPTsYgUcgZXi1GjA2wHzutz7BMEcbm5z", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100da21d666d853ed342f3cdc1f29eb6e6a557ca202c8876723637b51afd38499200220453d1e8130029e2c9b27bc97babefa23385b46f42b25dadd9467e867d2a6a66f", - "id": "d45a0dad2d8010afcfb30088104c4821dafaffa0c4348db0004e95e4b330fa24", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 17882662903696, - "fee": 0, - "recipientId": "AJAz37b4PJ9J5tnqBoQy2TDoDE5TiN8qnR", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220796c225df7d57a949b38b5dce6ec87cd4e8c1842826369e19ef2fe672c8cf3550220061c7b547e460153c1be12930ca3e9d8fa39edc2cbbdf550d3286ffc1bc2a628", - "id": "ab25cc4069078357692cde0f4cb9d850988fec28be74f7ad3e97c377bacec8ba", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 18446724051788, - "fee": 0, - "recipientId": "AGjo125YZU5Ssop4kuNTUYSeWqxMqvKA6c", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fced646103cd17b38cce5ff86201c1426304b6ca429e5231422d69e1db3ab93d022043255a9791928cd34118c57b07f1f587811179f29f8065ef35efbc8a698bd61d", - "id": "197db69caeb74f3de59dc23a8c5d65878964963e785874dd6b8474890106b791", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 20225218326294, - "fee": 0, - "recipientId": "AWDLp4YdsBUdxtqBjC8J4jNr7dddSCmbDJ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203f5912d44a52659b0a679ab303f5044ff5413876a759cd20974afe45f0041b3c02204e313f1fd22299f8f811fd603f7482ca519a8ca9595694bd28d0416a10952fc1", - "id": "0053820aeed9059247f556586e9e0a4109f4579fefd5245cdaf52f9fd901787a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 20741626925528, - "fee": 0, - "recipientId": "AN9sqKHVipVtacB39BFQkPa6dDhdSbUJ4F", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207f0cc0e15878619c6a0eb4a321492c62cbdb57ea87c5d38bf8c45fe8f188178a02206312324c971349b94bbbfca52ad71928386d6810194c2e1d3d0d7ea9d1f0b216", - "id": "1eff5e79d10063be3e29e764d3a6e4f64cd681a0dabecd2568492e25355bd2d1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 21951221806397, - "fee": 0, - "recipientId": "AS7WWoFGGutbnpBg3GmzqSLapSRxqNqoTZ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c98da3c32cd3fc557d169c23b454a294d7c226f5481593b22e4b4b0168b3110c022063e54d574b1580bbc056eac3598f96b3c6a6bfc4ff348ae3861835e6457eaf2a", - "id": "c14b7e1b79336f7c4b26ccd962d0d594c39b067cfc7475a2a577725937e1017d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 22059609327388, - "fee": 0, - "recipientId": "AHDuDQzUhW9r5AEcxWYLg6rtnAej8LpjVg", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200645d5b06ea85a4712b6dd58dfd40731036928dfd3c72142558b8d45d3889d2102200b2ca62f33a473edf0330d1773c505561e1334452d0bc1aad4eedd4a9771e5d7", - "id": "e5bbad079581ef00c4ade09d30c649cdd6b36b69437c0690561e7b950830a1c8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 22212505397146, - "fee": 0, - "recipientId": "AYo8E9DEoYD94vJuhFSmZ7Z7JdL5vUuFng", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210080fcc91a7c3aea6ab14ddb92132d820f48d44d08f956c6463a40139cc731051f02202f0dbbc598dfa8830d86d23ac58ba13a2e91c283590dcdbda9dcdc7a5ddd9e52", - "id": "f8e39f689d66d7277e0afd9c5e8d8e90582abf5eb2517ada993d9db8b6a4d5a3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 22232699614369, - "fee": 0, - "recipientId": "AL8BTYeajbkWG8r7A2uYpAsKoX3LMk9uga", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206259fb0a490e9fc37569a4f1fbeec01d783a53a18630b70d2ebba2bbe0f6d270022020025b4c0c7215410bb5ab68d5c551a377e7bf7ae7e364454b7baca54f1b045e", - "id": "500ce8f0b6eb93696a6445f97c26e559f93f043f80ec4eba7d8e59ab30cd6220", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 22622858823224, - "fee": 0, - "recipientId": "AWEmVoaBW9Xs9mt14YeXxmqfmSJ7iLszQu", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207d52cc181b70569c0f2058e68603232d5532b5ca9863ad0464ab0af2c29b369802201e7ca2e873ff0f73427d1afb837220a89f17204c04c41c15dc5a32b57e1262c8", - "id": "74f0e117703a37fb072ed990224d3173a02ed8577441faa8704e767f9dbaa517", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 23205200171281, - "fee": 0, - "recipientId": "AdCphTbTtmBouY5wTen7MSzjy9fc84J9M3", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200ac08f44e5c63a577d4dc5536ffb1bfe437813b5e79073d3118f66011c78bb41022034517534731c508f7c6d87d44e5848cd38d8475802a453295ec332ba79fe1366", - "id": "7622484aebbb489351c45157af39ec0e1c2f1c75ba8b6d3cdc5bbeeb87cd32ac", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 23285447659034, - "fee": 0, - "recipientId": "AMnNU9x52nTd9kEu8rDQu4wrDm4DPB3SCi", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202b899c4adaf2d1ba16c09c995dfeb02489ea611d07ed055662388ac291f12d3b02203965814654985d31c688c2678085328126fcc1959913fb6cbc1cf0b671a85e54", - "id": "d2174364d96891d86b3de6457e579b53b5750218ef9bbda87b5cd9fbb0aa24c2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 23749226298416, - "fee": 0, - "recipientId": "AQFdF9mpwxWsjMASsSQFD3kMxghDVfkWh1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204a71c021260c33ee6ae8bb5966e6ab27f09b2c3f11d8123b85c532339b2f6711022042f89f016efa114dee8c5944f160129dc5b1329ecbc61222f3ea5d7a2cd0c547", - "id": "d231ed2b05da5b4771bca09d3262cd4b66d7efd38ee36378b93ee9e66f0bf6aa", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 23788728527651, - "fee": 0, - "recipientId": "AT38VrTjd8gcmW1XWao5hHz7zA5Cxvzber", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402204f4d855fada8a76db9e26e0e79c9e67f51907cd2ea7ada9bb6d640c77d49c15a02206fd26c6dac762a78531b42e74ee643f541fab7b4467caa936a865b63302dab59", - "id": "4cfdd48b353e9f7324dc3991738c9dc8f4c93c51cc18c535390c5328a4ec5ed1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 25133628072635, - "fee": 0, - "recipientId": "ATYKgxB6sMBiW8bkuiq18eZBNM7ceyJ1zK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a7c5a575fc88063777204691c7d8c83bbe794820058c87a47099b4fc523b7ae802201925f71003886a98bd9a14d2e8a4596acf325186449825bfad2d2b0947e75967", - "id": "5d86d1704c731ec1454b149b7105c223ada5a8244045c91a7386444cbcf9fbc2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 25643974662172, - "fee": 0, - "recipientId": "AVQ1UscRdsXQZncshwXSZEEWqvPNMJXtpY", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210092d6502d9d4945e59d22fb7a1141717e41918428362fac7b365c5e6d2ee9bfdc02201c86ca71aac24424cbf2ac44ca3b77088cc7c873f826b8b6542abddb68ba50dd", - "id": "b387e98cd84f82172c378834cc12bf9b21646891deeb37ed9c2647bf400009c8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 25690453309429, - "fee": 0, - "recipientId": "AMpKaxERjupes1GjHCVV4Rctj49BJXQ5Qk", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207bb590646296b2ac4b2ae347eb2da399b9df6ba21273b463e7117dd14ab61e4702204861d99922766f5a05b12730ffd84bb9784a37c8e27b58aed3f0b896230ec082", - "id": "81b65afd6830ef600587c8f22cf425cb485df032f8fa236121d986a0937ba41c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 25763719365860, - "fee": 0, - "recipientId": "ANymwDRzUoszXjbJXQMhPBmLrBv37AoysR", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008815fa72ddf054b47d90c7a4b9f12c783eca5ce10a557caa79109ca2e51176a20220595c9d31fb930159603274e72362a8807999dc80b3bb49ec43958837ac60d270", - "id": "434775c5695597b6554e89281a194cd903f8808b655c65f1b8cbcfae3e39c89d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 25896835969408, - "fee": 0, - "recipientId": "AdLxpRiPQdsdZqxQWEc2kYxD5YFzKsLB5T", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022079e5465fdccb479bd275f6157553ae46ce6b5c51dd51ff0fd4ec517b6deb7c3d02205213870fefea75258a08f564a7920f2740f4026a8655fbc8d1a6efc6dae611b6", - "id": "3c33d4479fbe31777d0263d7a4b6c035be675a2a8b9eb9964353af2c43737a61", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 25963064569714, - "fee": 0, - "recipientId": "AYqoBy73QzTfN9LHCgvT7eH4tfet2RU4Av", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201e891a570ff244ae679fb0284f55f65595d7d86ce5ea42323708bcf5daab0b67022078488e4c73790511ed6c1f9bebe8bcb0dd8914fd9ce070d23ca5553923f9d775", - "id": "5016cce5130bdff278ac554c89615fce32aad318bb8917784b51fe40bbab4e63", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 26922263723607, - "fee": 0, - "recipientId": "APjnWFvHhfjudvjXHQ7t3d3JuW1efhiWkM", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203bdb6af67dbcc1a8a1fc4a71d9e7fd6ca66ac92d0321eafeb3e7e44aae2d25dc022045598a45acc95423dad43741624c047bd2c08aa878cf3175a789f3ef75e6ec26", - "id": "981e2c0669340b781e6989d2e4ed088e71df124c2c3f90eb97f024fdbea70ef1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 27197785575254, - "fee": 0, - "recipientId": "AZrX4pmxJEzr8WkANjFsofL4ww5UeqbVE5", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201b3c396a9b310ecc51420e3ba5d9a711269202abe71353aa9a99c9388b3a282c0220221c52a87c44586507dc1ba810a7aec7eabf07d84ed7185616a3ec891f224fab", - "id": "421acc286ec7cc4bea14a8d3cbe33e77cfdda80ac748e27e4f0dbfc09584bbc0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 27237835405410, - "fee": 0, - "recipientId": "ANgMKTXMWHB3WnU7sBeLqYmUCN8khwc4o4", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fc96ad466ecf9cde5f005a6124f12ea237e66013b782406db1d8974926be0946022063f106ce7ebeba7a8c56393748460eee5ac888385a2467cd495d0ac7e6dae9d7", - "id": "594abec1830a739b1cbf625eef2b6301b5595ca5f229f353545c920c9b74d2e3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 28691934514542, - "fee": 0, - "recipientId": "AM78rDegT1jy4U7CEsWErtPSuJCdF6fJVD", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3043021f33602385c5f0c9d5a374ab0a835c0ebecf104951dd15dc812cc94738ed6ff702202c366784aa6cec2524f816bb41b0eb397cb0702ac7e069a7a8938694093b868b", - "id": "c05ad581c646d9d8975a65e54a7deaf2c255fa6622af349bfa16a9dd753e418c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 29252093379711, - "fee": 0, - "recipientId": "AUL2WbCnaYBkSRfz3Ak11KA3Vn6b6eyM7B", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402203e1c6a962f0d9dac66fe40b694ddf60d1ae12a0e8d7d4d12d71615dc08c885380220597d2eb1eb70e8afac03f9f02a0fed3532d15958d431d41e852adf147015f43b", - "id": "909a1c0f7371c0e7bd5b668e80ee67c980c7c06ac95c9a8561e2d245439eb29f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 29403011432706, - "fee": 0, - "recipientId": "AW3MgXojRTWgrx4PzBmk5pjn5nyhY1aKH5", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402206afb959420376fd8e172ff9535ad4c73423eb6528b90d888ef4698437e5560e002206d00854f5d1964357562ed79f680e7d5cfe887ee413073645842cbb248f5c34e", - "id": "69fd70220c9ad3cef6201a5043bc55f944cabbdf705808c6331a947ffb7933e8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 29495120724982, - "fee": 0, - "recipientId": "ASaaHvXuvS52QJuvp3nkm3EC4pEAze47a3", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c3838c356872fd692642ca595c4c53678396cec839de9841a74a4799cd37c41c0220168441e0f980c92516b41c8ea7e337e384ef95ad130f2a62d297bafc5ae6f710", - "id": "87e6c248637dc0774a78b108505ad19ece71c9248cf5151ef517561135c5467a", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 29617494546387, - "fee": 0, - "recipientId": "Aabe2A3WdrsrhBp8uTjqxUEQVyB7G1tica", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022011583f87dc647bc5887425c585d04c395f17c6bda80dd0fb2b310acde7294e1102205e64a69a81cd848f5743ec144bb932ebf18136f952b240f5f579e9524ea1c61d", - "id": "ca4e72b41eb5b6bf5210d47eedcef40cc9ce15168fbeea443dc8c179ffa6e711", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 30052189818242, - "fee": 0, - "recipientId": "ANaT8P38GwSHV9mcCk7cEZZAieB3Mp8jxE", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100dfe6ce17738cd9e3565cc2ce92f2b1171104573deec8f7c35ebcf39b906afa5b02206310b1b28588bdee1c4c9cccad579606a0150a73fc2500a78b7f126c6a30a736", - "id": "1aee700c3737c07c9a6a8dbb6ad404ab7dc313af7e1e0c63e07cbbc1b3642845", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 31009000000000, - "fee": 0, - "recipientId": "ATgAA1gP4awvYXk4T3FrHRgpNsVtaBU5UY", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f44445e667716c93963815e8872bb798f050c69dd18cf11260cca530866aaf6e0220741085d44bcc255dbfc4a8f34ba652ef20798f50ea350929196dcdcdf79685ca", - "id": "2f5f4923cb78e7d9aaa2b5028c16f3ced1448fdb6749b82711b46d469865bb1d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 31239229496679, - "fee": 0, - "recipientId": "AUcXquR6CPooj4FPVQomhCjfhJik6KTzYp", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e20a35c940073e07cdc048f9cab3ce5417ee3886790f8d8211b72d0d2c68ae97022018201c4a586e505c12d7eda3a6a8976fa4009bc8f10e11debcbd6df8c92bc59a", - "id": "11d6023327daa0bdecfc7f0db4b7f476270cce07d1442af2d81282004841f302", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 31413424826151, - "fee": 0, - "recipientId": "AdYVznebAKBjBGhNuKeKA4zzXLFJBxX6Z4", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100ca7de35722d5a049d61c01a8bcbd7df1a990534e589e5890d07cf7ae6181c0da02206ce232bf4f5d2e144e0aae9001e0f64f38b462720be5417ccd4e3192efcf54dd", - "id": "db369c7c18acfacd9d702e63c7a77e8bcb07d4e104ad8fa39ffa37489e2f1b29", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 31703556507222, - "fee": 0, - "recipientId": "AFumy9qrTPRdfjMq3Q71CyJGADVURsQUyS", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220082801ddb5cee6641ae199fc46cdab4d8bf945a602b60099ab0a6014a07f1b4302205aae82168430ad6632563426a4b6efa855d7ba81773a50894427dc9f54832580", - "id": "1ec3d57963cfe1528f5032fc045c7516f2e811ae5b5362a5e5e98b887abbdd22", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 32988434694317, - "fee": 0, - "recipientId": "AQpbXQB2G9fyoTsc84PZKtWeTANaXg6USH", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220118c9096756390292e7fadd471894e27610985552c8a69abc091abbce4426527022073bfcdb62d459942d9fedfc00dd3b7f473a2b7a8f3b607caddebe79788732adf", - "id": "f5a02075ee137276ace1af818d4e40826cc57ca42a28e2f4966008114f1ee3e2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 33301358574530, - "fee": 0, - "recipientId": "AGv459sY198H3RyLRwSUNUNVY2sdHBakyF", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100baa3c39d1f99a14adadaabda9abcc74a8eb0fabf4478ec84e44c4c981194ea9f022026b3d6ed87d29120f5338fa371813700f08d989f8473f4e565e10ae7d7f3a5a0", - "id": "f85ed28225d31a5e12d1390e288d870d3fda8c31004435e7b581fbef143777a6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 34838200000000, - "fee": 0, - "recipientId": "APz3bVED2boFzmM6X8Ri6EptTuwYecymNG", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100bc5e1636cc1a3a20189320632b53d9ca4dd4d6ed236cd79bc39897cb32ce1b4e022012c647f2c41f7f7be18989d37b837a1c597b9e8d9db34830e8c96aedf793c36b", - "id": "f762656f41ede6c6b2248a567e9338fa5fbcffd6e3acfcd166b3d7091dabe45b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 34933049632938, - "fee": 0, - "recipientId": "AGnmhUFTHK9waUB2RvPKcGLBfxRow1Hz9e", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201feb35774ceabcbfc577b257045b93395c3eb0e81d91cf4e0799d0c74fa9db4502203fa395d409e2aad11c3cb7a0db6d2904cda3ec8c850b810b737202a9717d90b1", - "id": "9f9b749ef794c617b2136b392f09d358f27c1c7ae33d917812f777405d9ca61b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 36753764290883, - "fee": 0, - "recipientId": "AXicS7Jbvo9wCN2uVa7RfBLrBS4oPHXvmF", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a9d7ffc30ff5da829ab6a0705fc673c208fb1d90b4f37865fb859fe32771425a02204dd95d698733a1cd9ea1ae28044186dbca88e643f740593c4528e2a225be7656", - "id": "1f308b5f48e5396ca4b83e14ad69a329a486d695ecbd6819be782db4e79ef161", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 36753764290883, - "fee": 0, - "recipientId": "AMKQ7YtVjAHt8mWniZsvj6rqmA5jzu1rnZ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a75993db6caf823dc6d38968f205c3fec9406d2e215791a62cbe9951bad8677202202d0ccd24e0c9757d557720cb40182f5bbbd4f17b756aba16289de6190a2e7205", - "id": "dff7c0fe0b3548e5b68bc7705dcf7a33660bd77cc5d66bc1a5445f1ee5eee757", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 36827565849579, - "fee": 0, - "recipientId": "AdUHt2sqD22q3Jhby5K4nSVhBjPaBDrcN7", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008dfbca2daed7bead47d885fd3f763a75c4b076bfcac2ad209987a2c0a2ab913c022019fdb82528d253b78768f8b8e508da440fe8f2f7a34ad9aba2c37f91df76bd01", - "id": "22b6643f0273b7fba1e4c4095c245ffd0a59f8c75582bbaba951f0f626fb6b67", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 40000000000000, - "fee": 0, - "recipientId": "ALcLekYJLkWKLwEX4TNsQszu8nfQbWSkDt", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202a594df3905ee3f8c8db32a69857b686badcc6784b698f8ad1ffcbdc5cb5d2d0022072a8e72f42fde11f54bdaccd48de55ed2d3046b1f426ddbb560b97658a0bc83b", - "id": "08a515e48fde2ed1141f3b7c6726284d1ae7b5ed1dbef1742ec43bf52d229eee", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 41574092648018, - "fee": 0, - "recipientId": "AGctmMKFHy54o2pzgeh4ESHfqZ9B7zMnzA", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009ed97e274d06d1458aa4d0860329931ba6e3a2886f45ca9f9cdbe46f089d6a85022068a1f3f8edecbd96d580148602ea10709e92655fde424d68fb8d049d8841c418", - "id": "afc119b8eb143c9fffd3bfe31a39d7e42497770bfbad4ae7190b5b7b2001c9aa", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 42101522494901, - "fee": 0, - "recipientId": "ATAu9Q9UEQQua2UvXfQ6aev6eZAqWmSNFp", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022060955d98b915a99a40fab60a89c9813d050550f17ea432f309c62d1e4da4f80602205685972723f6a5223466af3fd20c15afb95938182e7b2a636a32f6ab88cb4628", - "id": "bbb16d3b87ba67e0ad32da5eb342cc9bf60b51825b11d2d435f94afcc4ec42e3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 43098358629104, - "fee": 0, - "recipientId": "AWbC9Wq2LyJki7J84AkTLJkzguF9mo89BF", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100fa22327b9cd6deb3153c39d8f5d76739754798733aa96fedf2283dfb9b1ba055022014e16da33b966e40e27c883b314341391b7f85ee3c1f272dae914533ba540c3a", - "id": "8a87ccc624c279197648fca4c03622ca87b4dbfac293377c260e536e6ca969f5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 44103929088831, - "fee": 0, - "recipientId": "AUJWBJDUgY52u89unPzk5oV9e9xge7P1Kp", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207069312fd56f16680a836c2a45772777be38c18c6f86287f414e786b8f2095d202203f646bbd58f31c2618c31649f1c48bc1f4ee3ec791a1805d788497179564b72e", - "id": "ba49cc0e31cee0207d2f0211262dfcf9787a314f0ce63d3c292f8f20c596a821", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 44104664164117, - "fee": 0, - "recipientId": "AUTMnQD8ANkE1wtMnH3aoPCrYkVntiaRDc", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402200bdcfb494ba5f808db740b6535ae3adf6719d3442d618e027314833aaa3fd7ef02200cd5039225a23be87af57866b6de9c0e005a643fdbb9d94e2bf0f1bc9eb4227e", - "id": "954643f48700f6776cecc0c8d28edd052b6ada807c4ed80d4020db027f8302a1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 46581295003558, - "fee": 0, - "recipientId": "AM6bDiAfJMXdivdUiGaDy984KA97ZEcKWq", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f8bdac69ac19d78a7db5398b5bc643399689262446788af4805d85766e705480022066cc9169d1a7f9f53351ee695e2016ca5384d8f7069feebd59e8fb4a9788559d", - "id": "545bd5d745ede704e8c2a8d69a2eb6925610f37e7fa79ed9483266d860c7f512", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 47047758593474, - "fee": 0, - "recipientId": "AWvqcwdrJyDEfsbveh5F7Nh6F1KWD3KAHS", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d41cbcf3488a0246488bf2cf73bf1e4e797260d1a5250ed8f04957b31586b0fb022036ded1aad7477562792bb697ed03f86d158ecc8dc325f37ba3efbfc2fa7c1fa2", - "id": "45838af24957952037e376f81200350a6d795b8435613a4845adbec9dece4d66", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 47594373941014, - "fee": 0, - "recipientId": "AJUkMpMFt8Zny1v1rENN9ZPZYitfePBvyz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100c5d4aa1d91f3a0b7468a31097fc9613e9c3830e1b3c6dc3926217442fb605f6f02207efbbe01ac68387e6fe0719ee635b4574d7040595d086d7030f903070f7c3247", - "id": "bb58a2aa2a8048b937156f3618663c1015f1b9ae7527ba8a0bc351c6f0bda349", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 51199117149060, - "fee": 0, - "recipientId": "AZaAZmaQgY3JaUTK72WUJEp9ZEgQgW1r6z", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220060cdc83a40e3ec69b3359c304a0ac46d863617599e2de03fc9a022efdec329f022018cbb65aea9d099cf6cc372a6599525b1aaf8a9cba53edbc95235764d265b3c5", - "id": "97d3f0573caf2552f8f5a696bbdb7f95782b98e5057f26ff7eec8e152513a3d4", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 52274142846490, - "fee": 0, - "recipientId": "AMRYJaup1hTjCsV79HCTn4ySvhAzb8xSo7", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022070140fe92e3dcf59f0ae1a87bbb061cc4048a8489d47cc37a3f3ef489548dc2302206163dd3630b960269613c98ca886637f32efc495f6c4e593cdb8c91dbe696c44", - "id": "223bf57b085d5fb463d106ae666648acfa042952e7417e4d22f51a100e3bbdd1", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 56564297142251, - "fee": 0, - "recipientId": "ALy8rPTjEELHQbkkDfsQTWT1M4s1Q4NFDX", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b5f571f366492003d3c17ddbcdafddee27389907a33cf348f7ef0b4d6f4cdffb02207300a2d680dd5ff2fe2fc70d71e76c875ea15572be63fbd583a4de383f99c6da", - "id": "5333df7856532e4d8a13adf69376b48c986a46f773a3e8677b5722baa45bbda3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 56945445022471, - "fee": 0, - "recipientId": "AVRGa6s7qAzChqfXrbJEhExzrTo1uscsf1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d41baf4236b93dac1d8604596cbdabedd8081b8666d239f2a193b69e56acfe490220046d22d267e480523194aeb5890d54b5e161718ad754321aebe61a5a9a6a4947", - "id": "f466357fc462681688413511091b23148fa0271b2045dbd8b28aa591db29f850", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 58952449862348, - "fee": 0, - "recipientId": "AWeSiyLTbvHyfqmUNNcRZABWZkcd36oz7x", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100d8f5f18629c666ef1aad569544d581c9c6fe2beaa751658389ef260559f946ff02202da47ce0d71725b3004c43de69c0fe0a5fc94dd7296d16b5f64c2fb9ce1a515a", - "id": "edacc4e6c26a064c04742503524ac91012a87e77f6bf7186b4f591f3221b7b58", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 60406501374583, - "fee": 0, - "recipientId": "ARviCJv7BdnDHCxPgFa2uqRLXNNtBqc8Jv", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b49e507c020746c9f70dcd26f52d071e05bfe9dbd303d528812a700883f7a0c4022009f6cbfd51b20e464451a6ebb5184c0abcfa758ca304bc88d031c8075c7d6902", - "id": "daa89776995d4fa94c6c64cd06b1c2d1036cfc9082151f9d3a70adf948c93939", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 61218300000000, - "fee": 0, - "recipientId": "ANLeC5wGgtqiDQcX5pmHiYayqMyWy3AYCQ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022049a07caf745eafae488a242e5066c8d2220b99ec3127818ff9ccb2faf682fee6022072aab5d565ac05759ebdf6f896a53c584961a6c0a362a321cd0efb2e78cfa9e8", - "id": "789e6d917e48fa9a4538ce5948a1c4013c189d080b94275eb975299d3d22177c", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 61966258534201, - "fee": 0, - "recipientId": "ASaaFCmPG3yPUwngEFoPA12KnQYqjgVKnv", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220449a94f1a85146353328281b937a9ce91b5644235ece1e2046a28d1199fc7f7d02200dd68146162a869688f44fddddb990bd2edb1c4194aa8c1edccd72cb1dfb7e03", - "id": "e09409c50d3ab8e86cec1216a5a8f971a8830c4bf6f847fa59c7eeff606ee9f5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 63613272588492, - "fee": 0, - "recipientId": "AYpQxRNbaiEL6FT7YUNmjNjRvpUfvRh6xA", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100953475d0a8a1f5b26eeea7d4697faf1eba8f4a4e465b387f6c3550407c2adbef022047a7f4af1bbad90c076617319eed901196e46a692131fb1c8861c3ba2df2a23c", - "id": "311931514d05d2af41ba127a24dbc950f7476f78d9184469947d4b3b59561c4f", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 66966172832127, - "fee": 0, - "recipientId": "ATVwQWf1mpyRa7L4BAkSUxz9osCfBsBopT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f571ced76143801d0760e47fdb4583bdd45d1dc46d03fe9195be5cbe0a9f44a402200f6a4cd36111e9b5dd06f966e3ebad05294ab03b5be9f6a231665ed4ae53a275", - "id": "28a7145ea1920ab8de9b6037f050627ffb2e37c9f9f1d16be8db7110f401fbd3", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 67622306078799, - "fee": 0, - "recipientId": "AKzAriWhTPPRXueXuSttRiBLkjP7i5wKpQ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100969e9376ec702a41b6da148d02603e8e1b4c1bfbf52e060aff80a89cab4eb3c9022076972f9de9cc4e883c63ab263cc76df952b0bc55dec80b958fa8069b94046f12", - "id": "7a6649786a864355ed73e0f194caab15593a11f93400b13ce6d0b7030057d903", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 80563884771309, - "fee": 0, - "recipientId": "AMFQ8md4BymLJ2ecw436fhyUyjyRM7ygzz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220188dd6b6c7e1c09b420ea73ecb17db20d85848342cf45c65192c77f5390fded502205eb3a4304dd2ee62ec1fa9e848dcf2d695ed92162e13b52271e3430ebde7eeb3", - "id": "fdeba3a56077063853cfb940d036d3ba75e03b6fa68d45de52bf58d9165c4b96", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 81926947255471, - "fee": 0, - "recipientId": "AMMDbSvuBNCi1oAXvqgBguAeTehWRTjBrc", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022043e6c8beefe6b5ab949adabed4830fd87d4639a6afd7fe8e1c3de3087f7f47b302202cce568aacb5bc2a416a20b6f940020b2e9c1f0404264230bf1b9c0086735ea7", - "id": "1630a5b12b69dc1317bce4ba97a2207c6bb4ff8c9e3b5af88d02f4b42829d51d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 97831169789473, - "fee": 0, - "recipientId": "Ab6JpVxrytQhj4QpBJ3LGsLvEhVmgCKk6Q", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202b44c2bf60f8af0927f9a5c62fba3ceabb58e5944dedfbd37cef6368b219225502201c1074fb7303b8a88479009e3a36dda95d6c8d0bc60770bd7f12beafcf680c0d", - "id": "0c8a56b4a0aa03b2f49dce2fd0e7f367096065a51128950188b553b8a750d4c6", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 98443286091931, - "fee": 0, - "recipientId": "AMQEjpMh7o1sJT65Pdm1Wt829evGsTWCJ2", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304502210082a8b45a0e351baaefcdddee3583b1b5ed7af81fdc9e2aa7243696388a5d6b4302205bd1469c96a3494a9b0bc8cc4513cb3ca57b8cf3b3250c028346d42666daa02e", - "id": "564f7c69a9cacf987aaee9ecb5bb726d1ae26a26111f0f8364611984d18b300d", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 100568151043750, - "fee": 0, - "recipientId": "AZdsyiib53nWP1wG5wara6XfvmmqqBWxWR", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100da0594484575e66f1eb34211a7d3249c15d0eb422be3e1b46ee364c4a377befc022041cd9cd4237cc8a1a7e9359adfe182da7edb24a69368ae1deb7e2fad26aa0312", - "id": "16a95bcd5ca6388de776cc01666f616f863f9dced646badfe97b53a266985bbd", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 110555322986976, - "fee": 0, - "recipientId": "APaRmUnSummHSAyHnYqd1BGvPqgYReEuWG", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100874c685c11233280806221994ce6ac3be8ca6f2dd88421991a1c9810614e9bb5022071ededd800067a5a3e6828ab6cec496b153c9331e5f08a417c09e583b05219d7", - "id": "a387aebbc8fefd8f0963f2ffbac837f5bed99137b19b19c356949bdf12c0d0cb", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 113717099151927, - "fee": 0, - "recipientId": "ALC5AHjaUUSaecu9R4wADbKdqzqf9U4e19", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100b5b9bf26d7020ca50abd010624a7443e7e4d0c5d17c50aaff12c2a357380a212022037b7e9e80dd9e5a092d99aaae3fe0722ff6e085b8ed42e4d47030e9497e6093a", - "id": "912d5b497042a6da16f4dc3fb0b7711f19aeadd1ebcb5aea32e2e49d6b2bcde0", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 115371683274712, - "fee": 0, - "recipientId": "AVNXBEcnwKmirrG3kcZSzHa6JvRkiCKqXc", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220401302e2773dfc0ef1a6b4b013d98fcbaca1838e9c688013989ad990a7eb51dc0220268eb491d53660b33ace47049d96e4c97dde689621044002f703425e17a3cc3e", - "id": "1dab66009d3db2e422824d6af3e727ff146c2b3bfb1daeef583742a920d51908", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 120262700000000, - "fee": 0, - "recipientId": "AHHpmXD7F8j1r5bftPMkp35ct9qGYiupwj", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100edfc8dbb54abcc1096194776c222e08fae1e125851b580f510ba5b6c6ea39f38022032b48c581a123b298838dba4a22b71ddfc51c0514f260fb07dcb2374bbfc8e92", - "id": "5ffd7c36deaef4295257fec15f27e451864538aeeae9b21ded6d4e579f19d7c8", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 123626090911753, - "fee": 0, - "recipientId": "AczFP54nMoafRABK4c7idxHpAC4RwmQsDE", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402207a3f7c3ecb0295f08a85e12af23156e0765ad1540047f68cd89be139307b5bb3022072be91d55a080d6e5fae0a327225dac4c63505b292dda6958a1207f9adadc8c4", - "id": "03b08987233a71d17b296c057e03821022e9b504b47471670ddad11080e1f4b2", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 125719320015809, - "fee": 0, - "recipientId": "AUq3S7bXMHmz9zBbz8YLN6LrSrshvxXTU5", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022033d2d418dae0c1c1ef89b1866258410008eb39a409c98f6ec3a73918f449ead102200ca603311c12cb4a5f050e0872e05a0e8f2953827b168b85211b179600154585", - "id": "82b2c63e0139fa52979e008e6a3d3086efc4aaf5e1799c57a29bdaaae9a50189", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 126273901505716, - "fee": 0, - "recipientId": "AdCXBbcpNrnMDHMar7Ebjxu959uwN2jt2y", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022078cb591e525902157b5736e798461266a2c7e32d7aa4d06d07f80d64244e0a2602202981d622da3539fd16efc0aa0ed8503ce2470ce8cc3235cc325904b9246dfb1d", - "id": "367b31d00256d8608bbe3b62f350bbbac10d896a3a3cc084e203493abf6f74b4", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 126299500000000, - "fee": 0, - "recipientId": "AeYkC4MJ24EF7yVkb8NfSryBw9xrTvSJ5o", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100f3fc2ad6305967410752b664c2d8bca041d552c013fa576e10889a69a6c4fce5022067ecc8de665c05a1594067f873e067db5e1884486d4815bd1cb3959c282cf0a0", - "id": "af6c2725034e35ca7dcf0b20a9161af2ece9d9e30d1d8f934661c2e121844832", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 126837200000000, - "fee": 0, - "recipientId": "AXx966jfTHUz4nSjZsFEKkpsgNoByhuMJo", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30440220025e2076ba6db9412d886925b4ccf810ff5aa45711ba9c9f049061f675560937022042ed7606e3f46bc5fb5b2ef2b36e894666c78804a1d95ba7916d6a41f92e36cf", - "id": "e274c6833dc8021404af6782020539329acda8f274ac2be31535eef95cd70668", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 127928194702051, - "fee": 0, - "recipientId": "ARwU8mRM9aM4KjwFLpNH8eHntj157LNAW8", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022050f8011fa9011b5b4501bcc1d4154864b6c5125e9a00f468a194e59edd32831c02200c9f77d38533ceaa8bbda2bbf9ddc73a7d6654d3d3a338a3e04a80f67fe16a59", - "id": "2debd1afcd9cbc2e3c57dc27258cb49d6ef21b10d36648efacc0053acf7cba19", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 128450700000000, - "fee": 0, - "recipientId": "AGto2VECRE2tGFr8X9pfhqHNgF2bdW5mgR", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100aecdaf102f6d5a4b18ddeb17c8d5c00c18cfe0ec6382df8c972937a17e9271e0022074d6bf200487ee5c03800c2cc28e571bea6129c95ebffc2a1a8435fe6bb351d0", - "id": "7477beb697266fa054ab120b1381e293d8533d1a56eec29731525b857d05e8dd", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 136497083929386, - "fee": 0, - "recipientId": "Ac15ysDrQ3fvMYL8S2u52VSwXZPKZQs8MY", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402201e2a494e971932480c8286c2c12748daf90afd3234969cd720ac9346da94fff802203fdeef1aa6daffc70709e5c86bf53fec3169651671060b8e495e1c0c40c725d2", - "id": "811f46c52bc4e94cebb2c8a4053c13c3ac3f7df24134cc027a37f7614e935a7b", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 140099329287361, - "fee": 0, - "recipientId": "AZB965rP7y3PUs8RXqpkRy5Uu9dbQgu8mM", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221008fdc7606464939463c4c48ef06663b63e447db9b560fd323efe695b59832e792022048631bfebc37ff98d5d5089f607869eb05b86119830da14817cd31125a4910e8", - "id": "8bb29e211493fd3f3282498d749b55d5824e9ed9d5813a834258b002204a2cb7", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 150034082630911, - "fee": 0, - "recipientId": "AQK3Zu6VW2QMh6a3ckNzNsYduTV1MmDkyJ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "304402202d42c892d4cd76cb582573977a7b2a294a945754dbd3de4411fe3a3ed814f0d402207c49588af322b49914a933cda46e2ade762f5bb9b9383cb690bded2f0a734d90", - "id": "7e1e33f30bf45a2b2b7be555693894171481a7cbdc48397575e6a99d98382138", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 151578069939920, - "fee": 0, - "recipientId": "ATUe1KJzRsHUW6rA8UnNNNo4yVEF6TqyEv", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100e97f8bccc9e3f5e3c3a5b32987c64caf4b60faf4a282784ab3b1ade1579c3b0c02202041fb2375eb061fc3ddb64cf94edc614a690d6fa9e22e9964aab80a66eb5b34", - "id": "be993fc90ee11f5b9bcbeec1a272e94c1894b65804011f76d0d3227c71ba19e5", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 191573850243351, - "fee": 0, - "recipientId": "Abee76TtVambNDBmTTyoCYosWQ13MC9XEn", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100bca5294ba5fd28e35afb067b328aa2469656158f4c8580d98bfea76ef925761102202ca7d152501f2999169ee65cac56b25f41d9b140d11708d236f9c4be972b0dcd", - "id": "2bec691439fdb6fd9a324f26d44e2ad64bd9e2ffd566d220e01c4aa12028fa91", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 196019568105246, - "fee": 0, - "recipientId": "AX1ZCuzNnVHfPvKikwsnsNRUxXfKq5g9dv", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3044022011856a7a6cf61478d183e18a4a7404241dc561629d7db7ac70d1ff385e85d724022003404898de3709cac4bd5a6aa718c7ada3c9d08219c60f034a45da8135ef4a51", - "id": "57b80107cf40b39135241aa92e7e254da815763735f0ac5a9919dd8485865d80", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 225493764614631, - "fee": 0, - "recipientId": "AbYwZ1DAUDLgJwusR9bCZoTfuUTwNq1C3c", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100bad48978061d554290cd1afd07851e3101aee65f3b7f9f677e85a28d6590df5f02204d7a721a90dcec6644bff0aecd2f1d5b506c334bad8810b1b2d123b6978d57aa", - "id": "5ffc47d5a0826f031d51f0502e45ddb9d7b8c4f4bf9b2d4bd7a60c4ab027b541", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1034744897737528, - "fee": 0, - "recipientId": "AaFgAghGAmNWndDnaxkbcYFE7fxbxZn6dJ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100a4489ad919a05f73c3be4de717a3b23115812c146caa1f33301485e1d9521dbd0220487441651432d5b34bbe7f383ee3a1bdf84dd22b82982d9566020a6033783685", - "id": "99a3fa3f91f257fd3e3ed284a9bbcc5eb007ca7e004372a5912bc3850d5ec9f7", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 1256766795179826, - "fee": 0, - "recipientId": "AUhVLSiqTnnzqhxp5RKzheuRyvh58TSCUR", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "30450221009e21a29b8428afdd7f140379d839d5ee75191c3e5add0582f58b9a3b2b3d69e30220749a0e7a3a8c63e877f1bdb0ec12987db8b138bb1746efe0b18d9ee817276cfc", - "id": "ac7ce9c3dcbee526a9f15af016fc15b6dabed5f8a61997c4de15fcc987926234", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 0, - "amount": 3141438227793004, - "fee": 0, - "recipientId": "AN7BURQn5oqBRBADeWhmmUMJGQTy5Seey3", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", - "signature": "3045022100df12738ec2164ce2d2ba980ab8499dae066149a1019f37ae5b17f28e9cc2aafb02202a0db97f9e012f2a8ed819d2cb02e5d9e63fda01754d6f42308c3cab4bf92e1a", - "id": "5222124556517be676fa67fccb07fd581ec2928140a72afdd65259dc3e5db921", - "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "033c9e5a710bff3131b406a8023a60e6b76a2ccf937cd85b56add7c4a33ae3090f", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_26", - "publicKey": "033c9e5a710bff3131b406a8023a60e6b76a2ccf937cd85b56add7c4a33ae3090f" - } - }, - "signature": "304402205532bc3fe7be805b4c8a0df2995158e634c7146c2467d05d75f754782b87bbbf02207164df69b13c9c3c46bb3c7d027e7ba81eeaf726f25e08d268c1507da4581b73", - "id": "8cc98e02422afa8a246faa66c1672b62996be356735b00614d8739ea3a5f73b6", - "senderId": "AQaKx7UU8857b4tJij1jb7aURUzd3GDyKt" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "031de61bd525abc902396bc66daf513eb20715180beb50be3a1c56a36dc73476a8", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_50", - "publicKey": "031de61bd525abc902396bc66daf513eb20715180beb50be3a1c56a36dc73476a8" - } - }, - "signature": "30440220125d7a0f64c0328590d67dd27eb5d8f209bdcce03d730c7469ab25a8943c8b920220027305ec4ac8d46b0c2e711274159ab2fffec7f5a5994aea775cd48260db93b4", - "id": "bf2641e6ffce5848282027221c7f43eedbd0b72a7ee2a56cee1472c5f69f194c", - "senderId": "AU9BgcsCBDCkzPyY9EZXqiwukYq4Kor4oX" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02614722c83a05de882d887ad51bc5c687e747d6d19b58f5731d38223c58bb6ca0", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_48", - "publicKey": "02614722c83a05de882d887ad51bc5c687e747d6d19b58f5731d38223c58bb6ca0" - } - }, - "signature": "3044022078d5f10573deff4cf16ee4b253c6b985b8a16e5f7f4840493e2834809e26ce6f022020d6502389f7512ea3b8f9fa9ac296c153aabce8f9066cd42d854b94069f6f2d", - "id": "3625b2591f15394ea0dc6b26a113284b1b56de0cf3a21c3a1dd92f373f796982", - "senderId": "AJqbav8MPPAe3zdzo1f471gaciQbx1SRe3" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "029191a8ae0fe0561e3ddce562554e8ba5ba36cf9ecb389290a1a74acdc53ca89e", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_47", - "publicKey": "029191a8ae0fe0561e3ddce562554e8ba5ba36cf9ecb389290a1a74acdc53ca89e" - } - }, - "signature": "3045022100abd4ff196ac1fb56fdcc0f0b71a49ceca5da07b3631570e22626fb43a415a9e2022042d32e0fc05c6e2467b9749ad1f6bf5e1fb9cc8eb5c21a40baa1381cf58fa327", - "id": "05c1fd17a20d62c2740782097261b960f9ad353f68b94d4a13dcab05d08f9dd1", - "senderId": "AXArbuCVSiRuYBkzCAajboxCfNiw8AyQX1" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0204f8aca74a87f69432298b13555cf50aa0709e1a942aa3efb447620eb78bbcbe", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_46", - "publicKey": "0204f8aca74a87f69432298b13555cf50aa0709e1a942aa3efb447620eb78bbcbe" - } - }, - "signature": "3045022100d15eb20b58fb9a6e7659706d20c3deb26dc176cdaab02fff557dc5a8d65982a3022064686cae9101510295993e1d3663dffc88741bf1e2781021e28a7b2aa71ba80b", - "id": "6debf628e330726bee0f64d9fe7c56fe4024941b4394ad5c7cb08fa9a3abc0f5", - "senderId": "AbrgipEvLp1ZHNJ1GcWWAsCLNgSgDG6Lxh" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02c12428bb56ceb96e9c2a558e045df6b7b2c551fdb6a132ac6c3956d10f479f52", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_45", - "publicKey": "02c12428bb56ceb96e9c2a558e045df6b7b2c551fdb6a132ac6c3956d10f479f52" - } - }, - "signature": "30450221008c43c6f251517d972386adb42d69510ca59d882a89d7fffa55484ad7989a3bbd02200925d009f1183934e4be66ad48ce7149c990d0d87afe629c14551ed34e54ee1d", - "id": "557d5fb9b8b948ba2a6fd3d4dceb476e97e61faefde8eb11f4372028346c5aca", - "senderId": "AbyacFxcWS1JsokdRCx8bFsWP8f48XftmS" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03f11ddeca3845ea59c82120a7eca68558c99e4e7d373142ea0554408c58ca82be", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_44", - "publicKey": "03f11ddeca3845ea59c82120a7eca68558c99e4e7d373142ea0554408c58ca82be" - } - }, - "signature": "3045022100f04fdee2cc09b029d1bedea130174f21e24e673438655e71bd61998732debb040220439b36ecd46cf6ccc9c8a8fc44085733bb82427a760ab87bfee1166c7623813a", - "id": "6d8c04b24c24c9680b4e496b686c2a37cc05fcd9e6f2090cc945712199b2b8ae", - "senderId": "AYLTbdiYWHvPvJo5Lh42MEVS4Fnepg5vgc" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02c134247a5d54cd30a5e3080daa99c74f54e21ad0cffa60e7efdecece862898c9", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_43", - "publicKey": "02c134247a5d54cd30a5e3080daa99c74f54e21ad0cffa60e7efdecece862898c9" - } - }, - "signature": "304402201820565556e3039944c8c7240c567c5d8f96a8a34a05dc1d68577883a8025e94022011f55c1511627de25b4cd7410efea22ef2df50b3c1f4ed55a8ce8d4f3da91862", - "id": "e606ac6acbfd96fc4054131061a69e3d3f58e044636a6646227775c4e646a126", - "senderId": "AVi8PFHr5jFBFGWSissPFDFXUPABuBgxSa" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03afac7e796d781e17600945010be34cb6760fa919be67baec2cfb691cf4ce5f33", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_42", - "publicKey": "03afac7e796d781e17600945010be34cb6760fa919be67baec2cfb691cf4ce5f33" - } - }, - "signature": "3045022100bd7e5550aecbd212d9fc13842c7ef586b146ce6f289199107af979eac6b61fe402204607eb502c9c8f2363e468e22afccd754e042e605199c92a93a0c29a19ec628a", - "id": "2cd3411cf5a52c717afca1f42cf97627fe81c0869f39ab494df0ce6e99f7e485", - "senderId": "APXkAdLbLiLJDC9Ls68Y9a5ws3PcgmUDAo" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "032879c56cfb96539f6a8c03a91b4a987e35973a79e62f9da438831b353066a84b", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_41", - "publicKey": "032879c56cfb96539f6a8c03a91b4a987e35973a79e62f9da438831b353066a84b" - } - }, - "signature": "3044022060dc174d40828324a18074db079ea300d382ed5c2f27a7ff782686e7e78002fb022072e809275cc872b3c4b430e3094268e0260aaf67ced17387ee17a207a9e2032e", - "id": "4b16c34911fac46716cf8ed383401f70657201763b54ecaa5904bc09fddc774d", - "senderId": "Ad8UiXMZPecuNGwCXZTmF8Mysn1TchVVTf" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03bc7be5c8b1221beb63f6ed23d4b5e2748b64983087986c4953579fa7d9022a71", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_40", - "publicKey": "03bc7be5c8b1221beb63f6ed23d4b5e2748b64983087986c4953579fa7d9022a71" - } - }, - "signature": "3045022100c8901dbad46f6fd0ae9db39c7be5b002bc871906a80181ae45de6fa67eb4068a022068af82d46fd008c8efe5c3fe265313e01aca9262b1160a5c095c6b31d97f1579", - "id": "2d808f28b223999c1d652c01b2f22ceeca15d1abf2acb42c04570358ed176913", - "senderId": "ANUfH6C3Jjp46pDUxWgeV6WUbWCagaVxM1" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03c5282b639d0e8f94cfac6c0ed242d1634d8a2c93cbd76c6ed2856a9f19cf6a13", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_39", - "publicKey": "03c5282b639d0e8f94cfac6c0ed242d1634d8a2c93cbd76c6ed2856a9f19cf6a13" - } - }, - "signature": "3044022051a8aa7906358589161956d1c182ef9ee5c77a144c2d9965eeff043ddc3b7a6b0220797a2475b5dcd8f0ef7a24a0fbe3d0185839e33f313b93b566b82be168d4ca33", - "id": "3f21a6f499292b9bf0c2970cac7d78953a977f7004d29446698c7a29da656fda", - "senderId": "Actv8ebcwNsbfx8MM5k2AeJidJuLL7PotT" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "036c474d6b22e6d7c2cf054721ca73d0e2a904135b49bbf9dcc7ed7ce9718984ed", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_38", - "publicKey": "036c474d6b22e6d7c2cf054721ca73d0e2a904135b49bbf9dcc7ed7ce9718984ed" - } - }, - "signature": "3045022100d3ab1ee59bd1a45bf936867661f9fa9b22c161506bcd61ad17ac871ba4a17e130220114d37a98120cd1f2465c9700089101db7748ab0562561d4e01ec98c0e96750f", - "id": "337968b8f3e7ddb26ff3e6740df0b12c7be6bc427d9d570bd77a9312baafc80c", - "senderId": "AR5z28tRUnvaBWC14KSBpvNJDgsVCNtagq" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "028bc0f094738f7699ab4432d13e3c18e09a462dca06960a1fd0eee82482f50be6", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_37", - "publicKey": "028bc0f094738f7699ab4432d13e3c18e09a462dca06960a1fd0eee82482f50be6" - } - }, - "signature": "304402200cd7121995da2f8fb24ef2aab15b8da97b050ff9aa600363305f2c0a0c8ca72602200099ab565497c84319dd91a34001b16a92211248652ee109fd28eb90112bf022", - "id": "061e51e451667ae7ea59e0d1cc66fe47700d6bed1dfa671efc028a2b580b71a3", - "senderId": "AbkDPAUDsfQJgvHn5g8AisDm9XqLAtFFai" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "038467e1dd4d138f007f70cb09afdd8439ea744b282cbba2d76fee8463dfd17e2b", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_36", - "publicKey": "038467e1dd4d138f007f70cb09afdd8439ea744b282cbba2d76fee8463dfd17e2b" - } - }, - "signature": "304402206772c6c4e2f58c1401570fb76ab87bf63865fcf32c5f9a5a3f88f4360f44e346022075710eb73a4303ecf5eb899019ee59c9c5ad206b6da902adf90f3df02f108512", - "id": "ee5347ef87ceaf28aefd8374f686725b8ffbbe55042dba0c59c625e4c822fbf5", - "senderId": "AbAeJ4YJU5rxuNtXpDn3E4W5E8UNHyc26a" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "023f425c88cfa289c28e5fefe120033c9beff72487dbc4722e900d6da59943b8d0", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_35", - "publicKey": "023f425c88cfa289c28e5fefe120033c9beff72487dbc4722e900d6da59943b8d0" - } - }, - "signature": "3045022100c185d867d976dff795ccba4654199f1b075bfd3441e045a2f6ac64c4fd0bb6d702202323d84585da2268276d6cce663e842ea5f8617e5e12cf4a20ed7436a1ff7f04", - "id": "592ee85d2922ef565fb02d649cdb2104caf06fb8747ba2425057f79518132b1c", - "senderId": "AP8agRcU4WmsYhC72pBqyfLwaDU6NYKUL6" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02d2a0fda621ac213ca51dfa8efe1772eab8659d8b8c7023a35dce48f2c88316ed", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_34", - "publicKey": "02d2a0fda621ac213ca51dfa8efe1772eab8659d8b8c7023a35dce48f2c88316ed" - } - }, - "signature": "3045022100da6c5c7945eb7dae41e7ed133a58e06e660fb8d012e9ba93df38b8b86a3aa7ca022007514624a32a5fd6f294bfd8d6fce6e8c75b20b7fcb8d3f8b82725c83fe43db6", - "id": "686baa6cda61403ce346c293a8f27e0dc3899eb4629d4b3bbbb9f02b41ea36bf", - "senderId": "AHmBqWJgxZfaC2azkyASdrbCxF6csE7Qxx" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "026ffd3c35c7ef08e3dcdde741994bfdf9cf6af75cdf9e6f4ef8c251b5eb321fd1", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_33", - "publicKey": "026ffd3c35c7ef08e3dcdde741994bfdf9cf6af75cdf9e6f4ef8c251b5eb321fd1" - } - }, - "signature": "30440220192c5a3433384ea1ec3f81473f18962a179fcdd067359accac33e8ee4e571a780220549fb42c1a5d40daca2fc97aa8e0379e041c28fa524505c0e43760f1022a1369", - "id": "bf1644830edb59dea6ea1f3fa107ce84546d14904715b84bf2d5e9648ad426d1", - "senderId": "AeLV4NUMsPJW1nvHquBWPFVKCWirs1pshf" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0295f1d78f3adae92f0c2d061367e0d06a3fcc9a838a725ccfe660b9c2024253fb", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_32", - "publicKey": "0295f1d78f3adae92f0c2d061367e0d06a3fcc9a838a725ccfe660b9c2024253fb" - } - }, - "signature": "304402207720c103e2c3000d867ce3073f9c5375d9f3cbc69dc6affd08d72cdf0322dd44022040ef700ba6c235af8b2e0b71b3b8a825a18f276a192ffdabc01118e2786eb567", - "id": "aa03f6eff50359838142b70634991e93d48480369f087d73cecd0b93847233d9", - "senderId": "Ad6y8ae35QWkrtiLBpiXRR5Cj2KK2u3EGX" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02ac0a9348306d3dea50bde6b38791b2716f698044c207bf005788e13f35b46693", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_31", - "publicKey": "02ac0a9348306d3dea50bde6b38791b2716f698044c207bf005788e13f35b46693" - } - }, - "signature": "3044022070bf433e253fa69a33abf85559d804d1d0e055199c89abef5dba34e5cccf1952022023fd278d32b75f0465c777c39b0a616a4dd0a957b08e9723c1702dbf4d6a1ff7", - "id": "c64e9e47d8c7573dd97d2bb634eb7bcb141c156ab701044319e19ac0a7f55f3c", - "senderId": "AGb36aHfdxvqbMqoDCnm6wVkKKtqkE3zAh" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03c075494ad044ab8c0b2dc7ccd19f649db844a4e558e539d3ac2610c4b90a5139", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_1", - "publicKey": "03c075494ad044ab8c0b2dc7ccd19f649db844a4e558e539d3ac2610c4b90a5139" - } - }, - "signature": "30440220470149adad4cf95460a3e02ce0fd79d933a1612ee9d8711d104efb5c708022c5022077eb9aee6dc62bafcb4217484cb2b892d8ddac8ba2a170390438cf47521a8d3a", - "id": "1a7f292a5f3df9f9a3ec97d7abace3d398adb943ff59da7c0b0eed8f19928ec7", - "senderId": "AeLpRK8rFVtBeyBVqBtdQpWDfLzaiNujKr" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02afe652f7d14a877e73f00cca6c836efda1a05e79c6fbd7f92b600a4cd519f4f3", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_30", - "publicKey": "02afe652f7d14a877e73f00cca6c836efda1a05e79c6fbd7f92b600a4cd519f4f3" - } - }, - "signature": "3045022100a7aa2d57b6598379d04e9143542bf9abc4fb4899aff37ea7a7be0dd07c7317cd02201284a2101aa06dd7fa6e34006b666e4916bd76071032002302dde92610e04dc7", - "id": "e8afeca5ff2aa3ccd8c29f7249d93d465049bc31b3cd3fd6cdc6e09ca92ab921", - "senderId": "AW91q3n1QYTn3caBm7KR35zexcJU7PgMtZ" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "024dd37755804e6dda0ddaff6691aa038c57d8db36d59fd1695a2519835a828072", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_51", - "publicKey": "024dd37755804e6dda0ddaff6691aa038c57d8db36d59fd1695a2519835a828072" - } - }, - "signature": "3045022100f5a4c4d258caffc712c9aa515f3e235b352a8d2250695e7570a14337be64cc410220446bbd588e8aab1f69c900e8472c8bbb61cb6b14aecd0e0d693f74714e8511be", - "id": "e77aac7c7d14794e86175a0b0e985a09dcc485c4e1117aba251dc3e45addf4fd", - "senderId": "AW58iWw1ATvzGHu338WqMYvgUhmvMMsRjF" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02763591456b7d3ed76125e4b9d5b34c3926f5aa166200dd270e45ecb6a6b15d9a", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_28", - "publicKey": "02763591456b7d3ed76125e4b9d5b34c3926f5aa166200dd270e45ecb6a6b15d9a" - } - }, - "signature": "3045022100f6ee4060cfdac8c8a9dbc50b49b7cb59d4a587a5d14135fc7345594ac2b7e10102205594aaafae4f78415f01e0228b7233ec36356db4d73da92f6720502874bc1672", - "id": "4164cada2725a8e52f8713f8600b3d945bb3045fc956d79066974e3a012021ec", - "senderId": "AYaYHEKaJvLLWX2NgM8VXk15zSDxV8vCgn" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "025e6a4c19af3228659e5aeb3638e78c50203d76a806d2e1ea938b79247a25a932", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_27", - "publicKey": "025e6a4c19af3228659e5aeb3638e78c50203d76a806d2e1ea938b79247a25a932" - } - }, - "signature": "3044022075186579fba3bb355622ca8e4e0470bc54e82ae15a16b5e1b16784b29087f70602203fabc6d8547b6eb07c59193e0b42f3bd6b5cc234ca5d415c791c9c5f4a4b7f90", - "id": "6aa2b74f026ff9cfb1e5e00a3b4a75f752f912337fdcb61ac9257d58fb406cce", - "senderId": "ARDkQVS4DbJnErrptyWSWdJD8gtaPEyRH8" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03916b256a6ff5c51bc0b7866678cdc40a2d06477fd022b61f79383b6cdf487bcf", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_49", - "publicKey": "03916b256a6ff5c51bc0b7866678cdc40a2d06477fd022b61f79383b6cdf487bcf" - } - }, - "signature": "304402207143545435e31741050f802e434d9559c486dcc19e136e6eb68c7881959f5f970220387f941b78ecbe29b209993bae101828daf5492cd2febf256a87d157b97af8cf", - "id": "d6805135ece218f780e604673b9946b789d4406553a5dcedee1c06575cc7c63b", - "senderId": "AJjkVwkhsvsX6dVKhVxpmhRvz4CyXLEvQ3" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02b38e56ef8fb018fe914c484ea4b0aa18f1a938f46af1c394dfca40adf2771bde", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_25", - "publicKey": "02b38e56ef8fb018fe914c484ea4b0aa18f1a938f46af1c394dfca40adf2771bde" - } - }, - "signature": "304402203222d23708aaba6f4904fa04ff5cd88c9c9aeb91771754763be9206d79f2d85402206ce18e2b3bccb6fbca2e024b1bb38ecd859c27986a0bc123bcc29f99b0dcc6b1", - "id": "86367f56d8b4a1bc34cf1790b3a1f81cf794b9e9683b347b7a5a5110e63b9b34", - "senderId": "AJrXd5u3y6FH5HktH2jgkLQHjgD9ZztMtk" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "034bef7fed4f718a450ec4672533d74ef95039cda85a1a0ff74e6b2dbb9e220d68", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_24", - "publicKey": "034bef7fed4f718a450ec4672533d74ef95039cda85a1a0ff74e6b2dbb9e220d68" - } - }, - "signature": "304402202b33813e4cdc7f97dd41747d53542803cc7c5ae7aae56cfef3e4b9d85e74302102203854d993b16efbf7b21454bcf44873969f35d033ee93866fd2293841f866441a", - "id": "65303140bae99aef3d68b36379acd8b9f4263f1d90887efc1fe7f0735c26b84f", - "senderId": "AZengw5WND4WLC8JKz6xUDFwLz3yCKPpTC" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03d48d4160457b1fe8d76e2da68f33860ad2520836b5ddec8af925757690d93c21", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_23", - "publicKey": "03d48d4160457b1fe8d76e2da68f33860ad2520836b5ddec8af925757690d93c21" - } - }, - "signature": "304402202c43ebd655af5fb0e7336fa41f03977bc5b4c05a5a6f335e544a58acb5f5ff1d022074d415ad20703c67fed90e1d0bc970ebe1d55f31a1a3dede173362c3736ba6e5", - "id": "c529cb54924f221a3aba98b204f82c033b67375a15d52e52671bb526957baa3c", - "senderId": "AaFxHxsjYyYCsZtpQwwYGvYESogJ2SHxe5" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0384e505b25eaac812f8acbaa1ecd09e2ca4b5d973210189a39dc48d2a8f908780", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_22", - "publicKey": "0384e505b25eaac812f8acbaa1ecd09e2ca4b5d973210189a39dc48d2a8f908780" - } - }, - "signature": "304502210099161fc12c6ea658f382dfcbd495c84961d1f8f029edfb6c2746ddca918418400220556ffdde284f10b5ba62bdf6a67139bc56f7d0e44e87c651cad6e8c2f646aefc", - "id": "bb014f5d3ba5ecdf3dba9949673e1cea6eeb3771f41bd88881aa4f055307e4d4", - "senderId": "AY5GwZtG9sFvDzMKAQfAD1Q8EHDh4bW718" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02c3709dda58fcf7e26f94e865458b08d95d398446f67f465387be56b03ec36f4b", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_21", - "publicKey": "02c3709dda58fcf7e26f94e865458b08d95d398446f67f465387be56b03ec36f4b" - } - }, - "signature": "30440220562a015669686e64c274be9823add0ce9da9bb8ea31e376c194b7e194c7306670220186b3482683572164588f2d89c8483eb6a789efaaf1945ba86b5333f23235254", - "id": "ee1933bf760161dfcce831d57e784e13f1e428bdf6ff59a0f06c778873172032", - "senderId": "AZvjdJSG5V4WnNjPaRbDNfLD72j3rYWqbs" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "021c2280e462313d08fbe92bac59f43203cef4e21611d42747535ec2987a80e30b", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_20", - "publicKey": "021c2280e462313d08fbe92bac59f43203cef4e21611d42747535ec2987a80e30b" - } - }, - "signature": "304402207e28352abc1eab6c5405cf78c2c1fe406912d3b08c6e02bf44877dd94d117eea0220144013da4977b0517f8fd8b7dc6838185e25d0f6f272af17125f50feced46242", - "id": "658f84d6568a7f48295e9f25281c6ca71c404245ece501cbbebb0c60efd08f31", - "senderId": "AKeDRRgG4TdDo4Z2iCzaBZS2UcvjWKMSrC" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0212fc419fd5f4c88f73b8475ea676f3800f4bc96433a074462d827fc35f4fd883", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_19", - "publicKey": "0212fc419fd5f4c88f73b8475ea676f3800f4bc96433a074462d827fc35f4fd883" - } - }, - "signature": "3044022036cc85f65b9cd55c1a336cc02c06cbecbc90a70314ed2848dbb7bb9cb7f7fad302200b217996c20eca5c5eaafcdc4d2a27a39d8945f55cd39322a0070b180e7a923d", - "id": "b8a1791640f64e4c977bc2c6f8afae412f6d125db9791db33d979fd3f607976d", - "senderId": "ANeLRbMxkSguPMq9CJeMgr8xZxwZ9mbqbx" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02015ebd34b20a1c7bcbcff1d53e7d2bbcb2b4eacee494830409e1f84117b802a1", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_18", - "publicKey": "02015ebd34b20a1c7bcbcff1d53e7d2bbcb2b4eacee494830409e1f84117b802a1" - } - }, - "signature": "3044022023390c4ff70c6f02923b4f55ecd6ef41e93871b4e4eb21be80b5023f72f1095f02205c921d9051395cf7a4d335a00a89a9e0f0d7afaae699b371503d35eda7cd13aa", - "id": "fa9bb4c78bbcbc164ef4a630997199aa01b53bc93d49b9f3237efea13717f04b", - "senderId": "AdCa1oGLMRQqygEBGGq1AEtSV44CJ5Kbdo" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "030cbba2415349f8093539632fe26692411219c11e740e9a3e02b6c64415f056b4", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_17", - "publicKey": "030cbba2415349f8093539632fe26692411219c11e740e9a3e02b6c64415f056b4" - } - }, - "signature": "3045022100c0e0115ba685768aa3aa11b9d0e1149a63824f72a486efe2dfa16df93d8f8123022023b207efa969e876be02f87ec8085da800750c127edeee1fc481fe978029802a", - "id": "4bfcd5ae4f01935aedb2fed2d509698902a054456f7dcf5fce02da02f1c7d752", - "senderId": "AXuVpX3tAewNp5YVWvXWv3etxjrMDgaZdK" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03367a6969c0d62e9b0fb3439ff2574dbacd5d616cc57b08f7c5417d4ac6e94faf", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_16", - "publicKey": "03367a6969c0d62e9b0fb3439ff2574dbacd5d616cc57b08f7c5417d4ac6e94faf" - } - }, - "signature": "3045022100f9a6be773cea615ec0d0cf0e330f3ca1faaa86f7475d620f6ae1299ca58671d5022065ae6e660f1c80e935db4e66387fb44225ee73f671e54003c0780e435029acc3", - "id": "54f2abed7bbdedacff1decc7be229f6385561cc8f800676ea61deae358bb252e", - "senderId": "APQgLh8MaztT1XuWVKb6d4FKM9HMmdmDVB" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0315ccdbcb0ec7bf484726f95bcb2b331cd976bd7d72f0e3f5c38fe4167d7c69fe", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_15", - "publicKey": "0315ccdbcb0ec7bf484726f95bcb2b331cd976bd7d72f0e3f5c38fe4167d7c69fe" - } - }, - "signature": "304402205a4959cab68877017ad4d4ac61a5b7c9a7cc674ec66b21e7463a8673b8d51ab002200fbdab9ab0e4601e1fccce869be1a1b3348d8127e4febeaab68228953a81cf04", - "id": "7348d455b5dae1aebd48b3668b571f5e44c0e8f612c1377a19de8f3e27c84644", - "senderId": "AGZhXHXFUdvd7W4aWs1fYJe6XFUYeSWrd4" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03477d8e77a43b443d401aeec8b32aec5429f8f453b93d5c4061cd17101e09b077", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_14", - "publicKey": "03477d8e77a43b443d401aeec8b32aec5429f8f453b93d5c4061cd17101e09b077" - } - }, - "signature": "304402201a4433b86c57e2701fdbf7640b13b21634b7cbd3319aa0c914e16b59fae45bfd022044dc7bec58897ddb36fadae3c52662aa228ae88b0ee6c467a52d1e476784a30b", - "id": "6f6fa4b601053f6fcf50e734d6caf590dc4d23980c32d9f1b62e10cda3241018", - "senderId": "AVoTzMjHaaWKDuA26ysXGU681N6Q2PQre6" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "037d5887d9a9bb48e45404fc5c3149bbd53d82bb4572bf468f0da9b4e9f6c73ae7", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_13", - "publicKey": "037d5887d9a9bb48e45404fc5c3149bbd53d82bb4572bf468f0da9b4e9f6c73ae7" - } - }, - "signature": "3045022100c2f43505df18e7682ac36c16f6429764ad86339527e554a78ef44d0941cfc937022007118cfd9b51ea359ce4dcbbb5dcf06147fd219a38bf0eee9a220c507c5944de", - "id": "dca332856f06a5431c648f73f859b8f8286bac60d7f452eac42d7febef0fd7f2", - "senderId": "AGdHR2UZ3MJuaXWejKGoAycztyN8BFQnNG" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "026f1910d432c8ca8f04248e74c4b565a236d9851caeed4422550c3803b313bf39", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_12", - "publicKey": "026f1910d432c8ca8f04248e74c4b565a236d9851caeed4422550c3803b313bf39" - } - }, - "signature": "30450221009a73cbe01aba47c293914b2bd382e5715a611dc14714e225fe9287cf293fc34f02201b05843284b43452c1b779b6121be37b4459e96d6e1328f6ca4c076522f4351f", - "id": "49620d01436262018949d76325f7f7c974fe5419a32626c3ba1e7c3b2f0752e1", - "senderId": "AYTEu82arYgRyvTgi7dbYwjodV7ignYucz" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "024eda8b8e70b93f87c1e18929a2ad789aad3f6b3fe4aa12b4f74513bc45916726", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_11", - "publicKey": "024eda8b8e70b93f87c1e18929a2ad789aad3f6b3fe4aa12b4f74513bc45916726" - } - }, - "signature": "30440220637254d742d5038797dd38323259ba4263c3e98eefae4a8c6717faec0e866a2f022075765f0a4036afbd297bb3bd10c7ee7f62731b45dfe708a04096947af7caf106", - "id": "63acffbbad5440dec99e17dd3eb4d501f44330f0d8c4db4cf161cc0992eae5c1", - "senderId": "AWLoVgSScNNB2kecswuhbY9tcrtv9kf2iC" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02886a2ad45ba50edeffbb7447cc1baf1cdd16e3b91e5ed6ba8b16c687f03e01db", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_10", - "publicKey": "02886a2ad45ba50edeffbb7447cc1baf1cdd16e3b91e5ed6ba8b16c687f03e01db" - } - }, - "signature": "3045022100e78d6752036f323c61e78cefc4355a1dd7372fd782377052b5c80d30f81597c3022004b86acb40c52d91a1eea79d4de929c59a5e24fed6f243157088c1eed03f039e", - "id": "531ecd8620d51f46dc1140c8d8f0ec8344b4ebef61f17e8c304e5b3bd5e02586", - "senderId": "Aa5rKoVusA5xiyh8Git1tJUWZE48ScbCR8" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "037bd8595ad6b5787671c99921208284ac6f791a8ca55c6e49ca94a94731b6cba9", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_9", - "publicKey": "037bd8595ad6b5787671c99921208284ac6f791a8ca55c6e49ca94a94731b6cba9" - } - }, - "signature": "3044022066203d448724540f14a916591051ed79f57e3995af8cd9bab5ef003064c08dd002202a60f251bda6088ce8d43d6289ea2ded6442e95344654f02a17488f26c10a893", - "id": "eb253b77c4560b226d8edbfbb860717289258f4cd1ef15cee6da88f80029a33b", - "senderId": "AbfnTeGFiRM3m8eHcMsrqNvrpUCoCnuSzH" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03e8eeb0e5063caf214986fa2e085dc67897908cc2501ccdeefeef33722afde50a", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_8", - "publicKey": "03e8eeb0e5063caf214986fa2e085dc67897908cc2501ccdeefeef33722afde50a" - } - }, - "signature": "3045022100c6bcd9f75dbc9bafeb2e134028b2c4f8be77214611012f4d9b92bad5610d42c1022039923f93586e1976ae614fc90208352dac120505a08be0a2b9b82840622473a4", - "id": "5378c9044477765f44580a5f42ace617df524457315fe63ef9806e41de5e65fc", - "senderId": "ANstQM4LaxfsuKtFMd8vqdGte3CL9s2vMA" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0307784cfc3d9002be47ffa32e8d99146869342254247df059452c5f92f7ae521a", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_7", - "publicKey": "0307784cfc3d9002be47ffa32e8d99146869342254247df059452c5f92f7ae521a" - } - }, - "signature": "30450221008ad9a84421282b28c6d4cabc42a7855bb3853a02edb0524fecc21b821216a6d702203b0558b44c659d52fa163f8941a61ae0b8cec81cdd3fdbc8e91577ede6815fcc", - "id": "20d635b856a468eefc0801853afd1d387d25fdbe69c677e56b850fc45a7c3029", - "senderId": "AVFkEkCmEg7cuCXoVrfvtH6mKz6XC9XnvV" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "028dc3fd930165f910571a159f574ab15ac740f48e68429a7fbfb42ba202c64a0d", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_6", - "publicKey": "028dc3fd930165f910571a159f574ab15ac740f48e68429a7fbfb42ba202c64a0d" - } - }, - "signature": "3045022100fdb6d70801c889e1173ae9de78a07e55bed999ef39107f2dac1e65d6bacbe89b022004557733f6fe0d96f67cf420691375a8ab23ab212365a96acb9b36aa54f8f415", - "id": "c7e1b81e3cb7f63eb947647fa572b5309b9f022d893e745baffa282f51e65dba", - "senderId": "AMG1Y3LP4kZJMAtoPhsnVkpsMTJ8nnCDr3" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03de80311e0ca23a780507fae2691b7c995cf36fb2b2d079b7c518e03302d56eff", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_5", - "publicKey": "03de80311e0ca23a780507fae2691b7c995cf36fb2b2d079b7c518e03302d56eff" - } - }, - "signature": "304402200bd5d223d887130a7a8b65f10e8f0a7eacda456257dc5eae4cf0f3f7068ed6e402207d6d5dd9cf0f69f592fa81bb117a83cd0e55a21b16abe048c1d4b603f295fcdc", - "id": "71debbd9fb57e0cdfcf42d9d012768a7d9ad85b4b6f32d520b424ef0e0893bc8", - "senderId": "AFxqVbsVuDfnfyd9ciRAuGq6waR5GqiC5R" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "021780f82dfb6331cbcf35b9fc233cf3494e569a329b2966249c5632b0ecf53cb2", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_4", - "publicKey": "021780f82dfb6331cbcf35b9fc233cf3494e569a329b2966249c5632b0ecf53cb2" - } - }, - "signature": "30440220043a0359c3d68ff69877cbf2f116410bea908036f57c3aa1d51684ef9e4d1fa102202a55ae852b5e547c6733d8ea0fdf137f6525b4effda003e09289936be0f333e4", - "id": "3eee8478d002ba59f2ab94bd539c26f805005b24d8d0cdfda6f79ba576db55ce", - "senderId": "ATjjXXcGPTum6wogPVGb9pmimpSo4EDDEv" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02d113acc492f613cfed6ec60fe31d0d0c1aa9787122070fb8dd76baf27f7a4766", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_3", - "publicKey": "02d113acc492f613cfed6ec60fe31d0d0c1aa9787122070fb8dd76baf27f7a4766" - } - }, - "signature": "304502210097b10f85338d39ca4dfda4baf9b86f97253cb06ff2c80d3d9a3e5023b2294f060220192986b55a91bf3c5d5ad1e8f7aebf69df89f022e1d8f8674ecb675faace1623", - "id": "69483bf341ab8e5ef989340da103a162b25e09ef205b53a7d2f6f8547bc7334c", - "senderId": "ARagsXvdeTHYghaQgJkwbdSkPLZ73qdMkR" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03aa98d2a27ef50e34f6882a089d0915edc0d21c2c7eedc9bf3323f8ca8c260531", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_2", - "publicKey": "03aa98d2a27ef50e34f6882a089d0915edc0d21c2c7eedc9bf3323f8ca8c260531" - } - }, - "signature": "304402207f3b69c5fe22ec832246ff2e0318b361849cb8fb7250d9eee96639e17d112ecd02203a4d4010360992f4162f7ffd5361884d787a07580a579da11fee4a8b8b7e78d0", - "id": "d6424b437baef1b93e967a48b29313347e6a79cd93818528c9a7515ad167b917", - "senderId": "AT9xWcPQ8hGYuXZ8aWE57VJFohyX1TTLkH" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02e83dae2b59ad7923d931f8d0ff96588b6f2b2183288c667bacf2888d5f9d80c9", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_29", - "publicKey": "02e83dae2b59ad7923d931f8d0ff96588b6f2b2183288c667bacf2888d5f9d80c9" - } - }, - "signature": "3045022100e6d497a3905baff592921a269d78882d787a03a4c67e7818a5c71aa57c00186e02205b54519080782485a6ca918a50bdac68c0cc1723259cededb1ae9f011a88b919", - "id": "fd90a8bf3d38e0fc81020705be347205da7006d4db889f8a5c28653069d060b8", - "senderId": "AGNMmJ5upuU38ucaG3TUsG1ESaQDExSMo4" - }], + "transactions": [ + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AU9BgcsCBDCkzPyY9EZXqiwukYq4Kor4oX", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ed57f27cabdb01f5398b30e63e3372735ee428e17e95de675c37586b6d1a5c12022062a0040ed189a4adac6c3d105e05180f7c74e8c68ca9912b3c60286c2226f3fa", + "id": "44d9d0a3093232b9368a24af90577741df8340b93732db23b90d44f6590d3e42", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AeLpRK8rFVtBeyBVqBtdQpWDfLzaiNujKr", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022018618cfd5dd1024c0dd7677fdbddcaa6977b57f832eca130583d36480dfa452302202c067556fd93899fb0d18ea28e6f0276a778099cdde3d97d3bb8733dff965a59", + "id": "512f1aa00538b24a3ba55d65519d34cea83d753f5b2cebfd7004d5c0eaa7177a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "ARagsXvdeTHYghaQgJkwbdSkPLZ73qdMkR", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022021e056a123b4a6c30e3f30dd68ff56f4cc1a994222cf27ff5b48434947e45f300220424cbc671a54a019cc655d02b2313a324702908a4a05c86bac4ac83029bb01ef", + "id": "8bb3997878a6a359f1418cf25f31c84f660e5e6897ebd6d07549ff6a4374a44d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AT9xWcPQ8hGYuXZ8aWE57VJFohyX1TTLkH", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fd0ab0bee79152978d8d5835e2d244fa159e4957f48d602c65e35e2383c0d14a022036380dac439784075befef7f7b14734f9ed782e4be5ac7f2f4c49985b08fdce9", + "id": "30cb724924823c689058c25243d1c213b9cdb8c157eff26ee9c89fc1e705fedd", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "ATjjXXcGPTum6wogPVGb9pmimpSo4EDDEv", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202e4a8dbbc11c3628f7aa9ef92825d84cb662a20e0af724d80475bcaf64416007022063e859ef5e9f9dcb294956e14d0680bad69641d1c254ef0ccc733f25b7814573", + "id": "69e5ced4fddc54dc4b688150e8bbb5bd3cb056252708e0d03401819490bc6125", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AW58iWw1ATvzGHu338WqMYvgUhmvMMsRjF", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b1a8dfbf6c37a984acb364311e22336c367c5c76741a29dae4d5f894a496738202203e93441406fe1b23ab6d8807179c2cfe9e4c33bfbc455cc30733b5237af35d60", + "id": "62a85a7d3c9c31eafba7b39b102ff4594c5dce17e5c9ed38ef897ae0970ea613", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AFxqVbsVuDfnfyd9ciRAuGq6waR5GqiC5R", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ff14b9189e4f4d6199737c9b9b00d7572b2e9a5e1d1280b0bcb02b51b233668d02207a9df93b66088faf216bdbd60f438974dd5000cd1dee92a5a391294d717fde00", + "id": "c7b221db20709d99cf25d4a5b75aedc2644c963be994f040c9582c8ca84524d5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AJjkVwkhsvsX6dVKhVxpmhRvz4CyXLEvQ3", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100aa43dec0f44ed1ae07fcca1bd4ed5075954cfe0a0bc6ae88f0a2640c9961cd1502205c750b5c957bb92e7dc032bdf01fdd2765cffa5dcdfdaec7201b8a2fd17e56b1", + "id": "647143b65234e1dd78f258cb32ba64008a1d23baea7739c02db82e60ce9147bd", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AMG1Y3LP4kZJMAtoPhsnVkpsMTJ8nnCDr3", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203519061e2b618b44181bee15f4ae561f710c6601995ee5e38149726366b3d14302200d0414c012b86429eae098b474acfa1c9f29ac4ef06d500eda8a9294c1ce14c8", + "id": "02dc2d050528586dbb9ec9dfe8a4118a21bcb3244d14e61a8cf41337925972a0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AVFkEkCmEg7cuCXoVrfvtH6mKz6XC9XnvV", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210088d431420331051cc29ee00cfe3851ac4fed969c9592a81dd0492c0dac83d0ec02200f2efd316f7506abc7c60ad6151b00977206aeacc5a3a538df94fbbb88a1bd70", + "id": "1a3522ccc27e223953d3978b891e4adc219ab41216b06eb956b138c8dd532243", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "ANstQM4LaxfsuKtFMd8vqdGte3CL9s2vMA", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b6e401941a798a09d5179752ac67c39af596f95d28aaded45a79cc8b8689bfa5022079ada29c01231e3fc2ad96050204047a7d0a9b56c56f609532bdb3d92b152e91", + "id": "574fbbd0c1f28cc923b03cd00bc9f6867fe246a645e3b261b6b9b6b041491c13", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AJqbav8MPPAe3zdzo1f471gaciQbx1SRe3", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201e4f4718c13b10300c478ea28fc4a6444f626fcd1fbe6d45f80504abd8f1e5ac022078c0fa5bd5701dc989ee3432a561e659d7a07c22e6a9eb198745d162a3eef958", + "id": "e1d3f456bc81aa88b5b9f790c383384fd24593ab4dd50b308a77a843e0de346a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AbfnTeGFiRM3m8eHcMsrqNvrpUCoCnuSzH", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fb740effa4f878b5afd3bf8202cedaa7bc4c76b5a9ec0e1791824008b08c04ab0220340e130184ea186b9c7acf058b9cb62c77fea9cbd954d5e5f0d883da8136d15c", + "id": "85c540e0e42f449a14541c4ab66a667a64a18ffb1dfc2213a143441c6d21069a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AXArbuCVSiRuYBkzCAajboxCfNiw8AyQX1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022073143336b15ab2a51da194873e14a2e08da329a325e570d3d525c764a8e546b402207055a169c2cf9b1da89bdd40b1e9a19c579865cc19e2f5e868343f594ebd87de", + "id": "0d00b60f1a26a05d52432e517e59a6e42b1597ba16547f25d5b4cc5a4d821c03", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "Aa5rKoVusA5xiyh8Git1tJUWZE48ScbCR8", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ea59db1db3462c4d08ed19920dd694e707181f63dedb48ad62991935f3f5da10022005d5981a84a82f8b7a881e50a07ffac814fa62d1052d43583de50e0ed62498a6", + "id": "bffa21418f3668024901a65e57f484ad45202ac71196e857d30b61c2a300ab6a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AbrgipEvLp1ZHNJ1GcWWAsCLNgSgDG6Lxh", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203e5fc71ee49506af5218a4d6dd3870493081984f16234dc53339e6dd411d774302200293cee5f33cc54c22c766f420a0658107339905c6d6b745e88d49be6154be18", + "id": "77456d6e6fe11bd3fb7ec636e115dd6cd105cfbc97f2c9af37513f9f74737c97", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AWLoVgSScNNB2kecswuhbY9tcrtv9kf2iC", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210089cb088a883d07418a6be847f45d2fdb1c8c09cc506b5ead7df7df3f54cb503202201b323319c4e8ae723c46886fc51ba311a722e25a0ed87a130ca57e9d6e725dd8", + "id": "79c7c34636d6bef31813438d5db5c2b02bd8a7964ec1654a2e24cc24563f5695", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AbyacFxcWS1JsokdRCx8bFsWP8f48XftmS", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100bc987030f590b970eade8df22b44f13deb89a652837b3cdbd9274a27b9d97f9802204ad6718c262ab2eba80202503ef5cc9704c13b3ebce7e2e5e80489e783e34540", + "id": "8e40e07b53f46d8b42c90b18383ae19d5af69ff657c13f5f6550890eb65939e3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AYTEu82arYgRyvTgi7dbYwjodV7ignYucz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e30c20254d8518201f0a46ec347352159ae81ab2d1a47d582dfb20bbbfbfdb7c0220300c012e88a107f9268e7593f2adebcf7ab72f2d240aad37b58b139d02067f40", + "id": "23241fac8b9f633b6749f0b7788ffaf9ac8997168c55718d7c20eb688856cfbd", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AYLTbdiYWHvPvJo5Lh42MEVS4Fnepg5vgc", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207c919607f7d4b17b0dd54cd82843f4b4da3f5c5ea92f07a1794f0fd666f065f402207245dbc1d97ed651e14849c84579f11bee9dad72ec7b73dcf0b3d79cb7d68eaa", + "id": "5c78d1808a47333800b9604fc1ab2352bd847ea5fccb9f834825fee74e5aabe0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AGdHR2UZ3MJuaXWejKGoAycztyN8BFQnNG", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f6f1153d93d37483e21cbad1b6c07bebf95a8d13dca45e8c51008a69be736dd602200f81dbda9b257e6c12314bc3a20c5b1c8ba86e0deecde76bd1606f79e836e008", + "id": "fe843047a6d408de46081217cea6f5f197f6c2aba86bbacab00240f147002501", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AVi8PFHr5jFBFGWSissPFDFXUPABuBgxSa", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022002a5daa6a6ac2cba5804e8bdc21769310f76fc6501c61147f9a5d97ff35737ac02202c6886b09e65cd90b3fb5ab5c906bf98512ff823f21cba66ee684c3e55e2058a", + "id": "eba8ca8a4c458bd3e15aa956a15e4b8cdf9336bf7d1050e9ab44bc83482005cb", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AVoTzMjHaaWKDuA26ysXGU681N6Q2PQre6", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203e6a954d0044affbfb9bf8097fb12fd030fa4d7b9f921a797ddbdac7d64d357002202404106e049c35fba4483451e9522ae46e201c916d50bf6971e5ffe7bc1f0155", + "id": "3c8b8785bb4213cb8df30aee1b061fa2ef0a515b59f05abbb0fc7e1c36f2052d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "APXkAdLbLiLJDC9Ls68Y9a5ws3PcgmUDAo", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022022b5f2321cc614962cb4fd9a1eefd128986d39285b59f6e418e459139b07528f022050988e49f7d25d9a44765514d50765a0f43a47b306df56def037be36d9c97d01", + "id": "ab8a92d54c08815a6dcb5561c0dfa0e93b8552eea75e3feac096f5a5e4eff784", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AGZhXHXFUdvd7W4aWs1fYJe6XFUYeSWrd4", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a66c0a231cf6f09d6ba27d7a835a4458edac26f7efce8fe1c6b58f80f88cd00e02207f92221ca0873e10a6415e62cdeb4da836cd16336715cc861784762d387a1749", + "id": "ea59d2aca71b241d063cc41061adab57d97369fe0e9e3bda651ada6c712665d2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "Ad8UiXMZPecuNGwCXZTmF8Mysn1TchVVTf", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100af001967b21b5715f68047911026eb0cef51d14a8e0563e1633b2bf213c191cd02204b85d55c4b13255b488a661dba416f7208237dc12c114040fe54692f76a7fd57", + "id": "b8b63cd15f19ef5671309e8d571482537d88af6226248c2fa0e5bfc3750606ed", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "APQgLh8MaztT1XuWVKb6d4FKM9HMmdmDVB", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206bf4937703d0b2fc171b86ed8596ba5ec58e9282e3cc4ac269192ce670478a4002205cd8f627869c5071fb99db462c47655eafdeb1b991beb75bc48f62a56915c137", + "id": "e1a4a5601e46dca9c9e2a5a67655bf976764efe72e82d2cae07c043e46e29928", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "ANUfH6C3Jjp46pDUxWgeV6WUbWCagaVxM1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100acc09397ff3c0b38214df5bead49d458931197b22e28426826d0173594a75a0702202d22e93e84748b52edfc2e420ddbc6887b9cfae3f7b7b3d7781886f085b9618d", + "id": "e47687f406ffdc59012079854958532ae22512e2021990c0c11cede226c64d58", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AXuVpX3tAewNp5YVWvXWv3etxjrMDgaZdK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100df1255aec444d8ce3ac9cd459669412376eb92d281ec0153c7a525b43b2cd7ca022078e22a0c52eace076baf1d89bfd03771ed1b45dfea105451cb9490371be6908b", + "id": "a9301a31302384e0428be63ca0731b93ebd2a2c18534b2ce771525c4a0c1a708", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AdCa1oGLMRQqygEBGGq1AEtSV44CJ5Kbdo", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220181358f06e1a2f2d43538dd72e7ec33ab64a39c92a512f2cb08e08fa32c3e2cc02203fddae5a4c9545093c9668c95688ec07b9b7ab1be27eb3efdf0c0acc41b2bc61", + "id": "f10ea8612fdb470c754f6ba5271d0b30c52c12d3a89ddffec0151cbc90e8d6fe", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "Actv8ebcwNsbfx8MM5k2AeJidJuLL7PotT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b2c5014c3967c971f57c995bad2385f5d3cdbef34d43304d17be215984f986de0220080cdd2e5a643d7dc8fa9c299c5456d554a2d46713ce3a8901abd94455dd5929", + "id": "2a992486b31f723a33458ca055b878e51f1c13359cc4bda87509fc124d57c6ec", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "ANeLRbMxkSguPMq9CJeMgr8xZxwZ9mbqbx", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009fddcf0b5071d43e7cfae4f9241011718d324ae16692ee674d668f09434041bd022050fd7c97e4206c2e07ef98032ed731593ec0cd8209a9debec36f39b153b752c5", + "id": "3e6debb349d1059af502804311bcb2cd37368d67b33845f9b50e4ba296d0aadc", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AR5z28tRUnvaBWC14KSBpvNJDgsVCNtagq", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220747d72aa2180e80d190ae4940dbffcad648ab743d551ee70ef221439357aa14a0220334be2dd1a004d188539af503467b37dceab37ec55ae5a035801746fa356412b", + "id": "7b97374ee88b881af118a757167c49ee0ae60b0ce88e377a200b015f87441b19", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AKeDRRgG4TdDo4Z2iCzaBZS2UcvjWKMSrC", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205882a3aa05216dc8495784c9b842e3066f331014c8b55644804deccc10d696e602200fae518daafe7c9599a3e9a4d1ab8388fd3e5751af5e946c00a0d5d7c062f82e", + "id": "0d1a17ff619a2dfd5b1d2abe09600fd1a9ae1f373ebffb70bba1dacf7a15947a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AbkDPAUDsfQJgvHn5g8AisDm9XqLAtFFai", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022016ea5da49920aec7c20e293270fc5aeb99a7a8e6020daee092ed11cf48b01a3002205d10abf6cd111443e4ed7ae84a9f29791c5441cf99dac64af09611d6dff00dca", + "id": "4888da0a60c337f287a6526c9fc86be8bd85460ac1e48aa39b5d2f5c4a4018f9", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AZvjdJSG5V4WnNjPaRbDNfLD72j3rYWqbs", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202d089f163508a18c061fc42c70a79583a0081d9afb49dfa36b7f881cf73a48ab022021dfa71c41e3b7303297dcfcf63a180094f0ec58953f52e8b8c424251514f7f6", + "id": "be67562ccb6fc1d6a04791726fbcc111067d5d54076425b91380bc9442b31ea0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AbAeJ4YJU5rxuNtXpDn3E4W5E8UNHyc26a", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022015b2f957cf3fe5f690786bdec5831efe41b59ea82a357bc520500c77ab20d9cf02201ac6773a21d83bf1f0b744576b620838ad984e6954965db199fea922ca5680ec", + "id": "2101c235de152ed1a0bde3f57593362d73149e1cb1e5b4df855718c392ac245c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AY5GwZtG9sFvDzMKAQfAD1Q8EHDh4bW718", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200ad645598de2adfa46f68a9c0b849457306a8744627c9d5a085238bcf51599fa022035823c617d15fc35bf7910a88ca45e47c9b3d2aa6c9146f6c1db2b92de0d3ecb", + "id": "f9aa1c9331948314027579cf07368180d49b452bb747f153c0f25c39328d955c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AP8agRcU4WmsYhC72pBqyfLwaDU6NYKUL6", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207b203b7f10f7fcd1c29379603c765d37d9c1eadb787885211729b63606fe7b3502202862e0cdc7af6f3f2ae8d48ce56b9a76bd38ef3320bb82f21bef96c6d793eee9", + "id": "f6445a905a38bf0454327fc4cd9976bbd971994b48a55906ed3c123efc0f5370", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AaFxHxsjYyYCsZtpQwwYGvYESogJ2SHxe5", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206f4c7616b756110ad060c31c2e4402219f77bd266bbf2c0bdcb4e8969cf59cb4022028355a38d68cf842b88b67ca9d9e261ca5adf017e84b2b5bf04e7adb6062285d", + "id": "4ccaadad7365662dcda0d68a13a18ee08174e2b0ce3638de5d45586cefe1fec7", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AHmBqWJgxZfaC2azkyASdrbCxF6csE7Qxx", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220088ea11151b787f4aac1c5bed478a83ed2b31a013942ee76f6c8b5a45dd1fb3d022068d99ce4db49d383fe1987682a459620153e616de651b45f092839b7afa4b29a", + "id": "600b4e8a38b45624d23f8f6a11424cd20a9ed956fa970cd317b126221c2c870b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AZengw5WND4WLC8JKz6xUDFwLz3yCKPpTC", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022001c34abe513df6f732d459e995d5ab3ac6ce064213ba79f502472fbd23d2a41b0220799e96bdbe031aa06aa9fd14cb25b49b71244298cc04f5835fd3c947bcacdb61", + "id": "fca76de221fc1f70b642f30c4e5ea024f5ff886fbbe2f51f4ac7fac4bce94629", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AeLV4NUMsPJW1nvHquBWPFVKCWirs1pshf", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d37946b7e677220e9333aa5d428e8b82a8553d2b3e0c1adbd8551a75112b54ee0220465fdfad076cdde91b5642305ee4c237c4093dcc210b9445c374660b1a11ae40", + "id": "6680f73be6c0d1f96e187440bf3575eed655477e15d8f1da85388453f5c9390a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AJrXd5u3y6FH5HktH2jgkLQHjgD9ZztMtk", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a97bd4beb5444b5c2dea233a7dfc11c5ccb705a88799a7386f188a159477ef56022011875cadccf32228d693ebf24b6a1acbd574b615dabb2763e4a29b75591dc75e", + "id": "0520f4b24257ba8ad735613737ac0f0f2bd593ab5c52edcac746f4bbc8c635e2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "Ad6y8ae35QWkrtiLBpiXRR5Cj2KK2u3EGX", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b6065b0dab807b36139d101154d5e16c145fcd9ee807c06e46ba60e172efedcd022030e641f2c5ee29da508ceab6649593a6cb872d89d4661b3fb2b79f48b20c4ec9", + "id": "04e36364fb8007bfe7f85914c22cbe4bad262c12631ec4f339858d82213adc7c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AQaKx7UU8857b4tJij1jb7aURUzd3GDyKt", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220540f725157e6fa9e1d5a7e495504b5007d9d554ad8f0c275e0e45a04028cf27f0220660a555068c7402672443beffc2bcaef8a85f06f9ed38ab558ede7a21e265bac", + "id": "3dbb56502f32939958b41aeaf84e9cbd4483a85b23ab32f979a3c1f0d683db10", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AGb36aHfdxvqbMqoDCnm6wVkKKtqkE3zAh", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022063d7b93cfedf0daa9255bb1ab9a3955367c5bc8941b386f548fb01db85507bb902200cdde437236daa8fc1b396fd7de9294a9cdcbfdbd22df347bd635bd66581704d", + "id": "1c99e21a5232ccecf47da6b530eba9ceef87f02baa91cb333fcb3b8ca18edccb", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "ARDkQVS4DbJnErrptyWSWdJD8gtaPEyRH8", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c1b92b570f6abf42650414541ddf44693c61835816883bc2de0c4e7997926640022015e109e9f622844d8930a8e497ea2af2fae7089a4a110ff2d3c6fca46b19a70e", + "id": "fda4e22bce9444a6bc7d952c0cab822a5408ff74a19aa8e6d47b61513e061bd3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AW91q3n1QYTn3caBm7KR35zexcJU7PgMtZ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009010a3346835bd198bd011a5a3cac7ef94685c96acd668ee92be386e9b267fe2022078a272a9552454e80ff83dd2a01b3621fce5818d71fbd6430e0848ba85cd2c32", + "id": "52cb2975b2dec5cd21beac470055a254a84169e51b1a72387757a340509a5049", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AYaYHEKaJvLLWX2NgM8VXk15zSDxV8vCgn", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100894832a480b4ce89972badf315ba89a21f9c200cf83dc402dfac475107197852022036158362b58228e69defeeed4035e9491f20e38b8435a4b8afd86718906ec42e", + "id": "1b693cf3a23efe80385fb0f8f2b7e1ec123af4f5b99795a154f7dd1aca505950", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 0, + "fee": 0, + "recipientId": "AGNMmJ5upuU38ucaG3TUsG1ESaQDExSMo4", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e2d35dbf837de046e351c2bdc8a7061edca5af3cf01d8c47ed468225a85f688e02202cd057264c2d6f17a4b0ab9d054de7e6db6349eb1ffa2beecda58960ce80b4d8", + "id": "509e2950f47ac036f4ca1545f3f3e4dee77db3756682175d292558b920948579", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 128537390, + "fee": 0, + "recipientId": "AapqpT6xF7q1Enu44UkL75c76uNuWmRWkB", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ba8eec5c24356ccc89437cfb53440d3db1929fdae0133a4744a4fc61ee1c768502202775dca5d3ac6c2c3b6d5b72e58a975cbdbdfeacf31f26d46486a420fa12bf9b", + "id": "6300b6f026c1e1657f7d7328bcbe58e5e1c6a8e56eb5f1cb1402bd1225786c90", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1470150572, + "fee": 0, + "recipientId": "ARc9Qz4v9wNbneBSNk5s4M1RKXwoMzLiug", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220084a67416a41da67ff634eab70f88443a7f3d531976c84b310a07cb0a6ced39102201f26c0d886785aaac15d5efc79b9545bf8da36ec4b4a491a2d33a937a97bb9d0", + "id": "33c5449bf830f309809f67aee50bafdfbabc3fe284aed0d5a84059baec213843", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1939749374, + "fee": 0, + "recipientId": "AcE7Xh9FTaMB9pUKQgST1BHfXnpmganLAN", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a3515ef9744947b6b3cfcc3c6bbc6ccc05b7c158ecb639b0a46b0c5d38132b3b02202d2c20ebd19a0f60da85961a6dfcdcc905858e11556a0fbe3f37a36ea286703d", + "id": "5359b1e1068625f47432ba3a1ac12fda7411225f9be163d7248c25a92080c496", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2223350287, + "fee": 0, + "recipientId": "AcGWNuiBErRUP9MeXGW3yUQrhQTNKh4keP", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207d9fc26887b0a6ebc7877d0f96cd49fb6f51e09c5f7086c8030740bd19c7f8200220229ac976a89a3f1b061d7f833c916fc76da131629d0373e20f6a10680128c246", + "id": "68e9ebe8e03c06a773223752296acaacc47503411398d75ce9aea8d1809900a1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2635948642, + "fee": 0, + "recipientId": "ASHDLexaM8z53tcrddDC9qNrG48KiykCFj", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220390fd742fd9ad375f06b2dd4be9fd28976facd9ab58a3b497f9c53627c54903e02207a13f2cf4b2e35b512d9f25344d7cbaffa7533a841b444be4131ef3ccbb9a707", + "id": "140dad637fb5e85d9bb48885be2ce2caf63599982325fceef875f5438dba6379", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3319628053, + "fee": 0, + "recipientId": "AKoFbGWi8ZpD1FKLtWbs4PFdR4H5L9mNqj", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fbaf95f5cf4ed909feefc9b0d3d82a27c6281837320174fb9c1cc65c6dfc4b3c0220571f50b5ba6c1b9effff224d5ea08a1dd79753d07487694897f5b053cc7bac56", + "id": "fc4460c527373e2cae1ef706aeb846d0d011f5fe3a15d5b29727ec6d4a65b378", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3500000000, + "fee": 0, + "recipientId": "AcT6rrsUh2T23TXVgfXxXLQKmpRbECs4N4", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ce9a0287b36c323e4dfbd845a2d0bd30cfeadbaaa4314c5055d3f4194d05aa1402207aeba8bf92955383a8bb95ce75628a258c5ce379e3bb482787b66db194bc24c6", + "id": "255952a161258cd10a8e70bb03be46b8005101f05ad0ad453e50bf8b5f1c39c1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3500000000, + "fee": 0, + "recipientId": "AYxobqMdZyUFvvX9o3ihE4iMnZWCzQBhgs", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a8ba213f88717697168ef6647a89ea7d7d1a7bb56c8b82a27f4019cb351f13b502207afb90964461534dff853f2bd8a55e36fe6660de37b0864f65e4220c45cff2b5", + "id": "4a761497352e5687757421e2cad81fd7881c45395fafd33fa5d4266d98d3b40e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3606920711, + "fee": 0, + "recipientId": "AMepHWLBpbShRDbwLcEJhyHRatqGAMDa6r", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a35fee7952af116cb4ec7b4881f9fe5056371287ee26034206d964171c76f05d022053b2d4cf6bd03c89db073a25270ce48fda9b1c98a6cf19136291b912040d8917", + "id": "5cbe722d6e53c668c603db420a577c8a88f2c57c838141d7b0d336ecf4d67541", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 4373745201, + "fee": 0, + "recipientId": "AXZCfAqHYyFUpYxYgNyw6W9XVngp25rGkq", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d430485cd384e4a58efddc72ce62e203a5ce80eb29699fb293b7d378521c932d02201e0d8cd73d3c98ca4973fe45ca2d161443f045125c971304864f9dc4e7d47645", + "id": "4f29a835860ea8533c479ecaac35bf14af9c12689a4d40ad8f4b07e55efe9a91", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 4410451715, + "fee": 0, + "recipientId": "ATyCrCUvZN7hJfkYWbCXgKfEZp7PB7ez6V", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e90a709462f9654e698f131cee2fe1ae82852e12909909c32bb4ad8883e5e764022065c75a2511725d489a625ce0f4321119c43d2df7831fa748d788c879cea94eca", + "id": "16f6d59d7b48c528332ba917f7710f5af66dcc647a0c129165da7508aa93e826", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 4410479871, + "fee": 0, + "recipientId": "ASrrGt6HcDBYe6hTqX2p4cD1AjNfiC3vnv", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f42315460ff894d560857f7b863e22b8e9b14bde5a86ccd34c4189e37e83a8ed022036ad285ab692485715db059896f7d394382dc6ae8386627d6bfde5771a01279e", + "id": "6497901d7e0d33d9ebc7b510100ada1146f9be06e960528d789c4d62f1198855", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 5445780417, + "fee": 0, + "recipientId": "APRgb6yUmpvtaCyPmLuSzXPucgPiJ6FRpJ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100cef35ed420e2dc8c5f0de5911474f0b22c0b5f0eebf9cfb453f6832892b47fe502207f52c64e0bcb8fabcfd641a8c0a680d6f6a80ce47df726e276f620131f681c70", + "id": "1ba4319ef107661772377dc6587a13c08493dc0a02499eea9f69de567fce243c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 5549484283, + "fee": 0, + "recipientId": "AQqQZPw1ZNhRqmbYfVisYc6muRF1TrUk32", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100aad3e80ae4d92622e819f38872ef85c0edb22300dfbc3fe8ec67ce570c0fa45a022076ce462d4b9cc5ae6340eae28219b1949ca4e5d70eb01fb70c92d759513402b6", + "id": "ddd800bcdce22996cf22036b8de5903e7f5719c5aa9142e4aea0a79b25837df7", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 5618558679, + "fee": 0, + "recipientId": "AXd5pgP55H9Xd9i6ErnzM3mWpZ8hZpYaCN", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b5860683085463cbb8f828e4749c08b31e1c8a0cb5c5be8166414c7d38da33100220053a0efa7541a6a63cdb752bf3ca7eff289d4314c01c1215ee86dddd27d0c68d", + "id": "12bc04a7470e5929cadeaaa4f1ac786861eaecac4f6792b38b5bd6a8596b6395", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 5677245896, + "fee": 0, + "recipientId": "AKURdwRzPFAS4XhPUtBAqKrTrLu9LPqFbj", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fcef07fa5b582bf19686f0df769c110a74e2503fa653475b82f7f5e6faa3be0b0220647b219bd0b2163b6fa363b62bdfef06f2df6006325b878455f806dfd44c09e1", + "id": "2436864a65bb862ba864aaf5e6334bba91a7674a032abd2ad9f2a3895d08309b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 6558699223, + "fee": 0, + "recipientId": "AaNyZo6YitELcMW9SyWXiG1FVTUmrK39Zc", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022078ce2baec0753ba02c05dff2efe59dbb628cd279307c7bd7d884776f2c15f35f022007f3cfe57778813c908496b147ada7c6d3531111cee9fb56053d09099a4b878d", + "id": "64277b25a02735c525a4f11417772288ac3e71f0fd75c8e00d6f40e6a2af8cb6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 6900000000, + "fee": 0, + "recipientId": "AY3adwSjUDSKysWv8Ym4UaGYeqDx9V5a1v", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200cd7794247be234bb63d915a2c777372a89d0762c3c5299178bccec15b6be0ce022048130b001b7d24136435c148838e1caa6b176b98a0fa052314e408f26f81db35", + "id": "644fdeb9e3e870bf0e6558234075ecd9be5addff36f9fec81c28aa7c8ff57a86", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 7350752858, + "fee": 0, + "recipientId": "AY9k6pyVCWzkCNdnfges2yjGJVJyhLdYw3", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220216dd68a632f1f0846cfb628921df1ff06772d478185d05c20986ba09efacc8a02207ea5c3932b37e98b491041ad0169554e3145e06a03088ca5c4e92a6fb184c6d4", + "id": "00cdc908312961a8350276e109985ee2dc325a984d92d8ad64d60dafae5e1ef6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 7350752858, + "fee": 0, + "recipientId": "AV6aU7fieAyQQhMpjAdiUPF8w1SMujpVo5", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f9e222aee99a87a56193fc9661fcb15754e43c41d3a37a1104c063b8e754d37202200c31da497f5e8e84069c9265d816d5ea8c80591836ea68ce94b4cfad308c619a", + "id": "71788c698bc0997546b1c9c2da21cdc2f391a3a295193c61582cb5788571c5c4", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 8174205069, + "fee": 0, + "recipientId": "AWhKaR8aPiTxfMaMypQqt2LtfDEUGpB1kz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ce4bac79228cd04ad09239a51a423a4c0e3e0aa48feecb5de9d3ad9402b6678b02205acaba891280ef0fe4c1ea18ed56d6c0693f5a0d31ae9fd00e266e3dddb0c5d5", + "id": "586cf12649c475cf490b6f7ad6bda018032da30e87bd257ebe2b222391e932ff", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 8335753741, + "fee": 0, + "recipientId": "AW1BDJsPkEV6AUfZtk5js9RKqHYfjEnuBH", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009c055053f467f1571cc395463e23f7225580fbf5814d17756a7a421eb812c709022011f5a333a164b685998de4fbd5625c55a35c4a35e31643f8653b74f84d488836", + "id": "dba64b2e7c7f94a2afc083b73fe947c069070b534e442cd5958361ef4b22880d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 8793099579, + "fee": 0, + "recipientId": "AH2QuDHZFX3rkLFkFTBrRshjz9VAaDVu2z", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022075820ff7058679540c808d1fceea1033fef3c80fdbdc1f7409ad40e9ee22249b02207a60b839bb427497387c71965871304b2418afcc7aef71495b3bed16bbb87445", + "id": "fd79cc4dced6ab4862faf2c0b5cde19b3ecda72ac2453558001cee1e5f90af09", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 8930739717, + "fee": 0, + "recipientId": "ATiYQXzewAtwbKtNb8n5uoRpATXvASGu9C", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022043721eada610fccc21dfcc12eca7604854d55ff996a1aee8ef1b6ed6dcfc9c7c02205c1b63a8dc3317a90c41366477b12e6bbb4b26aaf1951546b956b2a019849633", + "id": "4b309d61a46af825c19faec1e116c949e0e4958bed87afe0ef3c81336e269169", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 9285850665, + "fee": 0, + "recipientId": "AL2DsLKiUjXFKBbByaLP1RsdUMeNyj8Pre", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207310e88bc29ed44d42c60cc2bfd8cd0cf41751a7c44a72d47f0ef597a312efc0022074f06ab9ddb0dd66b6095f8324a65d8e57841db18df7569427e3001222bfffd1", + "id": "fc59c5754fa17a47bb34b642ee71b99fff47e1cca8d877788490a6401c1f969b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 10062477006, + "fee": 0, + "recipientId": "AQjGegCDm4ig1o2hAmxBwWYAta74ZvS8f8", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022035956acc21b16b19f446509f805fcda6ec6aa5bb09803e9367e3459b05de6a630220310de9e98092f88787e9ccc503bf67439dcb47e4516eeac015ca5064c6c8230e", + "id": "96db83cae120bcee57cc27436207abb76202272b558e5fd7579fcda5f5f9f61d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 10090126421, + "fee": 0, + "recipientId": "AXhCBxMufzWdxQoGQi3ZPS1SQokqHr7SQ2", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202cda06e19276c0d76680c0fd5177c8e143da4863cd47f2ab4a9f9634abf0b28402205e278ca769cdafefbe74862d94df273382ba379ac0efd90c306d817951d75703", + "id": "f5a2f41b66cb6ddcbc7d68cefea3f5b884f18c2e981eeb8731280dad92d781e9", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 10400000000, + "fee": 0, + "recipientId": "AbDSp8xeAfoUR6mauGYE5P3JTDXXnWYmjJ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220684bdff8dbcd3dbee5bd9d98d630db30d6e285f82f06349cd4c85500d4e20fe4022049809890d215e9041fedaa8996dcacf2b59cfa949ba44d5b19bfc0aa3d993f77", + "id": "6bcee0de136de52f7fa27f7641d3fd661bdc17069f874c189b09593936b9511a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 10469786602, + "fee": 0, + "recipientId": "ATQACwzUT92xq8ftk83nm9gc8cDELLk1wt", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203261caf9bd95edc131e4c18f7c0fd985d477314f70b85fea340501934f6968f602202c0c225421471e7ca9ba8e1bf3fa38ee5ab35187ceb5f272c6eaa36b2fcfa127", + "id": "8a8a7657c453a4eceeba12235add5d02a27dcfbd27a82238e586e673ba2d8dc2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 10792241696, + "fee": 0, + "recipientId": "AaD6oZFiPZaWDgAz3NGdjASA4Lcw1n1yFB", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f80771b2256f6e642bb27369d356716861ac83bc0d779870055e53a362bed01402201c5e896aeedc8acbe608ec78f14b87c623069b627d5470d835f07db98dd3394b", + "id": "194ee2091f2dfe779eaa985ae67489ef6f4caef181911050d2d3615292eb9345", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 10860889308, + "fee": 0, + "recipientId": "AQr31AJnzbHCTxtVgbguzDEL5VLHUqpjhb", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ffaa693ebc94e479852ec7d47a90b96f82eebaf2c00b73adfee062ec8f764851022039b50274a148a43a23f7744c30cb00a370ebbd5d39a2e8aff5d91465f3b3a95e", + "id": "177f350bb7801ca83c881fa56256c9f9d63dd8b78d508e67ee74d8455852eae8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 11300031743, + "fee": 0, + "recipientId": "AKgJL6ko3BvdJXKdRDuZ4f9kAdvmNRiq34", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d2012faa0994f60a9e9ab7049c703e223de18e4b89fc71b2204fe73b17af9708022024c5294f0424a68afc1d2975f7d300e35a4440b937f49684ceeeeb64277cc0cd", + "id": "b513d351901d269acf8389af328ed20dd0146542f83b80cb4c3ba8f8a0fb9bce", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 12028504677, + "fee": 0, + "recipientId": "APg3XHNRy3pxHmg9jnbb6iSqq67dEyeup6", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022018b80f68abdc7e6940dca597bb8d24c3a6150c3b6cedfa85f13f3e73aeefb720022047f45325bb01e0d6b9f300a80b0b5b15d5f9f453b646dd84371cc23ed63186b6", + "id": "e19f84fd9f142d50860f6725a79d8c1a14b90e19301ca793ba4a1d13bed8ab22", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 12416758078, + "fee": 0, + "recipientId": "AJZA2GSpqAAjxCBsQS6ASjryGwFvEDz4wY", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022012701d828ce4db33b2f03f4dc42720189cb3e0aa82f48ff8e0284b3a4deaa0b902207a1685bd283e1c51c42002a8041c31ee518307c4b86c7f22c78acdd863cbb4a7", + "id": "3c75b71a126df25c97986d07402e8b153919ed29dd8e86ef7b5d232dc4c27141", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 13626793145, + "fee": 0, + "recipientId": "AHUzDz27ouUBRnBB8MVYEAjaEkjzfYxAZy", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207dccfdaccd0afa9d7fe39da6737f1fa1588cfaa83011f9913e46f9e0bc2d60f5022030b46c49b11c5513d7041963c76394f6a643f60fc9f76af2549ea72758d0d33e", + "id": "ff635c6f6988222c2dfe24ebecd0ce33f5c9310dda198657343c16d9c2c73163", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 13900000000, + "fee": 0, + "recipientId": "Aezpc3WQ487fMYKeoH5CxF3X1BQpG3Z1Tv", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ee21909eedef0a8e7c587263c5a6d8430dc487a1b96ed2d5c662e69c9cc6cc610220341bac16dd02f854fc19f9f3af37489c0b4f4035bf309bc6ef81f22997a3b814", + "id": "06f9cae8f3f46a0f3fe4f1b53efe34cc8c502bd1fbbb2fd15d52d8d0cef3846d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 13900000000, + "fee": 0, + "recipientId": "AUhaVctz4y38gYtk8kAH5iiHsUZJyiV9QK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100cc8a312b243e021212b170071f32ce4174013460e275166c9f17020e769de2c202206b71d09fdc88f4ac32677c19ccaa21408045e1756ac5d7ab4b94352dd21ed038", + "id": "e5a8d56567089b515a7878383ea67dea1690fb4624e8870f566848a28fd2467e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 14407475602, + "fee": 0, + "recipientId": "AN5fzWHTJm6LuJjU2iLqKyS2HGrz7n1awJ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f6203ac00161224464cc3c4ec7df00bf57446cbc9b19d96b4895df4a550bc126022059ec4181988c1f19ae9e790098d17bafffb2668d11b4aa2dd6581abf4516de0a", + "id": "817ab520c018dbf31f24790d8ca23e5f5c1f6e598cf204c58427289dd9c7299a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 14554490659, + "fee": 0, + "recipientId": "AWQzdRCybJwnWsJcB4Ux1ZWCcudmuZj29L", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f61c81d36b176998d3c00b6490c0ecc79726693b04f7f32bdd0522076602e99e02204d8bffead0b7adc26cb5245c5a8de9db29909a4982bc1d371db83e69e005864f", + "id": "397f2509d05348aa49de4a15f4d3adec5379ef12521541ba3388d2c73d45ed35", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 14561654186, + "fee": 0, + "recipientId": "AdBh5du8W41f6JXJxFVmHE5x97cRG9kojq", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b15dbd1e14d3a4ec461cf52edf840144bb0094e09e2a9d1b91f9a9669f6b929f022038ae77df2e975e856a57f656bd04f4fd8b08b11166503de53affdf50da0891f5", + "id": "39d14c1d51ac1509fc9dab4be8b3b40f540c12b11392fc7fb45ed208f0696ca7", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 14701505716, + "fee": 0, + "recipientId": "AaoM7ppRsH58K2ABYH1YxSyBKW7z3FrDpY", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022049720a06d232f1232cd8f09e17128721f32bac33a8b210baa322ff6bd813f5520220402aa73d01e414a5953260b79946172ecb53e02326c9baef65c0d6a80e71afe4", + "id": "6d93427a7be1230f2faed5c635893d0f7e376b9bf13fec2ebbd7d6d314bc7e7c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15000000000, + "fee": 0, + "recipientId": "AM16EJe7VJpQtFPkoYLyatgNDJmaoNW1EK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ab3dded9d9a320de89ad11a137ec45cdc6caa558b1ed312c2cfab6a5e73028df022050adffc944953f798ddb791b9f233e1503856f6c16867e06cb91fc18f503685b", + "id": "a9e8e4e49962cffc045abba3b6eaaa77f2955daa6c3b2bb62497f861e26c5b04", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15000000000, + "fee": 0, + "recipientId": "AUPFE3QxTSpq61H8T5pumPcZNBtxbPSCvr", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100bc62bb643a1344403854746bbae7bffc44228db69528c485a1bac9b44051160302207628f7a3ca9b230a77dfa13714572f0f28d421356288fce43d695753077173a2", + "id": "c4ced95ee40260f04bb935b7709c4a19c969b77311dcc75537165c30f43793a4", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15000000000, + "fee": 0, + "recipientId": "ALeKWmZh3XGjdgSboRyFU5p1k1BQpuriwt", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203abcccd1b15a9857f111db5dfbc65135ae361ff3548a94cdcf9d18f38f1ccc4d022064f4dfbb1a13e532ea2d629ba4a4d5cc85622c18e6f5fea4c5cca9de6e8aeca9", + "id": "110689874c1ab40dd0cdb8af84630a1b89074c4f751e662105017f5e351e1841", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15000000000, + "fee": 0, + "recipientId": "Ac9tpzJ5h72V7rCobsaLxeC2Y4aHmki9EK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200a67c0321177682ad46b56c287807a6c6fb3c68cb35e7fea4325c26b1ff3c3b0022038d12784c4b342b950f43dfc5592d57703c33e331e867a33fc0bf5d6243406e3", + "id": "3293e055b85c9c3a34f2099261032891a326cbd39541a80dab24cc4c5efff8c8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15000000000, + "fee": 0, + "recipientId": "AZ8hMVpGVT1hyHt8nonk5ip8fKFCST7KZ8", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e1d4503779cf4c4e9e90579b2de7eea38a344ae1d1a5be81961309118b13ee7202207b977b82d13e913e0f4f9f37ac713b8deb3ea5b752cd3495af4a00a99c62f853", + "id": "b1d086b1b1bdfb25160c121232d62f2246e0f2125f557f7657439def1a5b473b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15000000000, + "fee": 0, + "recipientId": "AXxBftbe7ARvVnaLTpXyY6bSWSnL1b7iQw", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022057b0ec2903cf6d7741db49ae7ed7e6243e2bda73f878c5ff93e78b9e9941169402201c199cf06a81408eaafa26c8dc6195f243fbfd193076df3ee362e502b555ba8c", + "id": "5555d7f9855671019c47805a4aa14c3054fd4aef01fa161cb7d7e3fc79388b0a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15000000000, + "fee": 0, + "recipientId": "AcB6nKH6ueGiN1ygXurgkdXUVTNGPrAiVA", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b9a86d98d13a708b647d00ca9a28732af3707ed3ea34b173e66a20340666eb9802204de9b88e185c87055b454f146b8472d6513883ff065ebb251c155e59ac56ce28", + "id": "3922852d56b26b389bb1cbcfaf3235d2721a9e65e72185946dcbb46e09de2889", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15000000000, + "fee": 0, + "recipientId": "AZJByMD3mzvS1ux4emnxrJbYAf2mEsS8bu", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e7c70ded41dc8ff70b306e5fe5a01fcbf38057d2a38875e9618deecbd5e1bef40220031687e7a7286f4856e056fb86a600c5fe06cfd05d1373ad451a8e33c3d7ffb6", + "id": "dd619abb201619f8e6361f54aff5d95ab8a45f1b75c866e86a68b4319094bb01", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15000000000, + "fee": 0, + "recipientId": "ARVv9D5LedrdyjyuLPM45ALNowdWZCu9Ww", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022029337e12c30c5a1f3ea0b17a53dcc263bbb88343f140765e5dd5b7661cb7249802206c50a6520a2b47313a614d9d657199b5bd22f6a58c10374bde951078ab66bdf4", + "id": "271e64895989fc542cee02a54399c1e8dfab53f596658a095d7f3818f9d147c6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15000000000, + "fee": 0, + "recipientId": "AJ6Swgm7ABDGZd7vdBuAv3xHL64MGSFZ1d", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220640d9872265a1f6b0649c593e9850bb77023c1122e0483e03924cc44d8421cab022063368396d31392bd0fce5b5aeb2d0a745a4462ee3b47bea7499a8bfdbab3e218", + "id": "b1c51b691bd763cf532b060f04238af305a3965f2755d3b8295c1145c2c78acd", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15000000000, + "fee": 0, + "recipientId": "AbiXRAWJQvtxiEMzVZm45Jj7dTYF6amMx8", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008a0d3a40ba64688ce776449872561a1887d272b885ed9dc77464f5e0e9044ae5022062db52bcbf422b12bebdaffbf4f207f0240b803478764aade7c5440b0efdf413", + "id": "4616809d23f8caeac00a90f33547db0d3c31b6d21dc0c6d1223a2f2b6f8acb9b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15000000000, + "fee": 0, + "recipientId": "AQd294jzG4M7snWPK4chtyrKDTGBN3xU37", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220073c9db4fff5e1b5d59f7b36a29d250ccd0c352d8e30f42d641c0aecb9fcbb780220304f3f1237fbfdd6feb055a4d193a2a24f3d78d36891f86c752059704cb87d84", + "id": "8356eea142b2f8dc858aaf9ab5038dbfc8f71f6a6fae25eb0f9a1e7b0c9c02b8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15000000000, + "fee": 0, + "recipientId": "AJ4WmzahkzX1mzQGQ2ASfXUwVNsTr2nK8c", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100beb99fe85584c1db0e164c49ad211ef99e09b62fecb4ab5bd388b82f3069a3b602206657572320712fa459da101ea422229843f65f7c63cd0f2ec86d49aec3895cb4", + "id": "d3e6dae3d4d3bcad431182bcac5dff365e0ef615c1bc44be29776b9b62eaa847", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15000000000, + "fee": 0, + "recipientId": "ANZyNXsDsx8pCWwodv4VBp5vQotCgFSLpQ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c1b2099ba3d7dcc366b013be5a09fce01599bb707d25c8ca4b8112c1fa65eb1a02203468b56d9ed1247cf21bfa67fd83307eb6c78741f51f24d5722033249193300d", + "id": "eb1c6fbc04b75fdb056432946f90715f02c4a1f3cbba7a1da1e11cf923d9c26f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15000000000, + "fee": 0, + "recipientId": "AGZ466UoZ8rmMwYqCobkJieDn5WnmuNJBT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220115463a85eedde299e2181968838add9326a9f5f11a066e2de1063372d96d2b102203299c9a0998b75353b474a383f6a8ee5636964ded2265284924a1810dc8a2e6b", + "id": "42362155399528b008cb1945e8271cda6ab8232ac38c1a9f1ba092722162d5ef", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15000000000, + "fee": 0, + "recipientId": "AQK3Ew5GGnHTyrFyt4fZRY6xobNoiWAa9S", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220232b18ce1bb8fec9f105de89b07be45b4851032fd57adb11227c7b408fe4910002204fc98352522425910dedc1a10876da390acdf2737a3efeef36afc0b77c26c114", + "id": "01899d20bf6bb2163d05c2dfb1800fc9abfd8fda8c708b313dd38c44eed60e27", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15000000000, + "fee": 0, + "recipientId": "AKLLCyWEnnsXPLxQ1S91J76WXL2YsgCxo8", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009b8269539e07b9055f9cab99b49218c0535124d99a366cba09a674a31371e82902203b6b6cf090facfbda718b53f181e046bab31040ed1a6bcdc702c519b2fec40df", + "id": "053d16a85becee53a301904de426d478499b1de157a9f15db98f91c4783173f1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15000000000, + "fee": 0, + "recipientId": "AZ36zcRJmdUJ64NvN1M2T9pzv7dLAWtp6U", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008a664c0db5cdf291bb0da5dd05b22a539f8b538286650c2f7dc91def82ecf204022035033583b9bf16e4b0e3db65b4125c567e0591a8c69b5739ee158b55f8c842c9", + "id": "968c02469edccfcc11797a12463cef24aa7ae281aa648854fbff46b6634b5279", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15000000000, + "fee": 0, + "recipientId": "AYhCgzBpHXC9kgRCu9FUyRpjtqvfqNSr4o", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f207cdc66a586a04eb9e7a5c777c4ea37434b73dde96b05a0c7ac666064d69c7022058eb07e5f8adac444c5eb113d25d09da6fa42e9f7a3a5ae778f479c953039610", + "id": "67b0005a47824abec015c2799d99ddb2036bbf932a36cf05db7575fbaee92098", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15155129039, + "fee": 0, + "recipientId": "AN5x6WfeFwtvyqDvpaN6C1MusAvSCzZU45", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f2577c3278f2aae85a9cbce9b581c9c094d2f33b2e8173ff6b4091a12008da9a0220753f0064d21a0b871807911194832c3c255060f3a6dd7730fcd6538de884392b", + "id": "c2f08ecf56771833549e92030bc839761e353fd88330cd7e414f9e5e33869b99", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15155129039, + "fee": 0, + "recipientId": "AcgtP5SQDHp9gjDwe4KPVVE83JLGwWGvUG", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210096dd68b49e599249c0d35342a8375ef543fa62670c6f67602e2415db4b788cb302202cc2edc7b1b318c4c127acc7fdcf34c7a5385d078a683cb6f10593272091a6a0", + "id": "887cc5bf0335496a821123b14efb9b9e989645f90911c1f7fdb9f44924c89f52", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15155129039, + "fee": 0, + "recipientId": "AU61SM9NBrBfiCVyJ3wYMZ73GhvGPcQhkj", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022017fa1b374e87bb1dcc55ed07a0dbd64efa5a148d5b1f3604b6890dc43ff6022402204a0e788d401f1223b27b4c2e0cc5631cbc92d1301827a53bd2d7a7ca411d41dd", + "id": "3dc4b91d426b88fff8d78258c20991afa63c247572ba06ea469ae2a4887a4aa6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15155129039, + "fee": 0, + "recipientId": "AJN82CKCtJ912F93y6mHEmbWS7ny1He3c3", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022042cced4fe76ea745f6e41b70a696a800c2172eaecb24c77845b35355f882dde402200e7a5e5cdcb4411a92bae306df4c01a3ff8ee5d53b6972518dbb1f50f768ee0c", + "id": "445db40bc02d41ea28aba75cc2069cb212793b0c202fe5346feb1ae304288c35", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15458231620, + "fee": 0, + "recipientId": "AebPWjx5BvurHauVa1Qj6nJD1h6h7hrnAm", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100eb671a7f10f305a65bf38632f205cc28f850d304e24d49cdcd19d7ceecd20b830220658bee7489d4555361f2d330fd31f59e146c489070c2522dbfb2009a3ccc5209", + "id": "0a6de5b1e8dfbccd33051fa1bcdba56d8f8ba2beef3c5ff7310620695ed8f7ed", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15912885491, + "fee": 0, + "recipientId": "AZTp75YcToEXwnZU51Meb5etPteCx72DCp", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100831c7fabcbfc8e4f0d7d093d2f80f4dc964bbbb7139d1f438ee539cb3e5266ab02207a4c930391f10a571b7047df2059de1aafc255da9225425cc09f6008e8b93889", + "id": "6b144c56b46f2d418538d2af9ba9890847b3073cb6f0d91c0dd4406402361cb8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15912885491, + "fee": 0, + "recipientId": "ANFaKygQ8EoZFiyvWi2SaRT8WbfwXpW21R", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205d825095fba54447404abf0c7721ebde7ec9d1bafc56bd4673eaa2146dd0c24d022029586e4fd33e94280ce99760eeeb4f12c51e2b068df63cdadc090dc5de09a741", + "id": "74f7c9d800d11facf0e9fd059069e0a05eaddefddc35e684c77f8bc9c6502d45", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15912885491, + "fee": 0, + "recipientId": "AVbpuFDTAyRmt1BRakzWTJyuokTRpBbeqo", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f70e2674210db0cd7ab970fd8b58cb86da605ff850284058d8d6803668950ff902202669e91f8004f9ad85b19312539eb5b1a393d9ed101659980656fca3a7f2b978", + "id": "d828823d3b2287d38edca76dd4e83a88557b2b8da43475cd6197ce16c906834d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 16670641943, + "fee": 0, + "recipientId": "AG31y1h83VJt7MUvv4zu3ergGFqfpUpNkw", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022050e9976c6dade3e5c5e365ff0f4ffb1990ff83e6613015559439c18e62395ab20220083ae7dd6567213a1ea0d762c24af46f8845080bd554f57e675b501c30c11ebb", + "id": "85df60d54bca2146dc642dd2a2bde7ec60c2b00ab7868b3487c3e4cfec742385", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 17079830426, + "fee": 0, + "recipientId": "ANaUP88ggMTde3BhtTXvm8N3UwSLADG54e", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207e0f782747a7020e5f2b0c72ce0bf366bf43ce2b8016c937d376adfd583aadfd02204607186b59392cf5d7899a8f020fb7298d974dadac28f3beebe82cc58b2843d3", + "id": "4a78a7be1bb24b6b44a6d8d20a5be158edb30f7e33028703a01488194439628e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 17300000000, + "fee": 0, + "recipientId": "ARUNkZzsiJa8YECfHbTxiCGv9vrFLZcdKN", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d143d7c5f2d41212209c85a3f762dff3321fbf3e766b6746a9483e5136f62ab402203117b6c3c8fdeb69dd8779319c3652ee0390e3ff8771cab0fcf18512e885fd18", + "id": "ebc1f86a8dfcb7ae369e124628a80298b868939e410a2bb5262c467b43a21b3e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 17300000000, + "fee": 0, + "recipientId": "AepyttoE4qxeaX3Q6tmhvJmhWR4e59UgNN", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220100a5efb6722cb9e96ebd5bc5af40854bc765e7b68c5d42b56d7b92e48c32ecf0220428e3ef95633e89d1b125fbc8c75ffeaf093971b70c553722232e464965ac6ae", + "id": "3b6bb91064213ed8006dfbb57a7aa9fc9b92acd1ff152625bb13c84d4a1c9fdf", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 17300000000, + "fee": 0, + "recipientId": "AK1DoQ2TzXwZFpqRuuLRkuMLtxvnwYA6BN", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206d8e23fd7873b9b3b176c2f81ca68bb8f6a39e86f48e01afd58f1d72b2f370170220160f43117a81dea41d0bd16bca567744b30a0df789d4cdecf1b4969f0de5a16d", + "id": "f77518bfec4286fd33fb36f0c6bfddd86fb51a4394034d80f12616b9c839eca7", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 17300000000, + "fee": 0, + "recipientId": "Af2dxbRzquQbsEDdc6YyK38EYoa86bLaS7", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022072d8f98d2aa1dc1ea479aca3d4b3232de3619674c0b484b4f821394ffb91663802201ef857234756b2c4dc090b32375a399c9b9981c616d4106ce35f18b55e7883a2", + "id": "c05281457bb1438b3a8dd85840f6aa8a4e87089f8f41e3243ca146f1ca406836", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 17300000000, + "fee": 0, + "recipientId": "AdgRuyVNXHvKYyqfTqHNN6FL8nQhFuybe9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203fcc0e870991a56bb59b4d5e3a8be7efa5a07361a34c19802e4b7310bf2a79660220281eee0aa154c8ceb369173ba099b1cf0a46117576dd77d9d30e0bbe7cdc55b3", + "id": "bd02783756ed0a83080748833bd610847e7a54be76c138b07b417bbd09589040", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 17300000000, + "fee": 0, + "recipientId": "AJZcbQZWg6yk2nZvxpuenxNEg5vdNfP7d5", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204f2170f03f42e1a6013ee9ab7f585e420480fc72309e219aa536de5a1eeaeeb602207b5c6838c72cb39c48357df2419b569982eda8275bc4662c066faa7b390dc4cd", + "id": "3742052eb3b87c2e55476c66c85fb7d6f71206ef8c3c94c737a382576f142746", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 17428398395, + "fee": 0, + "recipientId": "APGnKfbcBc7pKjbSWd4dqYbC6zAS9UQn6u", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a9b09e31f0cdae58a7f91e18a967e12436dcbb5dc3e56304e4803d942cbbad7002204d398385e1776bb0ed9f1cf6325cdccfb8bdb64a78287e4d96d18d5754bab1cd", + "id": "f7bbbad0d7ef708f2df7af6116907e8b89d34348d1786d22687f6e680e70b918", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 17428398395, + "fee": 0, + "recipientId": "AMBQecZh541er6XkgwPgZxk7fNLWUDwjXZ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f78352db270ad2e970789ced7fb13b976f20d45905cf4374d9ecb7a7b89a072d0220634c8330932815d3c89aad1f22d74f4305f9a0209279c3b5b5e849a573b763ac", + "id": "849ada089f0422ce85f82cf22cb73ea146af98d1166ecaaab0f772873f854bed", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 17428398395, + "fee": 0, + "recipientId": "AZHYssEeVUGz2WkDiWWkjefoSRcmNtKcxj", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206cbf14e3cb952df65c1688fd79bb6dd657325b21dc9831ea4545617bd15acfe902202e828910f28cc99a91b1e28c8000b53c5389fdec3920c502ab7c2116c11d111c", + "id": "de2af52762d16398e677a58eab98730dd6ea3fa036b148fe8c701da96501938f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 17428398395, + "fee": 0, + "recipientId": "AefDEneWp8sNsesZ4aQkGk91vKWCpMm23n", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022023939f4888ab00f3e2c258fcb8671a70a8b1c25a2eb52d610e1efd91ca5f813902206bf4c893b636139551282d0274f6155df35e46688974c5d9225dc1e3c7ba2230", + "id": "dfe1495aae4a5c62976804ff5ecf1e993416996f4cba9bf1df0ab0795ef5005b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 17428398395, + "fee": 0, + "recipientId": "AciqQathcu91PZkK7wiKqRp61Cddop7YwY", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201b8ecb50cb16def362f572efe3385be176d0ffcac0aefe6f9f378d5e899e445d022062907eb7d5381840cfcd021a1c9283dc4047a61e76df88e9cecd7852ea63e3e4", + "id": "e86a19a03fadada17fa359e563c25ebec320915ce818f28bbdb3dbe7a15545e7", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 17432660696, + "fee": 0, + "recipientId": "AJTnGpoECgBAwkcWJFgxNAqq6BNNwQP1hm", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022045f5da273f2e2f227b3d422d418e3cbf3816958282d21131f3ec2844c9cd76920220591b8a380ee924fd2550a1e52a425fe3c7f185448347c119d2f0d515e15135ee", + "id": "aedb2f45e57c01965371534c52adbb99629ba581c788f7597da354fd72a0b885", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 18380568436, + "fee": 0, + "recipientId": "AUWioz7GLb9wrTXGMLVMGa6X4HytaUz1mt", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202dbb34ce6baa94e4996bf50310955636c5082e96db5314804af02e4c446846810220333215217bd86424975be8033217fb1d74b5897ba9cbcac196efa9006765ea6a", + "id": "bc0efb1b00e63694849e719ee3552176f4dbeaeb943910ad34b681b8250c0280", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 18726879545, + "fee": 0, + "recipientId": "AXJ2kuVeuwa2MMtc9XQqe5VBfxKgt8ZAsy", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210097fe86ad5302cdc3a189eb42fc873abb875e7f3c4f47b4b5e581e04be5a37a0902206e8a1fa9cdf78cd7d69d0e12059709f4c2301fc6235585db9dd8d638e01a3a3d", + "id": "a4cbe3e424ff70728cfce9f31324b8115012bc47293d480f62b05228969396dd", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 18826504375, + "fee": 0, + "recipientId": "AaPfmEsY8yCH9UhUdHaWr29UCruPbQC8EK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fc0dabf71ef6e74f376b5c646ceaaeb09f65c47322096e0d130e69463bd0a32f02202b52c16528b3106348834e75e68137fff3908755171c8ef89ae44e480da6d774", + "id": "79e4c62a158b1d95852406021ecc176c2eae643012071320c741c472be24ef25", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 19758347933, + "fee": 0, + "recipientId": "ASWwdLfs6zYsAnQB2MEVq2KVhbtsuuWELk", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100af87163f52e7bd36dd86f728b18360df16d9d9f499acb1709a0e365080ead6730220016e4040fe172f041da4ea90eae432d28f8fe4f49326ff7178f087eeafd52945", + "id": "b60e9a8a4229478192e1bf5df84df85e009a8517b5add54ea0e779550571515f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 20185909534, + "fee": 0, + "recipientId": "AXYVmQKznY2qtzpryr19zTSjTbSkfHd8aH", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022062ddc327d35dc5a02d06d6a91f9303fc340829d731a2ff8c71e868482c99d70402206c4bafa555098c358b0b5e68823b103401ecad4a05a65e5a49176ba0e435d09d", + "id": "60d339709c06fce066b14b06536b0afe9d7d8f0cd346da5763240fa937d2b7e6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 20235049486, + "fee": 0, + "recipientId": "AeR3975uH4kfYydrwgLQgo5pWkmJUww2nm", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204e06a134e0545f41c5f3a6f7f54881ae07c5e7791d23a7c9786c3015fa5fd4a60220422553d947eee3af1faf66e6e80119511651d5a2589d39c34d7cee4daba94ca3", + "id": "8242c9f18a6fa8535be6511f8b75cf6cbbc8da6cb962f8f9a0beeb697a95ecf0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 20301994953, + "fee": 0, + "recipientId": "APSfK5XyawPuumG2me4ovkwDPKCSx257gW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220789829516e896e6f204699d632176feb9a721d69bc3b72392ed1a1a7b787efea02203f736d9ffcf9ff0b899d7ea648d1b74e1e938a4fe26cf3c8c6f556b0fb4a4bb7", + "id": "e0ea1ebc9da7c1a67fcee0b06203e7df1bc6ad83444f4dfff4fc37ae58f41c2d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 20800000000, + "fee": 0, + "recipientId": "ARwCmALF48ZWiY9cCBWqhCV6PkFbp2Bre9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210098dcf23f4386de84fc4d75258d22469d2bd67017fea3417396393437d831628b022064427eb68be7fbfb7d034c682b2e5a3c0a740594da40843dafd4fc8fe1593528", + "id": "9c76e2b23ef60016ec4e1e54fae90bdf727172be152125e41fce7a69fb04f73d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 20800000000, + "fee": 0, + "recipientId": "AUGQoqoSkCGdT9gYPNsuFumhksQBDjFLeS", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022071580d7f06e5a33fe8e140208441455af5cd013853c94fd983c457e34685960b02201d7c1134e7c3e408b2dfdd61916e8b1fcbce9fa3e5539ddbb00ec47c424bc510", + "id": "8f444d8c999f8cb2a73f6b48be6f497b0230b4956ce62bc3c2c646367ae79d79", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 20800000000, + "fee": 0, + "recipientId": "AQayPyz6AWMwY8RPTCPeVhxkr8hNuez3Qi", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022045fc1b2a0389840a6e8495f0bab89579c2927936bbdc1237f56b2159ddbb152802207f2216ae4e65f848f96a5da8db61a64c7b0ff16a973783d1a6dc93afbabade13", + "id": "805e65bf89a54b7bf5043f510d74c9bc89a8fbdea7fa741a68bf4427bab5caa6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 20800000000, + "fee": 0, + "recipientId": "AGahFaiYodwt82Qi12rt5j29p2C2MeTLBh", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100897790cf4bd81566f48c2ade97bed334735704f19a67f8f9ca75f53c60756ad30220468cf778cb00ad16e4921c2377a06c2ea762f87ca41fc55e7864fe1cf18b841d", + "id": "133692fccaea85c45398542c5d4c8ac7971d4882764b60daf649f81a3204c49f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 20800000000, + "fee": 0, + "recipientId": "AUPkqi1hRw1Xk95PU9DmKn489PztyNjRYh", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200fd59320b0f0962b330c012ce0ebb55791d59ac26ceefbe0f89b140ffab7e5ea02201ace6578816b4751dc693f4894e04c25ca654e9f962d7f7ea710cf55a759df13", + "id": "faf85b52fd458c9be80059cd065cb328853cd66ebe35bc2f0c76160e271cdbbe", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 20800000000, + "fee": 0, + "recipientId": "APuwwoc1Btsz33vZNtuQDHNznD8G8CHcNY", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206633a9f528e3430e1ac997eb95252c483c94308a97462f9d8d8b6175e04efc9802204cec670befc7b7e2445aea1ad7af8d300a0fdcfe5f8e185df47bf5bf2918b210", + "id": "886bf5c983e9f90993a7fbb5a50064a6c9b32db2408d09561951578a12db73c1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 21622003904, + "fee": 0, + "recipientId": "AavfBaCqpww1LarHdp74ayFp3TSVZ9QHdu", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206329d87b5ab1bf32142a5688d09638ee7b80b79109350e42fca433dd4de0170702206d27e82dedb5ec747f7e16eae5c35408ad6600c0a847c130c615c7cf2875ecac", + "id": "3ac9d7d0173837c2079cfe16d4079d1f960ccbd320ecdfba026819239c4659a2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 21819296752, + "fee": 0, + "recipientId": "ARfsXLuowXfLk3pWNrJprdbn7F25hwMRYi", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207289896d987705b7a0be5edcbe197f61cdf28efe3a0844bcfd70f1f1e36f3bfe02203e49e3d9e01428c39a8e5966851fe94d7b798b4c3c6690be3a098f1ecd16db17", + "id": "ccfc33a398e393b8abcdc28d431fb5a3b4753b15544d58864d7a405b828ce957", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 22277220240, + "fee": 0, + "recipientId": "AGaMNkFFH7n6bXwKbXXEdfuDCN2JC4JMEY", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204e619395ae8cfc6dadcea3a709bb27a014c8836092bfea565ba8fa40c5fcb42002200b46a3a4503971b4238fd849b15a40a927945babd50e7107e205d9fb40bd4110", + "id": "ee656950500341fe56fbcb6b720b120a5e6ad4eb5eb75a2b89651b0526cbb782", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 22426664055, + "fee": 0, + "recipientId": "AYL4yJL3TfEafvWh5abik9mjrNGDS2N5ZT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b94073a33031731ec6ca84bebbb2e63e45d4d0c509b885684b7315d769b7cb7b02202e0662f659c239b2a69583fde44eb38e8650eaf91a9edfce4e9c602106fb33df", + "id": "b5e89bf8f85d527e891b8ca3ee0f2a2e24a1daf63e50e0ade2d791aa52e03b06", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 22493303746, + "fee": 0, + "recipientId": "Ac4V3AcXoBTb3gDXkBofGd996DySEZ8w68", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100bb49539eec3c2ddd506812379d6d9a126f3cb252fce6e918d72920dc389db7f40220135ab2cb8c335ac8e2b7fb563f9b3cf5ed4a3189e4ff9008871b21765def468d", + "id": "f418f20dd6f1c0826b102833e01fee05ac5eccfd3c69e70c6d9694c9885fef2b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 22606906279, + "fee": 0, + "recipientId": "ATksXZghzmn9RkctvKrpwPEctjEFG2s6Fv", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206ca341544ec2f0047a0f1001838d1aa42c0d94b49257034e037258bf09d34a2e022021c6958774ed74bbc8ad0fc4fefcbbf3711bfa0c0b47369fad575001fd3d7df6", + "id": "42e3bda812617277293b0efb08d308dc5494e47c5823d088e1c0520d2082ff57", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 22720508834, + "fee": 0, + "recipientId": "AKy9y4KXZ7XhtWmiodsb3mJSE2HH3H2VtS", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207d201e258c9244f724e94f5764513a16a42dc2aeddd50da09db88b6fac5919350220437202432b51c67ed7538ae1af5ee3445093d5fe85ab500923b23c866a4e12d9", + "id": "54a8922aceaf439f3efc4ebbcddcc60adfff7170351c57fb38a3a23ef2b6e1ee", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 22720508834, + "fee": 0, + "recipientId": "AdQTTtT1HGKsAuGzs1mgqBnwXHtMVCp6MJ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100df406f87bf59816e855ba7749af423879a850e20863ea5bf5e0ff96972aaefce02201a50f1f35dedc824860e5785dbcd6b49eb09510df251b5be71d4ec1fca16e546", + "id": "7f97907d31a72371925ee8ddd94f6c9460f2d7bd837533245c2aa41b9fbcab20", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 23338898720, + "fee": 0, + "recipientId": "AJeeb4cmTjh2oKsSUt6b1Cted554SrkCuE", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201500734913f9fad425d61e07ed00838e1c1e8171020c25dced36849b81be9da402200cf05fe867256dfb7467009a78e47ffc001eb80835413b4c558a465cc08c048b", + "id": "888fe214344f8d288fd0107747d8bcfc1cdd1baf596c75a1aa493b2e086861fe", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 23976819323, + "fee": 0, + "recipientId": "AXtJWNWJctDDFkwuYC3J8CNBGNJorqs5KS", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220678d7e0489942b5faae8fd0cf73542706f700bb4a9ae7a7037f1f13a64b74401022073f32ad4ca5b3a8ecbf843d645876656ff46382057586a85909c8454261d829e", + "id": "d7c0a0b53885f500999c7efde8b6f2dddd186247bf94f0f9b4a1864630d90dc5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 24200000000, + "fee": 0, + "recipientId": "AYet9i4fohv9fYye39z6TVkTkdAeb7g2Gm", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204382461f91941863a5256166d0202c684e4fb1ba39ac43eb7cb432c8b0a90a0002205ad3056fdf794935c28e94bab65673c01e51154624cf695331687f0a3974b420", + "id": "a14fddbb3784cf2bf6491f244fc9830559bc8b3fd355decee085db44c9953b5f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 24200000000, + "fee": 0, + "recipientId": "AS3b7yzfnNX97TLzWm4ez9GiAfkbzs8WTa", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022075bfdbe554fb74d09142042bcde603b6390903a8baa2eae9995193f87bcabad2022048a005a2d88496da6de06cf027ec78de4563267a8de12c0f258580d1e2d44638", + "id": "74b83c00431943cdf0a97d5f801eed6045c1f57e10d0c07c5437954b4b811efe", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 24748325720, + "fee": 0, + "recipientId": "AGUdj5MtJ4HnmcAFtdd8GscPBGwRC4hzYK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008600ceac976e10082007b40015e56d19d6924f888e6e620ddf8ae114bc877b5502207cc0afad875ec422d817fbcd6a067ffce41c013d6d971083b52389ee567726d5", + "id": "a64ef1a8982ad70a13440e5a901066ae8bbab1b1015113bd53a48c14e886d2b9", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 24859867470, + "fee": 0, + "recipientId": "AVu5QHc9C727s3wXJACZyvFRc9XJSiHkHs", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ee316c58495cc4729ad60d451d129d7a4f98574e764f8cf5bda95050e1a8c79a02204ba8d962c6128d528dfeebe64156e7ea6aed5b4c98f468265d5886066c350711", + "id": "81e9ca6c942e14621b6c0de8ca5deb8200114cc8dff364ad52e541663095090e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 25052610401, + "fee": 0, + "recipientId": "ANmAMut1Egf7zK4DBHbaki6tv7dzgsEzBt", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205f1aa6c3bc84dc585915658e7e03bdca6b05307a86df928cac71cb523be7510b02206cdad96a72947eab1a24acd55869a8888c12252583e3319ce11ad2de65f64857", + "id": "ea5534e532dfed08d41e0c0668e5b1d3e1aaf70831ff61c6afc65562580a40bc", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 25157514204, + "fee": 0, + "recipientId": "AUncJXmGFQDzHE2XWPWEqitaQg5Azw7Rux", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220354217fb3a9f69b30e0c74b86c3474260e276e4553c0dccbaffa5d2eb1101c5702200b9dfcb85de1773d239fa99288959577030eba8f3908a4cf2611d52c5f5e58dd", + "id": "bb609aaa336872e1a90049e64e08b329ba0e9b1b155b39555660f13e900cc5e6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 25248444979, + "fee": 0, + "recipientId": "AZ5MTXTuHnMtZsgpZJ2zM9B8gWojkpen4A", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100892b7674c9045e60026206aed6c6d8ca9fea571c02fb63a3d852e26de4d9aa1002200f4c29438eb6a7ec035105771370937732a0e076fb1bae458d42f6b864784d0a", + "id": "9e7cc0e06c0f91878772d1f3b3ef00fa270da3087442baaba6e2ecdfb1e788b3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 25763719365, + "fee": 0, + "recipientId": "APxxDqpuPch7PfMZ7611osF5bZYEyx5UMB", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100dafcc214d6f27318979493288f12f50e61a1398bc4276ff9e559dc2d00a2e61b02206b173725cbca509a7d26ae49ab1b063540c8d75843c887ca1e0139029a26d395", + "id": "b838f9fefc43e5780733198956cb88817b6b57ada2f8b9351ddeb38a1b1b4a13", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 25763719365, + "fee": 0, + "recipientId": "AJdxs7TGgcizNuXVMYgd9JaXpuyKe6fF5g", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008402e0f1908c2a7a75474b3262ec6a6b492cb8d63d9ac0fefd5e7935f91cd0bf02202e6225f7b03abe5f580bc1c7d7a2a33070fb139fa22122fa075a70d912fc7749", + "id": "e93052fe6fe08457995307ee8c843d5293f0d62d3a644b4613af01057f7b4182", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 25763719365, + "fee": 0, + "recipientId": "ARjehcSFYaDpcuEnZ1iPquKMnq7i3sW8Yd", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201b094974dd39f06be93b8fc08eac96a942eba37a5ee4aed9b38b4c4d5e85414502203470bb9167f1a5121ae1909a3336caab615fd947a9ba464ef4cdc0ec5efd6182", + "id": "f9b86470f90ca95e6ec3dba7dcf43a638992d501595dc2b311354b01420267f8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 25763719365, + "fee": 0, + "recipientId": "Aar18iMBogeroCZw8S4ELPzeLDuvXoRdH8", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f884dc287f4e68750c622c5cbcfa02efd10ef032e95e3dd5163fe0709f331f7002200b8fb3fb1c0a21467618f265d012a2d0094d62b6b95c5a36e77b1129d295033e", + "id": "7dce050a4abc7ae6ada53d03e78ee7e42774ea2dab60a084cc2f2b2a3f77cd4e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 26000000000, + "fee": 0, + "recipientId": "AXbPyMxJTmQ2iN7qoswFQoxAfZWW3wZj6t", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c343b8c44441d845cd4a56ace540f15ea2445b00a22a350a70f4694052480f2602203110b618b42594b5d8e148f53cf613b55d2eb83685120e40eb9b8f2ca2ee36ed", + "id": "78688e06570c4b2ee4017450f89cf8531cfe1ec31a5422887e84ba2a6a21427e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 26000000000, + "fee": 0, + "recipientId": "AJbQvAY7LCed3KXVa1qxJiySXMKWRrLZ5X", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022045b6f2b658a709eb8b9ec4f9d15839cfe270ee0be5f96e6550a6395e0f887c2c02201194477e971ebaa8b7b8dc4f281f2cf1157960905618602c060b35ccc29d8c0f", + "id": "1604c3e03314a5a83519482df25366aa40aa3bcb3738d7eeb42c177bd1a38b08", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 27559966014, + "fee": 0, + "recipientId": "AXBwNDce45Bw5upoPTup7NUmdhn8NP6D12", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c3d6ccd2349a07f0a94d99292863b4c40fd1fdcb541dd15554131b6f03b5c427022028e5387876964b386a74c01ce79c9435ae71b6690bc65284f6a88b6e313498ad", + "id": "cb5a0d3fd3c4edc2414b8036df50caf75b9b8c25b1bb4b645b368291c8506cda", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 27700000000, + "fee": 0, + "recipientId": "ASXb7xv6zz5N3JVKzhvfLrmZHGGVETBvSw", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ca228022c4c0932b3b548d1c3262894183c12f65c56981b54365360acd175db4022037711473cdbfec5110a4f4467d2f4f847cf8e1424a70bd31ed391c11440e4cbf", + "id": "1d466dc4a218dce9c63f753870cdd645e994c9af33ae0777596bece6fd95bdb5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 27700000000, + "fee": 0, + "recipientId": "AJMMbNCj4gMpfne8rg9QezvdBF9zxPfysh", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202ddc599782c761e60e98b40880fe924a162495a916e30b4fb7e119b5a0ed0a8f02207429cbe9b1e529682b78c2e30e8269673845621d809b9b0393b7386e396e0378", + "id": "a0c287269d928a06bad77dc7366afe8579308331b10f2fc67b0c249edd5652ba", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 27700000000, + "fee": 0, + "recipientId": "ATj3133FZRJqKK49nScR4yZ87S6BAWdtZm", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220690493de80d6ae99cf3108b18cbb9ba0b18d9c283f65d9dcb8158df40623e6df0220376c3e63badab403ed5bfbb298622a9449b8f40aa93f797b4678fb03a0615570", + "id": "7ea9ac0687d6c936dc61a9c6a8c131412cb973869a7073b7a679508d91243917", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 27700000000, + "fee": 0, + "recipientId": "APunbT9dgTkTpqpUAqxHHW1GvQ6pNzaTHL", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100bc128ca47b50617210c4efe3991eea82f3cfeeafce7e3ee464acc43c6962fb4b0220434e20c12c72b9e6f1cca4b0f79f5f8023cf054bddbc4e654cd195bed26ad923", + "id": "7fd55eb9e7a1576beb9060840cc704c3db6c2022c904d6ed4f6fd42bd2b94b96", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 27989653191, + "fee": 0, + "recipientId": "APTFQ7bZpw8n13J5v5sbgZ96YpgqbdYsNj", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022045ff469954bab872b82b892d9cc5422ab3284fbcb4976af1fe34abb3882fb18b02204ec503dd4f4491143fcd84a875b6ec8fa7aca68b2e8f6240cf5cefbc281538be", + "id": "6941d8c3cb4a3690680b6af7656f683e3f4d7dc77a8ffed8ca64af9ec501134c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 28721448453, + "fee": 0, + "recipientId": "APjsYt53nwje4wv8sBUJkuJPgHYfkJrvbr", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a5fb78077c9bd963201b4b73f26d1f57f9ff804d0e56080d7d5b11365b97218602205fcb7dd7009b4fc091cb21d8fb32c3b20ba8feee9eb95f19038caebaaa1b3de9", + "id": "653f5e251e1fa91014fc5d5fdb5160f1aab6408bb8e62baeaa69733a9d11b847", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 28730083421, + "fee": 0, + "recipientId": "ANPpsAJ5zUvsFSH89FpiuKn3HSE3F8MrvD", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203d66184dab85d76f32d99f406814204822417081b933227d247eb99aa5ca69420220470e38f361a771362db029ef353e384f002982dc5a40bcfd846c0db84d413576", + "id": "24df83ccb61485f2694a460efbb8ab77b38d0587adc4e48855ba4c496195a2e5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 29339140141, + "fee": 0, + "recipientId": "AWwHvryaqeQv7SsZVysNaG2xHQD65romAU", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022037e16fba790a42b0e56a0e7b353fb740eb499278cc8b9e638209ba06885e27f7022039d8876608f1afc24e7a27400844b4855e6f6b05f7fd2eb45f682760efcd5442", + "id": "54ec066a0475f3d3bb34b431aa58747a246a1e8513c6d295669f0738ad5208e2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 29885914464, + "fee": 0, + "recipientId": "AKWZFvNtkFcyp9qCd1qoaA1XHTCo6yumHz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203dc53e2d991bc80bfe7ef58bb5836b1016fac072bb04dd8ea307c675fb5fa86702201e4ca6d94cd78e647c9f1796bfe6855852a1b08d24033e31861cf4769da707e7", + "id": "882cb0fe98bfb862e7c1b0c89fa209cc1611691a92290ead9bd049b38fc69dfb", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30000000000, + "fee": 0, + "recipientId": "ANPjQL9f5qA6hiVgntKsdre4hRnt4kVXqb", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220641e29b2546a81aa442e6b13f7c6ca49cb3fd6ea836a3dcff16f9b8ac88b30d602206804d133dd4ab791569c95cb6db82d9e9ae9e8774ebb14be8de6a9ba15308bbf", + "id": "a1e0e700abedc3d7ad878be06f16cd2d565074462d81a731976a57411d1c4d35", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30000000000, + "fee": 0, + "recipientId": "AbGe4yigaf5FgBd791PKMeRkysFeRdNUJ6", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ac923911201411e738cc3d738b588fcefc6809d1cabe40042fd145624958f32c02201f3f39bdb47e5ed315cb3d88efd53d7f7582370261ec2956d1eadcfa33e1d560", + "id": "99992456df9d1108f11876975230e1f47bbce3defecb092aefcde7d015863426", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30000000000, + "fee": 0, + "recipientId": "AGWNji5TSq8tXMXK2JftSbUuytzkkUszKX", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202ed1f7fadf1c77665beac7333f23ea2afe3968219944d538a894fd5763f7cd320220637dbe52b04f82ca4f340695b9b77e939d6abefbfc10bd928781abdfe0770b59", + "id": "f11dcbbd114f6d70f1b90c5a54bc4dbabebe788ae0aab1473b9464d48686f0c6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30000000000, + "fee": 0, + "recipientId": "AZTfaXxi8ZEvtpvZnEbdJZaajFXqCf1B16", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ba7d814fe5391cedaf1eae38c14557e7f7842b0bb618a2043aebf040c10c23dc022002780b3165d68dad87c0dbfe646ca1e11852cc09e8f57443787b3fb4ac636b1a", + "id": "1ac2891f76ab45cce0d5297e9d896deb831ae644968c4b7aacd3c22ac3e2cc80", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30000000000, + "fee": 0, + "recipientId": "AbEXWz7aphvULaWnTs2LMt8PTnuvFM1tcQ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e5b9e4859b7541fd99124fae2704d5ccb01d9fd424168d931dd8ce7feae9e55b02205faed9d0716e2abea81cf4748db0189c7cf802706087f0570add7399eb51465d", + "id": "53ef0aaa67a4d02eebff7a550715542501d59849dff9ecd83b1be58956403276", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30000000000, + "fee": 0, + "recipientId": "ATHcSoKCMZzo4KW8ukygbkeJjQ3Hhdm1oC", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100cda20fa0f3a07fdce9d0b17acbd67703863c40311ded26bca2411ab6ea2f03b002200fd03ec6c9c62e33aecec9f704b7bc5a409cb727cbe2b43e7a9ff7ac894b7e85", + "id": "6038460b4fb005389c6df2e4e1513468063fe6ef332af5471e7e47390e09f7ba", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30000000000, + "fee": 0, + "recipientId": "AKrAqqmZ4SfjPqd9UqtbMoecpHR9tCgmWh", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204d13a7b0c8f6267c5134f40c9c03af1e75eced936834f100607ec8785b58b9fc02205f99a3e0133114f48a42f0eab3e1cf9546b2e71799244e31f12470eef16a5af7", + "id": "4727130dec5138ce4720b7c347fdba334c80d638549992d58e62d8ac6bac5e56", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30000000000, + "fee": 0, + "recipientId": "AJNdz4hjGwRxrt8CJSBzsqzTHgyBUmEkp9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e0218eb720635af56f74b4c3f531ab1146764cf082d9c934978c3cbf52a3c65e022041f23226a14f86a8893cee1ef08bbc8521df699ceb6e3925dee5ed947b06d70c", + "id": "9ae2cae32a3895d6fa5f6b7f6b36b21416a6fe14c4782e386d5ebc0831d9985b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30000000000, + "fee": 0, + "recipientId": "ANWw5vn73Hjh6pLHztyWjYvMiNxYynkbKn", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009a7f5002efea36c366ec5b7afe37b22e12a72d59b2ff43626ecbedeca83a14e802206ea4127d8d15eb80c28905d5047c16128a23ec64e9f25262345de8066e0a31d5", + "id": "3735e0e88737e8ab56057b4383d091ca5f0779177d5aa95da30cf0d8a81aa96f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30000000000, + "fee": 0, + "recipientId": "AcgKpQ3zVCN4St8seZaob41Brk7zpBbyF4", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220455306c09b4bcf68b3d503c3399d266ccfcd7355014e1edfb600e17ec67e4141022055e7128f5c2caa7b564a08b0dce9492448aaad0e4cd093b603e61d245b27fc28", + "id": "d4c0238a3d04e69ca8e2ee8ec3b8da3a41679ae8d131a1012c2cb300c4a437b7", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30000000000, + "fee": 0, + "recipientId": "AdT9uerGBa6ivvJ75gGJaDYjXyPXfGwJBF", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022063f7821d3d906617f9d60474e54259e408ee9f88c724ce5b40455eee8701042202203d0ca800bfc80788ed4888351174f6e1524b7ea63a41f222d770f305f97a35f6", + "id": "aa97fc714c3d8c6b5f5fb76c351b81e4e0fcd263b90597a72e94d55cffc14f2d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30000000000, + "fee": 0, + "recipientId": "AQ96VLizRnB1RtTb4voazDaMLB3VYKhoiW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203c248de6577db8045e71f536de61b935a3c6a2dfbf9ab80f92d810a31fa34b9f02202484f612bc171400b2b0471b6f5820be3ba8291031740e2cde5547948bd25f65", + "id": "371d63607d0af6c067a50dfeb58e56737e2636f4b0b0ff98aecaa44507a73f16", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30000000000, + "fee": 0, + "recipientId": "AZEYQFFZ31ybrZ7gcnt7YtJb11o72HcVCE", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202cad95342229afd4cff162e4f6166020be810f803ae87247e609ac6b476be6650220643568fb6eab880dcef52e35a6ae597da18d849ab7f77e4847216817dbdf2066", + "id": "8d4bcd6bbe8c0d21408c5c956e963c7edbe906e8d51618d15946356ed05f84d3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30000000000, + "fee": 0, + "recipientId": "AQrgHm3rfWGVXDhoPBSz4vXRYSJnezg5VE", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204abad6d12a702ad5bfe5d86738bb12e5fb77ccd3dc963f385f9fbc60369406f602207e473b2bbcd7176b9d1b8d3ac9429b651c8afa5e4f1394d97114923017734b2f", + "id": "c16763bfed71cf294553f0f3d6b3b0b3ca6d133d73d09c4b918b6e5cee11a895", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30000000000, + "fee": 0, + "recipientId": "ANBMsW2NRR5QUp8yhQNJc8BW6yrL7iRW8W", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220344f021c3a169186dd6ae0cdb48330b6224da92758de49503fff882d1b71b2c7022048f81b28b9a8ff3c07a1879fb2b3f0f31489f9409061df4cab21bc8403053f34", + "id": "3a359c2cc190a82229e1366b45d4c882bca83958d84063bbdf513d69f8da9bfd", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30000000000, + "fee": 0, + "recipientId": "AWHBi3iRAFasvWqRPrhBHYXvayzn6VNans", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210095a887589f959790c4c01da0adca893b9f288a8fc6ef32de25d19a4501f2fa770220267683c7e421d85c5d368c0416c0f067110ad2b39085a57b396300df68446827", + "id": "3deed8497e891cd9c8c52cb779542e4e0c14bc1434418558e20cb2d2e7a26f4b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30000000000, + "fee": 0, + "recipientId": "AKNx6tMWjp3wkCVmMKc6Lf7evoVQaVW2RR", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008a303a51a8eac6a3b47ac696cd9d561133dd3b08392060a20baced5d3d7659e5022032c11371eb5e80d42325caa9933e9cb218c03b17584bc20c8aae6045687c1a45", + "id": "8fe4b99d4943a9107010ec38e159f8208e1242087efa376d7345cfc8798fcf57", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30000000000, + "fee": 0, + "recipientId": "AX9teDU5aZqYBJUiGXFmkxFoVARFHpSZv1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009c77ca7fd50bbbe8244d6cf87d31fee1502d9cd53bc2719b4977b163601656cc022049cc61fe0848c5cc67bcd401339da0edf6490d59766f1eae6acf071f59d11bff", + "id": "960f6fd34b2aee0ec704559f85cb7889acfc8c5a3b635593d4660a5c4e84077e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30000000000, + "fee": 0, + "recipientId": "AbB54oR2UpH7Jh9beZbHAMU7i5FAZVqEPL", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205ac4b25ffcee117effac747f983502385778170bf4d9397aa36f0b68b660817502204d73b9266257237d35a1de1afed230c6512c7edb749e92cf978679aa9525e131", + "id": "a841cd49a92d5ecb39a5439a958d9d1d02622188a73b71800b45631d15ed14b9", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30000000000, + "fee": 0, + "recipientId": "AdDxYew7tm1TmxC6ASHJhzS1qgtoVKLEPc", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fa7ad99b7c0c61a861d253948568f93ed985cd832ccc49bd68b5fff69d7d0a3202205d3b4717783ed8db230108f8802644ca9b63e5edc60652d743e3792574cd0a18", + "id": "1eae0aa7ebb5ec9e7e421e704ead21748c4d211d899006b8e0c4df6c0dd54018", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30000000000, + "fee": 0, + "recipientId": "AXsSBj89cjVAu5Sc9gLiDDwoRhASaVPWpA", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201a00e76784ec8a63958aec45ea6677c6af0bed2c0fc698ddf5a62911459af0ea02200efae75686a8e3615b62fcb698148229837f5ff32c2cbc2d289447124bb2b5bd", + "id": "193e570b80302b146e5c034c941e1817f34979f322c1c8fe47bef69c8b129b94", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30000000000, + "fee": 0, + "recipientId": "AKUncjgDtuG8pJk7YQrFkwBxujN8SLp1By", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203f9a8eb03c96849a9327c877eae8bc07d3c8e469ef3ecb7bc92f3b10ff76e77d02206b2d2396c5f18be1a68689649acc583c7a827eddf3064d16ebb095a3cb6d4be6", + "id": "4aea1fd822d1a22ae2edefbf779ca2ffb6f8b49a0971e2f43addf9607933d513", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30000000000, + "fee": 0, + "recipientId": "AVbcaqopSmsUjmXDvW288cGUTYq9YSmWRR", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c26e6789b1f61fc93d15a669de8c5a8dd420f68fb8e2424bb5c40c4a15fd1abd022007007a2055610948879608dbfeb831ffdac2535e26614453bd029b93820c648c", + "id": "de983ec6b437575acf2c16bb9da752f6a901ece688be7bad75e24591baab23c1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30000000000, + "fee": 0, + "recipientId": "ANhuDMbZ8GPX6MNLNrn1wC13yKTKL4PjL3", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022057f327c74d0539fb43790a2315867fba5f2e8a3f1faa261852c146bcd26e570302206d543cb594a980b408f5bd8fa2c45251e7d4eb005b2e55950cebf36c92c4438a", + "id": "a869df9fc61b6e1693527a3981d465f6f46d96a318a09d9a92c9888145e88a7d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30000000000, + "fee": 0, + "recipientId": "ALg7ozgLSN9wLUGu94LwMhPhFzyWBxQobR", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a609672480799e9034457b36d6c8f78c1cb253af8a055ac82117e30a3582f96f02207616bc3a6de1cca1762a3dac65dd48022da00e6800c39b44ae53e0d26a322fd1", + "id": "7f7b0295b52a45c399379f18ee56ab09638718fb9346c5bc1963d11cef412afc", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30000000000, + "fee": 0, + "recipientId": "AcF5LeL5ooyt1wja5Mj52gU8X92TVtG318", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022019f8c0dc34957e29ad1e55901f0ab865b38a7e0e018ed69b8793253a5d207e8002205901d7f3d081664da8469ed8e6bd59b3041ac1a8455f629f5508b50dfc2f62ca", + "id": "dae4406da93d88d9398fb59cdb154503104687b2e3a0754b169d17807a634900", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30000000000, + "fee": 0, + "recipientId": "AZ3qjcSmk3vacEiV3GdcK3x18hAut72yAE", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100dc74c59b710ef47a0568517dfe242dd8df2bd1305155600e7b0d39113b34a9e602207abe3ef33953e3aee86dd4f1c8909edf6ccbb2a3eb181a0221665dc07e1e0023", + "id": "0d3cb578f886acc03177c1708528692590db30c8ca270b5032b5fcd86ed75033", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30000000000, + "fee": 0, + "recipientId": "AYdMCtcQjbEAUKWLb7f5NEkkBx9SmTJzcU", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100af1a06c135f43cd0c67c499d1ce310170ead6e61b87f5d673a3d1eee424ae1cb022065b02e0dba32c5f235d9a707cf279a8178d5e5b0baa34572327c9dab785500aa", + "id": "ca2382312af236ea7f5ecec7f860db5ca528b71a4030736eb824db55ea976167", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30000000000, + "fee": 0, + "recipientId": "AGRJC9bwD6npvCuYBZywtho8dBD3RAzikr", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d060d1ae9b22357dd0fb6062abc88eb2ae7e47eebb7af7bc21440495acd3803202207e33d96cfb29e5cc40e45b53eca85b5891ee1b4122ef041e579df50464b8b053", + "id": "40a6b024984183f0809d08d199fb2d7c1742995adea05f1fe51a2fdbbd969842", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30310258076, + "fee": 0, + "recipientId": "AU2s8RgEdGWJYXjSSh8M5zkoJjdguh41Tk", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100be9cd07b90814b2f4cb2a868f08dea6eddc297e79ad7d48c3a1230d078454edb02200171f1277e17ab3978a16fa260903bcad9e66b8667e632cc856d09ea9359a898", + "id": "8d3fe39309daed03ed0e02d4b1808d54a18b71108ad3316898a9109981f0b840", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30644619264, + "fee": 0, + "recipientId": "AQFEMBFnxk8j3ShwNErwoqSK977DidXAAK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100929d3ed3bf40d9aab26360d553f1016f7fad051af511b4111b45ba22571d2b4a02204600751a7a3dd8d0b9e5ae93b6c014facf6191b52a64963a893ce4ad6d74cb36", + "id": "49b13cd9ea10a35ee422e6cca7044ca7a4e4201f397cbb8fd8627d1ef641ca5c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30990774050, + "fee": 0, + "recipientId": "ASVZwCuU1a7qgUKSdiZzRkuRHJpLp9Fp4F", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c352876accf4af2e7395b682bb88e69b896166e3ba25ecb62de62dec09891c5102204bf978db3488674cedc28d875a218309195f3cf7fd2ff1e35b28ed9dadd60995", + "id": "dba6677347d67b9a1030a3f883d978a72c40870414b9dd9a6fafd888195d96cb", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 31371117110, + "fee": 0, + "recipientId": "AXnjrqJujCyYt9rMC5E6NmnbuoN8N8LtR8", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205a2ed6c565adbcea14620c4872181c55dd5df09cfdb0ea96242a6a8a16fd446e022019cd448d1b41aa454ac2cfc476eb4d8d95b3283489fed359d7228d87f97f4192", + "id": "f03293bcc0c837c7d0741081cd123574c51a55f7e58f430aab867047ed0ddf0a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 31808712368, + "fee": 0, + "recipientId": "AWecYiRcWfVFEqdU9Ph6j7F7YwZp2kuowr", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220126963651521701323eb3bc6d78d7bf598d7b12896138f91d0daaaa0cb2a37d4022027009cf91eb481191fb7058204489db792fe49cc2925f2ded59e06f7740f2cfa", + "id": "4b77e88f7746845ee2b045357fb2f1cdc9d23608c50a5587c6414b3a0c4df8a7", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 31825770981, + "fee": 0, + "recipientId": "APATpfYkUfDEhUnoq2icXy7ECqSumPRK4C", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d20fa45969cdf4217de7c8977675794023ceb702d0986785fc7d14200a836c2202201db190f80f13322618d3d5c27d07b36f78c0a876428550ba1fe3cc6e5a2be8dd", + "id": "d6dd825e9819c4bfa896bb33b25ccd26c0d6fdf07dd60567c8048b57a6046cb0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 32300000000, + "fee": 0, + "recipientId": "AWcBdMSL6DFzxf4zcbouKnXqT3xnsaxi4c", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a69a449089437fb0878f351b9abb5770b9e84041516b1fa92deb06dc648627a302200b30af92639075735109ddd39d1247a57e9ee7cccba8760f0e18da868f264d84", + "id": "b3971af4cbd2bf84c9766dfd4124993189e2e445bf5c0dff235aa49f4942a2fb", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 32490327633, + "fee": 0, + "recipientId": "AWq1wsJLPzAY4uiVTvH14F14YNZ2PozaUQ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f05a79d7bcd98a58c56630a91eaa25f14e80fd07bc9c70277ded30bf32dcdcf9022067761b7133837da252a7f12c54a5e59596a5bae74292751f4f71722d1d0aa3d6", + "id": "bb073805ed067d4e2efb8882453433f52d0fd6f44235299416f012d73688ec4f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 32583527433, + "fee": 0, + "recipientId": "APruVpipmehKJWeienqh2jbAdVC9o3x2Yn", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c421a27e857b78d81cfd6d12a5b5feb0fea128bfc43a7dd874c014040c91a29f02201df13abe3451a8039bef22d2e801cc09bc6f4d42f85bf4e62caaeb34131a5e7d", + "id": "439c60dc29d33a9d2e800a5b4ba1c1d195f580fbc46c4183cd4dfe1eaaf9dd27", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 32900000000, + "fee": 0, + "recipientId": "ANiKA7nwrdSW432oB4Xufeb4MyyTk9QeLb", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207a79a82616ea4c83b9bbfd52f8a53ea0ee6ea8bcbbad23a0aae1b74e5eb133390220179678e1b59b8e435fd19e68541d890136f85656f31ad1513169df3b947ea481", + "id": "e645add44af4985a0c44d63a7d33d6bbc87d8d0ded51a9074d8796a2af61a720", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 32900000000, + "fee": 0, + "recipientId": "AQvTNyqxVEHLVZfpVFttfMankBSGLyAfWh", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100cfc612e6c035e4ba731bc662abd91c151c0256379c975b2b0b301e4990f99c36022028380c0fcec416d7cae09ff6ad936087ecb43f162e7edb98b6773891003a494e", + "id": "d17aada75d6a2e7566d34ea4d19a4f044e7ec8a77954de872911f5e603d0ce2b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 32900000000, + "fee": 0, + "recipientId": "AYnzEccw2MrcTUT4yXRp7sHQGe6G7x7UkD", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100bc272d36bad69aef950ac0551b96dd488bc9a83cb4025fac78c57ca286d42a30022003e275f6f1f923c61d6c3a45141274ca2b32f396d9f15a37ecdf8e6299df9254", + "id": "685f94850350f66b039fd33e550f0c2d1114c9f2fd7b7f0f723f9a8dae08f4be", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 33114472223, + "fee": 0, + "recipientId": "AVzMmzLTmugSxbwqWPqxxSQA4QtXVcz5Le", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220699428272cbe81ce84c5556bdb47e05285e8f2a533c5e1f0fafdfb2ff47fe92802204b0c4c4ae35dedca243f3a322e82bba73d80802f01d8d584ce5abb75154db06a", + "id": "1a1efccbdf78b25765e859d14e2d623afb1fc2acffc1fcd8d2679c0aa1fb697a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 33341283885, + "fee": 0, + "recipientId": "AY5Q9bdBx2NnXsQ4L6Zw5XShNR5gL6ExPu", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220398e0ab17a01dee9508b61e2a42fdccd6f0e26ad76168dd5f78b3bf8ed5d0a5502202fe39e30d85935a83060a11be934999874065d837f18e65ce96041b502a4388b", + "id": "eae73dbe65e5699583a3db3933114222b264c45ef69c6ad26dfa517fbb028665", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 33341283885, + "fee": 0, + "recipientId": "Ac2vcL7D9SLoQKwm5K8G6bbFQWgAXNbN9o", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206826a73682fbfebf2b6e78341e339ca1265bbdc3a2a70ea36edecb3d50adb2d9022064a2a77effebcea2f7e8fa6de6249b1e205e518e0efeca9000826f5a493d46ed", + "id": "16158b459a0c1b2953d98feb4d5b43df41ded0f72f3d8f7b159d47f5fddb1c2e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 33341283885, + "fee": 0, + "recipientId": "AYNtaJsLCbs88Dqv2Cc9SUEhRn3gMi6y7B", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009c00f35dfbde9a28230439c618354b5bb60defa091c8795c455f8a3519dff48c02204dbaa156e94921647d58d271e1e94cbff2fbca92263f225b46fbafbd65aa67b5", + "id": "7c0a5ab8ab2aa880dc4688437645dc9d825e030fdac4df2a25d5a8e97f4b5c70", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 33412512992, + "fee": 0, + "recipientId": "ALa8NaNCRdYYfS5sx81qzvoFEVsA7H4VQw", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ed45f09cf19eb0819dce65b619923909e116fe75588a96d6d2e792857a1a887e022050ce6e62dd65fa58e4bae5d09c191290c669eaecbca5dc38813d1b043f8f565c", + "id": "bab26302a9ea1d99d9ae0a90ed17f44c66f1174dc8ff11f7e7b79ed7b2b49492", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 34492604732, + "fee": 0, + "recipientId": "AUJRMxuAJjUFEbS7sed3otS7K4R89caZx1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009e20c799169e14bee9d76da2ca433b8d98295f8593bcedbced345a3ce189b4e602205fef5c8b8225b20744c385f1bd2994a0a824849e2b65592fd5246d625cb6a28c", + "id": "6cb0b2faa48c09b48dfa6dd0391d3309be705c4704d55f72d8a39347da0cc6cf", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 34600000000, + "fee": 0, + "recipientId": "AHWoDbD86gdtvHfgRyKtxo7jHS92hLAnPL", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022043bac64f1f5a5b986fae5cf88d182ca4698d667a0989fb2b89e731282487021f02206b8d22d28a13bce3d61e513c6aa2ab9ed8aba0370ea38305c86df90796cca026", + "id": "fdb9291d29c3ba236ff008224764227942056a4d28f9c12c7ca7e22b4c4c9f56", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 34600000000, + "fee": 0, + "recipientId": "AbJv6ehN7bETURRPJtTgJ5LfJcmjnVCjjY", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e01a874648848f53e3c58f382b04c4d8372dfe14d5e715a0aafa483c4c1593e0022024d196708b95991b30f9a735aa5bdc951ce80455fd30b32265fb1ae8e20c4376", + "id": "f10183e8291eec17c2308b2731b25e0378a2753ac11024c6b967c04138491900", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 34600000000, + "fee": 0, + "recipientId": "AMGy7FcNBntN6FY9ouWS62dEmiNW5SNDSs", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100bc4ceeb3be6f423d167c08e8609e5224a43fe2692675c4cccb7ef35d9b5e286502205b9639e02cabb93e9d1262b8291022e87c8fb26e104ad46f38ba1ee4eecd8b16", + "id": "e72f27cd791fe40da52aa33d4534c6cb4061080e57a1f00ac5c0ca2e0f8e0adb", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 34600000000, + "fee": 0, + "recipientId": "ATgMvSP8FjG7mtDN84NKvxCJkHP63S2EMp", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206556edbb04478bf8492500e284ba73afa570a1ede51add1d0798e70f349e728802202846f2751bc43dd0c0541327e1f20e5e97149b2bb29ebf75d2c17890fdc751d4", + "id": "21d1a6e3205127c1c2008279631cde827bf82ef542a9706f255f0a52b0aea1f3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 34600000000, + "fee": 0, + "recipientId": "AHs1p6BVoscsszE917Zhvd9BPWrQbaUqcq", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a3e2779d7b46931554138df6b0cef64b7f087541eff83c07358e497e136ea23b02200477eb4b805e61433a164c1d0dac248aa2301bb20f774477bcb81c455b5ea709", + "id": "6e804117d3933b6731b936984bcd33a42319d096d5ee8d5784e1686658c72af9", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 34600000000, + "fee": 0, + "recipientId": "AHqN9DLFs6S26HcG3zNL93VfofkFSoMXQL", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022058b2c046dc42102008402d2aa1cedd8417f39663048e943227682186c8a5861b022062914b3c529429ed2e0612cf2dbf0e66baebd5ce3ee70679ec723862d8bbbed4", + "id": "d0d692c0b8ea05ba6adf6848c94c642a824840fe2b541e16c7fdc0acb8ab280d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 34600000000, + "fee": 0, + "recipientId": "AaAewYY6LEDiXVmMcsoZTbkvq2X1DQKoCF", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fd56b02b4933f9ad0f998c48d4305fc64c047d80fde18883c4c38561d787023702207f6c412361e281154d0868530a6bbe3261040d367087c401b9ad8a7915ff6a17", + "id": "72b77c936dfc9f4f38a825d79ae0360a351753a8aa7e89286edacece4ccd59fb", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 34600000000, + "fee": 0, + "recipientId": "Ac5rmbW5oQnjn51KeQeYPi8k8cB34kZFUY", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210084307422d072f2c09c3ba15404fe9bcd44932e92eb2ed608c60d707b960b69700220186c1250f67c8805c39661d121b8051aa983e0962cb34e046372641830dc7dea", + "id": "7fe1f32c8cb0217b9ef57edc5cf687a7fb07c1b1b82a6e9d6422e1ceec2643ae", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 34600000000, + "fee": 0, + "recipientId": "AR4BUMG1TKCcZi7rWMaNQ6HQkp6wikmknF", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f32acf1ce8f09eeef89d9b42c32b76dfc95da77375d96d22eabbaf837a318fbc0220059b6de004ce6fa0a2ce3f41ed053cd0d8f735888707bcb6f5163e6c05e762e3", + "id": "28148ffe3c46ac548cf5ca10fd40575acafc8cbd43f01e97cde9b5d385974b29", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 34600000000, + "fee": 0, + "recipientId": "AZDhZu4Bxs1Y4SgLc24PansSLP6gXZ29to", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f4963f319382de0ba03c3c0856b9a667a00c82a90de308f00581299aa649b30d02205f7023de13f3958320606b1db434cf40c5294759c01a21691070c90bc2b02bcd", + "id": "d7b7d4815d3617e96fc2f47bbd7424a8b841e2dd5acfa42fd96ac52cd91d2e90", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 34600000000, + "fee": 0, + "recipientId": "AVG7PZt7mWxsbHEuJHF8xjqDLCxhPXsH6V", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a6698eead4fc3e21e659f6705356bf1c1cbf11865a735ea83e60eac5488ce1c8022002c23b6bfe049f8a0e9dae2f7eddc50558b51898459bcb2310b4376ef29f1a21", + "id": "e0d87972b7727a514955e01278aa1803bd33f18170554c410d0c851f7c0e7340", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 34600000000, + "fee": 0, + "recipientId": "AWiJZUDjG9KKM5QnKhz1Gnb1C3WQB23Xyc", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220563392e63a4df3c65909808b2a4b69371e082af2e6f0a9d2c3fe8131b87d514902201657b05f6789b16a5cc4f83dacfd0479f222bbfe17ac97374f19238259566c81", + "id": "34aec54141d983219b001b20901745720f3c38d32cfc736b82697e11bd0848aa", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 34600000000, + "fee": 0, + "recipientId": "AXDoHhX3gwTapS24HEU72dgjsc8TFEre1w", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204d7f9490bb14995339dd36f4f36a34fcf37726f1ff6a821731a2e788e62c9e1f02204804a2d78f61b94ca546c21285de091fcb3779c2af7aeb7e62c483556c221849", + "id": "152802a6a0822b0d9082c0bfd4109dce3dde9efb491cbf09d76e071911f62083", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 34600000000, + "fee": 0, + "recipientId": "AQ1n5gCzkyT9DfgJVBEMdApdKsBhXS2ZjE", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206b5c708a8413bb94024010c291633528f6dcf3f86d06112312239bed0e488b5d022068113fcfc5dc3f522005841ea7972f92c75f57ac19f58fd186371d7548ed8ce0", + "id": "b0a303fff3f8d312ee52989778d5473173c0010bfffecf773d89e3db1a3c316c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 34600000000, + "fee": 0, + "recipientId": "AdJ7BZneub7qzyB8qPHg1FS3ViisAfXP55", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204e09b911019131814eff411b87aec770b43f90b15dee330ef901ae18f57178f90220381febfa6e3cb1e869ca682c3efce6c5c07f5002a234475a1724a7a3fbc6788b", + "id": "05e2795800c06da22617f5ecb702c5c178c610a9c1ccc8dfc8a5310f80c169c3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 34600000000, + "fee": 0, + "recipientId": "AXMgtmxcMTMTZkMWJJyZgFNuaP4jco9RZL", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100db75661cda0f02805787729e123ea7fd914448e56b5de0598c187d193a1fdc3002202823a45c4a674e70468185ca667f45fd2769c4a763c915e4e4c0975a672950a7", + "id": "e7f397170f9ec10b9e1605974c37d1ab68794956b6687c03e96ecae5057d12e0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 34600000000, + "fee": 0, + "recipientId": "AQFYCZf3XpzZyjo4BtAQ7PzD72Xhp7y7vb", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d3cc40176b487dafeffa3c068dec44b0e94e079d015811c0866e3eb96a77a2d6022051d678f7e7410d3b27a9c86e2829d31277462b37381eca23febd1d195b21cd1f", + "id": "56806a7b8d18fff61d209e977234bbafe94329804f06ce5dacb626c91e5efb7f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 34600000000, + "fee": 0, + "recipientId": "AZqUtuBczriacfQkM1iWaiobSGX4GN8KwP", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009897cfdf79fd8c69a0508292f557dd46b4ee751be8e158d0bce8338c73fd86b2022044dc1e89fc5eaa374c0703862cddec760a8f692718768b221ca561116af6eccd", + "id": "c9e886dbe8d9344cde99eceec3f927ad6f8ac08525b18daa8d2a72ddc2a0bddb", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 34600000000, + "fee": 0, + "recipientId": "AW8RbZZiYe8FbDGNS77MGWEE16Zu8AxxLz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207bc3c68c391fe49ed8c7f06d35db75a739ab9c8d97cefd2e108f7b9bc5f164bb022040ffe76e6f3bcc39f993df7405860880ece802b28e56336a17b40a91701587ce", + "id": "53f0027d4810bd37571d6a25fe9a212890210ec4ee42f700394ccd8a1672c8a2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 34856796789, + "fee": 0, + "recipientId": "AXk9foYqX2ExUBK9Rtdirj2XTZ2vReCmox", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022049aa0eb602199bde5b2163a99fb098af4687a8ce249923d7007f5155a4219764022076e659cb2877771720de2d695b7df6c981221010217e885f42fa7d0c09d329cd", + "id": "fc2c5586c3e6aa5bc6d08272c06caebce5592b9f9bea2657707c3ced4c008aaa", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 34856796789, + "fee": 0, + "recipientId": "AYJyrRtDNZPw3srKy34buKUFJ8vwCxAuzc", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220125967fe3764625cc68030e8111c0499a0c5102195f94aa38499802de03f267a02206a97bb532d9da550410499a3952ab4a6e01939ab247c17227792e67fc25fba03", + "id": "b4cfd3f8d50c8bec11bf73e8bda2e8c78de932ee460911e0b8ff69c49ed03a08", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 36400000000, + "fee": 0, + "recipientId": "AJtBjGqiABsp5bUduT6YaK9L9E4EVZXhjH", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210087a0a6cfd2e046140baf9899ee9734ebfdfeb5fa86da06d6b354a7035ae3bfd602207de557dfade43b2b1f79b57c19133df0c0c0f6fe5b72f6b34fd0a5b5de987a8f", + "id": "379d4537f2de2f2cd6d9dcdad6c922ff45d538571712ceb2eca4ebfb676d06e7", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 36400000000, + "fee": 0, + "recipientId": "ASE9D8yvqKef22qP7gAqKyxYqvNymPPm9a", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100dbdf2e7a976583aa29d4bf6e0d46f3919aa5bf281af7d2a655db076cd73aa1a702203d2a6c322152f63bcfa2db3f535f40b397bdccbd69a13557430bad54c3410cdf", + "id": "0fcf2fa0265d5c4bbdb6a0a0bde602f3342fa59c479af9c761e8032876ca7a34", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 37488839577, + "fee": 0, + "recipientId": "AT2FkCcRYAttXPz47FGpdgURLmza1cDctK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207cc3222d47958a7db0ccf22b6a82724ab14774498c3015c1efe72a4eaa81f0c002204c6d395c17568ee5f5831170da2ed918f5bdb637d2bec9711173b444b09a250b", + "id": "8a905c558371ad7a59243e489fd76d5ca42e522c8a04d3d8908a73445d6ecea9", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 37771522137, + "fee": 0, + "recipientId": "ARZQdfzNT9Bd7ym6p7VF4KTjnD1XyoBFdx", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205c90fa2f53194d4d662c53420e4ff1408aac499327e46ab09c5bdb4bcb367eaf02200c71e40ed64aaf058061a224a54d21d1da4719816a4ad90a73b2d86a2795d3f6", + "id": "0f8a2e414407bed22c8866f8f3ad446bd932f24089c15c3122677c7f5ddbf4af", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 38100000000, + "fee": 0, + "recipientId": "AQpo8EbxDh5FA4zATjVRzEFfLcnmUnzMAv", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201de54ef50c50d19a8c86aaaccd7ce55790faf0a58031f608f50929b0ea79e8550220533214087b327632aad01474d1abd56f24793bcddd2366f7cc8346cb75b72985", + "id": "079d07f46a09bde98d55c78ecb6c5205e5209ab32d27c4307dc5448552a25bbb", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 38645579049, + "fee": 0, + "recipientId": "AarTZVSMDRD4k2YPRRs4vNpARZMEa6MtHL", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e437c1b3391179c2c73f309351525aca426a52a050f84cb92463fb37c0f0da65022075660f2e0dfe215911ca518b55954cccd0e184f2d87eb3b7f4500a3e782a7b4b", + "id": "a16879ce73bbfd163115c767c3ffaba4dcf8d1cd2bbdacece77ef15c1a777ab8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 39403335501, + "fee": 0, + "recipientId": "AZdt1o9xiUGNbKtxX4GUjA2Qf8rrepeY8J", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022100c6415f478336f7eb59ada8084bb4656eff9e22a97670afaa4b7aeab9cdd38d40021f62e0546fdb8b200a526c79c67c1240fbd528f6cb332804713109b921b4a458", + "id": "6da4c777b0511056f1d5420621dd8b70b8ca6ab5fdc1a6df342938513e01b2c6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 39470224178, + "fee": 0, + "recipientId": "AV7fCGPQZi7tcKaKYDKf9yGJRiaTpicRTK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e0bbe7320e5972688505a4793e0e9cab39914b53a9ec5fba0ea6e179cd8f94340220737cb6e960f6c2af403f8a80b7a553b6baab74e517f3bf9de245621b1ca9cfac", + "id": "bd2280fa9b6d30ec1530bd9e5601de25f3dd3e0344472a2b4cc7c32818e8037d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 39620933325, + "fee": 0, + "recipientId": "APLS8VURVhTsQ8gYRh69cNbUCETjL89jik", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220548e77cba610645e3b5caa5fe0de930be30662ae976b837252b3fde06bd2f93202201bc93d5dd1710ed48d95cae56f0842df1acbf6da100d4d4d4a56a43b84a504df", + "id": "6bda585f91fe13005e7c2ae9e317e55486f3e6cd0d83d0a64636c409ee8962b3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 39676127823, + "fee": 0, + "recipientId": "APfd2W7pvN7889NjkxygPYuaeAg1XNvKSo", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f99b2ab861887bd456fe83981eb9bf17c655bd9fb3db399c57735001b8913c6102206166bff4926c83511798121ddbbe68e37ce8ef14baf47009c55385110bd470e0", + "id": "46aee861d13cbfa1e058f518e14f1accab43bc628b5aa1e5fcc5f28b38219a03", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 39676127823, + "fee": 0, + "recipientId": "AaLnoAq8B6ZQ9gWMNSc6EHa1PKKkNrPVFV", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b9dd2cd37c9f1838e81325c4ec8d738c9554cd658df1588bdfd568d4ef92e1a9022026e3e132290b7c040220c7a6acd09aa98f4f10cc203f632fe8beadb4f9e1b036", + "id": "d40b29ae4603902272be5e09112e1e5291d49ef8a05ac9e756974c92ae50a677", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 40208679058, + "fee": 0, + "recipientId": "AXVNkc31rXQchNorSwfpweu54jjPCuJkWu", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022078da406531b60613184867d8ab424d2de871bba0651bdfeb0fd90f57c50db48b02205ce247f5c318340534a0ab4abcf37102c09072085b78649b7dbfdc166e79151a", + "id": "d3c4f8396ff1a4ee221b03282321bb8e45ce23efb00d61b8e1f9c76039d2c744", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 41600000000, + "fee": 0, + "recipientId": "Ab2j8GC1y4QtgT7hYv7pA2g1tiiC4W2Hmb", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fab3f4e4d7b764645b4dc54ac55b3856fe95e32f5be4e1bcfa105823a9cb5ed20220053d7c446db556eba9cf85d8e6229360a28dc0cbf46d894481e29269e96ad74e", + "id": "cc6a17753f16a9bc0bfd922b5c39e54e2e8bd6c3daf60f0cb84752af997bcea0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 41600000000, + "fee": 0, + "recipientId": "Abbn712o4ZVx9WVhC3vy36KuW8nRQrKR7i", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022027d1dbc4e47f15a2acbf82f28391d94205ce0ca67fc6bcd88aa0661afb4cae550220717bc9f5525ea5f38d8a17ec4b265b56a58f0caa523071e584d5bc1505b9f525", + "id": "79fc75d4fef939b3967e65fac8103cbdb9dd6b7e60c08323d735611d4f4a1db4", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 41600000000, + "fee": 0, + "recipientId": "ANMGxQS3nccdwd4E9VCkUPx7kqCoNgTPBv", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203360d6ca61b6a128e399878bcff373b8ffbec4812df391d118eb972f8fa51cd8022057eadf2624d266fe0a054b103302832345189074c05502f9d9efd4969fb6678a", + "id": "000e2a9426529b65db56224bb9ada512a48395bdc14d22eefcc64ea1342b8e45", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 41600000000, + "fee": 0, + "recipientId": "AWPKFKMqjSFjMzzimsKMgQhyzJF9JBbu6s", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c8f1def0dd762083c23c58977202e0fb138ac22f987ecfc71f915425e3492827022054d427bbadc47b5aba27f3856cb00960a9c07ede09e438ab29928e3ed0096e26", + "id": "617a1168653fd2b8c17ca88d0186949cb8a155ffce2a20727b9940254b82f2e9", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 41600000000, + "fee": 0, + "recipientId": "AcQR4ymd1ezhUe82AuXZdWTooroxdt1cWF", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207f92c3391e8c66ee21f1f7a12b056e04056603ab6364055295e5bb9eca0862f5022058b6be51c4ae062433934609bf3d0b3f7c8e5aac5af9d72c0ab375abc89a6167", + "id": "948c73321a84c807cd7381d595361e64dfef9b87e957da57ff809f666b76f0e6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 41600000000, + "fee": 0, + "recipientId": "AQ4Bp3zg3oCoS1Kb2grC3DMVtkRCzzgsgz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022057a78d857515ab4028b94cf3bc3cc0bf378213f226fd1160d18c17f298dcd5830220574d2d14ec7972b165c138bbca3f01dd51b34499d2ea5516381572ae3a08ac84", + "id": "4b1cbd8fbd593f29f8fa05b2aaa44c0e0130748b17f09b0c43d65d3e643a4c3c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 41600000000, + "fee": 0, + "recipientId": "AHgivfsrR3CX3xQFoCQmui2DAvUZY2CNyZ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a76da3d4c56cf815cd0fc51160e7a78408c144bfce412d19ee1cc58665e8e44f0220348632438eb2902e6af28bf0a5c074dad45e9060a44b011eae325fa52a70177e", + "id": "dcb2ea9333efa45f3d66d4a3fc489ddc3853f998a902785da39f4ea2ca1520af", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 41600000000, + "fee": 0, + "recipientId": "APcJ3M8vmMQD7gU5ADj2sDgcf1N6FhJ1P8", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b530f23d6cfaf93c26ab19c19b06d4424bde9d28d9a26383603706e15a9c2273022064b7a2879828a23310603e34907761104bb7f3a3df81bfce674ff11ae2fbb664", + "id": "69a05ee826cc2ba50c2c034cb980ae47812567b7307814444b72b8e70f98b43e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 42131258728, + "fee": 0, + "recipientId": "AUHWHwFyrqGvBcNXUjvUwM3hadXg8Ao29t", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100bdc6bbfd224056cce2382d92e4a81821720bff470853dbb0afd886afd149cc4e02204b98db8db62174711cd168c11900262a210fbdcf3a9a6f37095e174b54ef5891", + "id": "31ef234dacbdde03bd42a16ec10113e15d07ec0a7b7be5ba53c0cea80667fec8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 42255389394, + "fee": 0, + "recipientId": "Ab71JZB8rZ8kpYVn85Tm5Ra2MPP9dP9zrg", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204adf5271946845e06db2bd764012260c81fe65fd53cc5153d197bfe49ec4c6b6022064637659ab09da617552f820fa155c0c8e927f6da4e64041ce1d1dc982dee5b5", + "id": "160d40dc3bf0931f17ba61708817191e818b5e3342c23de337ae4e90c865a371", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 42416655243, + "fee": 0, + "recipientId": "AQjvy3Lr3AnW7QzeEtDzaL2XvAZGNmA6od", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008d073a33310126298b08ecca7abf4f9af03086b76a62975c13e335e77880ce4d02200e928de4e5726b37f282d9e483ddcb7d4fed27c73cfc0261d8bff9f382606768", + "id": "cb63ced56cddfa2952302fe8878c721bf74dae1ccb014309d602caa2b1cd3787", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 42700000000, + "fee": 0, + "recipientId": "AbKA7AXhr2Hz4N3o4uLgxCVw9q445xygRs", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022061a00c4b115ae2f72d6c7a66d6bbc6bff9843239b65de88a214036c98bf2ecd9022059f612d1060bea12812fda983962c7909793151b0c33b57ea1c0b87cb979e588", + "id": "7e741a32b14ce1d4364ae4f93ba123042d430dbd76be81b0705a69921a07596e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 42700000000, + "fee": 0, + "recipientId": "AKRPP27m6RocDmDwUeSn9FPMZAdq7XZKeb", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204976b03c753c921b6ffcaf08b742e53f3944dd99f7604e9491128c2cd5bb06070220735eec837093c4b48d14dd6d91d02a0433e86ab5156070361245cf7204b7648a", + "id": "5aa56c54f898b59c422a478990d978382aa5ae7168e87afb3a693db7e5c4d897", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 43300000000, + "fee": 0, + "recipientId": "AboW3NE4S2atxnDiB5fE4FNq6ewXQX1jNM", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200bd507090d4afe13d3cfda6d6a3b8cd84d07f501c1d0b4dcab622d836f6f2baa0220597014fae0b01e2f26bd560804a8d2980df2695a0b277945140c2f7f3641d072", + "id": "d8768e339e6bfdc242cf3c395d3b0f11d4b4796977179cabb06c2ec3a758c301", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 43300000000, + "fee": 0, + "recipientId": "AYSgtUb1hE3WTkw7pQ2U1AxYmTXB6hSdAY", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220548744d15a0172cad94e4a2da25632d1074c78de9b5ab01299ce319b7e9554eb0220252400f1bce65a39a0060a64a5cb44aeda15fe33e01ca7b3524f2dd41ef517e5", + "id": "af598dc5b1ec4ca254f60e4abfdddda7a400afd42eca30863b7565899fb73396", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 43300000000, + "fee": 0, + "recipientId": "AJDZqWaKSug4kPadzqKYDzm4MHGxhhUYiE", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210083e24d007dfe080315146299f74d8129fcadabd3feefee65133cb26b4a7205f102202b0378b31f5810c7aeb96d4c1784d1cb098a36df52f8f8e10d16fc41370f7c69", + "id": "1c2e9b68f93e64f431c95d1aa03edfe301d01d5e5061bf303ca3510462f7dec0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 43300000000, + "fee": 0, + "recipientId": "ALDJhQh5YLMeT2TNf1viyoqJFDTdVxBpdr", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205a6741a4f2d76c61a93c300c5dc9542ffe7822c1d2eaf4d63e7f5dacaf7405d40220675355e51b2da2eebad0e1409be2b674415ed903fbda6257dde37e1851ce4fcc", + "id": "4522f2e824f76a2ca38b8f9bcb589d32394eeeeb44521c27a7d29b410d27ba2b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 43300000000, + "fee": 0, + "recipientId": "ANZed5qKqwcaj9Vy1emaYETWUeTVTuZE6q", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022002d24d963c7d96285437680fa90647d6380df7fa3f84fc3b26ebe80d6d5b4ab70220292fd00bed98449c72e246a94a5265324c16bb8357d4d5863cbd9bf95d7ce1c8", + "id": "72ceb8e73f321a870319b090a0840e83bd8257d86500ad1c23fd3df4e9f76288", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 43768613037, + "fee": 0, + "recipientId": "AVpuvWkhYahCaRt3HP27X42W5sLQp1par8", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202bf9aaf14081129fade556087d9c51d31b2ca79f316df943834364dc655e13a502200fee586bf2a8edf195f939b9b850bbec71eea69a04f4bacd592e38dd69c21910", + "id": "4f0a3f9b10798151efb56686d7920dd3447d824d0ff85e805923f6e429f35dbd", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 44117933985, + "fee": 0, + "recipientId": "ARKK5gYqzp8ZBQu6Lb2XCrhyFN7DW2u71y", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100982ecaaa74b2b64bc24eafeaa49951093212380f9784b4cdba3f39b4c6d80e84022054da5701fc8b6222fd56ce68c1c36f125b588e1b4a18fa2512674497c553d807", + "id": "f75cdbe651257ba7454fae6d967686c399a041698c666c25db6f31641a7dc9e3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 44286661880, + "fee": 0, + "recipientId": "AN87Bx6HtTjA6NpajYfTLrqSwKHzx5d5hW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fd9e1fad2be125b433ad14c77655b8f461db35bdcd68e2cc776c22c887908e46022013e50085edbe22d2feda04815b035ff06fc6a744822150ef8ea7f67c893f0c66", + "id": "9a01c2222033973b17d6014c970e033280053eedac7c1fa9092b2d104a72caa1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 44333481457, + "fee": 0, + "recipientId": "ASbW8T3Xx3bDZQYGincxMhgspZFZNrobJD", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009fcdb37789a54a1ca4134fa8a5931cb5ecff33a6928695d68a903d088fb086b502200e7c474cbb7d1f6245c569d3f2fd7468a7993bde91bccd9802c59ce0d2b56ddf", + "id": "48de47db070de621b582c945d2eee43674ce2ec38b48d7fa80294d20e857cdf8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 44556079374, + "fee": 0, + "recipientId": "ALBVdpLvZofQPLdHungdurd4iF2vHtoFbS", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210098e6b691e6c5c75fe5288d2a5cf0cd0b79694a03e782d9aa982a6df7fe206db202206df4cfb87cc5fe8fc61c5b95c16c947e98671390dbac8b74d5d9acc02fd6513f", + "id": "bb34fd7dc178bbc4ccf41b5ffe7a9b8d8bae117f006006bc710d76f36a83d5f2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 44571697840, + "fee": 0, + "recipientId": "AHXaXhX5ybwNZ7VDkJzJMSD81J6m225xNS", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ef3571ee051193e032dbee17d7b1baf58ea08de031521582416e7965407babe9022055b390e25f42ac5240921d89210f4a9c7176bb922941cc85f92b9dc7e12a1491", + "id": "6834021b254515836168aaaba7bad2ea5ba943f2f6ebab2ed65873342886e147", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 45000000000, + "fee": 0, + "recipientId": "AatvqNHtaZ3bEbegvVZKPoXUebZkNQgJG8", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100bdd197b4f1265984c8298d2780746f2e9c3bc375a2e316108fde2334d025e06702201c836e38d63e67910c20791d9fc4813de475b83ef954778ed5a309aa7691ba3f", + "id": "f3fba4cd40e1f99acd6f5fddf5d7fea6758053db2c37e0408976a4294068bc92", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 45000000000, + "fee": 0, + "recipientId": "AYzwRwPZiXuvP33QBjKC8aGyhtbQJad56t", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f87ba4784290c46da18275953842aa98133bc70d7b4e71d8ca12282f6c3aface02200ea514cffdaaed678ee27e9915546bd78735363976da8036347a99353373c981", + "id": "e81faed2cca7cbb2f9d059b2092adee98010bdd0be99cbd5a2fa3dd6cbfa2b50", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 45000000000, + "fee": 0, + "recipientId": "AFrMQ99PEVFX2fF6FHiczGKjXwetkGxYCy", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210089b572936a6429869c1824ff5c093f32519eda2f184c25e488044564fd4f773d0220300200b1497d89248eb06940f0ad30972666dac7971767e1e3d72290a2017457", + "id": "d50bbb062053072e469d59ac609cfa67f1b42db5bf94f50f00002a89253b09bd", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 45000000000, + "fee": 0, + "recipientId": "AZ5xjWNo8XA6xCbWvVeR5gWKF8Yh51ccpY", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201c7336f68570529c6964cb333047edffb7208a41b20946e3f1e33a6fd8c2808102200df8378a745cfebe85881fe2145d8b6dc54bf002e7232e966f10f852f2ac4e92", + "id": "0e671acd9b32bb08daec418f01e9a2b92533928190485a2444ce5ed10798903c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 45000000000, + "fee": 0, + "recipientId": "AUR1TuACuFHerTUB6nkvzfr8LYKw4D1DeA", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205f37144ad23e3cb508c39225b2aa5316c64a64c4dbd8d9f683c931f986862e1302202a6891bc8c03f50f697d5229fe5d9e968c731f54ee2661b4d87c4178be3bc2bc", + "id": "1e0c135240fec675f246e042f8d3677621cf69715a0f8ce8c0480c8c7e276d94", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 45000000000, + "fee": 0, + "recipientId": "AJhTg2R2MWsrzWfn2VMSa7YgthV9ciSAaz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b8c307b1cd5f04e3190470d66972ab3887286424834389efa4c0f14b29d5dbad022053bacfe7cb19002963ce7999a9b324e7b5beee348b827cdd071514c4f3a94fce", + "id": "625634fef958d669ba75d5feedd43da8930ee4f33cc192ae99803f9643d9d44d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 45000000000, + "fee": 0, + "recipientId": "AawK835dZLs9E5C9KXLsFEVmK6re5E2fwp", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f97b2eb6908446bebde6634b3b79d43eab3d425f02660216f1c2c753195d6aab02201c428ab520196041a462194e906afe6bb49ef7e4fd97955dd44bf4b2cb3c498d", + "id": "71ed3ebc697935d79efb1b1b0ec2f45a67a0e784c57fbff3965ce8ac73a8cdf3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 45000000000, + "fee": 0, + "recipientId": "ALyaoK69C8NT8yiKJdx2bPnPpggTkuJdFG", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f69603b3b32ed21e6b90d70b8053aea3c45c1c2e2c204bd5261246b97f43da2f022040756dae02033d7959f870bd1e05145f017aa7f9e8d8bde5ea9db4458eca7e14", + "id": "a38b475f390abd826db23697d8f3a11229ef4ff5e5d9a5486dfc2475cf9b2594", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 45000000000, + "fee": 0, + "recipientId": "AdrWr45gkfS17raTKgACtMwC1oeem29fLn", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022058cdcaabd8201113db1e2babddf080db1958c9072b1039fa245c7dd83e92caa7022070ad9408de0f11f8a39cb43d2533a8b6bf079c7237250288e4eb96dedc3806b1", + "id": "f0865d7b5fbb45687410d8abd0e4a491320fcd2803a80edc40d3a300ae0eb05f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 45000000000, + "fee": 0, + "recipientId": "ATLyQaK3RtKHa6eGCPZRkVrKjEMcKM2NNE", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022005e5bdc9a2eaf86059bc4d631765da8da416e108e6d2e07f2aae071e14fcf87d0220085c0961f9ca20cf2e40278cb27e3cc0de609d080599d4547905dc37bdbc60ed", + "id": "89fe6d2b213226f45a138ea256496d79ad5144353b0f5bd95315c34324674ce4", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 45000000000, + "fee": 0, + "recipientId": "AdMty9JNMNJ4eSoUZqwnE1pzRBZQW85Dmr", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201aeb9867943ae98594b74f68a44e2194eda83b52a7c01850f2da145af34554e80220615f683129fc5e3b109067e5bbae547d6c80581c2653b7bedd7d986bc19384c4", + "id": "6550d4dff8ecc93472441bde8d4b87b174719d14b9778f9f25e826cb58d57d08", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 45000000000, + "fee": 0, + "recipientId": "APEkkUCURK2SFA1rXq6nrqYyPVW13rsxtq", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022056e356a79e482348494a82271fa5c6ea1f1ff3857fc2429d248eb5c4ab859734022000b20a70ff281ae78a4ad63af9646c92e11b23a0108c6d646e0b2680f7a8cb53", + "id": "2640992456466adfef85dc33db1f0ad1bf731209a988ce0c3af7b9e2f0a15e36", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 45000000000, + "fee": 0, + "recipientId": "AYiQeJcxPMdGqdvKVHzLQvmAPcgK1JNuwX", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022072936a9c44c3c78e1da607c23346ae71a7dd55294a9f1dccc7ca7b995075b96e022022ceeb6db9237674388251c1acce2a1a6eb5665aeb8a42b9772853ab68284e90", + "id": "e288716799ad69535338745567163e9607bd2500e78f2fc1dd90b4deaa64cf7a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 45000000000, + "fee": 0, + "recipientId": "AQAeWRKR5mR124KMqCH44BciU6otGmbofj", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fb9aabdf5f55bfe910272ad8ce308f03f5db3dafd8c9d2a9007e784e0ba8b12e02203843f7b9e84f7a2a37a23843605dc6e1943b3ec3be0a7330d075024be0338f8c", + "id": "b7a4725339a9517ce667d69b50279c93c53e432ac8029cf1d1990033ce446479", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 45000000000, + "fee": 0, + "recipientId": "AYHJ3GQkHzy9f3ndLg3CsEBvqSrAr9WicB", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a609c9f810820be67db6b2ad25e582721da81ae29b1fbe95acc1e6ec9eae4f5502206cfd243d311190870177ddced286a50f7df71e3ed12bcf2544ccb61184441675", + "id": "6e68a86ad3f141ce115341c4167a0b8c8039671f7b8d593a9007c299a1742ab8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 45000000000, + "fee": 0, + "recipientId": "ATsDqjHX5hGuURrPfnDNmQ3jpB4q2aMcmK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fd13b731e92673d5ae20fbe28c9dafd55b4de120a8b8654b9db323c4ffce89bc02207df49ea18df0e5fd24e72ade2bfc2ea417f53d5a268364eda48a8af850a972fa", + "id": "f6432660a1f9291b952bcc0518abca3f0fc2a48cb553922f94ab82d5127d83de", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 45000000000, + "fee": 0, + "recipientId": "AbWMPtepNQdtZKbNFfkbEvBki3gLxgzpWZ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203fc4e5dcf19aec5c7cd014ec4aade1a177bcf1e8ba4c1ed8ba6636e6091d62fb02201935e26746309781e360a48577ef5ffcd82d41c6540943448d1bdfe44c804b7a", + "id": "1c67042ad2c0ea1436ffca3f18bdb68e192dad5cc1af9506db9187880bfcff58", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 45000000000, + "fee": 0, + "recipientId": "AcA3ke2piEk5tUbLcaaeU25tZckcYaVRo5", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220057351f830067dd2f2a6c554307d64f2cb01c4a41b4bcb56d92bd02353f2a00302205562002faae96f1915237f5ce1574cba8bb17f2cbe4cebcc4eb25f21b39018d7", + "id": "8abc18519bc37580a21b2b5d36bfe15eb4d6f63610fca4db2dee20f6a25417b2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 45000000000, + "fee": 0, + "recipientId": "AWMJezaNhsvRxDPMtEqNdYHt6iAMMCRroQ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206f1e30ed77982601cd7186278023615f0f9c19984ea459629a7d4ebcc4f31e9402207109ecb76a21e88e3dde1c9b1c996195def546b3e6c5affb44838c2fd6342a0e", + "id": "5977367c87cc269564188bb26cd03226dc5d182f7191ec3dc7948f6f21f71d13", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 46006407173, + "fee": 0, + "recipientId": "AMjF2vBKEdDs292kBAsPB2HpAYzCqwUmEC", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b58f5b2879ce4eb45501c18fc605821dc979e3e7efa7f204c85f5ff02b6623b602206f2b4c40f9e7ba54dab669024d3a5a53bbf35ad4bb815c3811a565e6d5325691", + "id": "faa89d3d52bebd59d0abe61d555e187c1b8c98c3446bc566a036a217c6fe5c7a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 46288347832, + "fee": 0, + "recipientId": "ATsdHdM4ZWFUXSmAS1MxvTJn4wEt75fyBu", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100cdad60bffc4d6b6e137f894becf8b7d67d2084a47df750d40590a133e02cd68d02205c99a8012fb42099ea7f26c45181a47e53a02602093a0fda29681ae77dd9e6e6", + "id": "87c1e1fdb88c4e153d3e3e85a767b0e76a29f7da8a88d299b79451abcead9365", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 46416322043, + "fee": 0, + "recipientId": "AZsbKy8LmWUf44H8XqGkbGA3mVdyoNsPc4", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ea15ca497460bb9d9ef34b644d107abf984cb3ca26e6c31b16509d7b9346119002206b732e6eaf0a6d14f43ed5d889726a5998d5a190895d4aeeb355cbc2c48ae2d2", + "id": "8aa8e83047ae4bc31b0775949ec3e9a393888ce39b463d91be26a9e5393fe7fc", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 46947045881, + "fee": 0, + "recipientId": "AG7uDVNphx9PerxNvELAPrHREsnDC4zNyN", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220697f3cf632d4a4e8a3a424be3e15cf7e9b8af40f484dbd862fa32fd0e7bded8e0220061d59d40d3f63cb496b1b1030cdbfc87a9e06e71c63fb9b05764fac08df8dd0", + "id": "e351f47deb7122873b04a91a6051db3812abc8fbe84c907533e6f68a224ad68f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 47400000000, + "fee": 0, + "recipientId": "AGkeeXQM5NjSMk5FwGs4wsVET2TojDJRgh", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210092e1610b6e99829aa9a149a92fb3117ea73ee1f0c7c2b7cea099b55769870de6022017ec1216d66d1c8f7546d9c5e2db23b95f033313d2aa8e1e4f9762cc74036dc4", + "id": "4d07eac2ace1a2cd2579dcd8b0de07d6dde9c3145a2d09ab7580f8ded1531def", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 47400000000, + "fee": 0, + "recipientId": "AHGo9dHkARtM2E2kqb8oVi9VMGZduFNFGT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b022f6e3c9b494d8c11e12c2014cb078876469c3ce2cf74ce1d2448cb7f813190220012990c9b719f8e80e69108a6e9e0501d7094cf47a0daa1df32f08c2cf29130b", + "id": "143256c98cf7c47331065de6db5e8e328680aa78a35a9b7c4038055a6a416961", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 47400000000, + "fee": 0, + "recipientId": "AVZugZBjYSTPC9ik4rB6RknCnjzWPBdP84", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205d010fa7f4e16cdd80da7f18052eb197794173f661abd51d5b8d3a377a88d853022021f3f75f96a21cd8e3c694b1635a286febb72427c1d7983d52d6dc20a79c3576", + "id": "058cd4a632a73218954a3b9dd18a5b21395ea99bffe9504be2c111e7b5df1628", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 47400000000, + "fee": 0, + "recipientId": "AVp8x3mBHzs7fpvPfpUyeE8WMPdtX5CK63", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c0b5dd428920c1f5148e1282ff66c13b845990b6bb31f497381dd060e8c6c0d50220756750f9565df70437787347c15c60cb5d71677b21c9ce6a7c8bb5e9b786b4df", + "id": "6a3a8a2adc4c7c5cee98d56b69f581b32dddf7da323eddec1bcff013841bded5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 47400000000, + "fee": 0, + "recipientId": "AbgCof5QkxSrpZNJGYsiepZuAEwPxhxT2T", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022063f69a740c7ea719eb624fcb71fee6b497a159b101f0f3b8f06e90791b7f508b0220710ebc92317ab726b2824684d51ae758059efa7c16b7ec78d38d45a4e7d6124e", + "id": "e5458cc7aff8e0bd8e2804a68822a783c48db482295997d53939305186376ea0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 47400000000, + "fee": 0, + "recipientId": "AJZtruVwKAPj1rv3ahcF3Z9GTXGcN9oc7K", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204849a42fc02fb6473c4a79a0c2c9ad9facda13ad294495b9b2786b38745b7f3c022070dbe71e4555efe7fa244a3cca10bf07744bbd0ff280b83676a2a2e188f44825", + "id": "3ee0be7406fb23f3ba38c0eb96698b168c043afeaa6fd918949e0ec7c90cc3d6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 47400000000, + "fee": 0, + "recipientId": "AJgvboi25qWyEgoZrqqWo39kPGaPVbrbki", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203c936c24a2e3490bfa4743b369ed09f12ed8dccefa55836551ba3c666febb58a0220586eac237dc31060f71bd86a893b78a578b76f2970b8f57ff31c31132b9f1008", + "id": "14de30e7e1bfc74127cca71e59bfc74a03b9b2f714837b4812a7e149cfef20d8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 47400000000, + "fee": 0, + "recipientId": "AU5SUAATEwfHjAtQDkGFXVPL8Vh4k6sNtN", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022049a821648ea42ce2c2d1d02c5c97d7a8964060bdf2e4028954528dd843faa00e02203e800a96beedff49f634ed9da667ff419bc8c9c582bccd0297c31006683056a6", + "id": "f41fed485ef003ccbd228edaec88d8087731e0005616a600dcdf94c67e72f0a6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 47400000000, + "fee": 0, + "recipientId": "AT6sBJKYptsn7csAsQSzrKuHeDNv7GkTSv", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200b60f4bf416eef8e104234eaeb92ebe80647bd5afa15953cb446fa06da0b169c02204dad39f650f29de7c6867453c4121a868a2e24b12443d5c7722c4b2465443015", + "id": "17a5a7826eb0676195d33e12b63705cf50846a4db052199cc330156a67607c55", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 48367953807, + "fee": 0, + "recipientId": "APcpfWW8rMcGe9gmiFmZZ6qfeYBtwneDP8", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100879fa90ae6b2d4c759e4ce307f0a1cd87980bce956d431fda9003f00ceffa6a4022054c7765423a5f512d1631d3ffa077d717d943298e5fb8cde08908a0a7c9b8267", + "id": "4a6b80c0f1feff81fd4450558c0da1528879ac2db42362ac7fe3b65f4fa52201", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 48500000000, + "fee": 0, + "recipientId": "ALKpxaTevuYjZYSXvTYav47Nj8jQaWSNqf", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201c5a1709172473523d605e4a21c02f3350df6bd9cc3c0951f20e8e2d13151f95022047b2993d4fe88e1e7d079de95f342202c45813aa0f1a6d17289b71022c03d512", + "id": "fc415685bb6fd5876d5ad3c492ce4696004aefe8995874b6b1f1dd0d5571ec52", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 48500000000, + "fee": 0, + "recipientId": "AH2ZufhZhdDsHWsY6qBbrdp9AwH1rF1kes", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207d9dba6ca6da8f7e49f6d2654d0a02cf36beaee6da12fe5e5470582e4d9ea28102202de0debfc82f03488b867493316c18949aba7ce6788b8e6b583b26f7d9335792", + "id": "22a3ad155d12e9679a0af1d5e8384417828eec2b9fc36cbae2785464b12b372d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 48500000000, + "fee": 0, + "recipientId": "AG2RijifYGo36FXJN2Noxq6hM1JEvX4Xxh", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100cc3629e0cfb25047f615976b40ebaec5d3048f34eec4739e4dfbff8537122a9d022034f893414c942792e86a25e64494c4fa92e72d2252236a2506d26ec1e6d64d41", + "id": "ce7f905a90772e79f6e7b54ecbff92625073fae404abce4af59244ac361b411a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 48500000000, + "fee": 0, + "recipientId": "AZcoh7wHpN3Ex7ijGMrdMRTF77i4sMEgiP", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ce4ea4644dce81416d60ad4de4ce33c7c389b6c6cb53f06cc3bd2c5f60a08e7302200dce4ca71921b485fc37eec0326bceae9c7345af73e16036a195d024c97644e5", + "id": "46016076914aa928d354260f80e77a6cee67c75a0fc754eb8c84c0278c8c5562", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 48500000000, + "fee": 0, + "recipientId": "AYnAUcC8xE7EXKouH467mTCiubcpbgQj1A", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201697eb4f8560bb074f208bc71be81f1308a275967f9af4931066f61c9f56912602204bd8f4577f71c2f5133295cf6d9f9cc54deb0d8c370fd8e1c100cbc8a192ec62", + "id": "37b6ab528f70a015c24f1d9532cee172e1ac7e24167b199de6afe74bec419b9e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 48500000000, + "fee": 0, + "recipientId": "AUYW8cN8SXecVeBLmTZrr4XGPL4MEbGz4o", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206a44108ed5a88f05d1de5932518d0c4f473ff9b85952ec7f168b7f013ccea9ac02205c0cdb66e19f9c4766eeae55d554af8e18954f88c008621eeaf4bbaada341df4", + "id": "9b7ce4722d40f509d67a01d676ea46ab007b7c3250e70cf450c0d4152c861356", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 48500000000, + "fee": 0, + "recipientId": "AHoMsGebVZJMkwd722t3SNQtz8kxbsK2j3", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a6ccd3bc952f8e17fe373625a22692d035ce466241cdb96e5412246c4288bd6602200c55d0122b0e09a7b98df0940538ab3308937637b03640ece423228eaf724964", + "id": "abb9425699d86129a675ebe33f6021ccfe0423fb2ee919030cd44856e29ae0d1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 48500000000, + "fee": 0, + "recipientId": "ARRMnpJsXLabK1nWxQqm3R1WKiY9ZyZxtn", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008b4c4f04e3234f263978b73e510bff42e7eecbccc61bdddc82c906434bd2665f022061480eeade9e85307b62121241c7dfad53168a851d5a3e141c460bac0c78fb80", + "id": "6c644f623c504fd6449dec1ece024fa5026b86d13896bd6466912ae6f8487011", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 48500000000, + "fee": 0, + "recipientId": "AV6ffXNFhte61rxqLoCuWVTs3ufuJ7Z8jW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200db348a71ec10ef1fe1498daf3c292411ce01e1f524cfbdbee6f2a9e86959ef002204bbbbf2e508f461a134a6acc333ab4c817c9e2c791baca36d1f235a30320b11d", + "id": "cdc3bf330b78fc143c82058b0674465da2b2e840270869d05a42c2d3eac7ac7b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 48500000000, + "fee": 0, + "recipientId": "APhVjG9pJj2YpG3A7rh9gApT2oFf1HHdbA", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009609b469e7ced5253be188cc3ccf069e155894e715ca8ce9b402c024ae62577a02204b6887fa2ff4881d0e539d66ddd8649783bf4aea3cae68aa5bacb0cdd1e5a106", + "id": "bafdf9d4628983cf25b0f411f0c957ebe6565d01dc043d5f79877d6503749b62", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 48500000000, + "fee": 0, + "recipientId": "AVa7ZKfPSMcnZn5b43m9Z17dLYAkKPepSC", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fbc0bd9719f34d1e39ab2c3eba2ae9b20434d4ed9550d745eba0a176c45abfae0220261f68db9cdbbd41ab3df574ffa1a7e5d07d94917bf3455f0348f2a8c86f33a4", + "id": "cae63006ef7dbc6d4bbb8c0f8b2f0c1821292a53c3720046d2f3e5aa9b18df74", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 48500000000, + "fee": 0, + "recipientId": "APJyeTaF5E619fNpruHNDppitroDorHt5a", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203a37ab7e59a3bebbcf9b1d55aa629f5eda60d60330c43ba2ba1c23c43783ac7702202e75368241dbcdf204a3d9e415f8fe755fd8e60c8c45454de3104e9212a9a56a", + "id": "22399be7427eedf993b9bda222c461f4daac136d9ae48988f073bd31d34d9c45", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 48500000000, + "fee": 0, + "recipientId": "AbWDXPoVRcHmUQ3KW4ZWeuD2mrPYfhodtr", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b245491f63892ba07fa18e5c6f0d3dd50c141bf978094934d32aca1efd8c6bbe0220625ad4d01d27ecc58c643353396093c12c9ee5f617e8a7bab48f590b4e0e92d9", + "id": "e7b6647114488172d1c18263e301818829f4ad9185cae8bed3622cfcc2c001d2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 48500000000, + "fee": 0, + "recipientId": "AUeBAB7qtntRpSt6GtXZXcVNeVkhuS2RRm", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206013142ca9cf760ad5f77a3f946e8cd39a254ba8d4b2424489e01897edd3cabc022050457ebaa39e2b84e773ffee063526ead54194a86281dc21492e3fb0188ece93", + "id": "b9d8c7f12cd758e451a70df541351b3f19dd2f2c5516f7a62629e04227d1d4e8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 48500000000, + "fee": 0, + "recipientId": "AMKTHeQDsTHWw3QeSRLAW2kWQnBrfrqKHV", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f6fae8c2f2fe7da5e0690c8b030e7ce4d7f49ed238d182c0bcd554e3c8daf1660220065e1ec76e1db8fc24fc360e04ed3a04782c04e29a9248597aa0974a67825937", + "id": "afaa4c75e302dfef1e9d36c63929decf4dfd7d8d1e8ec8f980bfb6459767ff76", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 48500000000, + "fee": 0, + "recipientId": "AJT7v8APQuYDV3uDJWsAFGBze9XDKpXdNt", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022043653b6aacf91675ba1ea798f0ef37e7fb265811ae4a52130959e57d4d90091f02202b046afa7f108d0d1e2a377246e9aa295531e053c359385c1406eae8ca9dc4ab", + "id": "3917c81dff0713611f02f1427a92b63d26058577ec5f16eade5bc5f313f8861a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 48500000000, + "fee": 0, + "recipientId": "AGuBeT5rVgCETkMTTAUc94Yzx788X9fiqH", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f17d6e2720d978efea176cbc85f9e5c472882df3f6886172c5fc94b8c207b1f5022049fd7c95a425608177ca111b78b6666829d6644a03c324d033de3d003f2a70dc", + "id": "6094c25254da89c6e8d08fb7c97e255448331fd054f3aeb2a7a239f4cab5c43b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 48500000000, + "fee": 0, + "recipientId": "AVvE9v9QyJvBPZK2kgMDwJxDMu1UEYvYRx", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022019dbbb234bdb03d4652206e72bf2294f4d5e18112b86e1e52e29d0419369e55f02202be9a176cec5b00ad3cb40900080100b8c3b15a0827ae5132e4004f22f820895", + "id": "06df438d747a1cad820cde398e0198333f4389c12faeba195c0abb7fd4d92350", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 49717819332, + "fee": 0, + "recipientId": "AKFLHqUXHQSV8qchdjbm1jUYPptVatZyQy", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100929159e14809ac7f07724a097962ed91909fae24bf045e51c74f5f212e2a4654022053ad7d90be5cd253e8fe175267b45453d5af2738f6478d611869ec5e4b124e46", + "id": "c57dfb4a2801c1ad9868dd2e14eca2115928f013ee8713e068ab670171e66abd", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 50011925828, + "fee": 0, + "recipientId": "AYTJNTk88MySw2YRJxb24XQrHr8fYe3SFf", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207a665bd64a6becf19aaaa99468984ce4e5e74cdea92ab4ff565d8d202319ba7c02201aad01d9484f0ec40e02fac399570338ff66cb5b8a84748ba1cffa0bef41fd3a", + "id": "89079a73bd4806bcf928c52bec954e11ec3de186a4caf4d1bc8f21a430373c88", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 51012164344, + "fee": 0, + "recipientId": "ASm2ZsSj9W7jmYCDdLi8Eh9RwLQALkH1T9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100cecb5a11966ec1d395eb2eead1ebf4d9c41f7a2e65d94bece07d8175fdb20125022062b79536de24c87d93ace4791643d62e2af941cba4aa457b776bc12524cdc0dd", + "id": "199a36b4f6be8326483599431afdc07c424c761826e5dc915103ab677d97112f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 51523164985, + "fee": 0, + "recipientId": "AYXPcxBW4EiZ3hav9w8qPnYCfMC7UiHUFc", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205006932929f7e0fcdfa814063682fa9576cd197d2ba944a52244d8ac573701620220540b8abb5d72775ef6fa039984fe4fb068fcbb11622715947e0bf43b00dcda85", + "id": "5af79acec8a2ca26ae1ef4a4bb4c36c9d756f4627407b9831dc1aefce88d41d1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 51527438731, + "fee": 0, + "recipientId": "AN8fTyWTGzGMWndi86xLuPZ6sx5RqDU3V8", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c86ad1039fbbf4dbf38750f6933eb94de081730aa4bbbab2e69fbf6bffd86994022065cb206c7a6da6a2cc49564fbdbfd861c2d7a43ae574a9152ca743ccef38883a", + "id": "0e875f8909e934d95123c4e39b0dff610726bf4cc793ff32ac3ab87607a869c0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 51527438731, + "fee": 0, + "recipientId": "AcoxZHkmsepyWCs2K77TaAAuKXzYFRhQCF", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a556f84c6f3ab557c61a3f103d5a19f967a624bc247905e6433206d17b05979702202bda3ea0fe77b2217dfef8a79921a4169a421451eb08f31350667e8253eacce2", + "id": "baf5b1d34f909d2ef94d82896e8354fb10d59464743e95174fdaf41f5816d986", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 52000000000, + "fee": 0, + "recipientId": "ANx31923yoBut3ToXoPugKPnzgRhRGELPX", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008e91db1c38a78379d51739c8e7c5bba7c7e10423f90d975a83ae8fcd5073e08a022025c8927e171c351598b0ef39f93c2bc2eb2bc86eccd43b5b8c9f6bca681edc97", + "id": "6e86383cbfbcf26c0268180644f7a946325559b282acd1b4166d1edc55271951", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 52000000000, + "fee": 0, + "recipientId": "AN1XZJrPk8cm7Vwf1ZTrKrZtCCLZgkyrJ1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205e39a2dfce53486be7370d92d65ccbf412e079c07e0405d68fecab4f1e17371e0220438de48ce7ef76a2bb2b65bb9e2013eb1790f1c9b26d2037138ba4796315611e", + "id": "6cd2b5fb62f45dfcff3337b52bc1f4750761e88df28c5d02acfecea7cd0164d0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 52000000000, + "fee": 0, + "recipientId": "ATGUpBz7YkxB86G86796U5yTEgyK5u4rJk", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202a418c3135e189187865442f8ffd4cfcd5469eb1858ceb9add3bd0810ea37a4a02204744e68ce981a9d4bbc54c992382dacd14b47458873da4488e3995f206b09db1", + "id": "722201637e0a6c263a9a2094f2ca0adda2d8b69f44a6f15e4d29a53a93cb2985", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 52000000000, + "fee": 0, + "recipientId": "AGyRgpaEFZ2ZnNHL9Kr5bpMGkv5LUWebQb", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207f5ce9d7c0055100d09575738ccde05ba74dfe3db8bdf4d8a30d0bcd6b99592b02205a0f50872db6a29e0f0bab2c687c44077f9be26558b022dd74b3e2275cb6b853", + "id": "33f843ae2198e8310d2055803607fac2d24907bf8f8daa2f7290967e81672e14", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 52000000000, + "fee": 0, + "recipientId": "AT3g4LwnJfZoN4vuFLtMJY9Wxq2uMtLuxT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022059078b6b0dcb5203a2c3ba3a46bef4d723a63ecd6fd3a2e3ad29f67b50fcac1c02206994e842c8011c3de756e762b831e9b1aa12d8df872d5838ff98d53aeec95e2d", + "id": "f5ed89f77f37b64aae398ba0e89fb520081aac2ef2ffb2aec87c42bf29a719a4", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 52285195184, + "fee": 0, + "recipientId": "AdJLdk5Vkejk95ah4j3ZRcEWu34E1Q7wVN", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022056d42be934431202be893e9d5e6d640d2d9f5acab7aac3bc40017654ee6688a902201f407d488855a6208aeaf3068f109a0b5de4abdfc4233e8bfbbb89ca3e33847d", + "id": "4912aebc2a0e8081a4761cdf85238d17a27277193389698d25200c3259116728", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 52325513889, + "fee": 0, + "recipientId": "AJE5ptbRLg4SGn7DQcaLChpuzjEo66WTDg", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fa8e197adcd0a62c4e79017cea097a9e22a2301be0ab22fb3b5466846bb78575022044a063dd5987a6e91f6ebc4858754ca6f7e7fefcf53bbd3e1e08e20c3f7e14db", + "id": "58aee6b0df8cea2a4fb9ec25402b3440a8e5076890a8cba8a9ccef0ca5b52148", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 52512522119, + "fee": 0, + "recipientId": "AR57nJGjbRknsTMoDJVPnKjeH7H8pQ4J3e", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fb7872a819b54bbc0b30dcf4d8c3e413c84278d631628dca3a6805ec1231e210022002c76cc1e9b7672ad3f0a1db859e4b36564f7f815e494c5f9b1d601b6081e8db", + "id": "3f54c13b225a0c71692660cc5cc0910fedd163ff1aada08cff0b6216df414f4f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 54692496501, + "fee": 0, + "recipientId": "AH1HPESny9sMqiJz1ySzoonvcgVLPNTVY8", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204b168552ce3f30befaf9a566986b6c17f67471fa0cc2ea308acf7e580586d58f022017a5a0173699a7a5440f82dabea25270637d7167372d9aa71ec62b09e4c1860e", + "id": "b1ac5258577f86365c9c532150696897e0f5b304fc755657e4166b7f784adf79", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 56071540498, + "fee": 0, + "recipientId": "AY4gFPmvcG2GfTcVE25mqeDmnDQMPcWndc", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203b1848de0b3be4cccfef6ff105581675c01006ec69da4492815ed63c194338f30220377f301d3fffb2a88f7ed13d42e2231cc5984f63775f082e3c85e02b37c1743d", + "id": "e1154407af38c6fbb875feb1badaeb5cd8262821b3b1b1a441cf506aaec41d4c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 57049922288, + "fee": 0, + "recipientId": "AQbcTN3TDRc57j6fpwAvLjxsc9FeAJThp5", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100dbc5ba06661abfcadade917512e640a45ba57ff29ca7fd7ef728405e87f8f0cf022016d0bd3ef6c0a88d161096520dcf4673dc2cb8fc96ca7e61095ea5e67465c8b5", + "id": "3fd968cf660e948f9fe340334684579db327ab1d6281ee05a840dd1deb0e4b7f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 57589490347, + "fee": 0, + "recipientId": "AZDQwckNFvu5RL2gP6x5SfNFtzSk91tPTQ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e3824a2385b1f4133877047b7d5e702d269c82e64bf96196f526a063047d97120220327dfbafefca990f871ed25bcbad0bb7308279930468676e84c54d701890ee15", + "id": "d1d7712844a3898546271abe9b6c0d139b3d322f436d26d7805caa0a34e1f8e3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 58900000000, + "fee": 0, + "recipientId": "AZe1BULQ52K9W8Pm2oz7WnS8EFsHSmtcGa", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100cef7f753f6cbce6fc6513cbbeffb4fed56e32f0f6632d87f4471d59841a8af2c022036f7202c8e437be380ecedf8f1930d38fada608900e93d33334ea8815c4ada2b", + "id": "00acf4f97b4d6baf38f7a16619a7bfb62d93a96cd30f5bb081fa15099dbaadfa", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 60000000000, + "fee": 0, + "recipientId": "AFuQS4a6wysBSmZJpMXq4xDNAetJJBAFsQ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d8865a56a63f070cbf21dc8e48685ecd862077ee52ccd2c8cd8f40be72c3c4d3022057b11b12e968dd5e87df9da6928c6028a131b59bda09ee07a204dfbb9a055844", + "id": "d3ac3ea41460fd549c79fe3badd7a80ba4d467869b62b6b4bb342d8db1570efe", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 60000000000, + "fee": 0, + "recipientId": "AeWauSzsoZ2FXZwP7GFX92pPLyJMSkSKph", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204531943ac76998e7bb5987455c901b6174d603114ebf915775590c8315653896022001eaa07b36c01e93b07c66aa139cf299ebf25ae16431eb85611dfb9cea9c09a1", + "id": "c6719c892816ee2bdd2c113614cbbd92a59de7b54b3a4c17de68c0da22256d3e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 60000000000, + "fee": 0, + "recipientId": "AMmqT7w7oXLazLwQcSV7WHnYx9S7KSXixq", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200e9b8f5aa7d2471eb1981ce5482230a2c2fd1bbcc6db017f6a1ddee9e4e90eb202201ec640c890050eac7108f74d40f010d1e7d5f9bb05f2fd17eb5d8fe385080342", + "id": "7d269a6a5a9c507c1637707448d5fa61324f9394471fde06b0b53bbd51b0cac3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 60000000000, + "fee": 0, + "recipientId": "AXdGv5eEBNGK5UTcRaFHbW3FwEiXifcegt", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fd07c0502e712b804344fdc118b52e2bd1f9082c52aaa6a87141f4e46d42107c0220718a1a7d58f887e544c92404b49824154352139fbe33eddb5a7dd5e4ef88d7ad", + "id": "f0425c83dd9d9eaae6158673566fc41a1d4dce9304fc82703c97463b4f93db7c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 60000000000, + "fee": 0, + "recipientId": "AYA5LBnUiYXCraG1jz6XxGe1FbViiJbj7n", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022036479d87611d110554a7fc93c08cc78094a769674379c3630c8a77498626c1b302203712a96621cb8133a43789b7f4c64dc6dec8de903de7c7275582c1fba30007ba", + "id": "2b65f2d5ba1c79f39c61a99642af209df57514ea158bcdd790c637d6287175bd", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 60000000000, + "fee": 0, + "recipientId": "AVf5Nefkn7H2m5ccTY2Gss783w4B2XHrZH", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b3ed017b9c924a513e4175d1ae026e1f6e0cf5062d8abf944a1d456c9b99a3e902206e81a45c621846a3b3975fdbc63e842926e2f0736a8cab98e382fb2027309e09", + "id": "afc6dc49249582cb59fd0ef44d5ef26d40d7a4faf6cec4edea6410396511a57a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 60000000000, + "fee": 0, + "recipientId": "AZmiLVom6XmmQjch8mPaZjzbiZt7xEJ4Ux", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022001981eb483fc7c992ee3b6491fee84e92940df9fe96655b36a451771563a94f002201d0494084a12cf4de2441081cae004067d1d43f802c7c661bd75d0c8882a6d9b", + "id": "c177aef927d06946f2c80cdb33855fc233d0b20a5bc0b70a72d3e1f6076e4e4c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 60000000000, + "fee": 0, + "recipientId": "AUs83fWgyxfn3vFcpr5DLhiNeCrRcrY8YL", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022025c7b0874fc7eba0e23e003d5172490a564e3eed0a504861ce0346e2782a28400220165dc08dcf6720694b67de43258f127630a4d4cddbec8a2f66ec1ddf853d454c", + "id": "6e6193eb69cb0ba573c5545757078fab69cd407c3ab4499ab75985fbf378634b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 60000000000, + "fee": 0, + "recipientId": "Ac2vFD8sqzixk7MaK7JwEYoe2QXEPna1e3", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ee6a0aead5de861b29caaf1c876304bd9792e917a5ceeb1164b69aee6293727002201edad412f00a6efa6148a6a62d7148466f4d24ef343e406b5291688a4270b92b", + "id": "ab0da3b48e067dfbdd94c6bbcac4f3e468946a508735dae2c7cae0ce051e2087", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 60000000000, + "fee": 0, + "recipientId": "AbJSiFHgiy1Gc9dnpnSUgRQVu7cmKUTJFo", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022007df858f6b336a855e06e11bde5f75b4584aa8941a8d61ed54b91ab8a76670ac02205fd2ca83ba0694a6a5ff2e552330616ac9896c319a319dc9998f5c6b57edda65", + "id": "6cbc50accd6cdccae73f205c0bddb4c944bdba76323c5100ba6331f89d16f952", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 60000000000, + "fee": 0, + "recipientId": "AaSvUFxNvGZcvxk9ncd7wnqtMw69qTF2NG", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200ecadd5dc516c178c2d80b3b52caf05720883e07c0b28bef1e0a20f27c0607900220178af5fb06c3327e6b5c6767c848bb2be60e311ed477bd64a56caa6e66dfa13b", + "id": "d1bc92a487e9202d245e42abfb7e37f60e08d0a78a3126624dd0e0783c2a9238", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 60000000000, + "fee": 0, + "recipientId": "ANFpv6FWVyodGiMNwfqBvfNo3tt59q2uwW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022064edc033b3ff422b695196c4a6d3a0bb6b321e467a2771632816d92ad05af9ca02203afca6079f18210a50218dc05956311a77b04c9b5c9f7c960f0f796c436c92fd", + "id": "a3429a6656e132eed4dbb74b2ed17238caf2790187166ecf4af877aa2a7087f5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 60000000000, + "fee": 0, + "recipientId": "Ab9vTWogfBcwA3d9BVdHLZ7RVasLqZ7qwg", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100923954a62e4ab7684af8694637e66839fcff5fc11d54de68b4fa82f7974b313202202d89f173b1c62ab26c6f9210a8cf5b7d12538124c7366c6c1914f8990bdcb272", + "id": "6cb18de69128b7a4c91bfce46d17227f1103f50f0061a9228e2488c58d26d18a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 60000000000, + "fee": 0, + "recipientId": "AGonR6i4nHcvrHN95rsmg25YTgqRm7TBox", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f906a1d22b886f4198c8e6e8729d55f15fbd10761b445f92a2b7748ad4ed0295022018b9fe3b0e95e59d612119d349472090f1a78be9057c754dc17a0c23610247cb", + "id": "4c650df3dca440c5d3f2f17f89fe1000e114a60df15a51190134eac8feb777e0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 60000000000, + "fee": 0, + "recipientId": "AZp6btpTxvxPCWdsJGUqZJCrZMYrS6cCk7", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c8211a6578d9f11108a1fd950260f2e30c15c854c5cbe33af0d6ee329a81bfef02201fa7a8226fee5217097353f9b00c39cd6901e8cd2471cd3d3a34daa56958dc5e", + "id": "9ef08f0bd8beda3e82d6c39147005bdf9590f6df478e87716c5c69942f6e34f5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 60000000000, + "fee": 0, + "recipientId": "AQT6VvbyD8BaVSBtkq2rQJf7ZFxpQMrGFF", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f989f104e83e5091791929078b408a0e6c56d86bb8c9caed517293bb377a92aa02201bd438311e99fac1e31bd4c031ebcb9fe7f05de8a330713be4bd25f5effc2e0e", + "id": "30e10c01d2e0a376ce6deb42cedf146f8a849f9ead0170286e7ae6f5ec14af92", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 60000000000, + "fee": 0, + "recipientId": "AJRzekFXBecN23nD3H17GCvU5ykTqZ9Qu1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100cf8ca12989b34d74df49b7f7db16c5d29d5c94e387890a6dc714628ec737f7c802207eda53f3c1d3f43b62598b1b6efc8de7a4b46ffc069750a90ef294b5a5d49fe8", + "id": "167ef310bcb21341cc2b7c32b1ded135a3223f5322eb438751a5081fd8a61c1e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 60000000000, + "fee": 0, + "recipientId": "ANVX8UQEt8MkJokm35rGPiQbkMD6Kc7KSt", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220723a3f4869ece9ec362b11c309a824ef17ff8287d3a6e2f1046db473bcc0faaa02201618ea49f81bf73c60ee427956afaa75826bf94788d73319c8810ef2c4538427", + "id": "b3734997009c33befcf1d9d3aad7917aed5eed0c4c7de9730ecba54a72db099c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 60600000000, + "fee": 0, + "recipientId": "AVFpsz7LiwhRJmCAq63uMCFBXhXYaMNAq8", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206c018a247cc32e4807e6fdc62fc83cab278d50ec7a4f0f67e26094387793cf7b022014782a31c92672ce921fe86b3b8cf36452e40b360830f47459c3fd8b26cbe5c5", + "id": "072dafcb1b3e774663b9c7be4c1c2054f7c9357e3708b5d61dde8104101026de", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 60600000000, + "fee": 0, + "recipientId": "AZ7M9chTUSjuxSUkWVDyQhAbEDVXbP2ZvA", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207ce6a75041112fe7cc42d42ee0e35cddbcae0f33ba051c425b5d3afc235b691e02206092e7c04965993b38e860019c498968baef52f05160e492c5bcfda86a868e33", + "id": "d728112b0c69a9c9f5a3c1800347aa8f87de5ba5407fb16fed5e1079f9a48ac2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 60600000000, + "fee": 0, + "recipientId": "ALMaBHtP4Ki4epwJut68XMDxYVRXTwhPuU", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022050f867d1d89a62e65a88c9861c6fa93971ea08bd0564d9864a51517244196866022032ba4ba30dcf55cd08834085ddcdd425eceb7cc784f4459e62c11e70f29eed21", + "id": "996aade098c28e002949de9eba9dd663f3d9a29a8042dc516142bd56c91f1b8a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 60600000000, + "fee": 0, + "recipientId": "Aapmg3eAWSv4bWzPYMNUWMx2cULimBsKDT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a76f37bb0e4c4eb508597231f437289107f7f9fd266c31c653c2e10c45d59cfd02202bcf4f912212e7d409bf2a425d73fd9697836a63019a064e6ce2ce8f174987d4", + "id": "544531e7295c7333e4e770a010b73b7584d06751a7d05388f3a523080299f929", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 60600000000, + "fee": 0, + "recipientId": "AZHUEDRF7B1wHT4qcg66t6f6AZpmAwnQzP", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022037ff7edd4d48a58cb2d3aca7cf2b4a6f047b5e0ecf930c6624deec7e6e7ca22102202a038b5e27f88d596acc94687529c4700fffa41e907a34118e4867c012083b2f", + "id": "ce8ac13ef4d89b3c3e9cb359a4e5ecd8ece85313dd6ed08e247995fa12ae92af", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 60600000000, + "fee": 0, + "recipientId": "ALMjKKEK2z3hLUY3XubSxkAhzdpU5i8jsL", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203589acf0d84cf3f231ae931522af87cd17ba02138f1b5fbaf71b1ee6f530451702204881f4bef7736594e5cb28e5fdac8bfadb467fc853c58ca7f59e55e7a7b121bf", + "id": "2988196f5d08ebe98c6bb9de0830e0675c85fbafb60a2ab7168a633360c112d1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 60620516154, + "fee": 0, + "recipientId": "AWFzsKF4dALGbqzQgR81VbFBDdTSUJCBNU", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210083abf4d927d402f0aec00e8c37e661e8be625b8ba47b3fe3d604500c358f88d30220645351b976be790dfeec71082328756d3610e33e57cb8b396657c69fff96feb5", + "id": "a68385459023327d26fa0e745c0891a34789bc3db0392294cee99cf1ddc1b190", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 62300000000, + "fee": 0, + "recipientId": "AGikMwhSBsgXuwCUZsv3EAkxeYSsHCRany", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022014e9a28ad7815e15bef49340133ef40a0ec92d8dfa80c125eb0c26e3d47ca96a02204a8ee6d3f847fadd1ccbf50e54d4a1f220ad28125f82cc1e653069761e953331", + "id": "71a75c1380f47a79f47847fcf615e733c9b8e4d44511490729cbc2cf7cb04b3a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 62614203690, + "fee": 0, + "recipientId": "Acu59K3HbqucEtsNMMLzogU4tFJxmuJkCc", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202448a56483a3ce4580734e2734c1cda29fec792689854f77a3bd2aeeb4b395be02206b17cca51c241b725a9f41d7a7d15e308f0f94f33480fbdea4f4ca2c99d01482", + "id": "d71afbccce8620d94b04bc74c40038eca31034383a296570c0b3181b00433bd0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 62821647096, + "fee": 0, + "recipientId": "AGg3tZ3u4gE8mSM68gmeEiQnjARwUpT2n9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022011162de5da032f0a5e15596ee983ac470d62876eb2e8348cd015eccfa0b9831102207c6b60bae672fd6e593b3f5040733dde21c7ed75741a85faff759d97f8a5e27b", + "id": "ec44a065625a762aed0e093f485104dd5cca3e4d73fae79d6ead07ee6bc4704a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 63651541963, + "fee": 0, + "recipientId": "AQEsgEhmEBzGLwtXeDzYacpgHFdmZzgxBD", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210099bf9fcf91b0efffd75888770663c351f6e8158fbaec8ea99fe43382e31ad5230220575000d242528aa103ac912daf6117cb4ffabdd867fccdcf847b46d6e46c0a12", + "id": "130c08efd433f91433f3170cd7bc85b484d2c3e3c53134c0d955932726bc5338", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 64100000000, + "fee": 0, + "recipientId": "AL3BcBwg6R2PZ9pmnYe6wzeY9xr2E4Rhdi", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220684f309ec0d8e34d82365c29e7ea21a08e4d044bf5a96e17f692ea4320ad12210220155cd1bce15cfb31d60d097fadfd6aec6bdd14f65c079039d9432ec9c7ab91ce", + "id": "22372757608284b2b88a6c068c4dc994ca37684d765c14f5be0bdb48ad50e968", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 64100000000, + "fee": 0, + "recipientId": "AbpU1DmufxiTYMDQrbKjeKumxoVPwKyczD", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202f40051c81e2bf95bff6cc78fcf9cab2b999d48ebd9b6524b593c95441902d9e0220347c380e7fbbdbe5dd4ea8492a5deb17835b48ac22f388c2b519fd4103fff0fc", + "id": "8726a184e737d57567c17b077a424fb7ac9fe5b0cc9acf509e3af87baf5167e4", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 64700000000, + "fee": 0, + "recipientId": "AR51dQ3b2iPD7kxY6Jr2f8nvG9V1Tp4bXn", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e701b0a5ae50d35cc985776be08a2af2a1189df4a7dd2bbaaf7b182ff5fe5ebd0220123def90996bfddd4c0769746130d4e13a8150d75e32770b6fc2024cad56e80a", + "id": "9f890472facb44d3f0fc91cc3100f33ff80a0ca419d6654479c0ad2e1867401e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 66023125672, + "fee": 0, + "recipientId": "ALMVkKVthbGLSyCAu99UXPTcJUCgycJCio", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204c190c4ae5a7885bdefb89112f08f782934fcd60fa2fcc0ffb5a57fc25589f0702206c086bd249bceabc559d1bce46a35687963c7af245e982b83bcb4679d27f048b", + "id": "f0db655b4c6a0cce96585893a9ae0b5834629b471c8a10bae2d03ba7b59a86a2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 66682567770, + "fee": 0, + "recipientId": "ALVWWv96ePvZpsr2LJiYkgczjp5HFh2vS6", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d4223e4d6d86f362b5d9bbcf4887e3b4a7905504509d7cba066761e5ab4f2eee022053f2f8f1e12ea2c979c1ff532d2529577ee1d5128e4863e4b88081fe4223074f", + "id": "e49671791471089e19114260ecf0d0410571a828831fc693900129992cbdcd32", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 66985670351, + "fee": 0, + "recipientId": "AK5aMpBxSFkveYCPLK7655BNCYxE2oDWTj", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022030059d3cb8c99259e250803496094fcbdf5c644a54be5de71ed67579c50dfe7c0220551dc20a9ea8fab2756d945ba96b6df226f786f1517ba500808990535517540a", + "id": "1ab441b67ca4f041fd0b4de0ee084f47808fc41327afbf0db652ec6e8eb0293d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 67500000000, + "fee": 0, + "recipientId": "AZiCsJNur5AHuBmzXFm8hrvzMtxaXeBmTP", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100819f9e25f210711c95d4f5bfda34f90c4cac0d2ee7fc788867059cc8437153a302202f94cd63aa4e59b051dc69a1acf46cd905be00b8547d377f705f6f63b3a61119", + "id": "373da2f2c548fb4f41d36f7b39aed883804bc453846bf42ad223c7dc22f65903", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 67922251265, + "fee": 0, + "recipientId": "AaVsZhcJWbpsrwHFYQ6Ms7dwRamLQGbiEQ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fadc2d82b1e12c7ade65115d3d2a80c59be0570cdcecba6b6d46500de0b1723f022027b16d7f88841422575354d423d0cde46edd1ff3dbfe77cec29aa3cce7ddb61b", + "id": "b6cebe893f177fac2b32bb805b3a8b6ef79dcf42d7e7e1e367da46fec3c6e659", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 68047923959, + "fee": 0, + "recipientId": "AcfGpnqyxHTTCg9qGGDNoJZxp9gP3RZJEs", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220056ebdfcf97cd26c4f1ddb8d2dc2eda872aa41c72122dbf4b1fb7dfe6a13a566022066e8ea897d1845fe11262d60550d930d4ec0be1408c874ae05b6705838499ee4", + "id": "636db58a8c9e586a4eb157c7b2be73af3edae8b5ff48248933970e06cc14ed67", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 69300000000, + "fee": 0, + "recipientId": "AdReKteT3KZV3nxYeaUwbxuvNu4Tbux8QV", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220045e674e2020858cb6db65016b0721094b18d69d5c40b21e420eaca23c7e5e530220581f3f511f5ac357d3dd730ebf0e6084d62a9aeb356d1317463799444ed3a327", + "id": "194bef1b8604a0d86e0dce346149d9a67dec990def05321fa4ca2f5d857a3b45", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 69300000000, + "fee": 0, + "recipientId": "ATBhoLR6mCACu9T9iHcvPmXBbeabR9o2Af", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fe79b98c6ac6eea23af36c1cbea5f5ce104ab7e8cadad9905bc86c36555e552f022050dc6c3a5334e5efaed6f072a584319c51dfda211522d9424561e0d48bf5d7d7", + "id": "bc5c5cbfbacf7ca885544dd956d82dd4a99d3d9a9b922124556711c35aeaef1f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 69300000000, + "fee": 0, + "recipientId": "AULwd36ELPQHp3MBCVjQPGsG5vLbWDwsX5", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220730f890799382a99a6082648a97e89117ee5ea2cf79405ddbf726c8732a48a9a02204791eb8cad7f9b987dbd4865a507c87d446b502f4faa5b469ef938be043e034f", + "id": "8de5f8c57d06f1a26d57f2b30e1a6de70c1f4181b5c7a5ac46d4d77d4aa0d1d0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 69300000000, + "fee": 0, + "recipientId": "ASWtE77ekytMEB82Snx3iZeyECBwcyYAGU", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009e5a8e6261a7c50f8cc6afeaaf51cf433a55a2ef85545823811c2bbca752046402204d879e4ff9709ac18288c75ff6b2d0bf210d4466a7c46d82d688727b3a49eaa9", + "id": "a0d0bd4e4470ad7708a1b6a8d8c26c5ac9de239b8e15a581cf2a29699648f944", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 69300000000, + "fee": 0, + "recipientId": "AMWKeZaKAZgtvX3McGVZGVCjR519mjdxod", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e910ea19a113d2fe010320fba9848358135d3989f92c328a59d9611e1382a2c902205e83c177d11dd68147d97a9536fb8657b18121c69e3257034a101c7c928d4cc9", + "id": "622e1654011fa90a79be805a43dcd875b0d649c5e5d455285c2103430f5329f7", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 69300000000, + "fee": 0, + "recipientId": "AMP3grMYVWSxx5g7KdRf84PjvT3f9NDiZ4", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100acbdeee8bdd4dc28809d30dfeff20965f48211675bddf7bed7a105a6e04092e202202c61fa35cc87ab1b02a8530b0021a8d05d2d20f34520637c9e17f60e603ac2b1", + "id": "9ade4fb6bd9dec55103ea68751040bb6cadbdb7f7518442327d72599dff0ec36", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 69300000000, + "fee": 0, + "recipientId": "APyUPnRwawq7LHHQbuLVwEVvviUS9gYvqf", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210082e9e6dc9eccb3d40725cd5434128ebb94f56d47bb864d879a79cf6a6d7d92e6022020e76a058819f2d1afb709d1262835bd3571112422f885d1bb5dab06900a41dc", + "id": "961478ef66c79ff2bfe8f9c1f7f530c1111e998ab0f36386ae9b5d6a27fe2875", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 69300000000, + "fee": 0, + "recipientId": "AaygtE13tPoD7HTNBJiJQ2McDRxVaWdJYw", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ef82c8eb76122d5557befd50e52d7c297ba3ec741cfc050fee3a1ca10d3bd01a02205b199789061011b890a09029642750b784f53a174082d8e113a43083fce2cd24", + "id": "5291bc37168adc5497986964e7f44a553aa5007143cb056be070857b285cdb0a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 69300000000, + "fee": 0, + "recipientId": "AamfrghtYBbWkQtRV7vohTfrJCPv8Sg15f", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220757f338c7cfd2ba9342a5246b2c20ab46c2fab13d8b8475f748ae596d721afd702207dd4f45e4a0562765392b4041a812f3caba35985ec8b0a27f59af91063ca0ff4", + "id": "49f82d3d4360a92c509afd96a16e76adb8cee98b82b17c9ef0d8403a7d933b8b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 71253891180, + "fee": 0, + "recipientId": "AHcjnPJA9tdupQcjcJMLtD6nnWJ9e6KFQs", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009ac53ee5d6f50ae5eb6021aae45b59f77ff49b259a42bb7b072d1c9506c0063602203238177cd22e6d418db707699b4051639c4c530283d13a02c8c9ebef4fe9b4e9", + "id": "04069fc9bc169922314401d138568a956bfe70d8f3658a5fc456c33ca10ad67f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 71429604399, + "fee": 0, + "recipientId": "AYFJQE3EPeSkuxEa4PubKaS4eVitUtZkiR", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200add47cd5990fcd49c559868724063fc58cbdffe8c79aa958a7ecbc75a603bf7022017f022de0655cd62e383d4b7d9d4a4a074b8222ae7c1bd6cf26716c1292bb3ad", + "id": "06ed48da4f8bfc579c4ef2298b43745eb77529889ece543daaaf68ff2bdbb9b3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 71590501751, + "fee": 0, + "recipientId": "AMP1K45yauAQU1c2NqwuUu6ekCmBqtaPoP", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022014db9f5d0e46fd745c970ca39b54ce13f245ddff480e7abd19b318c262f3b951022062ca17464681bdfc5381876ebeb66740f14ea227007c34a4dfb1fe0946c6e2ce", + "id": "34598c7779c1aff18a82cfb53f52f7cd9baf51bf2fd9eb2d8088f38e9de615e2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 71600000000, + "fee": 0, + "recipientId": "AQRhAZwfV8rwCvsb4WM1bVTbenugJn3c8r", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206b2f68e67bc4218888b389cadfca07d954a4388635974d1c4872819d9fb4305402201dfaa7ca2e83c0694ab80505ac5282ca28ae45970161acb774b38d87efaaff22", + "id": "e9a1f1079b09dbc72a80b56de6c65f7414455d7d569c6ef55540286c6e6cebce", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 72653688612, + "fee": 0, + "recipientId": "ATBxkNfkzM8NBxdCsJ44RdABoATkD98qdR", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ca29827b5530b9846ee5a9084d75a067fbd9a932073e731af57c460bc403b5210220487342cde09bc5c339223b575a8a4c325098202707c68d09e0ed48bffdf72f1e", + "id": "11ecc7e569168d579cb6273ce6d27f58f29fd4db7c2897082d6e49cc6a9bbf8d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 72700000000, + "fee": 0, + "recipientId": "AW5d3EEDJBQnKFHkPJnKPTinSivnBzUYkB", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204e68f134e251d796c0c4044c61881a7e49f260d17aef7fd2f4d54010d9fdf52d02203dd02402d012f4d91946dcb449f95d61d874e02ca02ef4bc2c36f7d4eb5b4547", + "id": "f38d068010566f2d81f972525779b84f6e8693880ef6251b6a63153a2e98d9ad", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 72700000000, + "fee": 0, + "recipientId": "AMYvEFsHMcctwEmRrghWE46Jj9kWbFPA3A", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a593780b9925611723664234d85ffde90f314afb68d45e4a0fccb00d40c1bef302200ddaf8f1677d988f24302a388e71d069149437822d9c7d2330fa037f96770110", + "id": "b1d8f7741c54407d505bcefc467f1daab79772ff77e71bbd0ef7f8708ae43582", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 72700000000, + "fee": 0, + "recipientId": "AR44YGUBeJXZDQcbUebK7Ds8fVHy7DHjgW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207ac0a6b2a5468d60e9f0290e5ceca35b896db702038309ffae2a410ba25f2b6902205d3643b2569c0b185f2bce2a1539f5a1cb92438a1e6efe3512080712fbf4774b", + "id": "1bb883cf35619f46d4839ebaff381c9ae4e00c3d4cbe981acd00bd98a1c4ab91", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 72700000000, + "fee": 0, + "recipientId": "AM3F4yHDLbzGGqJ9uMCjnPCv8xzoJ872sp", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d6ac3a85f45bd763fa1fa8850dc8fc12978155982c3dbc250a5514d2e4f6081502200d08e59cbb1dd6bd22a7ca8375ae7bde3dc2499367482483b84b5dbf2df4a0f7", + "id": "e46dc48c6353759f1bfd73f83112c808d8a2ebbb687fcd177002f7facc3da944", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 73796297519, + "fee": 0, + "recipientId": "AGcoFdESM7NdWm1HodtJyDU32BHyShDqat", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022071e03ef704b56aef2dc368d7ca2642275dba4b81eb085aef6b8c1fe48307006602200a4354795dd801e4752ca441187d98f25609ac9b58a0ab79d2bdad3659db6ff8", + "id": "71e2650406959057c6503cf336a99c7be97b592eb47e383b03a334bfc3cd5bcd", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 74014667709, + "fee": 0, + "recipientId": "ATkzTWGZPHNhEKCToyULmtTaxSJYNiZRYz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210096a5bada156e5b921023bc5d2e79b9cb6058c2a6b722674c3bc04ff45e2c2d0f02202a804f965b55887303c2f15ef22bdfa0f70639141ab4db6b982832b76e5111d8", + "id": "ebab1e0dc5d5a02577ba83b3bcb0641722dfd2f08acde9ff14e7f4d5c5415ecf", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 74124099984, + "fee": 0, + "recipientId": "APpwmia2SFKQmhNZq9zxav8aidP5vBBptx", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a4a58e349be3f5d8da0b00d71bc150261f2538a2031e06fc8dcf0df8afcb6865022003308a299af829c6bcad2f9bd36c2648d96eb3a3bb8b0c33e687b33099cd1fb3", + "id": "0dc2b86a4ea26f04660150949d00091900028bb6fef863392f2bb3110e77b498", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 75000000000, + "fee": 0, + "recipientId": "AWshU1zde3iSo4691GzJ1ibHDCqA8n7mGW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207a0ed602d07dca8bbf2b4d9458a0dc70fd92c192c2bd05cc455dab5977be3d48022044f872dff762af785e654198f8342b6083e66e9c0181a16c3c21a1f2423b982a", + "id": "2df19ff6e35c5a76a99a062d893432c27fbc7e98e6d4df4ded66109311b58744", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 75000000000, + "fee": 0, + "recipientId": "AVWUFjyvKxXZLYexXDWLiJLuLXZ49Ymb5f", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210093a55677a758062eeb56a99d5994dbd886a2bdd33f76287fb9dee7ce6f25322302202ce4a80a24aa3b75d0b8dce030b04985f3b625252ee8411223735ed013535f1a", + "id": "40dc85e19386d391e0da2c9d50cec7dbdef55e9777f8e0952e26ee7c9a2523e8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 75000000000, + "fee": 0, + "recipientId": "AL9X3YsJksdtUqAMS2yojWG3rThNH3rXqc", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022007d901327f63e75971e3a5a023ff97c2513cea96dbd4f4d2969fc33fcecf3c8d0220606584131bc5a786e15e7a7fb7e8dd752cffb73c578b5933a62d6ea6072c4ad0", + "id": "9d0d26d7fe267421fc7db3b7cdeb2b877696d056dfdbbd4dbc4fffbd052c5584", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 75000000000, + "fee": 0, + "recipientId": "ATE6aerp28bsHn4g9uhKk4ncJiGtKpuSNe", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204faead30048606f6b057ddbd4ee76da47657a853cb8b644e588c29d375c9f2ac02207785f0ecd77c1af9f8f0f68c5cc3d344e4176fbf911037ec8df681e72f5d5f09", + "id": "7f2a17f9a14b1c84cf539431573a00a63d9059051a58ee50a3ae575effc08bd5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 75000000000, + "fee": 0, + "recipientId": "ARc6St2Vj9T6PU8JPMtUn7RBb3DuM9uE8p", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100de6a748d2991d40d71bbdaa2de5cfd9cfef49c4bb9965174e0bdccc58cd7e0f5022027ed0e384fdaa03164d3e0f317f475d6f7728e1747afe8ba829a47edd3f39b59", + "id": "ff8a36e128dfadbdfd48159c0b65c608702425d36f3dbbe0db0657a80cae66de", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 75000000000, + "fee": 0, + "recipientId": "AHfcau8pKsQVGWzFCWSXDyoXGGkTKvuXsK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b1a48ab2f689a43aeb5e2b8d59f6e777ef945685301e64dcee3325bb9b3ef46202204b125c359a5d00bc54f0c0d0d3580a9841c73cf8e2ae19fe3e9666587a83a143", + "id": "64e0e887e60dfe4cf3c0a0a00ce3c89c5dbf6d76607e6c1bec2c8e65611492d6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 75000000000, + "fee": 0, + "recipientId": "AaSGhysJYBesZiFSf4zHj986A11DRvYtca", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ed44ab5a22710c41eaf06885e3b3801bc9234987085adae32f7277d1c31dbd51022022a855e38b1e57ad064a4004f37597ed6d31deaa6378e06dcbee180075ac0fbc", + "id": "c2742c309400d0bc0e4cd6b4a183cf9c58d2a8d00ad67564e6243e5019ce79a4", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 75000000000, + "fee": 0, + "recipientId": "AS3gXToMKTMydG7jNvxUMNxygvUc7okXXw", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d8b5a57241bd6982060e2a5260a6d6a9ad076c10e9a6b863503686b5b1d9ff0002200933f2e858f279ac24011d5008fe4a6ab99efab3ec795954a5b86c121fc09a90", + "id": "27fb7f36d8e0e19ff8caf5f74033b5912eec9611c439561f1d3edc37537c569a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 75000000000, + "fee": 0, + "recipientId": "ATS6jWiztxiZw8EFr2VU158ZiJev6bYfiF", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c434b9605d6bebe5950ae910388235326b701d218a72f630a523386a3d085fac02203ba1a9016a6738f0d6078d89d7e481aef5fb7e1c698262a345453f8978211ef0", + "id": "e78b60e89f9757af6f2193efd826c7f4e43cf55e992abb49a49fc6efd8488ffb", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 75435988442, + "fee": 0, + "recipientId": "AHZ3K294SDAyoNfoBX7ofAvxNr3u6bt2Tb", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b700ec2b35d2a4a0a36802e503a75794557148e37121ea7983bd3bfad456d19202204fc34d8b6fcfd513b1e7d74dbcde9963eb606b234897f1d8fcd1024d236a7118", + "id": "c331e66c718f09ab4d637cd139a5e0a9620b0aa268b8548b51f82113a6f91961", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 75912885491, + "fee": 0, + "recipientId": "AL8QkKgRswzkHyPfaYuknd8F98onyYfsw7", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b2b7083ee6801b455e14c24c1f739e1f19f39d429054e86c77475d82c54be2470220128182d6a3c7b36eb456a5e2438b9cf7579b981feef78a31fd71e63200ca1959", + "id": "9f74b82aa9272226bff1637d566a3e3ce213957f053eb6fb167ddc9d1b8833d2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 76800000000, + "fee": 0, + "recipientId": "AcHCwqRbb4vneRguSP6SXqFq9RzUt8CCto", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203e95f92a3a0ff1cca53e0acfd410a6204074cc52135671a1cb1ab193e7e42b1402202cb648ac7bcefe13152483a85f5cb54a1f2dcbbbdef70fda2e9744d210692614", + "id": "1758ed13f7ab2c65bf54bebfff06763f6955bec8836c1bb84b9277960aaf3cf3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 77291158098, + "fee": 0, + "recipientId": "ALikhBgeXghUsmNXXwXD37SPJJKP9YKFQZ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022037329d395aa796dec8db0f41eebeec510fdce6cbcbd5bf429bd308392def4c6102200f20bb5f7d5849d26ee324ebe881ac7fabbf3c4e7fe5e93605c0f7615810f50e", + "id": "144e1c573644f0461ed333bd72feca9b94c7233763ef21f196cc869937bb5de7", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 77900000000, + "fee": 0, + "recipientId": "AG755Z2rSmeXi4nXc2Dp5xjEnV3h9DSePY", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022072dad4689c20a7daec81141e12e12b48ccd71072cd2c6350321523515830f97302201e442d4448f5a0fb02e73deff73b0f798262beeae00d47c8f8a4ad94e041a4a3", + "id": "50259feb79aaba9640ac99629d6dd7cc84a43c14529be5549267c3fa219e071e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 77900000000, + "fee": 0, + "recipientId": "AX6JKGAGAURGfwYoy8r6BqCsiHibZQFtSH", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100894bcf3faf2ced40b12da116be0cebcccbdc17d822fecf2d52be9dad273dda8102207de8bca9554c27b1a37e7679c1b8ea4bd75b1b47697b9535789d5386f2a69289", + "id": "c6a38a970ca5a17e2632b958bf0f035c4760e2320fe5991c19dcce0fbc2ab0b8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 77900000000, + "fee": 0, + "recipientId": "APkL2ZzBb5Smjhv8f9ugVgS8iRJP48pZEs", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009f0a965cdca67e25a459cae3674e261d235b631393a521c95118260a50ef817b0220667fc3de471fea7ebe7d92776f8d0358bf1cb6e480c1964f45d104ee9ebc815c", + "id": "b11d02a6be882a82b57e34d0876feb673843ef6baafba06421adffbf34512108", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 77900000000, + "fee": 0, + "recipientId": "AaSzFFxYD6brxjKMaz6PsLM8Mgy611VWXU", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203968e6322e183b266a578d5f6599b707c74b8d35dfd2722b1e43abe8850434af02207e4a7783ba60cd39d8503769f886d7f699b673cc1811879f37c97e000aee180a", + "id": "8a51fa7f53ee7372961dbbc9dae868c1111748d769488e36cb21c575ef3e9475", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 78500000000, + "fee": 0, + "recipientId": "AavMxN9AF7pJ1yV2qmWjYeihGZN4QBVSTo", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f4b220829fbee7eaf190752898c3bc55359ab757413f2acb3d8f3f3c154e9206022076632671be2f123a47cc6b18b1f4ce8c5fa6697247a7b4a4da6e87e9c3810585", + "id": "becf405f252fa1c2c16031dc31feb20317838c2995476064f11fae9e7b3f23db", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 78806671001, + "fee": 0, + "recipientId": "AHTeBUJSraRKMDkpYmE2kzCTdEMTw2iS8v", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d1db2ff69f14e7066d9e3a8e9d9325f9c9c840ca2f3cb4499b72d615cbc47763022067e19df7ea14b245626624b76b408827093fe02036142966ad7c91c2a847bd83", + "id": "98e5b97afe377508e7c517db5d694167a9380169c78903aa92c557d673b7895c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 79513639585, + "fee": 0, + "recipientId": "ANg37TzJQgskwThhQ526R6EukJff7jWXZD", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e68c3dee5a9eb77645c958a81f8b3684485ab7ef7108eb29c95239d618ae6cbb0220779e760390ec7ef1700cc84b80361dc80c23df1bdc8fae6e2686e20f489342df", + "id": "e6fc80f568069d7ab3bb599d99e81f02ee2e8d85b449e37b2456f996f729f727", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 80575550021, + "fee": 0, + "recipientId": "AUwoiLFPxQimPnE8Bnp7Z9GVLGwNMn777R", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204d6e44f453221389ffcc58e8bc98a9a2691483f2e0713c1c0ebb38ca87236593022041a360781403cb8f434b221177060f206b3bc7bb184e011eb1e5066f1ea8d70f", + "id": "75dd1bd25d4413d6d4d5c2d9853d9c03283a2606365b1f0458d1f05d2923d4e2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 80648439946, + "fee": 0, + "recipientId": "AWojAkunWdVit59t4Pr29yGWAdhCrMzeNf", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022030ee47eac2cb2b80f4e22f407d8eee4c29733efd0e11daf7a3937bee384e44be02205695c43c6ed886a5db961b87b6008ff171ebc5add97e0318680528940ed0f007", + "id": "52f8f83b4a2346b02e454ecb7dbd9fac6a8d4c3f2596eccc5cc5c1444844a0e1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 80880602287, + "fee": 0, + "recipientId": "AdTfUqtiB3NJuhhw2T2xPYHiMJYGJLFXBT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e5957017f40d2b9a0a7f10722697b00e49c16e791e1debccb1c2a072e3d063c202205c19ad3b770b138245321ff7dc299ed5f411f3d9fe727f22b54d1165f0447b8a", + "id": "f8900c94b8fd4e9c80d07fccee69881edfd4c525f7d624f076522bf677c50c56", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 81355763706, + "fee": 0, + "recipientId": "AP2TBQe9NmoirGTja8cbSuH6158GFprhoS", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206a6476bd2d646155d0bab7dc4f952a8856c7789a6512718ae6d8b7736ae1ba1802205fc63cac9eb495ef7e2426a64668b771a694826c943023891f0f46f5ea8d4741", + "id": "ff059b0e5477e3417d2e3ed156d6cc48dcd62cbd7ab13e30c5120f80900d8e73", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 81837696809, + "fee": 0, + "recipientId": "Ab5x44ac1h97exN5QJsXY81WfMTAJx9YyW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022014c66256aef1f3094558a0890efc5a0f22a25dbcc1ff52c6f618a1ba519eb5cf02207a79ccc6cc6e562604c2d8e11eb041c27ff824a2682de9f399906e5360bfabc5", + "id": "4caf5c2aa360f7f94a872c50e41028b7c83540dc65ed63fe8c982fcf0472c0b8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 81837696809, + "fee": 0, + "recipientId": "ATpmYfefxVXdB6raUbujbqqj3bx5kVoDfB", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022073d07498a3e0ff75e0786796c973e8700139fe9222319fed425e96b03c78dad5022012fbc2aa62a479c88197a3656ec4488756356cb4d568ecf65fce5e8a15f5c5c0", + "id": "5e3146ffca3c3c29e76ffe1bbf28dacecf88566d393117d870feee892111cda9", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 83100000000, + "fee": 0, + "recipientId": "Acp2FNSe4DwXdMvJxBn6iLGGMZnvmtaR7X", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100cc65894c33488bd85d10eb2104a142710a36d8f4899c8198dd50db51ba7bc6c10220527d3192c1357d324ffb84a70fd02b848328fef04d26537255c4f8790283f138", + "id": "d584d07fac0668f426731192de3967134dc574c6fedf27d98118df0c796c2dc7", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 83353209713, + "fee": 0, + "recipientId": "AJHws2iLF46S5j8JYEwSHnSvcJsfGmXuY1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207934233bc6857a2ec4440fb1d3d80c30f3e71b86c59438fedc0cb8f773e6d15b02202f6915682768af0db3aaaeca4e8154acdda3446ba816d4086636af89ed8726b3", + "id": "f16ba7a15ee70202fde2f172673374204a3beab555954cb8edb829214d4d1f9c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 83989725133, + "fee": 0, + "recipientId": "APwVRmToNQFy3vq4wiEHfi8F1vYfwGXMxe", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f04bd60b6b64559d86587bf3c83f6407c20b0ba82b91db0d79a284222d5ccabb02204bac2bdc4e1b328c668aa33cac6f435b666cd6e3f907b91463b3f5b03678d799", + "id": "6cc3b4a346d67a46d101749766f64a6332dae291d148b969d042cc8d178085e4", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 84900000000, + "fee": 0, + "recipientId": "ALaNWEzy9zhCVGrJw28wSV91ES1fhWZpQb", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c27e16af3bac0ad147ffd8a884565fced7a6a609fea72d2b3e23a54cbf83e77b02205a8ad93c4da3473bec4315ea1917af5734413171b22df8d1f1cc14b1f0071f0f", + "id": "d7b32ba893728ea38b48d632302f22e87dab2c04a01cfd809413b7991afbc70a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 84900000000, + "fee": 0, + "recipientId": "AGNzHhBmg7JkSgae3DKbhj45cJvd3at1ht", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f0dfcdf262541ad079d15430a8057ca753ae9ad4030811913110356b177afc19022031c0156405f2ca3262c121a648242b65f40e6b9e02f981af090bf5fd83d77234", + "id": "d3173641dc8035ce4e2bcfb9d20ad323b3b525d9cab25a86f8c3ecd6cddb1c07", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 86600000000, + "fee": 0, + "recipientId": "AbcfAjLyDM9xKnnKyPq1esgwrpPffzuhpK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100868c42ee9b8707f4c5fe317090e9d4bf3ee8fa023fef5a2dd1ab6e5613b58c5d02201898a17c6bc802c3bf03522db36e4d23a4fd74e780e83aac72043f51dde78074", + "id": "8c0b5fb020e1c904661cc97dddcb5ab0a946d6b4f8e74e4ec22dd225ecbc29ce", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 86600000000, + "fee": 0, + "recipientId": "AKFXsYK3u5Yys3gaQVtQnARgQYr7K2qi7Y", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202298b4575ccaa0e90fc62851eeb490411cf463a7f81205b530d9abba7151376502205b1834247d0e24b428d211069e86d0fe7498dce5545c21fcbc669a04738440f9", + "id": "83b38ef3992d3ab5884eb9b7bdfd37d7f937134f238e0810aa807ec6c78bbd34", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 86600000000, + "fee": 0, + "recipientId": "AHiUknBbPYinqfG6pGkgJnLWXyH5SdiAwu", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022068147f79aeecf424c969d66138b8cfeb1a543bc833d0c1dcaea2b361ca67088202205af3b0111769ab1ad9a03f98c25b3df6db75e352c973cd6ac2a5adb9a528af23", + "id": "8fcf8c21aaa30f9a9cbe2e8f17ec58e811e52a7cb71ddd76a824560dd5ed26c2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 86600000000, + "fee": 0, + "recipientId": "AGpULTAeC1WWDY8PFZjkzrbhwUqnksCTKA", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ef2a3557376455e0d25cf3c951db49394f7b211503b42b57a239be0eb76b41a402203406584ba5c6b3f1c791f1bd54781c27cdc2e4f794b1c187e3ba05d8710559bf", + "id": "7c09fc8b85c9a9b231aaa24e4ba3149f2da51dba3693bdda7ef1dc584b6e2094", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 86600000000, + "fee": 0, + "recipientId": "AWhFiapndC1wvpb8o2cxWak84oFu4NBRMo", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009a5bed09102a91a9355bec42813eb86645d93ef79c7eb0b26db2bd155008678902207b8ce7fb53a59078b53581a81ded88b791737d1caa5554c16a05a9c4ce15034d", + "id": "0288e9d30d96bde32799db384292c36aef36840fe738d86431cf001180e171c1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 86600000000, + "fee": 0, + "recipientId": "AJUmYRUYf6hksjU2eWExtQZuxf7ZCACSzt", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100dfea58e5ce12a20be120decac2941a279eef12189d7a5491856278c7d18edd8e02202aba95df77908c8f46353fb1c4bdbbb1d68ad510dfdb082fb7c7f74e3f4f573f", + "id": "eba13a92a631ea574f1e478f8d5612d3af6ce7f6d610b669a7b46b30d878cc7d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 86600000000, + "fee": 0, + "recipientId": "AY87NwPwRs4tYVYHznKKoqDWLqCUHrErYg", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210098df44bd72c80c3ee825909494f2a973484d1b9d806e8b2d6359fd89afe5714b022002b29eea85c6bac9267d37d0ddc0f74a89c5833cc15f5b8cb5afc98355b6eb4a", + "id": "74d30f27ca09703402c3f09089ee5c4cb8548625974a0416f5efcff722984606", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 86600000000, + "fee": 0, + "recipientId": "ASmTzH5eR9V2nkrU7E8J7G8Mu8RTiQstJe", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008f15851112cd2825da273a761843bfe8d772c88da8e8108835f18758758e3bb7022040497db4055ffa5c14c2a2f3fb000cdbeddd5a8fab8a9066e55b2beddb34a790", + "id": "850b70f669c62b31665190b27391ec3dff00222e4e86757e04bb35cc01076357", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 86600000000, + "fee": 0, + "recipientId": "AQqd4UCBGeKi4kJZyjoqPB62W7Gqqi41YL", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022065e858357c4f598f1cf4c26e20e52b245fe92c2c58fb66c986106800e106d02e0220071dfa1c61fac54e79288d6b59f7b15c7271269e7cfb4c93a76bd0a7c6858011", + "id": "dc1dcfabdef49122d646d50d52fe9b558803df411c765ccf04fc4d86cc084d9e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 87141991973, + "fee": 0, + "recipientId": "AR8hYbKPJYajTNZ9pnpHjWrm7CFqSFaGHL", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c68c155894dc39eff0136d6aa9d7046964f2abbff63548e669298b937a2554dd0220669383cedd736fc3524a286ca3480001e17e6fdabe616b0290d151bed94361b5", + "id": "1697ab9993ff077aecedf05e5897d1366435f757709d0d4b8ba163cfbe64192f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 88300000000, + "fee": 0, + "recipientId": "Acd1WttVcq32Xv7agoi1KnoQZ3uhS3xx5D", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a6e73937fdb2867650c86e5ab5afe66407d79f38ccd10e9af6e6b9210852bd96022064e9f36604a80e8ebd292143d6dbb4dcde5fa48567c1389ab448a87b57a7edd3", + "id": "129f59b0d566a5081114b4a4a287e8d352baa05b6ecdf8efff73fd0661d92da5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 89405066332, + "fee": 0, + "recipientId": "AGzvuwhRjpXsCiF1acJxFnnXgNrMd8ekWe", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205dd8167fcd2a31bff75cb1a6a98adc1490bdd1c8a073929aa05bb56ef3cd199b02202d18b11bbb36c91fde4ae756b4cf7dba8197433c8723835ba91b1f4424a40a32", + "id": "87618b8944a3032bb912cbece834559d1f043e7d7255705c6abda7bda031f445", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 89514072770, + "fee": 0, + "recipientId": "Acn1izrpJYNCFrqFwFQhKXgXHHyxpGAVTw", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207a5fdefe87c639533e3a5ab01f52624f4d1b468ab88eedab0e523cac50513e1e0220388fe25747ea2764ca18cecd4ef8c3ddfdfd2a689effe830b22f336d1db292be", + "id": "2eb0bcffeb0067aa69f8438afdf76f91969faed45f26cd0c641fc0b11695145a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 90000000000, + "fee": 0, + "recipientId": "AG1bTaALP6A4Lh7Z3pDDehv8saCFpf3RZQ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204f0e2ff8ab6eb771ce67474134ca7a8b59f5d0fb421730fdd306803a548f867d022029256ce0d0c018660a1c3a9f38a7c627a07247a73b2058ae52a000fc06781267", + "id": "591c06ac993f8d1454caf4553330213b9fa246c7b8e761077768907b7f136dd4", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 90000000000, + "fee": 0, + "recipientId": "Aaq9zxgsq5heY5uGvHWpUanFsLp1aFYtzs", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c537c102f6d3e77742203961dd7718f4441db6f9c73e6dc17c139c7639707592022049a206a019ec362981d3377b6172d499de98a4e603b2c6b6772e676f3161ce7d", + "id": "c66078f962373fe9663a4a89460d2cb8694aee100ef510c511376b64a6129d14", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 90000000000, + "fee": 0, + "recipientId": "APdt2CLhn79TsuFb148bXN4yRWDtxXByi9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100be4c6dd3e6266e8f3c488f7a70e43547b289a8a838af519fc0e3718270133a7d02202b438a20931ed53c67c4122f3bc8543c5f51fbfdd918e87e2da4d0aaa9becaca", + "id": "fd445aafceecef71b3bf57c4f047fda3759aaa279f5bd7108a5ef27538b11002", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 90000000000, + "fee": 0, + "recipientId": "AcAs2VGLLA3CTwB4zzHBnbzrUpFU94qpo4", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c21d6ea2c66bc26ddbcb250dcfe904c10684eaf8a30aef233aec5b64d3ec9687022011396be43ba72cd7cf2f5001e619fc4856d972745d012194b3d951834562f802", + "id": "0963c73ce61593cb65e2faaba4c803783a37198d3b93ea54323d3d52615d45b7", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 90000000000, + "fee": 0, + "recipientId": "AHvDiW6VVXRHhGLkMpuR8ZX5auBZPHK4AB", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e333d51da7708efc3ab80ad3e510482ddfd87f2193b1d61939d38d5092fc5be402207bce382e3990b99c53e0c8e5dc3af4f948a7f511e514684e0f59c37aa0ec54a2", + "id": "f2d908530b25ea4f3cbce6547e4aaf248e18fe149f190d598f775fe26458e60e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 90100000000, + "fee": 0, + "recipientId": "AJ43cE4rT2RoUAv3LfkDzYYG6podChvrUQ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f4b85a3222ca9638fc1b8c5a64e4e23aec2cc4ccd8d957cd1ad0747cd430fe910220716428e2f6d7289bea53eb029006d1a1472cdf4661c0e55eb9b04ebcfde5958f", + "id": "a533655b53cfeff54fa341c2d9cb376e71c70f2b7625f798a66e6e1e0ca1c505", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 90882035337, + "fee": 0, + "recipientId": "ARQiX23neMcAX7SPfyauwbixNhfWF9DF7c", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022018c324014c8bdd445bd2025fe527f52cc668886705b068837b9d86cc079ff215022075646fa0b7eee5be5355c1630eacc5bf4b98b1653db006d1cbfd41e07c156218", + "id": "4111147e598f03fce985dfef561a5205500865a7adaf07ebef15a8035b070726", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 91944813749, + "fee": 0, + "recipientId": "AZRqkB1K4ybcsZXL5ZV6sYfcqYD2bRYwzW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220794d5cfc737927e6e6e2a628298466bda26bebacc349fa3b75cae81c636bdfcb0220463b4ef0055b4bad1150add80f192999486d91c4ccfdb07da77bc9100844271c", + "id": "8e3e472a029d3c34d9360a92e08f71ecadbe5c2290fcd295d691b35444510626", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 92749389717, + "fee": 0, + "recipientId": "AXiaU4ksGV7AZHLSPPMM5Ey1wbEwEXoV2m", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203436a912a9c53191957842d0d04401a5b33b3255bafecea63ffb703fe36bc4a402204bdd3dc39ea956d43a909b9e5ad8c71909bb5291238ef2b0ff7bfea8cecce5c1", + "id": "6d4a7e3b265f562969594ee5ada3abf8a1a3028a324803a7d8566b294ace73f6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 93006402914, + "fee": 0, + "recipientId": "AXZLHoMLqpEVAfeP1qcdtprba9GBoK8rU1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022074f4c6f3bc573b7e6ad33da49b2f429d8bd93d2947c8befb2eef024e24b885ff022035902bcc93a8f39dad93fa36d0c378378517d50ed2bfe1b910d8b6bf2712b3c6", + "id": "69adc07393e5f7e41408f665571ccdf56ed41e8414002df3a5ee78f83d4e51a3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 94906857132, + "fee": 0, + "recipientId": "AGwRjNYG47ycvkzKjM5f6QrzcHoU8MNRHT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f31598c11e21ad6c472aca50ae8c9e762bf7b9dfb720bf81e4edeb0c94a0863302207172d053daf3cca142027b29c62cf8ad23f2bcfe856d9ae9bee82f2398bfcd38", + "id": "c311c2d17e5882af306b820209a4cccc28f382dc7861e8e59d39b7a5e023502e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 95300000000, + "fee": 0, + "recipientId": "AY26UuQoCQTQA3Yaqf5Khwf1dWK79AkfuQ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205a0874f7f7aef5aa5eb650196cf1ee1739a3c0d3be23fcefb43cb63efee96f3602203aa0715dd7b00a84926f6e7081840adc97f9dc8dff542373b614bb9a20912074", + "id": "493a1e157bbab8a11059fd93f54cb3015076628ab11b09a1f6768b233d8c1454", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 95300000000, + "fee": 0, + "recipientId": "AFwj9n5ARhWX6oWNbTEeR9bbX3o7xBikXD", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220483099ced6fd44669d578eab70d4630660597f0df1a0fb734a62c72cb2581cf202206636e3f8066fc4857d558eeb5a3502b3aa2dc25b2f51f3d44aba967650479988", + "id": "a3273ca38ac6a49f276e658b11155fcd151f5745ce220bbf63373cc8971d784b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 95300000000, + "fee": 0, + "recipientId": "AU54w4okTRtFbFa19MC79VBL9B3QW45trR", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022055aefacb9cb4500f4573d6ab8e50e724970b2640b8a01cf071c4f0bd7076ca6a0220474772c7c8f44a38f98a1fd4be1cdd65120bbd3c2404c91f21fe5331f2f429c1", + "id": "de221e24f05801bb0c5681342127472e05e716852392d8d60733811779a0a142", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 95300000000, + "fee": 0, + "recipientId": "Adap1889XDiKC1bMLuLrSKzsabXmTuBXjR", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220083115c84effaa090c3b79b7e7036a9bf2d9dc8e5818aad77446445f17ac8e41022016a2dc3addd3d82605c5b20e27f89019dba0af6bb91cbb609f4f3be89f463b4b", + "id": "97aaec895cc684d562baab61c97def9a651cddd63b1b8fdea8ca846a86eb595e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 95559787156, + "fee": 0, + "recipientId": "AayAdq2K47PQiS7jMknrMwmQZujeEp5Fic", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200993e9038199932d4f9ea36724f89ac970875ce335ec578abd5792c24c4cce170220048ac8441077ce7e8eebb2fb0d22d4216f0ada9a0f8a3bff22e713f2d20b2875", + "id": "28103dfb6b5efe7dd7f5f880df2b3b910a96c4ba733c7bec80040aaf73b9a754", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 95612193593, + "fee": 0, + "recipientId": "AWgoLa9CgxHtUPAHqFvMpxvvFFK2iyBxUK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b71039017534404cadacb04535b1da38415411d5a2f6f5b511131c6a7d48843e02203504cabf89ca95390944620ed9398261da2a0a825e38d26ed5ce0c94bf58469c", + "id": "2a4c8eb73ba5fda2120f2ab91c7806ac9b603ca1a2b2d8301d676fda113ac29c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 97000000000, + "fee": 0, + "recipientId": "AbD1qLeYWasvZH4PX4j2h9bXFXJxAdhAuy", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203d888caf166966ca8a3559a40b6e8a7ac840048ef9469dc143bb1f9be26acbf302201d256b315dcbca537eaddc86c56850354726e67148088e38ea6763c8f774e2eb", + "id": "0725b2165c79199d1cb3087ce9f6989d0781c38bb4fd3bb054e9f42cf577532d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 97000000000, + "fee": 0, + "recipientId": "AWffb5DY3ceB9DcHknBsLSmZ7bQCX9BgZa", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200a3142e959218f0b3b7daf341222c3d2ceb5be21817e5c97bac96f964823faa70220086698050a3d8030bb6a1f01d4000297561b0a6204d58f8e4795b58a6b1448bc", + "id": "50f6375cdb90d9bf764f1544c5c85daaac335148e7c5b9706fad6564711eb832", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 97000000000, + "fee": 0, + "recipientId": "AJyxXb67KmdzRibbRSp55tC1NHcSXzNQmn", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201bc4e3f5e8bae4e7bd81da4e8d4d3e8a1f9c607c36e39e442235b133e3c350dc02200cdab848881bcfd15adf3f38afba7582753e9824cded8a96c35de855ed394c6d", + "id": "41cff0cb50f6902d42cc455467415829d66bc857002b904b63b959fdcf028215", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 97000000000, + "fee": 0, + "recipientId": "AYo5WNLUCNSRKkvxxMs5hHCNxme7xQ12ZK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205958c081b5336400e4a7a834a33cb8b5b05b81cfd7fd435b6f2c2109850db75d02205ac3c51a116db91e925e26da94efb2143e3e457669ebed1bd7464c9b1306099b", + "id": "ec651028a9b2b6924dd11472761295fad83f3738d2b1ca5867b32a867e17d946", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 97000000000, + "fee": 0, + "recipientId": "AZFKF8mKcoFVz6nG2zvbFxQXfumsXK5a2J", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ffabd89a120c2ed7c03c125c1da112043f5dd98cc99f205ae87488f422278b87022054bc18f5d6c732e8a2132086bb9961d9b3313bbfde4f428cca2f61db934275cf", + "id": "6dc4ec6abe9f5b39e3624841432e9c9af338edc2d4214468029d204d15bd50af", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 97000000000, + "fee": 0, + "recipientId": "Acye9MMv7bbhsBoN1T7TuiCKwPFprnoJgk", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f2dcee2429c1d6ed797c1d8825890474a4770f5f18774575308946bafb3b4c2502201ad6bd91169df28bb2fa6c827e8cecf0696d87136de193bcacae2068d0af83e4", + "id": "ddd07d35e2e0d2b1eb9d1fe7297051c22da9762283b767b6f8377d12959328fa", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 97000000000, + "fee": 0, + "recipientId": "ARWYVBZxnuxnp8JQp96fSZHZEw3Ea2Zd3X", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022007e6b2cbc4a6bf18e2b310325e1d7a56e0d455cd9afc6b7bffe419a9e70b710b02205faf2e91e740f331c04ca133da2e6408fa7f3ae4e5328b8ed6befabc8f7adef5", + "id": "52d56ac56c6e2363f94d1a953a908ba3d841bd193c4af65799f652044c66bde2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 97000000000, + "fee": 0, + "recipientId": "AdPV4RprkYHnm1YajzZYcQ7QjVLwyP9HrS", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203827a7141256877ba780e3b36875bb9af64f7f4fb3d9bbd4e9705d25dada25a7022027a1c9324c162cdc510aa1130099435d7d5569737249c3458f496577482a297b", + "id": "7cd4765b692240de26ec4341109869564754a541571ac191a1ecc960220cdc6f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 97000000000, + "fee": 0, + "recipientId": "AGNE5beBRiKtzAGxCGHPUEzSTbYNmB4x65", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220639fd4f4f25e365b6cdb6ba4cd631a93cd826376a07ad941aff9c83eacb438b3022060a52e0cfa6f7b4b0048d30deff592b185a7132439031c9f84aa5eab945413e6", + "id": "aff7235b112fbaeb9bd31ed8ddd827a95d735d74cfdbec373727031a6e752d07", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 97297237832, + "fee": 0, + "recipientId": "AWxt9gGVbxQ7cX7o9DBniXLA3FNnAzo5Yc", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100dda67cc7adf9bf59523c49e3862a569502c02b69d4183681ba73fca12720e14f02202744c8bed417d5bb28499eb7bd3d353041c32d86247d9152090925395642f2eb", + "id": "08977af886121fdadc51a53156c4d920998d236560d5ba5518eae27b0cb75460", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 97764047435, + "fee": 0, + "recipientId": "AXduXps2TeHn7AvTiJW6m9qqNCtrPAXD3H", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022033d10a0876ec4a4dc66e809ab4a852ad48cc688c68891ca5934b78550420e7ae02201798c11a5dcd1c21f873f0bb299a86d363895ea0e6d4e7a1137327498fa69256", + "id": "9d74cfa57b58e0470fdb88a9eb944096e1c749a4196820575b99e948c125caca", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 98045028617, + "fee": 0, + "recipientId": "AWYjUa8Y5UdaZKtit3Va899xqZDdXxsRaS", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c60266fade798d0a234c8e8d8fbdfe5f73fb015a29f2497acf95e78f1fb5e192022034c1a2debfaaf6068d46e70e42eb606082438aa53eeb75ae1d84f84b6cde0353", + "id": "828319edbb770b68aa5aa91afd76c02f76308f17f4a1c36523fb2817d1bc1e28", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 98100000000, + "fee": 0, + "recipientId": "AUzivjaUXHG8ivXWuj6evpdL2TjszQmVWs", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022008f1b85ead0a3a3328f43200c0c532a2a539715fbf4856e084dea1e7498a096402201e0daee01c06927dde071f5f5cc7e6fe1eeab7291cf4f7a0f330833c535d2deb", + "id": "fa1085f0ac80d410ef9530aba0af26ae0d652677f5e90195bf2184be93dfdf71", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 99262036541, + "fee": 0, + "recipientId": "ANGen8SGYqiBR8TFgtawL57qxbNZRN1hrt", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207557798214dc6bd35d8dc197714dc93287dbd45edd7ed832991635e5f20cf9a202207ca660d57db42578e31b0622648439ddf0219a862579b1c933d5987b76ce53c5", + "id": "f46f63e2877adbb32ffac6af90c5cbc79dc19ca5592a0579d395739d249a22a1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 100000000000, + "fee": 0, + "recipientId": "APSNQNbPQabUiMqxLxjhEyTkeh27nWQDu8", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009b295629afb30454c67ebce29203ec8b3f684f194fddb167bc4ef9d3739a300902202da7e99a48430663805db9cef9cc32915ad694ee75b5573a5be7d7d7d688afa4", + "id": "423abfb5a05784af1225894bc22e224dac42d421e90bb4227c945c35ccb9aa54", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 100000000000, + "fee": 0, + "recipientId": "Acj8SdBVCKnaCUFAydJ2Ggk6E7cfiRP1kJ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009d471ec487447ee43e43ecca799d7d1eab2528d75a1f98a35d9f1c777ebbfcf5022020d40ea9d1d3903bf5ee4e2f67f97b7d62fdfeba622ca8e72e67622c9dbdf8ee", + "id": "0977be517acbf17a25ebbe3c2568a91667b5bbc05c6deea85d61b2f1154440b9", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 100000000000, + "fee": 0, + "recipientId": "ATz8duPjUnEL5oXZeD59rLCmtvHEcbui6i", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200de765be6c4d07836d73dc78eafed1a80fd2e91e3217e7bd104b6b084b09d78802207b244d85ea74fb2248bbd4c265a9e88a5b6a55ac6126f1545f839d2c41204f95", + "id": "106903e0f03337c08dc2d9af7c17263b53376474f56134b76357113a4e92b3e9", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 100000000000, + "fee": 0, + "recipientId": "AUxTza9YeaMXKqgU2FXp6mr6kGyRNFACRF", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220697444d31def970f5a73bafad9d3c0865cfa82a8f200d95913a6953314b7b49102207f70b0f71f2177add874eafa7ddbac1c3f5162f1f410320b06cd9f312fa5cddb", + "id": "e2b78d5f015620390fc6dc0bb39dfe1473461281c1f2de2dc47668959cb705fe", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 100000000000, + "fee": 0, + "recipientId": "AdbbGesHxgSbb5S9BFVvvmgrLbz6vMwtti", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ff6e1f7efbd6cf34bd7e27dde486d29e6429d28f0407a2cb86b9d3b2430cf22802200f64f32c92f87a8591e674426c34e43534c3afae30c62f08b6492f53554e99f3", + "id": "900cc87a9f10d54378456a777b72168fa9a8e44d256d8c46c362a1e068b8a3ec", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 100000000000, + "fee": 0, + "recipientId": "ARRdKZqLoEz3BqkspqPFnjDMXUWHiK7rUf", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008ac2f93dca4a6e81886d0cd48cd8d05fe612364e9382f45eadce42e3051cb0da0220349b5ef16d0dd502d887fbd2caa4d666cf0080f55a6c8bb92b99819e15cb148b", + "id": "48bdcc189c2fe7e1796fe78cb49f18b99187feae93e80d3e014d30101c067f84", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 100000000000, + "fee": 0, + "recipientId": "AM14wbgpGVFcR6EeyFrZ98iBSGQdKGwoNR", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f56b28811f377035b6f5ef6597f622a8f45d0ab7ba46d9cf8b73367dc2ba72c4022021bc53a68673a43fbc49c98b19708527f61269f16bfa15571a74b468dde373e2", + "id": "1c0411c1f4e0cccf85034f50469939ef994740903f65ec5c51d3ea04a0d776d8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 100000000000, + "fee": 0, + "recipientId": "APwycJtjaT8LaXEwN6DmyanzBWMGLCDffz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022030e5363191d9681297a0b85fda62a95ed499f3b6ec18f7dfe115371456367bb5022018807046a5e802ed222f7b2f87e583942782a7a3f3241592f9d7bed5d5d88784", + "id": "f0825d84e64b56bf8f388530cd18cdd4909be54d364ff9703db24cdacece080b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 100000000000, + "fee": 0, + "recipientId": "AFwTR2Q1TyWgpYvnUD5AKZ3KtEhTZnjSen", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220767d49d3c2497cac443b78c806287b68deffea0b7bbbeb171335997b40a10d7c02201a7e30b1d7ac9115d98589b3b54c16e19e7466b8ccc4394b488cb2637315af0e", + "id": "0dd5220da9ca8ff958bbc8a4040a0502d8ee757ddde806625c00f4a7cdcdddda", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 100000000000, + "fee": 0, + "recipientId": "AWWbW4iYXRvXzXAG4DVNw13kxGyZXkXJZe", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e00353541efedb21d3bd42e33963056ec65f0a79880f8a3a5f991103d8f64b3d02202f324a1de8c96fa2fbc41d9c3cd544e3e25bd84de68013c38696115a497a12cb", + "id": "3fe581b3aa87b6cffddcb98d27f62ef83138e2e78fcf3feea8a44db4575f89d1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 100000000000, + "fee": 0, + "recipientId": "AZcPTCo5A8M36wCFvDvPz3H2cBBJo9p8iq", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100cc27cbdedfcb771e9d222bb6cb13a71d7aec8e36fd433ea04942633c5d5e84a20220564dacdf36c5d0abaacfb62c445c8fd1d046a794339f38a05b8f40ab1d338d2c", + "id": "7682c2fa3c74fc40d917290a665ca4412fe74b737cd464c908850ee631af679e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 100000000000, + "fee": 0, + "recipientId": "ARoVFy8w9CsSBazrXnigzRZVrrsVhUzfLs", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022072790cfc15458125cf1fe54e85d58955797d3f4409f99fe74d3405742fa72bda022013075f4dd0ec2054b42eabc9d41d4cbec07d885bf1650f75ef3936826dc2d1b4", + "id": "f20634bad0858d0e9b1fae15b9608e8b6c0eb8715adba0977e0f17cc20dbee99", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 100000000000, + "fee": 0, + "recipientId": "AaerL99dZfwZL7yghV9k8Ri5Hhpi9YPsYp", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e67003e1c964db17bf2bbb00e6a4c60ca12e46753d36785b13041a136bef4ebf02207846bf567a2bd72bee3289a321e58da645d3a64dd9030d0f52028de50efac7b8", + "id": "8aae4664984ac30d28b171541c9a41dccabe558089b073d8236171c40456c4a0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 100000000000, + "fee": 0, + "recipientId": "AYA1abqExAqcWxP4qHaMNN6MdwSVAzz23e", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205e46b3935995f1edd2797f8a4ecd5181cf16893d4f955747824e0cbd7effae40022012f11701804587a5c2d9bdd8295fbf67524bce5a26ac6758bb7d43ba6975ecd0", + "id": "fb4d5ab6087839d6bea3c4b93d91a5654cb556023c0c2648e3ddc47268b29447", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 100023851656, + "fee": 0, + "recipientId": "AG825v123YvZQuL4vbe7wNxvdyTewt9gGm", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009d37379a461696e7b42faf48419ac770ead1768095ff38997eee98fc01bccc3802203272ec96815df48dc692ff686952e04053d60f14c0cddd821f0bfca775034b27", + "id": "aca358d024faa5f4fa68b7943ccace6bbc5a9ba2bfcc614445b7a1b4e96be417", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 100749519793, + "fee": 0, + "recipientId": "AStWDeuQ3NTP619nCiyxbYbnyHTnR6cxb3", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022046f3e87a0851d6feaae6224127051c783d08efc892aa52118f89dab6f11f02310220030a37ce70dcc5b4554397934d67ea888f49c7ad825a337a5540f8fae99cca44", + "id": "b92dcea5e20cb9348374898f686f4d2e2b6ecfaceefd6a0ca637bc61c6a2bf46", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 100933159396, + "fee": 0, + "recipientId": "ANV8jYBCQdPscN31ES2NDFQ5Xe87zUrFzX", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022000ac1e8b3e471505f8476f98ea31920128876a804d22ee446af4ddf210442cfd02203032930c4d6d6646d3d4140ff89c48b4e58374770f6be9169d04c1099a39d216", + "id": "c57cb34e723d065e12f74b33c2ba5bcde69763ef191505ba9cb38af0a769360c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 101680182605, + "fee": 0, + "recipientId": "AUQroQ4if3dKyFwgv6ESDM8MHyJDe8MVLP", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022025f1efed2ab491fe87764de2cca46aeebe3e31e558210001798d86c831dd69fc022059dd3257cbb318ab88d7f21baa2cf56a975582d578a3c67cc188ce46793a2d2b", + "id": "f1d975e6feb911d060c7ee86cebf9f56ea0d3001d8d1e9813d24c0fd1791aeb4", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 101830636768, + "fee": 0, + "recipientId": "AR58rt33ihFKG56DXMVdKoidzNm4C8kCnF", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a8e1e2102f75026fdf1cdf3bd8a737a673315d48ccf8b28730235ac9f78dd2ed02205d5a50aefab9c7817d6769a64c83b19b96df69769a735a3051c9888eb4844ce7", + "id": "84ada517a25f66b23c3127830b7d77948fab1c1fd2e643f4166384c1a6af9bfe", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 102744627447, + "fee": 0, + "recipientId": "AY7JH5b3GdHv1ZcbFXW3c19ovA5k3jYtDc", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100dc91d5af8df4ce928414162c63d64452bc1a05ecf20fca159cc374deab7401ea0220749733c55f0532b454f3d401d41bc3bb79fec7fef8b439f54c34c17fd5865a1d", + "id": "edbb728bb5f8ccf9384ccd41be5689507179d05d60f72188c419d5163d76b6cd", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 103054877463, + "fee": 0, + "recipientId": "AHRjCLd18MVx4MevXGsygteD41pjjEmae5", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220223d32f9daa36a1d0c96c35d6825922ac18fd23cf9e69f640f707c27a49f9a4802206e4132f40a65ceabff49666671a7f8d1d22848e06ff91c31a42cb6cc38f0d9b9", + "id": "63a23da52548b2b0f932340589409d453f3d46656f78dea4d8688d926013f84d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 103054877463, + "fee": 0, + "recipientId": "AYwziM1FFZdiYJFpLjSDBQUnJD5gQG3T6U", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ef3d526e72b7021dfdaf9b7706c88ad8bd985f453754a116254d13b888e127140220259eebf0c8aa21adee9b573ceb4bc1b4597c72cf6a18cf1617cf645eb169dd4d", + "id": "915baba7089f762e6ff2398ad391de54f7285f0b155a277d88e5a9bd049139b8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 103054877463, + "fee": 0, + "recipientId": "AFygDabDnSBm2M1iDWofGNHPa6ZeCEeqj4", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009fb6a8eeca7df3b18fa9d1db1a1a4c1c63fb36dc5f71396c9f6d21070e7fe8d90220426ff00438c59643cf1ccd01575832f0a375d1217c43cd816538f3968c643fb1", + "id": "886d32c7624d952ff3db788984073b74e5dc6bc027ef926d1139b0a512dc3f2b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 103054877463, + "fee": 0, + "recipientId": "AMimZDyN8vdDp96CHVLtWkhtvmERvTmnnT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fd942aca86527ff6011d230a0ad9626468d361b91f44ad22e32c0774627b0cf90220410fe8a28dec6354408b5da8bb3b77f5f5a4e2b491dabf5177876a8b29928c97", + "id": "b7f7c997bc93d99f92b458affba8081b15e2349f35176e2100ad38bd859bcdf0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 103054877463, + "fee": 0, + "recipientId": "APdPdgkVCNJqQz1xP4qqzRY6K2tjybdH6V", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100bdb4e44659fffbe283616db6d45315d3abd1e4e559bbf323629b9efc4ed81b080220069b6e53fd81cea49c8136ba9ae23e00258ab6a2d30130d1b31784a21b669a96", + "id": "ffaa043601b679834ce66deff3b7ff00046acd8bb3f573ac6610165ef087879a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 103900000000, + "fee": 0, + "recipientId": "AZiQBaR5TwSH34NXrdrvErMX3aiYZWFxo8", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c87c4c23d0a4432c99df14afd1c88bdda73f3a156ad89a247ea662080b7214dd022055506cba670851b036bb39e638986879199b28312fdf356a685bdd1b17003708", + "id": "146b10f76eab1b6783af1c108c35df9bafa3c6ba25b72ac6597d9fc57c7cb215", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 103900000000, + "fee": 0, + "recipientId": "AZo1U1VRipZ4aWx8LYfEXmyEBcFTs2St36", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022040317a8ac4fe1308c10fdb2ccf695db0d4374cc57ce5b012e7d37766a7619ec70220014d508f6dda12b5b9ff095e6d53fa77bdaeeb04713de273725d09b55ca22251", + "id": "549b4107541aaa18058574d381323196285df6645476b9dd4e4f791ea4c49106", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 103900000000, + "fee": 0, + "recipientId": "Af4CtTPXJ4Wkgrsw1zsvmCoEUS1AksAyEk", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203e6c4eb1fa7b5311f04bc7cdc38445b9b737592b9eaf0df143998cf5ce66eeec02204ee48dfa39a93b9afb978afdb4b2de537dbbeaf1c82e31059d344be867378cbd", + "id": "3fe8bb50ef8e7f6346f7447e934e9cf8e51d981ab151698ac258cdf03c72b8ac", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 103900000000, + "fee": 0, + "recipientId": "AV1MipTPz9KkjJKqSfagNiQkpCDACG6A45", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009c3986801d041cc233bbd394cac166ddcb2c55482aca48a85a59c130c55cd8d50220164eb74f9ef23f5a6307756fe57ff385258a9fbdeecb5525802f79cf5dee8956", + "id": "54fc495250ae8a95f231553ba952f8ff502aba015ad586f03f68bd6fceaa7606", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 103900000000, + "fee": 0, + "recipientId": "AdFF3NRiwLpVuypouVth7HKk5Ca4xejtmq", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100efce8d12b523214f79402697597729647211ba94ef27ae2743af9d6ff0985da602202b75b8e0a0a655a8863b39940726b51b31566f98ddb51b2b17735a7970596edf", + "id": "436256751f2e97b12d0a99f725a71aaa4b4ace4644b4087298592e0a5cafda7d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 104570390367, + "fee": 0, + "recipientId": "AXowRmmMSAB7GFCy8XPpNLu7E23B7DmkPa", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e0b952d2bfc38186a4ca9ca51607f44ef64a3a0e58836171f1668f0f47fc10b5022071d9e89774682c5cb84897d5c406aab779527e759ddfac473c900add865e420c", + "id": "ef7a402d8c58133af24b24b5ec33821e0b443e680144a20b9ae83ac85ea2d16b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 104811009865, + "fee": 0, + "recipientId": "AJNitjA6dbbiz5vDaQkaKSXaNiktVFmopp", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100aef19847d686fa0e802b7eccdf3e302fd9bc3aacc87f6ed76ee2ef0d5abd0c570220248a00f81756031ad2b87a6bb367e7e6cedc11b4412ee3998db66972edd35166", + "id": "1d956208a3979f3224a4dd347109102afae6463b060bd94957440442904988fd", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 105000000000, + "fee": 0, + "recipientId": "ALrkZgaD6BBZCLx1FaUvcFRL9BkTsjXa6P", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100eb10d7c5fd4b9c27aae44cccefec7315600dbabf3cbb180fc66e996ea2856783022037c60b02b33ac06604cc39077d11372ade6e1a66aa89f99c43b6fd0f0fcd8ee3", + "id": "1d10aadc7d67af4ea389a2f0163fc174f261d71ca6c80c2b326b674858948ed2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 105000000000, + "fee": 0, + "recipientId": "AZnonaWAZjaGFbku3DLoeGwgg8PCy41sMj", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210091235be3645f78fa9d77d45882767b7280e779f3532defcdf0b71eeebc73bf63022050c9631aedf3c42231ed1fb9f385763c370ff1c9faa6c14ce07d14500fab3d0f", + "id": "a65fe81748277af637a844a6a21b8cd57f4d1dcbe6aa58a553a94cfcf0ee2650", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 105000000000, + "fee": 0, + "recipientId": "AbCoHPSKn16NSKL58h81seENSohU6xAT9w", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204ee2fa79681c3c86b4107e239596087b33a0fb6108e2bfe286598618945c859902203a32f45dd2538f1e49eea075fbda05db26f5c9cfb2b3d1f4aa85117bf4a92149", + "id": "306de8162df8007e47f95095c1386c4f838d32bd6072ea1e740e27720649058d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 105000000000, + "fee": 0, + "recipientId": "AMng2ZJC3Gh2ykVUAGUeKB2q16WnaqK9hF", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204d0818688736ad3bb25e21e4af2716b2038a3691e2cc7f27bda2df761df4c1c802201c2fd04143b52f2b5e5bc1d3f8c17cb038b90eebd5282ac3877012a874f8fa95", + "id": "1a64cc2367fc2d05a9fc862cbb99be77166117d5ba2ec25907126561b2d9e1ed", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 105381567713, + "fee": 0, + "recipientId": "ANzYwcwGfMg15SgWMkGuYPxjePuXLtvuEG", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220750181471cd14e07434ff8f59022127b7ebb36b643aaa1851142144fd6d0bfaf0220268280752dd52b66eda35bb6384e6148135461ae865154b175b36162860d71d6", + "id": "e4f2db2efffd43d8a99a2df742cc93ba40d3e97cc4e9cb421f9ad3c85a1d5e19", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 105714987355, + "fee": 0, + "recipientId": "AcJFXLL7uS4i8x6Jg2hZQftgirzmFt2X1t", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200c0d4ba6f603d8dc3b535fb8b442fd1c92c2d7deca82c1aff622981874563b0b022043f3c8a59e042b847b1359f1a28a34b44fccaa042c41947a1565ec2d7e719167", + "id": "a85f33a959089b825b8453138de87a63137c1fc61ab1038f3e8202d761133c31", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 106221504166, + "fee": 0, + "recipientId": "APk1d1oci5TiANq2XcdQjy8C8iLwmtTf1G", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206afbd9bc04c90409a31228c58e89f493ce384d7dd97a0b97412a4725d7358ccc022067b1f28540632ad989bd7458fdcd23e5897615e9d9017289850277034114888a", + "id": "b9cf7363f5730e0b1ac4ce9114ef5eee22797016bb718354940fcb53cab874b2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 107239514002, + "fee": 0, + "recipientId": "AGLvTbXCtBAdCD7bvAi8PBSSvRexEv1upC", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200ddf53eb746d313d24df80c2edb7a3d01b533a9691d05d4c863afe390ee5a82402204de5576afd6f9a54ad7f106cdc71691acbe16e206914e9da123709f9ab78ef85", + "id": "84b3f5981b62693819aaed660e3eed3e5f13042449234ab73a5870e760a45c7d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 107692346948, + "fee": 0, + "recipientId": "AR8jXLCoRWnnkaD78YxajVcFsTv7eVutRb", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022077094180476f993bcc0da365d9f9667c8724c5d07402689ece5f870af7e63b2f02200faa17f80991d65bc3e8a2593eb2ccbd7b12fda29dc3fb856ae0d222bd56113d", + "id": "dd832724781a028d0427b13d14813c82d8e949fa488e9885c872f1d7e6176642", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 109100000000, + "fee": 0, + "recipientId": "Ae8ZPCEgJEUMkR8oD1Pp9eDocsGE2MRtiZ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022040ea35b1906200719f7b79139f0bc3dcfd2d1f34b19c3e75a4fdd1e3ca84b60b022008522e9eb7dde5ec65fecddb318added37afed341c66d4c3f938cdb539bab0c3", + "id": "ae1127f0c65bc53762bb7b5e79c3dd2f0da85fb201afc5bb1577b1fcf371c31c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 109100000000, + "fee": 0, + "recipientId": "ASoz5DXAEBaQy8H5KrYWH6bzYkJ3zHVSsx", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b4b63ea88288f994776b80c78ecb41793cf70fbf72e3038acf73099c5677be9d02200358cad66ae2d98a08c43be0c73fe88a6ee869be49d0012e394db3d14659c43c", + "id": "f2d28d17f885481487547831f316bcf701a1be0d2263403740dc0516293384c3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 109100000000, + "fee": 0, + "recipientId": "AaPUG2PrNDy6UVUBkSwPuKvKh2DSZdnDqe", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008d7f47c01e28bec5afbf49a5cbfd68f4a911a4e840b624e13abfa4209c2e67c102201fcb385bc4fd9b55c687e5a253b2f181a658b7fc462d8830e63deee0c82967d7", + "id": "0974483b28113dc2ba87c4e8caa564f71b5a4dd10167252e66124b02fbddd7d9", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 109100000000, + "fee": 0, + "recipientId": "Aek4aTvvdA3hUVUjhgkDtPQF5E2iBuAVP5", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a05c9fc68f17c57f5adfc88c3bef13e616149a53b65a6a97c95d8f750a3251ad02203cd2aeed88591b244df1c05342d79fc7a5c0da989d5b024bb4c72582b28333ea", + "id": "cb54ba7a6a747c5d20e66648e3a7d12c6e5193d0ec1daba2dbae6b8bda726165", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 110800000000, + "fee": 0, + "recipientId": "AL32Ure9XiVh6emxgHdLQPRbLbr5otNqDc", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b8d1cd4c228ea834d371edd3ee9c59053d831c124edc7588cb358aaf0639f93102200cbfb5d6f0cb5498709897a24af743cc1a80a66a948d411c9d71ef18394872ee", + "id": "4683c51754c198ccaefd949f1becfa8dc36383bdf4f43b9a5ac3df0e848cbb01", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 111541749725, + "fee": 0, + "recipientId": "Af3iDQ3qYG53LHVXgGbQFXkffa2pyjdEFj", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c57f7ddf68a0d08feb91bc9d67e9b246bdff6d8fc3dc07e3524cde453ad60bb9022007a08e49417b03c201aae30e9c6b12360c1e5e92b7ea5e72cc3b257d48578f54", + "id": "df3260c10be2b53c385cbe025e84be776d6f9cc5bbced87a110ba3fee4ada362", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 112600000000, + "fee": 0, + "recipientId": "AU1k68nmfcpAkTkday2TZFoKuttD6eh7JL", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3043022004abba6942eb051d80c8faea823133159c8207251f82bae328b0227b77f92097021f1580e0ff6214cbec6d97059469e5f498b39c25873c889870d0450b1b892be5", + "id": "c4b480f9254eb4290b7acc61e2e85bd2131785e482f6e617b8c3a6084773760b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 112600000000, + "fee": 0, + "recipientId": "AS3SgCu4BQ4VxfdJyu4HKNVHZGTQBP6bTB", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100bd132234f55b6c486d34b3fb5b1b52558d45938ffbe0a02e2ee06ba9fe7673e802200f61ad1ae7b20468c496c0526bf726546eae7907387f72f85245e0c7fd9888a5", + "id": "66b7e7ae47d5663ceef394c8cec8ddd1851bb4034c5ad133c1b4f6d2b18b43a1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 112600000000, + "fee": 0, + "recipientId": "AWepJMLX9wD9nm8RqagQasNfypVX8n2wLF", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201dbf3a7b09b8a4e71db49504e3cd5bf8864a877218bffab4dbce5a50b199cd1e0220452ebc9b95206fea3629f11abc6a40a6be3c0738bf496ab2215c7033bba185a3", + "id": "a94b2af091d991840007d2644ece123f0f42d18276237f163935d2df2e075685", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 112600000000, + "fee": 0, + "recipientId": "AXBWn3Kf2yEy16mYKrwnTQsRFL3geunAxh", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220663a6cd1bef053f3376b19778d7256d08a34a8d8177e9fc36b3460cacea75c4602205b50dbdf88972c8868d15934c2a466f7cc6b82234002cd08391ffd13d173107b", + "id": "068b774d4990385eca9fb6e1ac6726cf6eaf99fd3687b35271fe407b33e9a784", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 112600000000, + "fee": 0, + "recipientId": "AYtpgFgBb7FJL88VBShq1GtBLoGnYBzLe2", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201d96f2acded9f3d609618ce34f387c2bc46402e7e14c7bca2592aae1e00562800220593d7ee4b3f97caff848c38b497140312855d9df2f007b8432c69b43182462e8", + "id": "df619578c2c85a4e2a3f9f41c7afd5992439c5a60f8d17eb3ec7a9ce8b23c96a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 114624967068, + "fee": 0, + "recipientId": "APR5muHZocUvsHqfXt3Y3QDuYLHHgiRnov", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fa7873fc955e0c2de2a6591ecf38fd0252b4b25f83c92b6eca220dca2c593e7b022007b86133cb60ece69909502ae21d7a5a0fffba04ae88522ffe15bebeba2882b0", + "id": "877ce4b295db21844c7dfdbaaa08571c2a376400d60cdabc9af1eac7fa2b591e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 115000000000, + "fee": 0, + "recipientId": "AQVCqqgTRUDR5NMaBBDNxgdpwxkZbtqGxs", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202927f829fea3a19b90b2144407b9a268daa489ab146c08106be90c4273220b960220220f2de203a334b320f9852c527e55b8f595d3175e6b78c2650c27487bcde63d", + "id": "0674ef83667bbf5c4dddc21c122777e76af7abb6ff73337b7c1f87231573e3ea", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 116000000000, + "fee": 0, + "recipientId": "AWEHZFuvK2sucehMNho7bFgs5Kct9MX9cM", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022023e9e21d3126edf7419081dc3d8ca781cf08b4f7a6250536859c4161d848799802207e4a553cc1b629c4727b4c3fef627e8fb592e839c80997dbfe631a08313f84b9", + "id": "aaacbb16a6a80d35c49796dd24c5ec944fa8e78323f7df908fee895a651b59a1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 116329005231, + "fee": 0, + "recipientId": "AMuZTwvJTd24XdckcZAi7Qiy3pMoitZLHV", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220523323f28caa94c93362d327129e8d3c4088f9c577a77e9c905464c5ebd04b1b0220705fe7ff0d17f52e3370d10be916af09ef1883614c76eec9899adca018888445", + "id": "7301a48380a2745cfefa1cdf1a2ecc9edbf70e619ef97440092bf80e8c392440", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 116897017953, + "fee": 0, + "recipientId": "AdFmnvX2noJxbAqXZvKKCRV8xewsq2L8mU", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a61b9e09531ab70652d5a188994c291247b3be964960448ba1fd0d21668d7f2302204d856caa8fa3ff06e8b91c69f5dcabc7c60e57d8b342205ce03233682b109c06", + "id": "55242c764f2a4cd791545e8b71cf09b205b99663760874500a814a942070939e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 118387830724, + "fee": 0, + "recipientId": "AGsD1iKAnYqa7q41f987DzMS9kVmuvMB4p", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b982e36000e67d68c16636c2f869d138f69612e2a2452584831d807bfd7e2b69022061eebe290b68359322fda287642ca41864a581bf666b74f998796b7abf418c54", + "id": "9c19c864bedeae508eadfb014a1716c8f6af01bffa05bde44a35e9400fb441ac", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 120000000000, + "fee": 0, + "recipientId": "AbToFt8MRXR3BmKcC6EpnEPWaNUMQzr1hz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d94cf00a4b6aef15f3243dcb3d68afbad70558b3928f096622eba887da94af4e02202d306ded93a5b9e21cfa7ed9db16dae8b78ce51586f4c6be5dd0ff69c379fdcc", + "id": "fa35c7b607c02653d4c3856476100bdb65b0af57df0864b0173da3fd370d1bf7", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 120000000000, + "fee": 0, + "recipientId": "AHWWoXDCa9RSeB5d9BCS2krPh6TzxUa9b5", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100af2fbcda194d173772c91a90ecea2ba0ae32aa24dd7a119a5cec4b92dd348a93022073dace8e3c3fb62051bccda308c1e80650e39ddf6db74cfbb1ff554fe5dfe773", + "id": "d96cef527759049343a6ceb34e973a6e873cd89ffdc0750dc94a9b8b11602c38", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 120000000000, + "fee": 0, + "recipientId": "ATqYMZ7zmQy5f3DFrPKaMZjiPVpGAjCWae", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220176a3dafb595afac283608fecb966d35be5f4ea746ee54a61cc837732b368f3d02201df396e59e4947dac9c31c0f6e3596fa366b3d6a1b537a04a3d39bd5b2705911", + "id": "942882235103abaf544d21ea54b7cd466fb9f0eccf13db858af4cf254444cc0f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 120100000000, + "fee": 0, + "recipientId": "AeEasb3UFnht7FJiYqFi7csnAavnTwxUHG", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30430220608fd2db9a7ab9160e8071694506c793a63ef0b3a70970488358a661e80e11eb021f6ac85f5fb747484f5cfc189b8cb75e2ae8a013b9f9f2f37b96ccd1a5e21f01", + "id": "5b51d62552fa2d44563a09c0e6b1e30610ace3fb9721fa24499cc19d6252f8a3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 121200000000, + "fee": 0, + "recipientId": "AR979mGe91DMX9dUPsKvEHhru5hc2aMqn2", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d97b547f60feb499b52f9b613366eeaba66f8f2675d7e1faba52dee39e3142810220617a00281f0c066eba13a80da45ace50b6d94766a50d0b975563c2e1617cb1cf", + "id": "03676f15ae81acf829753f2b3ac30cee6d4749a508ae32cf104124b9a4f612c6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 121200000000, + "fee": 0, + "recipientId": "Ad6npQratXMq87v27PgmpKfK9aMvmWTjSs", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022065eeb3aeec85e090ec09e772ed5d036d0e7521f09db0310e75622c0bb8e96c87022061e5b3ed0e12e3077522abcc5d15cb07a2d261d6fec0e59622700ec4466c89ec", + "id": "1e2ea66e2f12b91bb85d384b483f8a81c349adab4dfd2d20fb1d26346e4ceed3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 121200000000, + "fee": 0, + "recipientId": "AMeyqtTonCYWt1mPJwd1K2FpnHcPjCVznH", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b0d13c6cfd44a8e186e659c23a2af522cec69a41b8e28ea6a6131bd12795216402200a0a212cda71ddcc26629b53d7f1d6e455b99e8fe4bc8f4e3ddc29839316a82d", + "id": "2f27ad44ec7b4c1b612fb27a23a4d77e9309461f72c5613c1ccf60db7601e833", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 121200000000, + "fee": 0, + "recipientId": "ALvhge1cucXrjdpnMozCDaWM3C6gm2Xm33", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022059d6b72bf48d119e8e18924861ccd754aee7e71d7d3010daeba835d2b33daf8e02203f0dfc75e84aba60c389eeaa7b8cb704c5768e58d0c3e066004ca01b2015120e", + "id": "b46a24fae79c4b7b18b368b357785eed4efa908b0170fc0c955365d9a8764b31", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 121200000000, + "fee": 0, + "recipientId": "Ac427bp1DynWsNGXCCYwWXseyUCYMWr2CA", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100df366d759e02b5345ca59b52de2bcab1906b78729c65ded10fe89c6e0daed4c602205821d77a90716e943ddf58c31392f902c7777e3dbe69bdec5198bb2796c17a4b", + "id": "f5c95f62953e9c219850a8ae44c468d3a61fabcaac19446d99aefdf72714f32e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 121200000000, + "fee": 0, + "recipientId": "ALHBQuNjrFx3i3PgCz1QdkWgAEwX8zQ7zy", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200c9fa69d5adfc7f6c1a6dda8dbcaed58135738eb7e20975bf457cf288a4412fc02207be43c5bbf745b851bec3b076291f3800c54388da527b24853363b0c8144f0da", + "id": "190f5a757ecd8332701afd35805f0ab1ade99cd1aa3a9169b0fb9f48148e6cae", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 121200000000, + "fee": 0, + "recipientId": "ASn5uzMgJxu2bu54HGiKE8D64ZpkhXrPcX", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100bfc41e8af18b4505ef221990a17ae16c2be5e9ad554785523fbcbfd5393f006f022017978893e82ae7232da47b6ef37334bfa255c94cc19e9dcc8de51659b4bc47b9", + "id": "2e80037c72f52d9caa96bc27fa934e662be2497852c6162a50ea01b2487c5b4f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 121200000000, + "fee": 0, + "recipientId": "AYmpwBT59ZpMKJCUcsKxjCUBYfGb3i4r7P", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200b5a383750451bbfd892a9c444c41a029efe9fdddb40acf604851b6cd623ba320220129abddee1f38206fe9b688715471242f10ddfe99fff3717bbb0e17b5a43c071", + "id": "388d78941ad3978004c95a6507737c08e6b2840f1de9e054c215a1c800827c16", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 121200000000, + "fee": 0, + "recipientId": "APaWSMFzp9gNr2RRqwdGzMdKrf5rwa3dNV", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c69b404bda50b119d33763cdb23e3b69bdcc387668458dd33253955247763c5802204fc1cd9a805cca13f1c62bc706393a2f2e839a696afadcf528ca93177aaba237", + "id": "1b24b82d490655834aeacee9d6af2ec815bead657ff6405bd6cb29ab19faf737", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 121200000000, + "fee": 0, + "recipientId": "ANo6dapr6rCMDTKjwRzZgWUtQgbbQ1Nnz4", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fd106e25de0bd3b3c1e6cd3dd1f6b49968e482fb015f00556ed60a3853c2d576022050e02fdee6b72fa4c6027c17f8485e395391b9a342a6e212b064c0cc27a47aec", + "id": "96834d445ffb6224915b81236804f1a6f4e5231553b4019d5b9a9806afa632ed", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 121200000000, + "fee": 0, + "recipientId": "AWA6TybTgFiesGDtCasa68Jt15QP2Auvju", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203bc67263cf58ec7b90c524dd694b06184f705dc7a206b1e1a1a8fa1dd29cbaf1022049410d87332f9108ec487dcc2d4fcaf52ed36867b05e4b4f14deb94006e94802", + "id": "176a70f81ae2c02db9e422651bfb9fe7430639d86144b94a4f28585533403cca", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 121200000000, + "fee": 0, + "recipientId": "Ac97FP6Zt5mUcz8hRWRy8QgNRsPCxs7BaL", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202d1d32121b5e7ec0fcabcf04ddf8da303b4e3b5ffb55ab9ec037509f6d4df29902201526e223d63a19013b7e44fe44879ecaea07baf2c45ddf13c1234ed9c5163475", + "id": "7b50f54fb15fb3cb7c7c2e5b1ca1d241c37d3c10db990db87534ce366ea94d3f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 121200000000, + "fee": 0, + "recipientId": "AJEX11r4ECKF3r14KxNMwzLT29omPCtGHA", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022035208eb90354b15269c5b1a97197ef357799111600bbd313afacce965838eae10220036a346f41e67380824086cbda241e058dab979994c171be6b9f633ef4c0300a", + "id": "35242f8882db3e61b508761316879c32fcee9a5677bbbf23c76c731cd68b2cd8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 121200000000, + "fee": 0, + "recipientId": "AQ8PPGdBYLGPAiUjpo64YAWCyPzsUEEBvM", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022025cbb2d13fbc38c3de8cd8f134c41eccee79f133e78c83091888e4e1460f998402201abaf01c324594b4a3e2ebacf46c80ae6609ccb8dbc915304d0bb907a08a7869", + "id": "0889d189eb144fca050638e158ba32932733b39352998d2cc9307b4cfd5ce2fb", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 121200000000, + "fee": 0, + "recipientId": "AKhaX5DPoz59va7cMYhcUsBEGLw73S7524", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205c29cd985cc57d5dfb9cc47619030cc11860ade66201f73db301a411dcf8769802205329981e063b8f671cf6584bdf65f6d9ee12d304d4b167399d913e1e3fa3a8db", + "id": "2edd2baac328384231be9165095f0553378679aea26eba5b149e3a54303f5fae", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 121200000000, + "fee": 0, + "recipientId": "AN3u3wzJPUEbKkjRTW7JGnZwHj2U8ir1s6", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e2cb4fb8a510d122ff54873ae69f3ed0e05e5218f16caf3e10c719a46c1f493e02201c2a6640e6904f68a9ef5375bf4d3e0a568a558a088d68087071f09f34206d61", + "id": "85d4a553ed41bc54fd93c81ec5021a23088be6f50aba0055270e382acefd98cf", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 121200000000, + "fee": 0, + "recipientId": "AVL35iLjeDYJFrV3YK5kPHHijJcHbzGqv7", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200acc365ced6b1cbff5d6d586f373ca5f9a193a20de02ed784c2ed0969bd33a27022033ed50bc892f08d837f3e38ec8c3d4b2cff4ad2ba148712667870d7615047b80", + "id": "122ae3a92b89b6c5cb1234075b7e5415c0b284c4ccdb66a480cdc47a6f45591b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 121200000000, + "fee": 0, + "recipientId": "AYxAEgAvXoifkzMsN9P8nmDGaErUnGz6vE", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022079f8b805e20edaa4f0ee8e1a1136ced571a1a964c49f678ea4ac945c77aa40ad02205f03efae06c98fe37f8beb0e730a0f0b6cb5473c70fe0f5f03a33e71699b4816", + "id": "9d1bb9a20498867f18e4cd28d56b1b6d0330c78da178d3ec2a9ea776d657300f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 121482157847, + "fee": 0, + "recipientId": "AXdk1YaWraKLT1he2N3LW4aBaZLyAiyiMW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022036f7275a99c91e73aceb5d904bdd1aff19007fe45aa3c1d926170e9883134730022074df6932914e893362a8f6473bf32e1eca016efe823a02bb9fa3d9ab7f64c6a0", + "id": "6676dc925e0257740d79d42f4963e30cf1451dfe23c282732f9b2a0917e7fda0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 122958047810, + "fee": 0, + "recipientId": "ALHwE12mF1DbBNZCTxcPRB6x1om2bRnQxG", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201484a2b3a9bf798e204b01eeed2d235e3dfb11f9710bcaa5c78eb984c5a4cb2102200cdb0f5f44d445cd495f20b75707927abb3115b84fa1c95e12879f36e5d962c2", + "id": "50e3e17e80a61446fb6a9dd016d3ecd76d22014721416802fbb8ec212f732255", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 123284431502, + "fee": 0, + "recipientId": "APMwQmexasWJwpAyLZoDFYWFSGUamtNK1J", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220310d6c899dba99be0221deed8077220becb9da79118276ec3cab9226988e9b72022048bb5ea38ced208e1cb6d065248a390ecafcfc6aefd19b8f439c515132768603", + "id": "817ab6d80dd709d55baf1d885b47d8f83dbfe0009f8777dff77500745797fa3a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 123492648017, + "fee": 0, + "recipientId": "Ac33gzmvjrrbo75WJ6WVuuMYchi2oSG2cZ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022011862523ab035e2600fc17663721256caeb4b54de512cbb7f22064bfeb6f306b0220586576a37ee87ce14575e8e440aae35c6b370bf8ebbb3d220337395e4da3a127", + "id": "fc0ba615203b330acb7946235f7f4bf01739cf6847e07be0d23d5218ac106d03", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 123626298069, + "fee": 0, + "recipientId": "AePe8p3H3wqiUUJ7N63aR4tSiSkxnA8Li9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022023c78ea21b06e95bbe80641f27a39ded89ec17a2ee2c8f5be89135ac4098a464022058ee31b7830ed287622216e2c47c34c6fb1929b72917b3f95de4c3e1cab45083", + "id": "5776ccefa14dca3370b26abed21365f1ffe65228a6bf5b25631cd39c461d14ca", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 124700000000, + "fee": 0, + "recipientId": "ALL3T4hBL5Hy6N1ekevdHuK7c8SCoiKmSy", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100da7c3cc5cd62b428639c066eaf88fcf3fcd60b69b3a6988d1059868aced0a0b602204a2f5da3d7958c04d3edfd60bed8ce37a862ca10238c5175d49f8d994f4d0462", + "id": "b44e7fe2d2a0491576054ce4b6df112eb422691517c896ec9000e642d057eee6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 124700000000, + "fee": 0, + "recipientId": "AcM8Mm1xZLsaQ3C1UrpKBGETTWL42n74o3", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022051d19bcc61978325c50456ad68fcba62f75356d48611b6922b7b3386ecd1febe02204e16018952ec4bd29530eca80eb7d1485b279595524a69c77a199b7795bf52b5", + "id": "dd34a901ab4d46ed7f9e4b0d9e4ef54e36e412d1e0169c63fd5e6479c9f49eac", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 124700000000, + "fee": 0, + "recipientId": "AG9kM2jLaRKeTdRiDBnmHKFvEodwxkyns7", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ed04ff01b76d87858b06a9b4ac1fbbf452f237f3c89291ccc2dabf2ca2eae7650220307fbb2d586cf040baedd8a96b0745e7c5bff914ec9a36c6a9ecc1db28edb430", + "id": "f69027b2324e43c68a23e9a62a24689315571342b63651380d620e0d747cd561", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 124700000000, + "fee": 0, + "recipientId": "AbJe8Q4PeWXGd2hurMguwVe3BLaDHfWRcR", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206c292d5bc621a09520136d3763e2ea99994c92164f083317ac7d4d84ad67c9a7022064fce43058f8d19cdca3d633fcc34429086211c6947d4deedec92a96f5d72e7e", + "id": "d6b27e61b96f4a4e503454f052fbf313559f9317694aaf0e3b17f9c12a84ffcc", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 124700000000, + "fee": 0, + "recipientId": "AKm4VdRbpqQRxNUatCuHz6SaRGTatMGUsD", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100dec71fb87031a989bc6dc3f048ee308dbc97ec349a45861efae3459b04424b2d02207a5e5f4a089bd56368ce0cf6a83db247e9a8b215c0aed867dc83141ddd81894d", + "id": "f3cc88247afdfd0a8cab61e339840363c7353287cb76043acaa613f1ee5e8555", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 125174485431, + "fee": 0, + "recipientId": "AUYnvSaH7v8kU891WuBGDA8XraJnqfPft7", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210086f778878fc1586963bd8994419927a9a1f6c88f899c5f4f19840b2c42dc559c02207bde1d3bcc0f1faf3143b3845f6671a90792bb2e3ea1b041ac9d80a5daa02615", + "id": "2801d176b91ba63de86b0332a26346bc1e4c7a8a3a967473e18c09e559965121", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 129540204214, + "fee": 0, + "recipientId": "AbnX6Wyoz3d1LLBdY4pkYmRXvkv7qq57Nw", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200d2330b9edc3faf556ae66e1c689237bb630dea023ccaf3037dd706e7a9e34b702203ff844c9710095e75fab94dee0d6f15a2c233a4c05e37a593008ff36bffbbea4", + "id": "0a1e802ba4d8543ca30911f77fc551ef666486b36678ef2132ecbfee416331e9", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 130000000000, + "fee": 0, + "recipientId": "AYxWmuZJwzYkjUarmquFoHjG64ityMAwTm", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a55652d4a247e1e536a05ac2233c5cedcbeccf6e8b8e701af2bdb07b42a72fee022058737e0837e904be3c969f81e9622890bf7593604e8ef6ee19aa592ecaed0088", + "id": "3efe48cfa53baaacd2e25059d104d656493d9fd13eb2e8acb508db55db7417dd", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 130000000000, + "fee": 0, + "recipientId": "AFyuiPD8r62cdnrrAb8PHdiom3ZgUZsFQb", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009f3ec0907177655f8d54eb4eba7f2c96a3e86f239a914401174b45319c482c99022051c830003a1111109f2f726fb888107ec30c5faca8f54a34a078c4831e62ca0b", + "id": "7a58e80d25d0d063bfa357729ce25b66b833107b74beb953899a4724e981d47b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 130884887397, + "fee": 0, + "recipientId": "AGDxH1FYXf3XrL6nJ9qhwmGeri3M8hg7dM", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201cbd29a31f62bb30c95fda9d78c8d860fcac3939f39fb7b5638257d429bbc69702206cec558ca827f47711b6b0685b37a571487840d013dae31e95dcaccc31c0d82d", + "id": "218113406ee93b29cc9cd8ebd40d51df6eb6b37dab860641087fb2990dda7d88", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 132401763390, + "fee": 0, + "recipientId": "AdFxLwoJ8JVWW3zpPWkvcpTjbVtawPhh1L", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202cd5cd7114a86e5ea04746d2a44b1daf598749885f03cb8b69dbcb95e8f7591e0220062c9951b5f1476594c34f7bf9a47bb637ea83e843e46bc070ef8f80fd20112b", + "id": "21589db4eafcfe26a65312b727f705ba20dd4403d8ee7fc09dfe4722005251a9", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 133300000000, + "fee": 0, + "recipientId": "AVzze8R7jrAugNCcUDpS6gvtH3jLTBApfK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e575b4d782d64bfd7b3a5208a9b0b36baae254418f704ff71a519be9e33f4504022011766b87c099d21616072efcb5916ae72965886276837b08e8737ec00d20f691", + "id": "f0d6338a6ae19444416bd44a0a194c4dd6043950bd0488187c2ae522f0c9cec5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 133300000000, + "fee": 0, + "recipientId": "AHiw6LhXUDksaQkQ5YEys4bR3KQUpShuhK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220336d5cd425f12d9aba380a3112d53d3d7c8f64adb9ecef94f69e6b42afec87db0220521a58fd1b62eb89abaf64b5ba8e79493ff4b146fb9877ade991119b4d5096f1", + "id": "01968fa393539a33b61a61e9b27f6c666dfc9a75618c5515d4fc0ae3e5e2f7bc", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 133400000000, + "fee": 0, + "recipientId": "Ac9Z3Yq7xJeE2Vt5QcRPDmuaTS1FtypjyC", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c041ef867527f600f1c23510313ea3765322127147262b2137a7fd6ff8e8ea6002205d20cf3486dc1e2604b447f5cf48b4f1463c0fb8e2a5136d4ef43e5017355bbe", + "id": "fd69e79e125889c7e18e4ee6f3b9b6a6833185dc560cb07a24f76523911d9e87", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 133400000000, + "fee": 0, + "recipientId": "AeWazLDW2wcTR5tDFoThm96tZFVKvyg3Xw", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210094396bc42de431678812ed874f45e95dca0c9a28a3e67a48530f271fe1366c6202201aab946ee2c25becde260943d413a6b70e800ab2ec02bacfe6cff415c439a7eb", + "id": "99cbdf7999737e6e3ab6f3db168106e630e99e78c7c7f6610acc9cb77d9b74f1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 133400000000, + "fee": 0, + "recipientId": "AYKHBz1zZ1dQjpfBu7jJforx7wqX3MSw45", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022066f06afd81dd1ae22a41c79ae0f8592333f9a1f40d0dc09a91fc81556179ef6802201c0fb882cd5d81ef77ba6b1bca9ce4a52143fe2cfe9c06d0c4d1b6737d27b42c", + "id": "ac75980be3c16d88e18006a739c0405ba62ff7e4573297509c22799f36648090", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 133400000000, + "fee": 0, + "recipientId": "AGytj4HN26YqbqoYy8bVyAkHr5DBKqck5S", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022000cb76109a01edf4df270e3a942744877f14f08c462e21f48a97e8b401d7e0e00220497ef0efaa27f2b0f98ded7c797f897411629d2500eb9541e8450e2ec4a85b75", + "id": "dcb55ec4448b657e784ffce0a845657369bdcd31ea3118c6852f3a267858dbf5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 133400000000, + "fee": 0, + "recipientId": "AKv5bQtqcrS1NwWM744ApRXLGzxq8th83Q", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022000f10c1b56695f77a65301a9c63d16f2c6a984a921b4c43a1087e41362db454502203ee4bb6a6f6fec5cd685966c65e032b9dff460102e35423f16d677a98d4d9a77", + "id": "da79fa8dda0f553b25b8cf289fa917a8f2b3154d16754749c0beb2c0fd541909", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 133400000000, + "fee": 0, + "recipientId": "AW3MKtfA8qu3WyuWf3WzZsXyNJj4T9t9d9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009e8e61957950103cb3dfc4dad5e18efe80e1f1e4974d1c1c079122ec080087cf0220209c4741057ef4819de778e3353b58a0a9fbd45013775606e3eaf16f91b4c22e", + "id": "880ffeb2284de4b16dd38499fc6fd15320071d08a0d19b1837a1973284b44795", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 133400000000, + "fee": 0, + "recipientId": "Abe1tPmDJ7a34syYde7XCkdUfAGjPmhNyD", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206ee7dc450b5b1e60271ca2172e1e1c26b23d6b9e163bb8ef819e4d7a2cc3937402200b5b7687c82a928ce9856cc9d452ca71e762053135ebd791bf09e1ecf2f1d94f", + "id": "436a0eb389e7ebb2ffb7215e10fcfb90b707f9a3fe08b46b4a08e53919106bfa", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 133400000000, + "fee": 0, + "recipientId": "AaCJwF1eVDGA3Jy6MmQ8emMB5LKkPFhqPF", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c319ac615e8d54a36c919e40e7a6a77e534abbd952abded7533e11a1bcfbac2902203e9a945df2c06505823ea920839528d37fe946ec8cba4c75e1c2bc035d1e0624", + "id": "65451621e425a1118c592029a9b6f47f4635937da9640edbbe2aa7e1531b032e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 133400000000, + "fee": 0, + "recipientId": "AXYh1dUhBWumWF3Saj7F8UH46TqKoUR4oq", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210099fbf3734fcf70371ee259534f82e2ef84a37b9000b254f7bef53e812afee3a202201c0aed05b097804fc2e6103c996b323cd0d1a634d2bf08560d1473cb19c98583", + "id": "0e8d05444ae15dbb7cbfaf6ea4d03733dfdcad333267f9e7e7ed18f5975bc168", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 133400000000, + "fee": 0, + "recipientId": "AFzhTRcF1mdD8bswGM4kjyiAbvHFZ3utDf", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a40e1a906abb1198a9e6749f139169488103f6a089384414c228a375c3697c28022045e6829b51d7f3f0ffb9e6f27132aabb8c13c5612d9cf98b2bc65736d3bb7d6a", + "id": "53b7a5d15d2e6c5d4b977280ec050e8bde87040748e5b25901459f139c9afe46", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 133400000000, + "fee": 0, + "recipientId": "AHj3b7vTcrvS81U3xpWT62G6C4jVBpXB9z", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a226e5b1d830f56939fd2b860c004c54e6f49260ff1400d21509c2e1f6c7404d02201997e86e6cb516c88bf6ffc7ee6cafb855783954fb8e131bd65561fbbea8246b", + "id": "7bf54e1e48b45d11b86e06636fbc78f412d46ae1e71b2dd24dc3474aa6290dee", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 133400000000, + "fee": 0, + "recipientId": "AUjtjkgdiyEpuByP1uajKuT2HSeb68iq2K", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220415974bfe952d18dc3a26a966b9d7c63993568f834a3bed5c4bd08784331230b022029b654a8a4b0da40821d6a63dcf40fb325b58579041008ce1593aa8f1b785d09", + "id": "cc3fd2a9da7d622e24a186044bbe5479ce94cf75be168d9e2ce5a950853648b1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 134701272086, + "fee": 0, + "recipientId": "AGyWeMScLefasU8tiewWRkHBeqvSeaAGii", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e75d0bf3d62eea3631a95d6bf61055b0006c0ca0f92007b3b178e4ae82bcf5de022065d1c1c26883926792929c9945fd6fe6cd1054ca716113d146598c669f8b7db9", + "id": "2b80ef415bf5e28b1cc9b5fdd407c3005c498e6ed0d779defb5386f12a145b05", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 135000000000, + "fee": 0, + "recipientId": "ANZr3b2hPsGwTtVgNxpvMkyZZ6Vg9UZkrx", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220774c16ee61fb32555f68f77aa42d26f4df6689af47415876105fcc44049d00f0022026855b61fc8975aa07b518e0b4043f63f6e4e10936b25266754dd50f4d63c014", + "id": "70a85c890f419243809d0fefe37b7e6a03f73d859c8cda6f59cd34d1b7d67a5d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 135100000000, + "fee": 0, + "recipientId": "AHY7L1v8LzmNke19ArEgzN3tocigVaAzLX", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204ea6f57c6dad7869ddae0d8bd270a4f3ac278bf5887bdcf587ff4f083013e322022032a61c4901116e5714560a5ade681f74b41cb9947426384ac2db55df4004131c", + "id": "a5bb75d5aa8aad7955555060d8d43eaf3ddf39c0b7e43235466870752a8fc283", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 137900000000, + "fee": 0, + "recipientId": "ANAL6hHrK34Jy7v3YWGodsJcb3Egau8UcW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d12c766b40589e3c976e03c5a0ed64a8e44c32d3f0b1366051dd37bd9c6043520220455b383091894c83178c0ff07a45108abf5d442fa44d2dee6adc8b8cf884e018", + "id": "95fb3162c8f7beb2ab5f6fb61666094226db627b460f0d5ed45a76483064e6d0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 138600000000, + "fee": 0, + "recipientId": "AUArTLyiUVrf9h8N5fM4gtv3yeaT7sD7pt", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e4f07b7c14b4136b62ba30d4dbb23ef7c34d0b5aa574b528fc71975134700fee022018350059d6011c7c4310aae232b683b8bdfec4f366cb952c8a71573080eeeb73", + "id": "cce0cd6d09ba3eddc5acde554e079cda7dd1a370a2ad2136bee3da660a7bb6b0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 140300000000, + "fee": 0, + "recipientId": "AKbaSMZ36bgW2jL63Z2RYe221JvEKBJRpK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201e1e2cec556612a736da0487ae900c979093566cb9d461ee5f97c1cb8913521d022059f3e13018c3779000de42972f514a49cd359f1681a8f389d203483c95defd9e", + "id": "77de4c98b0eb2024ba7df54f734d9e0d86efe0250eb4c38921be96039a92273d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 140332554565, + "fee": 0, + "recipientId": "AS4JC75Lv8avQHSDT8aRu4qWLLzy7B8YnJ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220220c567e49b35270e9ad3f4618ce46a1d9b86d8bac6f51f77a561414b1c589b10220287e615bbcf9366ae1cc249f5652cffe72e61bc76dd6221bfb0b9751b359ed63", + "id": "b45e18990b9f754737ea2442fb4ce19f020f9ff1ac5bc083d69e5e24810d0e34", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 140332554565, + "fee": 0, + "recipientId": "AU1Bz7CJhiNYneNYEuBCXPY9WQBwCxCFSQ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022030a79416ae581e874e3f85ad8fac4d2c0ac39d7287c92e807452122a4b18977702205b3d6fc1ccddb6741330366926fd70ed89f160eef85bd2dc161e73984bf7c1e7", + "id": "627b1183a9f109a94542d761904f247ee43527810bb5b32c70c6089121223f1b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 141913175258, + "fee": 0, + "recipientId": "AWSYgoRKRpXfXbA3WpJ8eegTky4SdT6dYi", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d8aa4af8d9f52b9b1bac3b38217220c0aee778de34fa652dbc9d2df182540c840220687ddcebd64e8b0b02aa4e18ba738aba219e0a66157d373e840ffdcb4e3d5093", + "id": "fe7f90ba3d98988a846a2f943017bd03c475625ec021bdf13799f8cf7ed70b89", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 142400383746, + "fee": 0, + "recipientId": "AHomeJ2mZdS2HdBnfpznUGWKMdnGE2ZyBi", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ebc13c20a25aebab60d043e3983faeac70aea83008e8531afcd3b3aa986395e002207e37320b8a5085c0fcabdc8da57c7f67482b46847251beb21ced9096858d67a2", + "id": "73f0d8477a0a9691839f121b8a28b86f9c3a0283e60b5dcb57a74256ddc19c1e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 142597922946, + "fee": 0, + "recipientId": "AbCmk7JqsA2oNHjSxs33hwEwm7i9ZGfNTc", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ff68a3af0a8400a3f5bc2fa933df079aeae3cd8a33df0e6d06883b8bae604f3902200618c92f102ae967f90b5ab0bf2f17d561501fa6b0e42069cf958f58f10131b9", + "id": "1b8a6a9805b7c3a9185eb8692d93bf0130f0c090decfab0f25f33748465c34fd", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 143671138618, + "fee": 0, + "recipientId": "AKpcMURctYwUa7NFWwQbHMPShAmGvZxTDk", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203de99b3f8f7fb93625f52d07e75e9735674757e5728a0833e282e21887c399ff0220665f3516be9e94ea507964890dd5d1de7d0829143401ef78439503742444cb45", + "id": "ef58d87117fe3cfb73ed87681ef9df9144ef889a2027ad85f341809548a7d69b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 144747007068, + "fee": 0, + "recipientId": "ATw5aBDeZzzxdz1VhJH7zjYUS5c5m3wWcz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022016e3810651bdd50d22b4240aaeaed98bc01b383990a18711671e27fc1c2bfe35022027628ae55345065e5f4e21b462408a9845cfe2b3d9666506017fda87ac6f7e07", + "id": "d068d9b75cf07209d53076886c817de5d449938fe3fcafd31828ea400f4fd44e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 145130623474, + "fee": 0, + "recipientId": "AeReN9UHpbqNqA1zRP3My3iQYYw4vBQ85h", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022076fa46b96abcb0ac7b0b0b9b5c8870269edaa7b4a3ae4fe75585837c73c1194d022004e5e214749129ecef9fcbafd06325ec4645816366431199253fe349af14bf86", + "id": "a784b1ea1393c00ac0c8e58fa19b9e137f1e8611a4e8f81f65660dd36b4f3882", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 145500000000, + "fee": 0, + "recipientId": "AVgLdwCZLBUVRr84tPzwgCPLcdDRRTvkMd", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206d398c5a3c63f66e37216a297e442d8eb490c67bf99cc0a98c5680d9ddbe2933022048170d0c7dbe5ef0a30baee4c669579c1c414fc12cca94af65adcd40e90e2d39", + "id": "0d36bc9b909f51dd5bed75e5022f632bdf8707268e74aba53f8d7400849b49a4", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 145500000000, + "fee": 0, + "recipientId": "AVroDA7WnnpRhsAy9187e7mRs3c9p5ADoF", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201e8248c25c74669b3074a5efbdab29b715d4d796bf1b139917634cd27b72b1280220184b4d05880cabc910f372c43c13fe5f3db2540174993467dadd0bcab4c84873", + "id": "6277e6f92b5b75671e07fd26b28a16a82038447cd9ae5dbc4a8a525ea2969204", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 145500000000, + "fee": 0, + "recipientId": "AdQNZMDMYsqUhuZ3F5Yy5FvUsdRDSupxEP", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009b106d35d40c34def24a3af078288ce38a5c42374086bf13c1d43a354abd4ece02203797da879995e88f71e7a0d04b65ab17f80d073d0cd015bec58f1f4a5bac25a6", + "id": "a76db685b5fc59e38d3e25f7c43cadca9f35dbb079c8b5b73bc8da3066b501cc", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 145500000000, + "fee": 0, + "recipientId": "AbWS5yJ1gwx1GhpaTYDQvJSy3bCFbA2vpo", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204e1ff4b27c8fb80dc2427f493822b570600fab317cec5a5cb53a58e10769b6b202206a7dc2cdb7785ae00ab6240db3da4abcff95042a33f5c620e42af976925f2c73", + "id": "560771be8dc4d0c21922a7a57b7fb66a9b20803ac8051150cadb54816086eff4", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 145500000000, + "fee": 0, + "recipientId": "AXfFia87jEauZWU6DJHRbECKk44EXSQmbY", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d1ff7a6ec56fbd8fa592c687ba088f198d0752abc667ef957dd2c2e40d9589c70220218d36c822d70d25b1fe3c0ecc1efe85671b09d16765a93cd12c20b45f1fa6df", + "id": "63d81828f4c3e1455eb6a1aa99ef36b241b5fa9dd7c5cf86c92dc8781df88b92", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 145500000000, + "fee": 0, + "recipientId": "AJCWEe6hRQRiCC1gLdS2TUSbEwUPHxMJcn", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205b1550775c4cf879ec7500f8eb3880a3ec9173db41a7e8e249db14dad79a0d9902200cd06919a283c00dca6cbc647f1f09398dc377c8a4819db6ec20458c55a4affa", + "id": "ec03b808b1f705553a333f882008acb5330f3fbfb87eeb64b7879f4e3e9e013c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 145500000000, + "fee": 0, + "recipientId": "AM3Tdmm7PajytJqccZvjBmK2aNzfkmVNay", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100cb1a88bc254deed2de2aaaa7165c62d8ac24599cb716cf294fa7650d731c7cb8022040c5516b3945d87eb5bc4101ad5fd8e28c04a86a2475617d43611793c2e7619f", + "id": "58ea9d0e7a38ac86f105406e615eb08a288053f6be10db870a126b4d5b1a7558", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 145500000000, + "fee": 0, + "recipientId": "AY1tE8UrGCykVngKVmmjZfes21arcLLyzn", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d0b69b396392afd07b737fc4aab7262c5e693a61b4869afe53696e1d72c159d502200de0cb71068602b2552baec25e1d3421c4d59526c01a99bc3475abec5f63bd1c", + "id": "2f2c0ef7895193de3e7405dfda9ded41aebf2aa0143a3870f879800ff3af4a6a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 145500000000, + "fee": 0, + "recipientId": "APAFtJderG8gJDUr6avxr4thm5a2hrYk6q", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008d43e939b9b3789b1673ff939519fbcdbfcb6746688d1309318b2bd12f839c8e022009e186c21fb9d2963e2c01d863058aee90c9eed7349d3243c900d606cd7f5163", + "id": "d9e039153b8d06ab7b1e3fe64eca9bb917bd7a7c848eeaeda9f8d2b28d24d5e4", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 145500000000, + "fee": 0, + "recipientId": "AMFSfB5sy97Dr17fqAF64G93pxkSn6mGqH", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022005a7f2529d9264b887d323228132518980dc91ea2d0cd5bfed098b8f05b31acd0220676c8d86fe6be5a7fc90ef3ac2db26674377c33188b694e5106c36850fcdd5d3", + "id": "1f7ff73bd0c0b6c42a73499dc8948ffc23a5affa758ca17425d60d03f0e3c412", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 145500000000, + "fee": 0, + "recipientId": "AQ5kzJMSeEEr14YkwoTTGpjj8odwQj121R", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ba6df9e0ac6c1db0a889bcd3c30460b2d5460ddffb7867652dd4e0fb296d9bb70220039f2b0799cf13b3f9e5f4f950afb53c12c72ae1e6ccc15b6c86aaba0febd322", + "id": "39afbf86f83389014c2d00c1b56c215278a7d12f631a10e24615b4c69aab3dac", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 146600000000, + "fee": 0, + "recipientId": "AY3P1mc5878sCMkCFmJdEBhMXjzZivm4rd", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c563a228728d67c90cc13501efe0dafd97919ecec25afc4e56c48c9289f0d85a02205c91587eb8001188c7e291e0c851feed13f6960d1828b7fdc6303fa49eb08b41", + "id": "a1ab69f665a37b685d9219b051428f1e9930a4e8bd908623085b1cc5a85a7a37", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 146647519521, + "fee": 0, + "recipientId": "AVwxCqG9GamW79Xb96S7ipWUpxLgR3shoe", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009d426ec91319147e8ce9d95e7f4a2bb2ef20ac1a93c4b9a79e0a45b555aac9840220470cc4cd8993fe92f3e41ac71027ea68d6dc5e873a4f5f4042d2f6e03fea61f2", + "id": "6b19fd28e4fac7c60537e63d10d0bfeb1ac28eb768db7c05a0eacb22ed0c945a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 146868042106, + "fee": 0, + "recipientId": "AUALn8exeu8kXARs5HVxay2r8pmSmxMVdq", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022038a92d978af95b79d68342d7da3d86e0de7ec10fe793b87e15e889f962f78bfd02207095fdc539244f346eb46a50d00a5a692b0687ff1d6d4597ebc7f2f92c7b3aeb", + "id": "d3d03e03d5bba603521e8be851fbb870e25dee280cf5a1f6fc7a025d84314a10", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 146868042106, + "fee": 0, + "recipientId": "AUDTxFyejQZcR5bNSXBkoQocuoquYfChG9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c460859d8d9d4a18b8c336b5345adf8023234c90a0d2f86836a39ac3b1baacc9022068265214028204e47325d2f157d27c6ac20c0f43276d6df706d4492687b13e23", + "id": "04f2135cee1a37d6854cd0d10c8db0bcc83fd8176833428f8e5cb4b891aeaee5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 146868042106, + "fee": 0, + "recipientId": "ATxUGRxnCNHpafcsTQAimxEygTJEb3syCy", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008b9f09ada3004e0b966f2a208bb2c938b797b1973e1e8c2b53b7ad4b0860939f02206f08c4caaf1ed0102430c9b2f382f58e6e0337ef8c11ec6ca0894263b99086e1", + "id": "7c156161c977de562a5613d8b6b955144a56ebdd9efceee9e8981ea639e144fa", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 147015057164, + "fee": 0, + "recipientId": "AJeAvhsxGTJQKtd7RHBfmNtCy9fPUZYNVV", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100eba3c97cbd1002056427991b7c33c21336783809f814936183ff030378ed3c5002203c6dd00bfab286353f3565d3bc7be98975a9c8f412c409bf182892043e350719", + "id": "4511231384b91d494dd617db65cf90e99d7be45a761010761b39b2e07cf0a896", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 147015057164, + "fee": 0, + "recipientId": "AeyAvcAptKRxirAwuyLei1YLUMZap6RSCe", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e30b9369318e1cad7ec287448f11e9df997d10d4ccfa1cb14c5bc16f042969550220716c4d0772ffa77db00d076cea094ea196e1bad98aab377b20e87aea6e7b8b34", + "id": "a033da0ff01712d4b8e724846bc0f524a3931a0e268cbe798a006361a6b5a2e2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 147015057164, + "fee": 0, + "recipientId": "ASHqJXYyyKCVuhjs761cz5bLm6wy8nbSgn", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203c354c4d829f755371122ce7249619b2df5a86e74830f1809e977fb80875e5610220713491f7571edf18f009dd7d0a1d4ddd94ba8c53fdc7a1e53596dcbeaff40315", + "id": "86c30a20741f5fc1738e4f0180b64b585f0adb966d414ac45316a879fd5e7fe2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 147165816371, + "fee": 0, + "recipientId": "AVpQfwASwF3WSC5CM7HErLYvYBkpzkTmUu", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220030a63d6cd68e0fcac0e2eca89c14eb6a8832d52efa56e6d1a5b772805d1ea480220091c1fc5904423e14a6137f02d153573765905e76d1c4db66e945ec7851763b7", + "id": "93ea7b1a7e4a623e75cb4245a2ff78894c9f63c9ae4438a2b614350b9f65f1cd", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 147695811297, + "fee": 0, + "recipientId": "AevPmhwSCevsJkXhDcKvaRNQwnG32ygbC5", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d748dcbdd417e023f4e3976a7625d8c7f2ad45644e768bc5923210b70b8e535102203ecf2b3f03c5caabde8ab41047155bb14ef36073bcab9a76b1fde86baa8eb21b", + "id": "6cf7722a4793a9f5134e80853eb954b8772ec20f9e7732b109c7489b722f7c0e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 147792818385, + "fee": 0, + "recipientId": "AYdQPyMPRyP2jpp813PpvKn18rew13EJTk", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c946a710663b006a6065a032f29ae1eb13ecb2864ee79e7443e795a7d566714d02207dde19f663673b881bb01ddcffdc1bb88481b42c7b78058ef722238c3acea288", + "id": "5ced9e0a7ae04dbe285c3087898108f56f6ac791e3650a11c9b6d05c3279f0e8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 147794072165, + "fee": 0, + "recipientId": "Ab2sMHQxXcEFT347HyvsSdXqTwBWcYkiNo", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008f73302141cdd6646a1b0c2be14aeb4e40bed6eeea5ae720ba24d482f45ce1fe02203213e8ed9fd98004e859de842345e8a3856b9a1920608fa050211ea76dfd7cf3", + "id": "ef80b356e77a8b3e18c21b11b6ac09b3f89b7b99f33aa12fa53b4d2ee3f380b5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 148338192678, + "fee": 0, + "recipientId": "AVS2aoVuzEnY74iWsgzfzmMNQfSRc5KTzq", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c6b3c68949296e1794246ebbc64bd06f9f5d099c5a4498030442a6eb8a78d6f202205f0be315dfac6b7647a33934a04df6c40a2e40dd8a17303f0b20bb09c6bec6b9", + "id": "e38e2053c5110aed17e4a7654650a3061ca5441c3a5fd8d159e2140b20d26f33", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 148900000000, + "fee": 0, + "recipientId": "AeNApTdu2Kf7vphV4H2ZTbopitfEchc2eb", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201255ca8ef4fb94fb2a0f9eb089f9f1d48971adcc9bd153835e7df739109fd6d7022022a497a0b8ebc793d25e3348fd884f32cea85189bdae2f66799a3818c15e6936", + "id": "5e76229c1016f43b961ab11b51d4be7598434be225f68ca4347df5106c68b0b5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 149442810367, + "fee": 0, + "recipientId": "Ae9cyMJ32RatQDd1iPd5pftvBjFpRyghhJ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210099179595efa579206006e9b6689f62d222f67a4ce4565508d7dea57e3325c917022009425c7807f05f46406a05f02a8cd70dbb6cd20f7ee172749a54eb21f9fdfab5", + "id": "578b56b6076f8b418eb1df12980143f0ff841890cbdf447b7d1d5320785cd0fc", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 150899497250, + "fee": 0, + "recipientId": "AZGVDCCTnVz5zye3hsckws1AZkgnUdEwLj", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022056e8422f6cc77310114d7e7aab0eba13fbca2cc242a04594af17c8938d7a55c302205d8a258dcb617f878e4b25c84f08d69f77c5575e7c6840028059706635f5bd5e", + "id": "c543394aca3a02fea18e06f89d12e6f170269787be922539139bf72ba173caa8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 151036016000, + "fee": 0, + "recipientId": "APuhkVvG7u6itm8bUEfqDBpw8vTqTZMpdE", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008db754d788749079dadc57c9bec350c02487e095df746ae3e196c566b62edfa50220089ecf52f504b54a6d5ec5da34b0eef3bc5f151d8a65598c07da8cf61dc2524f", + "id": "2a5b77ad3a7559a3b066e6845f41c73b368032bf9c125825f6ecfe7f84a48f78", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 151200000000, + "fee": 0, + "recipientId": "AVJ6FhpMSHC7sywQDJujkwM9yv75tyzjrj", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202a8ffe7a80afccaff07d8d972d11e8af2396f9912171e3fd7ee869a30262739b02205b9785b72fd0ff1d1028c44d29d9423cf3a22a3e5c6514f86697742777868398", + "id": "e1e3ac19ac46f91d4be3977a0e95de5cb136219a984b03b1782243d0b5f2757d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 152400000000, + "fee": 0, + "recipientId": "AKMDyKrWkSbpU3q6oTxuoS7nr6G5US5Ppm", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b12f5c4a7c7e0366f303803b62486f0d6685eb60a873fdb9f15d508c8796af2f02207d28afc1bda7c2af2c650a7cdafcdd6111f950cc10d403fa95132e0bf5669661", + "id": "188f9c090bca5ec2214a0c41ef741aa5b7f3a947cd2cc6ffd51375c837bcf9b7", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 152400000000, + "fee": 0, + "recipientId": "AR5yuVPejTDoeHhfbAAYBMCoMPWfT64wS5", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207530f550343588e92edebc0c239f9d9215362cdba07fc9fb0a9a0ab5a3185baf02203a151c01fd5ee65b3b90915d6bc0d49a756a687e6e409ae21dc64f18cdf61c8f", + "id": "b5b6f86c2a8dcba704275301e6f78c80fc63a7c3f1e6f80a11e4c1f35e738e2d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 153500000000, + "fee": 0, + "recipientId": "ALhmTEX4c8Cu6j3LmvMy9QRScP4qd5uS1X", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009582b66e2d7e23ee2cd95f4a35683e67370dd60f84bdd4bf13a70b0e950255ce022027d4f0e29103bbe2c7626378b5d92f9976ef5637d4e30201f41762f6b58abcfd", + "id": "d337a4d55a6f848c4b56a1d8b4267ec04379b7ca49d51c4ff12bb4c91dfe07eb", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 153600000000, + "fee": 0, + "recipientId": "APL1n3DRcNdNvtGEAVXrZeF8aE3kSje39B", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022026c5e59f6f0389d02d8303807aa6b56a1677759397bf1131fa923da22cc0ff3102200c206cdad36b67bbfafcdc42bc5af3a43865c4dbcde49216cd6acffb1193a86c", + "id": "f855d660cd350500dd7c352d9e1e298f7faa93fe3b99d54fc5179caa3233e9f3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 154067041808, + "fee": 0, + "recipientId": "ANe5pi2srBMSp2Hsdi4dvEQkmRw6QRufWE", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b6021389172baf3c7416f95ce39a517a755f44e213c7fc174dc47c2a9f67aa14022002f08e8c6e0109219b258fec7dfbe25e18c5d563a99cb751219955a68ada0e0a", + "id": "300260d69932d0fee55a854007a7c8e16da8ba9a531fef306df009c500e42901", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 157600000000, + "fee": 0, + "recipientId": "ALUZm656LEa4TqfwdtkjP3XFidv8hdFG9y", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220564681998c47b9747919eec5e8d497815a14002b497a43789007d5fcfd1fa37d02205b6097bfe9e3c44dd8a7bd9d610a55d72c674cca6f89e29b37847ce57eb06ec4", + "id": "2c1eb9434e82279b5ba0aafea3b7813e4f024f3386126e65cbbdcaac3e1de27e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 157600000000, + "fee": 0, + "recipientId": "AWtwaGELZxRTxu6znTh3JaxMJWyUf5yg2b", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a87d31acee7834af08c83ca70917065c1a5a413a74d7c4443e316f24a8526ada022077ddd8c1add111bba68f01695dc922f680b83fa3db1edf0e9750a0e041a3c5d0", + "id": "b724ce6e1fd1bc009fd05da5523c735a21300fbe1a4fc1da52cf2c6ab9d66ba6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 157600000000, + "fee": 0, + "recipientId": "AH8dy4DPGzSnyMmfXmJrtyWhUkZoqsscWC", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022000f7c8a6f8a8b0bdda54992f15a566dd1c9c9d5d48f03b0205104ccef6397312022052ba2904b07535406df11778a86256ea7893b6e41c91a7889aa4e4f4e93ce7fa", + "id": "a7d0234ea7c0595d44d473619c7464781cfbd6b3be2edc583b624cb9210ae7f4", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 157600000000, + "fee": 0, + "recipientId": "APovNoMU6T9i1yvfXczPauvFA79FFPP3Ns", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e8a6834b4380b17f340853bda75c96ee9c553ba2b570402c28261504ac6f11e8022072c7c130180e042c97a660bf1f6f2b17625dc24acc16e03c4b54bfc767ba4e02", + "id": "86f6394cec011bda87c30b080e27320137e936adb8e67a9f9fde6afc84582c7e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 157613342003, + "fee": 0, + "recipientId": "AZd59X8LMYSdKgz6zz64jKxhs6YHUcE2Dc", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022021513ab40baf4bd11223c976ec339be0374e8a96ee60c90e499202e2e14916150220229b9355d285561da1b1cb33ad210df305e961ac485e3ce51db39faeac96475a", + "id": "a3b4066f32a764dd0cc8c357a401e91c30be8b7913851aaf8815c61f1fde18ed", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 159675898944, + "fee": 0, + "recipientId": "Ae4moTG7YCQ4yvzW7NV86aZVA1SL5jZGUy", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220799233668ec57eb2ca1b0c18b433e788ef25df88edd97bdfbc5919e1184efdb3022074a3d4fac5a531fee1ba3a6c6378d5fd080acd163e8e7f983969b1059376e9b1", + "id": "2d900441744993dfaa79989178ee5ed78cbf8dc5a67ed945b2558b0531c23653", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 160600000000, + "fee": 0, + "recipientId": "AeR1SNtu15o3UocwDDh8kBeov2RWeVYzve", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c3ca5aaa9b76d2d4f4916b9268fdedd5f8c75427bb980e7437e5e50e4028560d02207f145bba9763452fd5cf86013c35ff8a71aaeebd0966e2a6e218e7dcfbd43dda", + "id": "4f732a783e8fd503af9584c2116f4d2d9cdb0763c1629f202646dbaa79445be3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 161600000000, + "fee": 0, + "recipientId": "AP8RQXpVHCYEjNaQzHPZLYEARWeMzYAnUH", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100dea089096a8ef631cd271361fd564a626f541409e3e166082890f5c3d39a5db1022057eaa7c8ca2fc37cac5129c8994f26b231dada2607cf7f3e026bc5b22c9ab89d", + "id": "99aad499192c22c4bcbe71b8c133bef61eb16efb59b9281323e04c6c4b925860", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 161657213879, + "fee": 0, + "recipientId": "AdLtfyiktPxNa8Wf3uEgGiPHHRvBwb6BVS", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022074316c70b4b377bf7ede11dfd7e246e947479c62c6343c8370db0f0f5ba9e19702202487a7a8e86ee4970e3bfa3c42edebfab845b42f98c454db3bd0310c085acb07", + "id": "70a2af7bb1dc6807071d4c2ecc193a16ea4adaa872ff14de76d40e5d07c3498c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 162022981403, + "fee": 0, + "recipientId": "AW6FnNuwQGBcJ9nujbPDx7CBjukP2tK8KN", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c29213cead6a57f15622d66bb90dbfd8e9f46bbdbc186c752113d264e930486a022006f20912f179934ca1f2f94e0fd43ba5b415666d9949c11f0092de3553f648e7", + "id": "5c75d116edc4dcc35d0ba18d7ad56aa45dac0d9404fbf9f52e857fe8e8f34406", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 166527964751, + "fee": 0, + "recipientId": "ARkk3RAAeZSrA6Q2NiQYi1F5J27yW8Fz66", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220297e1206fd771d82406755d928bc86097eb8126f245e500f9c3f425d5b30fb1f02204b2258bcb30b1a11cde8cd76c81ee20482f870715cfb861c62c1512bc2737344", + "id": "4f3aa1ae966a9f4ea2bffb9e340bd522f3ee33479be4fea1f63d5a7b5eb47c0b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 168221932329, + "fee": 0, + "recipientId": "AN7y5f2nixsdifEkZTcgpnXWBzpiuCkcQQ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e460a99b932fe2c9b28720352ea943683be7120993e9dc4bd82bb336167c597502205a46ceac87e8dd5179eb40194229be169446ccdf085089e657b200089bcec557", + "id": "6bd4850be884fccb495c347ca9a9ee5b46be31fc1a0404c03cec0608912be6e6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 168973133925, + "fee": 0, + "recipientId": "AQ6ziotXeWnocAnwzz7V2idW8uxz5V1pka", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100bfeb6d49f03a89820a6dd1e82d238aca795866ca245be3f43e869dd1ae5bf9f20220580a0224b2b99b38564cee5b3470f88aa7c7106068e2bde76fd8ad1d8ec0ed98", + "id": "81e4e95e91247b73cd9e2dc3be2a84efb9fb428f04b184f63df43d3c1a9de40d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 169700000000, + "fee": 0, + "recipientId": "AKDpBAVgjd4cYXd7dP6khrK2Q5GyuyQfoi", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202619a5fef5f87ca49dadda59139f17bc7f388f09340914c5e0b997c1f0492b9d022031a12aabd0dca56193409dbf39fa3e9ee332d3e47fa4656252e161ea90563c6c", + "id": "6c86bd9ad81ff5305fa35d8eec25872292bf417ed456a801bb2301cfd9d5e79d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 169700000000, + "fee": 0, + "recipientId": "Ac6zKra111cp2QccMk6zDNYwyWrYsjY4zo", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203677d3e5102ea36a2a7693d8a47c86b3f182aaf7c4c8cb4118efb17eed87b6f002206a17cdfc67917a0c18faedec37baec1be75245eaccb45dc7fdf8ce4cf49b1e5a", + "id": "df692fe1270c264c2cad4bee6383428d2038d6b82d29b805d367690097136575", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 169700000000, + "fee": 0, + "recipientId": "AZbfRSargxVS9qk4cBB2BfVCiqir8bsrKS", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100bba6694b9e169a8b77a512b9c09079d99586551db4f5848a059b18d7500ec4e60220438d0b0f1d75a0621a6a06375ba8a3f75dfcc542d7d13f08175f9878b5feb409", + "id": "c0ca1a1626b404ec63d0a50fff867e2e9f9a1edaa744840c39a58c979862e33e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 169700000000, + "fee": 0, + "recipientId": "ANeUUTh74UcDqZhgxEwMe1SX2CP44MkfZX", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022072f2156f00911ae5b22ed9bb3701c89ee4ac9ede3f3b4451911e1e284e21f3ec022001918a7e52c65cf762ace735e980547e60abc3d00df59cf16770faaedc05e1a6", + "id": "b119402b26404e9bbba26df0e59cfbf8d50d41d28d428202fb0b293e19c30830", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 169700000000, + "fee": 0, + "recipientId": "AdVL1oAWGLDP5vKax1kfA9izMrZGkaStAj", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206d1a108b0dbbdb2c78252fc7ad9a91ebd9a525fc5d6a0c13f94d64a1e6f8ffe002203c04d2e0f607398933e30df73e93a40db9ddc41abef1980e954654a6bfdbce12", + "id": "ffce74f355622c5a278ee320d0d9eae789d9a8a81440815bd919179a5a0b2633", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 169700000000, + "fee": 0, + "recipientId": "AFpTaoXGqbwVG2HhaWJK5Vky8QMXCGNxAh", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206dd92556e443b03c0d88cbb88f562223e8def85b3c4e5ac40cefd0dc958ae157022012b06f7fbd4551ada6d470d25bfcd38cf8cc711c9af94ac56e4415f4f099f528", + "id": "ea0ed0b1bcb706d1e0b05b818a91691221010f7fece97113227de6a2851dac02", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 169700000000, + "fee": 0, + "recipientId": "ATzVyx4Et7ie5KLrjEUm4iULw9Lm77vgkt", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f42364a66c031a8584365c68b926931d1ffcd6edfa8a4a859a9e07ff248a507902201731c3bddd83d1f64f8514f5914b0bba1f385c6ca410241a0c313c5b8b614b1b", + "id": "6aec2e00bf4ff94b4374f83df59e85d0b6a5d05fa5520b021d02c74e9b582e26", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 169700000000, + "fee": 0, + "recipientId": "AUeaN1Nvksrkynuxe2KFQcDnE6U8dHFPdD", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206facc2f5e57cb6ffe15840f80384f3d386125e186234a6825accb2c8fae4dc940220456e79a2aa1c1302dd8d9437d815582b5cf6e2dcf9e7bb18f5036a1a1c77aa80", + "id": "965f90cc474b98cae2de4369455e85d1d10b71d5f6218bf8029eacbd8ac70324", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 169700000000, + "fee": 0, + "recipientId": "AbFmTF7BXLzyHYPsbzhH73fcUSzYrLcZeL", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022025a0f243b8cedb3282616eac1cd44a0f15f0d908c75cbe5cc9b0be8b46c4e72d02207463d2e7f585be69268fcdb655d3d23c6f3b50c376b2683d7e2f86cc7a5e1aed", + "id": "c1d0407270d31a4e5a569d340e0e71f3e7771dee306d0c229c2c4badced51dee", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 169700000000, + "fee": 0, + "recipientId": "AXvyLRRSRYxX8HsQHwLgDJNwwxQ6MPyuhz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a149e9edfd55fbd717c71c7150b9546a47072537b1021c7fc4e23703b4322c93022033f23dbec845e796d00102b8570fabea477c75c88b574611bc46e3aa94afdd73", + "id": "d7fccd7b5b4da68f0deaad41f9f132f5891a82295259510d2a4c8f5c1f2fb22e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 169938227241, + "fee": 0, + "recipientId": "AKLvGM1T9FCVstMPjWTC9ytw5UjyZJ9xMT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d361a2adb15f3e5b20238eb382fedf6a502ce30044b065b9169f4bd223d30fb902205e6004454fb61b7562e86ff5dec410db6765e29128e23285a6dd2b34fd437791", + "id": "a59e761db39ffcf16d170da0745cb36b5fa9d13c103592cfc28e1083ceacd886", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 170449652084, + "fee": 0, + "recipientId": "ALwMf5fAPMJhW3iwjxMydBBNr8EgZcTkrr", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200d97423751ff5c67b4a4bf29412b80ee84ec48c34a9412addeba4bc0a6278372022010398454bef83c100bfcbcd6920bef23951cc1534611f143c9dfc07a247d60e5", + "id": "d0dc0ac9dcbaea7ddeabf7fc94171d286fccc49fd07668e417b672e96b49f362", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 172000000000, + "fee": 0, + "recipientId": "AbpQwBzBGHQa2NdEpPbg8p1N5j1u9KUMkL", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203599ccae223b04921b15fb6dbf2282c0847656785d0fc12874e739520462d8b602207d431393872a4a6c5e9a7014e99c5d5dc6ce17ed2d21745661b36c34096a96c8", + "id": "245622a915732fb38c48597bce7bb1b91a4ae08bfc629ab7108f13f17804a962", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 172479663865, + "fee": 0, + "recipientId": "Adu9KbxhD6etHEMnjkf6n7diLWdjEGzwiw", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220702ff0e19a0dcc3fb0e62185a5cf1c094b6b67e3be700252e02ece19e3a53e3502205f45c8b0ab6d45cacc2572799244c5304b832f068e0cee10dbfefc14384e98d8", + "id": "3e2a032b3ea825987a4f374298f036806e3d032d7047ffb77f3c74c62d1bb8e9", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 172700000000, + "fee": 0, + "recipientId": "AT5ziEWMZjWzBjjKbgFVwa9XsXvgLF7E6x", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203072cc3eb52d630364deff654fedbc54d5a05feaac0e34e0b56acdd843c5d57502201e8f8c94205b700683610b373a3014b04fc0c064ecf7e48115febe1dd26e6c07", + "id": "760939c2cc34d8b911d94e7c5d33e577b4b521695ef1283793e47e9550cad9fb", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 174283983946, + "fee": 0, + "recipientId": "AUnkYxRkpMJZ9jKzRQMN9p5VGDmYhk6bZQ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100bf56948136cd8aabd99228cfe5b668e3c31ee9ba51904413885a0c28de5785b00220529937211a9e16896a45ce426309e06db74d3cf0014316d6472088d843ccb6ab", + "id": "1440feb6aeb77c3ceb720c4cc1aff6c3ca840ad482b13ca6fc44943f26bd41d1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 174283983946, + "fee": 0, + "recipientId": "AYP5kYDXLi1c6wrL6AbUX3S2JUEZPVLyug", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220564b80aa83110cfcf4c05976c11cb0bf022aea5539ccfc7285e6bb7024ea92a6022054cd14b6b69a9a7aced496951201a2b39b665282a053686b6095aa8f9af74be9", + "id": "2350844dac54c1d2b56608babd879cd5d1b986f4d0c3b32f587e0d270f9faac5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 174996809637, + "fee": 0, + "recipientId": "AZ8ijDkmLBLemmH1AVPQZz1ucfK7hmpLaG", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e3e8f38a1b850c94c87b33bb095221210280b1f9da1d2ec58669063f7b9302c902206b3b20dc5e9fac39ab48f418d4119751c52692aa353361c20839b564ae2d86d0", + "id": "af897d4026d8b58fc97ad3e0a4f555c1ec2d38954a590611780229514b07aac6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 175000000000, + "fee": 0, + "recipientId": "AQyWsH3NpyMMepkGbMJmqBqZehhQoDnzgu", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a9dadb4e5df8e5b324a66eca8e5a2abbe608886ceb3058c3b28d2c4eaaff255602205bd59390dd1b2b0019a5d928913d9379cad4adebd2b686d61b91733acc1629e9", + "id": "169028e76183f099c5c6937c4b0f33d085a4dc67b0cfdd5e70ef985a7640cc46", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 175000000000, + "fee": 0, + "recipientId": "ARaVs5XoWqrTdQrfXSSr2PTFWpz8ex6Tpd", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3043021f2f2ee4045f6a3a4072212a905fb674ac22021fbe4f627ab06254c9d8996a6302206011608f1e33f52c6e310bb6f5990fb97b40e3621266d832b5ff3336998c75d8", + "id": "b29913407f911e50a89ee33658efe0bdd856c17654f022df7dff3ba66037456a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 175000000000, + "fee": 0, + "recipientId": "AaAYd5qhdUN5Suq6wnJyLFgvVMbz7tAXhe", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100dbe0cac3b1a67b51c05c4dcf60cdd40898c0d797c9e82ead41c3d253ff5936aa02206a1367f167e42d0272eb4a2aacde2f6392b845324131d83e4060743e981a2982", + "id": "8c1d279a9c3e6fa01cdd41be4de0389ca0628a81e9f54738b3521a38cad15199", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 176418068596, + "fee": 0, + "recipientId": "ALemeBL1Rt6JgL6Z8CJysKDckba33SxDJg", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210087e1ac43a27da39206017ddb7b7d65c9104eb079587244283e27156769a6669a022002838c9763c2b4c53926175830c64dde70709773dd9ec5fc82880f8afcc57ac4", + "id": "d1e866be9ca942556ce9e7b7e86fc181cb4b2507a254e213837cc9549af568ea", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 178300000000, + "fee": 0, + "recipientId": "AK7bbYXM4Gkyscxp9sVecVn12z3oniuEfm", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204c1db106bfbc3cfb05d07cd96f73e94a858a3b48d98e6ecd569c70e6bd381b0d02202db38c2a3f4796f90719ac11132e0bccbf90f3c4df55a423a8102cdc2617dbf6", + "id": "dcfa805aa6fa5e3b48e2977f881e0b5e958fcd6d8f5e954d2ffcc19ec604b548", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 178300000000, + "fee": 0, + "recipientId": "AeBnLajb2S3ggu919PuDkcHKvQUyHogQ8e", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e22d2b3fa99c81cc47c253d98cf068c6e6d4392cea6b98046a6f9bf96f08cc2902206b95a356720f6ad9a1fc35a0ad4a20dd52ff5554e917b83a47323564f6a59eea", + "id": "b7f38f5e6054fac0d79bfad045c9d6320b25c5daafc7981cf20e97a86d0c960c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 178500479084, + "fee": 0, + "recipientId": "AQdLeqJwgo6Tq6K9ydgN79wyaFt5gzKFde", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fa25b2247f33f524a63be9001bc7bdcc5bec69b58672a2716c818bd6628e2dde02203b4fe9e4e3ee61142c081368f69b7aa585bff6a006d89be99f11c6812f8adefd", + "id": "f31cb0587377be839be6a8c831a618f305cf2aa81524fa8b7db848d1a890ff0a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 178900000000, + "fee": 0, + "recipientId": "AbZg4v2npAwLZfgjLAX3fj6ygRRXiT4uJ7", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205069080158b4cdea2222990a79074e3b604f8fa3c9fe3c64a6ef43c28e17235502200ae19cfc468e9a6be38f7d32418a8fdbd9645926cdbc41f69983b814a2370268", + "id": "741fa2cda9837f82593d70443034a0fffcce8513f05a6808230b4dbc222a517d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 180659436535, + "fee": 0, + "recipientId": "Ac9dEA2bwQW99JBREyPDyhEotZ7YQRH6ra", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ca9bd24ddc2d0da487f016603fcbec17be8c090360e57b8e8cfc33609bf72d080220033a502c201ddc296b9ffe5a6c8a439a56ae3b3e7c21907467f22b5c84afec74", + "id": "d777a58efef6dd5addf4b41c7d606d5087d2c04da46cc3de40df6b253179322c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 180700000000, + "fee": 0, + "recipientId": "AN1yL23GyoHGo9sa9k34ivBDsbJ9xNTso4", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202c19e9171610eea55add6b8ce88e6dd2df3cebcb2c7408750e2d439462053b9502202a0ac408178498ac59f3efef9fbe11595c6354e192d93384b40016ce4032d73b", + "id": "9baa8ef575418b7c21c114677123bdf2994083fdb026f71f3160e42749a3d896", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 180700000000, + "fee": 0, + "recipientId": "AQvopcUU3ynU28hy9qrgjNgAfNJUXxxh6d", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f192ccea6e18a7c7085772ac499c17747e47086e3e3f8091062a5024f6e1d77402207312fda88382fe4897d0f36660b431290e6cc28d09da713929cffaf9f6a49924", + "id": "bdb82c07d56940e5aa3ed4738521380d13c46dfcc2c41a08a552870b9b2f26c3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 181302136380, + "fee": 0, + "recipientId": "APytrs52Z9zEQFbTTsVseTAc2ah2w3Rz6E", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206333d9530c4bb019d2fa8505536bba29d34255860b173bbce1f3c04dd5dfaae502202f71f8001cd13550442493273dfb28a76be302bb4958fa2c00c1da0752c5584b", + "id": "c8e21ed6c8a7b2de81d217a948f55842dd2d9f3ee5c5355e333357d7345a0276", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 181861548464, + "fee": 0, + "recipientId": "AK3N2csioKfWiKcdFiM5Jz8bh6pQurd8B6", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205db6e528d94b20b8a25c31994a01ed5b2735bfa1bc5cf2e8a44d44b666ca11b8022056eccb3b38df08cd32a6d10abd316caf075582233a4e3f33cb73dbd143ee2905", + "id": "70ade5cda886880e03b60be04919c3623a511b655e98dca632b59c49c861a285", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 183741686918, + "fee": 0, + "recipientId": "Ad5ZbazVtWzjZJ7PPep5xcd6BrKXujAVRs", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022046b4f82debedc188166749d7eac5367ea18d2c56ec136943dfea7081d2a52af402207f6b27161c1b32de2738e9d55225e411d74872db44109b4ebd740abf1f3751d8", + "id": "d7f3e67bcfcf0e9be5368f8c3a0d23f48271465c61a3d345054c5be9aa01249d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 187700000000, + "fee": 0, + "recipientId": "APaeLc9yFj2Kr4c6TzDvSEhtv9yuyYt15r", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201f2ec1b7426bca1a40df431b64b458e41c3da447c9110f04752b17f27e19922802200f450da9a7053e18de7d92f27b373bbeb5e8d83d9ab97e521e7b2b97d70a56bc", + "id": "2d55f798fc91fdbbf8e8cadb68372e3562b7c14b5c8cc9c15e9835c442f37133", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 187862979565, + "fee": 0, + "recipientId": "AeK3nfKry9sXXTKdf1TpGxukzwjEbFsYzB", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022049d80b6b0f5e5592a925a105fa49d3824cf6ade3e1f82c6e08458fc6d1b4e1ea0220084e937408e7f66e690d2170723464652d7fc5e49b5a50d46edd4daeec028806", + "id": "90e496cfb4d6231cf2e764ba08e6d236086ee2b0126d754e96e1f046990b4741", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 189637269418, + "fee": 0, + "recipientId": "AURDY45qCCokzgcLMHFgMQedxx3fAAvrmS", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022070499c504fec7c112ea30ad8064083d50c86fc7bab9c35b906d3f5dc574a63c50220295bfade3e5b109dbd370a713f8166eede8aa42754b532dcfebb2e1208ee064f", + "id": "a344917af836c95bd810bbdb119bfa4505d53e314f7d8064b947a95765acc668", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 190000000000, + "fee": 0, + "recipientId": "AbQgQntyhfSarnTh8cFN7o5voAyDvbyZFa", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100bfd6cec5bf192f270babc3b0ba8435d592bdd369e3624c9c6c3b1a01b5f2b6820220191aa370fb41dc7e0f1c4ac848290419702e467f73dba7eb5e63f31028585fbe", + "id": "5174fb0eb29a8303387005b4518977b8386e811e228754863418ea5dae98953a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 191010602651, + "fee": 0, + "recipientId": "AQXAihgHkyTH2GaA5q7txsuGN8Wm1fRCsh", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f63d5da7c7ccdabaeee4c6d4d7a6a280feb33e4c0309291d9d32e689be6d83b6022013a07a743b78fb4a3fdc0c405279a72a1514baebb9dd166b9364c46eb934c3f5", + "id": "0b931be5bc7475ba3080a14a864bbde1f78e8dc0e9097c7d6541ac32990f55fc", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 192343079840, + "fee": 0, + "recipientId": "AJVL5Lh8fjMSrzDMTXxsBt8bjjEfMp6eFb", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100bf093f56441607b038305a26408c77428d3f41f0be77f1ad8a990b8837902eb702203c3badb9b7c845cd4c84261403de3ea42e644f11cc5536878828ff3536e91c0c", + "id": "e47fbbeb7f8b522d4a60ae7731df51df96a687adbea76a3d216c8671106e9c81", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 194167513244, + "fee": 0, + "recipientId": "AR8J56ZfnBCzB5Lvx5VyMbjKnfvN1ue8KT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fa1e878c673805908d682901f13bf1f0ce133822ba183e9c00425bcc1d43e8bd022043c553f199195ec42da2c5ffead7abcf0aa9046dcb8a5009f0b04d64f3611c8a", + "id": "2da708e273f79eae2ccfc37fb5ce48fa46f664f90715e7109b4b03d4f336820a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 195295588810, + "fee": 0, + "recipientId": "ARRpaRQ3t4LQdiJSN2ZMsuShCn4RqV6uq3", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202b4e543a3ac721ced2a4cde390f1b7e31d5efdc3d036d9e6a525c5a093ca7768022030c034a23ef72c1f335fb32fcc0e068ad14ddb0973302f8895f46060acac864c", + "id": "1cafd9c19b66bf9168a643075f84b1a78d80c909e2d6fcd13ebe51335ce45d83", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 196578368156, + "fee": 0, + "recipientId": "AXnet9aeWZ6SUKqHqHaZfCZNuTvQcdS9YR", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fde0862fac2154078b283cf6d5d95e9913b5b19ba708cc17f6287832216e54e502201f71dce1c39e215b9d5a3c971ff5a6e8ebbfa6fb79a7135ceddd490216fed391", + "id": "4a3e46a8378334a550bd54172491a19a8832ff1c4e909b68f54a9acd22fa9e0f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 197344240463, + "fee": 0, + "recipientId": "AV9rVNEKtxumKAuw7ZRui27Xqm5oDQTcGu", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fdadaef2d3b1c8eab520b7a5738db35eb35c224e2fdd0d215911454d74b09da302207d468b503cea3e7106c55f2b4e3081036c6ee71b0d22f3c7ef7c6ace38c2c1c5", + "id": "7a263c4f547c159bfeea9542f083060435453a72ef8251375930a6ce50788e35", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 199700000000, + "fee": 0, + "recipientId": "AGJDGWF7ZdcFg3py7fg5DXVLv7u835YEu4", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200d2557315c3ed28f6e9006adff24c8c7653482ae2c5a46536dffcd2de17187c7022021bb54089176340c71544b27388cd2836274b5fa4578af87a8bcebf8509160de", + "id": "73ee85253599b0a5c6795e002a0369b02caafe3d471e3ae50bf06257d9242ea6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 200000000000, + "fee": 0, + "recipientId": "AVQp4XzGX7xezNvAs7zK9THH52sHQ5cVMF", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f4497eb3cf8dab8dcc034e86323ed133378045e5be031e8a0aa7e146df51185102205b4e2fd28d73d1c6b0363163f3d43f455e909c5d1e91ab351f1c54a0c1180c56", + "id": "ab4b8af4e3bba9782ddd6e1cf423572c08018b97c1edb458ead90e71d84196ef", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 201600000000, + "fee": 0, + "recipientId": "Aa5mSdp95Q3UYCfq14hyqoFAb17nbvwtce", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a859f753c037cf28dd0adf78f00b25edfb1824a361dacaa6e638c1a026072f4002202f3fc4d70a9a783cb18cdf15cbcb44152c33c4b1bd3258a8d40b080fb677b93c", + "id": "f8f09ffcd58da0f41474741a12846a993315794679c3689f683e2caef0222616", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 202607842389, + "fee": 0, + "recipientId": "AZ1X4tRmPioTYsF7M9G6LptiwUC3FiTcSR", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d687ac1127083d06605b4f903c9052cc4d0d4b32a6721e2bf5802d7363dba00e022072fa83d6653c638db9f2f011a61c7277e3feda10551d6455be11f7ea8282e625", + "id": "9fbf5160fb1d3e8c0b218e2332a1fd4ec0bac96c346fafcf8430cad2aa7dfbea", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 202700000000, + "fee": 0, + "recipientId": "Ab9yCa4xAXYPMhDVQn4pq9sPaNPf87oPn6", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203b4ad209e97f90c9042d145d904fb43b7415dee167bc23704e29d1b1e6f57a7602207cd6aa93c337139424cc160791262310216b131fe347e6261f29c30fc470991a", + "id": "f553a38a56e7591467c16af7ad8b3b33661f70cc6e7ef38b7193ca30d7433e80", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 203859765516, + "fee": 0, + "recipientId": "AdAVt1aKEhoTSpoThdzoBc551Pd8TvcnTK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200ee9a0e9d21b09cf8456a7af712aff5576bbb7487afec2277c6ce857ea32044202202c7c723a32c2eb349c27cc9b53aba8c41eee9c668e606e8d1f39a4f4c51725cc", + "id": "fc7712497be31254a03197aa586d121307aee0db828ea22ae5f64efafd4a7d2d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 205000000000, + "fee": 0, + "recipientId": "ARpbHrGteAtmcuq4ogVhDHGYa5bNX43vuc", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100be97fc5e92f8dbe342499e2dfeb861e2a3034d90db0ed46263c492c02821842602203c072ccfcfc88cf36e9e2bb05f4bb6bad6055c6b5f409d46a686e2594d92b2f7", + "id": "3fa38602a65a4cbd8289112ad9d2dcc38682688422da1399192e9becb3713419", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 206040822146, + "fee": 0, + "recipientId": "ANiKFTez41cCVTDCeQMGDah3CZcQE3QtqM", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b2d3c8ff809e06ce7f18e8578c098a05f17ef5725f5493455fbdafb0a18c64d50220278ebca469d1ec78d436a6876bf69caf7c43b61de58bf725768e20e5467b214f", + "id": "fb110b753cecae568ea684ea89219ecc435e4c0b36c4732f39429b96c4324d42", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 210000000000, + "fee": 0, + "recipientId": "AMEiCa1gAAMQkkNBLq6U8XU6eojD9NDLhK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100858d68292d61d3ee9765bd761c669b387362768926892d13e20de085dab00b34022063217ca008673f5d910d52e76172ae3d5cd89c5397722555fa02ef904046b3f0", + "id": "5e160385a766397e2e8073acf3c6e61ebc1e5531c051511e2305e1f9a99c9074", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 210742589495, + "fee": 0, + "recipientId": "ASa6Ptm7PRBFEabEA3xSAaTzkXAATsgWYH", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201f7e5d2a2b1eb413415147c5b0531be4acc9657a258b0642674a9222c9e111aa02200a6b12557e8b15c93363cbd2f16c5da5b347808b81ff0787b509a5df402bdcb2", + "id": "7e416a3161f32a1c8fc7a50ddaee0005af24af5d71634ed412a850b272773300", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 213596124973, + "fee": 0, + "recipientId": "AW2WdVA4pT25G6Mg4Y8v4zVzwMqf4aSzVY", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f483231b8fa37f29b442b23f5cde12bd0a3c5aa9685b0474c9d8b49e29bba09202202909c7cfd49d450ac8230e0830b501c30d4bde12daf911c0123c2986a6cd940b", + "id": "c40a53464e01b2d155f20f7bee18aeff16912e6d0bf62ce7af98242c7d17129c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 214366548708, + "fee": 0, + "recipientId": "AY4zDyuA2GRwYA19o9MfJWHkYX5y284Qef", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220433e6ed95528685139036657dda5bd0d00835bf887ff48b50f2ab8fee55c862f0220454511b151d642bf325c1b76e4f87c10e2edcd6888db2ae93b80dc002c64fc26", + "id": "d11284b0b9371d544a9164d028d01780bd65f8c855c147788bf9863670756898", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 218074902818, + "fee": 0, + "recipientId": "AcGLR6W5eVw7Z4nUNxAKAsPbff7W3g27LL", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022059ae53f97ead4bcffcd1918d7441d2af25e3e82b8177543cf2ed491506ea4452022040e8491b7acda16b0cbe26376c7c363c31e007fe6d530d0a7b59a2e0fa8bd2c2", + "id": "492487dd0ac90a5e56db964bf01399a2e68a6ae90ae7df983d28bb7a016fd3ce", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 218233858158, + "fee": 0, + "recipientId": "Ady9TkKQPteVBFnEgsB1jReC31ChZPQTrM", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022044026bad7aac5170ffb87b2fab2d9e042093d05707d14e8cecb33de925fd04b70220181f5fdf565a57905911e0de52b99de3fb686768d269bd825e660a7136e88baf", + "id": "fe4a120e7ab4c9029ce22ff565bb6a3b1c94b271d356fdfb5ebff146b521e983", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 220000000000, + "fee": 0, + "recipientId": "Ac4TAJqrvBq4ts5VZBhHdH1NG9t12T5iG3", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207afeefd18cfef28ca2d575ce09186d5e73dc9b26164ce2f236b3191c0f96279202202716438a52ea4a50fc87bcf18b2053506f19cbc8063c6115d878c5f6392effbe", + "id": "97b34b6492aacfd46d6cc9abc808fe0a24753ddb97bbf6f6fecb926097faf36b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 220522585745, + "fee": 0, + "recipientId": "AVQxWb8vskpGUtBHGyWtZSdM9gGK4oWGAr", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022029c9ca7067178a57095b53e99b9ef5bf510797b677eff8270dd269c44d52af190220773c8cd4647f9bd75fa8d67164990b3dd5c4e872564438d5125be7c08224858c", + "id": "8bf8a19bc12cd56778d9ceed54b0f85bf35d93074acfc79360c845b3afc49701", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 223213787338, + "fee": 0, + "recipientId": "AdYX3f5TQrDG1E59vtT67yfUkePMA4kdLs", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ca26254fdba9aff2aac672c8f81d6501c7ed05f2310408211593616c79dd1d7f02205601d25d8967f49a12d32334a65c2a5135bffa6b00ae0b8409c20012db15c977", + "id": "01729bd3f0c4cf81b3c5ee92c11104e3ba3bdaf5ca1cff75468b1909b0702c0d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 223400000000, + "fee": 0, + "recipientId": "AW1Hn4dANHJAbEYZeEjY72kHziwS82vgnU", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206554e7abc84d48a0446916b7dedfe2ca80b81ee68fac6a1306e20f21fff13277022069ce2552631634c4ea0d8715b01b78b2a6a5ae0ae27adedee6fa6e943845a33d", + "id": "489622fac2962052e7aebeee1e4a4b2474432b88164ee70863fc4597ccb0f27e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 224600000000, + "fee": 0, + "recipientId": "ASHHaaJMGmaBdgYzLBnCf3QRzmBfiCLwCZ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f52a3a95b11ff46babb1a698a31a2c15543cd1e4edc0222b7f6593bf9e1d4a8402207aca0fc68e3096119766e390f2d20d2e48d308520f2700a4a1a8400fc9472407", + "id": "83ac0a39f01b70bd420881285a9cc7b4a99fe52f1329da58561a10bb7f933c4e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 225135109888, + "fee": 0, + "recipientId": "AShwN32PRrdnpqBNruVJBba54zvBxQT1fZ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205855eb9048241c2c794ceb57f89f4cfe6c6e7db7b75819eb2d6b613ddf830f3102205e55a04f4d782a61e969ad9cfcb8926990001650282849122773fcc25efd49a8", + "id": "83093ca92b08910d1701846610d091403f0caa583c539c555c676b6a31fc62e0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 225186625152, + "fee": 0, + "recipientId": "AU8vV51b4PJZb9fWwHgVUrgz4Qq9ybsM6o", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202ceb7829288662087ca7db79218ddb0d576cbcd112fc065bc5121d2726f7195c02202deb812e71c09a4e21095b881ba24d55a7cc135cc9dd739e66b22149d669269b", + "id": "2cac15432180f5f1a0459c96a42fa93dad5626ac6f3abba1b79116c9c785734e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 225944551562, + "fee": 0, + "recipientId": "AMw99hBqtW5JzU69NFnqdHmP7hezSHEJwd", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202ecfd14378b25946c8f865df0a638300d26e6f82c4c557e47acc3ae5fdee98590220047e32bd8b1cefe6ac337acee1671d0c83b6c4966bab9de30615c36f5b78afdb", + "id": "c62a1fc478ea0e2bf3e784ed5a79e7073e62911ee9d078dbbbe888fbdb69f4ca", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 226088941627, + "fee": 0, + "recipientId": "AYijkoBCzzshgn3N89mw6tVHfFVDEoHhTj", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008a560bec818d7a518488d631663ef9db1051402d2e9f24b7e45ed008de328adb0220783be0fe7394775314a1ac063e286a47d8f0d5a03bedef6fba927a08f16991ee", + "id": "b5ee7b65892cbd18ce165ec3039e9f103163b4775c19774223c7a039706c7be1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 226432949161, + "fee": 0, + "recipientId": "AQg79cKKYsHB27WksW9k5Zj4gfCgd6y334", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201b6566d5b7fef4e562a28df76b1cf240b1ab6d8e404fceeb6a73e8eeac2c410e02206fc6d1f95cc2f73268bc8c8a16c018f1e3d8841b5d1689a0ab9a994eca88c35c", + "id": "7f3c2b6326ae39f356f638e7ae2a62c6743f9a0ef5d96bf5579d4ab633945d3e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 226920728780, + "fee": 0, + "recipientId": "ASvcE2iGk6NjtGzsCdhtyEmYTZq8vzA4ro", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d491f759be71c566db0c613b002abe362d5773c394c4c334b2be2c594339cf1202207af821eab08a548cf1ac494066c9f5c44f1e012a2f802388cda6dd1d3e929136", + "id": "d5f945780826ed328ed99545019e5a71b6758320802accc0e27063a882bc410a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 227205088343, + "fee": 0, + "recipientId": "AHAD2pRZH6sqxHbhGYjAWWBbrUryGgLXNb", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fda316ddaeb730b7d40cef2c6b67b1ab4309013e1fc2dfad9c7338cdbddd99d8022068dbecf8adbe1f3772ec3ada57f712d621c6dbc05586a7d07657f515ceaf8301", + "id": "c90e06437de6b21fefbc7ad2740019ed8a21d3d2f8cf4dec41c9ca50fecf9878", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 227326935581, + "fee": 0, + "recipientId": "AMzGgQHh5MHzFzpMV2RnP2ZEaDxh648gYr", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022100df2e8ea17c584cd5c2b98d8f482073b0283a0e08dfff592d802b136397f482ae021f3b7a55fa8f7e6cf81dc6366730081f9350c929a64c00d57b278e8e927a6639", + "id": "4ff0f93c6049358eabbc1fc17d2085b198fb2f853898c31e4e86897921bf0739", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 227395512019, + "fee": 0, + "recipientId": "AadNd7r4Sxm8nRqRXauh8e93JieVxHr6SE", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100cb986908cda1d4cde6fc3d3d1d677cd884b44cae1f8baf1ff29c60ce9ec230f302206c17455c3a4a0cbac75aaf7827e3a2b6e04904114b580e6b2e34e1830824afe0", + "id": "8198e7da0ccb9bdddc19850d2b12b7f142e5bae867e699865c6e07f380249de3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 228227511241, + "fee": 0, + "recipientId": "ASyPsMFeWujywouFojtZHAmk8MhB3ZYMyr", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008f58884d3e390ffce7e7dd713c9f3c0522a03f995ab5e78310ad81e490dcb80c02206ef0c5569957702d9260aa8b1ddfe7460737fbae69f7685cad4615e497b027e0", + "id": "76cb4cb4da799f5652caa816f58da0851a83281f7412938263b9d93535026bff", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 229694826743, + "fee": 0, + "recipientId": "AQejgdtXnkygMaN4iYGsceURNvrnGLN96D", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022043a8989908833bb50b5a74aa77ba1172f4126ba24fcfbb7502a8b3adbf7f9bf602205227d5352082b42dc8ff3a6971d5c04cae58f7c84f44b9804a42d7d424e076fd", + "id": "5f4e06198e65476fd625fe07b5876e9e9fc27cec66fe4e48faef7c89bd79fd57", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 231352203905, + "fee": 0, + "recipientId": "ALr1QRnTAnsQXCKVoc5nHjA78uVSDNGArL", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202b798a36b794fa8ec3a75ad0edea4d6376cd39df6c0d263025c4b09b606acad80220371266d010a2cfd2a22e5e46322647528cca9eec61f6e17aedbb64ee19854b3a", + "id": "cefa0126ac7ae644b539f9004f2cd71b5e4520af416d93e4541c5ca8a84f75ce", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 232283790318, + "fee": 0, + "recipientId": "AeZPqVdexqu7VGES4UMMGdnySdKTRapfPi", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022015972edfca96fef8811354524dad92eb10b6f891d80fd0daed0b692e60f65b2b022052ca9bcd9a6963826ca5ed308c0268c94a0136d236245c522859091d405d9599", + "id": "e36e0129a20398b9ec6d8190e2ef349e4e3ae61e0e1a09085f153523f57bc3a8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 234568404307, + "fee": 0, + "recipientId": "ATAva6NSSHp4tfH7N9toWikSqd6YYKBBLk", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c2dd0fc577d306894f4464c70fe39c83e85c80f31003102a5ed878f6095ec21702202c64b5a075465f7c3014c9255ce0cbdf593b2158d6cdbd8e91f1b44ce9e3803d", + "id": "7d7fe67913bdd7317ac7b930a9cb90e7649f05125ebdf1e8691e4ed32a482af9", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 235000000000, + "fee": 0, + "recipientId": "ANMT9kqisqY2KKLx3VMokjLCynqMxQGUaS", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a8e13b798bd778badc34d9280e1d2ab9414c813f938384c0a86550e826cd8b8402205950252bc1efb41ff5b354dbff2ca5a8ebd5d4d815d9b5b3c39f2c787b881a48", + "id": "14b33a1754dd1dd5f243301dd176910255ab19ddaab5f6655f18790b9d2d8331", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 235931714746, + "fee": 0, + "recipientId": "ANpWLmDRAqDejcZ7GCdcKChmRGoMZCNJS6", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b99bd138ec399c08edd91e0219e9bd049ab7a80e32c813501d80442f436d2d19022056341b7bf689ddaf371c88ade20a7952815bdd784dc2ae64d30b2ad311e79e39", + "id": "6953ea52c0b42bd950b6a53eb1e0b4e6af5c13d0836a30288726a0cbbeb34f56", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 235942815916, + "fee": 0, + "recipientId": "AcqrcF2KJgjenxBxXoK5vtWo5ELqwfkbhX", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210094dd527f0c312b8ec349fa10aad1c7dfea7cd7dcc9c4c9196fc5a571c05d85cd0220595c9587b8bdefd34389e98cd78ef8b4bd9f1912700f0d3d713afbff6f5280f0", + "id": "6572a91980977673ed2d3c74edea33493e87d2855e060e3ee17a015e35331159", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 237605753191, + "fee": 0, + "recipientId": "APNyAxuJpws9bQ9agQN9J1hKE2kMoBpv1c", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ec9cc4a71bdfe43a491208b81c164c1a7dba990eaa9232235a6f26eac2bac7b002202ace026d4bceaab43df36c3a7dc38d859e00337e0a278550fc11d3f7ec2455d9", + "id": "45c45d469ad237b9eb967bf033998866e4671c955498a39bcc4ff652d7366e69", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 237874783089, + "fee": 0, + "recipientId": "AUn658PgseDk5iLkcAHwEMAYy7SLz7aByk", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022010c2a04ea0859438a7c8baec0c633a993afb4f2fa74b09fd3cdc36bd2a74cc36022074a2b5210fa27262bb40d9a5d6eaafcdd7791bb62bc678c3dec55d8a0e196b2d", + "id": "5809e7da60df4b7f9c8f359c859c43fae0d319b9ba0ba7e8dc2228d96cc8f651", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 238708836916, + "fee": 0, + "recipientId": "AS62XXxC49oGLwGiaFyMXCxCamuATfHSHo", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206e893e194882b8be5aa96582595ca69b55ea0ea9a7799789d0e3a79d003ea77c022034edefdf0793575f1f2139b925e7cd1e87c831ef0e2a11f923440ccbb62aec8e", + "id": "745488ac65b21596e11eb41d380bd595a4270fb691819b5c0437e3b9b0f5f52d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 239265443070, + "fee": 0, + "recipientId": "AUdHvFwv2fF2DBpYqbnh8fakj2Wc1HFDW9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203fadb40ba73bed4b275b2dcf2d205b496404c65e896468fdb66946792fad929902201ce6b87ca0ca7013dc22177e6915c06fddabeaba1f818098b63cc0918c33c9cc", + "id": "7d94f1bdecf28119468bad192f7ed5ef12f67800246f071a312bd23e8d8f2d9e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 240950563055, + "fee": 0, + "recipientId": "ALE7xUp2tVw4XqoA9gK1d2UADbZ5XbNPv4", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f2d3dbadcc28cb3aaa43b29caa35493ed229e7feb032985420d6cdae580e8355022005ad1413bc7dde581e08d60a2faa4faabcb8cb1d4e822cbe23f47922e737d7de", + "id": "8b057bffb3bfa183445d801a220a07a2c66e7e4e1aadc440265615fec4336442", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 245331115580, + "fee": 0, + "recipientId": "ALRhEXxjx8RxjBMbFJMZfRPVKYgTeABue1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c10b2b4f807ffc5f82391479dfbe6d1e455e16f6adb0c150bc92200c8fcbd9a30220033b3a351010143a22272ca5b48d73180b209b9d9f2367fff8ccd5dd899e642c", + "id": "09dd0da5b96f36e27e7d67779d3cdf266ccc2efdbe5c9ab88c20b5082942d4b7", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 245368130406, + "fee": 0, + "recipientId": "AR8zWTBs1pw55kwS3Wq58uvhhwPjtTYNyr", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220076a552745173a93750265a34cb80633d8d613dd72565420ccabe9d56f27c44002200509f4e62d51dd15d11fada0edf71e02af8397fe5e5bad521bf28bf9acf80655", + "id": "39c6bf781edd4da283148bb6f34d1152cee2fc98cec7464932a82bf380df151c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 250593911397, + "fee": 0, + "recipientId": "AGnxrUgmVmqqRNyo8nVVnFuSwiABeiMjXp", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a01fa1cd2c20a5012c88ed1a0756a1f643a62c78fcfc4f69a7c983e76932ebd202205ecc72be31c8732feee7ed2f79ada18b52b9d773f26fda89825d5364ffb0653a", + "id": "abe6f922e8ab5509fb29fbe11356a182a5b7feb4e91d0ffabe3969708b5d221c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 253760909613, + "fee": 0, + "recipientId": "AchFpiHbXRyCxc1ZY6z638QtmJnDi7hozK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008e32159083784acaf47a4a5bc2fae2f25b42f27ccfd4d1f0bb2e6263f902ae8b0220068d23c7a19fcf30456fe8117678b6f16d14765256e034764f7be575c53579a3", + "id": "99b8b895b70466c7984edfdf0f05dc35ad4b52b3a620bed624cb11fd68a588c0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 254454616560, + "fee": 0, + "recipientId": "AXt9rWvbGupykENfpxW88mnD9zdxTDvWXQ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022071ecea689811557ce917a64653771c2660ff29f9a5a903405a74f5f7e6884a0c022034acca7a4460d555b186d371be5c90de69ee6cd2e562b874fa37323dc9b7479a", + "id": "189b47b1a4ef03306276ad9e7afa6de0a26711fbdfb2bcb6527f679ca1afc192", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 254606167851, + "fee": 0, + "recipientId": "AaPyrCLTj12R3oc3iW2mWAwFBy6iu6VbwB", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b4927d09c6bbbc5e300e8e12107822350358939d92916affee3f5bd8147bf845022052635047282fc85c9fb4f115bd03f9fdfe42636668f1da00073827ee72835b4a", + "id": "bb4f8ad248ea6a382f7b492587bd4ac14bd1f06554261b9e2d187aac784930a6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 254687439215, + "fee": 0, + "recipientId": "ASddgAZdbm4jQAWaT1q6Y2zQWRqEkJFEX9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e7ba05a49b3b569d7f55ba5dc0309db7d775c5f1b5ad068f426cecf7e6973bfd022073aa72abef5c92119acbd30f5434b066d2e9c3f68d0a8d44f61c6ac60d76d9a3", + "id": "3aed748d0979d80a807df6e530f480a05485d147925f971b26e7c7826e854fe0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 257637193659, + "fee": 0, + "recipientId": "ASsSVAcmoUukQd71zZdmXu6nXzmG3gsKVk", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100823c1f1dd6b34885aaa0e0ad4fb4ce4362343dd5a328bbf0d670261a6b90d4a802205a54410b7ec114c84c47ca4de5390e78411fb580f966a790266ef570425ee935", + "id": "00dc859d0b95f33615098b9026cecae7a86f1aa61dc2402725bf41ed589fb563", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 257700000000, + "fee": 0, + "recipientId": "AdeWwxiobp9H6WiabttYQp5H3kkNrHXQ4h", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022052cfe09b5968829e0742892f8bf957072e13528e293879aaecd0c0c5c37273b5022021eb5fb8c940be0b569c6c90921ce4a5e6e20df8662d50d94f05b03429317e66", + "id": "b55d6a965744191be648d34aed3eafea6346102c9c078ac7e6ad16b3aa9528da", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 258336704622, + "fee": 0, + "recipientId": "AZeA4DJAW5qBbSdGavdC1CikwiW5usc19G", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3043021f791bd82b7e0414daa7a8a9567d935795438cf7e23c4ce95ec0c634ddf8bea102205eda1bf6bbb5f7f374460fefca7e8001e4a37d1d2615e776c347a3094ecb88a7", + "id": "5ab82d277db94a82df64931ca7c39d4708fe488152263dd47abc95f889fea4c3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 263400000000, + "fee": 0, + "recipientId": "AQ1qa5TMsSF4RWU6fBZCQCFxcEpzmtkGEM", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204fea12280fe69879e6dcd4eb86c2590293a9647627db7709ac6848690e3d9c3602201fd4810e4209edae71a9dcbd3b58daa95ee072bff610b035a8c642770d70de4b", + "id": "0985c36709c6452d9520cc9a2742c2388949c62c811f51add27bb59e0092f144", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 263517383725, + "fee": 0, + "recipientId": "AVLiBtEcZGEyUzME7mkjwn9whygssd6iio", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210083285814a6b94481dfac21296003cc4f343d4d7c8bc7a7a0e5345d4aa48eac1902207915c6bedd8a3a10812da78de0368acae101cbe093685d18fdcddc98b76053d7", + "id": "af50dd79f9d422fcbd301e204ba6a1e27f7b52bad2ef1183ff20e434049c2ea3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 264706758253, + "fee": 0, + "recipientId": "ANTb8pDUmSQHBQK47P3JSU5pTWYDnAuGGW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204175f6fc6e5b7e7b453dc121a8af4df6dfc4c55028d11c3ddf71b9d81f4e7e0402207723e4e6a7ca838f645fbab78af16c493d384a06e70b32909fc4cf915817d5e3", + "id": "0ed931759cb9de29db6d266868b504864389c2d1cf3a81f5d4a5efa54ae82a7a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 266600000000, + "fee": 0, + "recipientId": "AYpgKvx4aBst2hD5gaRYv21FtiELyaehMa", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210095cfda172969672c538a02e9befc1343f837d4fb1f3bb9570312f03e2dbfafd602202297f4fd1f28d1c63614a75d47c4cbf3f60ec5f77eadf12769d4de7a39290277", + "id": "2ad61362f35c9510c43e14c3968ae3ab8a1f0b1ebe69dbba2b0bdb094805d55a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 266600000000, + "fee": 0, + "recipientId": "AFsy81B8AvNKkxpneNm4WaPXsXezYLRVwV", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220632892e9de2b0f3e915e2af3a869e834b065a33d239888e4d9cc86068e9a8d9202201cf798edd4f1785b50425d3cf0e85b2cf41117479e4d0d354a00908ac809d711", + "id": "2e7d5d559b6bac5a49af20ad2e745daff3651fcd782d3a681e1935c2fec8793a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 267156888910, + "fee": 0, + "recipientId": "AWxBnbH6FrttJsempdhhoNqzzdynnue2Kr", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204ba5295df2c4e3d4b1c098c7ecdedc98ec316f115399ecca37ac08606010a4bc022057819841af1ce0f3c979c9b3ef0f6de3493e21b10040dab878cf753849c25b0a", + "id": "0caf79acb11be4d8712ca28485afcee25efc113aea6eee515d490a9235608e28", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 268215057163, + "fee": 0, + "recipientId": "AKU81Sra3nx1y9FcCJYxuuHQjZ81rjHavg", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022020e417bdf510dbae5780ddc943a9b2fbdc1a79d2225a3e491a223f3e6a8fda2f022021b6e95132010bfd534af5d9404295e9ab497f6f00798ee15d7a6b5ef49257b1", + "id": "fc18ebde76c5d15ef00d628b4e987f77c4ec85d4fe24dfb56d7c3a20fd8abe27", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 269700000000, + "fee": 0, + "recipientId": "AXHDNRmJ36baawXLcS8ipDHgrunCeRN471", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220580727096e40273d96f9f2c52109eb4810c2cc10797bc59228f1abb8fb42af22022062043d9bef15d4e1239a42735bc3cccf08a15c6b1e51058d3c0ea590418e269e", + "id": "fe60d828232ea75e7df9a6008cb7b1b3ad2e5d8e72f638350f6f40420b36bec5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 271217304301, + "fee": 0, + "recipientId": "AegyGSE9AKWNiYeiBPA7p7f5MDBbsQobNw", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220587cb825e6b40631e4b8262b05b170e219c6a42c723ba1fed4f6cc6b472474120220784a7ff6e72b544cd8807dfdabb9f00f3782322bef851bba6995ff4b2b826710", + "id": "fb0dfdcec943df0624049563fc6c04fdbdfe413bbeef620e7a27ac06af71f0bf", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 273312359613, + "fee": 0, + "recipientId": "AdG4rV1nutJ2VmGfKDvH1usesnFgxdokd1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220367368621c5adcf56ee4cda123934cc5fc9ac54332b0bcaeaa0b413a0d65a71402201971cf564a643d39c915a8328da5d3cfa36901b373ad69b8a72a21345946948a", + "id": "5a71a47bab2f7cab9e01e4694cfbfb67b77c411d4488555101f187dc88ca3372", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 275823348504, + "fee": 0, + "recipientId": "AQHWx36dxxzBjq7t4HD7sCMtBMBSjCBceS", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022020167d72b49f9c4b420066171449eedbd8313fcd5384f06881d19c1648c1b4d902205d0d2bbf805276426751a1a45daf52516d058a1776f43963c583cece69fe20c6", + "id": "a5b96fda073ea900e23c4c85cee5b79f0ebead350d4353d1697874abeb377ec4", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 275919189541, + "fee": 0, + "recipientId": "AdmQcPaXYhe7cJcD9C1Ghk6BKbfS9VqFQq", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008d577572afc4ed0362d6ec5c4a5c9b31abba6d2267c51a69c7d5f7349f8760b902203e73555f377d34d71c77786defe682711866f02f4be29787552bc25e1a277082", + "id": "99e450025bb676e306e237e05dde8a6f2d49913794ed927d9699c78a5e363409", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 279247094098, + "fee": 0, + "recipientId": "AT5ANRumUi7WBhCSVs35yfkbUg186x96fe", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100967b5bfbba242e8efe50f90f6880afe77a1e065e471a7885060af61baed6736d02202dfc5b008abb3466e78cc24315b51af9058ed24e2f77eb6e57c80b3a85ce250e", + "id": "ca2358076d0c35255bc017cc7a85023f41551867e9ef28287ff6d5da2d50833e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 280000000000, + "fee": 0, + "recipientId": "AQN9znPRTre9TCbGYmriMAc8Z2m8H8xrL1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022032247fec35acb98d299336331d44cd915e19b15857c36ed9f5bbe6dca7c2d9ea0220350197b5c1a25d9e0dad1d00d223596aff07e8a0da480661a19e27342a26dee3", + "id": "fa5d6719a86996e3661842604a1448e78e5b9d6a91e6c137a4ca6af765b9ca19", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 280803102800, + "fee": 0, + "recipientId": "ANfCguzStf32kWL6HueDisbWajTw8acRWs", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022014dc24aa9c13fa450a824e24a25ffb06005807c86b04aad84c4fd502e257647f02206479aaebb822b9c1e0ebc8d28acb759c7e5b09a3eaaadd48409dcca0c7045c0c", + "id": "08fc563e818b09004b5ce2e4c7c5eed2890146f62deebcafec6d5a2e4ad7f0bd", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 280988036090, + "fee": 0, + "recipientId": "AQypxoNmusR1UsP1u69SFbjb3R9YH7mszw", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d63d05d551bd6c9610dad7ecec2332de5675540eaa9c7989a00b4622d238ded3022071a021dbd0a3e69cf9cdc1ac0d949f803cb5137e08ddf476fe606a774f6f1127", + "id": "52cb8cbb5a802ca5d4f20438a0cf60ce155421404f9b8184952571a2382745c4", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 281336687456, + "fee": 0, + "recipientId": "AZx5ahPCDgGR7tdGeZUTv6oV4vfmKvPeJs", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201f040daf2812c5bca3ca29ea83bf0d24212707eec898547a76d6f00a114d1c330220179b38aa34cde2de80c519e0ac5beb23be3e14389d5e12b530fcc8769779f9ea", + "id": "b3e6422692e6b305050f7dcc3d23c3ea9efead66f14327c7ed41f02e1471039f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 289471840817, + "fee": 0, + "recipientId": "ALApc6GgN5sAA5MdRfws9MS3PxcP14Vk3i", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220284ba45d70676f0e34c9f8401d06c0d5807a6e84d021ebb52266730491ac5c0d022014d14816d1e86ca5568ea8c78e54def350ab3817f4fefe4404362042cdd12ef6", + "id": "899123718c97ccfc2af2a5bc4b50d97012d46c2d1403c60b51d54ae30e3e7da0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 290500000000, + "fee": 0, + "recipientId": "AVd1HMGBkguKeBduZoN7JD25mVv91G3diR", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220623a9ce997e94680b7fda4412921890ddb91de2dc833c76331026df41d4bc93f0220159e4f175d888472f3eb4318344b7fbde4140cac5b43dade415445a5c848c24e", + "id": "b2fd759ed4885ab57848dcb86ccc2026f47bae0cac4fe119183550435dc21d90", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 293042430719, + "fee": 0, + "recipientId": "ATdJXNdCCBdPaD9pTzZE1uHubNd4EixaoA", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220333ccf40d7686d7ede92e901701f2e4fb65206b40bf1f71abc85815e6eecce1e02204c30a9f447bb751fa78c08ac0eea0dd9bf22950cef4a8ae85ae101970a963362", + "id": "69d303c8dbbec71c451201ea88e64455da3260bcf9eb866a784b13128ae3e6d6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 294030114327, + "fee": 0, + "recipientId": "AaobgufVyjG5QYYUCHfdD62yqfKnheoiK7", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207badea2403c148d9573e4b8551e91ff258250cc339647cfc7c09492c64d57602022058a84d0ca29a3e2a9d469bb5e31460c3fc55a968a296337dda894b1f324a3406", + "id": "e1fc93b662aa17857ec8282b16af5accb50862272ac7e804c9a599072e13a7b4", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 297800000000, + "fee": 0, + "recipientId": "AavHyFGe2JQE9ZwkWVHZeZF4otbj8q8aKp", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210092332a9a11c56d75f25b407f22b3b910d469d888b30ddeb12ab843b37f5eccb2022008048a684ee0765e703fff4452d81e85eee5060c7730ce7959e66ca4c442414d", + "id": "e908984cbe697b713493d9e3f6a8e928932c5352d5f3eb262d7840cc04e8741e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 301300000000, + "fee": 0, + "recipientId": "AMwtequWhiTWPMH7R4PUf6wzEUVoQf41sE", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220284be66d3840c7c5a748d244c17b9255e2977142e43263139e36d89e1b204d9502206d9ebc18bd3f19ce852d2b4e8371baed5853cfe7a57d550fb89332f3cebed29d", + "id": "caa7b788cd2a9c62b6f83c5e549fdfecaafd76dc531f1f29689cf3490bcbdbc2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 301947752203, + "fee": 0, + "recipientId": "ATFJPWAy75j6jXHzYPCG1JbWYMm6XvAdiK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b5fb6d53b4dd98f55f120f556a6bb569291942b574a0977ffb82009a8422d8cd02205203575ca53fc5636a40e6f931e429ff63e2bb55931177732a04a0ce0431d431", + "id": "6f0fd1a8e7236b0e2ea0353de6aace7a1a9e52b2268a2e21a7d70ba50df685b8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 302851017757, + "fee": 0, + "recipientId": "AGrNFNUrFmtbDEtGmdmcXY4PmdcGt52xtD", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207085b431cd0a8ef985dc12b3b01b7e45ad8b3c0aade162cc21054fda777114b202205df8eb5b1e36a571083b0c89af506f917d5bb80859852a0435fa7af5ecef1994", + "id": "640cabc266bc124bb7575b0d0d54826bb4298f6dcf86728552a7c85cfb9d5c42", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 304323259134, + "fee": 0, + "recipientId": "AcmxYd8QHTF89awqRBCtJFsC1aPvwfnLqx", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c4a2d7ce45f32daeefaadb4b12d0f3022f207f68019a82d76fa41fae5f50461d022015bed2ebd307241f334322ac81eacac8b517a6b4942ee9dfa866ccc85cd3c4be", + "id": "88585b0976182c15633b99af07e08efd91f2e2ade96f6bcac9a87289b7b2f7bb", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 304700000000, + "fee": 0, + "recipientId": "AcjeSyWdbJbP7Y4xXZpPuGLuNtTL1EVmKx", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022040412540fd1740a5bf25c9edee8e55b8697f4862b476d93c57b7397b5265c14e0220394c3e19b2a9ffff36ff404e4ac60a77b695cd3641bdb119a0fe2d9a74ca5b19", + "id": "09b69e99fa28ffce86e2333899a9053e7cb915d4a6eef962c9b19fce83c42229", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 308731620043, + "fee": 0, + "recipientId": "ATXdja19fpLfnjPbpuusYqtSs2xGK1yYy7", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f16422eb334f756c50c1af8e4df9897a0341dd5b222fb7e24838978006d1b0b802206eb59fb05242d6208812e4601aeb2a0a64408ac03aa42ccfd6e4d2176cab3821", + "id": "71036c6537b211efc0da3ded963361c03c47b5002a0729cb8bd94c9171514900", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 309164632390, + "fee": 0, + "recipientId": "ARftmK1C8xzd6QJk4xNvvnLUHNNHr5oWD2", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d9ae4512d715c87e98370acc74818cb15f4a3575eadbe764e15a6aa4beff9ec10220042de90d3d51992d850581e2f717c40d7e00d85a07d5418856b8b4d28a6da8ed", + "id": "aeff6d588a242455a1226b253a08412327b1936cb47d911cffc5b0e1d4e01876", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 313315057164, + "fee": 0, + "recipientId": "AVziGRo9W9A4ngqrkof2wpHyrDDeBDiKiN", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022077e882d387450d847cc5ccf18042ef7c0c9a15b9f01ed523ab2dd90f3debec66022000b0525cdb09ce49c7ffb1588002e56e20f95798e2ed979e7f34cfb7c95aea6c", + "id": "c9fc04b7d64a5f6cc60fade0d91d344ecd925187f0e2b5591cb1e0748c293508", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 315100000000, + "fee": 0, + "recipientId": "ANPQroio7mrAH6hSrETf9nhoBvhz9UfrnY", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022004011cfce82a2b867330e93ac537230402fae45ebd6c28029c20a9a179fd588e02203c1d4518c47a0f86f33d93ddd32f6f97d297c74ce4a3a22464695aa14e144311", + "id": "b50c52e231192da85a6249b53545fcc91f17e03db263ba9ba9830f6e2198a36b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 323400000000, + "fee": 0, + "recipientId": "AbnhZAGRAWZQNfj3NSwWacXCcXsoDg1UDZ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022043e245c68837fc34dbf6a6f1806a5ded6a173f97a935aed9fe532ec5df5a045402202f5a8bb2ae72c7995e2fcaf1acbb9615b2d0f3567b2bd9db01af6e02c33c1a96", + "id": "5475983134ca085d94e93c8ad7847d8ec2d124c0606e7f65dc7360582927e28b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 333412838852, + "fee": 0, + "recipientId": "AHFC64BTXc4kKdmn2jw8Tb8487uxsbK65j", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f1d1ec1e2e7af629ab53f68441a83f4107ff97e7d21ae0db068cff630a2ad887022030152a4a06f8a0d390d7957995be0a5134f1fbf58693f4ccfb4815abefd9ba45", + "id": "178b974b999420ffc3f16c4b96a2886660174655e77f83e1277d1cc139c42445", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 334419127093, + "fee": 0, + "recipientId": "AbEtCb6JAawzHj3iDF1CnEBWpjdShoRes7", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100934d8a30fa7fad31b7e59d5befa251d41a9b476f381394569b6c670388b88ea702201789741ebd7614767df9f43b73a8ebc1ff546e9747ffd22cb1c2f7060891622f", + "id": "5889c1d56044d500f6abd85ba7e02e2fd69dae5740a88a6321acbf5620f0ed6b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 338228944448, + "fee": 0, + "recipientId": "ANm2X2bmWfVavS68Wf6zmisgvyKzmsYWEk", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100dad3e59166de998a91e9439ee044e318dd82040d8c20ab971d6ba12fe5057384022048f7c14d431001b88b2ce5abecba8fec190d38a1dad0886b1213c2bfe649b96f", + "id": "3255e17ccac83b9df7d9d34bd09ae2a6b6664423c632046b5ace6267e591fa0f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 338641901001, + "fee": 0, + "recipientId": "AR9nWb2Y4rZzrsCTpHCDBsjeTB2cSqxgLr", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100842b25c4dcaa3f85e3cffcb5412650e3d16f65600c6f76b3ffda4d3064649ce802204b6e0ff006c7045ec16bc1f2ddec0c778a192bf5f65203f1c9330dbd25e0317e", + "id": "11d040dd27672f77a6dd8088f2a40c0d095d714ff505582422eb9c280f65ca7f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 339243683819, + "fee": 0, + "recipientId": "APkQyY3hE8TTfDdYFxVX9BXfAhKvgLMFFC", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008d5444e7ab774e40da05ae30917882abef70cd94d28114658515c122bd33b32c022022e8c524d76b82f9241dcb8d49759dcb8e11efdbb2bc8f41ad1340b0ace8ef3e", + "id": "05c45393976a5e5daa2ad7386d12587d3f8096e6e99875b8aad24b6b87fec4c2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 340662911557, + "fee": 0, + "recipientId": "ATynVRNrhhRBWx9xLuwzqRMatJEebrNag5", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ab90a2e21ac0cb5269f1e3f662e29d54fba5e57b867fbe8c716a2212c9c2fa06022032daff32ee5c0167d8f1716462077882e411473116cbd3a23289832ddc414a6d", + "id": "863339c27a73d2b35fb206638b23c1048f35854c4d8ef4e0d2c2c9f664a38be3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 340892990675, + "fee": 0, + "recipientId": "AdDGwzuSnwbTgS5zCn9G2tjgbRSVwtwXgq", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205c4da9c7896032a24fb33f087f28cbd4ee68a1af5f242ad4cc246ce189c57fc70220754cda9f04dddd1db8a420374a314b3398d2b20c8a13ca69490c9c48af950917", + "id": "6b0fd1ad749e8923efea2a678bd5fa503cad05c1290b85d87336a46641148a1d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 341600000000, + "fee": 0, + "recipientId": "AZXZtF8s1rtY2x7qZ4fup9iXsGdwLgCy5o", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022029cb43b5e7381c8692a5e474af506b4443735f56198d2c03d8bac38edbfc46de0220736670e57d73f4d8ee09c27ddf435b1ddbe206fde50b3cf2362115b11ea8da9f", + "id": "79bd2a6949472941f09c7872534dd18cc5cc7d55d8ce9276f0859cc872f1f56f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 342836625893, + "fee": 0, + "recipientId": "AbSRLLJkexPZCWdhznU1YnBs6UmsvAsg8R", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220615218597c85309c9eb5db6cd1d0657998553494a8ceb6140102d9d6955bcd4f02205264ce22077d58684a39bec2dd60d2b90780ebcef424fa29720244d19907dc6b", + "id": "ebce164ccef6fb06922b26611a1d4c755ac5393812f1b6e6725f5a09eacf9607", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 348484491500, + "fee": 0, + "recipientId": "AVv22GuhDy6QAq5EbWmvqPpyNK327dDKpX", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210091c2b8ace2dc7f2d4bbda72cb5d52cae4b6413f823dfb4722d7a6b78d93d07df022046b2f87bdc34fb337175fbaa95d17ecd967a2b3bf2e158759b50edc1be0ab51c", + "id": "74c1b29f70e726c862c8db61964d259aabdc5fc1e5ec4a14caae3338c474b092", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 349954995610, + "fee": 0, + "recipientId": "AZKSX4x6Wrun1sKFcm5tUMQTyEDKHSGvEt", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204db55e406f565efc50329b609813b5361fa8829413c65dfbdb81eb62d45d4dc702206eef0b82a59c4ae156d53b5174d667b2239934b2f4ce6e3a433ffcf133dfac8d", + "id": "b4f3fff5b12a05df38f253328d0212e80e1b86f9f783d1845676a395fb46b72a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 350000000000, + "fee": 0, + "recipientId": "AXUuekRSD7Z8aAqRz5oEra8tjAhn5Jvvrr", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100875b2ed22d8bc7cef1683d8aa8b5f5bf4696859e2770afc120fc5fb9fcaea1c702202771caf3c8ca619fa15f339dfe2c1106d066804689421836b19d9a5d1fdb5cd9", + "id": "15a1e1313a9a1df3686417a2eed1cae978664b8413e79fea6b38925a286b4411", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 350000000000, + "fee": 0, + "recipientId": "AWnx5rbjMA3BNCXQ2JDXw9jjtdJtqG9gvU", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220723a306d9e64fb999de916be02dd0a12c45a33da542fb93eb5be5a73a39c7df0022063a52580d99354654e80fcd43440c0df1dd932c939eb672308bfa4ea705ff901", + "id": "6a717fdc8c6b1052bc7f70a2a18ffa4bf14f78b8d252825c90424d920f13a24f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 350918258935, + "fee": 0, + "recipientId": "AGUqJi6qb2E4F51wdxxdtomHGdTgDMYhkm", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a2ed646787d44f8f362242ce96426f32fa938967c409f3d1f748b713aab0a2c9022019adfe63d28f5b634ef60f843021e42514baa766c465a45840d73bedc00001f5", + "id": "a4b4f4cb2902f4d9a0489fe35641c04bf8911b064d9cd29b80cb0a1274ed64d5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 351177075272, + "fee": 0, + "recipientId": "AMQLH7k26GetQAX3q4shwWaDooL9cDcW9F", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e6ec5c6fcc7b88f4325f2e449d139e6889e8eea625463b9cb120b8921c26a902022049986b8ca2d95d0f3b461601b3411cc7e694271a2496ce84088899242a9212d4", + "id": "6f0898653b2de3e94b56625e6d6248bfe50f2e120b0a6425a311f6a47e7a3b26", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 352101061907, + "fee": 0, + "recipientId": "AKGkMr8fTn7d5Wcu3AAyjbVM338JWubiHm", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207b22f8fc7e97f5669baeefa2e72d9d30dce95e4ece077da817c391460050de28022045ecc963840f840ebf144a32ca3f47827a3f8665ccca7653a718d273a29c6a52", + "id": "35b48f395bb80488b5b9542206cac08dc7bb6e1c4ac2f07fceeaa028a615b2df", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 353468821454, + "fee": 0, + "recipientId": "ALkHY1xQK74faXu6C3Pejk1xSuAFqCFdhz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022077fe72a93d8d27611229b8f74ec4dcdd4fce7c4c3379d44237814ed7e5b81bf00220679f8baa1992972284470f22d085907bcaf41b5cbdeaf9ae886be71187e38c0a", + "id": "ac919bd687999aa984250568b6c43e8cedd7d1a639aed32a816f8e1588cd901a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 356573668788, + "fee": 0, + "recipientId": "AaEfJQu8y267hp5fQSyJtzR4iJSor7q5xH", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f101ca42eae873277eae594351e634addb1ecd245c28fab5a3b6ad97add0800f02204a262f763608d06ae684f5147b1ccf82bc9538bd82937de72cd1d8593c9e9804", + "id": "51f08208e82c1ea12099b608bc6cb3fdec272ae383c10cc18cca09d3a6906ad9", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 357292915405, + "fee": 0, + "recipientId": "Ab7CQLYGsWUEwHRY86hEPRXaABtMRfj4vp", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022048b11cb528691c8397aa0c8b01d4824ab9ab37b2ffbfd5c93ea7632be5414abf02205d868c12d097942225f488ae41bb9a0b83fb7e12fe163eabbec26a50a5751d17", + "id": "cbb6e663289d0af21a30738d8456ad4bf347fc60052eca55937598ddcd1f8127", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 357640325222, + "fee": 0, + "recipientId": "AQzZvHDiVUfrPTs3PhNi6xXaCmWwPJ9rW3", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c6744c0afeb8b450b915b4131c6a5318073f20cc7828f31f05b5fe7a51d40413022075e0848a80f03df23205e31438c4f7fdb16aa36060e87838f5ea4098ae5e92c5", + "id": "aae37ca7a805749e82bc2ccb0f812c0c80c5731d4b0258a6a44b394985f4e213", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 359722188329, + "fee": 0, + "recipientId": "AH45YgpupuJgJaKfNqpxrbusmyxxzAsSiZ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205685e59ae6d20fe9242cf689a3a6d7741215b7d473405716b61eaa15c4ae156f02201251a4a0cb27f4f5501c5b5feb891c730a795620d7092d7906b4d853e830ffaf", + "id": "bcf73615f4b48a7ea0a5570da0b75b6edbe053808301a5d3c0465da8a1c8a992", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 361053804649, + "fee": 0, + "recipientId": "ALGxVP1rkTWWUpEZyhTvzT8YJprKADx6jA", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100850f4683c8641e83b64d7076b43922e70569769b224813ab0513c88e51470eb302200ba35068526155c1413020bf4c18f2b4b8cc32f5e16877a9e10aa32dae1907cd", + "id": "afd3ee65410f9d76132c8cecbc796bfd54a530327ba33af33dc0e9a07760c1fd", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 363315727061, + "fee": 0, + "recipientId": "AMQ8ezFU9gvYfyxxk7VETnXmK6kpt1Looc", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201689314194023cd9e64eef30f0051279da6253ab7b487de47d5ce3b81487f2830220148ffa133c7bca9cf6d1d743105be8b3912af8426d7e0309b969c2e2d6334674", + "id": "a9bcd03694c114a041220271fd5f01274c7ae365a6b0f85d89b364a104a20e29", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 364303311651, + "fee": 0, + "recipientId": "Aeg4n5zYvShKUmhuXe7CmzvEJqFBTv3jVs", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100899497a5fba8b821e22acd35d5027771d09baf69899acf626c47d63ee4ac74fe0220481eab02c6e999522954a7da743125b5162b56620a93d6132195675464f64c8d", + "id": "e7ac9b3742d019488f8d93c3418e19fa8bf556bc232ff0af88cc300e631329ca", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 364467189703, + "fee": 0, + "recipientId": "AUSKfmvgiPu3LSAfY6Kfyo4zR1VgL2twcL", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022055af734911a3bfe58f44351b3ae7c15653ea3738911cb6d9872c62471eb3716d022032d62b6716655c8a6e9109fada3a82a3b4a20809ab6c0166ee79327529e92ac0", + "id": "635946b171c00b3f9c0983e4a43582187bd2a3016349a6760732e434bdfcd697", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 365586352150, + "fee": 0, + "recipientId": "ANV7tExbU5ZgSDJGYyDtDmfg3Z8SVZ6rvf", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220493d2343b10c305a73614abd14c038561f4ae878c6d9957a171c0616f149187f022042548385875006c2cb45faaf5322f455b178d256075a007913ac11be84fd68b7", + "id": "ebba2ab5afa6f21355ca4f77d4b79e55d08b88c0b8b35afb69749ac61f0b031d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 366287950968, + "fee": 0, + "recipientId": "AcM4tvSTkSHsvjLM2MtBEkMX53ErPpFEbo", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207f9c913da5d2500b202003576ef1c2f478ee3218ac7d90ec443b94b64e96012f0220537e1b8af0d427a41400ba6008a463d00006c5f722bbc6b65e1d83d524863ec4", + "id": "a6fa7609921c11ea4658cea3ee0626f1a87d0ae21324780ce17721ed0d21f539", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 369653766955, + "fee": 0, + "recipientId": "AMfKrnGPBwckMBZff3rR4wFGfeztHUXEXk", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202e4e5c658ba2857c9b0d56b5babd7bcb848bece7b38820f4407827132032d59d0220713d1203f84e049caebf326b1eb3424b91643f407ee34494d1614ecc7b06c7dd", + "id": "ac8c772db29278a0bd50fa5e4b0a016fa8bb80b35b20bbb538ead6f53218cfff", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 373149442409, + "fee": 0, + "recipientId": "AVHXn563x7mzNDVN32MCf8Jngc7UKgGoY2", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022009b8fc1be1c3fde84bf3099e79c2356bea23ae042a0f76bb1d07b34fd4e90b410220704e5c4ced7376c4c7135004c0f07ae545ea1b5a0e72355caf0aae0150c865af", + "id": "36ab40ef3b10937488dd8593e7726d4c965a5baa8b2839f06620cd6392c146aa", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 373746668966, + "fee": 0, + "recipientId": "AUc2gugBPs87YHajno9jVS2niPspZLydtb", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d83d24ca3f90fbf5791169619436bc87c015f58140ea0c72a4c68df3996ea50c02201a061ded755126c92713e464bdcfd652cd4f7530aa1c5a56f1c56e366b388236", + "id": "f46f2c84bfb139e6bd22eaafd4b8c18a0547635dc798b91a3bc40567ddedb41a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 373774406219, + "fee": 0, + "recipientId": "AasYFcLgSztcGK66vSat1rgHSpFSxbgMML", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100dd07f53bb0e76df7d4dae83990242fb5db90a9c53c1d93855620b03eacf5d95902207957e7389be539c14ff9a17b9b0cd4418ebb14e80a74e3e56b555062e209e333", + "id": "19b48281b3104b5c29a0858d05fb08e8c324437fbeba15fdf68756842b3434e2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 374988724940, + "fee": 0, + "recipientId": "AbNopZKDikntAR9jguVZBChPeVmrp363ey", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220238b5a7da45bc180902e8b2c49d8552306a721f6a7f7f435eea329e0fb6952af022028e04e87bb64fb457a3cde60771481e71aec7fc8c2522cb05918e6677242ef67", + "id": "3e5fa869674d84582bf5a2cd3a2d18a52af64b80c188ddc9b15d6dc4b129c67a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 395360944311, + "fee": 0, + "recipientId": "Abk1pu25HhKdUVPwwkGqp1zqhYMTHEU2bR", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008e3454257b6c3f1b6bcaf812b5f3551ecaf4cf7118fca5367d4cdd4155208650022038add348b1a48125de8a37d8724e497e140b69234cff0a3923e70fc305c8d58a", + "id": "e0aec5537bfbb10983ad3268b4059a8b08fecd76a16db4a871d76e3f9d82c6a8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 396243735944, + "fee": 0, + "recipientId": "AFrHJuVb2HT4c4tWqYEvWgiY6CuymhkNFs", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ef46b5c739f79696c0b0a9a8f735cec91a0dc546accc233ff32f7e5cbf38b40902200dfdc24247a4f60f3e791fba193d9e9d16d83131184028e248a50ea4cb2a7272", + "id": "f2205ba50118bfce10259a754db70528268ee9112d16da6e2bd7dac30d06418c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 396752660012, + "fee": 0, + "recipientId": "AdWC72U5LSwghdenW8DKXWHYuULfUDrCP3", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008a55e63ad2b9b3d0baa2b6a2f80606f38d02abaac071387077ccba86f315a80c022013c555cafa7277020701df0004f2b695e34253ed7cbcd6f2a9e0e66593390577", + "id": "61c5f683b3a21404863121a1833c43e94f7f97acfc4100198f24e8dce6e5fd7a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 398860671270, + "fee": 0, + "recipientId": "AHV54m6LqZG8A1YdPKzvJdBfdoV48VzNmt", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220281ea4f34930789c6890fcae28d56ae12d1877038a112355f45a8586a7f7108a02204b0ceb0a989c686b91d84d42cbb5c8de0657c2988d9acfda7911f6fb37a4d0d4", + "id": "8aa2f2aec071acb8418bea239baeabcf9e22a4ec3059777df5f2f379f0dde30d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 399900000000, + "fee": 0, + "recipientId": "AMDpfwcmvCFW1jZYJz5Vk16pytx8zwqf4M", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202512aac371fad98ace991a2c0b3c736cb12b18da8206f5308dab02b71043c1df022031d2c0fee93eadf08de6f04abbd6795f15467d0d9264bd22c67bcaab93a40307", + "id": "9147058ff25475d0975386208f9d0d4cc8c60bbdf77737a09dde4bc168638db9", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 406030861383, + "fee": 0, + "recipientId": "Ad8LXbyPdTSYMHvcCZiQzaUtsd8VkLRdUk", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201df9dcb7dfcd79218826fc4777d0216f5020377bf2c1ab94e3818f17a03a6ec3022052324948abd06924e123c5e5042f9b388bcfd0f127b962f4450b166207f6b4d8", + "id": "7dd69f0c7424458dc39d3500fda4e8b1e5faebb079d6917f908c88192e03602c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 410054755558, + "fee": 0, + "recipientId": "AejLSizWdJowzJq3o2DZstQmyZNdqGGzJK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b53a8ca2840af4fafdfd607ba7a2673d1a3a70c4c3001cdfd03998e1d85049bb02206d11131b4410a8214be0bb9035664caa24e5ac6788ad7201442e151ca4e75b2e", + "id": "84fd6c750dbc8697bf563b042b5590d7d543e0f14b07cc3af1de3a89ceeca224", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 411430774232, + "fee": 0, + "recipientId": "AQwJBgy1TXokikH7XvqpyWtgAexhvnEX4e", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022005de47c592104b12833c0de59912e4f98001ab5e263af9d085828237f378a73f022074efe6b3260b7fc941691a426dd73e567eae101b680e360652e9c1539dc26c1e", + "id": "4594cf80dd9c58f780619f1c5b07ded414855e984bfe92f9c8b5e253703eeac4", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 414435446144, + "fee": 0, + "recipientId": "ALcuF8EWQZo6wHdhEab3SPG6NNnUhxmtrS", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100be8dacfc1c3bf51ff37c4db4df096642aee830e9c54b03da3a2cb1093150099a02206694dc3b9cfb53ef9c9af478bb5663979bcf740cedd5c36dc892ae50ac2b5c38", + "id": "3683470aee128d9e3198d1367815a49543180de9e5b6a354c6cace53386b998f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 414495122050, + "fee": 0, + "recipientId": "ASCzbyDxfQipaZCjC6VR5hbGG9YYgsaAwd", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b9aef4b9f36b7c0fefd1a5fef061047e327f54935080c118cbf913f607e42d1c02206edd5cbb8feae8309a3ea4e53ce4a86f9d91a084d453cfb51dcbff13522ce002", + "id": "198ee58a22c79eb720667aa9d17e249be4e2eb3114c7206ab0a73b7c9127ccfb", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 421404948418, + "fee": 0, + "recipientId": "AcZ8qLedqB3pqDv59QMLD5zLCMLEPsZiyA", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203294398344f0e3863dcb9709bf6bf915ff4c678a681edf48f03ed605ef990aeb0220247299f0e0a0abf1595d9801220e2be6ae9baffd4611aa62683697dbfb051f92", + "id": "83fbac69f11ce4a4d5993f8b7c60a4d1da9738f85e0d2e6905d49f41f62f22ab", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 422404168409, + "fee": 0, + "recipientId": "ALEAsaG5tcombmn4ewk6CtCZcT8jxS5LfA", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022044a875f285cb908df1025a9246529b88c88320c3d2c5b212721a67afba69304e022035b80eec3f0b523df1d8b235f9c9ad05c569e33f6ed4b7d72127ac88a8e04a51", + "id": "f01d3a9212807fcad775b20db523002d72db87387a2c0c0e6d6e43a96f76e10c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 425000000000, + "fee": 0, + "recipientId": "AaFVVK4bHWAULm3enE5jFuW8w1tGDVAtPP", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e4c2fc79977dd2c8202b0b9b710c1d345266b58a583911b8d7dab80cf6a9efa8022043b02b4273d62a6bfb357060314f977c8688fa2c9fd9655f1225d76e5f210598", + "id": "a9d807156e0201c2e6b62cbcd86df7e744c113443547394481215613463aa517", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 428842921747, + "fee": 0, + "recipientId": "ARTND7EwNVQyRRcHmxRMXD4vDxMsuvWHe2", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206d2758d81dfb99fe616979b5241ddc7054c2ba0661db8534b27f5a15a6e42f52022075af3ca1a436a580397f182ffe8dc07734eb4b2a67bda747135546f8fd3462f1", + "id": "30cc3a106ccd48d7a88c1f6d948d5701670c7541ea85d7472bc0a8e66899a9a6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 429330120346, + "fee": 0, + "recipientId": "AUnowRvHGnZnpPYWQhjnP5GRh8waH9oaoW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220396919ca6596b28199114e6bed458f8b3fcd53d1bc01b9c55a3e8c393f2694480220072f26bdc63d2ca9bd7c3c4a4ad1e246676055338077894de505da12f2b81a8d", + "id": "b673418ffcaa8a343b85cc02856e8d1aa2167c9e80228b738ac3d9487a56adf1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 429900000000, + "fee": 0, + "recipientId": "AVtEhnUNTLMG1ABGW8MxoprpQpcnjVMMs5", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a4775a3edb88c12d3117057cb71c556f460bada4d578d14d52f6f16f52dbe1e502206f0793cf3cba1bbfb17195e79343b6652414cd85a1ad47a6e76819f58a41e794", + "id": "91d608f9137abb9d4f30446786eca2f74cd9173b0cf9e47f3a917b400bea2d78", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 430758143690, + "fee": 0, + "recipientId": "AcsmQm5EH94A8bmxVhBX5azqRZ5HxSFurH", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ffcdd344a83d815b35399377593e907593848c590e4f6b690f90c8d87970f7d20220098ae996ee30c244bfbe04fea6f0940488dace06119d2af396b7d08dd925a328", + "id": "9693698248b30da4d32f3bb74a94185545a22511a32789b6e7c6a62c22300d15", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 431169218840, + "fee": 0, + "recipientId": "AaNpyjWJC1SzuYNtPd5eJrfdNGD6syTzLe", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a19b4cae750b166dc50c3e22bd12dfc5f490b58cd13c139412b61dc7acc7149502200418a034b9a2b6fa26b12276e5bba9f79a15ddf3307b51ac1d3b35316087a080", + "id": "074cbdd2b8b306c0883d1e6d0a468376c98f00274da7467af05095edb852a044", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 433300000000, + "fee": 0, + "recipientId": "AS31C6KTNhEc6P3pHgpZYg6L6xduuqvSXW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200369f8d253aed3996199457e932c7f1b95d12cfbac50abf255e04a331eb6b30302200c9643963f4b856e9ddb9572797944164f4a2991e2073ddd0a9c0853da0b969a", + "id": "bed6b1d63572f48b674a38739a4f33608fffd9267989b21144f3fa1de1f6d39f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 434358663505, + "fee": 0, + "recipientId": "AMKqjbsJKvsiRyzBwc3htV5V2sqrwkXpzK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022026566e29b8b649d199aa887ab842f5b815df66865cc04f5e1d3a26378c3a39450220284f908cca59b861fcb512612c0e66a0ddd855d4472d0fe6a96d113963dd0ed5", + "id": "73c577979ee440ffcda796ac338ecc04d7a462b69c17336ddcbf05dafeff9e9d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 441082175858, + "fee": 0, + "recipientId": "AJCDjQNpuuEN2byRdGY9xf2qRBCeASsCv9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203e7de0ac5c2dca5bb3b367f2006e33648f0b99fe5321af1cf06923f5638376e702207b223a41226368a7fbf51a26ede9ce708c86dadf563446aadc82eee78a142f29", + "id": "295bc81dc9d3e434b8b4cd76bf32878432742128e94b10f133b6f8596e4ae65e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 442296547242, + "fee": 0, + "recipientId": "AeeJpSnh6sHMH9QFnaS8iNQUxHX5kxZwa1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205a6753a13b5dba6748e93d9ff8c9e0b243916edebc82d50f26dfa4023c5a1c97022015cff0083bd455c998ba99ad3836fe8f569dea1b16e46f3cb0a1789a9015abc1", + "id": "db2bd8f694e5d5d7193469bc9af661d54ccdc1bf5f8dd1672648edabcec5585a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 444900000000, + "fee": 0, + "recipientId": "AYBuKPH9GghfWpVeoXmHheJ3hFEHHsPLL6", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022076e35e14f992269d3388839ceb60bf32ec1b02a0ef6e63ddab97fce76cebe95702203cc902cf0c383317ee84a5b6fe7ad1a5d0e507d3dfb9a5e1cb6b72bed9c2e013", + "id": "05b8f0519ee71468c7b25ee5d7e80360de95b6e2076886f3c1407f0b1b2c9f35", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 454296574143, + "fee": 0, + "recipientId": "ANdCnCPbZcMmb5DcuxKiC4Cun8XfNpk9LH", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e4072324402b907461e4bcfcf4b064dad72e9099acd171f27d208a9a018c2c4d022011b20091c75c4dc05d32e8c40b202c910a32a6fd18da1b531ddb4f5dc677a0f5", + "id": "9c35f16fe5a213937cb9d260efb89e114bc59310f3843280f6f858626257cbe0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 454410176686, + "fee": 0, + "recipientId": "ASDxEzhr4QLiKvE8gx8NyBNpNJBiY93bBN", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100be0f72e16ac306667849e550bfa53a55f77446ba1b3e85190a28c789d80e2dda022021706b1b73b64cd7d98e85c79e9787cae57efdaddf31c60e9d13c6530432d09a", + "id": "68038c71701292ed7e30371c8f58c74de6926a9eecd9833f205e85817b4880c7", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 458329154329, + "fee": 0, + "recipientId": "Af4KkTdudJhshRqyQknHmieMTzgN1baKGk", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200d98f84a03352a7404824fbf2565597e3407f554602a05db8c9e94842121de5a02201500a98f7224e8e716c2719d8981995c6a9cb0c38b456842b8b219c6034819b4", + "id": "13437129b6e18a12d3acdb01c9e113c21bdd85e2058aa56a460af7f3c8423501", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 461698156433, + "fee": 0, + "recipientId": "AJJ7HZHTZGmkLjGLBiWJ2ni47EVVmsPAcW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100eb4bc75f85eb983bd0b2a1d73ebbaf29c0163ba020b3fb85781ce3c1a97d6a49022071bb413f07e6c7b13f6f8c82dc9d023da2ef6f262883aadbaae6def1dbe5cc1d", + "id": "2e52fe4e3801a2a567ab73693da5448d5f0bfde55a2f0d6f4052075820ecae65", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 462363719366, + "fee": 0, + "recipientId": "AVsMnuEh8yCdQjAtc81NZzRsxJJDVjf9Ka", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ffd9156e78730c609974cc6a31a597d827cde890c7e5de46bc54cb10d7b1d51d02200303b539a531b513eb059a15ed6a5b08f9299e634348e3228ba323cee42d16bb", + "id": "5ce506c37e536cf8d7da0c3d2208bf27e461c5b261b9eae156808812fa14a6ee", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 462789386912, + "fee": 0, + "recipientId": "AVmGqru9A4Zpn3kd7goY1kJ3h37nAaxkN1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022039e8e2eff6ee9b7df8d20d070143f244f3a29b4c673932576e2d1d514d31d7af02202a79c76be0c59c0d27af4a7c5e45da0ac00944eaee1eb9aaffb3768eb3986095", + "id": "a3875b9ae99d76e48778e0b37392498715806214a2cfca46307c828e0d160ba5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 464492402483, + "fee": 0, + "recipientId": "Acb9QU2CSwSXNcbZARBwyqBSSsQRubqjHq", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202e6eaaf793a04b8fd064315af7d6cc5b911f86faf21346fa2a6e013bdb2191d3022038a043a4914bc834a47c6c903cddf4dba4eef84885201b9c4a637cfdd9552f55", + "id": "7f81ee0bb3fe048921ccb934a4476c15a339019cd8bd3de40685062281d9373b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 466008654301, + "fee": 0, + "recipientId": "AQ2bpZffieDKR6TFatkS3vZwDLyvDpA6Jk", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220516e15a8cd6382b7e0b93ee04ce1ceff0621dbb17ec2f79158a1dfce7d3829e902201383e9cbe11f387f87cd8e1701a0d974c61ea92f75090620065125f1b283ceaa", + "id": "838d54e1f7681e910380bc08a02aefa3bd47d347c10c9f17030cc1bbdbc9067a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 468845108203, + "fee": 0, + "recipientId": "AbBz7xmNnHkkdww8fBK7x4EcEi26V5sqr6", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009364c19fed0bfc1c4566e19fe01e83bace4233e7f7bbb25ab08971ef5c2e00500220118bc321de72db6de795781e1ccfe1c587b89362be1a8f9ff43d9ec1e2411633", + "id": "de57689682daa61b89193fc451040ae47b6335ef07f363e86bb37ff0b28f75d1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 477386564720, + "fee": 0, + "recipientId": "AT3dyR6SqoMafVWKsMvL9h3iBvsU2Q7S63", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b8e109b247b4d83739b36d32ad9e54f11979bbb54ec0629da72f65274e468d7302203b1370fce9d9e950120e102ebce751b2381d2319353e5c0313c6c84e5f24fff6", + "id": "8ec9dac6224398952f9c801261fa4a901ec3e823bc47301201c8e1d377b77bd1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 477386564720, + "fee": 0, + "recipientId": "Aeb22zZXfmhNvEjUH6H3ZT64fJCEqR62iJ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009fea8a4720368c5228f554d16026c0286bc036d49f5de51abfa2689d27e54346022061f2f0b0165159567388103419fce40a4b296079369bff483df251fcb9427764", + "id": "a47039058f275732366634483cc82c01a7ceddcfb6fe448f4e60eab614ae0e64", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 477600000000, + "fee": 0, + "recipientId": "AWhmJrkMyrJsdGjVaz2LoqAboibJFdpeKg", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202f3417cab05063c88942c5011311b5d19f7c05bbffc67e6ae090388803a8639502200a05fb48af403296455264ca2a3a3f6d4b1cc89706877be3335fc5c490c88692", + "id": "b6c19da13c34a12fb2a06d6a081b172074f07641024f3021b2105864e31faa49", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 486438883282, + "fee": 0, + "recipientId": "ANVReFpTPz83WVcVZocHwuNwJLuGW8Hg5n", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100bc6894303b0552ad18f66494029308976efe651de9f707a0187059e33106431302203f70460a4113ba5b089efc2d85e885832a349a9860bd05563c55f5d5923bbca5", + "id": "2644a2b4e0c87b2b0fb23f8da21f0c085ea8aae031436e846d45d77699ad1c28", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 486986935045, + "fee": 0, + "recipientId": "APoqq5cehPy8xdqgY5nPMFtupDK8HcCWFD", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e1ac0a3e424f949cdafbabed541a5fe658eacf781e059b22460f1ccceeac7554022050119d98a70c087621994890f55d3d8a79e889b02cc186f8be1ef04ca4ede1fc", + "id": "0bb8b3edd973b8b51a57550b49252f708528319de548f0b89a77aaf8f567a685", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 499452432600, + "fee": 0, + "recipientId": "AaVHPBJGnHGAyDsXqcXMkgnTXrP2VA8zXd", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202040b29b5ae655905a4be13aa5160fcc682c0c3df0768ef4c15142e0b6d79f45022070a5b44807bfe60f84455ad05957fdee06cf677a99279b25c33eab56b33bba80", + "id": "a8a4acb7cd42fb523baa102fa6dfe72371a2686c99d18e8f26d83cd65ce69e62", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 506413677424, + "fee": 0, + "recipientId": "AViKTbBER3QdyjPYvu6aEikJG6jyMZeBMH", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220575b7844c2c7dfe981396bdba8d577ed88738a16e4307c522077255c5db8225502206ff9da12d3b9a67eebfb1234918c19e92b1d94f75983c5ffc8b5598d0992a40d", + "id": "a424e155f169f58f922458c89352fc80a71a214a9b7f5d7edf53b833b7e9bb3c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 507369287698, + "fee": 0, + "recipientId": "AN4SVH6wMd1J2UinEszD1m6rNd2Qf67s6p", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202fc2e97188ea29acbbb5cb669a91834399df4e95258f843e5f508b2ae92bdbaa02201503b9313688be4f868f27960bd4ec9d3e26b49d09455e7261f811a8f4bb9f64", + "id": "362dce6072bbf7ddabf9cefee0b27fb43eae636f5d4a0d2f777319764ae643b9", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 509141981427, + "fee": 0, + "recipientId": "Abjr6LJqKumLBkGwWdCmqQU6ySWNTvYs83", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210088070a6fcbbe069be1a6a7b9de2ac4baf72f01078d69e8b3203bc85bc87e68e802200993087e55d13928a55f3a543cb91e780fe082d1a571da71ad6e4edd4ae63af3", + "id": "980d85c7519a5bf12e66c830e13372ce93d7918dea83f61bf88aaf57e5d44e6f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 515274387317, + "fee": 0, + "recipientId": "AKsTx2HPyBzhbNiEuUTjaBefkXsbWBmAzj", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206799aa5ca25023037fc2046c9976c29eee3253c6110d6d68da3b38a011f85ae20220498f5755684e9f2525f2080ebbec2c1306b18dbcbb1ef40d9006f17b3e12c30b", + "id": "0b85faa2155edb7516010b7b78fab8170527f6f51a144eda464f9bf148a2997f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 516873898330, + "fee": 0, + "recipientId": "AWP1xqsXMMgBDfRpvJZum4fywFLtRvT5Uz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205a98023efaa4e52f9936bfc80e4f8d4230a2c907a7723a7766a7ec0eed9992fc02202266a5cb028f371ab13c03ac11ec40a711c0473834a595da18591c2293622f15", + "id": "bbf1e033954f8086c4ba041a94635ae3ed8e0a34fdb0ecb699aa1a62edf9dac7", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 522000000000, + "fee": 0, + "recipientId": "AZydcTLh6qTuJzSkt2i7j7neaaMxN57bqL", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022049014a7b3c815b9989d7c4da1275d9381d5ea1bf94fa0197e2f1cce3093f9001022018b6744495c6da6cec8820e4d28edac409e2f4a9383ea42f918a792c89fda18d", + "id": "253a6707bd401ebd1b7d1465bf5857db4aba9e8ad438b8d97d121a7bf3a6e7c5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 522851951837, + "fee": 0, + "recipientId": "AZ1BHFwiQLgXfnbiW8poyzX44z9fg6R7Pu", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e6ea691fcf6ceb3735eeca8e83cd6be8664b9c42bd31aa0317fda910b154e65002206556f64d1821aec7395eadb7d2aae1a5a95e7a063b62ca6dcb6176d3ae8190df", + "id": "a01d46e24b46904aa9a2163d3950c53af19460ac839238d03c7304ac83b33820", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 526711619581, + "fee": 0, + "recipientId": "AUsWkvkAVgvaFhj9VTX4U96FyGFh5KbdZU", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f4e1b32ed7f1c7831444c0b2452e8d329dc9a0a439da676a5a56d0ef2b8c266902201bf1c1a13f4ecd6289b91e866e73b727ce735baa4128f0825acbd976e147ea32", + "id": "c22131de3dff92e746993d7a01636fa1ca2dd20e01d4db0708271aae6a63bb49", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 528376108643, + "fee": 0, + "recipientId": "AUuTNzGAj9F1aNpcKDJfuDzHYj2ndYLihD", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200ffbe2910b4d88d818dbc798913af9ddc106e423242640cc712e0d55c1a4a1d602206262f13fc3fd933e9f92f1455ebe280d33727501dfca60f8dc1bf85bfeb51ce0", + "id": "b487b250cc3f98368b60ec6c5fabd510e1a8483cc03bcd74d4931ef792080712", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 531321344927, + "fee": 0, + "recipientId": "ARtGz4V9e3wzW3iRtpYo4DbREDAvCwAg2k", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203776cd4346a82b61c46c2ae9fe7e7b5e412b84727183646992b4764249881c59022025e092b1d5180fb4cf23717ba0de4444e52067414da0bf474752763cdbefb8c2", + "id": "fe48867e9156b1ada766c579bce19e3d01f92164d9c265902b7a6c20159d520e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 536606958259, + "fee": 0, + "recipientId": "AWFff1CkyqJWtugHuYYE8WWzBP8w9qwuhL", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220024c4fee1e8ac337e575ed098a4ecfe070ada692085295894459b7b7a3b86c37022034f2e22c2438ebf949955ee0e865b528a781da86b942321eb3725178a2f8173c", + "id": "f1fcd6c5c6b3c83d0bd5accfcb929061d8804a863015cb094100ed09c90b0076", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 538220305472, + "fee": 0, + "recipientId": "AMF2nM6FEMBBfv7qWc9tW1TWv93dxWbXjn", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220315cf7c033bfeda43ab267511e88fbe392380aede5ab0087e7295bc4b20b0abd02202524f858f7d42cc1c5fa6866221d7463abc1b94d0185067ff0b3dd57a182984e", + "id": "8e26b02745f1f5ced11fa24895b0bd773a2db5370126c1e92235f1b123570548", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 539888138573, + "fee": 0, + "recipientId": "AUoii6QU9zwWhRJzLZMF71E6dffv7c9f1P", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022045f6e18076dffb721463d1e34eaf47a3bdd0d1d0e87d19d9e0a2ece49c9ad71f02206a0b723c4937c7861579b098763ddb8c533a7308dced9baf55d943b17e8b6237", + "id": "b56baa4d48dda93fd85fcfed035b4ee474f64469e28eede0b2369b4ffe17a542", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 540008433875, + "fee": 0, + "recipientId": "AKpuB5YvWrEzgxGqs9RSGr9oT9WQLCyxaF", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022066b1533fde6b296e7cc40d4764676bed7e9e088489e2482d9d7151f845f1c7c3022041502f6705fed4575514296bb157a9c5ad601758992acb22be436badfbb66f21", + "id": "85882091ee2b032360bfc72a9502434cda2fb938f5362225d68c4f77c3a47600", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 540816219226, + "fee": 0, + "recipientId": "AGGeFX427aMiLYXk3n6u1c4hup1X2STgdV", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220276e0d0e57371d2e5d6d9dcdcc8f9f1267bc27f640e95eb88b8024716e019743022034bd26c909f2653ca8af6298aca77609e8eb367e16f4b4507ad280beeae51699", + "id": "d966f146fa457ac9906b6b928bff9807416e8506483774c8948c0398c0481435", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 552260891955, + "fee": 0, + "recipientId": "AQrYk1AbtQ2brZ3dvsbHh8rdErYGJb68pi", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a1ad97eeb99f64d9eae5da29ec69a174058788941b7d7d43348e0e84a8d04cc902202520b1fc1ffc869ab83da821886b904d1e94193dd33210b5fa6cf38a1c9ea9bd", + "id": "ccf83a1e1d918e27052860875f0abf5e55dc14f6933c432eab13264919a60d6a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 553060575959, + "fee": 0, + "recipientId": "ARMwrHG3miRYdVZsGYmeXKQULB6GwMyyad", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200110ca9f26cf5a36a36e2b035b932b98df256209b95465a57eaaf8c2b19c05b6022062f55565484251018cd6e30fe19ae6387d5bff36836dc7b09fcfb5c350efa4c4", + "id": "f8aecfe8e66cf62d917c2c231855f9d4a7a479e918464658a98d4cf5dc03edc7", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 559276526635, + "fee": 0, + "recipientId": "AUbZ5CjroZETpDU9rmQtJdVU1ZSBHhxWNk", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200c8f7e1cf87873f2035f917f692cb58ffb2e8a5ecd68a13f25e8ad08b3309eb002201b7d7b59ee7e63221343a44e4a04642118e38acd08ca658ec01bf620040f7ec9", + "id": "d94bfd69197aa074ae9ede3c8abf9fe3a67b49bf498d3c620c364197be028b16", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 564299912400, + "fee": 0, + "recipientId": "AcMseyJzDq5Rsh2RYqJsGXYncjQinXDtvX", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a5edcdabd03e64a2e29f5bbf6427db67691f39b54ac517fe46fcf26b3515db9a022074d62771c4396e6252d56581e6413ed4b24891272bc7c8fb2a3ae01d2b7d6161", + "id": "a2f8f856798ed3ea34daac7d04f99409ceb4b58e897f8a4a8f05e1706926c64c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 566286551662, + "fee": 0, + "recipientId": "AQFkoubX26ch8tFBy7dm9yG98LLqV7cMCo", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206e638a8e03710eb44c0d7e8ac09b1b38366156bc8c46e1a0ee2f88424b86c5b40220247f979fe46dce7faff11bff26d3fd1bcd510747dc857b9cce2c354fc8d31043", + "id": "392e37377917bbe974e3c8ce837d0ecf52f41f1bbb7ec2e0056d0b09fd44620a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 567899118315, + "fee": 0, + "recipientId": "AYMj9jGadgkv3uWMpRr9f8P9poV9HPqr8c", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100937f17e1cd7f010b860f1f87e21802ee7c72e826564e9eea6b942b862e56f0ef02201673df293e24e84c2528bc70bca4ebfa5f73102beb49bbf999ec169527e2a3e7", + "id": "efb581f15c255041206ec351d3ee4f0b20792e6f99b29da27f9f588d1a5fb34a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 567899118315, + "fee": 0, + "recipientId": "AGpjXT2iG15ACjpwGGnZuZ1rcEB8WuwLGn", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b12dd8dfdfad12e59a4bd1b13e589a882674f1d9ddfd7f91286e10def66a8e9e022054bd93d1ea02976eb99f7d2b12c3df7b4d10db3cd77bc02810332c24a2e26227", + "id": "4aa30ef712b9518114abbcfbcbc962414af90b4618d22288fcc6c9b8cedf4453", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 568012720859, + "fee": 0, + "recipientId": "AGM85ysEstriQdnff6hLY96CNegLmfsTNx", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009b5a8d8225cc5c573f92f1f007c19ee1a702093e08dde891385ed3c19f00258902205e1088df5448c3a8aed0cc80a51b16db6759b80cdcfc318ad0cf70bb1eb19ca3", + "id": "32da511a73a5b2077d70a3299332790197c37351f0f6a10178cf1f777126e6f2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 568126323403, + "fee": 0, + "recipientId": "AWkSJ6mwXFC75PCU2Jq35ddXHyDAWETy8d", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100bcb4517f522f1c416d6ff3a5112dd22b15de6ac76fa7288c3e53859265b71208022046f9365a91793e947578c86fc7ff612c6f34d468dd6ea61f35b7b4467ca7f87e", + "id": "6de463003b0a10c7372a8ba2490533ae3a485d916b93986d2049980bf3771e8d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 572950085963, + "fee": 0, + "recipientId": "AXQXmHt4c1EcpxFAqkC9Cy7J1ui7FJaTUe", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210081b78d77da50f2b94713bb862662883a4e0dbe744ff6d41e14c5448dec5f99ef02203d4ec23476ed4adebfde4e7043cb0fdf6f7a07800d0bc350c4509baa698eb45a", + "id": "2521232eaf12c8a956b5b0177a86b430e4557aa782be3719e3220a6ae1ef77fc", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 584622281689, + "fee": 0, + "recipientId": "AXVz1XQf4pdPdXgyyU4VCFjsRRV3i9VrbW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220296a2e02be62e0a620e5b5b166757a449fe5c45829a0d41efad153710f94d065022075f637f41da115284df9e0a3782e73db04e044935a60a90715555949add9a470", + "id": "1f4180750e1f7c3f5c48fcb94104ab167e677eac601f7414f675c984e8dced44", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 585926998753, + "fee": 0, + "recipientId": "AeWy7BY7i384uzceaAbtxT7k7N1RkQeVK1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220296d7c9a6a71dc7d9803a3c95c67f69fc0aef05e2309dc3038611d28a712f8d5022050fdf931fddfbdfff9a36c4a554a7198c3ac011d462580f103b419b6f9a996db", + "id": "f8ac8625237e4d9d263547e716bbc276f536c7dc5612a9b102195f76744e0d78", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 587913213597, + "fee": 0, + "recipientId": "AKEyZbWJ6qKChGPXrq41cHZk4Jz8xHTqh8", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100993c7c4f1c17412bc3f44f64181821c60a5532272d1f0436aaabda139274900f022010e72f7d9343ead3cc02fba0e111674f31c2cf573994415adeab4d664acbdcbb", + "id": "8691098d97c62a3d45c08b8193b7cdd5416518973eb699d713bd826f5b978fea", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 589063195094, + "fee": 0, + "recipientId": "AeZ5u74dBxufywKh6eKBafLKBnWBX7F39G", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203f7a428270130c3cb5cc77cf307f8f87e3e99da03bd9c673805de883aff6b4f7022062a643143c9be2a68a3c49ba308a96d89920130f4e28bc688a687b05e5554ceb", + "id": "7ef826360e319242f436e15599caff7ab705747e617cbb8a2e0865b3821afe7c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 592519033621, + "fee": 0, + "recipientId": "AJQkUYcMuHxLho6Ag8yLiZjTcjhMXZ9aHB", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c2f173878f73f99e2a044fcca1fe6d6e5f116c30a8153f0ede31f3c1963b19500220081480f6aba6fe8568d84a6ecb26c70a8b6e418c60aad5386148455d9d361b0c", + "id": "af49856b1c3f6a712330fced86bbb90b577150af1568b8fc64b024eee487daa4", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 597999101241, + "fee": 0, + "recipientId": "AGoFy5eoJDS7wWbNpAwyDQbwGcWHF4iAe6", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e0a578e2efa657e551cb1ec1fc7330b08ec8aefcbf4458f720d7ece9b04b655a0220065c046cf75908b41f1d540e33450ecc4506f838818d97240d3c256562bf1daa", + "id": "50a23397ce1b9f9af4bdae64c7658e7a98125d17e803340d310535c11aef57b1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 601400000000, + "fee": 0, + "recipientId": "AYqXPht63UU1HKGMYSTgmgPoZj33zKWAGV", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201d214d26ae57304653dbf4deff3a2f4c2b5c0faa6451821a4aaf0851a66f77070220563a930f4833d36732cc2845a318e4d59cf77c2c7808eab9fa80440b6649c3c7", + "id": "545a75b3f45b8d3ceb447f8a573ad527853ea7cbfcce54c2ded8e8add84b1574", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 603323064588, + "fee": 0, + "recipientId": "APue7kzQNznGLbD361AwVKyfeqk66Gp8pb", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202105a9341411c738f541af56b48370e5c670710f26375dc77c968e3a3d0306ab02204218af14c3f11038101be19628a0d34d7be466f0dbfc41518440498e23742b57", + "id": "ca525d14c00825ad6f0b1f41b8832ab154464f55adbefcdfcaa9158f195633cd", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 604220262324, + "fee": 0, + "recipientId": "AamyoMmKy6vucKTsu13jYFnP4GeBy1RMum", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022032a24879fdefdebcb46b671a4dadf43e6f84af8b4d58646044a13d2dffc19720022052301e1eedcbb6116cc327c27ecf021e0e69345fc8b64d8864de1799356cb052", + "id": "5fc2c74fe023282f5b142ede55e47f0b218daed782c307d3f516b1707afd89ea", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 636515419627, + "fee": 0, + "recipientId": "ALPyErixj2dXaoQf2aFKR5qRWrpQNSpVzW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210088327da183772be9161d481fc69fdfeee11f629481d8b564146f45709347775e02207bdac01a99707e5fd59cfdaaaf9aff15b0171bc5c4fd2a8a97695c5adae6e49f", + "id": "783b96a592c50b102e9e73a1d69279352e842cdd8dc7b967b2728f6f15031ac1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 639468721143, + "fee": 0, + "recipientId": "AWTTo6v3d5AwpVu7Z4zMTdzGt7nStpphgS", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022046efb627b31d7f8834c4cb53547c86b346cc0a0c52b00d8bed26910909cb759e02206c6e2c5b6d5fdbe74e6a05006fcc9f2c1c0b2e3a488dc8f9baae9c1e4f9f2538", + "id": "b5be81aec8875f631918ea7e3471074c1ead97de2eb760b6367d43360f3d7917", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 649700000000, + "fee": 0, + "recipientId": "ARRLBH2goVLrow9EgBstBpS13mjmKzYwNA", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210091648b7427049df79b49484ca0a5881a3b870354a1e74c38e56b83849d49fa43022010008dc0dac24a564eb2d82d51353602ff7d7cc0b01be101aba4e6bd8a3d5bb1", + "id": "f7d43309c24a58b257df1477766aafee1d1f4a41d4ee45a38fb874fa62517e29", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 650982673120, + "fee": 0, + "recipientId": "AeUoiRMhcgcw1BozjW2yesuRNsCaq4WzAt", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e7623c82f69ca00ef2b0f988cdf38f53ef71067be47637c7db4da7f010a33ac60220429410215eaf06057c4f8c7d1da490340b0147a3d72be9ab9b1f4e136451cf98", + "id": "f3c675a4dab04c4a3f7437bf4264e97402d36f43bcfe84f5c2a874c089509cf4", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 655486679871, + "fee": 0, + "recipientId": "AP7kuQYdDVNaxFpBy1RRZCtFJxEfjyafk8", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220157e94b4569a8eb2cf78c543010cfabddffd8fddf12b800c5ae82a6a90605e95022041d4a41672b6f85bb8c2171a033906eea7043a35f377f2c1e07ae09c07906f53", + "id": "8e4a229041acf3eb033f4215adc26faf8bcdfdd1a8f351b1f97bfb96972c48ae", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 667854242368, + "fee": 0, + "recipientId": "AXyLBiVC4v1vyXUwVCZywuGPgzGE6fwjfr", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220117105ef4a93b506305144a883d16778f4d15fb5cc7cdc4624770e1e0976c1e802201ef7dfaf16ccfa96f2e408f78f7026377a65a59d1289608c47fd6c96f9df8730", + "id": "dd2a692bf311ad077ab9e0eb14d321fd4be930012b9ee7439cee939330063ce5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 668477464923, + "fee": 0, + "recipientId": "ARanutQKuQepLjbaHuTGh3yvFVzDbuoWj6", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207bf98de6ba2b128320e753ee96a3740084cdb6aaa13b3452ea9c6dd3afbdb6ec02203a9c6e40cf99cc6694a504c913a3eda844cdcd0e89b594903d27774a78b96ce5", + "id": "a428541fc5455a8e86b42088317a82ec539ec88ee98e2b7016a8aed336046fe0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 669856703512, + "fee": 0, + "recipientId": "ASBZf3gbf2VLdkaFp8rkVRGjnCm89HRfEP", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100dfa8b07f91d5ac3309d0302898299f4695480d247e75cea9c316aead4eda1332022039a19ddb10f1b4b4471a6ae3af7cc70cc9a2fc5ba9f88da5cb14e25c1cef12a1", + "id": "3a0b61cf0227f3a14b973e4d991b3c892ca9c4b40f48c6b48dc0e12a70939126", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 683962013271, + "fee": 0, + "recipientId": "AM6uMWQkzps2vJqMMMMyEuZLNa8a9HetfJ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100aed03caf6374a94b18218b1d6557cc6b24336e14a14932f1c3de017d61d969e3022040ae6f228c81d7ef90a5cd59d57844e7e712c981cfde43b4f7bf5fc590550995", + "id": "1ed84533e28f9b77cf94331c50903a74d10f648d4bb290eff722fafd5ad726b7", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 685060228654, + "fee": 0, + "recipientId": "AMwuubQrccxV551wFW5oTmKWZhvbojTizD", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204618ffb59c02a2106b27c71d14148d1932968b0c31490664911c343e96e5316c0220313e2e7f2387c05e242f162fbd94bbfaa3c991aadd853ebbe19c994095cc2464", + "id": "07c8587383bcb1fa6cc35ac3517ddbb3ccbaee82084ed71682c81a53db7b7995", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 688309516953, + "fee": 0, + "recipientId": "AS3HG6pG4cgtJBHiai6DrZfMdpUyTFPkB1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022019ddc6fe655b187a051a3d7a0575c8f3fe2b6ddaf74c69c8c6dc84a05e67d20b0220568dc2da3b1d3dbd1a712a4dc8e492500b475a08200bc70f62f73559a10d80ed", + "id": "0e1e914e5931d52145327aecf15e302d44dd38bf5c87756af8cb22a0cc1b8177", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 690823753611, + "fee": 0, + "recipientId": "AL5qEAPm6HBApbNTqVE3awEgzr65w8JZA1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e7ab0f12b99f73cdec3b34ee4b52d3987aaef73fab54b7aada17d807428cd0730220383d3191195bd2819afd54dc40bdc165c9271a201ecf57444c6ccea480800d1e", + "id": "cb4091df5629df4208f1132ad20d8beedac84714e5c73e52e8dd025a2d571278", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 690970768669, + "fee": 0, + "recipientId": "AMRtZ94wfCYmF9eAgK8345Hy9unPa1GKWE", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022058163e796f8fac61be71bd7493ca8f729067086b0a850bf233a0f719ff7a4d8f0220126c32a7a178013b1c955dafa8ffc3ff7c785a41f9ed089fe0bdd5283ee2bbe4", + "id": "711bdc5c2a1da2fe4c488397f938dfd9569779581ad321f8f1471b2bc363e195", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 703958360199, + "fee": 0, + "recipientId": "ASCegDxvnqHPGYrUUS3YoX3fMC5B6WqYGx", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fbcb790ad306e8b67dad036b7b02185dd3f40e92cde91c942ebf65976ecd98b6022033e4e5eed3dc65ed5264efff8a3f581107557fe0033fc6ef440e3a1622e4500d", + "id": "15c7116a20f1740fd4fa8c6e93c23b5149be45117d14c9c38c36684517914c32", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 706898356567, + "fee": 0, + "recipientId": "AYSpB9rSgnR9Cp9siWsdPct9dKKxbhBnnL", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022000cf165386c43ac8d18e3304b5eb7d7a58bf1eccdffdefd3f5af84fceb94846c02202cfa34b89f205b55f7a8c90ba72bdb8698ad1abc18a87dd650fd41c348592f53", + "id": "be6736d3f90b290d9761ab4976c11397d23d0300cbb09a3d24f818c850c9fe68", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 716079847081, + "fee": 0, + "recipientId": "AGBi3EnW12LZUDcyybsqxbeqLzdxzxTsEV", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220524fee405d41e04fedacc0e38c031c26ffbbb70cb273e53106382add945918430220549f961152cdbb902d342a57dff174cc6cd7d6b689d5aa49eac318311784b4a1", + "id": "a5a5a47040cb7f878d89cbd7b9e2d4da7f17b686f9f031b9f4ab8485373a467b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 726541178342, + "fee": 0, + "recipientId": "ANkCc7vjQS8g1jo5pKEvYKvrVbPTVmZxx8", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220082613e1f512c2c74044df74ccfa0018f5066c27c1027911669e6a393094f22702204cc71514d9c0c72430d6b24dfa6d8e0ddc3e0d9e9877e5a45af7b66e06c77141", + "id": "bf09ad805c4fbe75d9e1dc6d17b319edf13885f5455094ce30e44c144a496ed2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 727897828829, + "fee": 0, + "recipientId": "AeX8N5GFDN6ZBqf3u3kXNxVHBYsz2jLg8v", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200198881de2264fc3c1921b214379e16bad210f1e3d62b289ec0714e4c47f51b8022013d911c9f57820450630bcb87670ea779e7ffed6bfd700f7be55fdbebfdef0c8", + "id": "83613475e1867eb2a82ecbb92db7506a2e50c0336514c42e48dd3868d5aeb6cc", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 732204904378, + "fee": 0, + "recipientId": "AbzyK6ESfRUtaVWgiw79Qjx23QpEpBQdDY", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022065140a29fa740ed9049d50e848a48398fc0976992611867e87e7fe0afc72e13402202bfab985f83e5ea588c2a15210e1f6751b263eae649c2eccaddffc07746a0a69", + "id": "03dc5b6869f88c387a1e29bc05e963c99e88a3861a8e6b215ea0c87852df252b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 733825657832, + "fee": 0, + "recipientId": "AX2fhE4ybwdvcWwnJKpcwsU2sHZAQqF9h6", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022014e54a8d9f603cd2ffb1b589b11e26c1f74d0aa0c3c457b67fdf614ba46d1b1802200ecc6519cfb098463a51a3a4c8791d8cdfd7d0ba1a7841402c1c61c37df556a0", + "id": "57a89b3732488bdcab397c8c52e9cf56cfc18d316659388d49bd59b9b104be11", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 734634240646, + "fee": 0, + "recipientId": "AJdkWn2xq9mfJ1XbsvMmGWgzg1qXZcpaVr", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022020e7d6b80e23a91b7ac3cf255416b0cd1ee4b8c99e7905f3f074e0389d41658002206e2056d8cd76a1017caf5657c0b2028f85e9769b8dffc3b55667f34e00b10187", + "id": "a6c0f4e9a9df5bd241fbddad25bb116624637bfc4aa4938c2167894d3b422d31", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 734928270761, + "fee": 0, + "recipientId": "AKBTUeWQRdFCE3Cs2tKVXdSSxFnm5m4dZL", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022056a156e3715c7e280dc5ada73fec5140c0d7d58a36a9d5c2d191e141558cf22b02206f1a3b08eb3f4ac221438eb716232c205e5574753ddfe10c215dfab5961af2b4", + "id": "3fee18fd82e1b26fff178afc44338454f947dd5cbfcfb9b26e95786d7a852a36", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 734928270761, + "fee": 0, + "recipientId": "AYcACtdVz7kyrUu1RyfyYmnSxd4TKYCiAH", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009173fbf35ca5887ba7e479349557a88564c45c0f9a2c84555ae04839fc96124d02206c2654536f9ff7f3192f2aa9ef23e612f4488263d77c342b81d0ff9638b59f93", + "id": "50743bc18dbf1b0b06b0b85da7831be155da905b66cb4c55061b2c87329b6857", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 734928270761, + "fee": 0, + "recipientId": "AJPBdGiVCiYb2Zo4ZWs4wQwGpiJxuPT6uC", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022001bc153ee897c9a8088bd7d83db9b0beba950a777c79a3e19168a280c9a58929022028538f8aa4e9932b2a779622b99bdfedc92e16cc05aca8e835ed647a41419872", + "id": "aa2748fd0d2f735f8937046030459798b03ff7ace43ab7a6858a1d63cf38965d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 735075285817, + "fee": 0, + "recipientId": "AXe51e9NEuXQPFhY6faMfWJNAru1ccTJ3a", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022008f25a62cf8b062f8264aabdbdfd46a3b7d8ac5086031e0465afb0f9e30403870220207ae7d8f21ef03284ef94bcfa9d0d370dbc4e5b795b183decdd446f89b26fea", + "id": "0dbe3c763cdab7222f45d7062cf94bdd72a5ed8895fa55b268e2bc7626198c22", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 735075285817, + "fee": 0, + "recipientId": "AHPpn51yRx8UnegXydxpXiivh9xnuyshH9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203f1447733e52b6d8529e108e9a59259656da14f448adbeccd11cdf3770afed200220236c460323b60286ee1667c51bf1d8a61e7c7ccc88c90195241db585e886ee3f", + "id": "8e61c93cec0bc73a53710fd0d35fa0d4dff90a240513d20964782de96f256a86", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 735075285818, + "fee": 0, + "recipientId": "AKST4cpT1s7nnoP9fVYvyWSEvnKLz7vT7U", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205559fddbf5dc0f93eef3713edaad47980b79f81dea309ec15dccfd4e04fb0d76022018c9a630b655ca36b9865b304ac7a256fce6282779092790079d6dc78fc4cbe3", + "id": "6ca20d3c6119bc42cf161f48f4d82c73f005d8e9e5f602df32fa5cc0bcefa9ee", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 735075285818, + "fee": 0, + "recipientId": "AGN9gWA67X1BxSdVNjDwuQrpJKr6waamAs", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100bbb6b489d4f1f55424f74280ab00615213d7c008718567eed1b849a66c9c0ce0022008129948f42b4be5837584c37bcc415d343c336d7a6988f1bc7ef69a698c188b", + "id": "031a5500249e80688c627180ecc8d3cb9cfa38c5ed42ea10d2624ecae5342fc9", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 735075285818, + "fee": 0, + "recipientId": "ATHa3HMBEGDM4BQ3VcH1rAY6FdviPyDg32", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100948cf4bd55210d34820da658b900d4d4dfc4f2b538b9f8281189abf139fec2070220749e0a1a746c346b324aa393796276ea95f449dd11058d1857bba366fd228977", + "id": "ac676439da598343cd82aeaad1f306e6d1fa15d8db51bfaa967de14572af508f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 735075285820, + "fee": 0, + "recipientId": "AdezHrqbRQdooEMbLf5HEQjStMcWtKaUrs", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a0265aa6bcc52dd3ce524eb0902b08a00139f01e8078412acb0d48021bd54100022061fd1f5fd3c0abfdbf11fe56932ed39ae9b25d468f9e9d2fe00a96b96b60e3ce", + "id": "e9d8c9795d3f32cbbd22b6811801dea2d4b99a3b5dd66013d8e1bf75a12fa573", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 743982782620, + "fee": 0, + "recipientId": "AMefnVvdW3xQzRnfy3RqzjpEjUayGp62cz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022046a419c537be06463ceef560a05950552f61b5429f7e2b4a2aa09ea2ad1d3d0f022038881350fc45a81a7c1c0ad407f258b100b87acb496b8ec6e6e62958468c55dc", + "id": "edd887ebf23a14ee72232666b61754f7835b4cfa4034f7294fc9bd9a30ac1f10", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 758597694964, + "fee": 0, + "recipientId": "Ae9YVNX8GAVUiVH4wA3PqeSMGTDTDeUfeC", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022009cc850c616124e30c7a173d679234436dacba9fe466a501b2f645f01a59944d0220042cc6acd2cc25538201006a7a1df425d3ffce08a4408b1f5fdeb73d27d7cfa6", + "id": "ae6f8253bd2b564690008ff3ada0199ae1389457eba14431897332e6588e111a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 762146976638, + "fee": 0, + "recipientId": "AdScYdTwx5YAJSZNXhFfCXGqNpUZfgUAun", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207aecd31e853d981b83f6b4381a7e2d6152afcb06e08f7b001ad88200aee9d33f022018b9af36be0290056ded2c835c80902c824826ec0955e53cea50f4f153fc62e2", + "id": "62c9ac8c0b9bc3590849da10c55d14ed79af7a11aed9c88d4820c043655d8d61", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 764781255703, + "fee": 0, + "recipientId": "AazxWnociyHVd8hBNgCxPqAepYe52psryF", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207fa864ffe01d95a14e23efbb66ea9a22ec47b0cecdb564c8842a6c0f0cceadf4022054ff2c650fbd053bf2b022422e49977f6bc4fe147834dca0198d5c87f39169b7", + "id": "3684f2c7ebac624519c3e3fa1751718e07c66bb695649cf049238506d3866e15", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 767271583336, + "fee": 0, + "recipientId": "AKBgENszA84HHwQg1eKG7t5KnU17WLUkDN", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022015ab4dce082428342f964b9372d37588cfb5be5f916c8c936eca4d7a4457ad440220632c804557c94797efb8d041f94561b3126d0ce2105f1f51f038b49ebe387a8e", + "id": "a7d10521629488ad012d27edb9083ad6dead0b3a401089fe34401af2da0a847d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 772911580976, + "fee": 0, + "recipientId": "Aai89ucFnPch8ZHFvt5NJ6qBZKACJVYTeP", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204335c3aa664c18916e6ca785fd3c89f76b790e77511df34ffdaf5094322dc0a002204506ffc0e8c85e5a68417b78c3c231ce5c48a8a1dc417f1962bf65d6a1b5da7d", + "id": "773b21c1fca3bd52438fb17f97403e5f26aeb20693c591ee9d4e9e3ffa748be1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 772911580976, + "fee": 0, + "recipientId": "AcBCaUbM8cS4sp6s1uXELKv3CESzCD5XX8", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e01f0a0d0194e905f33d5189eb1f46da9ec86cd2520af288d3a88bdb3096d54202200f1285e4b0a6b4d3036e1fb85637725532a39e4cdffd51c324af87d4d30d0a3e", + "id": "2465e6d3f6b17da590b6f53136e4af7f893b9178bdfd0f7b5cee9f7c8ef816f5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 780058983676, + "fee": 0, + "recipientId": "AcuUUQ4hUm4wfob8z2dy2fgzVjMBYBL7CE", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022015bf2469739a014eb0002e02a27cb9873058c6ce26bcc30b491dd1c2a783a285022027942002fec0c30c3f73859f03d0b22d6e6b9aa8f2b4f996fe440ba00920e643", + "id": "1efca8a1ea9b00029fc970c5680d14f2aaff245fa0757ad0f1853d2c2b2e7053", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 783225207027, + "fee": 0, + "recipientId": "Abj2DUoYZAET4WYB73sTyr6udaGA24QSaF", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207d994f0790b2279a417323e51fabe58f9406f3306b21846d986a3f7146bb2dc40220246635f1f8a5d028f72d6117a7a743410fc596e89722121f94f8643dde175495", + "id": "cafe13900519e38c9e814edf229a8a07f9f521ecedfeb8f2812d9c8a94aa7f4f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 792264143054, + "fee": 0, + "recipientId": "AH6gRrXAUiWeyi79vjBvysTKJHCny88jpo", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100bfabfef46710cdcc59a2223e554e3e7cc416890cb9d2aa3ea408724bdd11d08a02205aed7c99e38a0b4ae8991c7daf53da01ba8652434d589aab0122d7c043dff201", + "id": "26c101b6192346f37ee639f28da5b53ff81ecb7ac8802389ea6ae9cc9571fc2d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 795355926543, + "fee": 0, + "recipientId": "AL9EsuL167UcKpjH2Cco6zqiFena8LoURK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220601bcb86301d0406afb27b864ff246c6bbfb8e6668be9bdd87dde634cd44b1f4022070ecc8458fed79816df9f30790a903d99ce41bd765cfc92421cf6070c7e6961a", + "id": "b745abc6ac90e5123dd8235aa5b19cf96e2419a8b7710ba03828a33dc796fb11", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 800000000000, + "fee": 0, + "recipientId": "ALgKXQivLiRjcmchi1vaRBvZDPpYcMNv3K", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009ad6dfefc8a08f6337c0fb9283a07fca5b24dda8145dbb06644284a7f91a0aba0220730b2b1411070cc0f9cb67b09d8d4c897a2dd7fdfd49523ab3b9d4f759c9803c", + "id": "fde379bb0f8057769553fbf9c7e49b62c37f33999696b0a426d6df0f1198d7e9", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 800807608813, + "fee": 0, + "recipientId": "ASNbbDUUV537CWVyJhW4nEBaoqphsfdGoF", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205c5f5fbe87eb844f435035cee3b081a0594c30581165ab0c5ee5eede125c99b702202db7822920671f90a6bc5ef5056b6c91599f7f48b1441ce679e8aa6b0ca53e19", + "id": "0d34c831223debbc92140029644e84dab7664c4af7cb70acd1271b023df5777d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 807327846398, + "fee": 0, + "recipientId": "AaJkUNWfyrzaF8VeoujbCUB96bncRBxJwb", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204b973689c3730f93177aae4292752724a4ae4f313a98f70b8602a63d2fcd7898022061fc16b87f2e06b4f2adb56ea4e15de9ee8858b079b7783c749575c6fc8e647c", + "id": "784dabe70b09163d177db73a00dcdc56ec59620d25ea31e271fe15a479c31f35", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 817711112949, + "fee": 0, + "recipientId": "AY25aryyTvvZUjDtbG53zbpigrenCBXbEd", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e23b475b7f57825c23c18dd4adc239468a8d185f43f5fc35b815f8d9bc04d03d02205e27da5cec444f1fa6941ac1b28c6536b5c4e56c9908099aeedea3af4c8943bc", + "id": "50fd6a37dba73576473f5d47c3a08ae07e39b1c5451d50fdcf5e9d3c1469a521", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 817938318037, + "fee": 0, + "recipientId": "AGTFXFtkqYmcG6wZowdinGwb9K56rWbSjH", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c8908d3537c932ca3d4de3b28d09da5561604463bd531024a992be58de1802ae02202b07302aeb41d0a3fe01a7a519a0b19e14d726918dac560e79d575e5c68412f9", + "id": "9352eb84bca23a8932cba246fca96482c36b3c55cebf9545ab3260968c223b04", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 828092442164, + "fee": 0, + "recipientId": "AHNQc1eUKgSJWr7BiopwP3fCLm72NRGFnu", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022078d3cd96dfe78a40223df2d36967e46708c8ed21dd1e098e5994c9832b2bef1602200ac6d2c0ba0763740046aae684d542a3332ceaa98cd2d62d0217a75c57411e54", + "id": "190407bed322d0dc2626669ba6de2627c6ed18f86d158bdc4e3d24e4e49bbcdf", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 833532097131, + "fee": 0, + "recipientId": "AHSytS1gD6vMjHtcpkQ86V3tTLVbVy4UV7", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a35919ee25620b1cbf5f00d83d28329563805282f1de3c6a14c3f3718d5fb671022003b1c6755cc0d0f7451fc3c16e41cf2b5a771c4596063a2a3458544bf927dfd4", + "id": "c36f7006aa4ada2eda35951c1d8e88194598959783880832ebfe42357baa5661", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 838975285818, + "fee": 0, + "recipientId": "Accz8foPxAgb53QZq55r2J3MHyhFJhWjyN", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d38fbd8b4e808a943dc3ed39967191c50ab52d5049bcb95f8c7896232ad9a25102204ce41e68a375a7a77d12ac92c4eb5a32a87dd2646d481b4dd6a4fd9b28e0a8f4", + "id": "677b8dd3b694d5ca4f4a2d890d99038f0d3529372ca65f21ad0669eb2a703d4b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 843238131545, + "fee": 0, + "recipientId": "AVWJBw2eQiWU9dhYYiPZk6YDKgT8zWuJpr", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100908c7959593e47247fcc045d6c5d14798668266960532130f43c8f03ee9e4e3802205da61bf5c85eaafea399d9a0f6ba0002baa6f011fc6c10d0367197768d5fc7f1", + "id": "442e380e1881f46f13924593a158c58ab704e76686258a9e1b33b645c9f1913e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 861005612452, + "fee": 0, + "recipientId": "APLNgrLNdVJUcAg8n79DRo5d8krXTS9jBP", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210082d6450fb65d0734f8c6d7d7ddab2438055b37ba420a3283b73b7dd236cc855602203663d2b76b2c2e681e78f016bf74a300587259281d73be10a8ae1841db720bbd", + "id": "53462cdbd50f84cc911007ef46be4622b31fecc18415d27f7937b5c36a9c1c38", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 867237104113, + "fee": 0, + "recipientId": "ANnnZMq2TBZhCoQkrXtsuhKYVvX7ii5RKG", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220054a3b0e8eb109670e0fb452e1e58b8b82048aaa531c4238a011ade0f3c7662d0220711ad6eeeaf8888a8774cd572606e7ba0613d737d3255367a96542b95181d5b6", + "id": "e6c1a70720897231182fbac0ff131552e938891ca01be2fcd96afdf3ce2079b1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 868945860370, + "fee": 0, + "recipientId": "AdWni6sVGmYL1iWEeVAt5erYacKrNE6CHY", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022042ef637e7595b772dc0f2c6edd1d1cdf05decd33f67e595c94abc1357baab2c702204e8bd0a77224dd1bf329ead41f7d03ab79b61f3bbb4a607d9b1ec06978fe59c3", + "id": "93ea865c088bdf14d07332d702448dc31dceeed8f265334e3df8b859f06a048b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 871419919728, + "fee": 0, + "recipientId": "ALBGoFokLTX1VeswH5LRBtk3uEUitoYy5U", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022036757f788fe0baf560512809ee624ea8efa84ec50dc22f8c8d14bcf6daaae4c7022011760ffdfd5f5c283ae6561b017036027b62b70a1281bcfb7cf9fee718400800", + "id": "75dd4fc72a01bbd3b6faaf4adf4fdea8c88bb2a6708d15f124005079cb9cfc2f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 875407840383, + "fee": 0, + "recipientId": "AStpm2Vziqqgtm4Tc3xw8poVh9XUBGpode", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206fd3e896284765a4a81713111ed9bfac25e977e14b70b2db0febea67d8e14893022055d0b6b689b94312aa2f360f5930c43341499b6551f74cee2d2469527f5699e8", + "id": "85f1956ed442417404c08f274e8b70f65b139a35ce77b85bea78f9b913e4e4f6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 877995100899, + "fee": 0, + "recipientId": "AYGjRAJcBQokKnpxnEWvxsLYohpa3R22n9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220563f3bacdff499019a348d4c9feb8c965c3aa80385328d1ae7fe2d1abd7b133a022078402ff3128df4b1bd885b3abf5d79c3318d6255ef03f6aa2c4148b323569a7f", + "id": "92ab5e8f2f16a9e0b3e8a127101142184a3f2da044a47bc9ff72da0afdd5c0aa", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 879811609594, + "fee": 0, + "recipientId": "AN3odZjMnK4NY6oHHG5hKPySNbH6DvfcyA", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022076f3867eb0610cfb8c5ce5be956ac5b2c37561fdd58525db87c5c89e26af7c0002203635be4d862d33fdca979630ae2f08f43a8375f35632af2ba59b148045bf1f24", + "id": "ad3ab65ab8c782d704ebcb4f1ad69d54a225ca2e669aaaac22724b946b244508", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 881943327924, + "fee": 0, + "recipientId": "AdEnEMDqFd9FGjuTAdcLgVeSYB4Nroj5qR", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022022e4869dc0dba943de4d58bbad7c4252e5a7e29a4cc415940ec3ec947b4f427d02204dd4c32404556aa475eb6eee346ca5b408e6541d7078cb03af4c8acf72ce87b2", + "id": "7deba86a243c8bcf2c222986ba4fed01192817061e1721c1d42e55b04678c85d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 882010152950, + "fee": 0, + "recipientId": "AUNsfAkq6Pcqeew41Qb7fMMTtsjKMfLuBU", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203abb628561fafe13dcce54fb723168690a9a9e766bd4ec3a250a5b496abdfb33022017a450e3a2f31be397e2696b79535dc956c2faa59ed503ac81d57fd8c3078c23", + "id": "55dd0e380d2c6b884a719461ceb712f3c6ee0518841ba10f81f1f3c3cd044907", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 882090342981, + "fee": 0, + "recipientId": "AYxtKAvHGgKmjAyszFLeeUdrBrcx2T4HMj", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202dbbb29509d4944ae73a2957f94bc821480f99552f77b7b2576b63703832fe9902207c65af1e634a4f3f2140146658865b577d8fd0ab88563d943ac6ab9f5c2082d8", + "id": "ae02e0d07ada325ac33ee462c57bbfe4b175943bad966e7930af9b51a6a83888", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 882090342981, + "fee": 0, + "recipientId": "AQ9dsnRjod2zb1jYmQouSeqMECCjczHTe4", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204ca7df8131d2dbae7148bb7d600fd2ae9504838ae6e08a36ce5038898dface6302203016472420df3880b64e341b28ae44d9ba50a218a1be088692613fa69ab95245", + "id": "ccce88fed70924e2c19f5ce8ccde69f7c74377cbb3f698fb678dd6455cb74ae6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 895174683068, + "fee": 0, + "recipientId": "AX2ZAQGv5aZfuB7uEMrKVBJixqGjaD7QTk", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204000a219545ece7dfcabaf8d2bec29a6ac6d360046298e81f1fa847dc260bec9022004193aacae42218212effa3649334b8e5e865ca8018f4cc10a704e0bf464aac0", + "id": "fe23b603d883fcb3e0f2dcbd203a338e6402e95abd9c2d32ff36352b707ce12c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 895341745634, + "fee": 0, + "recipientId": "AKgTzN7RNMLvv4S8QzRHqvtP5Kx4KFeufC", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210086703eb4f783d915efde3bc0521c44c2c1fa7f09ef0fa0cce1b83c0567e55ea102203402af173407f63130b753f8e503acf6ab9272d4cf540ca2da5f76c5da2704a8", + "id": "e61c6ec80612d5006059f9551b9f34e928aeb6424694f773c56500bf2037e776", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 896791848697, + "fee": 0, + "recipientId": "ARyJArFNkcQUDDpQdLGL47BF4ZVXJ3y3fm", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022053fde5e97462ffe6d69adc37b4923118269fd9d858ecbca3b7ec8f9fd88e1cde022047da7a3a640d20856f1f267e2f06178d1ffefee2177e8a15b2957f24f83cfa0b", + "id": "45eed794987ba92e4d579a7aa21bf890bda28e3028a3139be7a4bae6ef232ac3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 900000000000, + "fee": 0, + "recipientId": "AKJn3FRweuCdDcNkjSGH36vXb5M8ZBjbcT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009e08602bf0177bd5ff9b95c0f173333563073c193eec6574a25b8a4c7453a15b0220778701ddbc1a30c3b0366dd7d7ad654b0066e4db8f8a884a668425c95dc57028", + "id": "5d3beece4057da03840834c3035f4b580872492de87afacbe44d540ed75453be", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 903190511125, + "fee": 0, + "recipientId": "ANN62YesPBDVEsW12iTwfwRaxhgTQGC6B8", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100cd15bb91ab56975fb578938b0ba8ec406c684015cc4a84386d93a1fd5660ab18022017b0b3c53b8d834a2a830676ccfcf346d21610f55e96c25eec771585d6993c87", + "id": "f7b3f239d399a69d954994d12753be50a09d71241516f3bc49dcc6fcdefb7d44", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 912865546892, + "fee": 0, + "recipientId": "ARuGpfJJNMi3BFFbsgS5BeHU2c5ASxcE3x", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008d232047da315e33fe38b625c3bebad7400b03cbbd0b046aa0c38e972d5843f20220261e30aa301f0f4956d1f95cf3e4ffc50f0a6d6dcb2f0175e6e589704eb88023", + "id": "e2c3a809125902671f2e0242d8cbafaed3fcbe90c659a782e9de638bca44ef44", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 913029661747, + "fee": 0, + "recipientId": "ASycZbKLnRNbYdYgek8YJQzvyNFwjcQGAt", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b27e1b308e009e6cdb6ebbe5b5ad0b81140bfb107e13ee7b044cf93d3152fd8802207b01d59ad8c5f909c37114ac86e763ad66c5398601d99fb1338e5944cd8810fb", + "id": "0a2f7813b32d7506cd8f633d7938b81c89d8aea083e830c65790ebaf4c6e7795", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 916154978619, + "fee": 0, + "recipientId": "APepu8ruATApkWtKxJhiU5CPYcFMfH5tfu", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100dba1440e8f6a7a3d4796995d180099e8abef17fff1f9d1c5d8c69cb3132cd1c10220351bb3f699b4dd023ad2ab75172a2c2f4d0854fd554ae437d11b3bd573f8aef8", + "id": "92f849292f6fc6ccb43b4f0feb73d9a875024a8aa9b32e4b4023936a71e2ce95", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 920325036170, + "fee": 0, + "recipientId": "AaDbKSFY6xA2UJgeBSE8r6n8wX65Py1feQ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ded1448f1d4b184b39b787c38e550308b2e458d19ffd23b403c8d8c836cbdce1022002d021095c60fbe111946539cbefa09e5202a7261d44df441cd1996c01e3e2d8", + "id": "879e49379ae26a5f8120f6a4535400fb01357eee8b4aae9322d51e149fb9a227", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 921784408416, + "fee": 0, + "recipientId": "AJGxTV9yTgqZWNiXifF9JM8U2vdPssLyEz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201d722c68e0a469d9bfc0a67bf0de5c63c4a969b2942c30cbab883fccff7e733e02202d9cf49d2fee94fb552e356cc09291a1a0cefd9fa5ca98af311a951433c6b3f0", + "id": "8e0a8082e102ee10405d32ba82988839770f5f8a4736b556ca64ea6b674d90a0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 922643224501, + "fee": 0, + "recipientId": "AbsrMsgKck1shqR8NwDm1ntDApWxGSZW3e", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009cd6e7355be59b5624201572983708b730e673c00b779c20273d94d4c34e9e4802202685f9d0798d3e167b787234885618a79d7f9967adc21786c7b127edaab39687", + "id": "59d8c7f34718a9845f8c670513b377e70b9f988c86007aad583f6318680be534", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 928155414454, + "fee": 0, + "recipientId": "Aaj14mdqcmAtZH7LnQqdWT3qf9BFmyR7hG", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d10065682321cd83ecf696a90d06022a557d0e6f64864be26aca6d3e7958348d02201eb4018574d93c83eb706107bf2108a5f48529782fc2b03a4c55482f49cc4ba7", + "id": "65e3b5466ee3e56a4646686a8bed5a279368eea489d49ef0e093d3c6848a8ddf", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 932790490195, + "fee": 0, + "recipientId": "AdQDEejPjoMpLg8cMDPJV7tyG2zLQmuDjg", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e668f456c6c608cae80c8c429f20cd6b38690f069c232a8d8ecb57def6986579022015f6758e04f379ff651fa51c06ae5b9f64b48203dead52a732f08d88fd5c7ac0", + "id": "f14cf4caeb5874d8bd03184939da80ee11ff146580438247ecb81af6dc116176", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 939660273449, + "fee": 0, + "recipientId": "AdGeDcDSCeYBfS2DA5Dd9VZ5SwvgmAgCz4", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100de0fa78884cbade7879b174697493b0d54e6810a8a5b1e9675b04d5a98668fe30220520492f5cf1c91d22bfe2d63edec163d25a09ab5c74338f20f3dc1ccb3a80e0e", + "id": "e11a97c65477cb5de932daf09eb0f377e14cb233813ddb680ffc030661dcd44b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 940453697923, + "fee": 0, + "recipientId": "AbfshU5wgXcrhfWNDjrkrvN52y3EScpg5V", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206cc11c0bf89c528f9efc84688be77e19339a847328790b7cdd407bfbbebfcdf8022057b0752aab9c9592f2387078df66d2ac5e40e49928df72a53b769b942cc40c1b", + "id": "1442d74ed4130eb43a84c53baa8ae6db3fc088d2ac900423f8b69953aa61a84b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 944039590123, + "fee": 0, + "recipientId": "AKj53MkBzDfkDf1SLXyMf5DnkC7Ra9cqug", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201edebd2222f9e616ed293c9c55f35c7cdfd6f0b4e739a588d912dc9761fe4dba02205b7b844d19d075b195a5cd94799d40c3292ca05f0b3bfdb4736739b7869e9d73", + "id": "8f981304ad1db95e27e2fca8bee4e51a421d0c8a406921d2e8aea3318e45fe9f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 944903185065, + "fee": 0, + "recipientId": "AUTtCwMqXuWDskRBVkdvDjCdMPz21Qqn1B", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220455ff666f653f5e990e60a35c440270b625b844ac3154e4d1a959e490fa11a1502203980c454fd84512adb7659279c031f72b23438cb3d5055238b34966837337856", + "id": "1741b8faaca3c787f7abc73fb5a926f1669b4c7ad363b2ff8db9c04f084b3f07", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 954261371043, + "fee": 0, + "recipientId": "ASdMtEgrbnpJzNg8ZbcA9wec7QcvgXBio7", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202a01b72970b65264a10f17e18db74bff086e4908e01ea391baea9f67528abb4a02200a63fe887e4aff1fcbe7235e72d58a6ca6cef97e3f0d7c89f7792afdba1cd41c", + "id": "cef4106da76091c4ea826c2f1cd235a182f20634765bf8f6183a3c767fe36e55", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 956921007076, + "fee": 0, + "recipientId": "AU3A2mNv21o4SkKrPjjumxAMSx9dNSJkbM", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009fb21352f67025aa234098c53b941d99b9afd9acd26e9a66fa08209561bacba0022067f9ec9f3b46d62bb5c30915f80b0da84b9efa71e6b9f357efc7089827803c40", + "id": "6f0e865e6a5d3b5564ebcc4f2e2c0aa6618418fa561284db9780fef7bf553f5b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 964800000000, + "fee": 0, + "recipientId": "AXUg9JM1fE7XbUPCsDeC3UxXCMv4tx8bgv", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206fc92484602f29f7b50a5ffc503c5d1a231dc0e54802d9aeb373ff327602325002204efccab14943708ca58cbf02824c6d1590dc1090bc0470bbfa7760f14fa629d8", + "id": "a059a31470b9a196a3894a864cd22eb0c92e159e776c7406f20cb92db7a54dc0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 967490707524, + "fee": 0, + "recipientId": "ASvJ5NScpJtLy2WQV6AyBtzh5FzKxP5N4H", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100873f68bcdf9688710966b018209079b9a4ebea3c7b49e281b220391537b5b6a7022033d3d9d2463907307693dcfdc80edf4b864cb92cab31bf89ccc3c260ba72b91b", + "id": "c996d17aeb1aebda108edbd8af91fae13aad80b959a5f6cd1b2f8152cf4e829b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 969700000000, + "fee": 0, + "recipientId": "AQinQgE4vAbgTXaUKCj1QabiQbpsAT8fzD", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022041619c75759c53ae76620fabf4c133b4bc2b8cf890f3c574a4ac706436a6e84e02204386f909f08ca380e03cc52330fa553bae5bc73ff9cfc5dbef030be47a4b934a", + "id": "ae59ee72e6a0f70f2a9ec115af54c17664b2515e5af10f3c66ae0ec5687fe005", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 984780889208, + "fee": 0, + "recipientId": "ATunEsg5YC1zoyYSuRap3zJyWmpzQkz9tT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f8ceeea56b0a689d42103fafd6a58cd236a14183201ede721f666309aa66769302204c345a794bd8c7aa04e3e734bbdac62cb1606cb1375ac66d4a405c9bf515c5fc", + "id": "5711b79607001f91ae6452e19d06b65a23310ffa4ad08acc8a30b24ee67bc3ca", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 993823555585, + "fee": 0, + "recipientId": "AWUKR4R5oo99dRkwRkvTvTJ6ffYBNv7zPF", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100eec0a2a2274589c7b1daa03e60382327c2a429daf422815f969a16a2cbe3bcab02201c2cc1ea66118960117cc6c00d5cbabb878e48783e37086bb7fe0e3ad3acb30a", + "id": "a71624227e6daceb049d5ae4cb83a6a6e9a04659f29e53a1fe30f4746f3dc194", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 998232238139, + "fee": 0, + "recipientId": "Ada2uLW2F4xsEVqmYhvk2y1gnjbQbeEGny", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008bcccaa6dc17a49848a90005e91d25cc5a2f3c50af365fb9e84bbd18f8cf19530220582fbdc99507556d418996f4aec523965f88c88efc5248d779526deff09b1460", + "id": "bd15a7f964c5ccfeeff073d396ccb099886e5bd562af5b66717f93dbb20e9bf5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1000000000000, + "fee": 0, + "recipientId": "AV5UwZD1wxVNcDjjXi4K136dBPjT8BUSMp", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022034080e7de43853b75340e97ad6a2823b8d08290c7050fb0b4e7be311d95067c0022035815502cfbadf9851555f9bf30b82544aacfa1c5eccac34377d86520b83d873", + "id": "494e41b53f142601472c50a49c966c2af768701a283d28dac2b09492b902f9f5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1001660153985, + "fee": 0, + "recipientId": "AKmat4frPHmBjrfwuMCk4uBRTPp2zAznfu", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203cd5409d500d5b5fbf817476f4ea709e7e09cdddcb93ebd2a1dd7cec3f46dd0f022051cb3f390cf2d0d9162d5409aded948a48fa466b25186498de1e35a0d360ea24", + "id": "6a948937670927c06e5c1358667bb2f7611dd7387a405bc429b25f43e4e56827", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1004564574086, + "fee": 0, + "recipientId": "AHnrwSwuuXKTxxL41xgqAwAjHBc7nsYCDU", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d73919bc931145f7dc02745832964a7cf2091a3540eacc25569f6fad1c954fd002202ca78633ac126f1a38818b7712572f0b17887e187dddfcfceaa4c92521b4c80e", + "id": "18f0983e59f657e62c56a4b3257d3a14cbbc405b4066f20d687852162c449a43", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1017708933348, + "fee": 0, + "recipientId": "AJnv4qX1hnuecj66hRM9mgLXfYUdEqWr8p", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022012492f457272b7d233a1324f49e7b1e04fcd80d555d91a05b1392b6559b62dcd0220530e2dab22b207a45dfeed314678a22822eb0118715ef7a87fb7bcdaf97cbb93", + "id": "5caa6ca9681dd44dc6bc566caf1289fa243e6448d9d9c5d19200800341f52dea", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1022309295002, + "fee": 0, + "recipientId": "AaZ88ShGS4izM2RAjdRb1v2XBDjeWNRiCS", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022022def44bc8637552e51371d00a3a39b5cd77cbbbf0166ad4f3431933ac94181f022055884070dc5ca41b51cfe9c8f363b03209c76b97c6dbd02476fe94397c1e4bee", + "id": "c09ea42b2ef6849ce9724fcb6e560e83c211df8c31bba0eb5853c1dbdfc2c9ff", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1024417009424, + "fee": 0, + "recipientId": "AXdzLoCsCHkLrhLGW7SbqQF7ycQMdHj5CW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008b4844b7dd8265790126f46b21ac699ac941d6b9e657ac3efc52ed7c874535e102204c3ac47d179cd180370993b8e7d2e322b584e3848b2d7a0ecb86f8f74169a08f", + "id": "3ad1bc54683cb14a70774636d880c11c2aa3a236ee3af42c524dfec3dbc7bd20", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1026165099001, + "fee": 0, + "recipientId": "Ab5PAShY5CX52trT6YmEB8Xu25t5tM5HjJ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f74a6839a13eb8a3df1b72407585ecddf0893ed4fa3ee32bc30a66f7c49c609a022051dcb39162f3aae1ba1269a4496eb62db24ed3c176e488419bf19250fef3680f", + "id": "fa7af6fc72bd13847f83a7e5b0a9c689315429725a6b6f87101f9f5210a67330", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1027972402698, + "fee": 0, + "recipientId": "AXk5qyz8GftcgVTEzUDhpfWZL52ZJMcN4G", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206a1ff97dae426570695a4585f2e9e5734c742bb8be2981a757890cf99a2d9fe402200f7e67d7241d9fbef45f4c0f51f7c86827649cb337ce8a902f242d6367b48ba7", + "id": "ace052f0c133b5875489f3a7397b48ade06a5ea9465c0860a290b3d34a5f927c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1028958385088, + "fee": 0, + "recipientId": "AK5NYn7AJdvYWy3DyESmvQb2SDf7PxRa5J", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009fb2a2c3952a7df061783e1f6acc7d7ebb1db208f242c9db13e82e0ae515eb8e022078dcba5d7c2487202d4a950b66cb3ba4e4cc8718bac248605405ada6131e617e", + "id": "e1230c88023ca1225588bd7a9dd7ddf53bfc6f93c0610c3dfdccf630f943ac09", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1029105400145, + "fee": 0, + "recipientId": "ARAkS27JzjnmAGTBPMQmKJgSwCgD6SNUDi", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e2fc6163e74ec9cb17eeda9bf171e5b4789200831d5ab73aa00356cb911f884102204a9b214977eedc6106cb9b6c416ee8a14d000e854be082764d65109f88ec2206", + "id": "6c8816c6f0b88e43ad7b4b790bcb539d7be48a61a830b9f4d32ecec9c595552d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1029105400145, + "fee": 0, + "recipientId": "Ac78t9XdQCAVc3aQVwrvB8HTUqSoDqiHAq", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100bb701ab9fe8c4f9dc7b1cefa260c8934b2bc4c2aad31fd607ded1c768526aeb902203b1b477789a7e8a69c02fca7bb5a8d348785a975e097b4e6cea3f2515d68ed82", + "id": "5005846db55b1f7f32d13b95ec2ed595dc8927902d1650fe366356fb6cdaa5fa", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1029518225860, + "fee": 0, + "recipientId": "AWPoYy3qsD94b5k2kbNuvUzZVh9SnQjBsa", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200c1463b83dac90ff2ce43bf2743c30616939b4a9a1c3dbee8ce27ab1015ef3bf02203c474948d5240127b76ea1f19ecbfff55033dcb3257faf741c0d73c0c4fbdf83", + "id": "fa84fe86327ff3ff43663f888df8c167f5567aca4f61c02157a7c4403af4f29a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1030548774634, + "fee": 0, + "recipientId": "AdPywJjNoHDnCzYua5irL8ShvUx9KSHnc5", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202199eca47200eb76742b28d1b0767359f588e9c2e6b19405a40ee32816cae9a402204d9b9980c2cf193f6cc38e6ca8796b0e192b055bec5b0c52eeb31b95da466bdd", + "id": "c65d4ec488a9d907cdbadcb865f4732ee6a0ea2edb8baeafa1e7e76c37237c2a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1031249725970, + "fee": 0, + "recipientId": "ANLRw9k91KW3snAC3NCPhhmzgg9cMgdg6j", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022052dd06e5866b27fe253f1b64dae8d3e1924bdd4666062d7e9384bf77cad2b86102201cea424f053cd156ac65ffbeb703d245b14bb2ba0575aa90d9613a7e8fe4a7c5", + "id": "5c7bcfce2963fff9eb502e79dcef563274a4c409a93334c3937c3019cbf55185", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1039396454147, + "fee": 0, + "recipientId": "AaAUZ1yWFqde5BYXbbUEWFB9FGGpQCcScK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008bf00e9e9954748def806ae413bc38629058e7c2daf5f56c34991b81a61fb7e0022015c587a5adb9e7cc11e4da7f2b6e5f1bc1e8f4f36c99a3fc15fef28390dd2c46", + "id": "7dbbdba5101c67507ff51e5375318d0aa8a9e3f25de019dd16af2fb62077d6d7", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1040719589660, + "fee": 0, + "recipientId": "ALHQ1oorGCEvSPsFNWdYPwRyk3rVvMj2B6", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204a48b4446d976bce24fe26d4e666947e59567c29d55254c4a4d986ed2e0af1cb02203147efd709c8bb850861b19c71997a5780e606889ccabddb70ea4f5beebcffeb", + "id": "b06a6b4aa2f8d71c39b5ab05f1535e521cea4d1a6cd304d56fcb02518e5d37ee", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1041975741930, + "fee": 0, + "recipientId": "AZVgPvHxJNtfVaG2YkJn7zPdFdUtk3jL53", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206c33c5318130b31313a7431a249900519d511ee8f2a43986ee37ca6d534aeca802204b833d1bd726a50e0a76edd62600031e215239c7e823c556e53aa225cf5d0691", + "id": "f9bf139b97f3dee7e627fab2bd00ad2ee7b2ca61ce259c8a9da4c0e33f8e6680", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1049727197915, + "fee": 0, + "recipientId": "AQrP3AzVXbRbps1UzCfjDFoCCnc1f19a5o", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220333ec0cb3e0cdf420ae2a89997b32607a748333fde1bd62becec1e8231b5a98d02201a424700aba7467ea4141d1d847156b83da94c26acb464cef725f4f8ab36f651", + "id": "69baefe519ef9cf9c530931b69908efef4ba290f89a014f2fe7c93f7d4f4d3da", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1078361899572, + "fee": 0, + "recipientId": "AXhwWcy8HhMYLbiWhUKnZPw28o6HfGJjaN", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008ebdc6ea8c2c50965088daffa9b2ec09f1a4548729284ba4aa2e9adf38cb82510220524ce025795ef5cfb044667870375c205818ba4da875e0c3cc4ad6283673d884", + "id": "fbcced1418f85f3aeb54a66bceb7bfee00708ba6eeaa3d5b7aa85cc841a14536", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1102465913669, + "fee": 0, + "recipientId": "ANMuAyS1SD2CfJvuZSi6RQb261gvFSJt1X", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205e2895cfc0f9708d2af9c6008451ffa63461201ccebd7037c81196198f3c25a00220151c81744a95f78670811a8b66995a0f2229be460d5dfd712a7e744f5d56b706", + "id": "9c19d49856030d283b8772771d575a16c5356413501e2acd042835873fc02cbf", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1102759943784, + "fee": 0, + "recipientId": "AVVhvtdbiqHm6zuFnUYbCQCsgfKs7GxJxS", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a5a5702c73261b34e2ebb67471524f509588fa51756b267c861b3cc8737c9b6e02204322f7c837883abeaa450b02e6c51e81c90c5a0d41196f046dbdbe0827e1de63", + "id": "734294bf0236a11b079ee873079c7c4c9f1b85a53750c0cd97fedcb5cdad0074", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1108427216593, + "fee": 0, + "recipientId": "AYnxyQgq1j5i7h7AEd1UcYVWeZhip2BPsy", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e3c2842f21cc80db48cc3a7fda70e84cf3fed43e68ec7486d2b6316bf94e85f2022040fb1c566bb45142bccea742c68cab0d9093a823c43d623ac6038062393cf171", + "id": "81ba05c7bfc196047ec8955ddb0ee07ab51176ed9884beac7e59d49e117e7bae", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1109838235948, + "fee": 0, + "recipientId": "AJvzuyNaWbYyC8UqDu7hPVBLtB4yEm8ovV", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008d0159ed2472012ee33ddf9230004b427c7f696bf22eccb67f3ef6320e657a33022000b1dab519c3bf58067af22ddb3fbd1df9144324ed404f0a3f67d7fb2f64f7af", + "id": "08c1f4dac6b650a1d2e5ca059fabd37ba23a2a8718ae034fa1759e32f0ecfcdf", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1110036076121, + "fee": 0, + "recipientId": "AGvTatnwQJR22A5dDEWXvWpfLCCFNu8tof", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205979870c79c60800f61d96ff866cc18b494945f2c805678b9d55650548562e6e02205a070cc7341571569be79255018a01cbe86a1330c1e2b02ad4aec2ab498910aa", + "id": "9541a811866acc0b84756a38bbf327a40cc96ae00eef7e20a540be4adce3ca69", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1110492080313, + "fee": 0, + "recipientId": "AGfChYyMy3ezANVDo7JBECGJxEYGeefPwV", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220298aa44e674cfaed265a12495d1ecd96299c34f8ee8beacb597ade8a5b22429c02203b640535bff8f890be8292c5ace7085658b1e71ed361a467945f1d6b97f5a223", + "id": "b1887110f49e04d53f26b0182321f2cc049877bc774784dd69a856ebae16d260", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1113211377847, + "fee": 0, + "recipientId": "AWhG1JweDmRpkT4jbojz4d8QshRZnf1AZr", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022060139759d9b0b550c2b108cf60902acd2da2cfbb0747e2782124c478fab51d1202202d51d8bd860b50a5822448e21f35eb97c39deab8cceabff01e30d7865a486fb3", + "id": "dd436734a516d0647539b60be1932d984dec023de8ec0b3d963bb48e2544da62", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1117612928727, + "fee": 0, + "recipientId": "AaTpLPFKjkyMqe1HAzsQvnvVDAPj7pyv6K", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206a305e6563c1eaca84abbe8141f6d16b053e58796933355afd0c004e4b4615f9022022de5f7a2dcb182a421cacb118d5606b3180e54397e535ead5fafb3808640ec5", + "id": "d946b6d8a8a3a305eaed80a1c5c856dba6b732d0a6f2976d2e1830168d242783", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1127012726593, + "fee": 0, + "recipientId": "AdwPm6G4tnxBBgtuB2UCX6kUt8KYv4vm4L", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201527ac126261312ad02383d5481500ac4bd030a800d2d1e8b0eb2e26d5986df90220666b7179f7e9eb56b0a91b43165247d2743083d37f61c773780314fc18d811fd", + "id": "228725e2039844ee5584f099930f5ab6c1c0185f78e69fd5d418c74abe97e512", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1133071775570, + "fee": 0, + "recipientId": "AQsoWhRqcDBKREvizPBDehMYfUMwpfoyts", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207f4c04ab56643d9175bd4c8179c2c3efc5743bb2b1149c38a182583c72b2ba1a02206fc46634fdd5548d2ae01950b9e9696ce6b880dcfc59abedd4c62c3757d0783b", + "id": "71e16485b6b1168dbedc07642c4dcd4295c7d6073b6b12d8c86afddbc392675a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1135911839174, + "fee": 0, + "recipientId": "AUw9RAfTKkMqFky8G7Q3s97cA1NMwsxsK1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d29979af23b1a9156c2a0223a3e5a76ecd62b666452dbc0931590730b0ef15bc02200eff2f5a2cb906c959ee855bf3261db9240d7ddefb5cc52bc1d70d295856ef99", + "id": "dfd87714aef9d4f11ee8a5383fd9cb8a467e3523a3206eaf99ec66d943bb41d6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1135911839174, + "fee": 0, + "recipientId": "AHkybDKEp9psTVmKPvHzqj47z56BY5UcEc", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205d422f18bd80adc6a12a4c8bf2f933fa5a49328137e696e1738f1e5ad0f743e602202522cbfbe59ca0e6d3080cf64011d7eada1505b5984553bcf353b871c2c6513d", + "id": "7500e3531f8b71b5f4b7aa57e9cfd47de4424a8b7eb5dca89e2f2b9e6f5dc34b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1136025441718, + "fee": 0, + "recipientId": "AKwY5JoLghksohAZG7oEG2JmgZuubyPGVp", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100bf6dc08b189c178a9201df3e5c32c3e42b534a09c7f676980d47d6d53335848c0220531edd5c8315583016cefb60ed96217a578c14dfcdc4d6ed703c052cc2c2adf6", + "id": "09bb287a691f3121e58b6f0d862b98e2fc1e6a703594897dada3f2775f8ad9fd", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1136025441718, + "fee": 0, + "recipientId": "AdbutZprjH2HAM17xxtqixENbzXPW9Wys5", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100df1312b79544c50df8309c5c47227587ffd9a46eacee45787cc56e37be4c0c8502206e7679edcba8ed6fe9bb634fdfc96115005803a8c12cc6292445585761069d4c", + "id": "d77a533c624889a76d7135695ab9c70217f78ffea9319af6800249ab846800f1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1136025441718, + "fee": 0, + "recipientId": "AJknkVe3o8zMyMVvhLoeoHsgMowWV2gZj6", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220090cff705808e2057c9375917aa0e29056143e9e30a4a631cf32be7e9d8f7281022001259193a883851281a9978aa198ede0dc910db7215f1da0aa40c6eb749fdbc4", + "id": "f0813945e05653ff3b2f3e0f7be0a392e5183f5805efe5fba11d23386cfa310a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1142768005049, + "fee": 0, + "recipientId": "AKjKD5TuG62qWVFPpeca7JGeg5ZSs87F2t", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008c34f0cc07ecff34844dc8b3c59859eb986e4713d2177923de88beded8a00e4302202dda4d34149b8269f5d62b28e18b3c0eff841acb41c7d19a657f673d8f2ae735", + "id": "f456730f13cabf7d2b355c690cef499f35613b3d9943769770a371d68ceda967", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1143514373646, + "fee": 0, + "recipientId": "AVzbLnDifGM3MgLLXGJokYRRaJtCTSDtJf", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e5ac125df4c653e04fcfa0ac241245873a2ab254eeaecf65b2e55a9974627da5022026cb84adf8e3f7b3b3acfe181df6cc1e4a1d64f06e9aeed4ee3dd2fc809da404", + "id": "7084d48327cb27c550dea563c70084c1b113aac2cfc8eaee8da2d2dfd231e7c4", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1166230353463, + "fee": 0, + "recipientId": "AdFkX9y3WiLxaeEsdHgTBr3fTUHSzEynGF", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100bc010d5be3aa4448bf37dd53b39cde7efd9112922ff340bd4271e6989ef0a6eb02200a155c4869414d9feb7359b3b7abe7a44dfeb329f70dba2f06679ed5f61943bc", + "id": "331e701070f52d72d30610165dfc9aa6c0d7077f7fefbf4daac202ed64563323", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1167544630860, + "fee": 0, + "recipientId": "ASDGBYEPJkRm16xDXW2uBtzegkmtDX7Fs3", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202e7deb619dddea19875e03f43270d03e73f37e48efaff365eda36e2962f676e60220697fe1276d816b0e5b2d6a55f06a0aedc12f76d6f228b07da41213d79d85f2a2", + "id": "4a2f713400914d0d3a66f565c2d1c9cc39a3f19c12543e2ec418110335a0b596", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1172864247614, + "fee": 0, + "recipientId": "AWbSK2Pwu5USnhcQxaraoybLz7XSRRM4JX", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100812581fa24ca31fb48b100b3bd5415e16727dd8be600f0f604c03408010055330220032db4b8659cadee9a1b949add6b4ac8fafaf0fca6774898848f3c417c36a180", + "id": "7dd6f8130f9d3f76512de04ba1c3473ca264e77b0613a2c8a86f3cd791fa659c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1176120457308, + "fee": 0, + "recipientId": "AaRaJMpnL5vKt7ADUsEAbVw3nqnLY6CvMg", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220379c7a758df66f5b8e7879119a902aa415fad87c14d36d7288b8565c90310773022074efd40722d365288b37f2e883b4a9c3aaa8dd211762b496649c63e477bf9e48", + "id": "df44e3d6aea679f21c528cb1e0831f1c2c1a92abf61ba046e05bfe4542b5cad2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1182001059596, + "fee": 0, + "recipientId": "ANZWuhTZmksp11sRpxy1JdT4mymjkdz2ys", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022004f1a606b87c3931b43aa9ad6c39c1b7a4425d7b9463d3fb1165ef64ef3515250220614138bfa85aa722ed98ce55a3a8445c39fdfea6add75b0d780e47f93a45d933", + "id": "fa762596e4127da262c6663483dacf38836d6efa88c818c9bef23d3c8c265cec", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1185739919799, + "fee": 0, + "recipientId": "AV7zqi8PG6BfB3Nud74eC2N3BQA3zi9zCa", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220246839d23affac82057511a02b479902a17d163a2df94b950e8cb7757436cbe402201fd4e87363021f4a3d341f8635d61d38010aba3ea51df5e1a10c9af1613db6c3", + "id": "d3aeecd07fcde727f3e8e8ba0852c7ff5b28adf9da80024cfea7c51f8d2c961d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1187780964457, + "fee": 0, + "recipientId": "ARyuySFRx29xHYMdL7TnKZv3xvBgrWRdep", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201235cf2bb5c1cf1c254fbe24d2337d87d100da46a7f39c211770ebcc937765b802205bbad34509bb0b7f86f8a2807e08be016273cec72bef1ab9bf5457939767832f", + "id": "b7eadc91dfd13958e6a36963095361b289c1c37c68f0aa3fca1ac4f648440ba5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1218554570073, + "fee": 0, + "recipientId": "AGqGgDyDQdj4stacZznPKNDRbdeQ7z4nfz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e43b353214830892288bbb6ac6da9459ccc205692fc81860f5551b4a6fe8f325022040f1567d23489b76539c272293702890658f1acb22ddaa3e43ec2c50ed293d14", + "id": "971db6562dad82beef13c4ec839c0d60866e141b03ec2d4a9d63c67e2fc46992", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1226105576744, + "fee": 0, + "recipientId": "AbumjiTo1eDMprMELVf5RnCwY4jFYxu5js", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205873b0046921b459e29f8227a7d59181a7abee5d75860c5f941c79a9618351dc0220795169efc3aa3651755c0563b623945bb5aa8908196cc2aa0d1fca2e87f4c6fc", + "id": "f22ec22f00452a8c00256018006eb2fd665b84932dff56090d95faffeb895a7f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1241085387065, + "fee": 0, + "recipientId": "AGNRsF3qaggSf4N9i9gpmMuGkHBKnLCYqS", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f6924dec0957658a213b7e04eb24a996018344513ea1a35163b4977bb1db709402205b8d978e83d7c5051c208c33617bf8ab611d63ab376fda7ab8a3ab6917ea0ac2", + "id": "9137dc5ad77a4c7b7946f24e7e150c2622c15b6d1765f3efa552a386dbec4552", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1248321295924, + "fee": 0, + "recipientId": "Ac9WFSBF9MPEjCD1f3G6vWCHtZNT53C538", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c9ff6cd56b1723f0bc7d5e7623bb66ca39e4561b79ed3f6b2e3fc541bd08787e02203b69a4d8b2837be4fc097bdbf174cc41c1b968626d125f497b106c30c6b8f5b7", + "id": "24d7adecccd21860742650572bf854e50a79d8edd7f23af74b7a41311b3d9917", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1251098136462, + "fee": 0, + "recipientId": "AZ8GhCcmNL9HGhLejRShEkbPL4fsDcB6Cw", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210087e8c65ba87f0af0fe5966e9d134ba62000972b7a4c5caba161f634141b2e07002205ec3411d77ffff2f5652d2074f622078dee8b8149b0f14b8dc779164ff03a3df", + "id": "912bb48bb857b0da7007fa875d86644c803c3acc59af672692cb0abe4fd684b3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1254056287561, + "fee": 0, + "recipientId": "ATRX4J1yKRWZwSsNyW2rEHwbgNxaj3SaDG", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009eaceaad92bedbcf6a3137ecef0dd7272072662bf6158c82ee8242dfd6a9265d022032b614fd8ddb333c1b7135197649a09e7cfd3ebee617f4b08753fe5011121330", + "id": "c9eb7cb21ffed293a6dc750757d50b459e5bb98dde6080ba44ea984bb5a3bb81", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1262124265749, + "fee": 0, + "recipientId": "APZXrDufYPZd4M6KK6mU3N9i1o5kypmeFB", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202dd40b2e9929255d731e525e3f2bc1d49dec2151eb3d65a58424d346b6e1ebb7022050c87541ba7b5da3e891df8b9148b9cc7f84d5e3c185172367b76afb8544c34f", + "id": "9c0e58750a4580a5efa8c5dab95ec4948feca82e6750647945584406b2b777c7", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1267980213012, + "fee": 0, + "recipientId": "AW5XkGBc44rDNynQgVwVSCSyUHd8dt2ap9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202fd98a801d3baf19fa8a77e2e0e5b8d684547744e26856719c37f37ed3e5af3202202b3f071b8daf7f5e57ea7ff8c4b54e46dac73204a72f2ceba6e5de7121f0de82", + "id": "b0ac53b52314830e2fecf20cac13d0e3c1c33795c55cc15fe575db1caf5e59a0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1275943681122, + "fee": 0, + "recipientId": "AekYhbhVD1qNL6NmWL1tUZTyopAjEjq1FD", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100bc37876c3e04ed282fdab28d5412486eda4952dd02d7cb625cc642409fa0262d0220263503fb14d31513ba463c6fa2bab58838daca4a19dda7604c7708002d576073", + "id": "17bf45d5a938ff3f0e910d5a75c731196d39553d66152b74cd4f8687241e3c49", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1281318617272, + "fee": 0, + "recipientId": "AY6ZLmZrpunUg3XuQZZBSXQCqhUqwdV7Pg", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022033eb26e2f3bf589d76033dbb4ab8a726bf495a26068e54782aa26f86edc83cb70220639b4a7648c43a4aae0e4d3cca922b7274aabdaf8096cc1f99aecbb93379cf70", + "id": "027298b8d2a4425c3b04df6e1200a87e504f79fa7ddf9f8e1453be427d51b5dc", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1283452028431, + "fee": 0, + "recipientId": "AZUXnt5f7UDcqCTn8GLMqrqxFumWzc6xdV", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022061a17e5dd43b0fe5b0bd9f3a10dc22a004fa2ed372e4668ab3fe162444a4a354022025f7353468432e788a5859f589e4cd840f107b908d496bce9e08a0ae8a48f81c", + "id": "fb90e727a1fb40e9f09caabc1bdf855f85ada79315a103e6201f4b05b9bc1554", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1290283529798, + "fee": 0, + "recipientId": "ASxqjAvYhLchFzgx2jwju4GsUCSQEH3AEP", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ee3204265b27ca699266a811730b567a7cc018f07e789156820f4b55bb5dc5a6022037f1b07874363ebac4373e04aa81cdacc8e462d0c8615dec4945254fd78bfdb3", + "id": "ab1293aa990a9bcf79d2c390946ee548564abe1961227cf01b6ea0e4f99caae8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1305366622447, + "fee": 0, + "recipientId": "AKoaU94wDMKcvDdon237iQ4ygpqVEP13Y3", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100bf1fcb56c3a81f457103bc035df6f52aa8f37b342db0d24b37d31ab09b345d85022033ea972e903998fd0b87d127f49638d31612c25ddbf176a8f28408da823c5382", + "id": "e33edc4c6ae458da431e7b3fa0c62bb9f04b900c071887835f9e7168cfe57076", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1307153045859, + "fee": 0, + "recipientId": "AYbyHKD2741E6HT7dM2YFnqM9mMPS2yYTd", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100eb0c6b3da5ea62ad2fc5d1d80b88627f9f88de9787c2369ad41d035fd4e984db02207b78c129b934570c69db9b52b5c47e7e922c64d9c0f6d05beb8b93507e232e3b", + "id": "b791858333e83013d9a2bc47ee3f32000e2a4b5425093c89e3615af4033bb90f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1332727985890, + "fee": 0, + "recipientId": "AMwPB8oS9vsN2mfaDVXSBZpGPx4cos5Mjt", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200ed8b29399b29160b2317c2eb075647fdff0f477844348d0c2419f6a99eabc5102205753d822e07f472849206cef2b0bd4e55f7584e793eaf40db6b1a1eb478a65b0", + "id": "393c15a74a9b38eafdb1b8bc58171ba17bfc61674792a0443abd4a4706674b0a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1353732126985, + "fee": 0, + "recipientId": "AeWDk3U68wyXzwYKrG1eFngLb1PmjEJ4NU", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f99a88f1106de48bf260252af1d7c94c0b128bf3a1293b39fa6aa3b39e855671022001c6a107ff261eaf289562ddc495ae5431f2c03eaae98e02d31d186b3891044e", + "id": "677d0d56c62618704636b51d569670848fdb4e838c1d127a643ade064730d7ae", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1363961613487, + "fee": 0, + "recipientId": "AYKGjy1QdNyw1QtuYMKEQiLeeim1PsMGse", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022072093aca8550c3ed5c93ee467e06dda194f02c5434da8b51e8ce1f425f4d6a0e02203b3969a7a176fde24aba664534284790c56aa157e3ab8a6144b2f82e14c328b1", + "id": "7f8fdbf6de9d41fca6389436ffbf660e670356a289f9b823a335e0c6f33a5fb2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1368486431867, + "fee": 0, + "recipientId": "ALqNN4gFAQ4i6keQYWt19VGVdf6srRw3fu", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203fa40db925f8076b84cb54c0442f866c882e25b67274df69d2e668d1713fb702022029b2294f08730eecb92ac2080c7f116ffd3b587ce00ff6907d0ac52b544188c3", + "id": "0ac5811bb68f5a2b9e1f9516414ae78b9b19d68c9d45abd95a83b45ee5b8245e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1373148336615, + "fee": 0, + "recipientId": "AWBBsjmyW9q9Eu6Esu738Bmhm2ZGZiwqmZ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200d6fb95c47336c8107cdda4217db3bbb5c7e6068e82d0e78c158f422d44e473b02202b2c57abf8045984d6a695a1e7396507b47c0e735a38bac8b4731217a618b922", + "id": "0d8c957621281c5dc06c45fd28fd69d0ae5bebd809f991f077d061e692470b25", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1414800000000, + "fee": 0, + "recipientId": "AYsi3kyJfxa5LvhTms3yLbVjLDcwZEuQFU", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201f2578fe3f6799f09c4e21ceb01444643676736794accb55e66065b5e2c7823d022057adec3762d37b685973d42c40d03b2c8ec414d3b4d2bb04499816845a358312", + "id": "0cf6ba6998cc228d806efa6663b4e1024aa417a15e46b5f64225dd86b2e1a2ae", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1445037440539, + "fee": 0, + "recipientId": "APNYtJ4DsTAPr7UzmPoQFsdj4GaBT4cDNw", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b55aacdbdafbf73aaa8ffdd77638cd52c2e572f68c82cce5a21182d8edef856402203605dc48ec3545efcc2ae67e9dfbc440a3e3fb89133dc2eac0969c65e9d7ea89", + "id": "a0f5649db4efa028d6eebdee0636a191c1981a80829cf6c2948c0cd3f5c14ff5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1445600000000, + "fee": 0, + "recipientId": "AZ82o4tRxNgRkjzV5GyBDkuaAgnLnUDMTx", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220713958c68f4b3f560c9592fcbda9dc2a6be93678f7e08ade6e96370c4eaa26d402202c862c934e996d1dd75dd49ed7204128b81b54b78b431076c997cf97e7747cfa", + "id": "2fac0236a0c0a9a6bcaf6401293611d1452f338213641627f8db909d47bfd8e8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1454528664622, + "fee": 0, + "recipientId": "AcCh8h1ZmQN5BeJ74rFJKE6hG9KZqbesYT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ca4227b7da265016be665600bc3e7bb20f75d7a65d72c13da8c8d9ab4ce383e2022038ff78d1c5e601365c28d9e6d2e4337a7d9d7d0dbde45c4a4023638fa07e87cd", + "id": "8ae411cae067cb9b9f15fac37ff5e9ecf9642a135de60053c3ecddc38a498f77", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1466807483534, + "fee": 0, + "recipientId": "AFqgu6rcFy6QTXGfN1FxC6sUHY2xCW7uc1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b2f227538d4b7706be16ade8e17139e739a09afe03282f64cc5c545dd1e2dafa02205597c6a4d88ced4a5f1a2773b27b256a9138310ec40c62bde619a99f6b4914f6", + "id": "2f4c8dab500b1105cc9545363586a417fd7946615170bfad8928f68b145e067c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1467651315664, + "fee": 0, + "recipientId": "AHHrxPEi2Kj5VP6W5ZKegVh49PCV5n1jYG", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e97ad561c742835e8d25dfe5e8417892e5b73a5fd29200bd36760092bca344c702202441a37b935457517e87484b64edd8b4d8343eee4e6acfb4a231faf29a079c9e", + "id": "806e0255fad866d11ce328cadcbe4002bd5a496bb152984bb09344e890d566e7", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1468250973203, + "fee": 0, + "recipientId": "AHBAMChcuEmR4GEqhyx8Kwf2uSadixGJ63", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b2484f242f0e10ff6a3c0a6ce4b32c308153788c8d844ea7b8b6f53eb2bc6013022009b277ce199b03c13cee24d7e1f0d0a519f097e783053ed8fb1e85ff174b5533", + "id": "e024d4271d53d17eee174f952a3577ce724d9f9896036a3c2cd3dfe7680b6853", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1468680421064, + "fee": 0, + "recipientId": "ANAjpvQ3YXDaQBdh3uq9UrCzpgdKbyyPec", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220329b1550fb0f30e6e506aa2a818bc28db4f5f83510cffb3e92c5237ed612e3ba02202b595447789bc432db35f5795a9f37a41dcb7c610dd1148fa46748291a08ef74", + "id": "04ca01893a22c45fc969173c7ae1d0b8f319b6ce02a52cd8439fd40bd7092452", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1468680421064, + "fee": 0, + "recipientId": "AZdWJgmHDvj77EmtJeV1WvpBP2iotiGAm1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022022abe78cf54b66aa2968b866a5f2c89b5ba498a10716b87a4f5b1b22294268b002203cc887e61beae4a9b5d1472a25fc5e9e19fa21195710159c19b433b9004fb33b", + "id": "e1a59241b4186c667e2092a767cad17bcd1e348c0e7507e57783ecaddd8b59a8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1469630945593, + "fee": 0, + "recipientId": "AJduNtdjCT13Xmn1HbRG7DA4H4g4Q6BvaV", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210090c7c64fdfd574b1a2e65c070b231e9c99a4fd26d4ab2046d985076c42fc21c90220481c1d8d1458f1dcf7adf39a52fab40a3f3d25830607ce853e20767623fa691c", + "id": "8bfc8aa67c36db1b6c8db6f65fd89687b83bbf8b45223be0984c084d2d507621", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1470003556578, + "fee": 0, + "recipientId": "Ad4QYPyJaqhXRoMKbezNvCREbK5XPa3zhy", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205188ab1d4c98d2f7c02b3825701e03b310655fbc44db5931a89432b666ffcf3f02200e1eb5e6220abf42c61477be919ab32c21626dc74dcd14a48c5d6078ac155cec", + "id": "4029404e82dedf7fa4e8df1e90238546b5fd8009d9cf6457ad8adc7504a1ac00", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1470150571634, + "fee": 0, + "recipientId": "AYF11aoSpagfi9wzfzY5PWdsYw8erLzi5N", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204973fbd8f15de9230d6a4cb6f9f3bdda3dc7e1b66abb0d5eca95ad2ab43b4d750220132d7876e371bffb26b076bcc1b68ac7b8719917b25d9f09c597ec58e37bfda4", + "id": "3112c2354cb4f918d6bab6f765a16084540663423d129abd46a7f98292f6e781", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1470150571635, + "fee": 0, + "recipientId": "Abw8geGxqiRSNtAZubYj6CM7NPeWK7VU8t", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220532893083e7e86ced90c28507bc86376998b7fe227c26d44835905dc2c4c3fe20220784051c6f98e86370580c94789326635a2737a3f1d9cbe553c9af5636e4c7a15", + "id": "508f69085efd61c4ac263c576c0da0e037ca716874a848a3ef14d7cd8fde3487", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1470150571635, + "fee": 0, + "recipientId": "AHbf1KCCkWZZYww8dBFjAbSK4oi44ATaNj", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207409532c4f13e05ccd6236cc3230bd8c4d8b9fb3335023566af2ec6a22ad545302202dbdccf7e42d4aade9dff05a5a16c5c96e9b8050dd5b2437f3471097f8ad4211", + "id": "dc3acba04a593a641812a6390fa5b0e63837447f08914576425715f8887c02a3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1470150571635, + "fee": 0, + "recipientId": "AP3uaTgqBZiPz6TFYNJ8zNNcZiNBidyLEa", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d44633e422ddb30db8bff2241ffec1290600ac1307393452dc7754e7c0928177022024cf31e3fa2a243218375cc5e66c8f0dfa1df07ec5480196884309b54a4068e8", + "id": "9273a1dda6e37f1e98206d1c5c89f5c36d869a7a4e59d1134875cfb923b9fff1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1470150571635, + "fee": 0, + "recipientId": "AGuHXDf1v7Hwfobh3P337B2579DBPpjSVs", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220278be19de5f1b004e82a31fbb872d3bc14f516c26b56dfd10fc69fa5c724252e02203dddd4e05320b906a2a3945e52b412e12760c0be9e64c9286afa2ed1b907a43c", + "id": "6dfe84e6247aee21e6df75a25030ac199eb74a7079b01df62095fe507c0f3b53", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1470738631864, + "fee": 0, + "recipientId": "AHUF2TeEq2KfWsdKJmKkyb2r7rn1ssxVTD", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c5944532bc50d544fbe393d8067585bac4c00239d96d2cec920b16b5e58be22702207e0594792578262ddd6c2ed4f443078a59b17412b835168837f58ea03268e8f2", + "id": "4e4ec69496a82528dd81743b7121fa8f8337d95a8c960e035ca863c9e9e945ed", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1471620722207, + "fee": 0, + "recipientId": "AdDYWwFY9CHymn4k8dbnShiEJZyF1gCTbe", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202febe57e819afd13b956afbf988130d00fc6894a72128595b9d3c5c10b7171ca0220127aeee9f9e67b4ced063e09300edb638be7001c3d823bf4873f2fc07c1a8052", + "id": "c3efc99b197e710b0db3510f26d78676fccff157f80a0043ff70f862b99bb48d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1476719471690, + "fee": 0, + "recipientId": "ARPtgH415JQHtdLmpkyfXm5QvUB9NWWZRY", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f9f6c9667ac8300ab05a51955046d8653cdbf93d28678be87e4892502aff5bf8022045b45cc9ba1a05612867c00cb08e881ceae4dc43e0369cad40789edc8dd3ea66", + "id": "5accfa3b6f5bde03070a900439418bfcf6e333eeaa78a55dd38dda5281f72359", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1501867950683, + "fee": 0, + "recipientId": "AaZMdjLc3oc2VU79SWzjaM8N6QQxD9JXsp", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a4efa1b07b43cdb06620c1ef7cc124505d440620ac4533bfd20d609d038b0018022050a04b85c435ad086578e698d11bcf35256cde10769c69945e144ea5b369a5b8", + "id": "99e166bd676b85006a59c88b96bafd199145e0464e120a72630a18886fe93347", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1521031173923, + "fee": 0, + "recipientId": "AHGrL6VPzSfw2kGfTZWFLN9hJxh11NLvRH", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022009ce1f620f2978fde9d02d346f69178a5339d0d34d229c9303a6bf3b0d390c7d022052bd984b7abf23e6e1f71f6c532a94eb92fa99a1b1a6683249ca16c93610e06e", + "id": "cd80da60be2804c472b529b4e41b3117d2c54b37047fe32363431735f21f4771", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1538544082336, + "fee": 0, + "recipientId": "Adse4g6EQzevtFtxCaymFKNTXfiqT8q3i3", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201e4d2f7d9ee5804329bcb4a16f1a925878dcc4f35d2462bbbc0e5dd63d6c5d86022039db901cb2fd1af4827f7c902cbf9d3758d56abaa3c2673f9a36eef29237bc4a", + "id": "16d0f95017cd07ec7ee5fb6b9a34cc55b4f3a43b7e551a8a2117fb22117cbe13", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1543246790015, + "fee": 0, + "recipientId": "ALreqLXn9X6tcgYfw7LD1WYYk7Pt77kdUd", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e5d85a41b1562fb3238d3e5fee2f4374b794aec61600ecf1eeaf745ec90b699402202b87a4c0574ee646af802ec7f4ccacfa7d6163c70f169b03384bbacde592b398", + "id": "b0078a99ab5fd8889b072e2022171a7eb345aef853d5d097a78b761989a260c6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1544792613177, + "fee": 0, + "recipientId": "AWuvoaPLVWvzGLAdJhSAY4gdLnTB5uEJdi", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a74e828d11fd810da6ce5be317d67c6795cb1bc02ebef637ff8d0f9de8c00412022073c5c9da3fae7a882d34d29ef370cede0e7b3fdef0ee054e72c659b0dbb25b71", + "id": "eb3495c47848de6b51b7d60f0918727bbd598a58625a3e308353dc27cbe2987b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1544843298795, + "fee": 0, + "recipientId": "AGWDijB8AcjiwxYTB6eybHiV9qeaFXPmsq", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201c541b0daa00bdb881cf99ccff32f8c04575e14f55e0987ddaaa9e83079ca420022042d986fda9b4e961d5487e602f78aa3c982bd4e0f9601ce33ca5b0be2cb51332", + "id": "cb64a6bb232fe4a160ef8a96b6f34bc76e8d1f1355edf969e0e1956886384aae", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1551677103335, + "fee": 0, + "recipientId": "ASqxPCEkpFj8ziJ6j4FY8pC3AmMXXT1KtR", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ecf1d28c1dfbc54be58569ec5f273008330340ab70df7629243b096e32357ff502205f9b0ed9cf1b7d7ee02b6e7a06799da79566c831cbbbb663b56b52b56f2f8632", + "id": "18fc455a58a3d42ae22c76540f497b5c1e74887612b6fb6128f6930d466fb6ca", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1557630114327, + "fee": 0, + "recipientId": "AYi6DEzFoDBwrRjj7sT78hXJGayRm3tZMm", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008ce7aae30ea9cb91237a4a646db6408a52917eef521c4575bb94e8a4a95e25b80220356cea901142679c62987b9d6f36b82029860226a46fc3e056c8120588658144", + "id": "e76471ed188cf048233c7114f4cf26d21b24e77b4e4c4e297cdc3e02645ab56b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1590480695140, + "fee": 0, + "recipientId": "AWevRPHEGJfM4rn2BRV435fKi3AAnZZuxP", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3043021f73eefa8d4dda995031746278feb82015905014306cab9766abb3d428d82fde02205852d35a40e3cf3a0113295ae54c76b4465bfbe46b67eaba24b2cb2590ff4b7a", + "id": "03d82bd53b9b6bb359d6773a6ef3fd340664e1946f8bd02cbda99e53fa35ba69", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1591288549068, + "fee": 0, + "recipientId": "AUkNoFqcTkMpPbvSx6FH5HPssnuWeUN1Wy", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f6ed9dac47067252fcf8bdaee46e90445a60b818d130f96755cfef8aed8c03830220139448b9a28051a55cf48f54f3162f7279e13e6a987a15b020d3d96a7e9cc3c9", + "id": "cba7cd24daeb4cbb94a63f729b6f4628bba3c878b09af82c6d81dcee220e8bd2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1598561495493, + "fee": 0, + "recipientId": "AGwteprikJgukHmkfyLepCefswocmkeJts", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203fd3b520f78acab6d4319657c1995b3abde676c85271af58fd8439fa41ac256502204add7191ae8d36d8028151d67956c891f67bf80b1cc3762fdf0871087a2ce8b1", + "id": "296c9e5c6c5f2fb5d7008c3b6d5191a02aa7410fc8efe451f8ced624d60de865", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1603639652925, + "fee": 0, + "recipientId": "AGQZLKtm74nXFBFvQX954zsXpBCVz6Vs6W", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100eae62745fa946e1d39d8f12c6a0f965c2dd95e709a728bd2b4aa800b8174ca0b0220529f3a59374eaf4208b8f6273d90af22dce3d183624fbe50b0ec49fa3dfc1519", + "id": "fca0223018570612e9d70ae707868624c6c7b9b42209077bfa7eedaecb136b86", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1605551439283, + "fee": 0, + "recipientId": "AH5EBGfkjr5UewU4Pkdk4X32FZUacp1wib", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022020d4c8eae1b41ba868e1796068e109d48cc208a5eeb374318c448b2aa21003d70220323a6f9fab9bc56481e8d6ff37be611370aad7957f8b0506688e20084466460d", + "id": "069a53a5dfb9ee6058e1202769e25903a014b12df9e4a815874bb4675e95ab37", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1608266337418, + "fee": 0, + "recipientId": "AXsBCKFEyrq1TmAyBHBFX6Fs2iLfg7qYsB", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200fa692b85aabb7c9cd1c23288ab8c3c51707598b7e4067ffc018f27a2428e37b02204dd58f775a2ce3340d1ece51a2133b628cf79e26df11dc75669c2f44b2e58df7", + "id": "399cd9f4dcfdd54a47fff7d51568cb6525e54332251a623a94c8497b228a88bd", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1612755177084, + "fee": 0, + "recipientId": "AbjtH1c5sw2cPFu9D7cCDNU5dchyWERKV6", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f78f0db05853c6639d8ab877bae34a93f65ec3001b62a313d0790c1f08429b9702200133bc555e10405721c43638af4b77eaa4c57b73c64f786ee40df2f4827d9f7d", + "id": "fcf8f52e8b0a6ea3d181ca56067bb44d93f744e28aedbbcdb8e06ffeef189db0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1615695478227, + "fee": 0, + "recipientId": "ATQZen8h9DzHAt7HgPAwzcWfAC6CaTH4dp", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203b9df7a00baac5b1c3b61b590455967d9a38701ef39fbc4e3e37d1c74631f0c202205625993ab0006b2b2d65b0b28871765a4345a6482cf2aa42d0d1ebc503f6ac93", + "id": "c13207f4ba76d22fe47a1d538019c73ac6652dd7b6351a4222ddc158950e9958", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1632724842016, + "fee": 0, + "recipientId": "AMbioVwHwrkTYHt4zqt1r577Z4Y5tgWwJH", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210084ed4b704b13b31aba705cdfc9df95fa552f0254e97f89371e9488d672aa337d02206ca6ec6c2cda84cc0534d21a4e74d8782f11aaa5690668ab17768bd97abafa9e", + "id": "18ae7a152adcb4616d7f396119eab66060b48e66553a4562737e95244dc2cf8b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1635164836036, + "fee": 0, + "recipientId": "Adkm397wm32bW55AE1kQTGyk1t6NCz7sfP", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c749b79487813d5201670106a0cf10f990e795c5405801c66e3fda6b7bb8515f022012a06e81726ef353b47297609051d850caba385828b5d9a4e044f1e5edb32471", + "id": "e583c7aa0cf2bb4da4d9886b55b893ce1b1052ba6d79ee510e7f58c273c8b1c3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1658329844804, + "fee": 0, + "recipientId": "AGvf9xsh3xgCMSnoCYLembrzthHqGJdwbM", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200a16ffd1d50f85db3ea81de649a38892df46548d4b69ac6ba8e1cb610bca9be6022005f0b9d13821099d92a8fe5662389f439c232e3da0a024dd43cd5eea7ab4fe21", + "id": "aa4d7b90b4c1fbbd4297a23df89b89a84c9c912f03af1a9bb4dcf77dd52b794b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1672675483771, + "fee": 0, + "recipientId": "AMW2gACZ82N8CNgjFL4q5bzC6dRwpave6f", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200fd4245350f29e79b767acd442c893689dbbe3fe5c6d0b1bb40d3d7d8f4e0dbc02200f0d67c711afabfc3d38324236f051384229ab00f1f9a698627567b8f73460c2", + "id": "a8870e6e74479438af8e464c62dcabafbe785b01824e078e1e121bfff01e880f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1738465434518, + "fee": 0, + "recipientId": "AKFT9sF88rSg7rvy3gvMEJJ8LaYsbEsYH7", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fa6c33a957f7b2b26549f37208c4ab1d968161f531cc2c681c863acaaa90627f02203138faffd5b376854a9e6d7080b2850d571f07b1a2c7c58113dfc105c6318f54", + "id": "b416130c8a04526c058e7dd56d79161c989f0cfcd83aaa798e6235ee6fcc3c57", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1742839839455, + "fee": 0, + "recipientId": "AMXgwGKJbUt9NT5qEMwY2dxUVQquQDBrTv", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220537c4ad8333d6c27ae2d4b5e3822242efa493084a984db369f4538f61fd55cb302205a054469d04d99e8d3e57f47ce237178014ea4c7c33c7e05f5bab627901b1e20", + "id": "d5355bc6a2601705af7f537514f45a838246dd11a95c2b33bd3a3bb2461bc89d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1775549503277, + "fee": 0, + "recipientId": "AWGk5PUpJCLBr9GppUnNY9ryL5RhbstthX", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100cd7bf83928c227b964f34cc5d55483743a1ccdf17f778f14bde1bde676a7051d022034e2bb957bdf212377580f3b6a7ac3024179b1aaa0dfe57e9cf76c32f37ecf6d", + "id": "ee657127722958204f85897e7825ffec69af1504e20ade4076b07aefdeb263cf", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1812187469576, + "fee": 0, + "recipientId": "AReskqQAtGi73GHG6tLyGxpyZKAw6kyhko", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f7d097824b01b8a9d290ac4f7c80cc8bd5f32ef07b22768ab289ae39048b2b2902205bff5fcf23fbcdfe1f60cdd017fe790153ee783facc851af6a65b7e2cde0cbfa", + "id": "3641ee56bb7b499407222f68f9b0432c80b7e6a32a8515f8c5c08ee38bcbdf8c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1847900000000, + "fee": 0, + "recipientId": "ALCuA5ST57RnThByiyCGYti1rFFpy2vaPy", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210088f32afedbe40f6ce661f0e828f6815288b96d78409c0067578bc016149d05c0022018dfcd5230d3fca401a478120a60a153c027212107b380c8f428e3991775d067", + "id": "ad9154e66ae59ac9f80f524568452bca4f00455ecfbfc25ab89652ec84f26c08", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1849124693198, + "fee": 0, + "recipientId": "AbpeUAgMG9Zk1XsLfPcNshwumea7mkekBZ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022012c3db569ba5f74749d21752f16fe382493c639d383aa30d9bc85ffbdb3dd1c002200dcce7a238a59263badcb59d57e531933ca1264161aec6f04e44e5c87a6767c1", + "id": "f5615283d55e13b2b690b281bdcc412f9d87493b212d2b6b76d529e54d0a6b32", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1876941234807, + "fee": 0, + "recipientId": "AdBizdK3H7zfp6cnpAsAi9uR2fvJNQSFd9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d595be37c3d0bc9d54b9746e84d92ea5d28f1a39df6c0ead2ab145191f95bb4e022020c5ece72829027083379f47cffe67674d4f4ee5e98f9eab80ad16b2fb44a4e4", + "id": "8bb71be1a515fcfdce9a10be706054e87bfd64cabc0e2ad958569ae7a03068a2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1891934510958, + "fee": 0, + "recipientId": "AKxpcA6iVjFtxKzcW8H1EvQY7nz2qrkGFT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205e4a8eb13b197165a479dd3c0aa6ef0d06a011ab5fc429de4b25021fed9024ab022061c25125f58c392d7d10d9b060edfd3a55df16009b3b50ed6b7825be84e0c375", + "id": "06f4102c8d21139312432f58fc981d0e183a97c6726506f8ea1ea71e5957c4fc", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1895283091114, + "fee": 0, + "recipientId": "AYR4E6VBw7Ut1ygyvwLxbwDYtsLHrq7T7Q", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022012c4b05c360635a515a257733ed66d9f100fd39810beba85b4014c21c068bcd30220090c79f001b853f4e38c3df7f043fc8c7c2c683fd2f2572a01e38d11f4219d88", + "id": "bb54551895feb42ba8c85355084adb36d7dff452ef87dd411558a07356989cae", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1903697975211, + "fee": 0, + "recipientId": "AbT1VtooS3gA8M6KRT4Fy98tFzaTg5N9Gk", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a905b417aa0cd3b7f1b195254e15bbe303e0e59d7e2f7007889e0615bfaf945b02204050e412101f519179944471aaa65e6d32045138a45631fce10b18e31a05748c", + "id": "3f1f30abd5977c35300930eb6a8af9b16f78ee602cbfeabbc3870149d0144c57", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1909607394110, + "fee": 0, + "recipientId": "AZt4XTwHPBLEhr6vkLEYX1b1RKmAN8Yit3", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f5fcda2c42c4756ee68e460366d4ee509299d67559a4ce904dc22adb03d8422c02204be79c434dad458962e524da2e99ab10116c61374ac17bc880dfc5061827bf61", + "id": "8c4192958e2a40b7ac6886d39d6324a17d4c05c9c7e96da6bf6316742f2a7b7f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1911195743126, + "fee": 0, + "recipientId": "ATd8DeNiNgb7R4uiQGyGNLYkq1q7FhikGk", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201e2d7e0d4153794e41d90c9cfdf873867f46da8fb73d4bf5df8250f782d4a4de02204c2c78faf8a805d97119e09e77c132630f7d525bed291fcc40b019e71bc85490", + "id": "cddf63350558f510f3bd2bb86009c71bd39f75d36ea1bb245bf4b3af761f2e1c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1940598754559, + "fee": 0, + "recipientId": "AYeUdkzuGw84sPXgFBdLjfjXtG6SsJ2Rjg", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220621146cc0eb8596f176a16040fa8832112c2fc19b49c5a4a1ba830de141df6b202202f1a8232b2057dd529355fc4aec34ca4825630d203182f02880de2efe342d736", + "id": "00f4cf49905ea8c652b71c522fb8bd19ddecde1d2e8feb1ee2961fcdf7034a04", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1941422708032, + "fee": 0, + "recipientId": "AeVN8SgGb4mUYCjHVCCmWfw8h7WHb8LApw", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203d2d268ff5c91f54eba179cdc53b51726f6eaa3c1dfc3598be7e444c12a5575a02201cd9dd296215e16ebc511146fbda0989c8a41051dcb07d62f9fd4622bfcbf27e", + "id": "fb2a707333b3286f4d44b61db19a2e617bbe3592de77da45695444b62fc0a5fb", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1946861217599, + "fee": 0, + "recipientId": "AGueDNGxUQRDsGUa9aSPw53XKNgNPjUAia", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a8a10c8b659087d985de4bbd6166a9f2c5f8cd46e28be26b2f9babe3a2d063c80220460ce29b3f0327359a4028ad600d25bcb25634f19bd9b3d8e4a3014b2b9636f8", + "id": "e127b243ad79cbf966ab4b1c77b45e6657fbb5f49e4cc3a96406887e2ce4637c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1949845628984, + "fee": 0, + "recipientId": "ARsJyHCQ8YnDZYm8v2sE51e1qtGnK3SdMo", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f82068304b6f191b9452c1160caede73592d36d75a00beb74a9af9f1886715eb02206b38b09daf8e9184cb91130165227fbf05e94b835a7399d4ba07ff8bca6c1179", + "id": "6ed82d8c0071b52aa28e9674e012ba28759081f527a793da1161fc32d058bcc5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1973042309220, + "fee": 0, + "recipientId": "AML7Pg7WEuKaEWAM52rAUfv3RWE8BAbp7i", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204806c034f7027b71d645ab6df4134ce5c2861e479b9ce8a608669221fa1f9991022052ff1460577ba1674b6a15ccc505b53749bd6fdb8f0d1e3dfa596ca91bc956cb", + "id": "5d719b936209fc04fbf9e118b78c688ae6b586d0d9ffac1cf88225f47e2c37e6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1973887957498, + "fee": 0, + "recipientId": "AcSTQCTesrVHnvoAK8r1bwZ9CpDqiPmRK1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201ee8cf1f90aee896e63feb920df725b6897c6d4cf0723198abe4dcb65fd6359702203e5307a6831a54072cf564804482661789e2c78b9c189760ef1b33579de60d56", + "id": "5b82367f3b78997169ed9fcba1e4eefa8054c96b64d2bd30d12f18f2a364444d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1991239524027, + "fee": 0, + "recipientId": "AGhLhXKXAUWDZRS3skaEVMzpcyeqCyE6as", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022019f81fc2e04573a9ec9ffcd4c6504da8d206467a742c8d9cbf96d1980ab77ff2022050b0746effd9c253e61dc8f89b015b4256764292860db88eb9a6832c33812b66", + "id": "b62ecd68c562fa705d41d59b3f871934b7a5594a89354cbce472c9772e100393", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2000000000000, + "fee": 0, + "recipientId": "AVMX3Y79qXSHBk6tUrcLAeKh9C25xtyJVL", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100edcdf6bd19aa85b0c2078804a9a021847592dce74d2dcdddb38a0ece549a080c022057316f1c9f36d89f08ad9020385c16fed5bc088f12e588166fc984e9b0c6fda4", + "id": "4a26a119361e812cb7fa868b10ad2c903dcb681418113abe72c610afd4c1475a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2007149179076, + "fee": 0, + "recipientId": "ARLoK9ABM7bFmaqLMaEBbfTVvsXqyYaeXV", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e924d9016e8ed30d3e06fbea56d70c05b670b6a9d6999a039b93b0d436357b25022015da3def5243cdac0d0baa92e8f695a5018e06da5155d17f7f48dd7814341b3a", + "id": "f40dec591c02dae1e1eb176583476d7a7e291ee5f6be1741b9ba3c0e97013f1a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2020119321574, + "fee": 0, + "recipientId": "AL4youLTt6UXwxXWmqzAxznH2aPEekZCpf", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b4c556e5c648045ac2cb50aea26bfc158506a494c66bfff2d22941ab8a3f6af902206b6560e4d19bbf8b770c2ea0cacca973f94e683b38df2a00d81727d4bc0b41a0", + "id": "394ffc5b4a91e6dd81621246ca0a1070f3b451aaeca3f1ad48c4a4186409079f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2048474511235, + "fee": 0, + "recipientId": "AGsx5dwwQju71REuRJd8iv8AAo6wuo2Hhj", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210083dab3dbab91f91a9f7bbb3fd91b16c5457fe84e918d475cb7e544d09466c8380220504deee2a01460cc9dfe7be2531f92ed2b14a6923bc6bdb02ad1131803fc7b28", + "id": "0c1e0d578f3f6afcdf8d0406ea5478ade1c52d87b31153fcde6c6345cb0db9c2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2058848207492, + "fee": 0, + "recipientId": "ALcc4t52pgbFF1iZ1dntq8oK1TjprrckKT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008ebec56c81cce72ade2152091e9771c0c9b46c411f17c49272b1647466b4d1bb022022bb7763cfb7af70ab4d97d6301db9a96046225be25b50234a5e1bc868e978e4", + "id": "e3e18ce2031b8052143296bee5317ba5013b6df080a1a222fcd41af5a3263398", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2061097549268, + "fee": 0, + "recipientId": "AFpxF8SMNEMaBjhw5NKdydhfU9zeDByEnK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100df0a94e388245d9cc205bd2739d9e17f02964f957707a88a51aaf03d029fb58f02204fe22271ef442b7364541ce62a5d833bdf061d8c6c3d78809a243e26428b2f05", + "id": "a91fab928d30719452a7890dc5d7b4bf323642923ee6e99c7e12aef8eb5ed821", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2061097549268, + "fee": 0, + "recipientId": "AbfyMpZLZXJukJ1jCLkQaDdxU8hRMCroHM", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203b386391a09c598649acf2575dabb917adcb14572a60f1ea8cbdfeeb4557549902200d3e0c146cd9d726ab91b215b817dbe68adc25dd8f506dec264445062dfff1ea", + "id": "0c1c747f9e680eb8199584b1f2a9b3b855db0f700e61ef3041f4b9388bb0c826", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2066612412189, + "fee": 0, + "recipientId": "AMgiiG8wXhd16NBjazW2je1hK9pfanLyMV", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204c5afff450f8735039b04fb34b6324136842b66fce3e1e87fb5cefbd23d1384c02203364cf3f9b63c10e14909c7ba9aa6d442da124bf257c707277a8167a05bf894e", + "id": "142834112cc331aabf1f30dbcec6c6a538c9b47927eb71ffc30083f8322bb224", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2109666070297, + "fee": 0, + "recipientId": "APJ25Fek6dNkA3jEExkyG67UAzrDRvPxf4", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022047b3d2953eb0b6e1834bb77053b207444fdf49669578ae639e062eaccb721c9b02204d142ead55d393dc0557b1d4b417e71cef41ef65623ffb5bde6e56665da2db91", + "id": "439911c5383eb2e090858e43740e9272b7053d4709c455a5fdf21ed46569a591", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2153677032409, + "fee": 0, + "recipientId": "AXtyzwP8X29Ddr5KUy6GuuxWibW2eNypng", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009ce7072f8d3bf7866b357aa36b475f3eb102e31caeae5d8d3c6a39d8f3c39a4a0220636f0f46dbd6a477194025d39f2db234449195b53798fbd03ce3e2ec3c86edb7", + "id": "dc9c7ec06d60f03495f590e1e46a6283db8cf62dcfd2186fc65249f4ddf51074", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2163834169022, + "fee": 0, + "recipientId": "AaJxRN92BCtogWtzRUrHJC8TWqSswRJGA5", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207120a932e96c536e2c2f051546d173f3c58bfc83946fbddb0f991431da9f685a02202ebb91ef9238d05341afd2012ba2bd456a54d2bfc20d22ce3d10d4a618ebc5a7", + "id": "fb426988eabaa074956707a42bdf4adf3a0c10cd719a6c4cd6fb2828fa9b7c53", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2184588569625, + "fee": 0, + "recipientId": "AXKzjecNQcpJvwpm72ZE2DDkf3c6qV9FQz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204dc5f6f772f7843dca653edee6da99c709d3efcb585092d3b563fbb58ef9ee93022011ad3b1c4226208c88fbe189f9a40fc22964d8336fdc290d3051840a20006499", + "id": "7853c4e80e57ad1152b9b7c8f7e8e1f6d5aa849ae1f0b5a3732121ae11b929c3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2191161363601, + "fee": 0, + "recipientId": "ARV6tjuLPdAAJFhTeho2KbZ3caMXNChvwK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e9fa2dd98b2518aaf44488865877488f3413caa3f38d70d690b8693519f96a7f02202959afa89b20dfc55786c82a636edc53260290744beb427150b506b666414da6", + "id": "0e73c449c0116a23ef5abb5993be907794353557601e0a39e96da882a7c948d8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2204931827339, + "fee": 0, + "recipientId": "AaUvDwmuhLvZRwmW8epsDmRQfLh11ufUzH", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009ebbd2c288878988a5f18a448ec7c33adaeecc203084620f2f98b3c74960ae6402204014eecc985db4e8d94b92e94148453480f526521a604c2222b3c04b90fcea17", + "id": "8e95a6db2d145e700e36e08a413e0d0f2a6f23d0640f468be65b73b56469ffde", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2205078842396, + "fee": 0, + "recipientId": "AJuvjPUQHDYkiV5R9QQrAmKQqMsdCiyW9k", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206083b54d4879edb8e02dcd5828e6117ee97624ac9f1381da575ca3654d7da3ad02201effb3b78038dfbb482cc8d60a8096c77fb351387cbeb5b1fe7423d1aac34c67", + "id": "bf0dad6cac85409e568de7d2ec72bf9a649a5a78e2f2d49c2096800e05dff8bc", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2205225857453, + "fee": 0, + "recipientId": "AdeDz2SgSHtNSS49qk89UQoosmM9nSn8yW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022060fb58e2b791d584bb622cbfbb9ae89489a68b63cd292445db2bb82c60031025022065952795086ac1cd075d4b2fb58356579b3000948628d8a0cd91170eff57a83a", + "id": "7acf01f865d9e3b0172fd107b066a11d10e561a233af85c325a1891ab695b94a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2241213029168, + "fee": 0, + "recipientId": "AcRFukzbp9dcnpAfhUR7tKr2T9TP9ysr8E", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c9efa61ad9f4ac61a62a753d773e5f5b07c68348d41f651ce11b4381403dbe9202205397961b89303df542243d52407a2f3d1d1314b7f419818fef1b6a5a172a7b9a", + "id": "68995bfad121ad8d25068bd9f6a1c7442730220b39cc002a41650ff3a38221b4", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2248243233437, + "fee": 0, + "recipientId": "AeZ1HHc1d6eg8P42i6fVcJVKsXw8Eo32hT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022047e447051f960a6d1e554a72640858c8557099de95f891b692f44b15ca6b85d102207a4d3e483e26de4de2de0c337ad2bbb581312cfcb77f806d320d88103a1aa227", + "id": "7eb9c09a76d966babff5fef1db9a160af8885f4545fa1da2cba9baf5b64cebe7", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2262177091195, + "fee": 0, + "recipientId": "AJzzwPzzyDCiDc23uQ2u7AMywkfzaVCcWt", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206772491d6df99e5475ed8609d3a35a646b77fe85b81aa0cbcd5a79ea725a0f6602205b19e267638b99baa4990e16ccdab0ebfbe2a9130618c83c30ff9f8fd750eb2a", + "id": "fd90da851810e57219244396325da5e2064640daf9ba6114102aabff880414ca", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2266868808469, + "fee": 0, + "recipientId": "ALNvcAUuj1GRHaTvDcEj3J2LJrpbigMfTd", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b0e14408162136a3d9a103e113d860643cb583e260bed70db986b548167bdd1d02201e3cd6711b3a5a47b07cc79a2a0fd24d701003ee54bf4e96c34feaae11586bcd", + "id": "997f9a8497ee44bce5675df192fbef70e582563d5a8d6774a10a38c1ffc870e9", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2271096947063, + "fee": 0, + "recipientId": "AKU5SETsMF21C4QNxSAFEuMtucEVZbHrbT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220405439f374319ae7818197cd605c29f981ec33ae5e5d8ff63daa6c28b79a12fd02204afb1feecba0339d1f6858f00f45053c4fe891a041a810df553c0274b8da8837", + "id": "625cabdf0b3e0ec7461e182b037d5050566ed0cfc96daeee199fec7372b428c9", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2272050883436, + "fee": 0, + "recipientId": "Ad3NrB9ak5ASf4k7u8UsMUw62onx7t7c5T", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210093ef0463dc9e57cf30e412631760d1f8c9546fabac8d02a81d4450c1b0225fc7022034d6e9612a01b53cbca18c08c95ded5ecf9e16486772e910e857e32dd7fcc8d6", + "id": "56ec4d726f2f6eb3bdbf96201d7bd4ec0dc76222145e4aab469a5a8031bc0897", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2276774784522, + "fee": 0, + "recipientId": "ASdJV1rBGrv8hr3n6PAzyEstMMaeKRC9r7", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022073089b31090a9893b58f7d356e2ab39709f213bc753efe142dce1028a18fcc85022027516343ec493797a210a0eded5d162f612c19221ee758925bd0bff3b9a38a4d", + "id": "b2f66b94ccca70109adff57f5b0327c01fb8b1cf9266cc5d34e67c1078619b6b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2287751179042, + "fee": 0, + "recipientId": "AQG5AyRdBMK1EiAxjtzumHBKTz5fQziJaQ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203358a1b09882d61785e37ac06243189f37c429a08c245dcb9cd302d67bc23a89022036c0830ea03b7fc64d9d673d83d99d5001a39487d5207983a09a6b2bb45e8b70", + "id": "27f99bcaff31983a34701f2db5614995f09298ec428508c0ef310abca3a17156", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2318734742927, + "fee": 0, + "recipientId": "AHWbM4U2eC5G8GqhEXjKjyjQ14gE2uz8WB", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206f65c7a1ff3c846ba9ecc55cc3485c498ea01d316a456d7044e801dc910edfde022057487ee7c70aa9f4920bd4a32759569e2dda24d493d427c1a1aa2cc92b6f860b", + "id": "726d10604f15f9e5007445f0b8f829d8811952a0b9f81895fa673d45e579a8e4", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2328424475356, + "fee": 0, + "recipientId": "Ad9T3DbNPoF7SnCuhBEMQwHuiKjEXmhTFn", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220725c7b21c8cf49ce86093c81ff5079c5f3ad6a7955529a52354e01c8b93db64502204463fa21a31a3cd7fac42e62f0e304ad7861d71c7eed6114e1c64cd37ade9438", + "id": "66ecd1311f19281f119c8bbbd34d6f32daceb58f2c747c32bac3821d1b22bc36", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2338875909420, + "fee": 0, + "recipientId": "AH5nQnHDEueDsMA1oL4AxTYgPkGgzrPPv4", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210093df608b5fc963f1724fbb3f0e3e3c52c1642b17330988bfa45d7e28b143f7af02203b04d3b802038a17bef863ba2e2e17f1a288ae1764ef61e7410643017643f054", + "id": "1446fe4a270106969f516ddb59b0d145c4df5ef0c58aaea92e16d4e73d4edf17", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2356684778844, + "fee": 0, + "recipientId": "AeNyCDJoThuMtgGCqo36Qj1RxiLzp2wKfX", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c7ae57e20b74727add16c03acabc3f2ee6e8e200651ed2dfdb973f3137cbad9d02201c33c46ac75f9d1183ce4a60bfdaf72021415676828992f5b4bb4a15bf8b06a3", + "id": "8e4d777e325bb6e75f240dc86f0def43fd27a1d7db6efeae8af457fb4a0e5a7c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2366781260994, + "fee": 0, + "recipientId": "AGog6GdAzTgGhYXuifWnrKvK8VAPaEhe3U", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210097204cf3140ccc71aa07a31cc969dd5b532d8ffbbe936581b08914982e823033022063df68f995e5b8f76d391cf7faea9b34fdb2b3b26db5ec42dc94055efafb86b2", + "id": "250af0610058d8455a4efe16382bc4b0cb0d3206cbb288333ac3550ceb44cda9", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2372499252388, + "fee": 0, + "recipientId": "AQRccct6eua3CnzgReDsYVdZhjJEGa55fM", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022048fcfeda36ed20495c633c7b1e671a306df8229e2a7d4a75547c81b8af509742022066b8f68d2adae68654bb0fd01d56c817b45f1d5fe686c1a180fb53f9109ebefb", + "id": "72c59a55be7083859a7fcbf1e4b9d5e3f39013b292c812fc61a83b07d44aca4a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2381643926049, + "fee": 0, + "recipientId": "AGvdP9o1xDU5HB9ZfFEBKTN9Td97rka9GG", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a95fbdf4d29b7d8d00bf352f5c0faae88fd0c6954119c1e7de8624c539efedd702200aaa95e4924771e70dafc892933be295c372f3d7614058f34f6568955e60e3d7", + "id": "c4be55dbb512485ddcfa1a44a64b77f72f6a623ba28a1ed74f7e164759921b69", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2411046937482, + "fee": 0, + "recipientId": "AS4BtWoaap3AVmgxh8cQj3xkcd7dkWfK1J", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d2efa679287190ad29fd7fbe91978ce07dd5819acfc9f08b12e9aca27c5d9fee02207da29d7168e36a88509b6d73344e461635bbb009e1203bff8c6ea31068f8b2c0", + "id": "dca8904b7776d845555706aa639fbaae9e6ae4d6d912c796a41e793dc2030d6f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2421793988476, + "fee": 0, + "recipientId": "AGErCuSAoSpZNQ7ubeV4HSuHrwoxGQoBbq", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c9947449ab96e6ebafcae96a6c080669ce3045f711e0ea1bce651061cb054d7b02204bd9e3e1fa0bbb0923571ddafa6943c69ca2096fd82dde9a0fea4e3eace6bbdf", + "id": "c36be7fc674eef93fff38d284a209599ffab56eace2e569f9f05db0ebbc98e8c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2424820646199, + "fee": 0, + "recipientId": "ANgyLRoKJC7a6RLUJw4nkkrL1Rni5eYs5i", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022040b3f827c57219cac01e956cb5aec623fcee151b57225ac06edf7fbea1d86521022021808f0d44f5a50c7f35a25e40c0034b7831deb627f8c2922ded0b406a00cc63", + "id": "f3f300b5fb8de1f81c863737617f45c4b67f80fbfb7b72cb4a4e0423718df75e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2440155918800, + "fee": 0, + "recipientId": "Ab9oevZRRtixxzvZjVA5jJrjxi1kwWhUN3", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201a6214822f6166833f7fcb539cbbca80debc0e0d01ca91c0f87a64a5dbe993b002205bfc9366366bca57d54bb5c389edff2e0b90728fdcb58ceca89984ba9aa12e66", + "id": "a6fdc2fec0e799ecc73e8310e8285cee66c1420f3edb9d915cdbe7414c23b824", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2471141445854, + "fee": 0, + "recipientId": "AcQgRCArM8s3iCzXmaNa4LFYcPwPUqR4Xw", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022014be56285973e8fa73c89a4de8c1d5f06c30bbdf6d69c9286e19e18d3c00cdca02203a8777b4f3cb0a28cb42af527b3a13d284c8bb5a8c6a97b1f04c5fa3b7d42dec", + "id": "8dd4e91bcad96169a7d3e4a01fcede8898b36e45797a4aaa6c318f1c0ac02889", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2481166956848, + "fee": 0, + "recipientId": "AbKSfhS4rZQXKJjnF1egbDqBh1fnkoDADx", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100bd942f63f791c0cc5f90d50edbbb6837a1445b053c599abd9cb8bf89e933d96e02202e1620e229f7657fd1d87fa97c076b42a5a8a4b5eb6992cd2cf1308a4d2585a2", + "id": "cc51d42bf081b422663bcebf7c9d4676a1ec5fae1e4df76e7ef63bc9184e7c50", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2484636536440, + "fee": 0, + "recipientId": "ANTd31Ts3VHYBkd3BmbAv1FHdrYjVU939o", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202aadc401035be55c7a644fc4204865a0b25c61c8ee7557c35c8d6908ae51748602200eee3eb04aaadda8f210440e269c03868d46fad3f80850c81f7f526471e7090c", + "id": "d5f9faff17330dc56236696dfb08548941a881159948c6aa100136fd416ae834", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2532393949328, + "fee": 0, + "recipientId": "AeZGayWNSzKRkeNxkHJFzHEygeXsh8eytK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022036bd56eef8476da49e4c226f6d5bff50a491a4b0d077f0320df704ec731b3ee9022057b53f23797d0cb167b534f88cb0004961c2ac0ca25adca7a83bb0eebc541cab", + "id": "b6f7fad4820bfd4a97c845918c3f7d39a9cce601db5947b30f0a8cf515346fe3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2576371936586, + "fee": 0, + "recipientId": "AZMvWheiHokcgXW1UBvepmCiSjtLESNoid", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200923d3e46b3595c3f9c728deb6f8f34cb5dc49e32cf5e9668d0d74e31181d5ad02202d6079625ff697cb987da8782d44333768b883c10407af365fb4cc9a5135aba0", + "id": "1768864cee1985d3e4440b710f7cc8dbb7bf095f57f61af22f4fe9c1cef4e1a8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2584344277365, + "fee": 0, + "recipientId": "AUpLiwm2WVWh7Pqeizt33LgjTfLxaeKQZM", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d3cb2ef1d65dfefc87c26a36c625d9c018924faa17876acb422727fafab78c5d022054abdebdb5079c36789fe3f7d97bf736ef5a314555aba0632ec3511f6b72af7c", + "id": "644c4cacbd139ed34ad275cc8e2c5d147a4d3a5e8ceda34f93c7860cbf3285e9", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2592139332838, + "fee": 0, + "recipientId": "AWEVGHr3x1e166sLRYWjub9tMuRmrwv5Rz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100dba9d478044f5f59fe1c85f8528f1e0fcbe8ff1fecd0cffc13d09ea320a180480220086a1fa2d5f23c120b0b8e49753d8e4c9a1772f8b2449700e9987f7679acbdbf", + "id": "27a27a46a268bf1af2f7309c1d6d4594513c1e6188d68216eadb573ebaaec3f0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2596699852052, + "fee": 0, + "recipientId": "AVpBNSkQsqp9VtK1hZtf32ZBszABP6mPxz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201d4b144431415a853dcb795f3ead4eb9947a0780af7303c7f8f1bbe95f0bf470022025539723eedc56622cff150b1f6d65e5ff10ee29a39b5f29b77af51d455616a9", + "id": "d6adcf3c3c7307e26318198bb541bfa38f3b12328b4b71a87eb3a6eb760baad0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2599032418076, + "fee": 0, + "recipientId": "AaQDmLECcNXVzALX99oWP8ed8wrz7E6vQV", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022052078242e033e71cc764c5e6cdb1f240fa434c674d8bbcf5253f17b2e4bdd95e02204a1095961b33110272cf1d944ff3cf147cf784f02cd37794205369f75aefeb09", + "id": "06f66303e2b00608900e64f219579cccaf060f93a50eb1ffb83a6af3374128ca", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2619541018549, + "fee": 0, + "recipientId": "AM1WQJyB6ENVcBM3qumifK1iyGgmxAtfky", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ec33ce506f26896c7cb3f5730859b4da1b52fe9ce4fddca9c17976e7522d82cb022040a6c88430b555f187b83324a99cea223f56be138e5de4d860fcf2a3315e91c7", + "id": "105f4cf709516db516b88e985518ccf82eb4939a886c1b8fe356ca85b2444325", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2625323003381, + "fee": 0, + "recipientId": "AbYapv2W4GTvn1XAQopCFPxHTmGuhZ7wrU", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100cbe7e43ef7a56ddda2308f5cb60204611e24dc16d1cd1c681a4190bb109ce8ac02202b41f1a599c6de7bf37d94b8105c618460729edb0235d3070948a002d408a315", + "id": "706cb7d860d44fd5ca836fa5667d81e60dfb86c0e8190850a1ef042da330e2fa", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2646271028944, + "fee": 0, + "recipientId": "ALGc47qvCBw7dL6y5ruLrpWXdghQSMjRX2", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204756f3e295f5dad6ffe44c0bc09e7a8e215acf01bd7fbe85babbea5e1682971802201cd1a6af8e4d6440405631ffaa0b77333ff31a4068675a4ed9e32e345e812c11", + "id": "a7b9cd14e449f0809494ef6a4e94e257206e3b339196dafa6cce9a5911eeccfd", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2735324506659, + "fee": 0, + "recipientId": "AW9ZtarPjeMUH3abFtVvC2ECNTkMS4w9ZY", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e1b443ca71f70cefd6dfd6cbd2120881c7963e60b9601d6793d46587bf64f8e102205519f08774fb4a7ccec42ee49cf10cc1e60c8bdd4b8f9b0ff3d403cf009022c8", + "id": "26d5fd2ff3c8975785fcbbefd6ad746f51727c273f70f5545e95d3fd683593fe", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2745083256244, + "fee": 0, + "recipientId": "AcWyTqpf7XuNnptSCJ4cTyw2hqc6PhDufV", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e1fe873519ee311dfe7114f754260443d272cb2faabdc67d5e13b3e22dce40b902201b2372a23b827ea4c3b588b9e55da4cb09f9f18f201293591bbba3791f1fe46a", + "id": "3ae55c8fc62086c2ab577dad2cc85e9fd025d8e035ccdd040857f25f3215a29f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2764221209306, + "fee": 0, + "recipientId": "AS2NDZSgogBv8K2PdDNYwWcU8RphnXARQo", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200d7315132954c4ddfb3a09c6204a1dc0be0a415d87b5243093e8ca01c02057f70220377bb5e835854b2a1372aac469e103ff59fb023acb7b05abb259083ac0a695c7", + "id": "41220183a52980e1897442d243a14f13cc5f6e3a9356c1fa229b6999899c152b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2806744646340, + "fee": 0, + "recipientId": "ARsQwGzjkRCscuwe8dQ2MHPHSYqmbY4iSU", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207f71fdb335a27b7d37d9e07677d14e546e91f1bc8be8c5519179853be3f6ca9d0220712a67657afe2b13a1ed42f7d29f662c625b55b577a87d032e5a513d3a33e875", + "id": "5a83436df7e6bcea1e1221846e05315cf36f3c5c4b06d785344e8010e48cb64b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2906876974000, + "fee": 0, + "recipientId": "AT51Pc6EAJKjK4Sgr2tf3i2X7Wp6L1Nmef", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210084c2421ebaf0f1cf5c9ebc09454762d5e6b47291c0b88d8c644cef634c92d4a9022000b3c741497725e2659358254baf0cf87ca742dd189ed5b29160e72e9a7e8d94", + "id": "5ef7d8921886188473d15c50c752fbcb5db7d094efbaa8011b23929409a7e642", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2910898131837, + "fee": 0, + "recipientId": "AST9oifUBT4nv5kiNZwFrkTneZEyUshbti", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100be3ed06ba98f260ce44e0049f1ea20d5efa532ec97e9c286a3dc6611f72048bd0220562050948f72a8747b5e9407033c083ecd60aa78621b0f8d7c57283eacd286f7", + "id": "f04b90545d3dfa0567f8b277d172f32c9cbd9de645036edd4d5e0e74c77267a5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2940154128213, + "fee": 0, + "recipientId": "AMZXd6g2nidHGd1pZFUqZVpJnNrpzqtCKF", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201396009e8dc5376c341ea496e7542c2b96514819dca5aa23ca8dbf8efc1175ae02205a6083d4d66a15d511c672cf521d57ee61ac55bc876f494ea6450d2b7b5f6640", + "id": "46f24f882e0b0a1df1eeb6e2b17ad3a37ec3b9eb413d8aeb2af5827c1a16e286", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2940154128214, + "fee": 0, + "recipientId": "AHwkTdboEC2Nm6NwXoURbTzoNRPmMVXCqc", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205f1d63f3ad6bb0ee39797711bd1939b72f6081abda7a3249ef9d690c4b2de86102206022e684106c6e47c8441c5cb2ca2e583b3e79fc2f8db0d6885ec2590cf88c2a", + "id": "f868bf1d98ad88b9fa263292382355e6e21513a7614bf35e0a413e94602b4f80", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2940301143271, + "fee": 0, + "recipientId": "ASBzgywUJ9UtciVtbYc512CDrgTDhcMYng", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204939d50212d6492e23e7f3ff583044ae1ad7f01b173966b8fa83491e2c94b7ba022033f1a5538b4790cc5cfdf0d52a093bfc9e579b4da08643c3359d3ef0f39bb34f", + "id": "202834102dabee749fb707c8f620ca53d51c5f92aaa4113dc1b86d7989433ed5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2940301143271, + "fee": 0, + "recipientId": "Ab2DLnDBmKqcwBuzhQUa6wWdCrECZ7MpTo", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100eac45b9e454362b7fa3852c5c8ce5d2ca19db0da27428f75543d6ef075c91b4002207a49026e26676748eb003fa34f5244e0d9ad7cd881e90d9adbd158ab322e82cb", + "id": "f608e70123ec8b29777cf6904ff2e530f8c150d8f59aed648866acd8bd250710", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2940301143271, + "fee": 0, + "recipientId": "Ae7NncFsoDvMMmVqiJPiTmibiB1aW8XYk7", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207767c2f983946bed560b7ebb36101222275a8bd64f0c0b4f8b2fa2727f344b0202204222fa85950d3ba68b37be153d77ee9135a12d1f3a4ca7f8bf201d18502aa12f", + "id": "56e775c567f7f7c2c7e728221167d54bdd021f722acfee6aae640ff888c50801", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2940595173385, + "fee": 0, + "recipientId": "AaYk4acmLnvcKiiuYbxQBB71goY5Tn3Dm3", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a0546e807d1390df8e97606cf30028b6145d287a93dfec9f5c7b9672d172afb102207325221156e2b4e32ad04c80691f073e1dc6402b61fe2aa7296cc7d424d584ea", + "id": "89d8e7581c333ef01ce0ded3dc08da5580c358e02444a6c37bb2637b53e747fe", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2941331203166, + "fee": 0, + "recipientId": "AKJdgCXk6ymHHKaVoNhkgwtsS7zeSHg323", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220172d555b9f5ecc5268d9af740ce9aabd35ba38a1e011b0ab05783148bce1f96102205d4491c92d5bef700518e4ba909025b6e0da94ac550af7f33f14a2a47189b72a", + "id": "09b3d72c0f9d6051e30ec2f6dce7512820a02c0d95edeeaffd79dcf90e461fc6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2943241444414, + "fee": 0, + "recipientId": "AeykjWcAMwZ8jf9UkS7NoAEX7W3kJiBWUZ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008260a61c32c694392729d954b56d02ca72468167ebfe0c2ab4f96999606656d10220247bbc53dfc30f0e6c0267e7cff73f44f3794a77512b483b3a16a78f95cfa609", + "id": "524c4e3f8d8c26f3b78ffeec170648af3410bcd1c4ff3dd91b783cd9a2f229ee", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2975619527639, + "fee": 0, + "recipientId": "AGT3E9aU7PuT3qF5dGVQFwAG8zuXTd7uAp", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220051f525cc7336031431dffad29a63ea2aaba824790c6db30ca40d529d77d1ba402200601f5acc9a39b41fda57e49a3d2e4ed473b323336f82b8c39be54cf72611de9", + "id": "dabb12f952a645ab435977dbe2353cdd2609dc6ed1a672394d547f0880d93cc6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2982935509848, + "fee": 0, + "recipientId": "AKU1FaKbLTBfonNqSAUidf6nWS7fyaAs8d", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a399bcad2f889782a418d8c4f43fd50545a9762a5afcc2f1c0a2584b9cd9cd99022033c4e961ea62a4db1bedf6dc894b402dde87328fc5426bf7080f8181b0220316", + "id": "ce7293fefd0f534c30b3c2845c129fd297d3fd3d4ed7c24d3e0ed490801eb0ea", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2985301143271, + "fee": 0, + "recipientId": "ASgKLrpaJGxArbtTNuKHTQNVWyGitGGpZC", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202de43275dc393daad998ce1dc35038299d94e82655584b05bf1ad3d88ed4ad5902206722a7a5753f18a2f280180f411bbe0be380d0fc48d95007ad5381f367ee3be7", + "id": "9a99bf84368d99e4a83fa780867596c6be71a181ab0e4d80b99e843956435c4d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 2991168353049, + "fee": 0, + "recipientId": "AZePtHJzYCXrdG4tF9SBHY6k6R25R8ZBn5", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f5b8cb767a75c487bb2d1bc078baf5e9bc1ffa024177bec52cd34de5c87306f7022024806722c1dfa0212e49d7cc22c1251ed59d4c0fbd9963bca459aa0c0f64f521", + "id": "a36430d45917be491b50a09e86615f3d1a67af148173e7867509d704df2b1367", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3029944047194, + "fee": 0, + "recipientId": "AM8f4MdYwPFB9XKqvki7wt3MNBXK6d1EtU", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022002187664dbc4b4203779ce0717e3efef35f94aa241477a5e326ececf4897e3d0022029c1e31d1591c2c54f242b43bb27575b94561bbb82fd726f3c54738f96c9025c", + "id": "e0c8f8e46c5377741c86b6854281d0056919cbebffdf4d641785826709879a51", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3030774378583, + "fee": 0, + "recipientId": "AJVm2UANQSZBH6WhTLM8ZBqTNDwmYf48GE", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100988c50ea74333df4771619f0cf7396f7569ed020b6d02ec3bc3ab1b2e93e186502206adc99ee4498664293176a09208ca5631fb03147f6fcc330d9dd28102f088e8c", + "id": "90090e44f39b81ebfd82a3c3c68e11c81c22757c91460e309879913aac6e915c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3043211683285, + "fee": 0, + "recipientId": "AJi3yet6WjHiMNx8j41pbwNyoKfZtFbzwE", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f0d5d871e104cb93b22fe9937872219bb52695f3be7508144d260de8fd33cb43022064656b7b33df040d9a49839e45250c44780cca7ee302112a123694fd5ddf2a81", + "id": "71b958d40ddcd3e70236969225049f99b99e012608253a52102926154e8e6eda", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3055154128214, + "fee": 0, + "recipientId": "Ack5VMNG38f4DCpn53a8rXNoijKCpaEEqq", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200fc998d1c31efc5222de1447a8284cd94cde778da61ef0f13ec333196318fabc022049cb07ea8df855b9712d85f334e2c2fda9ba07a5d7065f978b677bd900e0f899", + "id": "2c42da9e75c92d6f66144898ef06ff9fcdc35853a8036788f3a52fa7cbfcf033", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3059124967808, + "fee": 0, + "recipientId": "AaFaBMRCVAF1ZBfJx9wgpZNxxANpJdJSYs", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205fb4f163f5d2276083b58ce3c7a5739f74e751d86050c6d9bb10b2be84c343870220407388a647c4d12beac50154d72dffa01125a3a2ed5f4c26fe20fd385ad27316", + "id": "a05319b6d84c6991ade6f957ebfcd3193aefe5937122e7afb1bb7768eeeb4057", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3131025807748, + "fee": 0, + "recipientId": "AKuqp4G8AA3XWNe8JwMhTdNFsjhrWhQ7ZF", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009c9c994a2e54b52e7dd638337ba112c43bc2150f740f470de9d5b72b852947d10220050af097f8ec27f51f0fbc9d052e5864aee99e7b6082a61e3f1488497febb899", + "id": "e521e3dfa3379d083020dc9c8ab5856bdac23ed0f412e1568d9704ebd73f4114", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3136161306270, + "fee": 0, + "recipientId": "AHWAQFqCmJ5RrKvicKzg4qEvSStWN2f4PF", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c2673236c613f050e22ea59478067f803201b9c88b51a4e0215270ebd6ce17f402206a586fbc5b2e0e5b27edf94bca44e9b136fd35a7be96f5d12c2c3030286a8196", + "id": "08a2b9d852bd06e8a2158c95142c88624887ae9ec667eddd62b02036993c3d48", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3141084221939, + "fee": 0, + "recipientId": "Af4K4T6Y13ZyZi6hQxSuFwWHVRZQEhP1D9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008aa3a5f09a85a7e94a23beef8c95851670ebbaeaa7d251941a92a3f44420951e02204070c008e27d95e14ac9fd50741a889efa464ae4c740cb44791edeeab2815227", + "id": "391d96b95f7d84192a1f319932167a2d2457624222afdb0dba66eb4b3ef9cd69", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3182675621655, + "fee": 0, + "recipientId": "AY36AeEFHXi5uevkukSSY63Qv29xLtBNzj", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c502e26db7ca217fb755fcbe660da9ee6c29047ddbcfa3962e6cee1c15fd213002207ac54ce32e991a0c654e5b3c684d0d2efbee9d2967f4edeb80ad823f4b19f3e6", + "id": "f5c46574a98b4659092e4193d2c05405973cf80be9ef391e824eadf89003f116", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3208001085999, + "fee": 0, + "recipientId": "ARtWsVUYotKEXTXxx1ZxCNvQUrQsnXaGSB", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203d060f9f1a25f865c48d773b58228dd2ccc8061b9903039940c507dcdf895f5c02202bb37da139cd3d4a7cf5f677f1677202e28d0be38468601e829ccce2cb925263", + "id": "8a6dd2571b665a50bdd9aa12e5908b8b7bef290dd7e77365593830c0c3504355", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3234184242541, + "fee": 0, + "recipientId": "Ab3SAMJGK1fTrQAqoio6uxNiQqUPCmrzxj", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210083d0d329a80d6ee339c024b6a8143dc1ccd2a4ef9cc36e2a2290f3edcdb37afe02203a76762e23f40fc99ad1bf9684a19d3e5060ab3de016fe025acdab08546ae83a", + "id": "ab3ddb2107eb42d4b92b1ed42c5c60d6ba432932db57b3f250c5ddef2e5f0b40", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3234331257598, + "fee": 0, + "recipientId": "AYUmyzDXiqHcTnFjtKQC9GHJzFQb76rTjv", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022017b50c51bbc0d381d134b7fa916d7d2e3ff07819c217144c1969a993af614f4402207aa346585c21d6fafd6a31eae748581272ec2ffbcc4cdbf2cd12f258a113340e", + "id": "47d84153cbc76cece88fe01fd661a4fb388a40c05495fd2d4bbe8af7b650e1ee", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3240854690572, + "fee": 0, + "recipientId": "AKdcJzAriRFVftFqfHkrdZ1kYKtSajjVGe", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009956a1473b920fc46270c1b8b7b53ee4be22aad70d53a9e9059305f1a8d3107b022035e82d31b43b221e7a7da617454ad1c27a504ffb107cb4fb9efe88539b886e4e", + "id": "a599896c8dab5a4251366d83c44c108d21f2e82922a01214d24857c5d965c9a4", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3264823516954, + "fee": 0, + "recipientId": "AMnGLCrRYXtxmrnzsx7bDzEx3G2W4igcx5", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100cc08ed2979526f2e9e0876e177871deb20ac16bfb094b240475efa11cdf5642b022005f4dddc0a80d1c9df8eaf04f3fa4dff3c5b349e5b4315d6f037f80ebf95aa74", + "id": "0b33f80be4c0145ab42eb74dcd63c93ef5dd8093b8cc2358182e644f12287634", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3307427638563, + "fee": 0, + "recipientId": "AH66WwUgJHCYvEbX8hTFpuKpx4UwzoaQEz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a243814491855ae7abe45fad6ea7c7e939903f198383b224091a25e22fb357f002206e4849d25af6dc5bb6e002f30ab0cf7f8cd939528fa4780256abe3f9f38f4419", + "id": "af232d8be6ed5cceba703d618a040d13db05286235b2610de8c4cda5668ebe8a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3324317837586, + "fee": 0, + "recipientId": "ALTNeLaT2mvuvMohvSjg8FjYhVDNxbeMEu", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009f8ac3837eb8b6363c0ec7788dbaff01a07d9cf68cccad905a67a8016ebd24ca02207acf56e23a7485fffa201ebbe3c515b99bb4121170da3b0884193416881a23fc", + "id": "577010da36ec3f0cca45de28e26aeef46a3bb7fd932b755609aac454e9626fef", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3332461324329, + "fee": 0, + "recipientId": "ARLUcoV2hyhKCzfy25Lk8Y9VWix6deVAYj", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220724da3de0142e6139d36004f68e5ab4eefe84b786c5c80d0374b319c3be8d6f402207276502244f50eae18d9d8cc7ef1636936809fa9f6d72461a5bbe91db9c8c04f", + "id": "65306f6058181b91b964039ad1c18f711fbe7b7d9f318d33a02bc1acdc7618c6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3333461562845, + "fee": 0, + "recipientId": "AHFojRfYcbsAhEqvKY8MXMsAc8MEkxwZJU", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220179bbffea812db28bea6ddc3e3863b6798af30cf9b2789d5f827201fbca974d302200ded60e75ebf3d9eb1f947bf5dfb216e8206a4882eacdeb7269c728fe47c0bfd", + "id": "705f8aacb1c7cca2391a4d432053872f3dc302d9ec36f1f399377e1b10ab1347", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3337241797612, + "fee": 0, + "recipientId": "AHRETqnSboGYrrjQ87Bnu5ovyKZBvfuS35", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009eefca56858fd766265713c444958cccb5d615b012747c011c6f5f355955c60402207cab37ed16c6f328ead3ef60c35257cfeff84c0e36182125822142f2f4a3c471", + "id": "4f16617510a64b071be9c9aeeda35eea4947d52625610d7c8af2d47dc144632e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3341104284118, + "fee": 0, + "recipientId": "AXNH4NZ1wsrkZ1PPFfSQFucDGwt4sfsGor", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e443d4e4a9d3f91f9fddccb71e70555b5376d5928da292c4466f0fb4bfa7f12c02202b083a62b3e4d139c3bbc09c162259ea43c256fb0cd25870b724cddb4d7b074a", + "id": "7664dfadec3af8d62814ad0baf545d16c8aca1be546758a259a05a2115837cb8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3359667184998, + "fee": 0, + "recipientId": "AXDfDrajcMoF4ssBKAj72AefFrS32A6ErV", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100eee29af59dce2e725f1441b665b737c9bc22090bd4b37a68cb79c29e8a041a28022038b10296b17315ce07bfcecd521104a62a7c1598d07ef17fc397aebfebb094ba", + "id": "388dfda809f3802e4f7ca49ae7da2409e195be0b231c037c0c0ee139227b5e74", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3411370798936, + "fee": 0, + "recipientId": "AMg61zEWGdPqgRcebwuY3nABTXcEf5ursg", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ac107612d5b3790a6640e52d8d5cb277f32c7ce79f3d9881641b8e7b613213010220353d4bd4188fabe59e5d8ac78d4135b57faebcd5e8095c1c7ab8d9c1cdbb6b41", + "id": "a16f6f3d94d84c9e83cf9ab117cc17257632d3b7548fe779f21bd02e0cf3db90", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3431641346204, + "fee": 0, + "recipientId": "AV4uwLo1v4g78ZWWEfZWt3zssgjS3HUUK2", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c6ca22e986389d94fa3da2973a1bcea26492e76c8fc8ecc47d2f754ee21e0e65022031cb3ffe69ddd0d63c0c40b089fd445748c9b0527e71d71970f2c1e987670320", + "id": "71ae8506d64400ce1c01558b7dbf6eadb9b915b8576f8024ba54929f56273d8d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3472495650202, + "fee": 0, + "recipientId": "AREUm684gmTkURsYWAb5XFSWjtUpnkHXM1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a6977f3021aaa15636b427ecff64771bfe698cac3e6ab1fcf1113e927656b44d02203bdb670754598eb986329abbf9afa637afced4dd83415f117ffda3a40d7c2da1", + "id": "e03a176681d276f4c1a44b84923d8ae4458333954e8917c67cea9b412d743ceb", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3485679678910, + "fee": 0, + "recipientId": "AeUU182Jnq996yw8TZRaDAPj4khgpxBjKY", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022006a3492b8a039c733c6860409ad2b6639d288f4638863a10955502162aecfedd02205035b3a64ac33b34cc81b07bdec6d74dfd14b28639df434b97cb55c1eb15a9f0", + "id": "aa9f40571467e5776f3ff8378598356aa77cccd4ae6d20b9911472393a3aaa23", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3485679678910, + "fee": 0, + "recipientId": "AesYuSHWM25csWzyJE5aiXD6yL4Vb6G1Vw", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c4de585a2f48a005b07f3cce3a97ca0ad829250496930b3bd2410b0740b8ae2d02205f46e8dcb4cae8879992e1352a3bfa5c947706c36bb8d288516169b536f3299d", + "id": "0116ede2fa14adc70cf6286d703f9dac6d7d29d2121b62a382a197f2e0c9bcc4", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3528361371925, + "fee": 0, + "recipientId": "AUxFccM7Y1rX9rgzi7ashGogxk3Am2A5px", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220750199ce472faa98d3eee8da3efcc0e4a381473aa1d48ace4731d7dffa78fa1c02203c91c647378029ce9944d5b647776989c67c7b3e153e7f3af0f33e709c9d0954", + "id": "8911fe01cd1cc981963d244e82226027890ff383183acadde7023091ff3ba196", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3531301673068, + "fee": 0, + "recipientId": "AeeJBq15fTimUFojH6XpR4FUAZmDubP43u", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100933a2422b0d1ce2180e046a6071652758838311737a3424a23ace27474eefba602203e72e72184db462d5af7d862d1d2d20b8eda36d9d5df6cd9cd308b6868a7604e", + "id": "62f6c02daf915e73a4440f65838b9bdc7cd4af1cd3361d7e3ece2755643a753c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3535124064554, + "fee": 0, + "recipientId": "ALfWJY9kKj9UQkPG9WpmaD6ty1xzy19MH5", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022056e64e74a7762a00139bc688a97421ff9ef58d1052019cd594855abb279de55d022075b33e73eed827a243c96a46f97bb3ad1c3998407d84a8d557f61f3e93fb08e1", + "id": "785e5330cca5c0a53d97c3746427ad1dd4e72d75e64567ebad677d00bcb3b8b4", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3556280867780, + "fee": 0, + "recipientId": "AccgnHy72MjgSSByZcWQqmeRgMstvJcuYb", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022063057051b56093a07affaed97bdc4c80fcbf7e3e9f1ca81d68347176e39ab60b022054765fcde969a830d58d67dc80f1e2610ced4e6275d3c261b44542add4ff74a2", + "id": "fe4ec15b065062d5662f9d352d1e1885ff2f907f2ba0c6a1528e98bebc2bc32d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3557938075605, + "fee": 0, + "recipientId": "AVEz9XVtNWEBn7DKziwGAYRFUcaXetU2y7", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220603807fb9a4ae361dc3743551f4cec9f78bfc9a5e6bfd00a7576196f8970a1230220586ce37ff801f638feae33e0449cf80c4a389617fbae8712a50e03e45b6e11ce", + "id": "f0fff2d878b1fca856116cebb41cae5a5cc0aff75d6b1c986e302722a81feadd", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3593815899623, + "fee": 0, + "recipientId": "AdWUn8FcTbrtck26543q1oGyaSjZFWu6no", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022045025274c42fbda104625bf2cf9320a01045aee16cacc809074ee6d315cc17f7022036b821e1e26e19cf0a34bb6ba82a3d1e5c164990f1257119677f81e019bb231e", + "id": "e2ecfc0a1f1e5e47ef99d7de7963e51d2af78f5a3671859487a835447cdf9353", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3599965360713, + "fee": 0, + "recipientId": "AGYEkwK8grFmYGrrQkNSsEbQTRxSv1QGBH", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d44a62be1cd41baff04021452b670b11fa4466a50b19624e918c56950c0326d302204734db4e45f8c2fb42f41fc3488cafea5187c051a4b5c21820b864e46336cda5", + "id": "f851283dfdb3e819303fe22d6accb80c935a06112ee8ccd6da917eeda8d9e2d0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3637230969298, + "fee": 0, + "recipientId": "AXtwLLdXbcAhX9j7YadfNoAbEAwmzUDGe3", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202d65e277703ac1505ec5becca2491ae4cc63b47af9e3c9bfd4610601b14e17dd0220659e5031db6fe356fd2297cff629fe3a67f153f05fecc76a37d12ec81c7f77c9", + "id": "737a7570bd435e95df00dd9aea0d8dd9ed6a2d6715919814d240104a31cc29d8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3637230969298, + "fee": 0, + "recipientId": "AFtvTj3CU7Vr2C3bDwNCDXDpbqE5TAR7UD", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008d5661fd7a233b744682e4df941f880b2a499996700246100d94b196db0297e102202c1086cb609d5d24d960307f3adf858268cfa85608ac887b6579f48fdeb2efae", + "id": "8c2a012cf5e9de46fc73d5cf899a51508af66e88951d8d17d9bfeea7b53cbd7e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3675376429087, + "fee": 0, + "recipientId": "AJqdLZvhCLntP4asFsVa7BfxAzvm5vL1TD", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c69c239352a791354a5be8627cfbe1c5d266c11bd6113db1d7a156f33ae5f819022053aaa645c823507cc6bab83b87fda3f3e66bab8e69b4ca2ff29928be6a7b7a16", + "id": "5b19f5b4f515679b9e1dc6a3624a2dd740595f48dd236076fee85848ed65dfa7", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3675376429087, + "fee": 0, + "recipientId": "AKrejHN9mQwjGALapuuf38wjs5TTDZGYPD", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022058f35b0134f4ddca74ab3e3d3494946276c15748ac629b4949c1132bbb754dfd02204d6efde7d964d9f74327077b2f693642b5652fa5dab7de8da16aa5a587c04c1c", + "id": "6388b60ea1d6fca35d97d365f06309d93e211362aecf97d0bf4771dbe192006e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3675376429087, + "fee": 0, + "recipientId": "AXH4SRRS9WQqYW6tr32eDScenDgfmZvn6z", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022078cc3fc5584871fc50c9df131c162cae857088ed96cdaad082aeb2bf73a7237a02202175cbca5a39833cedc9c394e0c896b5eb5c4369748e021b588af40539c80e1b", + "id": "e64991d57370d9e29549f930e3c72ba1d2963fea228c69d07da985f20889992d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3675376429089, + "fee": 0, + "recipientId": "ARuZqMpJcTxfyqs9FYwN5o4vHrH9ofLvnm", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207c4cd8d49f9a5babd6d545162f31da577ec194b1783c1cb7a518ea922c589b78022053d81b6610d827dd8e4ee4be48d6ad9f397c28711d8225981027ac283aea127f", + "id": "bbd93094994a8367c48099c29dc4619dcc5da73cf63caa53b1e529395b6b9a6a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3697295037611, + "fee": 0, + "recipientId": "AZE3bGd41tQLJqtP7kmn1SUQLe4ULUpNtK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b7153b2711d4d93933b0d9de3fc66ce2d459464e57fe7c6d502d8a0ca6c8dd3b022027915527227c59c301929b18c2f04b65d58d6dac510d9f9720689fa3bf8bd180", + "id": "c8cf09babe8f3fdfc44ba66a538154418bcb3c3b4c960ddea6d710e893bd4337", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3706851016327, + "fee": 0, + "recipientId": "AXMnw2SyrKVtEpkos4pYLqLyKS6nzBjWL8", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207b5080ed8fa34486c079d94794804e2bb8fafab6c643507a322fb8f1266d4f9702207d80e5d261ec51e6c371b2fa59926163828d91856d8c0b482bd23a03a991e32b", + "id": "8dc1c97b5fd6cc3002868749b97114243ba2a950e9b2beff032840548a875f13", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3709028616718, + "fee": 0, + "recipientId": "AWjDzWr3whEepeRDHMcLSZzfrYykBc2e2V", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e660c72942d1e4722f23166e5a781f5ec8ff9c264e6841695d9799934a9e859b02201a2e7e073c30e1efdf4b1fd17d3ef33914276e7931cde622c42dd3a90dc3f7e7", + "id": "4e83f8b8b7acfea0f43dfba0f8cdf8a8809eec7717d4519f8ba762e7328bd338", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3822391486252, + "fee": 0, + "recipientId": "ASf6GkdyPRoxAQ9e6wNu1eTcGzdCxTwU4F", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008980846f5d043bab9bc69d533094c47209a08b6604052b9097e97d3fb884828002203dd82abb96ec6873149fc3a1f274b04792c30dbeef84d15d274432f91b53ebc1", + "id": "b25ef9750e5e136d27cd99248823856666cb496d15c45af37ef77850791157ae", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3841576429087, + "fee": 0, + "recipientId": "AdJqCvp1xnvHCJKRBYDm6Pps7Yn1Ly4gnJ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ee2c9b676bb97f604b5cddff9c35cd2995b9ed514d71eec031f606fe249cdd5902203cdadf32092513c27107651f170ec3209e52e2fdbf5d19fbc7d6cc222ae367eb", + "id": "4069a73c1653a4dd78863adc651caf01c46b1ce2c603656fabc4bef4e15cc243", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3912040733393, + "fee": 0, + "recipientId": "AR4SrANMGxGvnQNzBtKo4PMiW6gpfnWvrS", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ac2967b732aa360a24d7f5562b138970d165ff8f5bd6c9e8aa8e45e69ed94b0a0220360bce61f2bbedfb4fb7f12ca83b1d9cc803a1e39512b1fc5fe5667f12ac740b", + "id": "2eedf249fe84cfd6b31f3090424050ae839909a12a3c1e39c777bc2e98897b7a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3918939514059, + "fee": 0, + "recipientId": "APwMLxdB8EHM5XXKG3gfT76Z939dLz1JCz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d3efefdd5f23c7d432cfd10d2519ba3dec0cb225c4df2cac9435db8a71646dbb02202e46cc5d7721e3dd8ea325ca859b01899359a3a36657fba4c93f202ca58ffa89", + "id": "d51629cab0261f943ae8bf7c72d8f33220cfdd1cda45a5f4fa5407919e9af420", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3937230969298, + "fee": 0, + "recipientId": "AU412AFph2KBNp1ZUNbMr6UQP9o5NSf55s", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d38cb807e50f55665d84172ae9f51ad7496e6afbf2128f7d79ff6b245b2dd3bd0220315d0693ad470da6c87599ccaa083645aae0bff6f5ecf9f6c540f2b333e0dae3", + "id": "04de02148852008a6b34df8e5c3ec16c21d4d84acc7176ac5a4f828bc14e16c2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3965251953261, + "fee": 0, + "recipientId": "AGQ6aRNRA165aF71WK26Wd7WBn26d928dC", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100996ac1644a8e8fa34351933824de6c784aec3656fecf58b00ecc73058100037202205b82dd95182ecc1b5933392cb43106c56a93faad5da958145e55cb066d055b66", + "id": "00887bc4d7329a1cd596625f9befcc07758c39b425cbc173f70338a62455f8dd", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3970035705567, + "fee": 0, + "recipientId": "AcvUN694h6sjffQYucMLacGpPuq1ZAupLp", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fb1f077325d32c64f6047e8bcc8c4110e079af9fdc76c171d1f8a0abfb32c43a022063f5bd3195cd0985a836b925f56cec34f3331d1fa0a9f0c0243583b7f785ba01", + "id": "db7c86a83a6e9fba3775696e6d06a5051cbdb20b329cd9877358d8e5bf3e1545", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3991462828751, + "fee": 0, + "recipientId": "Aes2M6fkCxfwRyguG6R7K234a8aB3SiD93", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022059bcfb711cd879f837a28c9ab64e342750b5a3bcda836c1aa232ee472004eab50220609448b1560201f56d821c2bfc180e08de802a8349b0f132c111cc5ee7d0e6da", + "id": "c797c9e6646543db243df8ca6f595651745b1262062762393342dced20eaea82", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 4000000000000, + "fee": 0, + "recipientId": "AcomwPvjAGZoBiCx3u4e7pnHaXxeLnn4MD", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022024236bc5bde500949d5031c98e8b36f823e00fa915cf01773baad25e20eb77b802201dedd50e48b684a7934b341f4e961bcb703cbdaadf3047bc3a63179992c80367", + "id": "65636f924d10c01ba4289d064623dbc2bbb19b7e6f5da944635edc38442aafd6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 4001132109901, + "fee": 0, + "recipientId": "Ac7qjfgoPxS7CvKMsGgPY9qPjy8MRsxtFA", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f4622b4a0e92ef2b2e120d951f547a4bd22afeb383700cf21f66cafda92d752702203d815814d38b4885ecd59e747d6fc0131f3aca76ad6b8f795b8d7d05a13fd8e6", + "id": "4b66a47cd8eccc4247e661526a5010aef5156eeda176cf8e0b1471be657790e7", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 4015989936987, + "fee": 0, + "recipientId": "AaHvdU5zBUEkqUebphZdJuRQx4K7QxGBc5", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f1843d7b8f388f8fc2130ac2f5b5721b98e6e1905974cee0e5bee71f7bb5359002204ee81e364ba06b6ae5fdb9ff4c3772291dabe596664d64cd8fdc7f9041386b9c", + "id": "cf6bac6a58bd66f9820e8b92a2b7a093d3c874d652f81cf3956c11d785133f82", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 4042914071996, + "fee": 0, + "recipientId": "ATBpKuXuUDFEo3uxRDJpZYCYvAuRxedMQP", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022036b9cc8a055c30695316e968334a488c1daaeb796f189549ca5566ca677d4be102205df0433a63bc80d39594ec5aada62412a8776468c5d8996d7c670669f0819070", + "id": "356ddf4e0040d24014d624050eea27429e4ee5002b07977cdf08878e93397531", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 4048316026508, + "fee": 0, + "recipientId": "AWd7KCkz7PAP9K8noozmqggx1qdWNHxoa1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022064ae748e8002a9118a3e4bb16d56dc25a8aa37260cfad3b5ff30bb0fda6031b902204fa1d3f9faece8ab66054c47647ad8a863759f0ce3c3c36edcc1e33162e6bf80", + "id": "d37818308a718d3d8ef3c3f4364a10b354b63af68840195c436dbba2fa18e344", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 4131665330066, + "fee": 0, + "recipientId": "AMuFbxddTGnj41RK9QRCVymbSbdkxrJBoK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204e2de836477641275c567bd1b574bd277216d355bbaef3574821b70ee55affda02200e01aa3604454ef602992243324c66746e0ad04b91dd65f0275bc349f4329faf", + "id": "d9147524e74c26eaca62684a3a6a1876cfe97e71cbb85b95dc5490dcb1ba094d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 4131706645547, + "fee": 0, + "recipientId": "AZ9hZpKCaaJ8c5GyjvNqWVxKoiHj8fUkxj", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220618744db99463616257c71774ccbffbad439cf0cb6283b556a8a7fd98e54da2502206456d52a8c767b60e5de2f3280f852ac049b66dcec4f9e389b8e801ce00aec07", + "id": "265d72b2909c0d5500b9dcd4346f030c32be27ee393d755a4dd017cc66094e4e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 4153588271639, + "fee": 0, + "recipientId": "AK9RL2q4zGWGbLtLViUHHdrzGbY19JyVWp", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f6adccb21f415791105482edc5d6a640964148330fa534d8f7e2e80f24b4fcd70220246d7278626b4b645018240af6d11d558a086e9baa7be5f4c02e47cfcd28043d", + "id": "be1d5b2d28236cb2e1551a702bb633e003582007cef416286b54553d1b09f13a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 4209041086592, + "fee": 0, + "recipientId": "AQqyqd4wPnAceW8SNg2Jwq7kw7oJdbu8jX", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ad4d36816a2710a030966ae3dfd7964a36e3d6600877bc12a5787877117b160802207c3bcb1abf4acadc60182ba7c5f242cac9276382fdfe31f8cc5c1d34128497e6", + "id": "0657d38310031c46d2207d04760de4dd9768f0f88643c189f234cd0f09fcf33a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 4241270774064, + "fee": 0, + "recipientId": "AQ77PDtC953vqib9FNM1QxgHS4c8hTKbY4", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202152e05672aaffa4dd6728794f48c789449778ffee43732fd04a7daf0ea10fa502203d3b1e6d34399f84c96363adbe3e486c4b766e402387b1c88097794f5d681f47", + "id": "faf38dc7c24d054c7b542ca52119cd5325bfa8e48ca24488e259594c72c4b6a9", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 4335474035753, + "fee": 0, + "recipientId": "ARNrAn3AagtTUXwwPgfNMkG42om4y4tjXp", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022049deea24c707fdc7650d34b049bf69911105a2591b93789cef09ccee23386f1a0220693f7fc8a1bf4ed2c42fd89dff05b49ba16efa2b607dc040c99fee81fd94fa8c", + "id": "4321cc2b30fb9c56a2d3dc0e68cb711fb3706c2bdea33bf06f8d1b532bb15ba7", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 4362372912987, + "fee": 0, + "recipientId": "ARqijV9qpJv793nYJpSuzhJJtgGt7F5vMh", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220330da9b78b7aa2553cc5b832e4780c160d6c2c9177a2c07240f7ec4aac39f31b02201b6a1e5f6d7003d1d2428eb6d89c1b4dd896a083fc37e136bb7a030322027d2d", + "id": "ef30241456071ab5739cbc01b77c888de52548ce718d290e17ed78dad3ce9de8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 4395705996499, + "fee": 0, + "recipientId": "AMZueSSbjv5eBjytCubTZy8gkkFov5GQJb", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220201fa8fdb645e5a6d8867dceaac2c15a03323f7df042a1c32d2cc0500451dc9102202980c35218796eabfe7755d019448caca47b7892d756548585cc2f10803ff878", + "id": "b12f8bef995ddc79c9ab8b62294b59ca171e59af53daf5b45173758fef8314b9", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 4410451714906, + "fee": 0, + "recipientId": "AeeTLvBUBeVaWNW6WU4dQ5RaM1XkFvAz7Z", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e82506b38a0e8e95f0bba2735b71ea2d00ec3bdb4a1e11519960933acb202f2402207e93347b0fdc6263d6a0725cafb8a15cf6fd82dca3033a5a9520408b37dfd3e0", + "id": "0f41c6cab1711f15519c238ad3913e0f99f45604f01181bf312450fe142b42f3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 4410451714909, + "fee": 0, + "recipientId": "AeVsSShGJR7KWQg1DHKEqev1PDSDREiDfy", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a53783236e53c4d54ae16e2172b9152cb44d78194a72a404849ea9d36e783d39022030ea460212b5b2ad93542eb7e27806e6b6215f9d005863297e9a55814071bbcd", + "id": "41666cc004f1e16061027115720b89eb3fded76b0032c3db25e90178fa158ace", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 4411611467971, + "fee": 0, + "recipientId": "ASp6DK4Fcrji5LHRFCwx17YPG9wdnXUnq9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220456e45ce3c5fc8ac7ff423250d7ba6248b29edce819edf5e1ff2fad55702e70102203f1a313fe9dd3705f217ca2a2515cc7e26e316ab7bd4228dce7e600a54f2d98f", + "id": "0515f9a1e521fc8e692c197a0467ab01b300ffc3a4780bbbd5faef682ce9514c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 4415891272021, + "fee": 0, + "recipientId": "ANR1PwuJc4o8Wp2qpc6uUk6wWjX5QRhX47", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100cf11b29ca14aca61107d25fac12d9a994c965392dc0ba3e1177c9f91559132ba0220266d7dd8d55b8eabe70e95190c53e9cb606c82b3d4c4f4b578afa933873f6b20", + "id": "ccf658c1b13a22aca678f05fff271fb533459d73fe00e361d1b1b96b64fe2d43", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 4507507351910, + "fee": 0, + "recipientId": "AVF5GuU4tJ9qd6YewAzDbN4sZkzFDNFgUi", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ef1c683d99d3c0228c8af10864c6981991f0cd493262303514d907e1a2dbe46802200c087f8aa3e4f2aff028e14664e5760873d753d7f846eb0fe1e9e30fb885eb13", + "id": "450de1b4d45c627fb948d1badd4cc8a70c89f3436fa5e745b795545b1ef06927", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 4531651714906, + "fee": 0, + "recipientId": "AcKGYwT1xwcWveaQE3dBqqqqTT3nnfpKbg", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c71f196cf735ce57f667d19e98ca7296c9dddf84bfa634318315edae96a67ba5022062cb8e1fec6e86e0f79e50b9b0c52a943a772fda7f5aba0cac56eca7cbe7066a", + "id": "d679cde12bd6e8ee711e0979e8968a1b97d6ceb9fe19634835355733b0a012ea", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 4535436795104, + "fee": 0, + "recipientId": "ANPpeB8JWX4gfskbcev8a6RYXZSSaMs3pv", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b86b575d515ed5ba323eb805882031a307b11d63c65249dbb52d20bac8f41f6702201ecf99a70e608349febe6ff6d33da93336357df5f9255757e9096d1bd1ab0743", + "id": "d496570ca0432b0f7d71fa40c94fbf7f9388cf27d7bfd1c18617e70c96546be5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 4641265354653, + "fee": 0, + "recipientId": "AXyPubrCRRig234zKtDMzzSVrPKoTR2vNt", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220312e3a6206e914414d40c7011162de5061089520ed5dc02ac0f88e20ec1a52e2022069011ece4aa149869d180c118870995de0280b5343791f0152705094f088cc4d", + "id": "afc269e369f0a701457aad91613679e5151e0457bdaa3ca386359882cb3ece67", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 4680692119983, + "fee": 0, + "recipientId": "ASZgEyR6XZQ9RXFoUtuyXY7gqHbC64vkU2", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203c43b599138e87457b214b1e3d1c1e83bb699d06a01b01e6add07df59b4c5b42022079f8d76bcb6bec406e86a5acb5cf2e926af71349801d6ee20ba89287c432dfc1", + "id": "121fc9d4fc8e2cc2f95508394b6eb20ce3593cf6c297fd4e0cc7d48d852719cf", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 4691051871764, + "fee": 0, + "recipientId": "AGa6Frh3DWJMmAsd3Nkn4bGt7n6bFwG8qw", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100808d7e940940c758d49ef8fb12660f15efa0c0cf5ccd391805a490ef877322da022005388d608bf563be295af2d05a993b2b1a87c93ece23ffa0f29c1bb412104b85", + "id": "0ac956b61b69b38a04280abe2c372042dc63a8267b67c4a6f23b7870f88a978e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 4697862065215, + "fee": 0, + "recipientId": "ANQkpXR4MwEdPpgbEdi3BaxF3qQMTGo92w", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220522fa6db9ad2b0d1a899e533b97002774bc90d96495b2493c200eb777a52da32022049690e22275a24280cbc7df79b99c92731c8b9b95261a07ab01e02c295f2ebaa", + "id": "fc6e5363cc3ebcb775be0446dbe8add45d7642f58ab984cba460ab5d966116be", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 4807392369248, + "fee": 0, + "recipientId": "AXYbSuKBYev8pU4TK5GkcwxWXWsqFL1Vvq", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200ad8d8f2a9ecbd9f954853681c27b5a46ac43b0db909544e6b23763932aad2f4022075e36c1e9e5260f5099f0fef9748071fb3e3202c82b0f685f6e56497c0ed929e", + "id": "a0b9708d51039b38e4285f869cc4ee2e29f620f84837bf3147d09e7dbd91295b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 4900011855261, + "fee": 0, + "recipientId": "ALZLdzs2XH7Ma87nS6qnGBvipdXCwXEcom", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022055e239d43d618d29581141d520ea39e940a627d113d417d39b5e8600965ea1fa022013dabd576ca157cf2aacb55588570d6abefa793db90617f9b52b5f8bdc5c0bb9", + "id": "bde6c2c3a29e7d20ef59a478faba012f38555663d3468c12748c1d0d5e70e292", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 4972512330701, + "fee": 0, + "recipientId": "ALT8t2gVWLdEgc516c1QTXbajnsDxTvrMS", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c4bed4d0ee6867797c4c8e3c3a15d169602302dff9d0f60a683881ae0a2cad7b022067e97a1f63f524e3037d8f29471b30007579fc372551e0c8e02f2924d8f5cce2", + "id": "c2f507727122bd6a0d0b78f12a8dcf1169d9f16187877e64bc24daad9679e0d9", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 4977195555049, + "fee": 0, + "recipientId": "AeNTL1HCB6ZBvKLHVMpHnGqVksTDktSCfx", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a0a35c51f045c7b5020d616cedf80411457f899f160d1edc5a326f827b886e4e022009084b2462322f577fb92d07b220eb0d5f2c17e52838faa7ef0dd9a0913a01a5", + "id": "c0d6bb7397e069bf8fa73f3227860c1dc2f262ebb274d8ac79bc70ee5e6c5129", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 5000000000000, + "fee": 0, + "recipientId": "APBJH5q5UPjfekwkaMemUzo32WsAGPLgC7", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220668c6951f67ebbd0aad2929ce9b00210a7d9f669fdcc1de95d713264a0630d420220630ba108e8db883d532c16fa21901ff3fd2a150bb6473d083a859416164fc862", + "id": "595117b36fc9609f6012d0afb10f3c072301bde2b65ee67d4bd5e00b9ea5b456", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 5086720977858, + "fee": 0, + "recipientId": "APiXiBgZ5Vk47zL7r6nXbb1feEcJw37a3Z", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220532e792b6107cc509119c9761433c93ec9ffda5cc5f4ebde8b0add5b84d9960b02200ef235d5bfb86c9083ba1917160fe33ec880f547845b80c456f4a2cd2ebdd380", + "id": "2e02e34a648a1136e0237953a75deb9dc336bfa2851b764d3b419dea851b3688", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 5145527000724, + "fee": 0, + "recipientId": "AQvzCAZgwfEerwR8Wbi2jtLRZe1xckgwnz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022046c8c7d959a7e4a01250674d44fcfae8d2b1a1d1beb302061f98fb3baecbcca30220795103528d96a6b86575d359c68af22b864bc6e1c412e4501bbf80d55690164e", + "id": "29e47540c5c0663a2a8612e77717256275a82a29084a03ec6b0fdc940ca3b792", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 5145527000724, + "fee": 0, + "recipientId": "AUNQekNveCH4o9EGHfuMAc45P46vNAkJWQ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210096a8e326a4c0ae121e4ff4428d3eaf00682d0894367cf354ecd68ac2063fd14b02200f21db687cd6b747dc4da81857fe7decae1dbd7d1e1570c8e609a27b6008d17d", + "id": "fc43db98ac4c5b9f1b3687e91da1f922a1328e4a33b3d5fead709911acf6c810", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 5152228598785, + "fee": 0, + "recipientId": "AbFfKLj8cbZCpD1dFcnx9M1quKbGyvY72S", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200108edd763dc24457372d2be73c2e0bf08c551e81646221bd02c298222bd3f6d0220304c7a242cc0b1c97956e7ffde176e16c89bf6bc024ad2f85edf0b531686b235", + "id": "ca1eaa9b36e044f32ce3d08b3d2a25bf6fa71d52efaddff1fa1712eeadf76413", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 5165668063555, + "fee": 0, + "recipientId": "ASxsKmBbAojE934PbqhJ1mhXXpkdrEMGi2", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220218d87057621c85e71f76523b123fab334c76307c5ac2030c572ded289d211b702206a80d562a887ad92a6ff0f5ce69202578f382e55a79665526ae3a38af5908f46", + "id": "fabd7438e73fef81feade0e11ed6da77e2eb6e0a4962b9f945cd6288139c37e0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 5229284067939, + "fee": 0, + "recipientId": "AV5Ap4mdBEJKpbfUZQYZWxx6Q66yJv25ne", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022039474147574e5fd182277aaab990a51c8254d41ac8d8740b646dc26c2877a2d6022033eaf619263d1b0e415c5badc403f76a4c9851d2de87c35f7ea0c63d35840a77", + "id": "e03816fb6db7a11b0bd2ade86f9a85765e3ab7a94e2906b6c0e30e7d8e0b5fba", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 5292542057888, + "fee": 0, + "recipientId": "Abos1R3ZsDqgNa3T62XQ2gsyE9ogYs6fPi", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ea11ad93fe457b16aa68e3b89751a8556aecc737d0a5472695c8731beed5821c02206fce4f51c29956e7c996ce0b9bfb75702c90983b4a8a59a3fa3dc75c06a20ef2", + "id": "05ec9e7cdfa7944660f3468045a013182795f23b066e02d0706be47cc49fa88a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 5308261029410, + "fee": 0, + "recipientId": "AGqBNsAT7ndLy25CcGrsaRCrXRzwhR3gLY", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b2253589018b40a1f81e3a216adf75f1b6498cb9761023f6bbc0f120c21ff20f022042596e6765c285aa0905e8d173880704cb843b1ebf97de0e92ac285d972bc2a4", + "id": "c0ac0b134286a830d4f2a84e8e391215336a5f1e46ef05ce9a1b7f47da0729d0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 5312153866513, + "fee": 0, + "recipientId": "ANZCH2mAMCUAA9TJByBgt1R9PZp8j2dnsX", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210092551cd132785e29add9309d136a6883834349f2efa084138f259c7b500dc5f102203a39a5ef2dc305e947758bfa72d6d5ebaa3afa3e36cff9b17f3aaaeb0079cb58", + "id": "c646cc3909e6032cd9dbd8df7d5827abfecda82eadc0155d7f2667f33e37207c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 5357843265955, + "fee": 0, + "recipientId": "AQJwwgFQ4F8NxNUqn44d8Kx6rB8AmJFiBN", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210090279d7a8f908e661b3651cddb1f1690868b9906c0744724356747ec26e1d4db02200942dbfcdd9e72db4cf2ca3fb4d20b6b94133a781fa221ebe47d964e8c03f977", + "id": "aa45b2bfbff8221f7b5809e7ec6947f39e57754d1866a25d2b855b8b54080ae4", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 5399929874642, + "fee": 0, + "recipientId": "AeRzn9WbFJkeExpJ1ib9bcqPFGBz6fYha6", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202c2146192848bd5fe02d0968ed6629dc03b5531b945d8e7fd344902c46074a5c0220677a6ade625198cfc73d9e60d9735841111dc5fce252a8ceea6ef5aeea325337", + "id": "d8396e0dc6eff0baaf523bdb9ec0a0f683ea01b2e7b481edab37f679959c72e7", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 5452743873172, + "fee": 0, + "recipientId": "AK3xPfpuLgDxvcUgvHE8G7nzgJ9TikonCM", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100dddf3ac76223dc2e41a5bf9c19b0e4e448e2f90c1e9970c97c4642c13892f68202203e5e2ad64cc817c835b951212e7a65b09e565f47707f030ae39b770694fd6f6f", + "id": "96fa04274bbbb82e73be6c4baff991523c86cb022cc8f4b0ca267e8f2b5fcd29", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 5454583384732, + "fee": 0, + "recipientId": "APrqARoKAGvFvSd2ipxmhWt8LMNoJPxHDX", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205017cfe8817f69a0383d53361483393f92c9275face9004b127e7d3ee4730ecd02201259d5100eb0ed196778b34bdef3e90a59b34dc0d61949d56890c8c1c994e400", + "id": "12514530353f15e198fd07bf42693c050c1bbf92f1094b9060ec2a940f1bae19", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 5534027654283, + "fee": 0, + "recipientId": "AURkidZfCN8uin9FX8ByFwCpCpqAs37uyK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220752c29c7102b3d0967a2a369eb8ee0f8fb09bff978cc00502069626526a6b7150220351f29c9591b208740088abc640391b793dc7fdaa56a084b1a12bde9a3ca8ae6", + "id": "d39878fa44b4eacd96c1dde902d6ac74748525845fde03ae3bd74bcf99f0e14c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 5596708324890, + "fee": 0, + "recipientId": "AW8dQKTqagJnXcRfDyYXiPBJgtY82sjSoG", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100be71df263fcfb94fea34c0ade0751d3f7b3fd25406d995555f2692179b1100ff022000c3c93736cd0bb38fb59f5a4336dae6486c26f643c8cb8fdbff1b06d8f7bf5e", + "id": "5e016277b51da7b156b41d5790536d3f643297f005202b5e504d4ea588451d31", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 5613302182608, + "fee": 0, + "recipientId": "AYoqmnDvAruDtVpKpmJY5XGHVsdtAsfYxu", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220171cc8f28be49906b2b55123b0b5e1dba8a0a5be228aaf517c3b5f03d1202d2d0220559bab26591db1c5348b69ec6b801f607ec8ba8b84030759b6edb6827d3ac0cb", + "id": "9c1b2c56282b48749139ac851a3a991ef9e4ae3926e600cff88a4182cf9b3e19", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 5623070875236, + "fee": 0, + "recipientId": "AGtJTLKoLnx2oVgTpfi9briAHR7SrT97PV", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210080d87159f97654d34b9cd2ccb64b5c3b44824405bf464462184bff3cce93d49c02202e72887f5a73adfc0101cd5e4f0bd019ac66e52c029ed1790890389395c7b16e", + "id": "66ee1e6db3ff2989dea803fa06d2cd01981d1833a98b960c79295b63c653d3dc", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 5648505606296, + "fee": 0, + "recipientId": "AFsy8pLNJnnq1R36WeJmQNrRygxPZ4TBv7", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210087518cb76baf699d909ef78187be4e5918f47d90bcc88b64612201fef8d672b30220668295a8f17296c8992a8dce97ccafb840b1a939660c7793f76c55ba4d5074f8", + "id": "1eda98af243f8de2c3cfe8cfd2b2de565e5e5b8af91998b716edea0da85607c0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 5648906556452, + "fee": 0, + "recipientId": "ASjpXv62BcY7wLgJLkos781E8HhDjfPZ4c", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206f1c839e8b95af5b74909a9febbabc652f35bb9cc6afed4dfb1294fa3a57cabb02200a3e9a2ff90d7d72808c5da906d873984a07576d593343a520279d5d81053904", + "id": "450f9e10debe655d9786b3e3a181b79380207e54a5460e21d27c64cdfe48bd6b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 5667502986102, + "fee": 0, + "recipientId": "AMMB8GyfXAnSjbEQap9UV1KxfiQD4SFhnZ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022041f56e22efaa29c67f715270a3ccf5f1fefd2b2c9a3a3473afdaac2731542df802200d42682d5a7f7d578f3d8065395662cca264afcf6c8941d558a45caf3528380d", + "id": "3eb6c19696d81659c7bbd979cd9d926a6473f86263b262aeb0ee10ea6c71a57c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 5680013606036, + "fee": 0, + "recipientId": "AVgqPjPJ4RjFpw2bqmMkvHGHhTUnvrT7Sm", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022030881e7cfb479dfdfceccfabb2acc03ffe03ad5e515c79fee770be69e107d75e022071b7098cb80f71d6a26cc8aa3b62df4d1dc56ab67cb86541c3a217ec9737554a", + "id": "9571f17bd17068f34b02419e07be1c2e1a2984ead5800a4b666b38ca8b235816", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 5880602286541, + "fee": 0, + "recipientId": "AMjo1KKaWVXTKxgY8f7h95pBGi2wjX9kuW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022077e2def23f7441b5eebf718fcd350c6a5af8207e01f549932dc78c00eea12f2c02202697c2c7aa53ce55a12e88f4d28a9a92afa6d2e0b03da2c81de9cbeea5945c6b", + "id": "1f79270181b53adc2a6d320fdda137a3a2b0a5d76ebfa29623b7399f1bcd1cfc", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 5893686626629, + "fee": 0, + "recipientId": "AGWQjb8AZSSgin8H2HHHHcMNoA4iS1HweV", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205097acaa5ada5c48df6a182a101fd1ad2005a521ed387bda6a3cf48a93951796022001c1d933f2d00539a616151571e013e10a22c25804ca301ddc65652164a2e58d", + "id": "394aa80cac2db93a5aca32bed46ef28feb1c5e49b0fc26cc220bcdb6a255c58a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 6008981564334, + "fee": 0, + "recipientId": "AKX2t7kQ4asoStjoSHQKhGVBuDLfXVwtHk", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207f53f7fae41d09c34b7371af87d33ccfad7b3fd29df5644dea82ed1e45706d620220027cee4f90fa3a0e6037a4a321251a53940df0b8d44564343068187d19e423cd", + "id": "230f86676f4336a0a640ee78f3534633d1af95728a495c47bc0ab4ef1d826604", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 6048199451708, + "fee": 0, + "recipientId": "AQQCMjGnEgsutWWRfL8BbUrsGe1z5HryH4", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220211e94fec0b2a86f27a27009c1ca016d618d6415f2745e444ffe1d601963f2d1022023829c5346a27ab73f3f70cdde7200df4fdff5be708c6f965874fc200d529a18", + "id": "b26eba2e7164c76a09a874efe75237c6ea80369105872855350b1d3227d0249a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 6062051615496, + "fee": 0, + "recipientId": "AdTSi59wjy3uZTv4tnenKL9fFWajaeYsCU", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d5e6a1d7bdc9206e118eb2552e96893ed4af47543c1ac692798bc2085ae43fef022067cf6d3e916ef610dcdf6953c778f24306a989041bfff1ef3f1f599b90f11570", + "id": "6d99eb7d36ba0a942ae8e0c870b31312e6445392c2a05dbaa8734c56c249f1dd", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 6099257525671, + "fee": 0, + "recipientId": "ARPxAfyT51W26UdTgSbfVRdjUpzeiLg3Th", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3043021f4867133c5f9563bd0e953c12c2c7ed084e469b2933da10ba51eda964f3f74d0220527964fd63a3c23a6e140d7d2c142a0297d02786577d91f3a97c863ff1f43f00", + "id": "652889dd48a67aea94b758b01f454c7126398882189dc752bfb11e0a7d06602d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 6114940797408, + "fee": 0, + "recipientId": "Ad2CVhECLL4ekRXmFVrYjGjALmyFmDBV82", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fa235782a7afa225cc198c424876b1271be94a5cbd18b8b11a2d3a6e5b1ea561022006309b82f6241beea5cbc446d902ae570cb18c6847060e45d6287a2d0524302c", + "id": "2be98fdf7807c6d82dc2d8e7263194164b9f55822de204b1fc9258b735cb9003", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 6177278671897, + "fee": 0, + "recipientId": "AUwfer8xFsv4Yk889R3n4oQF1nxAKts1tL", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b8cbb6b32084b8ef479e3dfa560eb6a99fcd8391c26299ec9d7339e98bbf3e9b02201effcbfd175cf6d97ffc072c22d3966ed4b22ff771dfd78f7ae7b03039e00bdb", + "id": "d6c0d6f8ccb456ff951f74e3033b503433185415be2fef77b700b096a1dfc233", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 6233789537763, + "fee": 0, + "recipientId": "AJ8vfPKvPPLJFdqVSQh7BBcZRF5GSTvBQJ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022073c38a4d26f344b6ead47c4ac5f7e6d96a8946d423da13bb14b24c84c69e68c1022071d29be6bfe25b7b4e33b7b6d6757bb435f9ad9d00b1824b81cd5b16f1e4279a", + "id": "277669ed0959b0a322f658dc6cdc807ca4526ef9b7fb07f7b2c55436cffe85ea", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 6249771580151, + "fee": 0, + "recipientId": "AaXTDvrMHd2nW34ENidytBxjtrALaB3uVF", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206c0337c25c9f541d130700ac0475836bff0a69b427ad1a352fa18155212ceebf022022db04421beced42fd6fb6723769f5eb19443f4cee8146a11f2386fa882087b6", + "id": "5de7ff26c18b4b4ad9ccdf0e09a94fad3053d7f61a4d07beaec231083324a602", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 6336348963748, + "fee": 0, + "recipientId": "AGeS6jmsQfmvS95KTbXLCFEKqpwUoEAc5b", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022002d5c9af048e1efd8bc37d2ad0e0aa64781bb3a738bacda828a9d2c3cb7affb302205a3594eaff82c4c46a6386089df34ce45aab71ef0ef1123e623cd64793c5f4d9", + "id": "c13088a3d622fd2925df99c39a4b25eac1632c68b3386f3351d9ede44b4bdf48", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 6347464915470, + "fee": 0, + "recipientId": "ALvAAwn8MHupoymbgiJSCDYiqjQrWTEQ1H", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203d2c5ef313400dde6be26935d2bf2eaa8f7daf90acb6dda71af277fab69b55fd02207280ed0a4f4114db9dbab70b067343a36ca6361e0b00cb9064a39730e9162b76", + "id": "631288a43196ef9f2d5b214a93c261d1453a532d83f3f68a441905899c5e5165", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 6608432032957, + "fee": 0, + "recipientId": "AcbUExwmdGDJgA1GWAjdEvx5VZv5VZT6ck", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e9c9364a47769112d10d48b398c5190e30c124d1c22b6d3bcd751976bd149bf70220297154a4646628b181af186fafc2f2b89c64b2d6b91b472f14353a324663ed63", + "id": "3def7e1baefa19fdfaa298305b4fed13eeda8ee4d8627304754edfa9b656e403", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 6690095694899, + "fee": 0, + "recipientId": "Acj7HFPqsAauRBAmfHqAcPiscUCxdiS7b3", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022034909f75febe76da183cd50b5f7e0745a50b6317d1dd1327eeddab9f42701a9a02202583150e149038dff6694c382b45949ec0d052d1edddfee4cc31da83d7c39311", + "id": "e912a67d2b2f1f5579c60cc12b09898804fd06914fb6b7032add9807c7666bd6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 6816039047765, + "fee": 0, + "recipientId": "AHBdGME8KmcvG63JkaQ1FndwmPWyuBWTgZ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ba60a9d3173dd42720e271a63126cf2b49f83f0846083bc0314d047be29853cc02206d2fe11664db806837fdf975675360c51cf5429a2a32ec88439f4969a40e970c", + "id": "4d1f9302f5b7ceb7682750384d414bf0a5f6b36820de505c8965720f46874df2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 6845037580681, + "fee": 0, + "recipientId": "AXFnbzewz6GyVVXuMhvAm7cyMLZRijpZXZ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210084adf931c399b8330219ecb1e0091fa02e7e400e8f44abffa0011c3d5123a8c702207333080ef7f923e35c53f55fbda2cd3b686fd30606b0d6b92fffafc0990a51e2", + "id": "beaa5d25d2d5156209f7a6bcea44f483080f1a3790f72e2e7405a1b7adaf7d83", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 7198886304127, + "fee": 0, + "recipientId": "AYidBk2SLnvrtgCu9ZYX8thNPweQXKoBgt", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100bbc9400997cc61072e38bcf2a3b4a600275332a5667fcf9ba463935309b6a98f02202fa932ee91e6f940b9d943255e1ec649517302c5a93b54fdf49847ee5c0abcd3", + "id": "3e725df96a6f88901607d832bad39c83e18f7b52e689a3590869c85cc4dff5db", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 7274098215498, + "fee": 0, + "recipientId": "AQiRjkc6LSFBc5JgQHfEtRYTBKzuibCm9d", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a0d5eff67117daa369f3b77839d2053ab16c5b659dac2f3457a75877cf346ad402206ef582d8394a23e3f535385d02ec135d09bf6aba3c1d812228d59052f3cac48e", + "id": "f13e17151b9761aa406da0d987c8790eb0556d93eaeaab95d5d2b91458a951ee", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 7350458828062, + "fee": 0, + "recipientId": "ATWCEtjbAVLDMNCyHmdRMeoiqcHPahb3A5", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206fd243d047585330ab1711f38f4a5d8de5d283df73af280628aec73c56bc13f3022035c0af74cb2df381b3e3ea2056d77859d085da0105c2e85edc6d607a6ed6df57", + "id": "9492b0c5b908ff768932a67731efab51d12491d654ddf6144307949596c4f581", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 7350605843105, + "fee": 0, + "recipientId": "AG61Zuk9tUxhu53EfvBBNzh6aLiHshmbgk", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220289eb9006920d7e06fdf963d3a6b1252528cbc897bec005c20773c2a6fcc1d5d022010e275229dd9e83053e9cf8e931e8d6bf28c8b5a7a40275f6da2d08e68f12445", + "id": "a2e69e4e5391966a019444eb1920d8e6c8793cee7c6778848f14eb8e2a711d7b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 7350752858177, + "fee": 0, + "recipientId": "AJ89PsZmopZgpAEJYiFpN4Nsf37AmqGFEJ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b1d30a5b801388ff04e1afbb0a1a08cef63e0ea4f256826b49438559914965e002204c6311d26e092f282985591802be6819a159e368f86f8bc72b39ded94b3bb93c", + "id": "6372eabeb335296df1f7dd2d62aaa635bcfe1259195ae57967a47b1121d16578", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 7350752858177, + "fee": 0, + "recipientId": "AcxafSyp9wY2zZkqDSfX7uM1ZPsVsBw2mT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100af2d76096e5de9e708de3bd6d68f3144bebc43dfbf09272a9f402870c2581e49022017a11a3726d0930d47a965393455304dee143d0eeb992fba84880474de00a211", + "id": "05418f5b2eaf40ebb39646280a9f1ba7850e96727bfaf4bc4379637ab169e7f6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 7350752858177, + "fee": 0, + "recipientId": "AZXTaxgDD7YqDPJLTkWwKgB6XPZT9L9Ata", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a54c0c0c82ee1943d9fdd66b10a0a6f70f8697bf5c2e5a70b108ce26669a639b0220463b72006b1f45a7403ac406181fbdad7ad4173d4109f20c25c890551851994a", + "id": "d311075ad854a0aabcea25b63cdcdf8f4b81ea41aeecb05e09f64c5e9d9056c3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 7350752858177, + "fee": 0, + "recipientId": "AeX9ZCUY3TgYBmxhT1eA28buQymhzcRkdG", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202bc46f5c4714ddec901a698d0ecb09e4eaedeeb654ca202f55f3af3256774a97022034c060851358a005d60fdc2c88a4706e0cd4252d1ed84f64c42227bea5fa0a5a", + "id": "f5338178edbbfef4715e79399f932057179aa09bca7ec7fbae3c170bffa5bded", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 7350899873234, + "fee": 0, + "recipientId": "ARnH7KwF2dFqZBaVtg89YRNpiFoN9E5s4G", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009a0f64be9d209adf953456872e1bb098c29174f219b4b620287a624663890ed802202894dd9517455c765ef6868b12239246a2b4a862cd9e5c5e53cb7e24b452f5dd", + "id": "833780d0f9ddbdd029d0a4c3fc15248044540cafabd9ea99f39ef268de3e559b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 7350899873234, + "fee": 0, + "recipientId": "AboFjwBTGZYhpHeBSRyX1gRifpmGaba1Ne", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009f02dfcee31f851c53ee9ba7747732b8395dc294e22ce326bba9087ce845939b022067c32661f0ea2f62133dd9367ce19762e8ba976ae5d9fdbdd0b5747880527ef5", + "id": "da390944985838649b7fb34067c7335926531602ab7fd04993f3d3dca8cfa0aa", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 7352075993676, + "fee": 0, + "recipientId": "AHJUzj6eMQ9331gQSJ8VMmxwyTxXgojdUy", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202efe05396510be9de3a85403629b8de370c7e239b9aa7ba8274a3dfe813b7639022019fb6626e456e050efa3b49ff2bbe5d53ff9c7b0f857bb46a60c4574ae9706e3", + "id": "6baf648e78dd4f865452d1b2a10008e9ba53067f5f7b33689715e1012e11b920", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 7467974903126, + "fee": 0, + "recipientId": "ARBHK6526c75WtrSA9twWuFbcvxSQXh1ZB", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100820cd452944f0b765c309ecf5888f897a012290fdfa80ada1d79edc8048b068002200a7b4d0de4d6da32ca4e02527c9630f08e2efcb2b5d9a2ad9fb2ac59f9236058", + "id": "b615051a5fe01170d7972e4cc06eb635e0ac7d8435f7122873308a029d64b029", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 7596490265803, + "fee": 0, + "recipientId": "ATDz1si1NgxYVhwco5FU8rziXikgzMswrL", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203ffe6e56154cd9fec39d3b5ca60ea6b371eb95dac9857a4365b807b329156fdc0220733a0c695b65af96e3f2b8b92661c6a91e1667867580abf25f146ca2362e2545", + "id": "7c77338e20a9478450a35a4ce4a503ae93c1268850c4582deeed42b2ea202600", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 7728600535371, + "fee": 0, + "recipientId": "AUzNXqYNtmcbPUesxouPuLnAqcvxeBv62r", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207dfaa07820dff0518a6781b5637985188caad8c308a6716b0eb5b8e49a399d1a02202a44037fcd6142cd558e01469a283cb7abaa6b63f383eed37425a830a38952b9", + "id": "98b95f131466f769280d7aefbe5cf7fdb7aeefab4dda10d561fd22cefb329e1b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 7863973424054, + "fee": 0, + "recipientId": "AcGpDjv1Ja8gybNf1Kg1y5wfjRvB65nLJ1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022001916ce368bcfc70ab18b04a0972d24a4a798c1bfe1ac82af88af3e57f05109d02207d702327da226d245e3e73db80fda6ab378037e21cd96129b5eda4bdc44f0dd2", + "id": "8da4b1228b425051845def8bf958afddd81be64966832d56ae85f30c09b55298", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 8061487401793, + "fee": 0, + "recipientId": "AYpKBgSEGotwZF3BvgpXWxGKXsawYQEr7U", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b566d3021fa2bd2a9bac9320149fdea4f0aff2e710affebf98a8e4e132270f27022036fcfa529097201dc793d55940b20861d2a359bb14d82e8fd0a1ae17359577ff", + "id": "7f88e5d7f79c63317e0c732c03b451b1ff2714bd5d87900faf43b979e551970b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 8091708746281, + "fee": 0, + "recipientId": "AMgi4FUnRNsseqVpBVQLcHtk2PxkRFkv4M", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202750a5d5fdb30175ba7a0e8a417026664dfde32cff5df156e5d73e25b26b5f0d02202a6ecd37f045c321be0526ce5b854dfebd8a7b29e646fed77e98a126458a62e5", + "id": "834bb22d473469b193464fc80c52058042e14d82d6e3ed85b463cef6da9e68f4", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 8150156945826, + "fee": 0, + "recipientId": "ATuYepEksWdtwk3PTdYEdjytkTKv1L3R19", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a2f40bf9457f828ef8c32f1bcbde320417f0f70eae75ee0492509a44986b97be02206a1fa49f2b1079da0af70eab644a2e161c69774bdcaf10d6b924e3b4b0730a9c", + "id": "2e66f27a9f97ace05f8168b01858118e23cdb033ee68c84ab0c5cad7d9154eb1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 8360754246642, + "fee": 0, + "recipientId": "AbA6wrkyQS5p5iDZF25BXcvuUgfZm3Hy7A", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201477fff0e08a35db8bea53057aa0b8cf323ba63d32e3ad28bed7da6d79007ed102200a5bc18c359443f02793e2673e615dca45013fba0dcf11d9719d80478e8d6e93", + "id": "c087ec57f646b73353792010f5dab487f12111ba61950c3cb4dcf26c51daefe8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 8820462384640, + "fee": 0, + "recipientId": "AZf55Hbr3KnRwHbZn6zoEov7TSkJGhDHWU", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b964e775cf55c8c3c174c1a06ab32919bc940dc74121b06f5f985145c06781550220452aed6f7d901c9ea5ccdc9a3c9538fd5f2fffdc8b4abd1778627f54674319d5", + "id": "206c25241d5f0bf068e1d532c0005957992176629f09a897dd39dada84b7d500", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 8820903429812, + "fee": 0, + "recipientId": "AankYCzRAR2mK7z2fRXmXxzUwJMknRPkDq", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022023e35b79c2cd4429d44e9a152371760a704819b464132b8464313c139e8be78b02202b5fcd45b45515a5fb41a997d93f55c089e65090a1ffbf31f07147445181d5a9", + "id": "62b7ad211b62f4c87e4dcd71d72cc6d9aadc8a4077379d96377e3a8fdf468b78", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 8909427869508, + "fee": 0, + "recipientId": "AP47UoDcZ3XMq3P7VBLpJJnHGjGaD7yGyu", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f5619dd275b2e1857001e6a803b2cc5978b562f947e569bb61c66d57a381075702202087f6b32d421f28c766fde6853ce0aeffb672903a9c065f3520d4111653d5f3", + "id": "8a8001b5fd69483fb8abc89b2c13626c30adcdb94c04a25dcdc1d81a5bc3214e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 8947739735763, + "fee": 0, + "recipientId": "AeBVmaLa8zk43EApXSKPcTudHKRqDBYFWd", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100846c22b8c3b999a50686b0df62755762c8f3d6e856d30ef3e467ea55f0755b9402202611440aa0e7b6c220399b990995b991324b3cf2fe8eee8d3724736edc00be2b", + "id": "e434a3e0a1ca8c488797a9a7e10361b4f0889c8528263f2d5da8de0ce2f923b8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 8987732597729, + "fee": 0, + "recipientId": "AYtFa1PZcaXinZSwvsjoym27aAAKwEAnaX", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100871e75cefa2f4aa5aa3e2602c3a918a98589889bf157f72e7f550085423d3300022058f068d7af9ee807c49abae45edda26876e1205504229609397e42bf26d8b4a4", + "id": "89f718ec38b7ac3e6ed5c353e8d6c6b7c77558357fb317e4ad45f00a593b4d2b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 9019606582562, + "fee": 0, + "recipientId": "AKeLaHxdcSBzMyM5bJUvThFcTHsVxmmatz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210092e17b11d4c617baefc3df8fbb432d34ff142e1eba516f363507e6f7d5dd655902207278a3fc300dabd87c6103e680d0b4f9a9a9daa9a7ddedb372d8a5039a5b8118", + "id": "b1a04d1ff1bb94dc1b0b1902a803f95f29b4cb75577899ec9ec8f0b3d042fa17", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 9073460596513, + "fee": 0, + "recipientId": "ATNoXbqJPxJLUxNrPoGDYXo4TL8dsetmgz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008120ddb52945a8a06d38ed29d2444d99ffe8e2ee7a6626ab6444b3484cfd94f102202f304a833c539fe335c91ec20005231362b5872d37f2f716ef8705857dd44bc0", + "id": "aa0f4fabc4952d57a65943c6d9a4c6ffdeb77ddb984aa4c6e73918028e697816", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 9106661500215, + "fee": 0, + "recipientId": "Aa3rBGChkK7iz2NVnkUx7pkjwgtgaZRpVo", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e61fe14e4167951da3bb22c81a12a387602ca09796354cb5d2dfa34b453e31190220493edba4cce40195451c2ef5c260726dd80a81f9e53a2c0bf8714c9b2cd33b14", + "id": "9db14bae790c26d0073c5cb21b54d8a860d79573f6a24004d5938db55917d20b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 9116425808613, + "fee": 0, + "recipientId": "AbSakR7RXYAEWqBh4btWuVXCG29HTdxCgw", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009d069471d4566b87598efb5d7f4550a511b7ce0d303f8eecae2532ec3cf1664b022072ffdbbde754ca2d1b57600ad8f0bf8db9d0c628a4f761479ea547af329091b6", + "id": "a3ade2de7783875db21cdb97071f1cadba19e2a5258fedea37396443f7dc88b3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 9176679868148, + "fee": 0, + "recipientId": "AKWjaZp5KyKzdCnJq9wQiF8umWCJL33E6B", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f6d4983def05d2a75eda8867eb47c6ec6cef8c4d13d43c85302161685ec7a324022055c69ebb708ede45540d87ac55fb4b240f9a1160a5ba8dd1aa7d49a4587e6572", + "id": "4fae51a3f14bd18dd23869bfaa3fae58c31142644e18d4422ff46f922f68ff1e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 9212629406283, + "fee": 0, + "recipientId": "Acj1Rg3SaJrZbiPsTRN7mfzKwHxh9ZLciN", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204dbd9c143b3e6d1335ccee6965087fe0d875d4d8d9c9d3574e018317508e248302207cc154f6ed0baee54eb44551e9a3d67b89ae5c539568c208b6e6243e881909f8", + "id": "5aa7d5de2c38dcc27f69d679349af0ad153ee494ecaee656a757fbf3cc1bbdf0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 9261801586245, + "fee": 0, + "recipientId": "AJN6KnBY8VxHfiE7YDyAwneXCwDVtdh57q", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ce0a2d090fd6bfd170616d273b648bd862a37d30e5dc365af8e70dc702f0763502205b95aeadb2b0e3e02a68638e5e0ddfdf74ada07ee5630e00b22e58392144f3e6", + "id": "006c9df41217c960f9888779a7fe79f5f7e30dfc06d450379c54aafe01820606", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 9431021629737, + "fee": 0, + "recipientId": "AHpsBCfa32ufzETjsSJj3c3hJNGhjAyq6f", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f26cdb6fece9de8ef933318bb3af05a349e888ee8ab47310aa829d96f2b044d602206f97eab55c51cb15bc25e66da6832db6a4b436eb538aa727a5264fff4ccbfe37", + "id": "f543ab6ff8794636fe7aaa81367bbc5b3c47bdb7f9080df77d3fd09067941b56", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 9456800520174, + "fee": 0, + "recipientId": "AXt8HyD1jBZsYE1c6x2HdD8HoVJsjHuqjL", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100dbb11f95e9145884db5207db7a7a45b4eb04bb4f0c833c2949b2019194f7c7b602202d8c32008367ff0d486a7c584eb23a9feaf533188ad2e38d2a7bcdb912561ac1", + "id": "ddd35a61d78d3ef066178e240dee956ba70f73b0ff41aa59fba2543c01ceee60", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 9529256927883, + "fee": 0, + "recipientId": "AXmh1DXiL4g4JjqJp2RgQdHnycZspLeztT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022039c3d55cd46134f05af871e13604c76aff0e92381980fe2d4e5e61f63efa891a02207b707a5e64a03e5ec1b6cce3372da6da6ca0ebb2e2bab0cda4ee104aac92d0ab", + "id": "ac0915e202a613fe3d133a3b8e0a4b86737e0d06bcca02202d583e5e3ddbbb3f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 9547731294407, + "fee": 0, + "recipientId": "ASjGMDGXLfB9fViy9qPqYGEjgv1jeuwWox", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205e2ad7e24d33353687c030186542c4ecbe2602a35cea56d4e7b241454e785e51022028d425089617605caac7b1827be5cdf18abe4c8235c2a622669c97af32f965ac", + "id": "d31f907d222323d8e5d6034811433ab67dd7dd334e0a5c6bbe24cdd3accdb501", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 9657132907103, + "fee": 0, + "recipientId": "AGFfszsJjBPwUf5ko5gQJaX76xFVoKbh2E", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100cece660ea46f4303e6b76cacb62da21ae4c8a6d11481ffbdf1b071e49d498f4a022034ed3118a40013cfc73123a39ced55c65bdcb01dd8ebccdac9ca689faf8a8514", + "id": "2cf431f04c0124d8149a4493ce3b317257512684868568884658512f5bf02d27", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 9720973358155, + "fee": 0, + "recipientId": "ALxR1nKJXgDfNtEuek1jaiNJG7gNtfZ6qb", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210086691e951494d4808f416e82c1d346653b04f39272cbcafa934b3e643447dbcb0220292d0fd8915227ba07bdc17bb7a7e946f6a50c4c063950fccd47a73433f5b42b", + "id": "f532635980304bfc7afc3ee2873890f529431ecc3217f8bd580f47f1369d0541", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 9861574288956, + "fee": 0, + "recipientId": "AYAYsDGPzVarAcqXrpUE8eYcftN9J2UNtK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d7531a783114009e2775b63dfdf0123ba0bbadd193e284a9076b4e02ad1063dd022041f3c3c3a9dd40d17483c4c01d2615eb89762611a5924718a517aaa0ce09a829", + "id": "cb3f0522a4824486a1277d54d509ea9956aeec80cc2fa77dfdbccdfc7a888a62", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 9967620875688, + "fee": 0, + "recipientId": "AaxB3RG8EhWNB1axLbDrxza3v5E9kphnwn", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c9f22c83fd1327fab869e27902fdce90ed952126e7c43c7e9afae0cd9007591a02202141f6f04a4a4b519fcecbee3afa90cac41a090c31393db048946d780735d33d", + "id": "a47732e4feab4d3817daa01358f6f295d9e4f07ab1e383f08b09ba0cb755af05", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 10271698022691, + "fee": 0, + "recipientId": "AYDYbKKZ22ym3ZpXcyzPWc7bnvZXRZdiem", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205b259b711e8a7cbef4e8b103cdd7af07e6aed38f65d0f91ce15f906dbf6dff7102202a0e181a4c64494bb7a679e0d86b397c644e3139e0ecd8c90e38fb7dbc798811", + "id": "a46b6b26e9c55a9a265845d4109e3e03ea963491b5efa4756e49a6aaea94d91a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 10298404754306, + "fee": 0, + "recipientId": "AcdSagvBLHcUuh1f3GbqhwxDZ9kuNgt9Lw", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201deeb7ffb887271b4ee12f3feb9b5c5ef4ba4c60cb4a1bc6555474cc96e420830220542663416f5fc69b7797d6a4d231041a6d4467d77d1598e19cfc7a64d89632df", + "id": "f9006c06167e9095b7398eeb11f8195d715b04be4689eebe59a5864def4798f0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 10305487746344, + "fee": 0, + "recipientId": "AGVBHkaRr9XWBLZQJDdV1Q9RXcoB67PBeG", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205601083db78190cda32bbc1af11fffcd7f933052794e7d4c95b6292db63c3f2102202bdaf8d58e7cbeab12ce6fa0d34cc70cb02f381273d533db553e15f9b2cd2d08", + "id": "66092335843fe18ab2c4a8d137fe0e341057060964ab4169383b461df9f7f385", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 10318455720429, + "fee": 0, + "recipientId": "AdbuHGsffes9YYyKBp9DzKrcQofg7zuSKQ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200a8c0a7ace259d0393f8c3662af8f8e27a0f261e69fcbe00fe99a095193965ad022034badec2675471d2d846e28aa0f4cc48ec9d1b8f6879f2dfd769300496e0dc78", + "id": "457678f9e0c30fd116dda8f82fa4e479b23a0139d36872bc4b992fcda5fa095e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 10360354001447, + "fee": 0, + "recipientId": "AXkBtARJ9ibkidfLMhzVSRCAuqWBxRaDhj", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204131d85f9493b052192d281fef2a87ecebead69c4e4b72b306c967a2bffd013602201786ecd3284b341843cf434ae92600de4bd044840ea306ef36372da4f8fe7e13", + "id": "eb6590373de4b7155bd45679378a312473be8ceee6c9c4fb86f2ebaea4c1be1d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 10445981844431, + "fee": 0, + "recipientId": "Abu2eNnxLNUKimhqKJg6x2aAcsUJStuCAG", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100eccb27c0cfc2b60f4ebaf647654132c4e7fab649368a77241c55f72dc8ca3025022016463ae4170d699d3cdd336c992057ac3d5c2ace3be998adb189840afd328d20", + "id": "b4b03eee17ce3bfdefba3d60783e5fefbfa99f5e2a3ae36d3a77f42dbba37837", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 10446382135839, + "fee": 0, + "recipientId": "AXBkJGbRzM2rUD6orebcoP3peg2xGbgT7j", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022008bd51d33b28766782018df754e853f8d92672e3ff570d1261fb1cb2f30fc9640220022208c3f0da9cb972e2c1888f1fb720c1e977b7376caff753f23fcad801a5cf", + "id": "818bcbbb73b9470f0e4d0e9606f937ae2281dfec46f55251ac7b77d8ae545bd9", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 10585084115774, + "fee": 0, + "recipientId": "AJXuBCyg1jivEDuJqrJwu9R19C6uNG3rHM", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100887bab7c2e2800b93cc9df58e418ecec30395fb35db6c3598d541295cf4104580220128140bf3e75736d5710c9df703b7f3a9818a6a1caeae847c0ab154645bd68c4", + "id": "95ea9f02ecbd2722503b7ad6754a29b3c743e2e114fdd403fc96b16097a3ff31", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 10792241696323, + "fee": 0, + "recipientId": "ASSd4LMA4BLtskUS3XvPbQYLe84qCJBF5V", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202885acb08d8088274b1a8ab4a28c796f5489b82412344c5ddec9f21389bbb21b0220525fa2842e1e3b91b98a5f8326cdc89d880e543da82be9adff19d923a87b43c6", + "id": "872e270c3eb5dc0d487a040745293ee5373e2622ddc9d34cf3e4ad793f2c6a25", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 11033661805931, + "fee": 0, + "recipientId": "ARo1r6758wTHS1QR8LnhJiyLcudybWPhb7", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100bfa945a5eb00deeb1f4774b9a2d46a44832d38877976f385be3fa88628c00ab5022024546c571207800790fab06037d3292a46d31e9c947acf318a27f67db8e42ead", + "id": "1e03b495436ab9cad5aabd942c84cb315f7c7796a597a56a6aaf9680f1124173", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 12262151610133, + "fee": 0, + "recipientId": "AWFxQB7mKARk8W63fNRpp6kZjVsapdFsDa", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a31f640dc8ff053899dbcad3ba8b4d67b1046db0c9cfd2dbe8c15a1b7fb7d920022003b089de0b92bdb55701c76ab22306636acd88e933f75cf6d077bd4cc7844c5b", + "id": "e550f7a823f274dfb83ffdd148c2d18b573abad654583438af7a702ac6de40f1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 12274908823760, + "fee": 0, + "recipientId": "APcaeU4K9uQXSRLRGEgDM1G8gtiBG5tCYZ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210098a25f2a406512474e48e14d7d009cc8e7349e7b4a51f2ebcd63f4996c2507a502203cda6a22c4fec125995d1163ff1ff725ffe060c6b720f91ae76c20a7217b2e6a", + "id": "736b8f9771bbec8794353162441c1dc30720dab02dda5f17721f3577b0f7b454", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 12417330032449, + "fee": 0, + "recipientId": "AHLhrDJwqQmHnZnhEPBJqfEHYHegt9Y5rd", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100edd8d1aa1c15c0249e1cd88ccd81edae73250b10df8c8a32549632404b5f0c560220441b966469b37869d5415cc7d90205be883870c3895db4c8b5ce2b4a7d0dba17", + "id": "9340ea9bdaa5155914bf58d74b856d532f1710efe6c569ecee144d1c6ec51ceb", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 12465317334603, + "fee": 0, + "recipientId": "ASECaxsSkxVDWry9D5fcygAY5ZuutNBvPG", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201ecaf13c7ce1da00ef9f8e28e95be0d15d26951dff1f742399e5298031337c8c02202d756de469c1f1ea127c4d785d723ca5c7f6991bdb8b8e3a9e7be2498f5c9377", + "id": "6902bbe0e9cb1b9cf2faebf4f96d27c85f4b1aacf9ef7b4dd52aa7d882b4470c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 12637331924100, + "fee": 0, + "recipientId": "AJ8YEJ79noVf2n9dm7WktKLy2yJPqmUWiE", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b4236f3e9b43c0c3f503906f146a6c736e8572264c9da1507de8cca20d7df08902203004c4ded33dd32eec7b97384b8edaec3cf17c8b0f813084703c289e17572cfc", + "id": "695597762e9a98153891ef3ce163835b600d7d6c8d622b15b53f70b1da3ec08e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 13156450295530, + "fee": 0, + "recipientId": "AMnJCV7YZg3aQ9XFH2Wm48wX5Q8KP8yf3s", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220798836f686318188a82f5a0b37e419bd52a94582e4bea79a981bfef94485a06002205539539bda455d85f826a824772f5a068359d2c0af5f8fa94876fa7b6a83f14d", + "id": "dfe1528b1eda46e77923bee940a97c678ac3ccf209e146cee8b4d9e590d652f2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 13231355144718, + "fee": 0, + "recipientId": "AYhj1z71Ajs7gQPb7TQoK1Th2HWne8Dicz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204e4e7921958f482891c6edf82e87d577bc1525ec26a1606239dc3bde80c7e20e022036dfd51919362e104d7cf98a1d2fcad1517261761e780569d60503dd87c85b9c", + "id": "d531efdb301103524d38dd7720408e6692c77d4b2581c46b44e98352952e2990", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 13433119945670, + "fee": 0, + "recipientId": "AJuwxFoWbhWGiSghWDuNLh7B2u6orxYKEr", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e2e10a21a73b7fb49a51c9ce6981401bb7041ee97b929781e9a33c55ba85f8fd022045871513d5cd53061f7b21ba1638ea8502f17cec0eceeb1ef66715712d3a2d92", + "id": "c37d982d2277da42cb03590feed99bf612911df0df4d0819c410d906e28237f5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 13711299443014, + "fee": 0, + "recipientId": "AcFJgpMAH1SCrCRcsgWfXgbQvDiBh7suEd", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206fb5cbaef0ff5662a750ac6a89b6090cb5e54934f86e1852f75b65801397fbb4022052e7eab49c5daabe9b69fe1ced745c2cb722c3c221864f9336584082bdc750dd", + "id": "96f9f1ef9345ec0a80a1d49ac3a366ce130174c328432db08758a69f694ef2e0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 14115873577166, + "fee": 0, + "recipientId": "AZLm98LrEyNEmbfe2AHV1q5V3FZza6x6fB", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202d808872dea296887d825d2939947ac1ef11f72f86dd8d0c6725f280d611ac9002205b08d41e9438076a7689cc07f0d74f3af73158568cda9b0469cdeb4d631c1373", + "id": "60df15ce23bbf98fcfef08bd24668c1951af818540910ec3ad9dcbc5d2600995", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 14159732932194, + "fee": 0, + "recipientId": "AWiJP7L3ZvRPzZyc6mmM9qqNcaYbL9ABxx", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204c66842803665c4bcf29c2043e1d9714e3724a1e1dcd935e1ccefe6228704675022010f26ee2519ced03bd61a8095e0830cab83d159c56928d7f11017c67b8c6247c", + "id": "9d5279ed2f9c0e85a47378bdfd168d29b83e2ee7d6ce8813c3a7b4a68fe50d85", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 14302397057832, + "fee": 0, + "recipientId": "AcRE9hpuKFJtyqCSGDS1QcAFTYCU17t1F1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022019ce5205866f88b78846a07a0862122d34113cd250df8abd884c7202603af10c02206d05348f0438e537108ae858798cc390f104c69047eb00aa47455bd89fff0b22", + "id": "5dced5fe4b20327ae767ec3902dfe102e6764a86f20fcb9fc75c6356cbeb7385", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 14627998187772, + "fee": 0, + "recipientId": "AeDZmqf4hg8HYMvpxJujrVWqCyVUyqZ3Zj", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022050e3a4396de2c6bbbc7cd1120e46a01863b9d961bc19ed42f98a18750e61a8bc02205ba8fd0e08d26df41708ae78280ba08fffe1dbdac48092b464da8b77649a716e", + "id": "816320ee8653dbc97e201b24ab45af6d3c4d182ca9d59b96c60f218803bbe76c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 14701505716353, + "fee": 0, + "recipientId": "AdTzqZEgkihPhhqn7isgQNM7UmJCFjSRaJ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205fceba8d1f594a4c189f6939db2567a740598184cbb2787a82560c7d33939191022054ec9894c1f430554cadace94c584a6c6ea5f907f06f5636de53d01c9937667a", + "id": "bbf0def2ca931ae79bb421b00044e5873840c3b761a24cd6db19161a069d8575", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 14702758612028, + "fee": 0, + "recipientId": "AWSCxEf8ZFBNNMturNTbyrwaHqJHTAz5hF", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220415ce13dfa1e2a0f62c4a1b452747c0818aeb16cf852e7c649a7e061b522295f0220738dd8e58a0bd7b0cb3035295d38aa9c164cf1a023fb69c2512f964ff840c0b1", + "id": "39aa37fb064becdf8f37a9bb1e55d3a1e8a96beb6be1fc1779967690a74dd7b2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 14702828851868, + "fee": 0, + "recipientId": "ALcRivRn5MpE7gjYPfhvdjkT7EidnM6AsT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022041e7c81b713fe8ebc58fe4d9db338b89b3663afdd526ecd31dcb0b6e9a8f8b1d02201eafac17f41fdc7dfa29c748261f9a0e79bcfac5e418a1c144b0d820dcf54ab5", + "id": "19270d05eff4baf154541b1e9acea7f70990c9fad504e043c281d384a856314e", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 14708415424040, + "fee": 0, + "recipientId": "AbVMJrPSe2z7UCqxfebGwvVnCPePzYqqPX", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220429ea8d0eb83bc86a8ecbde1777798182f219eae5aa56de3cae7bbdb4d04e054022051e6769e588884e730ca65b1886452de1d2f7050a9bdf758675f78c0606db368", + "id": "a116b90dd6924989225c4ccee132706146ccc6a508c8c0f2055349c71d01a375", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 14818222131272, + "fee": 0, + "recipientId": "AbmqyXrS3NaqZL1JanAV7pi33cxKHewwQP", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b1d6a14c5c53e2c96d5080df55c593d397771c9d4cdd9c87a35dcb886102e7c202205e2ead847be17b2d5c71b93b7b50acffae974232c1164971145e6bdbf912a85e", + "id": "5b864466691fa06bd64c97204b10e4cc4de6acbc4f9f02d9183e96f53ae9e6e6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 14822705716353, + "fee": 0, + "recipientId": "AMwimBgD3PLbthyD2pw6x5kr7XdAG81u4Z", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100cc44646a784672d659731b5c7aa58da1d4f010845bef874c5dcabd149d2c871702204e067aa1fdfcd05315ff030f488bff4160bc6d4dff149e6d0f248cfe0606e5c1", + "id": "ae29982e256bf9213db1e8944b73f2c98942fc31a4b107c2d5201f67595102f4", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 14895015891637, + "fee": 0, + "recipientId": "AYJiw1a15awqfRNQWXXuDmxpQ3DNjWitzM", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402205f487f6903a7767049c69f2d80637c45ddf757d5cc2b879df4b12e421223e0c702201ff2ad7ab479099433d5cb74b17dd647a0fb0ea38fe72950601d4510910b730b", + "id": "4b00501c8bfb24939da2e8402e40ef56c58a5c61ab6b4eedfc528b1b28f35157", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15082558701296, + "fee": 0, + "recipientId": "AQbJg9r4c5TxoPPMcywzVfLHavxbWCQs5f", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220502e111dd7864a3bf81e5dfa24abe4f74db23747b2ae7017cdae6cccfb72567e02200737316bb0d540184321f56e7e1099d857c56fb50d9156f2fa4356c56b369d6e", + "id": "430dc9734272db7f88762940c12c32b5063b5ce5042e8846a48937d2636e11ee", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15241050976143, + "fee": 0, + "recipientId": "AdYqsVoQVTUto6ALnocgCvnssTbDWnPAbP", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204012639c893ef39e7d67a0ba9fb133a37120007ae3b9d8ab7544cb2bcdda32640220232cc268d227799a8ea63d58697cfe0a2cc9de3123ff825ee7551a894d0b6d3e", + "id": "bab6b296e910810366f4ccba38ef01545ee34cd4386c0c1f806369c8d71579db", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15458231619516, + "fee": 0, + "recipientId": "AcXhb4DBzzmBG2USvxuJY2uEuFnMr7Qfhm", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a2ce8edebcb297f1948498412a60c8b736320ce1ad347043222bf034b21fa69402205e098d716d247f85e9c454b7b53b43489d55a91be9f19d792ef92b303b48e9e9", + "id": "d4a58d3b71902d221cfe3cf915429551c77a0c4d3c73c92a2473c3c151c1f9af", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15525088530753, + "fee": 0, + "recipientId": "AXDwt4SoPBiSvfjSKgZdV4vMTaNCgaFHMK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100eef9c401c97b593bd75fb52828a9df9bbeb82508006ff0d683309a7c1119e6f10220040995de4c4246197bc51ac7abc5094d9ac8ed8b1a8562ba85634bf430d9d866", + "id": "f3e07c51b39f93978aa8b6e4f133400e33ab808f17b3a47825afa75a58bb76a5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15609782909903, + "fee": 0, + "recipientId": "AaT8V4r48jE2MtWySFmdk2gqz3oz5RkXvs", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b46dbd720df1b60f59d8221ba0f7af053d7447acfe378b0763edc899300e035602206723c53b8ec4b41f1c374efe7620b94e62f0894fc90174404fe2d36c190ec396", + "id": "c37f2b2b221265b74534bb17e8791ae000793bea52102905f35c89a5fea5bbf3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 15840600000000, + "fee": 0, + "recipientId": "APpQDTuoqkWQex8ZjLCHxNf7xpYuEdWpJ6", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b6d5bcdb2466f138713b14a398ad38c470affb52f714693f836574106ea1cc3002200bbe4f8923a286f2e677e660c7316a815b444db2b6f46849d73402466b12cd98", + "id": "4c20e8ee483a76470df958bf62ddd99ee14e9a2536be56599145d28afe1700bf", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 16008869346988, + "fee": 0, + "recipientId": "AeRmfbh2GUoEitySmsQRACFRkPQFh6XxCn", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210082cbed89e51bde2a686b62c96c564914f843ca0771b18ee0f57a1266eb181d2402200d87f5c50a8be268afe0210c67a394dc63cfc5bf026db1b58c8950ea185dfd57", + "id": "9ca43cdb29bb7b775d487bc7392be4f6da70b6065cad1ccf40483b0c53e0b23b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 16171656287989, + "fee": 0, + "recipientId": "Aa3E6iHPVW89sPXamzE5CUfAYhEp9arAw4", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c1f8856ceeae2243ebb9a171b36ab449c637536365e033e244a6ec47688922530220565bd9cea70b34e2f7a7fe5ed5b6b4fe2eec554def7c32b400df035c5dd9997f", + "id": "e370cd7fae15dfee56e44b6b602c0bea7819758a9a61fe0cfb5387cffbf5c747", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 16171656287989, + "fee": 0, + "recipientId": "AYHTbw2P8oKpk9JyPFXKuCw6auvVtr1Upn", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009985662bfaf857f58295def71d71bf62109d4e7454eb087bf0af4509896161e102207bce078f3fba1bddb717c318f6eced379c983b9830d4295ae2f6f90ba2fdfe60", + "id": "7874cc7ba980cda4c93a50b415074b3406415f7a84a10efb43db211eb3bbe794", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 16191556704498, + "fee": 0, + "recipientId": "ASUXHuCsmbvLNURKg8bG33iPKid3dvyX7d", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022061886ff0eba8d281f18efe0bcdd9ee543c91a19fa82e539aab7a1bd83cb5839002204f05a0c30ab8083a8fbd9d1e48f376b52aee5c23470c0f9f270e04e88fbf854b", + "id": "ee246b6d6c7fb8aad48fd8dc16e11b86a796a21d24068a87f9822f6fb6db857c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 16746157299652, + "fee": 0, + "recipientId": "ATybACcBV3KhQEuhhJC2CbEUeAX5V9UpGy", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ae2122c8f375f70a1d174ec4d2d0fcd25936177ecb38ba43095d7166fc19da2802206c22f1e50d9e150d40e1d77bf1e81b153c546c3f55444e9073c440f5f9a08467", + "id": "bdaf7fef1b17036b8c7e15f7bd23c975166b368dfcfa840b5e569e5e95b71d49", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 17763076895273, + "fee": 0, + "recipientId": "AGycSD9trbo9XRQh7cFjk68dniLHM7AfBa", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008ca39400df66d8192aaedf44bc2cd791bed8ac3e0e048f3a94da6d56e201b6a702205fa0caa9f2f27a0d5321e06b0e4a68ca30af1813f7e1069d8e70afa378f794cb", + "id": "d5102ff88df36c6c97dd02fb8ef8e178ea72e32556c91a2e36f41d2363cc4e7a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 17882280422877, + "fee": 0, + "recipientId": "AYzPTsYgUcgZXi1GjA2wHzutz7BMEcbm5z", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100da21d666d853ed342f3cdc1f29eb6e6a557ca202c8876723637b51afd38499200220453d1e8130029e2c9b27bc97babefa23385b46f42b25dadd9467e867d2a6a66f", + "id": "d45a0dad2d8010afcfb30088104c4821dafaffa0c4348db0004e95e4b330fa24", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 17882662903696, + "fee": 0, + "recipientId": "AJAz37b4PJ9J5tnqBoQy2TDoDE5TiN8qnR", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220796c225df7d57a949b38b5dce6ec87cd4e8c1842826369e19ef2fe672c8cf3550220061c7b547e460153c1be12930ca3e9d8fa39edc2cbbdf550d3286ffc1bc2a628", + "id": "ab25cc4069078357692cde0f4cb9d850988fec28be74f7ad3e97c377bacec8ba", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 18446724051788, + "fee": 0, + "recipientId": "AGjo125YZU5Ssop4kuNTUYSeWqxMqvKA6c", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fced646103cd17b38cce5ff86201c1426304b6ca429e5231422d69e1db3ab93d022043255a9791928cd34118c57b07f1f587811179f29f8065ef35efbc8a698bd61d", + "id": "197db69caeb74f3de59dc23a8c5d65878964963e785874dd6b8474890106b791", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 20225218326294, + "fee": 0, + "recipientId": "AWDLp4YdsBUdxtqBjC8J4jNr7dddSCmbDJ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203f5912d44a52659b0a679ab303f5044ff5413876a759cd20974afe45f0041b3c02204e313f1fd22299f8f811fd603f7482ca519a8ca9595694bd28d0416a10952fc1", + "id": "0053820aeed9059247f556586e9e0a4109f4579fefd5245cdaf52f9fd901787a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 20741626925528, + "fee": 0, + "recipientId": "AN9sqKHVipVtacB39BFQkPa6dDhdSbUJ4F", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207f0cc0e15878619c6a0eb4a321492c62cbdb57ea87c5d38bf8c45fe8f188178a02206312324c971349b94bbbfca52ad71928386d6810194c2e1d3d0d7ea9d1f0b216", + "id": "1eff5e79d10063be3e29e764d3a6e4f64cd681a0dabecd2568492e25355bd2d1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 21951221806397, + "fee": 0, + "recipientId": "AS7WWoFGGutbnpBg3GmzqSLapSRxqNqoTZ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c98da3c32cd3fc557d169c23b454a294d7c226f5481593b22e4b4b0168b3110c022063e54d574b1580bbc056eac3598f96b3c6a6bfc4ff348ae3861835e6457eaf2a", + "id": "c14b7e1b79336f7c4b26ccd962d0d594c39b067cfc7475a2a577725937e1017d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 22059609327388, + "fee": 0, + "recipientId": "AHDuDQzUhW9r5AEcxWYLg6rtnAej8LpjVg", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200645d5b06ea85a4712b6dd58dfd40731036928dfd3c72142558b8d45d3889d2102200b2ca62f33a473edf0330d1773c505561e1334452d0bc1aad4eedd4a9771e5d7", + "id": "e5bbad079581ef00c4ade09d30c649cdd6b36b69437c0690561e7b950830a1c8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 22212505397146, + "fee": 0, + "recipientId": "AYo8E9DEoYD94vJuhFSmZ7Z7JdL5vUuFng", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210080fcc91a7c3aea6ab14ddb92132d820f48d44d08f956c6463a40139cc731051f02202f0dbbc598dfa8830d86d23ac58ba13a2e91c283590dcdbda9dcdc7a5ddd9e52", + "id": "f8e39f689d66d7277e0afd9c5e8d8e90582abf5eb2517ada993d9db8b6a4d5a3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 22232699614369, + "fee": 0, + "recipientId": "AL8BTYeajbkWG8r7A2uYpAsKoX3LMk9uga", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206259fb0a490e9fc37569a4f1fbeec01d783a53a18630b70d2ebba2bbe0f6d270022020025b4c0c7215410bb5ab68d5c551a377e7bf7ae7e364454b7baca54f1b045e", + "id": "500ce8f0b6eb93696a6445f97c26e559f93f043f80ec4eba7d8e59ab30cd6220", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 22622858823224, + "fee": 0, + "recipientId": "AWEmVoaBW9Xs9mt14YeXxmqfmSJ7iLszQu", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207d52cc181b70569c0f2058e68603232d5532b5ca9863ad0464ab0af2c29b369802201e7ca2e873ff0f73427d1afb837220a89f17204c04c41c15dc5a32b57e1262c8", + "id": "74f0e117703a37fb072ed990224d3173a02ed8577441faa8704e767f9dbaa517", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 23205200171281, + "fee": 0, + "recipientId": "AdCphTbTtmBouY5wTen7MSzjy9fc84J9M3", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200ac08f44e5c63a577d4dc5536ffb1bfe437813b5e79073d3118f66011c78bb41022034517534731c508f7c6d87d44e5848cd38d8475802a453295ec332ba79fe1366", + "id": "7622484aebbb489351c45157af39ec0e1c2f1c75ba8b6d3cdc5bbeeb87cd32ac", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 23285447659034, + "fee": 0, + "recipientId": "AMnNU9x52nTd9kEu8rDQu4wrDm4DPB3SCi", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202b899c4adaf2d1ba16c09c995dfeb02489ea611d07ed055662388ac291f12d3b02203965814654985d31c688c2678085328126fcc1959913fb6cbc1cf0b671a85e54", + "id": "d2174364d96891d86b3de6457e579b53b5750218ef9bbda87b5cd9fbb0aa24c2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 23749226298416, + "fee": 0, + "recipientId": "AQFdF9mpwxWsjMASsSQFD3kMxghDVfkWh1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204a71c021260c33ee6ae8bb5966e6ab27f09b2c3f11d8123b85c532339b2f6711022042f89f016efa114dee8c5944f160129dc5b1329ecbc61222f3ea5d7a2cd0c547", + "id": "d231ed2b05da5b4771bca09d3262cd4b66d7efd38ee36378b93ee9e66f0bf6aa", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 23788728527651, + "fee": 0, + "recipientId": "AT38VrTjd8gcmW1XWao5hHz7zA5Cxvzber", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402204f4d855fada8a76db9e26e0e79c9e67f51907cd2ea7ada9bb6d640c77d49c15a02206fd26c6dac762a78531b42e74ee643f541fab7b4467caa936a865b63302dab59", + "id": "4cfdd48b353e9f7324dc3991738c9dc8f4c93c51cc18c535390c5328a4ec5ed1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 25133628072635, + "fee": 0, + "recipientId": "ATYKgxB6sMBiW8bkuiq18eZBNM7ceyJ1zK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a7c5a575fc88063777204691c7d8c83bbe794820058c87a47099b4fc523b7ae802201925f71003886a98bd9a14d2e8a4596acf325186449825bfad2d2b0947e75967", + "id": "5d86d1704c731ec1454b149b7105c223ada5a8244045c91a7386444cbcf9fbc2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 25643974662172, + "fee": 0, + "recipientId": "AVQ1UscRdsXQZncshwXSZEEWqvPNMJXtpY", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210092d6502d9d4945e59d22fb7a1141717e41918428362fac7b365c5e6d2ee9bfdc02201c86ca71aac24424cbf2ac44ca3b77088cc7c873f826b8b6542abddb68ba50dd", + "id": "b387e98cd84f82172c378834cc12bf9b21646891deeb37ed9c2647bf400009c8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 25690453309429, + "fee": 0, + "recipientId": "AMpKaxERjupes1GjHCVV4Rctj49BJXQ5Qk", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207bb590646296b2ac4b2ae347eb2da399b9df6ba21273b463e7117dd14ab61e4702204861d99922766f5a05b12730ffd84bb9784a37c8e27b58aed3f0b896230ec082", + "id": "81b65afd6830ef600587c8f22cf425cb485df032f8fa236121d986a0937ba41c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 25763719365860, + "fee": 0, + "recipientId": "ANymwDRzUoszXjbJXQMhPBmLrBv37AoysR", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008815fa72ddf054b47d90c7a4b9f12c783eca5ce10a557caa79109ca2e51176a20220595c9d31fb930159603274e72362a8807999dc80b3bb49ec43958837ac60d270", + "id": "434775c5695597b6554e89281a194cd903f8808b655c65f1b8cbcfae3e39c89d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 25896835969408, + "fee": 0, + "recipientId": "AdLxpRiPQdsdZqxQWEc2kYxD5YFzKsLB5T", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022079e5465fdccb479bd275f6157553ae46ce6b5c51dd51ff0fd4ec517b6deb7c3d02205213870fefea75258a08f564a7920f2740f4026a8655fbc8d1a6efc6dae611b6", + "id": "3c33d4479fbe31777d0263d7a4b6c035be675a2a8b9eb9964353af2c43737a61", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 25963064569714, + "fee": 0, + "recipientId": "AYqoBy73QzTfN9LHCgvT7eH4tfet2RU4Av", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201e891a570ff244ae679fb0284f55f65595d7d86ce5ea42323708bcf5daab0b67022078488e4c73790511ed6c1f9bebe8bcb0dd8914fd9ce070d23ca5553923f9d775", + "id": "5016cce5130bdff278ac554c89615fce32aad318bb8917784b51fe40bbab4e63", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 26922263723607, + "fee": 0, + "recipientId": "APjnWFvHhfjudvjXHQ7t3d3JuW1efhiWkM", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203bdb6af67dbcc1a8a1fc4a71d9e7fd6ca66ac92d0321eafeb3e7e44aae2d25dc022045598a45acc95423dad43741624c047bd2c08aa878cf3175a789f3ef75e6ec26", + "id": "981e2c0669340b781e6989d2e4ed088e71df124c2c3f90eb97f024fdbea70ef1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 27197785575254, + "fee": 0, + "recipientId": "AZrX4pmxJEzr8WkANjFsofL4ww5UeqbVE5", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201b3c396a9b310ecc51420e3ba5d9a711269202abe71353aa9a99c9388b3a282c0220221c52a87c44586507dc1ba810a7aec7eabf07d84ed7185616a3ec891f224fab", + "id": "421acc286ec7cc4bea14a8d3cbe33e77cfdda80ac748e27e4f0dbfc09584bbc0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 27237835405410, + "fee": 0, + "recipientId": "ANgMKTXMWHB3WnU7sBeLqYmUCN8khwc4o4", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fc96ad466ecf9cde5f005a6124f12ea237e66013b782406db1d8974926be0946022063f106ce7ebeba7a8c56393748460eee5ac888385a2467cd495d0ac7e6dae9d7", + "id": "594abec1830a739b1cbf625eef2b6301b5595ca5f229f353545c920c9b74d2e3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 28691934514542, + "fee": 0, + "recipientId": "AM78rDegT1jy4U7CEsWErtPSuJCdF6fJVD", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3043021f33602385c5f0c9d5a374ab0a835c0ebecf104951dd15dc812cc94738ed6ff702202c366784aa6cec2524f816bb41b0eb397cb0702ac7e069a7a8938694093b868b", + "id": "c05ad581c646d9d8975a65e54a7deaf2c255fa6622af349bfa16a9dd753e418c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 29252093379711, + "fee": 0, + "recipientId": "AUL2WbCnaYBkSRfz3Ak11KA3Vn6b6eyM7B", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402203e1c6a962f0d9dac66fe40b694ddf60d1ae12a0e8d7d4d12d71615dc08c885380220597d2eb1eb70e8afac03f9f02a0fed3532d15958d431d41e852adf147015f43b", + "id": "909a1c0f7371c0e7bd5b668e80ee67c980c7c06ac95c9a8561e2d245439eb29f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 29403011432706, + "fee": 0, + "recipientId": "AW3MgXojRTWgrx4PzBmk5pjn5nyhY1aKH5", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402206afb959420376fd8e172ff9535ad4c73423eb6528b90d888ef4698437e5560e002206d00854f5d1964357562ed79f680e7d5cfe887ee413073645842cbb248f5c34e", + "id": "69fd70220c9ad3cef6201a5043bc55f944cabbdf705808c6331a947ffb7933e8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 29495120724982, + "fee": 0, + "recipientId": "ASaaHvXuvS52QJuvp3nkm3EC4pEAze47a3", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c3838c356872fd692642ca595c4c53678396cec839de9841a74a4799cd37c41c0220168441e0f980c92516b41c8ea7e337e384ef95ad130f2a62d297bafc5ae6f710", + "id": "87e6c248637dc0774a78b108505ad19ece71c9248cf5151ef517561135c5467a", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 29617494546387, + "fee": 0, + "recipientId": "Aabe2A3WdrsrhBp8uTjqxUEQVyB7G1tica", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022011583f87dc647bc5887425c585d04c395f17c6bda80dd0fb2b310acde7294e1102205e64a69a81cd848f5743ec144bb932ebf18136f952b240f5f579e9524ea1c61d", + "id": "ca4e72b41eb5b6bf5210d47eedcef40cc9ce15168fbeea443dc8c179ffa6e711", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 30052189818242, + "fee": 0, + "recipientId": "ANaT8P38GwSHV9mcCk7cEZZAieB3Mp8jxE", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100dfe6ce17738cd9e3565cc2ce92f2b1171104573deec8f7c35ebcf39b906afa5b02206310b1b28588bdee1c4c9cccad579606a0150a73fc2500a78b7f126c6a30a736", + "id": "1aee700c3737c07c9a6a8dbb6ad404ab7dc313af7e1e0c63e07cbbc1b3642845", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 31009000000000, + "fee": 0, + "recipientId": "ATgAA1gP4awvYXk4T3FrHRgpNsVtaBU5UY", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f44445e667716c93963815e8872bb798f050c69dd18cf11260cca530866aaf6e0220741085d44bcc255dbfc4a8f34ba652ef20798f50ea350929196dcdcdf79685ca", + "id": "2f5f4923cb78e7d9aaa2b5028c16f3ced1448fdb6749b82711b46d469865bb1d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 31239229496679, + "fee": 0, + "recipientId": "AUcXquR6CPooj4FPVQomhCjfhJik6KTzYp", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e20a35c940073e07cdc048f9cab3ce5417ee3886790f8d8211b72d0d2c68ae97022018201c4a586e505c12d7eda3a6a8976fa4009bc8f10e11debcbd6df8c92bc59a", + "id": "11d6023327daa0bdecfc7f0db4b7f476270cce07d1442af2d81282004841f302", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 31413424826151, + "fee": 0, + "recipientId": "AdYVznebAKBjBGhNuKeKA4zzXLFJBxX6Z4", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100ca7de35722d5a049d61c01a8bcbd7df1a990534e589e5890d07cf7ae6181c0da02206ce232bf4f5d2e144e0aae9001e0f64f38b462720be5417ccd4e3192efcf54dd", + "id": "db369c7c18acfacd9d702e63c7a77e8bcb07d4e104ad8fa39ffa37489e2f1b29", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 31703556507222, + "fee": 0, + "recipientId": "AFumy9qrTPRdfjMq3Q71CyJGADVURsQUyS", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220082801ddb5cee6641ae199fc46cdab4d8bf945a602b60099ab0a6014a07f1b4302205aae82168430ad6632563426a4b6efa855d7ba81773a50894427dc9f54832580", + "id": "1ec3d57963cfe1528f5032fc045c7516f2e811ae5b5362a5e5e98b887abbdd22", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 32988434694317, + "fee": 0, + "recipientId": "AQpbXQB2G9fyoTsc84PZKtWeTANaXg6USH", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220118c9096756390292e7fadd471894e27610985552c8a69abc091abbce4426527022073bfcdb62d459942d9fedfc00dd3b7f473a2b7a8f3b607caddebe79788732adf", + "id": "f5a02075ee137276ace1af818d4e40826cc57ca42a28e2f4966008114f1ee3e2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 33301358574530, + "fee": 0, + "recipientId": "AGv459sY198H3RyLRwSUNUNVY2sdHBakyF", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100baa3c39d1f99a14adadaabda9abcc74a8eb0fabf4478ec84e44c4c981194ea9f022026b3d6ed87d29120f5338fa371813700f08d989f8473f4e565e10ae7d7f3a5a0", + "id": "f85ed28225d31a5e12d1390e288d870d3fda8c31004435e7b581fbef143777a6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 34838200000000, + "fee": 0, + "recipientId": "APz3bVED2boFzmM6X8Ri6EptTuwYecymNG", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100bc5e1636cc1a3a20189320632b53d9ca4dd4d6ed236cd79bc39897cb32ce1b4e022012c647f2c41f7f7be18989d37b837a1c597b9e8d9db34830e8c96aedf793c36b", + "id": "f762656f41ede6c6b2248a567e9338fa5fbcffd6e3acfcd166b3d7091dabe45b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 34933049632938, + "fee": 0, + "recipientId": "AGnmhUFTHK9waUB2RvPKcGLBfxRow1Hz9e", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201feb35774ceabcbfc577b257045b93395c3eb0e81d91cf4e0799d0c74fa9db4502203fa395d409e2aad11c3cb7a0db6d2904cda3ec8c850b810b737202a9717d90b1", + "id": "9f9b749ef794c617b2136b392f09d358f27c1c7ae33d917812f777405d9ca61b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 36753764290883, + "fee": 0, + "recipientId": "AXicS7Jbvo9wCN2uVa7RfBLrBS4oPHXvmF", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a9d7ffc30ff5da829ab6a0705fc673c208fb1d90b4f37865fb859fe32771425a02204dd95d698733a1cd9ea1ae28044186dbca88e643f740593c4528e2a225be7656", + "id": "1f308b5f48e5396ca4b83e14ad69a329a486d695ecbd6819be782db4e79ef161", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 36753764290883, + "fee": 0, + "recipientId": "AMKQ7YtVjAHt8mWniZsvj6rqmA5jzu1rnZ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a75993db6caf823dc6d38968f205c3fec9406d2e215791a62cbe9951bad8677202202d0ccd24e0c9757d557720cb40182f5bbbd4f17b756aba16289de6190a2e7205", + "id": "dff7c0fe0b3548e5b68bc7705dcf7a33660bd77cc5d66bc1a5445f1ee5eee757", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 36827565849579, + "fee": 0, + "recipientId": "AdUHt2sqD22q3Jhby5K4nSVhBjPaBDrcN7", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008dfbca2daed7bead47d885fd3f763a75c4b076bfcac2ad209987a2c0a2ab913c022019fdb82528d253b78768f8b8e508da440fe8f2f7a34ad9aba2c37f91df76bd01", + "id": "22b6643f0273b7fba1e4c4095c245ffd0a59f8c75582bbaba951f0f626fb6b67", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 40000000000000, + "fee": 0, + "recipientId": "ALcLekYJLkWKLwEX4TNsQszu8nfQbWSkDt", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202a594df3905ee3f8c8db32a69857b686badcc6784b698f8ad1ffcbdc5cb5d2d0022072a8e72f42fde11f54bdaccd48de55ed2d3046b1f426ddbb560b97658a0bc83b", + "id": "08a515e48fde2ed1141f3b7c6726284d1ae7b5ed1dbef1742ec43bf52d229eee", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 41574092648018, + "fee": 0, + "recipientId": "AGctmMKFHy54o2pzgeh4ESHfqZ9B7zMnzA", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009ed97e274d06d1458aa4d0860329931ba6e3a2886f45ca9f9cdbe46f089d6a85022068a1f3f8edecbd96d580148602ea10709e92655fde424d68fb8d049d8841c418", + "id": "afc119b8eb143c9fffd3bfe31a39d7e42497770bfbad4ae7190b5b7b2001c9aa", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 42101522494901, + "fee": 0, + "recipientId": "ATAu9Q9UEQQua2UvXfQ6aev6eZAqWmSNFp", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022060955d98b915a99a40fab60a89c9813d050550f17ea432f309c62d1e4da4f80602205685972723f6a5223466af3fd20c15afb95938182e7b2a636a32f6ab88cb4628", + "id": "bbb16d3b87ba67e0ad32da5eb342cc9bf60b51825b11d2d435f94afcc4ec42e3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 43098358629104, + "fee": 0, + "recipientId": "AWbC9Wq2LyJki7J84AkTLJkzguF9mo89BF", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100fa22327b9cd6deb3153c39d8f5d76739754798733aa96fedf2283dfb9b1ba055022014e16da33b966e40e27c883b314341391b7f85ee3c1f272dae914533ba540c3a", + "id": "8a87ccc624c279197648fca4c03622ca87b4dbfac293377c260e536e6ca969f5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 44103929088831, + "fee": 0, + "recipientId": "AUJWBJDUgY52u89unPzk5oV9e9xge7P1Kp", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207069312fd56f16680a836c2a45772777be38c18c6f86287f414e786b8f2095d202203f646bbd58f31c2618c31649f1c48bc1f4ee3ec791a1805d788497179564b72e", + "id": "ba49cc0e31cee0207d2f0211262dfcf9787a314f0ce63d3c292f8f20c596a821", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 44104664164117, + "fee": 0, + "recipientId": "AUTMnQD8ANkE1wtMnH3aoPCrYkVntiaRDc", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402200bdcfb494ba5f808db740b6535ae3adf6719d3442d618e027314833aaa3fd7ef02200cd5039225a23be87af57866b6de9c0e005a643fdbb9d94e2bf0f1bc9eb4227e", + "id": "954643f48700f6776cecc0c8d28edd052b6ada807c4ed80d4020db027f8302a1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 46581295003558, + "fee": 0, + "recipientId": "AM6bDiAfJMXdivdUiGaDy984KA97ZEcKWq", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f8bdac69ac19d78a7db5398b5bc643399689262446788af4805d85766e705480022066cc9169d1a7f9f53351ee695e2016ca5384d8f7069feebd59e8fb4a9788559d", + "id": "545bd5d745ede704e8c2a8d69a2eb6925610f37e7fa79ed9483266d860c7f512", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 47047758593474, + "fee": 0, + "recipientId": "AWvqcwdrJyDEfsbveh5F7Nh6F1KWD3KAHS", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d41cbcf3488a0246488bf2cf73bf1e4e797260d1a5250ed8f04957b31586b0fb022036ded1aad7477562792bb697ed03f86d158ecc8dc325f37ba3efbfc2fa7c1fa2", + "id": "45838af24957952037e376f81200350a6d795b8435613a4845adbec9dece4d66", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 47594373941014, + "fee": 0, + "recipientId": "AJUkMpMFt8Zny1v1rENN9ZPZYitfePBvyz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100c5d4aa1d91f3a0b7468a31097fc9613e9c3830e1b3c6dc3926217442fb605f6f02207efbbe01ac68387e6fe0719ee635b4574d7040595d086d7030f903070f7c3247", + "id": "bb58a2aa2a8048b937156f3618663c1015f1b9ae7527ba8a0bc351c6f0bda349", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 51199117149060, + "fee": 0, + "recipientId": "AZaAZmaQgY3JaUTK72WUJEp9ZEgQgW1r6z", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220060cdc83a40e3ec69b3359c304a0ac46d863617599e2de03fc9a022efdec329f022018cbb65aea9d099cf6cc372a6599525b1aaf8a9cba53edbc95235764d265b3c5", + "id": "97d3f0573caf2552f8f5a696bbdb7f95782b98e5057f26ff7eec8e152513a3d4", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 52274142846490, + "fee": 0, + "recipientId": "AMRYJaup1hTjCsV79HCTn4ySvhAzb8xSo7", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022070140fe92e3dcf59f0ae1a87bbb061cc4048a8489d47cc37a3f3ef489548dc2302206163dd3630b960269613c98ca886637f32efc495f6c4e593cdb8c91dbe696c44", + "id": "223bf57b085d5fb463d106ae666648acfa042952e7417e4d22f51a100e3bbdd1", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 56564297142251, + "fee": 0, + "recipientId": "ALy8rPTjEELHQbkkDfsQTWT1M4s1Q4NFDX", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b5f571f366492003d3c17ddbcdafddee27389907a33cf348f7ef0b4d6f4cdffb02207300a2d680dd5ff2fe2fc70d71e76c875ea15572be63fbd583a4de383f99c6da", + "id": "5333df7856532e4d8a13adf69376b48c986a46f773a3e8677b5722baa45bbda3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 56945445022471, + "fee": 0, + "recipientId": "AVRGa6s7qAzChqfXrbJEhExzrTo1uscsf1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d41baf4236b93dac1d8604596cbdabedd8081b8666d239f2a193b69e56acfe490220046d22d267e480523194aeb5890d54b5e161718ad754321aebe61a5a9a6a4947", + "id": "f466357fc462681688413511091b23148fa0271b2045dbd8b28aa591db29f850", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 58952449862348, + "fee": 0, + "recipientId": "AWeSiyLTbvHyfqmUNNcRZABWZkcd36oz7x", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100d8f5f18629c666ef1aad569544d581c9c6fe2beaa751658389ef260559f946ff02202da47ce0d71725b3004c43de69c0fe0a5fc94dd7296d16b5f64c2fb9ce1a515a", + "id": "edacc4e6c26a064c04742503524ac91012a87e77f6bf7186b4f591f3221b7b58", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 60406501374583, + "fee": 0, + "recipientId": "ARviCJv7BdnDHCxPgFa2uqRLXNNtBqc8Jv", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b49e507c020746c9f70dcd26f52d071e05bfe9dbd303d528812a700883f7a0c4022009f6cbfd51b20e464451a6ebb5184c0abcfa758ca304bc88d031c8075c7d6902", + "id": "daa89776995d4fa94c6c64cd06b1c2d1036cfc9082151f9d3a70adf948c93939", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 61218300000000, + "fee": 0, + "recipientId": "ANLeC5wGgtqiDQcX5pmHiYayqMyWy3AYCQ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022049a07caf745eafae488a242e5066c8d2220b99ec3127818ff9ccb2faf682fee6022072aab5d565ac05759ebdf6f896a53c584961a6c0a362a321cd0efb2e78cfa9e8", + "id": "789e6d917e48fa9a4538ce5948a1c4013c189d080b94275eb975299d3d22177c", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 61966258534201, + "fee": 0, + "recipientId": "ASaaFCmPG3yPUwngEFoPA12KnQYqjgVKnv", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220449a94f1a85146353328281b937a9ce91b5644235ece1e2046a28d1199fc7f7d02200dd68146162a869688f44fddddb990bd2edb1c4194aa8c1edccd72cb1dfb7e03", + "id": "e09409c50d3ab8e86cec1216a5a8f971a8830c4bf6f847fa59c7eeff606ee9f5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 63613272588492, + "fee": 0, + "recipientId": "AYpQxRNbaiEL6FT7YUNmjNjRvpUfvRh6xA", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100953475d0a8a1f5b26eeea7d4697faf1eba8f4a4e465b387f6c3550407c2adbef022047a7f4af1bbad90c076617319eed901196e46a692131fb1c8861c3ba2df2a23c", + "id": "311931514d05d2af41ba127a24dbc950f7476f78d9184469947d4b3b59561c4f", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 66966172832127, + "fee": 0, + "recipientId": "ATVwQWf1mpyRa7L4BAkSUxz9osCfBsBopT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f571ced76143801d0760e47fdb4583bdd45d1dc46d03fe9195be5cbe0a9f44a402200f6a4cd36111e9b5dd06f966e3ebad05294ab03b5be9f6a231665ed4ae53a275", + "id": "28a7145ea1920ab8de9b6037f050627ffb2e37c9f9f1d16be8db7110f401fbd3", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 67622306078799, + "fee": 0, + "recipientId": "AKzAriWhTPPRXueXuSttRiBLkjP7i5wKpQ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100969e9376ec702a41b6da148d02603e8e1b4c1bfbf52e060aff80a89cab4eb3c9022076972f9de9cc4e883c63ab263cc76df952b0bc55dec80b958fa8069b94046f12", + "id": "7a6649786a864355ed73e0f194caab15593a11f93400b13ce6d0b7030057d903", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 80563884771309, + "fee": 0, + "recipientId": "AMFQ8md4BymLJ2ecw436fhyUyjyRM7ygzz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220188dd6b6c7e1c09b420ea73ecb17db20d85848342cf45c65192c77f5390fded502205eb3a4304dd2ee62ec1fa9e848dcf2d695ed92162e13b52271e3430ebde7eeb3", + "id": "fdeba3a56077063853cfb940d036d3ba75e03b6fa68d45de52bf58d9165c4b96", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 81926947255471, + "fee": 0, + "recipientId": "AMMDbSvuBNCi1oAXvqgBguAeTehWRTjBrc", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022043e6c8beefe6b5ab949adabed4830fd87d4639a6afd7fe8e1c3de3087f7f47b302202cce568aacb5bc2a416a20b6f940020b2e9c1f0404264230bf1b9c0086735ea7", + "id": "1630a5b12b69dc1317bce4ba97a2207c6bb4ff8c9e3b5af88d02f4b42829d51d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 97831169789473, + "fee": 0, + "recipientId": "Ab6JpVxrytQhj4QpBJ3LGsLvEhVmgCKk6Q", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202b44c2bf60f8af0927f9a5c62fba3ceabb58e5944dedfbd37cef6368b219225502201c1074fb7303b8a88479009e3a36dda95d6c8d0bc60770bd7f12beafcf680c0d", + "id": "0c8a56b4a0aa03b2f49dce2fd0e7f367096065a51128950188b553b8a750d4c6", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 98443286091931, + "fee": 0, + "recipientId": "AMQEjpMh7o1sJT65Pdm1Wt829evGsTWCJ2", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304502210082a8b45a0e351baaefcdddee3583b1b5ed7af81fdc9e2aa7243696388a5d6b4302205bd1469c96a3494a9b0bc8cc4513cb3ca57b8cf3b3250c028346d42666daa02e", + "id": "564f7c69a9cacf987aaee9ecb5bb726d1ae26a26111f0f8364611984d18b300d", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 100568151043750, + "fee": 0, + "recipientId": "AZdsyiib53nWP1wG5wara6XfvmmqqBWxWR", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100da0594484575e66f1eb34211a7d3249c15d0eb422be3e1b46ee364c4a377befc022041cd9cd4237cc8a1a7e9359adfe182da7edb24a69368ae1deb7e2fad26aa0312", + "id": "16a95bcd5ca6388de776cc01666f616f863f9dced646badfe97b53a266985bbd", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 110555322986976, + "fee": 0, + "recipientId": "APaRmUnSummHSAyHnYqd1BGvPqgYReEuWG", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100874c685c11233280806221994ce6ac3be8ca6f2dd88421991a1c9810614e9bb5022071ededd800067a5a3e6828ab6cec496b153c9331e5f08a417c09e583b05219d7", + "id": "a387aebbc8fefd8f0963f2ffbac837f5bed99137b19b19c356949bdf12c0d0cb", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 113717099151927, + "fee": 0, + "recipientId": "ALC5AHjaUUSaecu9R4wADbKdqzqf9U4e19", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100b5b9bf26d7020ca50abd010624a7443e7e4d0c5d17c50aaff12c2a357380a212022037b7e9e80dd9e5a092d99aaae3fe0722ff6e085b8ed42e4d47030e9497e6093a", + "id": "912d5b497042a6da16f4dc3fb0b7711f19aeadd1ebcb5aea32e2e49d6b2bcde0", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 115371683274712, + "fee": 0, + "recipientId": "AVNXBEcnwKmirrG3kcZSzHa6JvRkiCKqXc", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220401302e2773dfc0ef1a6b4b013d98fcbaca1838e9c688013989ad990a7eb51dc0220268eb491d53660b33ace47049d96e4c97dde689621044002f703425e17a3cc3e", + "id": "1dab66009d3db2e422824d6af3e727ff146c2b3bfb1daeef583742a920d51908", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 120262700000000, + "fee": 0, + "recipientId": "AHHpmXD7F8j1r5bftPMkp35ct9qGYiupwj", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100edfc8dbb54abcc1096194776c222e08fae1e125851b580f510ba5b6c6ea39f38022032b48c581a123b298838dba4a22b71ddfc51c0514f260fb07dcb2374bbfc8e92", + "id": "5ffd7c36deaef4295257fec15f27e451864538aeeae9b21ded6d4e579f19d7c8", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 123626090911753, + "fee": 0, + "recipientId": "AczFP54nMoafRABK4c7idxHpAC4RwmQsDE", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402207a3f7c3ecb0295f08a85e12af23156e0765ad1540047f68cd89be139307b5bb3022072be91d55a080d6e5fae0a327225dac4c63505b292dda6958a1207f9adadc8c4", + "id": "03b08987233a71d17b296c057e03821022e9b504b47471670ddad11080e1f4b2", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 125719320015809, + "fee": 0, + "recipientId": "AUq3S7bXMHmz9zBbz8YLN6LrSrshvxXTU5", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022033d2d418dae0c1c1ef89b1866258410008eb39a409c98f6ec3a73918f449ead102200ca603311c12cb4a5f050e0872e05a0e8f2953827b168b85211b179600154585", + "id": "82b2c63e0139fa52979e008e6a3d3086efc4aaf5e1799c57a29bdaaae9a50189", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 126273901505716, + "fee": 0, + "recipientId": "AdCXBbcpNrnMDHMar7Ebjxu959uwN2jt2y", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022078cb591e525902157b5736e798461266a2c7e32d7aa4d06d07f80d64244e0a2602202981d622da3539fd16efc0aa0ed8503ce2470ce8cc3235cc325904b9246dfb1d", + "id": "367b31d00256d8608bbe3b62f350bbbac10d896a3a3cc084e203493abf6f74b4", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 126299500000000, + "fee": 0, + "recipientId": "AeYkC4MJ24EF7yVkb8NfSryBw9xrTvSJ5o", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100f3fc2ad6305967410752b664c2d8bca041d552c013fa576e10889a69a6c4fce5022067ecc8de665c05a1594067f873e067db5e1884486d4815bd1cb3959c282cf0a0", + "id": "af6c2725034e35ca7dcf0b20a9161af2ece9d9e30d1d8f934661c2e121844832", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 126837200000000, + "fee": 0, + "recipientId": "AXx966jfTHUz4nSjZsFEKkpsgNoByhuMJo", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30440220025e2076ba6db9412d886925b4ccf810ff5aa45711ba9c9f049061f675560937022042ed7606e3f46bc5fb5b2ef2b36e894666c78804a1d95ba7916d6a41f92e36cf", + "id": "e274c6833dc8021404af6782020539329acda8f274ac2be31535eef95cd70668", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 127928194702051, + "fee": 0, + "recipientId": "ARwU8mRM9aM4KjwFLpNH8eHntj157LNAW8", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022050f8011fa9011b5b4501bcc1d4154864b6c5125e9a00f468a194e59edd32831c02200c9f77d38533ceaa8bbda2bbf9ddc73a7d6654d3d3a338a3e04a80f67fe16a59", + "id": "2debd1afcd9cbc2e3c57dc27258cb49d6ef21b10d36648efacc0053acf7cba19", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 128450700000000, + "fee": 0, + "recipientId": "AGto2VECRE2tGFr8X9pfhqHNgF2bdW5mgR", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100aecdaf102f6d5a4b18ddeb17c8d5c00c18cfe0ec6382df8c972937a17e9271e0022074d6bf200487ee5c03800c2cc28e571bea6129c95ebffc2a1a8435fe6bb351d0", + "id": "7477beb697266fa054ab120b1381e293d8533d1a56eec29731525b857d05e8dd", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 136497083929386, + "fee": 0, + "recipientId": "Ac15ysDrQ3fvMYL8S2u52VSwXZPKZQs8MY", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402201e2a494e971932480c8286c2c12748daf90afd3234969cd720ac9346da94fff802203fdeef1aa6daffc70709e5c86bf53fec3169651671060b8e495e1c0c40c725d2", + "id": "811f46c52bc4e94cebb2c8a4053c13c3ac3f7df24134cc027a37f7614e935a7b", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 140099329287361, + "fee": 0, + "recipientId": "AZB965rP7y3PUs8RXqpkRy5Uu9dbQgu8mM", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221008fdc7606464939463c4c48ef06663b63e447db9b560fd323efe695b59832e792022048631bfebc37ff98d5d5089f607869eb05b86119830da14817cd31125a4910e8", + "id": "8bb29e211493fd3f3282498d749b55d5824e9ed9d5813a834258b002204a2cb7", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 150034082630911, + "fee": 0, + "recipientId": "AQK3Zu6VW2QMh6a3ckNzNsYduTV1MmDkyJ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "304402202d42c892d4cd76cb582573977a7b2a294a945754dbd3de4411fe3a3ed814f0d402207c49588af322b49914a933cda46e2ade762f5bb9b9383cb690bded2f0a734d90", + "id": "7e1e33f30bf45a2b2b7be555693894171481a7cbdc48397575e6a99d98382138", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 151578069939920, + "fee": 0, + "recipientId": "ATUe1KJzRsHUW6rA8UnNNNo4yVEF6TqyEv", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100e97f8bccc9e3f5e3c3a5b32987c64caf4b60faf4a282784ab3b1ade1579c3b0c02202041fb2375eb061fc3ddb64cf94edc614a690d6fa9e22e9964aab80a66eb5b34", + "id": "be993fc90ee11f5b9bcbeec1a272e94c1894b65804011f76d0d3227c71ba19e5", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 191573850243351, + "fee": 0, + "recipientId": "Abee76TtVambNDBmTTyoCYosWQ13MC9XEn", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100bca5294ba5fd28e35afb067b328aa2469656158f4c8580d98bfea76ef925761102202ca7d152501f2999169ee65cac56b25f41d9b140d11708d236f9c4be972b0dcd", + "id": "2bec691439fdb6fd9a324f26d44e2ad64bd9e2ffd566d220e01c4aa12028fa91", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 196019568105246, + "fee": 0, + "recipientId": "AX1ZCuzNnVHfPvKikwsnsNRUxXfKq5g9dv", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3044022011856a7a6cf61478d183e18a4a7404241dc561629d7db7ac70d1ff385e85d724022003404898de3709cac4bd5a6aa718c7ada3c9d08219c60f034a45da8135ef4a51", + "id": "57b80107cf40b39135241aa92e7e254da815763735f0ac5a9919dd8485865d80", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 225493764614631, + "fee": 0, + "recipientId": "AbYwZ1DAUDLgJwusR9bCZoTfuUTwNq1C3c", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100bad48978061d554290cd1afd07851e3101aee65f3b7f9f677e85a28d6590df5f02204d7a721a90dcec6644bff0aecd2f1d5b506c334bad8810b1b2d123b6978d57aa", + "id": "5ffc47d5a0826f031d51f0502e45ddb9d7b8c4f4bf9b2d4bd7a60c4ab027b541", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1034744897737528, + "fee": 0, + "recipientId": "AaFgAghGAmNWndDnaxkbcYFE7fxbxZn6dJ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100a4489ad919a05f73c3be4de717a3b23115812c146caa1f33301485e1d9521dbd0220487441651432d5b34bbe7f383ee3a1bdf84dd22b82982d9566020a6033783685", + "id": "99a3fa3f91f257fd3e3ed284a9bbcc5eb007ca7e004372a5912bc3850d5ec9f7", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 1256766795179826, + "fee": 0, + "recipientId": "AUhVLSiqTnnzqhxp5RKzheuRyvh58TSCUR", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "30450221009e21a29b8428afdd7f140379d839d5ee75191c3e5add0582f58b9a3b2b3d69e30220749a0e7a3a8c63e877f1bdb0ec12987db8b138bb1746efe0b18d9ee817276cfc", + "id": "ac7ce9c3dcbee526a9f15af016fc15b6dabed5f8a61997c4de15fcc987926234", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 0, + "amount": 3141438227793004, + "fee": 0, + "recipientId": "AN7BURQn5oqBRBADeWhmmUMJGQTy5Seey3", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "0235d486fea0193cbe77e955ab175b8f6eb9eaf784de689beffbd649989f5d6be3", + "signature": "3045022100df12738ec2164ce2d2ba980ab8499dae066149a1019f37ae5b17f28e9cc2aafb02202a0db97f9e012f2a8ed819d2cb02e5d9e63fda01754d6f42308c3cab4bf92e1a", + "id": "5222124556517be676fa67fccb07fd581ec2928140a72afdd65259dc3e5db921", + "senderId": "AewxfHQobSc49a4radHp74JZCGP8LRe4xA" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "033c9e5a710bff3131b406a8023a60e6b76a2ccf937cd85b56add7c4a33ae3090f", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_26", + "publicKey": "033c9e5a710bff3131b406a8023a60e6b76a2ccf937cd85b56add7c4a33ae3090f" + } + }, + "signature": "304402205532bc3fe7be805b4c8a0df2995158e634c7146c2467d05d75f754782b87bbbf02207164df69b13c9c3c46bb3c7d027e7ba81eeaf726f25e08d268c1507da4581b73", + "id": "8cc98e02422afa8a246faa66c1672b62996be356735b00614d8739ea3a5f73b6", + "senderId": "AQaKx7UU8857b4tJij1jb7aURUzd3GDyKt" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "031de61bd525abc902396bc66daf513eb20715180beb50be3a1c56a36dc73476a8", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_50", + "publicKey": "031de61bd525abc902396bc66daf513eb20715180beb50be3a1c56a36dc73476a8" + } + }, + "signature": "30440220125d7a0f64c0328590d67dd27eb5d8f209bdcce03d730c7469ab25a8943c8b920220027305ec4ac8d46b0c2e711274159ab2fffec7f5a5994aea775cd48260db93b4", + "id": "bf2641e6ffce5848282027221c7f43eedbd0b72a7ee2a56cee1472c5f69f194c", + "senderId": "AU9BgcsCBDCkzPyY9EZXqiwukYq4Kor4oX" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02614722c83a05de882d887ad51bc5c687e747d6d19b58f5731d38223c58bb6ca0", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_48", + "publicKey": "02614722c83a05de882d887ad51bc5c687e747d6d19b58f5731d38223c58bb6ca0" + } + }, + "signature": "3044022078d5f10573deff4cf16ee4b253c6b985b8a16e5f7f4840493e2834809e26ce6f022020d6502389f7512ea3b8f9fa9ac296c153aabce8f9066cd42d854b94069f6f2d", + "id": "3625b2591f15394ea0dc6b26a113284b1b56de0cf3a21c3a1dd92f373f796982", + "senderId": "AJqbav8MPPAe3zdzo1f471gaciQbx1SRe3" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "029191a8ae0fe0561e3ddce562554e8ba5ba36cf9ecb389290a1a74acdc53ca89e", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_47", + "publicKey": "029191a8ae0fe0561e3ddce562554e8ba5ba36cf9ecb389290a1a74acdc53ca89e" + } + }, + "signature": "3045022100abd4ff196ac1fb56fdcc0f0b71a49ceca5da07b3631570e22626fb43a415a9e2022042d32e0fc05c6e2467b9749ad1f6bf5e1fb9cc8eb5c21a40baa1381cf58fa327", + "id": "05c1fd17a20d62c2740782097261b960f9ad353f68b94d4a13dcab05d08f9dd1", + "senderId": "AXArbuCVSiRuYBkzCAajboxCfNiw8AyQX1" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0204f8aca74a87f69432298b13555cf50aa0709e1a942aa3efb447620eb78bbcbe", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_46", + "publicKey": "0204f8aca74a87f69432298b13555cf50aa0709e1a942aa3efb447620eb78bbcbe" + } + }, + "signature": "3045022100d15eb20b58fb9a6e7659706d20c3deb26dc176cdaab02fff557dc5a8d65982a3022064686cae9101510295993e1d3663dffc88741bf1e2781021e28a7b2aa71ba80b", + "id": "6debf628e330726bee0f64d9fe7c56fe4024941b4394ad5c7cb08fa9a3abc0f5", + "senderId": "AbrgipEvLp1ZHNJ1GcWWAsCLNgSgDG6Lxh" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02c12428bb56ceb96e9c2a558e045df6b7b2c551fdb6a132ac6c3956d10f479f52", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_45", + "publicKey": "02c12428bb56ceb96e9c2a558e045df6b7b2c551fdb6a132ac6c3956d10f479f52" + } + }, + "signature": "30450221008c43c6f251517d972386adb42d69510ca59d882a89d7fffa55484ad7989a3bbd02200925d009f1183934e4be66ad48ce7149c990d0d87afe629c14551ed34e54ee1d", + "id": "557d5fb9b8b948ba2a6fd3d4dceb476e97e61faefde8eb11f4372028346c5aca", + "senderId": "AbyacFxcWS1JsokdRCx8bFsWP8f48XftmS" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03f11ddeca3845ea59c82120a7eca68558c99e4e7d373142ea0554408c58ca82be", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_44", + "publicKey": "03f11ddeca3845ea59c82120a7eca68558c99e4e7d373142ea0554408c58ca82be" + } + }, + "signature": "3045022100f04fdee2cc09b029d1bedea130174f21e24e673438655e71bd61998732debb040220439b36ecd46cf6ccc9c8a8fc44085733bb82427a760ab87bfee1166c7623813a", + "id": "6d8c04b24c24c9680b4e496b686c2a37cc05fcd9e6f2090cc945712199b2b8ae", + "senderId": "AYLTbdiYWHvPvJo5Lh42MEVS4Fnepg5vgc" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02c134247a5d54cd30a5e3080daa99c74f54e21ad0cffa60e7efdecece862898c9", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_43", + "publicKey": "02c134247a5d54cd30a5e3080daa99c74f54e21ad0cffa60e7efdecece862898c9" + } + }, + "signature": "304402201820565556e3039944c8c7240c567c5d8f96a8a34a05dc1d68577883a8025e94022011f55c1511627de25b4cd7410efea22ef2df50b3c1f4ed55a8ce8d4f3da91862", + "id": "e606ac6acbfd96fc4054131061a69e3d3f58e044636a6646227775c4e646a126", + "senderId": "AVi8PFHr5jFBFGWSissPFDFXUPABuBgxSa" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03afac7e796d781e17600945010be34cb6760fa919be67baec2cfb691cf4ce5f33", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_42", + "publicKey": "03afac7e796d781e17600945010be34cb6760fa919be67baec2cfb691cf4ce5f33" + } + }, + "signature": "3045022100bd7e5550aecbd212d9fc13842c7ef586b146ce6f289199107af979eac6b61fe402204607eb502c9c8f2363e468e22afccd754e042e605199c92a93a0c29a19ec628a", + "id": "2cd3411cf5a52c717afca1f42cf97627fe81c0869f39ab494df0ce6e99f7e485", + "senderId": "APXkAdLbLiLJDC9Ls68Y9a5ws3PcgmUDAo" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "032879c56cfb96539f6a8c03a91b4a987e35973a79e62f9da438831b353066a84b", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_41", + "publicKey": "032879c56cfb96539f6a8c03a91b4a987e35973a79e62f9da438831b353066a84b" + } + }, + "signature": "3044022060dc174d40828324a18074db079ea300d382ed5c2f27a7ff782686e7e78002fb022072e809275cc872b3c4b430e3094268e0260aaf67ced17387ee17a207a9e2032e", + "id": "4b16c34911fac46716cf8ed383401f70657201763b54ecaa5904bc09fddc774d", + "senderId": "Ad8UiXMZPecuNGwCXZTmF8Mysn1TchVVTf" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03bc7be5c8b1221beb63f6ed23d4b5e2748b64983087986c4953579fa7d9022a71", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_40", + "publicKey": "03bc7be5c8b1221beb63f6ed23d4b5e2748b64983087986c4953579fa7d9022a71" + } + }, + "signature": "3045022100c8901dbad46f6fd0ae9db39c7be5b002bc871906a80181ae45de6fa67eb4068a022068af82d46fd008c8efe5c3fe265313e01aca9262b1160a5c095c6b31d97f1579", + "id": "2d808f28b223999c1d652c01b2f22ceeca15d1abf2acb42c04570358ed176913", + "senderId": "ANUfH6C3Jjp46pDUxWgeV6WUbWCagaVxM1" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03c5282b639d0e8f94cfac6c0ed242d1634d8a2c93cbd76c6ed2856a9f19cf6a13", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_39", + "publicKey": "03c5282b639d0e8f94cfac6c0ed242d1634d8a2c93cbd76c6ed2856a9f19cf6a13" + } + }, + "signature": "3044022051a8aa7906358589161956d1c182ef9ee5c77a144c2d9965eeff043ddc3b7a6b0220797a2475b5dcd8f0ef7a24a0fbe3d0185839e33f313b93b566b82be168d4ca33", + "id": "3f21a6f499292b9bf0c2970cac7d78953a977f7004d29446698c7a29da656fda", + "senderId": "Actv8ebcwNsbfx8MM5k2AeJidJuLL7PotT" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "036c474d6b22e6d7c2cf054721ca73d0e2a904135b49bbf9dcc7ed7ce9718984ed", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_38", + "publicKey": "036c474d6b22e6d7c2cf054721ca73d0e2a904135b49bbf9dcc7ed7ce9718984ed" + } + }, + "signature": "3045022100d3ab1ee59bd1a45bf936867661f9fa9b22c161506bcd61ad17ac871ba4a17e130220114d37a98120cd1f2465c9700089101db7748ab0562561d4e01ec98c0e96750f", + "id": "337968b8f3e7ddb26ff3e6740df0b12c7be6bc427d9d570bd77a9312baafc80c", + "senderId": "AR5z28tRUnvaBWC14KSBpvNJDgsVCNtagq" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "028bc0f094738f7699ab4432d13e3c18e09a462dca06960a1fd0eee82482f50be6", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_37", + "publicKey": "028bc0f094738f7699ab4432d13e3c18e09a462dca06960a1fd0eee82482f50be6" + } + }, + "signature": "304402200cd7121995da2f8fb24ef2aab15b8da97b050ff9aa600363305f2c0a0c8ca72602200099ab565497c84319dd91a34001b16a92211248652ee109fd28eb90112bf022", + "id": "061e51e451667ae7ea59e0d1cc66fe47700d6bed1dfa671efc028a2b580b71a3", + "senderId": "AbkDPAUDsfQJgvHn5g8AisDm9XqLAtFFai" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "038467e1dd4d138f007f70cb09afdd8439ea744b282cbba2d76fee8463dfd17e2b", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_36", + "publicKey": "038467e1dd4d138f007f70cb09afdd8439ea744b282cbba2d76fee8463dfd17e2b" + } + }, + "signature": "304402206772c6c4e2f58c1401570fb76ab87bf63865fcf32c5f9a5a3f88f4360f44e346022075710eb73a4303ecf5eb899019ee59c9c5ad206b6da902adf90f3df02f108512", + "id": "ee5347ef87ceaf28aefd8374f686725b8ffbbe55042dba0c59c625e4c822fbf5", + "senderId": "AbAeJ4YJU5rxuNtXpDn3E4W5E8UNHyc26a" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "023f425c88cfa289c28e5fefe120033c9beff72487dbc4722e900d6da59943b8d0", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_35", + "publicKey": "023f425c88cfa289c28e5fefe120033c9beff72487dbc4722e900d6da59943b8d0" + } + }, + "signature": "3045022100c185d867d976dff795ccba4654199f1b075bfd3441e045a2f6ac64c4fd0bb6d702202323d84585da2268276d6cce663e842ea5f8617e5e12cf4a20ed7436a1ff7f04", + "id": "592ee85d2922ef565fb02d649cdb2104caf06fb8747ba2425057f79518132b1c", + "senderId": "AP8agRcU4WmsYhC72pBqyfLwaDU6NYKUL6" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02d2a0fda621ac213ca51dfa8efe1772eab8659d8b8c7023a35dce48f2c88316ed", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_34", + "publicKey": "02d2a0fda621ac213ca51dfa8efe1772eab8659d8b8c7023a35dce48f2c88316ed" + } + }, + "signature": "3045022100da6c5c7945eb7dae41e7ed133a58e06e660fb8d012e9ba93df38b8b86a3aa7ca022007514624a32a5fd6f294bfd8d6fce6e8c75b20b7fcb8d3f8b82725c83fe43db6", + "id": "686baa6cda61403ce346c293a8f27e0dc3899eb4629d4b3bbbb9f02b41ea36bf", + "senderId": "AHmBqWJgxZfaC2azkyASdrbCxF6csE7Qxx" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "026ffd3c35c7ef08e3dcdde741994bfdf9cf6af75cdf9e6f4ef8c251b5eb321fd1", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_33", + "publicKey": "026ffd3c35c7ef08e3dcdde741994bfdf9cf6af75cdf9e6f4ef8c251b5eb321fd1" + } + }, + "signature": "30440220192c5a3433384ea1ec3f81473f18962a179fcdd067359accac33e8ee4e571a780220549fb42c1a5d40daca2fc97aa8e0379e041c28fa524505c0e43760f1022a1369", + "id": "bf1644830edb59dea6ea1f3fa107ce84546d14904715b84bf2d5e9648ad426d1", + "senderId": "AeLV4NUMsPJW1nvHquBWPFVKCWirs1pshf" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0295f1d78f3adae92f0c2d061367e0d06a3fcc9a838a725ccfe660b9c2024253fb", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_32", + "publicKey": "0295f1d78f3adae92f0c2d061367e0d06a3fcc9a838a725ccfe660b9c2024253fb" + } + }, + "signature": "304402207720c103e2c3000d867ce3073f9c5375d9f3cbc69dc6affd08d72cdf0322dd44022040ef700ba6c235af8b2e0b71b3b8a825a18f276a192ffdabc01118e2786eb567", + "id": "aa03f6eff50359838142b70634991e93d48480369f087d73cecd0b93847233d9", + "senderId": "Ad6y8ae35QWkrtiLBpiXRR5Cj2KK2u3EGX" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02ac0a9348306d3dea50bde6b38791b2716f698044c207bf005788e13f35b46693", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_31", + "publicKey": "02ac0a9348306d3dea50bde6b38791b2716f698044c207bf005788e13f35b46693" + } + }, + "signature": "3044022070bf433e253fa69a33abf85559d804d1d0e055199c89abef5dba34e5cccf1952022023fd278d32b75f0465c777c39b0a616a4dd0a957b08e9723c1702dbf4d6a1ff7", + "id": "c64e9e47d8c7573dd97d2bb634eb7bcb141c156ab701044319e19ac0a7f55f3c", + "senderId": "AGb36aHfdxvqbMqoDCnm6wVkKKtqkE3zAh" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03c075494ad044ab8c0b2dc7ccd19f649db844a4e558e539d3ac2610c4b90a5139", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_1", + "publicKey": "03c075494ad044ab8c0b2dc7ccd19f649db844a4e558e539d3ac2610c4b90a5139" + } + }, + "signature": "30440220470149adad4cf95460a3e02ce0fd79d933a1612ee9d8711d104efb5c708022c5022077eb9aee6dc62bafcb4217484cb2b892d8ddac8ba2a170390438cf47521a8d3a", + "id": "1a7f292a5f3df9f9a3ec97d7abace3d398adb943ff59da7c0b0eed8f19928ec7", + "senderId": "AeLpRK8rFVtBeyBVqBtdQpWDfLzaiNujKr" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02afe652f7d14a877e73f00cca6c836efda1a05e79c6fbd7f92b600a4cd519f4f3", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_30", + "publicKey": "02afe652f7d14a877e73f00cca6c836efda1a05e79c6fbd7f92b600a4cd519f4f3" + } + }, + "signature": "3045022100a7aa2d57b6598379d04e9143542bf9abc4fb4899aff37ea7a7be0dd07c7317cd02201284a2101aa06dd7fa6e34006b666e4916bd76071032002302dde92610e04dc7", + "id": "e8afeca5ff2aa3ccd8c29f7249d93d465049bc31b3cd3fd6cdc6e09ca92ab921", + "senderId": "AW91q3n1QYTn3caBm7KR35zexcJU7PgMtZ" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "024dd37755804e6dda0ddaff6691aa038c57d8db36d59fd1695a2519835a828072", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_51", + "publicKey": "024dd37755804e6dda0ddaff6691aa038c57d8db36d59fd1695a2519835a828072" + } + }, + "signature": "3045022100f5a4c4d258caffc712c9aa515f3e235b352a8d2250695e7570a14337be64cc410220446bbd588e8aab1f69c900e8472c8bbb61cb6b14aecd0e0d693f74714e8511be", + "id": "e77aac7c7d14794e86175a0b0e985a09dcc485c4e1117aba251dc3e45addf4fd", + "senderId": "AW58iWw1ATvzGHu338WqMYvgUhmvMMsRjF" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02763591456b7d3ed76125e4b9d5b34c3926f5aa166200dd270e45ecb6a6b15d9a", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_28", + "publicKey": "02763591456b7d3ed76125e4b9d5b34c3926f5aa166200dd270e45ecb6a6b15d9a" + } + }, + "signature": "3045022100f6ee4060cfdac8c8a9dbc50b49b7cb59d4a587a5d14135fc7345594ac2b7e10102205594aaafae4f78415f01e0228b7233ec36356db4d73da92f6720502874bc1672", + "id": "4164cada2725a8e52f8713f8600b3d945bb3045fc956d79066974e3a012021ec", + "senderId": "AYaYHEKaJvLLWX2NgM8VXk15zSDxV8vCgn" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "025e6a4c19af3228659e5aeb3638e78c50203d76a806d2e1ea938b79247a25a932", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_27", + "publicKey": "025e6a4c19af3228659e5aeb3638e78c50203d76a806d2e1ea938b79247a25a932" + } + }, + "signature": "3044022075186579fba3bb355622ca8e4e0470bc54e82ae15a16b5e1b16784b29087f70602203fabc6d8547b6eb07c59193e0b42f3bd6b5cc234ca5d415c791c9c5f4a4b7f90", + "id": "6aa2b74f026ff9cfb1e5e00a3b4a75f752f912337fdcb61ac9257d58fb406cce", + "senderId": "ARDkQVS4DbJnErrptyWSWdJD8gtaPEyRH8" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03916b256a6ff5c51bc0b7866678cdc40a2d06477fd022b61f79383b6cdf487bcf", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_49", + "publicKey": "03916b256a6ff5c51bc0b7866678cdc40a2d06477fd022b61f79383b6cdf487bcf" + } + }, + "signature": "304402207143545435e31741050f802e434d9559c486dcc19e136e6eb68c7881959f5f970220387f941b78ecbe29b209993bae101828daf5492cd2febf256a87d157b97af8cf", + "id": "d6805135ece218f780e604673b9946b789d4406553a5dcedee1c06575cc7c63b", + "senderId": "AJjkVwkhsvsX6dVKhVxpmhRvz4CyXLEvQ3" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02b38e56ef8fb018fe914c484ea4b0aa18f1a938f46af1c394dfca40adf2771bde", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_25", + "publicKey": "02b38e56ef8fb018fe914c484ea4b0aa18f1a938f46af1c394dfca40adf2771bde" + } + }, + "signature": "304402203222d23708aaba6f4904fa04ff5cd88c9c9aeb91771754763be9206d79f2d85402206ce18e2b3bccb6fbca2e024b1bb38ecd859c27986a0bc123bcc29f99b0dcc6b1", + "id": "86367f56d8b4a1bc34cf1790b3a1f81cf794b9e9683b347b7a5a5110e63b9b34", + "senderId": "AJrXd5u3y6FH5HktH2jgkLQHjgD9ZztMtk" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "034bef7fed4f718a450ec4672533d74ef95039cda85a1a0ff74e6b2dbb9e220d68", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_24", + "publicKey": "034bef7fed4f718a450ec4672533d74ef95039cda85a1a0ff74e6b2dbb9e220d68" + } + }, + "signature": "304402202b33813e4cdc7f97dd41747d53542803cc7c5ae7aae56cfef3e4b9d85e74302102203854d993b16efbf7b21454bcf44873969f35d033ee93866fd2293841f866441a", + "id": "65303140bae99aef3d68b36379acd8b9f4263f1d90887efc1fe7f0735c26b84f", + "senderId": "AZengw5WND4WLC8JKz6xUDFwLz3yCKPpTC" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03d48d4160457b1fe8d76e2da68f33860ad2520836b5ddec8af925757690d93c21", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_23", + "publicKey": "03d48d4160457b1fe8d76e2da68f33860ad2520836b5ddec8af925757690d93c21" + } + }, + "signature": "304402202c43ebd655af5fb0e7336fa41f03977bc5b4c05a5a6f335e544a58acb5f5ff1d022074d415ad20703c67fed90e1d0bc970ebe1d55f31a1a3dede173362c3736ba6e5", + "id": "c529cb54924f221a3aba98b204f82c033b67375a15d52e52671bb526957baa3c", + "senderId": "AaFxHxsjYyYCsZtpQwwYGvYESogJ2SHxe5" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0384e505b25eaac812f8acbaa1ecd09e2ca4b5d973210189a39dc48d2a8f908780", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_22", + "publicKey": "0384e505b25eaac812f8acbaa1ecd09e2ca4b5d973210189a39dc48d2a8f908780" + } + }, + "signature": "304502210099161fc12c6ea658f382dfcbd495c84961d1f8f029edfb6c2746ddca918418400220556ffdde284f10b5ba62bdf6a67139bc56f7d0e44e87c651cad6e8c2f646aefc", + "id": "bb014f5d3ba5ecdf3dba9949673e1cea6eeb3771f41bd88881aa4f055307e4d4", + "senderId": "AY5GwZtG9sFvDzMKAQfAD1Q8EHDh4bW718" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02c3709dda58fcf7e26f94e865458b08d95d398446f67f465387be56b03ec36f4b", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_21", + "publicKey": "02c3709dda58fcf7e26f94e865458b08d95d398446f67f465387be56b03ec36f4b" + } + }, + "signature": "30440220562a015669686e64c274be9823add0ce9da9bb8ea31e376c194b7e194c7306670220186b3482683572164588f2d89c8483eb6a789efaaf1945ba86b5333f23235254", + "id": "ee1933bf760161dfcce831d57e784e13f1e428bdf6ff59a0f06c778873172032", + "senderId": "AZvjdJSG5V4WnNjPaRbDNfLD72j3rYWqbs" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "021c2280e462313d08fbe92bac59f43203cef4e21611d42747535ec2987a80e30b", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_20", + "publicKey": "021c2280e462313d08fbe92bac59f43203cef4e21611d42747535ec2987a80e30b" + } + }, + "signature": "304402207e28352abc1eab6c5405cf78c2c1fe406912d3b08c6e02bf44877dd94d117eea0220144013da4977b0517f8fd8b7dc6838185e25d0f6f272af17125f50feced46242", + "id": "658f84d6568a7f48295e9f25281c6ca71c404245ece501cbbebb0c60efd08f31", + "senderId": "AKeDRRgG4TdDo4Z2iCzaBZS2UcvjWKMSrC" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0212fc419fd5f4c88f73b8475ea676f3800f4bc96433a074462d827fc35f4fd883", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_19", + "publicKey": "0212fc419fd5f4c88f73b8475ea676f3800f4bc96433a074462d827fc35f4fd883" + } + }, + "signature": "3044022036cc85f65b9cd55c1a336cc02c06cbecbc90a70314ed2848dbb7bb9cb7f7fad302200b217996c20eca5c5eaafcdc4d2a27a39d8945f55cd39322a0070b180e7a923d", + "id": "b8a1791640f64e4c977bc2c6f8afae412f6d125db9791db33d979fd3f607976d", + "senderId": "ANeLRbMxkSguPMq9CJeMgr8xZxwZ9mbqbx" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02015ebd34b20a1c7bcbcff1d53e7d2bbcb2b4eacee494830409e1f84117b802a1", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_18", + "publicKey": "02015ebd34b20a1c7bcbcff1d53e7d2bbcb2b4eacee494830409e1f84117b802a1" + } + }, + "signature": "3044022023390c4ff70c6f02923b4f55ecd6ef41e93871b4e4eb21be80b5023f72f1095f02205c921d9051395cf7a4d335a00a89a9e0f0d7afaae699b371503d35eda7cd13aa", + "id": "fa9bb4c78bbcbc164ef4a630997199aa01b53bc93d49b9f3237efea13717f04b", + "senderId": "AdCa1oGLMRQqygEBGGq1AEtSV44CJ5Kbdo" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "030cbba2415349f8093539632fe26692411219c11e740e9a3e02b6c64415f056b4", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_17", + "publicKey": "030cbba2415349f8093539632fe26692411219c11e740e9a3e02b6c64415f056b4" + } + }, + "signature": "3045022100c0e0115ba685768aa3aa11b9d0e1149a63824f72a486efe2dfa16df93d8f8123022023b207efa969e876be02f87ec8085da800750c127edeee1fc481fe978029802a", + "id": "4bfcd5ae4f01935aedb2fed2d509698902a054456f7dcf5fce02da02f1c7d752", + "senderId": "AXuVpX3tAewNp5YVWvXWv3etxjrMDgaZdK" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03367a6969c0d62e9b0fb3439ff2574dbacd5d616cc57b08f7c5417d4ac6e94faf", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_16", + "publicKey": "03367a6969c0d62e9b0fb3439ff2574dbacd5d616cc57b08f7c5417d4ac6e94faf" + } + }, + "signature": "3045022100f9a6be773cea615ec0d0cf0e330f3ca1faaa86f7475d620f6ae1299ca58671d5022065ae6e660f1c80e935db4e66387fb44225ee73f671e54003c0780e435029acc3", + "id": "54f2abed7bbdedacff1decc7be229f6385561cc8f800676ea61deae358bb252e", + "senderId": "APQgLh8MaztT1XuWVKb6d4FKM9HMmdmDVB" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0315ccdbcb0ec7bf484726f95bcb2b331cd976bd7d72f0e3f5c38fe4167d7c69fe", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_15", + "publicKey": "0315ccdbcb0ec7bf484726f95bcb2b331cd976bd7d72f0e3f5c38fe4167d7c69fe" + } + }, + "signature": "304402205a4959cab68877017ad4d4ac61a5b7c9a7cc674ec66b21e7463a8673b8d51ab002200fbdab9ab0e4601e1fccce869be1a1b3348d8127e4febeaab68228953a81cf04", + "id": "7348d455b5dae1aebd48b3668b571f5e44c0e8f612c1377a19de8f3e27c84644", + "senderId": "AGZhXHXFUdvd7W4aWs1fYJe6XFUYeSWrd4" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03477d8e77a43b443d401aeec8b32aec5429f8f453b93d5c4061cd17101e09b077", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_14", + "publicKey": "03477d8e77a43b443d401aeec8b32aec5429f8f453b93d5c4061cd17101e09b077" + } + }, + "signature": "304402201a4433b86c57e2701fdbf7640b13b21634b7cbd3319aa0c914e16b59fae45bfd022044dc7bec58897ddb36fadae3c52662aa228ae88b0ee6c467a52d1e476784a30b", + "id": "6f6fa4b601053f6fcf50e734d6caf590dc4d23980c32d9f1b62e10cda3241018", + "senderId": "AVoTzMjHaaWKDuA26ysXGU681N6Q2PQre6" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "037d5887d9a9bb48e45404fc5c3149bbd53d82bb4572bf468f0da9b4e9f6c73ae7", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_13", + "publicKey": "037d5887d9a9bb48e45404fc5c3149bbd53d82bb4572bf468f0da9b4e9f6c73ae7" + } + }, + "signature": "3045022100c2f43505df18e7682ac36c16f6429764ad86339527e554a78ef44d0941cfc937022007118cfd9b51ea359ce4dcbbb5dcf06147fd219a38bf0eee9a220c507c5944de", + "id": "dca332856f06a5431c648f73f859b8f8286bac60d7f452eac42d7febef0fd7f2", + "senderId": "AGdHR2UZ3MJuaXWejKGoAycztyN8BFQnNG" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "026f1910d432c8ca8f04248e74c4b565a236d9851caeed4422550c3803b313bf39", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_12", + "publicKey": "026f1910d432c8ca8f04248e74c4b565a236d9851caeed4422550c3803b313bf39" + } + }, + "signature": "30450221009a73cbe01aba47c293914b2bd382e5715a611dc14714e225fe9287cf293fc34f02201b05843284b43452c1b779b6121be37b4459e96d6e1328f6ca4c076522f4351f", + "id": "49620d01436262018949d76325f7f7c974fe5419a32626c3ba1e7c3b2f0752e1", + "senderId": "AYTEu82arYgRyvTgi7dbYwjodV7ignYucz" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "024eda8b8e70b93f87c1e18929a2ad789aad3f6b3fe4aa12b4f74513bc45916726", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_11", + "publicKey": "024eda8b8e70b93f87c1e18929a2ad789aad3f6b3fe4aa12b4f74513bc45916726" + } + }, + "signature": "30440220637254d742d5038797dd38323259ba4263c3e98eefae4a8c6717faec0e866a2f022075765f0a4036afbd297bb3bd10c7ee7f62731b45dfe708a04096947af7caf106", + "id": "63acffbbad5440dec99e17dd3eb4d501f44330f0d8c4db4cf161cc0992eae5c1", + "senderId": "AWLoVgSScNNB2kecswuhbY9tcrtv9kf2iC" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02886a2ad45ba50edeffbb7447cc1baf1cdd16e3b91e5ed6ba8b16c687f03e01db", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_10", + "publicKey": "02886a2ad45ba50edeffbb7447cc1baf1cdd16e3b91e5ed6ba8b16c687f03e01db" + } + }, + "signature": "3045022100e78d6752036f323c61e78cefc4355a1dd7372fd782377052b5c80d30f81597c3022004b86acb40c52d91a1eea79d4de929c59a5e24fed6f243157088c1eed03f039e", + "id": "531ecd8620d51f46dc1140c8d8f0ec8344b4ebef61f17e8c304e5b3bd5e02586", + "senderId": "Aa5rKoVusA5xiyh8Git1tJUWZE48ScbCR8" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "037bd8595ad6b5787671c99921208284ac6f791a8ca55c6e49ca94a94731b6cba9", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_9", + "publicKey": "037bd8595ad6b5787671c99921208284ac6f791a8ca55c6e49ca94a94731b6cba9" + } + }, + "signature": "3044022066203d448724540f14a916591051ed79f57e3995af8cd9bab5ef003064c08dd002202a60f251bda6088ce8d43d6289ea2ded6442e95344654f02a17488f26c10a893", + "id": "eb253b77c4560b226d8edbfbb860717289258f4cd1ef15cee6da88f80029a33b", + "senderId": "AbfnTeGFiRM3m8eHcMsrqNvrpUCoCnuSzH" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03e8eeb0e5063caf214986fa2e085dc67897908cc2501ccdeefeef33722afde50a", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_8", + "publicKey": "03e8eeb0e5063caf214986fa2e085dc67897908cc2501ccdeefeef33722afde50a" + } + }, + "signature": "3045022100c6bcd9f75dbc9bafeb2e134028b2c4f8be77214611012f4d9b92bad5610d42c1022039923f93586e1976ae614fc90208352dac120505a08be0a2b9b82840622473a4", + "id": "5378c9044477765f44580a5f42ace617df524457315fe63ef9806e41de5e65fc", + "senderId": "ANstQM4LaxfsuKtFMd8vqdGte3CL9s2vMA" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0307784cfc3d9002be47ffa32e8d99146869342254247df059452c5f92f7ae521a", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_7", + "publicKey": "0307784cfc3d9002be47ffa32e8d99146869342254247df059452c5f92f7ae521a" + } + }, + "signature": "30450221008ad9a84421282b28c6d4cabc42a7855bb3853a02edb0524fecc21b821216a6d702203b0558b44c659d52fa163f8941a61ae0b8cec81cdd3fdbc8e91577ede6815fcc", + "id": "20d635b856a468eefc0801853afd1d387d25fdbe69c677e56b850fc45a7c3029", + "senderId": "AVFkEkCmEg7cuCXoVrfvtH6mKz6XC9XnvV" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "028dc3fd930165f910571a159f574ab15ac740f48e68429a7fbfb42ba202c64a0d", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_6", + "publicKey": "028dc3fd930165f910571a159f574ab15ac740f48e68429a7fbfb42ba202c64a0d" + } + }, + "signature": "3045022100fdb6d70801c889e1173ae9de78a07e55bed999ef39107f2dac1e65d6bacbe89b022004557733f6fe0d96f67cf420691375a8ab23ab212365a96acb9b36aa54f8f415", + "id": "c7e1b81e3cb7f63eb947647fa572b5309b9f022d893e745baffa282f51e65dba", + "senderId": "AMG1Y3LP4kZJMAtoPhsnVkpsMTJ8nnCDr3" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03de80311e0ca23a780507fae2691b7c995cf36fb2b2d079b7c518e03302d56eff", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_5", + "publicKey": "03de80311e0ca23a780507fae2691b7c995cf36fb2b2d079b7c518e03302d56eff" + } + }, + "signature": "304402200bd5d223d887130a7a8b65f10e8f0a7eacda456257dc5eae4cf0f3f7068ed6e402207d6d5dd9cf0f69f592fa81bb117a83cd0e55a21b16abe048c1d4b603f295fcdc", + "id": "71debbd9fb57e0cdfcf42d9d012768a7d9ad85b4b6f32d520b424ef0e0893bc8", + "senderId": "AFxqVbsVuDfnfyd9ciRAuGq6waR5GqiC5R" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "021780f82dfb6331cbcf35b9fc233cf3494e569a329b2966249c5632b0ecf53cb2", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_4", + "publicKey": "021780f82dfb6331cbcf35b9fc233cf3494e569a329b2966249c5632b0ecf53cb2" + } + }, + "signature": "30440220043a0359c3d68ff69877cbf2f116410bea908036f57c3aa1d51684ef9e4d1fa102202a55ae852b5e547c6733d8ea0fdf137f6525b4effda003e09289936be0f333e4", + "id": "3eee8478d002ba59f2ab94bd539c26f805005b24d8d0cdfda6f79ba576db55ce", + "senderId": "ATjjXXcGPTum6wogPVGb9pmimpSo4EDDEv" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02d113acc492f613cfed6ec60fe31d0d0c1aa9787122070fb8dd76baf27f7a4766", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_3", + "publicKey": "02d113acc492f613cfed6ec60fe31d0d0c1aa9787122070fb8dd76baf27f7a4766" + } + }, + "signature": "304502210097b10f85338d39ca4dfda4baf9b86f97253cb06ff2c80d3d9a3e5023b2294f060220192986b55a91bf3c5d5ad1e8f7aebf69df89f022e1d8f8674ecb675faace1623", + "id": "69483bf341ab8e5ef989340da103a162b25e09ef205b53a7d2f6f8547bc7334c", + "senderId": "ARagsXvdeTHYghaQgJkwbdSkPLZ73qdMkR" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03aa98d2a27ef50e34f6882a089d0915edc0d21c2c7eedc9bf3323f8ca8c260531", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_2", + "publicKey": "03aa98d2a27ef50e34f6882a089d0915edc0d21c2c7eedc9bf3323f8ca8c260531" + } + }, + "signature": "304402207f3b69c5fe22ec832246ff2e0318b361849cb8fb7250d9eee96639e17d112ecd02203a4d4010360992f4162f7ffd5361884d787a07580a579da11fee4a8b8b7e78d0", + "id": "d6424b437baef1b93e967a48b29313347e6a79cd93818528c9a7515ad167b917", + "senderId": "AT9xWcPQ8hGYuXZ8aWE57VJFohyX1TTLkH" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02e83dae2b59ad7923d931f8d0ff96588b6f2b2183288c667bacf2888d5f9d80c9", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_29", + "publicKey": "02e83dae2b59ad7923d931f8d0ff96588b6f2b2183288c667bacf2888d5f9d80c9" + } + }, + "signature": "3045022100e6d497a3905baff592921a269d78882d787a03a4c67e7818a5c71aa57c00186e02205b54519080782485a6ca918a50bdac68c0cc1723259cededb1ae9f011a88b919", + "id": "fd90a8bf3d38e0fc81020705be347205da7006d4db889f8a5c28653069d060b8", + "senderId": "AGNMmJ5upuU38ucaG3TUsG1ESaQDExSMo4" + } + ], "height": 1, "id": "4366553906931540162", "blockSignature": "3045022100c442ef265f2a7fa102d61e9a180e335fd17e8e3224307dadf8ac856e569c5c5102201a34cb1302cf4e0887b45784bfbdaf5cfbc44f6d6dad638d56bafa82ec96fd45" diff --git a/packages/core/lib/config/mainnet/peers.json b/packages/core/lib/config/mainnet/peers.json index 20dba5cbcf..b4485e9738 100644 --- a/packages/core/lib/config/mainnet/peers.json +++ b/packages/core/lib/config/mainnet/peers.json @@ -1,5 +1,5 @@ { - "minimumVersion": ">=1.1.1", + "minimumVersion": ">=2.0.0", "minimumNetworkReach": 20, "globalTimeout": 5000, "coldStart": 30, @@ -7,135 +7,263 @@ "blackList": [], "list": [ { - "ip": "5.39.9.240", + "ip": "5.196.105.32", "port": 4001 }, { - "ip": "5.39.9.241", + "ip": "5.196.105.33", "port": 4001 }, { - "ip": "5.39.9.242", + "ip": "5.196.105.34", "port": 4001 }, { - "ip": "5.39.9.243", + "ip": "5.196.105.35", "port": 4001 }, { - "ip": "5.39.9.244", + "ip": "5.196.105.36", "port": 4001 }, { - "ip": "5.39.9.245", + "ip": "5.196.105.37", "port": 4001 }, { - "ip": "5.39.9.246", + "ip": "5.196.105.38", "port": 4001 }, { - "ip": "5.39.9.247", + "ip": "5.196.105.39", "port": 4001 }, { - "ip": "5.39.9.248", + "ip": "178.32.65.136", "port": 4001 }, { - "ip": "5.39.9.249", + "ip": "178.32.65.137", "port": 4001 }, { - "ip": "5.39.9.250", + "ip": "178.32.65.138", "port": 4001 }, { - "ip": "5.39.9.251", + "ip": "178.32.65.139", "port": 4001 }, { - "ip": "5.39.9.252", + "ip": "178.32.65.140", "port": 4001 }, { - "ip": "5.39.9.253", + "ip": "178.32.65.141", "port": 4001 }, { - "ip": "5.39.9.254", + "ip": "178.32.65.142", "port": 4001 }, { - "ip": "5.39.9.255", + "ip": "178.32.65.143", "port": 4001 }, { - "ip": "54.38.48.160", + "ip": "5.196.105.40", "port": 4001 }, { - "ip": "54.38.48.161", + "ip": "5.196.105.41", "port": 4001 }, { - "ip": "54.38.48.162", + "ip": "5.196.105.42", "port": 4001 }, { - "ip": "54.38.48.163", + "ip": "5.196.105.43", "port": 4001 }, { - "ip": "54.38.48.164", + "ip": "5.196.105.44", "port": 4001 }, { - "ip": "54.38.48.165", + "ip": "5.196.105.45", "port": 4001 }, { - "ip": "54.38.48.166", + "ip": "5.196.105.46", "port": 4001 }, { - "ip": "54.38.48.167", + "ip": "5.196.105.47", "port": 4001 }, { - "ip": "54.38.48.168", + "ip": "54.38.120.32", "port": 4001 }, { - "ip": "54.38.48.169", + "ip": "54.38.120.33", "port": 4001 }, { - "ip": "54.38.48.170", + "ip": "54.38.120.34", "port": 4001 }, { - "ip": "54.38.48.171", + "ip": "54.38.120.35", "port": 4001 }, { - "ip": "54.38.48.172", + "ip": "54.38.120.36", "port": 4001 }, { - "ip": "54.38.48.173", + "ip": "54.38.120.37", "port": 4001 }, { - "ip": "54.38.48.174", + "ip": "54.38.120.38", "port": 4001 }, { - "ip": "54.38.48.175", + "ip": "54.38.120.39", + "port": 4001 + }, + { + "ip": "151.80.125.32", + "port": 4001 + }, + { + "ip": "151.80.125.33", + "port": 4001 + }, + { + "ip": "151.80.125.34", + "port": 4001 + }, + { + "ip": "151.80.125.35", + "port": 4001 + }, + { + "ip": "151.80.125.36", + "port": 4001 + }, + { + "ip": "151.80.125.37", + "port": 4001 + }, + { + "ip": "151.80.125.38", + "port": 4001 + }, + { + "ip": "151.80.125.39", + "port": 4001 + }, + { + "ip": "213.32.41.104", + "port": 4001 + }, + { + "ip": "213.32.41.105", + "port": 4001 + }, + { + "ip": "213.32.41.106", + "port": 4001 + }, + { + "ip": "213.32.41.107", + "port": 4001 + }, + { + "ip": "213.32.41.108", + "port": 4001 + }, + { + "ip": "213.32.41.109", + "port": 4001 + }, + { + "ip": "213.32.41.110", + "port": 4001 + }, + { + "ip": "213.32.41.111", + "port": 4001 + }, + { + "ip": "5.135.22.92", + "port": 4001 + }, + { + "ip": "5.135.22.93", + "port": 4001 + }, + { + "ip": "5.135.22.94", + "port": 4001 + }, + { + "ip": "5.135.22.95", + "port": 4001 + }, + { + "ip": "5.135.52.96", + "port": 4001 + }, + { + "ip": "5.135.52.97", + "port": 4001 + }, + { + "ip": "5.135.52.98", + "port": 4001 + }, + { + "ip": "5.135.52.99", + "port": 4001 + }, + { + "ip": "51.255.105.52", + "port": 4001 + }, + { + "ip": "51.255.105.53", + "port": 4001 + }, + { + "ip": "51.255.105.54", + "port": 4001 + }, + { + "ip": "51.255.105.55", + "port": 4001 + }, + { + "ip": "46.105.160.104", + "port": 4001 + }, + { + "ip": "46.105.160.105", + "port": 4001 + }, + { + "ip": "46.105.160.106", + "port": 4001 + }, + { + "ip": "46.105.160.107", "port": 4001 } ], "sources": [ - "https://raw.githubusercontent.com/ArkEcosystem/ARK-Peers/master/mainnet.json" + "https://raw.githubusercontent.com/ArkEcosystem/peers/master/mainnet.json" ] } diff --git a/packages/core/lib/config/mainnet/plugins.js b/packages/core/lib/config/mainnet/plugins.js index dfa93d30fa..a52fee8f73 100644 --- a/packages/core/lib/config/mainnet/plugins.js +++ b/packages/core/lib/config/mainnet/plugins.js @@ -1,100 +1,73 @@ module.exports = { '@arkecosystem/core-event-emitter': {}, '@arkecosystem/core-config': {}, - '@arkecosystem/core-logger': {}, '@arkecosystem/core-logger-winston': { transports: { console: { options: { - colorize: true, - level: process.env.ARK_LOG_LEVEL || 'debug' - } + level: process.env.ARK_LOG_LEVEL || 'debug', + }, }, dailyRotate: { options: { - filename: process.env.ARK_LOG_FILE || `${process.env.ARK_PATH_DATA}/logs/core/${process.env.ARK_NETWORK_NAME}/%DATE%.log`, - datePattern: 'YYYY-MM-DD', level: process.env.ARK_LOG_LEVEL || 'debug', - zippedArchive: true - } - } - } - }, - '@arkecosystem/core-database': { - snapshots: `${process.env.ARK_PATH_DATA}/snapshots/${process.env.ARK_NETWORK_NAME}` + }, + }, + }, }, - '@arkecosystem/core-database-sequelize': { - dialect: 'sqlite', - storage: process.env.ARK_DB_STORAGE || `${process.env.ARK_PATH_DATA}/database/${process.env.ARK_NETWORK_NAME}.sqlite`, - // host: process.env.ARK_DB_HOST || 'localhost', - // dialect: process.env.ARK_DB_DIALECT || 'postgres', - // username: process.env.ARK_DB_USERNAME || 'ark', - // password: process.env.ARK_DB_PASSWORD || 'password', - // database: process.env.ARK_DB_DATABASE || 'ark_mainnet', - logging: process.env.ARK_DB_LOGGING, - redis: { - host: process.env.ARK_REDIS_HOST || 'localhost', - port: process.env.ARK_REDIS_PORT || 6379 - } + '@arkecosystem/core-database-postgres': { + connection: { + host: process.env.ARK_DB_HOST || 'localhost', + port: process.env.ARK_DB_PORT || 5432, + database: + process.env.ARK_DB_DATABASE || `ark_${process.env.ARK_NETWORK_NAME}`, + user: process.env.ARK_DB_USERNAME || 'ark', + password: process.env.ARK_DB_PASSWORD || 'password', + }, }, - '@arkecosystem/core-transaction-pool': {}, - '@arkecosystem/core-transaction-pool-redis': { + '@arkecosystem/core-transaction-pool-mem': { enabled: !process.env.ARK_TRANSACTION_POOL_DISABLED, - key: 'ark', - maxTransactionsPerSender: process.env.ARK_TRANSACTION_POOL_MAX_PER_SENDER || 100, - whitelist: [], - redis: { - host: process.env.ARK_REDIS_HOST || 'localhost', - port: process.env.ARK_REDIS_PORT || 6379 - } + maxTransactionsPerSender: + process.env.ARK_TRANSACTION_POOL_MAX_PER_SENDER || 300, + allowedSenders: [], }, '@arkecosystem/core-p2p': { host: process.env.ARK_P2P_HOST || '0.0.0.0', port: process.env.ARK_P2P_PORT || 4001, - whitelist: ['127.0.0.1', '::ffff:127.0.0.1', '192.168.*'] + whitelist: ['127.0.0.1', '::ffff:127.0.0.1'], }, '@arkecosystem/core-blockchain': { - fastRebuild: false + fastRebuild: false, }, '@arkecosystem/core-api': { - enabled: false, + enabled: !process.env.ARK_API_DISABLED, host: process.env.ARK_API_HOST || '0.0.0.0', port: process.env.ARK_API_PORT || 4003, - whitelist: ['*'] + whitelist: ['*'], }, '@arkecosystem/core-webhooks': { enabled: process.env.ARK_WEBHOOKS_ENABLED, - database: { - dialect: 'sqlite', - storage: `${process.env.ARK_PATH_DATA}/database/${process.env.ARK_NETWORK_NAME}/webhooks.sqlite`, - logging: process.env.ARK_DB_LOGGING - }, - redis: { - host: process.env.ARK_REDIS_HOST || 'localhost', - port: process.env.ARK_REDIS_PORT || 6379 - }, server: { enabled: process.env.ARK_WEBHOOKS_API_ENABLED, host: process.env.ARK_WEBHOOKS_HOST || '0.0.0.0', port: process.env.ARK_WEBHOOKS_PORT || 4004, - whitelist: ['127.0.0.1', '::ffff:127.0.0.1', '192.168.*'] - } + whitelist: ['127.0.0.1', '::ffff:127.0.0.1'], + }, }, '@arkecosystem/core-graphql': { enabled: process.env.ARK_GRAPHQL_ENABLED, host: process.env.ARK_GRAPHQL_HOST || '0.0.0.0', port: process.env.ARK_GRAPHQL_PORT || 4005, - path: '/graphql', - graphiql: true }, '@arkecosystem/core-forger': { - hosts: ['http://127.0.0.1:4001'] + hosts: [`http://127.0.0.1:${process.env.ARK_P2P_PORT || 4001}`], }, '@arkecosystem/core-json-rpc': { enabled: process.env.ARK_JSON_RPC_ENABLED, host: process.env.ARK_JSON_RPC_HOST || '0.0.0.0', port: process.env.ARK_JSON_RPC_PORT || 8080, - allowRemote: true, - whitelist: ['127.0.0.1', '::ffff:127.0.0.1', '192.168.*'] - } + allowRemote: false, + whitelist: ['127.0.0.1', '::ffff:127.0.0.1'], + }, + '@arkecosystem/core-snapshots': {}, } diff --git a/packages/core/lib/config/testnet.1/delegates.json b/packages/core/lib/config/testnet.1/delegates.json index e5da81af60..33f51bf736 100644 --- a/packages/core/lib/config/testnet.1/delegates.json +++ b/packages/core/lib/config/testnet.1/delegates.json @@ -1,8 +1,4 @@ { - "dynamicFees": { - "feeMultiplier": 1000, - "minAcceptableFee": 30000 - }, "secrets": [ "target sort neutral address language spike measure jaguar glance strong drop zone", "race total stage trap wool believe twin pudding claim claim eternal miss", diff --git a/packages/core/lib/config/testnet.1/genesisBlock.json b/packages/core/lib/config/testnet.1/genesisBlock.json index 28969efa39..317cd8ed94 100644 --- a/packages/core/lib/config/testnet.1/genesisBlock.json +++ b/packages/core/lib/config/testnet.1/genesisBlock.json @@ -9,2149 +9,2303 @@ "payloadLength": 35960, "previousBlock": null, "generatorPublicKey": "03b47f6b6719c76bad46a302d9cff7be9b1c2b2a20602a0d880f139b5b8901f068", - "transactions": [{ - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402205fcb0677e06bde7aac3dc776665615f4b93ef8c3ed0fddecef9900e74fcb00f302206958a0c9868ea1b1f3d151bdfa92da1ce24de0b1fcd91933e64fb7971e92f48d", - "id": "db1aa687737858cc9199bfa336f9b1c035915c30aaee60b1e0f8afadfdb946bd", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100ffff4e9ba62e5e3beb37deee052824da83c4030925bce09f190151652d0669b8022056a432e56a2e1b026d4b54f6c34ce88a0c9cebdccc730659c03449fe878c66f8", - "id": "0762007f825f02979a883396839d6f7425d5ab18f4b8c266bebe60212c793c6d", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022001a6326e5d1eb06d0ba1fa39446bd6d56ea45f0c269ebbce5dfc6a649277cfcc02203b252d3a6ef2b22349d9d0a9110ce28a199c39dc8b911edfa82c297a02009d07", - "id": "3c39aca95ad807ce19c0325e3059d7b1cf967751c6929035214a4ef320fb8154", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304502210084d855eddfe616cf1dc238b19226c7959c2fc4027ae2e8aea6fd8e9eb8928e6b0220440f980e40c1c56348782fd69d49a96944df7ee5b68d18028600e0e7501d4000", - "id": "9fdf6ae86f7c005b3b7dc1b9fb6411219407ecaa93adff85fdb61710f5121638", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402205438b8b9058bbde5d30794e7681e400e52b5fbd22324c5b6b521f97bc8b8aabc022000fe04d7afbd2e668b1d4576988ed596dc92251e33efebc081e2cba14ad5a898", - "id": "1d7c68087c875d7ce555b2c3e71e1d91a1ad62d0c2497efe3cab91415e634041", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100b2e634a95b011a68489870f003e4bac4a4f0578bfdc6b9f645c934016c2c0463022022cd4ebf276dd627d98be4b697bae2df10b86d94e984da2eb7e011b08d6dffd2", - "id": "0c993e115ba26981b0be9d22e7c4a13b0f106e0cb472f9d34eabfc8e414dd528", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100f965e5c280acb22d1cde405223fe9a6fcb765844adbc5321b17a268924e1f597022043d31b1edc5fe0cf60a960d84e3528472cdf34560c9463979043a409f37e7f29", - "id": "c279f2eb1f9e6e7d4b0ba7a98233a0f1a2536231976c99f56f64b248eb06a0c1", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "30440220715463c316a75959dbfb6a59a013fbf914bef1ff739ac8000d49dabbf5118df9022019345ae1c34173dc214bae82f3cfbf438092f0fd2d277acafe3e9deb644b1a3b", - "id": "7e2fc9ecf23e909a3d0fbecd615445a0eed8c2cef18e01b1492d63f616f5d87d", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100fdd8aff26dceeb5abb6e5e8a8f468c8ac1997a587225298e3d8135d57dadf4dc022072ab80a81b301a162ed5cfa67d213d5a3980185088632f5f592351aff8aa0e9c", - "id": "511c0e1076104743f98932f8e7720bdb3f1539134edadd331914fd9ece1ebede", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "30440220635e04ce278870f17fcd1883aa26c568e63dfbdd302add39aa30fd3637c79c2c02206fdd9e7b1f4d238a97d26ef1758927e2d39f121687490f2bd79831e36afdd43b", - "id": "0768d5016c53d884e3d68a09d1bab0d730b7067c71ef4ca1c4d61b3815f5ff66", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402200b1dac57ca6565ac31afb99686f2e0f0e8dc219b9860b295ca5444a1663cecfb02205787393561fe407449af4aaf2f621db9e4d3f11c7438666cd694d495c0a0c41f", - "id": "1aeb50080ea118165e5041f7a897974c2ed1ebde08add85dc78cc7cf73566a91", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304502210098dea25eccf31ce6f874a9528578805aaf07be8b41f1571865793f9e3e6e3c97022033ae9c73dad44c01fe6362665fccf63bb1a0ae8e26f77a1cf60b67dc96b05343", - "id": "254f0f4fa277cc651a746d6ac371eb27afc3ea155ba060552dd26b8e83d17b72", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402207f4bf346aac501e766156818089fb16905a9bdca69ff6d5a55ba918a08afc7ab02200ec2c25cc4bb30e2c176d55630d8e2679b899c14ab4ba43c3d62955dd940425b", - "id": "e5ebb02e8e8a6708e22ee5ef99fe1dd8b6eea1095be6b772aa21bf63cf7ade5a", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100a0bbc15bdad648bb9b439f1d34b12b853442d1cfd4ce7f569905082801fa58e8022036b4e73edf7ab7226f8007233f77b1d497cb6b4736f02721bf1b399312ebe114", - "id": "8a686b21477b64dfd85f08f8598a0f121ca1c7d65ccaca9e42326c75fb5f3abb", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402205d77dfcde527dcc6669bcb01c27b92c1a6399e35ebac9e69415645f596ab1d2802204179497bfd952f44d5f9e295b2a3219a290a4a82841c084a18553b7712e26415", - "id": "21175347e2acfabc09a7593aae0682e39fe7152199a90561c11125f525211243", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100cf77c16df9185727ff717b71a94f8b29ceeae1e5bb3a28da8cef9df5bc63b7c202207bca394ce9ebd344a548e5a5697f672dedbef640dc1f9105f7c063287bcd1840", - "id": "ce1d9b7377551f36568127f5b635b5443f5a58abba6566b50a8d4d7b53c8a874", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100eb8daebb5484f3b0a738c9344fb28298c596f9486963f8fe36e2501ee6876f2a0220559df66986dc9a9a8e76982ef85f907c62745757990c69f0b17b6ae5a7ca4719", - "id": "b56702f5eddad0d8dbbb33b6b1ca3e07e4740def9c5dd2aaed9a70b90a4e31b7", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100d088e9bcd78978f2d67e7c7bccecfb73ddd0d1a2dad5b039390812320355722d02207affe83d815f04f6b11abf98eebe0488bfb87f8cd6513d44b829008ed1c15ceb", - "id": "a73c053c42e83a83498cf58e5b077b31443e265ddf8228081cb17a36bba366ae", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100db16a8e9682f07efb607bc7c75b654646ff449761ed146ab9358e69d29fadd7f0220436554ad78db0e04ae5b573258e2c8067848e89b55a6e8e1e25011a43882a643", - "id": "2dccb8b44ad2e598673628fd9d74e336b467a0c941d5e257dceb85c8e0a0000c", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100b03738eccce8ad0b8ac0a656119c2cdd202089c5650d8e1486bd13eb9c3158980220059079900c7fdc16e799c50dccc074726fbf0068044462faabdf1e73f9f9bc38", - "id": "b2cce30021d139f97925807da796722bf4d5459442523823388c259ca5ad73db", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100becb49fe5edd6806d5ba6eddbbb34ca8eaf3a12dba123d1610b2b120ca8bd017022072972992ee0ca0f319ae754a2a5a10d715a08b23f8239f9d6d59774f790543ea", - "id": "9e4841f43ab355be7a4f93b09f3d82c17065fbe25387dd6c5eb4e2692ea05b0b", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402207f1a3fe8c5aa7a77a58ed35c34f128b5df6fba89aa918af35eff432be7d1f8e00220460d4f2a457e1a477974157e33bf2974de6588d56e59729ae980720e9794827a", - "id": "2c7ca823be21724a4876de632dded3b9afca45df357819ed028488128d85d29e", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022067266dfe9d8f2550b590e1eae2f73d28c6b80fecb24c3eb1b4539bc864b3b4f4022031e5122145c35874c0c48673d088e76fb3e11c308ffe9d5dee6431d3441d627e", - "id": "a91119f04e2201184761f7fdcb26e4aa81c7e1076cb11a58a422d351241d4e4a", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100b970ec89927de0cb7805e614a742d42c2967db5a9c68d0892956dc89d68ca7d1022067fa30265dd2e1a2985980be2bf876748a7a8c7f3cde0382265b601fa658dc17", - "id": "94955e6bac6269fbd19e92d2292ac947225fc6f68c6216001b528596a961040c", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402203671b82ddf8a824b8e5aac8bc28be4aef1c00aca1097d14ec1a55003d7a3f28d02203aacb6e7517e916478432b81399828ba7425183ce0fc43feb361bcf345fb0519", - "id": "df563ee9822bd3d7aada600d4800952743ec64fafdc7697428d7a19a60745885", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100b77653317c93eb20ee19c71e64a7f9ecb985351bfb1fe351ac65a5738cb37ae202203d540395e1d55f87caaaa867afbfbaf98c553be0b4c7d1748418a76b0c258c89", - "id": "d21b6341e2b4be5ffdc3dd8fbcdf2c576ba02e2ef4ab5eab0e4bfc9da4e9e442", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022046239e39062a58925099b005888355b8cd6700af66972bf509a10123f9abdec60220202321ea74e56177606fc079d19c29851d832e6d00c93985ffbec3dba6f0d675", - "id": "df6bc7a17ad34f8e9faaa2646e8e5dd8bca35affba352537184f690e200e17b6", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402204eeab87f7ecc2097b85606b986177964f3ae777535f6fc0cf08a55fec587d87602203779d59903b8de63511e4ed0a7967bd85e9cb1fc9d84bbc5091e3caa87d8bd52", - "id": "5f0d5f0dff464d0ad587da5bc93e600a8e2657d359d0a1224bdd4ccc3b6f376a", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402200a2b9d0f61066fa00a2a2882379aa8ee60e949bdc2a85103bbbb69ce3eafccd9022057364f349faceb3047fa95ada210c64fc4a81978d66925b37d3dbc21ede885af", - "id": "1b39e3702576e6ad7775e34d53e43210549d52a56b3f246031e6ba4121a66bf0", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304502210099e568d3d0c1b48410e0b85c74d04234dacfb2fdf2b1d4b51fca1cfb3445347a02207a2509645aae54560762a37422b66ba4b3ee1c42de35d58c36d2f9d8fdea11b4", - "id": "0f21e53dbb1edb1cfb4c31bb675aa4672b452a03ec363a2b3300a9dda49e3be3", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022026cc5f2b588a86241badca73cd9c1686916d516b8c6c397c66a9d5bb6b5d4cd402204ab5a8c8589ee954bda4a116999d2a0e4ab0e3e96f0c7fe131d7c57b9a1ede43", - "id": "410826c255a23a78ac5c3aa10dd48132693bc955845af16c20d9c6f69b05dfe9", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402205fedd8d3b5c8d69cdd7db5ca8e9e7c5004f6ba751e45eb1b85b26d9e89800a2402202be56bb2cd824bccf325b6b11432bf6d0ddb5ec97fcc121839ac2ebf884c7173", - "id": "ddb57d8270b2b6c876191c1e1c5974388b9fb3ae0980cb2245d8a7c426237f47", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022053cd42ad147eea33801b2b57388b33f633b4bfe2ad902190e12480522250d07802203066dc0d0c2ffacc4c74cca1e0187fbea1cef7e78a78666d2ec7e4e87ef546eb", - "id": "29e1aedf98935c369946c8dadb2d6784f9ab5ce8d73b9b4de2466c7757e2557b", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100c10448b87e7176735c8ddfc8fb3c4d5d55c2d71d18b7ce3ab321209ec299fd41022013517a09e4b366ab386698286ec7bb20410bdfb7f6674fab25a739259083b297", - "id": "4cf04852529b5525f22cc540790e36e61ed36045ad1b5b788f61ebe42637391e", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402204cc1588b204ebc0c20f44a31ce53d15ab5e4d1f9c103c02dd4e4eaa1c33630b40220194b6e427b6def0783461cd8d765f97b105d048942be468be2ee9b0a2785d2ac", - "id": "35c6bc3f0799d9c79efc6515f232c58be0d03a3a797d066cba879eef4afaae2c", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100be44f7ea12e2ee89245fb474643ec6c2c75afa00276826a4ecd6fca4cad5ff30022071a2c083b353a821345e4bbf74d98db0760b8721856572572cc3436ebdb8f08c", - "id": "45f75a349f3b4d73434c0f2ac9c291d5d07278b79e6eaa0d38d6e005f66c4783", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402202090f506e8f18fde70b87a3fd6c470a23e9e262f20ec6268dd59b6362e51a29202202b838c598b33c6317c998dc179fad2b660b8a72bfaf8223d7cc82414ab4c6af4", - "id": "a8d9034d1091a4dbe595647ad5f64ca8b243e7842301aee48f7eaf8b8ae98119", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100be59b689a48e198267305f1ae7e116f69f7c360857ea0b1fa81db122278cad69022033436d24ec0103674522f0c559e2357f8696bd498deccad2e0f66b2cf7469538", - "id": "061cb438ba1216cfd5a0f268ce18e6f280557bc944d9aed3655e2bc5f08bdf51", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402203b5d2aa7c4554d6d2dd6723043350df0199e6e7bbd9f21a1a20dbba8c63918cc022014a78064c5f9c5e2f43d3be36de2b5e2f17e9af557bb6c75e8d82d9f725d0188", - "id": "239f0640ddc3170a737ef349c07cb82b2493d207421b6f71b6b3dab856f16088", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022005eb29ad4cf79fd4f6898de19459e15cc816acb0975e53530a202e69c29d0d4a0220686cf6e0c14779d6d68dcb9d16358c0e859094d2eec8083598b7bb5869478bf2", - "id": "25d8eef755cfee7cab0d7f9fbbea0fad6d5f906c432d997ae8ef1c49d23735f5", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100b93096a287d59545fa3a08593dfc740d9d47f3cfa3c4bd3c8ff8ef53d3a2e957022027eda62e47220774cf799f46916195e5a8b30015c56ceff4f4a1c10a918e3675", - "id": "aac25996e3be809ee88996b6b4063e2097d6306e77a067de8ebc8d7076a28d43", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022017282aa4fac7b18e834abc3ca37b2f60cf989c26b12e2f2398a66cb907015a760220428218d39db812a22cc138acc7d5d4d2d5713f0546751c02d2c3fabecca0e724", - "id": "b040f86b75750b49c83ca7eb8f2a458f16b44789796ff306c5f942ca5f19164d", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402205970d53cb0921a62bbef540dc33189b2313f3574e44f046097067e6991d63b1102200a356c87642cc781df661a1fee21cce354a144463d37053280e000e1b75da7a5", - "id": "25ce96f951d7b7d886ef487331125b3413f655f9c5ee7fb4691a728c3cbce18f", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100aab0201c9d9a9641c11605d32353685cbaa051ecc276da1e6a3b309be9f20cf7022067aecbc7329bdf1770974e317a1243815511efa8c7af7801217a83c96d86eb0e", - "id": "285143b8b19cbde7c680b0f62ef51293e8f315c823ffbd97608c38c02045d831", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100dc7752f6f8acaa3a1ee2ed1bed306ee04556b3866db92a1e770c4b970c7a932e02202d137b312342f9d0708704833b26b6611d0464c87df97049ad8b616483e9d1f8", - "id": "87b06fccbb63809e976b3405cccec2eeaa3694d5510203f04c0e60bb6c2c0020", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402205ccad5c77ea339f5e3f2b7900b4b1c409d3c8204273e89b6401314fb61f0d224022026a63fef86356de64fe571ff8488a951dcacab56e980fc044ef9f43b9d37439c", - "id": "5597ed52e4123756bea9307c09c916ff9d0f9fbce8d2e9a3a2ff719a87ad0966", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402207c91153f820f34228bec62772e0d78876bd3277912eacd866fe35b5c86a316c80220104529c6f786cb387ec1e3d5826271c837f0d0a6d0fa5731b9a5c6663cce7108", - "id": "d46fde78608fcc668246cc35336210b3c167ba55c82e91b0fd99df7e36872130", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100acc0cf119c18861d3683bb3b0f6e209f2d62acfdd958f86dfbd35137ada814320220448f6f8adcd46204629b45a4a06f5dc7ccb4dbc2a1d702e107d91053847adf2f", - "id": "aa92faf5d80459b4e058dc8a8212608b589925052e22148384835ab687a4e875", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022055b6bbde5fa886db3cf1224a59f1fb43e850e2d9237db593368e1043698fe2c30220067dd20195e794af4152f1ff9e3ae4261698a86c54803ba1890bf176d97844d4", - "id": "432e67db0d5fc8c66376aa96c7324e5a1e6d00a415a9c8898b5e3bf25d8b083d", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "30450221009d6f38067264df8497d6888e4a8c316ec58ceba8a54c39ccb0ce261d114fbbab02200fae3f2f950f5c5e3387679f8ca341ec70cd90d0e32a30112f03cfb12cd9fc23", - "id": "9321e1b08faa544f592ad8dc7b60ff1cf845efcd28fedf8b445be3bda60434cb", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245100000000000, - "fee": 0, - "recipientId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402200aed5a4102bdafda00fda575294f149b393a798c510af8ba877b8c2d7ec8051e022004f7487c4f728c633aee5baa62ab0017f4b91cf2f494eb1c4cc9addc3e9155da", - "id": "0bbc9340798a18a81109bdfdbee9c9003f20a586dd9f80a39507c84588c1b4b1", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_9", - "publicKey": "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647" - } - }, - "signature": "30440220072124721ba7c997f7c29ad3d4819515fae7a67be2bc395cb73f114eb8d4abe60220523ac295e114de30ce8a4300f4670db91ad2abe1268460e6ad3463fbe9834b84", - "id": "d2e70f9d2de57240571905aa81db0b6883e27a83be2422530722d76b56e63ecd", - "senderId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_18", - "publicKey": "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a" - } - }, - "signature": "304402204b93b06e08e71e3317f9426a1d3d450d6293fdbf5a6b3043fce27b3ce65431e20220683609720ea1d7d921238ca8b5098d3d9c0caab7b1e26efe42a6aebbc095471a", - "id": "8695bcb906f5fd81d858794f7d90447aadaa38418d312e33115a81e856b34d12", - "senderId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_47", - "publicKey": "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd" - } - }, - "signature": "30450221009711559a43005c808113a1e9a01b1665495ff4bf30d635f7d98c752ead4cc3fc02207879e2a939914effe2b5c80cd515c4b3ff77a071b707c85c4444481878803db9", - "id": "55853d2d2a98def00c5ab842866a44d1db91678a07b6dd63d062508db28a00a5", - "senderId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_5", - "publicKey": "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565" - } - }, - "signature": "3044022025ba51a588253524557547ec492d71bd485fe5b291e60eef681c39eaf8ee781702202bf24c3d295c7a2c9aed97a79fb835506797dcfe7e7a2853e2578e7773c7e134", - "id": "553298aadf692c9c5d0334c307dd4ac0e277a49ed165c97ce1362f8ec639ee3f", - "senderId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_19", - "publicKey": "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb" - } - }, - "signature": "3044022041291ba10ad30fb9ebcb0e13902e92d85e2c3e98493b6d369d7d1e70e8474e31022009083444460c415eab6b4beed9e0206eb0733bad5d2a476af4db4f5b5e74b835", - "id": "90af927db7b258538c8e21116b5a31418c88ecc163628b2b65fac92a5a949b14", - "senderId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_42", - "publicKey": "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d" - } - }, - "signature": "304402205d4111c87874e696b8f4b8897d0dfe68fabe4ad5c5769026c6ecdd04f09a1e2f02207b9c8a2a16b50164215eb1efea6d5d9f4e693cbb7eec8535e526cf8ba68bb796", - "id": "8a920ebf5255a102d0c9c5fd720e0d36a6a3539991a2267442facf1fea2d0b86", - "senderId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_10", - "publicKey": "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd" - } - }, - "signature": "3045022100f15ff048872020d9efc561b8c837f542d54d43b9b071f7a6cc09643c6d4180f002207d0e82153a30b66f43fc4cb4b9b3093bb3d5dfd70f96928c8780c838b1448c19", - "id": "30738f376aa40fb3c8d8849a5dc698786aeb1409fa801c18729f8da624631391", - "senderId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_20", - "publicKey": "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751" - } - }, - "signature": "3045022100babb7410d09215def98078bbab6b5e5690c2ebf54960d94527226ed3925877320220342576d1d8fd2d2fe3b6974cab48a2e16b4813f022b341b32f88e13f572bf060", - "id": "ccbe1c27eadc1b3b33f3f87f645be4f756021ee3d4c96f4f094e1f82d5728a3a", - "senderId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_49", - "publicKey": "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374" - } - }, - "signature": "3044022032f2c350cc1319f5838d6880e91b49ae0438fb3a626ed9ab5e27ce8788e3347c02202cca18567c8491e0feea8a5f078e28605029346c509fac0c0a192e934f8c5326", - "id": "f99af0fbb4d65c2c3f2c1c558f0c0c0eac2724942802fcde02fa6da1d3a9000c", - "senderId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_3", - "publicKey": "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17" - } - }, - "signature": "3045022100f0cb5d885ddf3bd4a58837f9b86486da4171652a5eb39228dfd0ff9d34d9c7c602202dc6e3d268d745a7e8633311a337ec097382342049672880c7c2215cf58e5da2", - "id": "2dca03aed08533585d8bc609da5deb9f17ac9be5a8352769d7ae63d0db16ff59", - "senderId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_21", - "publicKey": "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a" - } - }, - "signature": "3045022100999f19fbdc9a12eebbb8c748a4cfc6c91b2233f333a09cddfd49dfeab6aaf38602203d8dc9d1551d400572a88ee812f51f897f8b35508713b789b2c1bf6dd0e88945", - "id": "5d7e51d57b5914ec201ab65a019ecdf651c4f267cbffe403fd2170bb95145f9d", - "senderId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_41", - "publicKey": "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f" - } - }, - "signature": "3045022100e86e648add940a1e637e32ea9187497c281b843da09597e62d0c927d7f43235102200479f64ae63abb55e338f9ce1073a5c46907f7a2a82ea6f9bd9bc29811683515", - "id": "eaeed4133da26612c53550b6572722d8c3380d0a2344da1bd270eed1ea91fdf3", - "senderId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_11", - "publicKey": "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904" - } - }, - "signature": "3045022100bc3b2ebc58a92bf38672206e8311e7ef0e54912abce7338155b11e7d191b0b5d0220765a568c1fa4665c0ace6b4bd3b7ba0f8329e2f25af7a3cc0d78b2ea398084c3", - "id": "bb91e78e43c59a19ac06c015d8a7ef09d7c5b274c9f98505e5a978027354b71c", - "senderId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_22", - "publicKey": "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a" - } - }, - "signature": "3045022100aae4868ab75a33e4e77f9bf6c53b920c5e7c523a7cfe271d1afc472655f3d6a60220499f1bcb79bc0fa830dfa939898db5c9fa8571a2788c8de0da7e550bfc818bcc", - "id": "a6e687647dde9c1db68690090afc4fcf11833dd35fff3186b6b709a1e7d24260", - "senderId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_46", - "publicKey": "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c" - } - }, - "signature": "3045022100c0cf1fc54705c13f70fde39c55a1703a4c612b8a919379cd5b1ada464c7cc8de022074ee62490a184010ad2418d3177ff2ab03d02d2589000176312b90422b1bd64b", - "id": "70262b0eec3ab5a60a736eb8a628cb600eae7522464a49791c0bf26e82318ec6", - "senderId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_6", - "publicKey": "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc" - } - }, - "signature": "3044022045db446b109215c6d3dfb0ee5869154a8a7624376c3760eec4fadc75a29033cf022003e524d64f3ccd0c6de4ca80a7327e2c47ffd16b3ad042bd25a02f5f64500ab7", - "id": "56048c449694964bee3d367609a7bc46c8da20f66878c09c01dcc53c3abd932e", - "senderId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_23", - "publicKey": "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a" - } - }, - "signature": "3045022100f8f69f2957781ed02d64983744c8e51fae613ebe5bbb330d4f509bdcf4fc6b6602205568ad1fd840e01ec26a24ac9a0ff093e978172da55d494138d018a45eb67893", - "id": "e15dfc4e18106480083b3c6211349fd9c803e334e9ba5eb62cca19ae3f57d8e7", - "senderId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_40", - "publicKey": "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689" - } - }, - "signature": "3044022021eeb9e1db8915a9adb99db72972cd17fc7b5b377fc532ac2c9deffcb2707edf022068b9e08f45bbebad89295f520ad40d7786fe64059d45df95551576e3acb736d1", - "id": "2bd0f888ccdeeca24a0134e3c1bf729582d284f32ee000d97f1417f1349a6594", - "senderId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_12", - "publicKey": "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12" - } - }, - "signature": "3044022040a9d0975f747df19792211546410d7c735aff2d26f367d1bf9233ffd1d993d702206890c66d4d0eb5de37df088c082d8fbd8da043817b48a76bd5d70f1e3f6b6529", - "id": "f75ac5ccd243e09fc9da2b3842a0654ca860d2dba5bb73866693a8a918937994", - "senderId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_24", - "publicKey": "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95" - } - }, - "signature": "30440220550c0ab565ab2de649ca7a2aaf2975453a1e4ab8b0d392d69663c0c9b6b80b7b022039047d4d1bf4e9b167a95adcde0a5a8631aeca060dfd426da28a10d968fb3a64", - "id": "aa2ed932faf4832848356beaf87e5381ee56a1a84fb485ba975acb28f8fcf5df", - "senderId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_50", - "publicKey": "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1" - } - }, - "signature": "3044022038df37ef25928d1a04516e982c99f49cbdc193603f814b48ab3802153bdd352002204c918915a3cbfa305c5f898ae4bcdd75394b57460f85c80daa0999751d466c08", - "id": "d30a726e1bb8d199d8f44700bc999c9a0a1a8be86e4be6a15764ecd424f9db1b", - "senderId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_2", - "publicKey": "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d" - } - }, - "signature": "3044022028dd44b9609b0b599c15a257757fd068f9014e33947c77776a6fcbe71879271b02200b46fd8eb0827da6de13f5efd63b17f29e8ba4600e4a690ec31eb08bf2d9af33", - "id": "1410b8b5f15c05528013378251bf5da30e04c8a6b7ac0f729b527664cfbdfbc4", - "senderId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_25", - "publicKey": "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964" - } - }, - "signature": "3044022038edfe34f7b89b4e69ea8b94e3335063b60deaee28246932147f53b2525924a402205b89f5e3d956aa49f24f81e2ba3447c19bd5c026568b3bef73a7a7d5160ad661", - "id": "58d14b74b71586e18f0499a50004ec2e0cc2e5b56aa53f4cf57084030ff90fa3", - "senderId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_39", - "publicKey": "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5" - } - }, - "signature": "3045022100bc1e477994bf4cbcdb5cbe2bd92c7d955a03adfe562f8e3bf04d2f62965e9f78022045512772d8453314361161b2bd2a39aa0a7fbb897a5a83f4c7ab54ced615b42c", - "id": "3ee53b3f1455ef0ddb52afe08854c9d87f42c7313babd3e05bb3ca4f94c495ef", - "senderId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_13", - "publicKey": "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f" - } - }, - "signature": "3044022052fe00e8e9f05b1d890f6910beab0627c823eb2d5875b4b9813a33aed11edfb6022034a723b827ce0e73bfdc0f535b244ffc983f8d549ee72b4d432de90d658db72e", - "id": "4a3d204c2916c93360d7bb11390e355bc1a930e3cf503965a45253d65bfe928b", - "senderId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_1", - "publicKey": "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37" - } - }, - "signature": "3044022013b2798a4ab4d741850abac10d962360cd4ab6a47dfac7c1c806d6f9c3d810cc02202742414ad8a04ce679b445fcd040fb877bbfed3d2692b873dec8cb46c01c8c4c", - "id": "7d0c5a44a7517f6ad7a1253db45d58e85aa1c735a282a32f45d28efdb7869d7e", - "senderId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_45", - "publicKey": "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b" - } - }, - "signature": "304402202c372b7b9679a8fe66f952a1d47d4327968d6e98770b215ada2fed6a8d87ed5502205a797fb511cfba557255dd37e028fb40981b7b65ad2ce8fe0e559a46eb274bf8", - "id": "70bfe97ae7452dc752ab4de0e2a0e81bd18bef07392c56e7a101257683d4d932", - "senderId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_7", - "publicKey": "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0" - } - }, - "signature": "3044022058851712200f7386d6b3c188444f9c8f05788667649ec17c71b9e514206eb105022061e6a4bc4cd11599792e03298f95509893d56af54d51e9f639981045e754b974", - "id": "f6f90ff09dee5be7d8f3d58d217772df7a95865bf8609d7d5b0b673e9a5bc953", - "senderId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_27", - "publicKey": "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d" - } - }, - "signature": "304402204878d69a166e60e0a779c31fbc48c67b70d2e4aed1d63c60beb9f070963e2894022078c46b6687f23493a4c2ed39709a183a0f7352568cc9cc2c1f0d7bf0d809a4a4", - "id": "f68809e407d20a50029fe460d411c866b79c7e09c076dada768a38d81f184aa3", - "senderId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_38", - "publicKey": "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294" - } - }, - "signature": "3045022100d5576393a1dea704cf79a5d0bc2757a3a5e66e1055103b52157fca05fc5693ec0220522832ce0e31b779decef83ac8ce764930de927df9ae1d6f6f99a3312d99c90c", - "id": "2ec6c6f33f00431ef063fbb8a79fb90eadb13a79bf46e6e1df36dd9434314df0", - "senderId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_14", - "publicKey": "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24" - } - }, - "signature": "3044022008a7d0bfe9c4c150566ddf701d08e84b4a5f84b07e3b1c91dde1cefa16d2a3c202200b787e898c0b2c68f4343e74f18ae7363f62b5f4ef2962386932aee09a9fa0d4", - "id": "e37b3efbf034bea4c852be7d7013978f8999eacc39549ceea775de197e14e8da", - "senderId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_28", - "publicKey": "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28" - } - }, - "signature": "3044022023b6fbfa5f4482a4dcc34411846696052b1592786ca87243b7d3344fc9fe9954022035402fbca22691de2497552c743f0f68c7591edd1bd7954ab7639548fcd558a3", - "id": "08268f5e6c15cf146523ca928f24aca65b162f363593d927c66144ee5df297cc", - "senderId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_48", - "publicKey": "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b" - } - }, - "signature": "3045022100b3cad169f29a3a95995b87e1b50b35583c1bff91d69cfa236f58ce452491c579022026775f4ef50b50ecf6d78b530b4633711394983456e6a45ec227b652c86e3014", - "id": "ad94ee2ae94813a638b93909930c7cc631c364b6c8528b2dcd6fa8f69260cc2d", - "senderId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_4", - "publicKey": "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93" - } - }, - "signature": "3044022007ac9ff2f272f3fda4947393b8688586cc8b2958ff5dc7931ac8f82c697bb76802202a66c28852bbff86ef17ac7f51e7eee52e611e825d91a9846f531ab3c3115c81", - "id": "76fb1984da9ef90fd7d588756163c97e00d3e4d6e9dfe78d9e3d3cb6d71ddd38", - "senderId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_29", - "publicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252" - } - }, - "signature": "304402204416e428688ad29928303fb2b00a26996cf79753fe70fb91c1f4635c644ba859022068ac5eab7d05f87c40ba36bd9dc149607c196778120c061698d7ab64aaade7ac", - "id": "0f442a91857061e87dd193b0b9f17a71719ca7e3da62841a63568713fc12b5e7", - "senderId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_37", - "publicKey": "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4" - } - }, - "signature": "304402206a248caa5949024202f297c38cee18845e344c5f140be74349787097d3b0a33c02207ac84336e02592bb5e00dcd0c490d30eb856b34177ab9ac03410d82a355a7b0d", - "id": "eed30a45c350fdffc5877458f7fe29f28dc4bf81aa1a197d003c9433148b71aa", - "senderId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_15", - "publicKey": "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca" - } - }, - "signature": "3045022100c99336ce666cb4a6db3727a61c04c14d8746365f72280d9984441b7d2b568b5402201759e4f417f683743e1d4a14f8a7a215009321cdfa29834b2dbdbe54ee22c1d9", - "id": "ecfba14a58f9d79782c4f905646df28bf566e3e7d1f17b39df6fe6b52c11de59", - "senderId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_30", - "publicKey": "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883" - } - }, - "signature": "3044022070de7b4d4ce64bd605c9d008142544c2b113cc84df07ed1982e0adf3cf69f4520220211b01710a6533a270dc2814c7f968adf27eb6dbf437e7a72960b013b9651a0c", - "id": "36ce5323859a92f302f77f27bd08ee3485d720f55842ccba353a47ea96a964c2", - "senderId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_44", - "publicKey": "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c" - } - }, - "signature": "3045022100a7c271633ecbf3c6641c7db36913b5fa0ea521f400a4848edf024648f3d7128002206a271f8a88644062b64d856407af9567c0b2937d4a3d89a3b3d07edbd3a0f177", - "id": "e120452e7c56a9327b2be7dfd3dcecae193f2e2e772903008b03cdf00146ebd1", - "senderId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_8", - "publicKey": "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564" - } - }, - "signature": "304402200394b6545015bcf2d0f291de57a4197cb6ef57b2ad5fa37f05e8a220913ba83502204d0d2f2206edba54ada5b8e5afd194ba83dd1bf15f744258409595251dbe3ff0", - "id": "7d15eee8e4e3be3d2c44acd51b87a816bdb593565d4ac358dab24ae9c8a5bae2", - "senderId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_31", - "publicKey": "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2" - } - }, - "signature": "3045022100989eb331951a13152aa03583efc765499e836c6fbafcafec4302b243ada8de5002203876fc4cf7fdeee4a095667e55a2fef84e5a7053e807b4d8e029883f0d578019", - "id": "baa686d521f95d265e7099cfd9ef14e0a9a92254dd94c16ce50c460bd013c588", - "senderId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_36", - "publicKey": "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e" - } - }, - "signature": "304402202be177dddfad323302565a866d38a3e7939e0234b16e7dc02075cf258502eba302200928a139ec1a82b4609fcc1bd6d1d027ad050e93fcd2eff94181936d2d43e39c", - "id": "9fcf7ec6fe98ed94710e212226d8b90df7e7467d66dd4c5c9d48474388be3099", - "senderId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_16", - "publicKey": "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9" - } - }, - "signature": "304402207b4f8c09a728acedf3b6ba0632e12d01670c683215053e49dde8598954d85a9a02202a7d7930baa17c2134b314e47dd6c334c828f78e573a2bf92fcbc1146d630541", - "id": "c35e4b1e7a2435664fc0939251c2052633ebf4b51fb22d15e71bfcab85b26de9", - "senderId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_32", - "publicKey": "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055" - } - }, - "signature": "30440220127d27312345e015c681adb799c1a87d16fb0caaabd5020b39257d567816b91c022018b2388f6d2d9afb3714d84ed102b3ea61159772786033c855947613c7ce7b5b", - "id": "0d682a3a9c252a674043bee5240e456dae2685d76fbd3bdeda6ff50f0c442fff", - "senderId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_51", - "publicKey": "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a" - } - }, - "signature": "304402203d0ee691830e4d001553bf4e49b6d9669b3c959376f391410551c8adc679dac902203ba6e275bf6d543efd19d20428649f802d9396bb0967114a1f09c24827be1da7", - "id": "ec2373b0d609ae72fb400ffdfbffc59670ebbf1c15f59c0ac22a4030dae700e3", - "senderId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_26", - "publicKey": "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983" - } - }, - "signature": "3045022100f2cf77b0510f589b5aaaf2b0027ffbce6ce8d4873cdc67dc8900865d156de3be02203c22e30945618683182f3d3873e6b3657e0900b062f866bab2705cd593669e79", - "id": "3cb2f0f7d05a515d4c5c873cbe96e33b1dfba1b7718e4548de7f9da54933b652", - "senderId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_33", - "publicKey": "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe" - } - }, - "signature": "304402201e328159172d543d2225c247c6b728800c52eb724f67c0e919f6b7215e6bd7f2022075fc02fe0b14a1499c5602d87ca2c99d6e789beaceed2b9702060dece872d14a", - "id": "2fd77e744399c9632cc8f106c39237f201dafda976f1040235359f99eea3b832", - "senderId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_35", - "publicKey": "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e" - } - }, - "signature": "3044022063903d82e8bd15a6741a298b9a6007d0dc3626acfe2f072c3b624ccbf91ce3360220486ba4cc5591d8aa31b77dfde025b61691dbaad0feabe13e840d26e40010c5df", - "id": "5baf9e318c9e4cb0513a21eaea27e51c849f95fddc963207fb07aa2fd2b9f9d4", - "senderId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_17", - "publicKey": "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357" - } - }, - "signature": "3045022100efc1bc16e0b646da48f84822543b62ef5253bfa98bed6613f2d6d4634076e61802200ef243f9dbac7633a8819ce45e2a85d0eacfdc9a33a92bd3a03e90cbd312b823", - "id": "b4a959ad75f81b7fdbb957c90a3a63a6c5589e7819e2c455733a3a2b4b034634", - "senderId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_34", - "publicKey": "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80" - } - }, - "signature": "3044022012e52a479648990bfc1ed12bf901cad865708ff45962c3724ea67967be4f9d0102201901525ed8dd090af6a2637c123afb304e9fd178794addcb88d916227e66887d", - "id": "6439f2308efe31ac52ad06ef1caa45b9abf6c589118b7997da6a287325ca36e7", - "senderId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_43", - "publicKey": "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e" - } - }, - "signature": "3045022100a0874d1582ce210081f7ab30e7f951dfb9ce8f512d237f8a8cbd5d85569ef3b902200f0053c05de3d6e5ada4e4cf1403a836779d653573c2f374055645cc954c4c4a", - "id": "b0733072e98d3d6afe977e32f3dd118c15e79212232417743ffb551dc2a2ba55", - "senderId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW", - "senderPublicKey": "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357", - "timestamp": 0, - "asset": { - "votes": [ - "+03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357" - ] - }, - "signature": "30440220158ed59156e0eef2d2b94a296451dffe079be701b3d74f0443ef43bc266b334202205a2c39f57abfcd279d568608b90884b3ebe107316aa7552eca35c743b318a47c", - "id": "ea294b610e51efb3ceb4229f27bf773e87f41d21b6bb1f3bf68629ffd652c2d3", - "senderId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7", - "senderPublicKey": "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80", - "timestamp": 0, - "asset": { - "votes": [ - "+030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80" - ] - }, - "signature": "3045022100898da9f693a458a6875344c6c4cb73069c4075904c75595ffbc665967d84b07002200f168aaf3ab1b52dfa74599394387dc4cf627a447fbc5a91000e9d251cdb20c0", - "id": "3639b5dc6d19d46d8254d941bf7ace0f3da8a7cf8a56361921b260820c7239cd", - "senderId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1", - "senderPublicKey": "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e", - "timestamp": 0, - "asset": { - "votes": [ - "+032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e" - ] - }, - "signature": "3044022055ed9a8b55ccb3bd0945a710269b6f243f1dbfaa28467d3218a17565eb0c962d02207d31561478f16d93a20f5454ad565dea24e8dda4ddc464cb011f4b6b360c4e81", - "id": "fe24509580cde0c2e2f49defedd3a0f7572d2f78f90b51a253b0d8cebd74c20d", - "senderId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof", - "senderPublicKey": "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055", - "timestamp": 0, - "asset": { - "votes": [ - "+0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055" - ] - }, - "signature": "30440220092f367f833d677e8d0609ad1df65f389c2c35d1501c71c245c2982e6a832268022018e67445f525613d6cb6ac0c9683bd0f55bd40d9c929165649414f083c9041f9", - "id": "6a76553db794ebf4d5f60a7d7d71cfe29f4dbcaad9610106fbc578cdc7167cd4", - "senderId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy", - "senderPublicKey": "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2", - "timestamp": 0, - "asset": { - "votes": [ - "+03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2" - ] - }, - "signature": "304402203dc028b5013c36b03f97b111a8d7c05d0cd8e505b0b0d18747c0656c9b5cfe8102205e9ce8a78d1183b3e9880c69635d04218d94d17808bcc3f92e7af53195c23daf", - "id": "0f9d7e7708918b77afbdfffb63eef8fe87ba36e0131c88b44c1a7f81750cc025", - "senderId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9", - "senderPublicKey": "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e", - "timestamp": 0, - "asset": { - "votes": [ - "+0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e" - ] - }, - "signature": "3045022100a80ddd7c3adaf0e97ab938773fc78a716f3054d7e03afc1ddfcb5005badbd2810220231c0dabe2262149f994c939f9dc90d46b9bd7ca96b19aad6788cd3571e4f71a", - "id": "0ac77b2637fb25be42b3b60d1651bbbd788aeaba933a08ec4a417c7b4c54e087", - "senderId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT", - "senderPublicKey": "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883", - "timestamp": 0, - "asset": { - "votes": [ - "+02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883" - ] - }, - "signature": "30440220772c9cd8b96f74fcddc429d57d466eca6fc40fc211845f59eeb78cb027e116c5022004cda291587eb118d622de21333d2a5783969794b5b0101ad8b1044c7d8058af", - "id": "4b0dda465564d53981c0e36d73caec888e3523633eaa80dfb99a9c81b2604c7d", - "senderId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU", - "senderPublicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252", - "timestamp": 0, - "asset": { - "votes": [ - "+0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252" - ] - }, - "signature": "30440220406d54714b6425ae4553ea8bec75f31fe52e9b1a9b6f6897151253ab7f637d3b022040a2df4b69840f4d9b0b67658c75efdae8d8269780d4cc50d055fa63922dbb9a", - "id": "c7db9d36d97ff0168d0d670ec695e1dc786dfb93f4081586870c8793b50e5f17", - "senderId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK", - "senderPublicKey": "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4", - "timestamp": 0, - "asset": { - "votes": [ - "+030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4" - ] - }, - "signature": "3044022018b7e51118ec83c985fa4eb3d7f0cf0655753bcbde7e82bac521665fb1c0ffaf02204e2ace460b2542db8c77e41d05d5e02fa5514b746a0a1e947256925846ed19f1", - "id": "c41f4cffcdd523f1718154d5bd5f4f0bec0376076b5f8dd340337e9edb4821ae", - "senderId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW", - "senderPublicKey": "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28", - "timestamp": 0, - "asset": { - "votes": [ - "+03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28" - ] - }, - "signature": "304502210088dbe249503da43c157485bfd4f2c95babfe4d0b8bbefe44afa52529b824a79e022045239b6a374fd9aca52c27171ee66b4863c956ae4085c9760d863b1902596c1a", - "id": "b1736ec6a1ea4c6d4eb278430a8ee214c88daefe296ba98530e692f8b7a7434c", - "senderId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej", - "senderPublicKey": "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d", - "timestamp": 0, - "asset": { - "votes": [ - "+02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d" - ] - }, - "signature": "3045022100fcdf750a775e728a31691a1b38908a7f990b579da510959cc2c63442f5ffde760220316ebb051d9fecb2486771dd39921fb12675b6d46b2441dd1db3c42fad0a59b0", - "id": "069271456015c2ff842771775993b8afc3404bc070572eeeb0f2fd72d58e18dc", - "senderId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U", - "senderPublicKey": "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294", - "timestamp": 0, - "asset": { - "votes": [ - "+0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294" - ] - }, - "signature": "3044022034ce8f77ea9d0f5cf3a9135d7b72d0ba3b96ac6d7eaa3670e9956aef2c9a83cb0220626d1f269128f673a23f9993ce00ba78a08103e697298be29a4c8ee94f204e3a", - "id": "9a99bba8340e7ad4e05d8424a0977ebbde428d31ee066c9828bd06b42bb42a72", - "senderId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2", - "senderPublicKey": "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983", - "timestamp": 0, - "asset": { - "votes": [ - "+02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983" - ] - }, - "signature": "3044022039ae1155f8b87a61c38b25cbbf30da6ecf6cfcc12b25c2e7fe576373754a41eb0220061a66a893129fbad5d48cdd19cf48b1a0d133dd2f3ecdc60ee7b87277e1f81d", - "id": "6c2c8926420ac269b50fa30127e0e791afb2131aff5821ca7aa80d38a0182048", - "senderId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf", - "senderPublicKey": "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964", - "timestamp": 0, - "asset": { - "votes": [ - "+02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964" - ] - }, - "signature": "3045022100d0dac2b7691aa059b1048d7925a0c5d5099f6e9b0f2e321e6d4f128ab1b3272b02207e8c4f643f8f9d1c3f81f0cce6a698df2da2ab71d5b01042766bbe0f46f4a775", - "id": "9259193c5de72276ed7a99f9d507dd6ea9856411fda521074fb41a556294fdf7", - "senderId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9", - "senderPublicKey": "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5", - "timestamp": 0, - "asset": { - "votes": [ - "+03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5" - ] - }, - "signature": "3045022100d5496fec447367ab6b53956a8c40cd8566e050ebb3b92d2c0b2a9d09bef36c7402205e32367605372375801f7b9db39aaafb46ee763b1494f0aca144fb91f3415752", - "id": "2a41e5946ab0773ca2334bba9d3510184bdd258f1c651ff8ec95b7b64a01dc2e", - "senderId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW", - "senderPublicKey": "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95", - "timestamp": 0, - "asset": { - "votes": [ - "+039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95" - ] - }, - "signature": "304502210099249695dc38826e04c8fcffd2570b98c43dec4788cc6a19737ed0872f17ec3302205301f645d803ad5df4ab1a700446e28c7cd76153607f6a2d68ae9168d46f3fe9", - "id": "e5c09b0fb2c24c57a4dcef0078953093800329ab4dc8e16a9d9f68215b5acd3d", - "senderId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU", - "senderPublicKey": "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a", - "timestamp": 0, - "asset": { - "votes": [ - "+034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a" - ] - }, - "signature": "3045022100f983b03e319aaa6c6ab6381e3ef8c0c035d6e3cc2139cedf70fd4e385393e38a0220286f73577765eb3e89e362785ad8a6de572bebf41bbc1f515b0ea93e41801eb3", - "id": "00b2c0455ef6f508d65f11bb49e3cfe1e6062d5fd153cafdfdfd2ccbf9c646e5", - "senderId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr", - "senderPublicKey": "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689", - "timestamp": 0, - "asset": { - "votes": [ - "+022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689" - ] - }, - "signature": "30440220103862ec51621ca27a0ec6b2817848e8824d2d09dbf7e6aac2f45aeea5d2dc9102205e8cce78b5cd7148aa4d406dc7b491dd7758047200e10cfe1e5fde5c56107ac5", - "id": "e25439ad11cb8db3d49ccb3b8b608c1bcb24cb29b2e5ea15101cce3e475224eb", - "senderId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ", - "senderPublicKey": "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a", - "timestamp": 0, - "asset": { - "votes": [ - "+03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a" - ] - }, - "signature": "304502210099241ced4a0fd1eb02f5cdcc880ae5f48eb3c7e490d4520c20124ecbf403893602204729dc6cacf3e87c97ca57c1be54d1e80791bf31ef022135e68fc06c950f6994", - "id": "1474f50815c6c7df41ab652414806d61abe15bee0d41f32d772f4e2793badce4", - "senderId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX", - "senderPublicKey": "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a", - "timestamp": 0, - "asset": { - "votes": [ - "+0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a" - ] - }, - "signature": "3045022100eccf81d44992c49a5ee37c6fc2ccc4b6bee9aa44888513b3e18e79452ede3156022056b0ddf079d2918d72e8781d3af009c87e6058563591dfd6ee0117b7df5534b2", - "id": "b394e2a8b5c2d20a72ed288408b8f0d48aed922edbee6e16c1c5b0e67517214c", - "senderId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf", - "senderPublicKey": "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f", - "timestamp": 0, - "asset": { - "votes": [ - "+03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f" - ] - }, - "signature": "3045022100bdb87894846eccc5a5473edaee1e6dca5f3469963e22f06123b6bde195aede0e02203d0c6833e87c5e60f4597ce624d4c2502a0562b4e54d943f82a4889e3cd69532", - "id": "6a399099bac6c74fa5e956512ef8b3a39f6f946d5d6996f192c2f1dd5ba172dc", - "senderId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv", - "senderPublicKey": "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751", - "timestamp": 0, - "asset": { - "votes": [ - "+02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751" - ] - }, - "signature": "304402200785771ccf1a6a40b51183a190d4cb4ce76b9ffd4c2c736d7724e6c667113d020220649ecfe73017d8dda96a7914793470ee7e582693e4866df123b1032194c163b1", - "id": "f20a831a6bae0a85470e308fb66517e70db479657459f6bb39f2cd1783c565e6", - "senderId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv", - "senderPublicKey": "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb", - "timestamp": 0, - "asset": { - "votes": [ - "+0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb" - ] - }, - "signature": "3044022020b79e1f07bcb17cae9485b9f44e9f583ca235da4ddd363b905fafb884347f71022015a20481b43720ddb3b1e3ca64b1f47e59b5cc2016a62f43327ca14533384dd4", - "id": "7a1285be87dca9718bece5b84266c1bf6801a39cc111d534e660aef9e6d26929", - "senderId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg", - "senderPublicKey": "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d", - "timestamp": 0, - "asset": { - "votes": [ - "+0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d" - ] - }, - "signature": "3045022100b1615d16763c46d42ca2aae967f04c1c07c119b5af7a378c262ba85515a8d35002202cf7df91676cd137943720e93f06c11907412a6bdc5ef2157cf536a203cf83a3", - "id": "76fb5a1de90f245b1eeb79cb11c7bea7c8b738add0fb8cd95191186a944b0229", - "senderId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri", - "senderPublicKey": "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a", - "timestamp": 0, - "asset": { - "votes": [ - "+02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a" - ] - }, - "signature": "3045022100e3c7b5d6a72acde4d22e8c1c6cd864c549deba89683f4b84320407d6c380827c02202da57df0ab7cd381b776bdf85802aed371e7cea7269a84f911b1d8e9956badee", - "id": "8da75c8100e6248ab37cc92f72ed9facec3067f4f82f03db8bb8063791463fb3", - "senderId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t", - "senderPublicKey": "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe", - "timestamp": 0, - "asset": { - "votes": [ - "+03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe" - ] - }, - "signature": "304402205779b5d8acbfedfc105fedb6fcbd4636713ed27605faa9bd988598072640a958022042d8a8b3d7910c7c385f3707a317c5d445d56da250f8d127c71df2d9d4c5d86e", - "id": "fd26e265be88289828d0ce7ffc5faeb9849e1f4cb37a8f1dd5d6fcc436d910b7", - "senderId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf", - "senderPublicKey": "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e", - "timestamp": 0, - "asset": { - "votes": [ - "+034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e" - ] - }, - "signature": "3045022100e18a89fe1fe0a8acaca2b6461314e784ffebbe7374f6aafdb06934e83985ccbf022027314b21a4a25b477bd7cc070b4e00ef8f3d69f3f1af028b96571dc245924c00", - "id": "41d92e128e6b8367cbf8fd111e5263d52e1abad553653f975dd60d7f7c5b637b", - "senderId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9", - "senderPublicKey": "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9", - "timestamp": 0, - "asset": { - "votes": [ - "+02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9" - ] - }, - "signature": "304402201c614c84dbae26f87973c9e2b38df883fe0c8c469080e31fe32a4c4946d50b67022075b8fb498fb1384aa6be785845da02813185ccf095597b5782618033828af4d5", - "id": "1e4a1f8aab6fbf8682c2b35e0d04e9e007ae717ce3f4a82894747e5807e3c759", - "senderId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV", - "senderPublicKey": "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca", - "timestamp": 0, - "asset": { - "votes": [ - "+02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca" - ] - }, - "signature": "3045022100b1ee6becc59d594776a40e5b3caec82390d273b703ecb0d7caece44953141449022016543cc29a28882845118afab6e51296cd216bc662260c28e5efd9597b6025b1", - "id": "2ce068bfccb3f967f4004e9a1e81614a738e55e45c80114c0af30a085f71a2e9", - "senderId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ", - "senderPublicKey": "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c", - "timestamp": 0, - "asset": { - "votes": [ - "+022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c" - ] - }, - "signature": "3044022036698a329d7f5f751f91ce02bc188a7527a377d01583b70427cfce64def945ec022079afafea10aa32394a1e42a80577de3869856656221d5f259e05fb44f01668b8", - "id": "3478d1ad3655e10fcc864f191972322c866616866bb1dbf66d7b66b31cd95de6", - "senderId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA", - "senderPublicKey": "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24", - "timestamp": 0, - "asset": { - "votes": [ - "+03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24" - ] - }, - "signature": "3044022035fa7be80cf881eefefc12b11de04ffb2e2e92815cf05074afef54a3c5b2eccb022041f3347f59db0b3caadefcbfbc5ae275d3fe3e2a52fe1504b23628d4b79a43bf", - "id": "8adfd8e73e96188ed9fdec459d88db1fb041a2b25b3f64830476aec661ae5010", - "senderId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm", - "senderPublicKey": "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f", - "timestamp": 0, - "asset": { - "votes": [ - "+021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f" - ] - }, - "signature": "30440220630da8a73979bd3988b7f84fe9e83a429cf3239f54c140c3dbcc407140513fc002203664ad54ed9f199f2683479b988bd97ad8fffb2c2d5dfdbdb10858aca4abfaca", - "id": "e306328ffefcd9e3809e7390a358199a62cf8ef037d57af1f5c7b54d728d427e", - "senderId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1", - "senderPublicKey": "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b", - "timestamp": 0, - "asset": { - "votes": [ - "+02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b" - ] - }, - "signature": "304402206f1df93f299ffedacc25aa201807df47d32c43369315cf9db280963c357be56302206a66acd553710f49bbb7b803a2bcb71128c8e617ffce66b37b7c968817349247", - "id": "dc69bc8f78502ba34655ed062987788939189709a4112760cd8807245d7461f5", - "senderId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8", - "senderPublicKey": "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12", - "timestamp": 0, - "asset": { - "votes": [ - "+03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12" - ] - }, - "signature": "30440220629e696a10e04d4fbc10a5ac443bf9bd40dd5d89d4b214224abe47d7ab5600340220643f361a24d9916e2c5aaec7bd7d8a6a0d3ffc5fc0b62c3ac4906eb799a862fa", - "id": "c3f49fb80c40f7779b32ba23616f5573a6ba58fc60c4629c2252933038dd89f0", - "senderId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2", - "senderPublicKey": "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904", - "timestamp": 0, - "asset": { - "votes": [ - "+0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904" - ] - }, - "signature": "30440220660f9604896dad2a97820b0d7524f0bce5a8b5766f150517d5061fd02bddf768022055e87c25891d4480e66e5d1a71e42cd5a4bef3ab2b2651cd72d44f30a4b32309", - "id": "8e8ac1b1a586e86867abbf25d63387bb6dfb793c691f0b06333c1581a9a568b3", - "senderId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT", - "senderPublicKey": "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c", - "timestamp": 0, - "asset": { - "votes": [ - "+034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c" - ] - }, - "signature": "304402202e2ad64129f61ef1156c4c7e80ab862d4823d62dac502685f53028536ddfb41a02201a3ec777fdfe8fae9f7cd5251fac322c1b6a2a4d41b3ec456daed474986d4872", - "id": "ff73565c373f2cefebf86c72dda3a6a6205750eb03b69178cb83378620715e1d", - "senderId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q", - "senderPublicKey": "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd", - "timestamp": 0, - "asset": { - "votes": [ - "+02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd" - ] - }, - "signature": "304402202e5c78cf21a088db10e1e1f64d98d84c8d3294fde7bc322d4af06bfe99d4c2e302207e7912a16a37b641a9f8c7c722f2b0d699917ca73e4d0f21584b717fb7f02f13", - "id": "3822273b496f2e253081cedf382e4f9937713fabb83449e1f892377cf536e68a", - "senderId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo", - "senderPublicKey": "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647", - "timestamp": 0, - "asset": { - "votes": [ - "+0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647" - ] - }, - "signature": "3045022100a65ce45164c9bc3e018e26703370c9deb2933ee3b4e814619043cc37c4a39c4802205ae4931ac9e8dffd714c3b601fe248a49c0185c8367887205f497d951c52eb54", - "id": "430d6db0b87c25dce4ce14ac907c13bcc6efa5d95135f05aa4ba7596ea9d400c", - "senderId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN", - "senderPublicKey": "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd", - "timestamp": 0, - "asset": { - "votes": [ - "+036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd" - ] - }, - "signature": "3045022100f3cdd7f688ad2d7b6a5b9cc7e793cb8a6e6e07d3327bc67add64691a53fd2911022026ae1adc8f4fcfc01bcca3efc83019026755b443a504265ad1f46f69d1f5951c", - "id": "dda86ecc0332e6c4eed1c0a5af7424374089b85dd274a300fed51b86e2655587", - "senderId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj", - "senderPublicKey": "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564", - "timestamp": 0, - "asset": { - "votes": [ - "+03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564" - ] - }, - "signature": "3045022100d419072a752acd55792257c96099fb14c56c29112a00535d39bca96fbd7951c902201abdf4db247dc956d79f4543c389823fbd1a9337f95d30df39603a3b52486bfb", - "id": "0998e9a055c53bf6697ee76af94c7a830c1364016d78fce889a21bc38ed70cd5", - "senderId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN", - "senderPublicKey": "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0", - "timestamp": 0, - "asset": { - "votes": [ - "+022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0" - ] - }, - "signature": "3045022100ba1e0ab761326d2a53cbda2a4a5135033c94d8166864d2ad3ceb963b4a0c046402207d755ecf4ada9fa2a598fd75e73a59d30cb83e01f510020b48b6bf162dc60b27", - "id": "be13743deb8486a575d1fb564d2b07d797ac77148d35793c9aca43c0d47aad61", - "senderId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA", - "senderPublicKey": "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b", - "timestamp": 0, - "asset": { - "votes": [ - "+03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b" - ] - }, - "signature": "3044022038a491e2e13ac32025209d00aec1af31b73a8b6ee77ad9b8bb80a34f5df59dfc02200ce82c89fe9f88bd5af236ceeaa80f9954e3fb4af7bc884c447505751d49c134", - "id": "f1d3d44cc289837de9623cba8891a1ed1cde8918473a91e2daead29975afad22", - "senderId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx", - "senderPublicKey": "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc", - "timestamp": 0, - "asset": { - "votes": [ - "+0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc" - ] - }, - "signature": "304402202ae599ce389cd030b8ab48ef53113458b9ba8bf9c9ed09c662eba2849bf540f802202ed63f8af492dd0b67d1b451170a989418a42466a3a7ffe89c4c5a18337e8fb9", - "id": "65ab302a44ea7550891eabc3b4a8d5ecbcb80784c4666195d5d0b7e33394300d", - "senderId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK", - "senderPublicKey": "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565", - "timestamp": 0, - "asset": { - "votes": [ - "+026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565" - ] - }, - "signature": "304502210088a3a4e82d307c238e01ce154b57631d4429e0b591e828ec36839a783736e842022042c6e1d719781e2edca3dbfe84ad13b9e490821a47ccadfcff379decb9c873c0", - "id": "d26a7ea56f398634a81086bb15c2f0c863c71b8bd728304d324d8245a8fb6c73", - "senderId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz", - "senderPublicKey": "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374", - "timestamp": 0, - "asset": { - "votes": [ - "+032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374" - ] - }, - "signature": "3045022100ae5805541f085a50076835422b2581d3b7a128a05b4f068ad7e3c14cd02799b802205f4bb40e06f90e02282ae74c0aba97923e601fd78234b9585468c4fb73f47893", - "id": "02504eae7ff4963c081219523bc48d7a07de4c29fdc1622224547f9a7c133abf", - "senderId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp", - "senderPublicKey": "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93", - "timestamp": 0, - "asset": { - "votes": [ - "+03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93" - ] - }, - "signature": "3044022078d38cabd8f427ef381d0aa6a0b98c6a590cb18f47acc1d80b429a1c1959b0ab022022a70d4d93d650ca3121dde6065e80cd90d1e2e91cb90f0d0b2eadde609e0d75", - "id": "addb8c1baa833baa52a5b51d8a86f8524bde826b5c9f0a99e57070e6323e1dfc", - "senderId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv", - "senderPublicKey": "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17", - "timestamp": 0, - "asset": { - "votes": [ - "+038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17" - ] - }, - "signature": "3044022076dd065e3fba825b77884a179d0231d7fc9e7d3a02e34bc6565fab81a84e559e02200a880c028e690a9d6f2c4c6576b1bf3e913817c834da8ec6afdbadfae78d341d", - "id": "72f31f9a829b93045ef2e860b24c33b9be6a2621c26914acd42121215c1d517e", - "senderId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P", - "senderPublicKey": "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1", - "timestamp": 0, - "asset": { - "votes": [ - "+030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1" - ] - }, - "signature": "304402205261d9d8ded6364fda8b10bd477982be84990cb010f9214d52c492676814e1f40220489f441ffe2478d361a12ab96caa59da495fe62d61d0e2255aa5ec4ed789afb8", - "id": "1f17b4ba072d205761ed3f786491eaf684ed3601b69082e487e568aa74a319e8", - "senderId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd", - "senderPublicKey": "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d", - "timestamp": 0, - "asset": { - "votes": [ - "+02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d" - ] - }, - "signature": "3044022040219da41054a3eebd3122df7f09a62a4e8b4fdc287ae77221f2217b42f291ad02202b9a70c54bb546a604eafadcc086ef6b6570f57542374d87de02ad7f61fe51a4", - "id": "5fa837023159d6a3d6cf7c5b2ed6fe05ff7df19300226b2f0be5a48a06993780", - "senderId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo", - "senderPublicKey": "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37", - "timestamp": 0, - "asset": { - "votes": [ - "+03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37" - ] - }, - "signature": "3045022100ded426768f114f459485ba6ae293c9649b340cf2dcb15e8e887fbb5fed6f7e0b0220752297022de6e93ff64bb9e07b4efef8e946cd2872f84d9e1cb3165ff5c342cb", - "id": "0a16dc31514629a36d7237968ada6a95d6cbec027b7d26e1e0f0d7d4febe9494", - "senderId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD", - "senderPublicKey": "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a", - "timestamp": 0, - "asset": { - "votes": [ - "+02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a" - ] - }, - "signature": "304402203aa292e7aedcd62bb5a79c2521b666b8e1886b57923d98f51911b0461cfdb5db0220539657d5c1dcb78c2c86376da87cc0db428e03c53da3f4f64ebe7115998f00b6", - "id": "8816f8d8c257ea0c951deba911266394b0f2614df023f8b4ffd9da43d36efd9d", - "senderId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD" - }], + "transactions": [ + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402205fcb0677e06bde7aac3dc776665615f4b93ef8c3ed0fddecef9900e74fcb00f302206958a0c9868ea1b1f3d151bdfa92da1ce24de0b1fcd91933e64fb7971e92f48d", + "id": "db1aa687737858cc9199bfa336f9b1c035915c30aaee60b1e0f8afadfdb946bd", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100ffff4e9ba62e5e3beb37deee052824da83c4030925bce09f190151652d0669b8022056a432e56a2e1b026d4b54f6c34ce88a0c9cebdccc730659c03449fe878c66f8", + "id": "0762007f825f02979a883396839d6f7425d5ab18f4b8c266bebe60212c793c6d", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022001a6326e5d1eb06d0ba1fa39446bd6d56ea45f0c269ebbce5dfc6a649277cfcc02203b252d3a6ef2b22349d9d0a9110ce28a199c39dc8b911edfa82c297a02009d07", + "id": "3c39aca95ad807ce19c0325e3059d7b1cf967751c6929035214a4ef320fb8154", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304502210084d855eddfe616cf1dc238b19226c7959c2fc4027ae2e8aea6fd8e9eb8928e6b0220440f980e40c1c56348782fd69d49a96944df7ee5b68d18028600e0e7501d4000", + "id": "9fdf6ae86f7c005b3b7dc1b9fb6411219407ecaa93adff85fdb61710f5121638", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402205438b8b9058bbde5d30794e7681e400e52b5fbd22324c5b6b521f97bc8b8aabc022000fe04d7afbd2e668b1d4576988ed596dc92251e33efebc081e2cba14ad5a898", + "id": "1d7c68087c875d7ce555b2c3e71e1d91a1ad62d0c2497efe3cab91415e634041", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100b2e634a95b011a68489870f003e4bac4a4f0578bfdc6b9f645c934016c2c0463022022cd4ebf276dd627d98be4b697bae2df10b86d94e984da2eb7e011b08d6dffd2", + "id": "0c993e115ba26981b0be9d22e7c4a13b0f106e0cb472f9d34eabfc8e414dd528", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100f965e5c280acb22d1cde405223fe9a6fcb765844adbc5321b17a268924e1f597022043d31b1edc5fe0cf60a960d84e3528472cdf34560c9463979043a409f37e7f29", + "id": "c279f2eb1f9e6e7d4b0ba7a98233a0f1a2536231976c99f56f64b248eb06a0c1", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "30440220715463c316a75959dbfb6a59a013fbf914bef1ff739ac8000d49dabbf5118df9022019345ae1c34173dc214bae82f3cfbf438092f0fd2d277acafe3e9deb644b1a3b", + "id": "7e2fc9ecf23e909a3d0fbecd615445a0eed8c2cef18e01b1492d63f616f5d87d", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100fdd8aff26dceeb5abb6e5e8a8f468c8ac1997a587225298e3d8135d57dadf4dc022072ab80a81b301a162ed5cfa67d213d5a3980185088632f5f592351aff8aa0e9c", + "id": "511c0e1076104743f98932f8e7720bdb3f1539134edadd331914fd9ece1ebede", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "30440220635e04ce278870f17fcd1883aa26c568e63dfbdd302add39aa30fd3637c79c2c02206fdd9e7b1f4d238a97d26ef1758927e2d39f121687490f2bd79831e36afdd43b", + "id": "0768d5016c53d884e3d68a09d1bab0d730b7067c71ef4ca1c4d61b3815f5ff66", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402200b1dac57ca6565ac31afb99686f2e0f0e8dc219b9860b295ca5444a1663cecfb02205787393561fe407449af4aaf2f621db9e4d3f11c7438666cd694d495c0a0c41f", + "id": "1aeb50080ea118165e5041f7a897974c2ed1ebde08add85dc78cc7cf73566a91", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304502210098dea25eccf31ce6f874a9528578805aaf07be8b41f1571865793f9e3e6e3c97022033ae9c73dad44c01fe6362665fccf63bb1a0ae8e26f77a1cf60b67dc96b05343", + "id": "254f0f4fa277cc651a746d6ac371eb27afc3ea155ba060552dd26b8e83d17b72", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402207f4bf346aac501e766156818089fb16905a9bdca69ff6d5a55ba918a08afc7ab02200ec2c25cc4bb30e2c176d55630d8e2679b899c14ab4ba43c3d62955dd940425b", + "id": "e5ebb02e8e8a6708e22ee5ef99fe1dd8b6eea1095be6b772aa21bf63cf7ade5a", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100a0bbc15bdad648bb9b439f1d34b12b853442d1cfd4ce7f569905082801fa58e8022036b4e73edf7ab7226f8007233f77b1d497cb6b4736f02721bf1b399312ebe114", + "id": "8a686b21477b64dfd85f08f8598a0f121ca1c7d65ccaca9e42326c75fb5f3abb", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402205d77dfcde527dcc6669bcb01c27b92c1a6399e35ebac9e69415645f596ab1d2802204179497bfd952f44d5f9e295b2a3219a290a4a82841c084a18553b7712e26415", + "id": "21175347e2acfabc09a7593aae0682e39fe7152199a90561c11125f525211243", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100cf77c16df9185727ff717b71a94f8b29ceeae1e5bb3a28da8cef9df5bc63b7c202207bca394ce9ebd344a548e5a5697f672dedbef640dc1f9105f7c063287bcd1840", + "id": "ce1d9b7377551f36568127f5b635b5443f5a58abba6566b50a8d4d7b53c8a874", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100eb8daebb5484f3b0a738c9344fb28298c596f9486963f8fe36e2501ee6876f2a0220559df66986dc9a9a8e76982ef85f907c62745757990c69f0b17b6ae5a7ca4719", + "id": "b56702f5eddad0d8dbbb33b6b1ca3e07e4740def9c5dd2aaed9a70b90a4e31b7", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100d088e9bcd78978f2d67e7c7bccecfb73ddd0d1a2dad5b039390812320355722d02207affe83d815f04f6b11abf98eebe0488bfb87f8cd6513d44b829008ed1c15ceb", + "id": "a73c053c42e83a83498cf58e5b077b31443e265ddf8228081cb17a36bba366ae", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100db16a8e9682f07efb607bc7c75b654646ff449761ed146ab9358e69d29fadd7f0220436554ad78db0e04ae5b573258e2c8067848e89b55a6e8e1e25011a43882a643", + "id": "2dccb8b44ad2e598673628fd9d74e336b467a0c941d5e257dceb85c8e0a0000c", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100b03738eccce8ad0b8ac0a656119c2cdd202089c5650d8e1486bd13eb9c3158980220059079900c7fdc16e799c50dccc074726fbf0068044462faabdf1e73f9f9bc38", + "id": "b2cce30021d139f97925807da796722bf4d5459442523823388c259ca5ad73db", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100becb49fe5edd6806d5ba6eddbbb34ca8eaf3a12dba123d1610b2b120ca8bd017022072972992ee0ca0f319ae754a2a5a10d715a08b23f8239f9d6d59774f790543ea", + "id": "9e4841f43ab355be7a4f93b09f3d82c17065fbe25387dd6c5eb4e2692ea05b0b", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402207f1a3fe8c5aa7a77a58ed35c34f128b5df6fba89aa918af35eff432be7d1f8e00220460d4f2a457e1a477974157e33bf2974de6588d56e59729ae980720e9794827a", + "id": "2c7ca823be21724a4876de632dded3b9afca45df357819ed028488128d85d29e", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022067266dfe9d8f2550b590e1eae2f73d28c6b80fecb24c3eb1b4539bc864b3b4f4022031e5122145c35874c0c48673d088e76fb3e11c308ffe9d5dee6431d3441d627e", + "id": "a91119f04e2201184761f7fdcb26e4aa81c7e1076cb11a58a422d351241d4e4a", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100b970ec89927de0cb7805e614a742d42c2967db5a9c68d0892956dc89d68ca7d1022067fa30265dd2e1a2985980be2bf876748a7a8c7f3cde0382265b601fa658dc17", + "id": "94955e6bac6269fbd19e92d2292ac947225fc6f68c6216001b528596a961040c", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402203671b82ddf8a824b8e5aac8bc28be4aef1c00aca1097d14ec1a55003d7a3f28d02203aacb6e7517e916478432b81399828ba7425183ce0fc43feb361bcf345fb0519", + "id": "df563ee9822bd3d7aada600d4800952743ec64fafdc7697428d7a19a60745885", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100b77653317c93eb20ee19c71e64a7f9ecb985351bfb1fe351ac65a5738cb37ae202203d540395e1d55f87caaaa867afbfbaf98c553be0b4c7d1748418a76b0c258c89", + "id": "d21b6341e2b4be5ffdc3dd8fbcdf2c576ba02e2ef4ab5eab0e4bfc9da4e9e442", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022046239e39062a58925099b005888355b8cd6700af66972bf509a10123f9abdec60220202321ea74e56177606fc079d19c29851d832e6d00c93985ffbec3dba6f0d675", + "id": "df6bc7a17ad34f8e9faaa2646e8e5dd8bca35affba352537184f690e200e17b6", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402204eeab87f7ecc2097b85606b986177964f3ae777535f6fc0cf08a55fec587d87602203779d59903b8de63511e4ed0a7967bd85e9cb1fc9d84bbc5091e3caa87d8bd52", + "id": "5f0d5f0dff464d0ad587da5bc93e600a8e2657d359d0a1224bdd4ccc3b6f376a", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402200a2b9d0f61066fa00a2a2882379aa8ee60e949bdc2a85103bbbb69ce3eafccd9022057364f349faceb3047fa95ada210c64fc4a81978d66925b37d3dbc21ede885af", + "id": "1b39e3702576e6ad7775e34d53e43210549d52a56b3f246031e6ba4121a66bf0", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304502210099e568d3d0c1b48410e0b85c74d04234dacfb2fdf2b1d4b51fca1cfb3445347a02207a2509645aae54560762a37422b66ba4b3ee1c42de35d58c36d2f9d8fdea11b4", + "id": "0f21e53dbb1edb1cfb4c31bb675aa4672b452a03ec363a2b3300a9dda49e3be3", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022026cc5f2b588a86241badca73cd9c1686916d516b8c6c397c66a9d5bb6b5d4cd402204ab5a8c8589ee954bda4a116999d2a0e4ab0e3e96f0c7fe131d7c57b9a1ede43", + "id": "410826c255a23a78ac5c3aa10dd48132693bc955845af16c20d9c6f69b05dfe9", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402205fedd8d3b5c8d69cdd7db5ca8e9e7c5004f6ba751e45eb1b85b26d9e89800a2402202be56bb2cd824bccf325b6b11432bf6d0ddb5ec97fcc121839ac2ebf884c7173", + "id": "ddb57d8270b2b6c876191c1e1c5974388b9fb3ae0980cb2245d8a7c426237f47", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022053cd42ad147eea33801b2b57388b33f633b4bfe2ad902190e12480522250d07802203066dc0d0c2ffacc4c74cca1e0187fbea1cef7e78a78666d2ec7e4e87ef546eb", + "id": "29e1aedf98935c369946c8dadb2d6784f9ab5ce8d73b9b4de2466c7757e2557b", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100c10448b87e7176735c8ddfc8fb3c4d5d55c2d71d18b7ce3ab321209ec299fd41022013517a09e4b366ab386698286ec7bb20410bdfb7f6674fab25a739259083b297", + "id": "4cf04852529b5525f22cc540790e36e61ed36045ad1b5b788f61ebe42637391e", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402204cc1588b204ebc0c20f44a31ce53d15ab5e4d1f9c103c02dd4e4eaa1c33630b40220194b6e427b6def0783461cd8d765f97b105d048942be468be2ee9b0a2785d2ac", + "id": "35c6bc3f0799d9c79efc6515f232c58be0d03a3a797d066cba879eef4afaae2c", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100be44f7ea12e2ee89245fb474643ec6c2c75afa00276826a4ecd6fca4cad5ff30022071a2c083b353a821345e4bbf74d98db0760b8721856572572cc3436ebdb8f08c", + "id": "45f75a349f3b4d73434c0f2ac9c291d5d07278b79e6eaa0d38d6e005f66c4783", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402202090f506e8f18fde70b87a3fd6c470a23e9e262f20ec6268dd59b6362e51a29202202b838c598b33c6317c998dc179fad2b660b8a72bfaf8223d7cc82414ab4c6af4", + "id": "a8d9034d1091a4dbe595647ad5f64ca8b243e7842301aee48f7eaf8b8ae98119", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100be59b689a48e198267305f1ae7e116f69f7c360857ea0b1fa81db122278cad69022033436d24ec0103674522f0c559e2357f8696bd498deccad2e0f66b2cf7469538", + "id": "061cb438ba1216cfd5a0f268ce18e6f280557bc944d9aed3655e2bc5f08bdf51", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402203b5d2aa7c4554d6d2dd6723043350df0199e6e7bbd9f21a1a20dbba8c63918cc022014a78064c5f9c5e2f43d3be36de2b5e2f17e9af557bb6c75e8d82d9f725d0188", + "id": "239f0640ddc3170a737ef349c07cb82b2493d207421b6f71b6b3dab856f16088", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022005eb29ad4cf79fd4f6898de19459e15cc816acb0975e53530a202e69c29d0d4a0220686cf6e0c14779d6d68dcb9d16358c0e859094d2eec8083598b7bb5869478bf2", + "id": "25d8eef755cfee7cab0d7f9fbbea0fad6d5f906c432d997ae8ef1c49d23735f5", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100b93096a287d59545fa3a08593dfc740d9d47f3cfa3c4bd3c8ff8ef53d3a2e957022027eda62e47220774cf799f46916195e5a8b30015c56ceff4f4a1c10a918e3675", + "id": "aac25996e3be809ee88996b6b4063e2097d6306e77a067de8ebc8d7076a28d43", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022017282aa4fac7b18e834abc3ca37b2f60cf989c26b12e2f2398a66cb907015a760220428218d39db812a22cc138acc7d5d4d2d5713f0546751c02d2c3fabecca0e724", + "id": "b040f86b75750b49c83ca7eb8f2a458f16b44789796ff306c5f942ca5f19164d", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402205970d53cb0921a62bbef540dc33189b2313f3574e44f046097067e6991d63b1102200a356c87642cc781df661a1fee21cce354a144463d37053280e000e1b75da7a5", + "id": "25ce96f951d7b7d886ef487331125b3413f655f9c5ee7fb4691a728c3cbce18f", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100aab0201c9d9a9641c11605d32353685cbaa051ecc276da1e6a3b309be9f20cf7022067aecbc7329bdf1770974e317a1243815511efa8c7af7801217a83c96d86eb0e", + "id": "285143b8b19cbde7c680b0f62ef51293e8f315c823ffbd97608c38c02045d831", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100dc7752f6f8acaa3a1ee2ed1bed306ee04556b3866db92a1e770c4b970c7a932e02202d137b312342f9d0708704833b26b6611d0464c87df97049ad8b616483e9d1f8", + "id": "87b06fccbb63809e976b3405cccec2eeaa3694d5510203f04c0e60bb6c2c0020", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402205ccad5c77ea339f5e3f2b7900b4b1c409d3c8204273e89b6401314fb61f0d224022026a63fef86356de64fe571ff8488a951dcacab56e980fc044ef9f43b9d37439c", + "id": "5597ed52e4123756bea9307c09c916ff9d0f9fbce8d2e9a3a2ff719a87ad0966", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402207c91153f820f34228bec62772e0d78876bd3277912eacd866fe35b5c86a316c80220104529c6f786cb387ec1e3d5826271c837f0d0a6d0fa5731b9a5c6663cce7108", + "id": "d46fde78608fcc668246cc35336210b3c167ba55c82e91b0fd99df7e36872130", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100acc0cf119c18861d3683bb3b0f6e209f2d62acfdd958f86dfbd35137ada814320220448f6f8adcd46204629b45a4a06f5dc7ccb4dbc2a1d702e107d91053847adf2f", + "id": "aa92faf5d80459b4e058dc8a8212608b589925052e22148384835ab687a4e875", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022055b6bbde5fa886db3cf1224a59f1fb43e850e2d9237db593368e1043698fe2c30220067dd20195e794af4152f1ff9e3ae4261698a86c54803ba1890bf176d97844d4", + "id": "432e67db0d5fc8c66376aa96c7324e5a1e6d00a415a9c8898b5e3bf25d8b083d", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "30450221009d6f38067264df8497d6888e4a8c316ec58ceba8a54c39ccb0ce261d114fbbab02200fae3f2f950f5c5e3387679f8ca341ec70cd90d0e32a30112f03cfb12cd9fc23", + "id": "9321e1b08faa544f592ad8dc7b60ff1cf845efcd28fedf8b445be3bda60434cb", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245100000000000, + "fee": 0, + "recipientId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402200aed5a4102bdafda00fda575294f149b393a798c510af8ba877b8c2d7ec8051e022004f7487c4f728c633aee5baa62ab0017f4b91cf2f494eb1c4cc9addc3e9155da", + "id": "0bbc9340798a18a81109bdfdbee9c9003f20a586dd9f80a39507c84588c1b4b1", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_9", + "publicKey": "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647" + } + }, + "signature": "30440220072124721ba7c997f7c29ad3d4819515fae7a67be2bc395cb73f114eb8d4abe60220523ac295e114de30ce8a4300f4670db91ad2abe1268460e6ad3463fbe9834b84", + "id": "d2e70f9d2de57240571905aa81db0b6883e27a83be2422530722d76b56e63ecd", + "senderId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_18", + "publicKey": "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a" + } + }, + "signature": "304402204b93b06e08e71e3317f9426a1d3d450d6293fdbf5a6b3043fce27b3ce65431e20220683609720ea1d7d921238ca8b5098d3d9c0caab7b1e26efe42a6aebbc095471a", + "id": "8695bcb906f5fd81d858794f7d90447aadaa38418d312e33115a81e856b34d12", + "senderId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_47", + "publicKey": "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd" + } + }, + "signature": "30450221009711559a43005c808113a1e9a01b1665495ff4bf30d635f7d98c752ead4cc3fc02207879e2a939914effe2b5c80cd515c4b3ff77a071b707c85c4444481878803db9", + "id": "55853d2d2a98def00c5ab842866a44d1db91678a07b6dd63d062508db28a00a5", + "senderId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_5", + "publicKey": "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565" + } + }, + "signature": "3044022025ba51a588253524557547ec492d71bd485fe5b291e60eef681c39eaf8ee781702202bf24c3d295c7a2c9aed97a79fb835506797dcfe7e7a2853e2578e7773c7e134", + "id": "553298aadf692c9c5d0334c307dd4ac0e277a49ed165c97ce1362f8ec639ee3f", + "senderId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_19", + "publicKey": "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb" + } + }, + "signature": "3044022041291ba10ad30fb9ebcb0e13902e92d85e2c3e98493b6d369d7d1e70e8474e31022009083444460c415eab6b4beed9e0206eb0733bad5d2a476af4db4f5b5e74b835", + "id": "90af927db7b258538c8e21116b5a31418c88ecc163628b2b65fac92a5a949b14", + "senderId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_42", + "publicKey": "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d" + } + }, + "signature": "304402205d4111c87874e696b8f4b8897d0dfe68fabe4ad5c5769026c6ecdd04f09a1e2f02207b9c8a2a16b50164215eb1efea6d5d9f4e693cbb7eec8535e526cf8ba68bb796", + "id": "8a920ebf5255a102d0c9c5fd720e0d36a6a3539991a2267442facf1fea2d0b86", + "senderId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_10", + "publicKey": "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd" + } + }, + "signature": "3045022100f15ff048872020d9efc561b8c837f542d54d43b9b071f7a6cc09643c6d4180f002207d0e82153a30b66f43fc4cb4b9b3093bb3d5dfd70f96928c8780c838b1448c19", + "id": "30738f376aa40fb3c8d8849a5dc698786aeb1409fa801c18729f8da624631391", + "senderId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_20", + "publicKey": "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751" + } + }, + "signature": "3045022100babb7410d09215def98078bbab6b5e5690c2ebf54960d94527226ed3925877320220342576d1d8fd2d2fe3b6974cab48a2e16b4813f022b341b32f88e13f572bf060", + "id": "ccbe1c27eadc1b3b33f3f87f645be4f756021ee3d4c96f4f094e1f82d5728a3a", + "senderId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_49", + "publicKey": "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374" + } + }, + "signature": "3044022032f2c350cc1319f5838d6880e91b49ae0438fb3a626ed9ab5e27ce8788e3347c02202cca18567c8491e0feea8a5f078e28605029346c509fac0c0a192e934f8c5326", + "id": "f99af0fbb4d65c2c3f2c1c558f0c0c0eac2724942802fcde02fa6da1d3a9000c", + "senderId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_3", + "publicKey": "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17" + } + }, + "signature": "3045022100f0cb5d885ddf3bd4a58837f9b86486da4171652a5eb39228dfd0ff9d34d9c7c602202dc6e3d268d745a7e8633311a337ec097382342049672880c7c2215cf58e5da2", + "id": "2dca03aed08533585d8bc609da5deb9f17ac9be5a8352769d7ae63d0db16ff59", + "senderId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_21", + "publicKey": "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a" + } + }, + "signature": "3045022100999f19fbdc9a12eebbb8c748a4cfc6c91b2233f333a09cddfd49dfeab6aaf38602203d8dc9d1551d400572a88ee812f51f897f8b35508713b789b2c1bf6dd0e88945", + "id": "5d7e51d57b5914ec201ab65a019ecdf651c4f267cbffe403fd2170bb95145f9d", + "senderId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_41", + "publicKey": "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f" + } + }, + "signature": "3045022100e86e648add940a1e637e32ea9187497c281b843da09597e62d0c927d7f43235102200479f64ae63abb55e338f9ce1073a5c46907f7a2a82ea6f9bd9bc29811683515", + "id": "eaeed4133da26612c53550b6572722d8c3380d0a2344da1bd270eed1ea91fdf3", + "senderId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_11", + "publicKey": "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904" + } + }, + "signature": "3045022100bc3b2ebc58a92bf38672206e8311e7ef0e54912abce7338155b11e7d191b0b5d0220765a568c1fa4665c0ace6b4bd3b7ba0f8329e2f25af7a3cc0d78b2ea398084c3", + "id": "bb91e78e43c59a19ac06c015d8a7ef09d7c5b274c9f98505e5a978027354b71c", + "senderId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_22", + "publicKey": "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a" + } + }, + "signature": "3045022100aae4868ab75a33e4e77f9bf6c53b920c5e7c523a7cfe271d1afc472655f3d6a60220499f1bcb79bc0fa830dfa939898db5c9fa8571a2788c8de0da7e550bfc818bcc", + "id": "a6e687647dde9c1db68690090afc4fcf11833dd35fff3186b6b709a1e7d24260", + "senderId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_46", + "publicKey": "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c" + } + }, + "signature": "3045022100c0cf1fc54705c13f70fde39c55a1703a4c612b8a919379cd5b1ada464c7cc8de022074ee62490a184010ad2418d3177ff2ab03d02d2589000176312b90422b1bd64b", + "id": "70262b0eec3ab5a60a736eb8a628cb600eae7522464a49791c0bf26e82318ec6", + "senderId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_6", + "publicKey": "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc" + } + }, + "signature": "3044022045db446b109215c6d3dfb0ee5869154a8a7624376c3760eec4fadc75a29033cf022003e524d64f3ccd0c6de4ca80a7327e2c47ffd16b3ad042bd25a02f5f64500ab7", + "id": "56048c449694964bee3d367609a7bc46c8da20f66878c09c01dcc53c3abd932e", + "senderId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_23", + "publicKey": "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a" + } + }, + "signature": "3045022100f8f69f2957781ed02d64983744c8e51fae613ebe5bbb330d4f509bdcf4fc6b6602205568ad1fd840e01ec26a24ac9a0ff093e978172da55d494138d018a45eb67893", + "id": "e15dfc4e18106480083b3c6211349fd9c803e334e9ba5eb62cca19ae3f57d8e7", + "senderId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_40", + "publicKey": "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689" + } + }, + "signature": "3044022021eeb9e1db8915a9adb99db72972cd17fc7b5b377fc532ac2c9deffcb2707edf022068b9e08f45bbebad89295f520ad40d7786fe64059d45df95551576e3acb736d1", + "id": "2bd0f888ccdeeca24a0134e3c1bf729582d284f32ee000d97f1417f1349a6594", + "senderId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_12", + "publicKey": "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12" + } + }, + "signature": "3044022040a9d0975f747df19792211546410d7c735aff2d26f367d1bf9233ffd1d993d702206890c66d4d0eb5de37df088c082d8fbd8da043817b48a76bd5d70f1e3f6b6529", + "id": "f75ac5ccd243e09fc9da2b3842a0654ca860d2dba5bb73866693a8a918937994", + "senderId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_24", + "publicKey": "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95" + } + }, + "signature": "30440220550c0ab565ab2de649ca7a2aaf2975453a1e4ab8b0d392d69663c0c9b6b80b7b022039047d4d1bf4e9b167a95adcde0a5a8631aeca060dfd426da28a10d968fb3a64", + "id": "aa2ed932faf4832848356beaf87e5381ee56a1a84fb485ba975acb28f8fcf5df", + "senderId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_50", + "publicKey": "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1" + } + }, + "signature": "3044022038df37ef25928d1a04516e982c99f49cbdc193603f814b48ab3802153bdd352002204c918915a3cbfa305c5f898ae4bcdd75394b57460f85c80daa0999751d466c08", + "id": "d30a726e1bb8d199d8f44700bc999c9a0a1a8be86e4be6a15764ecd424f9db1b", + "senderId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_2", + "publicKey": "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d" + } + }, + "signature": "3044022028dd44b9609b0b599c15a257757fd068f9014e33947c77776a6fcbe71879271b02200b46fd8eb0827da6de13f5efd63b17f29e8ba4600e4a690ec31eb08bf2d9af33", + "id": "1410b8b5f15c05528013378251bf5da30e04c8a6b7ac0f729b527664cfbdfbc4", + "senderId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_25", + "publicKey": "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964" + } + }, + "signature": "3044022038edfe34f7b89b4e69ea8b94e3335063b60deaee28246932147f53b2525924a402205b89f5e3d956aa49f24f81e2ba3447c19bd5c026568b3bef73a7a7d5160ad661", + "id": "58d14b74b71586e18f0499a50004ec2e0cc2e5b56aa53f4cf57084030ff90fa3", + "senderId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_39", + "publicKey": "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5" + } + }, + "signature": "3045022100bc1e477994bf4cbcdb5cbe2bd92c7d955a03adfe562f8e3bf04d2f62965e9f78022045512772d8453314361161b2bd2a39aa0a7fbb897a5a83f4c7ab54ced615b42c", + "id": "3ee53b3f1455ef0ddb52afe08854c9d87f42c7313babd3e05bb3ca4f94c495ef", + "senderId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_13", + "publicKey": "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f" + } + }, + "signature": "3044022052fe00e8e9f05b1d890f6910beab0627c823eb2d5875b4b9813a33aed11edfb6022034a723b827ce0e73bfdc0f535b244ffc983f8d549ee72b4d432de90d658db72e", + "id": "4a3d204c2916c93360d7bb11390e355bc1a930e3cf503965a45253d65bfe928b", + "senderId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_1", + "publicKey": "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37" + } + }, + "signature": "3044022013b2798a4ab4d741850abac10d962360cd4ab6a47dfac7c1c806d6f9c3d810cc02202742414ad8a04ce679b445fcd040fb877bbfed3d2692b873dec8cb46c01c8c4c", + "id": "7d0c5a44a7517f6ad7a1253db45d58e85aa1c735a282a32f45d28efdb7869d7e", + "senderId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_45", + "publicKey": "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b" + } + }, + "signature": "304402202c372b7b9679a8fe66f952a1d47d4327968d6e98770b215ada2fed6a8d87ed5502205a797fb511cfba557255dd37e028fb40981b7b65ad2ce8fe0e559a46eb274bf8", + "id": "70bfe97ae7452dc752ab4de0e2a0e81bd18bef07392c56e7a101257683d4d932", + "senderId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_7", + "publicKey": "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0" + } + }, + "signature": "3044022058851712200f7386d6b3c188444f9c8f05788667649ec17c71b9e514206eb105022061e6a4bc4cd11599792e03298f95509893d56af54d51e9f639981045e754b974", + "id": "f6f90ff09dee5be7d8f3d58d217772df7a95865bf8609d7d5b0b673e9a5bc953", + "senderId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_27", + "publicKey": "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d" + } + }, + "signature": "304402204878d69a166e60e0a779c31fbc48c67b70d2e4aed1d63c60beb9f070963e2894022078c46b6687f23493a4c2ed39709a183a0f7352568cc9cc2c1f0d7bf0d809a4a4", + "id": "f68809e407d20a50029fe460d411c866b79c7e09c076dada768a38d81f184aa3", + "senderId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_38", + "publicKey": "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294" + } + }, + "signature": "3045022100d5576393a1dea704cf79a5d0bc2757a3a5e66e1055103b52157fca05fc5693ec0220522832ce0e31b779decef83ac8ce764930de927df9ae1d6f6f99a3312d99c90c", + "id": "2ec6c6f33f00431ef063fbb8a79fb90eadb13a79bf46e6e1df36dd9434314df0", + "senderId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_14", + "publicKey": "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24" + } + }, + "signature": "3044022008a7d0bfe9c4c150566ddf701d08e84b4a5f84b07e3b1c91dde1cefa16d2a3c202200b787e898c0b2c68f4343e74f18ae7363f62b5f4ef2962386932aee09a9fa0d4", + "id": "e37b3efbf034bea4c852be7d7013978f8999eacc39549ceea775de197e14e8da", + "senderId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_28", + "publicKey": "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28" + } + }, + "signature": "3044022023b6fbfa5f4482a4dcc34411846696052b1592786ca87243b7d3344fc9fe9954022035402fbca22691de2497552c743f0f68c7591edd1bd7954ab7639548fcd558a3", + "id": "08268f5e6c15cf146523ca928f24aca65b162f363593d927c66144ee5df297cc", + "senderId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_48", + "publicKey": "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b" + } + }, + "signature": "3045022100b3cad169f29a3a95995b87e1b50b35583c1bff91d69cfa236f58ce452491c579022026775f4ef50b50ecf6d78b530b4633711394983456e6a45ec227b652c86e3014", + "id": "ad94ee2ae94813a638b93909930c7cc631c364b6c8528b2dcd6fa8f69260cc2d", + "senderId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_4", + "publicKey": "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93" + } + }, + "signature": "3044022007ac9ff2f272f3fda4947393b8688586cc8b2958ff5dc7931ac8f82c697bb76802202a66c28852bbff86ef17ac7f51e7eee52e611e825d91a9846f531ab3c3115c81", + "id": "76fb1984da9ef90fd7d588756163c97e00d3e4d6e9dfe78d9e3d3cb6d71ddd38", + "senderId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_29", + "publicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252" + } + }, + "signature": "304402204416e428688ad29928303fb2b00a26996cf79753fe70fb91c1f4635c644ba859022068ac5eab7d05f87c40ba36bd9dc149607c196778120c061698d7ab64aaade7ac", + "id": "0f442a91857061e87dd193b0b9f17a71719ca7e3da62841a63568713fc12b5e7", + "senderId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_37", + "publicKey": "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4" + } + }, + "signature": "304402206a248caa5949024202f297c38cee18845e344c5f140be74349787097d3b0a33c02207ac84336e02592bb5e00dcd0c490d30eb856b34177ab9ac03410d82a355a7b0d", + "id": "eed30a45c350fdffc5877458f7fe29f28dc4bf81aa1a197d003c9433148b71aa", + "senderId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_15", + "publicKey": "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca" + } + }, + "signature": "3045022100c99336ce666cb4a6db3727a61c04c14d8746365f72280d9984441b7d2b568b5402201759e4f417f683743e1d4a14f8a7a215009321cdfa29834b2dbdbe54ee22c1d9", + "id": "ecfba14a58f9d79782c4f905646df28bf566e3e7d1f17b39df6fe6b52c11de59", + "senderId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_30", + "publicKey": "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883" + } + }, + "signature": "3044022070de7b4d4ce64bd605c9d008142544c2b113cc84df07ed1982e0adf3cf69f4520220211b01710a6533a270dc2814c7f968adf27eb6dbf437e7a72960b013b9651a0c", + "id": "36ce5323859a92f302f77f27bd08ee3485d720f55842ccba353a47ea96a964c2", + "senderId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_44", + "publicKey": "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c" + } + }, + "signature": "3045022100a7c271633ecbf3c6641c7db36913b5fa0ea521f400a4848edf024648f3d7128002206a271f8a88644062b64d856407af9567c0b2937d4a3d89a3b3d07edbd3a0f177", + "id": "e120452e7c56a9327b2be7dfd3dcecae193f2e2e772903008b03cdf00146ebd1", + "senderId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_8", + "publicKey": "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564" + } + }, + "signature": "304402200394b6545015bcf2d0f291de57a4197cb6ef57b2ad5fa37f05e8a220913ba83502204d0d2f2206edba54ada5b8e5afd194ba83dd1bf15f744258409595251dbe3ff0", + "id": "7d15eee8e4e3be3d2c44acd51b87a816bdb593565d4ac358dab24ae9c8a5bae2", + "senderId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_31", + "publicKey": "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2" + } + }, + "signature": "3045022100989eb331951a13152aa03583efc765499e836c6fbafcafec4302b243ada8de5002203876fc4cf7fdeee4a095667e55a2fef84e5a7053e807b4d8e029883f0d578019", + "id": "baa686d521f95d265e7099cfd9ef14e0a9a92254dd94c16ce50c460bd013c588", + "senderId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_36", + "publicKey": "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e" + } + }, + "signature": "304402202be177dddfad323302565a866d38a3e7939e0234b16e7dc02075cf258502eba302200928a139ec1a82b4609fcc1bd6d1d027ad050e93fcd2eff94181936d2d43e39c", + "id": "9fcf7ec6fe98ed94710e212226d8b90df7e7467d66dd4c5c9d48474388be3099", + "senderId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_16", + "publicKey": "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9" + } + }, + "signature": "304402207b4f8c09a728acedf3b6ba0632e12d01670c683215053e49dde8598954d85a9a02202a7d7930baa17c2134b314e47dd6c334c828f78e573a2bf92fcbc1146d630541", + "id": "c35e4b1e7a2435664fc0939251c2052633ebf4b51fb22d15e71bfcab85b26de9", + "senderId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_32", + "publicKey": "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055" + } + }, + "signature": "30440220127d27312345e015c681adb799c1a87d16fb0caaabd5020b39257d567816b91c022018b2388f6d2d9afb3714d84ed102b3ea61159772786033c855947613c7ce7b5b", + "id": "0d682a3a9c252a674043bee5240e456dae2685d76fbd3bdeda6ff50f0c442fff", + "senderId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_51", + "publicKey": "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a" + } + }, + "signature": "304402203d0ee691830e4d001553bf4e49b6d9669b3c959376f391410551c8adc679dac902203ba6e275bf6d543efd19d20428649f802d9396bb0967114a1f09c24827be1da7", + "id": "ec2373b0d609ae72fb400ffdfbffc59670ebbf1c15f59c0ac22a4030dae700e3", + "senderId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_26", + "publicKey": "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983" + } + }, + "signature": "3045022100f2cf77b0510f589b5aaaf2b0027ffbce6ce8d4873cdc67dc8900865d156de3be02203c22e30945618683182f3d3873e6b3657e0900b062f866bab2705cd593669e79", + "id": "3cb2f0f7d05a515d4c5c873cbe96e33b1dfba1b7718e4548de7f9da54933b652", + "senderId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_33", + "publicKey": "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe" + } + }, + "signature": "304402201e328159172d543d2225c247c6b728800c52eb724f67c0e919f6b7215e6bd7f2022075fc02fe0b14a1499c5602d87ca2c99d6e789beaceed2b9702060dece872d14a", + "id": "2fd77e744399c9632cc8f106c39237f201dafda976f1040235359f99eea3b832", + "senderId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_35", + "publicKey": "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e" + } + }, + "signature": "3044022063903d82e8bd15a6741a298b9a6007d0dc3626acfe2f072c3b624ccbf91ce3360220486ba4cc5591d8aa31b77dfde025b61691dbaad0feabe13e840d26e40010c5df", + "id": "5baf9e318c9e4cb0513a21eaea27e51c849f95fddc963207fb07aa2fd2b9f9d4", + "senderId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_17", + "publicKey": "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357" + } + }, + "signature": "3045022100efc1bc16e0b646da48f84822543b62ef5253bfa98bed6613f2d6d4634076e61802200ef243f9dbac7633a8819ce45e2a85d0eacfdc9a33a92bd3a03e90cbd312b823", + "id": "b4a959ad75f81b7fdbb957c90a3a63a6c5589e7819e2c455733a3a2b4b034634", + "senderId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_34", + "publicKey": "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80" + } + }, + "signature": "3044022012e52a479648990bfc1ed12bf901cad865708ff45962c3724ea67967be4f9d0102201901525ed8dd090af6a2637c123afb304e9fd178794addcb88d916227e66887d", + "id": "6439f2308efe31ac52ad06ef1caa45b9abf6c589118b7997da6a287325ca36e7", + "senderId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_43", + "publicKey": "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e" + } + }, + "signature": "3045022100a0874d1582ce210081f7ab30e7f951dfb9ce8f512d237f8a8cbd5d85569ef3b902200f0053c05de3d6e5ada4e4cf1403a836779d653573c2f374055645cc954c4c4a", + "id": "b0733072e98d3d6afe977e32f3dd118c15e79212232417743ffb551dc2a2ba55", + "senderId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW", + "senderPublicKey": "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357", + "timestamp": 0, + "asset": { + "votes": [ + "+03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357" + ] + }, + "signature": "30440220158ed59156e0eef2d2b94a296451dffe079be701b3d74f0443ef43bc266b334202205a2c39f57abfcd279d568608b90884b3ebe107316aa7552eca35c743b318a47c", + "id": "ea294b610e51efb3ceb4229f27bf773e87f41d21b6bb1f3bf68629ffd652c2d3", + "senderId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7", + "senderPublicKey": "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80", + "timestamp": 0, + "asset": { + "votes": [ + "+030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80" + ] + }, + "signature": "3045022100898da9f693a458a6875344c6c4cb73069c4075904c75595ffbc665967d84b07002200f168aaf3ab1b52dfa74599394387dc4cf627a447fbc5a91000e9d251cdb20c0", + "id": "3639b5dc6d19d46d8254d941bf7ace0f3da8a7cf8a56361921b260820c7239cd", + "senderId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1", + "senderPublicKey": "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e", + "timestamp": 0, + "asset": { + "votes": [ + "+032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e" + ] + }, + "signature": "3044022055ed9a8b55ccb3bd0945a710269b6f243f1dbfaa28467d3218a17565eb0c962d02207d31561478f16d93a20f5454ad565dea24e8dda4ddc464cb011f4b6b360c4e81", + "id": "fe24509580cde0c2e2f49defedd3a0f7572d2f78f90b51a253b0d8cebd74c20d", + "senderId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof", + "senderPublicKey": "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055", + "timestamp": 0, + "asset": { + "votes": [ + "+0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055" + ] + }, + "signature": "30440220092f367f833d677e8d0609ad1df65f389c2c35d1501c71c245c2982e6a832268022018e67445f525613d6cb6ac0c9683bd0f55bd40d9c929165649414f083c9041f9", + "id": "6a76553db794ebf4d5f60a7d7d71cfe29f4dbcaad9610106fbc578cdc7167cd4", + "senderId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy", + "senderPublicKey": "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2", + "timestamp": 0, + "asset": { + "votes": [ + "+03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2" + ] + }, + "signature": "304402203dc028b5013c36b03f97b111a8d7c05d0cd8e505b0b0d18747c0656c9b5cfe8102205e9ce8a78d1183b3e9880c69635d04218d94d17808bcc3f92e7af53195c23daf", + "id": "0f9d7e7708918b77afbdfffb63eef8fe87ba36e0131c88b44c1a7f81750cc025", + "senderId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9", + "senderPublicKey": "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e", + "timestamp": 0, + "asset": { + "votes": [ + "+0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e" + ] + }, + "signature": "3045022100a80ddd7c3adaf0e97ab938773fc78a716f3054d7e03afc1ddfcb5005badbd2810220231c0dabe2262149f994c939f9dc90d46b9bd7ca96b19aad6788cd3571e4f71a", + "id": "0ac77b2637fb25be42b3b60d1651bbbd788aeaba933a08ec4a417c7b4c54e087", + "senderId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT", + "senderPublicKey": "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883", + "timestamp": 0, + "asset": { + "votes": [ + "+02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883" + ] + }, + "signature": "30440220772c9cd8b96f74fcddc429d57d466eca6fc40fc211845f59eeb78cb027e116c5022004cda291587eb118d622de21333d2a5783969794b5b0101ad8b1044c7d8058af", + "id": "4b0dda465564d53981c0e36d73caec888e3523633eaa80dfb99a9c81b2604c7d", + "senderId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU", + "senderPublicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252", + "timestamp": 0, + "asset": { + "votes": [ + "+0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252" + ] + }, + "signature": "30440220406d54714b6425ae4553ea8bec75f31fe52e9b1a9b6f6897151253ab7f637d3b022040a2df4b69840f4d9b0b67658c75efdae8d8269780d4cc50d055fa63922dbb9a", + "id": "c7db9d36d97ff0168d0d670ec695e1dc786dfb93f4081586870c8793b50e5f17", + "senderId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK", + "senderPublicKey": "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4", + "timestamp": 0, + "asset": { + "votes": [ + "+030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4" + ] + }, + "signature": "3044022018b7e51118ec83c985fa4eb3d7f0cf0655753bcbde7e82bac521665fb1c0ffaf02204e2ace460b2542db8c77e41d05d5e02fa5514b746a0a1e947256925846ed19f1", + "id": "c41f4cffcdd523f1718154d5bd5f4f0bec0376076b5f8dd340337e9edb4821ae", + "senderId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW", + "senderPublicKey": "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28", + "timestamp": 0, + "asset": { + "votes": [ + "+03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28" + ] + }, + "signature": "304502210088dbe249503da43c157485bfd4f2c95babfe4d0b8bbefe44afa52529b824a79e022045239b6a374fd9aca52c27171ee66b4863c956ae4085c9760d863b1902596c1a", + "id": "b1736ec6a1ea4c6d4eb278430a8ee214c88daefe296ba98530e692f8b7a7434c", + "senderId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej", + "senderPublicKey": "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d", + "timestamp": 0, + "asset": { + "votes": [ + "+02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d" + ] + }, + "signature": "3045022100fcdf750a775e728a31691a1b38908a7f990b579da510959cc2c63442f5ffde760220316ebb051d9fecb2486771dd39921fb12675b6d46b2441dd1db3c42fad0a59b0", + "id": "069271456015c2ff842771775993b8afc3404bc070572eeeb0f2fd72d58e18dc", + "senderId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U", + "senderPublicKey": "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294", + "timestamp": 0, + "asset": { + "votes": [ + "+0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294" + ] + }, + "signature": "3044022034ce8f77ea9d0f5cf3a9135d7b72d0ba3b96ac6d7eaa3670e9956aef2c9a83cb0220626d1f269128f673a23f9993ce00ba78a08103e697298be29a4c8ee94f204e3a", + "id": "9a99bba8340e7ad4e05d8424a0977ebbde428d31ee066c9828bd06b42bb42a72", + "senderId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2", + "senderPublicKey": "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983", + "timestamp": 0, + "asset": { + "votes": [ + "+02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983" + ] + }, + "signature": "3044022039ae1155f8b87a61c38b25cbbf30da6ecf6cfcc12b25c2e7fe576373754a41eb0220061a66a893129fbad5d48cdd19cf48b1a0d133dd2f3ecdc60ee7b87277e1f81d", + "id": "6c2c8926420ac269b50fa30127e0e791afb2131aff5821ca7aa80d38a0182048", + "senderId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf", + "senderPublicKey": "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964", + "timestamp": 0, + "asset": { + "votes": [ + "+02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964" + ] + }, + "signature": "3045022100d0dac2b7691aa059b1048d7925a0c5d5099f6e9b0f2e321e6d4f128ab1b3272b02207e8c4f643f8f9d1c3f81f0cce6a698df2da2ab71d5b01042766bbe0f46f4a775", + "id": "9259193c5de72276ed7a99f9d507dd6ea9856411fda521074fb41a556294fdf7", + "senderId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9", + "senderPublicKey": "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5", + "timestamp": 0, + "asset": { + "votes": [ + "+03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5" + ] + }, + "signature": "3045022100d5496fec447367ab6b53956a8c40cd8566e050ebb3b92d2c0b2a9d09bef36c7402205e32367605372375801f7b9db39aaafb46ee763b1494f0aca144fb91f3415752", + "id": "2a41e5946ab0773ca2334bba9d3510184bdd258f1c651ff8ec95b7b64a01dc2e", + "senderId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW", + "senderPublicKey": "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95", + "timestamp": 0, + "asset": { + "votes": [ + "+039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95" + ] + }, + "signature": "304502210099249695dc38826e04c8fcffd2570b98c43dec4788cc6a19737ed0872f17ec3302205301f645d803ad5df4ab1a700446e28c7cd76153607f6a2d68ae9168d46f3fe9", + "id": "e5c09b0fb2c24c57a4dcef0078953093800329ab4dc8e16a9d9f68215b5acd3d", + "senderId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU", + "senderPublicKey": "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a", + "timestamp": 0, + "asset": { + "votes": [ + "+034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a" + ] + }, + "signature": "3045022100f983b03e319aaa6c6ab6381e3ef8c0c035d6e3cc2139cedf70fd4e385393e38a0220286f73577765eb3e89e362785ad8a6de572bebf41bbc1f515b0ea93e41801eb3", + "id": "00b2c0455ef6f508d65f11bb49e3cfe1e6062d5fd153cafdfdfd2ccbf9c646e5", + "senderId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr", + "senderPublicKey": "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689", + "timestamp": 0, + "asset": { + "votes": [ + "+022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689" + ] + }, + "signature": "30440220103862ec51621ca27a0ec6b2817848e8824d2d09dbf7e6aac2f45aeea5d2dc9102205e8cce78b5cd7148aa4d406dc7b491dd7758047200e10cfe1e5fde5c56107ac5", + "id": "e25439ad11cb8db3d49ccb3b8b608c1bcb24cb29b2e5ea15101cce3e475224eb", + "senderId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ", + "senderPublicKey": "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a", + "timestamp": 0, + "asset": { + "votes": [ + "+03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a" + ] + }, + "signature": "304502210099241ced4a0fd1eb02f5cdcc880ae5f48eb3c7e490d4520c20124ecbf403893602204729dc6cacf3e87c97ca57c1be54d1e80791bf31ef022135e68fc06c950f6994", + "id": "1474f50815c6c7df41ab652414806d61abe15bee0d41f32d772f4e2793badce4", + "senderId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX", + "senderPublicKey": "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a", + "timestamp": 0, + "asset": { + "votes": [ + "+0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a" + ] + }, + "signature": "3045022100eccf81d44992c49a5ee37c6fc2ccc4b6bee9aa44888513b3e18e79452ede3156022056b0ddf079d2918d72e8781d3af009c87e6058563591dfd6ee0117b7df5534b2", + "id": "b394e2a8b5c2d20a72ed288408b8f0d48aed922edbee6e16c1c5b0e67517214c", + "senderId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf", + "senderPublicKey": "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f", + "timestamp": 0, + "asset": { + "votes": [ + "+03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f" + ] + }, + "signature": "3045022100bdb87894846eccc5a5473edaee1e6dca5f3469963e22f06123b6bde195aede0e02203d0c6833e87c5e60f4597ce624d4c2502a0562b4e54d943f82a4889e3cd69532", + "id": "6a399099bac6c74fa5e956512ef8b3a39f6f946d5d6996f192c2f1dd5ba172dc", + "senderId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv", + "senderPublicKey": "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751", + "timestamp": 0, + "asset": { + "votes": [ + "+02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751" + ] + }, + "signature": "304402200785771ccf1a6a40b51183a190d4cb4ce76b9ffd4c2c736d7724e6c667113d020220649ecfe73017d8dda96a7914793470ee7e582693e4866df123b1032194c163b1", + "id": "f20a831a6bae0a85470e308fb66517e70db479657459f6bb39f2cd1783c565e6", + "senderId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv", + "senderPublicKey": "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb", + "timestamp": 0, + "asset": { + "votes": [ + "+0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb" + ] + }, + "signature": "3044022020b79e1f07bcb17cae9485b9f44e9f583ca235da4ddd363b905fafb884347f71022015a20481b43720ddb3b1e3ca64b1f47e59b5cc2016a62f43327ca14533384dd4", + "id": "7a1285be87dca9718bece5b84266c1bf6801a39cc111d534e660aef9e6d26929", + "senderId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg", + "senderPublicKey": "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d", + "timestamp": 0, + "asset": { + "votes": [ + "+0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d" + ] + }, + "signature": "3045022100b1615d16763c46d42ca2aae967f04c1c07c119b5af7a378c262ba85515a8d35002202cf7df91676cd137943720e93f06c11907412a6bdc5ef2157cf536a203cf83a3", + "id": "76fb5a1de90f245b1eeb79cb11c7bea7c8b738add0fb8cd95191186a944b0229", + "senderId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri", + "senderPublicKey": "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a", + "timestamp": 0, + "asset": { + "votes": [ + "+02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a" + ] + }, + "signature": "3045022100e3c7b5d6a72acde4d22e8c1c6cd864c549deba89683f4b84320407d6c380827c02202da57df0ab7cd381b776bdf85802aed371e7cea7269a84f911b1d8e9956badee", + "id": "8da75c8100e6248ab37cc92f72ed9facec3067f4f82f03db8bb8063791463fb3", + "senderId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t", + "senderPublicKey": "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe", + "timestamp": 0, + "asset": { + "votes": [ + "+03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe" + ] + }, + "signature": "304402205779b5d8acbfedfc105fedb6fcbd4636713ed27605faa9bd988598072640a958022042d8a8b3d7910c7c385f3707a317c5d445d56da250f8d127c71df2d9d4c5d86e", + "id": "fd26e265be88289828d0ce7ffc5faeb9849e1f4cb37a8f1dd5d6fcc436d910b7", + "senderId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf", + "senderPublicKey": "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e", + "timestamp": 0, + "asset": { + "votes": [ + "+034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e" + ] + }, + "signature": "3045022100e18a89fe1fe0a8acaca2b6461314e784ffebbe7374f6aafdb06934e83985ccbf022027314b21a4a25b477bd7cc070b4e00ef8f3d69f3f1af028b96571dc245924c00", + "id": "41d92e128e6b8367cbf8fd111e5263d52e1abad553653f975dd60d7f7c5b637b", + "senderId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9", + "senderPublicKey": "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9", + "timestamp": 0, + "asset": { + "votes": [ + "+02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9" + ] + }, + "signature": "304402201c614c84dbae26f87973c9e2b38df883fe0c8c469080e31fe32a4c4946d50b67022075b8fb498fb1384aa6be785845da02813185ccf095597b5782618033828af4d5", + "id": "1e4a1f8aab6fbf8682c2b35e0d04e9e007ae717ce3f4a82894747e5807e3c759", + "senderId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV", + "senderPublicKey": "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca", + "timestamp": 0, + "asset": { + "votes": [ + "+02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca" + ] + }, + "signature": "3045022100b1ee6becc59d594776a40e5b3caec82390d273b703ecb0d7caece44953141449022016543cc29a28882845118afab6e51296cd216bc662260c28e5efd9597b6025b1", + "id": "2ce068bfccb3f967f4004e9a1e81614a738e55e45c80114c0af30a085f71a2e9", + "senderId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ", + "senderPublicKey": "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c", + "timestamp": 0, + "asset": { + "votes": [ + "+022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c" + ] + }, + "signature": "3044022036698a329d7f5f751f91ce02bc188a7527a377d01583b70427cfce64def945ec022079afafea10aa32394a1e42a80577de3869856656221d5f259e05fb44f01668b8", + "id": "3478d1ad3655e10fcc864f191972322c866616866bb1dbf66d7b66b31cd95de6", + "senderId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA", + "senderPublicKey": "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24", + "timestamp": 0, + "asset": { + "votes": [ + "+03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24" + ] + }, + "signature": "3044022035fa7be80cf881eefefc12b11de04ffb2e2e92815cf05074afef54a3c5b2eccb022041f3347f59db0b3caadefcbfbc5ae275d3fe3e2a52fe1504b23628d4b79a43bf", + "id": "8adfd8e73e96188ed9fdec459d88db1fb041a2b25b3f64830476aec661ae5010", + "senderId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm", + "senderPublicKey": "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f", + "timestamp": 0, + "asset": { + "votes": [ + "+021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f" + ] + }, + "signature": "30440220630da8a73979bd3988b7f84fe9e83a429cf3239f54c140c3dbcc407140513fc002203664ad54ed9f199f2683479b988bd97ad8fffb2c2d5dfdbdb10858aca4abfaca", + "id": "e306328ffefcd9e3809e7390a358199a62cf8ef037d57af1f5c7b54d728d427e", + "senderId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1", + "senderPublicKey": "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b", + "timestamp": 0, + "asset": { + "votes": [ + "+02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b" + ] + }, + "signature": "304402206f1df93f299ffedacc25aa201807df47d32c43369315cf9db280963c357be56302206a66acd553710f49bbb7b803a2bcb71128c8e617ffce66b37b7c968817349247", + "id": "dc69bc8f78502ba34655ed062987788939189709a4112760cd8807245d7461f5", + "senderId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8", + "senderPublicKey": "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12", + "timestamp": 0, + "asset": { + "votes": [ + "+03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12" + ] + }, + "signature": "30440220629e696a10e04d4fbc10a5ac443bf9bd40dd5d89d4b214224abe47d7ab5600340220643f361a24d9916e2c5aaec7bd7d8a6a0d3ffc5fc0b62c3ac4906eb799a862fa", + "id": "c3f49fb80c40f7779b32ba23616f5573a6ba58fc60c4629c2252933038dd89f0", + "senderId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2", + "senderPublicKey": "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904", + "timestamp": 0, + "asset": { + "votes": [ + "+0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904" + ] + }, + "signature": "30440220660f9604896dad2a97820b0d7524f0bce5a8b5766f150517d5061fd02bddf768022055e87c25891d4480e66e5d1a71e42cd5a4bef3ab2b2651cd72d44f30a4b32309", + "id": "8e8ac1b1a586e86867abbf25d63387bb6dfb793c691f0b06333c1581a9a568b3", + "senderId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT", + "senderPublicKey": "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c", + "timestamp": 0, + "asset": { + "votes": [ + "+034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c" + ] + }, + "signature": "304402202e2ad64129f61ef1156c4c7e80ab862d4823d62dac502685f53028536ddfb41a02201a3ec777fdfe8fae9f7cd5251fac322c1b6a2a4d41b3ec456daed474986d4872", + "id": "ff73565c373f2cefebf86c72dda3a6a6205750eb03b69178cb83378620715e1d", + "senderId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q", + "senderPublicKey": "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd", + "timestamp": 0, + "asset": { + "votes": [ + "+02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd" + ] + }, + "signature": "304402202e5c78cf21a088db10e1e1f64d98d84c8d3294fde7bc322d4af06bfe99d4c2e302207e7912a16a37b641a9f8c7c722f2b0d699917ca73e4d0f21584b717fb7f02f13", + "id": "3822273b496f2e253081cedf382e4f9937713fabb83449e1f892377cf536e68a", + "senderId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo", + "senderPublicKey": "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647", + "timestamp": 0, + "asset": { + "votes": [ + "+0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647" + ] + }, + "signature": "3045022100a65ce45164c9bc3e018e26703370c9deb2933ee3b4e814619043cc37c4a39c4802205ae4931ac9e8dffd714c3b601fe248a49c0185c8367887205f497d951c52eb54", + "id": "430d6db0b87c25dce4ce14ac907c13bcc6efa5d95135f05aa4ba7596ea9d400c", + "senderId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN", + "senderPublicKey": "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd", + "timestamp": 0, + "asset": { + "votes": [ + "+036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd" + ] + }, + "signature": "3045022100f3cdd7f688ad2d7b6a5b9cc7e793cb8a6e6e07d3327bc67add64691a53fd2911022026ae1adc8f4fcfc01bcca3efc83019026755b443a504265ad1f46f69d1f5951c", + "id": "dda86ecc0332e6c4eed1c0a5af7424374089b85dd274a300fed51b86e2655587", + "senderId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj", + "senderPublicKey": "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564", + "timestamp": 0, + "asset": { + "votes": [ + "+03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564" + ] + }, + "signature": "3045022100d419072a752acd55792257c96099fb14c56c29112a00535d39bca96fbd7951c902201abdf4db247dc956d79f4543c389823fbd1a9337f95d30df39603a3b52486bfb", + "id": "0998e9a055c53bf6697ee76af94c7a830c1364016d78fce889a21bc38ed70cd5", + "senderId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN", + "senderPublicKey": "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0", + "timestamp": 0, + "asset": { + "votes": [ + "+022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0" + ] + }, + "signature": "3045022100ba1e0ab761326d2a53cbda2a4a5135033c94d8166864d2ad3ceb963b4a0c046402207d755ecf4ada9fa2a598fd75e73a59d30cb83e01f510020b48b6bf162dc60b27", + "id": "be13743deb8486a575d1fb564d2b07d797ac77148d35793c9aca43c0d47aad61", + "senderId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA", + "senderPublicKey": "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b", + "timestamp": 0, + "asset": { + "votes": [ + "+03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b" + ] + }, + "signature": "3044022038a491e2e13ac32025209d00aec1af31b73a8b6ee77ad9b8bb80a34f5df59dfc02200ce82c89fe9f88bd5af236ceeaa80f9954e3fb4af7bc884c447505751d49c134", + "id": "f1d3d44cc289837de9623cba8891a1ed1cde8918473a91e2daead29975afad22", + "senderId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx", + "senderPublicKey": "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc", + "timestamp": 0, + "asset": { + "votes": [ + "+0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc" + ] + }, + "signature": "304402202ae599ce389cd030b8ab48ef53113458b9ba8bf9c9ed09c662eba2849bf540f802202ed63f8af492dd0b67d1b451170a989418a42466a3a7ffe89c4c5a18337e8fb9", + "id": "65ab302a44ea7550891eabc3b4a8d5ecbcb80784c4666195d5d0b7e33394300d", + "senderId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK", + "senderPublicKey": "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565", + "timestamp": 0, + "asset": { + "votes": [ + "+026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565" + ] + }, + "signature": "304502210088a3a4e82d307c238e01ce154b57631d4429e0b591e828ec36839a783736e842022042c6e1d719781e2edca3dbfe84ad13b9e490821a47ccadfcff379decb9c873c0", + "id": "d26a7ea56f398634a81086bb15c2f0c863c71b8bd728304d324d8245a8fb6c73", + "senderId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz", + "senderPublicKey": "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374", + "timestamp": 0, + "asset": { + "votes": [ + "+032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374" + ] + }, + "signature": "3045022100ae5805541f085a50076835422b2581d3b7a128a05b4f068ad7e3c14cd02799b802205f4bb40e06f90e02282ae74c0aba97923e601fd78234b9585468c4fb73f47893", + "id": "02504eae7ff4963c081219523bc48d7a07de4c29fdc1622224547f9a7c133abf", + "senderId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp", + "senderPublicKey": "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93", + "timestamp": 0, + "asset": { + "votes": [ + "+03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93" + ] + }, + "signature": "3044022078d38cabd8f427ef381d0aa6a0b98c6a590cb18f47acc1d80b429a1c1959b0ab022022a70d4d93d650ca3121dde6065e80cd90d1e2e91cb90f0d0b2eadde609e0d75", + "id": "addb8c1baa833baa52a5b51d8a86f8524bde826b5c9f0a99e57070e6323e1dfc", + "senderId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv", + "senderPublicKey": "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17", + "timestamp": 0, + "asset": { + "votes": [ + "+038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17" + ] + }, + "signature": "3044022076dd065e3fba825b77884a179d0231d7fc9e7d3a02e34bc6565fab81a84e559e02200a880c028e690a9d6f2c4c6576b1bf3e913817c834da8ec6afdbadfae78d341d", + "id": "72f31f9a829b93045ef2e860b24c33b9be6a2621c26914acd42121215c1d517e", + "senderId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P", + "senderPublicKey": "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1", + "timestamp": 0, + "asset": { + "votes": [ + "+030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1" + ] + }, + "signature": "304402205261d9d8ded6364fda8b10bd477982be84990cb010f9214d52c492676814e1f40220489f441ffe2478d361a12ab96caa59da495fe62d61d0e2255aa5ec4ed789afb8", + "id": "1f17b4ba072d205761ed3f786491eaf684ed3601b69082e487e568aa74a319e8", + "senderId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd", + "senderPublicKey": "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d", + "timestamp": 0, + "asset": { + "votes": [ + "+02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d" + ] + }, + "signature": "3044022040219da41054a3eebd3122df7f09a62a4e8b4fdc287ae77221f2217b42f291ad02202b9a70c54bb546a604eafadcc086ef6b6570f57542374d87de02ad7f61fe51a4", + "id": "5fa837023159d6a3d6cf7c5b2ed6fe05ff7df19300226b2f0be5a48a06993780", + "senderId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo", + "senderPublicKey": "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37", + "timestamp": 0, + "asset": { + "votes": [ + "+03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37" + ] + }, + "signature": "3045022100ded426768f114f459485ba6ae293c9649b340cf2dcb15e8e887fbb5fed6f7e0b0220752297022de6e93ff64bb9e07b4efef8e946cd2872f84d9e1cb3165ff5c342cb", + "id": "0a16dc31514629a36d7237968ada6a95d6cbec027b7d26e1e0f0d7d4febe9494", + "senderId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD", + "senderPublicKey": "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a", + "timestamp": 0, + "asset": { + "votes": [ + "+02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a" + ] + }, + "signature": "304402203aa292e7aedcd62bb5a79c2521b666b8e1886b57923d98f51911b0461cfdb5db0220539657d5c1dcb78c2c86376da87cc0db428e03c53da3f4f64ebe7115998f00b6", + "id": "8816f8d8c257ea0c951deba911266394b0f2614df023f8b4ffd9da43d36efd9d", + "senderId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD" + } + ], "height": 1, "id": "17184958558311101492", "blockSignature": "304402202fe5de5697fa25d3d3c0cb24617ac02ddfb1c915ee9194a89f8392f948c6076402200d07c5244642fe36afa53fb2d048735f1adfa623e8fa4760487e5f72e17d253b" diff --git a/packages/core/lib/config/testnet.1/peers.json b/packages/core/lib/config/testnet.1/peers.json index 9d34730345..d88c6511c5 100644 --- a/packages/core/lib/config/testnet.1/peers.json +++ b/packages/core/lib/config/testnet.1/peers.json @@ -1,15 +1,18 @@ { - "minimumVersion": ">=1.1.1", + "minimumVersion": ">=2.0.0", "minimumNetworkReach": 20, "globalTimeout": 5000, "coldStart": 30, - "whiteList":[], + "whiteList": [], "blackList": [], - "list": [{ - "ip": "127.0.0.1", - "port": 4102 - }, { - "ip": "127.0.0.1", - "port": 4202 - }] + "list": [ + { + "ip": "127.0.0.1", + "port": 4102 + }, + { + "ip": "127.0.0.1", + "port": 4202 + } + ] } diff --git a/packages/core/lib/config/testnet.1/plugins.js b/packages/core/lib/config/testnet.1/plugins.js index d8a95172c6..1cceec6f0a 100644 --- a/packages/core/lib/config/testnet.1/plugins.js +++ b/packages/core/lib/config/testnet.1/plugins.js @@ -1,100 +1,73 @@ module.exports = { '@arkecosystem/core-event-emitter': {}, '@arkecosystem/core-config': {}, - '@arkecosystem/core-logger': {}, '@arkecosystem/core-logger-winston': { transports: { console: { options: { - colorize: true, - level: process.env.ARK_LOG_LEVEL || 'debug' - } + level: process.env.ARK_LOG_LEVEL || 'debug', + }, }, dailyRotate: { options: { - filename: process.env.ARK_LOG_FILE || `${process.env.ARK_PATH_DATA}/logs/core/${process.env.ARK_NETWORK_NAME}.1/%DATE%.log`, - datePattern: 'YYYY-MM-DD', level: process.env.ARK_LOG_LEVEL || 'debug', - zippedArchive: true - } - } - } - }, - '@arkecosystem/core-database': { - snapshots: `${process.env.ARK_PATH_DATA}/${process.env.ARK_NETWORK_NAME}.1/snapshots` + }, + }, + }, }, - '@arkecosystem/core-database-sequelize': { - dialect: 'sqlite', - storage: process.env.ARK_DB_STORAGE || `${process.env.ARK_PATH_DATA}/database/${process.env.ARK_NETWORK_NAME}.1.sqlite`, - // host: process.env.ARK_DB_HOST || 'localhost', - // dialect: process.env.ARK_DB_DIALECT || 'postgres', - // username: process.env.ARK_DB_USERNAME || 'ark', - // password: process.env.ARK_DB_PASSWORD || 'password', - // database: process.env.ARK_DB_DATABASE || 'ark_testnet1', - logging: process.env.ARK_DB_LOGGING, - redis: { - host: process.env.ARK_REDIS_HOST || 'localhost', - port: process.env.ARK_REDIS_PORT || 6379 - } + '@arkecosystem/core-database-postgres': { + connection: { + host: process.env.ARK_DB_HOST || 'localhost', + port: process.env.ARK_DB_PORT || 5432, + database: + process.env.ARK_DB_DATABASE || `ark_${process.env.ARK_NETWORK_NAME}1`, + user: process.env.ARK_DB_USERNAME || 'ark', + password: process.env.ARK_DB_PASSWORD || 'password', + }, }, - '@arkecosystem/core-transaction-pool': {}, - '@arkecosystem/core-transaction-pool-redis': { - enabled: !process.env.ARK_TRANSACTION_POOL_DISABLED, - key: 'ark1', - maxTransactionsPerSender: process.env.ARK_TRANSACTION_POOL_MAX_PER_SENDER || 100, - whitelist: [], - redis: { - host: process.env.ARK_REDIS_HOST || 'localhost', - port: process.env.ARK_REDIS_PORT || 6379 - } + '@arkecosystem/core-transaction-pool-mem': { + enabled: true, + maxTransactionsPerSender: + process.env.ARK_TRANSACTION_POOL_MAX_PER_SENDER || 300, + allowedSenders: [], }, '@arkecosystem/core-p2p': { host: process.env.ARK_P2P_HOST || '0.0.0.0', port: process.env.ARK_P2P_PORT || 4102, - whitelist: ['127.0.0.1', '::ffff:127.0.0.1', '192.168.*'] + whitelist: ['127.0.0.1', '::ffff:127.0.0.1'], }, '@arkecosystem/core-blockchain': { - fastRebuild: false + fastRebuild: false, }, '@arkecosystem/core-api': { enabled: !process.env.ARK_API_DISABLED, host: process.env.ARK_API_HOST || '0.0.0.0', port: process.env.ARK_API_PORT || 4103, - whitelist: ['*'] + whitelist: ['*'], }, '@arkecosystem/core-webhooks': { enabled: process.env.ARK_WEBHOOKS_ENABLED, - database: { - dialect: 'sqlite', - storage: `${process.env.ARK_PATH_DATA}/database/${process.env.ARK_NETWORK_NAME}.1/webhooks.sqlite`, - logging: process.env.ARK_DB_LOGGING - }, - redis: { - host: process.env.ARK_REDIS_HOST || 'localhost', - port: process.env.ARK_REDIS_PORT || 6379 - }, server: { enabled: process.env.ARK_WEBHOOKS_API_ENABLED, host: process.env.ARK_WEBHOOKS_HOST || '0.0.0.0', port: process.env.ARK_WEBHOOKS_PORT || 4004, - whitelist: ['127.0.0.1', '::ffff:127.0.0.1', '192.168.*'] - } + whitelist: ['127.0.0.1', '::ffff:127.0.0.1'], + }, }, '@arkecosystem/core-graphql': { enabled: process.env.ARK_GRAPHQL_ENABLED, host: process.env.ARK_GRAPHQL_HOST || '0.0.0.0', port: process.env.ARK_GRAPHQL_PORT || 4105, - path: '/graphql', - graphiql: true }, '@arkecosystem/core-forger': { - hosts: ['http://127.0.0.1:4102'] + hosts: [`http://127.0.0.1:${process.env.ARK_P2P_PORT || 4102}`], }, '@arkecosystem/core-json-rpc': { enabled: process.env.ARK_JSON_RPC_ENABLED, host: process.env.ARK_JSON_RPC_HOST || '0.0.0.0', port: process.env.ARK_JSON_RPC_PORT || 8080, - allowRemote: true, - whitelist: ['127.0.0.1', '::ffff:127.0.0.1', '192.168.*'] - } + allowRemote: false, + whitelist: ['127.0.0.1', '::ffff:127.0.0.1'], + }, + '@arkecosystem/core-snapshots': {}, } diff --git a/packages/core/lib/config/testnet.2/delegates.json b/packages/core/lib/config/testnet.2/delegates.json index ba46283724..a094c271a3 100644 --- a/packages/core/lib/config/testnet.2/delegates.json +++ b/packages/core/lib/config/testnet.2/delegates.json @@ -1,8 +1,4 @@ { - "dynamicFees": { - "feeMultiplier": 100, - "minAcceptableFee": 20000 - }, "secrets": [ "clay harbor enemy utility margin pretty hub comic piece aerobic umbrella acquire", "venue below waste gather spin cruise title still boost mother flash tuna", diff --git a/packages/core/lib/config/testnet.2/genesisBlock.json b/packages/core/lib/config/testnet.2/genesisBlock.json index 28969efa39..317cd8ed94 100644 --- a/packages/core/lib/config/testnet.2/genesisBlock.json +++ b/packages/core/lib/config/testnet.2/genesisBlock.json @@ -9,2149 +9,2303 @@ "payloadLength": 35960, "previousBlock": null, "generatorPublicKey": "03b47f6b6719c76bad46a302d9cff7be9b1c2b2a20602a0d880f139b5b8901f068", - "transactions": [{ - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402205fcb0677e06bde7aac3dc776665615f4b93ef8c3ed0fddecef9900e74fcb00f302206958a0c9868ea1b1f3d151bdfa92da1ce24de0b1fcd91933e64fb7971e92f48d", - "id": "db1aa687737858cc9199bfa336f9b1c035915c30aaee60b1e0f8afadfdb946bd", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100ffff4e9ba62e5e3beb37deee052824da83c4030925bce09f190151652d0669b8022056a432e56a2e1b026d4b54f6c34ce88a0c9cebdccc730659c03449fe878c66f8", - "id": "0762007f825f02979a883396839d6f7425d5ab18f4b8c266bebe60212c793c6d", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022001a6326e5d1eb06d0ba1fa39446bd6d56ea45f0c269ebbce5dfc6a649277cfcc02203b252d3a6ef2b22349d9d0a9110ce28a199c39dc8b911edfa82c297a02009d07", - "id": "3c39aca95ad807ce19c0325e3059d7b1cf967751c6929035214a4ef320fb8154", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304502210084d855eddfe616cf1dc238b19226c7959c2fc4027ae2e8aea6fd8e9eb8928e6b0220440f980e40c1c56348782fd69d49a96944df7ee5b68d18028600e0e7501d4000", - "id": "9fdf6ae86f7c005b3b7dc1b9fb6411219407ecaa93adff85fdb61710f5121638", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402205438b8b9058bbde5d30794e7681e400e52b5fbd22324c5b6b521f97bc8b8aabc022000fe04d7afbd2e668b1d4576988ed596dc92251e33efebc081e2cba14ad5a898", - "id": "1d7c68087c875d7ce555b2c3e71e1d91a1ad62d0c2497efe3cab91415e634041", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100b2e634a95b011a68489870f003e4bac4a4f0578bfdc6b9f645c934016c2c0463022022cd4ebf276dd627d98be4b697bae2df10b86d94e984da2eb7e011b08d6dffd2", - "id": "0c993e115ba26981b0be9d22e7c4a13b0f106e0cb472f9d34eabfc8e414dd528", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100f965e5c280acb22d1cde405223fe9a6fcb765844adbc5321b17a268924e1f597022043d31b1edc5fe0cf60a960d84e3528472cdf34560c9463979043a409f37e7f29", - "id": "c279f2eb1f9e6e7d4b0ba7a98233a0f1a2536231976c99f56f64b248eb06a0c1", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "30440220715463c316a75959dbfb6a59a013fbf914bef1ff739ac8000d49dabbf5118df9022019345ae1c34173dc214bae82f3cfbf438092f0fd2d277acafe3e9deb644b1a3b", - "id": "7e2fc9ecf23e909a3d0fbecd615445a0eed8c2cef18e01b1492d63f616f5d87d", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100fdd8aff26dceeb5abb6e5e8a8f468c8ac1997a587225298e3d8135d57dadf4dc022072ab80a81b301a162ed5cfa67d213d5a3980185088632f5f592351aff8aa0e9c", - "id": "511c0e1076104743f98932f8e7720bdb3f1539134edadd331914fd9ece1ebede", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "30440220635e04ce278870f17fcd1883aa26c568e63dfbdd302add39aa30fd3637c79c2c02206fdd9e7b1f4d238a97d26ef1758927e2d39f121687490f2bd79831e36afdd43b", - "id": "0768d5016c53d884e3d68a09d1bab0d730b7067c71ef4ca1c4d61b3815f5ff66", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402200b1dac57ca6565ac31afb99686f2e0f0e8dc219b9860b295ca5444a1663cecfb02205787393561fe407449af4aaf2f621db9e4d3f11c7438666cd694d495c0a0c41f", - "id": "1aeb50080ea118165e5041f7a897974c2ed1ebde08add85dc78cc7cf73566a91", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304502210098dea25eccf31ce6f874a9528578805aaf07be8b41f1571865793f9e3e6e3c97022033ae9c73dad44c01fe6362665fccf63bb1a0ae8e26f77a1cf60b67dc96b05343", - "id": "254f0f4fa277cc651a746d6ac371eb27afc3ea155ba060552dd26b8e83d17b72", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402207f4bf346aac501e766156818089fb16905a9bdca69ff6d5a55ba918a08afc7ab02200ec2c25cc4bb30e2c176d55630d8e2679b899c14ab4ba43c3d62955dd940425b", - "id": "e5ebb02e8e8a6708e22ee5ef99fe1dd8b6eea1095be6b772aa21bf63cf7ade5a", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100a0bbc15bdad648bb9b439f1d34b12b853442d1cfd4ce7f569905082801fa58e8022036b4e73edf7ab7226f8007233f77b1d497cb6b4736f02721bf1b399312ebe114", - "id": "8a686b21477b64dfd85f08f8598a0f121ca1c7d65ccaca9e42326c75fb5f3abb", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402205d77dfcde527dcc6669bcb01c27b92c1a6399e35ebac9e69415645f596ab1d2802204179497bfd952f44d5f9e295b2a3219a290a4a82841c084a18553b7712e26415", - "id": "21175347e2acfabc09a7593aae0682e39fe7152199a90561c11125f525211243", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100cf77c16df9185727ff717b71a94f8b29ceeae1e5bb3a28da8cef9df5bc63b7c202207bca394ce9ebd344a548e5a5697f672dedbef640dc1f9105f7c063287bcd1840", - "id": "ce1d9b7377551f36568127f5b635b5443f5a58abba6566b50a8d4d7b53c8a874", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100eb8daebb5484f3b0a738c9344fb28298c596f9486963f8fe36e2501ee6876f2a0220559df66986dc9a9a8e76982ef85f907c62745757990c69f0b17b6ae5a7ca4719", - "id": "b56702f5eddad0d8dbbb33b6b1ca3e07e4740def9c5dd2aaed9a70b90a4e31b7", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100d088e9bcd78978f2d67e7c7bccecfb73ddd0d1a2dad5b039390812320355722d02207affe83d815f04f6b11abf98eebe0488bfb87f8cd6513d44b829008ed1c15ceb", - "id": "a73c053c42e83a83498cf58e5b077b31443e265ddf8228081cb17a36bba366ae", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100db16a8e9682f07efb607bc7c75b654646ff449761ed146ab9358e69d29fadd7f0220436554ad78db0e04ae5b573258e2c8067848e89b55a6e8e1e25011a43882a643", - "id": "2dccb8b44ad2e598673628fd9d74e336b467a0c941d5e257dceb85c8e0a0000c", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100b03738eccce8ad0b8ac0a656119c2cdd202089c5650d8e1486bd13eb9c3158980220059079900c7fdc16e799c50dccc074726fbf0068044462faabdf1e73f9f9bc38", - "id": "b2cce30021d139f97925807da796722bf4d5459442523823388c259ca5ad73db", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100becb49fe5edd6806d5ba6eddbbb34ca8eaf3a12dba123d1610b2b120ca8bd017022072972992ee0ca0f319ae754a2a5a10d715a08b23f8239f9d6d59774f790543ea", - "id": "9e4841f43ab355be7a4f93b09f3d82c17065fbe25387dd6c5eb4e2692ea05b0b", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402207f1a3fe8c5aa7a77a58ed35c34f128b5df6fba89aa918af35eff432be7d1f8e00220460d4f2a457e1a477974157e33bf2974de6588d56e59729ae980720e9794827a", - "id": "2c7ca823be21724a4876de632dded3b9afca45df357819ed028488128d85d29e", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022067266dfe9d8f2550b590e1eae2f73d28c6b80fecb24c3eb1b4539bc864b3b4f4022031e5122145c35874c0c48673d088e76fb3e11c308ffe9d5dee6431d3441d627e", - "id": "a91119f04e2201184761f7fdcb26e4aa81c7e1076cb11a58a422d351241d4e4a", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100b970ec89927de0cb7805e614a742d42c2967db5a9c68d0892956dc89d68ca7d1022067fa30265dd2e1a2985980be2bf876748a7a8c7f3cde0382265b601fa658dc17", - "id": "94955e6bac6269fbd19e92d2292ac947225fc6f68c6216001b528596a961040c", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402203671b82ddf8a824b8e5aac8bc28be4aef1c00aca1097d14ec1a55003d7a3f28d02203aacb6e7517e916478432b81399828ba7425183ce0fc43feb361bcf345fb0519", - "id": "df563ee9822bd3d7aada600d4800952743ec64fafdc7697428d7a19a60745885", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100b77653317c93eb20ee19c71e64a7f9ecb985351bfb1fe351ac65a5738cb37ae202203d540395e1d55f87caaaa867afbfbaf98c553be0b4c7d1748418a76b0c258c89", - "id": "d21b6341e2b4be5ffdc3dd8fbcdf2c576ba02e2ef4ab5eab0e4bfc9da4e9e442", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022046239e39062a58925099b005888355b8cd6700af66972bf509a10123f9abdec60220202321ea74e56177606fc079d19c29851d832e6d00c93985ffbec3dba6f0d675", - "id": "df6bc7a17ad34f8e9faaa2646e8e5dd8bca35affba352537184f690e200e17b6", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402204eeab87f7ecc2097b85606b986177964f3ae777535f6fc0cf08a55fec587d87602203779d59903b8de63511e4ed0a7967bd85e9cb1fc9d84bbc5091e3caa87d8bd52", - "id": "5f0d5f0dff464d0ad587da5bc93e600a8e2657d359d0a1224bdd4ccc3b6f376a", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402200a2b9d0f61066fa00a2a2882379aa8ee60e949bdc2a85103bbbb69ce3eafccd9022057364f349faceb3047fa95ada210c64fc4a81978d66925b37d3dbc21ede885af", - "id": "1b39e3702576e6ad7775e34d53e43210549d52a56b3f246031e6ba4121a66bf0", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304502210099e568d3d0c1b48410e0b85c74d04234dacfb2fdf2b1d4b51fca1cfb3445347a02207a2509645aae54560762a37422b66ba4b3ee1c42de35d58c36d2f9d8fdea11b4", - "id": "0f21e53dbb1edb1cfb4c31bb675aa4672b452a03ec363a2b3300a9dda49e3be3", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022026cc5f2b588a86241badca73cd9c1686916d516b8c6c397c66a9d5bb6b5d4cd402204ab5a8c8589ee954bda4a116999d2a0e4ab0e3e96f0c7fe131d7c57b9a1ede43", - "id": "410826c255a23a78ac5c3aa10dd48132693bc955845af16c20d9c6f69b05dfe9", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402205fedd8d3b5c8d69cdd7db5ca8e9e7c5004f6ba751e45eb1b85b26d9e89800a2402202be56bb2cd824bccf325b6b11432bf6d0ddb5ec97fcc121839ac2ebf884c7173", - "id": "ddb57d8270b2b6c876191c1e1c5974388b9fb3ae0980cb2245d8a7c426237f47", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022053cd42ad147eea33801b2b57388b33f633b4bfe2ad902190e12480522250d07802203066dc0d0c2ffacc4c74cca1e0187fbea1cef7e78a78666d2ec7e4e87ef546eb", - "id": "29e1aedf98935c369946c8dadb2d6784f9ab5ce8d73b9b4de2466c7757e2557b", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100c10448b87e7176735c8ddfc8fb3c4d5d55c2d71d18b7ce3ab321209ec299fd41022013517a09e4b366ab386698286ec7bb20410bdfb7f6674fab25a739259083b297", - "id": "4cf04852529b5525f22cc540790e36e61ed36045ad1b5b788f61ebe42637391e", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402204cc1588b204ebc0c20f44a31ce53d15ab5e4d1f9c103c02dd4e4eaa1c33630b40220194b6e427b6def0783461cd8d765f97b105d048942be468be2ee9b0a2785d2ac", - "id": "35c6bc3f0799d9c79efc6515f232c58be0d03a3a797d066cba879eef4afaae2c", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100be44f7ea12e2ee89245fb474643ec6c2c75afa00276826a4ecd6fca4cad5ff30022071a2c083b353a821345e4bbf74d98db0760b8721856572572cc3436ebdb8f08c", - "id": "45f75a349f3b4d73434c0f2ac9c291d5d07278b79e6eaa0d38d6e005f66c4783", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402202090f506e8f18fde70b87a3fd6c470a23e9e262f20ec6268dd59b6362e51a29202202b838c598b33c6317c998dc179fad2b660b8a72bfaf8223d7cc82414ab4c6af4", - "id": "a8d9034d1091a4dbe595647ad5f64ca8b243e7842301aee48f7eaf8b8ae98119", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100be59b689a48e198267305f1ae7e116f69f7c360857ea0b1fa81db122278cad69022033436d24ec0103674522f0c559e2357f8696bd498deccad2e0f66b2cf7469538", - "id": "061cb438ba1216cfd5a0f268ce18e6f280557bc944d9aed3655e2bc5f08bdf51", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402203b5d2aa7c4554d6d2dd6723043350df0199e6e7bbd9f21a1a20dbba8c63918cc022014a78064c5f9c5e2f43d3be36de2b5e2f17e9af557bb6c75e8d82d9f725d0188", - "id": "239f0640ddc3170a737ef349c07cb82b2493d207421b6f71b6b3dab856f16088", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022005eb29ad4cf79fd4f6898de19459e15cc816acb0975e53530a202e69c29d0d4a0220686cf6e0c14779d6d68dcb9d16358c0e859094d2eec8083598b7bb5869478bf2", - "id": "25d8eef755cfee7cab0d7f9fbbea0fad6d5f906c432d997ae8ef1c49d23735f5", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100b93096a287d59545fa3a08593dfc740d9d47f3cfa3c4bd3c8ff8ef53d3a2e957022027eda62e47220774cf799f46916195e5a8b30015c56ceff4f4a1c10a918e3675", - "id": "aac25996e3be809ee88996b6b4063e2097d6306e77a067de8ebc8d7076a28d43", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022017282aa4fac7b18e834abc3ca37b2f60cf989c26b12e2f2398a66cb907015a760220428218d39db812a22cc138acc7d5d4d2d5713f0546751c02d2c3fabecca0e724", - "id": "b040f86b75750b49c83ca7eb8f2a458f16b44789796ff306c5f942ca5f19164d", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402205970d53cb0921a62bbef540dc33189b2313f3574e44f046097067e6991d63b1102200a356c87642cc781df661a1fee21cce354a144463d37053280e000e1b75da7a5", - "id": "25ce96f951d7b7d886ef487331125b3413f655f9c5ee7fb4691a728c3cbce18f", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100aab0201c9d9a9641c11605d32353685cbaa051ecc276da1e6a3b309be9f20cf7022067aecbc7329bdf1770974e317a1243815511efa8c7af7801217a83c96d86eb0e", - "id": "285143b8b19cbde7c680b0f62ef51293e8f315c823ffbd97608c38c02045d831", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100dc7752f6f8acaa3a1ee2ed1bed306ee04556b3866db92a1e770c4b970c7a932e02202d137b312342f9d0708704833b26b6611d0464c87df97049ad8b616483e9d1f8", - "id": "87b06fccbb63809e976b3405cccec2eeaa3694d5510203f04c0e60bb6c2c0020", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402205ccad5c77ea339f5e3f2b7900b4b1c409d3c8204273e89b6401314fb61f0d224022026a63fef86356de64fe571ff8488a951dcacab56e980fc044ef9f43b9d37439c", - "id": "5597ed52e4123756bea9307c09c916ff9d0f9fbce8d2e9a3a2ff719a87ad0966", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402207c91153f820f34228bec62772e0d78876bd3277912eacd866fe35b5c86a316c80220104529c6f786cb387ec1e3d5826271c837f0d0a6d0fa5731b9a5c6663cce7108", - "id": "d46fde78608fcc668246cc35336210b3c167ba55c82e91b0fd99df7e36872130", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100acc0cf119c18861d3683bb3b0f6e209f2d62acfdd958f86dfbd35137ada814320220448f6f8adcd46204629b45a4a06f5dc7ccb4dbc2a1d702e107d91053847adf2f", - "id": "aa92faf5d80459b4e058dc8a8212608b589925052e22148384835ab687a4e875", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022055b6bbde5fa886db3cf1224a59f1fb43e850e2d9237db593368e1043698fe2c30220067dd20195e794af4152f1ff9e3ae4261698a86c54803ba1890bf176d97844d4", - "id": "432e67db0d5fc8c66376aa96c7324e5a1e6d00a415a9c8898b5e3bf25d8b083d", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "30450221009d6f38067264df8497d6888e4a8c316ec58ceba8a54c39ccb0ce261d114fbbab02200fae3f2f950f5c5e3387679f8ca341ec70cd90d0e32a30112f03cfb12cd9fc23", - "id": "9321e1b08faa544f592ad8dc7b60ff1cf845efcd28fedf8b445be3bda60434cb", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245100000000000, - "fee": 0, - "recipientId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402200aed5a4102bdafda00fda575294f149b393a798c510af8ba877b8c2d7ec8051e022004f7487c4f728c633aee5baa62ab0017f4b91cf2f494eb1c4cc9addc3e9155da", - "id": "0bbc9340798a18a81109bdfdbee9c9003f20a586dd9f80a39507c84588c1b4b1", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_9", - "publicKey": "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647" - } - }, - "signature": "30440220072124721ba7c997f7c29ad3d4819515fae7a67be2bc395cb73f114eb8d4abe60220523ac295e114de30ce8a4300f4670db91ad2abe1268460e6ad3463fbe9834b84", - "id": "d2e70f9d2de57240571905aa81db0b6883e27a83be2422530722d76b56e63ecd", - "senderId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_18", - "publicKey": "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a" - } - }, - "signature": "304402204b93b06e08e71e3317f9426a1d3d450d6293fdbf5a6b3043fce27b3ce65431e20220683609720ea1d7d921238ca8b5098d3d9c0caab7b1e26efe42a6aebbc095471a", - "id": "8695bcb906f5fd81d858794f7d90447aadaa38418d312e33115a81e856b34d12", - "senderId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_47", - "publicKey": "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd" - } - }, - "signature": "30450221009711559a43005c808113a1e9a01b1665495ff4bf30d635f7d98c752ead4cc3fc02207879e2a939914effe2b5c80cd515c4b3ff77a071b707c85c4444481878803db9", - "id": "55853d2d2a98def00c5ab842866a44d1db91678a07b6dd63d062508db28a00a5", - "senderId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_5", - "publicKey": "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565" - } - }, - "signature": "3044022025ba51a588253524557547ec492d71bd485fe5b291e60eef681c39eaf8ee781702202bf24c3d295c7a2c9aed97a79fb835506797dcfe7e7a2853e2578e7773c7e134", - "id": "553298aadf692c9c5d0334c307dd4ac0e277a49ed165c97ce1362f8ec639ee3f", - "senderId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_19", - "publicKey": "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb" - } - }, - "signature": "3044022041291ba10ad30fb9ebcb0e13902e92d85e2c3e98493b6d369d7d1e70e8474e31022009083444460c415eab6b4beed9e0206eb0733bad5d2a476af4db4f5b5e74b835", - "id": "90af927db7b258538c8e21116b5a31418c88ecc163628b2b65fac92a5a949b14", - "senderId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_42", - "publicKey": "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d" - } - }, - "signature": "304402205d4111c87874e696b8f4b8897d0dfe68fabe4ad5c5769026c6ecdd04f09a1e2f02207b9c8a2a16b50164215eb1efea6d5d9f4e693cbb7eec8535e526cf8ba68bb796", - "id": "8a920ebf5255a102d0c9c5fd720e0d36a6a3539991a2267442facf1fea2d0b86", - "senderId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_10", - "publicKey": "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd" - } - }, - "signature": "3045022100f15ff048872020d9efc561b8c837f542d54d43b9b071f7a6cc09643c6d4180f002207d0e82153a30b66f43fc4cb4b9b3093bb3d5dfd70f96928c8780c838b1448c19", - "id": "30738f376aa40fb3c8d8849a5dc698786aeb1409fa801c18729f8da624631391", - "senderId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_20", - "publicKey": "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751" - } - }, - "signature": "3045022100babb7410d09215def98078bbab6b5e5690c2ebf54960d94527226ed3925877320220342576d1d8fd2d2fe3b6974cab48a2e16b4813f022b341b32f88e13f572bf060", - "id": "ccbe1c27eadc1b3b33f3f87f645be4f756021ee3d4c96f4f094e1f82d5728a3a", - "senderId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_49", - "publicKey": "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374" - } - }, - "signature": "3044022032f2c350cc1319f5838d6880e91b49ae0438fb3a626ed9ab5e27ce8788e3347c02202cca18567c8491e0feea8a5f078e28605029346c509fac0c0a192e934f8c5326", - "id": "f99af0fbb4d65c2c3f2c1c558f0c0c0eac2724942802fcde02fa6da1d3a9000c", - "senderId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_3", - "publicKey": "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17" - } - }, - "signature": "3045022100f0cb5d885ddf3bd4a58837f9b86486da4171652a5eb39228dfd0ff9d34d9c7c602202dc6e3d268d745a7e8633311a337ec097382342049672880c7c2215cf58e5da2", - "id": "2dca03aed08533585d8bc609da5deb9f17ac9be5a8352769d7ae63d0db16ff59", - "senderId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_21", - "publicKey": "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a" - } - }, - "signature": "3045022100999f19fbdc9a12eebbb8c748a4cfc6c91b2233f333a09cddfd49dfeab6aaf38602203d8dc9d1551d400572a88ee812f51f897f8b35508713b789b2c1bf6dd0e88945", - "id": "5d7e51d57b5914ec201ab65a019ecdf651c4f267cbffe403fd2170bb95145f9d", - "senderId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_41", - "publicKey": "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f" - } - }, - "signature": "3045022100e86e648add940a1e637e32ea9187497c281b843da09597e62d0c927d7f43235102200479f64ae63abb55e338f9ce1073a5c46907f7a2a82ea6f9bd9bc29811683515", - "id": "eaeed4133da26612c53550b6572722d8c3380d0a2344da1bd270eed1ea91fdf3", - "senderId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_11", - "publicKey": "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904" - } - }, - "signature": "3045022100bc3b2ebc58a92bf38672206e8311e7ef0e54912abce7338155b11e7d191b0b5d0220765a568c1fa4665c0ace6b4bd3b7ba0f8329e2f25af7a3cc0d78b2ea398084c3", - "id": "bb91e78e43c59a19ac06c015d8a7ef09d7c5b274c9f98505e5a978027354b71c", - "senderId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_22", - "publicKey": "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a" - } - }, - "signature": "3045022100aae4868ab75a33e4e77f9bf6c53b920c5e7c523a7cfe271d1afc472655f3d6a60220499f1bcb79bc0fa830dfa939898db5c9fa8571a2788c8de0da7e550bfc818bcc", - "id": "a6e687647dde9c1db68690090afc4fcf11833dd35fff3186b6b709a1e7d24260", - "senderId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_46", - "publicKey": "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c" - } - }, - "signature": "3045022100c0cf1fc54705c13f70fde39c55a1703a4c612b8a919379cd5b1ada464c7cc8de022074ee62490a184010ad2418d3177ff2ab03d02d2589000176312b90422b1bd64b", - "id": "70262b0eec3ab5a60a736eb8a628cb600eae7522464a49791c0bf26e82318ec6", - "senderId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_6", - "publicKey": "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc" - } - }, - "signature": "3044022045db446b109215c6d3dfb0ee5869154a8a7624376c3760eec4fadc75a29033cf022003e524d64f3ccd0c6de4ca80a7327e2c47ffd16b3ad042bd25a02f5f64500ab7", - "id": "56048c449694964bee3d367609a7bc46c8da20f66878c09c01dcc53c3abd932e", - "senderId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_23", - "publicKey": "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a" - } - }, - "signature": "3045022100f8f69f2957781ed02d64983744c8e51fae613ebe5bbb330d4f509bdcf4fc6b6602205568ad1fd840e01ec26a24ac9a0ff093e978172da55d494138d018a45eb67893", - "id": "e15dfc4e18106480083b3c6211349fd9c803e334e9ba5eb62cca19ae3f57d8e7", - "senderId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_40", - "publicKey": "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689" - } - }, - "signature": "3044022021eeb9e1db8915a9adb99db72972cd17fc7b5b377fc532ac2c9deffcb2707edf022068b9e08f45bbebad89295f520ad40d7786fe64059d45df95551576e3acb736d1", - "id": "2bd0f888ccdeeca24a0134e3c1bf729582d284f32ee000d97f1417f1349a6594", - "senderId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_12", - "publicKey": "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12" - } - }, - "signature": "3044022040a9d0975f747df19792211546410d7c735aff2d26f367d1bf9233ffd1d993d702206890c66d4d0eb5de37df088c082d8fbd8da043817b48a76bd5d70f1e3f6b6529", - "id": "f75ac5ccd243e09fc9da2b3842a0654ca860d2dba5bb73866693a8a918937994", - "senderId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_24", - "publicKey": "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95" - } - }, - "signature": "30440220550c0ab565ab2de649ca7a2aaf2975453a1e4ab8b0d392d69663c0c9b6b80b7b022039047d4d1bf4e9b167a95adcde0a5a8631aeca060dfd426da28a10d968fb3a64", - "id": "aa2ed932faf4832848356beaf87e5381ee56a1a84fb485ba975acb28f8fcf5df", - "senderId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_50", - "publicKey": "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1" - } - }, - "signature": "3044022038df37ef25928d1a04516e982c99f49cbdc193603f814b48ab3802153bdd352002204c918915a3cbfa305c5f898ae4bcdd75394b57460f85c80daa0999751d466c08", - "id": "d30a726e1bb8d199d8f44700bc999c9a0a1a8be86e4be6a15764ecd424f9db1b", - "senderId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_2", - "publicKey": "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d" - } - }, - "signature": "3044022028dd44b9609b0b599c15a257757fd068f9014e33947c77776a6fcbe71879271b02200b46fd8eb0827da6de13f5efd63b17f29e8ba4600e4a690ec31eb08bf2d9af33", - "id": "1410b8b5f15c05528013378251bf5da30e04c8a6b7ac0f729b527664cfbdfbc4", - "senderId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_25", - "publicKey": "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964" - } - }, - "signature": "3044022038edfe34f7b89b4e69ea8b94e3335063b60deaee28246932147f53b2525924a402205b89f5e3d956aa49f24f81e2ba3447c19bd5c026568b3bef73a7a7d5160ad661", - "id": "58d14b74b71586e18f0499a50004ec2e0cc2e5b56aa53f4cf57084030ff90fa3", - "senderId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_39", - "publicKey": "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5" - } - }, - "signature": "3045022100bc1e477994bf4cbcdb5cbe2bd92c7d955a03adfe562f8e3bf04d2f62965e9f78022045512772d8453314361161b2bd2a39aa0a7fbb897a5a83f4c7ab54ced615b42c", - "id": "3ee53b3f1455ef0ddb52afe08854c9d87f42c7313babd3e05bb3ca4f94c495ef", - "senderId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_13", - "publicKey": "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f" - } - }, - "signature": "3044022052fe00e8e9f05b1d890f6910beab0627c823eb2d5875b4b9813a33aed11edfb6022034a723b827ce0e73bfdc0f535b244ffc983f8d549ee72b4d432de90d658db72e", - "id": "4a3d204c2916c93360d7bb11390e355bc1a930e3cf503965a45253d65bfe928b", - "senderId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_1", - "publicKey": "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37" - } - }, - "signature": "3044022013b2798a4ab4d741850abac10d962360cd4ab6a47dfac7c1c806d6f9c3d810cc02202742414ad8a04ce679b445fcd040fb877bbfed3d2692b873dec8cb46c01c8c4c", - "id": "7d0c5a44a7517f6ad7a1253db45d58e85aa1c735a282a32f45d28efdb7869d7e", - "senderId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_45", - "publicKey": "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b" - } - }, - "signature": "304402202c372b7b9679a8fe66f952a1d47d4327968d6e98770b215ada2fed6a8d87ed5502205a797fb511cfba557255dd37e028fb40981b7b65ad2ce8fe0e559a46eb274bf8", - "id": "70bfe97ae7452dc752ab4de0e2a0e81bd18bef07392c56e7a101257683d4d932", - "senderId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_7", - "publicKey": "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0" - } - }, - "signature": "3044022058851712200f7386d6b3c188444f9c8f05788667649ec17c71b9e514206eb105022061e6a4bc4cd11599792e03298f95509893d56af54d51e9f639981045e754b974", - "id": "f6f90ff09dee5be7d8f3d58d217772df7a95865bf8609d7d5b0b673e9a5bc953", - "senderId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_27", - "publicKey": "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d" - } - }, - "signature": "304402204878d69a166e60e0a779c31fbc48c67b70d2e4aed1d63c60beb9f070963e2894022078c46b6687f23493a4c2ed39709a183a0f7352568cc9cc2c1f0d7bf0d809a4a4", - "id": "f68809e407d20a50029fe460d411c866b79c7e09c076dada768a38d81f184aa3", - "senderId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_38", - "publicKey": "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294" - } - }, - "signature": "3045022100d5576393a1dea704cf79a5d0bc2757a3a5e66e1055103b52157fca05fc5693ec0220522832ce0e31b779decef83ac8ce764930de927df9ae1d6f6f99a3312d99c90c", - "id": "2ec6c6f33f00431ef063fbb8a79fb90eadb13a79bf46e6e1df36dd9434314df0", - "senderId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_14", - "publicKey": "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24" - } - }, - "signature": "3044022008a7d0bfe9c4c150566ddf701d08e84b4a5f84b07e3b1c91dde1cefa16d2a3c202200b787e898c0b2c68f4343e74f18ae7363f62b5f4ef2962386932aee09a9fa0d4", - "id": "e37b3efbf034bea4c852be7d7013978f8999eacc39549ceea775de197e14e8da", - "senderId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_28", - "publicKey": "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28" - } - }, - "signature": "3044022023b6fbfa5f4482a4dcc34411846696052b1592786ca87243b7d3344fc9fe9954022035402fbca22691de2497552c743f0f68c7591edd1bd7954ab7639548fcd558a3", - "id": "08268f5e6c15cf146523ca928f24aca65b162f363593d927c66144ee5df297cc", - "senderId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_48", - "publicKey": "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b" - } - }, - "signature": "3045022100b3cad169f29a3a95995b87e1b50b35583c1bff91d69cfa236f58ce452491c579022026775f4ef50b50ecf6d78b530b4633711394983456e6a45ec227b652c86e3014", - "id": "ad94ee2ae94813a638b93909930c7cc631c364b6c8528b2dcd6fa8f69260cc2d", - "senderId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_4", - "publicKey": "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93" - } - }, - "signature": "3044022007ac9ff2f272f3fda4947393b8688586cc8b2958ff5dc7931ac8f82c697bb76802202a66c28852bbff86ef17ac7f51e7eee52e611e825d91a9846f531ab3c3115c81", - "id": "76fb1984da9ef90fd7d588756163c97e00d3e4d6e9dfe78d9e3d3cb6d71ddd38", - "senderId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_29", - "publicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252" - } - }, - "signature": "304402204416e428688ad29928303fb2b00a26996cf79753fe70fb91c1f4635c644ba859022068ac5eab7d05f87c40ba36bd9dc149607c196778120c061698d7ab64aaade7ac", - "id": "0f442a91857061e87dd193b0b9f17a71719ca7e3da62841a63568713fc12b5e7", - "senderId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_37", - "publicKey": "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4" - } - }, - "signature": "304402206a248caa5949024202f297c38cee18845e344c5f140be74349787097d3b0a33c02207ac84336e02592bb5e00dcd0c490d30eb856b34177ab9ac03410d82a355a7b0d", - "id": "eed30a45c350fdffc5877458f7fe29f28dc4bf81aa1a197d003c9433148b71aa", - "senderId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_15", - "publicKey": "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca" - } - }, - "signature": "3045022100c99336ce666cb4a6db3727a61c04c14d8746365f72280d9984441b7d2b568b5402201759e4f417f683743e1d4a14f8a7a215009321cdfa29834b2dbdbe54ee22c1d9", - "id": "ecfba14a58f9d79782c4f905646df28bf566e3e7d1f17b39df6fe6b52c11de59", - "senderId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_30", - "publicKey": "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883" - } - }, - "signature": "3044022070de7b4d4ce64bd605c9d008142544c2b113cc84df07ed1982e0adf3cf69f4520220211b01710a6533a270dc2814c7f968adf27eb6dbf437e7a72960b013b9651a0c", - "id": "36ce5323859a92f302f77f27bd08ee3485d720f55842ccba353a47ea96a964c2", - "senderId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_44", - "publicKey": "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c" - } - }, - "signature": "3045022100a7c271633ecbf3c6641c7db36913b5fa0ea521f400a4848edf024648f3d7128002206a271f8a88644062b64d856407af9567c0b2937d4a3d89a3b3d07edbd3a0f177", - "id": "e120452e7c56a9327b2be7dfd3dcecae193f2e2e772903008b03cdf00146ebd1", - "senderId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_8", - "publicKey": "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564" - } - }, - "signature": "304402200394b6545015bcf2d0f291de57a4197cb6ef57b2ad5fa37f05e8a220913ba83502204d0d2f2206edba54ada5b8e5afd194ba83dd1bf15f744258409595251dbe3ff0", - "id": "7d15eee8e4e3be3d2c44acd51b87a816bdb593565d4ac358dab24ae9c8a5bae2", - "senderId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_31", - "publicKey": "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2" - } - }, - "signature": "3045022100989eb331951a13152aa03583efc765499e836c6fbafcafec4302b243ada8de5002203876fc4cf7fdeee4a095667e55a2fef84e5a7053e807b4d8e029883f0d578019", - "id": "baa686d521f95d265e7099cfd9ef14e0a9a92254dd94c16ce50c460bd013c588", - "senderId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_36", - "publicKey": "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e" - } - }, - "signature": "304402202be177dddfad323302565a866d38a3e7939e0234b16e7dc02075cf258502eba302200928a139ec1a82b4609fcc1bd6d1d027ad050e93fcd2eff94181936d2d43e39c", - "id": "9fcf7ec6fe98ed94710e212226d8b90df7e7467d66dd4c5c9d48474388be3099", - "senderId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_16", - "publicKey": "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9" - } - }, - "signature": "304402207b4f8c09a728acedf3b6ba0632e12d01670c683215053e49dde8598954d85a9a02202a7d7930baa17c2134b314e47dd6c334c828f78e573a2bf92fcbc1146d630541", - "id": "c35e4b1e7a2435664fc0939251c2052633ebf4b51fb22d15e71bfcab85b26de9", - "senderId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_32", - "publicKey": "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055" - } - }, - "signature": "30440220127d27312345e015c681adb799c1a87d16fb0caaabd5020b39257d567816b91c022018b2388f6d2d9afb3714d84ed102b3ea61159772786033c855947613c7ce7b5b", - "id": "0d682a3a9c252a674043bee5240e456dae2685d76fbd3bdeda6ff50f0c442fff", - "senderId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_51", - "publicKey": "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a" - } - }, - "signature": "304402203d0ee691830e4d001553bf4e49b6d9669b3c959376f391410551c8adc679dac902203ba6e275bf6d543efd19d20428649f802d9396bb0967114a1f09c24827be1da7", - "id": "ec2373b0d609ae72fb400ffdfbffc59670ebbf1c15f59c0ac22a4030dae700e3", - "senderId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_26", - "publicKey": "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983" - } - }, - "signature": "3045022100f2cf77b0510f589b5aaaf2b0027ffbce6ce8d4873cdc67dc8900865d156de3be02203c22e30945618683182f3d3873e6b3657e0900b062f866bab2705cd593669e79", - "id": "3cb2f0f7d05a515d4c5c873cbe96e33b1dfba1b7718e4548de7f9da54933b652", - "senderId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_33", - "publicKey": "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe" - } - }, - "signature": "304402201e328159172d543d2225c247c6b728800c52eb724f67c0e919f6b7215e6bd7f2022075fc02fe0b14a1499c5602d87ca2c99d6e789beaceed2b9702060dece872d14a", - "id": "2fd77e744399c9632cc8f106c39237f201dafda976f1040235359f99eea3b832", - "senderId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_35", - "publicKey": "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e" - } - }, - "signature": "3044022063903d82e8bd15a6741a298b9a6007d0dc3626acfe2f072c3b624ccbf91ce3360220486ba4cc5591d8aa31b77dfde025b61691dbaad0feabe13e840d26e40010c5df", - "id": "5baf9e318c9e4cb0513a21eaea27e51c849f95fddc963207fb07aa2fd2b9f9d4", - "senderId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_17", - "publicKey": "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357" - } - }, - "signature": "3045022100efc1bc16e0b646da48f84822543b62ef5253bfa98bed6613f2d6d4634076e61802200ef243f9dbac7633a8819ce45e2a85d0eacfdc9a33a92bd3a03e90cbd312b823", - "id": "b4a959ad75f81b7fdbb957c90a3a63a6c5589e7819e2c455733a3a2b4b034634", - "senderId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_34", - "publicKey": "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80" - } - }, - "signature": "3044022012e52a479648990bfc1ed12bf901cad865708ff45962c3724ea67967be4f9d0102201901525ed8dd090af6a2637c123afb304e9fd178794addcb88d916227e66887d", - "id": "6439f2308efe31ac52ad06ef1caa45b9abf6c589118b7997da6a287325ca36e7", - "senderId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_43", - "publicKey": "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e" - } - }, - "signature": "3045022100a0874d1582ce210081f7ab30e7f951dfb9ce8f512d237f8a8cbd5d85569ef3b902200f0053c05de3d6e5ada4e4cf1403a836779d653573c2f374055645cc954c4c4a", - "id": "b0733072e98d3d6afe977e32f3dd118c15e79212232417743ffb551dc2a2ba55", - "senderId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW", - "senderPublicKey": "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357", - "timestamp": 0, - "asset": { - "votes": [ - "+03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357" - ] - }, - "signature": "30440220158ed59156e0eef2d2b94a296451dffe079be701b3d74f0443ef43bc266b334202205a2c39f57abfcd279d568608b90884b3ebe107316aa7552eca35c743b318a47c", - "id": "ea294b610e51efb3ceb4229f27bf773e87f41d21b6bb1f3bf68629ffd652c2d3", - "senderId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7", - "senderPublicKey": "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80", - "timestamp": 0, - "asset": { - "votes": [ - "+030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80" - ] - }, - "signature": "3045022100898da9f693a458a6875344c6c4cb73069c4075904c75595ffbc665967d84b07002200f168aaf3ab1b52dfa74599394387dc4cf627a447fbc5a91000e9d251cdb20c0", - "id": "3639b5dc6d19d46d8254d941bf7ace0f3da8a7cf8a56361921b260820c7239cd", - "senderId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1", - "senderPublicKey": "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e", - "timestamp": 0, - "asset": { - "votes": [ - "+032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e" - ] - }, - "signature": "3044022055ed9a8b55ccb3bd0945a710269b6f243f1dbfaa28467d3218a17565eb0c962d02207d31561478f16d93a20f5454ad565dea24e8dda4ddc464cb011f4b6b360c4e81", - "id": "fe24509580cde0c2e2f49defedd3a0f7572d2f78f90b51a253b0d8cebd74c20d", - "senderId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof", - "senderPublicKey": "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055", - "timestamp": 0, - "asset": { - "votes": [ - "+0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055" - ] - }, - "signature": "30440220092f367f833d677e8d0609ad1df65f389c2c35d1501c71c245c2982e6a832268022018e67445f525613d6cb6ac0c9683bd0f55bd40d9c929165649414f083c9041f9", - "id": "6a76553db794ebf4d5f60a7d7d71cfe29f4dbcaad9610106fbc578cdc7167cd4", - "senderId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy", - "senderPublicKey": "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2", - "timestamp": 0, - "asset": { - "votes": [ - "+03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2" - ] - }, - "signature": "304402203dc028b5013c36b03f97b111a8d7c05d0cd8e505b0b0d18747c0656c9b5cfe8102205e9ce8a78d1183b3e9880c69635d04218d94d17808bcc3f92e7af53195c23daf", - "id": "0f9d7e7708918b77afbdfffb63eef8fe87ba36e0131c88b44c1a7f81750cc025", - "senderId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9", - "senderPublicKey": "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e", - "timestamp": 0, - "asset": { - "votes": [ - "+0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e" - ] - }, - "signature": "3045022100a80ddd7c3adaf0e97ab938773fc78a716f3054d7e03afc1ddfcb5005badbd2810220231c0dabe2262149f994c939f9dc90d46b9bd7ca96b19aad6788cd3571e4f71a", - "id": "0ac77b2637fb25be42b3b60d1651bbbd788aeaba933a08ec4a417c7b4c54e087", - "senderId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT", - "senderPublicKey": "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883", - "timestamp": 0, - "asset": { - "votes": [ - "+02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883" - ] - }, - "signature": "30440220772c9cd8b96f74fcddc429d57d466eca6fc40fc211845f59eeb78cb027e116c5022004cda291587eb118d622de21333d2a5783969794b5b0101ad8b1044c7d8058af", - "id": "4b0dda465564d53981c0e36d73caec888e3523633eaa80dfb99a9c81b2604c7d", - "senderId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU", - "senderPublicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252", - "timestamp": 0, - "asset": { - "votes": [ - "+0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252" - ] - }, - "signature": "30440220406d54714b6425ae4553ea8bec75f31fe52e9b1a9b6f6897151253ab7f637d3b022040a2df4b69840f4d9b0b67658c75efdae8d8269780d4cc50d055fa63922dbb9a", - "id": "c7db9d36d97ff0168d0d670ec695e1dc786dfb93f4081586870c8793b50e5f17", - "senderId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK", - "senderPublicKey": "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4", - "timestamp": 0, - "asset": { - "votes": [ - "+030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4" - ] - }, - "signature": "3044022018b7e51118ec83c985fa4eb3d7f0cf0655753bcbde7e82bac521665fb1c0ffaf02204e2ace460b2542db8c77e41d05d5e02fa5514b746a0a1e947256925846ed19f1", - "id": "c41f4cffcdd523f1718154d5bd5f4f0bec0376076b5f8dd340337e9edb4821ae", - "senderId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW", - "senderPublicKey": "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28", - "timestamp": 0, - "asset": { - "votes": [ - "+03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28" - ] - }, - "signature": "304502210088dbe249503da43c157485bfd4f2c95babfe4d0b8bbefe44afa52529b824a79e022045239b6a374fd9aca52c27171ee66b4863c956ae4085c9760d863b1902596c1a", - "id": "b1736ec6a1ea4c6d4eb278430a8ee214c88daefe296ba98530e692f8b7a7434c", - "senderId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej", - "senderPublicKey": "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d", - "timestamp": 0, - "asset": { - "votes": [ - "+02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d" - ] - }, - "signature": "3045022100fcdf750a775e728a31691a1b38908a7f990b579da510959cc2c63442f5ffde760220316ebb051d9fecb2486771dd39921fb12675b6d46b2441dd1db3c42fad0a59b0", - "id": "069271456015c2ff842771775993b8afc3404bc070572eeeb0f2fd72d58e18dc", - "senderId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U", - "senderPublicKey": "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294", - "timestamp": 0, - "asset": { - "votes": [ - "+0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294" - ] - }, - "signature": "3044022034ce8f77ea9d0f5cf3a9135d7b72d0ba3b96ac6d7eaa3670e9956aef2c9a83cb0220626d1f269128f673a23f9993ce00ba78a08103e697298be29a4c8ee94f204e3a", - "id": "9a99bba8340e7ad4e05d8424a0977ebbde428d31ee066c9828bd06b42bb42a72", - "senderId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2", - "senderPublicKey": "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983", - "timestamp": 0, - "asset": { - "votes": [ - "+02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983" - ] - }, - "signature": "3044022039ae1155f8b87a61c38b25cbbf30da6ecf6cfcc12b25c2e7fe576373754a41eb0220061a66a893129fbad5d48cdd19cf48b1a0d133dd2f3ecdc60ee7b87277e1f81d", - "id": "6c2c8926420ac269b50fa30127e0e791afb2131aff5821ca7aa80d38a0182048", - "senderId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf", - "senderPublicKey": "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964", - "timestamp": 0, - "asset": { - "votes": [ - "+02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964" - ] - }, - "signature": "3045022100d0dac2b7691aa059b1048d7925a0c5d5099f6e9b0f2e321e6d4f128ab1b3272b02207e8c4f643f8f9d1c3f81f0cce6a698df2da2ab71d5b01042766bbe0f46f4a775", - "id": "9259193c5de72276ed7a99f9d507dd6ea9856411fda521074fb41a556294fdf7", - "senderId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9", - "senderPublicKey": "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5", - "timestamp": 0, - "asset": { - "votes": [ - "+03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5" - ] - }, - "signature": "3045022100d5496fec447367ab6b53956a8c40cd8566e050ebb3b92d2c0b2a9d09bef36c7402205e32367605372375801f7b9db39aaafb46ee763b1494f0aca144fb91f3415752", - "id": "2a41e5946ab0773ca2334bba9d3510184bdd258f1c651ff8ec95b7b64a01dc2e", - "senderId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW", - "senderPublicKey": "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95", - "timestamp": 0, - "asset": { - "votes": [ - "+039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95" - ] - }, - "signature": "304502210099249695dc38826e04c8fcffd2570b98c43dec4788cc6a19737ed0872f17ec3302205301f645d803ad5df4ab1a700446e28c7cd76153607f6a2d68ae9168d46f3fe9", - "id": "e5c09b0fb2c24c57a4dcef0078953093800329ab4dc8e16a9d9f68215b5acd3d", - "senderId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU", - "senderPublicKey": "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a", - "timestamp": 0, - "asset": { - "votes": [ - "+034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a" - ] - }, - "signature": "3045022100f983b03e319aaa6c6ab6381e3ef8c0c035d6e3cc2139cedf70fd4e385393e38a0220286f73577765eb3e89e362785ad8a6de572bebf41bbc1f515b0ea93e41801eb3", - "id": "00b2c0455ef6f508d65f11bb49e3cfe1e6062d5fd153cafdfdfd2ccbf9c646e5", - "senderId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr", - "senderPublicKey": "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689", - "timestamp": 0, - "asset": { - "votes": [ - "+022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689" - ] - }, - "signature": "30440220103862ec51621ca27a0ec6b2817848e8824d2d09dbf7e6aac2f45aeea5d2dc9102205e8cce78b5cd7148aa4d406dc7b491dd7758047200e10cfe1e5fde5c56107ac5", - "id": "e25439ad11cb8db3d49ccb3b8b608c1bcb24cb29b2e5ea15101cce3e475224eb", - "senderId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ", - "senderPublicKey": "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a", - "timestamp": 0, - "asset": { - "votes": [ - "+03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a" - ] - }, - "signature": "304502210099241ced4a0fd1eb02f5cdcc880ae5f48eb3c7e490d4520c20124ecbf403893602204729dc6cacf3e87c97ca57c1be54d1e80791bf31ef022135e68fc06c950f6994", - "id": "1474f50815c6c7df41ab652414806d61abe15bee0d41f32d772f4e2793badce4", - "senderId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX", - "senderPublicKey": "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a", - "timestamp": 0, - "asset": { - "votes": [ - "+0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a" - ] - }, - "signature": "3045022100eccf81d44992c49a5ee37c6fc2ccc4b6bee9aa44888513b3e18e79452ede3156022056b0ddf079d2918d72e8781d3af009c87e6058563591dfd6ee0117b7df5534b2", - "id": "b394e2a8b5c2d20a72ed288408b8f0d48aed922edbee6e16c1c5b0e67517214c", - "senderId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf", - "senderPublicKey": "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f", - "timestamp": 0, - "asset": { - "votes": [ - "+03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f" - ] - }, - "signature": "3045022100bdb87894846eccc5a5473edaee1e6dca5f3469963e22f06123b6bde195aede0e02203d0c6833e87c5e60f4597ce624d4c2502a0562b4e54d943f82a4889e3cd69532", - "id": "6a399099bac6c74fa5e956512ef8b3a39f6f946d5d6996f192c2f1dd5ba172dc", - "senderId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv", - "senderPublicKey": "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751", - "timestamp": 0, - "asset": { - "votes": [ - "+02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751" - ] - }, - "signature": "304402200785771ccf1a6a40b51183a190d4cb4ce76b9ffd4c2c736d7724e6c667113d020220649ecfe73017d8dda96a7914793470ee7e582693e4866df123b1032194c163b1", - "id": "f20a831a6bae0a85470e308fb66517e70db479657459f6bb39f2cd1783c565e6", - "senderId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv", - "senderPublicKey": "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb", - "timestamp": 0, - "asset": { - "votes": [ - "+0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb" - ] - }, - "signature": "3044022020b79e1f07bcb17cae9485b9f44e9f583ca235da4ddd363b905fafb884347f71022015a20481b43720ddb3b1e3ca64b1f47e59b5cc2016a62f43327ca14533384dd4", - "id": "7a1285be87dca9718bece5b84266c1bf6801a39cc111d534e660aef9e6d26929", - "senderId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg", - "senderPublicKey": "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d", - "timestamp": 0, - "asset": { - "votes": [ - "+0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d" - ] - }, - "signature": "3045022100b1615d16763c46d42ca2aae967f04c1c07c119b5af7a378c262ba85515a8d35002202cf7df91676cd137943720e93f06c11907412a6bdc5ef2157cf536a203cf83a3", - "id": "76fb5a1de90f245b1eeb79cb11c7bea7c8b738add0fb8cd95191186a944b0229", - "senderId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri", - "senderPublicKey": "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a", - "timestamp": 0, - "asset": { - "votes": [ - "+02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a" - ] - }, - "signature": "3045022100e3c7b5d6a72acde4d22e8c1c6cd864c549deba89683f4b84320407d6c380827c02202da57df0ab7cd381b776bdf85802aed371e7cea7269a84f911b1d8e9956badee", - "id": "8da75c8100e6248ab37cc92f72ed9facec3067f4f82f03db8bb8063791463fb3", - "senderId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t", - "senderPublicKey": "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe", - "timestamp": 0, - "asset": { - "votes": [ - "+03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe" - ] - }, - "signature": "304402205779b5d8acbfedfc105fedb6fcbd4636713ed27605faa9bd988598072640a958022042d8a8b3d7910c7c385f3707a317c5d445d56da250f8d127c71df2d9d4c5d86e", - "id": "fd26e265be88289828d0ce7ffc5faeb9849e1f4cb37a8f1dd5d6fcc436d910b7", - "senderId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf", - "senderPublicKey": "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e", - "timestamp": 0, - "asset": { - "votes": [ - "+034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e" - ] - }, - "signature": "3045022100e18a89fe1fe0a8acaca2b6461314e784ffebbe7374f6aafdb06934e83985ccbf022027314b21a4a25b477bd7cc070b4e00ef8f3d69f3f1af028b96571dc245924c00", - "id": "41d92e128e6b8367cbf8fd111e5263d52e1abad553653f975dd60d7f7c5b637b", - "senderId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9", - "senderPublicKey": "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9", - "timestamp": 0, - "asset": { - "votes": [ - "+02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9" - ] - }, - "signature": "304402201c614c84dbae26f87973c9e2b38df883fe0c8c469080e31fe32a4c4946d50b67022075b8fb498fb1384aa6be785845da02813185ccf095597b5782618033828af4d5", - "id": "1e4a1f8aab6fbf8682c2b35e0d04e9e007ae717ce3f4a82894747e5807e3c759", - "senderId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV", - "senderPublicKey": "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca", - "timestamp": 0, - "asset": { - "votes": [ - "+02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca" - ] - }, - "signature": "3045022100b1ee6becc59d594776a40e5b3caec82390d273b703ecb0d7caece44953141449022016543cc29a28882845118afab6e51296cd216bc662260c28e5efd9597b6025b1", - "id": "2ce068bfccb3f967f4004e9a1e81614a738e55e45c80114c0af30a085f71a2e9", - "senderId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ", - "senderPublicKey": "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c", - "timestamp": 0, - "asset": { - "votes": [ - "+022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c" - ] - }, - "signature": "3044022036698a329d7f5f751f91ce02bc188a7527a377d01583b70427cfce64def945ec022079afafea10aa32394a1e42a80577de3869856656221d5f259e05fb44f01668b8", - "id": "3478d1ad3655e10fcc864f191972322c866616866bb1dbf66d7b66b31cd95de6", - "senderId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA", - "senderPublicKey": "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24", - "timestamp": 0, - "asset": { - "votes": [ - "+03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24" - ] - }, - "signature": "3044022035fa7be80cf881eefefc12b11de04ffb2e2e92815cf05074afef54a3c5b2eccb022041f3347f59db0b3caadefcbfbc5ae275d3fe3e2a52fe1504b23628d4b79a43bf", - "id": "8adfd8e73e96188ed9fdec459d88db1fb041a2b25b3f64830476aec661ae5010", - "senderId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm", - "senderPublicKey": "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f", - "timestamp": 0, - "asset": { - "votes": [ - "+021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f" - ] - }, - "signature": "30440220630da8a73979bd3988b7f84fe9e83a429cf3239f54c140c3dbcc407140513fc002203664ad54ed9f199f2683479b988bd97ad8fffb2c2d5dfdbdb10858aca4abfaca", - "id": "e306328ffefcd9e3809e7390a358199a62cf8ef037d57af1f5c7b54d728d427e", - "senderId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1", - "senderPublicKey": "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b", - "timestamp": 0, - "asset": { - "votes": [ - "+02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b" - ] - }, - "signature": "304402206f1df93f299ffedacc25aa201807df47d32c43369315cf9db280963c357be56302206a66acd553710f49bbb7b803a2bcb71128c8e617ffce66b37b7c968817349247", - "id": "dc69bc8f78502ba34655ed062987788939189709a4112760cd8807245d7461f5", - "senderId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8", - "senderPublicKey": "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12", - "timestamp": 0, - "asset": { - "votes": [ - "+03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12" - ] - }, - "signature": "30440220629e696a10e04d4fbc10a5ac443bf9bd40dd5d89d4b214224abe47d7ab5600340220643f361a24d9916e2c5aaec7bd7d8a6a0d3ffc5fc0b62c3ac4906eb799a862fa", - "id": "c3f49fb80c40f7779b32ba23616f5573a6ba58fc60c4629c2252933038dd89f0", - "senderId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2", - "senderPublicKey": "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904", - "timestamp": 0, - "asset": { - "votes": [ - "+0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904" - ] - }, - "signature": "30440220660f9604896dad2a97820b0d7524f0bce5a8b5766f150517d5061fd02bddf768022055e87c25891d4480e66e5d1a71e42cd5a4bef3ab2b2651cd72d44f30a4b32309", - "id": "8e8ac1b1a586e86867abbf25d63387bb6dfb793c691f0b06333c1581a9a568b3", - "senderId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT", - "senderPublicKey": "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c", - "timestamp": 0, - "asset": { - "votes": [ - "+034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c" - ] - }, - "signature": "304402202e2ad64129f61ef1156c4c7e80ab862d4823d62dac502685f53028536ddfb41a02201a3ec777fdfe8fae9f7cd5251fac322c1b6a2a4d41b3ec456daed474986d4872", - "id": "ff73565c373f2cefebf86c72dda3a6a6205750eb03b69178cb83378620715e1d", - "senderId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q", - "senderPublicKey": "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd", - "timestamp": 0, - "asset": { - "votes": [ - "+02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd" - ] - }, - "signature": "304402202e5c78cf21a088db10e1e1f64d98d84c8d3294fde7bc322d4af06bfe99d4c2e302207e7912a16a37b641a9f8c7c722f2b0d699917ca73e4d0f21584b717fb7f02f13", - "id": "3822273b496f2e253081cedf382e4f9937713fabb83449e1f892377cf536e68a", - "senderId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo", - "senderPublicKey": "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647", - "timestamp": 0, - "asset": { - "votes": [ - "+0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647" - ] - }, - "signature": "3045022100a65ce45164c9bc3e018e26703370c9deb2933ee3b4e814619043cc37c4a39c4802205ae4931ac9e8dffd714c3b601fe248a49c0185c8367887205f497d951c52eb54", - "id": "430d6db0b87c25dce4ce14ac907c13bcc6efa5d95135f05aa4ba7596ea9d400c", - "senderId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN", - "senderPublicKey": "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd", - "timestamp": 0, - "asset": { - "votes": [ - "+036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd" - ] - }, - "signature": "3045022100f3cdd7f688ad2d7b6a5b9cc7e793cb8a6e6e07d3327bc67add64691a53fd2911022026ae1adc8f4fcfc01bcca3efc83019026755b443a504265ad1f46f69d1f5951c", - "id": "dda86ecc0332e6c4eed1c0a5af7424374089b85dd274a300fed51b86e2655587", - "senderId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj", - "senderPublicKey": "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564", - "timestamp": 0, - "asset": { - "votes": [ - "+03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564" - ] - }, - "signature": "3045022100d419072a752acd55792257c96099fb14c56c29112a00535d39bca96fbd7951c902201abdf4db247dc956d79f4543c389823fbd1a9337f95d30df39603a3b52486bfb", - "id": "0998e9a055c53bf6697ee76af94c7a830c1364016d78fce889a21bc38ed70cd5", - "senderId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN", - "senderPublicKey": "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0", - "timestamp": 0, - "asset": { - "votes": [ - "+022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0" - ] - }, - "signature": "3045022100ba1e0ab761326d2a53cbda2a4a5135033c94d8166864d2ad3ceb963b4a0c046402207d755ecf4ada9fa2a598fd75e73a59d30cb83e01f510020b48b6bf162dc60b27", - "id": "be13743deb8486a575d1fb564d2b07d797ac77148d35793c9aca43c0d47aad61", - "senderId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA", - "senderPublicKey": "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b", - "timestamp": 0, - "asset": { - "votes": [ - "+03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b" - ] - }, - "signature": "3044022038a491e2e13ac32025209d00aec1af31b73a8b6ee77ad9b8bb80a34f5df59dfc02200ce82c89fe9f88bd5af236ceeaa80f9954e3fb4af7bc884c447505751d49c134", - "id": "f1d3d44cc289837de9623cba8891a1ed1cde8918473a91e2daead29975afad22", - "senderId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx", - "senderPublicKey": "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc", - "timestamp": 0, - "asset": { - "votes": [ - "+0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc" - ] - }, - "signature": "304402202ae599ce389cd030b8ab48ef53113458b9ba8bf9c9ed09c662eba2849bf540f802202ed63f8af492dd0b67d1b451170a989418a42466a3a7ffe89c4c5a18337e8fb9", - "id": "65ab302a44ea7550891eabc3b4a8d5ecbcb80784c4666195d5d0b7e33394300d", - "senderId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK", - "senderPublicKey": "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565", - "timestamp": 0, - "asset": { - "votes": [ - "+026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565" - ] - }, - "signature": "304502210088a3a4e82d307c238e01ce154b57631d4429e0b591e828ec36839a783736e842022042c6e1d719781e2edca3dbfe84ad13b9e490821a47ccadfcff379decb9c873c0", - "id": "d26a7ea56f398634a81086bb15c2f0c863c71b8bd728304d324d8245a8fb6c73", - "senderId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz", - "senderPublicKey": "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374", - "timestamp": 0, - "asset": { - "votes": [ - "+032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374" - ] - }, - "signature": "3045022100ae5805541f085a50076835422b2581d3b7a128a05b4f068ad7e3c14cd02799b802205f4bb40e06f90e02282ae74c0aba97923e601fd78234b9585468c4fb73f47893", - "id": "02504eae7ff4963c081219523bc48d7a07de4c29fdc1622224547f9a7c133abf", - "senderId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp", - "senderPublicKey": "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93", - "timestamp": 0, - "asset": { - "votes": [ - "+03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93" - ] - }, - "signature": "3044022078d38cabd8f427ef381d0aa6a0b98c6a590cb18f47acc1d80b429a1c1959b0ab022022a70d4d93d650ca3121dde6065e80cd90d1e2e91cb90f0d0b2eadde609e0d75", - "id": "addb8c1baa833baa52a5b51d8a86f8524bde826b5c9f0a99e57070e6323e1dfc", - "senderId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv", - "senderPublicKey": "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17", - "timestamp": 0, - "asset": { - "votes": [ - "+038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17" - ] - }, - "signature": "3044022076dd065e3fba825b77884a179d0231d7fc9e7d3a02e34bc6565fab81a84e559e02200a880c028e690a9d6f2c4c6576b1bf3e913817c834da8ec6afdbadfae78d341d", - "id": "72f31f9a829b93045ef2e860b24c33b9be6a2621c26914acd42121215c1d517e", - "senderId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P", - "senderPublicKey": "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1", - "timestamp": 0, - "asset": { - "votes": [ - "+030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1" - ] - }, - "signature": "304402205261d9d8ded6364fda8b10bd477982be84990cb010f9214d52c492676814e1f40220489f441ffe2478d361a12ab96caa59da495fe62d61d0e2255aa5ec4ed789afb8", - "id": "1f17b4ba072d205761ed3f786491eaf684ed3601b69082e487e568aa74a319e8", - "senderId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd", - "senderPublicKey": "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d", - "timestamp": 0, - "asset": { - "votes": [ - "+02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d" - ] - }, - "signature": "3044022040219da41054a3eebd3122df7f09a62a4e8b4fdc287ae77221f2217b42f291ad02202b9a70c54bb546a604eafadcc086ef6b6570f57542374d87de02ad7f61fe51a4", - "id": "5fa837023159d6a3d6cf7c5b2ed6fe05ff7df19300226b2f0be5a48a06993780", - "senderId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo", - "senderPublicKey": "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37", - "timestamp": 0, - "asset": { - "votes": [ - "+03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37" - ] - }, - "signature": "3045022100ded426768f114f459485ba6ae293c9649b340cf2dcb15e8e887fbb5fed6f7e0b0220752297022de6e93ff64bb9e07b4efef8e946cd2872f84d9e1cb3165ff5c342cb", - "id": "0a16dc31514629a36d7237968ada6a95d6cbec027b7d26e1e0f0d7d4febe9494", - "senderId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD", - "senderPublicKey": "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a", - "timestamp": 0, - "asset": { - "votes": [ - "+02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a" - ] - }, - "signature": "304402203aa292e7aedcd62bb5a79c2521b666b8e1886b57923d98f51911b0461cfdb5db0220539657d5c1dcb78c2c86376da87cc0db428e03c53da3f4f64ebe7115998f00b6", - "id": "8816f8d8c257ea0c951deba911266394b0f2614df023f8b4ffd9da43d36efd9d", - "senderId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD" - }], + "transactions": [ + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402205fcb0677e06bde7aac3dc776665615f4b93ef8c3ed0fddecef9900e74fcb00f302206958a0c9868ea1b1f3d151bdfa92da1ce24de0b1fcd91933e64fb7971e92f48d", + "id": "db1aa687737858cc9199bfa336f9b1c035915c30aaee60b1e0f8afadfdb946bd", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100ffff4e9ba62e5e3beb37deee052824da83c4030925bce09f190151652d0669b8022056a432e56a2e1b026d4b54f6c34ce88a0c9cebdccc730659c03449fe878c66f8", + "id": "0762007f825f02979a883396839d6f7425d5ab18f4b8c266bebe60212c793c6d", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022001a6326e5d1eb06d0ba1fa39446bd6d56ea45f0c269ebbce5dfc6a649277cfcc02203b252d3a6ef2b22349d9d0a9110ce28a199c39dc8b911edfa82c297a02009d07", + "id": "3c39aca95ad807ce19c0325e3059d7b1cf967751c6929035214a4ef320fb8154", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304502210084d855eddfe616cf1dc238b19226c7959c2fc4027ae2e8aea6fd8e9eb8928e6b0220440f980e40c1c56348782fd69d49a96944df7ee5b68d18028600e0e7501d4000", + "id": "9fdf6ae86f7c005b3b7dc1b9fb6411219407ecaa93adff85fdb61710f5121638", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402205438b8b9058bbde5d30794e7681e400e52b5fbd22324c5b6b521f97bc8b8aabc022000fe04d7afbd2e668b1d4576988ed596dc92251e33efebc081e2cba14ad5a898", + "id": "1d7c68087c875d7ce555b2c3e71e1d91a1ad62d0c2497efe3cab91415e634041", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100b2e634a95b011a68489870f003e4bac4a4f0578bfdc6b9f645c934016c2c0463022022cd4ebf276dd627d98be4b697bae2df10b86d94e984da2eb7e011b08d6dffd2", + "id": "0c993e115ba26981b0be9d22e7c4a13b0f106e0cb472f9d34eabfc8e414dd528", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100f965e5c280acb22d1cde405223fe9a6fcb765844adbc5321b17a268924e1f597022043d31b1edc5fe0cf60a960d84e3528472cdf34560c9463979043a409f37e7f29", + "id": "c279f2eb1f9e6e7d4b0ba7a98233a0f1a2536231976c99f56f64b248eb06a0c1", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "30440220715463c316a75959dbfb6a59a013fbf914bef1ff739ac8000d49dabbf5118df9022019345ae1c34173dc214bae82f3cfbf438092f0fd2d277acafe3e9deb644b1a3b", + "id": "7e2fc9ecf23e909a3d0fbecd615445a0eed8c2cef18e01b1492d63f616f5d87d", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100fdd8aff26dceeb5abb6e5e8a8f468c8ac1997a587225298e3d8135d57dadf4dc022072ab80a81b301a162ed5cfa67d213d5a3980185088632f5f592351aff8aa0e9c", + "id": "511c0e1076104743f98932f8e7720bdb3f1539134edadd331914fd9ece1ebede", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "30440220635e04ce278870f17fcd1883aa26c568e63dfbdd302add39aa30fd3637c79c2c02206fdd9e7b1f4d238a97d26ef1758927e2d39f121687490f2bd79831e36afdd43b", + "id": "0768d5016c53d884e3d68a09d1bab0d730b7067c71ef4ca1c4d61b3815f5ff66", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402200b1dac57ca6565ac31afb99686f2e0f0e8dc219b9860b295ca5444a1663cecfb02205787393561fe407449af4aaf2f621db9e4d3f11c7438666cd694d495c0a0c41f", + "id": "1aeb50080ea118165e5041f7a897974c2ed1ebde08add85dc78cc7cf73566a91", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304502210098dea25eccf31ce6f874a9528578805aaf07be8b41f1571865793f9e3e6e3c97022033ae9c73dad44c01fe6362665fccf63bb1a0ae8e26f77a1cf60b67dc96b05343", + "id": "254f0f4fa277cc651a746d6ac371eb27afc3ea155ba060552dd26b8e83d17b72", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402207f4bf346aac501e766156818089fb16905a9bdca69ff6d5a55ba918a08afc7ab02200ec2c25cc4bb30e2c176d55630d8e2679b899c14ab4ba43c3d62955dd940425b", + "id": "e5ebb02e8e8a6708e22ee5ef99fe1dd8b6eea1095be6b772aa21bf63cf7ade5a", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100a0bbc15bdad648bb9b439f1d34b12b853442d1cfd4ce7f569905082801fa58e8022036b4e73edf7ab7226f8007233f77b1d497cb6b4736f02721bf1b399312ebe114", + "id": "8a686b21477b64dfd85f08f8598a0f121ca1c7d65ccaca9e42326c75fb5f3abb", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402205d77dfcde527dcc6669bcb01c27b92c1a6399e35ebac9e69415645f596ab1d2802204179497bfd952f44d5f9e295b2a3219a290a4a82841c084a18553b7712e26415", + "id": "21175347e2acfabc09a7593aae0682e39fe7152199a90561c11125f525211243", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100cf77c16df9185727ff717b71a94f8b29ceeae1e5bb3a28da8cef9df5bc63b7c202207bca394ce9ebd344a548e5a5697f672dedbef640dc1f9105f7c063287bcd1840", + "id": "ce1d9b7377551f36568127f5b635b5443f5a58abba6566b50a8d4d7b53c8a874", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100eb8daebb5484f3b0a738c9344fb28298c596f9486963f8fe36e2501ee6876f2a0220559df66986dc9a9a8e76982ef85f907c62745757990c69f0b17b6ae5a7ca4719", + "id": "b56702f5eddad0d8dbbb33b6b1ca3e07e4740def9c5dd2aaed9a70b90a4e31b7", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100d088e9bcd78978f2d67e7c7bccecfb73ddd0d1a2dad5b039390812320355722d02207affe83d815f04f6b11abf98eebe0488bfb87f8cd6513d44b829008ed1c15ceb", + "id": "a73c053c42e83a83498cf58e5b077b31443e265ddf8228081cb17a36bba366ae", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100db16a8e9682f07efb607bc7c75b654646ff449761ed146ab9358e69d29fadd7f0220436554ad78db0e04ae5b573258e2c8067848e89b55a6e8e1e25011a43882a643", + "id": "2dccb8b44ad2e598673628fd9d74e336b467a0c941d5e257dceb85c8e0a0000c", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100b03738eccce8ad0b8ac0a656119c2cdd202089c5650d8e1486bd13eb9c3158980220059079900c7fdc16e799c50dccc074726fbf0068044462faabdf1e73f9f9bc38", + "id": "b2cce30021d139f97925807da796722bf4d5459442523823388c259ca5ad73db", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100becb49fe5edd6806d5ba6eddbbb34ca8eaf3a12dba123d1610b2b120ca8bd017022072972992ee0ca0f319ae754a2a5a10d715a08b23f8239f9d6d59774f790543ea", + "id": "9e4841f43ab355be7a4f93b09f3d82c17065fbe25387dd6c5eb4e2692ea05b0b", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402207f1a3fe8c5aa7a77a58ed35c34f128b5df6fba89aa918af35eff432be7d1f8e00220460d4f2a457e1a477974157e33bf2974de6588d56e59729ae980720e9794827a", + "id": "2c7ca823be21724a4876de632dded3b9afca45df357819ed028488128d85d29e", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022067266dfe9d8f2550b590e1eae2f73d28c6b80fecb24c3eb1b4539bc864b3b4f4022031e5122145c35874c0c48673d088e76fb3e11c308ffe9d5dee6431d3441d627e", + "id": "a91119f04e2201184761f7fdcb26e4aa81c7e1076cb11a58a422d351241d4e4a", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100b970ec89927de0cb7805e614a742d42c2967db5a9c68d0892956dc89d68ca7d1022067fa30265dd2e1a2985980be2bf876748a7a8c7f3cde0382265b601fa658dc17", + "id": "94955e6bac6269fbd19e92d2292ac947225fc6f68c6216001b528596a961040c", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402203671b82ddf8a824b8e5aac8bc28be4aef1c00aca1097d14ec1a55003d7a3f28d02203aacb6e7517e916478432b81399828ba7425183ce0fc43feb361bcf345fb0519", + "id": "df563ee9822bd3d7aada600d4800952743ec64fafdc7697428d7a19a60745885", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100b77653317c93eb20ee19c71e64a7f9ecb985351bfb1fe351ac65a5738cb37ae202203d540395e1d55f87caaaa867afbfbaf98c553be0b4c7d1748418a76b0c258c89", + "id": "d21b6341e2b4be5ffdc3dd8fbcdf2c576ba02e2ef4ab5eab0e4bfc9da4e9e442", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022046239e39062a58925099b005888355b8cd6700af66972bf509a10123f9abdec60220202321ea74e56177606fc079d19c29851d832e6d00c93985ffbec3dba6f0d675", + "id": "df6bc7a17ad34f8e9faaa2646e8e5dd8bca35affba352537184f690e200e17b6", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402204eeab87f7ecc2097b85606b986177964f3ae777535f6fc0cf08a55fec587d87602203779d59903b8de63511e4ed0a7967bd85e9cb1fc9d84bbc5091e3caa87d8bd52", + "id": "5f0d5f0dff464d0ad587da5bc93e600a8e2657d359d0a1224bdd4ccc3b6f376a", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402200a2b9d0f61066fa00a2a2882379aa8ee60e949bdc2a85103bbbb69ce3eafccd9022057364f349faceb3047fa95ada210c64fc4a81978d66925b37d3dbc21ede885af", + "id": "1b39e3702576e6ad7775e34d53e43210549d52a56b3f246031e6ba4121a66bf0", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304502210099e568d3d0c1b48410e0b85c74d04234dacfb2fdf2b1d4b51fca1cfb3445347a02207a2509645aae54560762a37422b66ba4b3ee1c42de35d58c36d2f9d8fdea11b4", + "id": "0f21e53dbb1edb1cfb4c31bb675aa4672b452a03ec363a2b3300a9dda49e3be3", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022026cc5f2b588a86241badca73cd9c1686916d516b8c6c397c66a9d5bb6b5d4cd402204ab5a8c8589ee954bda4a116999d2a0e4ab0e3e96f0c7fe131d7c57b9a1ede43", + "id": "410826c255a23a78ac5c3aa10dd48132693bc955845af16c20d9c6f69b05dfe9", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402205fedd8d3b5c8d69cdd7db5ca8e9e7c5004f6ba751e45eb1b85b26d9e89800a2402202be56bb2cd824bccf325b6b11432bf6d0ddb5ec97fcc121839ac2ebf884c7173", + "id": "ddb57d8270b2b6c876191c1e1c5974388b9fb3ae0980cb2245d8a7c426237f47", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022053cd42ad147eea33801b2b57388b33f633b4bfe2ad902190e12480522250d07802203066dc0d0c2ffacc4c74cca1e0187fbea1cef7e78a78666d2ec7e4e87ef546eb", + "id": "29e1aedf98935c369946c8dadb2d6784f9ab5ce8d73b9b4de2466c7757e2557b", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100c10448b87e7176735c8ddfc8fb3c4d5d55c2d71d18b7ce3ab321209ec299fd41022013517a09e4b366ab386698286ec7bb20410bdfb7f6674fab25a739259083b297", + "id": "4cf04852529b5525f22cc540790e36e61ed36045ad1b5b788f61ebe42637391e", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402204cc1588b204ebc0c20f44a31ce53d15ab5e4d1f9c103c02dd4e4eaa1c33630b40220194b6e427b6def0783461cd8d765f97b105d048942be468be2ee9b0a2785d2ac", + "id": "35c6bc3f0799d9c79efc6515f232c58be0d03a3a797d066cba879eef4afaae2c", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100be44f7ea12e2ee89245fb474643ec6c2c75afa00276826a4ecd6fca4cad5ff30022071a2c083b353a821345e4bbf74d98db0760b8721856572572cc3436ebdb8f08c", + "id": "45f75a349f3b4d73434c0f2ac9c291d5d07278b79e6eaa0d38d6e005f66c4783", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402202090f506e8f18fde70b87a3fd6c470a23e9e262f20ec6268dd59b6362e51a29202202b838c598b33c6317c998dc179fad2b660b8a72bfaf8223d7cc82414ab4c6af4", + "id": "a8d9034d1091a4dbe595647ad5f64ca8b243e7842301aee48f7eaf8b8ae98119", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100be59b689a48e198267305f1ae7e116f69f7c360857ea0b1fa81db122278cad69022033436d24ec0103674522f0c559e2357f8696bd498deccad2e0f66b2cf7469538", + "id": "061cb438ba1216cfd5a0f268ce18e6f280557bc944d9aed3655e2bc5f08bdf51", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402203b5d2aa7c4554d6d2dd6723043350df0199e6e7bbd9f21a1a20dbba8c63918cc022014a78064c5f9c5e2f43d3be36de2b5e2f17e9af557bb6c75e8d82d9f725d0188", + "id": "239f0640ddc3170a737ef349c07cb82b2493d207421b6f71b6b3dab856f16088", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022005eb29ad4cf79fd4f6898de19459e15cc816acb0975e53530a202e69c29d0d4a0220686cf6e0c14779d6d68dcb9d16358c0e859094d2eec8083598b7bb5869478bf2", + "id": "25d8eef755cfee7cab0d7f9fbbea0fad6d5f906c432d997ae8ef1c49d23735f5", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100b93096a287d59545fa3a08593dfc740d9d47f3cfa3c4bd3c8ff8ef53d3a2e957022027eda62e47220774cf799f46916195e5a8b30015c56ceff4f4a1c10a918e3675", + "id": "aac25996e3be809ee88996b6b4063e2097d6306e77a067de8ebc8d7076a28d43", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022017282aa4fac7b18e834abc3ca37b2f60cf989c26b12e2f2398a66cb907015a760220428218d39db812a22cc138acc7d5d4d2d5713f0546751c02d2c3fabecca0e724", + "id": "b040f86b75750b49c83ca7eb8f2a458f16b44789796ff306c5f942ca5f19164d", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402205970d53cb0921a62bbef540dc33189b2313f3574e44f046097067e6991d63b1102200a356c87642cc781df661a1fee21cce354a144463d37053280e000e1b75da7a5", + "id": "25ce96f951d7b7d886ef487331125b3413f655f9c5ee7fb4691a728c3cbce18f", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100aab0201c9d9a9641c11605d32353685cbaa051ecc276da1e6a3b309be9f20cf7022067aecbc7329bdf1770974e317a1243815511efa8c7af7801217a83c96d86eb0e", + "id": "285143b8b19cbde7c680b0f62ef51293e8f315c823ffbd97608c38c02045d831", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100dc7752f6f8acaa3a1ee2ed1bed306ee04556b3866db92a1e770c4b970c7a932e02202d137b312342f9d0708704833b26b6611d0464c87df97049ad8b616483e9d1f8", + "id": "87b06fccbb63809e976b3405cccec2eeaa3694d5510203f04c0e60bb6c2c0020", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402205ccad5c77ea339f5e3f2b7900b4b1c409d3c8204273e89b6401314fb61f0d224022026a63fef86356de64fe571ff8488a951dcacab56e980fc044ef9f43b9d37439c", + "id": "5597ed52e4123756bea9307c09c916ff9d0f9fbce8d2e9a3a2ff719a87ad0966", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402207c91153f820f34228bec62772e0d78876bd3277912eacd866fe35b5c86a316c80220104529c6f786cb387ec1e3d5826271c837f0d0a6d0fa5731b9a5c6663cce7108", + "id": "d46fde78608fcc668246cc35336210b3c167ba55c82e91b0fd99df7e36872130", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100acc0cf119c18861d3683bb3b0f6e209f2d62acfdd958f86dfbd35137ada814320220448f6f8adcd46204629b45a4a06f5dc7ccb4dbc2a1d702e107d91053847adf2f", + "id": "aa92faf5d80459b4e058dc8a8212608b589925052e22148384835ab687a4e875", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022055b6bbde5fa886db3cf1224a59f1fb43e850e2d9237db593368e1043698fe2c30220067dd20195e794af4152f1ff9e3ae4261698a86c54803ba1890bf176d97844d4", + "id": "432e67db0d5fc8c66376aa96c7324e5a1e6d00a415a9c8898b5e3bf25d8b083d", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "30450221009d6f38067264df8497d6888e4a8c316ec58ceba8a54c39ccb0ce261d114fbbab02200fae3f2f950f5c5e3387679f8ca341ec70cd90d0e32a30112f03cfb12cd9fc23", + "id": "9321e1b08faa544f592ad8dc7b60ff1cf845efcd28fedf8b445be3bda60434cb", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245100000000000, + "fee": 0, + "recipientId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402200aed5a4102bdafda00fda575294f149b393a798c510af8ba877b8c2d7ec8051e022004f7487c4f728c633aee5baa62ab0017f4b91cf2f494eb1c4cc9addc3e9155da", + "id": "0bbc9340798a18a81109bdfdbee9c9003f20a586dd9f80a39507c84588c1b4b1", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_9", + "publicKey": "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647" + } + }, + "signature": "30440220072124721ba7c997f7c29ad3d4819515fae7a67be2bc395cb73f114eb8d4abe60220523ac295e114de30ce8a4300f4670db91ad2abe1268460e6ad3463fbe9834b84", + "id": "d2e70f9d2de57240571905aa81db0b6883e27a83be2422530722d76b56e63ecd", + "senderId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_18", + "publicKey": "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a" + } + }, + "signature": "304402204b93b06e08e71e3317f9426a1d3d450d6293fdbf5a6b3043fce27b3ce65431e20220683609720ea1d7d921238ca8b5098d3d9c0caab7b1e26efe42a6aebbc095471a", + "id": "8695bcb906f5fd81d858794f7d90447aadaa38418d312e33115a81e856b34d12", + "senderId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_47", + "publicKey": "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd" + } + }, + "signature": "30450221009711559a43005c808113a1e9a01b1665495ff4bf30d635f7d98c752ead4cc3fc02207879e2a939914effe2b5c80cd515c4b3ff77a071b707c85c4444481878803db9", + "id": "55853d2d2a98def00c5ab842866a44d1db91678a07b6dd63d062508db28a00a5", + "senderId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_5", + "publicKey": "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565" + } + }, + "signature": "3044022025ba51a588253524557547ec492d71bd485fe5b291e60eef681c39eaf8ee781702202bf24c3d295c7a2c9aed97a79fb835506797dcfe7e7a2853e2578e7773c7e134", + "id": "553298aadf692c9c5d0334c307dd4ac0e277a49ed165c97ce1362f8ec639ee3f", + "senderId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_19", + "publicKey": "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb" + } + }, + "signature": "3044022041291ba10ad30fb9ebcb0e13902e92d85e2c3e98493b6d369d7d1e70e8474e31022009083444460c415eab6b4beed9e0206eb0733bad5d2a476af4db4f5b5e74b835", + "id": "90af927db7b258538c8e21116b5a31418c88ecc163628b2b65fac92a5a949b14", + "senderId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_42", + "publicKey": "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d" + } + }, + "signature": "304402205d4111c87874e696b8f4b8897d0dfe68fabe4ad5c5769026c6ecdd04f09a1e2f02207b9c8a2a16b50164215eb1efea6d5d9f4e693cbb7eec8535e526cf8ba68bb796", + "id": "8a920ebf5255a102d0c9c5fd720e0d36a6a3539991a2267442facf1fea2d0b86", + "senderId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_10", + "publicKey": "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd" + } + }, + "signature": "3045022100f15ff048872020d9efc561b8c837f542d54d43b9b071f7a6cc09643c6d4180f002207d0e82153a30b66f43fc4cb4b9b3093bb3d5dfd70f96928c8780c838b1448c19", + "id": "30738f376aa40fb3c8d8849a5dc698786aeb1409fa801c18729f8da624631391", + "senderId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_20", + "publicKey": "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751" + } + }, + "signature": "3045022100babb7410d09215def98078bbab6b5e5690c2ebf54960d94527226ed3925877320220342576d1d8fd2d2fe3b6974cab48a2e16b4813f022b341b32f88e13f572bf060", + "id": "ccbe1c27eadc1b3b33f3f87f645be4f756021ee3d4c96f4f094e1f82d5728a3a", + "senderId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_49", + "publicKey": "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374" + } + }, + "signature": "3044022032f2c350cc1319f5838d6880e91b49ae0438fb3a626ed9ab5e27ce8788e3347c02202cca18567c8491e0feea8a5f078e28605029346c509fac0c0a192e934f8c5326", + "id": "f99af0fbb4d65c2c3f2c1c558f0c0c0eac2724942802fcde02fa6da1d3a9000c", + "senderId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_3", + "publicKey": "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17" + } + }, + "signature": "3045022100f0cb5d885ddf3bd4a58837f9b86486da4171652a5eb39228dfd0ff9d34d9c7c602202dc6e3d268d745a7e8633311a337ec097382342049672880c7c2215cf58e5da2", + "id": "2dca03aed08533585d8bc609da5deb9f17ac9be5a8352769d7ae63d0db16ff59", + "senderId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_21", + "publicKey": "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a" + } + }, + "signature": "3045022100999f19fbdc9a12eebbb8c748a4cfc6c91b2233f333a09cddfd49dfeab6aaf38602203d8dc9d1551d400572a88ee812f51f897f8b35508713b789b2c1bf6dd0e88945", + "id": "5d7e51d57b5914ec201ab65a019ecdf651c4f267cbffe403fd2170bb95145f9d", + "senderId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_41", + "publicKey": "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f" + } + }, + "signature": "3045022100e86e648add940a1e637e32ea9187497c281b843da09597e62d0c927d7f43235102200479f64ae63abb55e338f9ce1073a5c46907f7a2a82ea6f9bd9bc29811683515", + "id": "eaeed4133da26612c53550b6572722d8c3380d0a2344da1bd270eed1ea91fdf3", + "senderId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_11", + "publicKey": "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904" + } + }, + "signature": "3045022100bc3b2ebc58a92bf38672206e8311e7ef0e54912abce7338155b11e7d191b0b5d0220765a568c1fa4665c0ace6b4bd3b7ba0f8329e2f25af7a3cc0d78b2ea398084c3", + "id": "bb91e78e43c59a19ac06c015d8a7ef09d7c5b274c9f98505e5a978027354b71c", + "senderId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_22", + "publicKey": "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a" + } + }, + "signature": "3045022100aae4868ab75a33e4e77f9bf6c53b920c5e7c523a7cfe271d1afc472655f3d6a60220499f1bcb79bc0fa830dfa939898db5c9fa8571a2788c8de0da7e550bfc818bcc", + "id": "a6e687647dde9c1db68690090afc4fcf11833dd35fff3186b6b709a1e7d24260", + "senderId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_46", + "publicKey": "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c" + } + }, + "signature": "3045022100c0cf1fc54705c13f70fde39c55a1703a4c612b8a919379cd5b1ada464c7cc8de022074ee62490a184010ad2418d3177ff2ab03d02d2589000176312b90422b1bd64b", + "id": "70262b0eec3ab5a60a736eb8a628cb600eae7522464a49791c0bf26e82318ec6", + "senderId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_6", + "publicKey": "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc" + } + }, + "signature": "3044022045db446b109215c6d3dfb0ee5869154a8a7624376c3760eec4fadc75a29033cf022003e524d64f3ccd0c6de4ca80a7327e2c47ffd16b3ad042bd25a02f5f64500ab7", + "id": "56048c449694964bee3d367609a7bc46c8da20f66878c09c01dcc53c3abd932e", + "senderId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_23", + "publicKey": "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a" + } + }, + "signature": "3045022100f8f69f2957781ed02d64983744c8e51fae613ebe5bbb330d4f509bdcf4fc6b6602205568ad1fd840e01ec26a24ac9a0ff093e978172da55d494138d018a45eb67893", + "id": "e15dfc4e18106480083b3c6211349fd9c803e334e9ba5eb62cca19ae3f57d8e7", + "senderId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_40", + "publicKey": "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689" + } + }, + "signature": "3044022021eeb9e1db8915a9adb99db72972cd17fc7b5b377fc532ac2c9deffcb2707edf022068b9e08f45bbebad89295f520ad40d7786fe64059d45df95551576e3acb736d1", + "id": "2bd0f888ccdeeca24a0134e3c1bf729582d284f32ee000d97f1417f1349a6594", + "senderId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_12", + "publicKey": "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12" + } + }, + "signature": "3044022040a9d0975f747df19792211546410d7c735aff2d26f367d1bf9233ffd1d993d702206890c66d4d0eb5de37df088c082d8fbd8da043817b48a76bd5d70f1e3f6b6529", + "id": "f75ac5ccd243e09fc9da2b3842a0654ca860d2dba5bb73866693a8a918937994", + "senderId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_24", + "publicKey": "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95" + } + }, + "signature": "30440220550c0ab565ab2de649ca7a2aaf2975453a1e4ab8b0d392d69663c0c9b6b80b7b022039047d4d1bf4e9b167a95adcde0a5a8631aeca060dfd426da28a10d968fb3a64", + "id": "aa2ed932faf4832848356beaf87e5381ee56a1a84fb485ba975acb28f8fcf5df", + "senderId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_50", + "publicKey": "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1" + } + }, + "signature": "3044022038df37ef25928d1a04516e982c99f49cbdc193603f814b48ab3802153bdd352002204c918915a3cbfa305c5f898ae4bcdd75394b57460f85c80daa0999751d466c08", + "id": "d30a726e1bb8d199d8f44700bc999c9a0a1a8be86e4be6a15764ecd424f9db1b", + "senderId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_2", + "publicKey": "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d" + } + }, + "signature": "3044022028dd44b9609b0b599c15a257757fd068f9014e33947c77776a6fcbe71879271b02200b46fd8eb0827da6de13f5efd63b17f29e8ba4600e4a690ec31eb08bf2d9af33", + "id": "1410b8b5f15c05528013378251bf5da30e04c8a6b7ac0f729b527664cfbdfbc4", + "senderId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_25", + "publicKey": "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964" + } + }, + "signature": "3044022038edfe34f7b89b4e69ea8b94e3335063b60deaee28246932147f53b2525924a402205b89f5e3d956aa49f24f81e2ba3447c19bd5c026568b3bef73a7a7d5160ad661", + "id": "58d14b74b71586e18f0499a50004ec2e0cc2e5b56aa53f4cf57084030ff90fa3", + "senderId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_39", + "publicKey": "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5" + } + }, + "signature": "3045022100bc1e477994bf4cbcdb5cbe2bd92c7d955a03adfe562f8e3bf04d2f62965e9f78022045512772d8453314361161b2bd2a39aa0a7fbb897a5a83f4c7ab54ced615b42c", + "id": "3ee53b3f1455ef0ddb52afe08854c9d87f42c7313babd3e05bb3ca4f94c495ef", + "senderId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_13", + "publicKey": "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f" + } + }, + "signature": "3044022052fe00e8e9f05b1d890f6910beab0627c823eb2d5875b4b9813a33aed11edfb6022034a723b827ce0e73bfdc0f535b244ffc983f8d549ee72b4d432de90d658db72e", + "id": "4a3d204c2916c93360d7bb11390e355bc1a930e3cf503965a45253d65bfe928b", + "senderId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_1", + "publicKey": "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37" + } + }, + "signature": "3044022013b2798a4ab4d741850abac10d962360cd4ab6a47dfac7c1c806d6f9c3d810cc02202742414ad8a04ce679b445fcd040fb877bbfed3d2692b873dec8cb46c01c8c4c", + "id": "7d0c5a44a7517f6ad7a1253db45d58e85aa1c735a282a32f45d28efdb7869d7e", + "senderId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_45", + "publicKey": "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b" + } + }, + "signature": "304402202c372b7b9679a8fe66f952a1d47d4327968d6e98770b215ada2fed6a8d87ed5502205a797fb511cfba557255dd37e028fb40981b7b65ad2ce8fe0e559a46eb274bf8", + "id": "70bfe97ae7452dc752ab4de0e2a0e81bd18bef07392c56e7a101257683d4d932", + "senderId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_7", + "publicKey": "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0" + } + }, + "signature": "3044022058851712200f7386d6b3c188444f9c8f05788667649ec17c71b9e514206eb105022061e6a4bc4cd11599792e03298f95509893d56af54d51e9f639981045e754b974", + "id": "f6f90ff09dee5be7d8f3d58d217772df7a95865bf8609d7d5b0b673e9a5bc953", + "senderId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_27", + "publicKey": "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d" + } + }, + "signature": "304402204878d69a166e60e0a779c31fbc48c67b70d2e4aed1d63c60beb9f070963e2894022078c46b6687f23493a4c2ed39709a183a0f7352568cc9cc2c1f0d7bf0d809a4a4", + "id": "f68809e407d20a50029fe460d411c866b79c7e09c076dada768a38d81f184aa3", + "senderId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_38", + "publicKey": "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294" + } + }, + "signature": "3045022100d5576393a1dea704cf79a5d0bc2757a3a5e66e1055103b52157fca05fc5693ec0220522832ce0e31b779decef83ac8ce764930de927df9ae1d6f6f99a3312d99c90c", + "id": "2ec6c6f33f00431ef063fbb8a79fb90eadb13a79bf46e6e1df36dd9434314df0", + "senderId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_14", + "publicKey": "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24" + } + }, + "signature": "3044022008a7d0bfe9c4c150566ddf701d08e84b4a5f84b07e3b1c91dde1cefa16d2a3c202200b787e898c0b2c68f4343e74f18ae7363f62b5f4ef2962386932aee09a9fa0d4", + "id": "e37b3efbf034bea4c852be7d7013978f8999eacc39549ceea775de197e14e8da", + "senderId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_28", + "publicKey": "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28" + } + }, + "signature": "3044022023b6fbfa5f4482a4dcc34411846696052b1592786ca87243b7d3344fc9fe9954022035402fbca22691de2497552c743f0f68c7591edd1bd7954ab7639548fcd558a3", + "id": "08268f5e6c15cf146523ca928f24aca65b162f363593d927c66144ee5df297cc", + "senderId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_48", + "publicKey": "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b" + } + }, + "signature": "3045022100b3cad169f29a3a95995b87e1b50b35583c1bff91d69cfa236f58ce452491c579022026775f4ef50b50ecf6d78b530b4633711394983456e6a45ec227b652c86e3014", + "id": "ad94ee2ae94813a638b93909930c7cc631c364b6c8528b2dcd6fa8f69260cc2d", + "senderId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_4", + "publicKey": "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93" + } + }, + "signature": "3044022007ac9ff2f272f3fda4947393b8688586cc8b2958ff5dc7931ac8f82c697bb76802202a66c28852bbff86ef17ac7f51e7eee52e611e825d91a9846f531ab3c3115c81", + "id": "76fb1984da9ef90fd7d588756163c97e00d3e4d6e9dfe78d9e3d3cb6d71ddd38", + "senderId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_29", + "publicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252" + } + }, + "signature": "304402204416e428688ad29928303fb2b00a26996cf79753fe70fb91c1f4635c644ba859022068ac5eab7d05f87c40ba36bd9dc149607c196778120c061698d7ab64aaade7ac", + "id": "0f442a91857061e87dd193b0b9f17a71719ca7e3da62841a63568713fc12b5e7", + "senderId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_37", + "publicKey": "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4" + } + }, + "signature": "304402206a248caa5949024202f297c38cee18845e344c5f140be74349787097d3b0a33c02207ac84336e02592bb5e00dcd0c490d30eb856b34177ab9ac03410d82a355a7b0d", + "id": "eed30a45c350fdffc5877458f7fe29f28dc4bf81aa1a197d003c9433148b71aa", + "senderId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_15", + "publicKey": "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca" + } + }, + "signature": "3045022100c99336ce666cb4a6db3727a61c04c14d8746365f72280d9984441b7d2b568b5402201759e4f417f683743e1d4a14f8a7a215009321cdfa29834b2dbdbe54ee22c1d9", + "id": "ecfba14a58f9d79782c4f905646df28bf566e3e7d1f17b39df6fe6b52c11de59", + "senderId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_30", + "publicKey": "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883" + } + }, + "signature": "3044022070de7b4d4ce64bd605c9d008142544c2b113cc84df07ed1982e0adf3cf69f4520220211b01710a6533a270dc2814c7f968adf27eb6dbf437e7a72960b013b9651a0c", + "id": "36ce5323859a92f302f77f27bd08ee3485d720f55842ccba353a47ea96a964c2", + "senderId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_44", + "publicKey": "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c" + } + }, + "signature": "3045022100a7c271633ecbf3c6641c7db36913b5fa0ea521f400a4848edf024648f3d7128002206a271f8a88644062b64d856407af9567c0b2937d4a3d89a3b3d07edbd3a0f177", + "id": "e120452e7c56a9327b2be7dfd3dcecae193f2e2e772903008b03cdf00146ebd1", + "senderId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_8", + "publicKey": "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564" + } + }, + "signature": "304402200394b6545015bcf2d0f291de57a4197cb6ef57b2ad5fa37f05e8a220913ba83502204d0d2f2206edba54ada5b8e5afd194ba83dd1bf15f744258409595251dbe3ff0", + "id": "7d15eee8e4e3be3d2c44acd51b87a816bdb593565d4ac358dab24ae9c8a5bae2", + "senderId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_31", + "publicKey": "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2" + } + }, + "signature": "3045022100989eb331951a13152aa03583efc765499e836c6fbafcafec4302b243ada8de5002203876fc4cf7fdeee4a095667e55a2fef84e5a7053e807b4d8e029883f0d578019", + "id": "baa686d521f95d265e7099cfd9ef14e0a9a92254dd94c16ce50c460bd013c588", + "senderId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_36", + "publicKey": "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e" + } + }, + "signature": "304402202be177dddfad323302565a866d38a3e7939e0234b16e7dc02075cf258502eba302200928a139ec1a82b4609fcc1bd6d1d027ad050e93fcd2eff94181936d2d43e39c", + "id": "9fcf7ec6fe98ed94710e212226d8b90df7e7467d66dd4c5c9d48474388be3099", + "senderId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_16", + "publicKey": "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9" + } + }, + "signature": "304402207b4f8c09a728acedf3b6ba0632e12d01670c683215053e49dde8598954d85a9a02202a7d7930baa17c2134b314e47dd6c334c828f78e573a2bf92fcbc1146d630541", + "id": "c35e4b1e7a2435664fc0939251c2052633ebf4b51fb22d15e71bfcab85b26de9", + "senderId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_32", + "publicKey": "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055" + } + }, + "signature": "30440220127d27312345e015c681adb799c1a87d16fb0caaabd5020b39257d567816b91c022018b2388f6d2d9afb3714d84ed102b3ea61159772786033c855947613c7ce7b5b", + "id": "0d682a3a9c252a674043bee5240e456dae2685d76fbd3bdeda6ff50f0c442fff", + "senderId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_51", + "publicKey": "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a" + } + }, + "signature": "304402203d0ee691830e4d001553bf4e49b6d9669b3c959376f391410551c8adc679dac902203ba6e275bf6d543efd19d20428649f802d9396bb0967114a1f09c24827be1da7", + "id": "ec2373b0d609ae72fb400ffdfbffc59670ebbf1c15f59c0ac22a4030dae700e3", + "senderId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_26", + "publicKey": "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983" + } + }, + "signature": "3045022100f2cf77b0510f589b5aaaf2b0027ffbce6ce8d4873cdc67dc8900865d156de3be02203c22e30945618683182f3d3873e6b3657e0900b062f866bab2705cd593669e79", + "id": "3cb2f0f7d05a515d4c5c873cbe96e33b1dfba1b7718e4548de7f9da54933b652", + "senderId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_33", + "publicKey": "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe" + } + }, + "signature": "304402201e328159172d543d2225c247c6b728800c52eb724f67c0e919f6b7215e6bd7f2022075fc02fe0b14a1499c5602d87ca2c99d6e789beaceed2b9702060dece872d14a", + "id": "2fd77e744399c9632cc8f106c39237f201dafda976f1040235359f99eea3b832", + "senderId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_35", + "publicKey": "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e" + } + }, + "signature": "3044022063903d82e8bd15a6741a298b9a6007d0dc3626acfe2f072c3b624ccbf91ce3360220486ba4cc5591d8aa31b77dfde025b61691dbaad0feabe13e840d26e40010c5df", + "id": "5baf9e318c9e4cb0513a21eaea27e51c849f95fddc963207fb07aa2fd2b9f9d4", + "senderId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_17", + "publicKey": "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357" + } + }, + "signature": "3045022100efc1bc16e0b646da48f84822543b62ef5253bfa98bed6613f2d6d4634076e61802200ef243f9dbac7633a8819ce45e2a85d0eacfdc9a33a92bd3a03e90cbd312b823", + "id": "b4a959ad75f81b7fdbb957c90a3a63a6c5589e7819e2c455733a3a2b4b034634", + "senderId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_34", + "publicKey": "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80" + } + }, + "signature": "3044022012e52a479648990bfc1ed12bf901cad865708ff45962c3724ea67967be4f9d0102201901525ed8dd090af6a2637c123afb304e9fd178794addcb88d916227e66887d", + "id": "6439f2308efe31ac52ad06ef1caa45b9abf6c589118b7997da6a287325ca36e7", + "senderId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_43", + "publicKey": "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e" + } + }, + "signature": "3045022100a0874d1582ce210081f7ab30e7f951dfb9ce8f512d237f8a8cbd5d85569ef3b902200f0053c05de3d6e5ada4e4cf1403a836779d653573c2f374055645cc954c4c4a", + "id": "b0733072e98d3d6afe977e32f3dd118c15e79212232417743ffb551dc2a2ba55", + "senderId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW", + "senderPublicKey": "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357", + "timestamp": 0, + "asset": { + "votes": [ + "+03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357" + ] + }, + "signature": "30440220158ed59156e0eef2d2b94a296451dffe079be701b3d74f0443ef43bc266b334202205a2c39f57abfcd279d568608b90884b3ebe107316aa7552eca35c743b318a47c", + "id": "ea294b610e51efb3ceb4229f27bf773e87f41d21b6bb1f3bf68629ffd652c2d3", + "senderId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7", + "senderPublicKey": "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80", + "timestamp": 0, + "asset": { + "votes": [ + "+030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80" + ] + }, + "signature": "3045022100898da9f693a458a6875344c6c4cb73069c4075904c75595ffbc665967d84b07002200f168aaf3ab1b52dfa74599394387dc4cf627a447fbc5a91000e9d251cdb20c0", + "id": "3639b5dc6d19d46d8254d941bf7ace0f3da8a7cf8a56361921b260820c7239cd", + "senderId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1", + "senderPublicKey": "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e", + "timestamp": 0, + "asset": { + "votes": [ + "+032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e" + ] + }, + "signature": "3044022055ed9a8b55ccb3bd0945a710269b6f243f1dbfaa28467d3218a17565eb0c962d02207d31561478f16d93a20f5454ad565dea24e8dda4ddc464cb011f4b6b360c4e81", + "id": "fe24509580cde0c2e2f49defedd3a0f7572d2f78f90b51a253b0d8cebd74c20d", + "senderId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof", + "senderPublicKey": "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055", + "timestamp": 0, + "asset": { + "votes": [ + "+0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055" + ] + }, + "signature": "30440220092f367f833d677e8d0609ad1df65f389c2c35d1501c71c245c2982e6a832268022018e67445f525613d6cb6ac0c9683bd0f55bd40d9c929165649414f083c9041f9", + "id": "6a76553db794ebf4d5f60a7d7d71cfe29f4dbcaad9610106fbc578cdc7167cd4", + "senderId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy", + "senderPublicKey": "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2", + "timestamp": 0, + "asset": { + "votes": [ + "+03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2" + ] + }, + "signature": "304402203dc028b5013c36b03f97b111a8d7c05d0cd8e505b0b0d18747c0656c9b5cfe8102205e9ce8a78d1183b3e9880c69635d04218d94d17808bcc3f92e7af53195c23daf", + "id": "0f9d7e7708918b77afbdfffb63eef8fe87ba36e0131c88b44c1a7f81750cc025", + "senderId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9", + "senderPublicKey": "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e", + "timestamp": 0, + "asset": { + "votes": [ + "+0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e" + ] + }, + "signature": "3045022100a80ddd7c3adaf0e97ab938773fc78a716f3054d7e03afc1ddfcb5005badbd2810220231c0dabe2262149f994c939f9dc90d46b9bd7ca96b19aad6788cd3571e4f71a", + "id": "0ac77b2637fb25be42b3b60d1651bbbd788aeaba933a08ec4a417c7b4c54e087", + "senderId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT", + "senderPublicKey": "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883", + "timestamp": 0, + "asset": { + "votes": [ + "+02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883" + ] + }, + "signature": "30440220772c9cd8b96f74fcddc429d57d466eca6fc40fc211845f59eeb78cb027e116c5022004cda291587eb118d622de21333d2a5783969794b5b0101ad8b1044c7d8058af", + "id": "4b0dda465564d53981c0e36d73caec888e3523633eaa80dfb99a9c81b2604c7d", + "senderId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU", + "senderPublicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252", + "timestamp": 0, + "asset": { + "votes": [ + "+0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252" + ] + }, + "signature": "30440220406d54714b6425ae4553ea8bec75f31fe52e9b1a9b6f6897151253ab7f637d3b022040a2df4b69840f4d9b0b67658c75efdae8d8269780d4cc50d055fa63922dbb9a", + "id": "c7db9d36d97ff0168d0d670ec695e1dc786dfb93f4081586870c8793b50e5f17", + "senderId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK", + "senderPublicKey": "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4", + "timestamp": 0, + "asset": { + "votes": [ + "+030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4" + ] + }, + "signature": "3044022018b7e51118ec83c985fa4eb3d7f0cf0655753bcbde7e82bac521665fb1c0ffaf02204e2ace460b2542db8c77e41d05d5e02fa5514b746a0a1e947256925846ed19f1", + "id": "c41f4cffcdd523f1718154d5bd5f4f0bec0376076b5f8dd340337e9edb4821ae", + "senderId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW", + "senderPublicKey": "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28", + "timestamp": 0, + "asset": { + "votes": [ + "+03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28" + ] + }, + "signature": "304502210088dbe249503da43c157485bfd4f2c95babfe4d0b8bbefe44afa52529b824a79e022045239b6a374fd9aca52c27171ee66b4863c956ae4085c9760d863b1902596c1a", + "id": "b1736ec6a1ea4c6d4eb278430a8ee214c88daefe296ba98530e692f8b7a7434c", + "senderId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej", + "senderPublicKey": "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d", + "timestamp": 0, + "asset": { + "votes": [ + "+02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d" + ] + }, + "signature": "3045022100fcdf750a775e728a31691a1b38908a7f990b579da510959cc2c63442f5ffde760220316ebb051d9fecb2486771dd39921fb12675b6d46b2441dd1db3c42fad0a59b0", + "id": "069271456015c2ff842771775993b8afc3404bc070572eeeb0f2fd72d58e18dc", + "senderId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U", + "senderPublicKey": "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294", + "timestamp": 0, + "asset": { + "votes": [ + "+0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294" + ] + }, + "signature": "3044022034ce8f77ea9d0f5cf3a9135d7b72d0ba3b96ac6d7eaa3670e9956aef2c9a83cb0220626d1f269128f673a23f9993ce00ba78a08103e697298be29a4c8ee94f204e3a", + "id": "9a99bba8340e7ad4e05d8424a0977ebbde428d31ee066c9828bd06b42bb42a72", + "senderId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2", + "senderPublicKey": "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983", + "timestamp": 0, + "asset": { + "votes": [ + "+02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983" + ] + }, + "signature": "3044022039ae1155f8b87a61c38b25cbbf30da6ecf6cfcc12b25c2e7fe576373754a41eb0220061a66a893129fbad5d48cdd19cf48b1a0d133dd2f3ecdc60ee7b87277e1f81d", + "id": "6c2c8926420ac269b50fa30127e0e791afb2131aff5821ca7aa80d38a0182048", + "senderId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf", + "senderPublicKey": "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964", + "timestamp": 0, + "asset": { + "votes": [ + "+02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964" + ] + }, + "signature": "3045022100d0dac2b7691aa059b1048d7925a0c5d5099f6e9b0f2e321e6d4f128ab1b3272b02207e8c4f643f8f9d1c3f81f0cce6a698df2da2ab71d5b01042766bbe0f46f4a775", + "id": "9259193c5de72276ed7a99f9d507dd6ea9856411fda521074fb41a556294fdf7", + "senderId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9", + "senderPublicKey": "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5", + "timestamp": 0, + "asset": { + "votes": [ + "+03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5" + ] + }, + "signature": "3045022100d5496fec447367ab6b53956a8c40cd8566e050ebb3b92d2c0b2a9d09bef36c7402205e32367605372375801f7b9db39aaafb46ee763b1494f0aca144fb91f3415752", + "id": "2a41e5946ab0773ca2334bba9d3510184bdd258f1c651ff8ec95b7b64a01dc2e", + "senderId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW", + "senderPublicKey": "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95", + "timestamp": 0, + "asset": { + "votes": [ + "+039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95" + ] + }, + "signature": "304502210099249695dc38826e04c8fcffd2570b98c43dec4788cc6a19737ed0872f17ec3302205301f645d803ad5df4ab1a700446e28c7cd76153607f6a2d68ae9168d46f3fe9", + "id": "e5c09b0fb2c24c57a4dcef0078953093800329ab4dc8e16a9d9f68215b5acd3d", + "senderId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU", + "senderPublicKey": "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a", + "timestamp": 0, + "asset": { + "votes": [ + "+034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a" + ] + }, + "signature": "3045022100f983b03e319aaa6c6ab6381e3ef8c0c035d6e3cc2139cedf70fd4e385393e38a0220286f73577765eb3e89e362785ad8a6de572bebf41bbc1f515b0ea93e41801eb3", + "id": "00b2c0455ef6f508d65f11bb49e3cfe1e6062d5fd153cafdfdfd2ccbf9c646e5", + "senderId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr", + "senderPublicKey": "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689", + "timestamp": 0, + "asset": { + "votes": [ + "+022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689" + ] + }, + "signature": "30440220103862ec51621ca27a0ec6b2817848e8824d2d09dbf7e6aac2f45aeea5d2dc9102205e8cce78b5cd7148aa4d406dc7b491dd7758047200e10cfe1e5fde5c56107ac5", + "id": "e25439ad11cb8db3d49ccb3b8b608c1bcb24cb29b2e5ea15101cce3e475224eb", + "senderId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ", + "senderPublicKey": "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a", + "timestamp": 0, + "asset": { + "votes": [ + "+03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a" + ] + }, + "signature": "304502210099241ced4a0fd1eb02f5cdcc880ae5f48eb3c7e490d4520c20124ecbf403893602204729dc6cacf3e87c97ca57c1be54d1e80791bf31ef022135e68fc06c950f6994", + "id": "1474f50815c6c7df41ab652414806d61abe15bee0d41f32d772f4e2793badce4", + "senderId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX", + "senderPublicKey": "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a", + "timestamp": 0, + "asset": { + "votes": [ + "+0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a" + ] + }, + "signature": "3045022100eccf81d44992c49a5ee37c6fc2ccc4b6bee9aa44888513b3e18e79452ede3156022056b0ddf079d2918d72e8781d3af009c87e6058563591dfd6ee0117b7df5534b2", + "id": "b394e2a8b5c2d20a72ed288408b8f0d48aed922edbee6e16c1c5b0e67517214c", + "senderId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf", + "senderPublicKey": "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f", + "timestamp": 0, + "asset": { + "votes": [ + "+03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f" + ] + }, + "signature": "3045022100bdb87894846eccc5a5473edaee1e6dca5f3469963e22f06123b6bde195aede0e02203d0c6833e87c5e60f4597ce624d4c2502a0562b4e54d943f82a4889e3cd69532", + "id": "6a399099bac6c74fa5e956512ef8b3a39f6f946d5d6996f192c2f1dd5ba172dc", + "senderId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv", + "senderPublicKey": "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751", + "timestamp": 0, + "asset": { + "votes": [ + "+02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751" + ] + }, + "signature": "304402200785771ccf1a6a40b51183a190d4cb4ce76b9ffd4c2c736d7724e6c667113d020220649ecfe73017d8dda96a7914793470ee7e582693e4866df123b1032194c163b1", + "id": "f20a831a6bae0a85470e308fb66517e70db479657459f6bb39f2cd1783c565e6", + "senderId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv", + "senderPublicKey": "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb", + "timestamp": 0, + "asset": { + "votes": [ + "+0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb" + ] + }, + "signature": "3044022020b79e1f07bcb17cae9485b9f44e9f583ca235da4ddd363b905fafb884347f71022015a20481b43720ddb3b1e3ca64b1f47e59b5cc2016a62f43327ca14533384dd4", + "id": "7a1285be87dca9718bece5b84266c1bf6801a39cc111d534e660aef9e6d26929", + "senderId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg", + "senderPublicKey": "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d", + "timestamp": 0, + "asset": { + "votes": [ + "+0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d" + ] + }, + "signature": "3045022100b1615d16763c46d42ca2aae967f04c1c07c119b5af7a378c262ba85515a8d35002202cf7df91676cd137943720e93f06c11907412a6bdc5ef2157cf536a203cf83a3", + "id": "76fb5a1de90f245b1eeb79cb11c7bea7c8b738add0fb8cd95191186a944b0229", + "senderId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri", + "senderPublicKey": "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a", + "timestamp": 0, + "asset": { + "votes": [ + "+02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a" + ] + }, + "signature": "3045022100e3c7b5d6a72acde4d22e8c1c6cd864c549deba89683f4b84320407d6c380827c02202da57df0ab7cd381b776bdf85802aed371e7cea7269a84f911b1d8e9956badee", + "id": "8da75c8100e6248ab37cc92f72ed9facec3067f4f82f03db8bb8063791463fb3", + "senderId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t", + "senderPublicKey": "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe", + "timestamp": 0, + "asset": { + "votes": [ + "+03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe" + ] + }, + "signature": "304402205779b5d8acbfedfc105fedb6fcbd4636713ed27605faa9bd988598072640a958022042d8a8b3d7910c7c385f3707a317c5d445d56da250f8d127c71df2d9d4c5d86e", + "id": "fd26e265be88289828d0ce7ffc5faeb9849e1f4cb37a8f1dd5d6fcc436d910b7", + "senderId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf", + "senderPublicKey": "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e", + "timestamp": 0, + "asset": { + "votes": [ + "+034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e" + ] + }, + "signature": "3045022100e18a89fe1fe0a8acaca2b6461314e784ffebbe7374f6aafdb06934e83985ccbf022027314b21a4a25b477bd7cc070b4e00ef8f3d69f3f1af028b96571dc245924c00", + "id": "41d92e128e6b8367cbf8fd111e5263d52e1abad553653f975dd60d7f7c5b637b", + "senderId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9", + "senderPublicKey": "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9", + "timestamp": 0, + "asset": { + "votes": [ + "+02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9" + ] + }, + "signature": "304402201c614c84dbae26f87973c9e2b38df883fe0c8c469080e31fe32a4c4946d50b67022075b8fb498fb1384aa6be785845da02813185ccf095597b5782618033828af4d5", + "id": "1e4a1f8aab6fbf8682c2b35e0d04e9e007ae717ce3f4a82894747e5807e3c759", + "senderId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV", + "senderPublicKey": "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca", + "timestamp": 0, + "asset": { + "votes": [ + "+02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca" + ] + }, + "signature": "3045022100b1ee6becc59d594776a40e5b3caec82390d273b703ecb0d7caece44953141449022016543cc29a28882845118afab6e51296cd216bc662260c28e5efd9597b6025b1", + "id": "2ce068bfccb3f967f4004e9a1e81614a738e55e45c80114c0af30a085f71a2e9", + "senderId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ", + "senderPublicKey": "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c", + "timestamp": 0, + "asset": { + "votes": [ + "+022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c" + ] + }, + "signature": "3044022036698a329d7f5f751f91ce02bc188a7527a377d01583b70427cfce64def945ec022079afafea10aa32394a1e42a80577de3869856656221d5f259e05fb44f01668b8", + "id": "3478d1ad3655e10fcc864f191972322c866616866bb1dbf66d7b66b31cd95de6", + "senderId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA", + "senderPublicKey": "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24", + "timestamp": 0, + "asset": { + "votes": [ + "+03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24" + ] + }, + "signature": "3044022035fa7be80cf881eefefc12b11de04ffb2e2e92815cf05074afef54a3c5b2eccb022041f3347f59db0b3caadefcbfbc5ae275d3fe3e2a52fe1504b23628d4b79a43bf", + "id": "8adfd8e73e96188ed9fdec459d88db1fb041a2b25b3f64830476aec661ae5010", + "senderId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm", + "senderPublicKey": "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f", + "timestamp": 0, + "asset": { + "votes": [ + "+021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f" + ] + }, + "signature": "30440220630da8a73979bd3988b7f84fe9e83a429cf3239f54c140c3dbcc407140513fc002203664ad54ed9f199f2683479b988bd97ad8fffb2c2d5dfdbdb10858aca4abfaca", + "id": "e306328ffefcd9e3809e7390a358199a62cf8ef037d57af1f5c7b54d728d427e", + "senderId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1", + "senderPublicKey": "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b", + "timestamp": 0, + "asset": { + "votes": [ + "+02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b" + ] + }, + "signature": "304402206f1df93f299ffedacc25aa201807df47d32c43369315cf9db280963c357be56302206a66acd553710f49bbb7b803a2bcb71128c8e617ffce66b37b7c968817349247", + "id": "dc69bc8f78502ba34655ed062987788939189709a4112760cd8807245d7461f5", + "senderId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8", + "senderPublicKey": "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12", + "timestamp": 0, + "asset": { + "votes": [ + "+03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12" + ] + }, + "signature": "30440220629e696a10e04d4fbc10a5ac443bf9bd40dd5d89d4b214224abe47d7ab5600340220643f361a24d9916e2c5aaec7bd7d8a6a0d3ffc5fc0b62c3ac4906eb799a862fa", + "id": "c3f49fb80c40f7779b32ba23616f5573a6ba58fc60c4629c2252933038dd89f0", + "senderId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2", + "senderPublicKey": "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904", + "timestamp": 0, + "asset": { + "votes": [ + "+0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904" + ] + }, + "signature": "30440220660f9604896dad2a97820b0d7524f0bce5a8b5766f150517d5061fd02bddf768022055e87c25891d4480e66e5d1a71e42cd5a4bef3ab2b2651cd72d44f30a4b32309", + "id": "8e8ac1b1a586e86867abbf25d63387bb6dfb793c691f0b06333c1581a9a568b3", + "senderId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT", + "senderPublicKey": "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c", + "timestamp": 0, + "asset": { + "votes": [ + "+034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c" + ] + }, + "signature": "304402202e2ad64129f61ef1156c4c7e80ab862d4823d62dac502685f53028536ddfb41a02201a3ec777fdfe8fae9f7cd5251fac322c1b6a2a4d41b3ec456daed474986d4872", + "id": "ff73565c373f2cefebf86c72dda3a6a6205750eb03b69178cb83378620715e1d", + "senderId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q", + "senderPublicKey": "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd", + "timestamp": 0, + "asset": { + "votes": [ + "+02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd" + ] + }, + "signature": "304402202e5c78cf21a088db10e1e1f64d98d84c8d3294fde7bc322d4af06bfe99d4c2e302207e7912a16a37b641a9f8c7c722f2b0d699917ca73e4d0f21584b717fb7f02f13", + "id": "3822273b496f2e253081cedf382e4f9937713fabb83449e1f892377cf536e68a", + "senderId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo", + "senderPublicKey": "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647", + "timestamp": 0, + "asset": { + "votes": [ + "+0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647" + ] + }, + "signature": "3045022100a65ce45164c9bc3e018e26703370c9deb2933ee3b4e814619043cc37c4a39c4802205ae4931ac9e8dffd714c3b601fe248a49c0185c8367887205f497d951c52eb54", + "id": "430d6db0b87c25dce4ce14ac907c13bcc6efa5d95135f05aa4ba7596ea9d400c", + "senderId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN", + "senderPublicKey": "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd", + "timestamp": 0, + "asset": { + "votes": [ + "+036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd" + ] + }, + "signature": "3045022100f3cdd7f688ad2d7b6a5b9cc7e793cb8a6e6e07d3327bc67add64691a53fd2911022026ae1adc8f4fcfc01bcca3efc83019026755b443a504265ad1f46f69d1f5951c", + "id": "dda86ecc0332e6c4eed1c0a5af7424374089b85dd274a300fed51b86e2655587", + "senderId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj", + "senderPublicKey": "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564", + "timestamp": 0, + "asset": { + "votes": [ + "+03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564" + ] + }, + "signature": "3045022100d419072a752acd55792257c96099fb14c56c29112a00535d39bca96fbd7951c902201abdf4db247dc956d79f4543c389823fbd1a9337f95d30df39603a3b52486bfb", + "id": "0998e9a055c53bf6697ee76af94c7a830c1364016d78fce889a21bc38ed70cd5", + "senderId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN", + "senderPublicKey": "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0", + "timestamp": 0, + "asset": { + "votes": [ + "+022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0" + ] + }, + "signature": "3045022100ba1e0ab761326d2a53cbda2a4a5135033c94d8166864d2ad3ceb963b4a0c046402207d755ecf4ada9fa2a598fd75e73a59d30cb83e01f510020b48b6bf162dc60b27", + "id": "be13743deb8486a575d1fb564d2b07d797ac77148d35793c9aca43c0d47aad61", + "senderId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA", + "senderPublicKey": "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b", + "timestamp": 0, + "asset": { + "votes": [ + "+03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b" + ] + }, + "signature": "3044022038a491e2e13ac32025209d00aec1af31b73a8b6ee77ad9b8bb80a34f5df59dfc02200ce82c89fe9f88bd5af236ceeaa80f9954e3fb4af7bc884c447505751d49c134", + "id": "f1d3d44cc289837de9623cba8891a1ed1cde8918473a91e2daead29975afad22", + "senderId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx", + "senderPublicKey": "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc", + "timestamp": 0, + "asset": { + "votes": [ + "+0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc" + ] + }, + "signature": "304402202ae599ce389cd030b8ab48ef53113458b9ba8bf9c9ed09c662eba2849bf540f802202ed63f8af492dd0b67d1b451170a989418a42466a3a7ffe89c4c5a18337e8fb9", + "id": "65ab302a44ea7550891eabc3b4a8d5ecbcb80784c4666195d5d0b7e33394300d", + "senderId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK", + "senderPublicKey": "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565", + "timestamp": 0, + "asset": { + "votes": [ + "+026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565" + ] + }, + "signature": "304502210088a3a4e82d307c238e01ce154b57631d4429e0b591e828ec36839a783736e842022042c6e1d719781e2edca3dbfe84ad13b9e490821a47ccadfcff379decb9c873c0", + "id": "d26a7ea56f398634a81086bb15c2f0c863c71b8bd728304d324d8245a8fb6c73", + "senderId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz", + "senderPublicKey": "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374", + "timestamp": 0, + "asset": { + "votes": [ + "+032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374" + ] + }, + "signature": "3045022100ae5805541f085a50076835422b2581d3b7a128a05b4f068ad7e3c14cd02799b802205f4bb40e06f90e02282ae74c0aba97923e601fd78234b9585468c4fb73f47893", + "id": "02504eae7ff4963c081219523bc48d7a07de4c29fdc1622224547f9a7c133abf", + "senderId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp", + "senderPublicKey": "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93", + "timestamp": 0, + "asset": { + "votes": [ + "+03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93" + ] + }, + "signature": "3044022078d38cabd8f427ef381d0aa6a0b98c6a590cb18f47acc1d80b429a1c1959b0ab022022a70d4d93d650ca3121dde6065e80cd90d1e2e91cb90f0d0b2eadde609e0d75", + "id": "addb8c1baa833baa52a5b51d8a86f8524bde826b5c9f0a99e57070e6323e1dfc", + "senderId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv", + "senderPublicKey": "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17", + "timestamp": 0, + "asset": { + "votes": [ + "+038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17" + ] + }, + "signature": "3044022076dd065e3fba825b77884a179d0231d7fc9e7d3a02e34bc6565fab81a84e559e02200a880c028e690a9d6f2c4c6576b1bf3e913817c834da8ec6afdbadfae78d341d", + "id": "72f31f9a829b93045ef2e860b24c33b9be6a2621c26914acd42121215c1d517e", + "senderId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P", + "senderPublicKey": "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1", + "timestamp": 0, + "asset": { + "votes": [ + "+030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1" + ] + }, + "signature": "304402205261d9d8ded6364fda8b10bd477982be84990cb010f9214d52c492676814e1f40220489f441ffe2478d361a12ab96caa59da495fe62d61d0e2255aa5ec4ed789afb8", + "id": "1f17b4ba072d205761ed3f786491eaf684ed3601b69082e487e568aa74a319e8", + "senderId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd", + "senderPublicKey": "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d", + "timestamp": 0, + "asset": { + "votes": [ + "+02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d" + ] + }, + "signature": "3044022040219da41054a3eebd3122df7f09a62a4e8b4fdc287ae77221f2217b42f291ad02202b9a70c54bb546a604eafadcc086ef6b6570f57542374d87de02ad7f61fe51a4", + "id": "5fa837023159d6a3d6cf7c5b2ed6fe05ff7df19300226b2f0be5a48a06993780", + "senderId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo", + "senderPublicKey": "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37", + "timestamp": 0, + "asset": { + "votes": [ + "+03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37" + ] + }, + "signature": "3045022100ded426768f114f459485ba6ae293c9649b340cf2dcb15e8e887fbb5fed6f7e0b0220752297022de6e93ff64bb9e07b4efef8e946cd2872f84d9e1cb3165ff5c342cb", + "id": "0a16dc31514629a36d7237968ada6a95d6cbec027b7d26e1e0f0d7d4febe9494", + "senderId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD", + "senderPublicKey": "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a", + "timestamp": 0, + "asset": { + "votes": [ + "+02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a" + ] + }, + "signature": "304402203aa292e7aedcd62bb5a79c2521b666b8e1886b57923d98f51911b0461cfdb5db0220539657d5c1dcb78c2c86376da87cc0db428e03c53da3f4f64ebe7115998f00b6", + "id": "8816f8d8c257ea0c951deba911266394b0f2614df023f8b4ffd9da43d36efd9d", + "senderId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD" + } + ], "height": 1, "id": "17184958558311101492", "blockSignature": "304402202fe5de5697fa25d3d3c0cb24617ac02ddfb1c915ee9194a89f8392f948c6076402200d07c5244642fe36afa53fb2d048735f1adfa623e8fa4760487e5f72e17d253b" diff --git a/packages/core/lib/config/testnet.2/peers.json b/packages/core/lib/config/testnet.2/peers.json index 9d34730345..d88c6511c5 100644 --- a/packages/core/lib/config/testnet.2/peers.json +++ b/packages/core/lib/config/testnet.2/peers.json @@ -1,15 +1,18 @@ { - "minimumVersion": ">=1.1.1", + "minimumVersion": ">=2.0.0", "minimumNetworkReach": 20, "globalTimeout": 5000, "coldStart": 30, - "whiteList":[], + "whiteList": [], "blackList": [], - "list": [{ - "ip": "127.0.0.1", - "port": 4102 - }, { - "ip": "127.0.0.1", - "port": 4202 - }] + "list": [ + { + "ip": "127.0.0.1", + "port": 4102 + }, + { + "ip": "127.0.0.1", + "port": 4202 + } + ] } diff --git a/packages/core/lib/config/testnet.2/plugins.js b/packages/core/lib/config/testnet.2/plugins.js index 413fa5dab3..f97525d009 100644 --- a/packages/core/lib/config/testnet.2/plugins.js +++ b/packages/core/lib/config/testnet.2/plugins.js @@ -1,100 +1,73 @@ module.exports = { '@arkecosystem/core-event-emitter': {}, '@arkecosystem/core-config': {}, - '@arkecosystem/core-logger': {}, '@arkecosystem/core-logger-winston': { transports: { console: { options: { - colorize: true, - level: process.env.ARK_LOG_LEVEL || 'debug' - } + level: process.env.ARK_LOG_LEVEL || 'debug', + }, }, dailyRotate: { options: { - filename: process.env.ARK_LOG_FILE || `${process.env.ARK_PATH_DATA}/logs/core/${process.env.ARK_NETWORK_NAME}.2/%DATE%.log`, - datePattern: 'YYYY-MM-DD', level: process.env.ARK_LOG_LEVEL || 'debug', - zippedArchive: true - } - } - } - }, - '@arkecosystem/core-database': { - snapshots: `${process.env.ARK_PATH_DATA}/${process.env.ARK_NETWORK_NAME}.2/snapshots` + }, + }, + }, }, - '@arkecosystem/core-database-sequelize': { - dialect: 'sqlite', - storage: process.env.ARK_DB_STORAGE || `${process.env.ARK_PATH_DATA}/database/${process.env.ARK_NETWORK_NAME}.2.sqlite`, - // host: process.env.ARK_DB_HOST || 'localhost', - // dialect: process.env.ARK_DB_DIALECT || 'postgres', - // username: process.env.ARK_DB_USERNAME || 'ark', - // password: process.env.ARK_DB_PASSWORD || 'password', - // database: process.env.ARK_DB_DATABASE || 'ark_testnet2', - logging: process.env.ARK_DB_LOGGING, - redis: { - host: process.env.ARK_REDIS_HOST || 'localhost', - port: process.env.ARK_REDIS_PORT || 6379 - } + '@arkecosystem/core-database-postgres': { + connection: { + host: process.env.ARK_DB_HOST || 'localhost', + port: process.env.ARK_DB_PORT || 5432, + database: + process.env.ARK_DB_DATABASE || `ark_${process.env.ARK_NETWORK_NAME}2`, + user: process.env.ARK_DB_USERNAME || 'ark', + password: process.env.ARK_DB_PASSWORD || 'password', + }, }, - '@arkecosystem/core-transaction-pool': {}, - '@arkecosystem/core-transaction-pool-redis': { - enabled: !process.env.ARK_TRANSACTION_POOL_DISABLED, - key: 'ark2', - maxTransactionsPerSender: process.env.ARK_TRANSACTION_POOL_MAX_PER_SENDER || 100, - whitelist: [], - redis: { - host: process.env.ARK_REDIS_HOST || 'localhost', - port: process.env.ARK_REDIS_PORT || 6379 - } + '@arkecosystem/core-transaction-pool-mem': { + enabled: true, + maxTransactionsPerSender: + process.env.ARK_TRANSACTION_POOL_MAX_PER_SENDER || 300, + allowedSenders: [], }, '@arkecosystem/core-p2p': { host: process.env.ARK_P2P_HOST || '0.0.0.0', port: process.env.ARK_P2P_PORT || 4202, - whitelist: ['127.0.0.1', '::ffff:127.0.0.1', '192.168.*'] + whitelist: ['127.0.0.1', '::ffff:127.0.0.1'], }, '@arkecosystem/core-blockchain': { - fastRebuild: false + fastRebuild: false, }, '@arkecosystem/core-api': { enabled: !process.env.ARK_API_DISABLED, host: process.env.ARK_API_HOST || '0.0.0.0', port: process.env.ARK_API_PORT || 4203, - whitelist: ['*'] + whitelist: ['*'], }, '@arkecosystem/core-webhooks': { enabled: process.env.ARK_WEBHOOKS_ENABLED, - database: { - dialect: 'sqlite', - storage: `${process.env.ARK_PATH_DATA}/database/${process.env.ARK_NETWORK_NAME}.2/webhooks.sqlite`, - logging: process.env.ARK_DB_LOGGING - }, - redis: { - host: process.env.ARK_REDIS_HOST || 'localhost', - port: process.env.ARK_REDIS_PORT || 6379 - }, server: { enabled: process.env.ARK_WEBHOOKS_API_ENABLED, host: process.env.ARK_WEBHOOKS_HOST || '0.0.0.0', port: process.env.ARK_WEBHOOKS_PORT || 4004, - whitelist: ['127.0.0.1', '::ffff:127.0.0.1', '192.168.*'] - } + whitelist: ['127.0.0.1', '::ffff:127.0.0.1'], + }, }, '@arkecosystem/core-graphql': { enabled: process.env.ARK_GRAPHQL_ENABLED, host: process.env.ARK_GRAPHQL_HOST || '0.0.0.0', port: process.env.ARK_GRAPHQL_PORT || 4205, - path: '/graphql', - graphiql: true }, '@arkecosystem/core-forger': { - hosts: ['http://127.0.0.1:4202'] + hosts: [`http://127.0.0.1:${process.env.ARK_P2P_PORT || 4202}`], }, '@arkecosystem/core-json-rpc': { enabled: process.env.ARK_JSON_RPC_ENABLED, host: process.env.ARK_JSON_RPC_HOST || '0.0.0.0', port: process.env.ARK_JSON_RPC_PORT || 8080, - allowRemote: true, - whitelist: ['127.0.0.1', '::ffff:127.0.0.1', '192.168.*'] - } + allowRemote: false, + whitelist: ['127.0.0.1', '::ffff:127.0.0.1'], + }, + '@arkecosystem/core-snapshots': {}, } diff --git a/packages/core/lib/config/testnet.live/delegates.json b/packages/core/lib/config/testnet.live/delegates.json index 9188834a29..096f5472e1 100644 --- a/packages/core/lib/config/testnet.live/delegates.json +++ b/packages/core/lib/config/testnet.live/delegates.json @@ -1,9 +1,3 @@ { - "dynamicFees": { - "feeMultiplier": 1000, - "minAcceptableFee": 30000 - }, - "secrets": [ - "" - ] + "secrets": [] } diff --git a/packages/core/lib/config/testnet.live/genesisBlock.json b/packages/core/lib/config/testnet.live/genesisBlock.json index 28969efa39..317cd8ed94 100644 --- a/packages/core/lib/config/testnet.live/genesisBlock.json +++ b/packages/core/lib/config/testnet.live/genesisBlock.json @@ -9,2149 +9,2303 @@ "payloadLength": 35960, "previousBlock": null, "generatorPublicKey": "03b47f6b6719c76bad46a302d9cff7be9b1c2b2a20602a0d880f139b5b8901f068", - "transactions": [{ - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402205fcb0677e06bde7aac3dc776665615f4b93ef8c3ed0fddecef9900e74fcb00f302206958a0c9868ea1b1f3d151bdfa92da1ce24de0b1fcd91933e64fb7971e92f48d", - "id": "db1aa687737858cc9199bfa336f9b1c035915c30aaee60b1e0f8afadfdb946bd", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100ffff4e9ba62e5e3beb37deee052824da83c4030925bce09f190151652d0669b8022056a432e56a2e1b026d4b54f6c34ce88a0c9cebdccc730659c03449fe878c66f8", - "id": "0762007f825f02979a883396839d6f7425d5ab18f4b8c266bebe60212c793c6d", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022001a6326e5d1eb06d0ba1fa39446bd6d56ea45f0c269ebbce5dfc6a649277cfcc02203b252d3a6ef2b22349d9d0a9110ce28a199c39dc8b911edfa82c297a02009d07", - "id": "3c39aca95ad807ce19c0325e3059d7b1cf967751c6929035214a4ef320fb8154", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304502210084d855eddfe616cf1dc238b19226c7959c2fc4027ae2e8aea6fd8e9eb8928e6b0220440f980e40c1c56348782fd69d49a96944df7ee5b68d18028600e0e7501d4000", - "id": "9fdf6ae86f7c005b3b7dc1b9fb6411219407ecaa93adff85fdb61710f5121638", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402205438b8b9058bbde5d30794e7681e400e52b5fbd22324c5b6b521f97bc8b8aabc022000fe04d7afbd2e668b1d4576988ed596dc92251e33efebc081e2cba14ad5a898", - "id": "1d7c68087c875d7ce555b2c3e71e1d91a1ad62d0c2497efe3cab91415e634041", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100b2e634a95b011a68489870f003e4bac4a4f0578bfdc6b9f645c934016c2c0463022022cd4ebf276dd627d98be4b697bae2df10b86d94e984da2eb7e011b08d6dffd2", - "id": "0c993e115ba26981b0be9d22e7c4a13b0f106e0cb472f9d34eabfc8e414dd528", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100f965e5c280acb22d1cde405223fe9a6fcb765844adbc5321b17a268924e1f597022043d31b1edc5fe0cf60a960d84e3528472cdf34560c9463979043a409f37e7f29", - "id": "c279f2eb1f9e6e7d4b0ba7a98233a0f1a2536231976c99f56f64b248eb06a0c1", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "30440220715463c316a75959dbfb6a59a013fbf914bef1ff739ac8000d49dabbf5118df9022019345ae1c34173dc214bae82f3cfbf438092f0fd2d277acafe3e9deb644b1a3b", - "id": "7e2fc9ecf23e909a3d0fbecd615445a0eed8c2cef18e01b1492d63f616f5d87d", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100fdd8aff26dceeb5abb6e5e8a8f468c8ac1997a587225298e3d8135d57dadf4dc022072ab80a81b301a162ed5cfa67d213d5a3980185088632f5f592351aff8aa0e9c", - "id": "511c0e1076104743f98932f8e7720bdb3f1539134edadd331914fd9ece1ebede", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "30440220635e04ce278870f17fcd1883aa26c568e63dfbdd302add39aa30fd3637c79c2c02206fdd9e7b1f4d238a97d26ef1758927e2d39f121687490f2bd79831e36afdd43b", - "id": "0768d5016c53d884e3d68a09d1bab0d730b7067c71ef4ca1c4d61b3815f5ff66", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402200b1dac57ca6565ac31afb99686f2e0f0e8dc219b9860b295ca5444a1663cecfb02205787393561fe407449af4aaf2f621db9e4d3f11c7438666cd694d495c0a0c41f", - "id": "1aeb50080ea118165e5041f7a897974c2ed1ebde08add85dc78cc7cf73566a91", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304502210098dea25eccf31ce6f874a9528578805aaf07be8b41f1571865793f9e3e6e3c97022033ae9c73dad44c01fe6362665fccf63bb1a0ae8e26f77a1cf60b67dc96b05343", - "id": "254f0f4fa277cc651a746d6ac371eb27afc3ea155ba060552dd26b8e83d17b72", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402207f4bf346aac501e766156818089fb16905a9bdca69ff6d5a55ba918a08afc7ab02200ec2c25cc4bb30e2c176d55630d8e2679b899c14ab4ba43c3d62955dd940425b", - "id": "e5ebb02e8e8a6708e22ee5ef99fe1dd8b6eea1095be6b772aa21bf63cf7ade5a", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100a0bbc15bdad648bb9b439f1d34b12b853442d1cfd4ce7f569905082801fa58e8022036b4e73edf7ab7226f8007233f77b1d497cb6b4736f02721bf1b399312ebe114", - "id": "8a686b21477b64dfd85f08f8598a0f121ca1c7d65ccaca9e42326c75fb5f3abb", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402205d77dfcde527dcc6669bcb01c27b92c1a6399e35ebac9e69415645f596ab1d2802204179497bfd952f44d5f9e295b2a3219a290a4a82841c084a18553b7712e26415", - "id": "21175347e2acfabc09a7593aae0682e39fe7152199a90561c11125f525211243", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100cf77c16df9185727ff717b71a94f8b29ceeae1e5bb3a28da8cef9df5bc63b7c202207bca394ce9ebd344a548e5a5697f672dedbef640dc1f9105f7c063287bcd1840", - "id": "ce1d9b7377551f36568127f5b635b5443f5a58abba6566b50a8d4d7b53c8a874", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100eb8daebb5484f3b0a738c9344fb28298c596f9486963f8fe36e2501ee6876f2a0220559df66986dc9a9a8e76982ef85f907c62745757990c69f0b17b6ae5a7ca4719", - "id": "b56702f5eddad0d8dbbb33b6b1ca3e07e4740def9c5dd2aaed9a70b90a4e31b7", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100d088e9bcd78978f2d67e7c7bccecfb73ddd0d1a2dad5b039390812320355722d02207affe83d815f04f6b11abf98eebe0488bfb87f8cd6513d44b829008ed1c15ceb", - "id": "a73c053c42e83a83498cf58e5b077b31443e265ddf8228081cb17a36bba366ae", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100db16a8e9682f07efb607bc7c75b654646ff449761ed146ab9358e69d29fadd7f0220436554ad78db0e04ae5b573258e2c8067848e89b55a6e8e1e25011a43882a643", - "id": "2dccb8b44ad2e598673628fd9d74e336b467a0c941d5e257dceb85c8e0a0000c", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100b03738eccce8ad0b8ac0a656119c2cdd202089c5650d8e1486bd13eb9c3158980220059079900c7fdc16e799c50dccc074726fbf0068044462faabdf1e73f9f9bc38", - "id": "b2cce30021d139f97925807da796722bf4d5459442523823388c259ca5ad73db", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100becb49fe5edd6806d5ba6eddbbb34ca8eaf3a12dba123d1610b2b120ca8bd017022072972992ee0ca0f319ae754a2a5a10d715a08b23f8239f9d6d59774f790543ea", - "id": "9e4841f43ab355be7a4f93b09f3d82c17065fbe25387dd6c5eb4e2692ea05b0b", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402207f1a3fe8c5aa7a77a58ed35c34f128b5df6fba89aa918af35eff432be7d1f8e00220460d4f2a457e1a477974157e33bf2974de6588d56e59729ae980720e9794827a", - "id": "2c7ca823be21724a4876de632dded3b9afca45df357819ed028488128d85d29e", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022067266dfe9d8f2550b590e1eae2f73d28c6b80fecb24c3eb1b4539bc864b3b4f4022031e5122145c35874c0c48673d088e76fb3e11c308ffe9d5dee6431d3441d627e", - "id": "a91119f04e2201184761f7fdcb26e4aa81c7e1076cb11a58a422d351241d4e4a", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100b970ec89927de0cb7805e614a742d42c2967db5a9c68d0892956dc89d68ca7d1022067fa30265dd2e1a2985980be2bf876748a7a8c7f3cde0382265b601fa658dc17", - "id": "94955e6bac6269fbd19e92d2292ac947225fc6f68c6216001b528596a961040c", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402203671b82ddf8a824b8e5aac8bc28be4aef1c00aca1097d14ec1a55003d7a3f28d02203aacb6e7517e916478432b81399828ba7425183ce0fc43feb361bcf345fb0519", - "id": "df563ee9822bd3d7aada600d4800952743ec64fafdc7697428d7a19a60745885", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100b77653317c93eb20ee19c71e64a7f9ecb985351bfb1fe351ac65a5738cb37ae202203d540395e1d55f87caaaa867afbfbaf98c553be0b4c7d1748418a76b0c258c89", - "id": "d21b6341e2b4be5ffdc3dd8fbcdf2c576ba02e2ef4ab5eab0e4bfc9da4e9e442", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022046239e39062a58925099b005888355b8cd6700af66972bf509a10123f9abdec60220202321ea74e56177606fc079d19c29851d832e6d00c93985ffbec3dba6f0d675", - "id": "df6bc7a17ad34f8e9faaa2646e8e5dd8bca35affba352537184f690e200e17b6", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402204eeab87f7ecc2097b85606b986177964f3ae777535f6fc0cf08a55fec587d87602203779d59903b8de63511e4ed0a7967bd85e9cb1fc9d84bbc5091e3caa87d8bd52", - "id": "5f0d5f0dff464d0ad587da5bc93e600a8e2657d359d0a1224bdd4ccc3b6f376a", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402200a2b9d0f61066fa00a2a2882379aa8ee60e949bdc2a85103bbbb69ce3eafccd9022057364f349faceb3047fa95ada210c64fc4a81978d66925b37d3dbc21ede885af", - "id": "1b39e3702576e6ad7775e34d53e43210549d52a56b3f246031e6ba4121a66bf0", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304502210099e568d3d0c1b48410e0b85c74d04234dacfb2fdf2b1d4b51fca1cfb3445347a02207a2509645aae54560762a37422b66ba4b3ee1c42de35d58c36d2f9d8fdea11b4", - "id": "0f21e53dbb1edb1cfb4c31bb675aa4672b452a03ec363a2b3300a9dda49e3be3", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022026cc5f2b588a86241badca73cd9c1686916d516b8c6c397c66a9d5bb6b5d4cd402204ab5a8c8589ee954bda4a116999d2a0e4ab0e3e96f0c7fe131d7c57b9a1ede43", - "id": "410826c255a23a78ac5c3aa10dd48132693bc955845af16c20d9c6f69b05dfe9", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402205fedd8d3b5c8d69cdd7db5ca8e9e7c5004f6ba751e45eb1b85b26d9e89800a2402202be56bb2cd824bccf325b6b11432bf6d0ddb5ec97fcc121839ac2ebf884c7173", - "id": "ddb57d8270b2b6c876191c1e1c5974388b9fb3ae0980cb2245d8a7c426237f47", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022053cd42ad147eea33801b2b57388b33f633b4bfe2ad902190e12480522250d07802203066dc0d0c2ffacc4c74cca1e0187fbea1cef7e78a78666d2ec7e4e87ef546eb", - "id": "29e1aedf98935c369946c8dadb2d6784f9ab5ce8d73b9b4de2466c7757e2557b", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100c10448b87e7176735c8ddfc8fb3c4d5d55c2d71d18b7ce3ab321209ec299fd41022013517a09e4b366ab386698286ec7bb20410bdfb7f6674fab25a739259083b297", - "id": "4cf04852529b5525f22cc540790e36e61ed36045ad1b5b788f61ebe42637391e", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402204cc1588b204ebc0c20f44a31ce53d15ab5e4d1f9c103c02dd4e4eaa1c33630b40220194b6e427b6def0783461cd8d765f97b105d048942be468be2ee9b0a2785d2ac", - "id": "35c6bc3f0799d9c79efc6515f232c58be0d03a3a797d066cba879eef4afaae2c", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100be44f7ea12e2ee89245fb474643ec6c2c75afa00276826a4ecd6fca4cad5ff30022071a2c083b353a821345e4bbf74d98db0760b8721856572572cc3436ebdb8f08c", - "id": "45f75a349f3b4d73434c0f2ac9c291d5d07278b79e6eaa0d38d6e005f66c4783", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402202090f506e8f18fde70b87a3fd6c470a23e9e262f20ec6268dd59b6362e51a29202202b838c598b33c6317c998dc179fad2b660b8a72bfaf8223d7cc82414ab4c6af4", - "id": "a8d9034d1091a4dbe595647ad5f64ca8b243e7842301aee48f7eaf8b8ae98119", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100be59b689a48e198267305f1ae7e116f69f7c360857ea0b1fa81db122278cad69022033436d24ec0103674522f0c559e2357f8696bd498deccad2e0f66b2cf7469538", - "id": "061cb438ba1216cfd5a0f268ce18e6f280557bc944d9aed3655e2bc5f08bdf51", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402203b5d2aa7c4554d6d2dd6723043350df0199e6e7bbd9f21a1a20dbba8c63918cc022014a78064c5f9c5e2f43d3be36de2b5e2f17e9af557bb6c75e8d82d9f725d0188", - "id": "239f0640ddc3170a737ef349c07cb82b2493d207421b6f71b6b3dab856f16088", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022005eb29ad4cf79fd4f6898de19459e15cc816acb0975e53530a202e69c29d0d4a0220686cf6e0c14779d6d68dcb9d16358c0e859094d2eec8083598b7bb5869478bf2", - "id": "25d8eef755cfee7cab0d7f9fbbea0fad6d5f906c432d997ae8ef1c49d23735f5", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100b93096a287d59545fa3a08593dfc740d9d47f3cfa3c4bd3c8ff8ef53d3a2e957022027eda62e47220774cf799f46916195e5a8b30015c56ceff4f4a1c10a918e3675", - "id": "aac25996e3be809ee88996b6b4063e2097d6306e77a067de8ebc8d7076a28d43", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022017282aa4fac7b18e834abc3ca37b2f60cf989c26b12e2f2398a66cb907015a760220428218d39db812a22cc138acc7d5d4d2d5713f0546751c02d2c3fabecca0e724", - "id": "b040f86b75750b49c83ca7eb8f2a458f16b44789796ff306c5f942ca5f19164d", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402205970d53cb0921a62bbef540dc33189b2313f3574e44f046097067e6991d63b1102200a356c87642cc781df661a1fee21cce354a144463d37053280e000e1b75da7a5", - "id": "25ce96f951d7b7d886ef487331125b3413f655f9c5ee7fb4691a728c3cbce18f", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100aab0201c9d9a9641c11605d32353685cbaa051ecc276da1e6a3b309be9f20cf7022067aecbc7329bdf1770974e317a1243815511efa8c7af7801217a83c96d86eb0e", - "id": "285143b8b19cbde7c680b0f62ef51293e8f315c823ffbd97608c38c02045d831", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100dc7752f6f8acaa3a1ee2ed1bed306ee04556b3866db92a1e770c4b970c7a932e02202d137b312342f9d0708704833b26b6611d0464c87df97049ad8b616483e9d1f8", - "id": "87b06fccbb63809e976b3405cccec2eeaa3694d5510203f04c0e60bb6c2c0020", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402205ccad5c77ea339f5e3f2b7900b4b1c409d3c8204273e89b6401314fb61f0d224022026a63fef86356de64fe571ff8488a951dcacab56e980fc044ef9f43b9d37439c", - "id": "5597ed52e4123756bea9307c09c916ff9d0f9fbce8d2e9a3a2ff719a87ad0966", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402207c91153f820f34228bec62772e0d78876bd3277912eacd866fe35b5c86a316c80220104529c6f786cb387ec1e3d5826271c837f0d0a6d0fa5731b9a5c6663cce7108", - "id": "d46fde78608fcc668246cc35336210b3c167ba55c82e91b0fd99df7e36872130", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100acc0cf119c18861d3683bb3b0f6e209f2d62acfdd958f86dfbd35137ada814320220448f6f8adcd46204629b45a4a06f5dc7ccb4dbc2a1d702e107d91053847adf2f", - "id": "aa92faf5d80459b4e058dc8a8212608b589925052e22148384835ab687a4e875", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022055b6bbde5fa886db3cf1224a59f1fb43e850e2d9237db593368e1043698fe2c30220067dd20195e794af4152f1ff9e3ae4261698a86c54803ba1890bf176d97844d4", - "id": "432e67db0d5fc8c66376aa96c7324e5a1e6d00a415a9c8898b5e3bf25d8b083d", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "30450221009d6f38067264df8497d6888e4a8c316ec58ceba8a54c39ccb0ce261d114fbbab02200fae3f2f950f5c5e3387679f8ca341ec70cd90d0e32a30112f03cfb12cd9fc23", - "id": "9321e1b08faa544f592ad8dc7b60ff1cf845efcd28fedf8b445be3bda60434cb", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245100000000000, - "fee": 0, - "recipientId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402200aed5a4102bdafda00fda575294f149b393a798c510af8ba877b8c2d7ec8051e022004f7487c4f728c633aee5baa62ab0017f4b91cf2f494eb1c4cc9addc3e9155da", - "id": "0bbc9340798a18a81109bdfdbee9c9003f20a586dd9f80a39507c84588c1b4b1", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_9", - "publicKey": "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647" - } - }, - "signature": "30440220072124721ba7c997f7c29ad3d4819515fae7a67be2bc395cb73f114eb8d4abe60220523ac295e114de30ce8a4300f4670db91ad2abe1268460e6ad3463fbe9834b84", - "id": "d2e70f9d2de57240571905aa81db0b6883e27a83be2422530722d76b56e63ecd", - "senderId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_18", - "publicKey": "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a" - } - }, - "signature": "304402204b93b06e08e71e3317f9426a1d3d450d6293fdbf5a6b3043fce27b3ce65431e20220683609720ea1d7d921238ca8b5098d3d9c0caab7b1e26efe42a6aebbc095471a", - "id": "8695bcb906f5fd81d858794f7d90447aadaa38418d312e33115a81e856b34d12", - "senderId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_47", - "publicKey": "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd" - } - }, - "signature": "30450221009711559a43005c808113a1e9a01b1665495ff4bf30d635f7d98c752ead4cc3fc02207879e2a939914effe2b5c80cd515c4b3ff77a071b707c85c4444481878803db9", - "id": "55853d2d2a98def00c5ab842866a44d1db91678a07b6dd63d062508db28a00a5", - "senderId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_5", - "publicKey": "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565" - } - }, - "signature": "3044022025ba51a588253524557547ec492d71bd485fe5b291e60eef681c39eaf8ee781702202bf24c3d295c7a2c9aed97a79fb835506797dcfe7e7a2853e2578e7773c7e134", - "id": "553298aadf692c9c5d0334c307dd4ac0e277a49ed165c97ce1362f8ec639ee3f", - "senderId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_19", - "publicKey": "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb" - } - }, - "signature": "3044022041291ba10ad30fb9ebcb0e13902e92d85e2c3e98493b6d369d7d1e70e8474e31022009083444460c415eab6b4beed9e0206eb0733bad5d2a476af4db4f5b5e74b835", - "id": "90af927db7b258538c8e21116b5a31418c88ecc163628b2b65fac92a5a949b14", - "senderId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_42", - "publicKey": "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d" - } - }, - "signature": "304402205d4111c87874e696b8f4b8897d0dfe68fabe4ad5c5769026c6ecdd04f09a1e2f02207b9c8a2a16b50164215eb1efea6d5d9f4e693cbb7eec8535e526cf8ba68bb796", - "id": "8a920ebf5255a102d0c9c5fd720e0d36a6a3539991a2267442facf1fea2d0b86", - "senderId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_10", - "publicKey": "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd" - } - }, - "signature": "3045022100f15ff048872020d9efc561b8c837f542d54d43b9b071f7a6cc09643c6d4180f002207d0e82153a30b66f43fc4cb4b9b3093bb3d5dfd70f96928c8780c838b1448c19", - "id": "30738f376aa40fb3c8d8849a5dc698786aeb1409fa801c18729f8da624631391", - "senderId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_20", - "publicKey": "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751" - } - }, - "signature": "3045022100babb7410d09215def98078bbab6b5e5690c2ebf54960d94527226ed3925877320220342576d1d8fd2d2fe3b6974cab48a2e16b4813f022b341b32f88e13f572bf060", - "id": "ccbe1c27eadc1b3b33f3f87f645be4f756021ee3d4c96f4f094e1f82d5728a3a", - "senderId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_49", - "publicKey": "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374" - } - }, - "signature": "3044022032f2c350cc1319f5838d6880e91b49ae0438fb3a626ed9ab5e27ce8788e3347c02202cca18567c8491e0feea8a5f078e28605029346c509fac0c0a192e934f8c5326", - "id": "f99af0fbb4d65c2c3f2c1c558f0c0c0eac2724942802fcde02fa6da1d3a9000c", - "senderId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_3", - "publicKey": "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17" - } - }, - "signature": "3045022100f0cb5d885ddf3bd4a58837f9b86486da4171652a5eb39228dfd0ff9d34d9c7c602202dc6e3d268d745a7e8633311a337ec097382342049672880c7c2215cf58e5da2", - "id": "2dca03aed08533585d8bc609da5deb9f17ac9be5a8352769d7ae63d0db16ff59", - "senderId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_21", - "publicKey": "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a" - } - }, - "signature": "3045022100999f19fbdc9a12eebbb8c748a4cfc6c91b2233f333a09cddfd49dfeab6aaf38602203d8dc9d1551d400572a88ee812f51f897f8b35508713b789b2c1bf6dd0e88945", - "id": "5d7e51d57b5914ec201ab65a019ecdf651c4f267cbffe403fd2170bb95145f9d", - "senderId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_41", - "publicKey": "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f" - } - }, - "signature": "3045022100e86e648add940a1e637e32ea9187497c281b843da09597e62d0c927d7f43235102200479f64ae63abb55e338f9ce1073a5c46907f7a2a82ea6f9bd9bc29811683515", - "id": "eaeed4133da26612c53550b6572722d8c3380d0a2344da1bd270eed1ea91fdf3", - "senderId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_11", - "publicKey": "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904" - } - }, - "signature": "3045022100bc3b2ebc58a92bf38672206e8311e7ef0e54912abce7338155b11e7d191b0b5d0220765a568c1fa4665c0ace6b4bd3b7ba0f8329e2f25af7a3cc0d78b2ea398084c3", - "id": "bb91e78e43c59a19ac06c015d8a7ef09d7c5b274c9f98505e5a978027354b71c", - "senderId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_22", - "publicKey": "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a" - } - }, - "signature": "3045022100aae4868ab75a33e4e77f9bf6c53b920c5e7c523a7cfe271d1afc472655f3d6a60220499f1bcb79bc0fa830dfa939898db5c9fa8571a2788c8de0da7e550bfc818bcc", - "id": "a6e687647dde9c1db68690090afc4fcf11833dd35fff3186b6b709a1e7d24260", - "senderId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_46", - "publicKey": "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c" - } - }, - "signature": "3045022100c0cf1fc54705c13f70fde39c55a1703a4c612b8a919379cd5b1ada464c7cc8de022074ee62490a184010ad2418d3177ff2ab03d02d2589000176312b90422b1bd64b", - "id": "70262b0eec3ab5a60a736eb8a628cb600eae7522464a49791c0bf26e82318ec6", - "senderId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_6", - "publicKey": "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc" - } - }, - "signature": "3044022045db446b109215c6d3dfb0ee5869154a8a7624376c3760eec4fadc75a29033cf022003e524d64f3ccd0c6de4ca80a7327e2c47ffd16b3ad042bd25a02f5f64500ab7", - "id": "56048c449694964bee3d367609a7bc46c8da20f66878c09c01dcc53c3abd932e", - "senderId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_23", - "publicKey": "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a" - } - }, - "signature": "3045022100f8f69f2957781ed02d64983744c8e51fae613ebe5bbb330d4f509bdcf4fc6b6602205568ad1fd840e01ec26a24ac9a0ff093e978172da55d494138d018a45eb67893", - "id": "e15dfc4e18106480083b3c6211349fd9c803e334e9ba5eb62cca19ae3f57d8e7", - "senderId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_40", - "publicKey": "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689" - } - }, - "signature": "3044022021eeb9e1db8915a9adb99db72972cd17fc7b5b377fc532ac2c9deffcb2707edf022068b9e08f45bbebad89295f520ad40d7786fe64059d45df95551576e3acb736d1", - "id": "2bd0f888ccdeeca24a0134e3c1bf729582d284f32ee000d97f1417f1349a6594", - "senderId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_12", - "publicKey": "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12" - } - }, - "signature": "3044022040a9d0975f747df19792211546410d7c735aff2d26f367d1bf9233ffd1d993d702206890c66d4d0eb5de37df088c082d8fbd8da043817b48a76bd5d70f1e3f6b6529", - "id": "f75ac5ccd243e09fc9da2b3842a0654ca860d2dba5bb73866693a8a918937994", - "senderId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_24", - "publicKey": "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95" - } - }, - "signature": "30440220550c0ab565ab2de649ca7a2aaf2975453a1e4ab8b0d392d69663c0c9b6b80b7b022039047d4d1bf4e9b167a95adcde0a5a8631aeca060dfd426da28a10d968fb3a64", - "id": "aa2ed932faf4832848356beaf87e5381ee56a1a84fb485ba975acb28f8fcf5df", - "senderId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_50", - "publicKey": "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1" - } - }, - "signature": "3044022038df37ef25928d1a04516e982c99f49cbdc193603f814b48ab3802153bdd352002204c918915a3cbfa305c5f898ae4bcdd75394b57460f85c80daa0999751d466c08", - "id": "d30a726e1bb8d199d8f44700bc999c9a0a1a8be86e4be6a15764ecd424f9db1b", - "senderId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_2", - "publicKey": "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d" - } - }, - "signature": "3044022028dd44b9609b0b599c15a257757fd068f9014e33947c77776a6fcbe71879271b02200b46fd8eb0827da6de13f5efd63b17f29e8ba4600e4a690ec31eb08bf2d9af33", - "id": "1410b8b5f15c05528013378251bf5da30e04c8a6b7ac0f729b527664cfbdfbc4", - "senderId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_25", - "publicKey": "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964" - } - }, - "signature": "3044022038edfe34f7b89b4e69ea8b94e3335063b60deaee28246932147f53b2525924a402205b89f5e3d956aa49f24f81e2ba3447c19bd5c026568b3bef73a7a7d5160ad661", - "id": "58d14b74b71586e18f0499a50004ec2e0cc2e5b56aa53f4cf57084030ff90fa3", - "senderId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_39", - "publicKey": "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5" - } - }, - "signature": "3045022100bc1e477994bf4cbcdb5cbe2bd92c7d955a03adfe562f8e3bf04d2f62965e9f78022045512772d8453314361161b2bd2a39aa0a7fbb897a5a83f4c7ab54ced615b42c", - "id": "3ee53b3f1455ef0ddb52afe08854c9d87f42c7313babd3e05bb3ca4f94c495ef", - "senderId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_13", - "publicKey": "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f" - } - }, - "signature": "3044022052fe00e8e9f05b1d890f6910beab0627c823eb2d5875b4b9813a33aed11edfb6022034a723b827ce0e73bfdc0f535b244ffc983f8d549ee72b4d432de90d658db72e", - "id": "4a3d204c2916c93360d7bb11390e355bc1a930e3cf503965a45253d65bfe928b", - "senderId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_1", - "publicKey": "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37" - } - }, - "signature": "3044022013b2798a4ab4d741850abac10d962360cd4ab6a47dfac7c1c806d6f9c3d810cc02202742414ad8a04ce679b445fcd040fb877bbfed3d2692b873dec8cb46c01c8c4c", - "id": "7d0c5a44a7517f6ad7a1253db45d58e85aa1c735a282a32f45d28efdb7869d7e", - "senderId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_45", - "publicKey": "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b" - } - }, - "signature": "304402202c372b7b9679a8fe66f952a1d47d4327968d6e98770b215ada2fed6a8d87ed5502205a797fb511cfba557255dd37e028fb40981b7b65ad2ce8fe0e559a46eb274bf8", - "id": "70bfe97ae7452dc752ab4de0e2a0e81bd18bef07392c56e7a101257683d4d932", - "senderId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_7", - "publicKey": "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0" - } - }, - "signature": "3044022058851712200f7386d6b3c188444f9c8f05788667649ec17c71b9e514206eb105022061e6a4bc4cd11599792e03298f95509893d56af54d51e9f639981045e754b974", - "id": "f6f90ff09dee5be7d8f3d58d217772df7a95865bf8609d7d5b0b673e9a5bc953", - "senderId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_27", - "publicKey": "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d" - } - }, - "signature": "304402204878d69a166e60e0a779c31fbc48c67b70d2e4aed1d63c60beb9f070963e2894022078c46b6687f23493a4c2ed39709a183a0f7352568cc9cc2c1f0d7bf0d809a4a4", - "id": "f68809e407d20a50029fe460d411c866b79c7e09c076dada768a38d81f184aa3", - "senderId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_38", - "publicKey": "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294" - } - }, - "signature": "3045022100d5576393a1dea704cf79a5d0bc2757a3a5e66e1055103b52157fca05fc5693ec0220522832ce0e31b779decef83ac8ce764930de927df9ae1d6f6f99a3312d99c90c", - "id": "2ec6c6f33f00431ef063fbb8a79fb90eadb13a79bf46e6e1df36dd9434314df0", - "senderId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_14", - "publicKey": "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24" - } - }, - "signature": "3044022008a7d0bfe9c4c150566ddf701d08e84b4a5f84b07e3b1c91dde1cefa16d2a3c202200b787e898c0b2c68f4343e74f18ae7363f62b5f4ef2962386932aee09a9fa0d4", - "id": "e37b3efbf034bea4c852be7d7013978f8999eacc39549ceea775de197e14e8da", - "senderId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_28", - "publicKey": "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28" - } - }, - "signature": "3044022023b6fbfa5f4482a4dcc34411846696052b1592786ca87243b7d3344fc9fe9954022035402fbca22691de2497552c743f0f68c7591edd1bd7954ab7639548fcd558a3", - "id": "08268f5e6c15cf146523ca928f24aca65b162f363593d927c66144ee5df297cc", - "senderId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_48", - "publicKey": "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b" - } - }, - "signature": "3045022100b3cad169f29a3a95995b87e1b50b35583c1bff91d69cfa236f58ce452491c579022026775f4ef50b50ecf6d78b530b4633711394983456e6a45ec227b652c86e3014", - "id": "ad94ee2ae94813a638b93909930c7cc631c364b6c8528b2dcd6fa8f69260cc2d", - "senderId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_4", - "publicKey": "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93" - } - }, - "signature": "3044022007ac9ff2f272f3fda4947393b8688586cc8b2958ff5dc7931ac8f82c697bb76802202a66c28852bbff86ef17ac7f51e7eee52e611e825d91a9846f531ab3c3115c81", - "id": "76fb1984da9ef90fd7d588756163c97e00d3e4d6e9dfe78d9e3d3cb6d71ddd38", - "senderId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_29", - "publicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252" - } - }, - "signature": "304402204416e428688ad29928303fb2b00a26996cf79753fe70fb91c1f4635c644ba859022068ac5eab7d05f87c40ba36bd9dc149607c196778120c061698d7ab64aaade7ac", - "id": "0f442a91857061e87dd193b0b9f17a71719ca7e3da62841a63568713fc12b5e7", - "senderId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_37", - "publicKey": "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4" - } - }, - "signature": "304402206a248caa5949024202f297c38cee18845e344c5f140be74349787097d3b0a33c02207ac84336e02592bb5e00dcd0c490d30eb856b34177ab9ac03410d82a355a7b0d", - "id": "eed30a45c350fdffc5877458f7fe29f28dc4bf81aa1a197d003c9433148b71aa", - "senderId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_15", - "publicKey": "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca" - } - }, - "signature": "3045022100c99336ce666cb4a6db3727a61c04c14d8746365f72280d9984441b7d2b568b5402201759e4f417f683743e1d4a14f8a7a215009321cdfa29834b2dbdbe54ee22c1d9", - "id": "ecfba14a58f9d79782c4f905646df28bf566e3e7d1f17b39df6fe6b52c11de59", - "senderId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_30", - "publicKey": "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883" - } - }, - "signature": "3044022070de7b4d4ce64bd605c9d008142544c2b113cc84df07ed1982e0adf3cf69f4520220211b01710a6533a270dc2814c7f968adf27eb6dbf437e7a72960b013b9651a0c", - "id": "36ce5323859a92f302f77f27bd08ee3485d720f55842ccba353a47ea96a964c2", - "senderId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_44", - "publicKey": "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c" - } - }, - "signature": "3045022100a7c271633ecbf3c6641c7db36913b5fa0ea521f400a4848edf024648f3d7128002206a271f8a88644062b64d856407af9567c0b2937d4a3d89a3b3d07edbd3a0f177", - "id": "e120452e7c56a9327b2be7dfd3dcecae193f2e2e772903008b03cdf00146ebd1", - "senderId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_8", - "publicKey": "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564" - } - }, - "signature": "304402200394b6545015bcf2d0f291de57a4197cb6ef57b2ad5fa37f05e8a220913ba83502204d0d2f2206edba54ada5b8e5afd194ba83dd1bf15f744258409595251dbe3ff0", - "id": "7d15eee8e4e3be3d2c44acd51b87a816bdb593565d4ac358dab24ae9c8a5bae2", - "senderId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_31", - "publicKey": "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2" - } - }, - "signature": "3045022100989eb331951a13152aa03583efc765499e836c6fbafcafec4302b243ada8de5002203876fc4cf7fdeee4a095667e55a2fef84e5a7053e807b4d8e029883f0d578019", - "id": "baa686d521f95d265e7099cfd9ef14e0a9a92254dd94c16ce50c460bd013c588", - "senderId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_36", - "publicKey": "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e" - } - }, - "signature": "304402202be177dddfad323302565a866d38a3e7939e0234b16e7dc02075cf258502eba302200928a139ec1a82b4609fcc1bd6d1d027ad050e93fcd2eff94181936d2d43e39c", - "id": "9fcf7ec6fe98ed94710e212226d8b90df7e7467d66dd4c5c9d48474388be3099", - "senderId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_16", - "publicKey": "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9" - } - }, - "signature": "304402207b4f8c09a728acedf3b6ba0632e12d01670c683215053e49dde8598954d85a9a02202a7d7930baa17c2134b314e47dd6c334c828f78e573a2bf92fcbc1146d630541", - "id": "c35e4b1e7a2435664fc0939251c2052633ebf4b51fb22d15e71bfcab85b26de9", - "senderId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_32", - "publicKey": "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055" - } - }, - "signature": "30440220127d27312345e015c681adb799c1a87d16fb0caaabd5020b39257d567816b91c022018b2388f6d2d9afb3714d84ed102b3ea61159772786033c855947613c7ce7b5b", - "id": "0d682a3a9c252a674043bee5240e456dae2685d76fbd3bdeda6ff50f0c442fff", - "senderId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_51", - "publicKey": "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a" - } - }, - "signature": "304402203d0ee691830e4d001553bf4e49b6d9669b3c959376f391410551c8adc679dac902203ba6e275bf6d543efd19d20428649f802d9396bb0967114a1f09c24827be1da7", - "id": "ec2373b0d609ae72fb400ffdfbffc59670ebbf1c15f59c0ac22a4030dae700e3", - "senderId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_26", - "publicKey": "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983" - } - }, - "signature": "3045022100f2cf77b0510f589b5aaaf2b0027ffbce6ce8d4873cdc67dc8900865d156de3be02203c22e30945618683182f3d3873e6b3657e0900b062f866bab2705cd593669e79", - "id": "3cb2f0f7d05a515d4c5c873cbe96e33b1dfba1b7718e4548de7f9da54933b652", - "senderId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_33", - "publicKey": "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe" - } - }, - "signature": "304402201e328159172d543d2225c247c6b728800c52eb724f67c0e919f6b7215e6bd7f2022075fc02fe0b14a1499c5602d87ca2c99d6e789beaceed2b9702060dece872d14a", - "id": "2fd77e744399c9632cc8f106c39237f201dafda976f1040235359f99eea3b832", - "senderId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_35", - "publicKey": "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e" - } - }, - "signature": "3044022063903d82e8bd15a6741a298b9a6007d0dc3626acfe2f072c3b624ccbf91ce3360220486ba4cc5591d8aa31b77dfde025b61691dbaad0feabe13e840d26e40010c5df", - "id": "5baf9e318c9e4cb0513a21eaea27e51c849f95fddc963207fb07aa2fd2b9f9d4", - "senderId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_17", - "publicKey": "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357" - } - }, - "signature": "3045022100efc1bc16e0b646da48f84822543b62ef5253bfa98bed6613f2d6d4634076e61802200ef243f9dbac7633a8819ce45e2a85d0eacfdc9a33a92bd3a03e90cbd312b823", - "id": "b4a959ad75f81b7fdbb957c90a3a63a6c5589e7819e2c455733a3a2b4b034634", - "senderId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_34", - "publicKey": "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80" - } - }, - "signature": "3044022012e52a479648990bfc1ed12bf901cad865708ff45962c3724ea67967be4f9d0102201901525ed8dd090af6a2637c123afb304e9fd178794addcb88d916227e66887d", - "id": "6439f2308efe31ac52ad06ef1caa45b9abf6c589118b7997da6a287325ca36e7", - "senderId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_43", - "publicKey": "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e" - } - }, - "signature": "3045022100a0874d1582ce210081f7ab30e7f951dfb9ce8f512d237f8a8cbd5d85569ef3b902200f0053c05de3d6e5ada4e4cf1403a836779d653573c2f374055645cc954c4c4a", - "id": "b0733072e98d3d6afe977e32f3dd118c15e79212232417743ffb551dc2a2ba55", - "senderId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW", - "senderPublicKey": "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357", - "timestamp": 0, - "asset": { - "votes": [ - "+03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357" - ] - }, - "signature": "30440220158ed59156e0eef2d2b94a296451dffe079be701b3d74f0443ef43bc266b334202205a2c39f57abfcd279d568608b90884b3ebe107316aa7552eca35c743b318a47c", - "id": "ea294b610e51efb3ceb4229f27bf773e87f41d21b6bb1f3bf68629ffd652c2d3", - "senderId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7", - "senderPublicKey": "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80", - "timestamp": 0, - "asset": { - "votes": [ - "+030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80" - ] - }, - "signature": "3045022100898da9f693a458a6875344c6c4cb73069c4075904c75595ffbc665967d84b07002200f168aaf3ab1b52dfa74599394387dc4cf627a447fbc5a91000e9d251cdb20c0", - "id": "3639b5dc6d19d46d8254d941bf7ace0f3da8a7cf8a56361921b260820c7239cd", - "senderId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1", - "senderPublicKey": "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e", - "timestamp": 0, - "asset": { - "votes": [ - "+032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e" - ] - }, - "signature": "3044022055ed9a8b55ccb3bd0945a710269b6f243f1dbfaa28467d3218a17565eb0c962d02207d31561478f16d93a20f5454ad565dea24e8dda4ddc464cb011f4b6b360c4e81", - "id": "fe24509580cde0c2e2f49defedd3a0f7572d2f78f90b51a253b0d8cebd74c20d", - "senderId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof", - "senderPublicKey": "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055", - "timestamp": 0, - "asset": { - "votes": [ - "+0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055" - ] - }, - "signature": "30440220092f367f833d677e8d0609ad1df65f389c2c35d1501c71c245c2982e6a832268022018e67445f525613d6cb6ac0c9683bd0f55bd40d9c929165649414f083c9041f9", - "id": "6a76553db794ebf4d5f60a7d7d71cfe29f4dbcaad9610106fbc578cdc7167cd4", - "senderId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy", - "senderPublicKey": "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2", - "timestamp": 0, - "asset": { - "votes": [ - "+03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2" - ] - }, - "signature": "304402203dc028b5013c36b03f97b111a8d7c05d0cd8e505b0b0d18747c0656c9b5cfe8102205e9ce8a78d1183b3e9880c69635d04218d94d17808bcc3f92e7af53195c23daf", - "id": "0f9d7e7708918b77afbdfffb63eef8fe87ba36e0131c88b44c1a7f81750cc025", - "senderId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9", - "senderPublicKey": "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e", - "timestamp": 0, - "asset": { - "votes": [ - "+0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e" - ] - }, - "signature": "3045022100a80ddd7c3adaf0e97ab938773fc78a716f3054d7e03afc1ddfcb5005badbd2810220231c0dabe2262149f994c939f9dc90d46b9bd7ca96b19aad6788cd3571e4f71a", - "id": "0ac77b2637fb25be42b3b60d1651bbbd788aeaba933a08ec4a417c7b4c54e087", - "senderId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT", - "senderPublicKey": "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883", - "timestamp": 0, - "asset": { - "votes": [ - "+02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883" - ] - }, - "signature": "30440220772c9cd8b96f74fcddc429d57d466eca6fc40fc211845f59eeb78cb027e116c5022004cda291587eb118d622de21333d2a5783969794b5b0101ad8b1044c7d8058af", - "id": "4b0dda465564d53981c0e36d73caec888e3523633eaa80dfb99a9c81b2604c7d", - "senderId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU", - "senderPublicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252", - "timestamp": 0, - "asset": { - "votes": [ - "+0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252" - ] - }, - "signature": "30440220406d54714b6425ae4553ea8bec75f31fe52e9b1a9b6f6897151253ab7f637d3b022040a2df4b69840f4d9b0b67658c75efdae8d8269780d4cc50d055fa63922dbb9a", - "id": "c7db9d36d97ff0168d0d670ec695e1dc786dfb93f4081586870c8793b50e5f17", - "senderId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK", - "senderPublicKey": "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4", - "timestamp": 0, - "asset": { - "votes": [ - "+030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4" - ] - }, - "signature": "3044022018b7e51118ec83c985fa4eb3d7f0cf0655753bcbde7e82bac521665fb1c0ffaf02204e2ace460b2542db8c77e41d05d5e02fa5514b746a0a1e947256925846ed19f1", - "id": "c41f4cffcdd523f1718154d5bd5f4f0bec0376076b5f8dd340337e9edb4821ae", - "senderId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW", - "senderPublicKey": "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28", - "timestamp": 0, - "asset": { - "votes": [ - "+03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28" - ] - }, - "signature": "304502210088dbe249503da43c157485bfd4f2c95babfe4d0b8bbefe44afa52529b824a79e022045239b6a374fd9aca52c27171ee66b4863c956ae4085c9760d863b1902596c1a", - "id": "b1736ec6a1ea4c6d4eb278430a8ee214c88daefe296ba98530e692f8b7a7434c", - "senderId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej", - "senderPublicKey": "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d", - "timestamp": 0, - "asset": { - "votes": [ - "+02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d" - ] - }, - "signature": "3045022100fcdf750a775e728a31691a1b38908a7f990b579da510959cc2c63442f5ffde760220316ebb051d9fecb2486771dd39921fb12675b6d46b2441dd1db3c42fad0a59b0", - "id": "069271456015c2ff842771775993b8afc3404bc070572eeeb0f2fd72d58e18dc", - "senderId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U", - "senderPublicKey": "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294", - "timestamp": 0, - "asset": { - "votes": [ - "+0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294" - ] - }, - "signature": "3044022034ce8f77ea9d0f5cf3a9135d7b72d0ba3b96ac6d7eaa3670e9956aef2c9a83cb0220626d1f269128f673a23f9993ce00ba78a08103e697298be29a4c8ee94f204e3a", - "id": "9a99bba8340e7ad4e05d8424a0977ebbde428d31ee066c9828bd06b42bb42a72", - "senderId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2", - "senderPublicKey": "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983", - "timestamp": 0, - "asset": { - "votes": [ - "+02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983" - ] - }, - "signature": "3044022039ae1155f8b87a61c38b25cbbf30da6ecf6cfcc12b25c2e7fe576373754a41eb0220061a66a893129fbad5d48cdd19cf48b1a0d133dd2f3ecdc60ee7b87277e1f81d", - "id": "6c2c8926420ac269b50fa30127e0e791afb2131aff5821ca7aa80d38a0182048", - "senderId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf", - "senderPublicKey": "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964", - "timestamp": 0, - "asset": { - "votes": [ - "+02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964" - ] - }, - "signature": "3045022100d0dac2b7691aa059b1048d7925a0c5d5099f6e9b0f2e321e6d4f128ab1b3272b02207e8c4f643f8f9d1c3f81f0cce6a698df2da2ab71d5b01042766bbe0f46f4a775", - "id": "9259193c5de72276ed7a99f9d507dd6ea9856411fda521074fb41a556294fdf7", - "senderId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9", - "senderPublicKey": "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5", - "timestamp": 0, - "asset": { - "votes": [ - "+03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5" - ] - }, - "signature": "3045022100d5496fec447367ab6b53956a8c40cd8566e050ebb3b92d2c0b2a9d09bef36c7402205e32367605372375801f7b9db39aaafb46ee763b1494f0aca144fb91f3415752", - "id": "2a41e5946ab0773ca2334bba9d3510184bdd258f1c651ff8ec95b7b64a01dc2e", - "senderId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW", - "senderPublicKey": "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95", - "timestamp": 0, - "asset": { - "votes": [ - "+039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95" - ] - }, - "signature": "304502210099249695dc38826e04c8fcffd2570b98c43dec4788cc6a19737ed0872f17ec3302205301f645d803ad5df4ab1a700446e28c7cd76153607f6a2d68ae9168d46f3fe9", - "id": "e5c09b0fb2c24c57a4dcef0078953093800329ab4dc8e16a9d9f68215b5acd3d", - "senderId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU", - "senderPublicKey": "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a", - "timestamp": 0, - "asset": { - "votes": [ - "+034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a" - ] - }, - "signature": "3045022100f983b03e319aaa6c6ab6381e3ef8c0c035d6e3cc2139cedf70fd4e385393e38a0220286f73577765eb3e89e362785ad8a6de572bebf41bbc1f515b0ea93e41801eb3", - "id": "00b2c0455ef6f508d65f11bb49e3cfe1e6062d5fd153cafdfdfd2ccbf9c646e5", - "senderId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr", - "senderPublicKey": "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689", - "timestamp": 0, - "asset": { - "votes": [ - "+022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689" - ] - }, - "signature": "30440220103862ec51621ca27a0ec6b2817848e8824d2d09dbf7e6aac2f45aeea5d2dc9102205e8cce78b5cd7148aa4d406dc7b491dd7758047200e10cfe1e5fde5c56107ac5", - "id": "e25439ad11cb8db3d49ccb3b8b608c1bcb24cb29b2e5ea15101cce3e475224eb", - "senderId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ", - "senderPublicKey": "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a", - "timestamp": 0, - "asset": { - "votes": [ - "+03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a" - ] - }, - "signature": "304502210099241ced4a0fd1eb02f5cdcc880ae5f48eb3c7e490d4520c20124ecbf403893602204729dc6cacf3e87c97ca57c1be54d1e80791bf31ef022135e68fc06c950f6994", - "id": "1474f50815c6c7df41ab652414806d61abe15bee0d41f32d772f4e2793badce4", - "senderId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX", - "senderPublicKey": "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a", - "timestamp": 0, - "asset": { - "votes": [ - "+0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a" - ] - }, - "signature": "3045022100eccf81d44992c49a5ee37c6fc2ccc4b6bee9aa44888513b3e18e79452ede3156022056b0ddf079d2918d72e8781d3af009c87e6058563591dfd6ee0117b7df5534b2", - "id": "b394e2a8b5c2d20a72ed288408b8f0d48aed922edbee6e16c1c5b0e67517214c", - "senderId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf", - "senderPublicKey": "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f", - "timestamp": 0, - "asset": { - "votes": [ - "+03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f" - ] - }, - "signature": "3045022100bdb87894846eccc5a5473edaee1e6dca5f3469963e22f06123b6bde195aede0e02203d0c6833e87c5e60f4597ce624d4c2502a0562b4e54d943f82a4889e3cd69532", - "id": "6a399099bac6c74fa5e956512ef8b3a39f6f946d5d6996f192c2f1dd5ba172dc", - "senderId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv", - "senderPublicKey": "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751", - "timestamp": 0, - "asset": { - "votes": [ - "+02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751" - ] - }, - "signature": "304402200785771ccf1a6a40b51183a190d4cb4ce76b9ffd4c2c736d7724e6c667113d020220649ecfe73017d8dda96a7914793470ee7e582693e4866df123b1032194c163b1", - "id": "f20a831a6bae0a85470e308fb66517e70db479657459f6bb39f2cd1783c565e6", - "senderId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv", - "senderPublicKey": "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb", - "timestamp": 0, - "asset": { - "votes": [ - "+0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb" - ] - }, - "signature": "3044022020b79e1f07bcb17cae9485b9f44e9f583ca235da4ddd363b905fafb884347f71022015a20481b43720ddb3b1e3ca64b1f47e59b5cc2016a62f43327ca14533384dd4", - "id": "7a1285be87dca9718bece5b84266c1bf6801a39cc111d534e660aef9e6d26929", - "senderId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg", - "senderPublicKey": "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d", - "timestamp": 0, - "asset": { - "votes": [ - "+0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d" - ] - }, - "signature": "3045022100b1615d16763c46d42ca2aae967f04c1c07c119b5af7a378c262ba85515a8d35002202cf7df91676cd137943720e93f06c11907412a6bdc5ef2157cf536a203cf83a3", - "id": "76fb5a1de90f245b1eeb79cb11c7bea7c8b738add0fb8cd95191186a944b0229", - "senderId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri", - "senderPublicKey": "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a", - "timestamp": 0, - "asset": { - "votes": [ - "+02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a" - ] - }, - "signature": "3045022100e3c7b5d6a72acde4d22e8c1c6cd864c549deba89683f4b84320407d6c380827c02202da57df0ab7cd381b776bdf85802aed371e7cea7269a84f911b1d8e9956badee", - "id": "8da75c8100e6248ab37cc92f72ed9facec3067f4f82f03db8bb8063791463fb3", - "senderId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t", - "senderPublicKey": "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe", - "timestamp": 0, - "asset": { - "votes": [ - "+03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe" - ] - }, - "signature": "304402205779b5d8acbfedfc105fedb6fcbd4636713ed27605faa9bd988598072640a958022042d8a8b3d7910c7c385f3707a317c5d445d56da250f8d127c71df2d9d4c5d86e", - "id": "fd26e265be88289828d0ce7ffc5faeb9849e1f4cb37a8f1dd5d6fcc436d910b7", - "senderId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf", - "senderPublicKey": "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e", - "timestamp": 0, - "asset": { - "votes": [ - "+034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e" - ] - }, - "signature": "3045022100e18a89fe1fe0a8acaca2b6461314e784ffebbe7374f6aafdb06934e83985ccbf022027314b21a4a25b477bd7cc070b4e00ef8f3d69f3f1af028b96571dc245924c00", - "id": "41d92e128e6b8367cbf8fd111e5263d52e1abad553653f975dd60d7f7c5b637b", - "senderId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9", - "senderPublicKey": "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9", - "timestamp": 0, - "asset": { - "votes": [ - "+02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9" - ] - }, - "signature": "304402201c614c84dbae26f87973c9e2b38df883fe0c8c469080e31fe32a4c4946d50b67022075b8fb498fb1384aa6be785845da02813185ccf095597b5782618033828af4d5", - "id": "1e4a1f8aab6fbf8682c2b35e0d04e9e007ae717ce3f4a82894747e5807e3c759", - "senderId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV", - "senderPublicKey": "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca", - "timestamp": 0, - "asset": { - "votes": [ - "+02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca" - ] - }, - "signature": "3045022100b1ee6becc59d594776a40e5b3caec82390d273b703ecb0d7caece44953141449022016543cc29a28882845118afab6e51296cd216bc662260c28e5efd9597b6025b1", - "id": "2ce068bfccb3f967f4004e9a1e81614a738e55e45c80114c0af30a085f71a2e9", - "senderId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ", - "senderPublicKey": "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c", - "timestamp": 0, - "asset": { - "votes": [ - "+022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c" - ] - }, - "signature": "3044022036698a329d7f5f751f91ce02bc188a7527a377d01583b70427cfce64def945ec022079afafea10aa32394a1e42a80577de3869856656221d5f259e05fb44f01668b8", - "id": "3478d1ad3655e10fcc864f191972322c866616866bb1dbf66d7b66b31cd95de6", - "senderId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA", - "senderPublicKey": "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24", - "timestamp": 0, - "asset": { - "votes": [ - "+03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24" - ] - }, - "signature": "3044022035fa7be80cf881eefefc12b11de04ffb2e2e92815cf05074afef54a3c5b2eccb022041f3347f59db0b3caadefcbfbc5ae275d3fe3e2a52fe1504b23628d4b79a43bf", - "id": "8adfd8e73e96188ed9fdec459d88db1fb041a2b25b3f64830476aec661ae5010", - "senderId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm", - "senderPublicKey": "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f", - "timestamp": 0, - "asset": { - "votes": [ - "+021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f" - ] - }, - "signature": "30440220630da8a73979bd3988b7f84fe9e83a429cf3239f54c140c3dbcc407140513fc002203664ad54ed9f199f2683479b988bd97ad8fffb2c2d5dfdbdb10858aca4abfaca", - "id": "e306328ffefcd9e3809e7390a358199a62cf8ef037d57af1f5c7b54d728d427e", - "senderId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1", - "senderPublicKey": "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b", - "timestamp": 0, - "asset": { - "votes": [ - "+02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b" - ] - }, - "signature": "304402206f1df93f299ffedacc25aa201807df47d32c43369315cf9db280963c357be56302206a66acd553710f49bbb7b803a2bcb71128c8e617ffce66b37b7c968817349247", - "id": "dc69bc8f78502ba34655ed062987788939189709a4112760cd8807245d7461f5", - "senderId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8", - "senderPublicKey": "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12", - "timestamp": 0, - "asset": { - "votes": [ - "+03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12" - ] - }, - "signature": "30440220629e696a10e04d4fbc10a5ac443bf9bd40dd5d89d4b214224abe47d7ab5600340220643f361a24d9916e2c5aaec7bd7d8a6a0d3ffc5fc0b62c3ac4906eb799a862fa", - "id": "c3f49fb80c40f7779b32ba23616f5573a6ba58fc60c4629c2252933038dd89f0", - "senderId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2", - "senderPublicKey": "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904", - "timestamp": 0, - "asset": { - "votes": [ - "+0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904" - ] - }, - "signature": "30440220660f9604896dad2a97820b0d7524f0bce5a8b5766f150517d5061fd02bddf768022055e87c25891d4480e66e5d1a71e42cd5a4bef3ab2b2651cd72d44f30a4b32309", - "id": "8e8ac1b1a586e86867abbf25d63387bb6dfb793c691f0b06333c1581a9a568b3", - "senderId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT", - "senderPublicKey": "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c", - "timestamp": 0, - "asset": { - "votes": [ - "+034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c" - ] - }, - "signature": "304402202e2ad64129f61ef1156c4c7e80ab862d4823d62dac502685f53028536ddfb41a02201a3ec777fdfe8fae9f7cd5251fac322c1b6a2a4d41b3ec456daed474986d4872", - "id": "ff73565c373f2cefebf86c72dda3a6a6205750eb03b69178cb83378620715e1d", - "senderId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q", - "senderPublicKey": "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd", - "timestamp": 0, - "asset": { - "votes": [ - "+02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd" - ] - }, - "signature": "304402202e5c78cf21a088db10e1e1f64d98d84c8d3294fde7bc322d4af06bfe99d4c2e302207e7912a16a37b641a9f8c7c722f2b0d699917ca73e4d0f21584b717fb7f02f13", - "id": "3822273b496f2e253081cedf382e4f9937713fabb83449e1f892377cf536e68a", - "senderId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo", - "senderPublicKey": "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647", - "timestamp": 0, - "asset": { - "votes": [ - "+0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647" - ] - }, - "signature": "3045022100a65ce45164c9bc3e018e26703370c9deb2933ee3b4e814619043cc37c4a39c4802205ae4931ac9e8dffd714c3b601fe248a49c0185c8367887205f497d951c52eb54", - "id": "430d6db0b87c25dce4ce14ac907c13bcc6efa5d95135f05aa4ba7596ea9d400c", - "senderId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN", - "senderPublicKey": "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd", - "timestamp": 0, - "asset": { - "votes": [ - "+036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd" - ] - }, - "signature": "3045022100f3cdd7f688ad2d7b6a5b9cc7e793cb8a6e6e07d3327bc67add64691a53fd2911022026ae1adc8f4fcfc01bcca3efc83019026755b443a504265ad1f46f69d1f5951c", - "id": "dda86ecc0332e6c4eed1c0a5af7424374089b85dd274a300fed51b86e2655587", - "senderId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj", - "senderPublicKey": "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564", - "timestamp": 0, - "asset": { - "votes": [ - "+03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564" - ] - }, - "signature": "3045022100d419072a752acd55792257c96099fb14c56c29112a00535d39bca96fbd7951c902201abdf4db247dc956d79f4543c389823fbd1a9337f95d30df39603a3b52486bfb", - "id": "0998e9a055c53bf6697ee76af94c7a830c1364016d78fce889a21bc38ed70cd5", - "senderId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN", - "senderPublicKey": "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0", - "timestamp": 0, - "asset": { - "votes": [ - "+022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0" - ] - }, - "signature": "3045022100ba1e0ab761326d2a53cbda2a4a5135033c94d8166864d2ad3ceb963b4a0c046402207d755ecf4ada9fa2a598fd75e73a59d30cb83e01f510020b48b6bf162dc60b27", - "id": "be13743deb8486a575d1fb564d2b07d797ac77148d35793c9aca43c0d47aad61", - "senderId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA", - "senderPublicKey": "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b", - "timestamp": 0, - "asset": { - "votes": [ - "+03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b" - ] - }, - "signature": "3044022038a491e2e13ac32025209d00aec1af31b73a8b6ee77ad9b8bb80a34f5df59dfc02200ce82c89fe9f88bd5af236ceeaa80f9954e3fb4af7bc884c447505751d49c134", - "id": "f1d3d44cc289837de9623cba8891a1ed1cde8918473a91e2daead29975afad22", - "senderId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx", - "senderPublicKey": "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc", - "timestamp": 0, - "asset": { - "votes": [ - "+0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc" - ] - }, - "signature": "304402202ae599ce389cd030b8ab48ef53113458b9ba8bf9c9ed09c662eba2849bf540f802202ed63f8af492dd0b67d1b451170a989418a42466a3a7ffe89c4c5a18337e8fb9", - "id": "65ab302a44ea7550891eabc3b4a8d5ecbcb80784c4666195d5d0b7e33394300d", - "senderId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK", - "senderPublicKey": "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565", - "timestamp": 0, - "asset": { - "votes": [ - "+026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565" - ] - }, - "signature": "304502210088a3a4e82d307c238e01ce154b57631d4429e0b591e828ec36839a783736e842022042c6e1d719781e2edca3dbfe84ad13b9e490821a47ccadfcff379decb9c873c0", - "id": "d26a7ea56f398634a81086bb15c2f0c863c71b8bd728304d324d8245a8fb6c73", - "senderId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz", - "senderPublicKey": "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374", - "timestamp": 0, - "asset": { - "votes": [ - "+032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374" - ] - }, - "signature": "3045022100ae5805541f085a50076835422b2581d3b7a128a05b4f068ad7e3c14cd02799b802205f4bb40e06f90e02282ae74c0aba97923e601fd78234b9585468c4fb73f47893", - "id": "02504eae7ff4963c081219523bc48d7a07de4c29fdc1622224547f9a7c133abf", - "senderId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp", - "senderPublicKey": "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93", - "timestamp": 0, - "asset": { - "votes": [ - "+03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93" - ] - }, - "signature": "3044022078d38cabd8f427ef381d0aa6a0b98c6a590cb18f47acc1d80b429a1c1959b0ab022022a70d4d93d650ca3121dde6065e80cd90d1e2e91cb90f0d0b2eadde609e0d75", - "id": "addb8c1baa833baa52a5b51d8a86f8524bde826b5c9f0a99e57070e6323e1dfc", - "senderId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv", - "senderPublicKey": "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17", - "timestamp": 0, - "asset": { - "votes": [ - "+038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17" - ] - }, - "signature": "3044022076dd065e3fba825b77884a179d0231d7fc9e7d3a02e34bc6565fab81a84e559e02200a880c028e690a9d6f2c4c6576b1bf3e913817c834da8ec6afdbadfae78d341d", - "id": "72f31f9a829b93045ef2e860b24c33b9be6a2621c26914acd42121215c1d517e", - "senderId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P", - "senderPublicKey": "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1", - "timestamp": 0, - "asset": { - "votes": [ - "+030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1" - ] - }, - "signature": "304402205261d9d8ded6364fda8b10bd477982be84990cb010f9214d52c492676814e1f40220489f441ffe2478d361a12ab96caa59da495fe62d61d0e2255aa5ec4ed789afb8", - "id": "1f17b4ba072d205761ed3f786491eaf684ed3601b69082e487e568aa74a319e8", - "senderId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd", - "senderPublicKey": "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d", - "timestamp": 0, - "asset": { - "votes": [ - "+02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d" - ] - }, - "signature": "3044022040219da41054a3eebd3122df7f09a62a4e8b4fdc287ae77221f2217b42f291ad02202b9a70c54bb546a604eafadcc086ef6b6570f57542374d87de02ad7f61fe51a4", - "id": "5fa837023159d6a3d6cf7c5b2ed6fe05ff7df19300226b2f0be5a48a06993780", - "senderId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo", - "senderPublicKey": "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37", - "timestamp": 0, - "asset": { - "votes": [ - "+03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37" - ] - }, - "signature": "3045022100ded426768f114f459485ba6ae293c9649b340cf2dcb15e8e887fbb5fed6f7e0b0220752297022de6e93ff64bb9e07b4efef8e946cd2872f84d9e1cb3165ff5c342cb", - "id": "0a16dc31514629a36d7237968ada6a95d6cbec027b7d26e1e0f0d7d4febe9494", - "senderId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD", - "senderPublicKey": "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a", - "timestamp": 0, - "asset": { - "votes": [ - "+02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a" - ] - }, - "signature": "304402203aa292e7aedcd62bb5a79c2521b666b8e1886b57923d98f51911b0461cfdb5db0220539657d5c1dcb78c2c86376da87cc0db428e03c53da3f4f64ebe7115998f00b6", - "id": "8816f8d8c257ea0c951deba911266394b0f2614df023f8b4ffd9da43d36efd9d", - "senderId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD" - }], + "transactions": [ + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402205fcb0677e06bde7aac3dc776665615f4b93ef8c3ed0fddecef9900e74fcb00f302206958a0c9868ea1b1f3d151bdfa92da1ce24de0b1fcd91933e64fb7971e92f48d", + "id": "db1aa687737858cc9199bfa336f9b1c035915c30aaee60b1e0f8afadfdb946bd", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100ffff4e9ba62e5e3beb37deee052824da83c4030925bce09f190151652d0669b8022056a432e56a2e1b026d4b54f6c34ce88a0c9cebdccc730659c03449fe878c66f8", + "id": "0762007f825f02979a883396839d6f7425d5ab18f4b8c266bebe60212c793c6d", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022001a6326e5d1eb06d0ba1fa39446bd6d56ea45f0c269ebbce5dfc6a649277cfcc02203b252d3a6ef2b22349d9d0a9110ce28a199c39dc8b911edfa82c297a02009d07", + "id": "3c39aca95ad807ce19c0325e3059d7b1cf967751c6929035214a4ef320fb8154", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304502210084d855eddfe616cf1dc238b19226c7959c2fc4027ae2e8aea6fd8e9eb8928e6b0220440f980e40c1c56348782fd69d49a96944df7ee5b68d18028600e0e7501d4000", + "id": "9fdf6ae86f7c005b3b7dc1b9fb6411219407ecaa93adff85fdb61710f5121638", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402205438b8b9058bbde5d30794e7681e400e52b5fbd22324c5b6b521f97bc8b8aabc022000fe04d7afbd2e668b1d4576988ed596dc92251e33efebc081e2cba14ad5a898", + "id": "1d7c68087c875d7ce555b2c3e71e1d91a1ad62d0c2497efe3cab91415e634041", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100b2e634a95b011a68489870f003e4bac4a4f0578bfdc6b9f645c934016c2c0463022022cd4ebf276dd627d98be4b697bae2df10b86d94e984da2eb7e011b08d6dffd2", + "id": "0c993e115ba26981b0be9d22e7c4a13b0f106e0cb472f9d34eabfc8e414dd528", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100f965e5c280acb22d1cde405223fe9a6fcb765844adbc5321b17a268924e1f597022043d31b1edc5fe0cf60a960d84e3528472cdf34560c9463979043a409f37e7f29", + "id": "c279f2eb1f9e6e7d4b0ba7a98233a0f1a2536231976c99f56f64b248eb06a0c1", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "30440220715463c316a75959dbfb6a59a013fbf914bef1ff739ac8000d49dabbf5118df9022019345ae1c34173dc214bae82f3cfbf438092f0fd2d277acafe3e9deb644b1a3b", + "id": "7e2fc9ecf23e909a3d0fbecd615445a0eed8c2cef18e01b1492d63f616f5d87d", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100fdd8aff26dceeb5abb6e5e8a8f468c8ac1997a587225298e3d8135d57dadf4dc022072ab80a81b301a162ed5cfa67d213d5a3980185088632f5f592351aff8aa0e9c", + "id": "511c0e1076104743f98932f8e7720bdb3f1539134edadd331914fd9ece1ebede", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "30440220635e04ce278870f17fcd1883aa26c568e63dfbdd302add39aa30fd3637c79c2c02206fdd9e7b1f4d238a97d26ef1758927e2d39f121687490f2bd79831e36afdd43b", + "id": "0768d5016c53d884e3d68a09d1bab0d730b7067c71ef4ca1c4d61b3815f5ff66", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402200b1dac57ca6565ac31afb99686f2e0f0e8dc219b9860b295ca5444a1663cecfb02205787393561fe407449af4aaf2f621db9e4d3f11c7438666cd694d495c0a0c41f", + "id": "1aeb50080ea118165e5041f7a897974c2ed1ebde08add85dc78cc7cf73566a91", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304502210098dea25eccf31ce6f874a9528578805aaf07be8b41f1571865793f9e3e6e3c97022033ae9c73dad44c01fe6362665fccf63bb1a0ae8e26f77a1cf60b67dc96b05343", + "id": "254f0f4fa277cc651a746d6ac371eb27afc3ea155ba060552dd26b8e83d17b72", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402207f4bf346aac501e766156818089fb16905a9bdca69ff6d5a55ba918a08afc7ab02200ec2c25cc4bb30e2c176d55630d8e2679b899c14ab4ba43c3d62955dd940425b", + "id": "e5ebb02e8e8a6708e22ee5ef99fe1dd8b6eea1095be6b772aa21bf63cf7ade5a", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100a0bbc15bdad648bb9b439f1d34b12b853442d1cfd4ce7f569905082801fa58e8022036b4e73edf7ab7226f8007233f77b1d497cb6b4736f02721bf1b399312ebe114", + "id": "8a686b21477b64dfd85f08f8598a0f121ca1c7d65ccaca9e42326c75fb5f3abb", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402205d77dfcde527dcc6669bcb01c27b92c1a6399e35ebac9e69415645f596ab1d2802204179497bfd952f44d5f9e295b2a3219a290a4a82841c084a18553b7712e26415", + "id": "21175347e2acfabc09a7593aae0682e39fe7152199a90561c11125f525211243", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100cf77c16df9185727ff717b71a94f8b29ceeae1e5bb3a28da8cef9df5bc63b7c202207bca394ce9ebd344a548e5a5697f672dedbef640dc1f9105f7c063287bcd1840", + "id": "ce1d9b7377551f36568127f5b635b5443f5a58abba6566b50a8d4d7b53c8a874", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100eb8daebb5484f3b0a738c9344fb28298c596f9486963f8fe36e2501ee6876f2a0220559df66986dc9a9a8e76982ef85f907c62745757990c69f0b17b6ae5a7ca4719", + "id": "b56702f5eddad0d8dbbb33b6b1ca3e07e4740def9c5dd2aaed9a70b90a4e31b7", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100d088e9bcd78978f2d67e7c7bccecfb73ddd0d1a2dad5b039390812320355722d02207affe83d815f04f6b11abf98eebe0488bfb87f8cd6513d44b829008ed1c15ceb", + "id": "a73c053c42e83a83498cf58e5b077b31443e265ddf8228081cb17a36bba366ae", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100db16a8e9682f07efb607bc7c75b654646ff449761ed146ab9358e69d29fadd7f0220436554ad78db0e04ae5b573258e2c8067848e89b55a6e8e1e25011a43882a643", + "id": "2dccb8b44ad2e598673628fd9d74e336b467a0c941d5e257dceb85c8e0a0000c", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100b03738eccce8ad0b8ac0a656119c2cdd202089c5650d8e1486bd13eb9c3158980220059079900c7fdc16e799c50dccc074726fbf0068044462faabdf1e73f9f9bc38", + "id": "b2cce30021d139f97925807da796722bf4d5459442523823388c259ca5ad73db", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100becb49fe5edd6806d5ba6eddbbb34ca8eaf3a12dba123d1610b2b120ca8bd017022072972992ee0ca0f319ae754a2a5a10d715a08b23f8239f9d6d59774f790543ea", + "id": "9e4841f43ab355be7a4f93b09f3d82c17065fbe25387dd6c5eb4e2692ea05b0b", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402207f1a3fe8c5aa7a77a58ed35c34f128b5df6fba89aa918af35eff432be7d1f8e00220460d4f2a457e1a477974157e33bf2974de6588d56e59729ae980720e9794827a", + "id": "2c7ca823be21724a4876de632dded3b9afca45df357819ed028488128d85d29e", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022067266dfe9d8f2550b590e1eae2f73d28c6b80fecb24c3eb1b4539bc864b3b4f4022031e5122145c35874c0c48673d088e76fb3e11c308ffe9d5dee6431d3441d627e", + "id": "a91119f04e2201184761f7fdcb26e4aa81c7e1076cb11a58a422d351241d4e4a", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100b970ec89927de0cb7805e614a742d42c2967db5a9c68d0892956dc89d68ca7d1022067fa30265dd2e1a2985980be2bf876748a7a8c7f3cde0382265b601fa658dc17", + "id": "94955e6bac6269fbd19e92d2292ac947225fc6f68c6216001b528596a961040c", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402203671b82ddf8a824b8e5aac8bc28be4aef1c00aca1097d14ec1a55003d7a3f28d02203aacb6e7517e916478432b81399828ba7425183ce0fc43feb361bcf345fb0519", + "id": "df563ee9822bd3d7aada600d4800952743ec64fafdc7697428d7a19a60745885", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100b77653317c93eb20ee19c71e64a7f9ecb985351bfb1fe351ac65a5738cb37ae202203d540395e1d55f87caaaa867afbfbaf98c553be0b4c7d1748418a76b0c258c89", + "id": "d21b6341e2b4be5ffdc3dd8fbcdf2c576ba02e2ef4ab5eab0e4bfc9da4e9e442", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022046239e39062a58925099b005888355b8cd6700af66972bf509a10123f9abdec60220202321ea74e56177606fc079d19c29851d832e6d00c93985ffbec3dba6f0d675", + "id": "df6bc7a17ad34f8e9faaa2646e8e5dd8bca35affba352537184f690e200e17b6", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402204eeab87f7ecc2097b85606b986177964f3ae777535f6fc0cf08a55fec587d87602203779d59903b8de63511e4ed0a7967bd85e9cb1fc9d84bbc5091e3caa87d8bd52", + "id": "5f0d5f0dff464d0ad587da5bc93e600a8e2657d359d0a1224bdd4ccc3b6f376a", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402200a2b9d0f61066fa00a2a2882379aa8ee60e949bdc2a85103bbbb69ce3eafccd9022057364f349faceb3047fa95ada210c64fc4a81978d66925b37d3dbc21ede885af", + "id": "1b39e3702576e6ad7775e34d53e43210549d52a56b3f246031e6ba4121a66bf0", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304502210099e568d3d0c1b48410e0b85c74d04234dacfb2fdf2b1d4b51fca1cfb3445347a02207a2509645aae54560762a37422b66ba4b3ee1c42de35d58c36d2f9d8fdea11b4", + "id": "0f21e53dbb1edb1cfb4c31bb675aa4672b452a03ec363a2b3300a9dda49e3be3", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022026cc5f2b588a86241badca73cd9c1686916d516b8c6c397c66a9d5bb6b5d4cd402204ab5a8c8589ee954bda4a116999d2a0e4ab0e3e96f0c7fe131d7c57b9a1ede43", + "id": "410826c255a23a78ac5c3aa10dd48132693bc955845af16c20d9c6f69b05dfe9", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402205fedd8d3b5c8d69cdd7db5ca8e9e7c5004f6ba751e45eb1b85b26d9e89800a2402202be56bb2cd824bccf325b6b11432bf6d0ddb5ec97fcc121839ac2ebf884c7173", + "id": "ddb57d8270b2b6c876191c1e1c5974388b9fb3ae0980cb2245d8a7c426237f47", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022053cd42ad147eea33801b2b57388b33f633b4bfe2ad902190e12480522250d07802203066dc0d0c2ffacc4c74cca1e0187fbea1cef7e78a78666d2ec7e4e87ef546eb", + "id": "29e1aedf98935c369946c8dadb2d6784f9ab5ce8d73b9b4de2466c7757e2557b", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100c10448b87e7176735c8ddfc8fb3c4d5d55c2d71d18b7ce3ab321209ec299fd41022013517a09e4b366ab386698286ec7bb20410bdfb7f6674fab25a739259083b297", + "id": "4cf04852529b5525f22cc540790e36e61ed36045ad1b5b788f61ebe42637391e", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402204cc1588b204ebc0c20f44a31ce53d15ab5e4d1f9c103c02dd4e4eaa1c33630b40220194b6e427b6def0783461cd8d765f97b105d048942be468be2ee9b0a2785d2ac", + "id": "35c6bc3f0799d9c79efc6515f232c58be0d03a3a797d066cba879eef4afaae2c", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100be44f7ea12e2ee89245fb474643ec6c2c75afa00276826a4ecd6fca4cad5ff30022071a2c083b353a821345e4bbf74d98db0760b8721856572572cc3436ebdb8f08c", + "id": "45f75a349f3b4d73434c0f2ac9c291d5d07278b79e6eaa0d38d6e005f66c4783", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402202090f506e8f18fde70b87a3fd6c470a23e9e262f20ec6268dd59b6362e51a29202202b838c598b33c6317c998dc179fad2b660b8a72bfaf8223d7cc82414ab4c6af4", + "id": "a8d9034d1091a4dbe595647ad5f64ca8b243e7842301aee48f7eaf8b8ae98119", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100be59b689a48e198267305f1ae7e116f69f7c360857ea0b1fa81db122278cad69022033436d24ec0103674522f0c559e2357f8696bd498deccad2e0f66b2cf7469538", + "id": "061cb438ba1216cfd5a0f268ce18e6f280557bc944d9aed3655e2bc5f08bdf51", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402203b5d2aa7c4554d6d2dd6723043350df0199e6e7bbd9f21a1a20dbba8c63918cc022014a78064c5f9c5e2f43d3be36de2b5e2f17e9af557bb6c75e8d82d9f725d0188", + "id": "239f0640ddc3170a737ef349c07cb82b2493d207421b6f71b6b3dab856f16088", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022005eb29ad4cf79fd4f6898de19459e15cc816acb0975e53530a202e69c29d0d4a0220686cf6e0c14779d6d68dcb9d16358c0e859094d2eec8083598b7bb5869478bf2", + "id": "25d8eef755cfee7cab0d7f9fbbea0fad6d5f906c432d997ae8ef1c49d23735f5", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100b93096a287d59545fa3a08593dfc740d9d47f3cfa3c4bd3c8ff8ef53d3a2e957022027eda62e47220774cf799f46916195e5a8b30015c56ceff4f4a1c10a918e3675", + "id": "aac25996e3be809ee88996b6b4063e2097d6306e77a067de8ebc8d7076a28d43", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022017282aa4fac7b18e834abc3ca37b2f60cf989c26b12e2f2398a66cb907015a760220428218d39db812a22cc138acc7d5d4d2d5713f0546751c02d2c3fabecca0e724", + "id": "b040f86b75750b49c83ca7eb8f2a458f16b44789796ff306c5f942ca5f19164d", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402205970d53cb0921a62bbef540dc33189b2313f3574e44f046097067e6991d63b1102200a356c87642cc781df661a1fee21cce354a144463d37053280e000e1b75da7a5", + "id": "25ce96f951d7b7d886ef487331125b3413f655f9c5ee7fb4691a728c3cbce18f", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100aab0201c9d9a9641c11605d32353685cbaa051ecc276da1e6a3b309be9f20cf7022067aecbc7329bdf1770974e317a1243815511efa8c7af7801217a83c96d86eb0e", + "id": "285143b8b19cbde7c680b0f62ef51293e8f315c823ffbd97608c38c02045d831", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100dc7752f6f8acaa3a1ee2ed1bed306ee04556b3866db92a1e770c4b970c7a932e02202d137b312342f9d0708704833b26b6611d0464c87df97049ad8b616483e9d1f8", + "id": "87b06fccbb63809e976b3405cccec2eeaa3694d5510203f04c0e60bb6c2c0020", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402205ccad5c77ea339f5e3f2b7900b4b1c409d3c8204273e89b6401314fb61f0d224022026a63fef86356de64fe571ff8488a951dcacab56e980fc044ef9f43b9d37439c", + "id": "5597ed52e4123756bea9307c09c916ff9d0f9fbce8d2e9a3a2ff719a87ad0966", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402207c91153f820f34228bec62772e0d78876bd3277912eacd866fe35b5c86a316c80220104529c6f786cb387ec1e3d5826271c837f0d0a6d0fa5731b9a5c6663cce7108", + "id": "d46fde78608fcc668246cc35336210b3c167ba55c82e91b0fd99df7e36872130", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100acc0cf119c18861d3683bb3b0f6e209f2d62acfdd958f86dfbd35137ada814320220448f6f8adcd46204629b45a4a06f5dc7ccb4dbc2a1d702e107d91053847adf2f", + "id": "aa92faf5d80459b4e058dc8a8212608b589925052e22148384835ab687a4e875", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022055b6bbde5fa886db3cf1224a59f1fb43e850e2d9237db593368e1043698fe2c30220067dd20195e794af4152f1ff9e3ae4261698a86c54803ba1890bf176d97844d4", + "id": "432e67db0d5fc8c66376aa96c7324e5a1e6d00a415a9c8898b5e3bf25d8b083d", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "30450221009d6f38067264df8497d6888e4a8c316ec58ceba8a54c39ccb0ce261d114fbbab02200fae3f2f950f5c5e3387679f8ca341ec70cd90d0e32a30112f03cfb12cd9fc23", + "id": "9321e1b08faa544f592ad8dc7b60ff1cf845efcd28fedf8b445be3bda60434cb", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245100000000000, + "fee": 0, + "recipientId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402200aed5a4102bdafda00fda575294f149b393a798c510af8ba877b8c2d7ec8051e022004f7487c4f728c633aee5baa62ab0017f4b91cf2f494eb1c4cc9addc3e9155da", + "id": "0bbc9340798a18a81109bdfdbee9c9003f20a586dd9f80a39507c84588c1b4b1", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_9", + "publicKey": "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647" + } + }, + "signature": "30440220072124721ba7c997f7c29ad3d4819515fae7a67be2bc395cb73f114eb8d4abe60220523ac295e114de30ce8a4300f4670db91ad2abe1268460e6ad3463fbe9834b84", + "id": "d2e70f9d2de57240571905aa81db0b6883e27a83be2422530722d76b56e63ecd", + "senderId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_18", + "publicKey": "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a" + } + }, + "signature": "304402204b93b06e08e71e3317f9426a1d3d450d6293fdbf5a6b3043fce27b3ce65431e20220683609720ea1d7d921238ca8b5098d3d9c0caab7b1e26efe42a6aebbc095471a", + "id": "8695bcb906f5fd81d858794f7d90447aadaa38418d312e33115a81e856b34d12", + "senderId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_47", + "publicKey": "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd" + } + }, + "signature": "30450221009711559a43005c808113a1e9a01b1665495ff4bf30d635f7d98c752ead4cc3fc02207879e2a939914effe2b5c80cd515c4b3ff77a071b707c85c4444481878803db9", + "id": "55853d2d2a98def00c5ab842866a44d1db91678a07b6dd63d062508db28a00a5", + "senderId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_5", + "publicKey": "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565" + } + }, + "signature": "3044022025ba51a588253524557547ec492d71bd485fe5b291e60eef681c39eaf8ee781702202bf24c3d295c7a2c9aed97a79fb835506797dcfe7e7a2853e2578e7773c7e134", + "id": "553298aadf692c9c5d0334c307dd4ac0e277a49ed165c97ce1362f8ec639ee3f", + "senderId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_19", + "publicKey": "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb" + } + }, + "signature": "3044022041291ba10ad30fb9ebcb0e13902e92d85e2c3e98493b6d369d7d1e70e8474e31022009083444460c415eab6b4beed9e0206eb0733bad5d2a476af4db4f5b5e74b835", + "id": "90af927db7b258538c8e21116b5a31418c88ecc163628b2b65fac92a5a949b14", + "senderId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_42", + "publicKey": "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d" + } + }, + "signature": "304402205d4111c87874e696b8f4b8897d0dfe68fabe4ad5c5769026c6ecdd04f09a1e2f02207b9c8a2a16b50164215eb1efea6d5d9f4e693cbb7eec8535e526cf8ba68bb796", + "id": "8a920ebf5255a102d0c9c5fd720e0d36a6a3539991a2267442facf1fea2d0b86", + "senderId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_10", + "publicKey": "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd" + } + }, + "signature": "3045022100f15ff048872020d9efc561b8c837f542d54d43b9b071f7a6cc09643c6d4180f002207d0e82153a30b66f43fc4cb4b9b3093bb3d5dfd70f96928c8780c838b1448c19", + "id": "30738f376aa40fb3c8d8849a5dc698786aeb1409fa801c18729f8da624631391", + "senderId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_20", + "publicKey": "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751" + } + }, + "signature": "3045022100babb7410d09215def98078bbab6b5e5690c2ebf54960d94527226ed3925877320220342576d1d8fd2d2fe3b6974cab48a2e16b4813f022b341b32f88e13f572bf060", + "id": "ccbe1c27eadc1b3b33f3f87f645be4f756021ee3d4c96f4f094e1f82d5728a3a", + "senderId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_49", + "publicKey": "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374" + } + }, + "signature": "3044022032f2c350cc1319f5838d6880e91b49ae0438fb3a626ed9ab5e27ce8788e3347c02202cca18567c8491e0feea8a5f078e28605029346c509fac0c0a192e934f8c5326", + "id": "f99af0fbb4d65c2c3f2c1c558f0c0c0eac2724942802fcde02fa6da1d3a9000c", + "senderId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_3", + "publicKey": "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17" + } + }, + "signature": "3045022100f0cb5d885ddf3bd4a58837f9b86486da4171652a5eb39228dfd0ff9d34d9c7c602202dc6e3d268d745a7e8633311a337ec097382342049672880c7c2215cf58e5da2", + "id": "2dca03aed08533585d8bc609da5deb9f17ac9be5a8352769d7ae63d0db16ff59", + "senderId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_21", + "publicKey": "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a" + } + }, + "signature": "3045022100999f19fbdc9a12eebbb8c748a4cfc6c91b2233f333a09cddfd49dfeab6aaf38602203d8dc9d1551d400572a88ee812f51f897f8b35508713b789b2c1bf6dd0e88945", + "id": "5d7e51d57b5914ec201ab65a019ecdf651c4f267cbffe403fd2170bb95145f9d", + "senderId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_41", + "publicKey": "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f" + } + }, + "signature": "3045022100e86e648add940a1e637e32ea9187497c281b843da09597e62d0c927d7f43235102200479f64ae63abb55e338f9ce1073a5c46907f7a2a82ea6f9bd9bc29811683515", + "id": "eaeed4133da26612c53550b6572722d8c3380d0a2344da1bd270eed1ea91fdf3", + "senderId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_11", + "publicKey": "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904" + } + }, + "signature": "3045022100bc3b2ebc58a92bf38672206e8311e7ef0e54912abce7338155b11e7d191b0b5d0220765a568c1fa4665c0ace6b4bd3b7ba0f8329e2f25af7a3cc0d78b2ea398084c3", + "id": "bb91e78e43c59a19ac06c015d8a7ef09d7c5b274c9f98505e5a978027354b71c", + "senderId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_22", + "publicKey": "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a" + } + }, + "signature": "3045022100aae4868ab75a33e4e77f9bf6c53b920c5e7c523a7cfe271d1afc472655f3d6a60220499f1bcb79bc0fa830dfa939898db5c9fa8571a2788c8de0da7e550bfc818bcc", + "id": "a6e687647dde9c1db68690090afc4fcf11833dd35fff3186b6b709a1e7d24260", + "senderId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_46", + "publicKey": "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c" + } + }, + "signature": "3045022100c0cf1fc54705c13f70fde39c55a1703a4c612b8a919379cd5b1ada464c7cc8de022074ee62490a184010ad2418d3177ff2ab03d02d2589000176312b90422b1bd64b", + "id": "70262b0eec3ab5a60a736eb8a628cb600eae7522464a49791c0bf26e82318ec6", + "senderId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_6", + "publicKey": "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc" + } + }, + "signature": "3044022045db446b109215c6d3dfb0ee5869154a8a7624376c3760eec4fadc75a29033cf022003e524d64f3ccd0c6de4ca80a7327e2c47ffd16b3ad042bd25a02f5f64500ab7", + "id": "56048c449694964bee3d367609a7bc46c8da20f66878c09c01dcc53c3abd932e", + "senderId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_23", + "publicKey": "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a" + } + }, + "signature": "3045022100f8f69f2957781ed02d64983744c8e51fae613ebe5bbb330d4f509bdcf4fc6b6602205568ad1fd840e01ec26a24ac9a0ff093e978172da55d494138d018a45eb67893", + "id": "e15dfc4e18106480083b3c6211349fd9c803e334e9ba5eb62cca19ae3f57d8e7", + "senderId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_40", + "publicKey": "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689" + } + }, + "signature": "3044022021eeb9e1db8915a9adb99db72972cd17fc7b5b377fc532ac2c9deffcb2707edf022068b9e08f45bbebad89295f520ad40d7786fe64059d45df95551576e3acb736d1", + "id": "2bd0f888ccdeeca24a0134e3c1bf729582d284f32ee000d97f1417f1349a6594", + "senderId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_12", + "publicKey": "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12" + } + }, + "signature": "3044022040a9d0975f747df19792211546410d7c735aff2d26f367d1bf9233ffd1d993d702206890c66d4d0eb5de37df088c082d8fbd8da043817b48a76bd5d70f1e3f6b6529", + "id": "f75ac5ccd243e09fc9da2b3842a0654ca860d2dba5bb73866693a8a918937994", + "senderId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_24", + "publicKey": "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95" + } + }, + "signature": "30440220550c0ab565ab2de649ca7a2aaf2975453a1e4ab8b0d392d69663c0c9b6b80b7b022039047d4d1bf4e9b167a95adcde0a5a8631aeca060dfd426da28a10d968fb3a64", + "id": "aa2ed932faf4832848356beaf87e5381ee56a1a84fb485ba975acb28f8fcf5df", + "senderId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_50", + "publicKey": "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1" + } + }, + "signature": "3044022038df37ef25928d1a04516e982c99f49cbdc193603f814b48ab3802153bdd352002204c918915a3cbfa305c5f898ae4bcdd75394b57460f85c80daa0999751d466c08", + "id": "d30a726e1bb8d199d8f44700bc999c9a0a1a8be86e4be6a15764ecd424f9db1b", + "senderId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_2", + "publicKey": "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d" + } + }, + "signature": "3044022028dd44b9609b0b599c15a257757fd068f9014e33947c77776a6fcbe71879271b02200b46fd8eb0827da6de13f5efd63b17f29e8ba4600e4a690ec31eb08bf2d9af33", + "id": "1410b8b5f15c05528013378251bf5da30e04c8a6b7ac0f729b527664cfbdfbc4", + "senderId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_25", + "publicKey": "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964" + } + }, + "signature": "3044022038edfe34f7b89b4e69ea8b94e3335063b60deaee28246932147f53b2525924a402205b89f5e3d956aa49f24f81e2ba3447c19bd5c026568b3bef73a7a7d5160ad661", + "id": "58d14b74b71586e18f0499a50004ec2e0cc2e5b56aa53f4cf57084030ff90fa3", + "senderId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_39", + "publicKey": "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5" + } + }, + "signature": "3045022100bc1e477994bf4cbcdb5cbe2bd92c7d955a03adfe562f8e3bf04d2f62965e9f78022045512772d8453314361161b2bd2a39aa0a7fbb897a5a83f4c7ab54ced615b42c", + "id": "3ee53b3f1455ef0ddb52afe08854c9d87f42c7313babd3e05bb3ca4f94c495ef", + "senderId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_13", + "publicKey": "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f" + } + }, + "signature": "3044022052fe00e8e9f05b1d890f6910beab0627c823eb2d5875b4b9813a33aed11edfb6022034a723b827ce0e73bfdc0f535b244ffc983f8d549ee72b4d432de90d658db72e", + "id": "4a3d204c2916c93360d7bb11390e355bc1a930e3cf503965a45253d65bfe928b", + "senderId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_1", + "publicKey": "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37" + } + }, + "signature": "3044022013b2798a4ab4d741850abac10d962360cd4ab6a47dfac7c1c806d6f9c3d810cc02202742414ad8a04ce679b445fcd040fb877bbfed3d2692b873dec8cb46c01c8c4c", + "id": "7d0c5a44a7517f6ad7a1253db45d58e85aa1c735a282a32f45d28efdb7869d7e", + "senderId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_45", + "publicKey": "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b" + } + }, + "signature": "304402202c372b7b9679a8fe66f952a1d47d4327968d6e98770b215ada2fed6a8d87ed5502205a797fb511cfba557255dd37e028fb40981b7b65ad2ce8fe0e559a46eb274bf8", + "id": "70bfe97ae7452dc752ab4de0e2a0e81bd18bef07392c56e7a101257683d4d932", + "senderId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_7", + "publicKey": "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0" + } + }, + "signature": "3044022058851712200f7386d6b3c188444f9c8f05788667649ec17c71b9e514206eb105022061e6a4bc4cd11599792e03298f95509893d56af54d51e9f639981045e754b974", + "id": "f6f90ff09dee5be7d8f3d58d217772df7a95865bf8609d7d5b0b673e9a5bc953", + "senderId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_27", + "publicKey": "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d" + } + }, + "signature": "304402204878d69a166e60e0a779c31fbc48c67b70d2e4aed1d63c60beb9f070963e2894022078c46b6687f23493a4c2ed39709a183a0f7352568cc9cc2c1f0d7bf0d809a4a4", + "id": "f68809e407d20a50029fe460d411c866b79c7e09c076dada768a38d81f184aa3", + "senderId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_38", + "publicKey": "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294" + } + }, + "signature": "3045022100d5576393a1dea704cf79a5d0bc2757a3a5e66e1055103b52157fca05fc5693ec0220522832ce0e31b779decef83ac8ce764930de927df9ae1d6f6f99a3312d99c90c", + "id": "2ec6c6f33f00431ef063fbb8a79fb90eadb13a79bf46e6e1df36dd9434314df0", + "senderId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_14", + "publicKey": "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24" + } + }, + "signature": "3044022008a7d0bfe9c4c150566ddf701d08e84b4a5f84b07e3b1c91dde1cefa16d2a3c202200b787e898c0b2c68f4343e74f18ae7363f62b5f4ef2962386932aee09a9fa0d4", + "id": "e37b3efbf034bea4c852be7d7013978f8999eacc39549ceea775de197e14e8da", + "senderId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_28", + "publicKey": "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28" + } + }, + "signature": "3044022023b6fbfa5f4482a4dcc34411846696052b1592786ca87243b7d3344fc9fe9954022035402fbca22691de2497552c743f0f68c7591edd1bd7954ab7639548fcd558a3", + "id": "08268f5e6c15cf146523ca928f24aca65b162f363593d927c66144ee5df297cc", + "senderId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_48", + "publicKey": "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b" + } + }, + "signature": "3045022100b3cad169f29a3a95995b87e1b50b35583c1bff91d69cfa236f58ce452491c579022026775f4ef50b50ecf6d78b530b4633711394983456e6a45ec227b652c86e3014", + "id": "ad94ee2ae94813a638b93909930c7cc631c364b6c8528b2dcd6fa8f69260cc2d", + "senderId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_4", + "publicKey": "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93" + } + }, + "signature": "3044022007ac9ff2f272f3fda4947393b8688586cc8b2958ff5dc7931ac8f82c697bb76802202a66c28852bbff86ef17ac7f51e7eee52e611e825d91a9846f531ab3c3115c81", + "id": "76fb1984da9ef90fd7d588756163c97e00d3e4d6e9dfe78d9e3d3cb6d71ddd38", + "senderId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_29", + "publicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252" + } + }, + "signature": "304402204416e428688ad29928303fb2b00a26996cf79753fe70fb91c1f4635c644ba859022068ac5eab7d05f87c40ba36bd9dc149607c196778120c061698d7ab64aaade7ac", + "id": "0f442a91857061e87dd193b0b9f17a71719ca7e3da62841a63568713fc12b5e7", + "senderId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_37", + "publicKey": "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4" + } + }, + "signature": "304402206a248caa5949024202f297c38cee18845e344c5f140be74349787097d3b0a33c02207ac84336e02592bb5e00dcd0c490d30eb856b34177ab9ac03410d82a355a7b0d", + "id": "eed30a45c350fdffc5877458f7fe29f28dc4bf81aa1a197d003c9433148b71aa", + "senderId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_15", + "publicKey": "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca" + } + }, + "signature": "3045022100c99336ce666cb4a6db3727a61c04c14d8746365f72280d9984441b7d2b568b5402201759e4f417f683743e1d4a14f8a7a215009321cdfa29834b2dbdbe54ee22c1d9", + "id": "ecfba14a58f9d79782c4f905646df28bf566e3e7d1f17b39df6fe6b52c11de59", + "senderId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_30", + "publicKey": "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883" + } + }, + "signature": "3044022070de7b4d4ce64bd605c9d008142544c2b113cc84df07ed1982e0adf3cf69f4520220211b01710a6533a270dc2814c7f968adf27eb6dbf437e7a72960b013b9651a0c", + "id": "36ce5323859a92f302f77f27bd08ee3485d720f55842ccba353a47ea96a964c2", + "senderId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_44", + "publicKey": "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c" + } + }, + "signature": "3045022100a7c271633ecbf3c6641c7db36913b5fa0ea521f400a4848edf024648f3d7128002206a271f8a88644062b64d856407af9567c0b2937d4a3d89a3b3d07edbd3a0f177", + "id": "e120452e7c56a9327b2be7dfd3dcecae193f2e2e772903008b03cdf00146ebd1", + "senderId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_8", + "publicKey": "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564" + } + }, + "signature": "304402200394b6545015bcf2d0f291de57a4197cb6ef57b2ad5fa37f05e8a220913ba83502204d0d2f2206edba54ada5b8e5afd194ba83dd1bf15f744258409595251dbe3ff0", + "id": "7d15eee8e4e3be3d2c44acd51b87a816bdb593565d4ac358dab24ae9c8a5bae2", + "senderId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_31", + "publicKey": "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2" + } + }, + "signature": "3045022100989eb331951a13152aa03583efc765499e836c6fbafcafec4302b243ada8de5002203876fc4cf7fdeee4a095667e55a2fef84e5a7053e807b4d8e029883f0d578019", + "id": "baa686d521f95d265e7099cfd9ef14e0a9a92254dd94c16ce50c460bd013c588", + "senderId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_36", + "publicKey": "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e" + } + }, + "signature": "304402202be177dddfad323302565a866d38a3e7939e0234b16e7dc02075cf258502eba302200928a139ec1a82b4609fcc1bd6d1d027ad050e93fcd2eff94181936d2d43e39c", + "id": "9fcf7ec6fe98ed94710e212226d8b90df7e7467d66dd4c5c9d48474388be3099", + "senderId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_16", + "publicKey": "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9" + } + }, + "signature": "304402207b4f8c09a728acedf3b6ba0632e12d01670c683215053e49dde8598954d85a9a02202a7d7930baa17c2134b314e47dd6c334c828f78e573a2bf92fcbc1146d630541", + "id": "c35e4b1e7a2435664fc0939251c2052633ebf4b51fb22d15e71bfcab85b26de9", + "senderId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_32", + "publicKey": "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055" + } + }, + "signature": "30440220127d27312345e015c681adb799c1a87d16fb0caaabd5020b39257d567816b91c022018b2388f6d2d9afb3714d84ed102b3ea61159772786033c855947613c7ce7b5b", + "id": "0d682a3a9c252a674043bee5240e456dae2685d76fbd3bdeda6ff50f0c442fff", + "senderId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_51", + "publicKey": "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a" + } + }, + "signature": "304402203d0ee691830e4d001553bf4e49b6d9669b3c959376f391410551c8adc679dac902203ba6e275bf6d543efd19d20428649f802d9396bb0967114a1f09c24827be1da7", + "id": "ec2373b0d609ae72fb400ffdfbffc59670ebbf1c15f59c0ac22a4030dae700e3", + "senderId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_26", + "publicKey": "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983" + } + }, + "signature": "3045022100f2cf77b0510f589b5aaaf2b0027ffbce6ce8d4873cdc67dc8900865d156de3be02203c22e30945618683182f3d3873e6b3657e0900b062f866bab2705cd593669e79", + "id": "3cb2f0f7d05a515d4c5c873cbe96e33b1dfba1b7718e4548de7f9da54933b652", + "senderId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_33", + "publicKey": "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe" + } + }, + "signature": "304402201e328159172d543d2225c247c6b728800c52eb724f67c0e919f6b7215e6bd7f2022075fc02fe0b14a1499c5602d87ca2c99d6e789beaceed2b9702060dece872d14a", + "id": "2fd77e744399c9632cc8f106c39237f201dafda976f1040235359f99eea3b832", + "senderId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_35", + "publicKey": "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e" + } + }, + "signature": "3044022063903d82e8bd15a6741a298b9a6007d0dc3626acfe2f072c3b624ccbf91ce3360220486ba4cc5591d8aa31b77dfde025b61691dbaad0feabe13e840d26e40010c5df", + "id": "5baf9e318c9e4cb0513a21eaea27e51c849f95fddc963207fb07aa2fd2b9f9d4", + "senderId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_17", + "publicKey": "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357" + } + }, + "signature": "3045022100efc1bc16e0b646da48f84822543b62ef5253bfa98bed6613f2d6d4634076e61802200ef243f9dbac7633a8819ce45e2a85d0eacfdc9a33a92bd3a03e90cbd312b823", + "id": "b4a959ad75f81b7fdbb957c90a3a63a6c5589e7819e2c455733a3a2b4b034634", + "senderId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_34", + "publicKey": "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80" + } + }, + "signature": "3044022012e52a479648990bfc1ed12bf901cad865708ff45962c3724ea67967be4f9d0102201901525ed8dd090af6a2637c123afb304e9fd178794addcb88d916227e66887d", + "id": "6439f2308efe31ac52ad06ef1caa45b9abf6c589118b7997da6a287325ca36e7", + "senderId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_43", + "publicKey": "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e" + } + }, + "signature": "3045022100a0874d1582ce210081f7ab30e7f951dfb9ce8f512d237f8a8cbd5d85569ef3b902200f0053c05de3d6e5ada4e4cf1403a836779d653573c2f374055645cc954c4c4a", + "id": "b0733072e98d3d6afe977e32f3dd118c15e79212232417743ffb551dc2a2ba55", + "senderId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW", + "senderPublicKey": "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357", + "timestamp": 0, + "asset": { + "votes": [ + "+03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357" + ] + }, + "signature": "30440220158ed59156e0eef2d2b94a296451dffe079be701b3d74f0443ef43bc266b334202205a2c39f57abfcd279d568608b90884b3ebe107316aa7552eca35c743b318a47c", + "id": "ea294b610e51efb3ceb4229f27bf773e87f41d21b6bb1f3bf68629ffd652c2d3", + "senderId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7", + "senderPublicKey": "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80", + "timestamp": 0, + "asset": { + "votes": [ + "+030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80" + ] + }, + "signature": "3045022100898da9f693a458a6875344c6c4cb73069c4075904c75595ffbc665967d84b07002200f168aaf3ab1b52dfa74599394387dc4cf627a447fbc5a91000e9d251cdb20c0", + "id": "3639b5dc6d19d46d8254d941bf7ace0f3da8a7cf8a56361921b260820c7239cd", + "senderId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1", + "senderPublicKey": "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e", + "timestamp": 0, + "asset": { + "votes": [ + "+032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e" + ] + }, + "signature": "3044022055ed9a8b55ccb3bd0945a710269b6f243f1dbfaa28467d3218a17565eb0c962d02207d31561478f16d93a20f5454ad565dea24e8dda4ddc464cb011f4b6b360c4e81", + "id": "fe24509580cde0c2e2f49defedd3a0f7572d2f78f90b51a253b0d8cebd74c20d", + "senderId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof", + "senderPublicKey": "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055", + "timestamp": 0, + "asset": { + "votes": [ + "+0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055" + ] + }, + "signature": "30440220092f367f833d677e8d0609ad1df65f389c2c35d1501c71c245c2982e6a832268022018e67445f525613d6cb6ac0c9683bd0f55bd40d9c929165649414f083c9041f9", + "id": "6a76553db794ebf4d5f60a7d7d71cfe29f4dbcaad9610106fbc578cdc7167cd4", + "senderId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy", + "senderPublicKey": "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2", + "timestamp": 0, + "asset": { + "votes": [ + "+03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2" + ] + }, + "signature": "304402203dc028b5013c36b03f97b111a8d7c05d0cd8e505b0b0d18747c0656c9b5cfe8102205e9ce8a78d1183b3e9880c69635d04218d94d17808bcc3f92e7af53195c23daf", + "id": "0f9d7e7708918b77afbdfffb63eef8fe87ba36e0131c88b44c1a7f81750cc025", + "senderId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9", + "senderPublicKey": "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e", + "timestamp": 0, + "asset": { + "votes": [ + "+0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e" + ] + }, + "signature": "3045022100a80ddd7c3adaf0e97ab938773fc78a716f3054d7e03afc1ddfcb5005badbd2810220231c0dabe2262149f994c939f9dc90d46b9bd7ca96b19aad6788cd3571e4f71a", + "id": "0ac77b2637fb25be42b3b60d1651bbbd788aeaba933a08ec4a417c7b4c54e087", + "senderId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT", + "senderPublicKey": "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883", + "timestamp": 0, + "asset": { + "votes": [ + "+02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883" + ] + }, + "signature": "30440220772c9cd8b96f74fcddc429d57d466eca6fc40fc211845f59eeb78cb027e116c5022004cda291587eb118d622de21333d2a5783969794b5b0101ad8b1044c7d8058af", + "id": "4b0dda465564d53981c0e36d73caec888e3523633eaa80dfb99a9c81b2604c7d", + "senderId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU", + "senderPublicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252", + "timestamp": 0, + "asset": { + "votes": [ + "+0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252" + ] + }, + "signature": "30440220406d54714b6425ae4553ea8bec75f31fe52e9b1a9b6f6897151253ab7f637d3b022040a2df4b69840f4d9b0b67658c75efdae8d8269780d4cc50d055fa63922dbb9a", + "id": "c7db9d36d97ff0168d0d670ec695e1dc786dfb93f4081586870c8793b50e5f17", + "senderId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK", + "senderPublicKey": "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4", + "timestamp": 0, + "asset": { + "votes": [ + "+030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4" + ] + }, + "signature": "3044022018b7e51118ec83c985fa4eb3d7f0cf0655753bcbde7e82bac521665fb1c0ffaf02204e2ace460b2542db8c77e41d05d5e02fa5514b746a0a1e947256925846ed19f1", + "id": "c41f4cffcdd523f1718154d5bd5f4f0bec0376076b5f8dd340337e9edb4821ae", + "senderId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW", + "senderPublicKey": "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28", + "timestamp": 0, + "asset": { + "votes": [ + "+03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28" + ] + }, + "signature": "304502210088dbe249503da43c157485bfd4f2c95babfe4d0b8bbefe44afa52529b824a79e022045239b6a374fd9aca52c27171ee66b4863c956ae4085c9760d863b1902596c1a", + "id": "b1736ec6a1ea4c6d4eb278430a8ee214c88daefe296ba98530e692f8b7a7434c", + "senderId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej", + "senderPublicKey": "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d", + "timestamp": 0, + "asset": { + "votes": [ + "+02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d" + ] + }, + "signature": "3045022100fcdf750a775e728a31691a1b38908a7f990b579da510959cc2c63442f5ffde760220316ebb051d9fecb2486771dd39921fb12675b6d46b2441dd1db3c42fad0a59b0", + "id": "069271456015c2ff842771775993b8afc3404bc070572eeeb0f2fd72d58e18dc", + "senderId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U", + "senderPublicKey": "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294", + "timestamp": 0, + "asset": { + "votes": [ + "+0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294" + ] + }, + "signature": "3044022034ce8f77ea9d0f5cf3a9135d7b72d0ba3b96ac6d7eaa3670e9956aef2c9a83cb0220626d1f269128f673a23f9993ce00ba78a08103e697298be29a4c8ee94f204e3a", + "id": "9a99bba8340e7ad4e05d8424a0977ebbde428d31ee066c9828bd06b42bb42a72", + "senderId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2", + "senderPublicKey": "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983", + "timestamp": 0, + "asset": { + "votes": [ + "+02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983" + ] + }, + "signature": "3044022039ae1155f8b87a61c38b25cbbf30da6ecf6cfcc12b25c2e7fe576373754a41eb0220061a66a893129fbad5d48cdd19cf48b1a0d133dd2f3ecdc60ee7b87277e1f81d", + "id": "6c2c8926420ac269b50fa30127e0e791afb2131aff5821ca7aa80d38a0182048", + "senderId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf", + "senderPublicKey": "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964", + "timestamp": 0, + "asset": { + "votes": [ + "+02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964" + ] + }, + "signature": "3045022100d0dac2b7691aa059b1048d7925a0c5d5099f6e9b0f2e321e6d4f128ab1b3272b02207e8c4f643f8f9d1c3f81f0cce6a698df2da2ab71d5b01042766bbe0f46f4a775", + "id": "9259193c5de72276ed7a99f9d507dd6ea9856411fda521074fb41a556294fdf7", + "senderId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9", + "senderPublicKey": "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5", + "timestamp": 0, + "asset": { + "votes": [ + "+03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5" + ] + }, + "signature": "3045022100d5496fec447367ab6b53956a8c40cd8566e050ebb3b92d2c0b2a9d09bef36c7402205e32367605372375801f7b9db39aaafb46ee763b1494f0aca144fb91f3415752", + "id": "2a41e5946ab0773ca2334bba9d3510184bdd258f1c651ff8ec95b7b64a01dc2e", + "senderId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW", + "senderPublicKey": "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95", + "timestamp": 0, + "asset": { + "votes": [ + "+039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95" + ] + }, + "signature": "304502210099249695dc38826e04c8fcffd2570b98c43dec4788cc6a19737ed0872f17ec3302205301f645d803ad5df4ab1a700446e28c7cd76153607f6a2d68ae9168d46f3fe9", + "id": "e5c09b0fb2c24c57a4dcef0078953093800329ab4dc8e16a9d9f68215b5acd3d", + "senderId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU", + "senderPublicKey": "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a", + "timestamp": 0, + "asset": { + "votes": [ + "+034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a" + ] + }, + "signature": "3045022100f983b03e319aaa6c6ab6381e3ef8c0c035d6e3cc2139cedf70fd4e385393e38a0220286f73577765eb3e89e362785ad8a6de572bebf41bbc1f515b0ea93e41801eb3", + "id": "00b2c0455ef6f508d65f11bb49e3cfe1e6062d5fd153cafdfdfd2ccbf9c646e5", + "senderId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr", + "senderPublicKey": "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689", + "timestamp": 0, + "asset": { + "votes": [ + "+022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689" + ] + }, + "signature": "30440220103862ec51621ca27a0ec6b2817848e8824d2d09dbf7e6aac2f45aeea5d2dc9102205e8cce78b5cd7148aa4d406dc7b491dd7758047200e10cfe1e5fde5c56107ac5", + "id": "e25439ad11cb8db3d49ccb3b8b608c1bcb24cb29b2e5ea15101cce3e475224eb", + "senderId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ", + "senderPublicKey": "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a", + "timestamp": 0, + "asset": { + "votes": [ + "+03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a" + ] + }, + "signature": "304502210099241ced4a0fd1eb02f5cdcc880ae5f48eb3c7e490d4520c20124ecbf403893602204729dc6cacf3e87c97ca57c1be54d1e80791bf31ef022135e68fc06c950f6994", + "id": "1474f50815c6c7df41ab652414806d61abe15bee0d41f32d772f4e2793badce4", + "senderId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX", + "senderPublicKey": "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a", + "timestamp": 0, + "asset": { + "votes": [ + "+0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a" + ] + }, + "signature": "3045022100eccf81d44992c49a5ee37c6fc2ccc4b6bee9aa44888513b3e18e79452ede3156022056b0ddf079d2918d72e8781d3af009c87e6058563591dfd6ee0117b7df5534b2", + "id": "b394e2a8b5c2d20a72ed288408b8f0d48aed922edbee6e16c1c5b0e67517214c", + "senderId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf", + "senderPublicKey": "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f", + "timestamp": 0, + "asset": { + "votes": [ + "+03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f" + ] + }, + "signature": "3045022100bdb87894846eccc5a5473edaee1e6dca5f3469963e22f06123b6bde195aede0e02203d0c6833e87c5e60f4597ce624d4c2502a0562b4e54d943f82a4889e3cd69532", + "id": "6a399099bac6c74fa5e956512ef8b3a39f6f946d5d6996f192c2f1dd5ba172dc", + "senderId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv", + "senderPublicKey": "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751", + "timestamp": 0, + "asset": { + "votes": [ + "+02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751" + ] + }, + "signature": "304402200785771ccf1a6a40b51183a190d4cb4ce76b9ffd4c2c736d7724e6c667113d020220649ecfe73017d8dda96a7914793470ee7e582693e4866df123b1032194c163b1", + "id": "f20a831a6bae0a85470e308fb66517e70db479657459f6bb39f2cd1783c565e6", + "senderId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv", + "senderPublicKey": "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb", + "timestamp": 0, + "asset": { + "votes": [ + "+0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb" + ] + }, + "signature": "3044022020b79e1f07bcb17cae9485b9f44e9f583ca235da4ddd363b905fafb884347f71022015a20481b43720ddb3b1e3ca64b1f47e59b5cc2016a62f43327ca14533384dd4", + "id": "7a1285be87dca9718bece5b84266c1bf6801a39cc111d534e660aef9e6d26929", + "senderId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg", + "senderPublicKey": "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d", + "timestamp": 0, + "asset": { + "votes": [ + "+0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d" + ] + }, + "signature": "3045022100b1615d16763c46d42ca2aae967f04c1c07c119b5af7a378c262ba85515a8d35002202cf7df91676cd137943720e93f06c11907412a6bdc5ef2157cf536a203cf83a3", + "id": "76fb5a1de90f245b1eeb79cb11c7bea7c8b738add0fb8cd95191186a944b0229", + "senderId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri", + "senderPublicKey": "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a", + "timestamp": 0, + "asset": { + "votes": [ + "+02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a" + ] + }, + "signature": "3045022100e3c7b5d6a72acde4d22e8c1c6cd864c549deba89683f4b84320407d6c380827c02202da57df0ab7cd381b776bdf85802aed371e7cea7269a84f911b1d8e9956badee", + "id": "8da75c8100e6248ab37cc92f72ed9facec3067f4f82f03db8bb8063791463fb3", + "senderId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t", + "senderPublicKey": "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe", + "timestamp": 0, + "asset": { + "votes": [ + "+03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe" + ] + }, + "signature": "304402205779b5d8acbfedfc105fedb6fcbd4636713ed27605faa9bd988598072640a958022042d8a8b3d7910c7c385f3707a317c5d445d56da250f8d127c71df2d9d4c5d86e", + "id": "fd26e265be88289828d0ce7ffc5faeb9849e1f4cb37a8f1dd5d6fcc436d910b7", + "senderId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf", + "senderPublicKey": "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e", + "timestamp": 0, + "asset": { + "votes": [ + "+034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e" + ] + }, + "signature": "3045022100e18a89fe1fe0a8acaca2b6461314e784ffebbe7374f6aafdb06934e83985ccbf022027314b21a4a25b477bd7cc070b4e00ef8f3d69f3f1af028b96571dc245924c00", + "id": "41d92e128e6b8367cbf8fd111e5263d52e1abad553653f975dd60d7f7c5b637b", + "senderId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9", + "senderPublicKey": "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9", + "timestamp": 0, + "asset": { + "votes": [ + "+02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9" + ] + }, + "signature": "304402201c614c84dbae26f87973c9e2b38df883fe0c8c469080e31fe32a4c4946d50b67022075b8fb498fb1384aa6be785845da02813185ccf095597b5782618033828af4d5", + "id": "1e4a1f8aab6fbf8682c2b35e0d04e9e007ae717ce3f4a82894747e5807e3c759", + "senderId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV", + "senderPublicKey": "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca", + "timestamp": 0, + "asset": { + "votes": [ + "+02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca" + ] + }, + "signature": "3045022100b1ee6becc59d594776a40e5b3caec82390d273b703ecb0d7caece44953141449022016543cc29a28882845118afab6e51296cd216bc662260c28e5efd9597b6025b1", + "id": "2ce068bfccb3f967f4004e9a1e81614a738e55e45c80114c0af30a085f71a2e9", + "senderId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ", + "senderPublicKey": "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c", + "timestamp": 0, + "asset": { + "votes": [ + "+022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c" + ] + }, + "signature": "3044022036698a329d7f5f751f91ce02bc188a7527a377d01583b70427cfce64def945ec022079afafea10aa32394a1e42a80577de3869856656221d5f259e05fb44f01668b8", + "id": "3478d1ad3655e10fcc864f191972322c866616866bb1dbf66d7b66b31cd95de6", + "senderId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA", + "senderPublicKey": "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24", + "timestamp": 0, + "asset": { + "votes": [ + "+03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24" + ] + }, + "signature": "3044022035fa7be80cf881eefefc12b11de04ffb2e2e92815cf05074afef54a3c5b2eccb022041f3347f59db0b3caadefcbfbc5ae275d3fe3e2a52fe1504b23628d4b79a43bf", + "id": "8adfd8e73e96188ed9fdec459d88db1fb041a2b25b3f64830476aec661ae5010", + "senderId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm", + "senderPublicKey": "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f", + "timestamp": 0, + "asset": { + "votes": [ + "+021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f" + ] + }, + "signature": "30440220630da8a73979bd3988b7f84fe9e83a429cf3239f54c140c3dbcc407140513fc002203664ad54ed9f199f2683479b988bd97ad8fffb2c2d5dfdbdb10858aca4abfaca", + "id": "e306328ffefcd9e3809e7390a358199a62cf8ef037d57af1f5c7b54d728d427e", + "senderId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1", + "senderPublicKey": "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b", + "timestamp": 0, + "asset": { + "votes": [ + "+02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b" + ] + }, + "signature": "304402206f1df93f299ffedacc25aa201807df47d32c43369315cf9db280963c357be56302206a66acd553710f49bbb7b803a2bcb71128c8e617ffce66b37b7c968817349247", + "id": "dc69bc8f78502ba34655ed062987788939189709a4112760cd8807245d7461f5", + "senderId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8", + "senderPublicKey": "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12", + "timestamp": 0, + "asset": { + "votes": [ + "+03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12" + ] + }, + "signature": "30440220629e696a10e04d4fbc10a5ac443bf9bd40dd5d89d4b214224abe47d7ab5600340220643f361a24d9916e2c5aaec7bd7d8a6a0d3ffc5fc0b62c3ac4906eb799a862fa", + "id": "c3f49fb80c40f7779b32ba23616f5573a6ba58fc60c4629c2252933038dd89f0", + "senderId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2", + "senderPublicKey": "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904", + "timestamp": 0, + "asset": { + "votes": [ + "+0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904" + ] + }, + "signature": "30440220660f9604896dad2a97820b0d7524f0bce5a8b5766f150517d5061fd02bddf768022055e87c25891d4480e66e5d1a71e42cd5a4bef3ab2b2651cd72d44f30a4b32309", + "id": "8e8ac1b1a586e86867abbf25d63387bb6dfb793c691f0b06333c1581a9a568b3", + "senderId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT", + "senderPublicKey": "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c", + "timestamp": 0, + "asset": { + "votes": [ + "+034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c" + ] + }, + "signature": "304402202e2ad64129f61ef1156c4c7e80ab862d4823d62dac502685f53028536ddfb41a02201a3ec777fdfe8fae9f7cd5251fac322c1b6a2a4d41b3ec456daed474986d4872", + "id": "ff73565c373f2cefebf86c72dda3a6a6205750eb03b69178cb83378620715e1d", + "senderId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q", + "senderPublicKey": "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd", + "timestamp": 0, + "asset": { + "votes": [ + "+02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd" + ] + }, + "signature": "304402202e5c78cf21a088db10e1e1f64d98d84c8d3294fde7bc322d4af06bfe99d4c2e302207e7912a16a37b641a9f8c7c722f2b0d699917ca73e4d0f21584b717fb7f02f13", + "id": "3822273b496f2e253081cedf382e4f9937713fabb83449e1f892377cf536e68a", + "senderId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo", + "senderPublicKey": "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647", + "timestamp": 0, + "asset": { + "votes": [ + "+0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647" + ] + }, + "signature": "3045022100a65ce45164c9bc3e018e26703370c9deb2933ee3b4e814619043cc37c4a39c4802205ae4931ac9e8dffd714c3b601fe248a49c0185c8367887205f497d951c52eb54", + "id": "430d6db0b87c25dce4ce14ac907c13bcc6efa5d95135f05aa4ba7596ea9d400c", + "senderId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN", + "senderPublicKey": "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd", + "timestamp": 0, + "asset": { + "votes": [ + "+036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd" + ] + }, + "signature": "3045022100f3cdd7f688ad2d7b6a5b9cc7e793cb8a6e6e07d3327bc67add64691a53fd2911022026ae1adc8f4fcfc01bcca3efc83019026755b443a504265ad1f46f69d1f5951c", + "id": "dda86ecc0332e6c4eed1c0a5af7424374089b85dd274a300fed51b86e2655587", + "senderId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj", + "senderPublicKey": "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564", + "timestamp": 0, + "asset": { + "votes": [ + "+03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564" + ] + }, + "signature": "3045022100d419072a752acd55792257c96099fb14c56c29112a00535d39bca96fbd7951c902201abdf4db247dc956d79f4543c389823fbd1a9337f95d30df39603a3b52486bfb", + "id": "0998e9a055c53bf6697ee76af94c7a830c1364016d78fce889a21bc38ed70cd5", + "senderId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN", + "senderPublicKey": "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0", + "timestamp": 0, + "asset": { + "votes": [ + "+022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0" + ] + }, + "signature": "3045022100ba1e0ab761326d2a53cbda2a4a5135033c94d8166864d2ad3ceb963b4a0c046402207d755ecf4ada9fa2a598fd75e73a59d30cb83e01f510020b48b6bf162dc60b27", + "id": "be13743deb8486a575d1fb564d2b07d797ac77148d35793c9aca43c0d47aad61", + "senderId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA", + "senderPublicKey": "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b", + "timestamp": 0, + "asset": { + "votes": [ + "+03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b" + ] + }, + "signature": "3044022038a491e2e13ac32025209d00aec1af31b73a8b6ee77ad9b8bb80a34f5df59dfc02200ce82c89fe9f88bd5af236ceeaa80f9954e3fb4af7bc884c447505751d49c134", + "id": "f1d3d44cc289837de9623cba8891a1ed1cde8918473a91e2daead29975afad22", + "senderId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx", + "senderPublicKey": "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc", + "timestamp": 0, + "asset": { + "votes": [ + "+0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc" + ] + }, + "signature": "304402202ae599ce389cd030b8ab48ef53113458b9ba8bf9c9ed09c662eba2849bf540f802202ed63f8af492dd0b67d1b451170a989418a42466a3a7ffe89c4c5a18337e8fb9", + "id": "65ab302a44ea7550891eabc3b4a8d5ecbcb80784c4666195d5d0b7e33394300d", + "senderId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK", + "senderPublicKey": "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565", + "timestamp": 0, + "asset": { + "votes": [ + "+026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565" + ] + }, + "signature": "304502210088a3a4e82d307c238e01ce154b57631d4429e0b591e828ec36839a783736e842022042c6e1d719781e2edca3dbfe84ad13b9e490821a47ccadfcff379decb9c873c0", + "id": "d26a7ea56f398634a81086bb15c2f0c863c71b8bd728304d324d8245a8fb6c73", + "senderId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz", + "senderPublicKey": "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374", + "timestamp": 0, + "asset": { + "votes": [ + "+032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374" + ] + }, + "signature": "3045022100ae5805541f085a50076835422b2581d3b7a128a05b4f068ad7e3c14cd02799b802205f4bb40e06f90e02282ae74c0aba97923e601fd78234b9585468c4fb73f47893", + "id": "02504eae7ff4963c081219523bc48d7a07de4c29fdc1622224547f9a7c133abf", + "senderId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp", + "senderPublicKey": "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93", + "timestamp": 0, + "asset": { + "votes": [ + "+03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93" + ] + }, + "signature": "3044022078d38cabd8f427ef381d0aa6a0b98c6a590cb18f47acc1d80b429a1c1959b0ab022022a70d4d93d650ca3121dde6065e80cd90d1e2e91cb90f0d0b2eadde609e0d75", + "id": "addb8c1baa833baa52a5b51d8a86f8524bde826b5c9f0a99e57070e6323e1dfc", + "senderId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv", + "senderPublicKey": "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17", + "timestamp": 0, + "asset": { + "votes": [ + "+038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17" + ] + }, + "signature": "3044022076dd065e3fba825b77884a179d0231d7fc9e7d3a02e34bc6565fab81a84e559e02200a880c028e690a9d6f2c4c6576b1bf3e913817c834da8ec6afdbadfae78d341d", + "id": "72f31f9a829b93045ef2e860b24c33b9be6a2621c26914acd42121215c1d517e", + "senderId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P", + "senderPublicKey": "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1", + "timestamp": 0, + "asset": { + "votes": [ + "+030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1" + ] + }, + "signature": "304402205261d9d8ded6364fda8b10bd477982be84990cb010f9214d52c492676814e1f40220489f441ffe2478d361a12ab96caa59da495fe62d61d0e2255aa5ec4ed789afb8", + "id": "1f17b4ba072d205761ed3f786491eaf684ed3601b69082e487e568aa74a319e8", + "senderId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd", + "senderPublicKey": "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d", + "timestamp": 0, + "asset": { + "votes": [ + "+02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d" + ] + }, + "signature": "3044022040219da41054a3eebd3122df7f09a62a4e8b4fdc287ae77221f2217b42f291ad02202b9a70c54bb546a604eafadcc086ef6b6570f57542374d87de02ad7f61fe51a4", + "id": "5fa837023159d6a3d6cf7c5b2ed6fe05ff7df19300226b2f0be5a48a06993780", + "senderId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo", + "senderPublicKey": "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37", + "timestamp": 0, + "asset": { + "votes": [ + "+03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37" + ] + }, + "signature": "3045022100ded426768f114f459485ba6ae293c9649b340cf2dcb15e8e887fbb5fed6f7e0b0220752297022de6e93ff64bb9e07b4efef8e946cd2872f84d9e1cb3165ff5c342cb", + "id": "0a16dc31514629a36d7237968ada6a95d6cbec027b7d26e1e0f0d7d4febe9494", + "senderId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD", + "senderPublicKey": "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a", + "timestamp": 0, + "asset": { + "votes": [ + "+02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a" + ] + }, + "signature": "304402203aa292e7aedcd62bb5a79c2521b666b8e1886b57923d98f51911b0461cfdb5db0220539657d5c1dcb78c2c86376da87cc0db428e03c53da3f4f64ebe7115998f00b6", + "id": "8816f8d8c257ea0c951deba911266394b0f2614df023f8b4ffd9da43d36efd9d", + "senderId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD" + } + ], "height": 1, "id": "17184958558311101492", "blockSignature": "304402202fe5de5697fa25d3d3c0cb24617ac02ddfb1c915ee9194a89f8392f948c6076402200d07c5244642fe36afa53fb2d048735f1adfa623e8fa4760487e5f72e17d253b" diff --git a/packages/core/lib/config/testnet.live/peers.json b/packages/core/lib/config/testnet.live/peers.json index 8fe66bd5b9..da767da2ff 100644 --- a/packages/core/lib/config/testnet.live/peers.json +++ b/packages/core/lib/config/testnet.live/peers.json @@ -1,5 +1,5 @@ { - "minimumVersion": ">=1.1.1", + "minimumVersion": ">=2.0.0", "minimumNetworkReach": 10, "blackList": [], "globalTimeout": 3000, @@ -25,7 +25,5 @@ "port": 4000 } ], - "sources": [ - "https://test-explorer.arknet.cloud/testnet.json" - ] + "sources": ["https://test-explorer.arknet.cloud/testnet.json"] } diff --git a/packages/core/lib/config/testnet.live/plugins.js b/packages/core/lib/config/testnet.live/plugins.js index d00279028b..93c1884fa8 100644 --- a/packages/core/lib/config/testnet.live/plugins.js +++ b/packages/core/lib/config/testnet.live/plugins.js @@ -1,100 +1,74 @@ module.exports = { '@arkecosystem/core-event-emitter': {}, '@arkecosystem/core-config': {}, - '@arkecosystem/core-logger': {}, '@arkecosystem/core-logger-winston': { transports: { console: { options: { - colorize: true, - level: process.env.ARK_LOG_LEVEL || 'debug' - } + level: process.env.ARK_LOG_LEVEL || 'debug', + }, }, dailyRotate: { options: { - filename: process.env.ARK_LOG_FILE || `${process.env.ARK_PATH_DATA}/logs/core/${process.env.ARK_NETWORK_NAME}.live/%DATE%.log`, - datePattern: 'YYYY-MM-DD', level: process.env.ARK_LOG_LEVEL || 'debug', - zippedArchive: true - } - } - } - }, - '@arkecosystem/core-database': { - snapshots: `${process.env.ARK_PATH_DATA}/${process.env.ARK_NETWORK_NAME}.live/snapshots` + }, + }, + }, }, - '@arkecosystem/core-database-sequelize': { - dialect: 'sqlite', - storage: process.env.ARK_DB_STORAGE || `${process.env.ARK_PATH_DATA}/database/${process.env.ARK_NETWORK_NAME}.live.sqlite`, - // host: process.env.ARK_DB_HOST || 'localhost', - // dialect: process.env.ARK_DB_DIALECT || 'postgres', - // username: process.env.ARK_DB_USERNAME || 'ark', - // password: process.env.ARK_DB_PASSWORD || 'password', - // database: process.env.ARK_DB_DATABASE || 'ark_testnet1', - logging: process.env.ARK_DB_LOGGING, - redis: { - host: process.env.ARK_REDIS_HOST || 'localhost', - port: process.env.ARK_REDIS_PORT || 6379 - } + '@arkecosystem/core-database-postgres': { + connection: { + host: process.env.ARK_DB_HOST || 'localhost', + port: process.env.ARK_DB_PORT || 5432, + database: + process.env.ARK_DB_DATABASE || + `ark_${process.env.ARK_NETWORK_NAME}live`, + user: process.env.ARK_DB_USERNAME || 'ark', + password: process.env.ARK_DB_PASSWORD || 'password', + }, }, - '@arkecosystem/core-transaction-pool': {}, - '@arkecosystem/core-transaction-pool-redis': { - enabled: !process.env.ARK_TRANSACTION_POOL_DISABLED, - key: 'ark1', - maxTransactionsPerSender: process.env.ARK_TRANSACTION_POOL_MAX_PER_SENDER || 100, - whitelist: ['127.0.0.1', '::ffff:127.0.0.1', '192.168.*'], - redis: { - host: process.env.ARK_REDIS_HOST || 'localhost', - port: process.env.ARK_REDIS_PORT || 6379 - } + '@arkecosystem/core-transaction-pool-mem': { + enabled: true, + maxTransactionsPerSender: + process.env.ARK_TRANSACTION_POOL_MAX_PER_SENDER || 300, + allowedSenders: [], }, '@arkecosystem/core-p2p': { host: process.env.ARK_P2P_HOST || '0.0.0.0', port: process.env.ARK_P2P_PORT || 4000, - whitelist: ['127.0.0.1', '::ffff:127.0.0.1', '192.168.*'] + whitelist: ['127.0.0.1', '::ffff:127.0.0.1'], }, '@arkecosystem/core-blockchain': { - fastRebuild: false + fastRebuild: false, }, '@arkecosystem/core-api': { enabled: true, host: process.env.ARK_API_HOST || '0.0.0.0', port: process.env.ARK_API_PORT || 4003, - whitelist: ['*'] + whitelist: ['*'], }, '@arkecosystem/core-webhooks': { enabled: process.env.ARK_WEBHOOKS_ENABLED, - database: { - dialect: 'sqlite', - storage: `${process.env.ARK_PATH_DATA}/database/${process.env.ARK_NETWORK_NAME}.live/webhooks.sqlite`, - logging: process.env.ARK_DB_LOGGING - }, - redis: { - host: process.env.ARK_REDIS_HOST || 'localhost', - port: process.env.ARK_REDIS_PORT || 6379 - }, server: { enabled: process.env.ARK_WEBHOOKS_API_ENABLED, host: process.env.ARK_WEBHOOKS_HOST || '0.0.0.0', port: process.env.ARK_WEBHOOKS_PORT || 4004, - whitelist: ['127.0.0.1', '::ffff:127.0.0.1', '192.168.*'] - } + whitelist: ['127.0.0.1', '::ffff:127.0.0.1'], + }, }, '@arkecosystem/core-graphql': { enabled: process.env.ARK_GRAPHQL_ENABLED, host: process.env.ARK_GRAPHQL_HOST || '0.0.0.0', port: process.env.ARK_GRAPHQL_PORT || 4105, - path: '/graphql', - graphiql: true }, '@arkecosystem/core-forger': { - hosts: ['http://127.0.0.1:4000'] + hosts: [`http://127.0.0.1:${process.env.ARK_P2P_PORT || 4000}`], }, '@arkecosystem/core-json-rpc': { enabled: process.env.ARK_JSON_RPC_ENABLED, host: process.env.ARK_JSON_RPC_HOST || '0.0.0.0', port: process.env.ARK_JSON_RPC_PORT || 8080, - allowRemote: true, - whitelist: ['127.0.0.1', '::ffff:127.0.0.1', '192.168.*'] - } + allowRemote: false, + whitelist: ['127.0.0.1', '::ffff:127.0.0.1'], + }, + '@arkecosystem/core-snapshots': {}, } diff --git a/packages/core/lib/config/testnet/delegates.json b/packages/core/lib/config/testnet/delegates.json index 3d27e96695..5af0f71488 100644 --- a/packages/core/lib/config/testnet/delegates.json +++ b/packages/core/lib/config/testnet/delegates.json @@ -1,8 +1,4 @@ { - "dynamicFees": { - "feeMultiplier": 1000, - "minAcceptableFee": 30000 - }, "secrets": [ "clay harbor enemy utility margin pretty hub comic piece aerobic umbrella acquire", "venue below waste gather spin cruise title still boost mother flash tuna", diff --git a/packages/core/lib/config/testnet/genesisBlock.json b/packages/core/lib/config/testnet/genesisBlock.json index 28969efa39..317cd8ed94 100644 --- a/packages/core/lib/config/testnet/genesisBlock.json +++ b/packages/core/lib/config/testnet/genesisBlock.json @@ -9,2149 +9,2303 @@ "payloadLength": 35960, "previousBlock": null, "generatorPublicKey": "03b47f6b6719c76bad46a302d9cff7be9b1c2b2a20602a0d880f139b5b8901f068", - "transactions": [{ - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402205fcb0677e06bde7aac3dc776665615f4b93ef8c3ed0fddecef9900e74fcb00f302206958a0c9868ea1b1f3d151bdfa92da1ce24de0b1fcd91933e64fb7971e92f48d", - "id": "db1aa687737858cc9199bfa336f9b1c035915c30aaee60b1e0f8afadfdb946bd", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100ffff4e9ba62e5e3beb37deee052824da83c4030925bce09f190151652d0669b8022056a432e56a2e1b026d4b54f6c34ce88a0c9cebdccc730659c03449fe878c66f8", - "id": "0762007f825f02979a883396839d6f7425d5ab18f4b8c266bebe60212c793c6d", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022001a6326e5d1eb06d0ba1fa39446bd6d56ea45f0c269ebbce5dfc6a649277cfcc02203b252d3a6ef2b22349d9d0a9110ce28a199c39dc8b911edfa82c297a02009d07", - "id": "3c39aca95ad807ce19c0325e3059d7b1cf967751c6929035214a4ef320fb8154", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304502210084d855eddfe616cf1dc238b19226c7959c2fc4027ae2e8aea6fd8e9eb8928e6b0220440f980e40c1c56348782fd69d49a96944df7ee5b68d18028600e0e7501d4000", - "id": "9fdf6ae86f7c005b3b7dc1b9fb6411219407ecaa93adff85fdb61710f5121638", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402205438b8b9058bbde5d30794e7681e400e52b5fbd22324c5b6b521f97bc8b8aabc022000fe04d7afbd2e668b1d4576988ed596dc92251e33efebc081e2cba14ad5a898", - "id": "1d7c68087c875d7ce555b2c3e71e1d91a1ad62d0c2497efe3cab91415e634041", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100b2e634a95b011a68489870f003e4bac4a4f0578bfdc6b9f645c934016c2c0463022022cd4ebf276dd627d98be4b697bae2df10b86d94e984da2eb7e011b08d6dffd2", - "id": "0c993e115ba26981b0be9d22e7c4a13b0f106e0cb472f9d34eabfc8e414dd528", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100f965e5c280acb22d1cde405223fe9a6fcb765844adbc5321b17a268924e1f597022043d31b1edc5fe0cf60a960d84e3528472cdf34560c9463979043a409f37e7f29", - "id": "c279f2eb1f9e6e7d4b0ba7a98233a0f1a2536231976c99f56f64b248eb06a0c1", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "30440220715463c316a75959dbfb6a59a013fbf914bef1ff739ac8000d49dabbf5118df9022019345ae1c34173dc214bae82f3cfbf438092f0fd2d277acafe3e9deb644b1a3b", - "id": "7e2fc9ecf23e909a3d0fbecd615445a0eed8c2cef18e01b1492d63f616f5d87d", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100fdd8aff26dceeb5abb6e5e8a8f468c8ac1997a587225298e3d8135d57dadf4dc022072ab80a81b301a162ed5cfa67d213d5a3980185088632f5f592351aff8aa0e9c", - "id": "511c0e1076104743f98932f8e7720bdb3f1539134edadd331914fd9ece1ebede", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "30440220635e04ce278870f17fcd1883aa26c568e63dfbdd302add39aa30fd3637c79c2c02206fdd9e7b1f4d238a97d26ef1758927e2d39f121687490f2bd79831e36afdd43b", - "id": "0768d5016c53d884e3d68a09d1bab0d730b7067c71ef4ca1c4d61b3815f5ff66", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402200b1dac57ca6565ac31afb99686f2e0f0e8dc219b9860b295ca5444a1663cecfb02205787393561fe407449af4aaf2f621db9e4d3f11c7438666cd694d495c0a0c41f", - "id": "1aeb50080ea118165e5041f7a897974c2ed1ebde08add85dc78cc7cf73566a91", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304502210098dea25eccf31ce6f874a9528578805aaf07be8b41f1571865793f9e3e6e3c97022033ae9c73dad44c01fe6362665fccf63bb1a0ae8e26f77a1cf60b67dc96b05343", - "id": "254f0f4fa277cc651a746d6ac371eb27afc3ea155ba060552dd26b8e83d17b72", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402207f4bf346aac501e766156818089fb16905a9bdca69ff6d5a55ba918a08afc7ab02200ec2c25cc4bb30e2c176d55630d8e2679b899c14ab4ba43c3d62955dd940425b", - "id": "e5ebb02e8e8a6708e22ee5ef99fe1dd8b6eea1095be6b772aa21bf63cf7ade5a", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100a0bbc15bdad648bb9b439f1d34b12b853442d1cfd4ce7f569905082801fa58e8022036b4e73edf7ab7226f8007233f77b1d497cb6b4736f02721bf1b399312ebe114", - "id": "8a686b21477b64dfd85f08f8598a0f121ca1c7d65ccaca9e42326c75fb5f3abb", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402205d77dfcde527dcc6669bcb01c27b92c1a6399e35ebac9e69415645f596ab1d2802204179497bfd952f44d5f9e295b2a3219a290a4a82841c084a18553b7712e26415", - "id": "21175347e2acfabc09a7593aae0682e39fe7152199a90561c11125f525211243", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100cf77c16df9185727ff717b71a94f8b29ceeae1e5bb3a28da8cef9df5bc63b7c202207bca394ce9ebd344a548e5a5697f672dedbef640dc1f9105f7c063287bcd1840", - "id": "ce1d9b7377551f36568127f5b635b5443f5a58abba6566b50a8d4d7b53c8a874", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100eb8daebb5484f3b0a738c9344fb28298c596f9486963f8fe36e2501ee6876f2a0220559df66986dc9a9a8e76982ef85f907c62745757990c69f0b17b6ae5a7ca4719", - "id": "b56702f5eddad0d8dbbb33b6b1ca3e07e4740def9c5dd2aaed9a70b90a4e31b7", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100d088e9bcd78978f2d67e7c7bccecfb73ddd0d1a2dad5b039390812320355722d02207affe83d815f04f6b11abf98eebe0488bfb87f8cd6513d44b829008ed1c15ceb", - "id": "a73c053c42e83a83498cf58e5b077b31443e265ddf8228081cb17a36bba366ae", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100db16a8e9682f07efb607bc7c75b654646ff449761ed146ab9358e69d29fadd7f0220436554ad78db0e04ae5b573258e2c8067848e89b55a6e8e1e25011a43882a643", - "id": "2dccb8b44ad2e598673628fd9d74e336b467a0c941d5e257dceb85c8e0a0000c", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100b03738eccce8ad0b8ac0a656119c2cdd202089c5650d8e1486bd13eb9c3158980220059079900c7fdc16e799c50dccc074726fbf0068044462faabdf1e73f9f9bc38", - "id": "b2cce30021d139f97925807da796722bf4d5459442523823388c259ca5ad73db", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100becb49fe5edd6806d5ba6eddbbb34ca8eaf3a12dba123d1610b2b120ca8bd017022072972992ee0ca0f319ae754a2a5a10d715a08b23f8239f9d6d59774f790543ea", - "id": "9e4841f43ab355be7a4f93b09f3d82c17065fbe25387dd6c5eb4e2692ea05b0b", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402207f1a3fe8c5aa7a77a58ed35c34f128b5df6fba89aa918af35eff432be7d1f8e00220460d4f2a457e1a477974157e33bf2974de6588d56e59729ae980720e9794827a", - "id": "2c7ca823be21724a4876de632dded3b9afca45df357819ed028488128d85d29e", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022067266dfe9d8f2550b590e1eae2f73d28c6b80fecb24c3eb1b4539bc864b3b4f4022031e5122145c35874c0c48673d088e76fb3e11c308ffe9d5dee6431d3441d627e", - "id": "a91119f04e2201184761f7fdcb26e4aa81c7e1076cb11a58a422d351241d4e4a", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100b970ec89927de0cb7805e614a742d42c2967db5a9c68d0892956dc89d68ca7d1022067fa30265dd2e1a2985980be2bf876748a7a8c7f3cde0382265b601fa658dc17", - "id": "94955e6bac6269fbd19e92d2292ac947225fc6f68c6216001b528596a961040c", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402203671b82ddf8a824b8e5aac8bc28be4aef1c00aca1097d14ec1a55003d7a3f28d02203aacb6e7517e916478432b81399828ba7425183ce0fc43feb361bcf345fb0519", - "id": "df563ee9822bd3d7aada600d4800952743ec64fafdc7697428d7a19a60745885", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100b77653317c93eb20ee19c71e64a7f9ecb985351bfb1fe351ac65a5738cb37ae202203d540395e1d55f87caaaa867afbfbaf98c553be0b4c7d1748418a76b0c258c89", - "id": "d21b6341e2b4be5ffdc3dd8fbcdf2c576ba02e2ef4ab5eab0e4bfc9da4e9e442", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022046239e39062a58925099b005888355b8cd6700af66972bf509a10123f9abdec60220202321ea74e56177606fc079d19c29851d832e6d00c93985ffbec3dba6f0d675", - "id": "df6bc7a17ad34f8e9faaa2646e8e5dd8bca35affba352537184f690e200e17b6", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402204eeab87f7ecc2097b85606b986177964f3ae777535f6fc0cf08a55fec587d87602203779d59903b8de63511e4ed0a7967bd85e9cb1fc9d84bbc5091e3caa87d8bd52", - "id": "5f0d5f0dff464d0ad587da5bc93e600a8e2657d359d0a1224bdd4ccc3b6f376a", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402200a2b9d0f61066fa00a2a2882379aa8ee60e949bdc2a85103bbbb69ce3eafccd9022057364f349faceb3047fa95ada210c64fc4a81978d66925b37d3dbc21ede885af", - "id": "1b39e3702576e6ad7775e34d53e43210549d52a56b3f246031e6ba4121a66bf0", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304502210099e568d3d0c1b48410e0b85c74d04234dacfb2fdf2b1d4b51fca1cfb3445347a02207a2509645aae54560762a37422b66ba4b3ee1c42de35d58c36d2f9d8fdea11b4", - "id": "0f21e53dbb1edb1cfb4c31bb675aa4672b452a03ec363a2b3300a9dda49e3be3", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022026cc5f2b588a86241badca73cd9c1686916d516b8c6c397c66a9d5bb6b5d4cd402204ab5a8c8589ee954bda4a116999d2a0e4ab0e3e96f0c7fe131d7c57b9a1ede43", - "id": "410826c255a23a78ac5c3aa10dd48132693bc955845af16c20d9c6f69b05dfe9", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402205fedd8d3b5c8d69cdd7db5ca8e9e7c5004f6ba751e45eb1b85b26d9e89800a2402202be56bb2cd824bccf325b6b11432bf6d0ddb5ec97fcc121839ac2ebf884c7173", - "id": "ddb57d8270b2b6c876191c1e1c5974388b9fb3ae0980cb2245d8a7c426237f47", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022053cd42ad147eea33801b2b57388b33f633b4bfe2ad902190e12480522250d07802203066dc0d0c2ffacc4c74cca1e0187fbea1cef7e78a78666d2ec7e4e87ef546eb", - "id": "29e1aedf98935c369946c8dadb2d6784f9ab5ce8d73b9b4de2466c7757e2557b", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100c10448b87e7176735c8ddfc8fb3c4d5d55c2d71d18b7ce3ab321209ec299fd41022013517a09e4b366ab386698286ec7bb20410bdfb7f6674fab25a739259083b297", - "id": "4cf04852529b5525f22cc540790e36e61ed36045ad1b5b788f61ebe42637391e", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402204cc1588b204ebc0c20f44a31ce53d15ab5e4d1f9c103c02dd4e4eaa1c33630b40220194b6e427b6def0783461cd8d765f97b105d048942be468be2ee9b0a2785d2ac", - "id": "35c6bc3f0799d9c79efc6515f232c58be0d03a3a797d066cba879eef4afaae2c", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100be44f7ea12e2ee89245fb474643ec6c2c75afa00276826a4ecd6fca4cad5ff30022071a2c083b353a821345e4bbf74d98db0760b8721856572572cc3436ebdb8f08c", - "id": "45f75a349f3b4d73434c0f2ac9c291d5d07278b79e6eaa0d38d6e005f66c4783", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402202090f506e8f18fde70b87a3fd6c470a23e9e262f20ec6268dd59b6362e51a29202202b838c598b33c6317c998dc179fad2b660b8a72bfaf8223d7cc82414ab4c6af4", - "id": "a8d9034d1091a4dbe595647ad5f64ca8b243e7842301aee48f7eaf8b8ae98119", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100be59b689a48e198267305f1ae7e116f69f7c360857ea0b1fa81db122278cad69022033436d24ec0103674522f0c559e2357f8696bd498deccad2e0f66b2cf7469538", - "id": "061cb438ba1216cfd5a0f268ce18e6f280557bc944d9aed3655e2bc5f08bdf51", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402203b5d2aa7c4554d6d2dd6723043350df0199e6e7bbd9f21a1a20dbba8c63918cc022014a78064c5f9c5e2f43d3be36de2b5e2f17e9af557bb6c75e8d82d9f725d0188", - "id": "239f0640ddc3170a737ef349c07cb82b2493d207421b6f71b6b3dab856f16088", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022005eb29ad4cf79fd4f6898de19459e15cc816acb0975e53530a202e69c29d0d4a0220686cf6e0c14779d6d68dcb9d16358c0e859094d2eec8083598b7bb5869478bf2", - "id": "25d8eef755cfee7cab0d7f9fbbea0fad6d5f906c432d997ae8ef1c49d23735f5", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100b93096a287d59545fa3a08593dfc740d9d47f3cfa3c4bd3c8ff8ef53d3a2e957022027eda62e47220774cf799f46916195e5a8b30015c56ceff4f4a1c10a918e3675", - "id": "aac25996e3be809ee88996b6b4063e2097d6306e77a067de8ebc8d7076a28d43", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022017282aa4fac7b18e834abc3ca37b2f60cf989c26b12e2f2398a66cb907015a760220428218d39db812a22cc138acc7d5d4d2d5713f0546751c02d2c3fabecca0e724", - "id": "b040f86b75750b49c83ca7eb8f2a458f16b44789796ff306c5f942ca5f19164d", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402205970d53cb0921a62bbef540dc33189b2313f3574e44f046097067e6991d63b1102200a356c87642cc781df661a1fee21cce354a144463d37053280e000e1b75da7a5", - "id": "25ce96f951d7b7d886ef487331125b3413f655f9c5ee7fb4691a728c3cbce18f", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100aab0201c9d9a9641c11605d32353685cbaa051ecc276da1e6a3b309be9f20cf7022067aecbc7329bdf1770974e317a1243815511efa8c7af7801217a83c96d86eb0e", - "id": "285143b8b19cbde7c680b0f62ef51293e8f315c823ffbd97608c38c02045d831", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100dc7752f6f8acaa3a1ee2ed1bed306ee04556b3866db92a1e770c4b970c7a932e02202d137b312342f9d0708704833b26b6611d0464c87df97049ad8b616483e9d1f8", - "id": "87b06fccbb63809e976b3405cccec2eeaa3694d5510203f04c0e60bb6c2c0020", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402205ccad5c77ea339f5e3f2b7900b4b1c409d3c8204273e89b6401314fb61f0d224022026a63fef86356de64fe571ff8488a951dcacab56e980fc044ef9f43b9d37439c", - "id": "5597ed52e4123756bea9307c09c916ff9d0f9fbce8d2e9a3a2ff719a87ad0966", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402207c91153f820f34228bec62772e0d78876bd3277912eacd866fe35b5c86a316c80220104529c6f786cb387ec1e3d5826271c837f0d0a6d0fa5731b9a5c6663cce7108", - "id": "d46fde78608fcc668246cc35336210b3c167ba55c82e91b0fd99df7e36872130", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3045022100acc0cf119c18861d3683bb3b0f6e209f2d62acfdd958f86dfbd35137ada814320220448f6f8adcd46204629b45a4a06f5dc7ccb4dbc2a1d702e107d91053847adf2f", - "id": "aa92faf5d80459b4e058dc8a8212608b589925052e22148384835ab687a4e875", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "3044022055b6bbde5fa886db3cf1224a59f1fb43e850e2d9237db593368e1043698fe2c30220067dd20195e794af4152f1ff9e3ae4261698a86c54803ba1890bf176d97844d4", - "id": "432e67db0d5fc8c66376aa96c7324e5a1e6d00a415a9c8898b5e3bf25d8b083d", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245098000000000, - "fee": 0, - "recipientId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "30450221009d6f38067264df8497d6888e4a8c316ec58ceba8a54c39ccb0ce261d114fbbab02200fae3f2f950f5c5e3387679f8ca341ec70cd90d0e32a30112f03cfb12cd9fc23", - "id": "9321e1b08faa544f592ad8dc7b60ff1cf845efcd28fedf8b445be3bda60434cb", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 0, - "amount": 245100000000000, - "fee": 0, - "recipientId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo", - "timestamp": 0, - "asset": {}, - "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", - "signature": "304402200aed5a4102bdafda00fda575294f149b393a798c510af8ba877b8c2d7ec8051e022004f7487c4f728c633aee5baa62ab0017f4b91cf2f494eb1c4cc9addc3e9155da", - "id": "0bbc9340798a18a81109bdfdbee9c9003f20a586dd9f80a39507c84588c1b4b1", - "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_9", - "publicKey": "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647" - } - }, - "signature": "30440220072124721ba7c997f7c29ad3d4819515fae7a67be2bc395cb73f114eb8d4abe60220523ac295e114de30ce8a4300f4670db91ad2abe1268460e6ad3463fbe9834b84", - "id": "d2e70f9d2de57240571905aa81db0b6883e27a83be2422530722d76b56e63ecd", - "senderId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_18", - "publicKey": "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a" - } - }, - "signature": "304402204b93b06e08e71e3317f9426a1d3d450d6293fdbf5a6b3043fce27b3ce65431e20220683609720ea1d7d921238ca8b5098d3d9c0caab7b1e26efe42a6aebbc095471a", - "id": "8695bcb906f5fd81d858794f7d90447aadaa38418d312e33115a81e856b34d12", - "senderId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_47", - "publicKey": "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd" - } - }, - "signature": "30450221009711559a43005c808113a1e9a01b1665495ff4bf30d635f7d98c752ead4cc3fc02207879e2a939914effe2b5c80cd515c4b3ff77a071b707c85c4444481878803db9", - "id": "55853d2d2a98def00c5ab842866a44d1db91678a07b6dd63d062508db28a00a5", - "senderId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_5", - "publicKey": "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565" - } - }, - "signature": "3044022025ba51a588253524557547ec492d71bd485fe5b291e60eef681c39eaf8ee781702202bf24c3d295c7a2c9aed97a79fb835506797dcfe7e7a2853e2578e7773c7e134", - "id": "553298aadf692c9c5d0334c307dd4ac0e277a49ed165c97ce1362f8ec639ee3f", - "senderId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_19", - "publicKey": "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb" - } - }, - "signature": "3044022041291ba10ad30fb9ebcb0e13902e92d85e2c3e98493b6d369d7d1e70e8474e31022009083444460c415eab6b4beed9e0206eb0733bad5d2a476af4db4f5b5e74b835", - "id": "90af927db7b258538c8e21116b5a31418c88ecc163628b2b65fac92a5a949b14", - "senderId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_42", - "publicKey": "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d" - } - }, - "signature": "304402205d4111c87874e696b8f4b8897d0dfe68fabe4ad5c5769026c6ecdd04f09a1e2f02207b9c8a2a16b50164215eb1efea6d5d9f4e693cbb7eec8535e526cf8ba68bb796", - "id": "8a920ebf5255a102d0c9c5fd720e0d36a6a3539991a2267442facf1fea2d0b86", - "senderId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_10", - "publicKey": "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd" - } - }, - "signature": "3045022100f15ff048872020d9efc561b8c837f542d54d43b9b071f7a6cc09643c6d4180f002207d0e82153a30b66f43fc4cb4b9b3093bb3d5dfd70f96928c8780c838b1448c19", - "id": "30738f376aa40fb3c8d8849a5dc698786aeb1409fa801c18729f8da624631391", - "senderId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_20", - "publicKey": "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751" - } - }, - "signature": "3045022100babb7410d09215def98078bbab6b5e5690c2ebf54960d94527226ed3925877320220342576d1d8fd2d2fe3b6974cab48a2e16b4813f022b341b32f88e13f572bf060", - "id": "ccbe1c27eadc1b3b33f3f87f645be4f756021ee3d4c96f4f094e1f82d5728a3a", - "senderId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_49", - "publicKey": "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374" - } - }, - "signature": "3044022032f2c350cc1319f5838d6880e91b49ae0438fb3a626ed9ab5e27ce8788e3347c02202cca18567c8491e0feea8a5f078e28605029346c509fac0c0a192e934f8c5326", - "id": "f99af0fbb4d65c2c3f2c1c558f0c0c0eac2724942802fcde02fa6da1d3a9000c", - "senderId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_3", - "publicKey": "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17" - } - }, - "signature": "3045022100f0cb5d885ddf3bd4a58837f9b86486da4171652a5eb39228dfd0ff9d34d9c7c602202dc6e3d268d745a7e8633311a337ec097382342049672880c7c2215cf58e5da2", - "id": "2dca03aed08533585d8bc609da5deb9f17ac9be5a8352769d7ae63d0db16ff59", - "senderId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_21", - "publicKey": "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a" - } - }, - "signature": "3045022100999f19fbdc9a12eebbb8c748a4cfc6c91b2233f333a09cddfd49dfeab6aaf38602203d8dc9d1551d400572a88ee812f51f897f8b35508713b789b2c1bf6dd0e88945", - "id": "5d7e51d57b5914ec201ab65a019ecdf651c4f267cbffe403fd2170bb95145f9d", - "senderId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_41", - "publicKey": "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f" - } - }, - "signature": "3045022100e86e648add940a1e637e32ea9187497c281b843da09597e62d0c927d7f43235102200479f64ae63abb55e338f9ce1073a5c46907f7a2a82ea6f9bd9bc29811683515", - "id": "eaeed4133da26612c53550b6572722d8c3380d0a2344da1bd270eed1ea91fdf3", - "senderId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_11", - "publicKey": "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904" - } - }, - "signature": "3045022100bc3b2ebc58a92bf38672206e8311e7ef0e54912abce7338155b11e7d191b0b5d0220765a568c1fa4665c0ace6b4bd3b7ba0f8329e2f25af7a3cc0d78b2ea398084c3", - "id": "bb91e78e43c59a19ac06c015d8a7ef09d7c5b274c9f98505e5a978027354b71c", - "senderId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_22", - "publicKey": "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a" - } - }, - "signature": "3045022100aae4868ab75a33e4e77f9bf6c53b920c5e7c523a7cfe271d1afc472655f3d6a60220499f1bcb79bc0fa830dfa939898db5c9fa8571a2788c8de0da7e550bfc818bcc", - "id": "a6e687647dde9c1db68690090afc4fcf11833dd35fff3186b6b709a1e7d24260", - "senderId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_46", - "publicKey": "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c" - } - }, - "signature": "3045022100c0cf1fc54705c13f70fde39c55a1703a4c612b8a919379cd5b1ada464c7cc8de022074ee62490a184010ad2418d3177ff2ab03d02d2589000176312b90422b1bd64b", - "id": "70262b0eec3ab5a60a736eb8a628cb600eae7522464a49791c0bf26e82318ec6", - "senderId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_6", - "publicKey": "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc" - } - }, - "signature": "3044022045db446b109215c6d3dfb0ee5869154a8a7624376c3760eec4fadc75a29033cf022003e524d64f3ccd0c6de4ca80a7327e2c47ffd16b3ad042bd25a02f5f64500ab7", - "id": "56048c449694964bee3d367609a7bc46c8da20f66878c09c01dcc53c3abd932e", - "senderId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_23", - "publicKey": "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a" - } - }, - "signature": "3045022100f8f69f2957781ed02d64983744c8e51fae613ebe5bbb330d4f509bdcf4fc6b6602205568ad1fd840e01ec26a24ac9a0ff093e978172da55d494138d018a45eb67893", - "id": "e15dfc4e18106480083b3c6211349fd9c803e334e9ba5eb62cca19ae3f57d8e7", - "senderId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_40", - "publicKey": "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689" - } - }, - "signature": "3044022021eeb9e1db8915a9adb99db72972cd17fc7b5b377fc532ac2c9deffcb2707edf022068b9e08f45bbebad89295f520ad40d7786fe64059d45df95551576e3acb736d1", - "id": "2bd0f888ccdeeca24a0134e3c1bf729582d284f32ee000d97f1417f1349a6594", - "senderId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_12", - "publicKey": "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12" - } - }, - "signature": "3044022040a9d0975f747df19792211546410d7c735aff2d26f367d1bf9233ffd1d993d702206890c66d4d0eb5de37df088c082d8fbd8da043817b48a76bd5d70f1e3f6b6529", - "id": "f75ac5ccd243e09fc9da2b3842a0654ca860d2dba5bb73866693a8a918937994", - "senderId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_24", - "publicKey": "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95" - } - }, - "signature": "30440220550c0ab565ab2de649ca7a2aaf2975453a1e4ab8b0d392d69663c0c9b6b80b7b022039047d4d1bf4e9b167a95adcde0a5a8631aeca060dfd426da28a10d968fb3a64", - "id": "aa2ed932faf4832848356beaf87e5381ee56a1a84fb485ba975acb28f8fcf5df", - "senderId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_50", - "publicKey": "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1" - } - }, - "signature": "3044022038df37ef25928d1a04516e982c99f49cbdc193603f814b48ab3802153bdd352002204c918915a3cbfa305c5f898ae4bcdd75394b57460f85c80daa0999751d466c08", - "id": "d30a726e1bb8d199d8f44700bc999c9a0a1a8be86e4be6a15764ecd424f9db1b", - "senderId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_2", - "publicKey": "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d" - } - }, - "signature": "3044022028dd44b9609b0b599c15a257757fd068f9014e33947c77776a6fcbe71879271b02200b46fd8eb0827da6de13f5efd63b17f29e8ba4600e4a690ec31eb08bf2d9af33", - "id": "1410b8b5f15c05528013378251bf5da30e04c8a6b7ac0f729b527664cfbdfbc4", - "senderId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_25", - "publicKey": "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964" - } - }, - "signature": "3044022038edfe34f7b89b4e69ea8b94e3335063b60deaee28246932147f53b2525924a402205b89f5e3d956aa49f24f81e2ba3447c19bd5c026568b3bef73a7a7d5160ad661", - "id": "58d14b74b71586e18f0499a50004ec2e0cc2e5b56aa53f4cf57084030ff90fa3", - "senderId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_39", - "publicKey": "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5" - } - }, - "signature": "3045022100bc1e477994bf4cbcdb5cbe2bd92c7d955a03adfe562f8e3bf04d2f62965e9f78022045512772d8453314361161b2bd2a39aa0a7fbb897a5a83f4c7ab54ced615b42c", - "id": "3ee53b3f1455ef0ddb52afe08854c9d87f42c7313babd3e05bb3ca4f94c495ef", - "senderId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_13", - "publicKey": "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f" - } - }, - "signature": "3044022052fe00e8e9f05b1d890f6910beab0627c823eb2d5875b4b9813a33aed11edfb6022034a723b827ce0e73bfdc0f535b244ffc983f8d549ee72b4d432de90d658db72e", - "id": "4a3d204c2916c93360d7bb11390e355bc1a930e3cf503965a45253d65bfe928b", - "senderId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_1", - "publicKey": "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37" - } - }, - "signature": "3044022013b2798a4ab4d741850abac10d962360cd4ab6a47dfac7c1c806d6f9c3d810cc02202742414ad8a04ce679b445fcd040fb877bbfed3d2692b873dec8cb46c01c8c4c", - "id": "7d0c5a44a7517f6ad7a1253db45d58e85aa1c735a282a32f45d28efdb7869d7e", - "senderId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_45", - "publicKey": "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b" - } - }, - "signature": "304402202c372b7b9679a8fe66f952a1d47d4327968d6e98770b215ada2fed6a8d87ed5502205a797fb511cfba557255dd37e028fb40981b7b65ad2ce8fe0e559a46eb274bf8", - "id": "70bfe97ae7452dc752ab4de0e2a0e81bd18bef07392c56e7a101257683d4d932", - "senderId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_7", - "publicKey": "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0" - } - }, - "signature": "3044022058851712200f7386d6b3c188444f9c8f05788667649ec17c71b9e514206eb105022061e6a4bc4cd11599792e03298f95509893d56af54d51e9f639981045e754b974", - "id": "f6f90ff09dee5be7d8f3d58d217772df7a95865bf8609d7d5b0b673e9a5bc953", - "senderId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_27", - "publicKey": "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d" - } - }, - "signature": "304402204878d69a166e60e0a779c31fbc48c67b70d2e4aed1d63c60beb9f070963e2894022078c46b6687f23493a4c2ed39709a183a0f7352568cc9cc2c1f0d7bf0d809a4a4", - "id": "f68809e407d20a50029fe460d411c866b79c7e09c076dada768a38d81f184aa3", - "senderId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_38", - "publicKey": "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294" - } - }, - "signature": "3045022100d5576393a1dea704cf79a5d0bc2757a3a5e66e1055103b52157fca05fc5693ec0220522832ce0e31b779decef83ac8ce764930de927df9ae1d6f6f99a3312d99c90c", - "id": "2ec6c6f33f00431ef063fbb8a79fb90eadb13a79bf46e6e1df36dd9434314df0", - "senderId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_14", - "publicKey": "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24" - } - }, - "signature": "3044022008a7d0bfe9c4c150566ddf701d08e84b4a5f84b07e3b1c91dde1cefa16d2a3c202200b787e898c0b2c68f4343e74f18ae7363f62b5f4ef2962386932aee09a9fa0d4", - "id": "e37b3efbf034bea4c852be7d7013978f8999eacc39549ceea775de197e14e8da", - "senderId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_28", - "publicKey": "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28" - } - }, - "signature": "3044022023b6fbfa5f4482a4dcc34411846696052b1592786ca87243b7d3344fc9fe9954022035402fbca22691de2497552c743f0f68c7591edd1bd7954ab7639548fcd558a3", - "id": "08268f5e6c15cf146523ca928f24aca65b162f363593d927c66144ee5df297cc", - "senderId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_48", - "publicKey": "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b" - } - }, - "signature": "3045022100b3cad169f29a3a95995b87e1b50b35583c1bff91d69cfa236f58ce452491c579022026775f4ef50b50ecf6d78b530b4633711394983456e6a45ec227b652c86e3014", - "id": "ad94ee2ae94813a638b93909930c7cc631c364b6c8528b2dcd6fa8f69260cc2d", - "senderId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_4", - "publicKey": "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93" - } - }, - "signature": "3044022007ac9ff2f272f3fda4947393b8688586cc8b2958ff5dc7931ac8f82c697bb76802202a66c28852bbff86ef17ac7f51e7eee52e611e825d91a9846f531ab3c3115c81", - "id": "76fb1984da9ef90fd7d588756163c97e00d3e4d6e9dfe78d9e3d3cb6d71ddd38", - "senderId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_29", - "publicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252" - } - }, - "signature": "304402204416e428688ad29928303fb2b00a26996cf79753fe70fb91c1f4635c644ba859022068ac5eab7d05f87c40ba36bd9dc149607c196778120c061698d7ab64aaade7ac", - "id": "0f442a91857061e87dd193b0b9f17a71719ca7e3da62841a63568713fc12b5e7", - "senderId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_37", - "publicKey": "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4" - } - }, - "signature": "304402206a248caa5949024202f297c38cee18845e344c5f140be74349787097d3b0a33c02207ac84336e02592bb5e00dcd0c490d30eb856b34177ab9ac03410d82a355a7b0d", - "id": "eed30a45c350fdffc5877458f7fe29f28dc4bf81aa1a197d003c9433148b71aa", - "senderId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_15", - "publicKey": "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca" - } - }, - "signature": "3045022100c99336ce666cb4a6db3727a61c04c14d8746365f72280d9984441b7d2b568b5402201759e4f417f683743e1d4a14f8a7a215009321cdfa29834b2dbdbe54ee22c1d9", - "id": "ecfba14a58f9d79782c4f905646df28bf566e3e7d1f17b39df6fe6b52c11de59", - "senderId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_30", - "publicKey": "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883" - } - }, - "signature": "3044022070de7b4d4ce64bd605c9d008142544c2b113cc84df07ed1982e0adf3cf69f4520220211b01710a6533a270dc2814c7f968adf27eb6dbf437e7a72960b013b9651a0c", - "id": "36ce5323859a92f302f77f27bd08ee3485d720f55842ccba353a47ea96a964c2", - "senderId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_44", - "publicKey": "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c" - } - }, - "signature": "3045022100a7c271633ecbf3c6641c7db36913b5fa0ea521f400a4848edf024648f3d7128002206a271f8a88644062b64d856407af9567c0b2937d4a3d89a3b3d07edbd3a0f177", - "id": "e120452e7c56a9327b2be7dfd3dcecae193f2e2e772903008b03cdf00146ebd1", - "senderId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_8", - "publicKey": "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564" - } - }, - "signature": "304402200394b6545015bcf2d0f291de57a4197cb6ef57b2ad5fa37f05e8a220913ba83502204d0d2f2206edba54ada5b8e5afd194ba83dd1bf15f744258409595251dbe3ff0", - "id": "7d15eee8e4e3be3d2c44acd51b87a816bdb593565d4ac358dab24ae9c8a5bae2", - "senderId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_31", - "publicKey": "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2" - } - }, - "signature": "3045022100989eb331951a13152aa03583efc765499e836c6fbafcafec4302b243ada8de5002203876fc4cf7fdeee4a095667e55a2fef84e5a7053e807b4d8e029883f0d578019", - "id": "baa686d521f95d265e7099cfd9ef14e0a9a92254dd94c16ce50c460bd013c588", - "senderId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_36", - "publicKey": "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e" - } - }, - "signature": "304402202be177dddfad323302565a866d38a3e7939e0234b16e7dc02075cf258502eba302200928a139ec1a82b4609fcc1bd6d1d027ad050e93fcd2eff94181936d2d43e39c", - "id": "9fcf7ec6fe98ed94710e212226d8b90df7e7467d66dd4c5c9d48474388be3099", - "senderId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_16", - "publicKey": "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9" - } - }, - "signature": "304402207b4f8c09a728acedf3b6ba0632e12d01670c683215053e49dde8598954d85a9a02202a7d7930baa17c2134b314e47dd6c334c828f78e573a2bf92fcbc1146d630541", - "id": "c35e4b1e7a2435664fc0939251c2052633ebf4b51fb22d15e71bfcab85b26de9", - "senderId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_32", - "publicKey": "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055" - } - }, - "signature": "30440220127d27312345e015c681adb799c1a87d16fb0caaabd5020b39257d567816b91c022018b2388f6d2d9afb3714d84ed102b3ea61159772786033c855947613c7ce7b5b", - "id": "0d682a3a9c252a674043bee5240e456dae2685d76fbd3bdeda6ff50f0c442fff", - "senderId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_51", - "publicKey": "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a" - } - }, - "signature": "304402203d0ee691830e4d001553bf4e49b6d9669b3c959376f391410551c8adc679dac902203ba6e275bf6d543efd19d20428649f802d9396bb0967114a1f09c24827be1da7", - "id": "ec2373b0d609ae72fb400ffdfbffc59670ebbf1c15f59c0ac22a4030dae700e3", - "senderId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_26", - "publicKey": "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983" - } - }, - "signature": "3045022100f2cf77b0510f589b5aaaf2b0027ffbce6ce8d4873cdc67dc8900865d156de3be02203c22e30945618683182f3d3873e6b3657e0900b062f866bab2705cd593669e79", - "id": "3cb2f0f7d05a515d4c5c873cbe96e33b1dfba1b7718e4548de7f9da54933b652", - "senderId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_33", - "publicKey": "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe" - } - }, - "signature": "304402201e328159172d543d2225c247c6b728800c52eb724f67c0e919f6b7215e6bd7f2022075fc02fe0b14a1499c5602d87ca2c99d6e789beaceed2b9702060dece872d14a", - "id": "2fd77e744399c9632cc8f106c39237f201dafda976f1040235359f99eea3b832", - "senderId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_35", - "publicKey": "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e" - } - }, - "signature": "3044022063903d82e8bd15a6741a298b9a6007d0dc3626acfe2f072c3b624ccbf91ce3360220486ba4cc5591d8aa31b77dfde025b61691dbaad0feabe13e840d26e40010c5df", - "id": "5baf9e318c9e4cb0513a21eaea27e51c849f95fddc963207fb07aa2fd2b9f9d4", - "senderId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_17", - "publicKey": "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357" - } - }, - "signature": "3045022100efc1bc16e0b646da48f84822543b62ef5253bfa98bed6613f2d6d4634076e61802200ef243f9dbac7633a8819ce45e2a85d0eacfdc9a33a92bd3a03e90cbd312b823", - "id": "b4a959ad75f81b7fdbb957c90a3a63a6c5589e7819e2c455733a3a2b4b034634", - "senderId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_34", - "publicKey": "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80" - } - }, - "signature": "3044022012e52a479648990bfc1ed12bf901cad865708ff45962c3724ea67967be4f9d0102201901525ed8dd090af6a2637c123afb304e9fd178794addcb88d916227e66887d", - "id": "6439f2308efe31ac52ad06ef1caa45b9abf6c589118b7997da6a287325ca36e7", - "senderId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7" - }, { - "type": 2, - "amount": 0, - "fee": 0, - "recipientId": null, - "senderPublicKey": "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e", - "timestamp": 0, - "asset": { - "delegate": { - "username": "genesis_43", - "publicKey": "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e" - } - }, - "signature": "3045022100a0874d1582ce210081f7ab30e7f951dfb9ce8f512d237f8a8cbd5d85569ef3b902200f0053c05de3d6e5ada4e4cf1403a836779d653573c2f374055645cc954c4c4a", - "id": "b0733072e98d3d6afe977e32f3dd118c15e79212232417743ffb551dc2a2ba55", - "senderId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW", - "senderPublicKey": "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357", - "timestamp": 0, - "asset": { - "votes": [ - "+03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357" - ] - }, - "signature": "30440220158ed59156e0eef2d2b94a296451dffe079be701b3d74f0443ef43bc266b334202205a2c39f57abfcd279d568608b90884b3ebe107316aa7552eca35c743b318a47c", - "id": "ea294b610e51efb3ceb4229f27bf773e87f41d21b6bb1f3bf68629ffd652c2d3", - "senderId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7", - "senderPublicKey": "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80", - "timestamp": 0, - "asset": { - "votes": [ - "+030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80" - ] - }, - "signature": "3045022100898da9f693a458a6875344c6c4cb73069c4075904c75595ffbc665967d84b07002200f168aaf3ab1b52dfa74599394387dc4cf627a447fbc5a91000e9d251cdb20c0", - "id": "3639b5dc6d19d46d8254d941bf7ace0f3da8a7cf8a56361921b260820c7239cd", - "senderId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1", - "senderPublicKey": "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e", - "timestamp": 0, - "asset": { - "votes": [ - "+032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e" - ] - }, - "signature": "3044022055ed9a8b55ccb3bd0945a710269b6f243f1dbfaa28467d3218a17565eb0c962d02207d31561478f16d93a20f5454ad565dea24e8dda4ddc464cb011f4b6b360c4e81", - "id": "fe24509580cde0c2e2f49defedd3a0f7572d2f78f90b51a253b0d8cebd74c20d", - "senderId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof", - "senderPublicKey": "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055", - "timestamp": 0, - "asset": { - "votes": [ - "+0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055" - ] - }, - "signature": "30440220092f367f833d677e8d0609ad1df65f389c2c35d1501c71c245c2982e6a832268022018e67445f525613d6cb6ac0c9683bd0f55bd40d9c929165649414f083c9041f9", - "id": "6a76553db794ebf4d5f60a7d7d71cfe29f4dbcaad9610106fbc578cdc7167cd4", - "senderId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy", - "senderPublicKey": "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2", - "timestamp": 0, - "asset": { - "votes": [ - "+03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2" - ] - }, - "signature": "304402203dc028b5013c36b03f97b111a8d7c05d0cd8e505b0b0d18747c0656c9b5cfe8102205e9ce8a78d1183b3e9880c69635d04218d94d17808bcc3f92e7af53195c23daf", - "id": "0f9d7e7708918b77afbdfffb63eef8fe87ba36e0131c88b44c1a7f81750cc025", - "senderId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9", - "senderPublicKey": "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e", - "timestamp": 0, - "asset": { - "votes": [ - "+0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e" - ] - }, - "signature": "3045022100a80ddd7c3adaf0e97ab938773fc78a716f3054d7e03afc1ddfcb5005badbd2810220231c0dabe2262149f994c939f9dc90d46b9bd7ca96b19aad6788cd3571e4f71a", - "id": "0ac77b2637fb25be42b3b60d1651bbbd788aeaba933a08ec4a417c7b4c54e087", - "senderId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT", - "senderPublicKey": "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883", - "timestamp": 0, - "asset": { - "votes": [ - "+02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883" - ] - }, - "signature": "30440220772c9cd8b96f74fcddc429d57d466eca6fc40fc211845f59eeb78cb027e116c5022004cda291587eb118d622de21333d2a5783969794b5b0101ad8b1044c7d8058af", - "id": "4b0dda465564d53981c0e36d73caec888e3523633eaa80dfb99a9c81b2604c7d", - "senderId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU", - "senderPublicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252", - "timestamp": 0, - "asset": { - "votes": [ - "+0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252" - ] - }, - "signature": "30440220406d54714b6425ae4553ea8bec75f31fe52e9b1a9b6f6897151253ab7f637d3b022040a2df4b69840f4d9b0b67658c75efdae8d8269780d4cc50d055fa63922dbb9a", - "id": "c7db9d36d97ff0168d0d670ec695e1dc786dfb93f4081586870c8793b50e5f17", - "senderId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK", - "senderPublicKey": "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4", - "timestamp": 0, - "asset": { - "votes": [ - "+030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4" - ] - }, - "signature": "3044022018b7e51118ec83c985fa4eb3d7f0cf0655753bcbde7e82bac521665fb1c0ffaf02204e2ace460b2542db8c77e41d05d5e02fa5514b746a0a1e947256925846ed19f1", - "id": "c41f4cffcdd523f1718154d5bd5f4f0bec0376076b5f8dd340337e9edb4821ae", - "senderId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW", - "senderPublicKey": "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28", - "timestamp": 0, - "asset": { - "votes": [ - "+03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28" - ] - }, - "signature": "304502210088dbe249503da43c157485bfd4f2c95babfe4d0b8bbefe44afa52529b824a79e022045239b6a374fd9aca52c27171ee66b4863c956ae4085c9760d863b1902596c1a", - "id": "b1736ec6a1ea4c6d4eb278430a8ee214c88daefe296ba98530e692f8b7a7434c", - "senderId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej", - "senderPublicKey": "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d", - "timestamp": 0, - "asset": { - "votes": [ - "+02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d" - ] - }, - "signature": "3045022100fcdf750a775e728a31691a1b38908a7f990b579da510959cc2c63442f5ffde760220316ebb051d9fecb2486771dd39921fb12675b6d46b2441dd1db3c42fad0a59b0", - "id": "069271456015c2ff842771775993b8afc3404bc070572eeeb0f2fd72d58e18dc", - "senderId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U", - "senderPublicKey": "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294", - "timestamp": 0, - "asset": { - "votes": [ - "+0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294" - ] - }, - "signature": "3044022034ce8f77ea9d0f5cf3a9135d7b72d0ba3b96ac6d7eaa3670e9956aef2c9a83cb0220626d1f269128f673a23f9993ce00ba78a08103e697298be29a4c8ee94f204e3a", - "id": "9a99bba8340e7ad4e05d8424a0977ebbde428d31ee066c9828bd06b42bb42a72", - "senderId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2", - "senderPublicKey": "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983", - "timestamp": 0, - "asset": { - "votes": [ - "+02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983" - ] - }, - "signature": "3044022039ae1155f8b87a61c38b25cbbf30da6ecf6cfcc12b25c2e7fe576373754a41eb0220061a66a893129fbad5d48cdd19cf48b1a0d133dd2f3ecdc60ee7b87277e1f81d", - "id": "6c2c8926420ac269b50fa30127e0e791afb2131aff5821ca7aa80d38a0182048", - "senderId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf", - "senderPublicKey": "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964", - "timestamp": 0, - "asset": { - "votes": [ - "+02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964" - ] - }, - "signature": "3045022100d0dac2b7691aa059b1048d7925a0c5d5099f6e9b0f2e321e6d4f128ab1b3272b02207e8c4f643f8f9d1c3f81f0cce6a698df2da2ab71d5b01042766bbe0f46f4a775", - "id": "9259193c5de72276ed7a99f9d507dd6ea9856411fda521074fb41a556294fdf7", - "senderId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9", - "senderPublicKey": "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5", - "timestamp": 0, - "asset": { - "votes": [ - "+03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5" - ] - }, - "signature": "3045022100d5496fec447367ab6b53956a8c40cd8566e050ebb3b92d2c0b2a9d09bef36c7402205e32367605372375801f7b9db39aaafb46ee763b1494f0aca144fb91f3415752", - "id": "2a41e5946ab0773ca2334bba9d3510184bdd258f1c651ff8ec95b7b64a01dc2e", - "senderId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW", - "senderPublicKey": "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95", - "timestamp": 0, - "asset": { - "votes": [ - "+039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95" - ] - }, - "signature": "304502210099249695dc38826e04c8fcffd2570b98c43dec4788cc6a19737ed0872f17ec3302205301f645d803ad5df4ab1a700446e28c7cd76153607f6a2d68ae9168d46f3fe9", - "id": "e5c09b0fb2c24c57a4dcef0078953093800329ab4dc8e16a9d9f68215b5acd3d", - "senderId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU", - "senderPublicKey": "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a", - "timestamp": 0, - "asset": { - "votes": [ - "+034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a" - ] - }, - "signature": "3045022100f983b03e319aaa6c6ab6381e3ef8c0c035d6e3cc2139cedf70fd4e385393e38a0220286f73577765eb3e89e362785ad8a6de572bebf41bbc1f515b0ea93e41801eb3", - "id": "00b2c0455ef6f508d65f11bb49e3cfe1e6062d5fd153cafdfdfd2ccbf9c646e5", - "senderId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr", - "senderPublicKey": "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689", - "timestamp": 0, - "asset": { - "votes": [ - "+022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689" - ] - }, - "signature": "30440220103862ec51621ca27a0ec6b2817848e8824d2d09dbf7e6aac2f45aeea5d2dc9102205e8cce78b5cd7148aa4d406dc7b491dd7758047200e10cfe1e5fde5c56107ac5", - "id": "e25439ad11cb8db3d49ccb3b8b608c1bcb24cb29b2e5ea15101cce3e475224eb", - "senderId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ", - "senderPublicKey": "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a", - "timestamp": 0, - "asset": { - "votes": [ - "+03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a" - ] - }, - "signature": "304502210099241ced4a0fd1eb02f5cdcc880ae5f48eb3c7e490d4520c20124ecbf403893602204729dc6cacf3e87c97ca57c1be54d1e80791bf31ef022135e68fc06c950f6994", - "id": "1474f50815c6c7df41ab652414806d61abe15bee0d41f32d772f4e2793badce4", - "senderId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX", - "senderPublicKey": "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a", - "timestamp": 0, - "asset": { - "votes": [ - "+0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a" - ] - }, - "signature": "3045022100eccf81d44992c49a5ee37c6fc2ccc4b6bee9aa44888513b3e18e79452ede3156022056b0ddf079d2918d72e8781d3af009c87e6058563591dfd6ee0117b7df5534b2", - "id": "b394e2a8b5c2d20a72ed288408b8f0d48aed922edbee6e16c1c5b0e67517214c", - "senderId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf", - "senderPublicKey": "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f", - "timestamp": 0, - "asset": { - "votes": [ - "+03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f" - ] - }, - "signature": "3045022100bdb87894846eccc5a5473edaee1e6dca5f3469963e22f06123b6bde195aede0e02203d0c6833e87c5e60f4597ce624d4c2502a0562b4e54d943f82a4889e3cd69532", - "id": "6a399099bac6c74fa5e956512ef8b3a39f6f946d5d6996f192c2f1dd5ba172dc", - "senderId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv", - "senderPublicKey": "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751", - "timestamp": 0, - "asset": { - "votes": [ - "+02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751" - ] - }, - "signature": "304402200785771ccf1a6a40b51183a190d4cb4ce76b9ffd4c2c736d7724e6c667113d020220649ecfe73017d8dda96a7914793470ee7e582693e4866df123b1032194c163b1", - "id": "f20a831a6bae0a85470e308fb66517e70db479657459f6bb39f2cd1783c565e6", - "senderId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv", - "senderPublicKey": "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb", - "timestamp": 0, - "asset": { - "votes": [ - "+0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb" - ] - }, - "signature": "3044022020b79e1f07bcb17cae9485b9f44e9f583ca235da4ddd363b905fafb884347f71022015a20481b43720ddb3b1e3ca64b1f47e59b5cc2016a62f43327ca14533384dd4", - "id": "7a1285be87dca9718bece5b84266c1bf6801a39cc111d534e660aef9e6d26929", - "senderId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg", - "senderPublicKey": "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d", - "timestamp": 0, - "asset": { - "votes": [ - "+0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d" - ] - }, - "signature": "3045022100b1615d16763c46d42ca2aae967f04c1c07c119b5af7a378c262ba85515a8d35002202cf7df91676cd137943720e93f06c11907412a6bdc5ef2157cf536a203cf83a3", - "id": "76fb5a1de90f245b1eeb79cb11c7bea7c8b738add0fb8cd95191186a944b0229", - "senderId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri", - "senderPublicKey": "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a", - "timestamp": 0, - "asset": { - "votes": [ - "+02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a" - ] - }, - "signature": "3045022100e3c7b5d6a72acde4d22e8c1c6cd864c549deba89683f4b84320407d6c380827c02202da57df0ab7cd381b776bdf85802aed371e7cea7269a84f911b1d8e9956badee", - "id": "8da75c8100e6248ab37cc92f72ed9facec3067f4f82f03db8bb8063791463fb3", - "senderId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t", - "senderPublicKey": "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe", - "timestamp": 0, - "asset": { - "votes": [ - "+03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe" - ] - }, - "signature": "304402205779b5d8acbfedfc105fedb6fcbd4636713ed27605faa9bd988598072640a958022042d8a8b3d7910c7c385f3707a317c5d445d56da250f8d127c71df2d9d4c5d86e", - "id": "fd26e265be88289828d0ce7ffc5faeb9849e1f4cb37a8f1dd5d6fcc436d910b7", - "senderId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf", - "senderPublicKey": "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e", - "timestamp": 0, - "asset": { - "votes": [ - "+034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e" - ] - }, - "signature": "3045022100e18a89fe1fe0a8acaca2b6461314e784ffebbe7374f6aafdb06934e83985ccbf022027314b21a4a25b477bd7cc070b4e00ef8f3d69f3f1af028b96571dc245924c00", - "id": "41d92e128e6b8367cbf8fd111e5263d52e1abad553653f975dd60d7f7c5b637b", - "senderId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9", - "senderPublicKey": "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9", - "timestamp": 0, - "asset": { - "votes": [ - "+02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9" - ] - }, - "signature": "304402201c614c84dbae26f87973c9e2b38df883fe0c8c469080e31fe32a4c4946d50b67022075b8fb498fb1384aa6be785845da02813185ccf095597b5782618033828af4d5", - "id": "1e4a1f8aab6fbf8682c2b35e0d04e9e007ae717ce3f4a82894747e5807e3c759", - "senderId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV", - "senderPublicKey": "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca", - "timestamp": 0, - "asset": { - "votes": [ - "+02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca" - ] - }, - "signature": "3045022100b1ee6becc59d594776a40e5b3caec82390d273b703ecb0d7caece44953141449022016543cc29a28882845118afab6e51296cd216bc662260c28e5efd9597b6025b1", - "id": "2ce068bfccb3f967f4004e9a1e81614a738e55e45c80114c0af30a085f71a2e9", - "senderId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ", - "senderPublicKey": "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c", - "timestamp": 0, - "asset": { - "votes": [ - "+022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c" - ] - }, - "signature": "3044022036698a329d7f5f751f91ce02bc188a7527a377d01583b70427cfce64def945ec022079afafea10aa32394a1e42a80577de3869856656221d5f259e05fb44f01668b8", - "id": "3478d1ad3655e10fcc864f191972322c866616866bb1dbf66d7b66b31cd95de6", - "senderId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA", - "senderPublicKey": "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24", - "timestamp": 0, - "asset": { - "votes": [ - "+03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24" - ] - }, - "signature": "3044022035fa7be80cf881eefefc12b11de04ffb2e2e92815cf05074afef54a3c5b2eccb022041f3347f59db0b3caadefcbfbc5ae275d3fe3e2a52fe1504b23628d4b79a43bf", - "id": "8adfd8e73e96188ed9fdec459d88db1fb041a2b25b3f64830476aec661ae5010", - "senderId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm", - "senderPublicKey": "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f", - "timestamp": 0, - "asset": { - "votes": [ - "+021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f" - ] - }, - "signature": "30440220630da8a73979bd3988b7f84fe9e83a429cf3239f54c140c3dbcc407140513fc002203664ad54ed9f199f2683479b988bd97ad8fffb2c2d5dfdbdb10858aca4abfaca", - "id": "e306328ffefcd9e3809e7390a358199a62cf8ef037d57af1f5c7b54d728d427e", - "senderId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1", - "senderPublicKey": "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b", - "timestamp": 0, - "asset": { - "votes": [ - "+02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b" - ] - }, - "signature": "304402206f1df93f299ffedacc25aa201807df47d32c43369315cf9db280963c357be56302206a66acd553710f49bbb7b803a2bcb71128c8e617ffce66b37b7c968817349247", - "id": "dc69bc8f78502ba34655ed062987788939189709a4112760cd8807245d7461f5", - "senderId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8", - "senderPublicKey": "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12", - "timestamp": 0, - "asset": { - "votes": [ - "+03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12" - ] - }, - "signature": "30440220629e696a10e04d4fbc10a5ac443bf9bd40dd5d89d4b214224abe47d7ab5600340220643f361a24d9916e2c5aaec7bd7d8a6a0d3ffc5fc0b62c3ac4906eb799a862fa", - "id": "c3f49fb80c40f7779b32ba23616f5573a6ba58fc60c4629c2252933038dd89f0", - "senderId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2", - "senderPublicKey": "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904", - "timestamp": 0, - "asset": { - "votes": [ - "+0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904" - ] - }, - "signature": "30440220660f9604896dad2a97820b0d7524f0bce5a8b5766f150517d5061fd02bddf768022055e87c25891d4480e66e5d1a71e42cd5a4bef3ab2b2651cd72d44f30a4b32309", - "id": "8e8ac1b1a586e86867abbf25d63387bb6dfb793c691f0b06333c1581a9a568b3", - "senderId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT", - "senderPublicKey": "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c", - "timestamp": 0, - "asset": { - "votes": [ - "+034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c" - ] - }, - "signature": "304402202e2ad64129f61ef1156c4c7e80ab862d4823d62dac502685f53028536ddfb41a02201a3ec777fdfe8fae9f7cd5251fac322c1b6a2a4d41b3ec456daed474986d4872", - "id": "ff73565c373f2cefebf86c72dda3a6a6205750eb03b69178cb83378620715e1d", - "senderId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q", - "senderPublicKey": "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd", - "timestamp": 0, - "asset": { - "votes": [ - "+02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd" - ] - }, - "signature": "304402202e5c78cf21a088db10e1e1f64d98d84c8d3294fde7bc322d4af06bfe99d4c2e302207e7912a16a37b641a9f8c7c722f2b0d699917ca73e4d0f21584b717fb7f02f13", - "id": "3822273b496f2e253081cedf382e4f9937713fabb83449e1f892377cf536e68a", - "senderId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo", - "senderPublicKey": "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647", - "timestamp": 0, - "asset": { - "votes": [ - "+0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647" - ] - }, - "signature": "3045022100a65ce45164c9bc3e018e26703370c9deb2933ee3b4e814619043cc37c4a39c4802205ae4931ac9e8dffd714c3b601fe248a49c0185c8367887205f497d951c52eb54", - "id": "430d6db0b87c25dce4ce14ac907c13bcc6efa5d95135f05aa4ba7596ea9d400c", - "senderId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN", - "senderPublicKey": "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd", - "timestamp": 0, - "asset": { - "votes": [ - "+036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd" - ] - }, - "signature": "3045022100f3cdd7f688ad2d7b6a5b9cc7e793cb8a6e6e07d3327bc67add64691a53fd2911022026ae1adc8f4fcfc01bcca3efc83019026755b443a504265ad1f46f69d1f5951c", - "id": "dda86ecc0332e6c4eed1c0a5af7424374089b85dd274a300fed51b86e2655587", - "senderId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj", - "senderPublicKey": "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564", - "timestamp": 0, - "asset": { - "votes": [ - "+03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564" - ] - }, - "signature": "3045022100d419072a752acd55792257c96099fb14c56c29112a00535d39bca96fbd7951c902201abdf4db247dc956d79f4543c389823fbd1a9337f95d30df39603a3b52486bfb", - "id": "0998e9a055c53bf6697ee76af94c7a830c1364016d78fce889a21bc38ed70cd5", - "senderId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN", - "senderPublicKey": "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0", - "timestamp": 0, - "asset": { - "votes": [ - "+022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0" - ] - }, - "signature": "3045022100ba1e0ab761326d2a53cbda2a4a5135033c94d8166864d2ad3ceb963b4a0c046402207d755ecf4ada9fa2a598fd75e73a59d30cb83e01f510020b48b6bf162dc60b27", - "id": "be13743deb8486a575d1fb564d2b07d797ac77148d35793c9aca43c0d47aad61", - "senderId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA", - "senderPublicKey": "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b", - "timestamp": 0, - "asset": { - "votes": [ - "+03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b" - ] - }, - "signature": "3044022038a491e2e13ac32025209d00aec1af31b73a8b6ee77ad9b8bb80a34f5df59dfc02200ce82c89fe9f88bd5af236ceeaa80f9954e3fb4af7bc884c447505751d49c134", - "id": "f1d3d44cc289837de9623cba8891a1ed1cde8918473a91e2daead29975afad22", - "senderId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx", - "senderPublicKey": "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc", - "timestamp": 0, - "asset": { - "votes": [ - "+0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc" - ] - }, - "signature": "304402202ae599ce389cd030b8ab48ef53113458b9ba8bf9c9ed09c662eba2849bf540f802202ed63f8af492dd0b67d1b451170a989418a42466a3a7ffe89c4c5a18337e8fb9", - "id": "65ab302a44ea7550891eabc3b4a8d5ecbcb80784c4666195d5d0b7e33394300d", - "senderId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK", - "senderPublicKey": "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565", - "timestamp": 0, - "asset": { - "votes": [ - "+026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565" - ] - }, - "signature": "304502210088a3a4e82d307c238e01ce154b57631d4429e0b591e828ec36839a783736e842022042c6e1d719781e2edca3dbfe84ad13b9e490821a47ccadfcff379decb9c873c0", - "id": "d26a7ea56f398634a81086bb15c2f0c863c71b8bd728304d324d8245a8fb6c73", - "senderId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz", - "senderPublicKey": "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374", - "timestamp": 0, - "asset": { - "votes": [ - "+032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374" - ] - }, - "signature": "3045022100ae5805541f085a50076835422b2581d3b7a128a05b4f068ad7e3c14cd02799b802205f4bb40e06f90e02282ae74c0aba97923e601fd78234b9585468c4fb73f47893", - "id": "02504eae7ff4963c081219523bc48d7a07de4c29fdc1622224547f9a7c133abf", - "senderId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp", - "senderPublicKey": "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93", - "timestamp": 0, - "asset": { - "votes": [ - "+03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93" - ] - }, - "signature": "3044022078d38cabd8f427ef381d0aa6a0b98c6a590cb18f47acc1d80b429a1c1959b0ab022022a70d4d93d650ca3121dde6065e80cd90d1e2e91cb90f0d0b2eadde609e0d75", - "id": "addb8c1baa833baa52a5b51d8a86f8524bde826b5c9f0a99e57070e6323e1dfc", - "senderId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv", - "senderPublicKey": "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17", - "timestamp": 0, - "asset": { - "votes": [ - "+038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17" - ] - }, - "signature": "3044022076dd065e3fba825b77884a179d0231d7fc9e7d3a02e34bc6565fab81a84e559e02200a880c028e690a9d6f2c4c6576b1bf3e913817c834da8ec6afdbadfae78d341d", - "id": "72f31f9a829b93045ef2e860b24c33b9be6a2621c26914acd42121215c1d517e", - "senderId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P", - "senderPublicKey": "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1", - "timestamp": 0, - "asset": { - "votes": [ - "+030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1" - ] - }, - "signature": "304402205261d9d8ded6364fda8b10bd477982be84990cb010f9214d52c492676814e1f40220489f441ffe2478d361a12ab96caa59da495fe62d61d0e2255aa5ec4ed789afb8", - "id": "1f17b4ba072d205761ed3f786491eaf684ed3601b69082e487e568aa74a319e8", - "senderId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd", - "senderPublicKey": "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d", - "timestamp": 0, - "asset": { - "votes": [ - "+02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d" - ] - }, - "signature": "3044022040219da41054a3eebd3122df7f09a62a4e8b4fdc287ae77221f2217b42f291ad02202b9a70c54bb546a604eafadcc086ef6b6570f57542374d87de02ad7f61fe51a4", - "id": "5fa837023159d6a3d6cf7c5b2ed6fe05ff7df19300226b2f0be5a48a06993780", - "senderId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo", - "senderPublicKey": "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37", - "timestamp": 0, - "asset": { - "votes": [ - "+03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37" - ] - }, - "signature": "3045022100ded426768f114f459485ba6ae293c9649b340cf2dcb15e8e887fbb5fed6f7e0b0220752297022de6e93ff64bb9e07b4efef8e946cd2872f84d9e1cb3165ff5c342cb", - "id": "0a16dc31514629a36d7237968ada6a95d6cbec027b7d26e1e0f0d7d4febe9494", - "senderId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo" - }, { - "type": 3, - "amount": 0, - "fee": 0, - "recipientId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD", - "senderPublicKey": "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a", - "timestamp": 0, - "asset": { - "votes": [ - "+02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a" - ] - }, - "signature": "304402203aa292e7aedcd62bb5a79c2521b666b8e1886b57923d98f51911b0461cfdb5db0220539657d5c1dcb78c2c86376da87cc0db428e03c53da3f4f64ebe7115998f00b6", - "id": "8816f8d8c257ea0c951deba911266394b0f2614df023f8b4ffd9da43d36efd9d", - "senderId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD" - }], + "transactions": [ + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402205fcb0677e06bde7aac3dc776665615f4b93ef8c3ed0fddecef9900e74fcb00f302206958a0c9868ea1b1f3d151bdfa92da1ce24de0b1fcd91933e64fb7971e92f48d", + "id": "db1aa687737858cc9199bfa336f9b1c035915c30aaee60b1e0f8afadfdb946bd", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100ffff4e9ba62e5e3beb37deee052824da83c4030925bce09f190151652d0669b8022056a432e56a2e1b026d4b54f6c34ce88a0c9cebdccc730659c03449fe878c66f8", + "id": "0762007f825f02979a883396839d6f7425d5ab18f4b8c266bebe60212c793c6d", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022001a6326e5d1eb06d0ba1fa39446bd6d56ea45f0c269ebbce5dfc6a649277cfcc02203b252d3a6ef2b22349d9d0a9110ce28a199c39dc8b911edfa82c297a02009d07", + "id": "3c39aca95ad807ce19c0325e3059d7b1cf967751c6929035214a4ef320fb8154", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304502210084d855eddfe616cf1dc238b19226c7959c2fc4027ae2e8aea6fd8e9eb8928e6b0220440f980e40c1c56348782fd69d49a96944df7ee5b68d18028600e0e7501d4000", + "id": "9fdf6ae86f7c005b3b7dc1b9fb6411219407ecaa93adff85fdb61710f5121638", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402205438b8b9058bbde5d30794e7681e400e52b5fbd22324c5b6b521f97bc8b8aabc022000fe04d7afbd2e668b1d4576988ed596dc92251e33efebc081e2cba14ad5a898", + "id": "1d7c68087c875d7ce555b2c3e71e1d91a1ad62d0c2497efe3cab91415e634041", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100b2e634a95b011a68489870f003e4bac4a4f0578bfdc6b9f645c934016c2c0463022022cd4ebf276dd627d98be4b697bae2df10b86d94e984da2eb7e011b08d6dffd2", + "id": "0c993e115ba26981b0be9d22e7c4a13b0f106e0cb472f9d34eabfc8e414dd528", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100f965e5c280acb22d1cde405223fe9a6fcb765844adbc5321b17a268924e1f597022043d31b1edc5fe0cf60a960d84e3528472cdf34560c9463979043a409f37e7f29", + "id": "c279f2eb1f9e6e7d4b0ba7a98233a0f1a2536231976c99f56f64b248eb06a0c1", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "30440220715463c316a75959dbfb6a59a013fbf914bef1ff739ac8000d49dabbf5118df9022019345ae1c34173dc214bae82f3cfbf438092f0fd2d277acafe3e9deb644b1a3b", + "id": "7e2fc9ecf23e909a3d0fbecd615445a0eed8c2cef18e01b1492d63f616f5d87d", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100fdd8aff26dceeb5abb6e5e8a8f468c8ac1997a587225298e3d8135d57dadf4dc022072ab80a81b301a162ed5cfa67d213d5a3980185088632f5f592351aff8aa0e9c", + "id": "511c0e1076104743f98932f8e7720bdb3f1539134edadd331914fd9ece1ebede", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "30440220635e04ce278870f17fcd1883aa26c568e63dfbdd302add39aa30fd3637c79c2c02206fdd9e7b1f4d238a97d26ef1758927e2d39f121687490f2bd79831e36afdd43b", + "id": "0768d5016c53d884e3d68a09d1bab0d730b7067c71ef4ca1c4d61b3815f5ff66", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402200b1dac57ca6565ac31afb99686f2e0f0e8dc219b9860b295ca5444a1663cecfb02205787393561fe407449af4aaf2f621db9e4d3f11c7438666cd694d495c0a0c41f", + "id": "1aeb50080ea118165e5041f7a897974c2ed1ebde08add85dc78cc7cf73566a91", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304502210098dea25eccf31ce6f874a9528578805aaf07be8b41f1571865793f9e3e6e3c97022033ae9c73dad44c01fe6362665fccf63bb1a0ae8e26f77a1cf60b67dc96b05343", + "id": "254f0f4fa277cc651a746d6ac371eb27afc3ea155ba060552dd26b8e83d17b72", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402207f4bf346aac501e766156818089fb16905a9bdca69ff6d5a55ba918a08afc7ab02200ec2c25cc4bb30e2c176d55630d8e2679b899c14ab4ba43c3d62955dd940425b", + "id": "e5ebb02e8e8a6708e22ee5ef99fe1dd8b6eea1095be6b772aa21bf63cf7ade5a", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100a0bbc15bdad648bb9b439f1d34b12b853442d1cfd4ce7f569905082801fa58e8022036b4e73edf7ab7226f8007233f77b1d497cb6b4736f02721bf1b399312ebe114", + "id": "8a686b21477b64dfd85f08f8598a0f121ca1c7d65ccaca9e42326c75fb5f3abb", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402205d77dfcde527dcc6669bcb01c27b92c1a6399e35ebac9e69415645f596ab1d2802204179497bfd952f44d5f9e295b2a3219a290a4a82841c084a18553b7712e26415", + "id": "21175347e2acfabc09a7593aae0682e39fe7152199a90561c11125f525211243", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100cf77c16df9185727ff717b71a94f8b29ceeae1e5bb3a28da8cef9df5bc63b7c202207bca394ce9ebd344a548e5a5697f672dedbef640dc1f9105f7c063287bcd1840", + "id": "ce1d9b7377551f36568127f5b635b5443f5a58abba6566b50a8d4d7b53c8a874", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100eb8daebb5484f3b0a738c9344fb28298c596f9486963f8fe36e2501ee6876f2a0220559df66986dc9a9a8e76982ef85f907c62745757990c69f0b17b6ae5a7ca4719", + "id": "b56702f5eddad0d8dbbb33b6b1ca3e07e4740def9c5dd2aaed9a70b90a4e31b7", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100d088e9bcd78978f2d67e7c7bccecfb73ddd0d1a2dad5b039390812320355722d02207affe83d815f04f6b11abf98eebe0488bfb87f8cd6513d44b829008ed1c15ceb", + "id": "a73c053c42e83a83498cf58e5b077b31443e265ddf8228081cb17a36bba366ae", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100db16a8e9682f07efb607bc7c75b654646ff449761ed146ab9358e69d29fadd7f0220436554ad78db0e04ae5b573258e2c8067848e89b55a6e8e1e25011a43882a643", + "id": "2dccb8b44ad2e598673628fd9d74e336b467a0c941d5e257dceb85c8e0a0000c", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100b03738eccce8ad0b8ac0a656119c2cdd202089c5650d8e1486bd13eb9c3158980220059079900c7fdc16e799c50dccc074726fbf0068044462faabdf1e73f9f9bc38", + "id": "b2cce30021d139f97925807da796722bf4d5459442523823388c259ca5ad73db", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100becb49fe5edd6806d5ba6eddbbb34ca8eaf3a12dba123d1610b2b120ca8bd017022072972992ee0ca0f319ae754a2a5a10d715a08b23f8239f9d6d59774f790543ea", + "id": "9e4841f43ab355be7a4f93b09f3d82c17065fbe25387dd6c5eb4e2692ea05b0b", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402207f1a3fe8c5aa7a77a58ed35c34f128b5df6fba89aa918af35eff432be7d1f8e00220460d4f2a457e1a477974157e33bf2974de6588d56e59729ae980720e9794827a", + "id": "2c7ca823be21724a4876de632dded3b9afca45df357819ed028488128d85d29e", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022067266dfe9d8f2550b590e1eae2f73d28c6b80fecb24c3eb1b4539bc864b3b4f4022031e5122145c35874c0c48673d088e76fb3e11c308ffe9d5dee6431d3441d627e", + "id": "a91119f04e2201184761f7fdcb26e4aa81c7e1076cb11a58a422d351241d4e4a", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100b970ec89927de0cb7805e614a742d42c2967db5a9c68d0892956dc89d68ca7d1022067fa30265dd2e1a2985980be2bf876748a7a8c7f3cde0382265b601fa658dc17", + "id": "94955e6bac6269fbd19e92d2292ac947225fc6f68c6216001b528596a961040c", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402203671b82ddf8a824b8e5aac8bc28be4aef1c00aca1097d14ec1a55003d7a3f28d02203aacb6e7517e916478432b81399828ba7425183ce0fc43feb361bcf345fb0519", + "id": "df563ee9822bd3d7aada600d4800952743ec64fafdc7697428d7a19a60745885", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100b77653317c93eb20ee19c71e64a7f9ecb985351bfb1fe351ac65a5738cb37ae202203d540395e1d55f87caaaa867afbfbaf98c553be0b4c7d1748418a76b0c258c89", + "id": "d21b6341e2b4be5ffdc3dd8fbcdf2c576ba02e2ef4ab5eab0e4bfc9da4e9e442", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022046239e39062a58925099b005888355b8cd6700af66972bf509a10123f9abdec60220202321ea74e56177606fc079d19c29851d832e6d00c93985ffbec3dba6f0d675", + "id": "df6bc7a17ad34f8e9faaa2646e8e5dd8bca35affba352537184f690e200e17b6", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402204eeab87f7ecc2097b85606b986177964f3ae777535f6fc0cf08a55fec587d87602203779d59903b8de63511e4ed0a7967bd85e9cb1fc9d84bbc5091e3caa87d8bd52", + "id": "5f0d5f0dff464d0ad587da5bc93e600a8e2657d359d0a1224bdd4ccc3b6f376a", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402200a2b9d0f61066fa00a2a2882379aa8ee60e949bdc2a85103bbbb69ce3eafccd9022057364f349faceb3047fa95ada210c64fc4a81978d66925b37d3dbc21ede885af", + "id": "1b39e3702576e6ad7775e34d53e43210549d52a56b3f246031e6ba4121a66bf0", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304502210099e568d3d0c1b48410e0b85c74d04234dacfb2fdf2b1d4b51fca1cfb3445347a02207a2509645aae54560762a37422b66ba4b3ee1c42de35d58c36d2f9d8fdea11b4", + "id": "0f21e53dbb1edb1cfb4c31bb675aa4672b452a03ec363a2b3300a9dda49e3be3", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022026cc5f2b588a86241badca73cd9c1686916d516b8c6c397c66a9d5bb6b5d4cd402204ab5a8c8589ee954bda4a116999d2a0e4ab0e3e96f0c7fe131d7c57b9a1ede43", + "id": "410826c255a23a78ac5c3aa10dd48132693bc955845af16c20d9c6f69b05dfe9", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402205fedd8d3b5c8d69cdd7db5ca8e9e7c5004f6ba751e45eb1b85b26d9e89800a2402202be56bb2cd824bccf325b6b11432bf6d0ddb5ec97fcc121839ac2ebf884c7173", + "id": "ddb57d8270b2b6c876191c1e1c5974388b9fb3ae0980cb2245d8a7c426237f47", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022053cd42ad147eea33801b2b57388b33f633b4bfe2ad902190e12480522250d07802203066dc0d0c2ffacc4c74cca1e0187fbea1cef7e78a78666d2ec7e4e87ef546eb", + "id": "29e1aedf98935c369946c8dadb2d6784f9ab5ce8d73b9b4de2466c7757e2557b", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100c10448b87e7176735c8ddfc8fb3c4d5d55c2d71d18b7ce3ab321209ec299fd41022013517a09e4b366ab386698286ec7bb20410bdfb7f6674fab25a739259083b297", + "id": "4cf04852529b5525f22cc540790e36e61ed36045ad1b5b788f61ebe42637391e", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402204cc1588b204ebc0c20f44a31ce53d15ab5e4d1f9c103c02dd4e4eaa1c33630b40220194b6e427b6def0783461cd8d765f97b105d048942be468be2ee9b0a2785d2ac", + "id": "35c6bc3f0799d9c79efc6515f232c58be0d03a3a797d066cba879eef4afaae2c", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100be44f7ea12e2ee89245fb474643ec6c2c75afa00276826a4ecd6fca4cad5ff30022071a2c083b353a821345e4bbf74d98db0760b8721856572572cc3436ebdb8f08c", + "id": "45f75a349f3b4d73434c0f2ac9c291d5d07278b79e6eaa0d38d6e005f66c4783", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402202090f506e8f18fde70b87a3fd6c470a23e9e262f20ec6268dd59b6362e51a29202202b838c598b33c6317c998dc179fad2b660b8a72bfaf8223d7cc82414ab4c6af4", + "id": "a8d9034d1091a4dbe595647ad5f64ca8b243e7842301aee48f7eaf8b8ae98119", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100be59b689a48e198267305f1ae7e116f69f7c360857ea0b1fa81db122278cad69022033436d24ec0103674522f0c559e2357f8696bd498deccad2e0f66b2cf7469538", + "id": "061cb438ba1216cfd5a0f268ce18e6f280557bc944d9aed3655e2bc5f08bdf51", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402203b5d2aa7c4554d6d2dd6723043350df0199e6e7bbd9f21a1a20dbba8c63918cc022014a78064c5f9c5e2f43d3be36de2b5e2f17e9af557bb6c75e8d82d9f725d0188", + "id": "239f0640ddc3170a737ef349c07cb82b2493d207421b6f71b6b3dab856f16088", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022005eb29ad4cf79fd4f6898de19459e15cc816acb0975e53530a202e69c29d0d4a0220686cf6e0c14779d6d68dcb9d16358c0e859094d2eec8083598b7bb5869478bf2", + "id": "25d8eef755cfee7cab0d7f9fbbea0fad6d5f906c432d997ae8ef1c49d23735f5", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100b93096a287d59545fa3a08593dfc740d9d47f3cfa3c4bd3c8ff8ef53d3a2e957022027eda62e47220774cf799f46916195e5a8b30015c56ceff4f4a1c10a918e3675", + "id": "aac25996e3be809ee88996b6b4063e2097d6306e77a067de8ebc8d7076a28d43", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022017282aa4fac7b18e834abc3ca37b2f60cf989c26b12e2f2398a66cb907015a760220428218d39db812a22cc138acc7d5d4d2d5713f0546751c02d2c3fabecca0e724", + "id": "b040f86b75750b49c83ca7eb8f2a458f16b44789796ff306c5f942ca5f19164d", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402205970d53cb0921a62bbef540dc33189b2313f3574e44f046097067e6991d63b1102200a356c87642cc781df661a1fee21cce354a144463d37053280e000e1b75da7a5", + "id": "25ce96f951d7b7d886ef487331125b3413f655f9c5ee7fb4691a728c3cbce18f", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100aab0201c9d9a9641c11605d32353685cbaa051ecc276da1e6a3b309be9f20cf7022067aecbc7329bdf1770974e317a1243815511efa8c7af7801217a83c96d86eb0e", + "id": "285143b8b19cbde7c680b0f62ef51293e8f315c823ffbd97608c38c02045d831", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100dc7752f6f8acaa3a1ee2ed1bed306ee04556b3866db92a1e770c4b970c7a932e02202d137b312342f9d0708704833b26b6611d0464c87df97049ad8b616483e9d1f8", + "id": "87b06fccbb63809e976b3405cccec2eeaa3694d5510203f04c0e60bb6c2c0020", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402205ccad5c77ea339f5e3f2b7900b4b1c409d3c8204273e89b6401314fb61f0d224022026a63fef86356de64fe571ff8488a951dcacab56e980fc044ef9f43b9d37439c", + "id": "5597ed52e4123756bea9307c09c916ff9d0f9fbce8d2e9a3a2ff719a87ad0966", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402207c91153f820f34228bec62772e0d78876bd3277912eacd866fe35b5c86a316c80220104529c6f786cb387ec1e3d5826271c837f0d0a6d0fa5731b9a5c6663cce7108", + "id": "d46fde78608fcc668246cc35336210b3c167ba55c82e91b0fd99df7e36872130", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3045022100acc0cf119c18861d3683bb3b0f6e209f2d62acfdd958f86dfbd35137ada814320220448f6f8adcd46204629b45a4a06f5dc7ccb4dbc2a1d702e107d91053847adf2f", + "id": "aa92faf5d80459b4e058dc8a8212608b589925052e22148384835ab687a4e875", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "3044022055b6bbde5fa886db3cf1224a59f1fb43e850e2d9237db593368e1043698fe2c30220067dd20195e794af4152f1ff9e3ae4261698a86c54803ba1890bf176d97844d4", + "id": "432e67db0d5fc8c66376aa96c7324e5a1e6d00a415a9c8898b5e3bf25d8b083d", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245098000000000, + "fee": 0, + "recipientId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "30450221009d6f38067264df8497d6888e4a8c316ec58ceba8a54c39ccb0ce261d114fbbab02200fae3f2f950f5c5e3387679f8ca341ec70cd90d0e32a30112f03cfb12cd9fc23", + "id": "9321e1b08faa544f592ad8dc7b60ff1cf845efcd28fedf8b445be3bda60434cb", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 0, + "amount": 245100000000000, + "fee": 0, + "recipientId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo", + "timestamp": 0, + "asset": {}, + "senderPublicKey": "035b63b4668ee261c16ca91443f3371e2fe349e131cb7bf5f8a3e93a3ddfdfc788", + "signature": "304402200aed5a4102bdafda00fda575294f149b393a798c510af8ba877b8c2d7ec8051e022004f7487c4f728c633aee5baa62ab0017f4b91cf2f494eb1c4cc9addc3e9155da", + "id": "0bbc9340798a18a81109bdfdbee9c9003f20a586dd9f80a39507c84588c1b4b1", + "senderId": "APnhwwyTbMiykJwYbGhYjNgtHiVJDSEhSn" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_9", + "publicKey": "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647" + } + }, + "signature": "30440220072124721ba7c997f7c29ad3d4819515fae7a67be2bc395cb73f114eb8d4abe60220523ac295e114de30ce8a4300f4670db91ad2abe1268460e6ad3463fbe9834b84", + "id": "d2e70f9d2de57240571905aa81db0b6883e27a83be2422530722d76b56e63ecd", + "senderId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_18", + "publicKey": "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a" + } + }, + "signature": "304402204b93b06e08e71e3317f9426a1d3d450d6293fdbf5a6b3043fce27b3ce65431e20220683609720ea1d7d921238ca8b5098d3d9c0caab7b1e26efe42a6aebbc095471a", + "id": "8695bcb906f5fd81d858794f7d90447aadaa38418d312e33115a81e856b34d12", + "senderId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_47", + "publicKey": "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd" + } + }, + "signature": "30450221009711559a43005c808113a1e9a01b1665495ff4bf30d635f7d98c752ead4cc3fc02207879e2a939914effe2b5c80cd515c4b3ff77a071b707c85c4444481878803db9", + "id": "55853d2d2a98def00c5ab842866a44d1db91678a07b6dd63d062508db28a00a5", + "senderId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_5", + "publicKey": "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565" + } + }, + "signature": "3044022025ba51a588253524557547ec492d71bd485fe5b291e60eef681c39eaf8ee781702202bf24c3d295c7a2c9aed97a79fb835506797dcfe7e7a2853e2578e7773c7e134", + "id": "553298aadf692c9c5d0334c307dd4ac0e277a49ed165c97ce1362f8ec639ee3f", + "senderId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_19", + "publicKey": "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb" + } + }, + "signature": "3044022041291ba10ad30fb9ebcb0e13902e92d85e2c3e98493b6d369d7d1e70e8474e31022009083444460c415eab6b4beed9e0206eb0733bad5d2a476af4db4f5b5e74b835", + "id": "90af927db7b258538c8e21116b5a31418c88ecc163628b2b65fac92a5a949b14", + "senderId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_42", + "publicKey": "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d" + } + }, + "signature": "304402205d4111c87874e696b8f4b8897d0dfe68fabe4ad5c5769026c6ecdd04f09a1e2f02207b9c8a2a16b50164215eb1efea6d5d9f4e693cbb7eec8535e526cf8ba68bb796", + "id": "8a920ebf5255a102d0c9c5fd720e0d36a6a3539991a2267442facf1fea2d0b86", + "senderId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_10", + "publicKey": "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd" + } + }, + "signature": "3045022100f15ff048872020d9efc561b8c837f542d54d43b9b071f7a6cc09643c6d4180f002207d0e82153a30b66f43fc4cb4b9b3093bb3d5dfd70f96928c8780c838b1448c19", + "id": "30738f376aa40fb3c8d8849a5dc698786aeb1409fa801c18729f8da624631391", + "senderId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_20", + "publicKey": "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751" + } + }, + "signature": "3045022100babb7410d09215def98078bbab6b5e5690c2ebf54960d94527226ed3925877320220342576d1d8fd2d2fe3b6974cab48a2e16b4813f022b341b32f88e13f572bf060", + "id": "ccbe1c27eadc1b3b33f3f87f645be4f756021ee3d4c96f4f094e1f82d5728a3a", + "senderId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_49", + "publicKey": "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374" + } + }, + "signature": "3044022032f2c350cc1319f5838d6880e91b49ae0438fb3a626ed9ab5e27ce8788e3347c02202cca18567c8491e0feea8a5f078e28605029346c509fac0c0a192e934f8c5326", + "id": "f99af0fbb4d65c2c3f2c1c558f0c0c0eac2724942802fcde02fa6da1d3a9000c", + "senderId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_3", + "publicKey": "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17" + } + }, + "signature": "3045022100f0cb5d885ddf3bd4a58837f9b86486da4171652a5eb39228dfd0ff9d34d9c7c602202dc6e3d268d745a7e8633311a337ec097382342049672880c7c2215cf58e5da2", + "id": "2dca03aed08533585d8bc609da5deb9f17ac9be5a8352769d7ae63d0db16ff59", + "senderId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_21", + "publicKey": "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a" + } + }, + "signature": "3045022100999f19fbdc9a12eebbb8c748a4cfc6c91b2233f333a09cddfd49dfeab6aaf38602203d8dc9d1551d400572a88ee812f51f897f8b35508713b789b2c1bf6dd0e88945", + "id": "5d7e51d57b5914ec201ab65a019ecdf651c4f267cbffe403fd2170bb95145f9d", + "senderId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_41", + "publicKey": "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f" + } + }, + "signature": "3045022100e86e648add940a1e637e32ea9187497c281b843da09597e62d0c927d7f43235102200479f64ae63abb55e338f9ce1073a5c46907f7a2a82ea6f9bd9bc29811683515", + "id": "eaeed4133da26612c53550b6572722d8c3380d0a2344da1bd270eed1ea91fdf3", + "senderId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_11", + "publicKey": "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904" + } + }, + "signature": "3045022100bc3b2ebc58a92bf38672206e8311e7ef0e54912abce7338155b11e7d191b0b5d0220765a568c1fa4665c0ace6b4bd3b7ba0f8329e2f25af7a3cc0d78b2ea398084c3", + "id": "bb91e78e43c59a19ac06c015d8a7ef09d7c5b274c9f98505e5a978027354b71c", + "senderId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_22", + "publicKey": "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a" + } + }, + "signature": "3045022100aae4868ab75a33e4e77f9bf6c53b920c5e7c523a7cfe271d1afc472655f3d6a60220499f1bcb79bc0fa830dfa939898db5c9fa8571a2788c8de0da7e550bfc818bcc", + "id": "a6e687647dde9c1db68690090afc4fcf11833dd35fff3186b6b709a1e7d24260", + "senderId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_46", + "publicKey": "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c" + } + }, + "signature": "3045022100c0cf1fc54705c13f70fde39c55a1703a4c612b8a919379cd5b1ada464c7cc8de022074ee62490a184010ad2418d3177ff2ab03d02d2589000176312b90422b1bd64b", + "id": "70262b0eec3ab5a60a736eb8a628cb600eae7522464a49791c0bf26e82318ec6", + "senderId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_6", + "publicKey": "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc" + } + }, + "signature": "3044022045db446b109215c6d3dfb0ee5869154a8a7624376c3760eec4fadc75a29033cf022003e524d64f3ccd0c6de4ca80a7327e2c47ffd16b3ad042bd25a02f5f64500ab7", + "id": "56048c449694964bee3d367609a7bc46c8da20f66878c09c01dcc53c3abd932e", + "senderId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_23", + "publicKey": "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a" + } + }, + "signature": "3045022100f8f69f2957781ed02d64983744c8e51fae613ebe5bbb330d4f509bdcf4fc6b6602205568ad1fd840e01ec26a24ac9a0ff093e978172da55d494138d018a45eb67893", + "id": "e15dfc4e18106480083b3c6211349fd9c803e334e9ba5eb62cca19ae3f57d8e7", + "senderId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_40", + "publicKey": "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689" + } + }, + "signature": "3044022021eeb9e1db8915a9adb99db72972cd17fc7b5b377fc532ac2c9deffcb2707edf022068b9e08f45bbebad89295f520ad40d7786fe64059d45df95551576e3acb736d1", + "id": "2bd0f888ccdeeca24a0134e3c1bf729582d284f32ee000d97f1417f1349a6594", + "senderId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_12", + "publicKey": "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12" + } + }, + "signature": "3044022040a9d0975f747df19792211546410d7c735aff2d26f367d1bf9233ffd1d993d702206890c66d4d0eb5de37df088c082d8fbd8da043817b48a76bd5d70f1e3f6b6529", + "id": "f75ac5ccd243e09fc9da2b3842a0654ca860d2dba5bb73866693a8a918937994", + "senderId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_24", + "publicKey": "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95" + } + }, + "signature": "30440220550c0ab565ab2de649ca7a2aaf2975453a1e4ab8b0d392d69663c0c9b6b80b7b022039047d4d1bf4e9b167a95adcde0a5a8631aeca060dfd426da28a10d968fb3a64", + "id": "aa2ed932faf4832848356beaf87e5381ee56a1a84fb485ba975acb28f8fcf5df", + "senderId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_50", + "publicKey": "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1" + } + }, + "signature": "3044022038df37ef25928d1a04516e982c99f49cbdc193603f814b48ab3802153bdd352002204c918915a3cbfa305c5f898ae4bcdd75394b57460f85c80daa0999751d466c08", + "id": "d30a726e1bb8d199d8f44700bc999c9a0a1a8be86e4be6a15764ecd424f9db1b", + "senderId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_2", + "publicKey": "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d" + } + }, + "signature": "3044022028dd44b9609b0b599c15a257757fd068f9014e33947c77776a6fcbe71879271b02200b46fd8eb0827da6de13f5efd63b17f29e8ba4600e4a690ec31eb08bf2d9af33", + "id": "1410b8b5f15c05528013378251bf5da30e04c8a6b7ac0f729b527664cfbdfbc4", + "senderId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_25", + "publicKey": "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964" + } + }, + "signature": "3044022038edfe34f7b89b4e69ea8b94e3335063b60deaee28246932147f53b2525924a402205b89f5e3d956aa49f24f81e2ba3447c19bd5c026568b3bef73a7a7d5160ad661", + "id": "58d14b74b71586e18f0499a50004ec2e0cc2e5b56aa53f4cf57084030ff90fa3", + "senderId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_39", + "publicKey": "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5" + } + }, + "signature": "3045022100bc1e477994bf4cbcdb5cbe2bd92c7d955a03adfe562f8e3bf04d2f62965e9f78022045512772d8453314361161b2bd2a39aa0a7fbb897a5a83f4c7ab54ced615b42c", + "id": "3ee53b3f1455ef0ddb52afe08854c9d87f42c7313babd3e05bb3ca4f94c495ef", + "senderId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_13", + "publicKey": "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f" + } + }, + "signature": "3044022052fe00e8e9f05b1d890f6910beab0627c823eb2d5875b4b9813a33aed11edfb6022034a723b827ce0e73bfdc0f535b244ffc983f8d549ee72b4d432de90d658db72e", + "id": "4a3d204c2916c93360d7bb11390e355bc1a930e3cf503965a45253d65bfe928b", + "senderId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_1", + "publicKey": "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37" + } + }, + "signature": "3044022013b2798a4ab4d741850abac10d962360cd4ab6a47dfac7c1c806d6f9c3d810cc02202742414ad8a04ce679b445fcd040fb877bbfed3d2692b873dec8cb46c01c8c4c", + "id": "7d0c5a44a7517f6ad7a1253db45d58e85aa1c735a282a32f45d28efdb7869d7e", + "senderId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_45", + "publicKey": "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b" + } + }, + "signature": "304402202c372b7b9679a8fe66f952a1d47d4327968d6e98770b215ada2fed6a8d87ed5502205a797fb511cfba557255dd37e028fb40981b7b65ad2ce8fe0e559a46eb274bf8", + "id": "70bfe97ae7452dc752ab4de0e2a0e81bd18bef07392c56e7a101257683d4d932", + "senderId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_7", + "publicKey": "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0" + } + }, + "signature": "3044022058851712200f7386d6b3c188444f9c8f05788667649ec17c71b9e514206eb105022061e6a4bc4cd11599792e03298f95509893d56af54d51e9f639981045e754b974", + "id": "f6f90ff09dee5be7d8f3d58d217772df7a95865bf8609d7d5b0b673e9a5bc953", + "senderId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_27", + "publicKey": "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d" + } + }, + "signature": "304402204878d69a166e60e0a779c31fbc48c67b70d2e4aed1d63c60beb9f070963e2894022078c46b6687f23493a4c2ed39709a183a0f7352568cc9cc2c1f0d7bf0d809a4a4", + "id": "f68809e407d20a50029fe460d411c866b79c7e09c076dada768a38d81f184aa3", + "senderId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_38", + "publicKey": "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294" + } + }, + "signature": "3045022100d5576393a1dea704cf79a5d0bc2757a3a5e66e1055103b52157fca05fc5693ec0220522832ce0e31b779decef83ac8ce764930de927df9ae1d6f6f99a3312d99c90c", + "id": "2ec6c6f33f00431ef063fbb8a79fb90eadb13a79bf46e6e1df36dd9434314df0", + "senderId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_14", + "publicKey": "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24" + } + }, + "signature": "3044022008a7d0bfe9c4c150566ddf701d08e84b4a5f84b07e3b1c91dde1cefa16d2a3c202200b787e898c0b2c68f4343e74f18ae7363f62b5f4ef2962386932aee09a9fa0d4", + "id": "e37b3efbf034bea4c852be7d7013978f8999eacc39549ceea775de197e14e8da", + "senderId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_28", + "publicKey": "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28" + } + }, + "signature": "3044022023b6fbfa5f4482a4dcc34411846696052b1592786ca87243b7d3344fc9fe9954022035402fbca22691de2497552c743f0f68c7591edd1bd7954ab7639548fcd558a3", + "id": "08268f5e6c15cf146523ca928f24aca65b162f363593d927c66144ee5df297cc", + "senderId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_48", + "publicKey": "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b" + } + }, + "signature": "3045022100b3cad169f29a3a95995b87e1b50b35583c1bff91d69cfa236f58ce452491c579022026775f4ef50b50ecf6d78b530b4633711394983456e6a45ec227b652c86e3014", + "id": "ad94ee2ae94813a638b93909930c7cc631c364b6c8528b2dcd6fa8f69260cc2d", + "senderId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_4", + "publicKey": "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93" + } + }, + "signature": "3044022007ac9ff2f272f3fda4947393b8688586cc8b2958ff5dc7931ac8f82c697bb76802202a66c28852bbff86ef17ac7f51e7eee52e611e825d91a9846f531ab3c3115c81", + "id": "76fb1984da9ef90fd7d588756163c97e00d3e4d6e9dfe78d9e3d3cb6d71ddd38", + "senderId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_29", + "publicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252" + } + }, + "signature": "304402204416e428688ad29928303fb2b00a26996cf79753fe70fb91c1f4635c644ba859022068ac5eab7d05f87c40ba36bd9dc149607c196778120c061698d7ab64aaade7ac", + "id": "0f442a91857061e87dd193b0b9f17a71719ca7e3da62841a63568713fc12b5e7", + "senderId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_37", + "publicKey": "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4" + } + }, + "signature": "304402206a248caa5949024202f297c38cee18845e344c5f140be74349787097d3b0a33c02207ac84336e02592bb5e00dcd0c490d30eb856b34177ab9ac03410d82a355a7b0d", + "id": "eed30a45c350fdffc5877458f7fe29f28dc4bf81aa1a197d003c9433148b71aa", + "senderId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_15", + "publicKey": "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca" + } + }, + "signature": "3045022100c99336ce666cb4a6db3727a61c04c14d8746365f72280d9984441b7d2b568b5402201759e4f417f683743e1d4a14f8a7a215009321cdfa29834b2dbdbe54ee22c1d9", + "id": "ecfba14a58f9d79782c4f905646df28bf566e3e7d1f17b39df6fe6b52c11de59", + "senderId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_30", + "publicKey": "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883" + } + }, + "signature": "3044022070de7b4d4ce64bd605c9d008142544c2b113cc84df07ed1982e0adf3cf69f4520220211b01710a6533a270dc2814c7f968adf27eb6dbf437e7a72960b013b9651a0c", + "id": "36ce5323859a92f302f77f27bd08ee3485d720f55842ccba353a47ea96a964c2", + "senderId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_44", + "publicKey": "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c" + } + }, + "signature": "3045022100a7c271633ecbf3c6641c7db36913b5fa0ea521f400a4848edf024648f3d7128002206a271f8a88644062b64d856407af9567c0b2937d4a3d89a3b3d07edbd3a0f177", + "id": "e120452e7c56a9327b2be7dfd3dcecae193f2e2e772903008b03cdf00146ebd1", + "senderId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_8", + "publicKey": "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564" + } + }, + "signature": "304402200394b6545015bcf2d0f291de57a4197cb6ef57b2ad5fa37f05e8a220913ba83502204d0d2f2206edba54ada5b8e5afd194ba83dd1bf15f744258409595251dbe3ff0", + "id": "7d15eee8e4e3be3d2c44acd51b87a816bdb593565d4ac358dab24ae9c8a5bae2", + "senderId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_31", + "publicKey": "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2" + } + }, + "signature": "3045022100989eb331951a13152aa03583efc765499e836c6fbafcafec4302b243ada8de5002203876fc4cf7fdeee4a095667e55a2fef84e5a7053e807b4d8e029883f0d578019", + "id": "baa686d521f95d265e7099cfd9ef14e0a9a92254dd94c16ce50c460bd013c588", + "senderId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_36", + "publicKey": "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e" + } + }, + "signature": "304402202be177dddfad323302565a866d38a3e7939e0234b16e7dc02075cf258502eba302200928a139ec1a82b4609fcc1bd6d1d027ad050e93fcd2eff94181936d2d43e39c", + "id": "9fcf7ec6fe98ed94710e212226d8b90df7e7467d66dd4c5c9d48474388be3099", + "senderId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_16", + "publicKey": "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9" + } + }, + "signature": "304402207b4f8c09a728acedf3b6ba0632e12d01670c683215053e49dde8598954d85a9a02202a7d7930baa17c2134b314e47dd6c334c828f78e573a2bf92fcbc1146d630541", + "id": "c35e4b1e7a2435664fc0939251c2052633ebf4b51fb22d15e71bfcab85b26de9", + "senderId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_32", + "publicKey": "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055" + } + }, + "signature": "30440220127d27312345e015c681adb799c1a87d16fb0caaabd5020b39257d567816b91c022018b2388f6d2d9afb3714d84ed102b3ea61159772786033c855947613c7ce7b5b", + "id": "0d682a3a9c252a674043bee5240e456dae2685d76fbd3bdeda6ff50f0c442fff", + "senderId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_51", + "publicKey": "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a" + } + }, + "signature": "304402203d0ee691830e4d001553bf4e49b6d9669b3c959376f391410551c8adc679dac902203ba6e275bf6d543efd19d20428649f802d9396bb0967114a1f09c24827be1da7", + "id": "ec2373b0d609ae72fb400ffdfbffc59670ebbf1c15f59c0ac22a4030dae700e3", + "senderId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_26", + "publicKey": "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983" + } + }, + "signature": "3045022100f2cf77b0510f589b5aaaf2b0027ffbce6ce8d4873cdc67dc8900865d156de3be02203c22e30945618683182f3d3873e6b3657e0900b062f866bab2705cd593669e79", + "id": "3cb2f0f7d05a515d4c5c873cbe96e33b1dfba1b7718e4548de7f9da54933b652", + "senderId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_33", + "publicKey": "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe" + } + }, + "signature": "304402201e328159172d543d2225c247c6b728800c52eb724f67c0e919f6b7215e6bd7f2022075fc02fe0b14a1499c5602d87ca2c99d6e789beaceed2b9702060dece872d14a", + "id": "2fd77e744399c9632cc8f106c39237f201dafda976f1040235359f99eea3b832", + "senderId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_35", + "publicKey": "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e" + } + }, + "signature": "3044022063903d82e8bd15a6741a298b9a6007d0dc3626acfe2f072c3b624ccbf91ce3360220486ba4cc5591d8aa31b77dfde025b61691dbaad0feabe13e840d26e40010c5df", + "id": "5baf9e318c9e4cb0513a21eaea27e51c849f95fddc963207fb07aa2fd2b9f9d4", + "senderId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_17", + "publicKey": "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357" + } + }, + "signature": "3045022100efc1bc16e0b646da48f84822543b62ef5253bfa98bed6613f2d6d4634076e61802200ef243f9dbac7633a8819ce45e2a85d0eacfdc9a33a92bd3a03e90cbd312b823", + "id": "b4a959ad75f81b7fdbb957c90a3a63a6c5589e7819e2c455733a3a2b4b034634", + "senderId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_34", + "publicKey": "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80" + } + }, + "signature": "3044022012e52a479648990bfc1ed12bf901cad865708ff45962c3724ea67967be4f9d0102201901525ed8dd090af6a2637c123afb304e9fd178794addcb88d916227e66887d", + "id": "6439f2308efe31ac52ad06ef1caa45b9abf6c589118b7997da6a287325ca36e7", + "senderId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7" + }, + { + "type": 2, + "amount": 0, + "fee": 0, + "recipientId": null, + "senderPublicKey": "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e", + "timestamp": 0, + "asset": { + "delegate": { + "username": "genesis_43", + "publicKey": "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e" + } + }, + "signature": "3045022100a0874d1582ce210081f7ab30e7f951dfb9ce8f512d237f8a8cbd5d85569ef3b902200f0053c05de3d6e5ada4e4cf1403a836779d653573c2f374055645cc954c4c4a", + "id": "b0733072e98d3d6afe977e32f3dd118c15e79212232417743ffb551dc2a2ba55", + "senderId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW", + "senderPublicKey": "03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357", + "timestamp": 0, + "asset": { + "votes": [ + "+03d7dfe44e771039334f4712fb95ad355254f674c8f5d286503199157b7bf7c357" + ] + }, + "signature": "30440220158ed59156e0eef2d2b94a296451dffe079be701b3d74f0443ef43bc266b334202205a2c39f57abfcd279d568608b90884b3ebe107316aa7552eca35c743b318a47c", + "id": "ea294b610e51efb3ceb4229f27bf773e87f41d21b6bb1f3bf68629ffd652c2d3", + "senderId": "AJPicaX6vmokoK3x8abBMDpi8GMPc7rLiW" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7", + "senderPublicKey": "030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80", + "timestamp": 0, + "asset": { + "votes": [ + "+030fc33db3d3ab20d73bc6d52633a4f3cc26081ce307c89ab9fe493def7dba4b80" + ] + }, + "signature": "3045022100898da9f693a458a6875344c6c4cb73069c4075904c75595ffbc665967d84b07002200f168aaf3ab1b52dfa74599394387dc4cf627a447fbc5a91000e9d251cdb20c0", + "id": "3639b5dc6d19d46d8254d941bf7ace0f3da8a7cf8a56361921b260820c7239cd", + "senderId": "AHXuTrYMxsdSvYJvRoBkM3kH8pS4QSq9i7" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1", + "senderPublicKey": "032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e", + "timestamp": 0, + "asset": { + "votes": [ + "+032b59ba992a9b8987b48606779d92101e4b332f6fcb47a4e61e9b49f2dbb45b2e" + ] + }, + "signature": "3044022055ed9a8b55ccb3bd0945a710269b6f243f1dbfaa28467d3218a17565eb0c962d02207d31561478f16d93a20f5454ad565dea24e8dda4ddc464cb011f4b6b360c4e81", + "id": "fe24509580cde0c2e2f49defedd3a0f7572d2f78f90b51a253b0d8cebd74c20d", + "senderId": "AZFEPTWnn2Sn8wDZgCRF8ohwKkrmk2AZi1" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof", + "senderPublicKey": "0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055", + "timestamp": 0, + "asset": { + "votes": [ + "+0305322487b6dfe8abe67f680bed2df70d92379a48840dd636b32a2c142baa1055" + ] + }, + "signature": "30440220092f367f833d677e8d0609ad1df65f389c2c35d1501c71c245c2982e6a832268022018e67445f525613d6cb6ac0c9683bd0f55bd40d9c929165649414f083c9041f9", + "id": "6a76553db794ebf4d5f60a7d7d71cfe29f4dbcaad9610106fbc578cdc7167cd4", + "senderId": "AeenH7EKK4Fo8Ebotorr9NrVfudukkXhof" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy", + "senderPublicKey": "03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2", + "timestamp": 0, + "asset": { + "votes": [ + "+03807f9abe33fb390546bb5dcab075dd1136d0b98c54420c8c463c4ed3545161b2" + ] + }, + "signature": "304402203dc028b5013c36b03f97b111a8d7c05d0cd8e505b0b0d18747c0656c9b5cfe8102205e9ce8a78d1183b3e9880c69635d04218d94d17808bcc3f92e7af53195c23daf", + "id": "0f9d7e7708918b77afbdfffb63eef8fe87ba36e0131c88b44c1a7f81750cc025", + "senderId": "ALiMCXj25VkGEAbj5PNbNez5NagZZJxLsy" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9", + "senderPublicKey": "0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e", + "timestamp": 0, + "asset": { + "votes": [ + "+0282d4297584488b9c843face25f1816f95ccdd6660b1a2788fef259ed26a86e8e" + ] + }, + "signature": "3045022100a80ddd7c3adaf0e97ab938773fc78a716f3054d7e03afc1ddfcb5005badbd2810220231c0dabe2262149f994c939f9dc90d46b9bd7ca96b19aad6788cd3571e4f71a", + "id": "0ac77b2637fb25be42b3b60d1651bbbd788aeaba933a08ec4a417c7b4c54e087", + "senderId": "ARJWp8VJEieDA8h8YDiHq5LqU9vWcpWGG9" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT", + "senderPublicKey": "02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883", + "timestamp": 0, + "asset": { + "votes": [ + "+02532c68cd0842fb86b2202c1027eafc741bdd581517047d9d19319e6741c54883" + ] + }, + "signature": "30440220772c9cd8b96f74fcddc429d57d466eca6fc40fc211845f59eeb78cb027e116c5022004cda291587eb118d622de21333d2a5783969794b5b0101ad8b1044c7d8058af", + "id": "4b0dda465564d53981c0e36d73caec888e3523633eaa80dfb99a9c81b2604c7d", + "senderId": "AMv3iLrvyvpi6d4wEfLqX8kzMxaRvxAcHT" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU", + "senderPublicKey": "0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252", + "timestamp": 0, + "asset": { + "votes": [ + "+0308c0d019cd9c0c59618e3b86afc584078b54a85a025c9f30a8bdc82cdc8e1252" + ] + }, + "signature": "30440220406d54714b6425ae4553ea8bec75f31fe52e9b1a9b6f6897151253ab7f637d3b022040a2df4b69840f4d9b0b67658c75efdae8d8269780d4cc50d055fa63922dbb9a", + "id": "c7db9d36d97ff0168d0d670ec695e1dc786dfb93f4081586870c8793b50e5f17", + "senderId": "Aa4M1zL3a74L51f1AvEsLmBTsKLKrkRScU" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK", + "senderPublicKey": "030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4", + "timestamp": 0, + "asset": { + "votes": [ + "+030d13c0a7f1433091a5730cfd7956175261bb9442d8c0c0beffeb3b5de32e5aa4" + ] + }, + "signature": "3044022018b7e51118ec83c985fa4eb3d7f0cf0655753bcbde7e82bac521665fb1c0ffaf02204e2ace460b2542db8c77e41d05d5e02fa5514b746a0a1e947256925846ed19f1", + "id": "c41f4cffcdd523f1718154d5bd5f4f0bec0376076b5f8dd340337e9edb4821ae", + "senderId": "AX1M38eZC6TB1mzz33PxZBYBGrmE2zPdFK" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW", + "senderPublicKey": "03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28", + "timestamp": 0, + "asset": { + "votes": [ + "+03747096ce60f19e52e99f5d80ae1ddedf6fa88be4ff0669b33f75f3fd991cff28" + ] + }, + "signature": "304502210088dbe249503da43c157485bfd4f2c95babfe4d0b8bbefe44afa52529b824a79e022045239b6a374fd9aca52c27171ee66b4863c956ae4085c9760d863b1902596c1a", + "id": "b1736ec6a1ea4c6d4eb278430a8ee214c88daefe296ba98530e692f8b7a7434c", + "senderId": "AJv5ZFmu6fuugsdTZNi6ukPgptbCmdW4AW" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej", + "senderPublicKey": "02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d", + "timestamp": 0, + "asset": { + "votes": [ + "+02589ffa5363e245f8068d823af8b721b6bf9742c17cdd7925bc9a1fefe66a243d" + ] + }, + "signature": "3045022100fcdf750a775e728a31691a1b38908a7f990b579da510959cc2c63442f5ffde760220316ebb051d9fecb2486771dd39921fb12675b6d46b2441dd1db3c42fad0a59b0", + "id": "069271456015c2ff842771775993b8afc3404bc070572eeeb0f2fd72d58e18dc", + "senderId": "ALJVm7EYiMtc1JJDG6BupFw3ttRR6Yewej" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U", + "senderPublicKey": "0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294", + "timestamp": 0, + "asset": { + "votes": [ + "+0232d790f7a6ac16f2581283a47d0dcfbb51ee100f92e46cea46a63a8a043cb294" + ] + }, + "signature": "3044022034ce8f77ea9d0f5cf3a9135d7b72d0ba3b96ac6d7eaa3670e9956aef2c9a83cb0220626d1f269128f673a23f9993ce00ba78a08103e697298be29a4c8ee94f204e3a", + "id": "9a99bba8340e7ad4e05d8424a0977ebbde428d31ee066c9828bd06b42bb42a72", + "senderId": "ALs933qA9Cm3caRDei4ZXxnzXexpXNem8U" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2", + "senderPublicKey": "02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983", + "timestamp": 0, + "asset": { + "votes": [ + "+02292be0bf30b21cf57d55b20f9092a70dc1d1b71f51a91d2ccb2d2f8d8abe6983" + ] + }, + "signature": "3044022039ae1155f8b87a61c38b25cbbf30da6ecf6cfcc12b25c2e7fe576373754a41eb0220061a66a893129fbad5d48cdd19cf48b1a0d133dd2f3ecdc60ee7b87277e1f81d", + "id": "6c2c8926420ac269b50fa30127e0e791afb2131aff5821ca7aa80d38a0182048", + "senderId": "AJRf2oWusRmm8QEiZuwvMg3qLbMxpd7BJ2" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf", + "senderPublicKey": "02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964", + "timestamp": 0, + "asset": { + "votes": [ + "+02be75b3862c454887da01b866972b4fb312e0b72fa7d5dda5c0e828c1f4d7f964" + ] + }, + "signature": "3045022100d0dac2b7691aa059b1048d7925a0c5d5099f6e9b0f2e321e6d4f128ab1b3272b02207e8c4f643f8f9d1c3f81f0cce6a698df2da2ab71d5b01042766bbe0f46f4a775", + "id": "9259193c5de72276ed7a99f9d507dd6ea9856411fda521074fb41a556294fdf7", + "senderId": "AJQuCRxeJpzkoGSBMXtmuRMYg9mtCb4qHf" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9", + "senderPublicKey": "03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5", + "timestamp": 0, + "asset": { + "votes": [ + "+03827628ae32074e284bcd660aec4f0504ba5d401586cb9566c887dd4da522c1d5" + ] + }, + "signature": "3045022100d5496fec447367ab6b53956a8c40cd8566e050ebb3b92d2c0b2a9d09bef36c7402205e32367605372375801f7b9db39aaafb46ee763b1494f0aca144fb91f3415752", + "id": "2a41e5946ab0773ca2334bba9d3510184bdd258f1c651ff8ec95b7b64a01dc2e", + "senderId": "AWdRZPxQQvG1TP6hdxvQCn2t3skerq9Ky9" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW", + "senderPublicKey": "039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95", + "timestamp": 0, + "asset": { + "votes": [ + "+039f71d74e13cd8c4b7e134ad46e2c28f1bc8e6eacaa9839b5bf59eef5cea06f95" + ] + }, + "signature": "304502210099249695dc38826e04c8fcffd2570b98c43dec4788cc6a19737ed0872f17ec3302205301f645d803ad5df4ab1a700446e28c7cd76153607f6a2d68ae9168d46f3fe9", + "id": "e5c09b0fb2c24c57a4dcef0078953093800329ab4dc8e16a9d9f68215b5acd3d", + "senderId": "AcFWyJRk5sRKagThYhk5e1jdkx3wzhL5cW" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU", + "senderPublicKey": "034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a", + "timestamp": 0, + "asset": { + "votes": [ + "+034ff439276ab784098e66dca4075111008448a3b3519c10701bd2d1600ec1203a" + ] + }, + "signature": "3045022100f983b03e319aaa6c6ab6381e3ef8c0c035d6e3cc2139cedf70fd4e385393e38a0220286f73577765eb3e89e362785ad8a6de572bebf41bbc1f515b0ea93e41801eb3", + "id": "00b2c0455ef6f508d65f11bb49e3cfe1e6062d5fd153cafdfdfd2ccbf9c646e5", + "senderId": "AZeX3qaqdU8iCebAKYoLMR2QkiuG5CffgU" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr", + "senderPublicKey": "022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689", + "timestamp": 0, + "asset": { + "votes": [ + "+022b80e0d314928d93e48d1fe02190378384215237a5d42a86bc91580ba8c88689" + ] + }, + "signature": "30440220103862ec51621ca27a0ec6b2817848e8824d2d09dbf7e6aac2f45aeea5d2dc9102205e8cce78b5cd7148aa4d406dc7b491dd7758047200e10cfe1e5fde5c56107ac5", + "id": "e25439ad11cb8db3d49ccb3b8b608c1bcb24cb29b2e5ea15101cce3e475224eb", + "senderId": "AdT9FrWUksf99Lhkr9JGb8f2HLSg14kTqr" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ", + "senderPublicKey": "03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a", + "timestamp": 0, + "asset": { + "votes": [ + "+03a46f2547d20b47003c1c376788db5a54d67264df2ae914f70bf453b6a1fa1b3a" + ] + }, + "signature": "304502210099241ced4a0fd1eb02f5cdcc880ae5f48eb3c7e490d4520c20124ecbf403893602204729dc6cacf3e87c97ca57c1be54d1e80791bf31ef022135e68fc06c950f6994", + "id": "1474f50815c6c7df41ab652414806d61abe15bee0d41f32d772f4e2793badce4", + "senderId": "AGqSC7M137ctKtkAjd3J1haCEWNfayXnuJ" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX", + "senderPublicKey": "0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a", + "timestamp": 0, + "asset": { + "votes": [ + "+0395ff46d07f197dd4d4cb5dbb46e164c1e7ca9896c33827f9d6f8003ea167917a" + ] + }, + "signature": "3045022100eccf81d44992c49a5ee37c6fc2ccc4b6bee9aa44888513b3e18e79452ede3156022056b0ddf079d2918d72e8781d3af009c87e6058563591dfd6ee0117b7df5534b2", + "id": "b394e2a8b5c2d20a72ed288408b8f0d48aed922edbee6e16c1c5b0e67517214c", + "senderId": "Aa3mWTMFTXeTJukUgpeihQLBYDHBzdpWZX" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf", + "senderPublicKey": "03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f", + "timestamp": 0, + "asset": { + "votes": [ + "+03343930630f8235c2b3ae9ba013dbecd4d8bfc999d34bda33e18c8caf43772f1f" + ] + }, + "signature": "3045022100bdb87894846eccc5a5473edaee1e6dca5f3469963e22f06123b6bde195aede0e02203d0c6833e87c5e60f4597ce624d4c2502a0562b4e54d943f82a4889e3cd69532", + "id": "6a399099bac6c74fa5e956512ef8b3a39f6f946d5d6996f192c2f1dd5ba172dc", + "senderId": "AcATpmcMU1tmLDX7TzR3wXop4tfLFR21Lf" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv", + "senderPublicKey": "02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751", + "timestamp": 0, + "asset": { + "votes": [ + "+02c1151ab35e371a333e73f72e9971cfc16782e421186cfff9325d3c3b9cf91751" + ] + }, + "signature": "304402200785771ccf1a6a40b51183a190d4cb4ce76b9ffd4c2c736d7724e6c667113d020220649ecfe73017d8dda96a7914793470ee7e582693e4866df123b1032194c163b1", + "id": "f20a831a6bae0a85470e308fb66517e70db479657459f6bb39f2cd1783c565e6", + "senderId": "ALHDQyTm7wALtwjmKwEejZjq7f6u6w5xCv" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv", + "senderPublicKey": "0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb", + "timestamp": 0, + "asset": { + "votes": [ + "+0287a12b336fc781f2621aeb703ae47feca4d3ba6f30625f09ba03d225be6ee2bb" + ] + }, + "signature": "3044022020b79e1f07bcb17cae9485b9f44e9f583ca235da4ddd363b905fafb884347f71022015a20481b43720ddb3b1e3ca64b1f47e59b5cc2016a62f43327ca14533384dd4", + "id": "7a1285be87dca9718bece5b84266c1bf6801a39cc111d534e660aef9e6d26929", + "senderId": "ARMEiPQE55CfHfR8WmosiFykTAPGYUyYJv" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg", + "senderPublicKey": "0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d", + "timestamp": 0, + "asset": { + "votes": [ + "+0311077c86a98b67850e7ed2c81775d094cf81c6991082ddc33fc7be5347dc765d" + ] + }, + "signature": "3045022100b1615d16763c46d42ca2aae967f04c1c07c119b5af7a378c262ba85515a8d35002202cf7df91676cd137943720e93f06c11907412a6bdc5ef2157cf536a203cf83a3", + "id": "76fb5a1de90f245b1eeb79cb11c7bea7c8b738add0fb8cd95191186a944b0229", + "senderId": "AcmXmomxpP8NahbbFivq32QmLuKFkTkqRg" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri", + "senderPublicKey": "02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a", + "timestamp": 0, + "asset": { + "votes": [ + "+02ad799c6bd670746892bd4331e1aebada26a2cc3ccaf0fde1e94942b20066b05a" + ] + }, + "signature": "3045022100e3c7b5d6a72acde4d22e8c1c6cd864c549deba89683f4b84320407d6c380827c02202da57df0ab7cd381b776bdf85802aed371e7cea7269a84f911b1d8e9956badee", + "id": "8da75c8100e6248ab37cc92f72ed9facec3067f4f82f03db8bb8063791463fb3", + "senderId": "AHXtmB84sTZ9Zd35h9Y1vfFvPE2Xzqj8ri" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t", + "senderPublicKey": "03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe", + "timestamp": 0, + "asset": { + "votes": [ + "+03ba0fa7dd4760a15e46bc762ac39fc8cfb7022bdfef31d1fd73428404796c23fe" + ] + }, + "signature": "304402205779b5d8acbfedfc105fedb6fcbd4636713ed27605faa9bd988598072640a958022042d8a8b3d7910c7c385f3707a317c5d445d56da250f8d127c71df2d9d4c5d86e", + "id": "fd26e265be88289828d0ce7ffc5faeb9849e1f4cb37a8f1dd5d6fcc436d910b7", + "senderId": "AU8hpb5QKJXBx6QhAzy3CJJR69pPfdvp5t" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf", + "senderPublicKey": "034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e", + "timestamp": 0, + "asset": { + "votes": [ + "+034985f6f2167cc8c9df1204aaf6744bc97c0d7f3c07c43ee6c0978bc91b6c680e" + ] + }, + "signature": "3045022100e18a89fe1fe0a8acaca2b6461314e784ffebbe7374f6aafdb06934e83985ccbf022027314b21a4a25b477bd7cc070b4e00ef8f3d69f3f1af028b96571dc245924c00", + "id": "41d92e128e6b8367cbf8fd111e5263d52e1abad553653f975dd60d7f7c5b637b", + "senderId": "AQBo4exLwyapRiDoDteh1fF2ctWWdxofSf" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9", + "senderPublicKey": "02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9", + "timestamp": 0, + "asset": { + "votes": [ + "+02dcb87d64ee2fdc6c2bcecdd841ad8e3b3163599214a818924fd433a8ffe7daf9" + ] + }, + "signature": "304402201c614c84dbae26f87973c9e2b38df883fe0c8c469080e31fe32a4c4946d50b67022075b8fb498fb1384aa6be785845da02813185ccf095597b5782618033828af4d5", + "id": "1e4a1f8aab6fbf8682c2b35e0d04e9e007ae717ce3f4a82894747e5807e3c759", + "senderId": "AWHGbGaz5FgvyChuAfWFmKY2LsbcwqPYL9" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV", + "senderPublicKey": "02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca", + "timestamp": 0, + "asset": { + "votes": [ + "+02c39e352d0f3c4ea19842a5bca3114b4247cd56da72157963a5873ecfcd824aca" + ] + }, + "signature": "3045022100b1ee6becc59d594776a40e5b3caec82390d273b703ecb0d7caece44953141449022016543cc29a28882845118afab6e51296cd216bc662260c28e5efd9597b6025b1", + "id": "2ce068bfccb3f967f4004e9a1e81614a738e55e45c80114c0af30a085f71a2e9", + "senderId": "AeooqGMJPE5UWRPkKW6kgLGZu3898vcLPV" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ", + "senderPublicKey": "022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c", + "timestamp": 0, + "asset": { + "votes": [ + "+022ebb110e9630377073d4f0e32897a5928a2c71f2941fb6d4b71251dbd62da98c" + ] + }, + "signature": "3044022036698a329d7f5f751f91ce02bc188a7527a377d01583b70427cfce64def945ec022079afafea10aa32394a1e42a80577de3869856656221d5f259e05fb44f01668b8", + "id": "3478d1ad3655e10fcc864f191972322c866616866bb1dbf66d7b66b31cd95de6", + "senderId": "AWtD9W5LCv2TH3VcdzbGQBGaJBwvbzZNDQ" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA", + "senderPublicKey": "03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24", + "timestamp": 0, + "asset": { + "votes": [ + "+03d27324bd4829f57d549bdb273bfd666d88f43d8429ba9a42a4fa1c9bd1032a24" + ] + }, + "signature": "3044022035fa7be80cf881eefefc12b11de04ffb2e2e92815cf05074afef54a3c5b2eccb022041f3347f59db0b3caadefcbfbc5ae275d3fe3e2a52fe1504b23628d4b79a43bf", + "id": "8adfd8e73e96188ed9fdec459d88db1fb041a2b25b3f64830476aec661ae5010", + "senderId": "AH39inbLsUBhC3k29NcvQP3zKZWnsQksvA" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm", + "senderPublicKey": "021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f", + "timestamp": 0, + "asset": { + "votes": [ + "+021770413ad01c60b94e1d3ed44c00e0145fe7897e40f5f6265e220f4e65cf427f" + ] + }, + "signature": "30440220630da8a73979bd3988b7f84fe9e83a429cf3239f54c140c3dbcc407140513fc002203664ad54ed9f199f2683479b988bd97ad8fffb2c2d5dfdbdb10858aca4abfaca", + "id": "e306328ffefcd9e3809e7390a358199a62cf8ef037d57af1f5c7b54d728d427e", + "senderId": "ANRNMPjQjJGVsVbyeqwShcxKTidYJ2S1Hm" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1", + "senderPublicKey": "02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b", + "timestamp": 0, + "asset": { + "votes": [ + "+02af50fcb5183b3f2c468fb4e75e573a6bf0a048a6fab095df6d70f9f91fd6651b" + ] + }, + "signature": "304402206f1df93f299ffedacc25aa201807df47d32c43369315cf9db280963c357be56302206a66acd553710f49bbb7b803a2bcb71128c8e617ffce66b37b7c968817349247", + "id": "dc69bc8f78502ba34655ed062987788939189709a4112760cd8807245d7461f5", + "senderId": "ASqzCDRS5cTBwCmC5moQ34W4QZhtrj4pT1" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8", + "senderPublicKey": "03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12", + "timestamp": 0, + "asset": { + "votes": [ + "+03c74d53dcfef0d79f249a812e95c1a58040b769867df036639f0c107d3b577b12" + ] + }, + "signature": "30440220629e696a10e04d4fbc10a5ac443bf9bd40dd5d89d4b214224abe47d7ab5600340220643f361a24d9916e2c5aaec7bd7d8a6a0d3ffc5fc0b62c3ac4906eb799a862fa", + "id": "c3f49fb80c40f7779b32ba23616f5573a6ba58fc60c4629c2252933038dd89f0", + "senderId": "AHysG9CfbXvHtxev9eziTK8WUbnFKKLFR8" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2", + "senderPublicKey": "0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904", + "timestamp": 0, + "asset": { + "votes": [ + "+0345ef2a1e4f64707044ba600efdc72aaad281c5a73195f930527c54d7cc891904" + ] + }, + "signature": "30440220660f9604896dad2a97820b0d7524f0bce5a8b5766f150517d5061fd02bddf768022055e87c25891d4480e66e5d1a71e42cd5a4bef3ab2b2651cd72d44f30a4b32309", + "id": "8e8ac1b1a586e86867abbf25d63387bb6dfb793c691f0b06333c1581a9a568b3", + "senderId": "AZuvQC5WuVpPE9jwMCJcA28X5e7Ni32WY2" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT", + "senderPublicKey": "034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c", + "timestamp": 0, + "asset": { + "votes": [ + "+034776bd6080a504b0f84f8d66b16af292dc253aa5f4be8b807746a82aa383bd3c" + ] + }, + "signature": "304402202e2ad64129f61ef1156c4c7e80ab862d4823d62dac502685f53028536ddfb41a02201a3ec777fdfe8fae9f7cd5251fac322c1b6a2a4d41b3ec456daed474986d4872", + "id": "ff73565c373f2cefebf86c72dda3a6a6205750eb03b69178cb83378620715e1d", + "senderId": "AMfyf9iRjXiKNcLQVTUE9oCESUPzmQ6iUT" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q", + "senderPublicKey": "02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd", + "timestamp": 0, + "asset": { + "votes": [ + "+02f7acb179ddfddb2e220aa600921574646ac59fd3f1ae6255ada40b9a7fab75fd" + ] + }, + "signature": "304402202e5c78cf21a088db10e1e1f64d98d84c8d3294fde7bc322d4af06bfe99d4c2e302207e7912a16a37b641a9f8c7c722f2b0d699917ca73e4d0f21584b717fb7f02f13", + "id": "3822273b496f2e253081cedf382e4f9937713fabb83449e1f892377cf536e68a", + "senderId": "AFyf2qVpX2JbpKcy29XbusedCpFDeYFX8Q" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo", + "senderPublicKey": "0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647", + "timestamp": 0, + "asset": { + "votes": [ + "+0377f81a18d25d77b100cb17e829a72259f08334d064f6c887298917a04df8f647" + ] + }, + "signature": "3045022100a65ce45164c9bc3e018e26703370c9deb2933ee3b4e814619043cc37c4a39c4802205ae4931ac9e8dffd714c3b601fe248a49c0185c8367887205f497d951c52eb54", + "id": "430d6db0b87c25dce4ce14ac907c13bcc6efa5d95135f05aa4ba7596ea9d400c", + "senderId": "AG8kwwk4TsYfA2HdwaWBVAJQBj6VhdcpMo" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN", + "senderPublicKey": "036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd", + "timestamp": 0, + "asset": { + "votes": [ + "+036f612457adc81041662e664ca4ae64f844b412065f2b7d2f9f7d305e59c908cd" + ] + }, + "signature": "3045022100f3cdd7f688ad2d7b6a5b9cc7e793cb8a6e6e07d3327bc67add64691a53fd2911022026ae1adc8f4fcfc01bcca3efc83019026755b443a504265ad1f46f69d1f5951c", + "id": "dda86ecc0332e6c4eed1c0a5af7424374089b85dd274a300fed51b86e2655587", + "senderId": "AW8n3yvSAqUJkyfcG5u3bgRxsNKzXYPamN" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj", + "senderPublicKey": "03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564", + "timestamp": 0, + "asset": { + "votes": [ + "+03691178f8610d0a295e650201b62345056c788d7f9ac7e8570b69c6c90091b564" + ] + }, + "signature": "3045022100d419072a752acd55792257c96099fb14c56c29112a00535d39bca96fbd7951c902201abdf4db247dc956d79f4543c389823fbd1a9337f95d30df39603a3b52486bfb", + "id": "0998e9a055c53bf6697ee76af94c7a830c1364016d78fce889a21bc38ed70cd5", + "senderId": "AdWRsk7Lbo97jxGBKzLAFwevVHbqVbW1Cj" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN", + "senderPublicKey": "022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0", + "timestamp": 0, + "asset": { + "votes": [ + "+022f2978d57f95c021b9d4bf082b482738ce392bcf6bc213710e7a21504cfeb5a0" + ] + }, + "signature": "3045022100ba1e0ab761326d2a53cbda2a4a5135033c94d8166864d2ad3ceb963b4a0c046402207d755ecf4ada9fa2a598fd75e73a59d30cb83e01f510020b48b6bf162dc60b27", + "id": "be13743deb8486a575d1fb564d2b07d797ac77148d35793c9aca43c0d47aad61", + "senderId": "AV6GP5qhhsZG6MHb4gShy22doUnVjEKHcN" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA", + "senderPublicKey": "03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b", + "timestamp": 0, + "asset": { + "votes": [ + "+03e59140fde881ac437ec3dc3e372bf25f7c19f0b471a5b35cc30f783e8a7b811b" + ] + }, + "signature": "3044022038a491e2e13ac32025209d00aec1af31b73a8b6ee77ad9b8bb80a34f5df59dfc02200ce82c89fe9f88bd5af236ceeaa80f9954e3fb4af7bc884c447505751d49c134", + "id": "f1d3d44cc289837de9623cba8891a1ed1cde8918473a91e2daead29975afad22", + "senderId": "AaUgne8txmQB1iBboiFVLVHwLaYChZiFVA" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx", + "senderPublicKey": "0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc", + "timestamp": 0, + "asset": { + "votes": [ + "+0363550e2a3fe2153526effd4302045fa2c3027d0d9b30b19821a4870c8cb134bc" + ] + }, + "signature": "304402202ae599ce389cd030b8ab48ef53113458b9ba8bf9c9ed09c662eba2849bf540f802202ed63f8af492dd0b67d1b451170a989418a42466a3a7ffe89c4c5a18337e8fb9", + "id": "65ab302a44ea7550891eabc3b4a8d5ecbcb80784c4666195d5d0b7e33394300d", + "senderId": "Ac9dCo9dFgAkkBdEBsoRAN4Mm6xMsgYdZx" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK", + "senderPublicKey": "026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565", + "timestamp": 0, + "asset": { + "votes": [ + "+026c598170201caf0357f202ff14f365a3b09322071e347873869f58d776bfc565" + ] + }, + "signature": "304502210088a3a4e82d307c238e01ce154b57631d4429e0b591e828ec36839a783736e842022042c6e1d719781e2edca3dbfe84ad13b9e490821a47ccadfcff379decb9c873c0", + "id": "d26a7ea56f398634a81086bb15c2f0c863c71b8bd728304d324d8245a8fb6c73", + "senderId": "AdXbS4GKvV6TZVHrNzcYSQKfpenQnFGTxK" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz", + "senderPublicKey": "032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374", + "timestamp": 0, + "asset": { + "votes": [ + "+032c51f895ccdafae44e68baf283c50605d3f7dbba1c48011c6577383791f4a374" + ] + }, + "signature": "3045022100ae5805541f085a50076835422b2581d3b7a128a05b4f068ad7e3c14cd02799b802205f4bb40e06f90e02282ae74c0aba97923e601fd78234b9585468c4fb73f47893", + "id": "02504eae7ff4963c081219523bc48d7a07de4c29fdc1622224547f9a7c133abf", + "senderId": "AReCSCQRssLGF4XyhTjxhQm6mBFAWTaDTz" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp", + "senderPublicKey": "03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93", + "timestamp": 0, + "asset": { + "votes": [ + "+03832487ab0aa9450a4c223999bf4311b7b65c50c06baa90d19d4f65c27bfeeb93" + ] + }, + "signature": "3044022078d38cabd8f427ef381d0aa6a0b98c6a590cb18f47acc1d80b429a1c1959b0ab022022a70d4d93d650ca3121dde6065e80cd90d1e2e91cb90f0d0b2eadde609e0d75", + "id": "addb8c1baa833baa52a5b51d8a86f8524bde826b5c9f0a99e57070e6323e1dfc", + "senderId": "ASEJEDLfTxy6upQDWTuYucoVwMUcmhSGhp" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv", + "senderPublicKey": "038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17", + "timestamp": 0, + "asset": { + "votes": [ + "+038082dad560a22ea003022015e3136b21ef1ffd9f2fd50049026cbe8e2258ca17" + ] + }, + "signature": "3044022076dd065e3fba825b77884a179d0231d7fc9e7d3a02e34bc6565fab81a84e559e02200a880c028e690a9d6f2c4c6576b1bf3e913817c834da8ec6afdbadfae78d341d", + "id": "72f31f9a829b93045ef2e860b24c33b9be6a2621c26914acd42121215c1d517e", + "senderId": "ARAibxGqLQJTo1bWMJfu5fCc88rdWWjqgv" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P", + "senderPublicKey": "030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1", + "timestamp": 0, + "asset": { + "votes": [ + "+030a9321ff83e384aef559e6030008c23a137e3b3c5d45028e46cccbaafce772b1" + ] + }, + "signature": "304402205261d9d8ded6364fda8b10bd477982be84990cb010f9214d52c492676814e1f40220489f441ffe2478d361a12ab96caa59da495fe62d61d0e2255aa5ec4ed789afb8", + "id": "1f17b4ba072d205761ed3f786491eaf684ed3601b69082e487e568aa74a319e8", + "senderId": "APRiwbs17FdbaF8DYU9js2jChRehQc2e6P" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd", + "senderPublicKey": "02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d", + "timestamp": 0, + "asset": { + "votes": [ + "+02def27da9336e7fbf63131b8d7e5c9f45b296235db035f1f4242c507398f0f21d" + ] + }, + "signature": "3044022040219da41054a3eebd3122df7f09a62a4e8b4fdc287ae77221f2217b42f291ad02202b9a70c54bb546a604eafadcc086ef6b6570f57542374d87de02ad7f61fe51a4", + "id": "5fa837023159d6a3d6cf7c5b2ed6fe05ff7df19300226b2f0be5a48a06993780", + "senderId": "AbfQq8iRSf9TFQRzQWo33dHYU7HFMS17Zd" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo", + "senderPublicKey": "03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37", + "timestamp": 0, + "asset": { + "votes": [ + "+03287bfebba4c7881a0509717e71b34b63f31e40021c321f89ae04f84be6d6ac37" + ] + }, + "signature": "3045022100ded426768f114f459485ba6ae293c9649b340cf2dcb15e8e887fbb5fed6f7e0b0220752297022de6e93ff64bb9e07b4efef8e946cd2872f84d9e1cb3165ff5c342cb", + "id": "0a16dc31514629a36d7237968ada6a95d6cbec027b7d26e1e0f0d7d4febe9494", + "senderId": "ANBkoGqWeTSiaEVgVzSKZd3jS7UWzv9PSo" + }, + { + "type": 3, + "amount": 0, + "fee": 0, + "recipientId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD", + "senderPublicKey": "02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a", + "timestamp": 0, + "asset": { + "votes": [ + "+02275d8577a0ec2b75fc8683282d53c5db76ebc54514a80c2854e419b793ea259a" + ] + }, + "signature": "304402203aa292e7aedcd62bb5a79c2521b666b8e1886b57923d98f51911b0461cfdb5db0220539657d5c1dcb78c2c86376da87cc0db428e03c53da3f4f64ebe7115998f00b6", + "id": "8816f8d8c257ea0c951deba911266394b0f2614df023f8b4ffd9da43d36efd9d", + "senderId": "AJjv7WztjJNYHrLAeveG5NgHWp6699ZJwD" + } + ], "height": 1, "id": "17184958558311101492", "blockSignature": "304402202fe5de5697fa25d3d3c0cb24617ac02ddfb1c915ee9194a89f8392f948c6076402200d07c5244642fe36afa53fb2d048735f1adfa623e8fa4760487e5f72e17d253b" diff --git a/packages/core/lib/config/testnet/peers.json b/packages/core/lib/config/testnet/peers.json index ca55614776..297c08a102 100644 --- a/packages/core/lib/config/testnet/peers.json +++ b/packages/core/lib/config/testnet/peers.json @@ -1,12 +1,14 @@ { - "minimumVersion": ">=1.1.1", + "minimumVersion": ">=2.0.0", "minimumNetworkReach": 5, "globalTimeout": 5000, "coldStart": 30, - "whiteList":[], + "whiteList": [], "blackList": [], - "list": [{ - "ip": "127.0.0.1", - "port": 4000 - }] + "list": [ + { + "ip": "127.0.0.1", + "port": 4000 + } + ] } diff --git a/packages/core/lib/config/testnet/plugins.js b/packages/core/lib/config/testnet/plugins.js index 91fd7c4fa1..04b85febc0 100644 --- a/packages/core/lib/config/testnet/plugins.js +++ b/packages/core/lib/config/testnet/plugins.js @@ -1,100 +1,73 @@ module.exports = { '@arkecosystem/core-event-emitter': {}, '@arkecosystem/core-config': {}, - '@arkecosystem/core-logger': {}, '@arkecosystem/core-logger-winston': { transports: { console: { options: { - colorize: true, - level: process.env.ARK_LOG_LEVEL || 'debug' - } + level: process.env.ARK_LOG_LEVEL || 'debug', + }, }, dailyRotate: { options: { - filename: process.env.ARK_LOG_FILE || `${process.env.ARK_PATH_DATA}/logs/core/${process.env.ARK_NETWORK_NAME}/%DATE%.log`, - datePattern: 'YYYY-MM-DD', level: process.env.ARK_LOG_LEVEL || 'debug', - zippedArchive: true - } - } - } - }, - '@arkecosystem/core-database': { - snapshots: `${process.env.ARK_PATH_DATA}/snapshots/${process.env.ARK_NETWORK_NAME}` + }, + }, + }, }, - '@arkecosystem/core-database-sequelize': { - dialect: 'sqlite', - storage: process.env.ARK_DB_STORAGE || `${process.env.ARK_PATH_DATA}/database/${process.env.ARK_NETWORK_NAME}_.sqlite`, - // host: process.env.ARK_DB_HOST || 'localhost', - // dialect: process.env.ARK_DB_DIALECT || 'postgres', - // username: process.env.ARK_DB_USERNAME || 'ark', - // password: process.env.ARK_DB_PASSWORD || 'password', - // database: process.env.ARK_DB_DATABASE || 'ark_testnet', - logging: process.env.ARK_DB_LOGGING, - redis: { - host: process.env.ARK_REDIS_HOST || 'localhost', - port: process.env.ARK_REDIS_PORT || 6379 - } + '@arkecosystem/core-database-postgres': { + connection: { + host: process.env.ARK_DB_HOST || 'localhost', + port: process.env.ARK_DB_PORT || 5432, + database: + process.env.ARK_DB_DATABASE || `ark_${process.env.ARK_NETWORK_NAME}`, + user: process.env.ARK_DB_USERNAME || 'ark', + password: process.env.ARK_DB_PASSWORD || 'password', + }, }, - '@arkecosystem/core-transaction-pool': {}, - '@arkecosystem/core-transaction-pool-redis': { - enabled: !process.env.ARK_TRANSACTION_POOL_DISABLED, - key: 'ark-testnet', - maxTransactionsPerSender: process.env.ARK_TRANSACTION_POOL_MAX_PER_SENDER || 100, - whitelist: [], - redis: { - host: process.env.ARK_REDIS_HOST || 'localhost', - port: process.env.ARK_REDIS_PORT || 6379 - } + '@arkecosystem/core-transaction-pool-mem': { + enabled: true, + maxTransactionsPerSender: + process.env.ARK_TRANSACTION_POOL_MAX_PER_SENDER || 300, + allowedSenders: [], }, '@arkecosystem/core-p2p': { host: process.env.ARK_P2P_HOST || '0.0.0.0', port: process.env.ARK_P2P_PORT || 4000, - whitelist: ['127.0.0.1', '::ffff:127.0.0.1', '192.168.*'] + whitelist: ['127.0.0.1', '::ffff:127.0.0.1'], }, '@arkecosystem/core-blockchain': { - fastRebuild: false + fastRebuild: false, }, '@arkecosystem/core-api': { enabled: !process.env.ARK_API_DISABLED, host: process.env.ARK_API_HOST || '0.0.0.0', port: process.env.ARK_API_PORT || 4003, - whitelist: ['*'] + whitelist: ['*'], }, '@arkecosystem/core-webhooks': { enabled: process.env.ARK_WEBHOOKS_ENABLED, - database: { - dialect: 'sqlite', - storage: `${process.env.ARK_PATH_DATA}/database/${process.env.ARK_NETWORK_NAME}/webhooks.sqlite`, - logging: process.env.ARK_DB_LOGGING - }, - redis: { - host: process.env.ARK_REDIS_HOST || 'localhost', - port: process.env.ARK_REDIS_PORT || 6379 - }, server: { enabled: process.env.ARK_WEBHOOKS_API_ENABLED, host: process.env.ARK_WEBHOOKS_HOST || '0.0.0.0', port: process.env.ARK_WEBHOOKS_PORT || 4004, - whitelist: ['127.0.0.1', '::ffff:127.0.0.1', '192.168.*'] - } + whitelist: ['127.0.0.1', '::ffff:127.0.0.1'], + }, }, '@arkecosystem/core-graphql': { enabled: process.env.ARK_GRAPHQL_ENABLED, host: process.env.ARK_GRAPHQL_HOST || '0.0.0.0', port: process.env.ARK_GRAPHQL_PORT || 4005, - path: '/graphql', - graphiql: true }, '@arkecosystem/core-forger': { - hosts: ['http://127.0.0.1:4000'] + hosts: [`http://127.0.0.1:${process.env.ARK_P2P_PORT || 4000}`], }, '@arkecosystem/core-json-rpc': { enabled: process.env.ARK_JSON_RPC_ENABLED, host: process.env.ARK_JSON_RPC_HOST || '0.0.0.0', port: process.env.ARK_JSON_RPC_PORT || 8080, - allowRemote: true, - whitelist: ['127.0.0.1', '::ffff:127.0.0.1', '192.168.*'] - } + allowRemote: false, + whitelist: ['127.0.0.1', '::ffff:127.0.0.1'], + }, + '@arkecosystem/core-snapshots': {}, } diff --git a/packages/core/lib/snapshot.js b/packages/core/lib/snapshot.js deleted file mode 100644 index 888588180c..0000000000 --- a/packages/core/lib/snapshot.js +++ /dev/null @@ -1,29 +0,0 @@ -'use strict' - -const container = require('@arkecosystem/core-container') - -/** - * Create a snapshot. - * @param {Object} options - * @return {void} - */ -module.exports = async (options) => { - await container.setUp(options, { - include: [ - '@arkecosystem/core-event-emitter', - '@arkecosystem/core-config', - '@arkecosystem/core-logger', - '@arkecosystem/core-logger-winston', - '@arkecosystem/core-database', - '@arkecosystem/core-database-sequelize', - '@arkecosystem/core-blockchain' - ], - options: { - '@arkecosystem/core-blockchain': { - networkStart: options.networkStart - } - } - }) - - container.resolvePlugin('database').snapshot() -} diff --git a/packages/core/lib/start-forger.js b/packages/core/lib/start-forger.js index 7f61d342fd..d54b102ae0 100644 --- a/packages/core/lib/start-forger.js +++ b/packages/core/lib/start-forger.js @@ -1,30 +1,26 @@ -'use strict' - -const container = require('@arkecosystem/core-container') +const app = require('@arkecosystem/core-container') /** * Start a forger. * @param {Object} options + * @param {String} version * @return {void} */ -module.exports = async (options) => { - await container.setUp(options, { +module.exports = async (options, version) => { + await app.setUp(version, options, { include: [ '@arkecosystem/core-event-emitter', '@arkecosystem/core-config', '@arkecosystem/core-logger', '@arkecosystem/core-logger-winston', - '@arkecosystem/core-forger' + '@arkecosystem/core-forger', ], options: { - '@arkecosystem/core-blockchain': { - networkStart: options.networkStart - }, '@arkecosystem/core-forger': { - bip38: options.bip38, + bip38: options.bip38 || process.env.ARK_FORGER_BIP38, address: options.address, - password: options.password - } - } + password: options.password || process.env.ARK_FORGER_PASSWORD, + }, + }, }) } diff --git a/packages/core/lib/start-relay-and-forger.js b/packages/core/lib/start-relay-and-forger.js index 3aadf5beb5..51bd23c405 100644 --- a/packages/core/lib/start-relay-and-forger.js +++ b/packages/core/lib/start-relay-and-forger.js @@ -1,26 +1,27 @@ -'use strict' - -const container = require('@arkecosystem/core-container') +const app = require('@arkecosystem/core-container') /** - * Start a node. + * Start a relay and forger. * @param {Object} options + * @param {String} version * @return {void} */ -module.exports = async (options) => { - await container.setUp(options, { +module.exports = async (options, version) => { + await app.setUp(version, options, { options: { '@arkecosystem/core-p2p': { - networkStart: options.networkStart + networkStart: options.networkStart, + disableDiscovery: options.disableDiscovery, + skipDiscovery: options.skipDiscovery, }, '@arkecosystem/core-blockchain': { - networkStart: options.networkStart + networkStart: options.networkStart, }, '@arkecosystem/core-forger': { - bip38: options.bip38, + bip38: options.bip38 || process.env.ARK_FORGER_BIP38, address: options.address, - password: options.password - } - } + password: options.password || process.env.ARK_FORGER_PASSWORD, + }, + }, }) } diff --git a/packages/core/lib/start-relay.js b/packages/core/lib/start-relay.js index 9bcaa52b0e..ebb9275c55 100644 --- a/packages/core/lib/start-relay.js +++ b/packages/core/lib/start-relay.js @@ -1,19 +1,23 @@ -'use strict' - -const container = require('@arkecosystem/core-container') +const app = require('@arkecosystem/core-container') /** * Start a relay. * @param {Object} options + * @param {String} version * @return {void} */ -module.exports = async (options) => { - await container.setUp(options, { +module.exports = async (options, version) => { + await app.setUp(version, options, { exclude: ['@arkecosystem/core-forger'], options: { + '@arkecosystem/core-p2p': { + networkStart: options.networkStart, + disableDiscovery: options.disableDiscovery, + skipDiscovery: options.skipDiscovery, + }, '@arkecosystem/core-blockchain': { - networkStart: options.networkStart - } - } + networkStart: options.networkStart, + }, + }, }) } diff --git a/packages/core/package.json b/packages/core/package.json index b64c4dd100..2bd379aec2 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,7 +1,7 @@ { "name": "@arkecosystem/core", - "description": "Core of the ARK Blockchain", - "version": "0.1.1", + "description": "Core of the Ark Blockchain", + "version": "2.0.0", "contributors": [ "François-Xavier Thoorens ", "Kristjan Košič ", @@ -46,31 +46,31 @@ "full:testnet:2tier:1": "cross-env ARK_ENV=test ./bin/ark start --config ./lib/config/testnet.1 --network testnet --network-start", "full:testnet:2tier": "cross-env ARK_ENV=test ./bin/ark start --config ./lib/config/testnet.1 --network testnet --network-start && ./bin/ark start --config ./lib/config/testnet.2 --network testnet --network-start", "lint": "eslint ./ --fix", - "depcheck": "depcheck ./ --ignores commander,bip38,fs,wif,@arkecosystem/core-api,@arkecosystem/core-blockchain,@arkecosystem/core-config,@arkecosystem/core-database,@arkecosystem/core-database-sequelize,@arkecosystem/core-forger,@arkecosystem/core-graphql,@arkecosystem/core-json-rpc,@arkecosystem/core-logger,@arkecosystem/core-logger-winston,@arkecosystem/core-p2p,@arkecosystem/core-transaction-pool,@arkecosystem/core-transaction-pool-redis,@arkecosystem/core-webhooks,@arkecosystem/crypto" + "depcheck": "depcheck ./ --ignores=commander,bip38,fs,wif,@arkecosystem/core-api,@arkecosystem/core-blockchain,@arkecosystem/core-config,@arkecosystem/core-database,@arkecosystem/core-database-postgres,@arkecosystem/core-forger,@arkecosystem/core-graphql,@arkecosystem/core-json-rpc,@arkecosystem/core-logger,@arkecosystem/core-logger-winston,@arkecosystem/core-p2p,@arkecosystem/core-transaction-pool,@arkecosystem/core-transaction-pool-mem,@arkecosystem/core-webhooks,@arkecosystem/core-snapshots,@arkecosystem/crypto" }, "dependencies": { - "@arkecosystem/core-api": "^0.1.1", - "@arkecosystem/core-blockchain": "^0.1.1", - "@arkecosystem/core-config": "^0.1.1", - "@arkecosystem/core-container": "^0.1.1", - "@arkecosystem/core-database": "^0.1.1", - "@arkecosystem/core-database-sequelize": "^0.1.1", - "@arkecosystem/core-forger": "^0.1.1", - "@arkecosystem/core-graphql": "^0.1.1", - "@arkecosystem/core-json-rpc": "^0.1.1", - "@arkecosystem/core-logger": "^0.1.1", - "@arkecosystem/core-logger-winston": "^0.1.1", - "@arkecosystem/core-p2p": "^0.1.1", - "@arkecosystem/core-transaction-pool": "^0.1.1", - "@arkecosystem/core-transaction-pool-redis": "^0.1.1", - "@arkecosystem/core-webhooks": "^0.1.1", - "@arkecosystem/crypto": "^0.1.1", + "@arkecosystem/core-api": "~0.2", + "@arkecosystem/core-blockchain": "~0.2", + "@arkecosystem/core-config": "~0.2", + "@arkecosystem/core-container": "~0.2", + "@arkecosystem/core-database-postgres": "~0.2", + "@arkecosystem/core-forger": "~0.2", + "@arkecosystem/core-graphql": "~0.2", + "@arkecosystem/core-json-rpc": "~0.2", + "@arkecosystem/core-logger-winston": "~0.2", + "@arkecosystem/core-p2p": "~0.2", + "@arkecosystem/core-snapshots": "~0.1", + "@arkecosystem/core-transaction-pool-mem": "~0.2", + "@arkecosystem/core-webhooks": "~0.2", + "@arkecosystem/crypto": "~0.2", "bip38": "^2.0.2", - "commander": "^2.15.1", - "fs": "^0.0.1-security", + "commander": "^2.19.0", "wif": "^2.0.6" }, "publishConfig": { "access": "public" + }, + "engines": { + "node": ">=10.x" } } diff --git a/packages/crypto/CHANGELOG.md b/packages/crypto/CHANGELOG.md index 127cc35e42..3a2b4edc73 100644 --- a/packages/crypto/CHANGELOG.md +++ b/packages/crypto/CHANGELOG.md @@ -7,6 +7,83 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ## Unreleased -## 0.0.1 - 2018-05-31 +## 0.2.5 - 2018-11-19 + +### Fixed + +- Added signWithWif to sign mixin used for vote builder + +## 0.2.4 - 2018-11-09 + +### Added + +- Address Identity +- Keys Identity +- Private Key Identity +- Public Key Identity +- WIF Identity + +### Fixed + +- Comparison of upper/lower-case public keys +- Validate the vendor field length +- Use network version in transaction builder when signing with mixin + +## 0.2.3 - 2018-10-26 + ### Added + +- Allow Message signing with WIF + +### Fixed + +- Use network WIF as default for WIF operations + +## 0.2.2 - 2018-10-23 + +### Added + +- Message signing +- Message verification + +## 0.2.1 - 2018-10-18 + +### Added + +- Sign transactions via WIF +- HDWallet handling + +### Changed + +- Exclude the network from the signing object +- Handle numerical values as `BigNumber` instances +- Change `transaction.serialized` from `Buffer` to hex + +### Fixed + +- Limit decimals to 0 to avoid floating numbers +- Properly verify block payload length +- Broken verification of faulty type 1 and 4 +- Broken multisignature serialization + +## 0.2.0 - 2018-09-17 + +### Changed + +- Improved overall performance of the crypto by calling the `secp256k1` methods directly instead of using a BTC package + +## 0.1.2 - 2018-08-10 + +### Fixed + +- Webpack build + +### Removed + +- Old and unused methods + +## 0.1.1 - 2018-06-14 + +### Added + - initial release diff --git a/packages/crypto/README.md b/packages/crypto/README.md index cf80c78967..1e5cfead81 100644 --- a/packages/crypto/README.md +++ b/packages/crypto/README.md @@ -1,6 +1,8 @@ -![ARK Core](banner.png) +# Ark - Crypto -# ARK - Crypto +

+ +

## Installation @@ -19,13 +21,13 @@ If you want to use the CDN version: Import the library in node.js: ``` -import ArkEcosytemCrypto from @arkecosystem/crypto +import ArkEcosystemCrypto from @arkecosystem/crypto ``` Use the library: ``` -const constants = ArkEcosytemCrypto.constants +const constants = ArkEcosystemCrypto.constants ``` ## Security diff --git a/packages/crypto/__tests__/builder/transactions/__shared__/transaction.js b/packages/crypto/__tests__/builder/transactions/__shared__/transaction.js index 9d5aacf450..608cb270e5 100644 --- a/packages/crypto/__tests__/builder/transactions/__shared__/transaction.js +++ b/packages/crypto/__tests__/builder/transactions/__shared__/transaction.js @@ -1,6 +1,6 @@ const TransactionBuilder = require('../../../../lib/builder/transactions/transaction') -const crypto = require('../../../../lib/crypto/crypto') -const { slots } = require('../../../../lib/crypto') +const Bignum = require('../../../../lib/utils/bignum') +const { crypto, slots } = require('../../../../lib/crypto') const configManager = require('../../../../lib/managers/config') const Transaction = require('../../../../lib/models/transaction') @@ -18,9 +18,12 @@ module.exports = () => { it('should have the essential properties', () => { expect(builder).toHaveProperty('data.id', null) - expect(builder).toHaveProperty('data.timestamp', slots.getTime()) + expect(builder).toHaveProperty('data.timestamp') expect(builder).toHaveProperty('data.version', 0x01) - expect(builder).toHaveProperty('data.network', configManager.get('pubKeyHash')) + expect(builder).toHaveProperty( + 'data.network', + configManager.get('pubKeyHash'), + ) expect(builder).toHaveProperty('data.type') expect(builder).toHaveProperty('data.fee') @@ -35,13 +38,14 @@ module.exports = () => { data = { id: 'fake-id', - amount: 1, - fee: 1, + amount: 0, + fee: 0, recipientId: 'DK2v39r3hD9Lw8R5fFFHjUyCtXm1VETi42', - senderPublicKey: '035440a82cb44faef75c3d7d881696530aac4d50da314b91795740cdbeaba9113c', + senderPublicKey: + '035440a82cb44faef75c3d7d881696530aac4d50da314b91795740cdbeaba9113c', timestamp, type: 0, - version: 0x03 + version: 0x03, } }) @@ -51,10 +55,14 @@ module.exports = () => { const transaction = builder.build() expect(transaction).toBeInstanceOf(Transaction) - expect(transaction.amount).toBe(1) - expect(transaction.fee).toBe(1) - expect(transaction.recipientId).toBe('DK2v39r3hD9Lw8R5fFFHjUyCtXm1VETi42') - expect(transaction.senderPublicKey).toBe('035440a82cb44faef75c3d7d881696530aac4d50da314b91795740cdbeaba9113c') + expect(transaction.amount).toEqual(Bignum.ZERO) + expect(transaction.fee).toEqual(Bignum.ZERO) + expect(transaction.recipientId).toBe( + 'DK2v39r3hD9Lw8R5fFFHjUyCtXm1VETi42', + ) + expect(transaction.senderPublicKey).toBe( + '035440a82cb44faef75c3d7d881696530aac4d50da314b91795740cdbeaba9113c', + ) expect(transaction.timestamp).toBe(timestamp) expect(transaction.type).toBe(0) expect(transaction.version).toBe(0x03) @@ -65,14 +73,18 @@ module.exports = () => { const transaction = builder.build({ amount: 33, - fee: 1000 + fee: 1000, }) expect(transaction).toBeInstanceOf(Transaction) - expect(transaction.amount).toBe(33) - expect(transaction.fee).toBe(1000) - expect(transaction.recipientId).toBe('DK2v39r3hD9Lw8R5fFFHjUyCtXm1VETi42') - expect(transaction.senderPublicKey).toBe('035440a82cb44faef75c3d7d881696530aac4d50da314b91795740cdbeaba9113c') + expect(transaction.amount).toEqual(new Bignum(33)) + expect(transaction.fee).toEqual(new Bignum(1000)) + expect(transaction.recipientId).toBe( + 'DK2v39r3hD9Lw8R5fFFHjUyCtXm1VETi42', + ) + expect(transaction.senderPublicKey).toBe( + '035440a82cb44faef75c3d7d881696530aac4d50da314b91795740cdbeaba9113c', + ) expect(transaction.timestamp).toBe(timestamp) expect(transaction.version).toBe(0x03) }) @@ -80,15 +92,15 @@ module.exports = () => { describe('fee', () => { it('should set the fee', () => { - builder.fee('fake') - expect(builder.data.fee).toBe('fake') + builder.fee(255) + expect(builder.data.fee).toBe(255) }) }) describe('amount', () => { it('should set the amount', () => { - builder.amount('fake') - expect(builder.data.amount).toBe('fake') + builder.amount(255) + expect(builder.data.amount).toBe(255) }) }) @@ -109,11 +121,11 @@ module.exports = () => { describe('sign', () => { it('signs this transaction with the keys of the passphrase', () => { - let keys - crypto.getKeys = jest.fn(pass => { - keys = { publicKey: `${pass} public key` } - return keys - }) + const keys = { + publicKey: + '02d0d835266297f15c192be2636eb3fbc30b39b87fc583ff112062ef8ae1a1f2af', + } + crypto.getKeys = jest.fn(() => keys) crypto.sign = jest.fn() const signingObject = builder.__getSigningObject() @@ -124,10 +136,44 @@ module.exports = () => { }) it('establishes the public key of the sender', () => { - crypto.getKeys = jest.fn(pass => ({ publicKey: `${pass} public key` })) + const keys = { + publicKey: + '02d0d835266297f15c192be2636eb3fbc30b39b87fc583ff112062ef8ae1a1f2af', + } + crypto.getKeys = jest.fn(() => keys) crypto.sign = jest.fn() builder.sign('my real pass') - expect(builder.data.senderPublicKey).toBe('my real pass public key') + expect(builder.data.senderPublicKey).toBe(keys.publicKey) + }) + }) + + describe('signWithWif', () => { + it('signs this transaction with keys from a wif', () => { + const keys = { + publicKey: + '02d0d835266297f15c192be2636eb3fbc30b39b87fc583ff112062ef8ae1a1f2af', + } + crypto.getKeysFromWIF = jest.fn(() => keys) + crypto.sign = jest.fn() + const signingObject = builder.__getSigningObject() + + builder.network(23).signWithWif('dummy pass') + + expect(crypto.getKeysFromWIF).toHaveBeenCalledWith('dummy pass', { + wif: 170, + }) + expect(crypto.sign).toHaveBeenCalledWith(signingObject, keys) + }) + + it('establishes the public key of the sender', () => { + const keys = { + publicKey: + '02d0d835266297f15c192be2636eb3fbc30b39b87fc583ff112062ef8ae1a1f2af', + } + crypto.getKeysFromWIF = jest.fn(() => keys) + crypto.sign = jest.fn() + builder.signWithWif('my real pass') + expect(builder.data.senderPublicKey).toBe(keys.publicKey) }) }) @@ -147,4 +193,24 @@ module.exports = () => { expect(crypto.secondSign).toHaveBeenCalledWith(signingObject, keys) }) }) + + describe('secondSignWithWif', () => { + it('signs this transaction with the keys of a second wif', () => { + let keys + crypto.getKeysFromWIF = jest.fn(pass => { + keys = { publicKey: `${pass} public key` } + return keys + }) + crypto.secondSign = jest.fn() + const signingObject = builder.__getSigningObject() + + builder.network(23).secondSignWithWif('my very real second pass') + + expect(crypto.getKeysFromWIF).toHaveBeenCalledWith( + 'my very real second pass', + { wif: 170 }, + ) + expect(crypto.secondSign).toHaveBeenCalledWith(signingObject, keys) + }) + }) } diff --git a/packages/crypto/__tests__/builder/transactions/delegate-registration.test.js b/packages/crypto/__tests__/builder/transactions/delegate-registration.test.js index d5854ce69c..51fee59edd 100644 --- a/packages/crypto/__tests__/builder/transactions/delegate-registration.test.js +++ b/packages/crypto/__tests__/builder/transactions/delegate-registration.test.js @@ -13,12 +13,35 @@ beforeEach(() => { }) describe('Delegate Registration Transaction', () => { + describe('verify', () => { + it('should be valid with a signature', () => { + const actual = builder.usernameAsset('homer').sign('dummy passphrase') + + expect(actual.build().verify()).toBeTrue() + }) + + it('should be valid with a second signature', () => { + const actual = builder + .usernameAsset('homer') + .sign('dummy passphrase') + .secondSign('dummy passphrase') + + expect(actual.build().verify()).toBeTrue() + }) + }) + transactionBuilderTests() it('should have its specific properties', () => { - expect(builder).toHaveProperty('data.type', TRANSACTION_TYPES.DELEGATE_REGISTRATION) + expect(builder).toHaveProperty( + 'data.type', + TRANSACTION_TYPES.DELEGATE_REGISTRATION, + ) expect(builder).toHaveProperty('data.amount', 0) - expect(builder).toHaveProperty('data.fee', feeManager.get(TRANSACTION_TYPES.DELEGATE_REGISTRATION)) + expect(builder).toHaveProperty( + 'data.fee', + feeManager.get(TRANSACTION_TYPES.DELEGATE_REGISTRATION), + ) expect(builder).toHaveProperty('data.recipientId', null) expect(builder).toHaveProperty('data.senderPublicKey', null) expect(builder).toHaveProperty('data.asset', { delegate: {} }) @@ -45,13 +68,15 @@ describe('Delegate Registration Transaction', () => { }) // FIXME problems with ark-js V1 - xdescribe('getStruct', () => { + describe('getStruct', () => { + beforeEach(() => { + builder = builder.usernameAsset('homer') + }) it('should fail if the transaction is not signed', () => { try { expect(() => builder.getStruct()).toThrow(/transaction.*sign/) expect('fail').toBe('this should fail when no error is thrown') } catch (_error) { - builder = ark.getBuilder().delegateRegistration() expect(() => builder.sign('example pass').getStruct()).not.toThrow() } }) @@ -62,39 +87,47 @@ describe('Delegate Registration Transaction', () => { }) // NOTE: V2 - xit('generates and returns the bytes as hex', () => { - expect(builder.getStruct().hex).toBe(crypto.getBytes(builder).toString('hex')) + it.skip('generates and returns the bytes as hex', () => { + expect(builder.getStruct().hex).toBe( + crypto.getBytes(builder.data).toString('hex'), + ) }) it('returns the id', () => { - expect(builder.getStruct().id).toBe(crypto.getId(builder)) + expect(builder.getStruct().id).toBe( + crypto.getId(builder.data).toString('hex'), + ) }) it('returns the signature', () => { - expect(builder.getStruct().signature).toBe(builder.signature) + expect(builder.getStruct().signature).toBe(builder.data.signature) }) it('returns the second signature', () => { - expect(builder.getStruct().secondSignature).toBe(builder.secondSignature) + expect(builder.getStruct().secondSignature).toBe( + builder.data.secondSignature, + ) }) it('returns the timestamp', () => { - expect(builder.getStruct().timestamp).toBe(builder.timestamp) + expect(builder.getStruct().timestamp).toBe(builder.data.timestamp) }) it('returns the transaction type', () => { - expect(builder.getStruct().type).toBe(builder.type) + expect(builder.getStruct().type).toBe(builder.data.type) }) it('returns the fee', () => { - expect(builder.getStruct().fee).toBe(builder.fee) + expect(builder.getStruct().fee).toBe(builder.data.fee) }) it('returns the sender public key', () => { - expect(builder.getStruct().senderPublicKey).toBe(builder.senderPublicKey) + expect(builder.getStruct().senderPublicKey).toBe( + builder.data.senderPublicKey, + ) }) it('returns the amount', () => { - expect(builder.getStruct().amount).toBe(builder.amount) + expect(builder.getStruct().amount).toBe(builder.data.amount) }) it('returns the recipient id', () => { - expect(builder.getStruct().recipientId).toBe(builder.recipientId) + expect(builder.getStruct().recipientId).toBe(builder.data.recipientId) }) it('returns the asset', () => { - expect(builder.getStruct().asset).toBe(builder.asset) + expect(builder.getStruct().asset).toBe(builder.data.asset) }) }) }) diff --git a/packages/crypto/__tests__/builder/transactions/delegate-resignation.test.js b/packages/crypto/__tests__/builder/transactions/delegate-resignation.test.js index a1dc7d0532..6a036a0a74 100644 --- a/packages/crypto/__tests__/builder/transactions/delegate-resignation.test.js +++ b/packages/crypto/__tests__/builder/transactions/delegate-resignation.test.js @@ -15,7 +15,13 @@ describe('Delegate Resignation Transaction', () => { transactionBuilderTests() it('should have its specific properties', () => { - expect(builder).toHaveProperty('data.type', TRANSACTION_TYPES.DELEGATE_RESIGNATION) - expect(builder).toHaveProperty('data.fee', feeManager.get(TRANSACTION_TYPES.DELEGATE_RESIGNATION)) + expect(builder).toHaveProperty( + 'data.type', + TRANSACTION_TYPES.DELEGATE_RESIGNATION, + ) + expect(builder).toHaveProperty( + 'data.fee', + feeManager.get(TRANSACTION_TYPES.DELEGATE_RESIGNATION), + ) }) }) diff --git a/packages/crypto/__tests__/builder/transactions/ipfs.test.js b/packages/crypto/__tests__/builder/transactions/ipfs.test.js index c1cec1d065..1512e85e70 100644 --- a/packages/crypto/__tests__/builder/transactions/ipfs.test.js +++ b/packages/crypto/__tests__/builder/transactions/ipfs.test.js @@ -16,7 +16,10 @@ describe('IPFS Transaction', () => { it('should have its specific properties', () => { expect(builder).toHaveProperty('data.type', TRANSACTION_TYPES.IPFS) - expect(builder).toHaveProperty('data.fee', feeManager.get(TRANSACTION_TYPES.IPFS)) + expect(builder).toHaveProperty( + 'data.fee', + feeManager.get(TRANSACTION_TYPES.IPFS), + ) expect(builder).toHaveProperty('data.amount', 0) expect(builder).toHaveProperty('data.vendorFieldHex', null) expect(builder).toHaveProperty('data.senderPublicKey', null) @@ -37,7 +40,7 @@ describe('IPFS Transaction', () => { describe('vendorField', () => { // TODO This is test is OK, but the Subject Under Test might be wrong, // so it is better to not assume that this is the desired behaviour - xit('should generate and set the vendorFieldHex', () => { + it('should generate and set the vendorFieldHex', () => { const data = 'hash' const hex = Buffer.from(data, 0).toString('hex') const paddedHex = hex.padStart(128, '0') diff --git a/packages/crypto/__tests__/builder/transactions/multi-payment.test.js b/packages/crypto/__tests__/builder/transactions/multi-payment.test.js index be91374431..f957c70315 100644 --- a/packages/crypto/__tests__/builder/transactions/multi-payment.test.js +++ b/packages/crypto/__tests__/builder/transactions/multi-payment.test.js @@ -16,7 +16,10 @@ describe('Multi Payment Transaction', () => { it('should have its specific properties', () => { expect(builder).toHaveProperty('data.type', TRANSACTION_TYPES.MULTI_PAYMENT) - expect(builder).toHaveProperty('data.fee', feeManager.get(TRANSACTION_TYPES.MULTI_PAYMENT)) + expect(builder).toHaveProperty( + 'data.fee', + feeManager.get(TRANSACTION_TYPES.MULTI_PAYMENT), + ) expect(builder).toHaveProperty('data.payments', {}) expect(builder).toHaveProperty('data.vendorFieldHex', null) }) @@ -41,7 +44,7 @@ describe('Multi Payment Transaction', () => { address3: 'address', amount1: 'amount', amount2: 'amount', - amount3: 'amount' + amount3: 'amount', }) }) }) diff --git a/packages/crypto/__tests__/builder/transactions/multi-signature.test.js b/packages/crypto/__tests__/builder/transactions/multi-signature.test.js index 458ce0a465..2098a0de27 100644 --- a/packages/crypto/__tests__/builder/transactions/multi-signature.test.js +++ b/packages/crypto/__tests__/builder/transactions/multi-signature.test.js @@ -13,10 +13,34 @@ beforeEach(() => { }) describe('Multi Signature Transaction', () => { + describe('verify', () => { + it('should be valid with a signature', () => { + const actual = builder + .multiSignatureAsset({ + keysgroup: [ + '+0376982a97dadbc65e694743d386084548a65431a82ce935ac9d957b1cffab2784', + '+03793904e0df839809bc89f2839e1ae4f8b1ea97ede6592b7d1e4d0ee194ca2998', + '+03e710267cdbc87cf8c2f32a6c3f22e1d1ce22ba30e1915360f511a2b16df8c5a5', + ], + lifetime: 72, + min: 2, + }) + .sign('dummy passphrase') + .multiSignatureSign('multi passphrase 1') + .multiSignatureSign('multi passphrase 2') + .multiSignatureSign('multi passphrase 3') + + expect(actual.build().verify()).toBeTrue() + }) + }) + transactionBuilderTests() it('should have its specific properties', () => { - expect(builder).toHaveProperty('data.type', TRANSACTION_TYPES.MULTI_SIGNATURE) + expect(builder).toHaveProperty( + 'data.type', + TRANSACTION_TYPES.MULTI_SIGNATURE, + ) expect(builder).toHaveProperty('data.fee', 0) expect(builder).toHaveProperty('data.amount', 0) expect(builder).toHaveProperty('data.recipientId', null) @@ -30,7 +54,7 @@ describe('Multi Signature Transaction', () => { const multisignature = { keysgroup: ['key a', 'key b', 'key c'], lifetime: 1, - min: 1 + min: 1, } it('establishes the multi-signature on the asset', () => { @@ -40,7 +64,7 @@ describe('Multi Signature Transaction', () => { it('calculates and establish the fee', () => { builder.multiSignatureAsset(multisignature) - expect(builder.data.fee).toEqual(4 * multiSignatureFee) + expect(builder.data.fee).toBe(4 * multiSignatureFee) }) }) @@ -48,11 +72,16 @@ describe('Multi Signature Transaction', () => { it('establishes the recipient id', () => { const pass = 'dummy pass' - crypto.getKeys = jest.fn(pass => ({ publicKey: `${pass} public key` })) + crypto.getKeys = jest.fn(() => ({ + publicKey: + '02d0d835266297f15c192be2636eb3fbc30b39b87fc583ff112062ef8ae1a1f2af', + })) crypto.sign = jest.fn() builder.sign(pass) - expect(builder.data.recipientId).toBe('DKNJwdxrPQg6xXbrpaQLfgi6kC2ndaz8N5') + expect(builder.data.recipientId).toBe( + 'D5q7YfEFDky1JJVQQEy4MGyiUhr5cGg47F', + ) }) }) @@ -61,8 +90,8 @@ describe('Multi Signature Transaction', () => { const pass = 'dummy pass' const signature = `${pass} signature` - crypto.getKeys = jest.fn(pass => ({ publicKey: `${pass} public key` })) - crypto.sign = jest.fn(() => (signature)) + crypto.getKeys = jest.fn(value => ({ publicKey: `${value} public key` })) + crypto.sign = jest.fn(() => signature) builder.multiSignatureSign(pass) expect(builder.data.signatures).toIncludeAllMembers([signature]) diff --git a/packages/crypto/__tests__/builder/transactions/second-signature.test.js b/packages/crypto/__tests__/builder/transactions/second-signature.test.js index 432204e264..321076b2fd 100644 --- a/packages/crypto/__tests__/builder/transactions/second-signature.test.js +++ b/packages/crypto/__tests__/builder/transactions/second-signature.test.js @@ -13,11 +13,27 @@ beforeEach(() => { }) describe('Second Signature Transaction', () => { + describe('verify', () => { + it('should be valid with a signature', () => { + const actual = builder + .signatureAsset('signature') + .sign('dummy passphrase') + + expect(actual.build().verify()).toBeTrue() + }) + }) + transactionBuilderTests() it('should have its specific properties', () => { - expect(builder).toHaveProperty('data.type', TRANSACTION_TYPES.SECOND_SIGNATURE) - expect(builder).toHaveProperty('data.fee', feeManager.get(TRANSACTION_TYPES.SECOND_SIGNATURE)) + expect(builder).toHaveProperty( + 'data.type', + TRANSACTION_TYPES.SECOND_SIGNATURE, + ) + expect(builder).toHaveProperty( + 'data.fee', + feeManager.get(TRANSACTION_TYPES.SECOND_SIGNATURE), + ) expect(builder).toHaveProperty('data.amount', 0) expect(builder).toHaveProperty('data.recipientId', null) expect(builder).toHaveProperty('data.senderPublicKey', null) diff --git a/packages/crypto/__tests__/builder/transactions/timelock-transfer.test.js b/packages/crypto/__tests__/builder/transactions/timelock-transfer.test.js index f55b341ad9..bfd26a3b6a 100644 --- a/packages/crypto/__tests__/builder/transactions/timelock-transfer.test.js +++ b/packages/crypto/__tests__/builder/transactions/timelock-transfer.test.js @@ -15,8 +15,14 @@ describe('Timelock Transfer Transaction', () => { transactionBuilderTests() it('should have its specific properties', () => { - expect(builder).toHaveProperty('data.type', TRANSACTION_TYPES.TIMELOCK_TRANSFER) - expect(builder).toHaveProperty('data.fee', feeManager.get(TRANSACTION_TYPES.TIMELOCK_TRANSFER)) + expect(builder).toHaveProperty( + 'data.type', + TRANSACTION_TYPES.TIMELOCK_TRANSFER, + ) + expect(builder).toHaveProperty( + 'data.fee', + feeManager.get(TRANSACTION_TYPES.TIMELOCK_TRANSFER), + ) expect(builder).toHaveProperty('data.amount', 0) expect(builder).toHaveProperty('data.recipientId', null) expect(builder).toHaveProperty('data.senderPublicKey', null) diff --git a/packages/crypto/__tests__/builder/transactions/transfer.test.js b/packages/crypto/__tests__/builder/transactions/transfer.test.js index 685f0bbfe0..b24abcd006 100644 --- a/packages/crypto/__tests__/builder/transactions/transfer.test.js +++ b/packages/crypto/__tests__/builder/transactions/transfer.test.js @@ -1,5 +1,6 @@ const ark = require('../../../lib/client') const { TRANSACTION_TYPES } = require('../../../lib/constants') +const { crypto } = require('../../../lib/crypto') const feeManager = require('../../../lib/managers/fee') const transactionBuilderTests = require('./__shared__/transaction') @@ -12,15 +13,91 @@ beforeEach(() => { }) describe('Transfer Transaction', () => { + describe('verify', () => { + it('should be valid with a signature', () => { + const actual = builder + .recipientId('D5q7YfEFDky1JJVQQEy4MGyiUhr5cGg47F') + .amount(1) + .vendorField('dummy') + .sign('dummy passphrase') + + expect(actual.build().verify()).toBeTrue() + }) + + it('should be valid with a second signature', () => { + const actual = builder + .recipientId('D5q7YfEFDky1JJVQQEy4MGyiUhr5cGg47F') + .amount(1) + .vendorField('dummy') + .sign('dummy passphrase') + .secondSign('dummy passphrase') + + expect(actual.build().verify()).toBeTrue() + }) + }) + + describe('signWithWif', () => { + it('should sign a transaction and match signed with a passphrase', () => { + const passphrase = 'sample passphrase' + const network = 23 + const keys = crypto.getKeys(passphrase) + const wif = crypto.keysToWIF(keys, { wif: 170 }) + + const wifTransaction = builder + .amount(10) + .fee(10) + .network(network) + + const passphraseTransaction = ark.getBuilder().transfer() + passphraseTransaction.data = { ...wifTransaction.data } + + wifTransaction.signWithWif(wif, 170) + passphraseTransaction.sign(passphrase) + + expect(wifTransaction.data.signature).toBe( + passphraseTransaction.data.signature, + ) + }) + }) + + describe('secondSignWithWif', () => { + it('should sign a transaction and match signed with a passphrase', () => { + const passphrase = 'first passphrase' + const secondPassphrase = 'second passphrase' + const network = 23 + const keys = crypto.getKeys(secondPassphrase) + const wif = crypto.keysToWIF(keys, { wif: 170 }) + + const wifTransaction = builder + .amount(10) + .fee(10) + .network(network) + .sign(passphrase) + + const passphraseTransaction = ark.getBuilder().transfer() + passphraseTransaction.data = { ...wifTransaction.data } + + wifTransaction.secondSignWithWif(wif, 170) + passphraseTransaction.secondSign(secondPassphrase) + + expect(wifTransaction.data.signSignature).toBe( + passphraseTransaction.data.signSignature, + ) + }) + }) + transactionBuilderTests() it('should have its specific properties', () => { expect(builder).toHaveProperty('data.type', TRANSACTION_TYPES.TRANSFER) - expect(builder).toHaveProperty('data.fee', feeManager.get(TRANSACTION_TYPES.TRANSFER)) + expect(builder).toHaveProperty( + 'data.fee', + feeManager.get(TRANSACTION_TYPES.TRANSFER), + ) expect(builder).toHaveProperty('data.amount', 0) expect(builder).toHaveProperty('data.recipientId', null) expect(builder).toHaveProperty('data.senderPublicKey', null) - expect(builder).toHaveProperty('data.expiration', 15) + expect(builder).toHaveProperty('data.expiration', 0) }) describe('vendorField', () => { diff --git a/packages/crypto/__tests__/builder/transactions/vote.test.js b/packages/crypto/__tests__/builder/transactions/vote.test.js index d91366935a..8697e48223 100644 --- a/packages/crypto/__tests__/builder/transactions/vote.test.js +++ b/packages/crypto/__tests__/builder/transactions/vote.test.js @@ -13,11 +13,37 @@ beforeEach(() => { }) describe('Vote Transaction', () => { + describe('verify', () => { + it('should be valid with a signature', () => { + const actual = builder + .votesAsset([ + '+02d0d835266297f15c192be2636eb3fbc30b39b87fc583ff112062ef8ae1a1f2af', + ]) + .sign('dummy passphrase') + + expect(actual.build().verify()).toBeTrue() + }) + + it('should be valid with a second signature', () => { + const actual = builder + .votesAsset([ + '+02d0d835266297f15c192be2636eb3fbc30b39b87fc583ff112062ef8ae1a1f2af', + ]) + .sign('dummy passphrase') + .secondSign('dummy passphrase') + + expect(actual.build().verify()).toBeTrue() + }) + }) + transactionBuilderTests() it('should have its specific properties', () => { expect(builder).toHaveProperty('data.type', TRANSACTION_TYPES.VOTE) - expect(builder).toHaveProperty('data.fee', feeManager.get(TRANSACTION_TYPES.VOTE)) + expect(builder).toHaveProperty( + 'data.fee', + feeManager.get(TRANSACTION_TYPES.VOTE), + ) expect(builder).toHaveProperty('data.amount', 0) expect(builder).toHaveProperty('data.recipientId', null) expect(builder).toHaveProperty('data.senderPublicKey', null) @@ -37,11 +63,33 @@ describe('Vote Transaction', () => { it('establishes the recipient id', () => { const pass = 'dummy pass' - crypto.getKeys = jest.fn(pass => ({ publicKey: `${pass} public key` })) + crypto.getKeys = jest.fn(() => ({ + publicKey: + '02d0d835266297f15c192be2636eb3fbc30b39b87fc583ff112062ef8ae1a1f2af', + })) crypto.sign = jest.fn() builder.sign(pass) - expect(builder.data.recipientId).toBe('DKNJwdxrPQg6xXbrpaQLfgi6kC2ndaz8N5') + expect(builder.data.recipientId).toBe( + 'D5q7YfEFDky1JJVQQEy4MGyiUhr5cGg47F', + ) + }) + }) + + describe('signWithWif', () => { + it('establishes the recipient id', () => { + const pass = 'dummy pass' + + crypto.getKeysFromWIF = jest.fn(() => ({ + publicKey: + '02d0d835266297f15c192be2636eb3fbc30b39b87fc583ff112062ef8ae1a1f2af', + })) + crypto.signWithWif = jest.fn() + + builder.signWithWif(pass) + expect(builder.data.recipientId).toBe( + 'D5q7YfEFDky1JJVQQEy4MGyiUhr5cGg47F', + ) }) }) }) diff --git a/packages/crypto/__tests__/crypto/crypto.test.js b/packages/crypto/__tests__/crypto/crypto.test.js index 63f7977ab0..899a7ff45e 100644 --- a/packages/crypto/__tests__/crypto/crypto.test.js +++ b/packages/crypto/__tests__/crypto/crypto.test.js @@ -1,8 +1,5 @@ -const { Buffer } = require('buffer/') -const ecurve = require('ecurve') +/* eslint max-len: "off" */ -const ECPair = require('../../lib/crypto/ecpair') -const ecdsa = require('../../lib/crypto/ecdsa') const crypto = require('../../lib/crypto/crypto') const configManager = require('../../lib/managers/config') const { TRANSACTION_TYPES, CONFIGURATIONS } = require('../../lib/constants') @@ -42,15 +39,19 @@ describe('crypto.js', () => { recipientId: 'AJWRd23HNEhPLkK1ymMnwnDBX2a7QBZqff', timestamp: 141738, asset: {}, - senderPublicKey: '5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09', - signature: '618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a', // eslint-disable-line max-len - id: '13987348420913138422' + senderPublicKey: + '5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09', + signature: + '618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a', // eslint-disable-line max-len + id: '13987348420913138422', } bytes = crypto.getBytes(transaction) expect(bytes).toBeObject() expect(bytes.length).toBe(202) - expect(bytes.toString('hex')).toBe('00aa2902005d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09171dfc69b54c7fe901e91d5a9ab78388645e2427ea00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e803000000000000d007000000000000618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a') + expect(bytes.toString('hex')).toBe( + '00aa2902005d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09171dfc69b54c7fe901e91d5a9ab78388645e2427ea00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e803000000000000d007000000000000618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a', + ) }) // it('should return Buffer of transaction with second signature and buffer must be 420 length', () => { @@ -80,16 +81,21 @@ describe('crypto.js', () => { recipientId: 'AJWRd23HNEhPLkK1ymMnwnDBX2a7QBZqff', timestamp: 141738, asset: {}, - senderPublicKey: '5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09', - signature: '618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a', // eslint-disable-line max-len - signSignature: '618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a', // eslint-disable-line max-len - id: '13987348420913138422' + senderPublicKey: + '5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09', + signature: + '618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a', // eslint-disable-line max-len + signSignature: + '618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a', // eslint-disable-line max-len + id: '13987348420913138422', } bytes = crypto.getBytes(transaction) expect(bytes).toBeObject() expect(bytes.length).toBe(266) - expect(bytes.toString('hex')).toBe('00aa2902005d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09171dfc69b54c7fe901e91d5a9ab78388645e2427ea00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e803000000000000d007000000000000618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a'); + expect(bytes.toString('hex')).toBe( + '00aa2902005d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09171dfc69b54c7fe901e91d5a9ab78388645e2427ea00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e803000000000000d007000000000000618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a', + ) }) }) @@ -107,14 +113,18 @@ describe('crypto.js', () => { recipientId: 'AJWRd23HNEhPLkK1ymMnwnDBX2a7QBZqff', timestamp: 141738, asset: {}, - senderPublicKey: '5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09', - signature: '618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a' // eslint-disable-line max-len + senderPublicKey: + '5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09', + signature: + '618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a', // eslint-disable-line max-len } const result = crypto.getHash(transaction) expect(result).toBeObject() expect(result).toHaveLength(32) - expect(result.toString('hex')).toBe('952e33b66c35a3805015657c008e73a0dee1efefd9af8c41adb59fe79745ccea') + expect(result.toString('hex')).toBe( + '952e33b66c35a3805015657c008e73a0dee1efefd9af8c41adb59fe79745ccea', + ) }) }) @@ -123,7 +133,7 @@ describe('crypto.js', () => { expect(crypto.getId).toBeFunction() }) - xit('should return string id and be equal to 952e33b66c35a3805015657c008e73a0dee1efefd9af8c41adb59fe79745ccea', () => { + it('should return string id and be equal to 952e33b66c35a3805015657c008e73a0dee1efefd9af8c41adb59fe79745ccea', () => { const transaction = { type: 0, amount: 1000, @@ -131,13 +141,17 @@ describe('crypto.js', () => { recipientId: 'AJWRd23HNEhPLkK1ymMnwnDBX2a7QBZqff', timestamp: 141738, asset: {}, - senderPublicKey: '5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09', - signature: '618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a' // eslint-disable-line max-len + senderPublicKey: + '5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09', + signature: + '618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a', // eslint-disable-line max-len } const id = crypto.getId(transaction) // old id expect(id).toBeString() - expect(id).toBe('952e33b66c35a3805015657c008e73a0dee1efefd9af8c41adb59fe79745ccea') + expect(id).toBe( + '952e33b66c35a3805015657c008e73a0dee1efefd9af8c41adb59fe79745ccea', + ) }) }) @@ -167,10 +181,12 @@ describe('crypto.js', () => { recipientId: 'AJWRd23HNEhPLkK1ymMnwnDBX2a7QBZqff', timestamp: 141738, asset: {}, - senderPublicKey: keys.getPublicKeyBuffer().toString('hex') + senderPublicKey: keys.publicKey, } const signature = crypto.sign(transaction, keys) - expect(signature.toString('hex')).toBe('3045022100f5c4ec7b3f9a2cb2e785166c7ae185abbff0aa741cbdfe322cf03b914002efee02206261cd419ea9074b5d4a007f1e2fffe17a38338358f2ac5fcc65d810dbe773fe') + expect(signature.toString('hex')).toBe( + '3045022100f5c4ec7b3f9a2cb2e785166c7ae185abbff0aa741cbdfe322cf03b914002efee02206261cd419ea9074b5d4a007f1e2fffe17a38338358f2ac5fcc65d810dbe773fe', + ) }) }) @@ -193,10 +209,119 @@ describe('crypto.js', () => { expect(keys).toHaveProperty('privateKey') expect(keys.publicKey).toBeString() - expect(keys.publicKey).toMatch(Buffer.from(keys.publicKey, 'hex').toString('hex')) + expect(keys.publicKey).toMatch( + Buffer.from(keys.publicKey, 'hex').toString('hex'), + ) expect(keys.privateKey).toBeString() - expect(keys.privateKey).toMatch(Buffer.from(keys.privateKey, 'hex').toString('hex')) + expect(keys.privateKey).toMatch( + Buffer.from(keys.privateKey, 'hex').toString('hex'), + ) + }) + + it('should return address', () => { + const keys = crypto.getKeys( + 'SDgGxWHHQHnpm5sth7MBUoeSw7V7nbimJ1RBU587xkryTh4qe9ov', + ) + const address = crypto.getAddress(keys.publicKey.toString('hex')) + expect(address).toBe('DUMjDrT8mgqGLWZtkCqzvy7yxWr55mBEub') + }) + }) + + describe('getKeysFromWIF', () => { + it('should be a function', () => { + expect(crypto.getKeysFromWIF).toBeFunction() + }) + + it('should return two keys in hex', () => { + const keys = crypto.getKeysFromWIF( + 'SDgGxWHHQHnpm5sth7MBUoeSw7V7nbimJ1RBU587xkryTh4qe9ov', + ) + + expect(keys).toBeObject() + expect(keys).toHaveProperty('publicKey') + expect(keys).toHaveProperty('privateKey') + + expect(keys.publicKey).toBeString() + expect(keys.publicKey).toMatch( + Buffer.from(keys.publicKey, 'hex').toString('hex'), + ) + + expect(keys.privateKey).toBeString() + expect(keys.privateKey).toMatch( + Buffer.from(keys.privateKey, 'hex').toString('hex'), + ) + }) + + it('should return address', () => { + const keys = crypto.getKeysFromWIF( + 'SDgGxWHHQHnpm5sth7MBUoeSw7V7nbimJ1RBU587xkryTh4qe9ov', + ) + const address = crypto.getAddress(keys.publicKey.toString('hex')) + expect(address).toBe('DCAaPzPAhhsMkHfQs7fZvXFW2EskDi92m8') + }) + + it('should get keys from compressed WIF', () => { + const keys = crypto.getKeysFromWIF( + 'SAaaKsDdWMXP5BoVnSBLwTLn48n96UvG42WSUUooRv1HrEHmaSd4', + ) + + expect(keys).toBeObject() + expect(keys).toHaveProperty('publicKey') + expect(keys).toHaveProperty('privateKey') + expect(keys).toHaveProperty('compressed', true) + }) + + it('should get keys from uncompressed WIF', () => { + const keys = crypto.getKeysFromWIF( + '6hgnAG19GiMUf75C43XteG2mC8esKTiX9PYbKTh4Gca9MELRWmg', + ) + + expect(keys).toBeObject() + expect(keys).toHaveProperty('publicKey') + expect(keys).toHaveProperty('privateKey') + expect(keys).toHaveProperty('compressed', false) + }) + }) + + describe('keysToWIF', () => { + it('should be a function', () => { + expect(crypto.keysToWIF).toBeFunction() + }) + + it('should get keys from WIF', () => { + const wifKey = 'SAaaKsDdWMXP5BoVnSBLwTLn48n96UvG42WSUUooRv1HrEHmaSd4' + const keys = crypto.getKeysFromWIF(wifKey) + const actual = crypto.keysToWIF(keys) + + expect(keys.compressed).toBeTruthy() + expect(actual).toBe(wifKey) + }) + + it('should get address from compressed WIF (mainnet)', () => { + const keys = crypto.getKeysFromWIF( + 'SAaaKsDdWMXP5BoVnSBLwTLn48n96UvG42WSUUooRv1HrEHmaSd4', + CONFIGURATIONS.ARK.MAINNET, + ) + const address = crypto.getAddress( + keys.publicKey, + CONFIGURATIONS.ARK.MAINNET.pubKeyHash, + ) + expect(keys.compressed).toBeTruthy() + expect(address).toBe('APnrtb2JGa6WjrRik9W3Hjt6h71mD6Zgez') + }) + + it('should get address from compressed WIF (devnet)', () => { + const keys = crypto.getKeysFromWIF( + 'SAaaKsDdWMXP5BoVnSBLwTLn48n96UvG42WSUUooRv1HrEHmaSd4', + CONFIGURATIONS.ARK.DEVNET, + ) + const address = crypto.getAddress( + keys.publicKey, + CONFIGURATIONS.ARK.DEVNET.pubKeyHash, + ) + expect(keys.compressed).toBeTruthy() + expect(address).toBe('DDA5nM7KEqLeTtQKv5qGgcnc6dpNBKJNTS') }) }) @@ -214,21 +339,43 @@ describe('crypto.js', () => { }) it('should generate address by publicKey - second test', () => { - const keys = crypto.getKeys('secret second test to be sure it works correctly') + const keys = crypto.getKeys( + 'secret second test to be sure it works correctly', + ) const address = crypto.getAddress(keys.publicKey) expect(address).toBeString() expect(address).toBe('DDp4SYpnuzFPuN4W79PYY762d7FtW3DFFN') }) - it('should generate the same address as ECPair.getAddress()', () => { - const keys = crypto.getKeys('secret second test to be sure it works correctly') - const address = crypto.getAddress(keys.publicKey) - - const Q = ecurve.Point.decodeFrom(ecdsa.__curve, Buffer.from(keys.publicKey, 'hex')) - const keyPair = new ECPair(null, Q) + it('should not throw an error if the publicKey is valid', () => { + try { + const validKeys = [ + '02d0d835266297f15c192be2636eb3fbc30b39b87fc583ff112062ef8ae1a1f2af', + 'a'.repeat(66), + ] + for (const validKey of validKeys) { + crypto.getAddress(validKey) + } + } catch (error) { + throw new Error( + 'Should not have failed to call getAddress with a valid publicKey', + ) + } + }) - expect(address).toBe(keyPair.getAddress()) + it('should throw an error if the publicKey is invalid', () => { + const invalidKeys = [ + 'invalid', + 'a'.repeat(65), + 'a'.repeat(67), + 'z'.repeat(66), + ] + for (const invalidKey of invalidKeys) { + expect(() => crypto.getAddress(invalidKey)).toThrow( + new Error(`publicKey '${invalidKey}' is invalid`), + ) + } }) }) @@ -248,13 +395,17 @@ describe('crypto.js', () => { it('should validate MAINNET addresses', () => { configManager.setConfig(CONFIGURATIONS.ARK.MAINNET) - expect(crypto.validateAddress('AdVSe37niA3uFUPgCgMUH2tMsHF4LpLoiX')).toBeTruthy() + expect( + crypto.validateAddress('AdVSe37niA3uFUPgCgMUH2tMsHF4LpLoiX'), + ).toBeTrue() }) it('should validate DEVNET addresses', () => { configManager.setConfig(CONFIGURATIONS.ARK.DEVNET) - expect(crypto.validateAddress('DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN')).toBeTruthy() + expect( + crypto.validateAddress('DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN'), + ).toBeTrue() }) }) }) diff --git a/packages/crypto/__tests__/crypto/ecdsa.test.js b/packages/crypto/__tests__/crypto/ecdsa.test.js deleted file mode 100644 index 731a93a729..0000000000 --- a/packages/crypto/__tests__/crypto/ecdsa.test.js +++ /dev/null @@ -1,138 +0,0 @@ -const BigInteger = require('bigi') -const ecdsa = require('../../lib/crypto/ecdsa') -const utils = require('../../lib/crypto/utils') -const ECSignature = require('../../lib/crypto/ecsignature') - -const fixtures = require('./fixtures/ecdsa.json') - -const curve = ecdsa.__curve - -// Make sure we reset fromBuffer to the original implementation -const restoreFromBuffer = BigInteger.fromBuffer -afterEach(() => { - BigInteger.fromBuffer = restoreFromBuffer -}) - -describe('ecdsa', () => { - describe('deterministicGenerateK', () => { - function checkSig () { - return true - } - - fixtures.valid.ecdsa.forEach((f) => { - it(`for "${f.message}"`, () => { - const x = BigInteger.fromHex(f.d).toBuffer(32) - const h1 = utils.sha256(f.message) - - const k = ecdsa.deterministicGenerateK(h1, x, checkSig) - expect(k.toHex()).toBe(f.k) - }) - }) - - it('loops until an appropriate k value is found', () => { - BigInteger.fromBuffer = jest.fn() - BigInteger.fromBuffer.mockReturnValueOnce(new BigInteger('0')) // < 1 - BigInteger.fromBuffer.mockReturnValueOnce(curve.n) // > n-1 - BigInteger.fromBuffer.mockReturnValue(new BigInteger('42')) // valid - - const x = new BigInteger('1').toBuffer(32) - const h1 = Buffer.alloc(32) - const k = ecdsa.deterministicGenerateK(h1, x, checkSig) - - expect(k.toString()).toBe('42') - - expect(BigInteger.fromBuffer).toHaveBeenCalledTimes(3) - }) - - it('loops until a suitable signature is found', () => { - BigInteger.fromBuffer = jest.fn() - BigInteger.fromBuffer.mockReturnValueOnce(new BigInteger('0')) // < 1 - BigInteger.fromBuffer.mockReturnValueOnce(curve.n) // > n-1 - BigInteger.fromBuffer.mockReturnValueOnce(new BigInteger('42')) // valid, but 'bad' signature - BigInteger.fromBuffer.mockReturnValue(new BigInteger('53')) // valid, good signature - - const checkSig = jest.fn() - checkSig.mockReturnValueOnce(false) // bad signature - checkSig.mockReturnValue(true) // good signature - - const x = new BigInteger('1').toBuffer(32) - const h1 = Buffer.alloc(32) - const k = ecdsa.deterministicGenerateK(h1, x, checkSig) - - expect(k.toString()).toBe('53') - - expect(BigInteger.fromBuffer).toHaveBeenCalledTimes(4) - expect(checkSig).toHaveBeenCalledTimes(2) - }) - - fixtures.valid.rfc6979.forEach((f) => { - it(`produces the expected k values for "${f.message}" if k wasn't suitable`, () => { - const x = BigInteger.fromHex(f.d).toBuffer(32) - const h1 = utils.sha256(f.message) - - const results = [] - ecdsa.deterministicGenerateK(h1, x, function (k) { - results.push(k) - - return results.length === 16 - }) - - expect(results[0].toHex()).toBe(f.k0) - expect(results[1].toHex()).toBe(f.k1) - expect(results[15].toHex()).toBe(f.k15) - }) - }) - }) - - describe('sign', () => { - fixtures.valid.ecdsa.forEach((f) => { - it(`produces a deterministic signature for "${f.message}"`, () => { - const d = BigInteger.fromHex(f.d) - const hash = utils.sha256(f.message) - const signature = ecdsa.sign(hash, d).toDER() - - expect(signature.toString('hex')).toBe(f.signature) - }) - }) - - it('should sign with low S value', () => { - const hash = utils.sha256('Vires in numeris') - const sig = ecdsa.sign(hash, BigInteger.ONE) - - // See BIP62 for more information - const N_OVER_TWO = curve.n.shiftRight(1) - expect(sig.s.compareTo(N_OVER_TWO)).toBeLessThanOrEqual(0) - }) - }) - - describe('verify', () => { - fixtures.valid.ecdsa.forEach((f) => { - it(`verifies a valid signature for "${f.message}"`, () => { - const d = BigInteger.fromHex(f.d) - const H = utils.sha256(f.message) - const signature = ECSignature.fromDER(Buffer.from(f.signature, 'hex')) - const Q = curve.G.multiply(d) - - expect(ecdsa.verify(H, signature, Q)).toBeTruthy() - }) - }) - - fixtures.invalid.verify.forEach((f) => { - it(`fails to verify with ${f.description}`, () => { - const H = utils.sha256(f.message) - const d = BigInteger.fromHex(f.d) - - let signature - if (f.signature) { - signature = ECSignature.fromDER(Buffer.from(f.signature, 'hex')) - } else if (f.signatureRaw) { - signature = new ECSignature(new BigInteger(f.signatureRaw.r, 16), new BigInteger(f.signatureRaw.s, 16)) - } - - const Q = curve.G.multiply(d) - - expect(ecdsa.verify(H, signature, Q)).toBeFalsy() - }) - }) - }) -}) diff --git a/packages/crypto/__tests__/crypto/ecpair.test.js b/packages/crypto/__tests__/crypto/ecpair.test.js deleted file mode 100644 index c0c6295009..0000000000 --- a/packages/crypto/__tests__/crypto/ecpair.test.js +++ /dev/null @@ -1,229 +0,0 @@ -const ecurve = require('ecurve') -const BigInteger = require('bigi') - -const ECPair = require('../../lib/crypto/ecpair') -const ecdsa = require('../../lib/crypto/ecdsa') -const configManager = require('../../lib/managers/config') - -const fixtures = require('./fixtures/ecpair.json') -const { NETWORKS, NETWORKS_LIST } = require('../utils/network-list') - -const curve = ecdsa.__curve - -beforeEach(() => configManager.setConfig(NETWORKS.mainnet)) - -describe('ECPair', () => { - describe('constructor', () => { - it('defaults to compressed', () => { - const keyPair = new ECPair(BigInteger.ONE) - - expect(keyPair.compressed).toBeTruthy() - }) - - it('supports the uncompressed option', () => { - const keyPair = new ECPair(BigInteger.ONE, null, { - compressed: false - }) - - expect(keyPair.compressed).toBeFalsy() - }) - - it('supports the network option', () => { - const keyPair = new ECPair(BigInteger.ONE, null, { - compressed: false, - network: NETWORKS.devnet - }) - - expect(keyPair.network).toEqual(NETWORKS.devnet) - }) - - fixtures.valid.forEach((f) => { - it(`calculates the public point for ${f.WIF}`, () => { - const d = new BigInteger(f.d) - const keyPair = new ECPair(d, null, { - compressed: f.compressed, - network: NETWORKS[f.network] - }) - - expect(keyPair.getPublicKeyBuffer().toString('hex')).toBe(f.Q) - }) - }) - - fixtures.invalid.constructor.forEach((f) => { - it(`throws ${f.exception}`, () => { - const d = f.d && new BigInteger(f.d) // eslint-disable-line no-new - const Q = f.Q && ecurve.Point.decodeFrom(curve, Buffer.from(f.Q, 'hex')) - - expect(() => { - new ECPair(d, Q, f.options) // eslint-disable-line no-new - }).toThrowError(new RegExp(f.exception)) - }) - }) - }) - - describe('getPublicKeyBuffer', () => { - let keyPair - - beforeEach(() => { - keyPair = new ECPair(BigInteger.ONE) - }) - - it('wraps Q.getEncoded', () => { - keyPair.Q.getEncoded = jest.fn() - - keyPair.getPublicKeyBuffer() - - expect(keyPair.Q.getEncoded).toHaveBeenCalledWith(keyPair.compressed) - }) - }) - - describe('fromWIF', () => { - fixtures.valid.forEach((f) => { - it(`imports ${f.WIF} (${f.network})`, () => { - const network = NETWORKS[f.network] - const keyPair = ECPair.fromWIF(f.WIF, network) - - expect(keyPair.d.toString()).toBe(f.d) - expect(keyPair.getPublicKeyBuffer().toString('hex')).toBe(f.Q) - expect(keyPair.compressed).toBe(f.compressed) - expect(keyPair.network).toEqual(network) - }) - }) - - fixtures.valid.forEach((f) => { - it(`imports ${f.WIF} (via list of networks)`, () => { - const network = NETWORKS[f.network] - const keyPair = ECPair.fromWIF(f.WIF, network) - - expect(keyPair.d.toString()).toBe(f.d) - expect(keyPair.getPublicKeyBuffer().toString('hex')).toBe(f.Q) - expect(keyPair.compressed).toBe(f.compressed) - expect(keyPair.network).toEqual(network) - }) - }) - - fixtures.invalid.fromWIF.forEach((f) => { - it(`throws on ${f.WIF}`, () => { - expect(() => { - const networks = f.network ? NETWORKS[f.network] : NETWORKS_LIST - - ECPair.fromWIF(f.WIF, networks) - }).toThrowError(new RegExp(f.exception)) - }) - }) - }) - - describe('toWIF', () => { - fixtures.valid.forEach((f) => { - it(`exports ${f.WIF}`, () => { - const keyPair = ECPair.fromWIF(f.WIF, NETWORKS_LIST) - - expect(keyPair.toWIF()).toBe(f.WIF) - }) - }) - }) - - describe('makeRandom', () => { - let d = Buffer.from('0404040404040404040404040404040404040404040404040404040404040404', 'hex') - let exWIF = 'S9hzwiZ5ziKjUiFpuZX4Lri3rUocDxZSTy7YzKKHvx8TSjUrYQ27' - - it('uses randombytes RNG to generate a ECPair', () => { - const stub = { - rng: () => { - return d - } - } - - const keyPair = ECPair.makeRandom(stub) - expect(keyPair.toWIF()).toBe(exWIF) - }) - - it('allows a custom RNG to be used', () => { - const keyPair = ECPair.makeRandom({ - rng: (size) => { - return d.slice(0, size) - } - }) - - expect(keyPair.toWIF()).toBe(exWIF) - }) - - it('retains the same defaults as ECPair constructor', () => { - const keyPair = ECPair.makeRandom() - - expect(keyPair.compressed).toBeTruthy() - expect(keyPair.network).toEqual(NETWORKS.mainnet) - }) - - it('supports the options parameter', () => { - const keyPair = ECPair.makeRandom({ - compressed: false, - network: NETWORKS.devnet - }) - - expect(keyPair.compressed).toBeFalsy() - expect(keyPair.network).toEqual(NETWORKS.devnet) - }) - - it('loops until d is within interval [1, n - 1] : 1', () => { - const rng = jest.fn() - rng.mockReturnValueOnce(BigInteger.ZERO.toBuffer(32)) // invalid length - rng.mockReturnValue(BigInteger.ONE.toBuffer(32)) // === 1 - - ECPair.makeRandom({rng}) - - expect(rng).toHaveBeenCalledTimes(2) - }) - - it('loops until d is within interval [1, n - 1] : n - 1', () => { - const rng = jest.fn() - rng.mockReturnValueOnce(BigInteger.ZERO.toBuffer(32)) // < 1 - rng.mockReturnValueOnce(curve.n.toBuffer(32)) // > n-1 - rng.mockReturnValue(curve.n.subtract(BigInteger.ONE).toBuffer(32)) // === n-1 - - ECPair.makeRandom({rng}) - - expect(rng).toHaveBeenCalledTimes(3) - }) - }) - - describe('getAddress', () => { - fixtures.valid.forEach((f) => { - it(`returns ${f.address} for ${f.WIF}`, () => { - const keyPair = ECPair.fromWIF(f.WIF, NETWORKS[f.network]) - - expect(keyPair.getAddress()).toBe(f.address) - }) - }) - }) - - describe('getNetwork', () => { - fixtures.valid.forEach((f) => { - it(`returns ${f.network} for ${f.WIF}`, () => { - const keyPair = ECPair.fromWIF(f.WIF, NETWORKS[f.network]) - - expect(keyPair.network).toEqual(NETWORKS[f.network]) - }) - }) - }) - - describe('ecdsa wrappers', () => { - let keyPair - let hash - - beforeEach(() => { - keyPair = ECPair.makeRandom() - hash = Buffer.alloc(32) - }) - - describe('signing', () => { - it('throws if no private key is found', () => { - keyPair.d = null - - expect(() => { - keyPair.sign(hash) - }).toThrowError(/Missing private key/) - }) - }) - }) -}) diff --git a/packages/crypto/__tests__/crypto/ecsignature.test.js b/packages/crypto/__tests__/crypto/ecsignature.test.js deleted file mode 100644 index b4b25e6a1c..0000000000 --- a/packages/crypto/__tests__/crypto/ecsignature.test.js +++ /dev/null @@ -1,123 +0,0 @@ -const BigInteger = require('bigi') - -const ECSignature = require('../../lib/crypto/ecsignature') -const configManager = require('../../lib/managers/config') -const network = require('../../lib/networks/ark/mainnet.json') - -const fixtures = require('./fixtures/ecsignature.json') - -beforeEach(() => configManager.setConfig(network)) - -describe('ECSignature', () => { - describe('toCompact', () => { - fixtures.valid.forEach((f) => { - it('exports ' + f.compact.hex + ' correctly', () => { - const signature = new ECSignature(new BigInteger(f.signature.r), new BigInteger(f.signature.s)) - - const buffer = signature.toCompact(f.compact.i, f.compact.compressed) - expect(buffer.toString('hex')).toBe(f.compact.hex) - }) - }) - }) - - describe('parseCompact', () => { - fixtures.valid.forEach((f) => { - it(`imports ${f.compact.hex} correctly`, () => { - const buffer = Buffer.from(f.compact.hex, 'hex') - const parsed = ECSignature.parseCompact(buffer) - - expect(parsed.compressed).toBe(f.compact.compressed) - expect(parsed.i).toBe(f.compact.i) - expect(parsed.signature.r.toString()).toBe(f.signature.r) - expect(parsed.signature.s.toString()).toBe(f.signature.s) - }) - }) - - fixtures.invalid.compact.forEach((f) => { - it(`throws on ${f.hex}`, () => { - const buffer = Buffer.from(f.hex, 'hex') - - expect(() => { - ECSignature.parseCompact(buffer) - }).toThrowError(new RegExp(f.exception)) - }) - }) - }) - - describe('toDER', () => { - fixtures.valid.forEach((f) => { - it(`exports ${f.DER} correctly`, () => { - const signature = new ECSignature(new BigInteger(f.signature.r), new BigInteger(f.signature.s)) - - const DER = signature.toDER() - expect(DER.toString('hex')).toBe(f.DER) - }) - }) - }) - - describe('fromDER', () => { - fixtures.valid.forEach((f) => { - it(`imports ${f.DER} correctly`, () => { - const buffer = Buffer.from(f.DER, 'hex') - const signature = ECSignature.fromDER(buffer) - - expect(signature.r.toString()).toBe(f.signature.r) - expect(signature.s.toString()).toBe(f.signature.s) - }) - }) - - fixtures.invalid.DER.forEach((f) => { - it(`throws ${f.exception} for ${f.hex}`, () => { - const buffer = Buffer.from(f.hex, 'hex') - - expect(() => { - ECSignature.fromDER(buffer) - }).toThrowError(new RegExp(f.exception)) - }) - }) - }) - - describe('toScriptSignature', () => { - fixtures.valid.forEach((f) => { - it(`exports ${f.scriptSignature.hex} correctly`, () => { - const signature = new ECSignature(new BigInteger(f.signature.r), new BigInteger(f.signature.s)) - - const scriptSignature = signature.toScriptSignature(f.scriptSignature.hashType) - expect(scriptSignature.toString('hex')).toBe(f.scriptSignature.hex) - }) - }) - - fixtures.invalid.scriptSignature.forEach((f) => { - it(`throws ${f.exception}`, () => { - const signature = new ECSignature(new BigInteger(f.signature.r), new BigInteger(f.signature.s)) - - expect(() => { - signature.toScriptSignature(f.hashType) - }).toThrowError(new RegExp(f.exception)) - }) - }) - }) - - describe('parseScriptSignature', () => { - fixtures.valid.forEach((f) => { - it(`imports ${f.scriptSignature.hex} correctly`, () => { - const buffer = Buffer.from(f.scriptSignature.hex, 'hex') - const parsed = ECSignature.parseScriptSignature(buffer) - - expect(parsed.signature.r.toString()).toBe(f.signature.r) - expect(parsed.signature.s.toString()).toBe(f.signature.s) - expect(parsed.hashType).toBe(f.scriptSignature.hashType) - }) - }) - - fixtures.invalid.scriptSignature.forEach((f) => { - it(`throws on ${f.hex}`, () => { - const buffer = Buffer.from(f.hex, 'hex') - - expect(() => { - ECSignature.parseScriptSignature(buffer) - }).toThrowError(new RegExp(f.exception)) - }) - }) - }) -}) diff --git a/packages/crypto/__tests__/crypto/fixtures/ecdsa.json b/packages/crypto/__tests__/crypto/fixtures/ecdsa.json deleted file mode 100644 index a3e13039cd..0000000000 --- a/packages/crypto/__tests__/crypto/fixtures/ecdsa.json +++ /dev/null @@ -1,172 +0,0 @@ -{ - "valid": { - "ecdsa": [{ - "d": "01", - "k": "ec633bd56a5774a0940cb97e27a9e4e51dc94af737596a0c5cbb3d30332d92a5", - "message": "Everything should be made as simple as possible, but not simpler.", - "i": 0, - "signature": "3044022033a69cd2065432a30f3d1ce4eb0d59b8ab58c74f27c41a7fdb5696ad4e6108c902206f807982866f785d3f6418d24163ddae117b7db4d5fdf0071de069fa54342262" - }, { - "d": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", - "k": "9dc74cbfd383980fb4ae5d2680acddac9dac956dca65a28c80ac9c847c2374e4", - "message": "Equations are more important to me, because politics is for the present, but an equation is something for eternity.", - "i": 0, - "signature": "3044022054c4a33c6423d689378f160a7ff8b61330444abb58fb470f96ea16d99d4a2fed022007082304410efa6b2943111b6a4e0aaa7b7db55a07e9861d1fb3cb1f421044a5" - }, { - "d": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", - "k": "fd27071f01648ebbdd3e1cfbae48facc9fa97edc43bbbc9a7fdc28eae13296f5", - "message": "Not only is the Universe stranger than we think, it is stranger than we can think.", - "i": 0, - "signature": "3045022100ff466a9f1b7b273e2f4c3ffe032eb2e814121ed18ef84665d0f515360dab3dd002206fc95f5132e5ecfdc8e5e6e616cc77151455d46ed48f5589b7db7771a332b283" - }, { - "d": "0000000000000000000000000000000000000000000000000000000000000001", - "k": "f0cd2ba5fc7c183de589f6416220a36775a146740798756d8d949f7166dcc87f", - "message": "How wonderful that we have met with a paradox. Now we have some hope of making progress.", - "i": 1, - "signature": "3045022100c0dafec8251f1d5010289d210232220b03202cba34ec11fec58b3e93a85b91d3022075afdc06b7d6322a590955bf264e7aaa155847f614d80078a90292fe205064d3" - }, { - "d": "69ec59eaa1f4f2e36b639716b7c30ca86d9a5375c7b38d8918bd9c0ebc80ba64", - "k": "6bb4a594ad57c1aa22dbe991a9d8501daf4688bf50a4892ef21bd7c711afda97", - "message": "Computer science is no more about computers than astronomy is about telescopes.", - "i": 0, - "signature": "304402207186363571d65e084e7f02b0b77c3ec44fb1b257dee26274c38c928986fea45d02200de0b38e06807e46bda1f1e293f4f6323e854c86d58abdd00c46c16441085df6" - }, { - "d": "00000000000000000000000000007246174ab1e92e9149c6e446fe194d072637", - "k": "097b5c8ee22c3ea78a4d3635e0ff6fe85a1eb92ce317ded90b9e71aab2b861cb", - "message": "...if you aren't, at any given time, scandalized by code you wrote five or even three years ago, you're not learning anywhere near enough", - "i": 1, - "signature": "3045022100fbfe5076a15860ba8ed00e75e9bd22e05d230f02a936b653eb55b61c99dda48702200e68880ebb0050fe4312b1b1eb0899e1b82da89baa5b895f612619edf34cbd37" - }, { - "d": "000000000000000000000000000000000000000000056916d0f9b31dc9b637f3", - "k": "19355c36c8cbcdfb2382e23b194b79f8c97bf650040fc7728dfbf6b39a97c25b", - "message": "The question of whether computers can think is like the question of whether submarines can swim.", - "i": 1, - "signature": "3045022100cde1302d83f8dd835d89aef803c74a119f561fbaef3eb9129e45f30de86abbf9022006ce643f5049ee1f27890467b77a6a8e11ec4661cc38cd8badf90115fbd03cef" - }], - "rfc6979": [{ - "message": "test data", - "d": "fee0a1f7afebf9d2a5a80c0c98a31c709681cce195cbcd06342b517970c0be1e", - "k0": "fcce1de7a9bcd6b2d3defade6afa1913fb9229e3b7ddf4749b55c4848b2a196e", - "k1": "727fbcb59eb48b1d7d46f95a04991fc512eb9dbf9105628e3aec87428df28fd8", - "k15": "398f0e2c9f79728f7b3d84d447ac3a86d8b2083c8f234a0ffa9c4043d68bd258" - }, { - "message": "Everything should be made as simple as possible, but not simpler.", - "d": "0000000000000000000000000000000000000000000000000000000000000001", - "k0": "ec633bd56a5774a0940cb97e27a9e4e51dc94af737596a0c5cbb3d30332d92a5", - "k1": "df55b6d1b5c48184622b0ead41a0e02bfa5ac3ebdb4c34701454e80aabf36f56", - "k15": "def007a9a3c2f7c769c75da9d47f2af84075af95cadd1407393dc1e26086ef87" - }, { - "message": "Satoshi Nakamoto", - "d": "0000000000000000000000000000000000000000000000000000000000000002", - "k0": "d3edc1b8224e953f6ee05c8bbf7ae228f461030e47caf97cde91430b4607405e", - "k1": "f86d8e43c09a6a83953f0ab6d0af59fb7446b4660119902e9967067596b58374", - "k15": "241d1f57d6cfd2f73b1ada7907b199951f95ef5ad362b13aed84009656e0254a" - }, { - "message": "Diffie Hellman", - "d": "7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f", - "k0": "c378a41cb17dce12340788dd3503635f54f894c306d52f6e9bc4b8f18d27afcc", - "k1": "90756c96fef41152ac9abe08819c4e95f16da2af472880192c69a2b7bac29114", - "k15": "7b3f53300ab0ccd0f698f4d67db87c44cf3e9e513d9df61137256652b2e94e7c" - }, { - "message": "Japan", - "d": "8080808080808080808080808080808080808080808080808080808080808080", - "k0": "f471e61b51d2d8db78f3dae19d973616f57cdc54caaa81c269394b8c34edcf59", - "k1": "6819d85b9730acc876fdf59e162bf309e9f63dd35550edf20869d23c2f3e6d17", - "k15": "d8e8bae3ee330a198d1f5e00ad7c5f9ed7c24c357c0a004322abca5d9cd17847" - }, { - "message": "Bitcoin", - "d": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", - "k0": "36c848ffb2cbecc5422c33a994955b807665317c1ce2a0f59c689321aaa631cc", - "k1": "4ed8de1ec952a4f5b3bd79d1ff96446bcd45cabb00fc6ca127183e14671bcb85", - "k15": "56b6f47babc1662c011d3b1f93aa51a6e9b5f6512e9f2e16821a238d450a31f8" - }, { - "message": "i2FLPP8WEus5WPjpoHwheXOMSobUJVaZM1JPMQZq", - "d": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", - "k0": "6e9b434fcc6bbb081a0463c094356b47d62d7efae7da9c518ed7bac23f4e2ed6", - "k1": "ae5323ae338d6117ce8520a43b92eacd2ea1312ae514d53d8e34010154c593bb", - "k15": "3eaa1b61d1b8ab2f1ca71219c399f2b8b3defa624719f1e96fe3957628c2c4ea" - }, { - "message": "lEE55EJNP7aLrMtjkeJKKux4Yg0E8E1SAJnWTCEh", - "d": "3881e5286abc580bb6139fe8e83d7c8271c6fe5e5c2d640c1f0ed0e1ee37edc9", - "k0": "5b606665a16da29cc1c5411d744ab554640479dd8abd3c04ff23bd6b302e7034", - "k1": "f8b25263152c042807c992eacd2ac2cc5790d1e9957c394f77ea368e3d9923bd", - "k15": "ea624578f7e7964ac1d84adb5b5087dd14f0ee78b49072aa19051cc15dab6f33" - }, { - "message": "2SaVPvhxkAPrayIVKcsoQO5DKA8Uv5X/esZFlf+y", - "d": "7259dff07922de7f9c4c5720d68c9745e230b32508c497dd24cb95ef18856631", - "k0": "3ab6c19ab5d3aea6aa0c6da37516b1d6e28e3985019b3adb388714e8f536686b", - "k1": "19af21b05004b0ce9cdca82458a371a9d2cf0dc35a813108c557b551c08eb52e", - "k15": "117a32665fca1b7137a91c4739ac5719fec0cf2e146f40f8e7c21b45a07ebc6a" - }, { - "message": "00A0OwO2THi7j5Z/jp0FmN6nn7N/DQd6eBnCS+/b", - "d": "0d6ea45d62b334777d6995052965c795a4f8506044b4fd7dc59c15656a28f7aa", - "k0": "79487de0c8799158294d94c0eb92ee4b567e4dc7ca18addc86e49d31ce1d2db6", - "k1": "9561d2401164a48a8f600882753b3105ebdd35e2358f4f808c4f549c91490009", - "k15": "b0d273634129ff4dbdf0df317d4062a1dbc58818f88878ffdb4ec511c77976c0" - }] - }, - "invalid": { - "verify": [{ - "description": "The wrong signature", - "d": "01", - "message": "foo", - "signature": "3044022054c4a33c6423d689378f160a7ff8b61330444abb58fb470f96ea16d99d4a2fed022007082304410efa6b2943111b6a4e0aaa7b7db55a07e9861d1fb3cb1f421044a5" - }, { - "description": "Invalid r value (< 0)", - "d": "01", - "message": "foo", - "signatureRaw": { - "r": "-01", - "s": "02" - } - }, { - "description": "Invalid r value (== 0)", - "d": "01", - "message": "foo", - "signatureRaw": { - "r": "00", - "s": "02" - } - }, { - "description": "Invalid r value (>= n)", - "d": "01", - "message": "foo", - "signatureRaw": { - "r": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", - "s": "02" - } - }, { - "description": "Invalid s value (< 0)", - "d": "01", - "message": "foo", - "signatureRaw": { - "r": "02", - "s": "-01" - } - }, { - "description": "Invalid s value (== 0)", - "d": "01", - "message": "foo", - "signatureRaw": { - "r": "02", - "s": "00" - } - }, { - "description": "Invalid s value (>= n)", - "d": "01", - "message": "foo", - "signatureRaw": { - "r": "02", - "s": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141" - } - }, { - "description": "Invalid r, s values (r = s = -n)", - "d": "01", - "message": "foo", - "signatureRaw": { - "r": "-fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", - "s": "-fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141" - } - }] - } -} diff --git a/packages/crypto/__tests__/crypto/fixtures/ecpair.json b/packages/crypto/__tests__/crypto/fixtures/ecpair.json deleted file mode 100644 index 79495ba282..0000000000 --- a/packages/crypto/__tests__/crypto/fixtures/ecpair.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "valid": [{ - "d": "13584612336291408845215256764386272569478030828575587083584323063789376056680", - "Q": "02e012f0a7cac12a74bdc17d844cbc9f637177b470019c32a53cef94c7a56e2ea9", - "compressed": true, - "network": "mainnet", - "address": "APnrtb2JGa6WjrRik9W3Hjt6h71mD6Zgez", - "WIF": "SAaaKsDdWMXP5BoVnSBLwTLn48n96UvG42WSUUooRv1HrEHmaSd4" - }, { - "d": "13584612336291408845215256764386272569478030828575587083584323063789376056680", - "Q": "04e012f0a7cac12a74bdc17d844cbc9f637177b470019c32a53cef94c7a56e2ea95a49f33d9dc6920d8f106d0503d6191266c523743bf19e316ebf4890b543e7d4", - "compressed": false, - "network": "mainnet", - "address": "AJfe8jWRFwDy63KbbCpaTkZCvtPzCWYF2F", - "WIF": "6hgnAG19GiMUf75C43XteG2mC8esKTiX9PYbKTh4Gca9MELRWmg" - }, { - "d": "13584612336291408845215256764386272569478030828575587083584323063789376056680", - "Q": "02e012f0a7cac12a74bdc17d844cbc9f637177b470019c32a53cef94c7a56e2ea9", - "compressed": true, - "network": "devnet", - "address": "DDA5nM7KEqLeTtQKv5qGgcnc6dpNBKJNTS", - "WIF": "SAaaKsDdWMXP5BoVnSBLwTLn48n96UvG42WSUUooRv1HrEHmaSd4" - }, { - "d": "13584612336291408845215256764386272569478030828575587083584323063789376056680", - "Q": "04e012f0a7cac12a74bdc17d844cbc9f637177b470019c32a53cef94c7a56e2ea95a49f33d9dc6920d8f106d0503d6191266c523743bf19e316ebf4890b543e7d4", - "compressed": false, - "network": "devnet", - "address": "D82s2VbSECU6p5JCm99ordTiLRCb8RWMy9", - "WIF": "6hgnAG19GiMUf75C43XteG2mC8esKTiX9PYbKTh4Gca9MELRWmg" - }], - "invalid": { - "constructor": [{ - "exception": "Private key must be greater than 0", - "d": "-1" - }, { - "exception": "Private key must be greater than 0", - "d": "0" - }, { - "exception": "Private key must be less than the curve order", - "d": "115792089237316195423570985008687907852837564279074904382605163141518161494337" - }, { - "exception": "Private key must be less than the curve order", - "d": "115792089237316195423570985008687907853269984665640564039457584007913129639935" - }, { - "exception": "Expected property \"compressed\" of type \\?Boolean, got Number 2", - "d": "1", - "options": { - "compressed": 2 - } - }, { - "exception": "Unexpected publicKey parameter", - "d": "1", - "Q": "0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798" - }, { - "exception": "Expected property \"network.messagePrefix\" of type Buffer|String, got undefined", - "d": "1", - "options": { - "network": {} - } - }], - "fromWIF": [{ - "exception": "Invalid network version", - "network": "mainnet", - "WIF": "7FP9Dnv6oxbmvmsEhrB9RMdYNXsUeEgDS8kJ2fFYtQqeVxBZpAC" - }, { - "exception": "Unknown network version", - "WIF": "brQnSed3Fia1w9VcbbS6ZGDgJ6ENkgwuQY2LS7pEC5bKHD1fMF" - }, { - "exception": "Invalid compression flag", - "WIF": "KwDiBf89QgGbjEhKnhXJuH7LrciVrZi3qYjgd9M7rFU73sfZr2ym" - }, { - "exception": "Invalid WIF length", - "WIF": "3tq8Vmhh9SN5XhjTGSWgx8iKk59XbKG6UH4oqpejRuJhfYD" - }, { - "exception": "Invalid WIF length", - "WIF": "38uMpGARR2BJy5p4dNFKYg9UsWNoBtkpbdrXDjmfvz8krCtw3T1W92ZDSR" - }] - } -} diff --git a/packages/crypto/__tests__/crypto/fixtures/ecsignature.json b/packages/crypto/__tests__/crypto/fixtures/ecsignature.json deleted file mode 100644 index 49c7f24f2e..0000000000 --- a/packages/crypto/__tests__/crypto/fixtures/ecsignature.json +++ /dev/null @@ -1,183 +0,0 @@ -{ - "valid": [{ - "compact": { - "hex": "1f33a69cd2065432a30f3d1ce4eb0d59b8ab58c74f27c41a7fdb5696ad4e6108c96f807982866f785d3f6418d24163ddae117b7db4d5fdf0071de069fa54342262", - "compressed": true, - "i": 0 - }, - "scriptSignature": { - "hex": "3044022033a69cd2065432a30f3d1ce4eb0d59b8ab58c74f27c41a7fdb5696ad4e6108c902206f807982866f785d3f6418d24163ddae117b7db4d5fdf0071de069fa5434226201", - "hashType": 1 - }, - "DER": "3044022033a69cd2065432a30f3d1ce4eb0d59b8ab58c74f27c41a7fdb5696ad4e6108c902206f807982866f785d3f6418d24163ddae117b7db4d5fdf0071de069fa54342262", - "signature": { - "r": "23362334225185207751494092901091441011938859014081160902781146257181456271561", - "s": "50433721247292933944369538617440297985091596895097604618403996029256432099938" - } - }, { - "compact": { - "hex": "1b54c4a33c6423d689378f160a7ff8b61330444abb58fb470f96ea16d99d4a2fed07082304410efa6b2943111b6a4e0aaa7b7db55a07e9861d1fb3cb1f421044a5", - "compressed": false, - "i": 0 - }, - "DER": "3044022054c4a33c6423d689378f160a7ff8b61330444abb58fb470f96ea16d99d4a2fed022007082304410efa6b2943111b6a4e0aaa7b7db55a07e9861d1fb3cb1f421044a5", - "scriptSignature": { - "hex": "3044022054c4a33c6423d689378f160a7ff8b61330444abb58fb470f96ea16d99d4a2fed022007082304410efa6b2943111b6a4e0aaa7b7db55a07e9861d1fb3cb1f421044a502", - "hashType": 2 - }, - "signature": { - "r": "38341707918488238920692284707283974715538935465589664377561695343399725051885", - "s": "3180566392414476763164587487324397066658063772201694230600609996154610926757" - } - }, { - "compact": { - "hex": "1fff466a9f1b7b273e2f4c3ffe032eb2e814121ed18ef84665d0f515360dab3dd06fc95f5132e5ecfdc8e5e6e616cc77151455d46ed48f5589b7db7771a332b283", - "compressed": true, - "i": 0 - }, - "scriptSignature": { - "hex": "3045022100ff466a9f1b7b273e2f4c3ffe032eb2e814121ed18ef84665d0f515360dab3dd002206fc95f5132e5ecfdc8e5e6e616cc77151455d46ed48f5589b7db7771a332b28303", - "hashType": 3 - }, - "DER": "3045022100ff466a9f1b7b273e2f4c3ffe032eb2e814121ed18ef84665d0f515360dab3dd002206fc95f5132e5ecfdc8e5e6e616cc77151455d46ed48f5589b7db7771a332b283", - "signature": { - "r": "115464191557905790016094131873849783294273568009648050793030031933291767741904", - "s": "50562520307781850052192542766631199590053690478900449960232079510155113443971" - } - }, { - "compact": { - "hex": "1cc0dafec8251f1d5010289d210232220b03202cba34ec11fec58b3e93a85b91d375afdc06b7d6322a590955bf264e7aaa155847f614d80078a90292fe205064d3", - "compressed": false, - "i": 1 - }, - "scriptSignature": { - "hex": "3045022100c0dafec8251f1d5010289d210232220b03202cba34ec11fec58b3e93a85b91d3022075afdc06b7d6322a590955bf264e7aaa155847f614d80078a90292fe205064d381", - "hashType": 129 - }, - "DER": "3045022100c0dafec8251f1d5010289d210232220b03202cba34ec11fec58b3e93a85b91d3022075afdc06b7d6322a590955bf264e7aaa155847f614d80078a90292fe205064d3", - "signature": { - "r": "87230998027579607140680851455601772643840468630989315269459846730712163783123", - "s": "53231320085894623106179381504478252331065330583563809963303318469380290929875" - } - }, { - "compact": { - "hex": "1f7186363571d65e084e7f02b0b77c3ec44fb1b257dee26274c38c928986fea45d0de0b38e06807e46bda1f1e293f4f6323e854c86d58abdd00c46c16441085df6", - "compressed": true, - "i": 0 - }, - "scriptSignature": { - "hex": "304402207186363571d65e084e7f02b0b77c3ec44fb1b257dee26274c38c928986fea45d02200de0b38e06807e46bda1f1e293f4f6323e854c86d58abdd00c46c16441085df682", - "hashType": 130 - }, - "DER": "304402207186363571d65e084e7f02b0b77c3ec44fb1b257dee26274c38c928986fea45d02200de0b38e06807e46bda1f1e293f4f6323e854c86d58abdd00c46c16441085df6", - "signature": { - "r": "51348483531757779992459563033975330355971795607481991320287437101831125115997", - "s": "6277080015686056199074771961940657638578000617958603212944619747099038735862" - } - }, { - "compact": { - "hex": "1cfbfe5076a15860ba8ed00e75e9bd22e05d230f02a936b653eb55b61c99dda4870e68880ebb0050fe4312b1b1eb0899e1b82da89baa5b895f612619edf34cbd37", - "compressed": false, - "i": 1 - }, - "scriptSignature": { - "hex": "3045022100fbfe5076a15860ba8ed00e75e9bd22e05d230f02a936b653eb55b61c99dda48702200e68880ebb0050fe4312b1b1eb0899e1b82da89baa5b895f612619edf34cbd3783", - "hashType": 131 - }, - "DER": "3045022100fbfe5076a15860ba8ed00e75e9bd22e05d230f02a936b653eb55b61c99dda48702200e68880ebb0050fe4312b1b1eb0899e1b82da89baa5b895f612619edf34cbd37", - "signature": { - "r": "113979859486826658566290715281614250298918272782414232881639314569529560769671", - "s": "6517071009538626957379450615706485096874328019806177698938278220732027419959" - } - }, { - "compact": { - "hex": "20cde1302d83f8dd835d89aef803c74a119f561fbaef3eb9129e45f30de86abbf906ce643f5049ee1f27890467b77a6a8e11ec4661cc38cd8badf90115fbd03cef", - "compressed": true, - "i": 1 - }, - "scriptSignature": { - "hex": "3045022100cde1302d83f8dd835d89aef803c74a119f561fbaef3eb9129e45f30de86abbf9022006ce643f5049ee1f27890467b77a6a8e11ec4661cc38cd8badf90115fbd03cef81", - "hashType": 129 - }, - "DER": "3045022100cde1302d83f8dd835d89aef803c74a119f561fbaef3eb9129e45f30de86abbf9022006ce643f5049ee1f27890467b77a6a8e11ec4661cc38cd8badf90115fbd03cef", - "signature": { - "r": "93122007060065279508564838030979550535085999589142852106617159184757394422777", - "s": "3078539468410661027472930027406594684630312677495124015420811882501887769839" - } - }], - "invalid": { - "compact": [{ - "exception": "Invalid signature parameter", - "hex": "23987ceade6a304fc5823ab38f99fc3c5f772a2d3e89ea05931e2726105fc53b9e601fc3231f35962c714fcbce5c95b427496edc7ae8b3d12e93791d7629795b62" - }, { - "exception": "Invalid signature length", - "hex": "1c987ceade6a304fc5823ab38f99fc3c5f772a2d3e89ea05931e2726105fc53b9e601fc3231f35962c714fcbce5c95b427496edc7ae8b3d12e93791d7629795b62000000" - }, { - "exception": "Invalid signature length", - "hex": "1c987ceade6a304fc5823ab38f99fc3c5f772a2d3e89ea05931e2726105fc53b9e601fc3231f35962c714fcbce5c95b427496edc7ae8b3d12e9379" - }], - "DER": [{ - "exception": "DER sequence length is too short", - "hex": "ffffffffffffff" - }, { - "exception": "DER sequence length is too long", - "hex": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - }, { - "exception": "Expected DER sequence", - "hex": "00ffff0400ffffff020400ffffff" - }, { - "exception": "DER sequence length is invalid", - "hex": "30ff020400ffffff020400ffffff" - }, { - "exception": "DER sequence length is invalid", - "hex": "300c030400ffffff030400ffffff0000" - }, { - "exception": "Expected DER integer", - "hex": "300cff0400ffffff020400ffffff" - }, { - "exception": "Expected DER integer \\(2\\)", - "hex": "300c020200ffffff020400ffffff" - }, { - "exception": "R length is zero", - "hex": "30080200020400ffffff" - }, { - "exception": "S length is zero", - "hex": "3008020400ffffff0200" - }, { - "exception": "R length is too long", - "hex": "300c02dd00ffffff020400ffffff" - }, { - "exception": "S length is invalid", - "hex": "300c020400ffffff02dd00ffffff" - }, { - "exception": "R value is negative", - "hex": "300c020480000000020400ffffff" - }, { - "exception": "S value is negative", - "hex": "300c020400ffffff020480000000" - }, { - "exception": "R value excessively padded", - "hex": "300c02040000ffff020400ffffff" - }, { - "exception": "S value excessively padded", - "hex": "300c020400ffffff02040000ffff" - }], - "scriptSignature": [{ - "exception": "Invalid hashType 7", - "hashType": 7, - "hex": "3044022033a69cd2065432a30f3d1ce4eb0d59b8ab58c74f27c41a7fdb5696ad4e6108c902206f807982866f785d3f6418d24163ddae117b7db4d5fdf0071de069fa5434226207", - "signature": { - "r": "23362334225185207751494092901091441011938859014081160902781146257181456271561", - "s": "50433721247292933944369538617440297985091596895097604618403996029256432099938" - } - }, { - "exception": "Invalid hashType 140", - "hashType": 140, - "hex": "3044022033a69cd2065432a30f3d1ce4eb0d59b8ab58c74f27c41a7fdb5696ad4e6108c902206f807982866f785d3f6418d24163ddae117b7db4d5fdf0071de069fa543422628c", - "signature": { - "r": "23362334225185207751494092901091441011938859014081160902781146257181456271561", - "s": "50433721247292933944369538617440297985091596895097604618403996029256432099938" - } - }] - } -} diff --git a/packages/crypto/__tests__/crypto/fixtures/hdnode.json b/packages/crypto/__tests__/crypto/fixtures/hdnode.json deleted file mode 100644 index 84f55bc822..0000000000 --- a/packages/crypto/__tests__/crypto/fixtures/hdnode.json +++ /dev/null @@ -1,261 +0,0 @@ -{ - "valid": [{ - "network": "mainnet", - "master": { - "seed": "000102030405060708090a0b0c0d0e0f", - "wif": "SHP217APiCmjmgjnf9pLDhP1ijJSxu6rsyAV2fibupLKp86JhaBo", - "pubKey": "0339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2", - "chainCode": "873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508", - "base58": "apubFZ6vkWBiARunuLDjfSpynmXY5xJb8rKCfhK9LPjZoxMqb4tCCW5wyYAQkCtbWYVRBedRjvbjNapwtdFCNd7JheoXeZeYeX7HBrooJFbR2km", - "base58Priv": "aprvbwWwpofWx4cF2p3v8fZ9WB1ZZupzF8XTidjuWGbKyVMgdeQHpfnNh8ShYf5Z2vDC73jkTwNoUmy8YkwncgHFEPAqvmzKXLU3mTu2tY4UFKr", - "identifier": "3442193e1bb70916e914552172cd4e2dbc9df811", - "fingerprint": "3442193e", - "address": "ALYBy5tH91frKYJtHXHj6pUHVAzzSiUwh5" - }, - "children": [{ - "path": "m/0'", - "m": 0, - "hardened": true, - "wif": "SHYFQVs66JoNeDDXJBBDgdMJDBLhCVGLdrwUQHfXkjQKdMjDYDMc", - "pubKey": "035a784662a4a20a65bf6aab9ae98a6c068a81c52e4b032c0fb5400c706cfccc56", - "chainCode": "47fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae6236141", - "base58": "apubFbNLkDVBFh2n3wMSsChcfodeQmrwWvoDMJk3JV7gn9Z7xMBNcjd36gWpXUTJFrPxBruzcA9A7Du2s2DLKeqgmYGFrCSoZq1VhnwMbtY72JF", - "base58Priv": "aprvbynMpWxz3KjEBRBdLRRnPD7ftjPLdD1UQFAoUMySwgYxzvhUEuKTpGo7KvRtSdb9p6dSqEhfs8p1GWyWGGZS2TFMzefTmJAwUUXtKiRcop1", - "identifier": "5c1bd648ed23aa5fd50ba52b2457c11e9e80a6a7", - "fingerprint": "5c1bd648", - "address": "AJoAPNFmiPV3q4i3DhhKSqt4yjtSAoo9KA", - "index": 2147483648, - "depth": 1 - }, { - "path": "m/0'/1", - "m": 1, - "wif": "SBbekBDe3JohdGUdb4pgWhAtmiyc5ZMv5CDSM811gZDLJCLBkTkK", - "pubKey": "03501e454bf00751f24b1b489aa925215d66af2234e3891c3b21a52bedb3cd711c", - "chainCode": "2a7857631386ba23dacac34180dd1983734e444fdbf774041578e9b6adb37c19", - "base58": "apubFdYTx134ePuqtPPtbTbVGYXJU9r3WxXWHdQstktVinMLBtgWLY3M4FR3wYusfo7J9aY3PabGDpPWTKx9nz1aTC6C9QHf3U1mLXU8toKk16b", - "base58Priv": "aprvc1xV2JWsS2cJ1sE54gKeyx1Kx7NSdEjmLZqe4dkFtKMBEUCbxhjmmqhLjycx3ZNCGBP8e4J6wqmRQTVjPcMQocjoWRdBq3wo9GrFrbQxcwA", - "identifier": "bef5a2f9a56a94aab12459f72ad9cf8cf19c7bbe", - "fingerprint": "bef5a2f9", - "address": "Aatdo4M1R3YGDsXucy91engPhD4VLSkQN5", - "index": 1, - "depth": 2 - }, { - "path": "m/0'/1/2'", - "m": 2, - "hardened": true, - "wif": "SGQN4aknd9b7eodTDvJXPX98kU3jB7eKsLQ5seuFM55TFuay1oWw", - "pubKey": "0357bfe1e341d01c69fe5654309956cbea516822fba8a601743a012a7896ee8dc2", - "chainCode": "04466b9cc8e161e966409ca52986c584f07e9dc81f735db683c3ff6ec7b1503f", - "base58": "apubFg9jzXrvMGmFkZByr3zrdYZShJiZnW7VdAeZ96Beteimbjsd9HsmxgxyVa6i7fYcW6dmzxZsbkxUuf6SW5Z7WeF2jJFo8R5T4DPGz674dm2", - "base58Priv": "aprvc4Zm4qLj8uTht32AKGj2Lx3UBGExtnKkg75KJy3R4BiceKPimTaCgHFGJ1qa1nsgmeQXEXF2NFbKdfEUydGbviBTs3BjyzBjkYbUVDzcynY", - "identifier": "ee7ab90cde56a8c0e2bb086ac49748b8db9dce72", - "fingerprint": "ee7ab90c", - "address": "AY9wc7S8P5dFbfksXoQy6J5FXAiVYfANaG", - "index": 2147483650, - "depth": 3 - }, { - "path": "m/0'/1/2'/2", - "m": 2, - "wif": "SA5ttH3963g9xJL7Gg9m1ks3NMpKiWLGmUvKMbB42sLuMQ7XtiV4", - "pubKey": "02e8445082a72f29b75ca48748a914df60622a609cacfce8ed0e35804560741d29", - "chainCode": "cfb71883f01676f587d023cc53a35bc7f88f724b1f8c2892ac1275ac822a3edd", - "base58": "apubFiP8pxysXkSEq2fhYKCwX3ikn81JR6Rh4eXrQ3i8D6HNxqVzD4a9AGRuAu66XThLyQkx8y3peVrbU5SSbNzKEEiHe5oyxbyH4uJ88fyjJzH", - "base58Priv": "aprvc6o9uGTgKP8gxWVt1Xw7ETCnG5XhXNdx7axcZvZtNdHE1R25qEGZsriByLF2UTH7qSYDrSUbH53V6r8wB3ox86mWGHGqY51SuX4dzjb3bFu", - "identifier": "d880d7d893848509a62d8fb74e32148dac68412f", - "fingerprint": "d880d7d8", - "address": "AXj65rgz8xBiSccDycCuERnsSVvWWarz2m", - "index": 2, - "depth": 4 - }, { - "path": "m/0'/1/2'/2/1000000000", - "m": 1000000000, - "wif": "SBxR9W8L1PGrt6FGgVh5vA6BjVeMb1QXkgyXJuoxftgt5W7hD6yx", - "pubKey": "022a471424da5e657499d1ff51cb43c47481a03b1e77f951fe64cec9f5a48f7011", - "chainCode": "c783e67b921d2beb8f6b389cc646d7263b4145701dadd2161548a8b078e65e9e", - "base58": "apubFk6uJeb7espSMNT9ermfpkikaMacEbEirtvQeL6GRAfsfxuNjUpoRNaxoj13Nin4T73VeJydBhZC4VqThEVA5VsQWdE4m5Yusrv3No5nFRu", - "base58Priv": "aprvc8WvNx4vSWWtUrHL85VqYACn4K71LsSyuqMApCx2ahfiiYRUMeXE8xsFcC2EPNQCSqwUdoTY87ac729Ji7pgF4R3bn34eymABrczjqRGiuj", - "identifier": "d69aa102255fed74378278c7812701ea641fdf32", - "fingerprint": "d69aa102", - "address": "AR1oxWprdmkhndyeAaWW6BQvt7GdiHWWuv", - "index": 1000000000, - "depth": 5 - }] - }, { - "network": "mainnet", - "master": { - "seed": "fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542", - "wif": "SC61ikR2WPwbcvJw49Jqa1ifyTuqeoSR9iXve9JW55LzkgT9z6Ux", - "pubKey": "03cbcaa9c98c877a26977d00825c956a238e8dddfbd322cce4f74b0b5bd6ace4a7", - "chainCode": "60499f801b896d83179a4374aeb7822aaeaceaa0db1f85ee3e904c4defbd9689", - "base58": "apubFZ6vkWBiARuntwj4mbuGEyFJL9T1pUa2MH6sdLUPnLUht3uPNertQSL16JyaDnrP6CsDebFtmfLCcQyRVp2TqZoUWVr1V1bwWEUua7Fjrr1", - "base58Priv": "aprvbwWwpofWx4cF2RZFEpdRxNjKp6yQvknHQDXdoDL9wsUYvdRUzpZK82cHtircDRmHM6VBDDqFkt1KeHftf6fwqkVcPC4ZfgNnLiXGFSSJ1eR", - "identifier": "bd16bee53961a47d6ad888e29545434a89bdfe95", - "fingerprint": "bd16bee5", - "address": "AZ1gc9nDfUvHRU3eMuyjs4CtzCJEo1ui4L" - }, - "children": [{ - "path": "m/0", - "m": 0, - "wif": "SFLMMdYsfouwpggAd2M4G7S7AgSNh6a7jSb1EcY3tJuHgY1yAku3", - "pubKey": "02fc9e5af0ac8d9b3cecfe2a888e2117ba3d089d8585886c9c826b6b22a98d12ea", - "chainCode": "f0909affaa7ee7abe5dd4e100598d4dc53cd709d5a5c2cac40e7412f232f7c9c", - "base58": "apubFcNg2DsfeSjsRDKMuPH9Jmeph7CGXT4JuSrEo9VqrkLfa2MMwvCxZGuFfmwU1srpJXMPWpFeAkBAmaQ7NxitBATknYagPMkKdiba1Q7Nz4e", - "base58Priv": "aprvbznh6XMUS5SKYh9YNc1K2B8rB4ifdjGZxPGzy2Mc2HLWcbsTa5uPGsBYUE8QrVc7kkj17EEzC3RSzoJiDPAzmyf1PNUd4AYXU8Rpcm5JvQn", - "identifier": "5a61ff8eb7aaca3010db97ebda76121610b78096", - "fingerprint": "5a61ff8e", - "address": "ALuTTVck6m5hGxzAmsJpQ9pkaSL2LEJyQ1", - "index": 0, - "depth": 1 - }, { - "path": "m/0/2147483647'", - "m": 2147483647, - "hardened": true, - "wif": "SE7ZWbjK7pHr37c224LT97Kunt8ZE9vF8UwjqSQhDhKqpPsJg4vH", - "pubKey": "03c01e7425647bdefa82b12d9bad5e3e6865bee0502694b94ca58b666abc0a5c3b", - "chainCode": "be17a268474a6bb9c61e1d720cf6215e2a88c5406c4aee7b38547f585c9a37d9", - "base58": "apubFdXjGpuC2Luyb5XYKqGnn7LP5rRB4wDzzbvmiYQcWV742KapZodGmLgrHABamcTv63GwAf7FTxbmSFGT9sCzuJvPKdCjk61LW6sAr85BULQ", - "base58Priv": "aprvc1wkM8NzoycRiZMio3zxVWpQZowaBDSG3YMXtRGNg26u4u6vByKhUvy95acPakLbez3ttFSdF3vZS33Uwkn8MH6Zp6hxpgGnFumMPDunVNS", - "identifier": "d8ab493736da02f11ed682f88339e720fb0379d1", - "fingerprint": "d8ab4937", - "address": "ALxpsBhgJd9UWUFxqjTSkhnCuv565macBB", - "index": 4294967295, - "depth": 2 - }, { - "path": "m/0/2147483647'/1", - "m": 1, - "wif": "SDLUYa8aJuPnyt9KZ5xFdFnQ2cUypHmB4r8YkbMMpQULiU19xFh9", - "pubKey": "03a7d1d856deb74c508e05031f9895dab54626251b3806e16b4bd12e781a7df5b9", - "chainCode": "f366f48f1ea9f2d1d3fe958c95ca84ea18e4c4ddb9366c336c927eb246fb38cb", - "base58": "apubFgLhgqt8BzDAghCgPVRMk4GcRPHgB89GK3RdZc4wpNTVh9SysK9yfF5E7xNiZVACgDjV1JCV75ubX3XU4mdxAePHuuQaxdSYRsY86apdXEG", - "base58Priv": "aprvc4kim9MvycucpB2rri9XTTkduLp5HQMXMyrPjUvhyuTLjiy5VUrQNqMWvNp1cTYHxwQbdYX1ebbmkjpdzeJWMkurwsEmfnFAjiC5rurnq6u", - "identifier": "78412e3a2296a40de124307b6485bd19833e2e34", - "fingerprint": "78412e3a", - "address": "ASZcE1gZbr7wkrpJeuNitWwzFWofoWbVwf", - "index": 1, - "depth": 3 - }, { - "path": "m/0/2147483647'/1/2147483646'", - "m": 2147483646, - "hardened": true, - "wif": "SHgBb94AtsynVXp2ev4QQGNSGeaTpfa94QZBLFQgJnHUHVy5q8s7", - "pubKey": "02d2b36900396c9282fa14628566582f206a5dd0bcc8d5e892611806cafb0301f0", - "chainCode": "637807030d55d01f9a0cb3a7839515d796bd07706386a6eddf06cc29a65a0e29", - "base58": "apubFhWjbopUoPAsyeSH7yEu7ZxoL7m3E6mmLk9X6KmMf8ik9Vmuxz5zBmSKkcWDkrgedfP7ooGC9hETAggrkekTt15kBoj5WvXxJ6chdZdX5yu", - "base58Priv": "aprvc5vkg7JHb1sL78GTbBy4pySpp5HSLNz2PgaHGCd7pfibC5J1b9nQuMicZ5YQEsvaWWhHwNJ12yBMZrv1WbD13bb2mon5ozGo5JCbvf6n5dB", - "identifier": "31a507b815593dfc51ffc7245ae7e5aee304246e", - "fingerprint": "31a507b8", - "address": "AbQUQs33ZmeE44L54BLkFW29j6C1cquuQU", - "index": 4294967294, - "depth": 4 - }, { - "path": "m/0/2147483647'/1/2147483646'/2", - "m": 2, - "wif": "SFreZ9JLkRRnbafaSAgmoTkfY5naqx7N4rXmrYZxmT1UQh9KuAyg", - "pubKey": "024d902e1a2fc7a8755ab5b694c575fce742c48d9ff192e63df5193e4c7afe1f9c", - "chainCode": "9452b549be8cea3ecb7a84bec10dcfd94afe4d129ebfd3b3cb58eedf394ed271", - "base58": "apubFismZF2zKZV7iudAr3Nb6KLmjBJ9URgqzumQW77rHvaLDh7V8d1kNLPKq1aVtS3M9ibM5imc3QFSf7kMakSNCFwKpyZATHpgyPotJFBfLAk", - "base58Priv": "aprvc7HndYWo7CBZrPTMKG6koipoD8pYahu73rCAfyycTTaBGGdakniB5vfcdVDQPu1eYpZ2E7vpV523cQoXEuaE6aKkafHasQQWmfYA1Bt8zAw", - "identifier": "26132fdbe7bf89cbc64cf8dafa3f9f88b8666220", - "fingerprint": "26132fdb", - "address": "AeCfpoa7UWhKBqtY4oUtPMs31nDZqEWciX", - "index": 2, - "depth": 5 - }] - }, { - "comment": "Private key has leading zeros, see PR #673", - "network": "mainnet", - "master": { - "seed": "d13de7bd1e54422d1a3b3b699a27fb460de2849e7e66a005c647e8e4a54075cb", - "wif": "S9aCDFDPDbSBsbyxBvHG3caxMfYmHdkBYggdQWiUYp9M41cTBtT2", - "pubKey": "0298ccc720d5dea817c7077605263bae52bca083cf8888fee77ff4c1b4797ee180", - "chainCode": "c23ab32b36ddff49fae350a1bed8ec6b4d9fc252238dd789b7273ba4416054eb", - "base58": "apubFZ6vkWBiARunuvHLZhFXGdZgVs3BZrhNEHf7PJMaTrzaytTUqdn1tyhnNVLFAG7aqv4crz8PSGxbuSKFid2v6Nd6vM3YWXwtPP2PqYAifBo", - "base58Priv": "aprvbwWwpofWx4cF3Q7X2uygz33hypZag8udHE5sZBDLdPzS2TyaToUScZz5AvySh5heKufyVx8CcdtVa3TszhJxRrb6UUPaWcjNUk6ULQVVdRR", - "identifier": "1a87677be6f73cc9655e8b4c5d2fd0aeeb1b23c7", - "fingerprint": "1a87677b", - "address": "AJC9RY6uYvMRp2M7vnPPaeNbgJLMx1DwNy" - }, - "children": [{ - "path": "m/44'/0'/0'/0/0'", - "wif": "SGLXNDyMEfsnB7qawJP26Km4c6ndKqH6JmNGkefkgLk2uaTTQfm2", - "pubKey": "027c3591221e28939e45f8ea297d62c3640ebb09d7058b01d09c963d984a40ad49", - "chainCode": "ca27553aa89617e982e621637d6478f564b32738f8bbe2e48d0a58a8e0f6da40", - "base58": "apubFjhkZuMnzDzFssCDRZtLQRE4M9nrQ8EzK8SXLSmBHvkT8vmjPGjnuPe4C9qdwxXDEKh7Wuj7dyKg1yDQcGVCXUx7aVyqUXdjVCapyVZKVpu", - "base58Priv": "aprvc87meCqbmrgi1M2PtncW7pi5q7KFWQTFN4sHWKcwTTkJBWHq1SSDcyvLzdEKFjBbbCh7Cqq4CKmxH4TtNQeWPpCtRr7ZLJgWhpHPckhCYNb", - "identifier": "e371d69b5dae6eacee832a130ee9f55545275a09", - "fingerprint": "e371d69b", - "address": "AcVyDRvH1W3Z2CEEJCMt6tyAZN18C1JD1j", - "index": 2147483648, - "depth": 5 - }] - }], - "invalid": { - "fromBase58": [{ - "exception": "Invalid checksum", - "string": "xprvQQQQQQQQQQQQQQQQCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334" - }, { - "exception": "Invalid buffer length", - "network": "bitcoin", - "string": "HAsbc6CgKmTYEQg2CTz7m5STEPAB" - }, { - "exception": "Invalid parent fingerprint", - "network": "bitcoin", - "string": "xprv9tnJFvAXAXPfPnMTKfwpwnkty7MzJwELVgp4NTBquaKXy4RndyfJJCJJf7zNaVpBpzrwVRutZNLRCVLEcZHcvuCNG3zGbGBcZn57FbNnmSP" - }, { - "exception": "Invalid private key", - "network": "bitcoin", - "string": "xprv9s21ZrQH143K3yLysFvsu3n1dMwhNusmNHr7xArzAeCc7MQYqDBBStmqnZq6WLi668siBBNs3SjiyaexduHu9sXT9ixTsqptL67ADqcaBdm" - }, { - "exception": "Invalid index", - "network": "bitcoin", - "string": "xprv9s21ZrQYdgnodnKW4Drm1Qg7poU6Gf2WUDsjPxvYiK7iLBMrsjbnF1wsZZQgmXNeMSG3s7jmHk1b3JrzhG5w8mwXGxqFxfrweico7k8DtxR" - }, { - "exception": "Unknown network version", - "string": "1111111111111adADjFaSNPxwXqLjHLj4mBfYxuewDPbw9hEj1uaXCzMxRPXDFF3cUoezTFYom4sEmEVSQmENPPR315cFk9YUFVek73wE9" - }, { - "exception": "Invalid network version", - "network": "bitcoin", - "string": "Ltpv73XYpw28ZyVe2zEVyiFnxUZxoKLGQNdZ8NxUi1WcqjNmMBgtLbh3KimGSnPHCoLv1RmvxHs4dnKmo1oXQ8dXuDu8uroxrbVxZPA1gXboYvx" - }, { - "exception": "Invalid buffer length", - "string": "9XpNiB4DberdMn4jZiMhNGtuZUd7xUrCEGw4MG967zsVNvUKBEC9XLrmVmFasanWGp15zXfTNw4vW4KdvUAynEwyKjdho9QdLMPA2H5uyt" - }, { - "exception": "Invalid buffer length", - "string": "7JJikZQ2NUXjSAnAF2SjFYE3KXbnnVxzRBNddFE1DjbDEHVGEJzYC7zqSgPoauBJS3cWmZwsER94oYSFrW9vZ4Ch5FtGeifdzmtS3FGYDB1vxFZsYKgMc" - }, { - "exception": "Invalid parent fingerprint", - "string": "xpub67tVq9SuNQCfm2PXBqjGRAtNZ935kx2uHJaURePth4JBpMfEy6jum7Euj7FTpbs7fnjhfZcNEktCucWHcJf74dbKLKNSTZCQozdDVwvkJhs" - }, { - "exception": "Invalid index", - "string": "xpub661MyMwTWkfYZq6BEh3ywGVXFvNj5hhzmWMhFBHSqmub31B1LZ9wbJ3DEYXZ8bHXGqnHKfepTud5a2XxGdnnePzZa2m2DyzTnFGBUXtaf9M" - }, { - "exception": "Unknown network version", - "string": "8FH81Rao5EgGmdScoN66TJAHsQP7phEMeyMTku9NBJd7hXgaj3HTvSNjqJjoqBpxdbuushwPEM5otvxXt2p9dcw33AqNKzZEPMqGHmz7Dpayi6Vb" - }, { - "exception": "Point is not on the curve", - "string": "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gYymDsxxRe3WWeZQ7TadaLSdKUffezzczTCpB8j3JP96UwE2n6w1" - }], - "deriveHardened": [ - 2147483648, - null, - "foo", -1 - ], - "derive": [ - 4294967296, - null, - "foo", -1 - ], - "derivePath": [ - 2, [ - 2, - 3, - 4 - ], - "/", - "m/m/123", - "a/0/1/2", - "m/0/ 1 /2", - "m/0/1.5/2" - ] - } -} diff --git a/packages/crypto/__tests__/crypto/hdnode/base58.test.js b/packages/crypto/__tests__/crypto/hdnode/base58.test.js deleted file mode 100644 index c163983d36..0000000000 --- a/packages/crypto/__tests__/crypto/hdnode/base58.test.js +++ /dev/null @@ -1,51 +0,0 @@ -const configManager = require('../../../lib/managers/config') -const HDNode = require('../../../lib/crypto/hdnode') -const { NETWORKS, NETWORKS_LIST } = require('../../utils/network-list') - -const fixtures = require('../fixtures/hdnode.json') - -beforeEach(() => configManager.setConfig(NETWORKS.mainnet)) - -let validAll = [] -fixtures.valid.forEach((f) => { - function addNetwork (n) { - n.network = f.network - return n - } - - validAll = validAll.concat(addNetwork(f.master), f.children.map(addNetwork)) -}) - -describe('HDNode', () => { - describe('fromBase58 / toBase58', () => { - validAll.forEach((f) => { - it(`exports ${f.base58} (public) correctly`, () => { - const hd = HDNode.fromBase58(f.base58, NETWORKS_LIST) - - expect(hd.toBase58()).toBe(f.base58) - expect(() => { - hd.keyPair.toWIF() - }).toThrowError(/Missing private key/) - }) - }) - - validAll.forEach((f) => { - it(`exports ${f.base58Priv} (private) correctly`, () => { - const hd = HDNode.fromBase58(f.base58Priv, NETWORKS_LIST) - - expect(hd.toBase58()).toBe(f.base58Priv) - expect(hd.keyPair.toWIF()).toBe(f.wif) - }) - }) - - fixtures.invalid.fromBase58.forEach((f) => { - it(`throws on ${f.string}`, () => { - expect(() => { - const networks = f.network ? NETWORKS[f.network] : NETWORKS_LIST - - HDNode.fromBase58(f.string, networks) - }).toThrowError(new RegExp(f.exception)) - }) - }) - }) -}) diff --git a/packages/crypto/__tests__/crypto/hdnode/constructor.test.js b/packages/crypto/__tests__/crypto/hdnode/constructor.test.js deleted file mode 100644 index c93d54d764..0000000000 --- a/packages/crypto/__tests__/crypto/hdnode/constructor.test.js +++ /dev/null @@ -1,83 +0,0 @@ -const BigInteger = require('bigi') - -const configManager = require('../../../lib/managers/config') -const ECPair = require('../../../lib/crypto/ecpair') -const HDNode = require('../../../lib/crypto/hdnode') -const { NETWORKS, NETWORKS_LIST } = require('../../utils/network-list') - -const fixtures = require('../fixtures/hdnode.json') - -beforeEach(() => configManager.setConfig(NETWORKS.mainnet)) - -let validAll = [] -fixtures.valid.forEach((f) => { - function addNetwork (n) { - n.network = f.network - return n - } - - validAll = validAll.concat(addNetwork(f.master), f.children.map(addNetwork)) -}) - -describe('HDNode', () => { - describe('Constructor', () => { - let keyPair - let chainCode - - beforeEach(() => { - const d = BigInteger.ONE - - keyPair = new ECPair(d, null) - chainCode = Buffer.alloc(32) - chainCode.fill(1) - }) - - it('stores the keyPair/chainCode directly', () => { - const hd = new HDNode(keyPair, chainCode) - - expect(hd.keyPair).toBe(keyPair) - expect(hd.chainCode).toBe(chainCode) - }) - - it('has a default depth/index of 0', () => { - const hd = new HDNode(keyPair, chainCode) - - expect(hd.depth).toBe(0) - expect(hd.index).toBe(0) - }) - - it('throws on uncompressed keyPair', () => { - keyPair.compressed = false - - expect(() => { - new HDNode(keyPair, chainCode) // eslint-disable-line no-new - }).toThrowError(/BIP32 only allows compressed keyPairs/) - }) - - it('throws when an invalid length chain code is given', () => { - expect(() => { - new HDNode(keyPair, Buffer.alloc(20)) // eslint-disable-line no-new - }).toThrowError(/Expected property "1" of type Buffer\(Length: 32\), got Buffer\(Length: 20\)/) - }) - }) - - describe('getIdentifier', () => { - validAll.forEach((f) => { - it(`returns the identifier for ${f.fingerprint}`, () => { - const hd = HDNode.fromBase58(f.base58, NETWORKS_LIST) - - expect(hd.getIdentifier().toString('hex')).toBe(f.identifier) - }) - }) - }) - - describe('getFingerprint', () => { - validAll.forEach((f) => { - it(`returns the fingerprint for ${f.fingerprint}`, () => { - const hd = HDNode.fromBase58(f.base58, NETWORKS_LIST) - - expect(hd.getFingerprint().toString('hex')).toBe(f.fingerprint) - }) - }) - }) -}) diff --git a/packages/crypto/__tests__/crypto/hdnode/derive.test.js b/packages/crypto/__tests__/crypto/hdnode/derive.test.js deleted file mode 100644 index ec0ce46bff..0000000000 --- a/packages/crypto/__tests__/crypto/hdnode/derive.test.js +++ /dev/null @@ -1,161 +0,0 @@ -const configManager = require('../../../lib/managers/config') -const HDNode = require('../../../lib/crypto/hdnode') -const { NETWORKS, NETWORKS_LIST } = require('../../utils/network-list') - -const fixtures = require('../fixtures/hdnode.json') - -beforeEach(() => configManager.setConfig(NETWORKS.mainnet)) - -let validAll = [] -fixtures.valid.forEach((f) => { - function addNetwork (n) { - n.network = f.network - return n - } - - validAll = validAll.concat(addNetwork(f.master), f.children.map(addNetwork)) -}) - -describe('HDNode', () => { - describe('derive', () => { - function verifyVector (hd, v) { - if (hd.isNeutered()) { - expect(hd.toBase58()).toBe(v.base58) - } else { - expect(hd.neutered().toBase58()).toBe(v.base58) - expect(hd.toBase58()).toBe(v.base58Priv) - } - - expect(hd.getFingerprint().toString('hex')).toBe(v.fingerprint) - expect(hd.getIdentifier().toString('hex')).toBe(v.identifier) - expect(hd.getAddress()).toBe(v.address) - expect(hd.keyPair.toWIF()).toBe(v.wif) - expect(hd.keyPair.getPublicKeyBuffer().toString('hex')).toBe(v.pubKey) - expect(hd.chainCode.toString('hex')).toBe(v.chainCode) - expect(hd.depth).toBe(v.depth >>> 0) // TODO: make sure it works later - expect(hd.index).toBe(v.index >>> 0) // TODO: make sure it works later - } - - fixtures.valid.forEach((f) => { - const network = NETWORKS[f.network] - let hd = HDNode.fromSeedHex(f.master.seed, network) - const master = hd - - // testing deriving path = require(master - f.children.forEach((c) => { - it(`${c.path} = require(${f.master.fingerprint} by path`, () => { - const child = master.derivePath(c.path) - const childNoM = master.derivePath(c.path.slice(2)) // no m/ on path - - verifyVector(child, c) - verifyVector(childNoM, c) - }) - }) - - // testing deriving path = require(children - f.children.forEach((c, i) => { - const cn = master.derivePath(c.path) - - f.children.slice(i + 1).forEach(function (cc) { - it(`${cc.path} = require(${f.fingerprint} by path`, () => { - const ipath = cc.path.slice(2).split('/').slice(i + 1).join('/') - const child = cn.derivePath(ipath) - verifyVector(child, cc) - - expect(() => { - cn.derivePath('m/' + ipath) - }).toThrowError(/Not a master node/) - }) - }) - }) - - // FIXME: test data is only testing Private -> private for now - f.children.forEach((c, i) => { - if (c.m === undefined) return - - it(`${c.path} = require(${f.master.fingerprint}`, () => { - if (c.hardened) { - hd = hd.deriveHardened(c.m) - } else { - hd = hd.derive(c.m) - } - - verifyVector(hd, c) - }) - }) - }) - - it('works for Private -> public (neutered)', () => { - const f = fixtures.valid[1] - const c = f.children[0] - - const master = HDNode.fromBase58(f.master.base58Priv, NETWORKS_LIST) - const child = master.derive(c.m).neutered() - - expect(child.toBase58()).toBe(c.base58) - }) - - it('works for Private -> public (neutered, hardened)', () => { - const f = fixtures.valid[0] - const c = f.children[0] - - const master = HDNode.fromBase58(f.master.base58Priv, NETWORKS_LIST) - const child = master.deriveHardened(c.m).neutered() - - expect(c.base58).toBe(child.toBase58()) - }) - - it('works for Public -> public', () => { - const f = fixtures.valid[1] - const c = f.children[0] - - const master = HDNode.fromBase58(f.master.base58, NETWORKS_LIST) - const child = master.derive(c.m) - - expect(c.base58).toBe(child.toBase58()) - }) - - it('throws on Public -> public (hardened)', () => { - const f = fixtures.valid[0] - const c = f.children[0] - - const master = HDNode.fromBase58(f.master.base58, NETWORKS_LIST) - - expect(() => { - master.deriveHardened(c.m) - }).toThrowError(/Could not derive hardened child key/) - }) - - it('throws on wrong types', () => { - const f = fixtures.valid[0] - const master = HDNode.fromBase58(f.master.base58, NETWORKS_LIST) - - fixtures.invalid.derive.forEach((fx) => { - expect(() => { - master.derive(fx) - }).toThrowError(/Expected UInt32/) - }) - - fixtures.invalid.deriveHardened.forEach((fx) => { - expect(() => { - master.deriveHardened(fx) - }).toThrowError(/Expected UInt31/) - }) - - fixtures.invalid.derivePath.forEach((fx) => { - expect(() => { - master.derivePath(fx) - }).toThrowError(/Expected BIP32 derivation path/) - }) - }) - - it('works when private key has leading zeros', () => { - const key = 'xprv9s21ZrQH143K3ckY9DgU79uMTJkQRLdbCCVDh81SnxTgPzLLGax6uHeBULTtaEtcAvKjXfT7ZWtHzKjTpujMkUd9dDb8msDeAfnJxrgAYhr' - const hdkey = HDNode.fromBase58(key, NETWORKS.bitcoin) - expect(hdkey.keyPair.d.toBuffer(32).toString('hex')).toBe('00000055378cf5fafb56c711c674143f9b0ee82ab0ba2924f19b64f5ae7cdbfd') - - const child = hdkey.derivePath('m/44\'/0\'/0\'/0/0\'') - expect(child.keyPair.d.toBuffer().toString('hex')).toBe('3348069561d2a0fb925e74bf198762acc47dce7db27372257d2d959a9e6f8aeb') - }) - }) -}) diff --git a/packages/crypto/__tests__/crypto/hdnode/ecpair.test.js b/packages/crypto/__tests__/crypto/hdnode/ecpair.test.js deleted file mode 100644 index 9211a2be1a..0000000000 --- a/packages/crypto/__tests__/crypto/hdnode/ecpair.test.js +++ /dev/null @@ -1,97 +0,0 @@ -const configManager = require('../../../lib/managers/config') -const ECPair = require('../../../lib/crypto/ecpair') -const HDNode = require('../../../lib/crypto/hdnode') -const { NETWORKS } = require('../../utils/network-list') - -const fixtures = require('../fixtures/hdnode.json') - -beforeEach(() => configManager.setConfig(NETWORKS.mainnet)) - -let validAll = [] -fixtures.valid.forEach((f) => { - function addNetwork (n) { - n.network = f.network - return n - } - - validAll = validAll.concat(addNetwork(f.master), f.children.map(addNetwork)) -}) - -describe('HDNode', () => { - describe('ECPair wrappers', () => { - let keyPair - let hd - let hash - - beforeEach(() => { - keyPair = ECPair.makeRandom() - hash = Buffer.alloc(32) - - const chainCode = Buffer.alloc(32) - hd = new HDNode(keyPair, chainCode) - }) - - describe('getAddress', () => { - it('wraps keyPair.getAddress', () => { - keyPair.getAddress = jest.fn() - keyPair.getAddress.mockReturnValue('foobar') - - expect(hd.getAddress()).toBe('foobar') - - expect(keyPair.getAddress).toHaveBeenCalledTimes(1) - }) - }) - - describe('getNetwork', () => { - it('wraps keyPair.getNetwork', () => { - keyPair.getNetwork = jest.fn() - keyPair.getNetwork.mockReturnValue('network') - - expect(hd.getNetwork()).toBe('network') - - expect(keyPair.getNetwork).toHaveBeenCalledTimes(1) - }) - }) - - describe('getPublicKeyBuffer', () => { - it('wraps keyPair.getPublicKeyBuffer', () => { - keyPair.getPublicKeyBuffer = jest.fn() - keyPair.getPublicKeyBuffer.mockReturnValue('pubKeyBuffer') - - expect(hd.getPublicKeyBuffer()).toBe('pubKeyBuffer') - - expect(keyPair.getPublicKeyBuffer).toHaveBeenCalledTimes(1) - }) - }) - - describe('sign', () => { - it('wraps keyPair.sign', () => { - keyPair.sign = jest.fn() - keyPair.sign.mockReturnValue('signed') - - expect(hd.sign(hash)).toBe('signed') - - expect(keyPair.sign).toHaveBeenCalledWith(hash) - expect(keyPair.sign).toHaveBeenCalledTimes(1) - }) - }) - - describe('verify', () => { - let signature - - beforeEach(() => { - signature = hd.sign(hash) - }) - - it('wraps keyPair.verify', () => { - keyPair.verify = jest.fn() - keyPair.verify.mockReturnValue('verified') - - expect(hd.verify(hash, signature)).toBe('verified') - - expect(keyPair.verify).toHaveBeenCalledWith(hash, signature) - expect(keyPair.verify).toHaveBeenCalledTimes(1) - }) - }) - }) -}) diff --git a/packages/crypto/__tests__/crypto/hdnode/fromSeed.test.js b/packages/crypto/__tests__/crypto/hdnode/fromSeed.test.js deleted file mode 100644 index 2b5030002d..0000000000 --- a/packages/crypto/__tests__/crypto/hdnode/fromSeed.test.js +++ /dev/null @@ -1,67 +0,0 @@ -const BigInteger = require('bigi') - -const configManager = require('../../../lib/managers/config') -const ecdsa = require('../../../lib/crypto/ecdsa') -const HDNode = require('../../../lib/crypto/hdnode') -const { NETWORKS } = require('../../utils/network-list') - -const fixtures = require('../fixtures/hdnode.json') - -beforeEach(() => configManager.setConfig(NETWORKS.mainnet)) - -let validAll = [] -fixtures.valid.forEach((f) => { - function addNetwork (n) { - n.network = f.network - return n - } - - validAll = validAll.concat(addNetwork(f.master), f.children.map(addNetwork)) -}) - -describe('HDNode', () => { - describe('fromSeed*', () => { - fixtures.valid.forEach((f) => { - it(`calculates privKey and chainCode for ${f.master.fingerprint}`, () => { - const hd = HDNode.fromSeedHex(f.master.seed, NETWORKS[f.network]) - - expect(hd.keyPair.toWIF()).toBe(f.master.wif) - expect(hd.chainCode.toString('hex')).toBe(f.master.chainCode) - }) - }) - - it('throws if IL is not within interval [1, n - 1] | IL === 0', () => { - BigInteger.fromBuffer = jest.fn() - BigInteger.fromBuffer.mockReturnValue(BigInteger.ZERO) - - expect(() => { - HDNode.fromSeedHex('ffffffffffffffffffffffffffffffff') - }).toThrowError(/Private key must be greater than 0/) - - expect(BigInteger.fromBuffer).toHaveBeenCalledTimes(1) - }) - - it('throws if IL is not within interval [1, n - 1] | IL === n', () => { - BigInteger.fromBuffer = jest.fn() - BigInteger.fromBuffer.mockReturnValue(ecdsa.__curve.n) - - expect(() => { - HDNode.fromSeedHex('ffffffffffffffffffffffffffffffff') - }).toThrowError(/Private key must be less than the curve order/) - - expect(BigInteger.fromBuffer).toHaveBeenCalledTimes(1) - }) - - it('throws on low entropy seed', () => { - expect(() => { - HDNode.fromSeedHex('ffffffffff') - }).toThrowError(/Seed should be at least 128 bits/) - }) - - it('throws on too high entropy seed', () => { - expect(() => { - HDNode.fromSeedHex('ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff') // eslint-disable-line max-len - }).toThrowError(/Seed should be at most 512 bits/) - }) - }) -}) diff --git a/packages/crypto/__tests__/crypto/hdnode/neutered.test.js b/packages/crypto/__tests__/crypto/hdnode/neutered.test.js deleted file mode 100644 index a8d480bc63..0000000000 --- a/packages/crypto/__tests__/crypto/hdnode/neutered.test.js +++ /dev/null @@ -1,44 +0,0 @@ -const assert = require('assert') - -const configManager = require('../../../lib/managers/config') -const HDNode = require('../../../lib/crypto/hdnode') -const { NETWORKS, NETWORKS_LIST } = require('../../utils/network-list') - -const fixtures = require('../fixtures/hdnode.json') - -beforeEach(() => configManager.setConfig(NETWORKS.mainnet)) - -let validAll = [] -fixtures.valid.forEach((f) => { - function addNetwork (n) { - n.network = f.network - return n - } - - validAll = validAll.concat(addNetwork(f.master), f.children.map(addNetwork)) -}) - -describe('HDNode', () => { - describe('neutered / isNeutered', () => { - validAll.forEach((f) => { - it(`drops the private key for ${f.fingerprint}`, () => { - const hd = HDNode.fromBase58(f.base58Priv, NETWORKS_LIST) - const hdn = hd.neutered() - - assert.notEqual(hdn.keyPair, hd.keyPair) - expect(() => { - hdn.keyPair.toWIF() - }).toThrowError(/Missing private key/) - expect(hdn.toBase58()).toBe(f.base58) - expect(hdn.chainCode).toBe(hd.chainCode) - expect(hdn.depth).toBe(f.depth >>> 0) // TODO: make sure it works later - expect(hdn.index).toBe(f.index >>> 0) // TODO: make sure it works later - expect(hdn.isNeutered()).toBeTruthy() - - // does not modify the original - expect(hd.toBase58()).toBe(f.base58Priv) - expect(hd.isNeutered()).toBeFalsy() - }) - }) - }) -}) diff --git a/packages/crypto/__tests__/crypto/hdwallet.test.js b/packages/crypto/__tests__/crypto/hdwallet.test.js new file mode 100644 index 0000000000..2792eb29cb --- /dev/null +++ b/packages/crypto/__tests__/crypto/hdwallet.test.js @@ -0,0 +1,196 @@ +const bip32 = require('bip32') +const { crypto, hdwallet } = require('../../lib/crypto') +const configManager = require('../../lib/managers/config') +const network = require('../../lib/networks/ark/mainnet.json') + +const mnemonic = 'sorry hawk one science reject employ museum ride into post machine attack bar seminar myself unhappy faculty differ grain fish chest bird muffin mesh' + +beforeEach(() => configManager.setConfig(network)) + +describe('HDWallet', () => { + describe('bip32', () => { + it('can create a BIP32 wallet external address', () => { + const path = "m/0'/0/0" + const root = bip32.fromSeed( + Buffer.from( + 'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd', + 'hex', + ), + ) + + const child1 = root.derivePath(path) + + // option 2, manually + const child2 = root + .deriveHardened(0) + .derive(0) + .derive(0) + + expect(crypto.getAddress(child1.publicKey.toString('hex'))).toBe( + 'AZXdSTRFGHPokX6yfXTfHcTzzHKncioj31', + ) + expect(crypto.getAddress(child2.publicKey.toString('hex'))).toBe( + 'AZXdSTRFGHPokX6yfXTfHcTzzHKncioj31', + ) + }) + }) + + describe('bip44', () => { + it('can create a BIP44, ark, account 0, external address', () => { + /* eslint quotes: ["error", "single", { avoidEscape: true }] */ + const path = "m/44'/111'/0'/0/0" + const root = bip32.fromSeed( + Buffer.from( + 'dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd', + 'hex', + ), + ) + + const child1 = root.derivePath(path) + + // option 2, manually + const child2 = root + .deriveHardened(44) + .deriveHardened(111) + .deriveHardened(0) + .derive(0) + .derive(0) + + expect(crypto.getAddress(child1.publicKey.toString('hex'))).toBe( + 'AKdstZSrxzeF54e1M41fQzqGqjod9ydG3E', + ) + expect(crypto.getAddress(child2.publicKey.toString('hex'))).toBe( + 'AKdstZSrxzeF54e1M41fQzqGqjod9ydG3E', + ) + }) + }) + + describe('fromMnemonic', () => { + it('should be a function', () => { + expect(hdwallet.fromMnemonic).toBeFunction() + }) + + it('should return the root node', () => { + const root = hdwallet.fromMnemonic(mnemonic) + expect(root.constructor.name).toBe('BIP32') + }) + + it('should derive path', () => { + const root = hdwallet.fromMnemonic(mnemonic) + const node = root.derivePath("44'/1'/0'/0/0") + expect(node.publicKey.toString('hex')).toBe( + '02126148679f22c162afa24a264a6b6722a61aab622248f2f536da289f48a9291f', + ) + expect(node.privateKey.toString('hex')).toBe( + 'b6f84081b674cf1f765ac182aaabd94d944c367d214263d1f7f3102d1cec98d5', + ) + }) + }) + + describe('getKeys', () => { + it('should be a function', () => { + expect(hdwallet.fromKeys).toBeFunction() + }) + + it('should return keys from a node', () => { + const root = hdwallet.fromMnemonic(mnemonic) + const node = root.derivePath("44'/1'/0'/0/0") + const keys = hdwallet.getKeys(node) + expect(keys.publicKey).toBe( + '02126148679f22c162afa24a264a6b6722a61aab622248f2f536da289f48a9291f', + ) + expect(keys.privateKey).toBe( + 'b6f84081b674cf1f765ac182aaabd94d944c367d214263d1f7f3102d1cec98d5', + ) + expect(keys.compressed).toBeTrue() + }) + }) + + describe('fromKeys', () => { + it('should be a function', () => { + expect(hdwallet.fromKeys).toBeFunction() + }) + + it('should return node from keys', () => { + const keys = { + publicKey: '', + privateKey: + 'b6f84081b674cf1f765ac182aaabd94d944c367d214263d1f7f3102d1cec98d5', + compressed: true, + } + + const chainCode = Buffer.from( + '2bbe729fab21bf8bca70763caf7fe85752726a363b494dea7a65e51e2d423d7b', + 'hex', + ) + const node = hdwallet.fromKeys(keys, chainCode) + expect(node.publicKey.toString('hex')).toBe( + '02126148679f22c162afa24a264a6b6722a61aab622248f2f536da289f48a9291f', + ) + expect(node.privateKey.toString('hex')).toBe( + 'b6f84081b674cf1f765ac182aaabd94d944c367d214263d1f7f3102d1cec98d5', + ) + }) + }) + + describe('deriveSlip44', () => { + it('should be a function', () => { + expect(hdwallet.deriveSlip44).toBeFunction() + }) + + it('should derive path', () => { + const root = hdwallet.fromMnemonic(mnemonic) + + const actual = hdwallet + .deriveSlip44(root) + .deriveHardened(0) + .derive(0) + .derive(0) + + const expected = root + .deriveHardened(44) + .deriveHardened(111) + .deriveHardened(0) + .derive(0) + .derive(0) + + expect(crypto.getAddress(actual.publicKey.toString('hex'))).toBe( + 'AHQhEsLWX5BbvvK836f1rUyZZZ77YikYq5', + ) + expect(actual.publicKey.toString('hex')).toBe( + '0330d7c2df15da16c72ac524f7548b2bca689beb0527ce54a50d3b79e4e91a8e9b', + ) + expect(actual.privateKey.toString('hex')).toBe( + '693bef1f16bad3c8096191af2362dae95873468fc5de30510b61d36fb3f1e33c', + ) + + expect(actual.publicKey).toEqual(expected.publicKey) + expect(actual.privateKey).toEqual(expected.privateKey) + }) + }) + + describe('deriveNetwork', () => { + it('should be a function', () => { + expect(hdwallet.deriveNetwork).toBeFunction() + }) + + it('should derive path', () => { + const root = hdwallet.fromMnemonic(mnemonic) + + const actual = hdwallet + .deriveNetwork(root) + .deriveHardened(0) + .derive(0) + + expect(crypto.getAddress(actual.publicKey.toString('hex'))).toBe( + 'AKjBp5V1xG9c5PQqUvtvtoGjvnyA3wLVpA', + ) + expect(actual.publicKey.toString('hex')).toBe( + '0281d69cadc9cf1bbbadd69503f071ce5de3826cee702e67a21d86f4fbe2d61b77', + ) + expect(actual.privateKey.toString('hex')).toBe( + 'de9b9b025d65b61a997c100419df05d1a26a4053f668e42e7ab2747ac6eed997', + ) + }) + }) +}) diff --git a/packages/crypto/__tests__/crypto/integration/basic.test.js b/packages/crypto/__tests__/crypto/integration/basic.test.js deleted file mode 100644 index b5d92f7163..0000000000 --- a/packages/crypto/__tests__/crypto/integration/basic.test.js +++ /dev/null @@ -1,41 +0,0 @@ -const bigi = require('bigi') -const utils = require('../../../lib/crypto/utils') -const ECPair = require('../../../lib/crypto/ecpair') - -const configManager = require('../../../lib/managers/config') -const network = require('../../../lib/networks/ark/mainnet.json') - -beforeEach(() => configManager.setConfig(network)) - -describe('Basic Crypto', () => { - it('can generate a random ark address', () => { - const keyPair = ECPair.makeRandom({ - rng: () => Buffer.from('zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz') - }) - - expect(keyPair.getAddress()).toBe('ANoMWEJ9jSdE2FgohBLLXeLzci59BDFsP4') - }) - - it('can generate an address = require(a SHA256 hash', () => { - const hash = utils.sha256('correct horse battery staple') - const keyPair = new ECPair(bigi.fromBuffer(hash)) - - expect(keyPair.getAddress()).toBe('AG5AtmiNbgv51eLwAWnRGvkMudVd7anYP2') - }) - - it('can generate a random keypair for alternative networks', () => { - const keyPair = ECPair.makeRandom({ - network, - rng: () => Buffer.from('zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz') - }) - - expect(keyPair.getAddress()).toBe('ANoMWEJ9jSdE2FgohBLLXeLzci59BDFsP4') - expect(keyPair.toWIF()).toBe('SDgGxWHHQHnpm5sth7MBUoeSw7V7nbimJ1RBU587xkryTh4qe9ov') - }) - - it('can const an address via WIF', () => { - const keyPair = ECPair.fromWIF('SDgGxWHHQHnpm5sth7MBUoeSw7V7nbimJ1RBU587xkryTh4qe9ov') - - expect(keyPair.getAddress()).toBe('ANoMWEJ9jSdE2FgohBLLXeLzci59BDFsP4') - }) -}) diff --git a/packages/crypto/__tests__/crypto/integration/bip32.test.js b/packages/crypto/__tests__/crypto/integration/bip32.test.js deleted file mode 100644 index b2da0488a4..0000000000 --- a/packages/crypto/__tests__/crypto/integration/bip32.test.js +++ /dev/null @@ -1,92 +0,0 @@ -const assert = require('assert') -const bigi = require('bigi') -const ecurve = require('ecurve') -const crypto = require('crypto') - -const HDNode = require('../../../lib/crypto/hdnode') -const { HIGHEST_BIT } = require('../../../lib/crypto/hdnode/constants') -const ECPair = require('../../../lib/crypto/ecpair') -const configManager = require('../../../lib/managers/config') -const network = require('../../../lib/networks/ark/mainnet.json') - -beforeEach(() => configManager.setConfig(network)) - -describe('ark-js (BIP32)', () => { - it('can create a BIP32 wallet external address', () => { - const path = "m/0'/0/0" - const root = HDNode.fromSeedHex('dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd') - - const child1 = root.derivePath(path) - - // option 2, manually - const child2 = root.deriveHardened(0).derive(0).derive(0) - - expect(child1.getAddress()).toBe('AZXdSTRFGHPokX6yfXTfHcTzzHKncioj31') - expect(child2.getAddress()).toBe('AZXdSTRFGHPokX6yfXTfHcTzzHKncioj31') - }) - - it('can create a BIP44, ark, account 0, external address', () => { - /* eslint quotes: ["error", "single", { avoidEscape: true }] */ - const path = "m/44'/0'/0'/0/0" - const root = HDNode.fromSeedHex('dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd') - - const child1 = root.derivePath(path) - - // option 2, manually - const child2 = root.deriveHardened(44) - .deriveHardened(0) - .deriveHardened(0) - .derive(0) - .derive(0) - - expect(child1.getAddress()).toBe('AVbXc2KyxtXeAP9zQpp7ixsnaxEEQ6wZbq') - expect(child2.getAddress()).toBe('AVbXc2KyxtXeAP9zQpp7ixsnaxEEQ6wZbq') - }) - - it('can recover a BIP32 parent private key = require(the parent public key, and a derived, non-hardened child private key', () => { - function recoverParent (master, child) { - assert(!master.keyPair.d, 'You already have the parent private key') - assert(child.keyPair.d, 'Missing child private key') - - const curve = ecurve.getCurveByName('secp256k1') - const QP = master.keyPair.Q - const serQP = master.keyPair.getPublicKeyBuffer() - - const d1 = child.keyPair.d - let d2 - const data = Buffer.alloc(37) - serQP.copy(data, 0) - - // search index space until we find it - for (let i = 0; i < HIGHEST_BIT; ++i) { - data.writeUInt32BE(i, 33) - - // calculate I - const I = crypto.createHmac('sha512', master.chainCode).update(data).digest() - const IL = I.slice(0, 32) - const pIL = bigi.fromBuffer(IL) - - // See hdnode.js:273 to understand - d2 = d1.subtract(pIL).mod(curve.n) - - const Qp = new ECPair(d2).Q - if (Qp.equals(QP)) break - } - - let node = new HDNode(new ECPair(d2), master.chainCode, master.network) - node.depth = master.depth - node.index = master.index - node.masterFingerprint = master.masterFingerprint - return node - } - - const seed = crypto.randomBytes(32) - const master = HDNode.fromSeedBuffer(seed) - const child = master.derive(6) // m/6 - - // now for the recovery - const neuteredMaster = master.neutered() - const recovered = recoverParent(neuteredMaster, child) - expect(recovered.toBase58()).toBe(master.toBase58()) - }) -}) diff --git a/packages/crypto/__tests__/crypto/message.test.js b/packages/crypto/__tests__/crypto/message.test.js new file mode 100644 index 0000000000..75f154107a --- /dev/null +++ b/packages/crypto/__tests__/crypto/message.test.js @@ -0,0 +1,64 @@ +const Message = require('../../lib/crypto/message') +const { crypto } = require('../../lib/crypto') + +const passphrase = 'sample passphrase' +const wif = crypto.keysToWIF(crypto.getKeys(passphrase), { wif: 170 }) +const signedMessageEntries = [ + [ + 'publicKey', + '03bb51bbf5bf84759452e33dd97cf72cc8904be07df07a946a0d84939400f17e87', + ], + [ + 'signature', + '304402204550cd28d369a7f6eccd399b315e42e054a2f21f6771983af4ed3c5f7c7fa83102200699fef72cc64e79ccba85a31666e9508c052038c71c04260264e3d2d11c7e08', + ], + ['message', 'test'], +] + +describe('Message', () => { + describe('sign', () => { + it('should be a function', () => { + expect(Message.sign).toBeFunction() + }) + + it('should sign a message', () => { + expect(Message.sign('test', passphrase)).toContainAllEntries( + signedMessageEntries, + ) + }) + }) + + describe('signWithWif', () => { + it('should be a function', () => { + expect(Message.signWithWif).toBeFunction() + }) + + it('should sign a message', () => { + expect(Message.signWithWif('test', wif)).toContainAllEntries( + signedMessageEntries, + ) + }) + + it('should sign a message and match passphrase', () => { + const signedMessage = Message.sign('test', passphrase) + const signedWifMessage = Message.signWithWif('test', wif) + expect(signedMessage).toEqual(signedWifMessage) + }) + }) + + describe('verify', () => { + it('should be a function', () => { + expect(Message.verify).toBeFunction() + }) + + it('should verify a signed message', () => { + const signedMessage = Message.sign('test', passphrase) + expect(Message.verify(signedMessage)).toBe(true) + }) + + it('should verify a signed wif message', () => { + const signedMessage = Message.signWithWif('test', wif) + expect(Message.verify(signedMessage)).toBe(true) + }) + }) +}) diff --git a/packages/crypto/__tests__/crypto/slots.test.js b/packages/crypto/__tests__/crypto/slots.test.js index c0da99f93c..5fdc725472 100644 --- a/packages/crypto/__tests__/crypto/slots.test.js +++ b/packages/crypto/__tests__/crypto/slots.test.js @@ -5,6 +5,44 @@ const slots = require('../../lib/crypto/slots') beforeEach(() => configManager.setConfig(network)) describe('Slots', () => { + describe('getHeight', () => { + it('should be a function', () => { + expect(slots.getHeight).toBeFunction() + }) + + it('should return the set height', () => { + expect(slots.getHeight()).toBe(1) + }) + }) + + describe('setHeight', () => { + it('should be a function', () => { + expect(slots.setHeight).toBeFunction() + }) + + it('should set the height', () => { + slots.setHeight(123) + + expect(slots.getHeight()).toBe(123) + }) + }) + + describe('resetHeight', () => { + it('should be a function', () => { + expect(slots.resetHeight).toBeFunction() + }) + + it('should reset the height', () => { + slots.setHeight(123) + + expect(slots.getHeight()).toBe(123) + + slots.resetHeight() + + expect(slots.getHeight()).toBe(1) + }) + }) + describe('getEpochTime', () => { it('should be a function', () => { expect(slots.getEpochTime).toBeFunction() @@ -21,10 +59,12 @@ describe('Slots', () => { }) it('return epoch datetime', () => { - expect(slots.beginEpochTime().format()).toBe('2017-03-21T13:00:00Z') + expect(slots.beginEpochTime().toISOString()).toBe( + '2017-03-21T13:00:00.000Z', + ) }) - it('return epoch datetime', () => { + it('return epoch unix', () => { expect(slots.beginEpochTime().unix()).toBe(1490101200) }) }) diff --git a/packages/crypto/__tests__/handlers/transactions/__fixtures__/transaction.js b/packages/crypto/__tests__/handlers/transactions/__fixtures__/transaction.js index afd138e6a8..f50d134948 100644 --- a/packages/crypto/__tests__/handlers/transactions/__fixtures__/transaction.js +++ b/packages/crypto/__tests__/handlers/transactions/__fixtures__/transaction.js @@ -1,14 +1,18 @@ +const Bignum = require('../../../../lib/utils/bignum') + module.exports = { version: 1, id: '943c220691e711c39c79d437ce185748a0018940e1a4144293af9d05627d2eb4', blockid: '11233167632577333611', type: 0, timestamp: 36482198, - amount: 100000000, - fee: 10000000, + amount: new Bignum(100000000), + fee: new Bignum(10000000), senderId: 'DTRdbaUW3RQQSL5By4G43JVaeHiqfVp9oh', recipientId: 'DTRdbaUW3RQQSL5By4G43JVaeHiqfVp9oh', - senderPublicKey: '034da006f958beba78ec54443df4a3f52237253f7ae8cbdb17dccf3feaa57f3126', - signature: '304402205881204c6e515965098099b0e20a7bf104cd1bad6cfe8efd1641729fcbfdbf1502203cfa3bd9efb2ad250e2709aaf719ac0db04cb85d27a96bc8149aeaab224de82b', // eslint-disable-line max-len - asset: {} + senderPublicKey: + '034da006f958beba78ec54443df4a3f52237253f7ae8cbdb17dccf3feaa57f3126', + signature: + '304402205881204c6e515965098099b0e20a7bf104cd1bad6cfe8efd1641729fcbfdbf1502203cfa3bd9efb2ad250e2709aaf719ac0db04cb85d27a96bc8149aeaab224de82b', // eslint-disable-line max-len + asset: {}, } diff --git a/packages/crypto/__tests__/handlers/transactions/__fixtures__/wallet.js b/packages/crypto/__tests__/handlers/transactions/__fixtures__/wallet.js index 791b9e7431..07dc131a74 100644 --- a/packages/crypto/__tests__/handlers/transactions/__fixtures__/wallet.js +++ b/packages/crypto/__tests__/handlers/transactions/__fixtures__/wallet.js @@ -1,5 +1,8 @@ +const Bignum = require('../../../../lib/utils/bignum') + module.exports = { address: 'DTRdbaUW3RQQSL5By4G43JVaeHiqfVp9oh', - balance: 4527654310, - publicKey: '034da006f958beba78ec54443df4a3f52237253f7ae8cbdb17dccf3feaa57f3126' + balance: new Bignum(4527654310), + publicKey: + '034da006f958beba78ec54443df4a3f52237253f7ae8cbdb17dccf3feaa57f3126', } diff --git a/packages/crypto/__tests__/handlers/transactions/delegate-registration.test.js b/packages/crypto/__tests__/handlers/transactions/delegate-registration.test.js index 74be3e2f98..2323a82c49 100644 --- a/packages/crypto/__tests__/handlers/transactions/delegate-registration.test.js +++ b/packages/crypto/__tests__/handlers/transactions/delegate-registration.test.js @@ -1,3 +1,4 @@ +const Bignum = require('../../../lib/utils/bignum') const handler = require('../../../lib/handlers/transactions/delegate-registration') let wallet @@ -12,18 +13,20 @@ beforeEach(() => { blockid: '11233167632577333611', type: 2, timestamp: 36482198, - amount: 0, - fee: 10000000, + amount: Bignum.ZERO, + fee: new Bignum(10000000), senderId: 'DTRdbaUW3RQQSL5By4G43JVaeHiqfVp9oh', recipientId: 'DTRdbaUW3RQQSL5By4G43JVaeHiqfVp9oh', - senderPublicKey: '034da006f958beba78ec54443df4a3f52237253f7ae8cbdb17dccf3feaa57f3126', - signature: '304402205881204c6e515965098099b0e20a7bf104cd1bad6cfe8efd1641729fcbfdbf1502203cfa3bd9efb2ad250e2709aaf719ac0db04cb85d27a96bc8149aeaab224de82b', // eslint-disable-line max-len + senderPublicKey: + '034da006f958beba78ec54443df4a3f52237253f7ae8cbdb17dccf3feaa57f3126', + signature: + '304402205881204c6e515965098099b0e20a7bf104cd1bad6cfe8efd1641729fcbfdbf1502203cfa3bd9efb2ad250e2709aaf719ac0db04cb85d27a96bc8149aeaab224de82b', // eslint-disable-line max-len asset: { delegate: { username: 'dummy', - publicKey: 'a'.repeat(66) - } - } + publicKey: 'a'.repeat(66), + }, + }, } }) @@ -37,14 +40,16 @@ describe('DelegateRegistrationHandler', () => { expect(handler.canApply).toBeFunction() }) - it('should be ok', () => { - expect(handler.canApply(wallet, transaction)).toBeTruthy() + it('should be true', () => { + expect(handler.canApply(wallet, transaction, [])).toBeTrue() }) - it('should not be ok', () => { + it('should be false if wallet already registered a username', () => { wallet.username = 'dummy' + const errors = [] - expect(handler.canApply(wallet, transaction)).toBeFalsy() + expect(handler.canApply(wallet, transaction, errors)).toBeFalse() + expect(errors).toContain('Wallet already has a registered username') }) }) @@ -53,7 +58,7 @@ describe('DelegateRegistrationHandler', () => { expect(handler.apply).toBeFunction() }) - it('should be ok', () => { + it('should set username', () => { handler.apply(wallet, transaction) expect(wallet.username).toBe('dummy') @@ -65,7 +70,7 @@ describe('DelegateRegistrationHandler', () => { expect(handler.revert).toBeFunction() }) - it('should be ok', () => { + it('should unset username', () => { handler.revert(wallet, transaction) expect(wallet.username).toBeNull() diff --git a/packages/crypto/__tests__/handlers/transactions/delegate-resignation.test.js b/packages/crypto/__tests__/handlers/transactions/delegate-resignation.test.js index f78939934f..80728652fb 100644 --- a/packages/crypto/__tests__/handlers/transactions/delegate-resignation.test.js +++ b/packages/crypto/__tests__/handlers/transactions/delegate-resignation.test.js @@ -18,16 +18,18 @@ describe('DelegateResignationHandler', () => { expect(handler.canApply).toBeFunction() }) - it('should be ok', () => { + it('should be truth', () => { wallet.username = 'dummy' - expect(handler.canApply(wallet, transaction)).toBeTruthy() + expect(handler.canApply(wallet, transaction, [])).toBeTrue() }) - it('should not be ok', () => { + it('should be false if wallet has no registered username', () => { wallet.username = null + const errors = [] - expect(handler.canApply(wallet, transaction)).toBeFalsy() + expect(handler.canApply(wallet, transaction, errors)).toBeFalse() + expect(errors).toContain('Wallet has not registered a username') }) }) diff --git a/packages/crypto/__tests__/handlers/transactions/handler.test.js b/packages/crypto/__tests__/handlers/transactions/handler.test.js index 497c00edef..fabe3274e1 100644 --- a/packages/crypto/__tests__/handlers/transactions/handler.test.js +++ b/packages/crypto/__tests__/handlers/transactions/handler.test.js @@ -1,5 +1,6 @@ const BaseHandler = require('../../../lib/handlers/transactions/handler') const { ARKTOSHI } = require('../../../lib/constants') +const Bignum = require('../../../lib/utils/bignum') let handler let wallet @@ -10,8 +11,9 @@ beforeEach(() => { wallet = { address: 'DTRdbaUW3RQQSL5By4G43JVaeHiqfVp9oh', - balance: 4527654310, - publicKey: '034da006f958beba78ec54443df4a3f52237253f7ae8cbdb17dccf3feaa57f3126' + balance: new Bignum(4527654310), + publicKey: + '034da006f958beba78ec54443df4a3f52237253f7ae8cbdb17dccf3feaa57f3126', } transaction = { @@ -20,13 +22,15 @@ beforeEach(() => { blockid: '11233167632577333611', type: 0, timestamp: 36482198, - amount: 100000000, - fee: 10000000, + amount: new Bignum(100000000), + fee: new Bignum(10000000), senderId: 'DTRdbaUW3RQQSL5By4G43JVaeHiqfVp9oh', recipientId: 'DTRdbaUW3RQQSL5By4G43JVaeHiqfVp9oh', - senderPublicKey: '034da006f958beba78ec54443df4a3f52237253f7ae8cbdb17dccf3feaa57f3126', - signature: '304402205881204c6e515965098099b0e20a7bf104cd1bad6cfe8efd1641729fcbfdbf1502203cfa3bd9efb2ad250e2709aaf719ac0db04cb85d27a96bc8149aeaab224de82b', // eslint-disable-line max-len - asset: {} + senderPublicKey: + '034da006f958beba78ec54443df4a3f52237253f7ae8cbdb17dccf3feaa57f3126', + signature: + '304402205881204c6e515965098099b0e20a7bf104cd1bad6cfe8efd1641729fcbfdbf1502203cfa3bd9efb2ad250e2709aaf719ac0db04cb85d27a96bc8149aeaab224de82b', // eslint-disable-line max-len + asset: {}, } }) @@ -40,14 +44,28 @@ describe('Handler', () => { expect(handler.canApply).toBeFunction() }) - it('should be truthy', () => { - expect(handler.canApply(wallet, transaction)).toBeTruthy() + it('should be true', () => { + const errors = [] + expect(handler.canApply(wallet, transaction, errors)).toBeTrue() + expect(errors).toHaveLength(0) }) - it('should be falsy', () => { - transaction.senderPublicKey = 'p'.repeat(66) + it('should be false if wallet publicKey does not match tx senderPublicKey', () => { + transaction.senderPublicKey = 'a'.repeat(66) + const errors = [] + const result = handler.canApply(wallet, transaction, errors) - expect(handler.canApply(wallet, transaction)).toBeFalsy() + expect(result).toBeFalse() + expect(errors).toContain( + 'wallet "publicKey" does not match transaction "senderPublicKey"', + ) + }) + + it('should be true even with publicKey case mismatch', () => { + transaction.senderPublicKey = transaction.senderPublicKey.toUpperCase() + wallet.publicKey = wallet.publicKey.toLowerCase() + + expect(handler.canApply(wallet, transaction, [])).toBeTrue() }) }) @@ -60,24 +78,45 @@ describe('Handler', () => { handler.apply = jest.fn() const initialBalance = 1000 * ARKTOSHI - wallet.balance = initialBalance + wallet.balance = new Bignum(initialBalance) handler.applyTransactionToSender(wallet, transaction) - expect(wallet.balance).toBe(initialBalance - (transaction.amount + transaction.fee)) + expect(wallet.balance).toEqual( + new Bignum(initialBalance) + .minus(transaction.amount) + .minus(transaction.fee), + ) }) it('should not be ok', () => { handler.apply = jest.fn() - transaction.senderPublicKey = 'p'.repeat(66) + transaction.senderPublicKey = 'a'.repeat(66) const initialBalance = 1000 * ARKTOSHI - wallet.balance = initialBalance + wallet.balance = new Bignum(initialBalance) handler.applyTransactionToSender(wallet, transaction) - expect(wallet.balance).toBe(initialBalance) + expect(wallet.balance).toEqual(new Bignum(initialBalance)) + }) + + it('should not fail due to case mismatch', () => { + handler.apply = jest.fn() + + const initialBalance = 1000 * ARKTOSHI + wallet.balance = new Bignum(initialBalance) + transaction.senderPublicKey = transaction.senderPublicKey.toUpperCase() + wallet.publicKey = wallet.publicKey.toLowerCase() + + handler.applyTransactionToSender(wallet, transaction) + + expect(wallet.balance).toEqual( + new Bignum(initialBalance) + .minus(transaction.amount) + .minus(transaction.fee), + ) }) }) @@ -90,24 +129,45 @@ describe('Handler', () => { handler.revert = jest.fn() const initialBalance = 1000 * ARKTOSHI - wallet.balance = initialBalance + wallet.balance = new Bignum(initialBalance) handler.revertTransactionForSender(wallet, transaction) - expect(wallet.balance).toBe(initialBalance + (transaction.amount + transaction.fee)) + expect(wallet.balance).toEqual( + new Bignum(initialBalance) + .plus(transaction.amount) + .plus(transaction.fee), + ) }) it('should not be ok', () => { handler.revert = jest.fn() - transaction.senderPublicKey = 'p'.repeat(66) + transaction.senderPublicKey = 'a'.repeat(66) + + const initialBalance = 1000 * ARKTOSHI + wallet.balance = new Bignum(initialBalance) + + handler.revertTransactionForSender(wallet, transaction) + + expect(wallet.balance).toEqual(new Bignum(initialBalance)) + }) + + it('should not fail due to case mismatch', () => { + handler.revert = jest.fn() const initialBalance = 1000 * ARKTOSHI - wallet.balance = initialBalance + wallet.balance = new Bignum(initialBalance) + transaction.senderPublicKey = transaction.senderPublicKey.toUpperCase() + wallet.publicKey = wallet.publicKey.toLowerCase() handler.revertTransactionForSender(wallet, transaction) - expect(wallet.balance).toBe(initialBalance) + expect(wallet.balance).toEqual( + new Bignum(initialBalance) + .plus(transaction.amount) + .plus(transaction.fee), + ) }) }) @@ -118,22 +178,24 @@ describe('Handler', () => { it('should be ok', () => { const initialBalance = 1000 * ARKTOSHI - wallet.balance = initialBalance + wallet.balance = new Bignum(initialBalance) handler.applyTransactionToRecipient(wallet, transaction) - expect(wallet.balance).toBe(initialBalance + transaction.amount) + expect(wallet.balance).toEqual( + new Bignum(initialBalance).plus(transaction.amount), + ) }) it('should not be ok', () => { transaction.recipientId = 'invalid-recipientId' const initialBalance = 1000 * ARKTOSHI - wallet.balance = initialBalance + wallet.balance = new Bignum(initialBalance) handler.applyTransactionToRecipient(wallet, transaction) - expect(wallet.balance).toBe(initialBalance) + expect(wallet.balance).toEqual(new Bignum(initialBalance)) }) }) @@ -144,22 +206,24 @@ describe('Handler', () => { it('should be ok', () => { const initialBalance = 1000 * ARKTOSHI - wallet.balance = initialBalance + wallet.balance = new Bignum(initialBalance) handler.revertTransactionForRecipient(wallet, transaction) - expect(wallet.balance).toBe(initialBalance - transaction.amount) + expect(wallet.balance).toEqual( + new Bignum(initialBalance - transaction.amount), + ) }) it('should not be ok', () => { transaction.recipientId = 'invalid-recipientId' const initialBalance = 1000 * ARKTOSHI - wallet.balance = initialBalance + wallet.balance = new Bignum(initialBalance) handler.revertTransactionForRecipient(wallet, transaction) - expect(wallet.balance).toBe(initialBalance) + expect(wallet.balance).toEqual(new Bignum(initialBalance)) }) }) }) diff --git a/packages/crypto/__tests__/handlers/transactions/ipfs.test.js b/packages/crypto/__tests__/handlers/transactions/ipfs.test.js index 4ad6f8081d..96db5ff75b 100644 --- a/packages/crypto/__tests__/handlers/transactions/ipfs.test.js +++ b/packages/crypto/__tests__/handlers/transactions/ipfs.test.js @@ -18,14 +18,14 @@ describe('IpfsHandler', () => { expect(handler.canApply).toBeFunction() }) - it('should be ok', () => { - expect(handler.canApply(wallet, transaction)).toBeTruthy() + it('should be true', () => { + expect(handler.canApply(wallet, transaction, [])).toBeTrue() }) - it('should not be ok', () => { - transaction.senderPublicKey = 'p'.repeat(66) + it('should be false', () => { + transaction.senderPublicKey = 'a'.repeat(66) - expect(handler.canApply(wallet, transaction)).toBeFalsy() + expect(handler.canApply(wallet, transaction, [])).toBeFalse() }) }) diff --git a/packages/crypto/__tests__/handlers/transactions/multi-payment.test.js b/packages/crypto/__tests__/handlers/transactions/multi-payment.test.js index c25f902671..9d05491225 100644 --- a/packages/crypto/__tests__/handlers/transactions/multi-payment.test.js +++ b/packages/crypto/__tests__/handlers/transactions/multi-payment.test.js @@ -1,6 +1,6 @@ /* eslint-disable */ -const sumBy = require('lodash/sumBy') +const Bignum = require('../../../lib/utils/bignum') const handler = require('../../../lib/handlers/transactions/multi-payment') let wallet @@ -15,25 +15,33 @@ beforeEach(() => { blockid: '11233167632577333611', type: 7, timestamp: 36482198, - amount: 100000000, - fee: 10000000, + amount: new Bignum(100000000), + fee: new Bignum(10000000), senderId: 'DTRdbaUW3RQQSL5By4G43JVaeHiqfVp9oh', recipientId: 'DTRdbaUW3RQQSL5By4G43JVaeHiqfVp9oh', - senderPublicKey: '034da006f958beba78ec54443df4a3f52237253f7ae8cbdb17dccf3feaa57f3126', - signature: '304402205881204c6e515965098099b0e20a7bf104cd1bad6cfe8efd1641729fcbfdbf1502203cfa3bd9efb2ad250e2709aaf719ac0db04cb85d27a96bc8149aeaab224de82b', // eslint-disable-line max-len + senderPublicKey: + '034da006f958beba78ec54443df4a3f52237253f7ae8cbdb17dccf3feaa57f3126', + signature: + '304402205881204c6e515965098099b0e20a7bf104cd1bad6cfe8efd1641729fcbfdbf1502203cfa3bd9efb2ad250e2709aaf719ac0db04cb85d27a96bc8149aeaab224de82b', // eslint-disable-line max-len asset: { - payments: [{ - amount: 10 - }, { - amount: 20 - }, { - amount: 30 - }, { - amount: 40 - }, { - amount: 50 - }] - } + payments: [ + { + amount: new Bignum(10), + }, + { + amount: new Bignum(20), + }, + { + amount: new Bignum(30), + }, + { + amount: new Bignum(40), + }, + { + amount: new Bignum(50), + }, + ], + }, } }) @@ -47,18 +55,25 @@ describe('MultiPaymentHandler', () => { expect(handler.canApply).toBeFunction() }) - it('should be ok', () => { - const amount = sumBy(transaction.asset.payments, 'amount') + it('should be true', () => { + const amount = transaction.asset.payments.reduce( + (a, p) => a.plus(p.amount), + Bignum.ZERO, + ) - expect(handler.canApply(wallet, transaction)).toBeTruthy() + expect(handler.canApply(wallet, transaction, [])).toBeTrue() }) - it('should not be ok', () => { - const amount = sumBy(transaction.asset.payments, 'amount') + it('should be false if wallet has insufficient balance', () => { + const amount = transaction.asset.payments.reduce( + (a, p) => a.plus(p.amount), + Bignum.ZERO, + ) + wallet.balance = Bignum.ZERO + const errors = [] - wallet.balance = 0 - - expect(handler.canApply(wallet, transaction)).toBeFalsy() + expect(handler.canApply(wallet, transaction, errors)).toBeFalse() + expect(errors).toContain('Insufficient balance in the wallet') }) }) diff --git a/packages/crypto/__tests__/handlers/transactions/multi-signature.test.js b/packages/crypto/__tests__/handlers/transactions/multi-signature.test.js index 2fe105413f..d36199198b 100644 --- a/packages/crypto/__tests__/handlers/transactions/multi-signature.test.js +++ b/packages/crypto/__tests__/handlers/transactions/multi-signature.test.js @@ -1,93 +1,97 @@ +const Bignum = require('../../../lib/utils/bignum') const handler = require('../../../lib/handlers/transactions/multi-signature') const WalletModel = require('../../../lib/models/wallet') let wallet let transaction - -const multisignatureTest = { - min: 15, - lifetime: 72, - keysgroup: [ - '034a7aca6841cfbdc688f09d55345f21c7ffbd1844693fa68d607fc94f729cbbea', - '02fd6743ddfdc7c5bac24145e449c2e4f2d569b5297dd7bf088c3bc219f582a2f0', - '02f9c51812f4be127b9f1f21cb4e146eca6aecc85739a243db0f1064981deda216', - '0214d60ca95cd87a097ed6e6e42281acb68ae1815c8f494b8ff18d24dc9e072171', - '02a14634e04e80b05acd56bc361af98498d76fbf5233f8d62773ceaa07172ddaa6', - '021a9ba0e72f02b8fa7bad386582ec1d6c05b7664c892bf2a86035a85350f37203', - '02e3ba373c6c352316b748e75358ead36504b0ef5139d215fb6a83a330c4eb60d5', - '0309039bfa18d6fd790edb79438783b27fbcab06040a2fdaa66fb81ad53ca8db5f', - '0393d12aff5962fa9065487959719a81c5d991e7c48a823039acd9254c2b673841', - '03d3265264f06fe1dd752798403a73e537eb461fc729c83a84b579e8434adfe7c4', - '02acfa496a6c12cb9acc3219993b17c62d19f4b570996c12a37d6e89eaa9716859', - '03136f2101f1767b0d63d9545410bcaf3a941b2b6f06851093f3c679e0d31ca1cd', - '02e6ec3941be86177bf0b998589c07da1b73e990466fdaee347c972c10f61b3797', - '037dcd05d921a9f2ddd11960fec2ea9904fc55cad030549a6c5f5a41b2e35e56d2', - '03206f7ae26f14cffb62b8c28b5e632952cdeb84b7c74ac0c2198b08bd84ee4f23' - ] -} +let multisignatureTest beforeEach(() => { wallet = new WalletModel('D61xc3yoBQDitwjqUspMPx1ooET6r1XLt7') - wallet.balance = 100390000000 - wallet.publicKey = '02337316a26d8d49ec27059bd0589c49ba474029c3627715380f4df83fb431aece' - wallet.secondPublicKey = '020d3c837d0a47ee7de1082cd48885003c5e92964e58bb34af3b58c6e42208ae03' + wallet.balance = new Bignum(100390000000) + wallet.publicKey = + '026f717e50bf3dbb9d8593996df5435ba22217410fc7a132f3d2c942a01a00a202' + wallet.secondPublicKey = + '0380728436880a0a11eadf608c4d4e7f793719e044ee5151074a5f2d5d43cb9066' wallet.multisignature = multisignatureTest transaction = { version: 1, - id: '95199581d640eda97ea810fc3248e34f6e5ab1d8c9802e64a50b930f4ff044ab', - blockid: '9156936215323004070', + id: 'e22ddd7385b42c00f79b9c6ecd253333ddef6e0bf955341ace2e63dad1f4bd70', type: 4, - timestamp: 25921690, - amount: 0, - fee: 9000000000, - vendorField: 'wl8lwts8je', - senderId: 'D61xc3yoBQDitwjqUspMPx1ooET6r1XLt7', - recipientId: 'D61xc3yoBQDitwjqUspMPx1ooET6r1XLt7', - senderPublicKey: '02337316a26d8d49ec27059bd0589c49ba474029c3627715380f4df83fb431aece', - signature: '3045022100c59d8efdd95010b0368963e492e8f7da1a3f6993b0723724f84aeccf658ea9a30220103d2b4ac07ad808b4ea79829a0081992586c6ef73892cfa7510ab37f0093bcd', // eslint-disable-line max-len - signSignature: '3044022059ab88d3fe83d6b52ddd5e863696416168f9cac6de962368587ad7343542f99f02207a95ca473006ab57dee6b06e06f8fa8f1b260548b9226614a0e1f760cc910479', // eslint-disable-line max-len + timestamp: 48059808, + amount: Bignum.ZERO, + fee: new Bignum(8000000000), + recipientId: 'DGN48KSVFx88chiSu7JbqkAXstqtM1uLJQ', + senderPublicKey: + '026f717e50bf3dbb9d8593996df5435ba22217410fc7a132f3d2c942a01a00a202', + signature: + '30450221008baddfae37be66d725e22d9e93c10334d859558f2aef38762803178dbb39354f022025a9bdc7fc4c86d3f67cd1d012dbee3d5691ab3188b5457fdeae82fdd5995767', // eslint-disable-line max-len + signSignature: + '3045022100eb9844a235309309f805235ec40336260cc3dc2c3cbb4cb687dd55b32d8f405402202a98ca5b3b2ad31cec0ed01d9c085a828dd5c07c3893858d4c127fce57d6d410', // eslint-disable-line max-len signatures: [ - '3045022100e9d0015e6e50e4852ad057ae6f83d0bf3e28fd722d1acf58f1a069a8f5043cf002201ee5b35b7f61af853802020fecf629ab59309c09d7e002b20636bdbb26ea92e3', // eslint-disable-line max-len - '3044022042c796e7f447462e60dfeeb8233d5fde3026e9c0aeda4544ae47995694d815a802204a183ae7d885fd875f6795d047364a73802c0d967d32cd797ee765ac10715f2d', // eslint-disable-line max-len - '30450221008a000e62a63298f401c616ae7222df9c187c92906736c0f879ba1162647e25c00220612cf87641075334b37f6e19590fcb45f9941aa50092fd429eda375caf5b8144', // eslint-disable-line max-len - '3045022100bd5ee0064df149406c7b4a64116c913181d7527a078972591280305b14686232022039e7437629b935ac39e2f547cbf191ffad4ab83805a360f50b49176dd5d604cc', // eslint-disable-line max-len - '30440220133a8dde6d87bcc8f627a57e7a1ad8a1f441d77246dee9d9d999851b4aeecbf102205c93de5881e6fd8ce808552b2ee91c6e144a734a9ef8640e0ca055904d5e5bd1', // eslint-disable-line max-len - '3045022100bb9de3351337532b42598a4bccba2f07a5a1dbbb23859094dd90eafa409c7bf3022071ff0989dc6f9c95b95784d3aa3386940a46372d3fb50b7f4e9d6372b0d3b73d', // eslint-disable-line max-len - '3044022075e2e0137f1567b7efeac40faf5b8d55ef32540c7d3931c27ae45748241a118e02203cbf5c251eec1e2c033b556315069bcc4f04960bfc705db6288530de28211fc9', // eslint-disable-line max-len - '30440220259d5ed227ec1cd6275f6e7c6dd299f73500f8b4aa21025296c87419e91e5900022045a70031c442c336f2b280a94e7058976c7f8ae6617fd4fbf41b913ac608c54a', // eslint-disable-line max-len - '3045022100f8537736fb7e25e9ccb4e5d6f3cf7f053d45dc7ff7d41914e4ab9f7b48b9347502204a46de5fd0cc03e2e1a559bc5ffc25a1fce5dc05d5f6f1794a0f3b9f38ebe406', // eslint-disable-line max-len - '3045022100d361e24290fddf2ad194c9a29200d88ccae83afc0f930e5fd5b2ecefcd2cebf3022065049135ced0fe238270511a748ba82be72f6298e2895d8b20680698bbc03ef5', // eslint-disable-line max-len - '30440220556b517965101ef1e0cf59eead99b802b053ac4a631111348d961df29952f2150220630ca079a5647d7d1f22b6f253d58b1f7fb128be9aeb33c9c1fdf53948e52db4', // eslint-disable-line max-len - '3044022047838187fcd1c79059ab53769678940e634400cf7431337a7e27e30bc17ac39702200d2cb974f44239b0edbb7c10096d5d7b682d0788dc3f8d0f5061373f4eefdff8', // eslint-disable-line max-len - '3044022057bbd8432154bf72244f987c5b4c49ba094a0e4abffc3644ba91c5ce1b79712a0220708a2743d4b4ab1d9379bcd60acf70b63e16cd24b95cd142a0b3ced0d43e6cb8', // eslint-disable-line max-len - '304502210097e1a36e47422455f030fa5f79153a4c49d25a2fb487837462b7f9d0fa3bd436022008a212ce0dfa18543987a1381b1261652d76e49f923e0b2ac79073b22367b3a5', // eslint-disable-line max-len - '304402201cbe68b0383c243cf61a9af9a42746688b85f6ee106815906d9d8c4d717837aa022038c1eb4e06b90e24b44903de18c3f260e8be945b84126c9a048794f830b9f272' // eslint-disable-line max-len + '3045022100f073a3f59ed753f98734462dbe7c9082bb7cb9d46348c671708c93df2fdd2a7602206dc19039d3561f8d1226755dd3b0ca25f359347729eff066eaf3cc3b5c18bc59', + '3045022100c560d6d8504b6761245f7bb3e3b723380b50c380ae30c9544c781f3a9b1359a702206b50506ba6c0a39bed7bec226b55bf9ece979716eb95e2a757f025d3592fde17', + '30440220344345bcb9754ab242dc27bd3d705e5213597914183818005ff1f2e91466f17a0220474c27d05cd5f121c3cad0295e6fc9f8a8cdfa03647e70eb3783e4c1139dde04', + '3045022100998e29255a8f1c140aa41d93ec43271fd8d0e5b9c18df366e3c7b59cc0c293d902205292dd36e9db18f072f00559267361b9426ab26bff2ee613ec0c3627317b4dab', + '3044022007379b5643032d9e9d3395298776be041b2a85a211be2d7b6a5855cf030ae0ca02203c5d3da458034483fdef9f43ee4db4428999cfeb8893795f695e663407238090', + '3044022060461195aeb4386dfab1e3618cdec48f4b988ea394461962379cdbfe8f17b7110220415522adf0239bff7e44e6c0cc8d57211d9d9fe745a6ba2911a81586d5dfc5dc', + '3044022057355ab8ad9502745895a649aede98dfe829c46465eda57438720baeaa6ece5c02200ed3c2eb019579b243380ac066d691f6f27012dc6b93a1403e1a49c992cc0812', + '3044022010cf1079e46cbac198e49f763795095c3a1f33b772cf3e6f335c313f786eb0570220450a110a813cc5453265f0e97850794b0f9d5c6efd6d9ea08009df3d4b9f2299', + '3044022000f35223b23f03413f17538b157e62388c0b150fc046fdcc35792a48d694499402205c2e494ca74565e7841cd6034228cd3d9b57bb832f0da5834991bf92b415c0b8', + '304402206b69cbd52335fca4a510fa1dcb1417617ad1128aa06dcf543d1f11890e46fdef022012d3054adc0a924429d34091910bf82c0abc757f39cfc0887c7e4d9b35f21ad6', + '30440220490bf3e963aa500404e5d559dc06bb1ce176ddbab92f46add87c17c19c3781c90220775f0a3f65d95e3e268eb1f2f2fc86044995e7ebdd1f51f99a973fd00c952d57', + '30450221008795d2e1a454c2cbda92d5fcb7e539372cefbe9f8a181d658abcbd2ba18da8e702207b395488d31f037dc158c12799885edb94f36b1437b2bda79d9074c9a82aa686', + '3045022100cf706e93a9984a958dba6e17287d17febae005d277afc77890e0a3912ee7ed3d02206618718ee68cae209c42a801b7b295fa2564878838712a1b22beaa3637b57c58', + '30440220743aba2fdb663dda73b64ada17812a98adf26f2419c6ab2cfba8f66666527a91022036ade1b37b72079eb43b51a8fe5e31da2e42f7b6d0b437f8a693cc276b9123b8', + '304402206902fc8f519670a7768ad13f1b2d69373aa14c89b70020f83273d6bb0cfd89d102207de30b9ac0c17ff11e364b72c41f1cd8d4e6dccbe28399cb78e96eea32deef12', ], asset: { multisignature: { min: 15, lifetime: 72, keysgroup: [ - '+034a7aca6841cfbdc688f09d55345f21c7ffbd1844693fa68d607fc94f729cbbea', - '+02fd6743ddfdc7c5bac24145e449c2e4f2d569b5297dd7bf088c3bc219f582a2f0', - '+02f9c51812f4be127b9f1f21cb4e146eca6aecc85739a243db0f1064981deda216', - '+0214d60ca95cd87a097ed6e6e42281acb68ae1815c8f494b8ff18d24dc9e072171', - '+02a14634e04e80b05acd56bc361af98498d76fbf5233f8d62773ceaa07172ddaa6', - '+021a9ba0e72f02b8fa7bad386582ec1d6c05b7664c892bf2a86035a85350f37203', - '+02e3ba373c6c352316b748e75358ead36504b0ef5139d215fb6a83a330c4eb60d5', - '+0309039bfa18d6fd790edb79438783b27fbcab06040a2fdaa66fb81ad53ca8db5f', - '+0393d12aff5962fa9065487959719a81c5d991e7c48a823039acd9254c2b673841', - '+03d3265264f06fe1dd752798403a73e537eb461fc729c83a84b579e8434adfe7c4', - '+02acfa496a6c12cb9acc3219993b17c62d19f4b570996c12a37d6e89eaa9716859', - '+03136f2101f1767b0d63d9545410bcaf3a941b2b6f06851093f3c679e0d31ca1cd', - '+02e6ec3941be86177bf0b998589c07da1b73e990466fdaee347c972c10f61b3797', - '+037dcd05d921a9f2ddd11960fec2ea9904fc55cad030549a6c5f5a41b2e35e56d2', - '+03206f7ae26f14cffb62b8c28b5e632952cdeb84b7c74ac0c2198b08bd84ee4f23' - ] - } + '+0217e9e2a1aca300a7011acaadf60af94252875568373546895f227c050d48aac5', + '+02b3b3233c171a122f88c1dbe44539dfefb36530ca3ec04163aef9f448a1823795', + '+03a3013f144160e1964b97e78117571e571a631f0042efcd0de309c7159c7886c8', + '+02fb475ef881b8f56e00407095a87319934c34467db11d3230e54d9328c6cddbe5', + '+03ab9cc2c5364f1676a94b2b5ff3fbc3705e8ce94c6e7e4712890905addf765a3f', + '+024be9e731a63f86b56e5f48dbdfb3443a0628c82ea308ee4c88d3fcbe3183eb9d', + '+0371b8fd17fb1f31095e8a1586bbe29e205904c9100de07c84090a423929a20dcf', + '+02cc09a7c5560db72e312f58a9f5ca4b60b5109efc5ce9dd58a116fa16516bb493', + '+02145fbe9309ebb1547eb332686efb4d8b6e2aaa1fe636663bf6ab1000e5cf72d3', + '+0274966781d4d23f8991530b33bdb051905cde809ae52e58e45cfd1bc8f6f70cc6', + '+0347288f8db9be069415c6c97fd4825867f4bd9b9f78557e8aa1244890beb85001', + '+035359097c405e90516be78104de0ca17001da2826397e0937b8b1e8e613fff352', + '+021aa343234514f8fdaf5e668bdc822a42805382567fa2ca9a5e06e92065f5658a', + '+033a28a0a9592952336918ddded08dd55503b82852fe67df1d358f07a575910844', + '+02747bec17b02cc09345c8c0dbeb09bff2db74d1c355135e10af0001eb1dc00265', + ], + }, }, - confirmations: 1091040 + confirmations: 1091040, + } + + multisignatureTest = { + min: 15, + lifetime: 72, + keysgroup: [ + '034a7aca6841cfbdc688f09d55345f21c7ffbd1844693fa68d607fc94f729cbbea', + '02fd6743ddfdc7c5bac24145e449c2e4f2d569b5297dd7bf088c3bc219f582a2f0', + '02f9c51812f4be127b9f1f21cb4e146eca6aecc85739a243db0f1064981deda216', + '0214d60ca95cd87a097ed6e6e42281acb68ae1815c8f494b8ff18d24dc9e072171', + '02a14634e04e80b05acd56bc361af98498d76fbf5233f8d62773ceaa07172ddaa6', + '021a9ba0e72f02b8fa7bad386582ec1d6c05b7664c892bf2a86035a85350f37203', + '02e3ba373c6c352316b748e75358ead36504b0ef5139d215fb6a83a330c4eb60d5', + '0309039bfa18d6fd790edb79438783b27fbcab06040a2fdaa66fb81ad53ca8db5f', + '0393d12aff5962fa9065487959719a81c5d991e7c48a823039acd9254c2b673841', + '03d3265264f06fe1dd752798403a73e537eb461fc729c83a84b579e8434adfe7c4', + '02acfa496a6c12cb9acc3219993b17c62d19f4b570996c12a37d6e89eaa9716859', + '03136f2101f1767b0d63d9545410bcaf3a941b2b6f06851093f3c679e0d31ca1cd', + '02e6ec3941be86177bf0b998589c07da1b73e990466fdaee347c972c10f61b3797', + '037dcd05d921a9f2ddd11960fec2ea9904fc55cad030549a6c5f5a41b2e35e56d2', + '03206f7ae26f14cffb62b8c28b5e632952cdeb84b7c74ac0c2198b08bd84ee4f23', + ], } }) @@ -101,16 +105,27 @@ describe('MultiSignatureHandler', () => { expect(handler.canApply).toBeFunction() }) - it('should be ok', () => { + it('should be true', () => { delete wallet.multisignature - expect(handler.canApply(wallet, transaction)).toBeTruthy() + expect(handler.canApply(wallet, transaction, [])).toBeTrue() + }) + + it('should be false if failure to verify signatures', () => { + wallet.multisignature = multisignatureTest + const errors = [] + + expect(handler.canApply(wallet, transaction, errors)).toBeFalse() + expect(errors).toContain('Failed to verify multi-signatures') }) - it('should not be ok', () => { + it('should be false if keyCount is less than minimum', () => { wallet.multisignature = multisignatureTest + wallet.multisignature.min = 20 + const errors = [] - expect(handler.canApply(wallet, transaction)).toBeFalsy() + expect(handler.canApply(wallet, transaction, errors)).toBeFalse() + expect(errors).toContain('Failed to verify multi-signatures') }) }) diff --git a/packages/crypto/__tests__/handlers/transactions/second-signature.test.js b/packages/crypto/__tests__/handlers/transactions/second-signature.test.js index 72bcbd2baa..c8e90a4ca9 100644 --- a/packages/crypto/__tests__/handlers/transactions/second-signature.test.js +++ b/packages/crypto/__tests__/handlers/transactions/second-signature.test.js @@ -1,3 +1,4 @@ +const Bignum = require('../../../lib/utils/bignum') const handler = require('../../../lib/handlers/transactions/second-signature') let wallet @@ -6,9 +7,11 @@ let transaction beforeEach(() => { wallet = { address: 'DQ7VAW7u171hwDW75R1BqfHbA9yiKRCBSh', - balance: '6453530000000', - publicKey: '0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0', - secondPublicKey: '03791c7d0229966ee41af0e5362f3bb2534ef8c706d7151fec70aead607227fce1' + balance: new Bignum('6453530000000'), + publicKey: + '0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0', + secondPublicKey: + '03791c7d0229966ee41af0e5362f3bb2534ef8c706d7151fec70aead607227fce1', } transaction = { @@ -17,16 +20,20 @@ beforeEach(() => { blockid: '18049953523739571613', type: 0, timestamp: 36350726, - amount: 5000000000, - fee: 10000000, + amount: new Bignum(5000000000), + fee: new Bignum(10000000), senderId: 'DQ7VAW7u171hwDW75R1BqfHbA9yiKRCBSh', recipientId: 'D92qxqLRYwTannfANNGFm138WTrhsq9RVi', - senderPublicKey: '0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0', - signature: '3044022071d48f273ac2181dc03cdd9326bb93bc8260966089b6548b32ba9bcb3cc0912302205b9dbc037c789576728ae7ab80f050c697c7aa00ad98d11086353c7d03f9f013', // eslint-disable-line max-len - signSignature: '3044022023791a170f5b44b9b11f7ca91af02519f241deb4b33e2bcda858df631e20e6d702200ced02b468543db5212ef9a53623fc87227125be4447c29c759c79100dc66544', // eslint-disable-line max-len - secondSignature: '3044022023791a170f5b44b9b11f7ca91af02519f241deb4b33e2bcda858df631e20e6d702200ced02b468543db5212ef9a53623fc87227125be4447c29c759c79100dc66544', // eslint-disable-line max-len + senderPublicKey: + '0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0', + signature: + '3044022071d48f273ac2181dc03cdd9326bb93bc8260966089b6548b32ba9bcb3cc0912302205b9dbc037c789576728ae7ab80f050c697c7aa00ad98d11086353c7d03f9f013', // eslint-disable-line max-len + signSignature: + '3044022023791a170f5b44b9b11f7ca91af02519f241deb4b33e2bcda858df631e20e6d702200ced02b468543db5212ef9a53623fc87227125be4447c29c759c79100dc66544', // eslint-disable-line max-len + secondSignature: + '3044022023791a170f5b44b9b11f7ca91af02519f241deb4b33e2bcda858df631e20e6d702200ced02b468543db5212ef9a53623fc87227125be4447c29c759c79100dc66544', // eslint-disable-line max-len asset: {}, - confirmations: 19620 + confirmations: 19620, } }) @@ -40,14 +47,17 @@ describe('SecondSignatureHandler', () => { expect(handler.canApply).toBeFunction() }) - it('should be ok', () => { + it('should be true', () => { wallet.secondPublicKey = null - expect(handler.canApply(wallet, transaction)).toBeTruthy() + expect(handler.canApply(wallet, transaction, [])).toBeTrue() }) - it('should not be ok', () => { - expect(handler.canApply(wallet, transaction)).toBeFalsy() + it('should be false if wallet already has a second signature', () => { + const errors = [] + + expect(handler.canApply(wallet, transaction, errors)).toBeFalse() + expect(errors).toContain('Wallet already has a second signature') }) }) @@ -58,7 +68,7 @@ describe('SecondSignatureHandler', () => { it('should be ok', () => { transaction.asset.signature = { - publicKey: 'dummy' + publicKey: 'dummy', } handler.apply(wallet, transaction) diff --git a/packages/crypto/__tests__/handlers/transactions/timelock-transfer.test.js b/packages/crypto/__tests__/handlers/transactions/timelock-transfer.test.js index e2fcc92834..c4fd67c492 100644 --- a/packages/crypto/__tests__/handlers/transactions/timelock-transfer.test.js +++ b/packages/crypto/__tests__/handlers/transactions/timelock-transfer.test.js @@ -18,14 +18,14 @@ describe('TimelockTransferHandler', () => { expect(handler.canApply).toBeFunction() }) - it('should be ok', () => { - expect(handler.canApply(wallet, transaction)).toBeTruthy() + it('should be true', () => { + expect(handler.canApply(wallet, transaction, [])).toBeTrue() }) - it('should not be ok', () => { - transaction.senderPublicKey = 'p'.repeat(66) + it('should be false', () => { + transaction.senderPublicKey = 'a'.repeat(66) - expect(handler.canApply(wallet, transaction)).toBeFalsy() + expect(handler.canApply(wallet, transaction, [])).toBeFalse() }) }) diff --git a/packages/crypto/__tests__/handlers/transactions/transfer.test.js b/packages/crypto/__tests__/handlers/transactions/transfer.test.js index 0f50293374..b9a56a1c0b 100644 --- a/packages/crypto/__tests__/handlers/transactions/transfer.test.js +++ b/packages/crypto/__tests__/handlers/transactions/transfer.test.js @@ -18,14 +18,14 @@ describe('TransferHandler', () => { expect(handler.canApply).toBeFunction() }) - it('should be ok', () => { - expect(handler.canApply(wallet, transaction)).toBeTruthy() + it('should be true', () => { + expect(handler.canApply(wallet, transaction, [])).toBeTrue() }) - it('should not be ok', () => { - transaction.senderPublicKey = 'p'.repeat(66) + it('should be false', () => { + transaction.senderPublicKey = 'a'.repeat(66) - expect(handler.canApply(wallet, transaction)).toBeFalsy() + expect(handler.canApply(wallet, transaction, [])).toBeFalse() }) }) diff --git a/packages/crypto/__tests__/handlers/transactions/vote.test.js b/packages/crypto/__tests__/handlers/transactions/vote.test.js index 70b014b69a..47186e04e1 100644 --- a/packages/crypto/__tests__/handlers/transactions/vote.test.js +++ b/packages/crypto/__tests__/handlers/transactions/vote.test.js @@ -1,3 +1,4 @@ +const Bignum = require('../../../lib/utils/bignum') const handler = require('../../../lib/handlers/transactions/vote') let wallet @@ -6,10 +7,10 @@ let transaction beforeEach(() => { wallet = { address: 'DQ7VAW7u171hwDW75R1BqfHbA9yiKRCBSh', - balance: '6453530000000', - publicKey: '0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0', - secondPublicKey: '03791c7d0229966ee41af0e5362f3bb2534ef8c706d7151fec70aead607227fce1', - vote: null + balance: new Bignum('6453530000000'), + publicKey: + '0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0', + vote: null, } transaction = { @@ -18,18 +19,20 @@ beforeEach(() => { blockid: '5273958469976113749', type: 3, timestamp: 36345270, - amount: 0, - fee: 100000000, + amount: Bignum.ZERO, + fee: new Bignum(100000000), senderId: 'DQ7VAW7u171hwDW75R1BqfHbA9yiKRCBSh', recipientId: 'DQ7VAW7u171hwDW75R1BqfHbA9yiKRCBSh', - senderPublicKey: '0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0', - signature: '304402204da11f2677ea67ad3718520020eb2e2d43b5c83f947490d2b454ce3ec0f1dcba022011a00e3c3febdaf531a404d728b111812647c2f0e33df439c7cbae01dcb702ba', // eslint-disable-line max-len + senderPublicKey: + '0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0', + signature: + '304402204da11f2677ea67ad3718520020eb2e2d43b5c83f947490d2b454ce3ec0f1dcba022011a00e3c3febdaf531a404d728b111812647c2f0e33df439c7cbae01dcb702ba', // eslint-disable-line max-len asset: { votes: [ - '+0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0' - ] + '+0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0', + ], }, - confirmations: 19771 + confirmations: 19771, } }) @@ -42,6 +45,34 @@ describe('VoteHandler', () => { it('should be a function', () => { expect(handler.canApply).toBeFunction() }) + it('should be false if wallet has already voted', () => { + wallet.vote = + '0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0' + const errors = [] + + expect(handler.canApply(wallet, transaction, errors)).toBeFalse() + expect(errors).toContain('Wallet has already voted') + }) + it('should be false if tx vote-choice does not match wallet vote-choice', () => { + wallet.vote = + 'a310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0' + transaction.asset.votes[0] = + '-0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0' + const errors = [] + + expect(handler.canApply(wallet, transaction, errors)).toBeFalse() + expect(errors).toContain( + 'Wallet vote-choice does not match transaction vote-choice', + ) + }) + it('should be false if unvoting a non-voted wallet', () => { + transaction.asset.votes[0] = + '-0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0' + const errors = [] + + expect(handler.canApply(wallet, transaction, errors)).toBeFalse() + expect(errors).toContain('Wallet has not voted yet') + }) }) describe('apply', () => { @@ -58,7 +89,8 @@ describe('VoteHandler', () => { }) it('should not be ok', () => { - wallet.vote = '0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0' + wallet.vote = + '0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0' expect(wallet.vote).not.toBeNull() @@ -74,7 +106,8 @@ describe('VoteHandler', () => { }) it('should be ok', () => { - wallet.vote = '0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0' + wallet.vote = + '0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0' expect(wallet.vote).not.toBeNull() diff --git a/packages/crypto/__tests__/identities/address.test.js b/packages/crypto/__tests__/identities/address.test.js new file mode 100644 index 0000000000..e58fe13ea8 --- /dev/null +++ b/packages/crypto/__tests__/identities/address.test.js @@ -0,0 +1,47 @@ +const testSubject = require('../../lib/identities/address') +const Keys = require('../../lib/identities/keys') +const { data, passphrase } = require('./fixture') + +describe('Identities - Address', () => { + describe('fromPassphrase', () => { + it('should be a function', () => { + expect(testSubject.fromPassphrase).toBeFunction() + }) + + it('should be OK', () => { + expect(testSubject.fromPassphrase(passphrase)).toBe(data.address) + }) + }) + + describe('fromPublicKey', () => { + it('should be a function', () => { + expect(testSubject.fromPublicKey).toBeFunction() + }) + + it('should be OK', () => { + expect(testSubject.fromPublicKey(data.publicKey)).toBe(data.address) + }) + }) + + describe('fromPrivateKey', () => { + it('should be a function', () => { + expect(testSubject.fromPrivateKey).toBeFunction() + }) + + it('should be OK', () => { + expect(testSubject.fromPrivateKey(Keys.fromPassphrase(passphrase))).toBe( + data.address, + ) + }) + }) + + describe('validate', () => { + it('should be a function', () => { + expect(testSubject.validate).toBeFunction() + }) + + it('should be OK', () => { + expect(testSubject.validate(data.address)).toBeTrue() + }) + }) +}) diff --git a/packages/crypto/__tests__/identities/fixture.json b/packages/crypto/__tests__/identities/fixture.json new file mode 100644 index 0000000000..ce876dd30b --- /dev/null +++ b/packages/crypto/__tests__/identities/fixture.json @@ -0,0 +1,9 @@ +{ + "data": { + "privateKey": "d8839c2432bfd0a67ef10a804ba991eabba19f154a3d707917681d45822a5712", + "publicKey": "034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192", + "address": "D61mfSggzbvQgTUe6JhYKH2doHaqJ3Dyib", + "wif": "SGq4xLgZKCGxs7bjmwnBrWcT4C1ADFEermj846KC97FSv1WFD1dA" + }, + "passphrase": "this is a top secret passphrase" +} diff --git a/packages/crypto/__tests__/identities/keys.test.js b/packages/crypto/__tests__/identities/keys.test.js new file mode 100644 index 0000000000..963a0790b2 --- /dev/null +++ b/packages/crypto/__tests__/identities/keys.test.js @@ -0,0 +1,92 @@ +const testSubject = require('../../lib/identities/keys') +const Address = require('../../lib/identities/address') + +describe('Identities - Keys', () => { + describe('fromPassphrase', () => { + it('should be a function', () => { + expect(testSubject.fromPassphrase).toBeFunction() + }) + + it('should return two keys in hex', () => { + const keys = testSubject.fromPassphrase('secret') + + expect(keys).toBeObject() + expect(keys).toHaveProperty('publicKey') + expect(keys).toHaveProperty('privateKey') + + expect(keys.publicKey).toBeString() + expect(keys.publicKey).toMatch( + Buffer.from(keys.publicKey, 'hex').toString('hex'), + ) + + expect(keys.privateKey).toBeString() + expect(keys.privateKey).toMatch( + Buffer.from(keys.privateKey, 'hex').toString('hex'), + ) + }) + + it('should return address', () => { + const keys = testSubject.fromPassphrase( + 'SDgGxWHHQHnpm5sth7MBUoeSw7V7nbimJ1RBU587xkryTh4qe9ov', + ) + const address = Address.fromPublicKey(keys.publicKey.toString('hex')) + expect(address).toBe('DUMjDrT8mgqGLWZtkCqzvy7yxWr55mBEub') + }) + }) + + describe('fromWIF', () => { + it('should be a function', () => { + expect(testSubject.fromWIF).toBeFunction() + }) + + it('should return two keys in hex', () => { + const keys = testSubject.fromWIF( + 'SDgGxWHHQHnpm5sth7MBUoeSw7V7nbimJ1RBU587xkryTh4qe9ov', + ) + + expect(keys).toBeObject() + expect(keys).toHaveProperty('publicKey') + expect(keys).toHaveProperty('privateKey') + + expect(keys.publicKey).toBeString() + expect(keys.publicKey).toMatch( + Buffer.from(keys.publicKey, 'hex').toString('hex'), + ) + + expect(keys.privateKey).toBeString() + expect(keys.privateKey).toMatch( + Buffer.from(keys.privateKey, 'hex').toString('hex'), + ) + }) + + it('should return address', () => { + const keys = testSubject.fromWIF( + 'SDgGxWHHQHnpm5sth7MBUoeSw7V7nbimJ1RBU587xkryTh4qe9ov', + ) + const address = Address.fromPublicKey(keys.publicKey.toString('hex')) + expect(address).toBe('DCAaPzPAhhsMkHfQs7fZvXFW2EskDi92m8') + }) + + it('should get keys from compressed WIF', () => { + const keys = testSubject.fromWIF( + 'SAaaKsDdWMXP5BoVnSBLwTLn48n96UvG42WSUUooRv1HrEHmaSd4', + ) + + expect(keys).toBeObject() + expect(keys).toHaveProperty('publicKey') + expect(keys).toHaveProperty('privateKey') + expect(keys).toHaveProperty('compressed', true) + }) + + it('should get keys from uncompressed WIF', () => { + const keys = testSubject.fromWIF( + '6hgnAG19GiMUf75C43XteG2mC8esKTiX9PYbKTh4Gca9MELRWmg', + ) + + expect(keys).toBeObject() + expect(keys).toHaveProperty('publicKey') + expect(keys).toHaveProperty('privateKey') + expect(keys).toHaveProperty('compressed', false) + }) + }) +}) diff --git a/packages/crypto/__tests__/identities/private-key.test.js b/packages/crypto/__tests__/identities/private-key.test.js new file mode 100644 index 0000000000..cb054b130c --- /dev/null +++ b/packages/crypto/__tests__/identities/private-key.test.js @@ -0,0 +1,24 @@ +const testSubject = require('../../lib/identities/private-key') +const { data, passphrase } = require('./fixture') + +describe('Identities - Private Key', () => { + describe('fromPassphrase', () => { + it('should be a function', () => { + expect(testSubject.fromPassphrase).toBeFunction() + }) + + it('should be OK', () => { + expect(testSubject.fromPassphrase(passphrase)).toBe(data.privateKey) + }) + }) + + describe('fromWIF', () => { + it('should be a function', () => { + expect(testSubject.fromWIF).toBeFunction() + }) + + it('should be OK', () => { + expect(testSubject.fromWIF(data.wif)).toBe(data.privateKey) + }) + }) +}) diff --git a/packages/crypto/__tests__/identities/public-key.test.js b/packages/crypto/__tests__/identities/public-key.test.js new file mode 100644 index 0000000000..cd301aebbe --- /dev/null +++ b/packages/crypto/__tests__/identities/public-key.test.js @@ -0,0 +1,34 @@ +const testSubject = require('../../lib/identities/public-key') +const { data, passphrase } = require('./fixture') + +describe('Identities - Public Key', () => { + describe('fromPassphrase', () => { + it('should be a function', () => { + expect(testSubject.fromPassphrase).toBeFunction() + }) + + it('should be OK', () => { + expect(testSubject.fromPassphrase(passphrase)).toBe(data.publicKey) + }) + }) + + describe('fromWIF', () => { + it('should be a function', () => { + expect(testSubject.fromWIF).toBeFunction() + }) + + it('should be OK', () => { + expect(testSubject.fromWIF(data.wif)).toBe(data.publicKey) + }) + }) + + describe('validate', () => { + it('should be a function', () => { + expect(testSubject.validate).toBeFunction() + }) + + it('should be OK', () => { + expect(testSubject.validate(data.publicKey)).toBeTrue() + }) + }) +}) diff --git a/packages/crypto/__tests__/identities/wif.test.js b/packages/crypto/__tests__/identities/wif.test.js new file mode 100644 index 0000000000..e5d7f26e17 --- /dev/null +++ b/packages/crypto/__tests__/identities/wif.test.js @@ -0,0 +1,14 @@ +const testSubject = require('../../lib/identities/wif') +const { data, passphrase } = require('./fixture') + +describe('Identities - WIF', () => { + describe('fromPassphrase', () => { + it('should be a function', () => { + expect(testSubject.fromPassphrase).toBeFunction() + }) + + it('should be OK', () => { + expect(testSubject.fromPassphrase(passphrase)).toBe(data.wif) + }) + }) +}) diff --git a/packages/crypto/__tests__/managers/config.test.js b/packages/crypto/__tests__/managers/config.test.js index 6da3460747..b4eebac9cd 100644 --- a/packages/crypto/__tests__/managers/config.test.js +++ b/packages/crypto/__tests__/managers/config.test.js @@ -25,7 +25,9 @@ describe('Configuration', () => { }) it('key should be "get"', () => { - expect(configManager.get('nethash')).toBe('578e820911f24e039733b45e4882b73e301f813a0d2c31330dafda84534ffa23') + expect(configManager.get('nethash')).toBe( + '2a44f340d76ffc3df204c5f38cd355b7496c9065a1ade2ef92071436bd72e867', + ) }) it('should build constants', () => { @@ -33,35 +35,67 @@ describe('Configuration', () => { }) it('should build fees', () => { - const fees = network.constants[0].fees + const fees = network.constants[0].fees.staticFees expect(feeManager.get(TRANSACTION_TYPES.TRANSFER)).toEqual(fees.transfer) - expect(feeManager.get(TRANSACTION_TYPES.SECOND_SIGNATURE)).toEqual(fees.secondSignature) - expect(feeManager.get(TRANSACTION_TYPES.DELEGATE_REGISTRATION)).toEqual(fees.delegateRegistration) + expect(feeManager.get(TRANSACTION_TYPES.SECOND_SIGNATURE)).toEqual( + fees.secondSignature, + ) + expect(feeManager.get(TRANSACTION_TYPES.DELEGATE_REGISTRATION)).toEqual( + fees.delegateRegistration, + ) expect(feeManager.get(TRANSACTION_TYPES.VOTE)).toEqual(fees.vote) - expect(feeManager.get(TRANSACTION_TYPES.MULTI_SIGNATURE)).toEqual(fees.multiSignature) + expect(feeManager.get(TRANSACTION_TYPES.MULTI_SIGNATURE)).toEqual( + fees.multiSignature, + ) expect(feeManager.get(TRANSACTION_TYPES.IPFS)).toEqual(fees.ipfs) - expect(feeManager.get(TRANSACTION_TYPES.TIMELOCK_TRANSFER)).toEqual(fees.timelockTransfer) - expect(feeManager.get(TRANSACTION_TYPES.MULTI_PAYMENT)).toEqual(fees.multiPayment) - expect(feeManager.get(TRANSACTION_TYPES.DELEGATE_RESIGNATION)).toEqual(fees.delegateResignation) + expect(feeManager.get(TRANSACTION_TYPES.TIMELOCK_TRANSFER)).toEqual( + fees.timelockTransfer, + ) + expect(feeManager.get(TRANSACTION_TYPES.MULTI_PAYMENT)).toEqual( + fees.multiPayment, + ) + expect(feeManager.get(TRANSACTION_TYPES.DELEGATE_RESIGNATION)).toEqual( + fees.delegateResignation, + ) }) it('should build dynamic fee offsets', () => { - const dynamicOffsets = network.constants[0].dynamicOffsets + const addonBytes = network.constants[0].fees.dynamicFees.addonBytes - expect(dynamicFeeManager.get(TRANSACTION_TYPES.TRANSFER)).toEqual(dynamicOffsets.transfer) - expect(dynamicFeeManager.get(TRANSACTION_TYPES.SECOND_SIGNATURE)).toEqual(dynamicOffsets.secondSignature) - expect(dynamicFeeManager.get(TRANSACTION_TYPES.DELEGATE_REGISTRATION)).toEqual(dynamicOffsets.delegateRegistration) - expect(dynamicFeeManager.get(TRANSACTION_TYPES.VOTE)).toEqual(dynamicOffsets.vote) - expect(dynamicFeeManager.get(TRANSACTION_TYPES.MULTI_SIGNATURE)).toEqual(dynamicOffsets.multiSignature) - expect(dynamicFeeManager.get(TRANSACTION_TYPES.IPFS)).toEqual(dynamicOffsets.ipfs) - expect(dynamicFeeManager.get(TRANSACTION_TYPES.TIMELOCK_TRANSFER)).toEqual(dynamicOffsets.timelockTransfer) - expect(dynamicFeeManager.get(TRANSACTION_TYPES.MULTI_PAYMENT)).toEqual(dynamicOffsets.multiPayment) - expect(dynamicFeeManager.get(TRANSACTION_TYPES.DELEGATE_RESIGNATION)).toEqual(dynamicOffsets.delegateResignation) + expect(dynamicFeeManager.get(TRANSACTION_TYPES.TRANSFER)).toEqual( + addonBytes.transfer, + ) + expect(dynamicFeeManager.get(TRANSACTION_TYPES.SECOND_SIGNATURE)).toEqual( + addonBytes.secondSignature, + ) + expect( + dynamicFeeManager.get(TRANSACTION_TYPES.DELEGATE_REGISTRATION), + ).toEqual(addonBytes.delegateRegistration) + expect(dynamicFeeManager.get(TRANSACTION_TYPES.VOTE)).toEqual( + addonBytes.vote, + ) + expect(dynamicFeeManager.get(TRANSACTION_TYPES.MULTI_SIGNATURE)).toEqual( + addonBytes.multiSignature, + ) + expect(dynamicFeeManager.get(TRANSACTION_TYPES.IPFS)).toEqual( + addonBytes.ipfs, + ) + expect(dynamicFeeManager.get(TRANSACTION_TYPES.TIMELOCK_TRANSFER)).toEqual( + addonBytes.timelockTransfer, + ) + expect(dynamicFeeManager.get(TRANSACTION_TYPES.MULTI_PAYMENT)).toEqual( + addonBytes.multiPayment, + ) + expect( + dynamicFeeManager.get(TRANSACTION_TYPES.DELEGATE_RESIGNATION), + ).toEqual(addonBytes.delegateResignation) }) it('should get constants for height', () => { - expect(configManager.getConstants(75600)).toEqual(network.constants[1]) + expect(configManager.getConstants(75600)).toEqual( + Object.assign({}, ...network.constants), + ) }) it('should set the height', () => { diff --git a/packages/crypto/__tests__/managers/fee.test.js b/packages/crypto/__tests__/managers/fee.test.js index d87c82050f..03fad69168 100644 --- a/packages/crypto/__tests__/managers/fee.test.js +++ b/packages/crypto/__tests__/managers/fee.test.js @@ -17,9 +17,9 @@ describe('Fee Manager', () => { type: TRANSACTION_TYPES.MULTI_SIGNATURE, asset: { multisignature: { - keysgroup: [1, 2, 3] - } - } + keysgroup: [1, 2, 3], + }, + }, } feeManager.set(TRANSACTION_TYPES.MULTI_SIGNATURE, 1) diff --git a/packages/crypto/__tests__/models/block.test.js b/packages/crypto/__tests__/models/block.test.js index 6198438f89..a5b8ef750d 100644 --- a/packages/crypto/__tests__/models/block.test.js +++ b/packages/crypto/__tests__/models/block.test.js @@ -1,14 +1,18 @@ const ByteBuffer = require('bytebuffer') const Block = require('../../lib/models/block') +const Bignum = require('../../lib/utils/bignum') describe('Models - Block', () => { const data = { id: '187940162505562345', - blockSignature: '3045022100a6605198e0f590c88798405bc76748d84e280d179bcefed2c993e70cded2a5dd022008c7f915b89fc4f3250fc4b481abb753c68f30ac351871c50bd6cfaf151370e8', // eslint-disable-line max-len - generatorPublicKey: '024c8247388a02ecd1de2a3e3fd5b7c61ecc2797fa3776599d558333ef1802d231', + blockSignature: + '3045022100a6605198e0f590c88798405bc76748d84e280d179bcefed2c993e70cded2a5dd022008c7f915b89fc4f3250fc4b481abb753c68f30ac351871c50bd6cfaf151370e8', // eslint-disable-line max-len + generatorPublicKey: + '024c8247388a02ecd1de2a3e3fd5b7c61ecc2797fa3776599d558333ef1802d231', height: 10, numberOfTransactions: 0, - payloadHash: '578e820911f24e039733b45e4882b73e301f813a0d2c31330dafda84534ffa23', + payloadHash: + '578e820911f24e039733b45e4882b73e301f813a0d2c31330dafda84534ffa23', payloadLength: 1, previousBlock: '12123', reward: 1, @@ -16,25 +20,32 @@ describe('Models - Block', () => { totalAmount: 10, totalFee: 1, transactions: [], - version: 6 + version: 6, } describe('constructor', () => { - xit('stores the data', () => {}) - xit('verifies the block', () => {}) + it.skip('stores the data', () => {}) + it.skip('verifies the block', () => {}) }) describe('getHeader', () => { it('returns the block data without the transactions', () => { // Ignore the verification for testing purposes - jest.spyOn(Block.prototype, 'verify').mockImplementation(() => ({ verified: true })) + jest + .spyOn(Block.prototype, 'verify') + .mockImplementation(() => ({ verified: true })) const data2 = { ...data } - const header = (new Block(data2)).getHeader() + const header = new Block(data2).getHeader() + const bignumProperties = ['reward', 'totalAmount', 'totalFee'] Object.keys(data).forEach(key => { if (key !== 'transactions') { - expect(header[key]).toEqual(data2[key]) + if (bignumProperties.includes(key)) { + expect(header[key]).toEqual(new Bignum(data2[key])) + } else { + expect(header[key]).toEqual(data2[key]) + } } }) @@ -43,8 +54,8 @@ describe('Models - Block', () => { }) describe('serialize', () => { - const serialize = (data, includeSignature) => { - const serialized = Block.serialize(data, includeSignature) + const serialize = (object, includeSignature) => { + const serialized = Block.serialize(object, includeSignature) const buffer = new ByteBuffer(1024, true) buffer.append(serialized) buffer.flip() @@ -63,16 +74,28 @@ describe('Models - Block', () => { expect(serialize(data).readUInt32(8)).toEqual(data.height) }) - describe('if `previousBlockHex` exists', () => { + describe('if `previousBlock` exists', () => { it('is serialized as hexadecimal', () => { - const data2 = { ...data, ...{ previousBlockHex: 'a00000000000000a' } } - expect(serialize(data2).slice(12, 20).toString('hex')).toEqual(data2.previousBlockHex) + const dataWithPreviousBlock = Object.assign({}, data, { + previousBlock: '1234', + }) + expect( + serialize(dataWithPreviousBlock) + .slice(12, 20) + .toString('hex'), + ).toEqual(dataWithPreviousBlock.previousBlockHex) }) }) - describe('if `previousBlockHex` does not exist', () => { + describe('if `previousBlock` does not exist', () => { it('8 bytes are added, as padding', () => { - expect(serialize(data).slice(12, 20).toString('hex')).toEqual('0000000000000000') + const dataWithoutPreviousBlock = Object.assign({}, data) + delete dataWithoutPreviousBlock.previousBlock + expect( + serialize(dataWithoutPreviousBlock) + .slice(12, 20) + .toString('hex'), + ).toEqual('0000000000000000') }) }) @@ -81,15 +104,27 @@ describe('Models - Block', () => { }) it('`totalAmount` of transactions is serialized as a UInt64', () => { - expect(serialize(data).readUInt64(24).toNumber()).toEqual(data.totalAmount) + expect( + serialize(data) + .readUInt64(24) + .toNumber(), + ).toEqual(+data.totalAmount) }) it('`totalFee` of transactions is serialized as a UInt64', () => { - expect(serialize(data).readUInt64(32).toNumber()).toEqual(data.totalFee) + expect( + serialize(data) + .readUInt64(32) + .toNumber(), + ).toEqual(+data.totalFee) }) it('`reward` of transactions is serialized as a UInt64', () => { - expect(serialize(data).readUInt64(40).toNumber()).toEqual(data.reward) + expect( + serialize(data) + .readUInt64(40) + .toNumber(), + ).toEqual(+data.reward) }) it('`payloadLength` of transactions is serialized as a UInt32', () => { @@ -97,11 +132,19 @@ describe('Models - Block', () => { }) it('`payloadHash` of transactions is appended, using 32 bytes, as hexadecimal', () => { - expect(serialize(data).slice(52, 52 + 32).toString('hex')).toEqual(data.payloadHash) + expect( + serialize(data) + .slice(52, 52 + 32) + .toString('hex'), + ).toEqual(data.payloadHash) }) it('`generatorPublicKey` of transactions is appended, using 33 bytes, as hexadecimal', () => { - expect(serialize(data).slice(84, 84 + 33).toString('hex')).toEqual(data.generatorPublicKey) + expect( + serialize(data) + .slice(84, 84 + 33) + .toString('hex'), + ).toEqual(data.generatorPublicKey) }) describe('if the `blockSignature` is not included', () => { @@ -120,168 +163,205 @@ describe('Models - Block', () => { describe('if the `blockSignature` is included', () => { it('is serialized', () => { - expect(serialize(data).slice(117, 188).toString('hex')).toEqual(data.blockSignature) + expect( + serialize(data) + .slice(117, 188) + .toString('hex'), + ).toEqual(data.blockSignature) }) it('is serialized unless the `includeSignature` parameter is false', () => { expect(serialize(data, false).limit).toEqual(117) }) }) + }) - describe('test blocks', () => { - let serialiseds = [ - '00000000c85408015fc4150029b6af826e640cce020000001a458d1600000000002d31010000000000c2eb0b00000000400000002763ddc267de1adf1a0e1cf69b19d15c16894580330178ecfbd785c7b73161db02df70fa5cf1687438363c06f97f8e1b67bb565f77ded6988dd46d4456bfdaf4af304402206353051efc7b562aae5e100a4b2b4d1f9d7789b9c3a7dd8675edc7ddddc71f6e02204aff17470b390d7ff2c332e405bdd835f01121de5aec3c8fde23a7a3fb574adbb6000000c7000000ff011e00c25408010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000001c676f6f736520726573657276652e207c74782062792061726b2d676fa505430000000000000000001e41ac3c020d83d8238a538de849089a0d392be489304502210096423bff6d99fba7664b860ffc39643f615caf3dedbd636aeb48089f970acd87022051d502022748b631b6b00a0e6818d96496c0fa796ad39d77e2089a252e730abeff011e00c25408010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000002d676f6f73653a20766f746572732073686172652e205468616e6b20796f7521207c74782062792061726b2d676f753f4a1600000000000000001ee51d5433e842b8f5393a9c9ba0a2cacf9e620d023045022100f6906fdad0e07f00ec6e6b5d2c1c38a823893b27dcc9291323a662a8cd5808a00220034a6e3e2dc382d7b36b97834dc4ba56363eab2c4cfc048a51828a679472962a', - '00000000b0120c01173a160092b87bdc4850eb8103000000e0dcf30c0000000080c3c9010000000000c2eb0b0000000060000000101f4afd4dc88f1149a1d90d5298c218852e04cd95122e51d4fa31ebc80a8a1903794e95585ab18fd95c963cfb2ec24f37ad159f6a43e05dd826577b58a32de3093045022100d405bcab8e48866bdd81bc4ff311110a843ab862e0382ecc2b1784befb41585002201d6be7ab405069351775a24b53bfd647adb52a2f7a66f41102cfdfb4768173b7b9000000c6000000b4000000ff011e00a6120c010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c0809698000000000020676f6f7365204465764e65742046756e642e207c74782062792061726b2d676fc1749d0100000000000000001e41ac3c020d83d8238a538de849089a0d392be489304402203354ae8cb3c1353e20bd51545ebdd4a04437dc5bcef251cbc41ecc514d7ef0b7022019a8dee2ea2e3cf760c84eb3be0261e47085b88949dba1d03a8edd9181a4ce01ff011e00a6120c010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000002d676f6f73653a20766f746572732073686172652e205468616e6b20796f7521207c74782062792061726b2d676fde89510a00000000000000001ee51d5433e842b8f5393a9c9ba0a2cacf9e620d0230440220511edb58fb45fa0e297afde97e446f045b599fcbfb957f2e7fd2fccd990eb26902205af32eb1f0d80e5c1dde36d34e8c5a94f0c1e36bc4b99a14cd819a90e0e30590ff011e00a6120c010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000001c676f6f736520726573657276652e207c74782062792061726b2d676f41de040100000000000000001e41ac3c020d83d8238a538de849089a0d392be489304302202080fe9020b7eeb018e2c0187477af714243b089e1ab90924af54a80732a81eb021f3d3385e4a47f09142a37a02fa53096ffdf5a09c5330329687843f2379e06a4', - '00000000a87f1501ca591700f640bdcc7c822639030000002667b30c0000000080c3c9010000000000c2eb0b0000000060000000648750fda993744468a26e253d6186e8d7d85230c67b23d4c8d95749bd91076e0265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c0304402204834295f96c1af91fb9e673315581417cb0bc5a4f5ad33b9768bef1f4f42250d02206307737b60bbdbc4afea082d20997f24de932140dcf66f8c09f7f84a7315f100ba000000c6000000b6000000ff011e008a7f15010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c0809698000000000020676f6f7365204465764e65742046756e642e207c74782062792061726b2d676f7fc9930100000000000000001e41ac3c020d83d8238a538de849089a0d392be48930450221009a6fd7ed6a47bb652d3e4e2ce32ef79d91c43e45eb06b93ccafd29583f4660fc02205fc835c4697b8a73bb1f82247a6279003213e9e8b1213124fb83a400cfa5d446ff011e008a7f15010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000002d676f6f73653a20766f746572732073686172652e205468616e6b20796f7521207c74782062792061726b2d676fa86a240a00000000000000001ee51d5433e842b8f5393a9c9ba0a2cacf9e620d02304402201696335cca3631c4a7287f7b93ea5bdcf1f57109faee479ada4b093288a3a558022034786a509932a45be878ffce13c78aac356c995ed82d04a872de8323839820f1ff011e008a7f15010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000001c676f6f736520726573657276652e207c74782062792061726b2d676fff32fb0000000000000000001e41ac3c020d83d8238a538de849089a0d392be4893045022100859589b1258904c475e7bba9c31bc38f58a58adc1bb28b576bb81ed5d420f60602203a1883a9e54a06e32a56e6e8f8992e387e00c76288bd23a6ce3bd320d1451803', - '00000000c8291901b8c4170098a81ee52effe78806000000186e1c188a060000008793030000000000c2eb0b00000000c000000099ace34c0d0ee732d2f2f1a8289aacbed6c78338d522e7674c56572c028a0948028f0a25321cd9d3bf051b34a835cd5eee0125120c17654bc95790f8f2d970dc46304402203d277f68d6123d9f2caa17b65ab333b523b6ef4a8daf03efd79ad1604424882502204985f45c34a9fad2b517fefafa65293f47751516f1ea802996785ff396af84cab0000000a6000000a5000000b1000000a6000000b0000000ff011e00c029190102bcfa0951a92e7876db1fb71996a853b57f996972ed059a950d910f7d541706c9809698000000000016636872697320626f747c74782062792061726b2d676f3c9e8b1411000000000000001ed3348ec3a821e123661d40f92f876246a68023f23045022100812ad00f621472278a000685bb8086ab2e0fdabd091003a60aae370b90c81c3102206b6d6f6563cfb9ba12bf3d954891c308ce9aa98a6c293fcb93c227081499d2c3ff011e00c029190102bcfa0951a92e7876db1fb71996a853b57f996972ed059a950d910f7d541706c980969800000000000c74782062792061726b2d676fcd3f500000000000000000001e035d21fa40b1e94e244c7eff7cb0c71cfa9e13c43045022100aa3550ecce4f5d2c8741177233717dc1ce35867291fb132eafdd87653fbba41902207eb50859d2a894dbf509c2c9acbacda417264d95da8a8850e76d8e9f641e0139ff011e00c029190102bcfa0951a92e7876db1fb71996a853b57f996972ed059a950d910f7d541706c980969800000000000c74782062792061726b2d676f64769b0100000000000000001ed3348ec3a821e123661d40f92f876246a68023f23044022006732e562b2e50c4f156a12e08de8edea7e07cd3babe0b6c8c8a7cb60cd8bc91022035b8cf52935e701179747ad0e50060de02099f9c128bda478f2463ed90a6a20eff011e00c029190102bcfa0951a92e7876db1fb71996a853b57f996972ed059a950d910f7d541706c9809698000000000017636872697320626f74207c74782062792061726b2d676f3c9e8b1411000000000000001eb09c56caa5da3727181852feb4ec28437ee680f23045022100e2fe012c8183fd7081e04d50349442d605e8338157036a0cde4713ccd4f59b5802200a1d3a5d39aeeb64b1f5ddbfc6843888d07befe44823477a58f02bd62cde9917ff011e00c029190102bcfa0951a92e7876db1fb71996a853b57f996972ed059a950d910f7d541706c980969800000000000c74782062792061726b2d676f434b1e0000000000000000001eb09c56caa5da3727181852feb4ec28437ee680f230450221008eaa41f5035a193c1922d50e8a79a6ab4760d205e25997d2b5318a3a98d887c802203e6034188c9fd1464a6e6f1a97e9c58e41de43761d8955349150dfdcb553fa05ff011e00c029190102bcfa0951a92e7876db1fb71996a853b57f996972ed059a950d910f7d541706c9809698000000000017636872697320626f74207c74782062792061726b2d676f2c30fbec67060000000000001ed421060ebd11f29b416a5802c55db49db93e27313044022056fd51a12ff65d5aa4b81b26d33f01c9411f74f814d3a1a6b78d47a8759da5a702206f2a20f94cd1d16ec0ebe71e9eba391d9c5e7ea2821a84e0e5d086bd19695fdb', - '00000000902519013fc417007ce7a87ec4508b0c0c0000008ce4b60f00000000000e27070000000000c2eb0b00000000800100000e14663db43354388312960f3e83d2d39c10d1cc71d0bb7c377cb5641ff7d8eb02ce086b1e1609c691c0d2e0670a15248a7244195798bcc578b12133fe04defe593045022100de21b64ccff8e3b7cf24319e272cf8eac8508b16ccf504dd6d611c3bc32d68d402202e8b956e3c7a3e231ccc2fae0024dc9627db47b145ac4aad72565cc1be737871b6000000a6000000a6000000c7000000a6000000ba000000a5000000a5000000a5000000a5000000a6000000a5000000ff011e00862519010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000001c676f6f736520726573657276652e207c74782062792061726b2d676f32ec6e0100000000000000001e41ac3c020d83d8238a538de849089a0d392be4893045022100edbb88822e17646651fa1f25700e304c05a2a9b1a968a735a0245665247d03a80220400d03132f75d5988e0d8f3331c05a724873fd13d2af0fd0a023ca3034641d77ff011e00bf24190102bcfa0951a92e7876db1fb71996a853b57f996972ed059a950d910f7d541706c980969800000000000c7065726620746573742023310200000000000000000000001e7143fd56b4ade52677fb877e02553c9a08745dea3045022100ffce543d4b8d7ebed8d2ebdef75eca9cb2a83f6f0140899c2947451da31ef1ad02207367bd87a1dfb33171a49ba4a31562d602439ea98b42880d1f8aa828bf65021eff011e00bf24190102bcfa0951a92e7876db1fb71996a853b57f996972ed059a950d910f7d541706c980969800000000000c7065726620746573742023310300000000000000000000001e7143fd56b4ade52677fb877e02553c9a08745dea3045022100a29adcf6812bdbce2b4d9d33b1d2007edbf43eba9db9bc36ad245e4acfddb47102205771a7f3f208dac19eb791f79d39d150b3b14912bc233bce72b23b084bd3d476ff011e00862519010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000002d676f6f73653a20766f746572732073686172652e205468616e6b20796f7521207c74782062792061726b2d676f9675400c00000000000000001ee51d5433e842b8f5393a9c9ba0a2cacf9e620d023045022100a523ea18aad4be535b669615487256dc5bac847c07ae8da447151e069e8bdf7802202597feef6a011c45bd6bcef8e6aebaa16037439725f31a46ebdc373117e9b8e5ff011e00b724190102bcfa0951a92e7876db1fb71996a853b57f996972ed059a950d910f7d541706c980969800000000000c7065726620746573742023310300000000000000000000001e7143fd56b4ade52677fb877e02553c9a08745dea3045022100b61eae15cfbb04676bf00ce1320ca9316f3a5345a959ba9414225fb7115b7e4d02200666e11f0cf4644a6507c96d987f68a55055920264c53c86be1cda6f4dcee24dff011e00862519010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c0809698000000000020676f6f7365204465764e65742046756e642e207c74782062792061726b2d676fb282070200000000000000001e41ac3c020d83d8238a538de849089a0d392be4893045022100bfbc9e7c67550326639d273399671d5eae5345f826529c83a55c11cb68d0092a022054627dbe51091dc9811f1f453a8944f50f0f2d372a71c106a9a380bad7da01b5ff011e00b724190102bcfa0951a92e7876db1fb71996a853b57f996972ed059a950d910f7d541706c980969800000000000c7065726620746573742023310200000000000000000000001e7143fd56b4ade52677fb877e02553c9a08745dea304402206f1f4b1a76d8dcd4df0041e0282aa812be7b8dec349a461fe1ebb0baa5c4a5fd0220517e00ebca6f5fad2949e640cf7172269207fd1c3c5eaf4b210411fdcff32c1fff011e00be24190102bcfa0951a92e7876db1fb71996a853b57f996972ed059a950d910f7d541706c980969800000000000c7065726620746573742023310100000000000000000000001e7143fd56b4ade52677fb877e02553c9a08745dea3044022012e5cc84e3f4ddd78541bc3d0cca77835c6ee923faeb0e49b08fc2025643662802201b7b61a059ee6de3c17b7c61271aaf1462350f21c49186d6cd4e7bd13b4e064fff011e00b724190102bcfa0951a92e7876db1fb71996a853b57f996972ed059a950d910f7d541706c980969800000000000c7065726620746573742023310100000000000000000000001e7143fd56b4ade52677fb877e02553c9a08745dea304402207c5276a703dd648c812a6d6ee59f474e979f6aea5866d5ec559264b01e49c5250220577b835a74dd2ac2eb704629c542800f2843694adba679c24abe6d7744444ad9ff011e00be24190102bcfa0951a92e7876db1fb71996a853b57f996972ed059a950d910f7d541706c980969800000000000c7065726620746573742023310300000000000000000000001e7143fd56b4ade52677fb877e02553c9a08745dea30440220158a2ccd30a0c546a264311e714edfb8014aaecd43720eacee3291eb2c61a295022018c300eec32fa00ea9dfe6f2c8806fbfe1cbbf641ccc0f7c60ea6f638aac52bbff011e00be24190102bcfa0951a92e7876db1fb71996a853b57f996972ed059a950d910f7d541706c980969800000000000c7065726620746573742023310200000000000000000000001e7143fd56b4ade52677fb877e02553c9a08745dea3045022100f2660609fc2fbf25cfc84ba93a2c8ef5cae95ad3d01accccb26398e191196041022078982e7e42c31744031ba96fb04728631de3683cf30d2961560be79fa4a64506ff011e00bf24190102bcfa0951a92e7876db1fb71996a853b57f996972ed059a950d910f7d541706c980969800000000000c7065726620746573742023310100000000000000000000001e7143fd56b4ade52677fb877e02553c9a08745dea304402205dc5d2f914737fa8df63918a69ab795dd03580099b527ac9086d6368bbc45bcd02207ea804611de09bb79a54427678574c92dc3d7a18bd53809420572097becccd09', - '0000000080341b01810018002ad26e6fc5deed3803000000b6fcab0c0000000080c3c9010000000000c2eb0b0000000060000000e6fc87c3ad48574e9407bae80b670eb13ebf3703331306c980ff13f7478df3cc03f5b199727b5caf1d33d81b83d19313aff8515009d4a7e48685cb61ebf56f2ffb3045022100ba773a1a201067c54d6b45ab9e67d5dbe590282ecb0211d600db3d116ccb0824022073343c775469392fbbc649c5ea4cf94b00f8b7a646933bf0ec81ba610a8997eeb5000000c6000000b9000000ff011e0066341b010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000001c676f6f736520726573657276652e207c74782062792061726b2d676f3b16fa0000000000000000001e41ac3c020d83d8238a538de849089a0d392be489304402203df52c6870b7a177e166071da409218f583527115aefb9fbe0cfdc6f589c969902201d7a47c1210accb78347e4e313b4e5facc70d21050311bafc9b19b5ba298b937ff011e0066341b010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000002d676f6f73653a20766f746572732073686172652e205468616e6b20796f7521207c74782062792061726b2d676fc0391f0a00000000000000001ee51d5433e842b8f5393a9c9ba0a2cacf9e620d02304402206dd0f3877b05dc068ae76e8bfe2fca5a2a9c6fa04e3a99f534892c855ebe3dde02200363a219ea66857efd88a62e19af9be56aae8eed944134cdceb3348bf4a9fc41ff011e0066341b010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c0809698000000000020676f6f7365204465764e65742046756e642e207c74782062792061726b2d676fbbac920100000000000000001e41ac3c020d83d8238a538de849089a0d392be4893044022074ef8c766d853a23def407ec2ec8e9813c3310a0a02c8b5ceb4511e6410f185d022010fd85f9fd4cd1ca13369c5ec00b7b6a98aa0669d4c5378b4e98da1e4a64e2b9', - '00000000f8301b011c00180091c7652b2450690c0400000055ba4bc400000000005a62020000000000c2eb0b0000000080000000395e2bedb95411f8d87e821978b5beb7554ed06f6c101ea095f1ad0108e37f4e0266ec6b35766c81465af51b07e2e2f0bd45b01abd1662bdf673b1fe76aafe3df03045022100fbe10dca96230e73ce46c8298f3982885f82d6407b39128f52b57a5a3e66e230022003eac74392fbbbc131cef3a6d5fd431c84092132ce615f30c6f9d0640f2ceb86b0000000b1000000a5000000af000000ff011e00e5301b0102bcfa0951a92e7876db1fb71996a853b57f996972ed059a950d910f7d541706c9809698000000000017636872697320626f74207c74782062792061726b2d676f120b640100000000000000001eb09c56caa5da3727181852feb4ec28437ee680f23044022026548fa6d17e51f5868a7069d98dabbbb233757d6a4ce557c145294d9366b967022019c6c3565850a8a9febddadd75f23031b49b3f8d09005298794c4d93173322eaff011e00e5301b0102bcfa0951a92e7876db1fb71996a853b57f996972ed059a950d910f7d541706c9809698000000000017636872697320626f74207c74782062792061726b2d676f5a0024be00000000000000001ed421060ebd11f29b416a5802c55db49db93e27313045022100b69da543c02f052a8181c265abe39eda5c767309a343e460dc9213af767a2fcb02204616556146ca24407f648723a9548821874a43ed0a835f4abc52615f8e128adaff011e00e5301b0102bcfa0951a92e7876db1fb71996a853b57f996972ed059a950d910f7d541706c980969800000000000c74782062792061726b2d676fd7a35f0300000000000000001e7f048c40fd8a0442ffe79e0aa804f27fd5db159430440220372876dfb46d460b33b0821273f484b89ea4b0a96b2d1cd49d7e4b94b059ec4102206b2d19d7bb3c1c31284496686a6860f451d70e36470804b1f1f9eefad1f34ed8ff011e00e5301b0102bcfa0951a92e7876db1fb71996a853b57f996972ed059a950d910f7d541706c9809698000000000016636872697320626f747c74782062792061726b2d676f120b640100000000000000001ed3348ec3a821e123661d40f92f876246a68023f23044022002bed17317243f2db7c5628d730c19832e22b9265ae16242e18557c2d0c882e4022054de01158b791d582009692b6f277f42b80e83e4e971a033035797c38495adf5', - '00000000386b2b0187db1900e55de78db50f2cbb04000000083132bb00000000005a62020000000000c2eb0b00000000800000004162170808446d5bcdd88da6e1a85b7fc2a4dd97d60ee1cd39a239ece523f54b03d4ec98dfc6f3fe2ccb64a950534709ab6bb9134ae02205822f7cecf4391f03bd30440220493613ca8e3a628d1716166dab979f8a59caf91bb030f3c5bb151de6211fc60902202781ddf1bfa87eff30f5268e23921622280b305f61cf4204731a9089136ab6b6a5000000b0000000b1000000af000000ff011e00326b2b0102bcfa0951a92e7876db1fb71996a853b57f996972ed059a950d910f7d541706c980969800000000000c74782062792061726b2d676fb10b310300000000000000001e7f048c40fd8a0442ffe79e0aa804f27fd5db159430440220506cd61192ccf52bd8289b9775e363a5b37b5ad70ec1f61ac65452bc9e58eee60220086e05ba2324fb175f8aa575262c6ece3b59e9bd5fd8ca56827acbf6c43a9684ff011e00326b2b0102bcfa0951a92e7876db1fb71996a853b57f996972ed059a950d910f7d541706c9809698000000000017636872697320626f74207c74782062792061726b2d676f69a667b500000000000000001ed421060ebd11f29b416a5802c55db49db93e273130440220052bafded3c85372bedef4afaad4e94b8698bbbdb58511e858f05049257d306702207419a987b2b55800ae3aaccebb58a0ff169644a22441e0909e44c6e9f6d47344ff011e00326b2b0102bcfa0951a92e7876db1fb71996a853b57f996972ed059a950d910f7d541706c9809698000000000017636872697320626f74207c74782062792061726b2d676f77bf4c0100000000000000001eb09c56caa5da3727181852feb4ec28437ee680f23045022100eda27367b5f81475d4208efb48043144fe8c4eb351e23b2890f8a6df07ef8f0b022018c3c6ab858dd2438e4638c0858fcee96706ba505f51f7fd1c64d0dfb3bcf26eff011e00326b2b0102bcfa0951a92e7876db1fb71996a853b57f996972ed059a950d910f7d541706c9809698000000000016636872697320626f747c74782062792061726b2d676f77bf4c0100000000000000001ed3348ec3a821e123661d40f92f876246a68023f2304402207e0fbc350e8f81ab4a76236772cae08a0e5bc9752cf962018d30372c1e44624702204b7f9ea71f24ef853f61bb6553a52c5a882c78906972ff2498cecd1997134267', - '00000000d8566601ee4f20009b07bdb0aa81f0d0030000006b9138020000000080c3c9010000000000c2eb0b00000000600000008220084a6b78d25b4e7da7b2e6ea01fe46af23dd3d15cdad134dae541b0a98100275776018638e5c40f1b922901e96cac2caa734585ef302b4a2801ee9a338a45630440220713895f46593f74e0c2c79071e3c5d902ee96c7f3c61b84e472f8119192ec55402201192b673416b8782d607f0c061d0ee0af19c5c7f10e6ce2490e83ec427aa44ce00010000f9000000ff000000ff011e00d55666010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000001f476f6f736520566f746572202d205472756520426c6f636b20576569676874b1f95b0000000000000000001e9daf5f70eb6ba962347f0c782559dfe3fe240c673045022100a3777bcd2b84509028354872befadecccb594ec00dde96efbd0ce368d154e1dd022030136fc55530a5fa00f5740587a1232e2211a8bcf44aed143e642fabbbc3410a3045022100f91d4fd4b0f8da6853b7ea3aa6ca9704a0715df973225780b5269404a3c6770d022030e192a9f3dd33fbb5cc07916fc8575af2be73f4bce611818b8a7fd0c82a02c9ff011e00cf5666010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000001a666175636574202d205472756520426c6f636b2057656967687420d5860100000000000000001e6df4a0f58b398cb19e6d5258a7915c70981ce9613044022051fc06968e940ed228895cac64bfbc0f6e4274ccbeb94e1d9800e08fc49a9c6a022037d636e74e10d447afc06c4f80d5e00886aa46a3f079e21ae8be36b13c2f98d430440220475be5104d3884508b78d5da9dce7e0b3b8be1cc5f595e3a121c3c907105a54402204c6827dc428b0bfbc193edf71f8207b4766dcec67866b128c862c08a8678f339ff011e00d25666010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000001f476f6f736520566f746572202d205472756520426c6f636b205765696768749ac2550000000000000000001e97836063007c77e6a73b4deeca07f44bb13a524e3044022023b54bddf19d8810d09daa4ee5db1d2411ab3e36be3729f1ee48d18cf4dd9aee022063942ee0fda2552118e206c5bad52f90f644c4327f6c8f29d21ed951da5feb0b3045022100e2e8b73ac24ea431d50362e7a6f1a551c2fd3d02fe7db6420d1960e05c4e8cfa022064a30125ace8d15bd64bbe654c8bd499477ddd1746096cd4a890f6f9bf466954' - ] - serialiseds.forEach(s => console.log(new Block(Block.deserialize(s)))) + describe('serializeFull', () => { + describe('genesis block', () => { + describe.each([ + ['mainnet', 468048], + ['devnet', 14492], + ['testnet', 46488], + ])('%s', (network, length) => { + const genesis = require(`@arkecosystem/core/lib/config/${network}/genesisBlock.json`) + const serialized = Block.serializeFull(genesis).toString('hex') + const genesisBlock = new Block(Block.deserialize(serialized)) + expect(serialized).toHaveLength(length) + expect(genesisBlock.verifySignature()).toBeTrue() + }) }) describe('should validate hash', () => { const b = { - 'id': '7176646138626297930', - 'version': 0, - 'height': 2243161, - 'timestamp': 24760440, - 'previousBlock': '3112633353705641986', - 'numberOfTransactions': 7, - 'totalAmount': '3890300', - 'totalFee': '70000000', - 'reward': '200000000', - 'payloadLength': 224, - 'payloadHash': '3784b953afcf936bdffd43fdf005b5732b49c1fc6b11e195c364c20b2eb06282', - 'generatorPublicKey': '020f5df4d2bc736d12ce43af5b1663885a893fade7ee5e62b3cc59315a63e6a325', - 'blockSignature': '3045022100eee6c37b5e592e99811d588532726353592923f347c701d52912e6d583443e400220277ffe38ad31e216ba0907c4738fed19b2071246b150c72c0a52bae4477ebe29', - 'transactions': [ - { - 'type': 0, - 'amount': 555760, - 'fee': 10000000, - 'recipientId': 'DB4gFuDztmdGALMb8i1U4Z4R5SktxpNTAY', - 'timestamp': 24760418, - 'asset': {}, - 'vendorField': 'Goose Voter - True Block Weight', - 'senderPublicKey': '0265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c0', - 'signature': '304402204f12469157b19edd06ba25fcad3d4a5ef5b057c23f9e02de4641e6f8eef0553e022010121ab282f83efe1043de9c16bbf2c6845a03684229a0d7c965ffb9abdfb978', - 'signSignature': '30450221008327862f0b9178d6665f7d6674978c5caf749649558d814244b1c66cdf945c40022015918134ef01fed3fe2a2efde3327917731344332724522c75c2799a14f78717', - 'id': '170543154a3b79459cbaa529f9f62b6f1342682799eb549dbf09fcca2d1f9c11', - 'senderId': 'DB8LnnQqYvHpG4WkGJ9AJWBYEct7G3yRZg', - 'hop': 2, - 'broadcast': false, - 'blockId': '7176646138626297930' - }, - { - 'type': 0, - 'amount': 555750, - 'fee': 10000000, - 'recipientId': 'DGExsNogZR7JFa2656ZFP9TMWJYJh5djzQ', - 'timestamp': 24760416, - 'asset': {}, - 'vendorField': 'Goose Voter - True Block Weight', - 'senderPublicKey': '0265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c0', - 'signature': '304402205f82feb8c5d1d79c565c2ff7badb93e4c9827b132d135dda11cb25427d4ef8ac02205ff136f970533c4ec4c7d0cd1ea7e02d7b62629b66c6c93265f608d7f2389727', - 'signSignature': '304402207e912031fcc700d8a55fbc415993302a0d8e6aea128397141b640b6dba52331702201fd1ad3984e42af44f548907add6cb7ad72ca0070c8cc1d8dc9bbda208c56bd9', - 'id': '1da153f37eceda233ff1b407ac18e47b3cae47c14cdcd5297d929618a916c4a7', - 'senderId': 'DB8LnnQqYvHpG4WkGJ9AJWBYEct7G3yRZg', - 'hop': 2, - 'broadcast': false, - 'blockId': '7176646138626297930' - }, - { - 'type': 0, - 'amount': 555770, - 'fee': 10000000, - 'recipientId': 'DHGK5np6LuMMErfRfC5CmjpGu3ME85c25n', - 'timestamp': 24760420, - 'asset': {}, - 'vendorField': 'Goose Voter - True Block Weight', - 'senderPublicKey': '0265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c0', - 'signature': '304502210083216e6969e068770e6d2fe5c244881002309df84d20290ddf3f858967ed010202202a479b3da5080ea475d310ff13494654b42db75886a8808bd211b4bdb9146a7a', - 'signSignature': '3045022100e1dcab3406bbeb968146a4a391909ce41df9b71592a753b001e7c2ee1d382c5102202a74aeafd4a152ec61854636fbae829c41f1416c1e0637a0809408394973099f', - 'id': '1e255f07dc25ce22d900ea81663c8f00d05a7b7c061e6fc3c731b05d642fa0b9', - 'senderId': 'DB8LnnQqYvHpG4WkGJ9AJWBYEct7G3yRZg', - 'hop': 2, - 'broadcast': false, - 'blockId': '7176646138626297930' - }, - { - 'type': 0, - 'amount': 555750, - 'fee': 10000000, - 'recipientId': 'D7pcLJNGe197ibmWEmT8mM9KKU1htrcDyW', - 'timestamp': 24760417, - 'asset': {}, - 'vendorField': 'Goose Voter - True Block Weight', - 'senderPublicKey': '0265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c0', - 'signature': '3045022100cd4fa9855227be11e17201419dacfbbd5d9946df8d6792a9488160025693821402207fb83969bad6a26959f437b5bb88e255b0a48eb04964d0c0d29f7ee94bd15e11', - 'signSignature': '304402205f50c2991a17743d17ffbb09159cadc35a3f848044261842879ccf5be9d81c5e022023bf21c32fb6e94494104f15f8d3a942ab120d0abd6fb4c93790b68e1b307a79', - 'id': '66336c61d6ec623f8a1d2fd156a0fac16a4fe93bb3fba337859355c2119923a8', - 'senderId': 'DB8LnnQqYvHpG4WkGJ9AJWBYEct7G3yRZg', - 'hop': 2, - 'broadcast': false, - 'blockId': '7176646138626297930' - }, - { - 'type': 0, - 'amount': 555760, - 'fee': 10000000, - 'recipientId': 'DD4yhwzryQdNGqKtezmycToQv63g27Tqqq', - 'timestamp': 24760418, - 'asset': {}, - 'vendorField': 'Goose Voter - True Block Weight', - 'senderPublicKey': '0265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c0', - 'signature': '30450221009c792062e13399ac6756b2e9f137194d06e106360ac0f3e24e55c7249cee0b3602205dc1d9c76d0451d1cb5a2396783a13e6d2d790ccfd49291e3d0a78349f7ea0e8', - 'signSignature': '30440220083ba8a9af49b8be6e93794d71ec43ffc96a158375810e5d9f2478e71655315b0220278402ecaa1d224dab9f0f3b28295bbaea339c85c7400edafdc49df87439fc64', - 'id': '78db36f7d79f51c67d7210ee3819dfb8d0d47b16a7484ebf55c5a055b17209a3', - 'senderId': 'DB8LnnQqYvHpG4WkGJ9AJWBYEct7G3yRZg', - 'hop': 2, - 'broadcast': false, - 'blockId': '7176646138626297930' - }, - { - 'type': 0, - 'amount': 555760, - 'fee': 10000000, - 'recipientId': 'D5LiYGXL5keycWuTF6AFFwSRc6Mt4uEHMu', - 'timestamp': 24760419, - 'asset': {}, - 'vendorField': 'Goose Voter - True Block Weight', - 'senderPublicKey': '0265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c0', - 'signature': '3044022063c65263e42be02bd9831b375c1d76a88332f00ed0557ecc1e7d2375ca40070902206797b5932c0bad68444beb5a38daa7cadf536ee2144e0d9777b812284d14374e', - 'signSignature': '3045022100b04da6692f75d43229ffd8486c1517e8952d38b4c03dfac38b6b360190a5c33e0220776622e5f09f92a1258b4a011f22181c977b622b8d1bbb2f83b42f4126d00739', - 'id': '83c80bb58777bb43f5037544b44ef69f191d3548fd1b2a00bed368f9f0d694c5', - 'senderId': 'DB8LnnQqYvHpG4WkGJ9AJWBYEct7G3yRZg', - 'hop': 2, - 'broadcast': false, - 'blockId': '7176646138626297930' - }, - { - 'type': 0, - 'amount': 555750, - 'fee': 10000000, - 'recipientId': 'DPopNLwMvv4zSjdZnqUk8HFH13Mcb7NbEK', - 'timestamp': 24760416, - 'asset': {}, - 'vendorField': 'Goose Voter - True Block Weight', - 'senderPublicKey': '0265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c0', - 'signature': '3045022100d4513c3608c2072e38e7a0e3bb8daf2cd5f7cc6fec9a5570dccd1eda696c591902202ecbbf3c9d0757be7b23c8b1cc6481c51600d158756c47fcb6f4a7f4893e31c4', - 'signSignature': '304402201fed4858d0806dd32220960900a871dd2f60e1f623af75feef9b1034a9a0a46402205a29b27c63fcc3e1ee1e77ecbbf4dd6e7db09901e7a09b9fd490cd68d62392cb', - 'id': 'd2faf992fdd5da96d6d15038b6ddb65230338fa2096e45e44da51daad5e2f3ca', - 'senderId': 'DB8LnnQqYvHpG4WkGJ9AJWBYEct7G3yRZg', - 'hop': 2, - 'broadcast': false, - 'blockId': '7176646138626297930' - } - ] - } + id: '7176646138626297930', + version: 0, + height: 2243161, + timestamp: 24760440, + previousBlock: '3112633353705641986', + numberOfTransactions: 7, + totalAmount: '3890300', + totalFee: '70000000', + reward: '200000000', + payloadLength: 224, + payloadHash: + '3784b953afcf936bdffd43fdf005b5732b49c1fc6b11e195c364c20b2eb06282', + generatorPublicKey: + '020f5df4d2bc736d12ce43af5b1663885a893fade7ee5e62b3cc59315a63e6a325', + blockSignature: + '3045022100eee6c37b5e592e99811d588532726353592923f347c701d52912e6d583443e400220277ffe38ad31e216ba0907c4738fed19b2071246b150c72c0a52bae4477ebe29', + transactions: [ + { + type: 0, + amount: 555760, + fee: 10000000, + recipientId: 'DB4gFuDztmdGALMb8i1U4Z4R5SktxpNTAY', + timestamp: 24760418, + asset: {}, + vendorField: 'Goose Voter - True Block Weight', + senderPublicKey: + '0265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c0', + signature: + '304402204f12469157b19edd06ba25fcad3d4a5ef5b057c23f9e02de4641e6f8eef0553e022010121ab282f83efe1043de9c16bbf2c6845a03684229a0d7c965ffb9abdfb978', + signSignature: + '30450221008327862f0b9178d6665f7d6674978c5caf749649558d814244b1c66cdf945c40022015918134ef01fed3fe2a2efde3327917731344332724522c75c2799a14f78717', + id: + '170543154a3b79459cbaa529f9f62b6f1342682799eb549dbf09fcca2d1f9c11', + senderId: 'DB8LnnQqYvHpG4WkGJ9AJWBYEct7G3yRZg', + hop: 2, + broadcast: false, + blockId: '7176646138626297930', + }, + { + type: 0, + amount: 555750, + fee: 10000000, + recipientId: 'DGExsNogZR7JFa2656ZFP9TMWJYJh5djzQ', + timestamp: 24760416, + asset: {}, + vendorField: 'Goose Voter - True Block Weight', + senderPublicKey: + '0265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c0', + signature: + '304402205f82feb8c5d1d79c565c2ff7badb93e4c9827b132d135dda11cb25427d4ef8ac02205ff136f970533c4ec4c7d0cd1ea7e02d7b62629b66c6c93265f608d7f2389727', + signSignature: + '304402207e912031fcc700d8a55fbc415993302a0d8e6aea128397141b640b6dba52331702201fd1ad3984e42af44f548907add6cb7ad72ca0070c8cc1d8dc9bbda208c56bd9', + id: + '1da153f37eceda233ff1b407ac18e47b3cae47c14cdcd5297d929618a916c4a7', + senderId: 'DB8LnnQqYvHpG4WkGJ9AJWBYEct7G3yRZg', + hop: 2, + broadcast: false, + blockId: '7176646138626297930', + }, + { + type: 0, + amount: 555770, + fee: 10000000, + recipientId: 'DHGK5np6LuMMErfRfC5CmjpGu3ME85c25n', + timestamp: 24760420, + asset: {}, + vendorField: 'Goose Voter - True Block Weight', + senderPublicKey: + '0265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c0', + signature: + '304502210083216e6969e068770e6d2fe5c244881002309df84d20290ddf3f858967ed010202202a479b3da5080ea475d310ff13494654b42db75886a8808bd211b4bdb9146a7a', + signSignature: + '3045022100e1dcab3406bbeb968146a4a391909ce41df9b71592a753b001e7c2ee1d382c5102202a74aeafd4a152ec61854636fbae829c41f1416c1e0637a0809408394973099f', + id: + '1e255f07dc25ce22d900ea81663c8f00d05a7b7c061e6fc3c731b05d642fa0b9', + senderId: 'DB8LnnQqYvHpG4WkGJ9AJWBYEct7G3yRZg', + hop: 2, + broadcast: false, + blockId: '7176646138626297930', + }, + { + type: 0, + amount: 555750, + fee: 10000000, + recipientId: 'D7pcLJNGe197ibmWEmT8mM9KKU1htrcDyW', + timestamp: 24760417, + asset: {}, + vendorField: 'Goose Voter - True Block Weight', + senderPublicKey: + '0265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c0', + signature: + '3045022100cd4fa9855227be11e17201419dacfbbd5d9946df8d6792a9488160025693821402207fb83969bad6a26959f437b5bb88e255b0a48eb04964d0c0d29f7ee94bd15e11', + signSignature: + '304402205f50c2991a17743d17ffbb09159cadc35a3f848044261842879ccf5be9d81c5e022023bf21c32fb6e94494104f15f8d3a942ab120d0abd6fb4c93790b68e1b307a79', + id: + '66336c61d6ec623f8a1d2fd156a0fac16a4fe93bb3fba337859355c2119923a8', + senderId: 'DB8LnnQqYvHpG4WkGJ9AJWBYEct7G3yRZg', + hop: 2, + broadcast: false, + blockId: '7176646138626297930', + }, + { + type: 0, + amount: 555760, + fee: 10000000, + recipientId: 'DD4yhwzryQdNGqKtezmycToQv63g27Tqqq', + timestamp: 24760418, + asset: {}, + vendorField: 'Goose Voter - True Block Weight', + senderPublicKey: + '0265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c0', + signature: + '30450221009c792062e13399ac6756b2e9f137194d06e106360ac0f3e24e55c7249cee0b3602205dc1d9c76d0451d1cb5a2396783a13e6d2d790ccfd49291e3d0a78349f7ea0e8', + signSignature: + '30440220083ba8a9af49b8be6e93794d71ec43ffc96a158375810e5d9f2478e71655315b0220278402ecaa1d224dab9f0f3b28295bbaea339c85c7400edafdc49df87439fc64', + id: + '78db36f7d79f51c67d7210ee3819dfb8d0d47b16a7484ebf55c5a055b17209a3', + senderId: 'DB8LnnQqYvHpG4WkGJ9AJWBYEct7G3yRZg', + hop: 2, + broadcast: false, + blockId: '7176646138626297930', + }, + { + type: 0, + amount: 555760, + fee: 10000000, + recipientId: 'D5LiYGXL5keycWuTF6AFFwSRc6Mt4uEHMu', + timestamp: 24760419, + asset: {}, + vendorField: 'Goose Voter - True Block Weight', + senderPublicKey: + '0265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c0', + signature: + '3044022063c65263e42be02bd9831b375c1d76a88332f00ed0557ecc1e7d2375ca40070902206797b5932c0bad68444beb5a38daa7cadf536ee2144e0d9777b812284d14374e', + signSignature: + '3045022100b04da6692f75d43229ffd8486c1517e8952d38b4c03dfac38b6b360190a5c33e0220776622e5f09f92a1258b4a011f22181c977b622b8d1bbb2f83b42f4126d00739', + id: + '83c80bb58777bb43f5037544b44ef69f191d3548fd1b2a00bed368f9f0d694c5', + senderId: 'DB8LnnQqYvHpG4WkGJ9AJWBYEct7G3yRZg', + hop: 2, + broadcast: false, + blockId: '7176646138626297930', + }, + { + type: 0, + amount: 555750, + fee: 10000000, + recipientId: 'DPopNLwMvv4zSjdZnqUk8HFH13Mcb7NbEK', + timestamp: 24760416, + asset: {}, + vendorField: 'Goose Voter - True Block Weight', + senderPublicKey: + '0265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c0', + signature: + '3045022100d4513c3608c2072e38e7a0e3bb8daf2cd5f7cc6fec9a5570dccd1eda696c591902202ecbbf3c9d0757be7b23c8b1cc6481c51600d158756c47fcb6f4a7f4893e31c4', + signSignature: + '304402201fed4858d0806dd32220960900a871dd2f60e1f623af75feef9b1034a9a0a46402205a29b27c63fcc3e1ee1e77ecbbf4dd6e7db09901e7a09b9fd490cd68d62392cb', + id: + 'd2faf992fdd5da96d6d15038b6ddb65230338fa2096e45e44da51daad5e2f3ca', + senderId: 'DB8LnnQqYvHpG4WkGJ9AJWBYEct7G3yRZg', + hop: 2, + broadcast: false, + blockId: '7176646138626297930', + }, + ], + } const s = Block.serializeFull(b).toString('hex') - const serialized = '0000000078d07901593a22002b324b8b33a85802070000007c5c3b0000000000801d2c040000000000c2eb0b00000000e00000003784b953afcf936bdffd43fdf005b5732b49c1fc6b11e195c364c20b2eb06282020f5df4d2bc736d12ce43af5b1663885a893fade7ee5e62b3cc59315a63e6a3253045022100eee6c37b5e592e99811d588532726353592923f347c701d52912e6d583443e400220277ffe38ad31e216ba0907c4738fed19b2071246b150c72c0a52bae4477ebe29ff000000fe00000000010000ff000000ff000000ff000000ff000000ff011e0062d079010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000001f476f6f736520566f746572202d205472756520426c6f636b20576569676874f07a080000000000000000001e40fad23d21da7a4fd4decb5c49726ea22f5e6bf6304402204f12469157b19edd06ba25fcad3d4a5ef5b057c23f9e02de4641e6f8eef0553e022010121ab282f83efe1043de9c16bbf2c6845a03684229a0d7c965ffb9abdfb97830450221008327862f0b9178d6665f7d6674978c5caf749649558d814244b1c66cdf945c40022015918134ef01fed3fe2a2efde3327917731344332724522c75c2799a14f78717ff011e0060d079010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000001f476f6f736520566f746572202d205472756520426c6f636b20576569676874e67a080000000000000000001e79c579fb08f448879c22fe965906b4e3b88d02ed304402205f82feb8c5d1d79c565c2ff7badb93e4c9827b132d135dda11cb25427d4ef8ac02205ff136f970533c4ec4c7d0cd1ea7e02d7b62629b66c6c93265f608d7f2389727304402207e912031fcc700d8a55fbc415993302a0d8e6aea128397141b640b6dba52331702201fd1ad3984e42af44f548907add6cb7ad72ca0070c8cc1d8dc9bbda208c56bd9ff011e0064d079010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000001f476f6f736520566f746572202d205472756520426c6f636b20576569676874fa7a080000000000000000001e84fee45dde2b11525afe192a2e991d014ff93a36304502210083216e6969e068770e6d2fe5c244881002309df84d20290ddf3f858967ed010202202a479b3da5080ea475d310ff13494654b42db75886a8808bd211b4bdb9146a7a3045022100e1dcab3406bbeb968146a4a391909ce41df9b71592a753b001e7c2ee1d382c5102202a74aeafd4a152ec61854636fbae829c41f1416c1e0637a0809408394973099fff011e0061d079010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000001f476f6f736520566f746572202d205472756520426c6f636b20576569676874e67a080000000000000000001e1d69583ede5ee82d220e74bffb36bae2ce762dfb3045022100cd4fa9855227be11e17201419dacfbbd5d9946df8d6792a9488160025693821402207fb83969bad6a26959f437b5bb88e255b0a48eb04964d0c0d29f7ee94bd15e11304402205f50c2991a17743d17ffbb09159cadc35a3f848044261842879ccf5be9d81c5e022023bf21c32fb6e94494104f15f8d3a942ab120d0abd6fb4c93790b68e1b307a79ff011e0062d079010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000001f476f6f736520566f746572202d205472756520426c6f636b20576569676874f07a080000000000000000001e56f9a37a859f4f84e93ce7593e809b15a524db2930450221009c792062e13399ac6756b2e9f137194d06e106360ac0f3e24e55c7249cee0b3602205dc1d9c76d0451d1cb5a2396783a13e6d2d790ccfd49291e3d0a78349f7ea0e830440220083ba8a9af49b8be6e93794d71ec43ffc96a158375810e5d9f2478e71655315b0220278402ecaa1d224dab9f0f3b28295bbaea339c85c7400edafdc49df87439fc64ff011e0063d079010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000001f476f6f736520566f746572202d205472756520426c6f636b20576569676874f07a080000000000000000001e0232a083c16aba4362dddec1b3050ffdd6d43f2e3044022063c65263e42be02bd9831b375c1d76a88332f00ed0557ecc1e7d2375ca40070902206797b5932c0bad68444beb5a38daa7cadf536ee2144e0d9777b812284d14374e3045022100b04da6692f75d43229ffd8486c1517e8952d38b4c03dfac38b6b360190a5c33e0220776622e5f09f92a1258b4a011f22181c977b622b8d1bbb2f83b42f4126d00739ff011e0060d079010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000001f476f6f736520566f746572202d205472756520426c6f636b20576569676874e67a080000000000000000001eccc4fce0dc95f9951ee40c09a7ae807746cf51403045022100d4513c3608c2072e38e7a0e3bb8daf2cd5f7cc6fec9a5570dccd1eda696c591902202ecbbf3c9d0757be7b23c8b1cc6481c51600d158756c47fcb6f4a7f4893e31c4304402201fed4858d0806dd32220960900a871dd2f60e1f623af75feef9b1034a9a0a46402205a29b27c63fcc3e1ee1e77ecbbf4dd6e7db09901e7a09b9fd490cd68d62392cb' + const serialized = + '0000000078d07901593a22002b324b8b33a85802070000007c5c3b0000000000801d2c040000000000c2eb0b00000000e00000003784b953afcf936bdffd43fdf005b5732b49c1fc6b11e195c364c20b2eb06282020f5df4d2bc736d12ce43af5b1663885a893fade7ee5e62b3cc59315a63e6a3253045022100eee6c37b5e592e99811d588532726353592923f347c701d52912e6d583443e400220277ffe38ad31e216ba0907c4738fed19b2071246b150c72c0a52bae4477ebe29ff000000fe00000000010000ff000000ff000000ff000000ff000000ff011e0062d079010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000001f476f6f736520566f746572202d205472756520426c6f636b20576569676874f07a080000000000000000001e40fad23d21da7a4fd4decb5c49726ea22f5e6bf6304402204f12469157b19edd06ba25fcad3d4a5ef5b057c23f9e02de4641e6f8eef0553e022010121ab282f83efe1043de9c16bbf2c6845a03684229a0d7c965ffb9abdfb97830450221008327862f0b9178d6665f7d6674978c5caf749649558d814244b1c66cdf945c40022015918134ef01fed3fe2a2efde3327917731344332724522c75c2799a14f78717ff011e0060d079010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000001f476f6f736520566f746572202d205472756520426c6f636b20576569676874e67a080000000000000000001e79c579fb08f448879c22fe965906b4e3b88d02ed304402205f82feb8c5d1d79c565c2ff7badb93e4c9827b132d135dda11cb25427d4ef8ac02205ff136f970533c4ec4c7d0cd1ea7e02d7b62629b66c6c93265f608d7f2389727304402207e912031fcc700d8a55fbc415993302a0d8e6aea128397141b640b6dba52331702201fd1ad3984e42af44f548907add6cb7ad72ca0070c8cc1d8dc9bbda208c56bd9ff011e0064d079010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000001f476f6f736520566f746572202d205472756520426c6f636b20576569676874fa7a080000000000000000001e84fee45dde2b11525afe192a2e991d014ff93a36304502210083216e6969e068770e6d2fe5c244881002309df84d20290ddf3f858967ed010202202a479b3da5080ea475d310ff13494654b42db75886a8808bd211b4bdb9146a7a3045022100e1dcab3406bbeb968146a4a391909ce41df9b71592a753b001e7c2ee1d382c5102202a74aeafd4a152ec61854636fbae829c41f1416c1e0637a0809408394973099fff011e0061d079010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000001f476f6f736520566f746572202d205472756520426c6f636b20576569676874e67a080000000000000000001e1d69583ede5ee82d220e74bffb36bae2ce762dfb3045022100cd4fa9855227be11e17201419dacfbbd5d9946df8d6792a9488160025693821402207fb83969bad6a26959f437b5bb88e255b0a48eb04964d0c0d29f7ee94bd15e11304402205f50c2991a17743d17ffbb09159cadc35a3f848044261842879ccf5be9d81c5e022023bf21c32fb6e94494104f15f8d3a942ab120d0abd6fb4c93790b68e1b307a79ff011e0062d079010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000001f476f6f736520566f746572202d205472756520426c6f636b20576569676874f07a080000000000000000001e56f9a37a859f4f84e93ce7593e809b15a524db2930450221009c792062e13399ac6756b2e9f137194d06e106360ac0f3e24e55c7249cee0b3602205dc1d9c76d0451d1cb5a2396783a13e6d2d790ccfd49291e3d0a78349f7ea0e830440220083ba8a9af49b8be6e93794d71ec43ffc96a158375810e5d9f2478e71655315b0220278402ecaa1d224dab9f0f3b28295bbaea339c85c7400edafdc49df87439fc64ff011e0063d079010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000001f476f6f736520566f746572202d205472756520426c6f636b20576569676874f07a080000000000000000001e0232a083c16aba4362dddec1b3050ffdd6d43f2e3044022063c65263e42be02bd9831b375c1d76a88332f00ed0557ecc1e7d2375ca40070902206797b5932c0bad68444beb5a38daa7cadf536ee2144e0d9777b812284d14374e3045022100b04da6692f75d43229ffd8486c1517e8952d38b4c03dfac38b6b360190a5c33e0220776622e5f09f92a1258b4a011f22181c977b622b8d1bbb2f83b42f4126d00739ff011e0060d079010265c1f6b8c1966a90f3fed7bc32fd4f42238ab4938fdb2a4e7ddd01ae8b58b4c080969800000000001f476f6f736520566f746572202d205472756520426c6f636b20576569676874e67a080000000000000000001eccc4fce0dc95f9951ee40c09a7ae807746cf51403045022100d4513c3608c2072e38e7a0e3bb8daf2cd5f7cc6fec9a5570dccd1eda696c591902202ecbbf3c9d0757be7b23c8b1cc6481c51600d158756c47fcb6f4a7f4893e31c4304402201fed4858d0806dd32220960900a871dd2f60e1f623af75feef9b1034a9a0a46402205a29b27c63fcc3e1ee1e77ecbbf4dd6e7db09901e7a09b9fd490cd68d62392cb' const block1 = new Block(b) const block2 = new Block(Block.deserialize(serialized)) @@ -291,8 +371,76 @@ describe('Models - Block', () => { }) }) + describe('should reorder correctly transactions in deserialization', () => { + const issue = { + version: 0, + timestamp: 25029544, + height: 3084276, + previousBlockHex: '63b315f3663e4299', + previousBlock: '7184109965722665625', + numberOfTransactions: 2, + totalAmount: 0, + totalFee: 600000000, + reward: 200000000, + payloadLength: 64, + payloadHash: + 'c2fa2d400b4c823873d476f6e0c9e423cf925e9b48f1b5706c7e2771d4095538', + generatorPublicKey: + '02fa6902e91e127d6d3410f6abc271a79ae24029079caa0db5819757e3c1c1c5a4', + blockSignature: + '30440220543f71d6f6445b703459b4f91d2c6f2446cbe6669e9c9008b1c77cc57073af2402206036fee3b434ffd5a31a579dd5b514a1c6384962291fda27b2463de903422834', + id: '11773170219525190460', + transactions: [ + { + type: 3, + network: 0x17, + timestamp: 25028325, + senderPublicKey: + '02aadc3e0993c1d3447db27741745eb9c2c6522cccf02fc8efe3bf2d49708243dd', + fee: 100000000, + amount: 0, + asset: { + votes: [ + '+020431436cf94f3c6a6ba566fe9e42678db8486590c732ca6c3803a10a86f50b92', + ], + }, + signature: + '3045022100be28bdd7dc7117de903eccf97e3afbe87e1a32ee25b0b9bf814b35c6773ed51802202c8d62e708aa7afc08dbfcfd4640d105fe97337fb6145a8d916f2ce11c920255', + recipientId: 'ANYiQJSPSoDT8U9Quh5vU8timD2RM7RS38', + id: + 'bace38ea544678f951cdd4abc269be24b4f5bab925ff6d5b480657952eb5aa65', + }, + { + id: + '7a1a43098cd253db395514220f69e3b99afaabb2bfcf5ecfa3b99727b367344b', + network: 0x17, + type: 1, + timestamp: 25028279, + fee: 500000000, + amount: 0, + senderPublicKey: + '02aadc3e0993c1d3447db27741745eb9c2c6522cccf02fc8efe3bf2d49708243dd', + signature: + '3044022071f4f5281ba7be76e43df4ea9e74f820da761e1f9f3b168b3a6e42c55ccf343a02203629d94845709e31be20943e2cd26637f0d8ccfb4a59764d45c161a942def069', + asset: { + signature: { + publicKey: + '02135e2ebd97d1f1ab5141b4269defc6e5650848062c40baaf869d72571526e6c6', + }, + }, + }, + ], + } + + const block = new Block(issue) + expect(block.data.id).toBe(issue.id) + expect(block.transactions[0].id).toBe(issue.transactions[1].id) + }) + describe('v1 fix', () => { - const { outlookTable } = require('../../lib/constants').CONFIGURATIONS.ARK.MAINNET + const { + outlookTable, + } = require('../../lib/constants').CONFIGURATIONS.ARK.MAINNET const table = { '5139199631254983076': '1000099631254983076', '4683900276587456793': '1000000276587456793', @@ -329,7 +477,7 @@ describe('Models - Block', () => { '2222163236406460530': '1000063236406460530', '5059382813585250340': '1000082813585250340', '7091362542116598855': '1000062542116598855', - '8225244493039935740': '1000044493039935740' + '8225244493039935740': '1000044493039935740', } describe('outlook table', () => { @@ -342,13 +490,16 @@ describe('Models - Block', () => { }) describe('apply v1 fix', () => { it('should not process a common block', () => { - let mock = { + const mock = { id: '187940162505562345', - blockSignature: '3045022100a6605198e0f590c88798405bc76748d84e280d179bcefed2c993e70cded2a5dd022008c7f915b89fc4f3250fc4b481abb753c68f30ac351871c50bd6cfaf151370e8', // eslint-disable-line max-len - generatorPublicKey: '024c8247388a02ecd1de2a3e3fd5b7c61ecc2797fa3776599d558333ef1802d231', + blockSignature: + '3045022100a6605198e0f590c88798405bc76748d84e280d179bcefed2c993e70cded2a5dd022008c7f915b89fc4f3250fc4b481abb753c68f30ac351871c50bd6cfaf151370e8', // eslint-disable-line max-len + generatorPublicKey: + '024c8247388a02ecd1de2a3e3fd5b7c61ecc2797fa3776599d558333ef1802d231', height: 10, numberOfTransactions: 0, - payloadHash: '578e820911f24e039733b45e4882b73e301f813a0d2c31330dafda84534ffa23', + payloadHash: + '578e820911f24e039733b45e4882b73e301f813a0d2c31330dafda84534ffa23', payloadLength: 1, previousBlock: '12123', reward: 1, @@ -356,19 +507,22 @@ describe('Models - Block', () => { totalAmount: 10, totalFee: 1, transactions: [], - version: 6 + version: 6, } const blk = new Block(mock) expect(blk.data.id).toBe(mock.id) }) it('should process a matching id', () => { - let mock2 = { + const mock2 = { id: '8225244493039935740', - blockSignature: '3045022100a6605198e0f590c88798405bc76748d84e280d179bcefed2c993e70cded2a5dd022008c7f915b89fc4f3250fc4b481abb753c68f30ac351871c50bd6cfaf151370e8', // eslint-disable-line max-len - generatorPublicKey: '024c8247388a02ecd1de2a3e3fd5b7c61ecc2797fa3776599d558333ef1802d231', + blockSignature: + '3045022100a6605198e0f590c88798405bc76748d84e280d179bcefed2c993e70cded2a5dd022008c7f915b89fc4f3250fc4b481abb753c68f30ac351871c50bd6cfaf151370e8', // eslint-disable-line max-len + generatorPublicKey: + '024c8247388a02ecd1de2a3e3fd5b7c61ecc2797fa3776599d558333ef1802d231', height: 10, numberOfTransactions: 0, - payloadHash: '578e820911f24e039733b45e4882b73e301f813a0d2c31330dafda84534ffa23', + payloadHash: + '578e820911f24e039733b45e4882b73e301f813a0d2c31330dafda84534ffa23', payloadLength: 1, previousBlock: '12123', reward: 1, @@ -376,7 +530,7 @@ describe('Models - Block', () => { totalAmount: 10, totalFee: 1, transactions: [], - version: 6 + version: 6, } const blk2 = new Block(mock2) expect(blk2.data.id).not.toBe(mock2.id) diff --git a/packages/crypto/__tests__/models/delegate.test.js b/packages/crypto/__tests__/models/delegate.test.js index d05af22854..2b37328658 100644 --- a/packages/crypto/__tests__/models/delegate.test.js +++ b/packages/crypto/__tests__/models/delegate.test.js @@ -1,12 +1,17 @@ +const Bignum = require('../../lib/utils/bignum') const Wallet = require('../../lib/models/wallet') +const { ARKTOSHI } = require('../../lib/constants') const sortTransactions = require('../../lib/utils/sort-transactions') +const configManager = require('../../lib/managers/config') describe('Models - Delegate', () => { describe('static sortTransactions', () => { it('returns the transactions ordered by type and id', () => { const ordered = [ - { type: 1, id: 2 }, { type: 1, id: 8 }, - { type: 2, id: 5 }, { type: 2, id: 9 } + { type: 1, id: 2 }, + { type: 1, id: 8 }, + { type: 2, id: 5 }, + { type: 2, id: 9 }, ] const unordered = [ordered[3], ordered[2], ordered[1], ordered[0]] @@ -16,12 +21,14 @@ describe('Models - Delegate', () => { describe('forge', () => { describe('without version option', () => { - it('doesn\'t sort the transactions', () => { + it("doesn't sort the transactions", () => { const address = 'Abcde' const wallet = new Wallet(address) - wallet.balance = 10 ** 8 + wallet.balance = new Bignum(ARKTOSHI) - expect(wallet.toString()).toBe(`${address}=1`) + expect(wallet.toString()).toBe( + `${address} (1 ${configManager.config.client.symbol})`, + ) }) // TODO probably useful for debugging diff --git a/packages/crypto/__tests__/models/fixtures/multi-transaction.js b/packages/crypto/__tests__/models/fixtures/multi-transaction.js index c227b42d13..89be35c1dd 100644 --- a/packages/crypto/__tests__/models/fixtures/multi-transaction.js +++ b/packages/crypto/__tests__/models/fixtures/multi-transaction.js @@ -3,7 +3,8 @@ module.exports = { network: 30, type: 4, timestamp: 25921690, - senderPublicKey: '02337316a26d8d49ec27059bd0589c49ba474029c3627715380f4df83fb431aece', + senderPublicKey: + '02337316a26d8d49ec27059bd0589c49ba474029c3627715380f4df83fb431aece', fee: 9000000000, vendorFieldHex: '776c386c777473386a65', asset: { @@ -25,9 +26,9 @@ module.exports = { '+03136f2101f1767b0d63d9545410bcaf3a941b2b6f06851093f3c679e0d31ca1cd', '+02e6ec3941be86177bf0b998589c07da1b73e990466fdaee347c972c10f61b3797', '+037dcd05d921a9f2ddd11960fec2ea9904fc55cad030549a6c5f5a41b2e35e56d2', - '+03206f7ae26f14cffb62b8c28b5e632952cdeb84b7c74ac0c2198b08bd84ee4f23' - ] - } + '+03206f7ae26f14cffb62b8c28b5e632952cdeb84b7c74ac0c2198b08bd84ee4f23', + ], + }, }, signature: '3045022100c59d8efdd95010b0368963e492e8f7da1a3f6993b0723724f84aeccf658ea9a30220103d2b4ac07ad808b4ea79829a0081992586c6ef73892cfa7510ab37f0093bcd', // eslint-disable-line max-len @@ -48,12 +49,12 @@ module.exports = { '3044022047838187fcd1c79059ab53769678940e634400cf7431337a7e27e30bc17ac39702200d2cb974f44239b0edbb7c10096d5d7b682d0788dc3f8d0f5061373f4eefdff8', // eslint-disable-line max-len '3044022057bbd8432154bf72244f987c5b4c49ba094a0e4abffc3644ba91c5ce1b79712a0220708a2743d4b4ab1d9379bcd60acf70b63e16cd24b95cd142a0b3ced0d43e6cb8', // eslint-disable-line max-len '304502210097e1a36e47422455f030fa5f79153a4c49d25a2fb487837462b7f9d0fa3bd436022008a212ce0dfa18543987a1381b1261652d76e49f923e0b2ac79073b22367b3a5', // eslint-disable-line max-len - '304402201cbe68b0383c243cf61a9af9142746688b85f6ee106815906d9d8c4d717837aa022038c1eb4e06b90e24b44903de18c3f260e8be945b84126c9a048794f830b9f272' // eslint-disable-line max-len + '304402201cbe68b0383c243cf61a9af9142746688b85f6ee106815906d9d8c4d717837aa022038c1eb4e06b90e24b44903de18c3f260e8be945b84126c9a048794f830b9f272', // eslint-disable-line max-len ], amount: 0, signSignature: '3044022059ab88d3fe83d6b52ddd5e863696416168f9cac6de962368587ad7343542f99f02207a95ca473006ab57dee6b06e06f8fa8f1b260548b9226614a0e1f760cc910479', // eslint-disable-line max-len vendorField: 'wl8lwts8je', recipientId: 'D61xc3yoBQDitwjqUspMPx1ooET6r1XLt7', - id: '95199581d640eda97ea810fc3248e34f6e5ab1d8c9802e64a50b930f4ff044ab' + id: '95199581d640eda97ea810fc3248e34f6e5ab1d8c9802e64a50b930f4ff044ab', } diff --git a/packages/crypto/__tests__/models/fixtures/transaction.js b/packages/crypto/__tests__/models/fixtures/transaction.js index b76c385c32..6137dd8bf9 100644 --- a/packages/crypto/__tests__/models/fixtures/transaction.js +++ b/packages/crypto/__tests__/models/fixtures/transaction.js @@ -1,29 +1,30 @@ module.exports = { version: 1, - network: 23, + network: 30, type: 4, - timestamp: 10112114, - senderPublicKey: '036928c98ee53a1f52ed01dd87db10ffe1980eb47cd7c0a7d688321f47b5d7d760', + timestamp: 48069935, + senderPublicKey: + '023b31dd57d9025a538ed6433c8e0d339abba3084612e8bbbe09a240e0208b33c9', fee: 2000000000, asset: { multisignature: { - min: 2, - lifetime: 24, keysgroup: [ - '+03543c6cc3545be6bac09c82721973a052c690658283472e88f24d14739f75acc8', - '+0276dc5b8706a85ca9fdc46e571ac84e52fbb48e13ec7a165a80731b44ae89f1fc', - '+02e8d5d17eb17bbc8d7bf1001d29a2d25d1249b7bb7a5b7ad8b7422063091f4b31' - ] - } + '+02db1d199f20038e569500895b3521a453b2924e4a07c75aa9f7bf2aa4ad71392d', + '+02a7442df1f6cbef57d84c9c0eff248f9af48370384987de90bdcebd000feccdb6', + '+037a9458c87080768f79c4320941fdc64c9fe580673f17358125b93e80bd0b1d27', + ], + min: 3, + lifetime: 72, + }, }, + signature: + '3045022100874eed54c9b4e8e41e47cfa340b38b87d6a16469d67462b066aea51fb3a8918d02205d812e19f382cfee5f9ce3bc98abc050f5aaa8262d9a2bf24d5cb117840d2948', signatures: [ - '304502210097f17c8eecf36f86a967cc52a83fa661e4ffc70cc4ea08df58673669406d424c0220798f5710897b75dda42f6548f841afbe4ed1fa262097112cf5a1b3f7dade60e4', // eslint-disable-line max-len - '304402201a4a4c718bfdc699bbb891b2e89be018027d2dcd10640b5ddf07802424dab78e02204ec7c7d505d2158c3b51fdd3843d16aecd2eaaa4c6c7a555ef123c5e59fd41fb', // eslint-disable-line max-len - '304402207e660489bced5ce80c33d45c86781b63898775ab4a231bb48780f97b40073a63022026f0cefd0d83022d822522ab4366a82e3b89085c328817919939f2efeabd913d' // eslint-disable-line max-len + '3044022022fb3b1d48d9e4905ab566949d637f0832dd0ab6f2cb67a620496e23e83a86d902203182ad967d22db258f97f9fab6d3856c29738ae745eb2f40eb5d472722b794b9', + '3045022100aef482ecaea6ecaf8e6f86bd7ac474458e657614b3eb9e440789549d1ea85f6002205c75763411e0febb7d11a7ccf7cb826fc11ddbe3722b73f77e22e9f0919e179d', + '3045022100e1dff5c0a4289ffee8caa79fd25fe86f0ded4daaeb9f25e123ea327b01fdb9710220476da4d177652fe4a375e414089ce8c86800bcc4ca6ce0b6d974ef98d8c9d4cf', ], - signature: '30440220324d89c5792e4a54ae70b4f1e27e2f87a8b7169cc6f2f7b2c83dba894960f987022053b8d0ae23ff9d1769364db7b6fd03216d93753c82a711c3558045e787bc01a5', // eslint-disable-line max-len amount: 0, - signSignature: '304402201fcd54a9ac9c0269b8cec213566ddf43207798e2cf9ca1ce3c5d315d66321c6902201aa94c4ed3e5e479a12220aa886b259e488eb89b697c711f91e8c03b9620e0b1', // eslint-disable-line max-len - secondSignature: '304402201fcd54a9ac9c0269b8cec213566ddf43207798e2cf9ca1ce3c5d315d66321c6902201aa94c4ed3e5e479a12220aa886b259e488eb89b697c711f91e8c03b9620e0b1', // eslint-disable-line max-len - id: 'cbd6862966bb1b03ba742397b7e5a88d6eefb393a362ead0d605723b840db2af' + recipientId: 'DJLxkgm7JMortrGVh1ZrvDH39XALWLa83e', + id: '115d68cd8a8a9e589ddd51b721085831ce9472273b64b14e195e31dfbab4bf4e', } diff --git a/packages/crypto/__tests__/models/transaction.test.js b/packages/crypto/__tests__/models/transaction.test.js index 02051a6e1a..ecb9be6d09 100644 --- a/packages/crypto/__tests__/models/transaction.test.js +++ b/packages/crypto/__tests__/models/transaction.test.js @@ -1,8 +1,6 @@ const Transaction = require('../../lib/models/transaction') const builder = require('../../lib/builder') const crypto = require('../../lib/crypto/crypto') -const ECPair = require('../../lib/crypto/ecpair') -const ECSignature = require('../../lib/crypto/ecsignature') const transactionData = require('./fixtures/transaction') const configManager = require('../../lib/managers/config') @@ -12,44 +10,57 @@ const createRandomTx = type => { let transaction switch (type) { - case 0: // transfer + case 0: { + // transfer transaction = builder .transfer() .recipientId('AMw3TiLrmVmwmFVwRzn96kkUsUpFTqsAEX') - .amount(1000 * Math.pow(10, 10)) + .amount(1000 * 1e10) .vendorField(Math.random().toString(36)) .sign(Math.random().toString(36)) .secondSign(Math.random().toString(36)) .build() break + } - case 1: // second signature + case 1: { + // second signature transaction = builder .secondSignature() .signatureAsset(Math.random().toString(36)) .sign(Math.random().toString(36)) .build() break + } - case 2: // delegate registration + case 2: { + // delegate registration transaction = builder .delegateRegistration() .usernameAsset('dummy-delegate') .sign(Math.random().toString(36)) .build() break + } - case 3: // vote registration + case 3: { + // vote registration transaction = builder .vote() - .votesAsset(['+036928c98ee53a1f52ed01dd87db10ffe1980eb47cd7c0a7d688321f47b5d7d760']) + .votesAsset([ + '+036928c98ee53a1f52ed01dd87db10ffe1980eb47cd7c0a7d688321f47b5d7d760', + ]) .sign(Math.random().toString(36)) .build() break + } - case 4: // multisignature registration + case 4: { + // multisignature registration const passphrases = [1, 2, 3].map(() => Math.random().toString(36)) - const publicKeys = passphrases.map(passphrase => '+' + crypto.getKeys(passphrase).publicKey) + const publicKeys = passphrases.map( + passphrase => `+${crypto.getKeys(passphrase).publicKey}`, + ) const min = Math.min(1, publicKeys.length) const max = Math.max(1, publicKeys.length) const minSignatures = Math.floor(Math.random() * (max - min)) + min @@ -59,7 +70,7 @@ const createRandomTx = type => { .multiSignatureAsset({ keysgroup: publicKeys, min: minSignatures, - lifetime: Math.floor(Math.random() * (72 - 1)) + 1 + lifetime: Math.floor(Math.random() * (72 - 1)) + 1, }) .sign(Math.random().toString(36)) @@ -68,90 +79,166 @@ const createRandomTx = type => { } transaction = transactionBuilder.build() + break + } + default: { + throw new Error('Invalid transaction type') + } } return transaction } -const verifyEcdsaNonMalleability = (transaction) => { - const ecurve = require('ecurve') - const secp256k1 = ecurve.getCurveByName('secp256k1') - const n = secp256k1.n - const hash = crypto.getHash(transaction, true, true) - - const signatureBuffer = Buffer.from(transaction.signature, 'hex') - const senderPublicKeyBuffer = Buffer.from(transaction.senderPublicKey, 'hex') - const ecpair = ECPair.fromPublicKeyBuffer(senderPublicKeyBuffer, transaction.network) - const ecsignature = ECSignature.fromDER(signatureBuffer) - const ecs2 = ECSignature.fromDER(signatureBuffer) - ecs2.s = n.subtract(ecs2.s) - const result1 = ecpair.verify(hash, ecsignature) - const result2 = ecpair.verify(hash, ecs2) - return result1 === true && result2 === false -} - describe('Models - Transaction', () => { beforeEach(() => configManager.setConfig(network)) describe('static fromBytes', () => { - it('returns a new transaction', () => { - [0, 1, 2, 3, 4].map(type => createRandomTx(type)) - .map(transaction => { - transaction.version = 1 - - if (transaction.vendorField) { - transaction.vendorFieldHex = Buffer.from(transaction.vendorField, 'utf8').toString('hex') - transaction.data.vendorField = transaction.vendorField - } - - if (transaction.asset && transaction.asset.delegate) { - delete transaction.asset.delegate.publicKey - } - - if (transaction.type === 0) { - delete transaction.asset - transaction.expiration = 0 - transaction.data.expiration = 0 - } - - if (transaction.signSignature) { - transaction.secondSignature = transaction.signSignature - } - - if (!transaction.recipientId) { - delete transaction.recipientId - } - - return transaction - }) - .map(transaction => { - const newTransaction = Transaction.fromBytes(Transaction.serialize(transaction).toString('hex')) + it('should verify all transactions', () => { + ;[0, 1, 2, 3, 4] + .map(type => createRandomTx(type)) + .forEach(transaction => { + const ser = Transaction.serialize(transaction.data).toString('hex') + const newTransaction = Transaction.fromBytes(ser) expect(newTransaction.data).toEqual(transaction.data) - expect(newTransaction.verified).toBeTruthy() + expect(newTransaction.verified).toBeTrue() }) + }) + + it('should create a transaction', () => { const hex = Transaction.serialize(transactionData).toString('hex') const transaction = Transaction.fromBytes(hex) expect(transaction).toBeInstanceOf(Transaction) - expect(transaction.data).toEqual(transactionData) + + // We can't compare the data directly, since the created instance uses Bignums. + // ... call toJson() which casts the Bignums to numbers beforehand. + expect(transaction.toJson()).toEqual(transactionData) }) }) describe('static deserialize', () => { it('should match transaction id', () => { - [0, 1, 2, 3, 4].map(type => createRandomTx(type)) - .map(transaction => { - const originalId = transaction.id - const newTransaction = Transaction.deserialize(Transaction.serialize(transaction).toString('hex')) + ;[0, 1, 2, 3, 4] + .map(type => createRandomTx(type)) + .forEach(transaction => { + const originalId = transaction.data.id + const newTransaction = new Transaction(transaction.data) expect(newTransaction.id).toEqual(originalId) }) }) }) + describe('should deserialize correctly some tests transactions', () => { + const txs = [ + { + id: '80d75c7b90288246199e4a97ba726bad6639595ef92ad7c2bd14fd31563241ab', + network: 0x17, + height: 918991, + type: 1, + timestamp: 7410965, + amount: 0, + fee: 500000000, + recipientId: 'AP4UQ6j9hAHsxudpXh47RNQi7oF1AEfkAG', + senderPublicKey: + '03ca269b2942104b2ad601ccfbe7bd30b14b99cb55210ef7c1a5e25b6669646b99', + signature: + '3045022100d01e0cf0813a722ab5ad92aece2d4d1c3a537422e2ea769182f9172417224e890220437e407db51c4c47393db2e5b1258b2e3ecb707738a5ffdc6e96f08aee7e9c74', + asset: { + signature: { + publicKey: + '03c0e7e86dadd316275a31d84a1fdccd00cd26cc059982f95a1b24382c6ec2ceb0', + }, + }, + }, + { + id: '89f354918b36197269b0e5514f8da66f19829a024f664ccc124bfaabe0266e10', + version: 1, + timestamp: 48068690, + senderPublicKey: + '03b7d1da5c1b9f8efd0737d47123eb9cf7eb6d58198ef31bb6f01aa04bc4dda19d', + recipientId: 'DHPNjqCaTR9KYtC8nHh7Zt1G86Xj4YiU2V', + type: 1, + amount: '0', + fee: '500000000', + signature: + '3045022100e8e03bdac70e18f220feacba25c1575aa89d1ab61673e54eb2aff38439666d2702207e2d84290d7ef2571f5b2fab7e22a77dec96b1c4187cf9def15be74db98e2700', + asset: { + signature: { + publicKey: + '03b7d1da5c1b9f8efd0737d47123eb9cf7eb6d58198ef31bb6f01aa04bc4dda19d', + }, + }, + }, + { + id: 'a50af2bb1f043d128480346d0b49f5b3165716d5c630c6b0978dc7aa168e77a8', + version: 1, + timestamp: 48068923, + senderPublicKey: + '03173fd793c4bac0d64e9bd74ec5c2055716a7c0266feec9d6d94cb75be097b75d', + recipientId: 'DQrj9eh9otRgz2jWdu1K1ASBQqZA6dTkra', + type: 1, + amount: '0', + fee: '500000000', + signature: + '3045022100b263d28a5da58b17c874a5666afab0657f8492266554ad8ff722b00d41e1493d02200c2156dd9b9c1739f1c2099e98b763952bc7ef0423ad9786dcd32f7ffaf4aafc', + asset: { + signature: { + publicKey: + '03173fd793c4bac0d64e9bd74ec5c2055716a7c0266feec9d6d94cb75be097b75d', + }, + }, + }, + { + id: '68e34dc1c417cbfb47e5deea142974bc24c8d03df206f168c8b23d6a4decff73', + version: 1, + timestamp: 48068956, + senderPublicKey: + '02813ade967f05384e0567841d175294b4102c06c428011646e5ef989212925fcf', + recipientId: 'D8PGSYLUC3CxYaXoKjMA2gjV4RaeBpwghZ', + type: 1, + amount: '0', + fee: '500000000', + signature: + '3045022100e593eb501e89941461e247606d088b6e226cc5b5224f89cede532d35f9b16250022034bbdd098493639221e808301e0a99c3790ef9c6d357ac10266c518a2a66066f', + asset: { + signature: { + publicKey: + '02813ade967f05384e0567841d175294b4102c06c428011646e5ef989212925fcf', + }, + }, + }, + { + id: 'b4b3433be888b4b95b68b83a84a08e40d748b0ad92acf8487072ef01c1de251a', + version: 1, + timestamp: 48069792, + senderPublicKey: + '03f9f9dafc06faf4a54be2e45cd7a5523e41f38bb439f6f93cf00a0990e7afc116', + recipientId: 'DNuwcwYGTHDdhTPWMTYekhuGM1fFUpW9Jj', + type: 1, + amount: '0', + fee: '500000000', + signature: + '3044022052d1e5be426a79f827a67597fd460237de65e035593144e4e3afb0e82ab40f3802201d6e31892d000e73532bf8659851a3d221205d65ed1c0b8d08ce46b72c7f00ae', + asset: { + signature: { + publicKey: + '03f9f9dafc06faf4a54be2e45cd7a5523e41f38bb439f6f93cf00a0990e7afc116', + }, + }, + }, + ] + txs.forEach(tx => + it(`txid: ${tx.id}`, () => { + const newtx = new Transaction(tx) + expect(newtx.id).toEqual(tx.id) + }), + ) + }) + describe('static serialize', () => {}) - it('Signatures are not malleable', () => { - [0, 1, 2, 3, 4] + it('Signatures are verified', () => { + ;[0, 1, 2, 3, 4] .map(type => createRandomTx(type)) - .forEach(transaction => expect(verifyEcdsaNonMalleability(transaction)).toBeTruthy()) + .forEach(transaction => expect(crypto.verify(transaction)).toBeTrue()) }) }) diff --git a/packages/crypto/__tests__/models/wallet.test.js b/packages/crypto/__tests__/models/wallet.test.js index 8a9786eb12..e55e4f4751 100644 --- a/packages/crypto/__tests__/models/wallet.test.js +++ b/packages/crypto/__tests__/models/wallet.test.js @@ -1,6 +1,7 @@ +const Bignum = require('../../lib/utils/bignum') const Wallet = require('../../lib/models/wallet') const multiTx = require('./fixtures/multi-transaction') - +const { ARKTOSHI } = require('../../lib/constants') const configManager = require('../../lib/managers/config') const network = require('../../lib/networks/ark/devnet.json') @@ -12,31 +13,36 @@ describe('Models - Wallet', () => { it('returns the address and the balance', () => { const address = 'Abcde' const wallet = new Wallet(address) - const balance = parseFloat((Math.random() * 1000).toFixed(8)) - wallet.balance = balance * 10 ** 8 - - expect(wallet.toString()).toBe(`${address}=${balance}`) + const balance = parseInt((Math.random() * 1000).toFixed(8)) + wallet.balance = new Bignum(balance * ARKTOSHI) + expect(wallet.toString()).toBe( + `${address} (${balance} ${configManager.config.client.symbol})`, + ) }) }) describe('apply transaction', () => { const testWallet = new Wallet('D61xc3yoBQDitwjqUspMPx1ooET6r1XLt7') const data = { - publicKey: '02337316a26d8d49ec27059bd0589c49ba474029c3627715380f4df83fb431aece', - secondPublicKey: '020d3c837d0a47ee7de1082cd48885003c5e92964e58bb34af3b58c6e42208ae03', - balance: 109390000000, + publicKey: + '02337316a26d8d49ec27059bd0589c49ba474029c3627715380f4df83fb431aece', + secondPublicKey: + '020d3c837d0a47ee7de1082cd48885003c5e92964e58bb34af3b58c6e42208ae03', + balance: new Bignum(109390000000), vote: null, username: null, - votebalance: 0, + voteBalance: Bignum.ZERO, multisignature: null, dirty: false, producedBlocks: 0, - missedBlocks: 0 + missedBlocks: 0, } - xit('should be ok for a multi-transaction', () => { - Object.keys(data).forEach(k => (testWallet[k] = data[k])) - expect(testWallet.canApply(multiTx)).toBeTruthy() + it.skip('should be ok for a multi-transaction', () => { + Object.keys(data).forEach(k => { + testWallet[k] = data[k] + }) + expect(testWallet.canApply(multiTx, [])).toBeTrue() }) }) @@ -46,55 +52,42 @@ describe('Models - Wallet', () => { beforeEach(() => { testWallet = new Wallet('D61xc3yoBQDitwjqUspMPx1ooET6r1XLt7') - testWallet.publicKey = '02337316a26d8d49ec27059bd0589c49ba474029c3627715380f4df83fb431aece' - testWallet.balance = 0 + testWallet.publicKey = + '02337316a26d8d49ec27059bd0589c49ba474029c3627715380f4df83fb431aece' + testWallet.balance = Bignum.ZERO testWallet.producedBlocks = 0 - testWallet.forgedFees = 0 - testWallet.forgedRewards = 0 + testWallet.forgedFees = Bignum.ZERO + testWallet.forgedRewards = Bignum.ZERO testWallet.lastBlock = null block = { id: 1, generatorPublicKey: testWallet.publicKey, - reward: 1000000000, - totalFee: 1000000000 + reward: new Bignum(1000000000), + totalFee: new Bignum(1000000000), } }) it('should apply correct block', () => { testWallet.applyBlock(block) - expect(testWallet.balance).toBe(block.reward + block.totalFee) + expect(testWallet.balance).toEqual(block.reward.plus(block.totalFee)) expect(testWallet.producedBlocks).toBe(1) - expect(testWallet.forgedFees).toBe(block.totalFee) - expect(testWallet.forgedRewards).toBe(block.totalFee) + expect(testWallet.forgedFees).toEqual(block.totalFee) + expect(testWallet.forgedRewards).toEqual(block.totalFee) expect(testWallet.lastBlock).toBeObject(block) - expect(testWallet.dirty).toBeTruthy() - }) - - it('should apply correct block with string values', () => { - const originalBlock = Object.assign({}, block) - block.reward += '' - block.totalFee += '' - block.reward += '' - testWallet.applyBlock(block) - expect(testWallet.balance).toBe(originalBlock.reward + originalBlock.totalFee) - expect(testWallet.producedBlocks).toBe(1) - expect(testWallet.forgedFees).toBe(originalBlock.totalFee) - expect(testWallet.forgedRewards).toBe(originalBlock.totalFee) - expect(testWallet.lastBlock).toBeObject(originalBlock) - expect(testWallet.dirty).toBeTruthy() + expect(testWallet.dirty).toBeTrue() }) it('should not apply incorrect block', () => { - block.generatorPublicKey = 'wrong' + block.generatorPublicKey = 'a'.repeat(66) const originalWallet = Object.assign({}, testWallet) testWallet.applyBlock(block) - expect(testWallet.balance).toBe(originalWallet.balance) + expect(testWallet.balance).toEqual(originalWallet.balance) expect(testWallet.producedBlocks).toBe(0) - expect(testWallet.forgedFees).toBe(originalWallet.forgedFees) - expect(testWallet.forgedRewards).toBe(originalWallet.forgedRewards) + expect(testWallet.forgedFees).toEqual(originalWallet.forgedFees) + expect(testWallet.forgedRewards).toEqual(originalWallet.forgedRewards) expect(testWallet.lastBlock).toBe(originalWallet.lastBlock) - expect(testWallet.dirty).toBeTruthy() + expect(testWallet.dirty).toBeTrue() }) }) }) diff --git a/packages/crypto/__tests__/utils/format-arktoshi.test.js b/packages/crypto/__tests__/utils/format-arktoshi.test.js new file mode 100644 index 0000000000..89d96d7e9a --- /dev/null +++ b/packages/crypto/__tests__/utils/format-arktoshi.test.js @@ -0,0 +1,12 @@ +const { Bignum, formatArktoshi } = require('../../lib/utils') +const { ARKTOSHI } = require('../../lib/constants') + +describe('Format Arktoshi', () => { + it('should format arktoshis', () => { + expect(formatArktoshi(ARKTOSHI)).toBe('1 DѦ') + expect(formatArktoshi(0.1 * ARKTOSHI)).toBe('0.1 DѦ') + expect(formatArktoshi((0.1 * ARKTOSHI).toString())).toBe('0.1 DѦ') + expect(formatArktoshi(new Bignum(10))).toBe('0.0000001 DѦ') + expect(formatArktoshi(new Bignum(ARKTOSHI + 10012))).toBe('1.00010012 DѦ') + }) +}) diff --git a/packages/crypto/__tests__/utils/message.test.js b/packages/crypto/__tests__/utils/message.test.js new file mode 100644 index 0000000000..175d504e36 --- /dev/null +++ b/packages/crypto/__tests__/utils/message.test.js @@ -0,0 +1,39 @@ +const { Message } = require('../../lib/crypto') + +const fixture = { + data: { + publicKey: + '034151a3ec46b5670a682b0a63394f863587d1bc97483b1b6c70eb58e7f0aed192', + signature: + '304402200fb4adddd1f1d652b544ea6ab62828a0a65b712ed447e2538db0caebfa68929e02205ecb2e1c63b29879c2ecf1255db506d671c8b3fa6017f67cfd1bf07e6edd1cc8', + message: 'Hello World', + }, + passphrase: 'this is a top secret passphrase', +} + +describe('Message', () => { + describe('sign', () => { + it('should be a function', () => { + expect(Message.sign).toBeFunction() + }) + + it('should be ok', () => { + const actual = Message.sign(fixture.data.message, fixture.passphrase) + + expect(actual).toHaveProperty('publicKey') + expect(actual).toHaveProperty('signature') + expect(actual).toHaveProperty('message') + expect(Message.verify(actual)).toBeTrue() + }) + }) + + describe('verify', () => { + it('should be a function', () => { + expect(Message.verify).toBeFunction() + }) + + it('should be ok', () => { + expect(Message.verify(fixture.data)).toBeTrue() + }) + }) +}) diff --git a/packages/crypto/__tests__/utils/network-list.js b/packages/crypto/__tests__/utils/network-list.js index 5d8f57e529..e598ed993e 100644 --- a/packages/crypto/__tests__/utils/network-list.js +++ b/packages/crypto/__tests__/utils/network-list.js @@ -1,12 +1,14 @@ const tg = require('tiny-glob/sync') const path = require('path') -const entries = tg('../../lib/networks/**/*.json', {cwd: __dirname}) +const entries = tg('../../lib/networks/**/*.json', { cwd: __dirname }) -let NETWORKS = {} -entries.forEach(file => (NETWORKS[path.parse(file).name] = require(file))) +const NETWORKS = {} +entries.forEach(file => { + NETWORKS[path.parse(file).name] = require(file) +}) -let NETWORKS_LIST = [] +const NETWORKS_LIST = [] entries.forEach(file => NETWORKS_LIST.push(require(file))) module.exports = { NETWORKS, NETWORKS_LIST } diff --git a/packages/crypto/__tests__/validation/extensions/transactions/delegate-registration.test.js b/packages/crypto/__tests__/validation/extensions/transactions/delegate-registration.test.js new file mode 100644 index 0000000000..32f504830d --- /dev/null +++ b/packages/crypto/__tests__/validation/extensions/transactions/delegate-registration.test.js @@ -0,0 +1,109 @@ +/* eslint no-empty: "off" */ + +const Joi = require('joi').extend( + require('../../../../lib/validation/extensions'), +) + +const { constants, transactionBuilder } = require('../../../../lib') + +let transaction +beforeEach(() => { + transaction = transactionBuilder.delegateRegistration() +}) + +describe('Delegate Registration Transaction', () => { + it('should be valid', () => { + transaction.usernameAsset('delegate1').sign('passphrase') + + expect( + Joi.validate(transaction.getStruct(), Joi.arkDelegateRegistration()) + .error, + ).toBeNull() + }) + + it('should be invalid due to no transaction as object', () => { + expect( + Joi.validate('test', Joi.arkDelegateRegistration()).error, + ).not.toBeNull() + }) + + it('should be invalid due to non-zero amount', () => { + transaction + .usernameAsset('delegate1') + .amount(10 * constants.ARKTOSHI) + .sign('passphrase') + + expect( + Joi.validate(transaction.getStruct(), Joi.arkDelegateRegistration()) + .error, + ).not.toBeNull() + }) + + it('should be invalid due to space in username', () => { + transaction.usernameAsset('test 123').sign('passphrase') + + expect( + Joi.validate(transaction.getStruct(), Joi.arkDelegateRegistration()) + .error, + ).not.toBeNull() + }) + + it('should be invalid due to non-alphanumeric in username', () => { + transaction.usernameAsset('£££').sign('passphrase') + + expect( + Joi.validate(transaction.getStruct(), Joi.arkDelegateRegistration()) + .error, + ).not.toBeNull() + }) + + it('should be invalid due to username too long', () => { + transaction.usernameAsset('1234567890123456789012345').sign('passphrase') + + expect( + Joi.validate(transaction.getStruct(), Joi.arkDelegateRegistration()) + .error, + ).not.toBeNull() + }) + + it('should be invalid due to undefined username', () => { + try { + transaction.usernameAsset(undefined).sign('passphrase') + expect( + Joi.validate(transaction.getStruct(), Joi.arkDelegateRegistration()) + .error, + ).not.toBeNull() + } catch (error) {} + }) + + it('should be invalid due to no username', () => { + transaction.usernameAsset('').sign('passphrase') + + expect( + Joi.validate(transaction.getStruct(), Joi.arkDelegateRegistration()) + .error, + ).not.toBeNull() + }) + + it('should be invalid due to capitals in username', () => { + transaction.usernameAsset('I_AM_INVALID').sign('passphrase') + + expect( + Joi.validate(transaction.getStruct(), Joi.arkDelegateRegistration()) + .error, + ).not.toBeNull() + }) + + it('should be invalid due to wrong transaction type', () => { + transaction = transactionBuilder.transfer() + transaction + .recipientId(null) + .amount(10 * constants.ARKTOSHI) + .sign('passphrase') + + expect( + Joi.validate(transaction.getStruct(), Joi.arkDelegateRegistration()) + .error, + ).not.toBeNull() + }) +}) diff --git a/packages/crypto/__tests__/validation/extensions/transactions/multi-signature.test.js b/packages/crypto/__tests__/validation/extensions/transactions/multi-signature.test.js new file mode 100644 index 0000000000..31dafdca5e --- /dev/null +++ b/packages/crypto/__tests__/validation/extensions/transactions/multi-signature.test.js @@ -0,0 +1,215 @@ +/* eslint no-empty: "off" */ + +const Joi = require('joi').extend( + require('../../../../lib/validation/extensions'), +) + +const { constants, crypto, transactionBuilder } = require('../../../../lib') + +const passphrase = 'passphrase 1' +const publicKey = + '+03e8021105a6c202097e97e6c6d650942d913099bf6c9f14a6815df1023dde3b87' +const passphrases = [passphrase, 'passphrase 2', 'passphrase 3'] +const keysGroup = [ + publicKey, + '+03dfdaaa7fd28bc9359874b7e33138f4d0afe9937e152c59b83a99fae7eeb94899', + '+03de72ef9d3ebf1b374f1214f5b8dde823690ab2aa32b4b8b3226cc568aaed1562', +] + +const signTransaction = (transaction, values) => { + values.map(value => transaction.multiSignatureSign(value)) +} + +let transaction +let multiSignatureAsset +beforeEach(() => { + transaction = transactionBuilder.multiSignature() + multiSignatureAsset = { + min: 1, + keysgroup: keysGroup, + lifetime: 72, + } +}) + +describe('Multi Signature Transaction', () => { + it('should be valid with min of 3', () => { + multiSignatureAsset.min = 3 + transaction.multiSignatureAsset(multiSignatureAsset).sign('passphrase') + signTransaction(transaction, passphrases) + expect( + Joi.validate(transaction.getStruct(), Joi.arkMultiSignature()).error, + ).toBeNull() + }) + + it('should be valid with 3 public keys', () => { + transaction.multiSignatureAsset(multiSignatureAsset).sign('passphrase') + signTransaction(transaction, passphrases) + expect( + Joi.validate(transaction.getStruct(), Joi.arkMultiSignature()).error, + ).toBeNull() + }) + + it('should be valid with lifetime of 10', () => { + multiSignatureAsset.lifetime = 10 + transaction.multiSignatureAsset(multiSignatureAsset).sign('passphrase') + signTransaction(transaction, passphrases) + expect( + Joi.validate(transaction.getStruct(), Joi.arkMultiSignature()).error, + ).toBeNull() + }) + + it('should be invalid due to no transaction as object', () => { + expect(Joi.validate('test', Joi.arkMultiSignature()).error).not.toBeNull() + }) + + it('should be invalid due to non-zero amount', () => { + transaction + .multiSignatureAsset(multiSignatureAsset) + .amount(10 * constants.ARKTOSHI) + .sign('passphrase') + signTransaction(transaction, passphrases) + expect( + Joi.validate(transaction.getStruct(), Joi.arkMultiSignature()).error, + ).not.toBeNull() + }) + + it('should be invalid due to zero fee', () => { + transaction + .multiSignatureAsset(multiSignatureAsset) + .fee(0) + .sign('passphrase') + signTransaction(transaction, passphrases) + expect( + Joi.validate(transaction.getStruct(), Joi.arkMultiSignature()).error, + ).not.toBeNull() + }) + + it('should be invalid due to min too low', () => { + multiSignatureAsset.min = 0 + transaction.multiSignatureAsset(multiSignatureAsset).sign('passphrase') + signTransaction(transaction, passphrases) + expect( + Joi.validate(transaction.getStruct(), Joi.arkMultiSignature()).error, + ).not.toBeNull() + }) + + it('should be invalid due to min too high', () => { + multiSignatureAsset.min = multiSignatureAsset.keysgroup.length + 1 + transaction.multiSignatureAsset(multiSignatureAsset).sign('passphrase') + signTransaction(transaction, passphrases) + expect( + Joi.validate(transaction.getStruct(), Joi.arkMultiSignature()).error, + ).not.toBeNull() + }) + + it('should be invalid due to lifetime too low', () => { + multiSignatureAsset.lifetime = 0 + transaction.multiSignatureAsset(multiSignatureAsset).sign('passphrase') + signTransaction(transaction, passphrases) + expect( + Joi.validate(transaction.getStruct(), Joi.arkMultiSignature()).error, + ).not.toBeNull() + }) + + it('should be invalid due to lifetime too high', () => { + multiSignatureAsset.lifetime = 100 + transaction.multiSignatureAsset(multiSignatureAsset).sign('passphrase') + signTransaction(transaction, passphrases) + expect( + Joi.validate(transaction.getStruct(), Joi.arkMultiSignature()).error, + ).not.toBeNull() + }) + + it('should be invalid due to no public keys', () => { + multiSignatureAsset.keysgroup = [] + transaction.multiSignatureAsset(multiSignatureAsset).sign('passphrase') + signTransaction(transaction, passphrases) + expect( + Joi.validate(transaction.getStruct(), Joi.arkMultiSignature()).error, + ).not.toBeNull() + }) + + it('should be invalid due to too many public keys', () => { + const values = [] + multiSignatureAsset.keysgroup = [] + for (let i = 0; i < 20; i++) { + const value = `passphrase ${i}` + values.push(value) + multiSignatureAsset.keysgroup.push(crypto.getKeys(value).publicKey) + } + transaction.multiSignatureAsset(multiSignatureAsset).sign('passphrase') + signTransaction(transaction, values) + expect( + Joi.validate(transaction.getStruct(), Joi.arkMultiSignature()).error, + ).not.toBeNull() + }) + + it('should be invalid due to duplicate public keys', () => { + multiSignatureAsset.keysgroup = [publicKey, publicKey] + transaction.multiSignatureAsset(multiSignatureAsset).sign('passphrase') + signTransaction(transaction, passphrases) + expect( + Joi.validate(transaction.getStruct(), Joi.arkMultiSignature()).error, + ).not.toBeNull() + }) + + it('should be invalid due to no signatures', () => { + transaction.multiSignatureAsset(multiSignatureAsset).sign('passphrase') + expect( + Joi.validate(transaction.getStruct(), Joi.arkMultiSignature()).error, + ).not.toBeNull() + }) + + it('should be invalid due to not enough signatures', () => { + transaction.multiSignatureAsset(multiSignatureAsset).sign('passphrase') + signTransaction(transaction, passphrases.slice(1)) + expect( + Joi.validate(transaction.getStruct(), Joi.arkMultiSignature()).error, + ).not.toBeNull() + }) + + it('should be invalid due to too many signatures', () => { + transaction.multiSignatureAsset(multiSignatureAsset).sign('passphrase') + signTransaction(transaction, ['wrong passphrase', ...passphrases]) + expect( + Joi.validate(transaction.getStruct(), Joi.arkMultiSignature()).error, + ).not.toBeNull() + }) + + it('should be invalid due to no "+" for publicKeys', () => { + multiSignatureAsset.keysgroup = keysGroup.map(value => value.slice(1)) + transaction.multiSignatureAsset(multiSignatureAsset).sign('passphrase') + signTransaction(transaction, passphrases) + expect( + Joi.validate(transaction.getStruct(), Joi.arkMultiSignature()).error, + ).not.toBeNull() + }) + + it('should be invalid due to having "-" for publicKeys', () => { + multiSignatureAsset.keysgroup = keysGroup.map(value => `-${value.slice(1)}`) + transaction.multiSignatureAsset(multiSignatureAsset).sign('passphrase') + signTransaction(transaction, passphrases) + expect( + Joi.validate(transaction.getStruct(), Joi.arkMultiSignature()).error, + ).not.toBeNull() + }) + + it('should be invalid due to wrong keysgroup type', () => { + try { + multiSignatureAsset.keysgroup = publicKey + transaction.multiSignatureAsset(publicKey).sign('passphrase') + signTransaction(transaction, passphrases) + expect( + Joi.validate(transaction.getStruct(), Joi.arkMultiSignature()).error, + ).not.toBeNull() + } catch (error) {} + }) + + it('should be invalid due to wrong transaction type', () => { + transaction = transactionBuilder.delegateRegistration() + transaction.usernameAsset('delegate_name').sign('passphrase') + expect( + Joi.validate(transaction.getStruct(), Joi.arkMultiSignature()).errors, + ).not.toBeNull() + }) +}) diff --git a/packages/crypto/__tests__/validation/extensions/transactions/second-signature.test.js b/packages/crypto/__tests__/validation/extensions/transactions/second-signature.test.js new file mode 100644 index 0000000000..81a6cb7962 --- /dev/null +++ b/packages/crypto/__tests__/validation/extensions/transactions/second-signature.test.js @@ -0,0 +1,74 @@ +const Joi = require('joi').extend( + require('../../../../lib/validation/extensions'), +) + +const { constants, transactionBuilder } = require('../../../../lib') + +let transaction +beforeEach(() => { + transaction = transactionBuilder.secondSignature() +}) + +// NOTE: some tests aren't strictly about the second signature + +describe('Second Signature Transaction', () => { + it('should be valid', () => { + transaction.signatureAsset('second passphrase').sign('passphrase') + expect( + Joi.validate(transaction.getStruct(), Joi.arkSecondSignature()).error, + ).toBeNull() + }) + + it('should be valid with correct data', () => { + transaction + .signatureAsset('second passphrase') + .fee(1 * constants.ARKTOSHI) + .sign('passphrase') + expect( + Joi.validate(transaction.getStruct(), Joi.arkSecondSignature()).error, + ).toBeNull() + }) + + it('should be invalid due to no transaction as object', () => { + expect(Joi.validate('test', Joi.arkSecondSignature()).error).not.toBeNull() + }) + + it('should be invalid due to non-zero amount', () => { + transaction + .signatureAsset('second passphrase') + .amount(10 * constants.ARKTOSHI) + .sign('passphrase') + expect( + Joi.validate(transaction.getStruct(), Joi.arkSecondSignature()).error, + ).not.toBeNull() + }) + + it('should be invalid due to zero fee', () => { + transaction + .signatureAsset('second passphrase') + .fee(0) + .sign('passphrase') + expect( + Joi.validate(transaction.getStruct(), Joi.arkSecondSignature()).error, + ).not.toBeNull() + }) + + it('should be invalid due to second signature', () => { + transaction + .signatureAsset('second passphrase') + .fee(1) + .sign('passphrase') + .secondSign('second passphrase') + expect( + Joi.validate(transaction.getStruct(), Joi.arkSecondSignature()), + ).not.toBeNull() + }) + + it('should be invalid due to wrong transaction type', () => { + transaction = transactionBuilder.delegateRegistration() + transaction.usernameAsset('delegate_name').sign('passphrase') + expect( + Joi.validate(transaction.getStruct(), Joi.arkSecondSignature()).error, + ).not.toBeNull() + }) +}) diff --git a/packages/crypto/__tests__/validation/extensions/transactions/transfer.test.js b/packages/crypto/__tests__/validation/extensions/transactions/transfer.test.js new file mode 100644 index 0000000000..1e0883aaeb --- /dev/null +++ b/packages/crypto/__tests__/validation/extensions/transactions/transfer.test.js @@ -0,0 +1,135 @@ +const Joi = require('joi').extend( + require('../../../../lib/validation/extensions'), +) + +const { constants, transactionBuilder } = require('../../../../lib') + +const address = 'APnDzjtDb1FthuqcLMeL5XMWb1uD1KeMGi' +const fee = 1 * constants.ARKTOSHI +const amount = 10 * constants.ARKTOSHI + +let transaction +beforeEach(() => { + transaction = transactionBuilder.transfer() +}) + +describe('Transfer Transaction', () => { + it('should be valid', () => { + transaction + .recipientId(address) + .amount(amount) + .sign('passphrase') + expect( + Joi.validate(transaction.getStruct(), Joi.arkTransfer()).error, + ).toBeNull() + }) + + it('should be valid with correct data', () => { + transaction + .recipientId(address) + .amount(amount) + .fee(fee) + .vendorField('Ahoy') + .sign('passphrase') + expect( + Joi.validate(transaction.getStruct(), Joi.arkTransfer()).error, + ).toBeNull() + }) + + it('should be valid with up to 64 bytes in vendor field', () => { + transaction + .recipientId(address) + .amount(amount) + .fee(fee) + .vendorField('a'.repeat(64)) + .sign('passphrase') + expect( + Joi.validate(transaction.getStruct(), Joi.arkTransfer()).error, + ).toBeNull() + + transaction + .recipientId(address) + .amount(amount) + .fee(fee) + .vendorField('⊁'.repeat(21)) + .sign('passphrase') + expect( + Joi.validate(transaction.getStruct(), Joi.arkTransfer()).error, + ).toBeNull() + }) + + it('should be invalid with more than 64 bytes in vendor field', () => { + transaction + .recipientId(address) + .amount(amount) + .fee(fee) + .vendorField('a'.repeat(65)) + .sign('passphrase') + expect( + Joi.validate(transaction.getStruct(), Joi.arkTransfer()).error, + ).not.toBeNull() + + transaction + .recipientId(address) + .amount(amount) + .fee(fee) + .vendorField('⊁'.repeat(22)) + .sign('passphrase') + expect( + Joi.validate(transaction.getStruct(), Joi.arkTransfer()).error, + ).not.toBeNull() + }) + + it('should be invalid due to no transaction as object', () => { + expect(Joi.validate('test', Joi.arkTransfer()).error).not.toBeNull() + }) + + it('should be invalid due to no address', () => { + transaction + .recipientId(null) + .amount(amount) + .sign('passphrase') + expect( + Joi.validate(transaction.getStruct(), Joi.arkTransfer()).error, + ).not.toBeNull() + }) + + it('should be invalid due to invalid address', () => { + transaction + .recipientId(address) + .amount(amount) + .sign('passphrase') + const struct = transaction.getStruct() + struct.recipientId = 'woop' + expect(Joi.validate(struct, Joi.arkTransfer()).error).not.toBeNull() + }) + + it('should be invalid due to zero amount', () => { + transaction + .recipientId(address) + .amount(0) + .sign('passphrase') + expect( + Joi.validate(transaction.getStruct(), Joi.arkTransfer()).error, + ).not.toBeNull() + }) + + it('should be invalid due to zero fee', () => { + transaction + .recipientId(address) + .amount(0) + .fee(0) + .sign('passphrase') + expect( + Joi.validate(transaction.getStruct(), Joi.arkTransfer()).error, + ).not.toBeNull() + }) + + it('should be invalid due to wrong transaction type', () => { + transaction = transactionBuilder.delegateRegistration() + transaction.usernameAsset('delegate_name').sign('passphrase') + expect( + Joi.validate(transaction.getStruct(), Joi.arkTransfer()).error, + ).not.toBeNull() + }) +}) diff --git a/packages/crypto/__tests__/validation/extensions/transactions/vote.test.js b/packages/crypto/__tests__/validation/extensions/transactions/vote.test.js new file mode 100644 index 0000000000..a677916dc7 --- /dev/null +++ b/packages/crypto/__tests__/validation/extensions/transactions/vote.test.js @@ -0,0 +1,115 @@ +/* eslint no-empty: "off" */ + +const Joi = require('joi').extend( + require('../../../../lib/validation/extensions'), +) + +const { constants, transactionBuilder } = require('../../../../lib') + +const vote = + '+02bcfa0951a92e7876db1fb71996a853b57f996972ed059a950d910f7d541706c9' +const unvote = + '-0326580718fc86ba609799ac95fcd2721af259beb5afa81bfce0ab7d9fe95de991' +const votes = [ + vote, + '+0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0', + unvote, +] +const invalidVotes = [ + '02bcfa0951a92e7876db1fb71996a853b57f996972ed059a950d910f7d541706c9', + '0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0', + '0326580718fc86ba609799ac95fcd2721af259beb5afa81bfce0ab7d9fe95de991', +] + +let transaction +beforeEach(() => { + transaction = transactionBuilder.vote() +}) + +describe('Vote Transaction', () => { + it('should be valid with 1 vote', () => { + transaction + .votesAsset([vote]) + + .sign('passphrase') + expect( + Joi.validate(transaction.getStruct(), Joi.arkVote()).error, + ).toBeNull() + }) + + it('should be valid with 1 unvote', () => { + transaction.votesAsset([unvote]).sign('passphrase') + + expect( + Joi.validate(transaction.getStruct(), Joi.arkVote()).error, + ).toBeNull() + }) + + it('should be invalid due to no transaction as object', () => { + expect(Joi.validate('test', Joi.arkVote()).error).not.toBeNull() + }) + + it('should be invalid due to non-zero amount', () => { + transaction + .votesAsset([vote]) + .amount(10 * constants.ARKTOSHI) + .sign('passphrase') + + expect( + Joi.validate(transaction.getStruct(), Joi.arkVote()).error, + ).not.toBeNull() + }) + + it('should be invalid due to zero fee', () => { + transaction + .votesAsset(votes) + .fee(0) + .sign('passphrase') + + expect( + Joi.validate(transaction.getStruct(), Joi.arkVote()).error, + ).not.toBeNull() + }) + + it('should be invalid due to no votes', () => { + transaction.votesAsset([]).sign('passphrase') + + expect( + Joi.validate(transaction.getStruct(), Joi.arkVote()).error, + ).not.toBeNull() + }) + + it('should be invalid due to more than 1 vote', () => { + transaction.votesAsset(votes).sign('passphrase') + + expect( + Joi.validate(transaction.getStruct(), Joi.arkVote()).error, + ).not.toBeNull() + }) + + it('should be invalid due to invalid votes', () => { + transaction.votesAsset(invalidVotes).sign('passphrase') + + expect( + Joi.validate(transaction.getStruct(), Joi.arkVote()).error, + ).not.toBeNull() + }) + + it('should be invalid due to wrong vote type', () => { + try { + transaction.votesAsset(vote).sign('passphrase') + expect( + Joi.validate(transaction.getStruct(), Joi.arkVote()).error, + ).not.toBeNull() + } catch (error) {} + }) + + it('should be invalid due to wrong transaction type', () => { + transaction = transactionBuilder.delegateRegistration() + transaction.usernameAsset('delegate_name').sign('passphrase') + + expect( + Joi.validate(transaction.getStruct(), Joi.arkVote()).error, + ).not.toBeNull() + }) +}) diff --git a/packages/validation/__tests__/rules/address.test.js b/packages/crypto/__tests__/validation/rules/address.test.js similarity index 62% rename from packages/validation/__tests__/rules/address.test.js rename to packages/crypto/__tests__/validation/rules/address.test.js index 42ddd5597d..f66a674e25 100644 --- a/packages/validation/__tests__/rules/address.test.js +++ b/packages/crypto/__tests__/validation/rules/address.test.js @@ -1,17 +1,15 @@ -'use strict' - -const rule = require('../../lib/rules/address') +const rule = require('../../../lib/validation/rules/address') describe('Address Rule', () => { it('should be a function', () => { expect(rule).toBeFunction() }) - it('should be truthy', () => { - expect(rule('DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN').passes).toBeTruthy() + it('should be true', () => { + expect(rule('DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN').passes).toBeTrue() }) - it('should be falsy', () => { - expect(rule('_DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN_').passes).toBeFalsy() + it('should be false', () => { + expect(rule('_DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN_').passes).toBeFalse() }) }) diff --git a/packages/crypto/__tests__/validation/rules/public-key.test.js b/packages/crypto/__tests__/validation/rules/public-key.test.js new file mode 100644 index 0000000000..a6345a539a --- /dev/null +++ b/packages/crypto/__tests__/validation/rules/public-key.test.js @@ -0,0 +1,22 @@ +const rule = require('../../../lib/validation/rules/public-key') + +describe('Public Key Rule', () => { + it('should be a function', () => { + expect(rule).toBeFunction() + }) + + it('should be true', () => { + expect( + rule('022cca9529ec97a772156c152a00aad155ee6708243e65c9d211a589cb5d43234d') + .passes, + ).toBeTrue() + }) + + it('should be false', () => { + expect( + rule( + '_022cca9529ec97a772156c152a00aad155ee6708243e65c9d211a589cb5d43234d_', + ).passes, + ).toBeFalse() + }) +}) diff --git a/packages/crypto/__tests__/validation/rules/username.test.js b/packages/crypto/__tests__/validation/rules/username.test.js new file mode 100644 index 0000000000..6ce8279e72 --- /dev/null +++ b/packages/crypto/__tests__/validation/rules/username.test.js @@ -0,0 +1,15 @@ +const rule = require('../../../lib/validation/rules/username') + +describe('Username Rule', () => { + it('should be a function', () => { + expect(rule).toBeFunction() + }) + + it('should be true', () => { + expect(rule('boldninja').passes).toBeTrue() + }) + + it('should be false', () => { + expect(rule('bold ninja').passes).toBeFalse() + }) +}) diff --git a/packages/validation/__tests__/validators/transaction.test.js b/packages/crypto/__tests__/validation/transaction-validator.test.js similarity index 79% rename from packages/validation/__tests__/validators/transaction.test.js rename to packages/crypto/__tests__/validation/transaction-validator.test.js index 4a0816c71f..d3cf9d2e14 100644 --- a/packages/validation/__tests__/validators/transaction.test.js +++ b/packages/crypto/__tests__/validation/transaction-validator.test.js @@ -1,4 +1,4 @@ -const transactionValidator = require('../../lib/validators/transaction') +const { transactionValidator } = require('../../lib/validation') describe('Validators - Transaction', () => { it('should be instantiated', () => { diff --git a/packages/validation/__tests__/validator.test.js b/packages/crypto/__tests__/validation/validator.test.js similarity index 58% rename from packages/validation/__tests__/validator.test.js rename to packages/crypto/__tests__/validation/validator.test.js index 4dfd26dbc3..644c7af9ea 100755 --- a/packages/validation/__tests__/validator.test.js +++ b/packages/crypto/__tests__/validation/validator.test.js @@ -1,11 +1,9 @@ -'use strict' - const Joi = require('joi') let validator beforeEach(() => { - validator = require('../lib/validator') + validator = require('../../lib/validation').validator }) describe('Validator', () => { @@ -20,20 +18,20 @@ describe('Validator', () => { expect(validator.passes).toBeFunction() }) - it('should be truthy', () => { + it('should be true', () => { validator.results = { - passes: true + passes: true, } - expect(validator.passes()).toBeTruthy() + expect(validator.passes()).toBeTrue() }) - it('should be falsy', () => { + it('should be false', () => { validator.results = { - passes: false + passes: false, } - expect(validator.passes()).toBeFalsy() + expect(validator.passes()).toBeFalse() }) }) @@ -42,20 +40,20 @@ describe('Validator', () => { expect(validator.fails).toBeFunction() }) - it('should be truthy', () => { + it('should be true', () => { validator.results = { - fails: true + fails: true, } - expect(validator.fails()).toBeTruthy() + expect(validator.fails()).toBeTrue() }) - it('should be falsy', () => { + it('should be false', () => { validator.results = { - fails: false + fails: false, } - expect(validator.fails()).toBeFalsy() + expect(validator.fails()).toBeFalse() }) }) @@ -64,21 +62,21 @@ describe('Validator', () => { expect(validator.validated).toBeFunction() }) - it('should be truthy', () => { + it('should be true', () => { validator.results = { data: { - key: 'value' - } + key: 'value', + }, } expect(validator.validated()).toHaveProperty('key', 'value') }) - it('should be falsy', () => { + it('should be false', () => { validator.results = { data: { - invalidKey: 'value' - } + invalidKey: 'value', + }, } expect(validator.validated()).not.toHaveProperty('key', 'value') @@ -104,16 +102,22 @@ describe('Validator', () => { expect(validator.__validateWithRule).toBeFunction() }) - it('should be truthy', () => { - validator.__validateWithRule('DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN', 'address') + it('should be true', () => { + validator.__validateWithRule( + 'DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN', + 'address', + ) - expect(validator.passes()).toBeTruthy() + expect(validator.passes()).toBeTrue() }) - it('should be falsy', () => { - validator.__validateWithRule('_DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN_', 'address') + it('should be false', () => { + validator.__validateWithRule( + '_DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN_', + 'address', + ) - expect(validator.passes()).toBeFalsy() + expect(validator.passes()).toBeFalse() }) }) @@ -122,28 +126,30 @@ describe('Validator', () => { expect(validator.__validateWithFunction).toBeFunction() }) - it('should be truthy', () => { - validator.__validateWithFunction('DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN', value => { - return { + it('should be true', () => { + validator.__validateWithFunction( + 'DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN', + value => ({ data: value, passes: value.length === 34, - fails: value.length !== 34 - } - }) + fails: value.length !== 34, + }), + ) - expect(validator.passes()).toBeTruthy() + expect(validator.passes()).toBeTrue() }) - it('should be falsy', () => { - validator.__validateWithFunction('_DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN_', value => { - return { + it('should be false', () => { + validator.__validateWithFunction( + '_DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN_', + value => ({ data: value, passes: value.length === 34, - fails: value.length !== 34 - } - }) + fails: value.length !== 34, + }), + ) - expect(validator.passes()).toBeFalsy() + expect(validator.passes()).toBeFalse() }) }) @@ -152,22 +158,28 @@ describe('Validator', () => { expect(validator.__validateWithJoi).toBeFunction() }) - it('should be truthy', () => { + it('should be true', () => { validator.__validateWithJoi( 'DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN', - Joi.string().alphanum().length(34).required() + Joi.string() + .alphanum() + .length(34) + .required(), ) - expect(validator.passes()).toBeTruthy() + expect(validator.passes()).toBeTrue() }) - it('should be falsy', () => { + it('should be false', () => { validator.__validateWithJoi( '_DARiJqhogp2Lu6bxufUFQQMuMyZbxjCydN_', - Joi.string().alphanum().length(34).required() + Joi.string() + .alphanum() + .length(34) + .required(), ) - expect(validator.passes()).toBeFalsy() + expect(validator.passes()).toBeFalse() }) }) @@ -178,7 +190,7 @@ describe('Validator', () => { it('should be empty', () => { validator.results = { - key: 'value' + key: 'value', } expect(validator.results).not.toBeNull() diff --git a/packages/crypto/build/webpack.base.js b/packages/crypto/build/webpack.base.js index cca9dfc4d0..aa00bfb9ee 100644 --- a/packages/crypto/build/webpack.base.js +++ b/packages/crypto/build/webpack.base.js @@ -4,21 +4,21 @@ module.exports = (babelOptions = {}) => ({ context: __dirname, module: { - rules: [{ - test: /\.js$/, - exclude: /node_modules/, - use: { - loader: 'babel-loader', - options: { - presets: [ - ['@babel/preset-env', babelOptions] - ] - } - } - }] + rules: [ + { + test: /\.js$/, + exclude: /node_modules/, + use: { + loader: 'babel-loader', + options: { + presets: [['@babel/preset-env', babelOptions]], + }, + }, + }, + ], }, resolve: { - extensions: ['.js', '.json'] - } + extensions: ['.js', '.json'], + }, }) diff --git a/packages/crypto/build/webpack.config.js b/packages/crypto/build/webpack.config.js index 58db6f12b0..9b856b70c1 100644 --- a/packages/crypto/build/webpack.config.js +++ b/packages/crypto/build/webpack.config.js @@ -1,14 +1,16 @@ +/* eslint max-len: "off" */ + const path = require('path') const merge = require('webpack-merge') +const nodeExternals = require('webpack-node-externals') const pkg = require('../package.json') const base = require('./webpack.base') -const nodeExternals = require('webpack-node-externals') -const resolve = (dir) => path.resolve(__dirname, '..', dir) +const resolve = dir => path.resolve(__dirname, '..', dir) -const format = (dist) => ({ +const format = dist => ({ path: resolve(path.dirname(dist)), - filename: path.basename(dist) + filename: path.basename(dist), }) const browserConfig = { @@ -18,24 +20,24 @@ const browserConfig = { modules: 'umd', useBuiltIns: 'usage', targets: { - browsers: 'defaults' - } + browsers: 'defaults', + }, }, resolve: { alias: { - deepmerge$: 'deepmerge/dist/umd.js' - } + deepmerge$: 'deepmerge/dist/umd.js', + }, }, node: { - net: 'empty' + net: 'empty', }, output: { ...format(pkg.browser), library: 'ArkEcosystemCrypto', libraryTarget: 'umd', umdNamedDefine: true, - globalObject: 'this' - } + globalObject: 'this', + }, } const moduleConfig = { @@ -44,26 +46,30 @@ const moduleConfig = { modules: 'commonjs', useBuiltIns: 'usage', targets: { - node: 'current' - } + node: 'current', + }, }, resolve: { alias: { - deepmerge$: 'deepmerge/dist/cjs.js' - } + deepmerge$: 'deepmerge/dist/cjs.js', + }, }, - externals: [nodeExternals({ - modulesFromFile: true, - modulesDir: resolve('node_modules') - })], + externals: [ + nodeExternals({ + modulesFromFile: true, + modulesDir: resolve('node_modules'), + }), + ], entry: resolve(pkg.main), output: { ...format(pkg.module), - libraryTarget: 'commonjs2' + libraryTarget: 'commonjs2', }, optimization: { - minimize: false - } + minimize: false, + }, } -module.exports = [browserConfig, moduleConfig].map(({ babel, ...entry }) => merge(base(babel), entry)); +module.exports = [browserConfig, moduleConfig].map(({ babel, ...entry }) => + merge(base(babel), entry), +) diff --git a/packages/crypto/jest.config.js b/packages/crypto/jest.config.js index 75cca1cf6d..4bb674ebeb 100644 --- a/packages/crypto/jest.config.js +++ b/packages/crypto/jest.config.js @@ -2,19 +2,11 @@ module.exports = { testEnvironment: 'node', bail: false, verbose: true, - testMatch: [ - '**/__tests__/**/*.test.js' - ], - moduleFileExtensions: [ - 'js', - 'json' - ], + testMatch: ['**/__tests__/**/*.test.js'], + moduleFileExtensions: ['js', 'json'], coverageDirectory: '/.coverage', - collectCoverageFrom: [ - 'lib/**/*.js', - '!**/node_modules/**' - ], + collectCoverageFrom: ['lib/**/*.js', '!**/node_modules/**'], watchman: false, setupFiles: ['/../../node_modules/regenerator-runtime/runtime'], - setupTestFrameworkScriptFile: 'jest-extended' + setupTestFrameworkScriptFile: 'jest-extended', } diff --git a/packages/crypto/jsdoc.json b/packages/crypto/jsdoc.json index 23276f74ea..f3ea8aab33 100644 --- a/packages/crypto/jsdoc.json +++ b/packages/crypto/jsdoc.json @@ -7,9 +7,7 @@ "includePattern": ".js$", "excludePattern": "(node_modules/|docs)" }, - "plugins": [ - "plugins/markdown" - ], + "plugins": ["plugins/markdown"], "opts": { "template": "../../node_modules/docdash", "encoding": "utf8", diff --git a/packages/crypto/lib/builder/index.js b/packages/crypto/lib/builder/index.js index b5f11b3eda..54dafea4f8 100644 --- a/packages/crypto/lib/builder/index.js +++ b/packages/crypto/lib/builder/index.js @@ -3,7 +3,7 @@ class TransactionBuilderDirector { * Create new delegate resignation transaction type. * @return {DelegateResignationBuilder} */ - delegateResignation () { + delegateResignation() { return this.__getTransaction('delegate-resignation') } @@ -11,7 +11,7 @@ class TransactionBuilderDirector { * Create new delegate transaction type. * @return {DelegateRegistrationBuilder} */ - delegateRegistration () { + delegateRegistration() { return this.__getTransaction('delegate-registration') } @@ -19,7 +19,7 @@ class TransactionBuilderDirector { * Create new IPFS transaction type. * @return {IPFSBuilder} */ - ipfs () { + ipfs() { return this.__getTransaction('ipfs') } @@ -27,7 +27,7 @@ class TransactionBuilderDirector { * Create new multi-payment transaction type. * @return {MultiPaymentBuilder} */ - multiPayment () { + multiPayment() { return this.__getTransaction('multi-payment') } @@ -35,7 +35,7 @@ class TransactionBuilderDirector { * Create new multi-signature transaction type. * @return {MultiSignatureBuilder} */ - multiSignature () { + multiSignature() { return this.__getTransaction('multi-signature') } @@ -43,7 +43,7 @@ class TransactionBuilderDirector { * Create new second signature transaction type. * @return {SecondSignatureBuilder} */ - secondSignature () { + secondSignature() { return this.__getTransaction('second-signature') } @@ -51,7 +51,7 @@ class TransactionBuilderDirector { * Create new timelock transfer transaction type. * @return {TimelockTransferBuilder} */ - timelockTransfer () { + timelockTransfer() { return this.__getTransaction('timelock-transfer') } @@ -59,7 +59,7 @@ class TransactionBuilderDirector { * Create new transfer transaction type. * @return {TransferBuilder} */ - transfer () { + transfer() { return this.__getTransaction('transfer') } @@ -67,7 +67,7 @@ class TransactionBuilderDirector { * Create new vote transaction type. * @return {VoteBuilder} */ - vote () { + vote() { return this.__getTransaction('vote') } @@ -76,7 +76,7 @@ class TransactionBuilderDirector { * @param {String} transactionType * @return {TransactionBuilder} */ - __getTransaction (transactionType) { + __getTransaction(transactionType) { return new (require(`./transactions/${transactionType}`))() // eslint-disable-line new-cap } } diff --git a/packages/crypto/lib/builder/transactions/delegate-registration.js b/packages/crypto/lib/builder/transactions/delegate-registration.js index b08622388e..451b14f31a 100644 --- a/packages/crypto/lib/builder/transactions/delegate-registration.js +++ b/packages/crypto/lib/builder/transactions/delegate-registration.js @@ -7,7 +7,7 @@ module.exports = class DelegateRegistrationBuilder extends TransactionBuilder { /** * @constructor */ - constructor () { + constructor() { super() this.data.type = TRANSACTION_TYPES.DELEGATE_REGISTRATION @@ -23,7 +23,7 @@ module.exports = class DelegateRegistrationBuilder extends TransactionBuilder { * @param {String} username * @return {DelegateRegistrationBuilder} */ - usernameAsset (username) { + usernameAsset(username) { this.data.asset.delegate.username = username return this } @@ -34,7 +34,7 @@ module.exports = class DelegateRegistrationBuilder extends TransactionBuilder { * @return {DelegateRegistrationBuilder} * TODO rename to `assetDelegate` and merge with username ? */ - sign (passphrase) { + sign(passphrase) { this.data.asset.delegate.publicKey = crypto.getKeys(passphrase).publicKey super.sign(passphrase) return this @@ -44,7 +44,7 @@ module.exports = class DelegateRegistrationBuilder extends TransactionBuilder { * Overrides the inherited method to return the additional required by this type of transaction. * @return {Object} */ - getStruct () { + getStruct() { const struct = super.getStruct() struct.amount = this.data.amount struct.recipientId = this.data.recipientId diff --git a/packages/crypto/lib/builder/transactions/delegate-resignation.js b/packages/crypto/lib/builder/transactions/delegate-resignation.js index 8b31c90356..eb6072edc4 100644 --- a/packages/crypto/lib/builder/transactions/delegate-resignation.js +++ b/packages/crypto/lib/builder/transactions/delegate-resignation.js @@ -6,7 +6,7 @@ module.exports = class DelegateResignationBuilder extends TransactionBuilder { /** * @constructor */ - constructor () { + constructor() { super() this.data.type = TRANSACTION_TYPES.DELEGATE_RESIGNATION diff --git a/packages/crypto/lib/builder/transactions/ipfs.js b/packages/crypto/lib/builder/transactions/ipfs.js index 2e9bbb4203..d86ead86b1 100644 --- a/packages/crypto/lib/builder/transactions/ipfs.js +++ b/packages/crypto/lib/builder/transactions/ipfs.js @@ -6,7 +6,7 @@ module.exports = class IPFSBuilder extends TransactionBuilder { /** * @constructor */ - constructor () { + constructor() { super() this.data.type = TRANSACTION_TYPES.IPFS @@ -22,7 +22,7 @@ module.exports = class IPFSBuilder extends TransactionBuilder { * @param {String} ipfsHash * @return {IPFSBuilder} */ - ipfsHash (ipfsHash) { + ipfsHash(ipfsHash) { this.data.ipfsHash = ipfsHash return this } @@ -32,14 +32,17 @@ module.exports = class IPFSBuilder extends TransactionBuilder { * @param {String} type TODO is it necessary? * @return {IPFSBuilder} */ - vendorField (type) { - this.data.vendorFieldHex = Buffer.from(this.data.ipfsHash, type).toString('hex') + vendorField(type) { + this.data.vendorFieldHex = Buffer.from(this.data.ipfsHash, type).toString( + 'hex', + ) while (this.data.vendorFieldHex.length < 128) { - this.data.vendorFieldHex = '00' + this.data.vendorFieldHex + this.data.vendorFieldHex = `00${this.data.vendorFieldHex}` } - // TODO is this right? when is vendorFieldHex.length is odd, it will add 1 more "0" than previous way + // TODO is this right? when is vendorFieldHex.length is odd, + // it will add 1 more "0" than previous way // const vendorFieldHex = Buffer.from(this.data.ipfsHash, type).toString('hex') // this.data.vendorFieldHex = vendorFieldHex.padStart(128, '0') @@ -50,7 +53,7 @@ module.exports = class IPFSBuilder extends TransactionBuilder { * Overrides the inherited method to return the additional required by this. * @return {Object} */ - getStruct () { + getStruct() { const struct = super.getStruct() struct.amount = this.data.amount struct.vendorFieldHex = this.data.vendorFieldHex diff --git a/packages/crypto/lib/builder/transactions/mixins/sign.js b/packages/crypto/lib/builder/transactions/mixins/sign.js index 84620d8948..04455a23ad 100644 --- a/packages/crypto/lib/builder/transactions/mixins/sign.js +++ b/packages/crypto/lib/builder/transactions/mixins/sign.js @@ -1,18 +1,44 @@ const { crypto } = require('../../../crypto') +const configManager = require('../../../managers/config') module.exports = { - mixin (Base) { + mixin(Base) { return class extends Base { /** * Overrides the inherited `sign` method to set the sender as the recipient too * @param {String} passphrase * @return {TransactionBuilder} */ - sign (passphrase) { - this.data.recipientId = crypto.getAddress(crypto.getKeys(passphrase).publicKey) + sign(passphrase) { + const pubKeyHash = this.data.network + ? this.data.network.pubKeyHash + : null + this.data.recipientId = crypto.getAddress( + crypto.getKeys(passphrase).publicKey, + pubKeyHash, + ) super.sign(passphrase) return this } + + /** + * Overrides the inherited `signWithWif` method to set the sender as the recipient too + * @param {String} wif + * @param {String} networkWif - value associated with network + * @return {TransactionBuilder} + */ + signWithWif(wif, networkWif) { + const pubKeyHash = this.data.network + ? this.data.network.pubKeyHash + : null + const keys = crypto.getKeysFromWIF(wif, { + wif: networkWif || configManager.get('wif'), + }) + this.data.recipientId = crypto.getAddress(keys.publicKey, pubKeyHash) + super.signWithWif(wif, networkWif) + + return this + } } - } + }, } diff --git a/packages/crypto/lib/builder/transactions/mixins/vendor-field.js b/packages/crypto/lib/builder/transactions/mixins/vendor-field.js index 1931d9d964..87e15d50d9 100644 --- a/packages/crypto/lib/builder/transactions/mixins/vendor-field.js +++ b/packages/crypto/lib/builder/transactions/mixins/vendor-field.js @@ -1,12 +1,12 @@ module.exports = { - mixin (Base) { + mixin(Base) { return class extends Base { /** * Set vendor field from data. * @param {(String|undefined)} value * @return {TransactionBuilder} */ - vendorField (value) { + vendorField(value) { this.data.vendorField = value // V2 // this.data.vendorFieldHex = Buffer.from(value, type).toString('hex') @@ -14,5 +14,5 @@ module.exports = { return this } } - } + }, } diff --git a/packages/crypto/lib/builder/transactions/multi-payment.js b/packages/crypto/lib/builder/transactions/multi-payment.js index b174c58c60..d481741d7b 100644 --- a/packages/crypto/lib/builder/transactions/multi-payment.js +++ b/packages/crypto/lib/builder/transactions/multi-payment.js @@ -7,7 +7,7 @@ class MultiPaymentBuilder extends TransactionBuilder { /** * @constructor */ - constructor () { + constructor() { super() this.data.type = TRANSACTION_TYPES.MULTI_PAYMENT @@ -22,7 +22,7 @@ class MultiPaymentBuilder extends TransactionBuilder { * @param {Number} amount * @return {MultiPaymentBuilder} */ - addPayment (address, amount) { + addPayment(address, amount) { const paymentsCount = Object.keys(this.data.payments).length / 2 if (paymentsCount >= 2258) { @@ -40,7 +40,7 @@ class MultiPaymentBuilder extends TransactionBuilder { * Overrides the inherited method to return the additional required by this. * @return {Object} */ - getStruct () { + getStruct() { const struct = super.getStruct() struct.senderPublicKey = this.data.senderPublicKey struct.vendorFieldHex = this.data.vendorFieldHex diff --git a/packages/crypto/lib/builder/transactions/multi-signature.js b/packages/crypto/lib/builder/transactions/multi-signature.js index fe2d644429..b2d020d9d6 100644 --- a/packages/crypto/lib/builder/transactions/multi-signature.js +++ b/packages/crypto/lib/builder/transactions/multi-signature.js @@ -7,7 +7,7 @@ class MultiSignatureBuilder extends TransactionBuilder { /** * @constructor */ - constructor () { + constructor() { super() this.data.type = TRANSACTION_TYPES.MULTI_SIGNATURE @@ -23,9 +23,10 @@ class MultiSignatureBuilder extends TransactionBuilder { * @param {Object} multiSignature { keysgroup, lifetime, min } * @return {MultiSignatureBuilder} */ - multiSignatureAsset (multiSignature) { + multiSignatureAsset(multiSignature) { this.data.asset.multisignature = multiSignature - this.data.fee = (multiSignature.keysgroup.length + 1) * feeManager.get(TRANSACTION_TYPES.MULTI_SIGNATURE) + this.data.fee = (multiSignature.keysgroup.length + 1) + * feeManager.get(TRANSACTION_TYPES.MULTI_SIGNATURE) return this } @@ -34,7 +35,7 @@ class MultiSignatureBuilder extends TransactionBuilder { * Overrides the inherited method to return the additional required by this. * @return {Object} */ - getStruct () { + getStruct() { const struct = super.getStruct() struct.amount = this.data.amount struct.recipientId = this.data.recipientId diff --git a/packages/crypto/lib/builder/transactions/second-signature.js b/packages/crypto/lib/builder/transactions/second-signature.js index cb8e37f683..04e3d29ece 100644 --- a/packages/crypto/lib/builder/transactions/second-signature.js +++ b/packages/crypto/lib/builder/transactions/second-signature.js @@ -7,7 +7,7 @@ module.exports = class SecondSignatureBuilder extends TransactionBuilder { /** * @constructor */ - constructor () { + constructor() { super() this.data.type = TRANSACTION_TYPES.SECOND_SIGNATURE @@ -24,8 +24,10 @@ module.exports = class SecondSignatureBuilder extends TransactionBuilder { * @param {String} secondPassphrase * @return {SecondSignatureBuilder} */ - signatureAsset (secondPassphrase) { - this.data.asset.signature.publicKey = crypto.getKeys(secondPassphrase).publicKey + signatureAsset(secondPassphrase) { + this.data.asset.signature.publicKey = crypto.getKeys( + secondPassphrase, + ).publicKey return this } @@ -33,7 +35,7 @@ module.exports = class SecondSignatureBuilder extends TransactionBuilder { * Overrides the inherited method to return the additional required by this. * @return {Object} */ - getStruct () { + getStruct() { const struct = super.getStruct() struct.amount = this.data.amount struct.recipientId = this.data.recipientId diff --git a/packages/crypto/lib/builder/transactions/timelock-transfer.js b/packages/crypto/lib/builder/transactions/timelock-transfer.js index 1ce697a390..862da0ed44 100644 --- a/packages/crypto/lib/builder/transactions/timelock-transfer.js +++ b/packages/crypto/lib/builder/transactions/timelock-transfer.js @@ -7,7 +7,7 @@ class TimelockTransferBuilder extends TransactionBuilder { /** * @constructor */ - constructor () { + constructor() { super() this.data.type = TRANSACTION_TYPES.TIMELOCK_TRANSFER @@ -25,7 +25,7 @@ class TimelockTransferBuilder extends TransactionBuilder { * @param {Number} timelockType * @return {TimelockTransferBuilder} */ - timelock (timelock, timelockType) { + timelock(timelock, timelockType) { this.data.timelock = timelock this.data.timelockType = timelockType return this @@ -35,7 +35,7 @@ class TimelockTransferBuilder extends TransactionBuilder { * Overrides the inherited method to return the additional required by this * @return {Object} */ - getStruct () { + getStruct() { const struct = super.getStruct() struct.amount = this.data.amount struct.recipientId = this.data.recipientId diff --git a/packages/crypto/lib/builder/transactions/transaction.js b/packages/crypto/lib/builder/transactions/transaction.js index c42a8840c4..f39c4a83c1 100644 --- a/packages/crypto/lib/builder/transactions/transaction.js +++ b/packages/crypto/lib/builder/transactions/transaction.js @@ -6,12 +6,12 @@ module.exports = class TransactionBuilder { /** * @constructor */ - constructor () { + constructor() { this.data = { id: null, timestamp: slots.getTime(), version: 0x01, - network: configManager.get('pubKeyHash') + network: configManager.get('pubKeyHash'), } } @@ -19,8 +19,8 @@ module.exports = class TransactionBuilder { * Build a new Transaction instance. * @return {Transaction} */ - build (data) { - return new Transaction({ ...(this.data), ...data }) + build(data) { + return new Transaction({ ...this.data, ...data }) } /** @@ -28,18 +28,31 @@ module.exports = class TransactionBuilder { * @param {Number} version * @return {TransactionBuilder} */ - version (version) { + version(version) { this.data.version = version return this } + /** + * Set transaction network. + * @param {Number} network + * @return {TransactionBuilder} + */ + network(network) { + this.data.network = network + return this + } + /** * Set transaction fee. * @param {Number} fee * @return {TransactionBuilder} */ - fee (fee) { - this.data.fee = fee + fee(fee) { + if (fee !== null) { + this.data.fee = fee + } + return this } @@ -48,7 +61,7 @@ module.exports = class TransactionBuilder { * @param {Number} amount * @return {TransactionBuilder} */ - amount (amount) { + amount(amount) { this.data.amount = amount return this } @@ -58,7 +71,7 @@ module.exports = class TransactionBuilder { * @param {String} recipientId * @return {TransactionBuilder} */ - recipientId (recipientId) { + recipientId(recipientId) { this.data.recipientId = recipientId return this } @@ -68,16 +81,29 @@ module.exports = class TransactionBuilder { * @param {String} publicKey * @return {TransactionBuilder} */ - senderPublicKey (publicKey) { + senderPublicKey(publicKey) { this.data.senderPublicKey = publicKey return this } + /** + * Set vendor field. + * @param {String} vendorField + * @return {TransactionBuilder} + */ + vendorField(vendorField) { + if (vendorField && Buffer.from(vendorField).length <= 64) { + this.data.vendorField = vendorField + } + + return this + } + /** * Verify the transaction. * @return {Boolean} */ - verify () { + verify() { return crypto.verify(this.data) } @@ -86,7 +112,7 @@ module.exports = class TransactionBuilder { * TODO @deprecated when a Transaction model is returned * @return {Buffer} */ - serialize () { + serialize() { return this.model.serialize(this.getStruct()) } @@ -95,7 +121,7 @@ module.exports = class TransactionBuilder { * @param {String} passphrase * @return {TransactionBuilder} */ - sign (passphrase) { + sign(passphrase) { const keys = crypto.getKeys(passphrase) this.data.senderPublicKey = keys.publicKey this.data.signature = crypto.sign(this.__getSigningObject(), keys) @@ -103,15 +129,57 @@ module.exports = class TransactionBuilder { return this } + /** + * Sign transaction using wif. + * @param {String} wif + * @param {String} networkWif - value associated with network + * @return {TransactionBuilder} + */ + signWithWif(wif, networkWif) { + const keys = crypto.getKeysFromWIF(wif, { + wif: networkWif || configManager.get('wif'), + }) + this.data.senderPublicKey = keys.publicKey + this.data.signature = crypto.sign(this.__getSigningObject(), keys) + + return this + } + /** * Sign transaction with second passphrase. * @param {String} secondPassphrase * @return {TransactionBuilder} */ - secondSign (secondPassphrase) { - const keys = crypto.getKeys(secondPassphrase) - // TODO sign or second? - this.data.signSignature = crypto.secondSign(this.__getSigningObject(), keys) + secondSign(secondPassphrase) { + if (secondPassphrase) { + const keys = crypto.getKeys(secondPassphrase) + // TODO sign or second? + this.data.signSignature = crypto.secondSign( + this.__getSigningObject(), + keys, + ) + } + + return this + } + + /** + * Sign transaction with wif. + * @param {String} wif + * @param {String} networkWif - value associated with network + * @return {TransactionBuilder} + */ + secondSignWithWif(wif, networkWif) { + if (wif) { + const keys = crypto.getKeysFromWIF(wif, { + wif: networkWif || configManager.get('wif'), + }) + // TODO sign or second? + this.data.signSignature = crypto.secondSign( + this.__getSigningObject(), + keys, + ) + } return this } @@ -121,7 +189,7 @@ module.exports = class TransactionBuilder { * @param {String} passphrase * @return {TransactionBuilder} */ - multiSignatureSign (passphrase) { + multiSignatureSign(passphrase) { const keys = crypto.getKeys(passphrase) if (!this.data.signatures) { this.data.signatures = [] @@ -135,11 +203,11 @@ module.exports = class TransactionBuilder { * Get structure of transaction * @return {Object} */ - getStruct () { - // TODO - // if (!this.data.senderPublicKey || !this.data.signature) { - // throw new Error('The transaction is not signed yet') - // } + getStruct() { + if (!this.data.senderPublicKey || !this.data.signature) { + throw new Error('The transaction is not signed yet') + } + const struct = { // hex: crypto.getBytes(this).toString('hex'), // v2 id: crypto.getId(this.data).toString('hex'), @@ -149,7 +217,7 @@ module.exports = class TransactionBuilder { type: this.data.type, fee: this.data.fee, - senderPublicKey: this.data.senderPublicKey + senderPublicKey: this.data.senderPublicKey, } if (Array.isArray(this.data.signatures)) { @@ -163,7 +231,7 @@ module.exports = class TransactionBuilder { * Get a valid object used to sign a transaction. * @return {Object} */ - __getSigningObject () { + __getSigningObject() { const { data } = this Object.keys(data).forEach(key => { diff --git a/packages/crypto/lib/builder/transactions/transfer.js b/packages/crypto/lib/builder/transactions/transfer.js index de7b3b744b..53b62359d1 100644 --- a/packages/crypto/lib/builder/transactions/transfer.js +++ b/packages/crypto/lib/builder/transactions/transfer.js @@ -7,7 +7,7 @@ class TransferBuilder extends TransactionBuilder { /** * @constructor */ - constructor () { + constructor() { super() this.data.type = TRANSACTION_TYPES.TRANSFER @@ -15,14 +15,14 @@ class TransferBuilder extends TransactionBuilder { this.data.amount = 0 this.data.recipientId = null this.data.senderPublicKey = null - this.data.expiration = 15 // 15 blocks, 120s + this.data.expiration = 0 } /** * Overrides the inherited method to return the additional required by this * @return {Object} */ - getStruct () { + getStruct() { const struct = super.getStruct() struct.amount = this.data.amount struct.recipientId = this.data.recipientId diff --git a/packages/crypto/lib/builder/transactions/vote.js b/packages/crypto/lib/builder/transactions/vote.js index 3ea497d802..010684bb07 100644 --- a/packages/crypto/lib/builder/transactions/vote.js +++ b/packages/crypto/lib/builder/transactions/vote.js @@ -7,7 +7,7 @@ class VoteBuilder extends TransactionBuilder { /** * @constructor */ - constructor () { + constructor() { super() this.data.type = TRANSACTION_TYPES.VOTE @@ -23,7 +23,7 @@ class VoteBuilder extends TransactionBuilder { * @param {Array} votes * @return {VoteBuilder} */ - votesAsset (votes) { + votesAsset(votes) { this.data.asset.votes = votes return this } @@ -32,7 +32,7 @@ class VoteBuilder extends TransactionBuilder { * Overrides the inherited method to return the additional required by this * @return {Object} */ - getStruct () { + getStruct() { const struct = super.getStruct() struct.amount = this.data.amount struct.recipientId = this.data.recipientId diff --git a/packages/crypto/lib/client.js b/packages/crypto/lib/client.js index ca40ca3313..46e84afcf1 100644 --- a/packages/crypto/lib/client.js +++ b/packages/crypto/lib/client.js @@ -8,7 +8,7 @@ class Client { * @constructor * @param {Object} config */ - constructor (config) { + constructor(config) { this.setConfig(config || NetworkManager.findByName('devnet')) } @@ -16,7 +16,7 @@ class Client { * Set config for client. * @param {Object} config */ - setConfig (config) { + setConfig(config) { configManager.setConfig(config) } @@ -24,7 +24,7 @@ class Client { * Get fee manager. * @return {FeeManager} */ - getFeeManager () { + getFeeManager() { return feeManager } @@ -32,7 +32,7 @@ class Client { * Get config manager. * @return {ConfigManager} */ - getConfigManager () { + getConfigManager() { return configManager } @@ -40,7 +40,7 @@ class Client { * Get transaction builder. * @return {TransactionBuilder} */ - getBuilder () { + getBuilder() { return transactionBuilder } } diff --git a/packages/crypto/lib/constants.js b/packages/crypto/lib/constants.js index c7467886cd..367e5c921f 100644 --- a/packages/crypto/lib/constants.js +++ b/packages/crypto/lib/constants.js @@ -6,7 +6,7 @@ const configTestnet = require('./networks/ark/testnet.json') * The Arktoshi base. * @type {Number} */ -exports.ARKTOSHI = Math.pow(10, 8) +exports.ARKTOSHI = 1e8 /** * Available transaction types. @@ -21,7 +21,31 @@ exports.TRANSACTION_TYPES = Object.freeze({ IPFS: 5, TIMELOCK_TRANSFER: 6, MULTI_PAYMENT: 7, - DELEGATE_RESIGNATION: 8 + DELEGATE_RESIGNATION: 8, + toString(type) { + switch (type) { + case this.TRANSFER: + return 'transfer' + case this.SECOND_SIGNATURE: + return 'second signature' + case this.DELEGATE_REGISTRATION: + return 'delegate registration' + case this.VOTE: + return 'vote' + case this.MULTI_SIGNATURE: + return 'multi signature' + case this.IPFS: + return 'ipfs' + case this.TIMELOCK_TRANSFER: + return 'timelock transfer' + case this.MULTI_PAYMENT: + return 'multi payment' + case this.DELEGATE_RESIGNATION: + return 'delegate resignation' + default: + throw new Error('Invalid transaction type') + } + }, }) /** @@ -32,6 +56,6 @@ exports.CONFIGURATIONS = Object.freeze({ ARK: { MAINNET: configMainnet, DEVNET: configDevnet, - TESTNET: configTestnet - } + TESTNET: configTestnet, + }, }) diff --git a/packages/crypto/lib/crypto/crypto.js b/packages/crypto/lib/crypto/crypto.js index 752e751cc6..555ffb7ab3 100644 --- a/packages/crypto/lib/crypto/crypto.js +++ b/packages/crypto/lib/crypto/crypto.js @@ -1,14 +1,18 @@ -// const createHash = require('create-hash') +/* eslint default-case: "off" */ + const bs58check = require('bs58check') -// const crypto = require('crypto') -const arkjsv1 = require('arkjsv1') -// const { Buffer } = require('buffer/') +const crypto = require('crypto') +const ByteBuffer = require('bytebuffer') +const secp256k1 = require('secp256k1') +const wif = require('wif') const configManager = require('../managers/config') const utils = require('./utils') -const ECPair = require('./ecpair') -const ECSignature = require('./ecsignature') +const { Bignum } = require('../utils') const feeManager = require('../managers/fee') +const { + transactionIdFixTable, +} = require('../constants').CONFIGURATIONS.ARK.MAINNET class Crypto { /** @@ -16,7 +20,7 @@ class Crypto { * @param {Transaction} transaction * @return {Number} */ - getFee (transaction) { + getFee(transaction) { return feeManager.get(transaction.type) } @@ -27,10 +31,159 @@ class Crypto { * @param {Boolean} skipSecondSignature * @return {String} */ - getBytes (transaction, skipSignature, skipSecondSignature) { - if (!transaction.version || transaction.version === 1) { - return arkjsv1.crypto.getBytes(transaction, skipSignature, skipSecondSignature) + getBytes(transaction, skipSignature, skipSecondSignature) { + if (transaction.version && transaction.version !== 1) { + throw new Error('not supported yet') + } + + let assetSize = 0 + let assetBytes = null + + switch (transaction.type) { + case 1: { + // Signature + const { signature } = transaction.asset + const bb = new ByteBuffer(33, true) + const publicKeyBuffer = Buffer.from(signature.publicKey, 'hex') + + for (let i = 0; i < publicKeyBuffer.length; i++) { + bb.writeByte(publicKeyBuffer[i]) + } + + bb.flip() + + assetBytes = new Uint8Array(bb.toArrayBuffer()) + assetSize = assetBytes.length + break + } + + case 2: { + // Delegate + assetBytes = Buffer.from(transaction.asset.delegate.username, 'utf8') + assetSize = assetBytes.length + break + } + + case 3: { + // Vote + if (transaction.asset.votes !== null) { + assetBytes = Buffer.from(transaction.asset.votes.join(''), 'utf8') + assetSize = assetBytes.length + } + break + } + + case 4: { + // Multi-Signature + const keysgroupBuffer = Buffer.from( + transaction.asset.multisignature.keysgroup.join(''), + 'utf8', + ) + const bb = new ByteBuffer(1 + 1 + keysgroupBuffer.length, true) + + bb.writeByte(transaction.asset.multisignature.min) + bb.writeByte(transaction.asset.multisignature.lifetime) + + for (let i = 0; i < keysgroupBuffer.length; i++) { + bb.writeByte(keysgroupBuffer[i]) + } + + bb.flip() + + assetBytes = bb.toBuffer() + assetSize = assetBytes.length + break + } + } + + const bb = new ByteBuffer( + 1 + 4 + 32 + 8 + 8 + 21 + 64 + 64 + 64 + assetSize, + true, + ) + bb.writeByte(transaction.type) + bb.writeInt(transaction.timestamp) + + const senderPublicKeyBuffer = Buffer.from( + transaction.senderPublicKey, + 'hex', + ) + for (let i = 0; i < senderPublicKeyBuffer.length; i++) { + bb.writeByte(senderPublicKeyBuffer[i]) + } + + // Apply fix for broken type 1 and 4 transactions, which were + // erroneously calculated with a recipient id. + const isBrokenTransaction = Object.values(transactionIdFixTable).includes( + transaction.id, + ) + const correctType = transaction.type !== 1 && transaction.type !== 4 + if (transaction.recipientId && (isBrokenTransaction || correctType)) { + const recipient = bs58check.decode(transaction.recipientId) + for (let i = 0; i < recipient.length; i++) { + bb.writeByte(recipient[i]) + } + } else { + for (let i = 0; i < 21; i++) { + bb.writeByte(0) + } + } + + if (transaction.vendorFieldHex) { + const vf = Buffer.from(transaction.vendorFieldHex, 'hex') + const fillstart = vf.length + for (let i = 0; i < fillstart; i++) { + bb.writeByte(vf[i]) + } + for (let i = fillstart; i < 64; i++) { + bb.writeByte(0) + } + } else if (transaction.vendorField) { + const vf = Buffer.from(transaction.vendorField) + const fillstart = vf.length + for (let i = 0; i < fillstart; i++) { + bb.writeByte(vf[i]) + } + for (let i = fillstart; i < 64; i++) { + bb.writeByte(0) + } + } else { + for (let i = 0; i < 64; i++) { + bb.writeByte(0) + } + } + + bb.writeLong(+new Bignum(transaction.amount).toFixed()) + bb.writeLong(+new Bignum(transaction.fee).toFixed()) + + if (assetSize > 0) { + for (let i = 0; i < assetSize; i++) { + bb.writeByte(assetBytes[i]) + } + } + + if (!skipSignature && transaction.signature) { + const signatureBuffer = Buffer.from(transaction.signature, 'hex') + for (let i = 0; i < signatureBuffer.length; i++) { + bb.writeByte(signatureBuffer[i]) + } } + + if (!skipSecondSignature && transaction.signSignature) { + const signSignatureBuffer = Buffer.from(transaction.signSignature, 'hex') + for (let i = 0; i < signSignatureBuffer.length; i++) { + bb.writeByte(signSignatureBuffer[i]) + } + } + + bb.flip() + const arrayBuffer = new Uint8Array(bb.toArrayBuffer()) + const buffer = [] + + for (let i = 0; i < arrayBuffer.length; i++) { + buffer[i] = arrayBuffer[i] + } + + return Buffer.from(buffer) } /** @@ -38,13 +191,19 @@ class Crypto { * @param {Transaction} transaction * @return {String} */ - getId (transaction) { - if (!transaction.version || transaction.version === 1) { - return arkjsv1.crypto.getId(transaction) + getId(transaction) { + if (transaction.version && transaction.version !== 1) { + throw new Error('not supported yet') } + const bytes = this.getBytes(transaction) + return crypto + .createHash('sha256') + .update(bytes) + .digest() + .toString('hex') + // TODO: Enable AIP11 id here - // return crypto.createHash('sha256').update(this.getBytes(transaction)).digest() } /** @@ -52,13 +211,18 @@ class Crypto { * @param {Transaction} transaction * @return {Buffer} */ - getHash (transaction, skipSignature, skipSecondSignature) { - if (!transaction.version || transaction.version === 1) { - return arkjsv1.crypto.getHash(transaction, skipSignature, skipSecondSignature) + getHash(transaction, skipSignature, skipSecondSignature) { + if (transaction.version && transaction.version !== 1) { + throw new Error('not supported yet') } + const bytes = this.getBytes(transaction, skipSignature, skipSecondSignature) + return crypto + .createHash('sha256') + .update(bytes) + .digest() + // TODO: Enable AIP11 id here - // return crypto.createHash('sha256').update(this.getBytes(transaction)).digest() } /** @@ -67,13 +231,15 @@ class Crypto { * @param {Object} keys * @return {Object} */ - sign (transaction, keys) { + sign(transaction, keys) { + let hash if (!transaction.version || transaction.version === 1) { - return arkjsv1.crypto.sign(transaction, keys) + hash = this.getHash(transaction, true, true) + } else { + hash = this.getHash(transaction, false, false) } - const hash = this.getHash(transaction, false, false) - const signature = keys.sign(hash).toDER().toString('hex') + const signature = this.signHash(hash, keys) if (!transaction.signature) { transaction.signature = signature @@ -88,13 +254,9 @@ class Crypto { * @param {Object} keys * @return {Object} */ - secondSign (transaction, keys) { - if (!transaction.version || transaction.version === 1) { - return arkjsv1.crypto.secondSign(transaction, keys) - } - + secondSign(transaction, keys) { const hash = this.getHash(transaction, false, true) - const signature = keys.sign(hash).toDER().toString('hex') + const signature = this.signHash(hash, keys) if (!transaction.secondSignature) { transaction.secondSignature = signature @@ -103,59 +265,163 @@ class Crypto { return signature } + /** + * Sign a hash + * @param {Buffer} hash + * @param {Object} keys + * @return {String} + */ + signHash(hash, keys) { + const { signature } = secp256k1.sign( + hash, + Buffer.from(keys.privateKey, 'hex'), + ) + return secp256k1.signatureExport(signature).toString('hex') + } + /** * Verify transaction on the network. * @param {Transaction} transaction - * @param {(Number|undefined)} networkVersion * @return {Boolean} */ - verify (transaction, network) { - if (!transaction.version || transaction.version === 1) { - return arkjsv1.crypto.verify(transaction, network) + verify(transaction) { + if (transaction.version && transaction.version !== 1) { + // TODO: enable AIP11 when ready here + return false + } + + if (!transaction.signature) { + return false } - // TODO: enable AIP11 when ready here - return false + const hash = this.getHash(transaction, true, true) + return this.verifyHash( + hash, + transaction.signature, + transaction.senderPublicKey, + ) } /** * Verify second signature for transaction. * @param {Transaction} transaction * @param {String} publicKey - * @param {(Number|undefined)} networkVersion * @return {Boolean} */ - verifySecondSignature (transaction, publicKey, network) { - if (!transaction.version || transaction.version === 1) { - try { - return arkjsv1.crypto.verifySecondSignature(transaction, publicKey, network) - } catch (error) { - return false - } + verifySecondSignature(transaction, publicKey) { + let hash + let secondSignature + if (transaction.version && transaction.version !== 1) { + hash = this.getHash(transaction) + secondSignature = transaction.secondSignature + } else { + hash = this.getHash(transaction, false, true) + secondSignature = transaction.signSignature } - const hash = this.getHash(transaction, false, true) + if (!secondSignature) { + return false + } - const secondSignatureBuffer = Buffer.from(transaction.secondSignature, 'hex') - const publicKeyBuffer = Buffer.from(publicKey, 'hex') - const ecpair = ECPair.fromPublicKeyBuffer(publicKeyBuffer, network) - const ecsignature = ECSignature.fromDER(secondSignatureBuffer) + return this.verifyHash(hash, secondSignature, publicKey) + } - return ecpair.verify(hash, ecsignature) + /** + * Verify the hash. + * @param {Buffer} hash + * @param {(Buffer|String)} signature + * @param {(Buffer|String)} publicKey + * @return {Boolean} + */ + verifyHash(hash, signature, publicKey) { + signature = + signature instanceof Buffer ? signature : Buffer.from(signature, 'hex') + publicKey = + publicKey instanceof Buffer ? publicKey : Buffer.from(publicKey, 'hex') + return secp256k1.verify( + hash, + secp256k1.signatureImport(signature), + publicKey, + ) } /** * Get keys from secret. * @param {String} secret - * @param {Object} options - * @return {ECPair} + * @param {boolean} compressed + * @return {Object} */ - getKeys (secret, options) { - const ecpair = ECPair.fromSeed(secret, options) - ecpair.publicKey = ecpair.getPublicKeyBuffer().toString('hex') - ecpair.privateKey = '' + getKeys(secret, compressed = true) { + const privateKey = utils.sha256(Buffer.from(secret, 'utf8')) + return this.getKeysByPrivateKey(privateKey, compressed) + } - return ecpair + /** + * Get keys from a private key. + * @param {String|Buffer} privateKey + * @param {boolean} compressed + * @return {Object} + */ + getKeysByPrivateKey(privateKey, compressed = true) { + privateKey = + privateKey instanceof Buffer ? privateKey : Buffer.from(privateKey, 'hex') + + const publicKey = secp256k1.publicKeyCreate(privateKey, compressed) + const keyPair = { + publicKey: publicKey.toString('hex'), + privateKey: privateKey.toString('hex'), + compressed, + } + + return keyPair + } + + /** + * Get keys from WIF key. + * @param {String} wifKey + * @param {Object} network + * @return {Object} + */ + getKeysFromWIF(wifKey, network) { + const decoded = wif.decode(wifKey) + const version = decoded.version + + if (!network) { + network = configManager.all() + } + + if (version !== network.wif) { + throw new Error('Invalid network version') + } + + const privateKey = decoded.privateKey + const publicKey = secp256k1.publicKeyCreate(privateKey, decoded.compressed) + + const keyPair = { + publicKey: publicKey.toString('hex'), + privateKey: privateKey.toString('hex'), + compressed: decoded.compressed, + } + + return keyPair + } + + /** + * Get WIF key from keys + * @param {Object} keys + * @param {(Object|undefined)} network + * @returns {String} + */ + keysToWIF(keys, network) { + if (!network) { + network = configManager.all() + } + + return wif.encode( + network.wif, + Buffer.from(keys.privateKey, 'hex'), + keys.compressed, + ) } /** @@ -164,7 +430,12 @@ class Crypto { * @param {(Number|undefined)} networkVersion * @return {String} */ - getAddress (publicKey, networkVersion) { + getAddress(publicKey, networkVersion) { + const pubKeyRegex = /^[0-9A-Fa-f]{66}$/ + if (!pubKeyRegex.test(publicKey)) { + throw new Error(`publicKey '${publicKey}' is invalid`) + } + if (!networkVersion) { networkVersion = configManager.get('pubKeyHash') } @@ -184,13 +455,13 @@ class Crypto { * @param {(Number|undefined)} networkVersion * @return {Boolean} */ - validateAddress (address, networkVersion) { + validateAddress(address, networkVersion) { if (!networkVersion) { networkVersion = configManager.get('pubKeyHash') } try { - var decode = bs58check.decode(address) + const decode = bs58check.decode(address) return decode[0] === networkVersion } catch (e) { return false @@ -203,7 +474,7 @@ class Crypto { * @param {(Number|undefined)} networkVersion * @return {Boolean} */ - validatePublicKey (address, networkVersion) { + validatePublicKey(address, networkVersion) { if (!networkVersion) { networkVersion = configManager.get('pubKeyHash') } diff --git a/packages/crypto/lib/crypto/ecdsa.js b/packages/crypto/lib/crypto/ecdsa.js deleted file mode 100644 index e9c0e5b1e3..0000000000 --- a/packages/crypto/lib/crypto/ecdsa.js +++ /dev/null @@ -1,183 +0,0 @@ -const createHmac = require('create-hmac') -const typeforce = require('typeforce') -const ecurve = require('ecurve') -const BigInteger = require('bigi') - -const types = require('./types') -const ECSignature = require('./ecsignature') - -const ZERO = Buffer.from([0]) -const ONE = Buffer.from([1]) - -const secp256k1 = ecurve.getCurveByName('secp256k1') -const N_OVER_TWO = secp256k1.n.shiftRight(1) - -class ECDSA { - /** - * @constructor - */ - constructor () { - this.__curve = secp256k1 - } - - /** - * [Generation of k.](https://tools.ietf.org/html/rfc6979#section-3.2) - * - * @param {Buffer} hash - * @param {Buffer} x - * @param {function} checkSig - * @returns {BigInteger} - */ - deterministicGenerateK (hash, x, checkSig) { - typeforce(types.tuple( - types.Hash256bit, - types.Buffer256bit, - types.Function - ), arguments) - - let k = Buffer.alloc(32) - let v = Buffer.alloc(32) - - // Step A, ignored as hash already provided - // Step B - v.fill(1) - - // Step C - k.fill(0) - - // Step D - k = createHmac('sha256', k) - .update(v) - .update(ZERO) - .update(x) - .update(hash) - .digest() - - // Step E - v = createHmac('sha256', k).update(v).digest() - - // Step F - k = createHmac('sha256', k) - .update(v) - .update(ONE) - .update(x) - .update(hash) - .digest() - - // Step G - v = createHmac('sha256', k).update(v).digest() - - // Step H1/H2a, ignored as tlen === qlen (256 bit) - // Step H2b - v = createHmac('sha256', k).update(v).digest() - - let T = BigInteger.fromBuffer(v) - - // Step H3, repeat until T is within the interval [1, n - 1] and is suitable for ECDSA - while (T.signum() <= 0 || T.compareTo(secp256k1.n) >= 0 || !checkSig(T)) { - k = createHmac('sha256', k) - .update(v) - .update(ZERO) - .digest() - - v = createHmac('sha256', k).update(v).digest() - - // Step H1/H2a, again, ignored as tlen === qlen (256 bit) - // Step H2b again - v = createHmac('sha256', k).update(v).digest() - T = BigInteger.fromBuffer(v) - } - - return T - } - - /** - * @param {Buffer} hash - * @param {BigInteger} d - * @returns {ECSignature} - */ - sign (hash, d) { - typeforce(types.tuple(types.Hash256bit, types.BigInt), arguments) - - const x = d.toBuffer(32) - const e = BigInteger.fromBuffer(hash) - const n = secp256k1.n - const G = secp256k1.G - - let r, s - this.deterministicGenerateK(hash, x, function (k) { - const Q = G.multiply(k) - - if (secp256k1.isInfinity(Q)) return false - - r = Q.affineX.mod(n) - if (r.signum() === 0) return false - - s = k.modInverse(n).multiply(e.add(d.multiply(r))).mod(n) - if (s.signum() === 0) return false - - return true - }) - - // enforce low S values, see bip62: 'low s values in signatures' - if (s.compareTo(N_OVER_TWO) > 0) { - s = n.subtract(s) - } - - return new ECSignature(r, s) - } - - /** - * @param {Buffer} hash - * @param {ECSignature} signature - * @param {ECPoint} Q - * @returns {boolean} - */ - verify (hash, signature, Q) { - typeforce(types.tuple( - types.Hash256bit, - types.ECSignature, - types.ECPoint - ), arguments) - - const n = secp256k1.n - const G = secp256k1.G - - const r = signature.r - const s = signature.s - - // 1.4.1 Enforce r and s are both integers in the interval [1, n − 1] - if (r.signum() <= 0 || r.compareTo(n) >= 0) return false - if (s.signum() <= 0 || s.compareTo(n) >= 0) return false - - // 1.4.2 H = Hash(M), already done by the user - // 1.4.3 e = H - const e = BigInteger.fromBuffer(hash) - - // Compute s^-1 - const sInv = s.modInverse(n) - - // 1.4.4 Compute u1 = es^−1 mod n - // u2 = rs^−1 mod n - const u1 = e.multiply(sInv).mod(n) - const u2 = r.multiply(sInv).mod(n) - - // 1.4.5 Compute R = (xR, yR) - // R = u1G + u2Q - const R = G.multiplyTwo(u1, Q, u2) - - // 1.4.5 (cont.) Enforce R is not at infinity - if (secp256k1.isInfinity(R)) return false - - // 1.4.6 Convert the field element R.x to an integer - const xR = R.affineX - - // 1.4.7 Set v = xR mod n - const v = xR.mod(n) - - // 1.4.8 If v = r, output "valid", and if v != r, output "invalid" - return v.equals(r) - } -} - -module.exports = new ECDSA() diff --git a/packages/crypto/lib/crypto/ecpair.js b/packages/crypto/lib/crypto/ecpair.js deleted file mode 100644 index 11af879f4b..0000000000 --- a/packages/crypto/lib/crypto/ecpair.js +++ /dev/null @@ -1,196 +0,0 @@ -const base58check = require('bs58check') -const BigInteger = require('bigi') -const ecurve = require('ecurve') -const randomBytes = require('randombytes') -const secp256k1native = require('secp256k1') -const typeforce = require('typeforce') -const wif = require('wif') - -const configManager = require('../managers/config') -const utils = require('./utils') -const ECSignature = require('./ecsignature') -const types = require('./types') - -const secp256k1 = ecurve.getCurveByName('secp256k1') - -class ECPair { - /** - * @param {BigInteger} [d] Private key. - * @param {Point} [Q] Public key. - * @param {object} [options] - * @param {boolean} [options.compressed=true] - * @param {Network} [options.network=networks.mainnet] - */ - constructor (d, Q, options) { - if (options) { - typeforce({ - compressed: types.maybe(types.Boolean), - network: types.maybe(types.Network) - }, options) - } - - options = options || {} - - if (d) { - if (d.signum() <= 0) throw new Error('Private key must be greater than 0') - if (d.compareTo(secp256k1.n) >= 0) throw new Error('Private key must be less than the curve order') - if (Q) throw new TypeError('Unexpected publicKey parameter') - - this.d = d - this.Q = secp256k1.G.multiply(this.d) - } else { - typeforce(types.ECPoint, Q) - - this.Q = Q - } - - /** @type {boolean} */ - this.compressed = options.compressed === undefined ? true : options.compressed - /** @type {Network} */ - this.network = options.network || configManager.all() - } - - /** - * @param {Buffer} buffer - * @param {(Object|Array)} network - * @returns {ECPair} - */ - static fromPublicKeyBuffer (buffer, network) { - const Q = ecurve.Point.decodeFrom(secp256k1, buffer) - - return new ECPair(null, Q, { - compressed: Q.compressed, - network - }) - } - - /** - * @param {String} seed - * @param {Object} options - * @returns {ECPair} - */ - static fromSeed (seed, options) { - const hash = utils.sha256(Buffer.from(seed, 'utf-8')) - const d = BigInteger.fromBuffer(hash) - - if (d.signum() <= 0 || d.compareTo(secp256k1.n) >= 0) { - throw new Error('seed cannot resolve to a compatible private key') - } - - return new ECPair(d, null, options) - } - - /** - * @param {String} string - * @param {(Object|Array)} network - * @returns {ECPair} - */ - static fromWIF (string, network) { - const decoded = wif.decode(string) - const version = decoded.version - - // [network, ...] - if (types.Array(network)) { - network = network.filter(function (network) { - return version === network.wif - }).pop() - - if (!network) throw new Error('Unknown network version') - - // network - } else { - network = network || configManager.all() - - if (version !== network.wif) throw new Error('Invalid network version') - } - - const d = BigInteger.fromBuffer(decoded.privateKey) - - return new ECPair(d, null, { - compressed: decoded.compressed, - network - }) - } - - /** - * @param {Object} options - * @returns {ECPair} - */ - static makeRandom (options) { - options = options || {} - - const rng = options.rng || randomBytes - - let d - do { - const buffer = rng(32) - typeforce(types.Buffer256bit, buffer) - - d = BigInteger.fromBuffer(buffer) - } while (d.signum() <= 0 || d.compareTo(secp256k1.n) >= 0) - - return new ECPair(d, null, options) - } - - /** - * @returns {ECPair} - */ - getAddress () { - const payload = Buffer.alloc(21) - const hash = utils.ripemd160(this.getPublicKeyBuffer()) - const version = this.network.pubKeyHash - payload.writeUInt8(version, 0) - hash.copy(payload, 1) - - return base58check.encode(payload) - } - - /** - * @returns {ECPair} - */ - getNetwork () { - return this.network - } - - /** - * @returns {ECPair} - */ - getPublicKeyBuffer () { - return this.Q.getEncoded(this.compressed) - } - - /** - * @param {Buffer} hash - * @returns {ECPair} - */ - sign (hash) { - if (!this.d) { - throw new Error('Missing private key') - } - - const native = secp256k1native.sign(hash, this.d.toBuffer(32)) - return ECSignature.parseNativeSecp256k1(native).signature - } - - /** - * @returns {ECPair} - */ - toWIF () { - if (!this.d) { - throw new Error('Missing private key') - } - - return wif.encode(this.network.wif, this.d.toBuffer(32), this.compressed) - } - - /** - * @param {Buffer} hash - * @param {ECPair} signature - * @returns {ECPair} - */ - verify (hash, signature) { - return secp256k1native.verify(hash, signature.toNativeSecp256k1(), this.Q.getEncoded(this.compressed)) - } -} - -module.exports = ECPair diff --git a/packages/crypto/lib/crypto/ecsignature.js b/packages/crypto/lib/crypto/ecsignature.js deleted file mode 100644 index c26f29f9f9..0000000000 --- a/packages/crypto/lib/crypto/ecsignature.js +++ /dev/null @@ -1,166 +0,0 @@ -const bip66 = require('bip66') -const typeforce = require('typeforce') -const BigInteger = require('bigi') -const types = require('./types') - -/** - * @typedef {Object} SignatureParseResult - * @property {boolean} compressed - * @property {number} i - * @property {ECSignature} signature - */ - -/** - * Creates a new ECSignature. - */ -class ECSignature { - /** - * Create a new ECSignature instance. - * @param {BigInteger} r - * @param {BigInteger} s - * @return {void} - */ - constructor (r, s) { - typeforce(types.tuple(types.BigInt, types.BigInt), arguments) - - /** @type {BigInteger} */ - this.r = r - /** @type {BigInteger} */ - this.s = s - } - - /** - * @param {*} native - * @return {SignatureParseResult} - */ - static parseNativeSecp256k1 (native) { - if (native.signature.length !== 64) throw new Error('Invalid signature length') - - const compressed = 0 - const recoveryParam = native.recovery - - const r = BigInteger.fromBuffer(native.signature.slice(0, 32)) - const s = BigInteger.fromBuffer(native.signature.slice(32)) - - return { - compressed, - i: recoveryParam, - signature: new ECSignature(r, s) - } - } - - /** - * @return {Buffer} - */ - toNativeSecp256k1 () { - const buffer = Buffer.alloc(64) - if (this.r.toBuffer().length > 32 || this.s.toBuffer().length > 32) { - return buffer - } - - this.r.toBuffer(32).copy(buffer, 0) - this.s.toBuffer(32).copy(buffer, 32) - - return buffer - } - - /** - * @param {Buffer} buffer - * @return {SignatureParseResult} - */ - static parseCompact (buffer) { - if (buffer.length !== 65) throw new Error('Invalid signature length') - - const flagByte = buffer.readUInt8(0) - 27 - if (flagByte !== (flagByte & 7)) throw new Error('Invalid signature parameter') - - const compressed = !!(flagByte & 4) - const recoveryParam = flagByte & 3 - - const r = BigInteger.fromBuffer(buffer.slice(1, 33)) - const s = BigInteger.fromBuffer(buffer.slice(33)) - - return { - compressed, - i: recoveryParam, - signature: new ECSignature(r, s) - } - } - - /** - * @param {Buffer} buffer - * @return {ECSignature} - */ - static fromDER (buffer) { - const decode = bip66.decode(buffer) - const r = BigInteger.fromDERInteger(decode.r) - const s = BigInteger.fromDERInteger(decode.s) - - return new ECSignature(r, s) - } - - /** - * BIP62: 1-byte `hashType` flag (only `0x01`, `0x02`, `0x03`, `0x81`, `0x82`, and `0x83` are allowed). - * - * @param {Buffer} buffer - * @return {Object} - */ - static parseScriptSignature (buffer) { - const hashType = buffer.readUInt8(buffer.length - 1) - const hashTypeMod = hashType & ~0x80 - - if (hashTypeMod <= 0x00 || hashTypeMod >= 0x04) throw new Error('Invalid hashType ' + hashType) - - return { - signature: this.fromDER(buffer.slice(0, -1)), - hashType - } - } - - /** - * @param {Number} i - * @param {Boolean} compressed - * @return {Buffer} - */ - toCompact (i, compressed) { - if (compressed) { - i += 4 - } - - i += 27 - - const buffer = Buffer.alloc(65) - buffer.writeUInt8(i, 0) - - this.r.toBuffer(32).copy(buffer, 1) - this.s.toBuffer(32).copy(buffer, 33) - - return buffer - } - - /** - * @return {Buffer} - */ - toDER () { - const r = Buffer.from(this.r.toDERInteger()) - const s = Buffer.from(this.s.toDERInteger()) - - return bip66.encode(r, s) - } - - /** - * @param {Number} hashType - * @return {Buffer} - */ - toScriptSignature (hashType) { - const hashTypeMod = hashType & ~0x80 - if (hashTypeMod <= 0 || hashTypeMod >= 4) throw new Error('Invalid hashType ' + hashType) - - const hashTypeBuffer = Buffer.alloc(1) - hashTypeBuffer.writeUInt8(hashType, 0) - - return Buffer.concat([this.toDER(), hashTypeBuffer]) - } -} - -module.exports = ECSignature diff --git a/packages/crypto/lib/crypto/hdnode/constants.js b/packages/crypto/lib/crypto/hdnode/constants.js deleted file mode 100644 index 119d57b0a4..0000000000 --- a/packages/crypto/lib/crypto/hdnode/constants.js +++ /dev/null @@ -1,14 +0,0 @@ -/** - * @type {Number} - */ -exports.HIGHEST_BIT = 0x80000000 - -/** - * @type {Number} - */ -exports.LENGTH = 78 - -/** - * @type {Buffer} - */ -exports.MASTER_SECRET = Buffer.from('Bitcoin seed') diff --git a/packages/crypto/lib/crypto/hdnode/index.js b/packages/crypto/lib/crypto/hdnode/index.js deleted file mode 100644 index c9624352dc..0000000000 --- a/packages/crypto/lib/crypto/hdnode/index.js +++ /dev/null @@ -1,395 +0,0 @@ -const base58check = require('bs58check') -const createHmac = require('create-hmac') -const typeforce = require('typeforce') -const ecurve = require('ecurve') -const BigInteger = require('bigi') - -const configManager = require('../../managers/config') -const utils = require('../utils') -const types = require('../types') -const ECPair = require('../ecpair') -const { HIGHEST_BIT, MASTER_SECRET } = require('./constants') - -const curve = ecurve.getCurveByName('secp256k1') - -module.exports = class HDNode { - /** - * Create a new HDNode instance. - * @param {ECPair} keyPair - * @param {Buffer} chainCode - * @return {void} - */ - constructor (keyPair, chainCode) { - typeforce(types.tuple('ECPair', types.Buffer256bit), arguments) - - if (!keyPair.compressed) { - throw new TypeError('BIP32 only allows compressed keyPairs') - } - - /** @type {ECPair} */ - this.keyPair = keyPair - /** @type {Buffer} */ - this.chainCode = chainCode - /** @type {number} */ - this.depth = 0 - /** @type {number} */ - this.index = 0 - /** @type {number} */ - this.parentFingerprint = 0x00000000 - } - - /** - * @param {(String|Buffer)} seed - * @param {Object} network - * @return {HDNode} - */ - static fromSeedBuffer (seed, network) { - typeforce(types.tuple(types.Buffer, types.maybe(types.Network)), arguments) - - if (seed.length < 16) { - throw new TypeError('Seed should be at least 128 bits') - } - - if (seed.length > 64) { - throw new TypeError('Seed should be at most 512 bits') - } - - const I = createHmac('sha512', MASTER_SECRET).update(seed).digest() - const IL = I.slice(0, 32) - const IR = I.slice(32) - - // In case IL is 0 or >= n, the master key is invalid - // This is handled by the ECPair constructor - const pIL = BigInteger.fromBuffer(IL) - const keyPair = new ECPair(pIL, null, { - network: network - }) - - return new HDNode(keyPair, IR) - } - - /** - * @param {String} hex - * @param {Object} network - * @return {HDNode} - */ - static fromSeedHex (hex, network) { - return HDNode.fromSeedBuffer(Buffer.from(hex, 'hex'), network) - } - - /** - * @param {String} string - * @param {(Object|Array)} networks - * @return {HDNode} - */ - static fromBase58 (string, networks) { - const buffer = base58check.decode(string) - - if (buffer.length !== 78) throw new Error('Invalid buffer length') - - // 4 bytes: version bytes - const version = buffer.readUInt32BE(0) - let network - - // list of networks? - if (Array.isArray(networks)) { - network = networks.filter(function (network) { - return version === network.bip32.private || version === network.bip32.public - }).pop() - - if (!network) throw new Error('Unknown network version') - - // otherwise, assume a network object (or default to ark) - } else { - network = networks || configManager.all() - } - - if (version !== network.bip32.private && - version !== network.bip32.public) throw new Error('Invalid network version') - - // 1 byte: depth: 0x00 for master nodes, 0x01 for level-1 descendants, ... - const depth = buffer[4] - - // 4 bytes: the fingerprint of the parent's key (0x00000000 if master key) - const parentFingerprint = buffer.readUInt32BE(5) - if (depth === 0) { - if (parentFingerprint !== 0x00000000) throw new Error('Invalid parent fingerprint') - } - - // 4 bytes: child number. This is the number i in xi = xpar/i, with xi the key being serialized. - // This is encoded in MSB order. (0x00000000 if master key) - const index = buffer.readUInt32BE(9) - if (depth === 0 && index !== 0) throw new Error('Invalid index') - - // 32 bytes: the chain code - const chainCode = buffer.slice(13, 45) - let keyPair - - // 33 bytes: private key data (0x00 + k) - if (version === network.bip32.private) { - if (buffer.readUInt8(45) !== 0x00) throw new Error('Invalid private key') - - const d = BigInteger.fromBuffer(buffer.slice(46, 78)) - keyPair = new ECPair(d, null, { - network: network - }) - - // 33 bytes: public key data (0x02 + X or 0x03 + X) - } else { - const Q = ecurve.Point.decodeFrom(curve, buffer.slice(45, 78)) - // Q.compressed is assumed, if somehow this assumption is broken, `new HDNode` will throw - - // Verify that the X coordinate in the public point corresponds to a point on the curve. - // If not, the extended public key is invalid. - curve.validate(Q) - - keyPair = new ECPair(null, Q, { - network: network - }) - } - - let hd = new HDNode(keyPair, chainCode) - hd.depth = depth - hd.index = index - hd.parentFingerprint = parentFingerprint - - return hd - } - - /** - * @return {Buffer} - */ - getAddress () { - return this.keyPair.getAddress() - } - - /** - * @return {Buffer} - */ - getIdentifier () { - return utils.hash160(this.keyPair.getPublicKeyBuffer()) - } - - /** - * @return {Buffer} - */ - getFingerprint () { - return this.getIdentifier().slice(0, 4) - } - - /** - * @return {Object} - */ - getNetwork () { - return this.keyPair.getNetwork() - } - - /** - * @return {Buffer} - */ - getPublicKeyBuffer () { - return this.keyPair.getPublicKeyBuffer() - } - - /** - * @return {HDNode} - */ - neutered () { - const neuteredKeyPair = new ECPair(null, this.keyPair.Q, { - network: this.keyPair.network - }) - - let neutered = new HDNode(neuteredKeyPair, this.chainCode) - neutered.depth = this.depth - neutered.index = this.index - neutered.parentFingerprint = this.parentFingerprint - - return neutered - } - - /** - * @param {Buffer} hash - * @return {ECSignature} - */ - sign (hash) { - return this.keyPair.sign(hash) - } - - /** - * @param {Buffer} hash - * @param {ECPair} signature - * @return {boolean} - */ - verify (hash, signature) { - return this.keyPair.verify(hash, signature) - } - - /** - * @return {String} - */ - toBase58 () { - // Version - const network = this.keyPair.network - const version = this.isNeutered() ? network.bip32.public : network.bip32.private - const buffer = Buffer.alloc(78) - - // 4 bytes: version bytes - buffer.writeUInt32BE(version, 0) - - // 1 byte: depth: 0x00 for master nodes, 0x01 for level-1 descendants, .... - buffer.writeUInt8(this.depth, 4) - - // 4 bytes: the fingerprint of the parent's key (0x00000000 if master key) - buffer.writeUInt32BE(this.parentFingerprint, 5) - - // 4 bytes: child number. This is the number i in xi = xpar/i, with xi the key being serialized. - // This is encoded in big endian. (0x00000000 if master key) - buffer.writeUInt32BE(this.index, 9) - - // 32 bytes: the chain code - this.chainCode.copy(buffer, 13) - - // 33 bytes: the public key or private key data - if (!this.isNeutered()) { - // 0x00 + k for private keys - buffer.writeUInt8(0, 45) - this.keyPair.d.toBuffer(32).copy(buffer, 46) - - // 33 bytes: the public key - } else { - // X9.62 encoding for public keys - this.keyPair.getPublicKeyBuffer().copy(buffer, 45) - } - - return base58check.encode(buffer) - } - - /** - * https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#child-key-derivation-ckd-functions - * - * @param {Number} index - * @return {HDNode} - */ - derive (index) { - typeforce(types.UInt32, index) - - const isHardened = index >= HIGHEST_BIT - const data = Buffer.alloc(37) - - // Hardened child - if (isHardened) { - if (this.isNeutered()) throw new TypeError('Could not derive hardened child key') - - // data = 0x00 || ser256(kpar) || ser32(index) - data[0] = 0x00 - this.keyPair.d.toBuffer(32).copy(data, 1) - data.writeUInt32BE(index, 33) - - // Normal child - } else { - // data = serP(point(kpar)) || ser32(index) - // = serP(Kpar) || ser32(index) - this.keyPair.getPublicKeyBuffer().copy(data, 0) - data.writeUInt32BE(index, 33) - } - - const I = createHmac('sha512', this.chainCode).update(data).digest() - const IL = I.slice(0, 32) - const IR = I.slice(32) - - const pIL = BigInteger.fromBuffer(IL) - - // In case parse256(IL) >= n, proceed with the next value for i - if (pIL.compareTo(curve.n) >= 0) { - return this.derive(index + 1) - } - - // Private parent key -> private child key - let derivedKeyPair - if (!this.isNeutered()) { - // ki = parse256(IL) + kpar (mod n) - const ki = pIL.add(this.keyPair.d).mod(curve.n) - - // In case ki === 0, proceed with the next value for i - if (ki.signum() === 0) { - return this.derive(index + 1) - } - - derivedKeyPair = new ECPair(ki, null, { - network: this.keyPair.network - }) - - // Public parent key -> public child key - } else { - // Ki = point(parse256(IL)) + Kpar - // = G*IL + Kpar - const Ki = curve.G.multiply(pIL).add(this.keyPair.Q) - - // In case Ki is the point at infinity, proceed with the next value for i - if (curve.isInfinity(Ki)) { - return this.derive(index + 1) - } - - derivedKeyPair = new ECPair(null, Ki, { - network: this.keyPair.network - }) - } - - let hd = new HDNode(derivedKeyPair, IR) - hd.depth = this.depth + 1 - hd.index = index - hd.parentFingerprint = this.getFingerprint().readUInt32BE(0) - - return hd - } - - /** - * @param {Number} index - * @return {HDNode} - */ - deriveHardened (index) { - typeforce(types.UInt31, index) - - // Only derives hardened private keys by default - return this.derive(index + HIGHEST_BIT) - } - - /** - * Private `===` not neutered. - * Public `===` neutered. - * - * @return {Boolean} - */ - isNeutered () { - return !(this.keyPair.d) - } - - /** - * @param {String} path - * @return {HDNode} - */ - derivePath (path) { - typeforce(types.BIP32Path, path) - - let splitPath = path.split('/') - if (splitPath[0] === 'm') { - if (this.parentFingerprint) { - throw new Error('Not a master node') - } - - splitPath = splitPath.slice(1) - } - - return splitPath.reduce((prevHd, indexStr) => { - let index - /* eslint quotes: ["error", "single", { avoidEscape: true }] */ - if (indexStr.slice(-1) === "'") { - index = parseInt(indexStr.slice(0, -1), 10) - return prevHd.deriveHardened(index) - } else { - index = parseInt(indexStr, 10) - return prevHd.derive(index) - } - }, this) - } -} diff --git a/packages/crypto/lib/crypto/hdwallet.js b/packages/crypto/lib/crypto/hdwallet.js new file mode 100644 index 0000000000..84f6588b25 --- /dev/null +++ b/packages/crypto/lib/crypto/hdwallet.js @@ -0,0 +1,74 @@ +const bip32 = require('bip32') +const bip39 = require('bip39') +const configManager = require('../managers/config') + +class HDWallet { + constructor() { + this.slip44 = 111 + } + + /** + * Get root node from the given mnemonic with an optional passphrase. + * @param {String} mnemonic + * @param {(String|undefined)} passphrase + * @returns {bip32} + */ + fromMnemonic(mnemonic, passphrase) { + const seed = bip39.mnemonicToSeed(mnemonic, passphrase) + return bip32.fromSeed(seed, configManager.config) + } + + /** + * Get bip32 node from keys. + * @param {Object} keys + * @param {Buffer} chainCode + * @returns {bip32} + */ + fromKeys(keys, chainCode) { + if (!keys.compressed) { + throw new TypeError('BIP32 only allows compressed keys.') + } + + return bip32.fromPrivateKey( + Buffer.from(keys.privateKey, 'hex'), + chainCode, + configManager.config, + ) + } + + /** + * Get key pair from the given node. + * @param {bip32} node + * @return {Object} + */ + getKeys(node) { + return { + publicKey: node.publicKey.toString('hex'), + privateKey: node.privateKey.toString('hex'), + compressed: true, + } + } + + /** + * Derives a node from the coin type as specified by slip44. + * @param {bip32} root + * @param {(Boolean|undefined)} hardened + * @returns {bip32} + */ + deriveSlip44(root, hardened = true) { + return root.derivePath(`m/44'/${this.slip44}${hardened ? "'" : ''}`) + } + + /** + * Derives a node from the network as specified by AIP20. + * @param {bip32} root + * @returns {bip32} + */ + deriveNetwork(root) { + return this.deriveSlip44(root).deriveHardened( + configManager.config.aip20 || 1, + ) + } +} + +module.exports = new HDWallet() diff --git a/packages/crypto/lib/crypto/index.js b/packages/crypto/lib/crypto/index.js index ed8ea3af23..580886af85 100644 --- a/packages/crypto/lib/crypto/index.js +++ b/packages/crypto/lib/crypto/index.js @@ -1,9 +1,7 @@ module.exports = { crypto: require('./crypto'), - ecdsa: require('./ecdsa'), - ECPair: require('./ecpair'), - ECSignature: require('./ecsignature'), - HDNode: require('./hdnode'), + hdwallet: require('./hdwallet'), + Message: require('./message'), slots: require('./slots'), - utils: require('./utils') + utils: require('./utils'), } diff --git a/packages/crypto/lib/crypto/message.js b/packages/crypto/lib/crypto/message.js new file mode 100644 index 0000000000..5ba4eebecf --- /dev/null +++ b/packages/crypto/lib/crypto/message.js @@ -0,0 +1,58 @@ +const crypto = require('crypto') +const arkCrypto = require('./crypto') +const configManager = require('../managers/config') + +const createHash = message => crypto + .createHash('sha256') + .update(Buffer.from(message, 'utf-8')) + .digest() + +module.exports = class Message { + /** + * Sign the given message. + * @param {String} message + * @param {String} passphrase + * @return {Object} + */ + static sign(message, passphrase) { + const keys = arkCrypto.getKeys(passphrase) + + return { + publicKey: keys.publicKey, + signature: arkCrypto.signHash(createHash(message), keys), + message, + } + } + + /** + * Sign the given message using a WIF. + * @param {String} message + * @param {String} wif + * @param {Object} network + * @return {Object} + */ + static signWithWif(message, wif, network) { + if (!network) { + network = configManager.all() + } + + const keys = arkCrypto.getKeysFromWIF(wif, network) + + return { + publicKey: keys.publicKey, + signature: arkCrypto.signHash(createHash(message), keys), + message, + } + } + + /** + * Verify the given message. + * @param {String} options.message + * @param {String} options.publicKey + * @param {String} options.signature + * @return {Boolean} + */ + static verify({ message, publicKey, signature }) { + return arkCrypto.verifyHash(createHash(message), signature, publicKey) + } +} diff --git a/packages/crypto/lib/crypto/slots.js b/packages/crypto/lib/crypto/slots.js index d90642cbc8..900d7a3cf5 100644 --- a/packages/crypto/lib/crypto/slots.js +++ b/packages/crypto/lib/crypto/slots.js @@ -1,15 +1,47 @@ -const moment = require('moment') +const dayjs = require('dayjs-ext') const configManager = require('../managers/config') class Slots { + /** + * Create a new Slot instance. + */ + constructor() { + this.resetHeight() + } + + /** + * Get the height we are currently at. + * @return {Number} + */ + getHeight() { + return this.height + } + + /** + * Set the height we are currently at. + * @param {Number} height + * @return {void} + */ + setHeight(height) { + this.height = height + } + + /** + * Reset the height to the initial value. + * @return {void} + */ + resetHeight() { + this.height = 1 + } + /** * Get epoch time relative to beginning epoch time. * @param {Number} time * @return {Number} */ - getEpochTime (time) { + getEpochTime(time) { if (time === undefined) { - time = moment().valueOf() + time = dayjs().valueOf() } const start = this.beginEpochTime().valueOf() @@ -21,8 +53,8 @@ class Slots { * Get beginning epoch time. * @return {Moment} */ - beginEpochTime () { - return moment(this.getConstant('epoch')).utc() + beginEpochTime() { + return dayjs(this.getConstant('epoch')).utc() } /** @@ -30,7 +62,7 @@ class Slots { * @param {Number} time * @return {Number} */ - getTime (time) { + getTime(time) { return this.getEpochTime(time) } @@ -39,7 +71,7 @@ class Slots { * @param {Number} epochTime * @return {Number} */ - getRealTime (epochTime) { + getRealTime(epochTime) { if (epochTime === undefined) { epochTime = this.getTime() } @@ -54,7 +86,7 @@ class Slots { * @param {Number} epochTime * @return {Number} */ - getSlotNumber (epochTime) { + getSlotNumber(epochTime) { if (epochTime === undefined) { epochTime = this.getTime() } @@ -67,7 +99,7 @@ class Slots { * @param {Number} slot * @return {Number} */ - getSlotTime (slot) { + getSlotTime(slot) { return slot * this.getConstant('blocktime') } @@ -75,7 +107,7 @@ class Slots { * Get the next slot number. * @return {Number} */ - getNextSlot () { + getNextSlot() { return this.getSlotNumber() + 1 } @@ -84,7 +116,7 @@ class Slots { * @param {Number} nextSlot * @return {Number} */ - getLastSlot (nextSlot) { + getLastSlot(nextSlot) { return nextSlot + this.getConstant('activeDelegates') } @@ -93,8 +125,8 @@ class Slots { * @param {String} key * @return {*} */ - getConstant (key) { - return configManager.getConstants(1)[key] + getConstant(key) { + return configManager.getConstants(this.height)[key] } /** @@ -102,12 +134,14 @@ class Slots { * @param {Number} epochTime * @return {Boolean} */ - isForgingAllowed (epochTime) { + isForgingAllowed(epochTime) { if (epochTime === undefined) { epochTime = this.getTime() } - return Math.floor(epochTime / this.getConstant('blocktime')) === Math.floor((epochTime + this.getConstant('blocktime') / 2) / this.getConstant('blocktime')) // eslint-disable-line max-len + const blockTime = this.getConstant('blocktime') + + return epochTime % blockTime < blockTime / 2 } } diff --git a/packages/crypto/lib/crypto/types.js b/packages/crypto/lib/crypto/types.js deleted file mode 100644 index c8c764fd42..0000000000 --- a/packages/crypto/lib/crypto/types.js +++ /dev/null @@ -1,95 +0,0 @@ -const typeforce = require('typeforce') - -/** - * @type {Number} - */ -const UINT31_MAX = Math.pow(2, 31) - 1 - -/** - * @param {Number} value - */ -function UInt31 (value) { - return typeforce.UInt32(value) && value <= UINT31_MAX -} - -/** - * @param {String} value - */ -function BIP32Path (value) { - return typeforce.String(value) && value.match(/^(m\/)?(\d+'?\/)*\d+'?$/) -} - -BIP32Path.toJSON = () => { - return 'BIP32 derivation path' -} - -/** - * @type {Number} - */ -const SATOSHI_MAX = 21 * 1e14 - -function Satoshi (value) { - return typeforce.UInt53(value) && value <= SATOSHI_MAX -} - -/** - * external dependent types - * - * @type {BigInteger} - */ -const BigInt = typeforce.quacksLike('BigInteger') - -/** - * @type {Point} - */ -const ECPoint = typeforce.quacksLike('Point') - -/** - * exposed, external API - * - * @type {Object} - */ -const ECSignature = typeforce.compile({ - r: BigInt, - s: BigInt -}) - -/** - * @type {Object} - */ -const Network = typeforce.compile({ - messagePrefix: typeforce.oneOf(typeforce.Buffer, typeforce.String), - bip32: { - public: typeforce.UInt32, - private: typeforce.UInt32 - }, - pubKeyHash: typeforce.UInt8, - wif: typeforce.UInt8 -}) - -/** - * extend typeforce types with ours - * - * @type {Object} - */ -let types = { - BigInt: BigInt, - BIP32Path: BIP32Path, - Buffer256bit: typeforce.BufferN(32), - ECPoint: ECPoint, - ECSignature: ECSignature, - Hash160bit: typeforce.BufferN(20), - Hash256bit: typeforce.BufferN(32), - Network: Network, - Satoshi: Satoshi, - UInt31: UInt31 -} - -for (const typeName in typeforce) { - types[typeName] = typeforce[typeName] -} - -/** - * @type {Object} - */ -module.exports = types diff --git a/packages/crypto/lib/crypto/utils.js b/packages/crypto/lib/crypto/utils.js index 78123f0b50..56abd43de4 100644 --- a/packages/crypto/lib/crypto/utils.js +++ b/packages/crypto/lib/crypto/utils.js @@ -6,8 +6,10 @@ class Utils { * @param {Buffer} buffer * @return {Buffer} */ - ripemd160 (buffer) { - return createHash('rmd160').update(buffer).digest() + ripemd160(buffer) { + return createHash('rmd160') + .update(buffer) + .digest() } /** @@ -15,8 +17,10 @@ class Utils { * @param {Buffer} buffer * @return {Buffer} */ - sha1 (buffer) { - return createHash('sha1').update(buffer).digest() + sha1(buffer) { + return createHash('sha1') + .update(buffer) + .digest() } /** @@ -24,8 +28,10 @@ class Utils { * @param {Buffer} buffer * @return {Buffer} */ - sha256 (buffer) { - return createHash('sha256').update(buffer).digest() + sha256(buffer) { + return createHash('sha256') + .update(buffer) + .digest() } /** @@ -33,7 +39,7 @@ class Utils { * @param {Buffer} buffer * @return {Buffer} */ - hash160 (buffer) { + hash160(buffer) { return this.ripemd160(this.sha256(buffer)) } @@ -42,7 +48,7 @@ class Utils { * @param {Buffer} buffer * @return {Buffer} */ - hash256 (buffer) { + hash256(buffer) { return this.sha256(this.sha256(buffer)) } } diff --git a/packages/crypto/lib/handlers/transactions/delegate-registration.js b/packages/crypto/lib/handlers/transactions/delegate-registration.js index 406149d6a7..80fbafea19 100644 --- a/packages/crypto/lib/handlers/transactions/delegate-registration.js +++ b/packages/crypto/lib/handlers/transactions/delegate-registration.js @@ -5,16 +5,22 @@ class DelegateRegistrationHandler extends Handler { * Check if the transaction can be applied to the wallet. * @param {Wallet} wallet * @param {Transaction} transaction + * @param {Array} errors * @return {Boolean} */ - canApply (wallet, transaction) { - if (!super.canApply(wallet, transaction)) { + canApply(wallet, transaction, errors) { + if (!super.canApply(wallet, transaction, errors)) { return false } const username = transaction.asset.delegate.username - - return !wallet.username && username && username === username.toLowerCase() + // TODO: Checking whether the username is a lowercase version of itself seems silly. Why can't we mutate it to lowercase + const canApply = + !wallet.username && username && username === username.toLowerCase() + if (!canApply) { + errors.push('Wallet already has a registered username') + } + return canApply } /** @@ -23,7 +29,7 @@ class DelegateRegistrationHandler extends Handler { * @param {Transaction} transaction * @return {void} */ - apply (wallet, transaction) { + apply(wallet, transaction) { wallet.username = transaction.asset.delegate.username } @@ -33,7 +39,7 @@ class DelegateRegistrationHandler extends Handler { * @param {Transaction} transaction * @return {void} */ - revert (wallet, transaction) { + revert(wallet, transaction) { wallet.username = null } } diff --git a/packages/crypto/lib/handlers/transactions/delegate-resignation.js b/packages/crypto/lib/handlers/transactions/delegate-resignation.js index b6cbfcc619..eb913b545f 100644 --- a/packages/crypto/lib/handlers/transactions/delegate-resignation.js +++ b/packages/crypto/lib/handlers/transactions/delegate-resignation.js @@ -5,14 +5,19 @@ class DelegateResignationHandler extends Handler { * Check if the transaction can be applied to the wallet. * @param {Wallet} wallet * @param {Transaction} transaction + * @param {Array} errors * @return {Boolean} */ - canApply (wallet, transaction) { - if (!super.canApply(wallet, transaction)) { + canApply(wallet, transaction, errors) { + if (!super.canApply(wallet, transaction, errors)) { return false } - return !!wallet.username + const canApply = !!wallet.username + if (!canApply) { + errors.push('Wallet has not registered a username') + } + return canApply } /** @@ -21,7 +26,7 @@ class DelegateResignationHandler extends Handler { * @param {Transaction} transaction * @return {void} */ - apply (wallet, transaction) { + apply(wallet, transaction) { // } @@ -31,7 +36,7 @@ class DelegateResignationHandler extends Handler { * @param {Transaction} transaction * @return {void} */ - revert (wallet, transaction) { + revert(wallet, transaction) { // } } diff --git a/packages/crypto/lib/handlers/transactions/handler.js b/packages/crypto/lib/handlers/transactions/handler.js index d427ea6aff..a3fd3cb3e6 100644 --- a/packages/crypto/lib/handlers/transactions/handler.js +++ b/packages/crypto/lib/handlers/transactions/handler.js @@ -1,32 +1,59 @@ +const assert = require('assert') const { crypto } = require('../../crypto') -const configManager = require('../../managers/config') -const { transactionValidator } = require('@arkecosystem/validation') +const { transactionValidator } = require('../../validation') module.exports = class Handler { /** * Check if the transaction can be applied to the wallet. * @param {Wallet} wallet * @param {Transaction} transaction + * @param {Array} errors * @return {Boolean} */ - canApply (wallet, transaction) { - if (transactionValidator.validate(transaction).fails) { + canApply(wallet, transaction, errors) { + const validationResult = transactionValidator.validate(transaction) + assert.ok(errors instanceof Array) + if (validationResult.fails) { + errors.push(validationResult.fails.message) return false } - let applicable = true - if (wallet.multisignature) { - applicable = wallet.verifySignatures(transaction, wallet.multisignature) + if (!wallet.verifySignatures(transaction, wallet.multisignature)) { + errors.push('Failed to verify multi-signatures') + return false + } } else { - const enoughBalance = (wallet.balance - transaction.amount - transaction.fee) >= 0 - applicable = (transaction.senderPublicKey === wallet.publicKey) && enoughBalance + const balance = +wallet.balance + .minus(transaction.amount) + .minus(transaction.fee) + .toFixed() + if (balance < 0) { + errors.push('Insufficient balance in the wallet') + return false + } + if ( + !( + transaction.senderPublicKey.toLowerCase() === + wallet.publicKey.toLowerCase() + ) + ) { + errors.push( + 'wallet "publicKey" does not match transaction "senderPublicKey"', + ) + return false + } // TODO: this can blow up if 2nd phrase and other transactions are in the wrong order - applicable = applicable && (!wallet.secondPublicKey || crypto.verifySecondSignature(transaction, wallet.secondPublicKey, configManager.config)) // eslint-disable-line max-len + if ( + wallet.secondPublicKey && + !crypto.verifySecondSignature(transaction, wallet.secondPublicKey) + ) { + errors.push('Failed to verify second-signature') + return false + } } - - return applicable + return true } /** @@ -35,9 +62,15 @@ module.exports = class Handler { * @param {Transaction} transaction * @return {void} */ - applyTransactionToSender (wallet, transaction) { - if (transaction.senderPublicKey === wallet.publicKey || crypto.getAddress(transaction.senderPublicKey) === wallet.address) { - wallet.balance -= transaction.amount + transaction.fee + applyTransactionToSender(wallet, transaction) { + if ( + transaction.senderPublicKey.toLowerCase() === + wallet.publicKey.toLowerCase() || + crypto.getAddress(transaction.senderPublicKey) === wallet.address + ) { + wallet.balance = wallet.balance + .minus(transaction.amount) + .minus(transaction.fee) this.apply(wallet, transaction) @@ -51,9 +84,15 @@ module.exports = class Handler { * @param {Transaction} transaction * @return {void} */ - revertTransactionForSender (wallet, transaction) { - if (transaction.senderPublicKey === wallet.publicKey || crypto.getAddress(transaction.senderPublicKey) === wallet.address) { - wallet.balance += transaction.amount + transaction.fee + revertTransactionForSender(wallet, transaction) { + if ( + transaction.senderPublicKey.toLowerCase() === + wallet.publicKey.toLowerCase() || + crypto.getAddress(transaction.senderPublicKey) === wallet.address + ) { + wallet.balance = wallet.balance + .plus(transaction.amount) + .plus(transaction.fee) this.revert(wallet, transaction) @@ -67,9 +106,9 @@ module.exports = class Handler { * @param {Transaction} transaction * @return {void} */ - applyTransactionToRecipient (wallet, transaction) { + applyTransactionToRecipient(wallet, transaction) { if (transaction.recipientId === wallet.address) { - wallet.balance += transaction.amount + wallet.balance = wallet.balance.plus(transaction.amount) wallet.dirty = true } } @@ -80,9 +119,9 @@ module.exports = class Handler { * @param {Transaction} transaction * @return {void} */ - revertTransactionForRecipient (wallet, transaction) { + revertTransactionForRecipient(wallet, transaction) { if (transaction.recipientId === wallet.address) { - wallet.balance -= transaction.amount + wallet.balance = wallet.balance.minus(transaction.amount) wallet.dirty = true } } diff --git a/packages/crypto/lib/handlers/transactions/index.js b/packages/crypto/lib/handlers/transactions/index.js index 9da51c791c..8d92b89d47 100644 --- a/packages/crypto/lib/handlers/transactions/index.js +++ b/packages/crypto/lib/handlers/transactions/index.js @@ -4,7 +4,7 @@ class TransactionHandler { /** * [constructor description] */ - constructor () { + constructor() { this.handlers = { [TRANSACTION_TYPES.TRANSFER]: require('./transfer'), [TRANSACTION_TYPES.SECOND_SIGNATURE]: require('./second-signature'), @@ -14,7 +14,7 @@ class TransactionHandler { [TRANSACTION_TYPES.IPFS]: require('./ipfs'), [TRANSACTION_TYPES.TIMELOCK_TRANSFER]: require('./timelock-transfer'), [TRANSACTION_TYPES.MULTI_PAYMENT]: require('./multi-payment'), - [TRANSACTION_TYPES.DELEGATE_RESIGNATION]: require('./delegate-resignation') + [TRANSACTION_TYPES.DELEGATE_RESIGNATION]: require('./delegate-resignation'), } } @@ -22,10 +22,11 @@ class TransactionHandler { * [canApply description] * @param {Wallet} wallet * @param {Transaction} transaction + * @param {Array} errors * @return {Boolean} */ - canApply (wallet, transaction) { - return this.handlers[transaction.type].canApply(wallet, transaction) + canApply(wallet, transaction, errors) { + return this.handlers[transaction.type].canApply(wallet, transaction, errors) } /** @@ -34,7 +35,7 @@ class TransactionHandler { * @param {Transaction} transaction * @return {void} */ - apply (wallet, transaction) { + apply(wallet, transaction) { return this.handlers[transaction.type].apply(wallet, transaction) } @@ -44,8 +45,11 @@ class TransactionHandler { * @param {Transaction} transaction * @return {void} */ - applyTransactionToSender (wallet, transaction) { - return this.handlers[transaction.type].applyTransactionToSender(wallet, transaction) + applyTransactionToSender(wallet, transaction) { + return this.handlers[transaction.type].applyTransactionToSender( + wallet, + transaction, + ) } /** @@ -54,8 +58,11 @@ class TransactionHandler { * @param {Transaction} transaction * @return {void} */ - applyTransactionToRecipient (wallet, transaction) { - return this.handlers[transaction.type].applyTransactionToRecipient(wallet, transaction) + applyTransactionToRecipient(wallet, transaction) { + return this.handlers[transaction.type].applyTransactionToRecipient( + wallet, + transaction, + ) } /** @@ -64,7 +71,7 @@ class TransactionHandler { * @param {Transaction} transaction * @return {void} */ - revert (wallet, transaction) { + revert(wallet, transaction) { return this.handlers[transaction.type].revert(wallet, transaction) } @@ -74,8 +81,11 @@ class TransactionHandler { * @param {Transaction} transaction * @return {void} */ - revertTransactionForSender (wallet, transaction) { - return this.handlers[transaction.type].revertTransactionForSender(wallet, transaction) + revertTransactionForSender(wallet, transaction) { + return this.handlers[transaction.type].revertTransactionForSender( + wallet, + transaction, + ) } /** @@ -84,8 +94,11 @@ class TransactionHandler { * @param {Transaction} transaction * @return {void} */ - revertTransactionForRecipient (wallet, transaction) { - return this.handlers[transaction.type].revertTransactionForRecipient(wallet, transaction) + revertTransactionForRecipient(wallet, transaction) { + return this.handlers[transaction.type].revertTransactionForRecipient( + wallet, + transaction, + ) } } diff --git a/packages/crypto/lib/handlers/transactions/ipfs.js b/packages/crypto/lib/handlers/transactions/ipfs.js index dc1d21b448..56b434b50a 100644 --- a/packages/crypto/lib/handlers/transactions/ipfs.js +++ b/packages/crypto/lib/handlers/transactions/ipfs.js @@ -5,10 +5,11 @@ class IpfsHandler extends Handler { * Check if the transaction can be applied to the wallet. * @param {Wallet} wallet * @param {Transaction} transaction + * @param {Array} errors * @return {Boolean} */ - canApply (wallet, transaction) { - return super.canApply(wallet, transaction) + canApply(wallet, transaction, errors) { + return super.canApply(wallet, transaction, errors) } /** @@ -17,7 +18,7 @@ class IpfsHandler extends Handler { * @param {Transaction} transaction * @return {void} */ - apply (wallet, transaction) { + apply(wallet, transaction) { // } @@ -27,7 +28,7 @@ class IpfsHandler extends Handler { * @param {Transaction} transaction * @return {void} */ - revert (wallet, transaction) { + revert(wallet, transaction) { // } } diff --git a/packages/crypto/lib/handlers/transactions/multi-payment.js b/packages/crypto/lib/handlers/transactions/multi-payment.js index 756a76a9fc..0e308fd4da 100644 --- a/packages/crypto/lib/handlers/transactions/multi-payment.js +++ b/packages/crypto/lib/handlers/transactions/multi-payment.js @@ -1,20 +1,33 @@ const Handler = require('./handler') +const Bignum = require('../../utils/bignum') class MultiPaymentHandler extends Handler { /** * Check if the transaction can be applied to the wallet. * @param {Wallet} wallet * @param {Transaction} transaction + * @param {Array} errors * @return {Boolean} */ - canApply (wallet, transaction) { - if (!super.canApply(wallet, transaction)) { + canApply(wallet, transaction, errors) { + if (!super.canApply(wallet, transaction, errors)) { return false } - const amount = transaction.asset.payments.reduce((total, payment) => (total += payment.amount), 0) + const amount = transaction.asset.payments.reduce( + (total, payment) => total.plus(payment.amount), + Bignum.ZERO, + ) - return wallet.balance - amount - transaction.fee > -1 + const canApply = + +wallet.balance + .minus(amount) + .minus(transaction.fee) + .toFixed() >= 0 + if (!canApply) { + errors.push('Insufficient balance in the wallet') + } + return canApply } /** @@ -23,7 +36,7 @@ class MultiPaymentHandler extends Handler { * @param {Transaction} transaction * @return {void} */ - apply (wallet, transaction) { + apply(wallet, transaction) { // } @@ -33,7 +46,7 @@ class MultiPaymentHandler extends Handler { * @param {Transaction} transaction * @return {void} */ - revert (wallet, transaction) { + revert(wallet, transaction) { // } } diff --git a/packages/crypto/lib/handlers/transactions/multi-signature.js b/packages/crypto/lib/handlers/transactions/multi-signature.js index 0dba902f63..1935b0b5cf 100644 --- a/packages/crypto/lib/handlers/transactions/multi-signature.js +++ b/packages/crypto/lib/handlers/transactions/multi-signature.js @@ -5,28 +5,39 @@ class MultiSignatureHandler extends Handler { * Check if the transaction can be applied to the wallet. * @param {Wallet} wallet * @param {Transaction} transaction + * @param {Array} errors * @return {Boolean} */ - canApply (wallet, transaction) { - if (!super.canApply(wallet, transaction)) { + canApply(wallet, transaction, errors) { + if (!super.canApply(wallet, transaction, errors)) { return false } if (wallet.multisignature) { + errors.push('Wallet is already a multi-signature wallet') return false } const keysgroup = transaction.asset.multisignature.keysgroup if (keysgroup.length < transaction.asset.multisignature.min) { + errors.push('Specified key count does not meet minimum key count') return false } if (keysgroup.length !== transaction.signatures.length) { + errors.push('Specified key count does not equal signature count') return false } - return wallet.verifySignatures(transaction, transaction.asset.multisignature) + const canApply = wallet.verifySignatures( + transaction, + transaction.asset.multisignature, + ) + if (!canApply) { + errors.push('Failed to verify multi-signatures') + } + return canApply } /** @@ -35,7 +46,7 @@ class MultiSignatureHandler extends Handler { * @param {Transaction} transaction * @return {void} */ - apply (wallet, transaction) { + apply(wallet, transaction) { wallet.multisignature = transaction.asset.multisignature } @@ -45,7 +56,7 @@ class MultiSignatureHandler extends Handler { * @param {Transaction} transaction * @return {void} */ - revert (wallet, transaction) { + revert(wallet, transaction) { wallet.multisignature = null } } diff --git a/packages/crypto/lib/handlers/transactions/second-signature.js b/packages/crypto/lib/handlers/transactions/second-signature.js index 2b1654decd..90c8db2351 100644 --- a/packages/crypto/lib/handlers/transactions/second-signature.js +++ b/packages/crypto/lib/handlers/transactions/second-signature.js @@ -5,14 +5,19 @@ class SecondSignatureHandler extends Handler { * Check if the transaction can be applied to the wallet. * @param {Wallet} wallet * @param {Transaction} transaction + * @param {Array} errors * @return {Boolean} */ - canApply (wallet, transaction) { - if (!super.canApply(wallet, transaction)) { + canApply(wallet, transaction, errors) { + if (!super.canApply(wallet, transaction, errors)) { return false } - return !wallet.secondPublicKey + const canApply = !wallet.secondPublicKey + if (!canApply) { + errors.push('Wallet already has a second signature') + } + return canApply } /** @@ -21,7 +26,7 @@ class SecondSignatureHandler extends Handler { * @param {Transaction} transaction * @return {void} */ - apply (wallet, transaction) { + apply(wallet, transaction) { wallet.secondPublicKey = transaction.asset.signature.publicKey } @@ -31,7 +36,7 @@ class SecondSignatureHandler extends Handler { * @param {Transaction} transaction * @return {void} */ - revert (wallet, transaction) { + revert(wallet, transaction) { wallet.secondPublicKey = null } } diff --git a/packages/crypto/lib/handlers/transactions/timelock-transfer.js b/packages/crypto/lib/handlers/transactions/timelock-transfer.js index 31df890276..260c748b25 100644 --- a/packages/crypto/lib/handlers/transactions/timelock-transfer.js +++ b/packages/crypto/lib/handlers/transactions/timelock-transfer.js @@ -5,10 +5,11 @@ class TimelockTransferHandler extends Handler { * Check if the transaction can be applied to the wallet. * @param {Wallet} wallet * @param {Transaction} transaction + * @param {Array} errors * @return {Boolean} */ - canApply (wallet, transaction) { - return super.canApply(wallet, transaction) + canApply(wallet, transaction, errors) { + return super.canApply(wallet, transaction, errors) } /** @@ -17,7 +18,7 @@ class TimelockTransferHandler extends Handler { * @param {Transaction} transaction * @return {void} */ - apply (wallet, transaction) { + apply(wallet, transaction) { // } @@ -27,7 +28,7 @@ class TimelockTransferHandler extends Handler { * @param {Transaction} transaction * @return {void} */ - revert (wallet, transaction) { + revert(wallet, transaction) { // } } diff --git a/packages/crypto/lib/handlers/transactions/transfer.js b/packages/crypto/lib/handlers/transactions/transfer.js index e3f3055df9..ee0560d71b 100644 --- a/packages/crypto/lib/handlers/transactions/transfer.js +++ b/packages/crypto/lib/handlers/transactions/transfer.js @@ -5,10 +5,11 @@ class TransferHandler extends Handler { * Check if the transaction can be applied to the wallet. * @param {Wallet} wallet * @param {Transaction} transaction + * @param {Array} errors * @return {Boolean} */ - canApply (wallet, transaction) { - return super.canApply(wallet, transaction) + canApply(wallet, transaction, errors) { + return super.canApply(wallet, transaction, errors) } /** @@ -17,7 +18,7 @@ class TransferHandler extends Handler { * @param {Transaction} transaction * @return {void} */ - apply (wallet, transaction) { + apply(wallet, transaction) { // } @@ -27,7 +28,7 @@ class TransferHandler extends Handler { * @param {Transaction} transaction * @return {void} */ - revert (wallet, transaction) { + revert(wallet, transaction) { // } } diff --git a/packages/crypto/lib/handlers/transactions/vote.js b/packages/crypto/lib/handlers/transactions/vote.js index d6fadde6c1..864f869058 100644 --- a/packages/crypto/lib/handlers/transactions/vote.js +++ b/packages/crypto/lib/handlers/transactions/vote.js @@ -5,24 +5,32 @@ class VoteHandler extends Handler { * Check if the transaction can be applied to the wallet. * @param {Wallet} wallet * @param {Transaction} transaction + * @param {Array} errors * @return {Boolean} */ - canApply (wallet, transaction) { - if (!super.canApply(wallet, transaction)) { + canApply(wallet, transaction, errors) { + if (!super.canApply(wallet, transaction, errors)) { return false } const vote = transaction.asset.votes[0] - - if (vote.startsWith('-') && (wallet.vote === vote.slice(1))) { - return true + if ( + vote.startsWith('-') && + (!wallet.vote || wallet.vote !== vote.slice(1)) + ) { + if (!wallet.vote) { + errors.push('Wallet has not voted yet') + } else { + errors.push('Wallet vote-choice does not match transaction vote-choice') + } + return false } - if (vote.startsWith('+') && !wallet.vote) { - return true + if (vote.startsWith('+') && wallet.vote) { + errors.push('Wallet has already voted') + return false } - - return false + return true } /** @@ -31,7 +39,7 @@ class VoteHandler extends Handler { * @param {Transaction} transaction * @return {void} */ - apply (wallet, transaction) { + apply(wallet, transaction) { const vote = transaction.asset.votes[0] if (vote.startsWith('+')) { @@ -49,7 +57,7 @@ class VoteHandler extends Handler { * @param {Transaction} transaction * @return {void} */ - revert (wallet, transaction) { + revert(wallet, transaction) { const vote = transaction.asset.votes[0] if (vote.startsWith('+')) { diff --git a/packages/crypto/lib/identities/address.js b/packages/crypto/lib/identities/address.js new file mode 100644 index 0000000000..9d317d941f --- /dev/null +++ b/packages/crypto/lib/identities/address.js @@ -0,0 +1,49 @@ +const bs58check = require('bs58check') +const configManager = require('../managers/config') +const utils = require('../crypto/utils') +const PublicKey = require('./public-key') + +module.exports = class Address { + static fromPassphrase(passphrase, networkVersion) { + return Address.fromPublicKey( + PublicKey.fromPassphrase(passphrase), + networkVersion, + ) + } + + static fromPublicKey(publicKey, networkVersion) { + const pubKeyRegex = /^[0-9A-Fa-f]{66}$/ + if (!pubKeyRegex.test(publicKey)) { + throw new Error(`publicKey '${publicKey}' is invalid`) + } + + if (!networkVersion) { + networkVersion = configManager.get('pubKeyHash') + } + + const buffer = utils.ripemd160(Buffer.from(publicKey, 'hex')) + const payload = Buffer.alloc(21) + + payload.writeUInt8(networkVersion, 0) + buffer.copy(payload, 1) + + return bs58check.encode(payload) + } + + static fromPrivateKey(privateKey, networkVersion) { + return Address.fromPublicKey(privateKey.publicKey, networkVersion) + } + + static validate(address, networkVersion) { + if (!networkVersion) { + networkVersion = configManager.get('pubKeyHash') + } + + try { + const decode = bs58check.decode(address) + return decode[0] === networkVersion + } catch (e) { + return false + } + } +} diff --git a/packages/crypto/lib/identities/keys.js b/packages/crypto/lib/identities/keys.js new file mode 100644 index 0000000000..2cd57ca74d --- /dev/null +++ b/packages/crypto/lib/identities/keys.js @@ -0,0 +1,49 @@ +const secp256k1 = require('secp256k1') +const wif = require('wif') + +const configManager = require('../managers/config') +const utils = require('../crypto/utils') + +module.exports = class Keys { + static fromPassphrase(passphrase, compressed = true) { + const privateKey = utils.sha256(Buffer.from(passphrase, 'utf8')) + return Keys.fromPrivateKey(privateKey, compressed) + } + + static fromPrivateKey(privateKey, compressed = true) { + privateKey = privateKey instanceof Buffer ? privateKey : Buffer.from(privateKey, 'hex') + + const publicKey = secp256k1.publicKeyCreate(privateKey, compressed) + const keyPair = { + publicKey: publicKey.toString('hex'), + privateKey: privateKey.toString('hex'), + compressed, + } + + return keyPair + } + + static fromWIF(wifKey, network) { + const decoded = wif.decode(wifKey) + const version = decoded.version + + if (!network) { + network = configManager.all() + } + + if (version !== network.wif) { + throw new Error('Invalid network version') + } + + const privateKey = decoded.privateKey + const publicKey = secp256k1.publicKeyCreate(privateKey, decoded.compressed) + + const keyPair = { + publicKey: publicKey.toString('hex'), + privateKey: privateKey.toString('hex'), + compressed: decoded.compressed, + } + + return keyPair + } +} diff --git a/packages/crypto/lib/identities/private-key.js b/packages/crypto/lib/identities/private-key.js new file mode 100644 index 0000000000..98e351e0b4 --- /dev/null +++ b/packages/crypto/lib/identities/private-key.js @@ -0,0 +1,13 @@ +const Keys = require('./keys') + +module.exports = class PrivateKey { + static fromPassphrase(passphrase) { + return Keys.fromPassphrase(passphrase).privateKey + } + + // static fromHex (privateKey) {} + + static fromWIF(wif, network) { + return Keys.fromWIF(wif, network).privateKey + } +} diff --git a/packages/crypto/lib/identities/public-key.js b/packages/crypto/lib/identities/public-key.js new file mode 100644 index 0000000000..c4d67d2d1a --- /dev/null +++ b/packages/crypto/lib/identities/public-key.js @@ -0,0 +1,27 @@ +const configManager = require('../managers/config') +const Address = require('./address') +const Keys = require('./keys') + +module.exports = class PublicKey { + static fromPassphrase(passphrase) { + return Keys.fromPassphrase(passphrase).publicKey + } + + // static fromHex (publicKey) {} + + static fromWIF(wif, network) { + return Keys.fromWIF(wif, network).publicKey + } + + static validate(publicKey, networkVersion) { + if (!networkVersion) { + networkVersion = configManager.get('pubKeyHash') + } + + try { + return Address.fromPublicKey(publicKey, networkVersion).length === 34 + } catch (e) { + return false + } + } +} diff --git a/packages/crypto/lib/identities/wif.js b/packages/crypto/lib/identities/wif.js new file mode 100644 index 0000000000..5b380159c8 --- /dev/null +++ b/packages/crypto/lib/identities/wif.js @@ -0,0 +1,19 @@ +const wif = require('wif') +const configManager = require('../managers/config') +const Keys = require('./keys') + +module.exports = class WIF { + static fromPassphrase(passphrase, network) { + const keys = Keys.fromPassphrase(passphrase) + + if (!network) { + network = configManager.all() + } + + return wif.encode( + network.wif, + Buffer.from(keys.privateKey, 'hex'), + keys.compressed, + ) + } +} diff --git a/packages/crypto/lib/index.js b/packages/crypto/lib/index.js index ce03e814ac..00a93f966a 100644 --- a/packages/crypto/lib/index.js +++ b/packages/crypto/lib/index.js @@ -7,7 +7,16 @@ module.exports = { Block: require('./models/block'), Delegate: require('./models/delegate'), Transaction: require('./models/transaction'), - Wallet: require('./models/wallet') + Wallet: require('./models/wallet'), + }, + + // Identities... + identities: { + address: require('./identities/address'), + keys: require('./identities/keys'), + privateKey: require('./identities/private-key'), + publicKey: require('./identities/public-key'), + wif: require('./identities/wif'), }, // Builder... @@ -26,5 +35,8 @@ module.exports = { constants: require('./constants'), // Utils... - sortTransactions: require('./utils/sort-transactions') + ...require('./utils'), + + // Validations + ...require('./validation'), } diff --git a/packages/crypto/lib/managers/config.js b/packages/crypto/lib/managers/config.js index 099f26ab52..0e3859417c 100644 --- a/packages/crypto/lib/managers/config.js +++ b/packages/crypto/lib/managers/config.js @@ -1,5 +1,4 @@ -const arkjsv1 = require('arkjsv1') -const _ = require('lodash') +const camelCase = require('lodash/camelCase') const deepmerge = require('deepmerge') const feeManager = require('./fee') const dynamicFeeManager = require('./dynamic-fee') @@ -11,7 +10,7 @@ class ConfigManager { /** * @constructor */ - constructor () { + constructor() { this.setConfig(defaultConfig) } @@ -19,18 +18,16 @@ class ConfigManager { * Set config data. * @param {Object} config */ - setConfig (config) { + setConfig(config) { this.config = {} for (const [key, value] of Object.entries(config)) { this.config[key] = value - } - - arkjsv1.crypto.setNetworkVersion(this.config.pubKeyHash) // make sure ark.js v1 uses our config + } this.buildConstants() this.buildFees() - this.buildDynamicOffsets() + this.buildAddonBytes() } /** @@ -38,7 +35,7 @@ class ConfigManager { * @param {String} coin * @param {String} network */ - setFromPreset (coin, network) { + setFromPreset(coin, network) { this.setConfig(CONFIGURATIONS[coin.toUpperCase()][network.toUpperCase()]) } @@ -46,7 +43,7 @@ class ConfigManager { * Get all config data. * @return {Object} */ - all () { + all() { return this.config } @@ -55,7 +52,7 @@ class ConfigManager { * @param {String} key * @param {*} value */ - set (key, value) { + set(key, value) { this.config[key] = value } @@ -64,7 +61,7 @@ class ConfigManager { * @param {String} key * @return {*} */ - get (key) { + get(key) { return this.config[key] } @@ -72,7 +69,7 @@ class ConfigManager { * Set config manager height. * @param {Number} value */ - setHeight (value) { + setHeight(value) { this.height = value } @@ -80,7 +77,7 @@ class ConfigManager { * Get config manager height. * @return {Number} */ - getHeight () { + getHeight() { return this.height } @@ -89,7 +86,7 @@ class ConfigManager { * @param {String} key * @return {*} */ - getConstant (key) { + getConstant(key) { return this.getConstants()[key] } @@ -98,7 +95,7 @@ class ConfigManager { * @param {(Number|undefined)} height * @return {*} */ - getConstants (height) { + getConstants(height) { if (!height && this.height) { height = this.height } @@ -107,7 +104,10 @@ class ConfigManager { height = 1 } - while ((this.constant.index < this.constants.length - 1) && height >= this.constants[this.constant.index + 1].height) { + while ( + this.constant.index < this.constants.length - 1 && + height >= this.constants[this.constant.index + 1].height + ) { this.constant.index++ this.constant.data = this.constants[this.constant.index] } @@ -123,17 +123,20 @@ class ConfigManager { /** * Build constant data based on active heights. */ - buildConstants () { + buildConstants() { this.constants = this.config.constants.sort((a, b) => a.height - b.height) this.constant = { index: 0, - data: this.constants[0] + data: this.constants[0], } let lastmerged = 0 while (lastmerged < this.constants.length - 1) { - this.constants[lastmerged + 1] = deepmerge(this.constants[lastmerged], this.constants[lastmerged + 1]) + this.constants[lastmerged + 1] = deepmerge( + this.constants[lastmerged], + this.constants[lastmerged + 1], + ) lastmerged++ } } @@ -141,20 +144,26 @@ class ConfigManager { /** * Build fees from config constants. */ - buildFees () { - Object - .keys(TRANSACTION_TYPES) - .forEach(type => feeManager.set(TRANSACTION_TYPES[type], this.getConstant('fees')[_.camelCase(type)])) + buildFees() { + Object.keys(TRANSACTION_TYPES).forEach(type => + feeManager.set( + TRANSACTION_TYPES[type], + this.getConstant('fees').staticFees[camelCase(type)], + ), + ) } /** - * Build dynamic offsets from config constants. + * Build addon bytes from config constants. */ - buildDynamicOffsets () { - if (this.getConstant('dynamicOffsets')) { - Object - .keys(TRANSACTION_TYPES) - .forEach(type => dynamicFeeManager.set(TRANSACTION_TYPES[type], this.getConstant('dynamicOffsets')[_.camelCase(type)])) + buildAddonBytes() { + if (this.getConstant('fees').dynamicFees.addonBytes) { + Object.keys(TRANSACTION_TYPES).forEach(type => + dynamicFeeManager.set( + TRANSACTION_TYPES[type], + this.getConstant('fees').dynamicFees.addonBytes[camelCase(type)], + ), + ) } } } diff --git a/packages/crypto/lib/managers/dynamic-fee.js b/packages/crypto/lib/managers/dynamic-fee.js index 80bb5357c6..d2a73b5e63 100644 --- a/packages/crypto/lib/managers/dynamic-fee.js +++ b/packages/crypto/lib/managers/dynamic-fee.js @@ -4,21 +4,27 @@ class DynamicFeeManager { /** * @constructor */ - constructor () { + constructor() { this.offsets = {} } - /** Calculates delegate fee for processing and forging if transaction - * @param {Number} Fee price per byte in ARKTOSHI as set by forger/delegate in delegate.json setting feeMultiplier - * @param {Transaction} Transaction for which we calculate dynamic fee - * @returns {Number} Calculated dynamic fee in ARKTOSHI - */ - calculateFee (feeMultiplier, transaction) { - if (feeMultiplier === 0) { - feeMultiplier = 1 + /** + * Calculate minimum fee of a transaction for entering the pool. + * @param {Number} Minimum fee ARKTOSHI/byte + * @param {Transaction} Transaction for which we calculate the fee + * @returns {Number} Calculated minimum acceptable fee in ARKTOSHI + */ + calculateFee(arktoshiPerByte, transaction) { + if (arktoshiPerByte <= 0) { + arktoshiPerByte = 1 } - return (this.get(transaction.type) + (transaction.serialized.length)) * feeMultiplier + // serialized is in hex + const transactionSizeInBytes = transaction.serialized.length / 2 + + return ( + (this.get(transaction.type) + transactionSizeInBytes) * arktoshiPerByte + ) } /** @@ -26,7 +32,7 @@ class DynamicFeeManager { * @param {Number} type * @return {Number} */ - get (type) { + get(type) { return this.offsets[type] } @@ -35,7 +41,7 @@ class DynamicFeeManager { * @param {Number} type * @param {Number} value */ - set (type, value) { + set(type, value) { if (!this.__validType(type)) { throw new Error('Invalid transaction type.') } @@ -48,7 +54,7 @@ class DynamicFeeManager { * @param {Number} type * @return {Boolean} */ - __validType (type) { + __validType(type) { return Object.values(TRANSACTION_TYPES).indexOf(type) > -1 } } diff --git a/packages/crypto/lib/managers/fee.js b/packages/crypto/lib/managers/fee.js index 44fe4f2329..6b791a8721 100644 --- a/packages/crypto/lib/managers/fee.js +++ b/packages/crypto/lib/managers/fee.js @@ -4,7 +4,7 @@ class FeeManager { /** * @constructor */ - constructor () { + constructor() { this.fees = {} } @@ -13,7 +13,7 @@ class FeeManager { * @param {Number} type * @param {Number} value */ - set (type, value) { + set(type, value) { if (!this.__validType(type)) { throw new Error('Invalid transaction type.') } @@ -26,7 +26,7 @@ class FeeManager { * @param {Number} type * @return {Number} */ - get (type) { + get(type) { return this.fees[type] } @@ -35,9 +35,12 @@ class FeeManager { * @param {Transaction} transaction * @return {Number} */ - getForTransaction (transaction) { + getForTransaction(transaction) { if (transaction.type === TRANSACTION_TYPES.MULTI_SIGNATURE) { - return this.fees[transaction.type] * (transaction.asset.multisignature.keysgroup.length + 1) + return ( + this.fees[transaction.type] + * (transaction.asset.multisignature.keysgroup.length + 1) + ) } return this.fees[transaction.type] @@ -48,7 +51,7 @@ class FeeManager { * @param {Number} type * @return {Boolean} */ - __validType (type) { + __validType(type) { return Object.values(TRANSACTION_TYPES).indexOf(type) > -1 } } diff --git a/packages/crypto/lib/managers/network.js b/packages/crypto/lib/managers/network.js index 3e501fdaa6..150a02f16a 100644 --- a/packages/crypto/lib/managers/network.js +++ b/packages/crypto/lib/managers/network.js @@ -6,7 +6,7 @@ module.exports = class NetworkManager { * Get all network types. * @return {Object} */ - static getAll () { + static getAll() { return networks } @@ -16,7 +16,7 @@ module.exports = class NetworkManager { * @param {String} [token=ark] * @return {Object} */ - static findByName (name, token = 'ark') { + static findByName(name, token = 'ark') { return get(networks, `${token.toLowerCase()}.${name}`) } } diff --git a/packages/crypto/lib/models/block.js b/packages/crypto/lib/models/block.js index ee02f08d2a..be66fef1e9 100644 --- a/packages/crypto/lib/models/block.js +++ b/packages/crypto/lib/models/block.js @@ -1,39 +1,18 @@ -const crypto = require('crypto') -const Bignum = require('bigi') +const cloneDeepWith = require('lodash/cloneDeepWith') +const { createHash } = require('crypto') +const pluralize = require('pluralize') const ByteBuffer = require('bytebuffer') +const { Bignum } = require('../utils') const Transaction = require('./transaction') const configManager = require('../managers/config') -const slots = require('../crypto/slots') -const ECPair = require('../crypto/ecpair') -const ECSignature = require('../crypto/ecsignature') +const { crypto, slots } = require('../crypto') const { outlookTable } = require('../constants').CONFIGURATIONS.ARK.MAINNET -const toBytesHex = (buffer) => { - let temp = buffer.toString('hex') +const toBytesHex = data => { + const temp = data ? new Bignum(data).toString(16) : '' return '0'.repeat(16 - temp.length) + temp } -/** - * Fix to allow blocks to be backwards-compatible. - * @param {Object} data - */ -const applyV1Fix = (data) => { - // START Fix for v1 api - data.totalAmount = parseInt(data.totalAmount) - data.totalFee = parseInt(data.totalFee) - data.reward = parseInt(data.reward) - data.previousBlockHex = data.previousBlock ? toBytesHex(new Bignum(data.previousBlock).toBuffer()) : '0000000000000000' - data.idHex = toBytesHex(new Bignum(data.id).toBuffer()) - // END Fix for v1 api - - // order of transactions messed up in mainnet V1 - // if (block.data.transactions.length === 2 && (block.data.height === 3084276 || block.data.height === 34420)) { - // const temp = block.data.transactions[0] - // block.data.transactions[0] = block.data.transactions[1] - // block.data.transactions[1] = temp - // } -} - /** * TODO copy some parts to ArkDocs * @classdesc This model holds the block data, its verification and serialization @@ -67,15 +46,25 @@ module.exports = class Block { * @constructor * @param {Object} data - The data of the block */ - constructor (data) { + constructor(data) { + if (typeof data === 'string') { + data = Block.deserialize(data) + } + if (!data.transactions) { data.transactions = [] } - if (data.numberOfTransactions > 0 && data.transactions.length === data.numberOfTransactions) { + if ( + data.numberOfTransactions > 0 && + data.transactions.length === data.numberOfTransactions + ) { delete data.transactionIds } - this.headerOnly = data.numberOfTransactions > 0 && data.transactionIds && data.transactionIds.length === data.numberOfTransactions + this.headerOnly = + data.numberOfTransactions > 0 && + data.transactionIds && + data.transactionIds.length === data.numberOfTransactions if (this.headerOnly) { this.serialized = Block.serialize(data).toString('hex') } else { @@ -83,31 +72,24 @@ module.exports = class Block { } this.data = Block.deserialize(this.serialized) - this.data.idHex = Block.getIdHex(this.data) this.data.id = Block.getId(this.data) + this.data.idHex = Block.getIdHex(this.data) if (outlookTable[this.data.id]) { this.data.id = outlookTable[this.data.id] - this.data.idHex = toBytesHex(new Bignum(this.data.id).toBuffer()) + this.data.idHex = toBytesHex(this.data.id) } - if (data.id !== this.data.id) { - console.log(`'${this.data.id}': '${data.id}',`) - } - - // if (data.height === 1622706) { - // console.log(data) - // console.log(this.data) - // } if (data.height === 1) { this.genesis = true // TODO genesis block calculated id is wrong for some reason this.data.id = data.id - this.data.idHex = toBytesHex(new Bignum(this.data.id).toBuffer()) + this.data.idHex = toBytesHex(this.data.id) delete this.data.previousBlock } - // fix on real timestamp, this is overloading transaction timestamp with block timestamp for storage only + // fix on real timestamp, this is overloading transaction + // timestamp with block timestamp for storage only // also add sequence to keep database sequence let sequence = 0 this.transactions = data.transactions.map(transaction => { @@ -125,57 +107,66 @@ module.exports = class Block { this.verification = this.verify() - if (!this.verification.verified && this.data.height !== 1) { - // console.log(JSON.stringify(data, null, 2)) - console.log(this.serialized) - console.log(this.verification) + // order of transactions messed up in mainnet V1 + // TODO: move this to network constants exception using block ids + if ( + this.transactions && + this.data.numberOfTransactions === 2 && + (this.data.height === 3084276 || this.data.height === 34420) + ) { + const temp = this.transactions[0] + this.transactions[0] = this.transactions[1] + this.transactions[1] = temp } } - /* + /** * Create block from data. * @param {Object} data - * @param {ECPair}} keys + * @param {Object} keys * @return {Block} * @static */ - static create (data, keys) { + static create(data, keys) { data.generatorPublicKey = keys.publicKey const payloadHash = Block.serialize(data, false) - const hash = crypto.createHash('sha256').update(payloadHash).digest() + const hash = createHash('sha256') + .update(payloadHash) + .digest() - data.blockSignature = keys.sign(hash).toDER().toString('hex') + data.blockSignature = crypto.signHash(hash, keys) data.id = Block.getId(data) return new Block(data) } - /* + /** * Return block as string. * @return {String} */ - toString () { - return `${this.data.id}, height: ${this.data.height}, ${this.data.numberOfTransactions} transactions, verified: ${this.verification.verified}, errors:${this.verification.errors}` // eslint-disable-line max-len - } - - /* - * Return block data for v1. - * @return {Object} - */ - toBroadcastV1 () { - return this.toRawJson() + toString() { + return `${ + this.data.id + }, height: ${this.data.height.toLocaleString()}, ${pluralize( + 'transaction', + this.data.numberOfTransactions, + true, + )}, verified: ${this.verification.verified}, errors: ${ + this.verification.errors + }` // eslint-disable-line max-len } /* * Get block id - * TODO rename to getIdHex ? * @param {Object} data * @return {String} * @static */ - static getIdHex (data) { - const hash = crypto.createHash('sha256').update(Block.serialize(data, true)).digest() + static getIdHex(data) { + const hash = createHash('sha256') + .update(Block.serialize(data, true)) + .digest() const temp = Buffer.alloc(8) for (let i = 0; i < 8; i++) { @@ -184,50 +175,65 @@ module.exports = class Block { return temp.toString('hex') } - static getId (data) { - const hash = crypto.createHash('sha256').update(Block.serialize(data, true)).digest() + /** + * Get block id from already serialized buffer + * @param {Buffer} serialized block buffer with block-signature included + * @return {String} + * @static + */ + static getIdFromSerialized(serializedBuffer) { + const hash = createHash('sha256') + .update(serializedBuffer) + .digest() const temp = Buffer.alloc(8) for (let i = 0; i < 8; i++) { temp[i] = hash[7 - i] } - return Bignum.fromBuffer(temp).toString() + return new Bignum(temp.toString('hex'), 16).toFixed() } - /* + static getId(data) { + const idHex = Block.getIdHex(data) + return new Bignum(idHex, 16).toFixed() + } + + /** * Get header from block. * @return {Object} The block data, without the transactions */ - getHeader () { - const header = this.data + getHeader() { + const header = Object.assign({}, this.data) delete header.transactions return header } - /* + /** * Verify signature associated with this block. * @return {Boolean} */ - verifySignature () { + verifySignature() { const bytes = Block.serialize(this.data, false) - const hash = crypto.createHash('sha256').update(bytes).digest() - const blockSignatureBuffer = Buffer.from(this.data.blockSignature, 'hex') - const generatorPublicKeyBuffer = Buffer.from(this.data.generatorPublicKey, 'hex') - const ecpair = ECPair.fromPublicKeyBuffer(generatorPublicKeyBuffer) - const ecsignature = ECSignature.fromDER(blockSignatureBuffer) - - return ecpair.verify(hash, ecsignature) + const hash = createHash('sha256') + .update(bytes) + .digest() + + return crypto.verifyHash( + hash, + this.data.blockSignature, + this.data.generatorPublicKey, + ) } - /* + /** * Verify this block. * @return {Object} */ - verify () { + verify() { const block = this.data const result = { verified: false, - errors: [] + errors: [], } try { @@ -241,11 +247,18 @@ module.exports = class Block { } } - if (constants.reward !== block.reward) { - result.errors.push(['Invalid block reward:', block.reward, 'expected:', constants.reward].join(' ')) + if (!block.reward.isEqualTo(constants.reward)) { + result.errors.push( + [ + 'Invalid block reward:', + block.reward, + 'expected:', + constants.reward, + ].join(' '), + ) } - let valid = this.verifySignature(block) + const valid = this.verifySignature(block) if (!valid) { result.errors.push('Failed to verify block signature') @@ -267,12 +280,8 @@ module.exports = class Block { // } // } - if (block.payloadLength > constants.maxPayloadLength) { - result.errors.push('Payload length is too high') - } - let size = 0 - let payloadHash = crypto.createHash('sha256') + const payloadHash = createHash('sha256') if (this.headerOnly) { if (this.transactionIds.length !== block.numberOfTransactions) { @@ -280,16 +289,17 @@ module.exports = class Block { } if (this.transactionIds.length > constants.block.maxTransactions) { - if (block.height > 1) result.errors.push('Transactions length is too high') + if (block.height > 1) + result.errors.push('Transactions length is too high') } // Checking if transactions of the block adds up to block values. - let appliedTransactions = {} + const appliedTransactions = {} this.transactionIds.forEach(id => { const bytes = Buffer.from(id, 'hex') if (appliedTransactions[id]) { - result.errors.push('Encountered duplicate transaction: ' + id) + result.errors.push(`Encountered duplicate transaction: ${id}`) } appliedTransactions[id] = id @@ -298,8 +308,12 @@ module.exports = class Block { payloadHash.update(bytes) }) } else { - if (!this.transactions.reduce((wallet, transaction) => wallet && transaction.verified, true)) { - result.errors.push('One or more transactions are not verified') + const invalidTransactions = this.transactions.filter(tx => !tx.verified) + if (invalidTransactions.length > 0) { + result.errors.push('One or more transactions are not verified:') + invalidTransactions.forEach(tx => + result.errors.push(`=> ${tx.serialized}`), + ) } if (this.transactions.length !== block.numberOfTransactions) { @@ -307,34 +321,37 @@ module.exports = class Block { } if (this.transactions.length > constants.block.maxTransactions) { - if (block.height > 1) result.errors.push('Transactions length is too high') + if (block.height > 1) + result.errors.push('Transactions length is too high') } // Checking if transactions of the block adds up to block values. - let appliedTransactions = {} - let totalAmount = 0 - let totalFee = 0 + const appliedTransactions = {} + let totalAmount = Bignum.ZERO + let totalFee = Bignum.ZERO this.transactions.forEach(transaction => { const bytes = Buffer.from(transaction.data.id, 'hex') if (appliedTransactions[transaction.data.id]) { - result.errors.push('Encountered duplicate transaction: ' + transaction.data.id) + result.errors.push( + `Encountered duplicate transaction: ${transaction.data.id}`, + ) } appliedTransactions[transaction.data.id] = transaction.data - totalAmount += transaction.data.amount - totalFee += transaction.data.fee + totalAmount = totalAmount.plus(transaction.data.amount) + totalFee = totalFee.plus(transaction.data.fee) size += bytes.length payloadHash.update(bytes) }) - if (totalAmount !== block.totalAmount) { + if (!totalAmount.isEqualTo(block.totalAmount)) { result.errors.push('Invalid total amount') } - if (totalFee !== block.totalFee) { + if (!totalFee.isEqualTo(block.totalFee)) { result.errors.push('Invalid total fee') } } @@ -343,7 +360,10 @@ module.exports = class Block { result.errors.push('Payload is too large') } - if (!this.genesis && payloadHash.digest().toString('hex') !== block.payloadHash) { + if ( + !this.genesis && + payloadHash.digest().toString('hex') !== block.payloadHash + ) { result.errors.push('Invalid payload hash') } } catch (error) { @@ -355,68 +375,97 @@ module.exports = class Block { return result } - /* + /** * Deserialize block from hex string. * @param {String} hexString + * @param {Boolean} headerOnly - deserialize onlu headers * @return {Object} * @static */ - static deserialize (hexString) { + static deserialize(hexString, headerOnly = false) { const block = {} const buf = ByteBuffer.fromHex(hexString, true) block.version = buf.readUInt32(0) block.timestamp = buf.readUInt32(4) block.height = buf.readUInt32(8) block.previousBlockHex = buf.slice(12, 20).toString('hex') - block.previousBlock = Bignum(block.previousBlockHex, 16).toString() + block.previousBlock = new Bignum(block.previousBlockHex, 16).toFixed() block.numberOfTransactions = buf.readUInt32(20) - block.totalAmount = buf.readUInt64(24).toNumber() - block.totalFee = buf.readUInt64(32).toNumber() - block.reward = buf.readUInt64(40).toNumber() + block.totalAmount = new Bignum(buf.readUInt64(24)) + block.totalFee = new Bignum(buf.readUInt64(32)) + block.reward = new Bignum(buf.readUInt64(40)) block.payloadLength = buf.readUInt32(48) block.payloadHash = hexString.substring(104, 104 + 64) block.generatorPublicKey = hexString.substring(104 + 64, 104 + 64 + 33 * 2) - const length = parseInt('0x' + hexString.substring(104 + 64 + 33 * 2 + 2, 104 + 64 + 33 * 2 + 4), 16) + 2 - block.blockSignature = hexString.substring(104 + 64 + 33 * 2, 104 + 64 + 33 * 2 + length * 2) + const length = + parseInt( + `0x${hexString.substring( + 104 + 64 + 33 * 2 + 2, + 104 + 64 + 33 * 2 + 4, + )}`, + 16, + ) + 2 + block.blockSignature = hexString.substring( + 104 + 64 + 33 * 2, + 104 + 64 + 33 * 2 + length * 2, + ) + + if (headerOnly) return block let transactionOffset = (104 + 64 + 33 * 2 + length * 2) / 2 block.transactions = [] if (hexString.length === transactionOffset * 2) return block - for (let i = 0; i < block.numberOfTransactions; i++) { - block.transactions.push(buf.readUint32(transactionOffset)) - transactionOffset += 4 - } + // A serialized block stores transactions like this: + // |L1|L2|L3|...|LN| TX1 | TX2 | TX3 | ... | TXN | + // Each L is 4 bytes and denotes the length in bytes of the corresponding TX. + const lengthOffset = transactionOffset // Position right before L1 + transactionOffset += block.numberOfTransactions * 4 // Position right after LN for (let i = 0; i < block.numberOfTransactions; i++) { - const transactionsLength = block.transactions[i] - block.transactions[i] = Transaction.deserialize(buf.slice(transactionOffset, transactionOffset + transactionsLength).toString('hex')) - transactionOffset += transactionsLength + const transactionLength = buf.readUint32(lengthOffset + i * 4) + + const transaction = Transaction.deserialize( + buf + .slice(transactionOffset, transactionOffset + transactionLength) + .toString('hex'), + ) + block.transactions.push(transaction) + + transactionOffset += transactionLength } return block } - /* + /** * Serialize block. * @param {Object} data * @return {Buffer} * @static */ - static serializeFull (block) { - const buf = new ByteBuffer(1024, true) - buf.append(Block.serialize(block, true)) - - const serializedTransactions = block.transactions.map(transaction => Transaction.serialize(transaction)) - serializedTransactions.forEach(transaction => buf.writeUInt32(transaction.length)) - serializedTransactions.forEach(transaction => buf.append(transaction)) - buf.flip() + static serializeFull(block) { + const serializedBlock = Block.serialize(block, true) + const transactions = block.transactions + + const buf = new ByteBuffer( + serializedBlock.length + transactions.length * 4, + true, + ) + .append(serializedBlock) + .skip(transactions.length * 4) + + for (let i = 0; i < transactions.length; i++) { + const serialized = Transaction.serialize(transactions[i]) + buf.writeUint32(serialized.length, serializedBlock.length + i * 4) + buf.append(serialized) + } - return buf.toBuffer() + return buf.flip().toBuffer() } - /* + /** * Serialize block * TODO split this method between bufferize (as a buffer) and serialize (as hex) * @param {Object} block @@ -424,24 +473,18 @@ module.exports = class Block { * @return {Buffer} * @static */ - static serialize (block, includeSignature = true) { - applyV1Fix(block) + static serialize(block, includeSignature = true) { + block.previousBlockHex = toBytesHex(block.previousBlock) + const bb = new ByteBuffer(256, true) bb.writeUInt32(block.version) bb.writeUInt32(block.timestamp) bb.writeUInt32(block.height) - - // TODO: previousBlock can stay as 8byte hex, it will be simple to process - if (block.previousBlockHex) { - bb.append(block.previousBlockHex, 'hex') - } else { - bb.append('0000000000000000', 'hex') - } - + bb.append(block.previousBlockHex, 'hex') bb.writeUInt32(block.numberOfTransactions) - bb.writeUInt64(block.totalAmount) - bb.writeUInt64(block.totalFee) - bb.writeUInt64(block.reward) + bb.writeUInt64(+new Bignum(block.totalAmount).toFixed()) + bb.writeUInt64(+new Bignum(block.totalFee).toFixed()) + bb.writeUInt64(+new Bignum(block.reward).toFixed()) bb.writeUInt32(block.payloadLength) bb.append(block.payloadHash, 'hex') bb.append(block.generatorPublicKey, 'hex') @@ -454,7 +497,7 @@ module.exports = class Block { return bb.toBuffer() } - static getBytesV1 (block, includeSignature) { + static getBytesV1(block, includeSignature) { if (includeSignature === undefined) { includeSignature = block.blockSignature !== undefined } @@ -478,7 +521,10 @@ module.exports = class Block { let i if (block.previousBlock) { - const pb = Bignum(block.previousBlock).toBuffer({size: '8'}) + const pb = Buffer.from( + new Bignum(block.previousBlock).toString(16), + 'hex', + ) for (i = 0; i < 8; i++) { bb.writeByte(pb[i]) @@ -490,9 +536,9 @@ module.exports = class Block { } bb.writeInt(block.numberOfTransactions) - bb.writeLong(block.totalAmount) - bb.writeLong(block.totalFee) - bb.writeLong(block.reward) + bb.writeLong(+block.totalAmount.toFixed()) + bb.writeLong(+block.totalFee.toFixed()) + bb.writeLong(+block.reward.toFixed()) bb.writeInt(block.payloadLength) @@ -501,7 +547,10 @@ module.exports = class Block { bb.writeByte(payloadHashBuffer[i]) } - const generatorPublicKeyBuffer = Buffer.from(block.generatorPublicKey, 'hex') + const generatorPublicKeyBuffer = Buffer.from( + block.generatorPublicKey, + 'hex', + ) for (i = 0; i < generatorPublicKeyBuffer.length; i++) { bb.writeByte(generatorPublicKeyBuffer[i]) } @@ -521,9 +570,16 @@ module.exports = class Block { return b } - toRawJson () { - return Object.assign(this.data, { - transactions: this.transactions.map(transaction => transaction.data) + toJson() { + // Convert Bignums + const blockData = cloneDeepWith(this.data, (value, key) => { + if (['reward', 'totalAmount', 'totalFee'].indexOf(key) !== -1) { + return +value.toFixed() + } + }) + + return Object.assign(blockData, { + transactions: this.transactions.map(transaction => transaction.toJson()), }) } } diff --git a/packages/crypto/lib/models/delegate.js b/packages/crypto/lib/models/delegate.js index 77999e8230..3fa3eb454f 100644 --- a/packages/crypto/lib/models/delegate.js +++ b/packages/crypto/lib/models/delegate.js @@ -3,9 +3,9 @@ const wif = require('wif') const { createHash } = require('crypto') const otplib = require('otplib') const forge = require('node-forge') +const Bignum = require('../utils/bignum') const Block = require('./block') -const ECPair = require('../crypto/ecpair') const crypto = require('../crypto/crypto') const sortTransactions = require('../utils/sort-transactions') @@ -30,7 +30,7 @@ module.exports = class Delegate { * @param {Number} network * @param {String} password */ - constructor (passphrase, network, password) { + constructor(passphrase, network, password) { this.network = network this.keySize = 32 // AES-256 this.iterations = 5000 @@ -38,8 +38,11 @@ module.exports = class Delegate { if (bip38.verify(passphrase)) { try { this.keys = Delegate.decryptPassphrase(passphrase, network, password) - this.publicKey = this.keys.getPublicKeyBuffer().toString('hex') - this.address = this.keys.getAddress(network.pubKeyHash) + this.publicKey = this.keys.publicKey + this.address = crypto.getAddress( + this.keys.publicKey, + network.pubKeyHash, + ) this.otpSecret = otplib.authenticator.generateSecret() this.bip38 = true this.encryptKeysWithOtp() @@ -51,7 +54,7 @@ module.exports = class Delegate { } else { this.keys = crypto.getKeys(passphrase) this.publicKey = this.keys.publicKey - this.address = this.keys.getAddress(network.pubKeyHash) + this.address = crypto.getAddress(this.publicKey, network.pubKeyHash) } } @@ -63,10 +66,9 @@ module.exports = class Delegate { * @return {String} * @static */ - static encryptPassphrase (passphrase, network, password) { - const keys = crypto.getKeys(passphrase, network) - const wifKey = keys.toWIF() - const decoded = wif.decode(wifKey) + static encryptPassphrase(passphrase, network, password) { + const keys = crypto.getKeys(passphrase) + const decoded = wif.decode(crypto.keysToWIF(keys, network)) return bip38.encrypt(decoded.privateKey, decoded.compressed, password) } @@ -76,35 +78,35 @@ module.exports = class Delegate { * @param {String} passphrase * @param {Number} network * @param {String} password - * @return {ECPair} + * @return {Object} * @static */ - static decryptPassphrase (passphrase, network, password) { + static decryptPassphrase(passphrase, network, password) { const decryptedWif = bip38.decrypt(passphrase, password) - const wifKey = wif.encode(network.wif, decryptedWif.privateKey, decryptedWif.compressed) - - let keys = ECPair.fromWIF(wifKey, network) - keys.publicKey = keys.getPublicKeyBuffer().toString('hex') - - return keys + const wifKey = wif.encode( + network.wif, + decryptedWif.privateKey, + decryptedWif.compressed, + ) + return crypto.getKeysFromWIF(wifKey, network) } /** * Encrypt keys with one time password - used to store encrypted in memory. */ - encryptKeysWithOtp () { + encryptKeysWithOtp() { this.otp = otplib.authenticator.generate(this.otpSecret) - this.encryptedKeys = this.__encryptData(this.keys.toWIF(), this.otp) + const wifKey = crypto.keysToWIF(this.keys, this.network) + this.encryptedKeys = this.__encryptData(wifKey, this.otp) this.keys = null } /** * Decrypt keys with one time password. */ - decryptKeysWithOtp () { - let wifKey = this.__decryptData(this.encryptedKeys, this.otp) - this.keys = ECPair.fromWIF(wifKey, this.network) - this.keys.publicKey = this.keys.getPublicKeyBuffer().toString('hex') + decryptKeysWithOtp() { + const wifKey = this.__decryptData(this.encryptedKeys, this.otp) + this.keys = crypto.getKeysFromWIF(wifKey, this.network) this.otp = null this.encryptedKeys = null } @@ -115,18 +117,18 @@ module.exports = class Delegate { * @param {Object} options * @return {(Block|undefined)} */ - forge (transactions, options) { + forge(transactions, options) { if (!options.version && (this.encryptedKeys || !this.bip38)) { const transactionData = { - amount: 0, - fee: 0, - sha256: createHash('sha256') + amount: Bignum.ZERO, + fee: Bignum.ZERO, + sha256: createHash('sha256'), } const sortedTransactions = sortTransactions(transactions) sortedTransactions.forEach(transaction => { - transactionData.amount += transaction.amount - transactionData.fee += transaction.fee + transactionData.amount = transactionData.amount.plus(transaction.amount) + transactionData.fee = transactionData.fee.plus(transaction.fee) transactionData.sha256.update(Buffer.from(transaction.id, 'hex')) }) @@ -143,14 +145,14 @@ module.exports = class Delegate { reward: options.reward, payloadLength: 32 * sortedTransactions.length, payloadHash: transactionData.sha256.digest().toString('hex'), - transactions: sortedTransactions + transactions: sortedTransactions, } if (this.bip38) { this.decryptKeysWithOtp() } - let block = Block.create(data, this.keys) + const block = Block.create(data, this.keys) if (this.bip38) { this.encryptKeysWithOtp() @@ -158,6 +160,8 @@ module.exports = class Delegate { return block } + + return false } /** @@ -166,9 +170,14 @@ module.exports = class Delegate { * @param {String} password * @return {String} */ - __encryptData (content, password) { - let derivedKey = forge.pkcs5.pbkdf2(password, this.otpSecret, this.iterations, this.keySize) - let cipher = forge.cipher.createCipher('AES-CBC', derivedKey) + __encryptData(content, password) { + const derivedKey = forge.pkcs5.pbkdf2( + password, + this.otpSecret, + this.iterations, + this.keySize, + ) + const cipher = forge.cipher.createCipher('AES-CBC', derivedKey) cipher.start({ iv: forge.util.decode64(this.otp) }) cipher.update(forge.util.createBuffer(content)) cipher.finish() @@ -182,9 +191,14 @@ module.exports = class Delegate { * @param {String} password * @return {String} */ - __decryptData (cipherText, password) { - let derivedKey = forge.pkcs5.pbkdf2(password, this.otpSecret, this.iterations, this.keySize) - let decipher = forge.cipher.createDecipher('AES-CBC', derivedKey) + __decryptData(cipherText, password) { + const derivedKey = forge.pkcs5.pbkdf2( + password, + this.otpSecret, + this.iterations, + this.keySize, + ) + const decipher = forge.cipher.createDecipher('AES-CBC', derivedKey) decipher.start({ iv: forge.util.decode64(this.otp) }) decipher.update(forge.util.createBuffer(forge.util.decode64(cipherText))) decipher.finish() diff --git a/packages/crypto/lib/models/transaction.js b/packages/crypto/lib/models/transaction.js index eeff6b2973..95ea3c70c1 100644 --- a/packages/crypto/lib/models/transaction.js +++ b/packages/crypto/lib/models/transaction.js @@ -1,9 +1,16 @@ +/* eslint no-bitwise: "off" */ + const bs58check = require('bs58check') +const cloneDeepWith = require('lodash/cloneDeepWith') const ByteBuffer = require('bytebuffer') const { createHash } = require('crypto') +const { Bignum } = require('../utils') const crypto = require('../crypto/crypto') const configManager = require('../managers/config') const { TRANSACTION_TYPES } = require('../constants') +const { + transactionIdFixTable, +} = require('../constants').CONFIGURATIONS.ARK.MAINNET /** * TODO copy some parts to ArkDocs @@ -31,33 +38,28 @@ const { TRANSACTION_TYPES } = require('../constants') * - network */ module.exports = class Transaction { - constructor (data) { - this.serialized = Transaction.serialize(data) - this.data = Transaction.deserialize(this.serialized.toString('hex')) - - if (this.data.version === 1) { - this.verified = crypto.verify(this.data) - - if (!this.verified) { - // fix on issue of non homogeneus transaction type 1 payload - if (this.data.type === TRANSACTION_TYPES.SECOND_SIGNATURE || this.data.type === TRANSACTION_TYPES.MULTI_SIGNATURE) { - if (this.data.recipientId) { - delete this.data.recipientId - } else { - this.data.recipientId = crypto.getAddress(this.data.senderPublicKey, this.data.network) - } - - this.verified = crypto.verify(this.data) - this.data.id = crypto.getId(this.data) - } - } + constructor(data) { + if (typeof data === 'string') { + this.serialized = data } else { + this.serialized = Transaction.serialize(data).toString('hex') + } + const deserialized = Transaction.deserialize(this.serialized) + + if (deserialized.version === 1) { + Transaction.applyV1Compatibility(deserialized) + this.verified = deserialized.verified + delete deserialized.verified + } else if (deserialized.version === 2) { + deserialized.id = createHash('sha256') + .update(Buffer.from(this.serialized, 'hex')) + .digest() + .toString('hex') + // TODO: enable AIP11 when network ready this.verified = false } - - // if (this.data.amount !== transaction.amount) console.error('bang', transaction, this.data); - [ + ;[ 'id', 'sequence', 'version', @@ -65,6 +67,7 @@ module.exports = class Transaction { 'senderPublicKey', 'recipientId', 'type', + 'vendorField', 'vendorFieldHex', 'amount', 'fee', @@ -76,49 +79,93 @@ module.exports = class Transaction { 'asset', 'expiration', 'timelock', - 'timelockType' - ].forEach((key) => { - this[key] = this.data[key] + 'timelockType', + ].forEach(key => { + this[key] = deserialized[key] }, this) + + this.data = deserialized + } + + static applyV1Compatibility(deserialized) { + if (deserialized.secondSignature) { + deserialized.signSignature = deserialized.secondSignature + } + + if (deserialized.type === TRANSACTION_TYPES.VOTE) { + deserialized.recipientId = crypto.getAddress( + deserialized.senderPublicKey, + deserialized.network, + ) + } + + if (deserialized.vendorFieldHex) { + deserialized.vendorField = Buffer.from( + deserialized.vendorFieldHex, + 'hex', + ).toString('utf8') + } + + if (deserialized.type === TRANSACTION_TYPES.MULTI_SIGNATURE) { + deserialized.asset.multisignature.keysgroup = deserialized.asset.multisignature.keysgroup.map( + k => `+${k}`, + ) + } + + if ( + deserialized.type === TRANSACTION_TYPES.SECOND_SIGNATURE || + deserialized.type === TRANSACTION_TYPES.MULTI_SIGNATURE + ) { + deserialized.recipientId = crypto.getAddress( + deserialized.senderPublicKey, + deserialized.network, + ) + } + + if (!deserialized.id) { + deserialized.id = crypto.getId(deserialized) + + // Apply fix for broken type 1 and 4 transactions, which were + // erroneously calculated with a recipient id. + if (transactionIdFixTable[deserialized.id]) { + deserialized.id = transactionIdFixTable[deserialized.id] + } + } + + if (deserialized.type <= 4) { + deserialized.verified = crypto.verify(deserialized) + } else { + deserialized.verified = false + } } - static fromBytes (hexString) { - return new Transaction(Transaction.deserialize(hexString)) + /* + * Return a clean transaction data from the serialized form. + * @return {Transaction} + */ + static fromBytes(hexString) { + return new Transaction(hexString) } - verify () { + verify() { return this.verified } /* - * Return transaction data for v1. + * Return transaction data. * @return {Object} */ - toBroadcastV1 () { - if (this.type === TRANSACTION_TYPES.DELEGATE_REGISTRATION) { - return { - id: this.id, - type: this.type, - amount: 0, - fee: this.fee, - recipientId: null, - senderPublicKey: this.senderPublicKey, - timestamp: this.timestamp, - asset: { - delegate: { - username: this.asset.delegate.username, - publicKey: this.senderPublicKey - } - }, - signature: this.signature + toJson() { + // Convert Bignums + return cloneDeepWith(this.data, (value, key) => { + if (['amount', 'fee'].indexOf(key) !== -1) { + return +value.toFixed() } - } - - return this.data + }) } // AIP11 serialization - static serialize (transaction) { + static serialize(transaction) { const bb = new ByteBuffer(512, true) bb.writeByte(0xff) // fill, to disambiguate from v1 bb.writeByte(transaction.version || 0x01) // version @@ -126,10 +173,10 @@ module.exports = class Transaction { bb.writeByte(transaction.type) bb.writeUInt32(transaction.timestamp) bb.append(transaction.senderPublicKey, 'hex') - bb.writeUInt64(transaction.fee) + bb.writeUInt64(+new Bignum(transaction.fee).toFixed()) if (transaction.vendorField) { - let vf = Buffer.from(transaction.vendorField, 'utf8') + const vf = Buffer.from(transaction.vendorField, 'utf8') bb.writeByte(vf.length) bb.append(vf) } else if (transaction.vendorFieldHex) { @@ -139,35 +186,32 @@ module.exports = class Transaction { bb.writeByte(0x00) } - // TODO use else if - if (transaction.type === TRANSACTION_TYPES.TRANSFER) { - bb.writeUInt64(transaction.amount) + bb.writeUInt64(+new Bignum(transaction.amount).toFixed()) bb.writeUInt32(transaction.expiration || 0) bb.append(bs58check.decode(transaction.recipientId)) - } - - if (transaction.type === TRANSACTION_TYPES.VOTE) { - const voteBytes = transaction.asset.votes.map(vote => (vote[0] === '+' ? '01' : '00') + vote.slice(1)).join('') + } else if (transaction.type === TRANSACTION_TYPES.VOTE) { + const voteBytes = transaction.asset.votes + .map(vote => (vote[0] === '+' ? '01' : '00') + vote.slice(1)) + .join('') bb.writeByte(transaction.asset.votes.length) bb.append(voteBytes, 'hex') - } - - if (transaction.type === TRANSACTION_TYPES.SECOND_SIGNATURE) { + } else if (transaction.type === TRANSACTION_TYPES.SECOND_SIGNATURE) { bb.append(transaction.asset.signature.publicKey, 'hex') - } - - if (transaction.type === TRANSACTION_TYPES.DELEGATE_REGISTRATION) { - const delegateBytes = Buffer.from(transaction.asset.delegate.username, 'utf8') + } else if (transaction.type === TRANSACTION_TYPES.DELEGATE_REGISTRATION) { + const delegateBytes = Buffer.from( + transaction.asset.delegate.username, + 'utf8', + ) bb.writeByte(delegateBytes.length) bb.append(delegateBytes, 'hex') - } - - if (transaction.type === TRANSACTION_TYPES.MULTI_SIGNATURE) { + } else if (transaction.type === TRANSACTION_TYPES.MULTI_SIGNATURE) { let joined = null if (!transaction.version || transaction.version === 1) { - joined = transaction.asset.multisignature.keysgroup.map(k => k.slice(1)).join('') // eslint-disable-line max-len + joined = transaction.asset.multisignature.keysgroup + .map(k => (k[0] === '+' ? k.slice(1) : k)) + .join('') // eslint-disable-line max-len } else { joined = transaction.asset.multisignature.keysgroup.join('') } @@ -177,29 +221,21 @@ module.exports = class Transaction { bb.writeByte(transaction.asset.multisignature.keysgroup.length) bb.writeByte(transaction.asset.multisignature.lifetime) bb.append(keysgroupBuffer, 'hex') - } - - if (transaction.type === TRANSACTION_TYPES.IPFS) { + } else if (transaction.type === TRANSACTION_TYPES.IPFS) { bb.writeByte(transaction.asset.ipfs.dag.length / 2) bb.append(transaction.asset.ipfs.dag, 'hex') - } - - if (transaction.type === TRANSACTION_TYPES.TIMELOCK_TRANSFER) { - bb.writeUInt64(transaction.amount) + } else if (transaction.type === TRANSACTION_TYPES.TIMELOCK_TRANSFER) { + bb.writeUInt64(+transaction.amount.toFixed()) bb.writeByte(transaction.timelockType) bb.writeUInt32(transaction.timelock) bb.append(bs58check.decode(transaction.recipientId)) - } - - if (transaction.type === TRANSACTION_TYPES.MULTI_PAYMENT) { + } else if (transaction.type === TRANSACTION_TYPES.MULTI_PAYMENT) { bb.writeUInt32(transaction.asset.payments.length) transaction.asset.payments.forEach(p => { bb.writeUInt64(p.amount) bb.append(bs58check.decode(p.recipientId)) }) - } - - if (transaction.type === TRANSACTION_TYPES.DELEGATE_RESIGNATION) { + } else if (transaction.type === TRANSACTION_TYPES.DELEGATE_RESIGNATION) { // delegate resignation - empty payload } @@ -223,7 +259,7 @@ module.exports = class Transaction { return bb.toBuffer() } - static deserialize (hexString) { + static deserialize(hexString) { const transaction = {} const buf = ByteBuffer.fromHex(hexString, true) transaction.version = buf.readInt8(1) @@ -231,21 +267,30 @@ module.exports = class Transaction { transaction.type = buf.readInt8(3) transaction.timestamp = buf.readUInt32(4) transaction.senderPublicKey = hexString.substring(16, 16 + 33 * 2) - transaction.fee = buf.readUInt64(41).toNumber() + transaction.fee = new Bignum(buf.readUInt64(41)) const vflength = buf.readInt8(41 + 8) if (vflength > 0) { - transaction.vendorFieldHex = hexString.substring((41 + 8 + 1) * 2, (41 + 8 + 1) * 2 + vflength * 2) + transaction.vendorFieldHex = hexString.substring( + (41 + 8 + 1) * 2, + (41 + 8 + 1) * 2 + vflength * 2, + ) } const assetOffset = (41 + 8 + 1) * 2 + vflength * 2 if (transaction.type === TRANSACTION_TYPES.TRANSFER) { - transaction.amount = buf.readUInt64(assetOffset / 2).toNumber() + transaction.amount = new Bignum(buf.readUInt64(assetOffset / 2)) transaction.expiration = buf.readUInt32(assetOffset / 2 + 8) - transaction.recipientId = bs58check.encode(buf.buffer.slice(assetOffset / 2 + 12, assetOffset / 2 + 12 + 21)) - - Transaction.parseSignatures(hexString, transaction, assetOffset + (21 + 12) * 2) + transaction.recipientId = bs58check.encode( + buf.buffer.slice(assetOffset / 2 + 12, assetOffset / 2 + 12 + 21), + ) + + Transaction.parseSignatures( + hexString, + transaction, + assetOffset + (21 + 12) * 2, + ) } if (transaction.type === TRANSACTION_TYPES.VOTE) { @@ -254,19 +299,26 @@ module.exports = class Transaction { let vote for (let i = 0; i < votelength; i++) { - vote = hexString.substring(assetOffset + 2 + i * 2 * 34, assetOffset + 2 + (i + 1) * 2 * 34) + vote = hexString.substring( + assetOffset + 2 + i * 2 * 34, + assetOffset + 2 + (i + 1) * 2 * 34, + ) vote = (vote[1] === '1' ? '+' : '-') + vote.slice(2) transaction.asset.votes.push(vote) } - Transaction.parseSignatures(hexString, transaction, assetOffset + 2 + votelength * 34 * 2) + Transaction.parseSignatures( + hexString, + transaction, + assetOffset + 2 + votelength * 34 * 2, + ) } if (transaction.type === TRANSACTION_TYPES.SECOND_SIGNATURE) { transaction.asset = { signature: { - publicKey: hexString.substring(assetOffset, assetOffset + 66) - } + publicKey: hexString.substring(assetOffset, assetOffset + 66), + }, } Transaction.parseSignatures(hexString, transaction, assetOffset + 66) @@ -277,42 +329,70 @@ module.exports = class Transaction { transaction.asset = { delegate: { - username: buf.slice(assetOffset / 2 + 1, assetOffset / 2 + 1 + usernamelength).toString('utf8') - } + username: buf + .slice(assetOffset / 2 + 1, assetOffset / 2 + 1 + usernamelength) + .toString('utf8'), + }, } - Transaction.parseSignatures(hexString, transaction, assetOffset + (usernamelength + 1) * 2) + Transaction.parseSignatures( + hexString, + transaction, + assetOffset + (usernamelength + 1) * 2, + ) } if (transaction.type === TRANSACTION_TYPES.MULTI_SIGNATURE) { transaction.asset = { multisignature: { keysgroup: [] } } - transaction.asset.multisignature.min = buf.readInt8(assetOffset / 2) & 0xff + transaction.asset.multisignature.min = + buf.readInt8(assetOffset / 2) & 0xff const num = buf.readInt8(assetOffset / 2 + 1) & 0xff - transaction.asset.multisignature.lifetime = buf.readInt8(assetOffset / 2 + 2) & 0xff + transaction.asset.multisignature.lifetime = + buf.readInt8(assetOffset / 2 + 2) & 0xff for (let index = 0; index < num; index++) { - const key = hexString.slice(assetOffset + 6 + index * 66, assetOffset + 6 + (index + 1) * 66) + const key = hexString.slice( + assetOffset + 6 + index * 66, + assetOffset + 6 + (index + 1) * 66, + ) transaction.asset.multisignature.keysgroup.push(key) } - Transaction.parseSignatures(hexString, transaction, assetOffset + 6 + num * 66) + Transaction.parseSignatures( + hexString, + transaction, + assetOffset + 6 + num * 66, + ) } if (transaction.type === TRANSACTION_TYPES.IPFS) { transaction.asset = {} const l = buf.readInt8(assetOffset / 2) & 0xff - transaction.asset.dag = hexString.substring(assetOffset + 2, assetOffset + 2 + l * 2) - Transaction.parseSignatures(hexString, transaction, assetOffset + 2 + l * 2) + transaction.asset.dag = hexString.substring( + assetOffset + 2, + assetOffset + 2 + l * 2, + ) + Transaction.parseSignatures( + hexString, + transaction, + assetOffset + 2 + l * 2, + ) } if (transaction.type === TRANSACTION_TYPES.TIMELOCK_TRANSFER) { - transaction.amount = buf.readUInt64(assetOffset / 2).toNumber() + transaction.amount = new Bignum(buf.readUInt64(assetOffset / 2)) transaction.timelockType = buf.readInt8(assetOffset / 2 + 8) & 0xff transaction.timelock = buf.readUInt64(assetOffset / 2 + 9).toNumber() - transaction.recipientId = bs58check.encode(buf.buffer.slice(assetOffset / 2 + 13, assetOffset / 2 + 13 + 21)) - - Transaction.parseSignatures(hexString, transaction, assetOffset + (21 + 13) * 2) + transaction.recipientId = bs58check.encode( + buf.buffer.slice(assetOffset / 2 + 13, assetOffset / 2 + 13 + 21), + ) + + Transaction.parseSignatures( + hexString, + transaction, + assetOffset + (21 + 13) * 2, + ) } if (transaction.type === TRANSACTION_TYPES.MULTI_PAYMENT) { @@ -323,13 +403,18 @@ module.exports = class Transaction { for (let j = 0; j < total; j++) { const payment = {} - payment.amount = buf.readUInt64(offset).toNumber() - payment.recipientId = bs58check.encode(buf.buffer.slice(offset + 1, offset + 1 + 21)) + payment.amount = new Bignum(buf.readUInt64(offset)) + payment.recipientId = bs58check.encode( + buf.buffer.slice(offset + 1, offset + 1 + 21), + ) transaction.asset.payments.push(payment) offset += 22 } - transaction.amount = transaction.asset.payments.reduce((a, p) => (a += p.amount), 0) + transaction.amount = transaction.asset.payments.reduce( + (a, p) => a.plus(p.amount), + Bignum.ZERO, + ) Transaction.parseSignatures(hexString, transaction, offset * 2) } @@ -338,44 +423,15 @@ module.exports = class Transaction { Transaction.parseSignatures(hexString, transaction, assetOffset) } - if (!transaction.amount) { // this is needed for computation over the blockchain - transaction.amount = 0 - } - - if (!transaction.version || transaction.version === 1) { - if (transaction.secondSignature) { - transaction.signSignature = transaction.secondSignature - } - - if (transaction.type === TRANSACTION_TYPES.VOTE) { - transaction.recipientId = crypto.getAddress(transaction.senderPublicKey, transaction.network) - } - - if (transaction.vendorFieldHex) { - transaction.vendorField = Buffer.from(transaction.vendorFieldHex, 'hex').toString('utf8') - } - - if (transaction.type === TRANSACTION_TYPES.MULTI_SIGNATURE) { - transaction.asset.multisignature.keysgroup = transaction.asset.multisignature.keysgroup.map(k => '+' + k) - } - - if (!transaction.id) { - transaction.id = crypto.getId(transaction) - } - - if (transaction.type === TRANSACTION_TYPES.SECOND_SIGNATURE || transaction.type === TRANSACTION_TYPES.MULTI_SIGNATURE) { - transaction.recipientId = crypto.getAddress(transaction.senderPublicKey, transaction.network) - } - } - - if (transaction.version === 2) { - transaction.id = createHash('sha256').update(Buffer.from(hexString, 'hex')).digest().toString('hex') + if (!transaction.amount) { + // this is needed for computation over the blockchain + transaction.amount = Bignum.ZERO } return transaction } - static parseSignatures (hexString, transaction, startOffset) { + static parseSignatures(hexString, transaction, startOffset) { transaction.signature = hexString.substring(startOffset) let multioffset = 0 @@ -383,21 +439,30 @@ module.exports = class Transaction { if (transaction.signature.length === 0) { delete transaction.signature } else { - const length1 = parseInt('0x' + transaction.signature.substring(2, 4), 16) + 2 - transaction.signature = hexString.substring(startOffset, startOffset + length1 * 2) + const length1 = + parseInt(`0x${transaction.signature.substring(2, 4)}`, 16) + 2 + transaction.signature = hexString.substring( + startOffset, + startOffset + length1 * 2, + ) multioffset += length1 * 2 - transaction.secondSignature = hexString.substring(startOffset + length1 * 2) + transaction.secondSignature = hexString.substring( + startOffset + length1 * 2, + ) if (transaction.secondSignature.length === 0) { delete transaction.secondSignature + } else if (transaction.secondSignature.slice(0, 2) === 'ff') { + // start of multisign + delete transaction.secondSignature } else { - if (transaction.secondSignature.slice(0, 2) === 'ff') { // start of multisign - delete transaction.secondSignature - } else { - const length2 = parseInt('0x' + transaction.secondSignature.substring(2, 4), 16) + 2 - transaction.secondSignature = transaction.secondSignature.substring(0, length2 * 2) - multioffset += length2 * 2 - } + const length2 = + parseInt(`0x${transaction.secondSignature.substring(2, 4)}`, 16) + 2 + transaction.secondSignature = transaction.secondSignature.substring( + 0, + length2 * 2, + ) + multioffset += length2 * 2 } let signatures = hexString.substring(startOffset + multioffset) @@ -414,7 +479,7 @@ module.exports = class Transaction { let moreSignatures = true while (moreSignatures) { - const mlength = parseInt('0x' + signatures.substring(2, 4), 16) + 2 + const mlength = parseInt(`0x${signatures.substring(2, 4)}`, 16) + 2 if (mlength > 0) { transaction.signatures.push(signatures.substring(0, mlength * 2)) diff --git a/packages/crypto/lib/models/wallet.js b/packages/crypto/lib/models/wallet.js index 3735d07a5b..fa29fbcb4c 100644 --- a/packages/crypto/lib/models/wallet.js +++ b/packages/crypto/lib/models/wallet.js @@ -1,7 +1,6 @@ const configManager = require('../managers/config') -const { ARKTOSHI, TRANSACTION_TYPES } = require('../constants') -const ECPair = require('../crypto/ecpair') -const ECSignature = require('../crypto/ecsignature') +const { TRANSACTION_TYPES } = require('../constants') +const { Bignum, formatArktoshi } = require('../utils') const crypto = require('../crypto/crypto') const transactionHandler = require('../handlers/transactions') @@ -31,31 +30,32 @@ module.exports = class Wallet { * @constructor * @param {String} address */ - constructor (address) { + constructor(address) { this.address = address this.publicKey = null this.secondPublicKey = null - this.balance = 0 + this.balance = Bignum.ZERO this.vote = null this.voted = false this.username = null this.lastBlock = null - this.votebalance = 0 + this.voteBalance = Bignum.ZERO this.multisignature = null this.dirty = true this.producedBlocks = 0 this.missedBlocks = 0 - this.forgedFees = 0 - this.forgedRewards = 0 + this.forgedFees = Bignum.ZERO + this.forgedRewards = Bignum.ZERO } /** * Check if can apply a transaction to the wallet. * @param {Transaction} transaction + * @param {Array} errors * @return {Boolean} */ - canApply (transaction) { - return transactionHandler.canApply(this, transaction) + canApply(transaction, errors) { + return transactionHandler.canApply(this, transaction, errors) } /** @@ -63,7 +63,7 @@ module.exports = class Wallet { * @param {Transaction} transaction * @return {Boolean} */ - apply (transaction) { + apply(transaction) { return transactionHandler.apply(this, transaction) } @@ -72,7 +72,7 @@ module.exports = class Wallet { * @param {Transaction} transaction * @return {Boolean} */ - revert (transaction) { + revert(transaction) { return transactionHandler.revert(this, transaction) } @@ -80,7 +80,7 @@ module.exports = class Wallet { * Associate this wallet as the sender of a transaction. * @param {Transaction} transaction */ - applyTransactionToSender (transaction) { + applyTransactionToSender(transaction) { return transactionHandler.applyTransactionToSender(this, transaction) } @@ -88,7 +88,7 @@ module.exports = class Wallet { * Remove this wallet as the sender of a transaction. * @param {Transaction} transaction */ - revertTransactionForSender (transaction) { + revertTransactionForSender(transaction) { return transactionHandler.revertTransactionForSender(this, transaction) } @@ -96,7 +96,7 @@ module.exports = class Wallet { * Add transaction balance to this wallet. * @param {Transaction} transaction */ - applyTransactionToRecipient (transaction) { + applyTransactionToRecipient(transaction) { return transactionHandler.applyTransactionToRecipient(this, transaction) } @@ -104,47 +104,60 @@ module.exports = class Wallet { * Remove transaction balance from this wallet. * @param {Transaction} transaction */ - revertTransactionForRecipient (transaction) { + revertTransactionForRecipient(transaction) { return transactionHandler.revertTransactionForRecipient(this, transaction) } /** * Add block data to this wallet. * @param {Block} block + * @returns {Boolean} */ - applyBlock (block) { - if (block.generatorPublicKey === this.publicKey || crypto.getAddress(block.generatorPublicKey) === this.address) { - this.balance += +block.reward + +block.totalFee + applyBlock(block) { + this.dirty = true + + if ( + block.generatorPublicKey === this.publicKey || + crypto.getAddress(block.generatorPublicKey) === this.address + ) { + this.balance = this.balance.plus(block.reward).plus(block.totalFee) // update stats this.producedBlocks++ - this.forgedFees += +block.totalFee - this.forgedRewards += +block.reward + this.forgedFees = this.forgedFees.plus(block.totalFee) + this.forgedRewards = this.forgedRewards.plus(block.reward) this.lastBlock = block + return true } - this.dirty = true + return false } /** * Remove block data from this wallet. * @param {Block} block */ - revertBlock (block) { - if (block.generatorPublicKey === this.publicKey || crypto.getAddress(block.generatorPublicKey) === this.address) { - this.balance -= block.reward + block.totalFee + revertBlock(block) { + this.dirty = true + + if ( + block.generatorPublicKey === this.publicKey || + crypto.getAddress(block.generatorPublicKey) === this.address + ) { + this.balance = this.balance.minus(block.reward).minus(block.totalFee) // update stats - this.forgedFees -= block.totalFee - this.forgedRewards -= block.reward + this.forgedFees = this.forgedFees.minus(block.totalFee) + this.forgedRewards = this.forgedRewards.minus(block.reward) this.lastBlock = block this.producedBlocks-- // TODO: get it back from database? this.lastBlock = null + return true } - this.dirty = true + return false } /** @@ -154,14 +167,9 @@ module.exports = class Wallet { * @param {String} publicKey * @return {Boolean} */ - verify (transaction, signature, publicKey) { + verify(transaction, signature, publicKey) { const hash = crypto.getHash(transaction, true, true) - const signSignatureBuffer = Buffer.from(signature, 'hex') - const publicKeyBuffer = Buffer.from(publicKey, 'hex') - const ecpair = ECPair.fromPublicKeyBuffer(publicKeyBuffer, configManager.config) - const ecsignature = ECSignature.fromDER(signSignatureBuffer) - - return ecpair.verify(hash, ecsignature) + return crypto.verifyHash(hash, signature, publicKey) } /** @@ -170,19 +178,26 @@ module.exports = class Wallet { * @param {MultiSignature} multisignature * @return {Boolean} */ - verifySignatures (transaction, multisignature) { - if (!transaction.signatures || transaction.signatures.length < multisignature.min) { + verifySignatures(transaction, multisignature) { + if ( + !transaction.signatures || + transaction.signatures.length < multisignature.min + ) { return false } - const keysgroup = multisignature.keysgroup.map(publicKey => { - return publicKey.startsWith('+') ? publicKey.slice(1) : publicKey - }) - let signatures = Object.values(transaction.signatures) + const keysgroup = multisignature.keysgroup.map(publicKey => + publicKey.startsWith('+') ? publicKey.slice(1) : publicKey, + ) + const signatures = Object.values(transaction.signatures) let valid = 0 for (const publicKey of keysgroup) { - const signature = this.__verifyTransactionSignatures(transaction, signatures, publicKey) + const signature = this.__verifyTransactionSignatures( + transaction, + signatures, + publicKey, + ) if (signature) { signatures.splice(signatures.indexOf(signature), 1) valid++ @@ -200,85 +215,108 @@ module.exports = class Wallet { * @param {Transaction} transaction * @return {[type]} */ - auditApply (transaction) { + auditApply(transaction) { const audit = [] - audit.push({'Network': configManager.config}) - if (this.multisignature) { - audit.push({'Mutisignature': this.verifySignatures(transaction, this.multisignature)}) + audit.push({ + Mutisignature: this.verifySignatures(transaction, this.multisignature), + }) } else { - audit.push({'Remaining amount': this.balance - transaction.amount - transaction.fee}) - audit.push({'Signature validation': crypto.verify(transaction)}) + audit.push({ + 'Remaining amount': +this.balance + .minus(transaction.amount) + .minus(transaction.fee) + .toFixed(), + }) + audit.push({ 'Signature validation': crypto.verify(transaction) }) // TODO: this can blow up if 2nd phrase and other transactions are in the wrong order if (this.secondPublicKey) { audit.push({ - 'Second Signature Verification': crypto.verifySecondSignature(transaction, this.secondPublicKey, configManager.config) // eslint-disable-line max-len + 'Second Signature Verification': crypto.verifySecondSignature( + transaction, + this.secondPublicKey, + configManager.config, + ), // eslint-disable-line max-len }) } } if (transaction.type === TRANSACTION_TYPES.TRANSFER) { - audit.push({'Transfer': true}) + audit.push({ Transfer: true }) } if (transaction.type === TRANSACTION_TYPES.SECOND_SIGNATURE) { - audit.push({'Second public key': this.secondPublicKey}) + audit.push({ 'Second public key': this.secondPublicKey }) } if (transaction.type === TRANSACTION_TYPES.DELEGATE_REGISTRATION) { const username = transaction.asset.delegate.username - audit.push({'Current username': this.username}) - audit.push({'New username': username}) + audit.push({ 'Current username': this.username }) + audit.push({ 'New username': username }) } if (transaction.type === TRANSACTION_TYPES.VOTE) { - audit.push({'Current vote': this.vote}) - audit.push({'New vote': transaction.asset.votes[0]}) + audit.push({ 'Current vote': this.vote }) + audit.push({ 'New vote': transaction.asset.votes[0] }) } if (transaction.type === TRANSACTION_TYPES.MULTI_SIGNATURE) { const keysgroup = transaction.asset.multisignature.keysgroup - audit.push({'Multisignature not yet registered': !this.multisignature}) - audit.push({'Multisignature enough keys': keysgroup.length >= transaction.asset.multisignature.min}) - audit.push({'Multisignature all keys signed': keysgroup.length === transaction.signatures.length}) - audit.push({'Multisignature verification': this.verifySignatures(transaction, transaction.asset.multisignature)}) + audit.push({ 'Multisignature not yet registered': !this.multisignature }) + audit.push({ + 'Multisignature enough keys': + keysgroup.length >= transaction.asset.multisignature.min, + }) + audit.push({ + 'Multisignature all keys signed': + keysgroup.length === transaction.signatures.length, + }) + audit.push({ + 'Multisignature verification': this.verifySignatures( + transaction, + transaction.asset.multisignature, + ), + }) } if (transaction.type === TRANSACTION_TYPES.IPFS) { - audit.push({'IPFS': true}) + audit.push({ IPFS: true }) } if (transaction.type === TRANSACTION_TYPES.TIMELOCK_TRANSFER) { - audit.push({'Timelock': true}) + audit.push({ Timelock: true }) } if (transaction.type === TRANSACTION_TYPES.MULTI_PAYMENT) { - const amount = transaction.asset.payments.reduce((a, p) => (a += p.amount), 0) - audit.push({'Multipayment remaining amount': amount}) + const amount = transaction.asset.payments.reduce( + (a, p) => a.plus(p.amount), + Bignum.ZERO, + ) + audit.push({ 'Multipayment remaining amount': amount }) } if (transaction.type === TRANSACTION_TYPES.DELEGATE_RESIGNATION) { - audit.push({'Resignate Delegate': this.username}) + audit.push({ 'Resignate Delegate': this.username }) } if (transaction.type === TRANSACTION_TYPES.DELEGATE_RESIGNATION) { - audit.push({'Resignate Delegate': this.username}) + audit.push({ 'Resignate Delegate': this.username }) } if (!Object.values(TRANSACTION_TYPES).includes(transaction.type)) { - audit.push({'Unknown Type': true}) + audit.push({ 'Unknown Type': true }) } return audit } /** - * Get formatted wallet balance as string. + * Get formatted wallet address and balance as string. * @return {String} */ - toString () { - return `${this.address}=${this.balance / ARKTOSHI}` + toString() { + return `${this.address} (${formatArktoshi(this.balance)})` } /** @@ -288,7 +326,7 @@ module.exports = class Wallet { * @param {String} publicKey * @return {Boolean} */ - __verifyTransactionSignatures (transaction, signatures, publicKey) { + __verifyTransactionSignatures(transaction, signatures, publicKey) { for (let i = 0; i < signatures.length; i++) { const signature = signatures[i] if (this.verify(transaction, signature, publicKey)) { diff --git a/packages/crypto/lib/networks/ark/devnet.json b/packages/crypto/lib/networks/ark/devnet.json index 83ce656b0e..049fcfa883 100644 --- a/packages/crypto/lib/networks/ark/devnet.json +++ b/packages/crypto/lib/networks/ark/devnet.json @@ -8,49 +8,80 @@ "pubKeyHash": 30, "nethash": "2a44f340d76ffc3df204c5f38cd355b7496c9065a1ade2ef92071436bd72e867", "wif": 170, + "aip20": 1, "client": { "token": "DARK", "symbol": "DѦ", "explorer": "https://dexplorer.ark.io" }, - "constants": [{ - "height": 1, - "reward": 0, - "activeDelegates": 51, - "blocktime": 8, - "block": { - "version": 0, - "maxTransactions": 50, - "maxPayload": 2097152 + "constants": [ + { + "height": 1, + "reward": 0, + "activeDelegates": 51, + "blocktime": 8, + "block": { + "version": 0, + "maxTransactions": 50, + "maxPayload": 2097152 + }, + "epoch": "2017-03-21T13:00:00.000Z", + "fees": { + "dynamic": true, + "dynamicFees": { + "minFeePool": 1000, + "minFeeBroadcast": 1000, + "addonBytes": { + "transfer": 100, + "secondSignature": 250, + "delegateRegistration": 500, + "vote": 100, + "multiSignature": 500, + "ipfs": 250, + "timelockTransfer": 500, + "multiPayment": 500, + "delegateResignation": 500 + } + }, + "staticFees": { + "transfer": 10000000, + "secondSignature": 500000000, + "delegateRegistration": 2500000000, + "vote": 100000000, + "multiSignature": 500000000, + "ipfs": 0, + "timelockTransfer": 0, + "multiPayment": 0, + "delegateResignation": 0 + } + } }, - "epoch": "2017-03-21T13:00:00.000Z", - "fees": { - "dynamic" : false, - "transfer": 10000000, - "secondSignature": 500000000, - "delegateRegistration": 2500000000, - "vote": 100000000, - "multiSignature": 500000000, - "ipfs": 0, - "timelockTransfer": 0, - "multiPayment": 0, - "delegateResignation": 0 + { + "height": 10800, + "reward": 200000000 }, - "dynamicOffsets": { - "transfer": 100, - "secondSignature": 250, - "delegateRegistration": 500, - "vote": 100, - "multiSignature": 500, - "ipfs": 250, - "timelockTransfer": 500, - "multiPayment": 500, - "delegateResignation": 500 + { + "height": 21600, + "block": { + "maxTransactions": 150, + "maxPayload": 6300000 + } } - }, { - "height": 10800, - "reward": 200000000 - }], + ], "exceptions": { + "blocks": ["15895730198424359628", "14746174532446639362"], + "transactions": [ + "76bd168e57a4431a64617c4e7864df1e0be89831eabaa230e37643efae2def6f", + "90d06cb306dcc33faba59545e03d91ee83b0409e66a45ffe6a9e3b1049a0c521", + "0f7a3e8036fbaae7c76f7615b09b8c4f1337e96d87042d86e03cc5ab9b6ed745", + "23733214f347970a34ccd772f89396056309744688bd6dbc35129e1f12d46d2f", + "e30d7290ca9cab570aa72bf0365dde39b8d75fe65a4e804844e5708a021f8ab4", + "03d3902bb30f71c29151f8b85ff478be1dc5264785c8c84550b6b59339dc03c9", + "7a00dc347a50186bc0d789a7899f1a4dcbc1e5d5adbb5359df238cd2b9363b41", + "bbe266eac2bbc505b40e74ae6d1960d7c76d3ca8d4b942b6046f0c5f750ff9f4", + "cb63ee14068a8d2987c90ecb12998653161cd8748af7790c75592647260d3266", + "d184752c1546c366866013aa00a2a0f9b40463656072334fc302ff783ff4ee98", + "f8122e3d8b7ad31c58ed3254196b16c23249b8372f06de42191c43bfcf39849d" + ] } } diff --git a/packages/crypto/lib/networks/ark/index.js b/packages/crypto/lib/networks/ark/index.js index d50ab2ef05..542122e472 100644 --- a/packages/crypto/lib/networks/ark/index.js +++ b/packages/crypto/lib/networks/ark/index.js @@ -2,5 +2,5 @@ module.exports = { bitcoin: require('./bitcoin.json'), devnet: require('./devnet.json'), mainnet: require('./mainnet.json'), - testnet: require('./testnet.json') + testnet: require('./testnet.json'), } diff --git a/packages/crypto/lib/networks/ark/mainnet.json b/packages/crypto/lib/networks/ark/mainnet.json index 35fbd4db44..2b8820e511 100644 --- a/packages/crypto/lib/networks/ark/mainnet.json +++ b/packages/crypto/lib/networks/ark/mainnet.json @@ -8,51 +8,70 @@ "pubKeyHash": 23, "nethash": "6e84d08bd299ed97c212c886c98a57e36545c8f5d645ca7eeae63a8bd62d8988", "wif": 170, + "aip20": 0, "client": { "token": "ARK", "symbol": "Ѧ", "explorer": "https://explorer.ark.io" }, - "constants": [{ - "height": 1, - "reward": 0, - "activeDelegates": 51, - "blocktime": 8, - "block": { - "version": 0, - "maxTransactions": 50, - "maxPayload": 2097152 + "constants": [ + { + "height": 1, + "reward": 0, + "activeDelegates": 51, + "blocktime": 8, + "block": { + "version": 0, + "maxTransactions": 50, + "maxPayload": 2097152 + }, + "epoch": "2017-03-21T13:00:00.000Z", + "fees": { + "dynamic": true, + "dynamicFees": { + "minFeePool": 3000, + "minFeeBroadcast": 3000, + "addonBytes": { + "transfer": 100, + "secondSignature": 250, + "delegateRegistration": 500, + "vote": 100, + "multiSignature": 500, + "ipfs": 250, + "timelockTransfer": 500, + "multiPayment": 500, + "delegateResignation": 500 + } + }, + "staticFees": { + "transfer": 10000000, + "secondSignature": 500000000, + "delegateRegistration": 2500000000, + "vote": 100000000, + "multiSignature": 500000000, + "ipfs": 0, + "timelockTransfer": 0, + "multiPayment": 0, + "delegateResignation": 0 + } + } }, - "epoch": "2017-03-21T13:00:00.000Z", - "fees": { - "dynamic" : false, - "transfer": 10000000, - "secondSignature": 500000000, - "delegateRegistration": 2500000000, - "vote": 100000000, - "multiSignature": 500000000, - "ipfs": 0, - "timelockTransfer": 0, - "multiPayment": 0, - "delegateResignation": 0 + { + "height": 75600, + "reward": 200000000 }, - "dynamicOffsets": { - "transfer": 100, - "secondSignature": 250, - "delegateRegistration": 500, - "vote": 100, - "multiSignature": 500, - "ipfs": 250, - "timelockTransfer": 500, - "multiPayment": 500, - "delegateResignation": 500 + { + "height": 6600000, + "block": { + "maxTransactions": 150, + "maxPayload": 6300000 + } } - }, { - "height": 75600, - "reward": 200000000 - }], + ], "exceptions": { - "608c7aeba0895da4517496590896eb325a0b5d367e1b186b1c07d7651a568b9e": true + "transactions": [ + "608c7aeba0895da4517496590896eb325a0b5d367e1b186b1c07d7651a568b9e" + ] }, "outlookTable": { "5139199631254983076": "1000099631254983076", @@ -91,5 +110,8 @@ "5059382813585250340": "1000082813585250340", "7091362542116598855": "1000062542116598855", "8225244493039935740": "1000044493039935740" + }, + "transactionIdFixTable": { + "ca764c01dd78f93393b02f7f6c4f0c12ed8e7ca26d3098e91d6e461a238a6b33": "80d75c7b90288246199e4a97ba726bad6639595ef92ad7c2bd14fd31563241ab" } } diff --git a/packages/crypto/lib/networks/ark/testnet.json b/packages/crypto/lib/networks/ark/testnet.json index b3cadc36f1..b3ba84a7c8 100644 --- a/packages/crypto/lib/networks/ark/testnet.json +++ b/packages/crypto/lib/networks/ark/testnet.json @@ -8,56 +8,64 @@ "pubKeyHash": 23, "nethash": "d9acd04bde4234a81addb8482333b4ac906bed7be5a9970ce8ada428bd083192", "wif": 186, + "aip20": 0, "client": { "token": "TARK", "symbol": "TѦ", "explorer": "http://texplorer.ark.io" }, - "constants": [{ - "height": 1, - "reward": 0, - "activeDelegates": 51, - "blocktime": 8, - "block": { - "version": 0, - "maxTransactions": 50, - "maxPayload": 2097152 + "constants": [ + { + "height": 1, + "reward": 0, + "activeDelegates": 51, + "blocktime": 8, + "block": { + "version": 0, + "maxTransactions": 150, + "maxPayload": 2097152 + }, + "epoch": "2017-03-21T13:00:00.000Z", + "fees": { + "dynamic": true, + "dynamicFees": { + "minFeePool": 1000, + "minFeeBroadcast": 1000, + "addonBytes": { + "transfer": 100, + "secondSignature": 250, + "delegateRegistration": 500, + "vote": 100, + "multiSignature": 500, + "ipfs": 250, + "timelockTransfer": 500, + "multiPayment": 500, + "delegateResignation": 500 + } + }, + "staticFees": { + "transfer": 10000000, + "secondSignature": 500000000, + "delegateRegistration": 2500000000, + "vote": 100000000, + "multiSignature": 500000000, + "ipfs": 0, + "timelockTransfer": 0, + "multiPayment": 0, + "delegateResignation": 0 + } + } }, - "epoch": "2017-03-21T13:00:00.000Z", - "fees": { - "dynamic" : false, - "transfer": 10000000, - "secondSignature": 500000000, - "delegateRegistration": 2500000000, - "vote": 100000000, - "multiSignature": 500000000, - "ipfs": 0, - "timelockTransfer": 0, - "multiPayment": 0, - "delegateResignation": 0 + { + "height": 10, + "fees": { + "dynamic": true + } }, - "dynamicOffsets": { - "transfer": 100, - "secondSignature": 250, - "delegateRegistration": 500, - "vote": 100, - "multiSignature": 500, - "ipfs": 250, - "timelockTransfer": 500, - "multiPayment": 500, - "delegateResignation": 500 + { + "height": 75600, + "reward": 200000000 } - }, - { - "height": 10, - "fees":{ - "dynamic" : true - } - }, - { - "height": 75600, - "reward": 200000000 - } -], + ], "exceptions": {} } diff --git a/packages/crypto/lib/networks/index.js b/packages/crypto/lib/networks/index.js index 3e6ffee1ba..d0645a65e8 100644 --- a/packages/crypto/lib/networks/index.js +++ b/packages/crypto/lib/networks/index.js @@ -1,3 +1,3 @@ module.exports = { - ark: require('./ark') + ark: require('./ark'), } diff --git a/packages/crypto/lib/utils/bignum.js b/packages/crypto/lib/utils/bignum.js new file mode 100644 index 0000000000..5032dac9d6 --- /dev/null +++ b/packages/crypto/lib/utils/bignum.js @@ -0,0 +1,8 @@ +const BigNumber = require('bignumber.js') + +BigNumber.config({ DECIMAL_PLACES: 0 }) + +BigNumber.ZERO = new BigNumber(0) +BigNumber.ONE = new BigNumber(1) + +module.exports = BigNumber diff --git a/packages/crypto/lib/utils/format-arktoshi.js b/packages/crypto/lib/utils/format-arktoshi.js new file mode 100644 index 0000000000..96eb5d4162 --- /dev/null +++ b/packages/crypto/lib/utils/format-arktoshi.js @@ -0,0 +1,16 @@ +const { ARKTOSHI } = require('../constants') +const configManager = require('../managers/config') + +/** + * Get human readable string from arktoshis + * @param {Number|String|Bignum} amount + * @return {String} + */ +module.exports = amount => { + const localeString = (+amount / ARKTOSHI).toLocaleString('en', { + minimumFractionDigits: 0, + maximumFractionDigits: 8, + }) + + return `${localeString} ${configManager.config.client.symbol}` +} diff --git a/packages/crypto/lib/utils/index.js b/packages/crypto/lib/utils/index.js new file mode 100644 index 0000000000..2c5be9bd0e --- /dev/null +++ b/packages/crypto/lib/utils/index.js @@ -0,0 +1,5 @@ +module.exports = { + Bignum: require('./bignum'), + formatArktoshi: require('./format-arktoshi'), + sortTransactions: require('./sort-transactions'), +} diff --git a/packages/crypto/lib/utils/sort-transactions.js b/packages/crypto/lib/utils/sort-transactions.js index b3e237fb44..e06d7f6c66 100644 --- a/packages/crypto/lib/utils/sort-transactions.js +++ b/packages/crypto/lib/utils/sort-transactions.js @@ -3,26 +3,22 @@ * @param {Transaction[]} transactions * @return {Transaction[]} */ -module.exports = (transactions) => { - // Map to create a new array (sort is done in place) - // TODO does it matter modifying the order of the original array - return transactions.map(t => t).sort((a, b) => { - if (a.type < b.type) { - return -1 - } +module.exports = transactions => transactions.sort((a, b) => { + if (a.type < b.type) { + return -1 + } - if (a.type > b.type) { - return 1 - } + if (a.type > b.type) { + return 1 + } - if (a.id < b.id) { - return -1 - } + if (a.id < b.id) { + return -1 + } - if (a.id > b.id) { - return 1 - } + if (a.id > b.id) { + return 1 + } - return 0 - }) -} + return 0 +}) diff --git a/packages/crypto/lib/validation/engine.js b/packages/crypto/lib/validation/engine.js new file mode 100644 index 0000000000..a24f7f584e --- /dev/null +++ b/packages/crypto/lib/validation/engine.js @@ -0,0 +1,27 @@ +const Joi = require('joi') +const extensions = require('./extensions') + +class Engine { + constructor() { + this.joi = Joi.extend(extensions) + } + + validate(attributes, rules, options) { + try { + return this.joi.validate( + attributes, + rules, + Object.assign( + { + convert: true, + }, + options, + ), + ) + } catch (error) { + return { value: null, error: error.stack } + } + } +} + +module.exports = new Engine() diff --git a/packages/crypto/lib/validation/extensions/address.js b/packages/crypto/lib/validation/extensions/address.js new file mode 100644 index 0000000000..feead0cdeb --- /dev/null +++ b/packages/crypto/lib/validation/extensions/address.js @@ -0,0 +1,7 @@ +module.exports = joi => ({ + name: 'arkAddress', + base: joi + .string() + .alphanum() + .length(34), +}) diff --git a/packages/crypto/lib/validation/extensions/bignumber.js b/packages/crypto/lib/validation/extensions/bignumber.js new file mode 100644 index 0000000000..29c746bff8 --- /dev/null +++ b/packages/crypto/lib/validation/extensions/bignumber.js @@ -0,0 +1,43 @@ +const Bignum = require('../../utils/bignum') + +module.exports = joi => ({ + name: 'bignumber', + base: joi.object().type(Bignum), + language: { + min: 'is lower than minimum', + only: 'is different from allowed value', + }, + rules: [ + { + name: 'min', + params: { + q: joi.number().required(), + }, + validate(params, value, state, options) { + if (value.isLessThan(params.q)) { + return this.createError('bignumber.min', { v: value }, state, options) + } + + return value + }, + }, + { + name: 'only', + params: { + q: joi.number().required(), + }, + validate(params, value, state, options) { + if (!value.isEqualTo(params.q)) { + return this.createError( + 'bignumber.only', + { v: value }, + state, + options, + ) + } + + return value + }, + }, + ], +}) diff --git a/packages/crypto/lib/validation/extensions/block-id.js b/packages/crypto/lib/validation/extensions/block-id.js new file mode 100644 index 0000000000..87615f9972 --- /dev/null +++ b/packages/crypto/lib/validation/extensions/block-id.js @@ -0,0 +1,4 @@ +module.exports = joi => ({ + name: 'arkBlockId', + base: joi.string().regex(/^[0-9]+$/, 'numbers'), +}) diff --git a/packages/crypto/lib/validation/extensions/block.js b/packages/crypto/lib/validation/extensions/block.js new file mode 100644 index 0000000000..57d0f0cbb6 --- /dev/null +++ b/packages/crypto/lib/validation/extensions/block.js @@ -0,0 +1,63 @@ +module.exports = joi => ({ + name: 'arkBlock', + base: joi.object().keys({ + id: joi.arkBlockId().required(), + idHex: joi.string().hex(), + version: joi + .number() + .integer() + .min(0), + timestamp: joi + .number() + .integer() + .min(0) + .required(), + previousBlock: joi.arkBlockId().required(), + previousBlockHex: joi.string().hex(), + height: joi + .number() + .integer() + .positive() + .required(), + numberOfTransactions: joi + .number() + .integer() + .only(joi.ref('transactions.length')), + totalAmount: joi.alternatives().try( + joi + .number() + .integer() + .min(0) + .required(), + joi + .string() + .regex(/[0-9]+/) + .required(), + ), + totalFee: joi + .number() + .integer() + .min(0) + .required(), + reward: joi + .number() + .integer() + .min(0) + .required(), + payloadLength: joi + .number() + .integer() + .min(0), + payloadHash: joi.string().hex(), + generatorPublicKey: joi + .string() + .hex() + .length(66) + .required(), + blockSignature: joi + .string() + .hex() + .required(), + transactions: joi.arkTransactions(), + }), +}) diff --git a/packages/crypto/lib/validation/extensions/index.js b/packages/crypto/lib/validation/extensions/index.js new file mode 100644 index 0000000000..ca1dc52e85 --- /dev/null +++ b/packages/crypto/lib/validation/extensions/index.js @@ -0,0 +1,11 @@ +module.exports = [ + require('./address'), + require('./bignumber'), + require('./public-key'), + require('./username'), + + require('./block-id'), + ...require('./transactions/index'), // individual transactions + require('./transactions'), + require('./block'), +] diff --git a/packages/crypto/lib/validation/extensions/public-key.js b/packages/crypto/lib/validation/extensions/public-key.js new file mode 100644 index 0000000000..5dd66e4957 --- /dev/null +++ b/packages/crypto/lib/validation/extensions/public-key.js @@ -0,0 +1,7 @@ +module.exports = joi => ({ + name: 'arkPublicKey', + base: joi + .string() + .hex() + .length(66), +}) diff --git a/packages/crypto/lib/validation/extensions/transactions.js b/packages/crypto/lib/validation/extensions/transactions.js new file mode 100644 index 0000000000..afdc9cae09 --- /dev/null +++ b/packages/crypto/lib/validation/extensions/transactions.js @@ -0,0 +1,16 @@ +module.exports = joi => ({ + name: 'arkTransactions', + base: joi + .array() + .items( + joi + .alternatives() + .try( + joi.arkTransfer(), + joi.arkSecondSignature(), + joi.arkDelegateRegistration(), + joi.arkVote(), + joi.arkMultiSignature(), + ), + ), +}) diff --git a/packages/crypto/lib/validation/extensions/transactions/base.js b/packages/crypto/lib/validation/extensions/transactions/base.js new file mode 100644 index 0000000000..06622b0832 --- /dev/null +++ b/packages/crypto/lib/validation/extensions/transactions/base.js @@ -0,0 +1,59 @@ +const { TRANSACTION_TYPES } = require('../../../constants') + +module.exports = joi => + joi.object().keys({ + id: joi + .string() + .alphanum() + .required(), + blockid: joi.alternatives().try( + // TODO: remove in 2.1 + joi.arkBlockId(), + joi.number().unsafe(), + ), + version: joi + .number() + .integer() + .min(1) + .max(2) + .optional(), + timestamp: joi + .number() + .integer() + .min(0) + .required(), + amount: joi + .alternatives() + .try( + joi.bignumber(), + joi + .number() + .integer() + .positive(), + ) + .required(), + fee: joi + .alternatives() + .try( + joi.bignumber().min(1), + joi + .number() + .integer() + .positive(), + ) + .required(), + senderId: joi.arkAddress(), // TODO: remove in 2.1 + recipientId: joi.arkAddress().required(), + senderPublicKey: joi.arkPublicKey().required(), + signature: joi + .string() + .alphanum() + .required(), + signatures: joi.array(), + secondSignature: joi.string().alphanum(), + signSignature: joi.string().alphanum(), // TODO: remove in 2.1 + confirmations: joi // TODO: remove in 2.1 + .number() + .integer() + .min(0), + }) diff --git a/packages/crypto/lib/validation/extensions/transactions/delegate-registration.js b/packages/crypto/lib/validation/extensions/transactions/delegate-registration.js new file mode 100644 index 0000000000..60b5b157d9 --- /dev/null +++ b/packages/crypto/lib/validation/extensions/transactions/delegate-registration.js @@ -0,0 +1,27 @@ +const { TRANSACTION_TYPES } = require('../../../constants') +const transaction = require('./base') + +module.exports = joi => ({ + name: 'arkDelegateRegistration', + base: transaction(joi).append({ + type: joi + .number() + .only(TRANSACTION_TYPES.DELEGATE_REGISTRATION) + .required(), + amount: joi + .alternatives() + .try(joi.bignumber().only(0), joi.number().only(0)) + .optional(), + asset: joi + .object({ + delegate: joi + .object({ + username: joi.arkUsername().required(), + publicKey: joi.arkPublicKey(), + }) + .required(), + }) + .required(), + recipientId: joi.empty(), + }), +}) diff --git a/packages/crypto/lib/validation/extensions/transactions/delegate-resignation.js b/packages/crypto/lib/validation/extensions/transactions/delegate-resignation.js new file mode 100644 index 0000000000..10424080ed --- /dev/null +++ b/packages/crypto/lib/validation/extensions/transactions/delegate-resignation.js @@ -0,0 +1,18 @@ +const { TRANSACTION_TYPES } = require('../../../constants') +const transaction = require('./base') + +module.exports = joi => ({ + name: 'arkDelegateResignation', + base: transaction(joi).append({ + type: joi + .number() + .only(TRANSACTION_TYPES.DELEGATE_RESIGNATION) + .required(), + amount: joi + .alternatives() + .try(joi.bignumber().only(0), joi.number().valid(0)) + .optional(), + asset: joi.object().required(), + recipientId: joi.empty(), + }), +}) diff --git a/packages/crypto/lib/validation/extensions/transactions/index.js b/packages/crypto/lib/validation/extensions/transactions/index.js new file mode 100644 index 0000000000..6a40f5b152 --- /dev/null +++ b/packages/crypto/lib/validation/extensions/transactions/index.js @@ -0,0 +1,11 @@ +module.exports = [ + require('./transfer'), + require('./second-signature'), + require('./delegate-registration'), + require('./vote'), + require('./multi-signature'), + require('./ipfs'), + require('./timelock-transfer'), + require('./multi-payment'), + require('./delegate-resignation'), +] diff --git a/packages/crypto/lib/validation/extensions/transactions/ipfs.js b/packages/crypto/lib/validation/extensions/transactions/ipfs.js new file mode 100644 index 0000000000..0532698e06 --- /dev/null +++ b/packages/crypto/lib/validation/extensions/transactions/ipfs.js @@ -0,0 +1,18 @@ +const { TRANSACTION_TYPES } = require('../../../constants') +const transaction = require('./base') + +module.exports = joi => ({ + name: 'arkIpfs', + base: transaction(joi).append({ + type: joi + .number() + .only(TRANSACTION_TYPES.IPFS) + .required(), + amount: joi + .alternatives() + .try(joi.bignumber().only(0), joi.number().valid(0)) + .optional(), + asset: joi.object().required(), + recipientId: joi.empty(), + }), +}) diff --git a/packages/crypto/lib/validation/extensions/transactions/multi-payment.js b/packages/crypto/lib/validation/extensions/transactions/multi-payment.js new file mode 100644 index 0000000000..b409b6fcb9 --- /dev/null +++ b/packages/crypto/lib/validation/extensions/transactions/multi-payment.js @@ -0,0 +1,14 @@ +const { TRANSACTION_TYPES } = require('../../../constants') +const transaction = require('./base') + +module.exports = joi => ({ + name: 'arkMultiPayment', + base: transaction(joi).append({ + type: joi + .number() + .only(TRANSACTION_TYPES.MULTI_PAYMENT) + .required(), + asset: joi.object().required(), + recipientId: joi.empty(), + }), +}) diff --git a/packages/crypto/lib/validation/extensions/transactions/multi-signature.js b/packages/crypto/lib/validation/extensions/transactions/multi-signature.js new file mode 100644 index 0000000000..e20885c3c5 --- /dev/null +++ b/packages/crypto/lib/validation/extensions/transactions/multi-signature.js @@ -0,0 +1,61 @@ +const { TRANSACTION_TYPES } = require('../../../constants') +const transaction = require('./base') + +module.exports = joi => ({ + name: 'arkMultiSignature', + base: transaction(joi).append({ + type: joi + .number() + .only(TRANSACTION_TYPES.MULTI_SIGNATURE) + .required(), + amount: joi + .alternatives() + .try(joi.bignumber().only(0), joi.number().only(0)) + .optional(), + recipientId: joi.empty(), + signatures: joi + .array() + .length(joi.ref('asset.multisignature.keysgroup.length')) + .required(), + asset: joi + .object({ + multisignature: joi + .object({ + min: joi + .when(joi.ref('keysgroup.length'), { + is: joi.number().greater(16), + then: joi + .number() + .positive() + .max(16), + otherwise: joi + .number() + .positive() + .max(joi.ref('keysgroup.length')), + }) + .required(), + keysgroup: joi + .array() + .unique() + .min(2) + .items( + joi + .string() + .not(`+${transaction.senderPublicKey}`) + .length(67) + .regex(/^\+/) + .required(), + ) + .required(), + lifetime: joi + .number() + .integer() + .min(1) + .max(72) + .required(), + }) + .required(), + }) + .required(), + }), +}) diff --git a/packages/crypto/lib/validation/extensions/transactions/second-signature.js b/packages/crypto/lib/validation/extensions/transactions/second-signature.js new file mode 100644 index 0000000000..78d250d1f9 --- /dev/null +++ b/packages/crypto/lib/validation/extensions/transactions/second-signature.js @@ -0,0 +1,27 @@ +const { TRANSACTION_TYPES } = require('../../../constants') +const transaction = require('./base') + +module.exports = joi => ({ + name: 'arkSecondSignature', + base: transaction(joi).append({ + type: joi + .number() + .only(TRANSACTION_TYPES.SECOND_SIGNATURE) + .required(), + amount: joi + .alternatives() + .try(joi.bignumber().only(0), joi.number().only(0)) + .optional(), + secondSignature: joi.string().only(''), + asset: joi + .object({ + signature: joi + .object({ + publicKey: joi.arkPublicKey().required(), + }) + .required(), + }) + .required(), + recipientId: joi.empty(), + }), +}) diff --git a/packages/crypto/lib/validation/extensions/transactions/timelock-transfer.js b/packages/crypto/lib/validation/extensions/transactions/timelock-transfer.js new file mode 100644 index 0000000000..224f2d1c5a --- /dev/null +++ b/packages/crypto/lib/validation/extensions/transactions/timelock-transfer.js @@ -0,0 +1,18 @@ +const { TRANSACTION_TYPES } = require('../../../constants') +const transaction = require('./base') + +module.exports = joi => ({ + name: 'arkTimelockTransfer', + base: transaction(joi).append({ + type: joi + .number() + .only(TRANSACTION_TYPES.MULTI_PAYMENT) + .required(), + amount: joi + .alternatives() + .try(joi.bignumber().only(0), joi.number().only(0)) + .optional(), + asset: joi.object().required(), + recipientId: joi.empty(), + }), +}) diff --git a/packages/crypto/lib/validation/extensions/transactions/transfer.js b/packages/crypto/lib/validation/extensions/transactions/transfer.js new file mode 100644 index 0000000000..4e4a35164a --- /dev/null +++ b/packages/crypto/lib/validation/extensions/transactions/transfer.js @@ -0,0 +1,26 @@ +const { TRANSACTION_TYPES } = require('../../../constants') +const transaction = require('./base') + +module.exports = joi => ({ + name: 'arkTransfer', + base: transaction(joi).append({ + type: joi + .number() + .only(TRANSACTION_TYPES.TRANSFER) + .required(), + expiration: joi + .number() + .integer() + .min(0), + vendorField: joi + .string() + .max(64, 'utf8') + .allow('', null) + .optional(), // TODO: remove in 2.1 + vendorFieldHex: joi + .string() + .max(64, 'hex') + .optional(), + asset: joi.object().empty(), + }), +}) diff --git a/packages/crypto/lib/validation/extensions/transactions/vote.js b/packages/crypto/lib/validation/extensions/transactions/vote.js new file mode 100644 index 0000000000..4c05b496e0 --- /dev/null +++ b/packages/crypto/lib/validation/extensions/transactions/vote.js @@ -0,0 +1,34 @@ +const { TRANSACTION_TYPES } = require('../../../constants') +const transaction = require('./base') + +module.exports = joi => ({ + name: 'arkVote', + base: transaction(joi).append({ + type: joi + .number() + .only(TRANSACTION_TYPES.VOTE) + .required(), + amount: joi + .alternatives() + .try(joi.bignumber().only(0), joi.number().only(0)) + .optional(), + asset: joi + .object({ + votes: joi + .array() + .items( + joi + .string() + .length(67) + .regex(/^(\+|-)[a-zA-Z0-9]+$/), + ) + .length(1) + .required(), + }) + .required(), + recipientId: joi + .arkAddress() + .allow(null) + .optional(), + }), +}) diff --git a/packages/crypto/lib/validation/extensions/username.js b/packages/crypto/lib/validation/extensions/username.js new file mode 100644 index 0000000000..89ead49097 --- /dev/null +++ b/packages/crypto/lib/validation/extensions/username.js @@ -0,0 +1,8 @@ +module.exports = joi => ({ + name: 'arkUsername', + base: joi + .string() + .regex(/^[a-z0-9!@$&_.]+$/) + .min(1) + .max(20), +}) diff --git a/packages/crypto/lib/validation/index.js b/packages/crypto/lib/validation/index.js new file mode 100644 index 0000000000..4247badce0 --- /dev/null +++ b/packages/crypto/lib/validation/index.js @@ -0,0 +1,4 @@ +module.exports = { + validator: require('./validator'), + transactionValidator: require('./validators/transaction'), +} diff --git a/packages/validation/lib/rules/address.js b/packages/crypto/lib/validation/rules/address.js similarity index 80% rename from packages/validation/lib/rules/address.js rename to packages/crypto/lib/validation/rules/address.js index 70b1f8d66c..b0fed68c3f 100644 --- a/packages/validation/lib/rules/address.js +++ b/packages/crypto/lib/validation/rules/address.js @@ -1,12 +1,12 @@ const engine = require('../engine') -module.exports = (attributes) => { +module.exports = attributes => { const { error, value } = engine.validate(attributes, engine.joi.arkAddress()) return { data: value, errors: error ? error.details : null, passes: !error, - fails: error + fails: error, } } diff --git a/packages/validation/lib/rules/index.js b/packages/crypto/lib/validation/rules/index.js similarity index 72% rename from packages/validation/lib/rules/index.js rename to packages/crypto/lib/validation/rules/index.js index e3fd615c72..9a03355bb9 100644 --- a/packages/validation/lib/rules/index.js +++ b/packages/crypto/lib/validation/rules/index.js @@ -1,5 +1,5 @@ module.exports = { address: require('./address'), publicKey: require('./public-key'), - username: require('./username') + username: require('./username'), } diff --git a/packages/crypto/lib/validation/rules/models/transactions.js b/packages/crypto/lib/validation/rules/models/transactions.js new file mode 100644 index 0000000000..392e8d7742 --- /dev/null +++ b/packages/crypto/lib/validation/rules/models/transactions.js @@ -0,0 +1,4 @@ +exports.transfer = require('./transactions/transfer') +exports.signature = require('./transactions/second-signature') +exports.delegate = require('./transactions/delegate-registration') +exports.vote = require('./transactions/vote') diff --git a/packages/crypto/lib/validation/rules/models/transactions/delegate-registration.js b/packages/crypto/lib/validation/rules/models/transactions/delegate-registration.js new file mode 100644 index 0000000000..8ea8dd2058 --- /dev/null +++ b/packages/crypto/lib/validation/rules/models/transactions/delegate-registration.js @@ -0,0 +1,71 @@ +const { TRANSACTION_TYPES } = require('../../../../constants') +const engine = require('../../../engine') + +module.exports = transaction => { + const { error, value } = engine.validate( + transaction, + engine.joi.object({ + id: engine.joi + .string() + .alphanum() + .required(), + blockid: engine.joi + .alternatives() + .try(engine.joi.arkBlockId(), engine.joi.number().unsafe()), + type: engine.joi.number().valid(TRANSACTION_TYPES.DELEGATE_REGISTRATION), + timestamp: engine.joi + .number() + .integer() + .min(0) + .required(), + amount: engine.joi.alternatives().try( + engine.joi.bignumber(), + engine.joi + .number() + .valid(0) + .required(), + ), + fee: engine.joi.alternatives().try( + engine.joi.bignumber(), + engine.joi + .number() + .integer() + .positive() + .required(), + ), + senderId: engine.joi.arkAddress(), + recipientId: engine.joi.empty(), + senderPublicKey: engine.joi.arkPublicKey().required(), + signature: engine.joi + .string() + .alphanum() + .required(), + signatures: engine.joi.array(), + secondSignature: engine.joi.string().alphanum(), + asset: engine.joi + .object({ + delegate: engine.joi + .object({ + username: engine.joi.arkUsername().required(), + publicKey: engine.joi.arkPublicKey(), + }) + .required(), + }) + .required(), + confirmations: engine.joi + .number() + .integer() + .min(0), + }), + { + allowUnknown: true, + }, + ) + + return { + data: value, + errors: error ? error.details : null, + passes: !error, + fails: error, + } +} diff --git a/packages/crypto/lib/validation/rules/models/transactions/delegate-resignation.js b/packages/crypto/lib/validation/rules/models/transactions/delegate-resignation.js new file mode 100644 index 0000000000..e49762acb5 --- /dev/null +++ b/packages/crypto/lib/validation/rules/models/transactions/delegate-resignation.js @@ -0,0 +1,62 @@ +const { TRANSACTION_TYPES } = require('../../../../constants') +const engine = require('../../../engine') + +module.exports = transaction => { + const { error, value } = engine.validate( + transaction, + engine.joi.object({ + id: engine.joi + .string() + .alphanum() + .required(), + blockid: engine.joi + .alternatives() + .try(engine.joi.arkBlockId(), engine.joi.number().unsafe()), + type: engine.joi.number().valid(TRANSACTION_TYPES.DELEGATE_RESIGNATION), + timestamp: engine.joi + .number() + .integer() + .min(0) + .required(), + amount: engine.joi.alternatives().try( + engine.joi.bignumber(), + engine.joi + .number() + .integer() + .min(0) + .required(), + ), + fee: engine.joi.alternatives().try( + engine.joi.bignumber(), + engine.joi + .number() + .integer() + .positive() + .required(), + ), + senderId: engine.joi.arkAddress(), + senderPublicKey: engine.joi.arkPublicKey().required(), + signature: engine.joi + .string() + .alphanum() + .required(), + signatures: engine.joi.array(), + secondSignature: engine.joi.string().alphanum(), + asset: engine.joi.object().required(), + confirmations: engine.joi + .number() + .integer() + .min(0), + }), + { + allowUnknown: true, + }, + ) + + return { + data: value, + errors: error ? error.details : null, + passes: !error, + fails: error, + } +} diff --git a/packages/crypto/lib/validation/rules/models/transactions/ipfs.js b/packages/crypto/lib/validation/rules/models/transactions/ipfs.js new file mode 100644 index 0000000000..a499721c33 --- /dev/null +++ b/packages/crypto/lib/validation/rules/models/transactions/ipfs.js @@ -0,0 +1,62 @@ +const { TRANSACTION_TYPES } = require('../../../../constants') +const engine = require('../../../engine') + +module.exports = transaction => { + const { error, value } = engine.validate( + transaction, + engine.joi.object({ + id: engine.joi + .string() + .alphanum() + .required(), + blockid: engine.joi + .alternatives() + .try(engine.joi.arkBlockId(), engine.joi.number().unsafe()), + type: engine.joi.number().valid(TRANSACTION_TYPES.IPFS), + timestamp: engine.joi + .number() + .integer() + .min(0) + .required(), + amount: engine.joi.alternatives().try( + engine.joi.bignumber(), + engine.joi + .number() + .integer() + .min(0) + .required(), + ), + fee: engine.joi.alternatives().try( + engine.joi.bignumber(), + engine.joi + .number() + .integer() + .min(0) + .required(), + ), + senderId: engine.joi.arkAddress(), + senderPublicKey: engine.joi.arkPublicKey().required(), + signature: engine.joi + .string() + .alphanum() + .required(), + signatures: engine.joi.array(), + secondSignature: engine.joi.string().alphanum(), + asset: engine.joi.object().required(), + confirmations: engine.joi + .number() + .integer() + .min(0), + }), + { + allowUnknown: true, + }, + ) + + return { + data: value, + errors: error ? error.details : null, + passes: !error, + fails: error, + } +} diff --git a/packages/crypto/lib/validation/rules/models/transactions/multi-payment.js b/packages/crypto/lib/validation/rules/models/transactions/multi-payment.js new file mode 100644 index 0000000000..278ecdde2c --- /dev/null +++ b/packages/crypto/lib/validation/rules/models/transactions/multi-payment.js @@ -0,0 +1,62 @@ +const { TRANSACTION_TYPES } = require('../../../../constants') +const engine = require('../../../engine') + +module.exports = transaction => { + const { error, value } = engine.validate( + transaction, + engine.joi.object({ + id: engine.joi + .string() + .alphanum() + .required(), + blockid: engine.joi + .alternatives() + .try(engine.joi.arkBlockId(), engine.joi.number().unsafe()), + type: engine.joi.number().valid(TRANSACTION_TYPES.MULTI_PAYMENT), + timestamp: engine.joi + .number() + .integer() + .min(0) + .required(), + amount: engine.joi.alternatives().try( + engine.joi.bignumber(), + engine.joi + .number() + .integer() + .min(0) + .required(), + ), + fee: engine.joi.alternatives().try( + engine.joi.bignumber(), + engine.joi + .number() + .integer() + .min(0) + .required(), + ), + senderId: engine.joi.arkAddress(), + senderPublicKey: engine.joi.arkPublicKey().required(), + signature: engine.joi + .string() + .alphanum() + .required(), + signatures: engine.joi.array(), + secondSignature: engine.joi.string().alphanum(), + asset: engine.joi.object().required(), + confirmations: engine.joi + .number() + .integer() + .min(0), + }), + { + allowUnknown: true, + }, + ) + + return { + data: value, + errors: error ? error.details : null, + passes: !error, + fails: error, + } +} diff --git a/packages/crypto/lib/validation/rules/models/transactions/multi-signature.js b/packages/crypto/lib/validation/rules/models/transactions/multi-signature.js new file mode 100644 index 0000000000..fe0b436e2a --- /dev/null +++ b/packages/crypto/lib/validation/rules/models/transactions/multi-signature.js @@ -0,0 +1,103 @@ +const { TRANSACTION_TYPES } = require('../../../../constants') +const engine = require('../../../engine') + +module.exports = transaction => { + let maxMinValue = 16 + let signaturesLength = 2 + if ( + transaction.asset && + transaction.asset.multisignature && + Array.isArray(transaction.asset.multisignature.keysgroup) + ) { + maxMinValue = transaction.asset.multisignature.keysgroup.length + signaturesLength = maxMinValue + } + const { error, value } = engine.validate( + transaction, + engine.joi.object({ + id: engine.joi + .string() + .alphanum() + .required(), + blockid: engine.joi + .alternatives() + .try(engine.joi.arkBlockId(), engine.joi.number().unsafe()), + type: engine.joi.number().valid(TRANSACTION_TYPES.MULTI_SIGNATURE), + timestamp: engine.joi + .number() + .integer() + .min(0) + .required(), + amount: engine.joi + .alternatives() + .try(engine.joi.bignumber(), engine.joi.number().valid(0)), + fee: engine.joi.alternatives().try( + engine.joi.bignumber(), + engine.joi + .number() + .integer() + .positive() + .required(), + ), + senderId: engine.joi.arkAddress(), + recipientId: engine.joi.empty(), + senderPublicKey: engine.joi.arkPublicKey().required(), + signature: engine.joi + .string() + .alphanum() + .required(), + signatures: engine.joi + .array() + .length(signaturesLength) + .required(), + secondSignature: engine.joi.string().alphanum(), + asset: engine.joi + .object({ + multisignature: engine.joi + .object({ + min: engine.joi + .number() + .integer() + .positive() + .max(Math.min(maxMinValue, 16)) + .required(), + keysgroup: engine.joi + .array() + .unique() + .min(2) + .items( + engine.joi + .string() + .not(`+${transaction.senderPublicKey}`) + .length(67) + .regex(/^\+/) + .required(), + ) + .required(), + lifetime: engine.joi + .number() + .integer() + .min(1) + .max(72) + .required(), + }) + .required(), + }) + .required(), + confirmations: engine.joi + .number() + .integer() + .min(0), + }), + { + allowUnknown: true, + }, + ) + + return { + data: value, + errors: error ? error.details : null, + passes: !error, + fails: error, + } +} diff --git a/packages/crypto/lib/validation/rules/models/transactions/second-signature.js b/packages/crypto/lib/validation/rules/models/transactions/second-signature.js new file mode 100644 index 0000000000..69f1d82055 --- /dev/null +++ b/packages/crypto/lib/validation/rules/models/transactions/second-signature.js @@ -0,0 +1,65 @@ +const { TRANSACTION_TYPES } = require('../../../../constants') +const engine = require('../../../engine') + +module.exports = transaction => { + const { error, value } = engine.validate( + transaction, + engine.joi.object({ + id: engine.joi + .string() + .alphanum() + .required(), + blockid: engine.joi + .alternatives() + .try(engine.joi.arkBlockId(), engine.joi.number().unsafe()), + type: engine.joi.number().valid(TRANSACTION_TYPES.SECOND_SIGNATURE), + timestamp: engine.joi + .number() + .integer() + .min(0) + .required(), + amount: engine.joi + .alternatives() + .try(engine.joi.bignumber(), engine.joi.number().valid(0)), + fee: engine.joi.alternatives().try( + engine.joi.bignumber(), + engine.joi + .number() + .integer() + .positive() + .required(), + ), + senderId: engine.joi.arkAddress(), + senderPublicKey: engine.joi.arkPublicKey().required(), + signature: engine.joi + .string() + .alphanum() + .required(), + signatures: engine.joi.array(), + secondSignature: engine.joi.empty(), + asset: engine.joi + .object({ + signature: engine.joi + .object({ + publicKey: engine.joi.arkPublicKey().required(), + }) + .required(), + }) + .required(), + confirmations: engine.joi + .number() + .integer() + .min(0), + }), + { + allowUnknown: true, + }, + ) + + return { + data: value, + errors: error ? error.details : null, + passes: !error, + fails: error, + } +} diff --git a/packages/crypto/lib/validation/rules/models/transactions/timelock-transfer.js b/packages/crypto/lib/validation/rules/models/transactions/timelock-transfer.js new file mode 100644 index 0000000000..e1862fa3de --- /dev/null +++ b/packages/crypto/lib/validation/rules/models/transactions/timelock-transfer.js @@ -0,0 +1,52 @@ +const { TRANSACTION_TYPES } = require('../../../../constants') +const engine = require('../../../engine') + +module.exports = transaction => { + const { error, value } = engine.validate( + transaction, + engine.joi.object({ + id: engine.joi + .string() + .alphanum() + .required(), + blockid: engine.joi + .alternatives() + .try(engine.joi.arkBlockId(), engine.joi.number().unsafe()), + type: engine.joi.number().valid(TRANSACTION_TYPES.TIMELOCK_TRANSFER), + timestamp: engine.joi + .number() + .integer() + .min(0) + .required(), + amount: engine.joi + .alternatives() + .try(engine.joi.bignumber(), engine.joi.number().integer()), + fee: engine.joi + .alternatives() + .try(engine.joi.bignumber(), engine.joi.number().integer()), + senderId: engine.joi.arkAddress(), + senderPublicKey: engine.joi.arkPublicKey().required(), + signature: engine.joi + .string() + .alphanum() + .required(), + signatures: engine.joi.array(), + secondSignature: engine.joi.string().alphanum(), + asset: engine.joi.object().required(), + confirmations: engine.joi + .number() + .integer() + .min(0), + }), + { + allowUnknown: true, + }, + ) + + return { + data: value, + errors: error ? error.details : null, + passes: !error, + fails: error, + } +} diff --git a/packages/crypto/lib/validation/rules/models/transactions/transfer.js b/packages/crypto/lib/validation/rules/models/transactions/transfer.js new file mode 100644 index 0000000000..463c05de9c --- /dev/null +++ b/packages/crypto/lib/validation/rules/models/transactions/transfer.js @@ -0,0 +1,63 @@ +const { TRANSACTION_TYPES } = require('../../../../constants') +const engine = require('../../../engine') + +module.exports = transaction => { + const { error, value } = engine.validate( + transaction, + engine.joi.object({ + id: engine.joi + .string() + .alphanum() + .required(), + blockid: engine.joi + .alternatives() + .try(engine.joi.arkBlockId(), engine.joi.number().unsafe()), + type: engine.joi.number().valid(TRANSACTION_TYPES.TRANSFER), + timestamp: engine.joi + .number() + .integer() + .min(0) + .required(), + amount: engine.joi.alternatives().try( + engine.joi.bignumber(), + engine.joi + .number() + .integer() + .positive() + .required(), + ), + fee: engine.joi.alternatives().try( + engine.joi.bignumber(), + engine.joi + .number() + .integer() + .positive() + .required(), + ), + senderId: engine.joi.arkAddress(), + recipientId: engine.joi.arkAddress().required(), + senderPublicKey: engine.joi.arkPublicKey().required(), + signature: engine.joi + .string() + .alphanum() + .required(), + signatures: engine.joi.array(), + secondSignature: engine.joi.string().alphanum(), + vendorField: engine.joi.string().max(64, 'utf8'), + confirmations: engine.joi + .number() + .integer() + .min(0), + }), + { + allowUnknown: true, + }, + ) + + return { + data: value, + errors: error ? error.details : null, + passes: !error, + fails: error, + } +} diff --git a/packages/crypto/lib/validation/rules/models/transactions/vote.js b/packages/crypto/lib/validation/rules/models/transactions/vote.js new file mode 100644 index 0000000000..ad28b6a3dc --- /dev/null +++ b/packages/crypto/lib/validation/rules/models/transactions/vote.js @@ -0,0 +1,71 @@ +const { TRANSACTION_TYPES } = require('../../../../constants') +const engine = require('../../../engine') + +module.exports = transaction => { + const { error, value } = engine.validate( + transaction, + engine.joi.object({ + id: engine.joi + .string() + .alphanum() + .required(), + blockid: engine.joi + .alternatives() + .try(engine.joi.arkBlockId(), engine.joi.number().unsafe()), + type: engine.joi.number().valid(TRANSACTION_TYPES.VOTE), + timestamp: engine.joi + .number() + .integer() + .min(0) + .required(), + amount: engine.joi + .alternatives() + .try(engine.joi.bignumber(), engine.joi.number().valid(0)), + fee: engine.joi.alternatives().try( + engine.joi.bignumber(), + engine.joi + .number() + .integer() + .positive() + .required(), + ), + senderId: engine.joi.arkAddress(), + recipientId: engine.joi.arkAddress().required(), + senderPublicKey: engine.joi.arkPublicKey().required(), + signature: engine.joi + .string() + .alphanum() + .required(), + signatures: engine.joi.array(), + secondSignature: engine.joi.string().alphanum(), + asset: engine.joi + .object({ + votes: engine.joi + .array() + .items( + engine.joi + .string() + .length(67) + .regex(/^(\+|-)[a-zA-Z0-9]+$/), + ) + .length(1) + .required(), + }) + .required(), + confirmations: engine.joi + .number() + .integer() + .min(0), + }), + { + allowUnknown: true, + }, + ) + + return { + data: value, + errors: error ? error.details : null, + passes: !error, + fails: error, + } +} diff --git a/packages/crypto/lib/validation/rules/public-key.js b/packages/crypto/lib/validation/rules/public-key.js new file mode 100644 index 0000000000..a5522b003c --- /dev/null +++ b/packages/crypto/lib/validation/rules/public-key.js @@ -0,0 +1,15 @@ +const engine = require('../engine') + +module.exports = attributes => { + const { error, value } = engine.validate( + attributes, + engine.joi.arkPublicKey(), + ) + + return { + data: value, + errors: error ? error.details : null, + passes: !error, + fails: error, + } +} diff --git a/packages/validation/lib/rules/username.js b/packages/crypto/lib/validation/rules/username.js similarity index 80% rename from packages/validation/lib/rules/username.js rename to packages/crypto/lib/validation/rules/username.js index ec043262f5..20d8720c4e 100644 --- a/packages/validation/lib/rules/username.js +++ b/packages/crypto/lib/validation/rules/username.js @@ -1,12 +1,12 @@ const engine = require('../engine') -module.exports = (attributes) => { +module.exports = attributes => { const { error, value } = engine.validate(attributes, engine.joi.arkUsername()) return { data: value, errors: error ? error.details : null, passes: !error, - fails: error + fails: error, } } diff --git a/packages/validation/lib/validator.js b/packages/crypto/lib/validation/validator.js similarity index 85% rename from packages/validation/lib/validator.js rename to packages/crypto/lib/validation/validator.js index 8f4a291cd9..4994feb7ba 100644 --- a/packages/validation/lib/validator.js +++ b/packages/crypto/lib/validation/validator.js @@ -4,7 +4,7 @@ class Validator { /** * Create a new validator instance. */ - constructor () { + constructor() { this.rules = require('./rules') this.engine = engine } @@ -13,9 +13,9 @@ class Validator { * Run the validator's rules against its data. * @param {*} attributes * @param {Object} rules - * @return {void} + * @return {void|Boolean} */ - async validate (attributes, rules) { + async validate(attributes, rules) { this.__reset() if (rules instanceof String) { @@ -29,13 +29,15 @@ class Validator { if (rules instanceof Object) { return this.__validateWithJoi(attributes, rules) } + + return false } /** * Determine if the data passes the validation rules. * @return {Boolean} */ - passes () { + passes() { return this.results.passes } @@ -43,7 +45,7 @@ class Validator { * Determine if the data fails the validation rules. * @return {Boolean} */ - fails () { + fails() { return this.results.fails } @@ -51,7 +53,7 @@ class Validator { * Get the validated data. * @return {*} */ - validated () { + validated() { return this.results.data } @@ -59,7 +61,7 @@ class Validator { * Get the validation errors. * @return {Array} */ - errors () { + errors() { return this.results.errors } @@ -67,7 +69,7 @@ class Validator { * Add a new rule to the validator. * @return {void} */ - extend (name, implementation) { + extend(name, implementation) { this.rules[name] = implementation } @@ -77,7 +79,7 @@ class Validator { * @param {String} rule * @return {void} */ - __validateWithRule (attributes, rules) { + __validateWithRule(attributes, rules) { const validate = this.rules[rules] if (!rules) { @@ -93,7 +95,7 @@ class Validator { * @param {String} rule * @return {void} */ - __validateWithFunction (attributes, validate) { + __validateWithFunction(attributes, validate) { this.results = validate(attributes) } @@ -103,21 +105,21 @@ class Validator { * @param {String} rule * @return {void} */ - __validateWithJoi (attributes, rules) { + __validateWithJoi(attributes, rules) { const { error, value } = this.engine.validate(attributes, rules) this.results = { data: value, errors: error ? error.details : null, passes: !error, - fails: error + fails: error, } } /** * Reset any previous results. */ - __reset () { + __reset() { this.results = null } } diff --git a/packages/crypto/lib/validation/validators/transaction.js b/packages/crypto/lib/validation/validators/transaction.js new file mode 100644 index 0000000000..b9a36e5847 --- /dev/null +++ b/packages/crypto/lib/validation/validators/transaction.js @@ -0,0 +1,27 @@ +const engine = require('../engine') +const transactionExtensions = require('../extensions/transactions/index') + +class TransactionValidator { + constructor() { + this.rules = Object.keys(transactionExtensions).reduce((rules, type) => { + rules[type] = transactionExtensions[type](engine.joi).base + return rules + }, {}) + } + + validate(transaction) { + const { value, error } = engine.validate( + transaction, + this.rules[transaction.type], + { allowUnknown: true }, + ) + return { + data: value, + errors: error ? error.details : null, + passes: !error, + fails: error, + } + } +} + +module.exports = new TransactionValidator() diff --git a/packages/crypto/package.json b/packages/crypto/package.json index 065f956ba7..e5a7d29f97 100644 --- a/packages/crypto/package.json +++ b/packages/crypto/package.json @@ -1,13 +1,14 @@ { "name": "@arkecosystem/crypto", - "description": "Crypto utilities for the ARK blockchain", - "version": "0.1.2", + "description": "Crypto utilities for the Ark Blockchain", + "version": "0.2.5", "contributors": [ "François-Xavier Thoorens ", "Brian Faust ", "Alex Barnsley ", "Lúcio Rubens ", - "Juan A. Martín " + "Juan A. Martín ", + "Joshua Noack " ], "license": "MIT", "main": "lib/index.js", @@ -20,36 +21,34 @@ "scripts": { "prepublish": "yarn run lint && yarn run build", "build": "rimraf dist && cross-env NODE_ENV=production webpack --config build/webpack.config.js", - "build:docs": "../../node_modules/.bin/jsdoc -c jsdoc.json", "test": "cross-env ARK_ENV=test jest --runInBand --detectOpenHandles", - "test:coverage": "cross-env ARK_ENV=test jest --coverage --runInBand --detectOpenHandles", - "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand --watch", + "test:coverage": "cross-env ARK_ENV=test jest --coverage --coveragePathIgnorePatterns='/(defaults.js|index.js)$' --runInBand --detectOpenHandles", + "test:debug": "cross-env ARK_ENV=test node --inspect-brk ../../node_modules/.bin/jest --runInBand", "test:watch": "jest --watch", "test:watch:all": "jest --watchAll", - "lint": "eslint -c ../../.eslintrc --ignore-pattern dist ./ --fix", - "depcheck": "depcheck ./" + "lint": "eslint ./ --fix", + "depcheck": "depcheck ./ --ignores=lodash,lodash.*" }, "dependencies": { - "@arkecosystem/validation": "^0.1.1", - "arkjsv1": "arkecosystem/ark-js#master", - "bigi": "^1.4.2", + "bignumber.js": "^8.0.1", + "bip32": "^1.0.2", "bip38": "^2.0.2", - "bip66": "^1.1.5", - "bs58check": "^2.1.1", + "bip39": "^2.5.0", + "bs58check": "^2.1.2", "bytebuffer": "^5.0.1", "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "deepmerge": "^2.1.0", - "ecurve": "^1.0.6", - "lodash": "^4.17.10", - "moment": "^2.22.1", - "node-forge": "^0.7.5", - "otplib": "^9.0.0", - "randombytes": "^2.0.6", - "secp256k1": "^3.5.0", - "tiny-glob": "^0.2.2", - "typeforce": "^1.12.0", - "webpack-merge": "^4.1.3", + "dayjs-ext": "^2.2.0", + "deepmerge": "^2.2.1", + "joi": "^14.3.0", + "lodash.camelcase": "^4.3.0", + "lodash.clonedeepwith": "^4.5.0", + "lodash.get": "^4.4.2", + "node-forge": "^0.7.6", + "otplib": "^10.0.1", + "pluralize": "^7.0.0", + "secp256k1": "^3.5.2", + "tiny-glob": "^0.2.3", + "webpack-merge": "^4.1.4", "webpack-node-externals": "^1.7.2", "wif": "^2.0.6" }, diff --git a/packages/validation/__tests__/rules/models/transactions/delegate-registration.test.js b/packages/validation/__tests__/rules/models/transactions/delegate-registration.test.js deleted file mode 100644 index 9875bd904d..0000000000 --- a/packages/validation/__tests__/rules/models/transactions/delegate-registration.test.js +++ /dev/null @@ -1,95 +0,0 @@ -'use strict' - -const rule = require('../../../../lib/rules/models/transactions/delegate-registration') -const { constants, transactionBuilder } = require('@arkecosystem/crypto') - -let transaction -beforeEach(() => { - transaction = transactionBuilder.delegateRegistration() -}) - -describe('Delegate Registration Transaction Rule', () => { - it('should be a function', () => { - expect(rule).toBeFunction() - }) - - it('should be valid', () => { - transaction.usernameAsset('delegate1') - .sign('passphrase') - - expect(rule(transaction.getStruct()).errors).toBeNull() - }) - - it('should be invalid due to no transaction as object', () => { - expect(rule('test').errors).not.toBeNull() - }) - - it('should be invalid due to non-zero amount', () => { - transaction.usernameAsset('delegate1') - .amount(10 * constants.ARKTOSHI) - .sign('passphrase') - - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to zero fee', () => { - transaction.usernameAsset('delegate1') - .fee(0) - .sign('passphrase') - - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to space in username', () => { - transaction.usernameAsset('test 123') - .sign('passphrase') - - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to non-alphanumeric in username', () => { - transaction.usernameAsset('£££') - .sign('passphrase') - - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to username too long', () => { - transaction.usernameAsset('1234567890123456789012345') - .sign('passphrase') - - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to undefined username', () => { - try { - transaction.usernameAsset(undefined) - .sign('passphrase') - expect(rule(transaction.getStruct()).errors).not.toBeNull() - } catch (error) { - } - }) - - it('should be invalid due to no username', () => { - transaction.usernameAsset('') - .sign('passphrase') - - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to capitals in username', () => { - transaction.usernameAsset('I_AM_INVALID') - .sign('passphrase') - - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to wrong transaction type', () => { - transaction = transactionBuilder.transfer() - transaction.recipientId(null) - .amount(10 * constants.ARKTOSHI) - .sign('passphrase') - - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) -}) diff --git a/packages/validation/__tests__/rules/models/transactions/multi-signature.test.js b/packages/validation/__tests__/rules/models/transactions/multi-signature.test.js deleted file mode 100644 index 64bceae241..0000000000 --- a/packages/validation/__tests__/rules/models/transactions/multi-signature.test.js +++ /dev/null @@ -1,196 +0,0 @@ -'use strict' - -const rule = require('../../../../lib/rules/models/transactions/multi-signature') -const { constants, crypto, transactionBuilder } = require('@arkecosystem/crypto') -const passphrase = 'passphrase 1' -const publicKey = '+03e8021105a6c202097e97e6c6d650942d913099bf6c9f14a6815df1023dde3b87' -const passphrases = [ - passphrase, - 'passphrase 2', - 'passphrase 3' -] -const keysGroup = [ - publicKey, - '+03dfdaaa7fd28bc9359874b7e33138f4d0afe9937e152c59b83a99fae7eeb94899', - '+03de72ef9d3ebf1b374f1214f5b8dde823690ab2aa32b4b8b3226cc568aaed1562' -] - -const signTransaction = (transaction, passphrases) => { - passphrases.map(passphrase => transaction.multiSignatureSign(passphrase)) -} - -let transaction -let multiSignatureAsset -beforeEach(() => { - transaction = transactionBuilder.multiSignature() - multiSignatureAsset = { - min: 1, - keysgroup: keysGroup, - lifetime: 72 - } -}) - -describe('Multi Signature Transaction Rule', () => { - it('should be a function', () => { - expect(rule).toBeFunction() - }) - - it('should be valid with min of 3', () => { - multiSignatureAsset.min = 3 - transaction.multiSignatureAsset(multiSignatureAsset) - .sign('passphrase') - signTransaction(transaction, passphrases) - expect(rule(transaction.getStruct()).errors).toBeNull() - }) - - it('should be valid with 3 public keys', () => { - transaction.multiSignatureAsset(multiSignatureAsset) - .sign('passphrase') - signTransaction(transaction, passphrases) - expect(rule(transaction.getStruct()).errors).toBeNull() - }) - - it('should be valid with lifetime of 10', () => { - multiSignatureAsset.lifetime = 10 - transaction.multiSignatureAsset(multiSignatureAsset) - .sign('passphrase') - signTransaction(transaction, passphrases) - expect(rule(transaction.getStruct()).errors).toBeNull() - }) - - it('should be invalid due to no transaction as object', () => { - expect(rule('test').errors).not.toBeNull() - }) - - it('should be invalid due to non-zero amount', () => { - transaction.multiSignatureAsset(multiSignatureAsset) - .amount(10 * constants.ARKTOSHI) - .sign('passphrase') - signTransaction(transaction, passphrases) - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to zero fee', () => { - transaction.multiSignatureAsset(multiSignatureAsset) - .fee(0) - .sign('passphrase') - signTransaction(transaction, passphrases) - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to min too low', () => { - multiSignatureAsset.min = 0 - transaction.multiSignatureAsset(multiSignatureAsset) - .sign('passphrase') - signTransaction(transaction, passphrases) - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to min too high', () => { - multiSignatureAsset.min = multiSignatureAsset.keysgroup.length + 1 - transaction.multiSignatureAsset(multiSignatureAsset) - .sign('passphrase') - signTransaction(transaction, passphrases) - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to lifetime too low', () => { - multiSignatureAsset.lifetime = 0 - transaction.multiSignatureAsset(multiSignatureAsset) - .sign('passphrase') - signTransaction(transaction, passphrases) - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to lifetime too high', () => { - multiSignatureAsset.lifetime = 100 - transaction.multiSignatureAsset(multiSignatureAsset) - .sign('passphrase') - signTransaction(transaction, passphrases) - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to no public keys', () => { - multiSignatureAsset.keysgroup = [] - transaction.multiSignatureAsset(multiSignatureAsset) - .sign('passphrase') - signTransaction(transaction, passphrases) - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to too many public keys', () => { - const passphrases = [] - multiSignatureAsset.keysgroup = [] - for (let i = 0; i < 20; i++) { - const passphrase = `passphrase ${i}` - passphrases.push(passphrase) - multiSignatureAsset.keysgroup.push(crypto.getKeys(passphrase).publicKey) - } - transaction.multiSignatureAsset(multiSignatureAsset) - .sign('passphrase') - signTransaction(transaction, passphrases) - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to duplicate public keys', () => { - multiSignatureAsset.keysgroup = [publicKey, publicKey] - transaction.multiSignatureAsset(multiSignatureAsset) - .sign('passphrase') - signTransaction(transaction, passphrases) - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to no signatures', () => { - transaction.multiSignatureAsset(multiSignatureAsset) - .sign('passphrase') - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to not enough signatures', () => { - transaction.multiSignatureAsset(multiSignatureAsset) - .sign('passphrase') - signTransaction(transaction, passphrases.slice(1)) - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to too many signatures', () => { - transaction.multiSignatureAsset(multiSignatureAsset) - .sign('passphrase') - signTransaction(transaction, ['wrong passphrase', ...passphrases]) - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to no "+" for publicKeys', () => { - multiSignatureAsset.keysgroup = keysGroup.map(publicKey => publicKey.slice(1)) - transaction.multiSignatureAsset(multiSignatureAsset) - .sign('passphrase') - signTransaction(transaction, passphrases) - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to having "-" for publicKeys', () => { - multiSignatureAsset.keysgroup = keysGroup.map(publicKey => `-${publicKey.slice(1)}`) - transaction.multiSignatureAsset(multiSignatureAsset) - .sign('passphrase') - signTransaction(transaction, passphrases) - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to wrong keysgroup type', () => { - try { - multiSignatureAsset.keysgroup = publicKey - transaction.multiSignatureAsset(publicKey) - .sign('passphrase') - signTransaction(transaction, passphrases) - expect(rule(transaction.getStruct()).errors).not.toBeNull() - } catch (error) { - } - }) - - it('should be invalid due to wrong transaction type', () => { - transaction = transactionBuilder.delegateRegistration() - transaction.usernameAsset('delegate_name') - .sign('passphrase') - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) -}) diff --git a/packages/validation/__tests__/rules/models/transactions/second-signature.test.js b/packages/validation/__tests__/rules/models/transactions/second-signature.test.js deleted file mode 100644 index 20d4c47dd3..0000000000 --- a/packages/validation/__tests__/rules/models/transactions/second-signature.test.js +++ /dev/null @@ -1,63 +0,0 @@ -'use strict' - -const rule = require('../../../../lib/rules/models/transactions/second-signature') -const { constants, transactionBuilder } = require('@arkecosystem/crypto') - -let transaction -beforeEach(() => { - transaction = transactionBuilder.secondSignature() -}) - -// NOTE some tests aren't strictly about the second signature - -describe('Second Signature Transaction Rule', () => { - it('should be a function', () => { - expect(rule).toBeFunction() - }) - - it('should be valid', () => { - transaction.signatureAsset('second passphrase') - .sign('passphrase') - expect(rule(transaction.getStruct()).errors).toBeNull() - }) - - it('should be valid with correct data', () => { - transaction.signatureAsset('second passphrase') - .fee(1 * constants.ARKTOSHI) - .sign('passphrase') - expect(rule(transaction.getStruct()).errors).toBeNull() - }) - - it('should be invalid due to no transaction as object', () => { - expect(rule('test').errors).not.toBeNull() - }) - - it('should be invalid due to non-zero amount', () => { - transaction.signatureAsset('second passphrase') - .amount(10 * constants.ARKTOSHI) - .sign('passphrase') - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to zero fee', () => { - transaction.signatureAsset('second passphrase') - .fee(0) - .sign('passphrase') - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to second signature', () => { - transaction.signatureAsset('second passphrase') - .fee(0) - .sign('passphrase') - .secondSign('second passphrase') - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to wrong transaction type', () => { - transaction = transactionBuilder.delegateRegistration() - transaction.usernameAsset('delegate_name') - .sign('passphrase') - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) -}) diff --git a/packages/validation/__tests__/rules/models/transactions/transfer.test.js b/packages/validation/__tests__/rules/models/transactions/transfer.test.js deleted file mode 100644 index 0d19575f70..0000000000 --- a/packages/validation/__tests__/rules/models/transactions/transfer.test.js +++ /dev/null @@ -1,76 +0,0 @@ -'use strict' - -const rule = require('../../../../lib/rules/models/transactions/transfer') -const { constants, transactionBuilder } = require('@arkecosystem/crypto') -const address = 'APnDzjtDb1FthuqcLMeL5XMWb1uD1KeMGi' -const fee = 1 * constants.ARKTOSHI -const amount = 10 * constants.ARKTOSHI - -let transaction -beforeEach(() => { - transaction = transactionBuilder.transfer() -}) - -describe('Transfer Transaction Rule', () => { - it('should be a function', () => { - expect(rule).toBeFunction() - }) - - it('should be valid', () => { - transaction.recipientId(address) - .amount(amount) - .sign('passphrase') - expect(rule(transaction.getStruct()).errors).toBeNull() - }) - - it('should be valid with correct data', () => { - transaction.recipientId(address) - .amount(amount) - .fee(fee) - .vendorField('Ahoy') - .sign('passphrase') - expect(rule(transaction.getStruct()).errors).toBeNull() - }) - - it('should be invalid due to no transaction as object', () => { - expect(rule('test').errors).not.toBeNull() - }) - - it('should be invalid due to no address', () => { - transaction.recipientId(null) - .amount(amount) - .sign('passphrase') - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to invalid address', () => { - transaction.recipientId(address) - .amount(amount) - .sign('passphrase') - const struct = transaction.getStruct() - struct.recipientId = 'woop' - expect(rule(struct).errors).not.toBeNull() - }) - - it('should be invalid due to zero amount', () => { - transaction.recipientId(address) - .amount(0) - .sign('passphrase') - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to zero fee', () => { - transaction.recipientId(address) - .amount(0) - .fee(0) - .sign('passphrase') - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to wrong transaction type', () => { - transaction = transactionBuilder.delegateRegistration() - transaction.usernameAsset('delegate_name') - .sign('passphrase') - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) -}) diff --git a/packages/validation/__tests__/rules/models/transactions/votes.test.js b/packages/validation/__tests__/rules/models/transactions/votes.test.js deleted file mode 100644 index 1942428f56..0000000000 --- a/packages/validation/__tests__/rules/models/transactions/votes.test.js +++ /dev/null @@ -1,99 +0,0 @@ -'use strict' - -const rule = require('../../../../lib/rules/models/transactions/vote') -const { constants, transactionBuilder } = require('@arkecosystem/crypto') -const vote = '+02bcfa0951a92e7876db1fb71996a853b57f996972ed059a950d910f7d541706c9' -const unvote = '-0326580718fc86ba609799ac95fcd2721af259beb5afa81bfce0ab7d9fe95de991' -const votes = [ - vote, - '+0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0', - unvote -] -const invalidVotes = [ - '02bcfa0951a92e7876db1fb71996a853b57f996972ed059a950d910f7d541706c9', - '0310ad026647eed112d1a46145eed58b8c19c67c505a67f1199361a511ce7860c0', - '0326580718fc86ba609799ac95fcd2721af259beb5afa81bfce0ab7d9fe95de991' -] - -let transaction -beforeEach(() => { - transaction = transactionBuilder.vote() -}) - -describe('Vote Transaction Rule', () => { - it('should be a function', () => { - expect(rule).toBeFunction() - }) - - it('should be valid with 1 vote', () => { - transaction.votesAsset([vote]) - - .sign('passphrase') - expect(rule(transaction.getStruct()).errors).toBeNull() - }) - - it('should be valid with 1 unvote', () => { - transaction.votesAsset([unvote]) - .sign('passphrase') - - expect(rule(transaction.getStruct()).errors).toBeNull() - }) - - it('should be invalid due to no transaction as object', () => { - expect(rule('test').errors).not.toBeNull() - }) - - it('should be invalid due to non-zero amount', () => { - transaction.votesAsset(votes) - .amount(10 * constants.ARKTOSHI) - .sign('passphrase') - - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to zero fee', () => { - transaction.votesAsset(votes) - .fee(0) - .sign('passphrase') - - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to no votes', () => { - transaction.votesAsset([]) - .sign('passphrase') - - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to more than 1 vote', () => { - transaction.votesAsset(votes) - .sign('passphrase') - - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to invalid votes', () => { - transaction.votesAsset(invalidVotes) - .sign('passphrase') - - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) - - it('should be invalid due to wrong vote type', () => { - try { - transaction.votesAsset(vote) - .sign('passphrase') - expect(rule(transaction.getStruct()).errors).not.toBeNull() - } catch (error) { - } - }) - - it('should be invalid due to wrong transaction type', () => { - transaction = transactionBuilder.delegateRegistration() - transaction.usernameAsset('delegate_name') - .sign('passphrase') - - expect(rule(transaction.getStruct()).errors).not.toBeNull() - }) -}) diff --git a/packages/validation/__tests__/rules/public-key.test.js b/packages/validation/__tests__/rules/public-key.test.js deleted file mode 100644 index 28b768cf5b..0000000000 --- a/packages/validation/__tests__/rules/public-key.test.js +++ /dev/null @@ -1,17 +0,0 @@ -'use strict' - -const rule = require('../../lib/rules/public-key') - -describe('Public Key Rule', () => { - it('should be a function', () => { - expect(rule).toBeFunction() - }) - - it('should be truthy', () => { - expect(rule('022cca9529ec97a772156c152a00aad155ee6708243e65c9d211a589cb5d43234d').passes).toBeTruthy() - }) - - it('should be falsy', () => { - expect(rule('_022cca9529ec97a772156c152a00aad155ee6708243e65c9d211a589cb5d43234d_').passes).toBeFalsy() - }) -}) diff --git a/packages/validation/__tests__/rules/username.test.js b/packages/validation/__tests__/rules/username.test.js deleted file mode 100644 index 5ef3ebfff4..0000000000 --- a/packages/validation/__tests__/rules/username.test.js +++ /dev/null @@ -1,17 +0,0 @@ -'use strict' - -const rule = require('../../lib/rules/username') - -describe('Username Rule', () => { - it('should be a function', () => { - expect(rule).toBeFunction() - }) - - it('should be truthy', () => { - expect(rule('boldninja').passes).toBeTruthy() - }) - - it('should be falsy', () => { - expect(rule('bold ninja').passes).toBeFalsy() - }) -}) diff --git a/packages/validation/banner.png b/packages/validation/banner.png deleted file mode 100644 index 6dbab99298..0000000000 Binary files a/packages/validation/banner.png and /dev/null differ diff --git a/packages/validation/jest.config.js b/packages/validation/jest.config.js deleted file mode 100644 index 26f7a25796..0000000000 --- a/packages/validation/jest.config.js +++ /dev/null @@ -1,22 +0,0 @@ -'use strict' - -module.exports = { - testEnvironment: 'node', - bail: false, - verbose: true, - testMatch: [ - '**/__tests__/**/*.test.js' - ], - moduleFileExtensions: [ - 'js', - 'json' - ], - collectCoverage: false, - coverageDirectory: '/.coverage', - collectCoverageFrom: [ - 'lib/**/*.js', - '!**/node_modules/**' - ], - watchman: false, - setupTestFrameworkScriptFile: 'jest-extended' -} diff --git a/packages/validation/lib/constants.js b/packages/validation/lib/constants.js deleted file mode 100644 index cf480ef22f..0000000000 --- a/packages/validation/lib/constants.js +++ /dev/null @@ -1,11 +0,0 @@ -exports.TRANSACTION_TYPES = Object.freeze({ - TRANSFER: 0, - SECOND_SIGNATURE: 1, - DELEGATE_REGISTRATION: 2, - VOTE: 3, - MULTI_SIGNATURE: 4, - IPFS: 5, - TIMELOCK_TRANSFER: 6, - MULTI_PAYMENT: 7, - DELEGATE_RESIGNATION: 8 -}) diff --git a/packages/validation/lib/engine.js b/packages/validation/lib/engine.js deleted file mode 100644 index 07b4d4f943..0000000000 --- a/packages/validation/lib/engine.js +++ /dev/null @@ -1,16 +0,0 @@ -const Joi = require('joi') -const extensions = require('./extensions') - -class Engine { - constructor () { - this.joi = Joi.extend(extensions) - } - - validate (attributes, rules, options) { - return this.joi.validate(attributes, rules, Object.assign({ - convert: true - }, options)) - } -} - -module.exports = new Engine() diff --git a/packages/validation/lib/extensions/address.js b/packages/validation/lib/extensions/address.js deleted file mode 100644 index 747a2c5458..0000000000 --- a/packages/validation/lib/extensions/address.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = (joi) => ({ - name: 'arkAddress', - base: joi.string().alphanum().length(34) -}) diff --git a/packages/validation/lib/extensions/index.js b/packages/validation/lib/extensions/index.js deleted file mode 100644 index d7db84df26..0000000000 --- a/packages/validation/lib/extensions/index.js +++ /dev/null @@ -1,5 +0,0 @@ -module.exports = [ - require('./address'), - require('./public-key'), - require('./username') -] diff --git a/packages/validation/lib/extensions/public-key.js b/packages/validation/lib/extensions/public-key.js deleted file mode 100644 index 67f660e762..0000000000 --- a/packages/validation/lib/extensions/public-key.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = (joi) => ({ - name: 'arkPublicKey', - base: joi.string().hex().length(66) -}) diff --git a/packages/validation/lib/extensions/username.js b/packages/validation/lib/extensions/username.js deleted file mode 100644 index f953feaf5f..0000000000 --- a/packages/validation/lib/extensions/username.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = (joi) => ({ - name: 'arkUsername', - base: joi.string().regex(/^[a-z0-9!@$&_.]+$/).min(1).max(20) -}) diff --git a/packages/validation/lib/index.js b/packages/validation/lib/index.js deleted file mode 100644 index 8d36ba8790..0000000000 --- a/packages/validation/lib/index.js +++ /dev/null @@ -1,6 +0,0 @@ -'use strict' - -module.exports = { - validator: require('./validator'), - transactionValidator: require('./validators/transaction') -} diff --git a/packages/validation/lib/rules/models/transactions.js b/packages/validation/lib/rules/models/transactions.js deleted file mode 100644 index 3f7a847703..0000000000 --- a/packages/validation/lib/rules/models/transactions.js +++ /dev/null @@ -1,6 +0,0 @@ -'use strict' - -exports.transfer = require('./transactions/transfer') -exports.signature = require('./transactions/signature') -exports.delegate = require('./transactions/delegate') -exports.vote = require('./transactions/vote') diff --git a/packages/validation/lib/rules/models/transactions/delegate-registration.js b/packages/validation/lib/rules/models/transactions/delegate-registration.js deleted file mode 100644 index 191699863a..0000000000 --- a/packages/validation/lib/rules/models/transactions/delegate-registration.js +++ /dev/null @@ -1,35 +0,0 @@ -const { TRANSACTION_TYPES } = require('../../../constants') -const engine = require('../../../engine') - -module.exports = (transaction) => { - const { error, value } = engine.validate(transaction, engine.joi.object({ - id: engine.joi.string().alphanum().required(), - blockid: engine.joi.number(), - type: engine.joi.number().valid(TRANSACTION_TYPES.DELEGATE_REGISTRATION), - timestamp: engine.joi.number().min(0).required(), - amount: engine.joi.number().valid(0).required(), - fee: engine.joi.number().min(1).required(), - senderId: engine.joi.arkAddress(), - recipientId: engine.joi.empty(), - senderPublicKey: engine.joi.arkPublicKey().required(), - signature: engine.joi.string().alphanum().required(), - signatures: engine.joi.array(), - secondSignature: engine.joi.string().alphanum(), - asset: engine.joi.object({ - delegate: engine.joi.object({ - username: engine.joi.arkUsername().required(), - publicKey: engine.joi.arkPublicKey() - }).required() - }).required(), - confirmations: engine.joi.number().min(0) - }), { - allowUnknown: true - }) - - return { - data: value, - errors: error ? error.details : null, - passes: !error, - fails: error - } -} diff --git a/packages/validation/lib/rules/models/transactions/delegate-resignation.js b/packages/validation/lib/rules/models/transactions/delegate-resignation.js deleted file mode 100644 index c49880454b..0000000000 --- a/packages/validation/lib/rules/models/transactions/delegate-resignation.js +++ /dev/null @@ -1,29 +0,0 @@ -const { TRANSACTION_TYPES } = require('../../../constants') -const engine = require('../../../engine') - -module.exports = (transaction) => { - const { error, value } = engine.validate(transaction, engine.joi.object({ - id: engine.joi.string().alphanum().required(), - blockid: engine.joi.number(), - type: engine.joi.number().valid(TRANSACTION_TYPES.DELEGATE_RESIGNATION), - timestamp: engine.joi.number().min(0).required(), - amount: engine.joi.number().required(), - fee: engine.joi.number().required(), - senderId: engine.joi.arkAddress(), - senderPublicKey: engine.joi.arkPublicKey().required(), - signature: engine.joi.string().alphanum().required(), - signatures: engine.joi.array(), - secondSignature: engine.joi.string().alphanum(), - asset: engine.joi.object().required(), - confirmations: engine.joi.number().min(0) - }), { - allowUnknown: true - }) - - return { - data: value, - errors: error ? error.details : null, - passes: !error, - fails: error - } -} diff --git a/packages/validation/lib/rules/models/transactions/ipfs.js b/packages/validation/lib/rules/models/transactions/ipfs.js deleted file mode 100644 index ca5f9fd086..0000000000 --- a/packages/validation/lib/rules/models/transactions/ipfs.js +++ /dev/null @@ -1,29 +0,0 @@ -const { TRANSACTION_TYPES } = require('../../../constants') -const engine = require('../../../engine') - -module.exports = (transaction) => { - const { error, value } = engine.validate(transaction, engine.joi.object({ - id: engine.joi.string().alphanum().required(), - blockid: engine.joi.number(), - type: engine.joi.number().valid(TRANSACTION_TYPES.IPFS), - timestamp: engine.joi.number().min(0).required(), - amount: engine.joi.number().required(), - fee: engine.joi.number().required(), - senderId: engine.joi.arkAddress(), - senderPublicKey: engine.joi.arkPublicKey().required(), - signature: engine.joi.string().alphanum().required(), - signatures: engine.joi.array(), - secondSignature: engine.joi.string().alphanum(), - asset: engine.joi.object().required(), - confirmations: engine.joi.number().min(0) - }), { - allowUnknown: true - }) - - return { - data: value, - errors: error ? error.details : null, - passes: !error, - fails: error - } -} diff --git a/packages/validation/lib/rules/models/transactions/multi-payment.js b/packages/validation/lib/rules/models/transactions/multi-payment.js deleted file mode 100644 index 7197d71e62..0000000000 --- a/packages/validation/lib/rules/models/transactions/multi-payment.js +++ /dev/null @@ -1,29 +0,0 @@ -const { TRANSACTION_TYPES } = require('../../../constants') -const engine = require('../../../engine') - -module.exports = (transaction) => { - const { error, value } = engine.validate(transaction, engine.joi.object({ - id: engine.joi.string().alphanum().required(), - blockid: engine.joi.number(), - type: engine.joi.number().valid(TRANSACTION_TYPES.MULTI_PAYMENT), - timestamp: engine.joi.number().min(0).required(), - amount: engine.joi.number().required(), - fee: engine.joi.number().required(), - senderId: engine.joi.arkAddress(), - senderPublicKey: engine.joi.arkPublicKey().required(), - signature: engine.joi.string().alphanum().required(), - signatures: engine.joi.array(), - secondSignature: engine.joi.string().alphanum(), - asset: engine.joi.object().required(), - confirmations: engine.joi.number().min(0) - }), { - allowUnknown: true - }) - - return { - data: value, - errors: error ? error.details : null, - passes: !error, - fails: error - } -} diff --git a/packages/validation/lib/rules/models/transactions/multi-signature.js b/packages/validation/lib/rules/models/transactions/multi-signature.js deleted file mode 100644 index 244b121260..0000000000 --- a/packages/validation/lib/rules/models/transactions/multi-signature.js +++ /dev/null @@ -1,44 +0,0 @@ -const { TRANSACTION_TYPES } = require('../../../constants') -const engine = require('../../../engine') - -module.exports = (transaction) => { - let maxMinValue = 16 - let signaturesLength = 2 - if (transaction.asset && transaction.asset.multisignature && Array.isArray(transaction.asset.multisignature.keysgroup)) { - maxMinValue = transaction.asset.multisignature.keysgroup.length - signaturesLength = maxMinValue - } - const { error, value } = engine.validate(transaction, engine.joi.object({ - id: engine.joi.string().alphanum().required(), - blockid: engine.joi.number(), - type: engine.joi.number().valid(TRANSACTION_TYPES.MULTI_SIGNATURE), - timestamp: engine.joi.number().min(0).required(), - amount: engine.joi.number().valid(0), - fee: engine.joi.number().min(1).required(), - senderId: engine.joi.arkAddress(), - recipientId: engine.joi.empty(), - senderPublicKey: engine.joi.arkPublicKey().required(), - signature: engine.joi.string().alphanum().required(), - signatures: engine.joi.array().length(signaturesLength).required(), - secondSignature: engine.joi.string().alphanum(), - asset: engine.joi.object({ - multisignature: engine.joi.object({ - min: engine.joi.number().min(1).max(Math.min(maxMinValue, 16)).required(), - keysgroup: engine.joi.array().unique().min(2).items( - engine.joi.string().not(`+${transaction.senderPublicKey}`).length(67).regex(/^\+/).required() - ).required(), - lifetime: engine.joi.number().min(1).max(72).required() - }).required() - }).required(), - confirmations: engine.joi.number().min(0) - }), { - allowUnknown: true - }) - - return { - data: value, - errors: error ? error.details : null, - passes: !error, - fails: error - } -} diff --git a/packages/validation/lib/rules/models/transactions/second-signature.js b/packages/validation/lib/rules/models/transactions/second-signature.js deleted file mode 100644 index 392fa59e11..0000000000 --- a/packages/validation/lib/rules/models/transactions/second-signature.js +++ /dev/null @@ -1,33 +0,0 @@ -const { TRANSACTION_TYPES } = require('../../../constants') -const engine = require('../../../engine') - -module.exports = (transaction) => { - const { error, value } = engine.validate(transaction, engine.joi.object({ - id: engine.joi.string().alphanum().required(), - blockid: engine.joi.number(), - type: engine.joi.number().valid(TRANSACTION_TYPES.SECOND_SIGNATURE), - timestamp: engine.joi.number().min(0).required(), - amount: engine.joi.number().valid(0), - fee: engine.joi.number().min(1).required(), - senderId: engine.joi.arkAddress(), - senderPublicKey: engine.joi.arkPublicKey().required(), - signature: engine.joi.string().alphanum().required(), - signatures: engine.joi.array(), - secondSignature: engine.joi.empty(), - asset: engine.joi.object({ - signature: engine.joi.object({ - publicKey: engine.joi.arkPublicKey().required() - }).required() - }).required(), - confirmations: engine.joi.number().min(0) - }), { - allowUnknown: true - }) - - return { - data: value, - errors: error ? error.details : null, - passes: !error, - fails: error - } -} diff --git a/packages/validation/lib/rules/models/transactions/timelock-transfer.js b/packages/validation/lib/rules/models/transactions/timelock-transfer.js deleted file mode 100644 index 445bb685ea..0000000000 --- a/packages/validation/lib/rules/models/transactions/timelock-transfer.js +++ /dev/null @@ -1,29 +0,0 @@ -const { TRANSACTION_TYPES } = require('../../../constants') -const engine = require('../../../engine') - -module.exports = (transaction) => { - const { error, value } = engine.validate(transaction, engine.joi.object({ - id: engine.joi.string().alphanum().required(), - blockid: engine.joi.number(), - type: engine.joi.number().valid(TRANSACTION_TYPES.TIMELOCK_TRANSFER), - timestamp: engine.joi.number().min(0).required(), - amount: engine.joi.number().required(), - fee: engine.joi.number().required(), - senderId: engine.joi.arkAddress(), - senderPublicKey: engine.joi.arkPublicKey().required(), - signature: engine.joi.string().alphanum().required(), - signatures: engine.joi.array(), - secondSignature: engine.joi.string().alphanum(), - asset: engine.joi.object().required(), - confirmations: engine.joi.number().min(0) - }), { - allowUnknown: true - }) - - return { - data: value, - errors: error ? error.details : null, - passes: !error, - fails: error - } -} diff --git a/packages/validation/lib/rules/models/transactions/transfer.js b/packages/validation/lib/rules/models/transactions/transfer.js deleted file mode 100644 index 0948a78143..0000000000 --- a/packages/validation/lib/rules/models/transactions/transfer.js +++ /dev/null @@ -1,29 +0,0 @@ -const { TRANSACTION_TYPES } = require('../../../constants') -const engine = require('../../../engine') - -module.exports = (transaction) => { - const { error, value } = engine.validate(transaction, engine.joi.object({ - id: engine.joi.string().alphanum().required(), - blockid: engine.joi.number(), - type: engine.joi.number().valid(TRANSACTION_TYPES.TRANSFER), - timestamp: engine.joi.number().min(0).required(), - amount: engine.joi.number().min(1).required(), - fee: engine.joi.number().min(1).required(), - senderId: engine.joi.arkAddress(), - recipientId: engine.joi.arkAddress().required(), - senderPublicKey: engine.joi.arkPublicKey().required(), - signature: engine.joi.string().alphanum().required(), - signatures: engine.joi.array(), - secondSignature: engine.joi.string().alphanum(), - confirmations: engine.joi.number().min(0) - }), { - allowUnknown: true - }) - - return { - data: value, - errors: error ? error.details : null, - passes: !error, - fails: error - } -} diff --git a/packages/validation/lib/rules/models/transactions/vote.js b/packages/validation/lib/rules/models/transactions/vote.js deleted file mode 100644 index 7de66ff8da..0000000000 --- a/packages/validation/lib/rules/models/transactions/vote.js +++ /dev/null @@ -1,34 +0,0 @@ -const { TRANSACTION_TYPES } = require('../../../constants') -const engine = require('../../../engine') - -module.exports = (transaction) => { - const { error, value } = engine.validate(transaction, engine.joi.object({ - id: engine.joi.string().alphanum().required(), - blockid: engine.joi.number(), - type: engine.joi.number().valid(TRANSACTION_TYPES.VOTE), - timestamp: engine.joi.number().min(0).required(), - amount: engine.joi.number().valid(0), - fee: engine.joi.number().min(1).required(), - senderId: engine.joi.arkAddress(), - recipientId: engine.joi.arkAddress().required(), - senderPublicKey: engine.joi.arkPublicKey().required(), - signature: engine.joi.string().alphanum().required(), - signatures: engine.joi.array(), - secondSignature: engine.joi.string().alphanum(), - asset: engine.joi.object({ - votes: engine.joi.array().items( - engine.joi.string().length(67).regex(/^(\+|-)[a-zA-Z0-9]+$/) - ).length(1).required() - }).required(), - confirmations: engine.joi.number().min(0) - }), { - allowUnknown: true - }) - - return { - data: value, - errors: error ? error.details : null, - passes: !error, - fails: error - } -} diff --git a/packages/validation/lib/rules/public-key.js b/packages/validation/lib/rules/public-key.js deleted file mode 100644 index 55e23ad09e..0000000000 --- a/packages/validation/lib/rules/public-key.js +++ /dev/null @@ -1,12 +0,0 @@ -const engine = require('../engine') - -module.exports = (attributes) => { - const { error, value } = engine.validate(attributes, engine.joi.arkPublicKey()) - - return { - data: value, - errors: error ? error.details : null, - passes: !error, - fails: error - } -} diff --git a/packages/validation/lib/validators/transaction.js b/packages/validation/lib/validators/transaction.js deleted file mode 100644 index fd9bf416a6..0000000000 --- a/packages/validation/lib/validators/transaction.js +++ /dev/null @@ -1,25 +0,0 @@ -'use strict' - -const { TRANSACTION_TYPES } = require('../constants') - -class TransactionValidator { - constructor () { - this.rules = { - [TRANSACTION_TYPES.TRANSFER]: require('../rules/models/transactions/transfer'), - [TRANSACTION_TYPES.SECOND_SIGNATURE]: require('../rules/models/transactions/second-signature'), - [TRANSACTION_TYPES.DELEGATE_REGISTRATION]: require('../rules/models/transactions/delegate-registration'), - [TRANSACTION_TYPES.VOTE]: require('../rules/models/transactions/vote'), - [TRANSACTION_TYPES.MULTI_SIGNATURE]: require('../rules/models/transactions/multi-signature'), - [TRANSACTION_TYPES.IPFS]: require('../rules/models/transactions/ipfs'), - [TRANSACTION_TYPES.TIMELOCK_TRANSFER]: require('../rules/models/transactions/timelock-transfer'), - [TRANSACTION_TYPES.MULTI_PAYMENT]: require('../rules/models/transactions/multi-payment'), - [TRANSACTION_TYPES.DELEGATE_RESIGNATION]: require('../rules/models/transactions/delegate-resignation') - } - } - - validate (transaction) { - return this.rules[transaction.type](transaction) - } -} - -module.exports = new TransactionValidator() diff --git a/scripts/pre-commit.sh b/scripts/pre-commit.sh new file mode 100755 index 0000000000..d901b9a3ea --- /dev/null +++ b/scripts/pre-commit.sh @@ -0,0 +1,6 @@ +echo "Running pre-commit script..." + +node .circleci/generateConfig.js +git add .circleci/config.yml + +echo "pre-commit script was run succesfully" diff --git a/scripts/update-deps.sh b/scripts/update-deps.sh new file mode 100644 index 0000000000..450b50548e --- /dev/null +++ b/scripts/update-deps.sh @@ -0,0 +1,8 @@ +# NOTE: run this from the root directory as "bash scripts/update-deps.sh" +./node_modules/npm-check-updates/bin/ncu -a + +for dir in `ls ./packages`; do + cd "./packages/$dir" + ../../node_modules/npm-check-updates/bin/ncu -a + cd ../.. +done diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000000..bc624e1b32 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,13053 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@apollographql/apollo-tools@^0.2.6": + version "0.2.8" + resolved "https://registry.yarnpkg.com/@apollographql/apollo-tools/-/apollo-tools-0.2.8.tgz#f755baa3576eabdd93afa2782be61f5ae8a856dc" + integrity sha512-A7FTUigtpGCFBaLT1ILicdjM6pZ7LQNw7Vgos0t4aLYtvlKO/L1nMi/NO7bPypzZaJSToTgcxHJPRydP1Md+Kw== + dependencies: + apollo-env "0.2.5" + +"@apollographql/apollo-upload-server@^5.0.3": + version "5.0.3" + resolved "https://registry.yarnpkg.com/@apollographql/apollo-upload-server/-/apollo-upload-server-5.0.3.tgz#8558c378ff6457de82147e5072c96a6b242773b7" + integrity sha512-tGAp3ULNyoA8b5o9LsU2Lq6SwgVPUOKAqKywu2liEtTvrFSGPrObwanhYwArq3GPeOqp2bi+JknSJCIU3oQN1Q== + dependencies: + "@babel/runtime-corejs2" "^7.0.0-rc.1" + busboy "^0.2.14" + object-path "^0.11.4" + +"@apollographql/graphql-playground-html@^1.6.6": + version "1.6.6" + resolved "https://registry.yarnpkg.com/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.6.tgz#022209e28a2b547dcde15b219f0c50f47aa5beb3" + integrity sha512-lqK94b+caNtmKFs5oUVXlSpN3sm5IXZ+KfhMxOtr0LR2SqErzkoJilitjDvJ1WbjHlxLI7WtCjRmOLdOGJqtMQ== + +"@arkecosystem/eslint-config-base@^0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@arkecosystem/eslint-config-base/-/eslint-config-base-0.1.0.tgz#c4e39d1051598b1ecc7f7ce4ca54f577deecaf0c" + integrity sha512-5Fx2xy+gOkwW92ahUACAjv7cHHKtxPS5Sz6Ef5ejbglrkXl/7Wzh+OKDJ1yXS1lkjI0CQr6ooWiSh7nRp4HHqw== + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.0.0-beta.35": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" + integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA== + dependencies: + "@babel/highlight" "^7.0.0" + +"@babel/core@^7.1.6": + version "7.1.6" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.1.6.tgz#3733cbee4317429bc87c62b29cf8587dba7baeb3" + integrity sha512-Hz6PJT6e44iUNpAn8AoyAs6B3bl60g7MJQaI0rZEar6ECzh6+srYO1xlIdssio34mPaUtAb1y+XlkkSJzok3yw== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/generator" "^7.1.6" + "@babel/helpers" "^7.1.5" + "@babel/parser" "^7.1.6" + "@babel/template" "^7.1.2" + "@babel/traverse" "^7.1.6" + "@babel/types" "^7.1.6" + convert-source-map "^1.1.0" + debug "^4.1.0" + json5 "^2.1.0" + lodash "^4.17.10" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + +"@babel/generator@^7.1.6": + version "7.1.6" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.1.6.tgz#001303cf87a5b9d093494a4bf251d7b5d03d3999" + integrity sha512-brwPBtVvdYdGxtenbQgfCdDPmtkmUBZPjUoK5SXJEBuHaA5BCubh9ly65fzXz7R6o5rA76Rs22ES8Z+HCc0YIQ== + dependencies: + "@babel/types" "^7.1.6" + jsesc "^2.5.1" + lodash "^4.17.10" + source-map "^0.5.0" + trim-right "^1.0.1" + +"@babel/helper-annotate-as-pure@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32" + integrity sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz#6b69628dfe4087798e0c4ed98e3d4a6b2fbd2f5f" + integrity sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w== + dependencies: + "@babel/helper-explode-assignable-expression" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-call-delegate@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-call-delegate/-/helper-call-delegate-7.1.0.tgz#6a957f105f37755e8645343d3038a22e1449cc4a" + integrity sha512-YEtYZrw3GUK6emQHKthltKNZwszBcHK58Ygcis+gVUrF4/FmTVr5CCqQNSfmvg2y+YDEANyYoaLz/SHsnusCwQ== + dependencies: + "@babel/helper-hoist-variables" "^7.0.0" + "@babel/traverse" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-define-map@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.1.0.tgz#3b74caec329b3c80c116290887c0dd9ae468c20c" + integrity sha512-yPPcW8dc3gZLN+U1mhYV91QU3n5uTbx7DUdf8NnPbjS0RMwBuHi9Xt2MUgppmNz7CJxTBWsGczTiEp1CSOTPRg== + dependencies: + "@babel/helper-function-name" "^7.1.0" + "@babel/types" "^7.0.0" + lodash "^4.17.10" + +"@babel/helper-explode-assignable-expression@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz#537fa13f6f1674df745b0c00ec8fe4e99681c8f6" + integrity sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA== + dependencies: + "@babel/traverse" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-function-name@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz#a0ceb01685f73355d4360c1247f582bfafc8ff53" + integrity sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw== + dependencies: + "@babel/helper-get-function-arity" "^7.0.0" + "@babel/template" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-get-function-arity@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz#83572d4320e2a4657263734113c42868b64e49c3" + integrity sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-hoist-variables@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.0.0.tgz#46adc4c5e758645ae7a45deb92bab0918c23bb88" + integrity sha512-Ggv5sldXUeSKsuzLkddtyhyHe2YantsxWKNi7A+7LeD12ExRDWTRk29JCXpaHPAbMaIPZSil7n+lq78WY2VY7w== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-member-expression-to-functions@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz#8cd14b0a0df7ff00f009e7d7a436945f47c7a16f" + integrity sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-module-imports@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz#96081b7111e486da4d2cd971ad1a4fe216cc2e3d" + integrity sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-module-transforms@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.1.0.tgz#470d4f9676d9fad50b324cdcce5fbabbc3da5787" + integrity sha512-0JZRd2yhawo79Rcm4w0LwSMILFmFXjugG3yqf+P/UsKsRS1mJCmMwwlHDlMg7Avr9LrvSpp4ZSULO9r8jpCzcw== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-simple-access" "^7.1.0" + "@babel/helper-split-export-declaration" "^7.0.0" + "@babel/template" "^7.1.0" + "@babel/types" "^7.0.0" + lodash "^4.17.10" + +"@babel/helper-optimise-call-expression@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz#a2920c5702b073c15de51106200aa8cad20497d5" + integrity sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-plugin-utils@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250" + integrity sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA== + +"@babel/helper-regex@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.0.0.tgz#2c1718923b57f9bbe64705ffe5640ac64d9bdb27" + integrity sha512-TR0/N0NDCcUIUEbqV6dCO+LptmmSQFQ7q70lfcEB4URsjD0E1HzicrwUH+ap6BAQ2jhCX9Q4UqZy4wilujWlkg== + dependencies: + lodash "^4.17.10" + +"@babel/helper-remap-async-to-generator@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz#361d80821b6f38da75bd3f0785ece20a88c5fe7f" + integrity sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.0.0" + "@babel/helper-wrap-function" "^7.1.0" + "@babel/template" "^7.1.0" + "@babel/traverse" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-replace-supers@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.1.0.tgz#5fc31de522ec0ef0899dc9b3e7cf6a5dd655f362" + integrity sha512-BvcDWYZRWVuDeXTYZWxekQNO5D4kO55aArwZOTFXw6rlLQA8ZaDicJR1sO47h+HrnCiDFiww0fSPV0d713KBGQ== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.0.0" + "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/traverse" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-simple-access@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz#65eeb954c8c245beaa4e859da6188f39d71e585c" + integrity sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w== + dependencies: + "@babel/template" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-split-export-declaration@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz#3aae285c0311c2ab095d997b8c9a94cad547d813" + integrity sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-wrap-function@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.1.0.tgz#8cf54e9190706067f016af8f75cb3df829cc8c66" + integrity sha512-R6HU3dete+rwsdAfrOzTlE9Mcpk4RjU3aX3gi9grtmugQY0u79X7eogUvfXA5sI81Mfq1cn6AgxihfN33STjJA== + dependencies: + "@babel/helper-function-name" "^7.1.0" + "@babel/template" "^7.1.0" + "@babel/traverse" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helpers@^7.1.5": + version "7.1.5" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.1.5.tgz#68bfc1895d685f2b8f1995e788dbfe1f6ccb1996" + integrity sha512-2jkcdL02ywNBry1YNFAH/fViq4fXG0vdckHqeJk+75fpQ2OH+Az6076tX/M0835zA45E0Cqa6pV5Kiv9YOqjEg== + dependencies: + "@babel/template" "^7.1.2" + "@babel/traverse" "^7.1.5" + "@babel/types" "^7.1.5" + +"@babel/highlight@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4" + integrity sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw== + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^4.0.0" + +"@babel/parser@^7.1.2", "@babel/parser@^7.1.6": + version "7.1.6" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.1.6.tgz#16e97aca1ec1062324a01c5a6a7d0df8dd189854" + integrity sha512-dWP6LJm9nKT6ALaa+bnL247GHHMWir3vSlZ2+IHgHgktZQx0L3Uvq2uAWcuzIe+fujRsYWBW2q622C5UvGK9iQ== + +"@babel/plugin-proposal-async-generator-functions@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.1.0.tgz#41c1a702e10081456e23a7b74d891922dd1bb6ce" + integrity sha512-Fq803F3Jcxo20MXUSDdmZZXrPe6BWyGcWBPPNB/M7WaUYESKDeKMOGIxEzQOjGSmW/NWb6UaPZrtTB2ekhB/ew== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-remap-async-to-generator" "^7.1.0" + "@babel/plugin-syntax-async-generators" "^7.0.0" + +"@babel/plugin-proposal-json-strings@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.0.0.tgz#3b4d7b5cf51e1f2e70f52351d28d44fc2970d01e" + integrity sha512-kfVdUkIAGJIVmHmtS/40i/fg/AGnw/rsZBCaapY5yjeO5RA9m165Xbw9KMOu2nqXP5dTFjEjHdfNdoVcHv133Q== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-json-strings" "^7.0.0" + +"@babel/plugin-proposal-object-rest-spread@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.0.0.tgz#9a17b547f64d0676b6c9cecd4edf74a82ab85e7e" + integrity sha512-14fhfoPcNu7itSen7Py1iGN0gEm87hX/B+8nZPqkdmANyyYWYMY2pjA3r8WXbWVKMzfnSNS0xY8GVS0IjXi/iw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-object-rest-spread" "^7.0.0" + +"@babel/plugin-proposal-optional-catch-binding@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.0.0.tgz#b610d928fe551ff7117d42c8bb410eec312a6425" + integrity sha512-JPqAvLG1s13B/AuoBjdBYvn38RqW6n1TzrQO839/sIpqLpbnXKacsAgpZHzLD83Sm8SDXMkkrAvEnJ25+0yIpw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.0.0" + +"@babel/plugin-proposal-unicode-property-regex@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.0.0.tgz#498b39cd72536cd7c4b26177d030226eba08cd33" + integrity sha512-tM3icA6GhC3ch2SkmSxv7J/hCWKISzwycub6eGsDrFDgukD4dZ/I+x81XgW0YslS6mzNuQ1Cbzh5osjIMgepPQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.0.0" + regexpu-core "^4.2.0" + +"@babel/plugin-syntax-async-generators@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.0.0.tgz#bf0891dcdbf59558359d0c626fdc9490e20bc13c" + integrity sha512-im7ged00ddGKAjcZgewXmp1vxSZQQywuQXe2B1A7kajjZmDeY/ekMPmWr9zJgveSaQH0k7BcGrojQhcK06l0zA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-json-strings@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.0.0.tgz#0d259a68090e15b383ce3710e01d5b23f3770cbd" + integrity sha512-UlSfNydC+XLj4bw7ijpldc1uZ/HB84vw+U6BTuqMdIEmz/LDe63w/GHtpQMdXWdqQZFeAI9PjnHe/vDhwirhKA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-object-rest-spread@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.0.0.tgz#37d8fbcaf216bd658ea1aebbeb8b75e88ebc549b" + integrity sha512-5A0n4p6bIiVe5OvQPxBnesezsgFJdHhSs3uFSvaPdMqtsovajLZ+G2vZyvNe10EzJBWWo3AcHGKhAFUxqwp2dw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.0.0.tgz#886f72008b3a8b185977f7cb70713b45e51ee475" + integrity sha512-Wc+HVvwjcq5qBg1w5RG9o9RVzmCaAg/Vp0erHCKpAYV8La6I94o4GQAmFYNmkzoMO6gzoOSulpKeSSz6mPEoZw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-arrow-functions@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.0.0.tgz#a6c14875848c68a3b4b3163a486535ef25c7e749" + integrity sha512-2EZDBl1WIO/q4DIkIp4s86sdp4ZifL51MoIviLY/gG/mLSuOIEg7J8o6mhbxOTvUJkaN50n+8u41FVsr5KLy/w== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-async-to-generator@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.1.0.tgz#109e036496c51dd65857e16acab3bafdf3c57811" + integrity sha512-rNmcmoQ78IrvNCIt/R9U+cixUHeYAzgusTFgIAv+wQb9HJU4szhpDD6e5GCACmj/JP5KxuCwM96bX3L9v4ZN/g== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-remap-async-to-generator" "^7.1.0" + +"@babel/plugin-transform-block-scoped-functions@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.0.0.tgz#482b3f75103927e37288b3b67b65f848e2aa0d07" + integrity sha512-AOBiyUp7vYTqz2Jibe1UaAWL0Hl9JUXEgjFvvvcSc9MVDItv46ViXFw2F7SVt1B5k+KWjl44eeXOAk3UDEaJjQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-block-scoping@^7.1.5": + version "7.1.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.1.5.tgz#3e8e0bc9a5104519923302a24f748f72f2f61f37" + integrity sha512-jlYcDrz+5ayWC7mxgpn1Wj8zj0mmjCT2w0mPIMSwO926eXBRxpEgoN/uQVRBfjtr8ayjcmS+xk2G1jaP8JjMJQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + lodash "^4.17.10" + +"@babel/plugin-transform-classes@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.1.0.tgz#ab3f8a564361800cbc8ab1ca6f21108038432249" + integrity sha512-rNaqoD+4OCBZjM7VaskladgqnZ1LO6o2UxuWSDzljzW21pN1KXkB7BstAVweZdxQkHAujps5QMNOTWesBciKFg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.0.0" + "@babel/helper-define-map" "^7.1.0" + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-optimise-call-expression" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-replace-supers" "^7.1.0" + "@babel/helper-split-export-declaration" "^7.0.0" + globals "^11.1.0" + +"@babel/plugin-transform-computed-properties@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.0.0.tgz#2fbb8900cd3e8258f2a2ede909b90e7556185e31" + integrity sha512-ubouZdChNAv4AAWAgU7QKbB93NU5sHwInEWfp+/OzJKA02E6Woh9RVoX4sZrbRwtybky/d7baTUqwFx+HgbvMA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-destructuring@^7.0.0": + version "7.1.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.1.3.tgz#e69ff50ca01fac6cb72863c544e516c2b193012f" + integrity sha512-Mb9M4DGIOspH1ExHOUnn2UUXFOyVTiX84fXCd+6B5iWrQg/QMeeRmSwpZ9lnjYLSXtZwiw80ytVMr3zue0ucYw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-dotall-regex@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.0.0.tgz#73a24da69bc3c370251f43a3d048198546115e58" + integrity sha512-00THs8eJxOJUFVx1w8i1MBF4XH4PsAjKjQ1eqN/uCH3YKwP21GCKfrn6YZFZswbOk9+0cw1zGQPHVc1KBlSxig== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.0.0" + regexpu-core "^4.1.3" + +"@babel/plugin-transform-duplicate-keys@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.0.0.tgz#a0601e580991e7cace080e4cf919cfd58da74e86" + integrity sha512-w2vfPkMqRkdxx+C71ATLJG30PpwtTpW7DDdLqYt2acXU7YjztzeWW2Jk1T6hKqCLYCcEA5UQM/+xTAm+QCSnuQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-exponentiation-operator@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.1.0.tgz#9c34c2ee7fd77e02779cfa37e403a2e1003ccc73" + integrity sha512-uZt9kD1Pp/JubkukOGQml9tqAeI8NkE98oZnHZ2qHRElmeKCodbTZgOEUtujSCSLhHSBWbzNiFSDIMC4/RBTLQ== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-for-of@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.0.0.tgz#f2ba4eadb83bd17dc3c7e9b30f4707365e1c3e39" + integrity sha512-TlxKecN20X2tt2UEr2LNE6aqA0oPeMT1Y3cgz8k4Dn1j5ObT8M3nl9aA37LLklx0PBZKETC9ZAf9n/6SujTuXA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-function-name@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.1.0.tgz#29c5550d5c46208e7f730516d41eeddd4affadbb" + integrity sha512-VxOa1TMlFMtqPW2IDYZQaHsFrq/dDoIjgN098NowhexhZcz3UGlvPgZXuE1jEvNygyWyxRacqDpCZt+par1FNg== + dependencies: + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-literals@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.0.0.tgz#2aec1d29cdd24c407359c930cdd89e914ee8ff86" + integrity sha512-1NTDBWkeNXgpUcyoVFxbr9hS57EpZYXpje92zv0SUzjdu3enaRwF/l3cmyRnXLtIdyJASyiS6PtybK+CgKf7jA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-modules-amd@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.1.0.tgz#f9e0a7072c12e296079b5a59f408ff5b97bf86a8" + integrity sha512-wt8P+xQ85rrnGNr2x1iV3DW32W8zrB6ctuBkYBbf5/ZzJY99Ob4MFgsZDFgczNU76iy9PWsy4EuxOliDjdKw6A== + dependencies: + "@babel/helper-module-transforms" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-modules-commonjs@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.1.0.tgz#0a9d86451cbbfb29bd15186306897c67f6f9a05c" + integrity sha512-wtNwtMjn1XGwM0AXPspQgvmE6msSJP15CX2RVfpTSTNPLhKhaOjaIfBaVfj4iUZ/VrFSodcFedwtPg/NxwQlPA== + dependencies: + "@babel/helper-module-transforms" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-simple-access" "^7.1.0" + +"@babel/plugin-transform-modules-systemjs@^7.0.0": + version "7.1.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.1.3.tgz#2119a3e3db612fd74a19d88652efbfe9613a5db0" + integrity sha512-PvTxgjxQAq4pvVUZF3mD5gEtVDuId8NtWkJsZLEJZMZAW3TvgQl1pmydLLN1bM8huHFVVU43lf0uvjQj9FRkKw== + dependencies: + "@babel/helper-hoist-variables" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-modules-umd@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.1.0.tgz#a29a7d85d6f28c3561c33964442257cc6a21f2a8" + integrity sha512-enrRtn5TfRhMmbRwm7F8qOj0qEYByqUvTttPEGimcBH4CJHphjyK1Vg7sdU7JjeEmgSpM890IT/efS2nMHwYig== + dependencies: + "@babel/helper-module-transforms" "^7.1.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-new-target@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.0.0.tgz#ae8fbd89517fa7892d20e6564e641e8770c3aa4a" + integrity sha512-yin069FYjah+LbqfGeTfzIBODex/e++Yfa0rH0fpfam9uTbuEeEOx5GLGr210ggOV77mVRNoeqSYqeuaqSzVSw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-object-super@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.1.0.tgz#b1ae194a054b826d8d4ba7ca91486d4ada0f91bb" + integrity sha512-/O02Je1CRTSk2SSJaq0xjwQ8hG4zhZGNjE8psTsSNPXyLRCODv7/PBozqT5AmQMzp7MI3ndvMhGdqp9c96tTEw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-replace-supers" "^7.1.0" + +"@babel/plugin-transform-parameters@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.1.0.tgz#44f492f9d618c9124026e62301c296bf606a7aed" + integrity sha512-vHV7oxkEJ8IHxTfRr3hNGzV446GAb+0hgbA7o/0Jd76s+YzccdWuTU296FOCOl/xweU4t/Ya4g41yWz80RFCRw== + dependencies: + "@babel/helper-call-delegate" "^7.1.0" + "@babel/helper-get-function-arity" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-regenerator@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.0.0.tgz#5b41686b4ed40bef874d7ed6a84bdd849c13e0c1" + integrity sha512-sj2qzsEx8KDVv1QuJc/dEfilkg3RRPvPYx/VnKLtItVQRWt1Wqf5eVCOLZm29CiGFfYYsA3VPjfizTCV0S0Dlw== + dependencies: + regenerator-transform "^0.13.3" + +"@babel/plugin-transform-shorthand-properties@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.0.0.tgz#85f8af592dcc07647541a0350e8c95c7bf419d15" + integrity sha512-g/99LI4vm5iOf5r1Gdxq5Xmu91zvjhEG5+yZDJW268AZELAu4J1EiFLnkSG3yuUsZyOipVOVUKoGPYwfsTymhw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-spread@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.0.0.tgz#93583ce48dd8c85e53f3a46056c856e4af30b49b" + integrity sha512-L702YFy2EvirrR4shTj0g2xQp7aNwZoWNCkNu2mcoU0uyzMl0XRwDSwzB/xp6DSUFiBmEXuyAyEN16LsgVqGGQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-sticky-regex@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.0.0.tgz#30a9d64ac2ab46eec087b8530535becd90e73366" + integrity sha512-LFUToxiyS/WD+XEWpkx/XJBrUXKewSZpzX68s+yEOtIbdnsRjpryDw9U06gYc6klYEij/+KQVRnD3nz3AoKmjw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.0.0" + +"@babel/plugin-transform-template-literals@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.0.0.tgz#084f1952efe5b153ddae69eb8945f882c7a97c65" + integrity sha512-vA6rkTCabRZu7Nbl9DfLZE1imj4tzdWcg5vtdQGvj+OH9itNNB6hxuRMHuIY8SGnEt1T9g5foqs9LnrHzsqEFg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-typeof-symbol@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.0.0.tgz#4dcf1e52e943e5267b7313bff347fdbe0f81cec9" + integrity sha512-1r1X5DO78WnaAIvs5uC48t41LLckxsYklJrZjNKcevyz83sF2l4RHbw29qrCPr/6ksFsdfRpT/ZgxNWHXRnffg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-unicode-regex@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.0.0.tgz#c6780e5b1863a76fe792d90eded9fcd5b51d68fc" + integrity sha512-uJBrJhBOEa3D033P95nPHu3nbFwFE9ZgXsfEitzoIXIwqAZWk7uXcg06yFKXz9FSxBH5ucgU/cYdX0IV8ldHKw== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.0.0" + regexpu-core "^4.1.3" + +"@babel/preset-env@^7.1.6": + version "7.1.6" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.1.6.tgz#a0bf4b96b6bfcf6e000afc5b72b4abe7cc13ae97" + integrity sha512-YIBfpJNQMBkb6MCkjz/A9J76SNCSuGVamOVBgoUkLzpJD/z8ghHi9I42LQ4pulVX68N/MmImz6ZTixt7Azgexw== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-proposal-async-generator-functions" "^7.1.0" + "@babel/plugin-proposal-json-strings" "^7.0.0" + "@babel/plugin-proposal-object-rest-spread" "^7.0.0" + "@babel/plugin-proposal-optional-catch-binding" "^7.0.0" + "@babel/plugin-proposal-unicode-property-regex" "^7.0.0" + "@babel/plugin-syntax-async-generators" "^7.0.0" + "@babel/plugin-syntax-object-rest-spread" "^7.0.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.0.0" + "@babel/plugin-transform-arrow-functions" "^7.0.0" + "@babel/plugin-transform-async-to-generator" "^7.1.0" + "@babel/plugin-transform-block-scoped-functions" "^7.0.0" + "@babel/plugin-transform-block-scoping" "^7.1.5" + "@babel/plugin-transform-classes" "^7.1.0" + "@babel/plugin-transform-computed-properties" "^7.0.0" + "@babel/plugin-transform-destructuring" "^7.0.0" + "@babel/plugin-transform-dotall-regex" "^7.0.0" + "@babel/plugin-transform-duplicate-keys" "^7.0.0" + "@babel/plugin-transform-exponentiation-operator" "^7.1.0" + "@babel/plugin-transform-for-of" "^7.0.0" + "@babel/plugin-transform-function-name" "^7.1.0" + "@babel/plugin-transform-literals" "^7.0.0" + "@babel/plugin-transform-modules-amd" "^7.1.0" + "@babel/plugin-transform-modules-commonjs" "^7.1.0" + "@babel/plugin-transform-modules-systemjs" "^7.0.0" + "@babel/plugin-transform-modules-umd" "^7.1.0" + "@babel/plugin-transform-new-target" "^7.0.0" + "@babel/plugin-transform-object-super" "^7.1.0" + "@babel/plugin-transform-parameters" "^7.1.0" + "@babel/plugin-transform-regenerator" "^7.0.0" + "@babel/plugin-transform-shorthand-properties" "^7.0.0" + "@babel/plugin-transform-spread" "^7.0.0" + "@babel/plugin-transform-sticky-regex" "^7.0.0" + "@babel/plugin-transform-template-literals" "^7.0.0" + "@babel/plugin-transform-typeof-symbol" "^7.0.0" + "@babel/plugin-transform-unicode-regex" "^7.0.0" + browserslist "^4.1.0" + invariant "^2.2.2" + js-levenshtein "^1.1.3" + semver "^5.3.0" + +"@babel/runtime-corejs2@^7.0.0-rc.1": + version "7.1.5" + resolved "https://registry.yarnpkg.com/@babel/runtime-corejs2/-/runtime-corejs2-7.1.5.tgz#ec8341c9aec71d1139c985327314739d66b204a0" + integrity sha512-WsYRwQsFhVmxkAqwypPTZyV9GpkqMEaAr2zOItOmqSX2GBFaI+eq98CN81e13o0zaUKJOQGYyjhNVqj56nnkYg== + dependencies: + core-js "^2.5.7" + regenerator-runtime "^0.12.0" + +"@babel/template@^7.1.0", "@babel/template@^7.1.2": + version "7.1.2" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.1.2.tgz#090484a574fef5a2d2d7726a674eceda5c5b5644" + integrity sha512-SY1MmplssORfFiLDcOETrW7fCLl+PavlwMh92rrGcikQaRq4iWPVH0MpwPpY3etVMx6RnDjXtr6VZYr/IbP/Ag== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.1.2" + "@babel/types" "^7.1.2" + +"@babel/traverse@^7.1.0", "@babel/traverse@^7.1.5", "@babel/traverse@^7.1.6": + version "7.1.6" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.1.6.tgz#c8db9963ab4ce5b894222435482bd8ea854b7b5c" + integrity sha512-CXedit6GpISz3sC2k2FsGCUpOhUqKdyL0lqNrImQojagnUMXf8hex4AxYFRuMkNGcvJX5QAFGzB5WJQmSv8SiQ== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/generator" "^7.1.6" + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-split-export-declaration" "^7.0.0" + "@babel/parser" "^7.1.6" + "@babel/types" "^7.1.6" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.10" + +"@babel/types@^7.0.0", "@babel/types@^7.1.2", "@babel/types@^7.1.5", "@babel/types@^7.1.6": + version "7.1.6" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.1.6.tgz#0adb330c3a281348a190263aceb540e10f04bcce" + integrity sha512-DMiUzlY9DSjVsOylJssxLHSgj6tWM9PRFJOGW/RaOglVOK9nzTxoOMfTfRQXGUCUQ/HmlG2efwC+XqUEJ5ay4w== + dependencies: + esutils "^2.0.2" + lodash "^4.17.10" + to-fast-properties "^2.0.0" + +"@iamstarkov/listr-update-renderer@0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@iamstarkov/listr-update-renderer/-/listr-update-renderer-0.4.1.tgz#d7c48092a2dcf90fd672b6c8b458649cb350c77e" + integrity sha512-IJyxQWsYDEkf8C8QthBn5N8tIUR9V9je6j3sMIpAkonaadjbvxmRC6RAhpa3RKxndhNnU2M6iNbtJwd7usQYIA== + dependencies: + chalk "^1.1.3" + cli-truncate "^0.2.1" + elegant-spinner "^1.0.1" + figures "^1.7.0" + indent-string "^3.0.0" + log-symbols "^1.0.2" + log-update "^2.3.0" + strip-ansi "^3.0.1" + +"@keyv/sql@1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@keyv/sql/-/sql-1.1.2.tgz#1dd84a5c5ad2384df8934f0ddfe20ab81dc2a75d" + integrity sha1-HdhKXFrSOE34k08N3+IKuB3Cp10= + dependencies: + sql "~0.78.0" + +"@keyv/sqlite@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@keyv/sqlite/-/sqlite-2.0.0.tgz#1cd03849e027bc8ba7dd37ab3a89ef38856362d8" + integrity sha512-7rsbZwIFwmxH5N4TCZM1C3ci55jLB4MaFooeAu/yHwBxO/4JuvsS2k0hX7V9rGqsjcfmwFF0qfUzltC45dOZHQ== + dependencies: + "@keyv/sql" "1.1.2" + pify "3.0.0" + sqlite3 "4.0.2" + +"@lerna/add@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@lerna/add/-/add-3.5.0.tgz#3518b3d4afc3743b7227b1ee3534114eb9575888" + integrity sha512-hoOqtal/ChEEtt9rxR/6xmyvTN7581XF4kWHoWPV9NbfZN9e8uTR8z4mCcJq2DiZhRuY7aA5FEROEbl12soowQ== + dependencies: + "@lerna/bootstrap" "^3.5.0" + "@lerna/command" "^3.5.0" + "@lerna/filter-options" "^3.5.0" + "@lerna/npm-conf" "^3.4.1" + "@lerna/validation-error" "^3.0.0" + dedent "^0.7.0" + npm-package-arg "^6.0.0" + p-map "^1.2.0" + pacote "^9.1.0" + semver "^5.5.0" + +"@lerna/batch-packages@^3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@lerna/batch-packages/-/batch-packages-3.1.2.tgz#74b5312a01a8916204cbc71237ffbe93144b99df" + integrity sha512-HAkpptrYeUVlBYbLScXgeCgk6BsNVXxDd53HVWgzzTWpXV4MHpbpeKrByyt7viXlNhW0w73jJbipb/QlFsHIhQ== + dependencies: + "@lerna/package-graph" "^3.1.2" + "@lerna/validation-error" "^3.0.0" + npmlog "^4.1.2" + +"@lerna/bootstrap@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@lerna/bootstrap/-/bootstrap-3.5.0.tgz#4d21ef0d1e648c8121432443a7d80c9442756347" + integrity sha512-+z4kVVJFO5EGfC2ob/4C9LetqWwDtbhZgTRllr1+zOi/2clbD+WKcVI0ku+/ckzKjz783SOc83swX7RrmiLwMQ== + dependencies: + "@lerna/batch-packages" "^3.1.2" + "@lerna/command" "^3.5.0" + "@lerna/filter-options" "^3.5.0" + "@lerna/has-npm-version" "^3.3.0" + "@lerna/npm-conf" "^3.4.1" + "@lerna/npm-install" "^3.3.0" + "@lerna/rimraf-dir" "^3.3.0" + "@lerna/run-lifecycle" "^3.4.1" + "@lerna/run-parallel-batches" "^3.0.0" + "@lerna/symlink-binary" "^3.3.0" + "@lerna/symlink-dependencies" "^3.3.0" + "@lerna/validation-error" "^3.0.0" + dedent "^0.7.0" + get-port "^3.2.0" + multimatch "^2.1.0" + npm-package-arg "^6.0.0" + npmlog "^4.1.2" + p-finally "^1.0.0" + p-map "^1.2.0" + p-map-series "^1.0.0" + p-waterfall "^1.0.0" + read-package-tree "^5.1.6" + semver "^5.5.0" + +"@lerna/changed@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@lerna/changed/-/changed-3.5.0.tgz#c96c4bde6d78f4b2a7b3b3e2511bf78cb6aabe17" + integrity sha512-p9o7/hXwFAoet7UPeHIzIPonYxLHZe9bcNcjxKztZYAne5/OgmZiF4X1UPL2S12wtkT77WQy4Oz8NjRTczcapg== + dependencies: + "@lerna/collect-updates" "^3.5.0" + "@lerna/command" "^3.5.0" + "@lerna/listable" "^3.0.0" + "@lerna/output" "^3.0.0" + "@lerna/version" "^3.5.0" + +"@lerna/check-working-tree@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@lerna/check-working-tree/-/check-working-tree-3.5.0.tgz#015f90247fa0b44a940eab0dd6a9da2ae5b8f455" + integrity sha512-aWeIputHddeZgf7/wA1e5yuv6q9S5si2y7fzO2Ah7m3KyDyl8XHP1M0VSSDzZeiloYCryAYQAoRgcrdH65Vhow== + dependencies: + "@lerna/describe-ref" "^3.5.0" + "@lerna/validation-error" "^3.0.0" + +"@lerna/child-process@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@lerna/child-process/-/child-process-3.3.0.tgz#71184a763105b6c8ece27f43f166498d90fe680f" + integrity sha512-q2d/OPlNX/cBXB6Iz1932RFzOmOHq6ZzPjqebkINNaTojHWuuRpvJJY4Uz3NGpJ3kEtPDvBemkZqUBTSO5wb1g== + dependencies: + chalk "^2.3.1" + execa "^1.0.0" + strong-log-transformer "^2.0.0" + +"@lerna/clean@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@lerna/clean/-/clean-3.5.0.tgz#38e0e58443fa43c19b3eeffcafa46cf254a328ee" + integrity sha512-bHUFF6Wv7ms81Tmwe56xk296oqU74Sg9NSkUCDG4kZLpYZx347Aw+89ZPTlaSmUwqCgEXKYLr65ZVVvKmflpcA== + dependencies: + "@lerna/command" "^3.5.0" + "@lerna/filter-options" "^3.5.0" + "@lerna/prompt" "^3.3.1" + "@lerna/rimraf-dir" "^3.3.0" + p-map "^1.2.0" + p-map-series "^1.0.0" + p-waterfall "^1.0.0" + +"@lerna/cli@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@lerna/cli/-/cli-3.2.0.tgz#3ed25bcbc0b8f0878bc6a102ee0296f01476cfdf" + integrity sha512-JdbLyTxHqxUlrkI+Ke+ltXbtyA+MPu9zR6kg/n8Fl6uaez/2fZWtReXzYi8MgLxfUFa7+1OHWJv4eAMZlByJ+Q== + dependencies: + "@lerna/global-options" "^3.1.3" + dedent "^0.7.0" + npmlog "^4.1.2" + yargs "^12.0.1" + +"@lerna/collect-updates@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@lerna/collect-updates/-/collect-updates-3.5.0.tgz#e81c17f89367e71ff59e0f244a523a1dc13891c5" + integrity sha512-rFCng14K8vHyrDJSAacj6ABKKT/TxZdpL9uPEtZN7DsoJKlKPzqFeRvRGA2+ed/I6mEm4ltauEjEpKG5O6xqtw== + dependencies: + "@lerna/child-process" "^3.3.0" + "@lerna/describe-ref" "^3.5.0" + minimatch "^3.0.4" + npmlog "^4.1.2" + slash "^1.0.0" + +"@lerna/command@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@lerna/command/-/command-3.5.0.tgz#6b5cc530653aaa631061c1c234f3bc4408cb9613" + integrity sha512-C/0e7qPbuKZ9vEqzRePksoKDJk4TOWzsU5qaPP/ikqc6vClJbKucsIehk3za6glSjlgLCJpzBTF2lFjHfb+JNw== + dependencies: + "@lerna/child-process" "^3.3.0" + "@lerna/package-graph" "^3.1.2" + "@lerna/project" "^3.5.0" + "@lerna/validation-error" "^3.0.0" + "@lerna/write-log-file" "^3.0.0" + dedent "^0.7.0" + execa "^1.0.0" + is-ci "^1.0.10" + lodash "^4.17.5" + npmlog "^4.1.2" + +"@lerna/conventional-commits@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@lerna/conventional-commits/-/conventional-commits-3.5.0.tgz#1c08013c48acdbdbf6400ccfbe1200a18e1f11ce" + integrity sha512-roKPILPYnDWiCDxOeBQ0cObJ2FbDgzJSToxr1ZwIqvJU5hGQ4RmooCf8GHcCW9maBJz7ETeestv8M2mBUgBPbg== + dependencies: + "@lerna/validation-error" "^3.0.0" + conventional-changelog-angular "^5.0.2" + conventional-changelog-core "^3.1.5" + conventional-recommended-bump "^4.0.4" + fs-extra "^7.0.0" + get-stream "^4.0.0" + npm-package-arg "^6.0.0" + npmlog "^4.1.2" + semver "^5.5.0" + +"@lerna/create-symlink@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@lerna/create-symlink/-/create-symlink-3.3.0.tgz#91de00fd576018ba4251f0c6a5b4b7f768f22a82" + integrity sha512-0lb88Nnq1c/GG+fwybuReOnw3+ah4dB81PuWwWwuqUNPE0n50qUf/M/7FfSb5JEh/93fcdbZI0La8t3iysNW1w== + dependencies: + cmd-shim "^2.0.2" + fs-extra "^7.0.0" + npmlog "^4.1.2" + +"@lerna/create@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@lerna/create/-/create-3.5.0.tgz#22f64a7af7a08cfbed4af2a01ff82307ee9e0b2b" + integrity sha512-ek4flHRmpMegZp9tP3RmuDhmMb9+/Hhy9B5eaZc5X5KWqDvFKJtn56sw+M9hNjiYehiimCwhaLWgE2WSikPvcQ== + dependencies: + "@lerna/child-process" "^3.3.0" + "@lerna/command" "^3.5.0" + "@lerna/npm-conf" "^3.4.1" + "@lerna/validation-error" "^3.0.0" + camelcase "^4.1.0" + dedent "^0.7.0" + fs-extra "^7.0.0" + globby "^8.0.1" + init-package-json "^1.10.3" + npm-package-arg "^6.0.0" + pify "^3.0.0" + semver "^5.5.0" + slash "^1.0.0" + validate-npm-package-license "^3.0.3" + validate-npm-package-name "^3.0.0" + whatwg-url "^7.0.0" + +"@lerna/describe-ref@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@lerna/describe-ref/-/describe-ref-3.5.0.tgz#d59090d201a0e587798496417373c7fbc1151fc4" + integrity sha512-XvecK2PSwUv4z+otib5moWJMI+h3mtAg8nFlfo4KbivVtD/sI11jfKsr3S75HuAwhVAa8tAijoAxmuBJSsTE1g== + dependencies: + "@lerna/child-process" "^3.3.0" + npmlog "^4.1.2" + +"@lerna/diff@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@lerna/diff/-/diff-3.5.0.tgz#4d131a1045321bcea20d743f5cc7f0d0095cf027" + integrity sha512-iyZ0ZRPqH5Y5XEhOYoKS8H/8UXC/gZ/idlToMFHhUn1oTSd8v9HVU1c2xq1ge0u36ZH/fx/YydUk0A/KSv+p3Q== + dependencies: + "@lerna/child-process" "^3.3.0" + "@lerna/command" "^3.5.0" + "@lerna/validation-error" "^3.0.0" + npmlog "^4.1.2" + +"@lerna/exec@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@lerna/exec/-/exec-3.5.0.tgz#98f4e8719681c07a739241fadb4cbdbd9d518982" + integrity sha512-H5jeIueDiuNsxeuGKaP7HqTcenvMsFfBFeWr0W6knHv9NrOF8il34dBqYgApZEDSQ7+2fA3ghwWbF+jUGTSh/A== + dependencies: + "@lerna/batch-packages" "^3.1.2" + "@lerna/child-process" "^3.3.0" + "@lerna/command" "^3.5.0" + "@lerna/filter-options" "^3.5.0" + "@lerna/run-parallel-batches" "^3.0.0" + "@lerna/validation-error" "^3.0.0" + +"@lerna/filter-options@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@lerna/filter-options/-/filter-options-3.5.0.tgz#34d1719908edbb52d4963c796df565a716282165" + integrity sha512-7pEQy1i5ynYOYjcSeo+Qaps4+Ais55RRdnT6/SLLBgyyHAMziflFLX5TnoyEaaXoU90iKfQ5z/ioEp6dFAXSMg== + dependencies: + "@lerna/collect-updates" "^3.5.0" + "@lerna/filter-packages" "^3.0.0" + dedent "^0.7.0" + +"@lerna/filter-packages@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@lerna/filter-packages/-/filter-packages-3.0.0.tgz#5eb25ad1610f3e2ab845133d1f8d7d40314e838f" + integrity sha512-zwbY1J4uRjWRZ/FgYbtVkq7I3Nduwsg2V2HwLKSzwV2vPglfGqgovYOVkND6/xqe2BHwDX4IyA2+e7OJmLaLSA== + dependencies: + "@lerna/validation-error" "^3.0.0" + multimatch "^2.1.0" + npmlog "^4.1.2" + +"@lerna/get-npm-exec-opts@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@lerna/get-npm-exec-opts/-/get-npm-exec-opts-3.0.0.tgz#8fc7866e8d8e9a2f2dc385287ba32eb44de8bdeb" + integrity sha512-arcYUm+4xS8J3Palhl+5rRJXnZnFHsLFKHBxznkPIxjwGQeAEw7df38uHdVjEQ+HNeFmHnBgSqfbxl1VIw5DHg== + dependencies: + npmlog "^4.1.2" + +"@lerna/global-options@^3.1.3": + version "3.1.3" + resolved "https://registry.yarnpkg.com/@lerna/global-options/-/global-options-3.1.3.tgz#cf85e24655a91d04d4efc9a80c1f83fc768d08ae" + integrity sha512-LVeZU/Zgc0XkHdGMRYn+EmHfDmmYNwYRv3ta59iCVFXLVp7FRFWF7oB1ss/WRa9x/pYU0o6L8as/5DomLUGASA== + +"@lerna/has-npm-version@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@lerna/has-npm-version/-/has-npm-version-3.3.0.tgz#8a73c2c437a0e1e68a19ccbd0dd3c014d4d39135" + integrity sha512-GX7omRep1eBRZHgjZLRw3MpBJSdA5gPZFz95P7rxhpvsiG384Tdrr/cKFMhm0A09yq27Tk/nuYTaZIj7HsVE6g== + dependencies: + "@lerna/child-process" "^3.3.0" + semver "^5.5.0" + +"@lerna/import@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@lerna/import/-/import-3.5.0.tgz#b42d368378d53c664a3324c1e2fc656a23819f12" + integrity sha512-vgI6lMEzd1ODgi75cmAlfPYylaK37WY3E2fwKyO/lj6UKSGj46dVSK0KwTRHx33tu4PLvPzFi5C6nbY57o5ykQ== + dependencies: + "@lerna/child-process" "^3.3.0" + "@lerna/command" "^3.5.0" + "@lerna/prompt" "^3.3.1" + "@lerna/validation-error" "^3.0.0" + dedent "^0.7.0" + fs-extra "^7.0.0" + p-map-series "^1.0.0" + +"@lerna/init@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@lerna/init/-/init-3.5.0.tgz#40796d70dc261907e4149df62db8acbda8dc56fc" + integrity sha512-V21/UWj34Mph+9NxIGH1kYcuJAp+uFjfG8Ku2nMy62OGL3553+YQ+Izr+R6egY8y/99UMCDpi5gkQni5eGv3MA== + dependencies: + "@lerna/child-process" "^3.3.0" + "@lerna/command" "^3.5.0" + fs-extra "^7.0.0" + p-map "^1.2.0" + write-json-file "^2.3.0" + +"@lerna/link@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@lerna/link/-/link-3.5.0.tgz#ae7fe19df1bb0555dfa5aafcaf45c7fad537d81a" + integrity sha512-KSu1mhxwNRmguqMqUTJd4c7QIk9/xmxJxbmMkA71OaJd4fwondob6DyI/B17NIWutdLbvSWQ7pRlFOPxjQVoUw== + dependencies: + "@lerna/command" "^3.5.0" + "@lerna/package-graph" "^3.1.2" + "@lerna/symlink-dependencies" "^3.3.0" + p-map "^1.2.0" + slash "^1.0.0" + +"@lerna/list@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@lerna/list/-/list-3.5.0.tgz#ae38724f1cdc588fde8495385e3b1a9aeac0c80f" + integrity sha512-T+NZBQ/l6FmZklgrtFuN7luMs3AC/BoS52APOPrM7ZmxW4nenvov0xMwQW1783w/t365YDkDlYd5gM0nX3D1Hg== + dependencies: + "@lerna/command" "^3.5.0" + "@lerna/filter-options" "^3.5.0" + "@lerna/listable" "^3.0.0" + "@lerna/output" "^3.0.0" + +"@lerna/listable@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@lerna/listable/-/listable-3.0.0.tgz#27209b1382c87abdbc964220e75c247d803d4199" + integrity sha512-HX/9hyx1HLg2kpiKXIUc1EimlkK1T58aKQ7ovO7rQdTx9ForpefoMzyLnHE1n4XrUtEszcSWJIICJ/F898M6Ag== + dependencies: + chalk "^2.3.1" + columnify "^1.5.4" + +"@lerna/log-packed@^3.0.4": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@lerna/log-packed/-/log-packed-3.0.4.tgz#6d1f6ce5ca68b9971f2a27f0ecf3c50684be174a" + integrity sha512-vVQHgMagE2wnbxhNY9nFkdu+Cx2TsyWalkJfkxbNzmo6gOCrDsxCBDj9vTEV8Q+4aWx0C0Bsc0sB2Eb8y/+ofA== + dependencies: + byte-size "^4.0.3" + columnify "^1.5.4" + has-unicode "^2.0.1" + npmlog "^4.1.2" + +"@lerna/npm-conf@^3.4.1": + version "3.4.1" + resolved "https://registry.yarnpkg.com/@lerna/npm-conf/-/npm-conf-3.4.1.tgz#859e931b0bc9a5eed86309cc09508810c1e7d121" + integrity sha512-i9G6DnbCqiAqxKx2rSXej/n14qxlV/XOebL6QZonxJKzNTB+Q2wglnhTXmfZXTPJfoqimLaY4NfAEtbOXRWOXQ== + dependencies: + config-chain "^1.1.11" + pify "^3.0.0" + +"@lerna/npm-dist-tag@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@lerna/npm-dist-tag/-/npm-dist-tag-3.3.0.tgz#e1c5ab67674216d901266a16846b21cc81ff6afd" + integrity sha512-EtZJXzh3w5tqXEev+EBBPrWKWWn0WgJfxm4FihfS9VgyaAW8udIVZHGkIQ3f+tBtupcAzA9Q8cQNUkGF2efwmA== + dependencies: + "@lerna/child-process" "^3.3.0" + "@lerna/get-npm-exec-opts" "^3.0.0" + npmlog "^4.1.2" + +"@lerna/npm-install@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@lerna/npm-install/-/npm-install-3.3.0.tgz#16d00ffd668d11b2386b3ac68bdac2cf8320e533" + integrity sha512-WoVvKdS8ltROTGSNQwo6NDq0YKnjwhvTG4li1okcN/eHKOS3tL9bxbgPx7No0wOq5DKBpdeS9KhAfee6LFAZ5g== + dependencies: + "@lerna/child-process" "^3.3.0" + "@lerna/get-npm-exec-opts" "^3.0.0" + fs-extra "^7.0.0" + npm-package-arg "^6.0.0" + npmlog "^4.1.2" + signal-exit "^3.0.2" + write-pkg "^3.1.0" + +"@lerna/npm-publish@^3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@lerna/npm-publish/-/npm-publish-3.3.1.tgz#30384665d7ee387343332ece62ca231207bbabea" + integrity sha512-bVTlWIcBL6Zpyzqvr9C7rxXYcoPw+l7IPz5eqQDNREj1R39Wj18OWB2KTJq8l7LIX7Wf4C2A1uT5hJaEf9BuvA== + dependencies: + "@lerna/child-process" "^3.3.0" + "@lerna/get-npm-exec-opts" "^3.0.0" + "@lerna/has-npm-version" "^3.3.0" + "@lerna/log-packed" "^3.0.4" + fs-extra "^7.0.0" + npmlog "^4.1.2" + p-map "^1.2.0" + +"@lerna/npm-run-script@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@lerna/npm-run-script/-/npm-run-script-3.3.0.tgz#3c79601c27c67121155b20e039be53130217db72" + integrity sha512-YqDguWZzp4jIomaE4aWMUP7MIAJAFvRAf6ziQLpqwoQskfWLqK5mW0CcszT1oLjhfb3cY3MMfSTFaqwbdKmICg== + dependencies: + "@lerna/child-process" "^3.3.0" + "@lerna/get-npm-exec-opts" "^3.0.0" + npmlog "^4.1.2" + +"@lerna/output@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@lerna/output/-/output-3.0.0.tgz#4ed4a30ed2f311046b714b3840a090990ba3ce35" + integrity sha512-EFxnSbO0zDEVKkTKpoCUAFcZjc3gn3DwPlyTDxbeqPU7neCfxP4rA4+0a6pcOfTlRS5kLBRMx79F2TRCaMM3DA== + dependencies: + npmlog "^4.1.2" + +"@lerna/package-graph@^3.1.2": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@lerna/package-graph/-/package-graph-3.1.2.tgz#b70298a3a8c82e12090da33233bf242223a38f20" + integrity sha512-9wIWb49I1IJmyjPdEVZQ13IAi9biGfH/OZHOC04U2zXGA0GLiY+B3CAx6FQvqkZ8xEGfqzmXnv3LvZ0bQfc1aQ== + dependencies: + "@lerna/validation-error" "^3.0.0" + npm-package-arg "^6.0.0" + semver "^5.5.0" + +"@lerna/package@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@lerna/package/-/package-3.0.0.tgz#14afc9a6cb1f7f7b23c1d7c7aa81bdac7d44c0e5" + integrity sha512-djzEJxzn212wS8d9znBnlXkeRlPL7GqeAYBykAmsuq51YGvaQK67Umh5ejdO0uxexF/4r7yRwgrlRHpQs8Rfqg== + dependencies: + npm-package-arg "^6.0.0" + write-pkg "^3.1.0" + +"@lerna/project@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@lerna/project/-/project-3.5.0.tgz#ac5c7b3c49318552b29ccb7a471a657fd57d3091" + integrity sha512-uFDzqwrD7a/tTohQoo0voTsRy2cgl9D1ZOU2pHZzHzow9S1M8E0x5q3hJI2HlwsZry9IUugmDUGO6UddTjwm3Q== + dependencies: + "@lerna/package" "^3.0.0" + "@lerna/validation-error" "^3.0.0" + cosmiconfig "^5.0.2" + dedent "^0.7.0" + dot-prop "^4.2.0" + glob-parent "^3.1.0" + globby "^8.0.1" + load-json-file "^4.0.0" + npmlog "^4.1.2" + p-map "^1.2.0" + resolve-from "^4.0.0" + write-json-file "^2.3.0" + +"@lerna/prompt@^3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@lerna/prompt/-/prompt-3.3.1.tgz#ec53f9034a7a02a671627241682947f65078ab88" + integrity sha512-eJhofrUCUaItMIH6et8kI7YqHfhjWqGZoTsE+40NRCfAraOMWx+pDzfRfeoAl3qeRAH2HhNj1bkYn70FbUOxuQ== + dependencies: + inquirer "^6.2.0" + npmlog "^4.1.2" + +"@lerna/publish@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@lerna/publish/-/publish-3.5.0.tgz#e6543375457846557f3cb803f7795a577333a941" + integrity sha512-CoK+wzPP/0xG54Iwf9WEbB3VgwayoiVYsubhYpC072Ue7V6mGXQh97KZMm8NzCoMDg35ZGqa85Kxpeqd5hqQlw== + dependencies: + "@lerna/batch-packages" "^3.1.2" + "@lerna/check-working-tree" "^3.5.0" + "@lerna/child-process" "^3.3.0" + "@lerna/collect-updates" "^3.5.0" + "@lerna/command" "^3.5.0" + "@lerna/describe-ref" "^3.5.0" + "@lerna/get-npm-exec-opts" "^3.0.0" + "@lerna/npm-conf" "^3.4.1" + "@lerna/npm-dist-tag" "^3.3.0" + "@lerna/npm-publish" "^3.3.1" + "@lerna/output" "^3.0.0" + "@lerna/prompt" "^3.3.1" + "@lerna/run-lifecycle" "^3.4.1" + "@lerna/run-parallel-batches" "^3.0.0" + "@lerna/validation-error" "^3.0.0" + "@lerna/version" "^3.5.0" + fs-extra "^7.0.0" + libnpmaccess "^3.0.0" + npm-package-arg "^6.0.0" + npm-registry-fetch "^3.8.0" + npmlog "^4.1.2" + p-finally "^1.0.0" + p-map "^1.2.0" + p-pipe "^1.2.0" + p-reduce "^1.0.0" + semver "^5.5.0" + +"@lerna/resolve-symlink@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@lerna/resolve-symlink/-/resolve-symlink-3.3.0.tgz#c5d99a60cb17e2ea90b3521a0ba445478d194a44" + integrity sha512-KmoPDcFJ2aOK2inYHbrsiO9SodedUj0L1JDvDgirVNIjMUaQe2Q6Vi4Gh+VCJcyB27JtfHioV9R2NxU72Pk2hg== + dependencies: + fs-extra "^7.0.0" + npmlog "^4.1.2" + read-cmd-shim "^1.0.1" + +"@lerna/rimraf-dir@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@lerna/rimraf-dir/-/rimraf-dir-3.3.0.tgz#687e9bb3668a9e540e281302a52d9a573860f5db" + integrity sha512-vSqOcZ4kZduiSprbt+y40qziyN3VKYh+ygiCdnbBbsaxpdKB6CfrSMUtrLhVFrqUfBHIZRzHIzgjTdtQex1KLw== + dependencies: + "@lerna/child-process" "^3.3.0" + npmlog "^4.1.2" + path-exists "^3.0.0" + rimraf "^2.6.2" + +"@lerna/run-lifecycle@^3.4.1": + version "3.4.1" + resolved "https://registry.yarnpkg.com/@lerna/run-lifecycle/-/run-lifecycle-3.4.1.tgz#6d7e44eada31cb4ec78b18ef050da0d86f6c892b" + integrity sha512-N/hi2srM9A4BWEkXccP7vCEbf4MmIuALF00DTBMvc0A/ccItwUpl3XNuM7+ADDRK0mkwE3hDw89lJ3A7f8oUQw== + dependencies: + "@lerna/npm-conf" "^3.4.1" + npm-lifecycle "^2.0.0" + npmlog "^4.1.2" + +"@lerna/run-parallel-batches@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@lerna/run-parallel-batches/-/run-parallel-batches-3.0.0.tgz#468704934084c74991d3124d80607857d4dfa840" + integrity sha512-Mj1ravlXF7AkkewKd9YFq9BtVrsStNrvVLedD/b2wIVbNqcxp8lS68vehXVOzoL/VWNEDotvqCQtyDBilCodGw== + dependencies: + p-map "^1.2.0" + p-map-series "^1.0.0" + +"@lerna/run@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@lerna/run/-/run-3.5.0.tgz#f2bf479d8ef12e6a11be5a6404bb1a83eb56146c" + integrity sha512-BnPD52tj794xG2Xsc4FvgksyFX2CLmSR28TZw/xASEuy14NuQYMZkvbaj61SEhyOEsq7pLhHE5PpfbIv2AIFJw== + dependencies: + "@lerna/batch-packages" "^3.1.2" + "@lerna/command" "^3.5.0" + "@lerna/filter-options" "^3.5.0" + "@lerna/npm-run-script" "^3.3.0" + "@lerna/output" "^3.0.0" + "@lerna/run-parallel-batches" "^3.0.0" + "@lerna/timer" "^3.5.0" + "@lerna/validation-error" "^3.0.0" + p-map "^1.2.0" + +"@lerna/symlink-binary@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@lerna/symlink-binary/-/symlink-binary-3.3.0.tgz#99ea570b21baabd61ecab27582eeb1d7b2c5f9cf" + integrity sha512-zRo6CimhvH/VJqCFl9T4IC6syjpWyQIxEfO2sBhrapEcfwjtwbhoGgKwucsvt4rIpFazCw63jQ/AXMT27KUIHg== + dependencies: + "@lerna/create-symlink" "^3.3.0" + "@lerna/package" "^3.0.0" + fs-extra "^7.0.0" + p-map "^1.2.0" + read-pkg "^3.0.0" + +"@lerna/symlink-dependencies@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@lerna/symlink-dependencies/-/symlink-dependencies-3.3.0.tgz#13bcaed3e37986ab01b13498a459c7f609397dc3" + integrity sha512-IRngSNCmuD5uBKVv23tHMvr7Mplti0lKHilFKcvhbvhAfu6m/Vclxhkfs/uLyHzG+DeRpl/9o86SQET3h4XDhg== + dependencies: + "@lerna/create-symlink" "^3.3.0" + "@lerna/resolve-symlink" "^3.3.0" + "@lerna/symlink-binary" "^3.3.0" + fs-extra "^7.0.0" + p-finally "^1.0.0" + p-map "^1.2.0" + p-map-series "^1.0.0" + +"@lerna/timer@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@lerna/timer/-/timer-3.5.0.tgz#8dee6acf002c55de64678c66ef37ca52143f1b9b" + integrity sha512-TAb99hqQN6E3JBGtG9iyZNPq1/DbmqgBOeNrKtdJsGvIeX/NGLgUDWMrj2h04V4O+jpBFmSf6HIld6triKmxCA== + +"@lerna/validation-error@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@lerna/validation-error/-/validation-error-3.0.0.tgz#a27e90051c3ba71995e2a800a43d94ad04b3e3f4" + integrity sha512-5wjkd2PszV0kWvH+EOKZJWlHEqCTTKrWsvfHnHhcUaKBe/NagPZFWs+0xlsDPZ3DJt5FNfbAPAnEBQ05zLirFA== + dependencies: + npmlog "^4.1.2" + +"@lerna/version@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@lerna/version/-/version-3.5.0.tgz#df6d4d8ef077b51962126c0f52c800d98c53cc26" + integrity sha512-vxuGkUSfjJuvOIgPG7SDXVmk4GPwJF9F+uhDW9T/wJzTk4UaxL37GpBeJDo43eutQ7mwluP+t88Luwf8S3WXlA== + dependencies: + "@lerna/batch-packages" "^3.1.2" + "@lerna/check-working-tree" "^3.5.0" + "@lerna/child-process" "^3.3.0" + "@lerna/collect-updates" "^3.5.0" + "@lerna/command" "^3.5.0" + "@lerna/conventional-commits" "^3.5.0" + "@lerna/output" "^3.0.0" + "@lerna/prompt" "^3.3.1" + "@lerna/run-lifecycle" "^3.4.1" + "@lerna/validation-error" "^3.0.0" + chalk "^2.3.1" + dedent "^0.7.0" + minimatch "^3.0.4" + npmlog "^4.1.2" + p-map "^1.2.0" + p-pipe "^1.2.0" + p-reduce "^1.0.0" + p-waterfall "^1.0.0" + semver "^5.5.0" + slash "^1.0.0" + temp-write "^3.4.0" + +"@lerna/write-log-file@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@lerna/write-log-file/-/write-log-file-3.0.0.tgz#2f95fee80c6821fe1ee6ccf8173d2b4079debbd2" + integrity sha512-SfbPp29lMeEVOb/M16lJwn4nnx5y+TwCdd7Uom9umd7KcZP0NOvpnX0PHehdonl7TyHZ1Xx2maklYuCLbQrd/A== + dependencies: + npmlog "^4.1.2" + write-file-atomic "^2.3.0" + +"@mrmlnc/readdir-enhanced@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" + integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== + dependencies: + call-me-maybe "^1.0.1" + glob-to-regexp "^0.3.0" + +"@nodelib/fs.stat@^1.1.2": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" + integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== + +"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + integrity sha1-m4sMxmPWaafY9vXQiToU00jzD78= + +"@protobufjs/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== + +"@protobufjs/codegen@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== + +"@protobufjs/eventemitter@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + integrity sha1-NVy8mLr61ZePntCV85diHx0Ga3A= + +"@protobufjs/fetch@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + integrity sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU= + dependencies: + "@protobufjs/aspromise" "^1.1.1" + "@protobufjs/inquire" "^1.1.0" + +"@protobufjs/float@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + integrity sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E= + +"@protobufjs/inquire@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + integrity sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik= + +"@protobufjs/path@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + integrity sha1-bMKyDFya1q0NzP0hynZz2Nf79o0= + +"@protobufjs/pool@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + integrity sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q= + +"@protobufjs/utf8@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= + +"@samverschueren/stream-to-observable@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f" + integrity sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg== + dependencies: + any-observable "^0.3.0" + +"@sentry/core@4.4.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-4.4.0.tgz#32caf17751cbd50345214d7bb61d498d51bb13c5" + integrity sha512-t/qKC6LhAaAp3/bgfNaZ2Ed5de6FpJT0xEvB9dpILYLy083tg4evmBZA/DspuGn0XZek9GKDhcxbO7BA5/QBpA== + dependencies: + "@sentry/hub" "4.4.0" + "@sentry/minimal" "4.4.0" + "@sentry/types" "4.4.0" + "@sentry/utils" "4.4.0" + tslib "^1.9.3" + +"@sentry/hub@4.4.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-4.4.0.tgz#9aa47ce9143cbd44de6ac1aeddd2a6532517673c" + integrity sha512-nsKNKD9hcj5b95KBqVH7sCPXezI7kngyP36Cst4GXUKU9StQ6F4ZUG2fUflvREUo+Rj1lz3y2UB8+WrcnLejag== + dependencies: + "@sentry/types" "4.4.0" + "@sentry/utils" "4.4.0" + tslib "^1.9.3" + +"@sentry/minimal@4.4.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-4.4.0.tgz#e2c19296312311851704bb5d61f6892253ae52e6" + integrity sha512-BBI/dL+imR8mAh4gHxnsfAgCjvOGtLWalIOV29QsVXM6OgXX+se/14zAbSlAk8a/u9bFQq+/235P/OCMVb9mqA== + dependencies: + "@sentry/hub" "4.4.0" + "@sentry/types" "4.4.0" + tslib "^1.9.3" + +"@sentry/node@^4.4.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@sentry/node/-/node-4.4.0.tgz#56962f718811ce6f55e04189d3ebb4acdc50d79d" + integrity sha512-EvHfDURVaiFFa2vDS/3FjgytOaSaJlJqbTYaHxoJYQBs5WJmlw6tqnMNAzpGu2I2iV5hjo13SspU3mN4SwNY5Q== + dependencies: + "@sentry/core" "4.4.0" + "@sentry/hub" "4.4.0" + "@sentry/types" "4.4.0" + "@sentry/utils" "4.4.0" + "@types/stack-trace" "0.0.29" + cookie "0.3.1" + https-proxy-agent "^2.2.1" + lsmod "1.0.0" + stack-trace "0.0.10" + tslib "^1.9.3" + +"@sentry/types@4.4.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-4.4.0.tgz#99e662c1b9955f293e2673433a1c84b50db1ed64" + integrity sha512-db0Vw8EofVszUOTj86cE4YeM0ZGQIp/YYi/isu3SV28+tLUJlDPlU11xhXCSsoyvqk0L0Ld6QFOfIKJeMCtl5Q== + +"@sentry/utils@4.4.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-4.4.0.tgz#1e81f8849763477bb32707d6eba60897c9de9044" + integrity sha512-n3uqSiAhKjMS24NS2RLOl3OFsODr82D6aSHwIByXH83O+tHdLeyin3yEuosfiKkvvurELPI1tSh9QPCgW35dJw== + dependencies: + "@sentry/types" "4.4.0" + tslib "^1.9.3" + +"@sindresorhus/is@^0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" + integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow== + +"@snyk/dep-graph@1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@snyk/dep-graph/-/dep-graph-1.1.2.tgz#a0377fbb29dd42bc12d1c2493b51a7b7fe0d334a" + integrity sha512-mCoAFKtmezBL61JOzLMzqqd/sXXxp0iektEwf4zw+sM3zuG4Tnmhf8OqNO6Wscn84bMIfLlI/nvECdxvSS7MTw== + dependencies: + graphlib "^2.1.5" + lodash "^4" + source-map-support "^0.5.9" + tslib "^1.9.3" + +"@snyk/gemfile@1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@snyk/gemfile/-/gemfile-1.1.0.tgz#8c254dfc7739b2e8513c44c976fc41872d5f6af0" + integrity sha512-mLwF+ccuvRZMS0SxUAxA3dAp8mB3m2FxIsBIUWFTYvzxl+E4XTZb8uFrUqXHbcxhZH1Z8taHohNTbzXZn3M8ag== + +"@types/events@*": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" + integrity sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA== + +"@types/geojson@^1.0.0": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-1.0.6.tgz#3e02972728c69248c2af08d60a48cbb8680fffdf" + integrity sha512-Xqg/lIZMrUd0VRmSRbCAewtwGZiAk3mEUDvV4op1tGl+LvyPcb/MIOSxTl9z+9+J+R4/vpjiCAT4xeKzH9ji1w== + +"@types/long@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.0.tgz#719551d2352d301ac8b81db732acb6bdc28dbdef" + integrity sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q== + +"@types/node@*", "@types/node@^10.1.0": + version "10.12.10" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.10.tgz#4fa76e6598b7de3f0cb6ec3abacc4f59e5b3a2ce" + integrity sha512-8xZEYckCbUVgK8Eg7lf5Iy4COKJ5uXlnIOnePN0WUwSQggy9tolM+tDJf7wMOnT/JT/W9xDYIaYggt3mRV2O5w== + +"@types/stack-trace@0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/stack-trace/-/stack-trace-0.0.29.tgz#eb7a7c60098edb35630ed900742a5ecb20cfcb4d" + integrity sha512-TgfOX+mGY/NyNxJLIbDWrO9DjGoVSW9+aB8H2yy1fy32jsvxijhmyJI9fDFgvz3YP4lvJaq9DzdR/M1bOgVc9g== + +"@types/ws@^6.0.0": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-6.0.1.tgz#ca7a3f3756aa12f62a0a62145ed14c6db25d5a28" + integrity sha512-EzH8k1gyZ4xih/MaZTXwT2xOkPiIMSrhQ9b8wrlX88L0T02eYsddatQlwVFlEPyEqV0ChpdpNnE51QPH6NVT4Q== + dependencies: + "@types/events" "*" + "@types/node" "*" + +"@webassemblyjs/ast@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.7.11.tgz#b988582cafbb2b095e8b556526f30c90d057cace" + integrity sha512-ZEzy4vjvTzScC+SH8RBssQUawpaInUdMTYwYYLh54/s8TuT0gBLuyUnppKsVyZEi876VmmStKsUs28UxPgdvrA== + dependencies: + "@webassemblyjs/helper-module-context" "1.7.11" + "@webassemblyjs/helper-wasm-bytecode" "1.7.11" + "@webassemblyjs/wast-parser" "1.7.11" + +"@webassemblyjs/floating-point-hex-parser@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.7.11.tgz#a69f0af6502eb9a3c045555b1a6129d3d3f2e313" + integrity sha512-zY8dSNyYcgzNRNT666/zOoAyImshm3ycKdoLsyDw/Bwo6+/uktb7p4xyApuef1dwEBo/U/SYQzbGBvV+nru2Xg== + +"@webassemblyjs/helper-api-error@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.7.11.tgz#c7b6bb8105f84039511a2b39ce494f193818a32a" + integrity sha512-7r1qXLmiglC+wPNkGuXCvkmalyEstKVwcueZRP2GNC2PAvxbLYwLLPr14rcdJaE4UtHxQKfFkuDFuv91ipqvXg== + +"@webassemblyjs/helper-buffer@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.7.11.tgz#3122d48dcc6c9456ed982debe16c8f37101df39b" + integrity sha512-MynuervdylPPh3ix+mKZloTcL06P8tenNH3sx6s0qE8SLR6DdwnfgA7Hc9NSYeob2jrW5Vql6GVlsQzKQCa13w== + +"@webassemblyjs/helper-code-frame@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.7.11.tgz#cf8f106e746662a0da29bdef635fcd3d1248364b" + integrity sha512-T8ESC9KMXFTXA5urJcyor5cn6qWeZ4/zLPyWeEXZ03hj/x9weSokGNkVCdnhSabKGYWxElSdgJ+sFa9G/RdHNw== + dependencies: + "@webassemblyjs/wast-printer" "1.7.11" + +"@webassemblyjs/helper-fsm@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.7.11.tgz#df38882a624080d03f7503f93e3f17ac5ac01181" + integrity sha512-nsAQWNP1+8Z6tkzdYlXT0kxfa2Z1tRTARd8wYnc/e3Zv3VydVVnaeePgqUzFrpkGUyhUUxOl5ML7f1NuT+gC0A== + +"@webassemblyjs/helper-module-context@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.7.11.tgz#d874d722e51e62ac202476935d649c802fa0e209" + integrity sha512-JxfD5DX8Ygq4PvXDucq0M+sbUFA7BJAv/GGl9ITovqE+idGX+J3QSzJYz+LwQmL7fC3Rs+utvWoJxDb6pmC0qg== + +"@webassemblyjs/helper-wasm-bytecode@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.7.11.tgz#dd9a1e817f1c2eb105b4cf1013093cb9f3c9cb06" + integrity sha512-cMXeVS9rhoXsI9LLL4tJxBgVD/KMOKXuFqYb5oCJ/opScWpkCMEz9EJtkonaNcnLv2R3K5jIeS4TRj/drde1JQ== + +"@webassemblyjs/helper-wasm-section@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.7.11.tgz#9c9ac41ecf9fbcfffc96f6d2675e2de33811e68a" + integrity sha512-8ZRY5iZbZdtNFE5UFunB8mmBEAbSI3guwbrsCl4fWdfRiAcvqQpeqd5KHhSWLL5wuxo53zcaGZDBU64qgn4I4Q== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-buffer" "1.7.11" + "@webassemblyjs/helper-wasm-bytecode" "1.7.11" + "@webassemblyjs/wasm-gen" "1.7.11" + +"@webassemblyjs/ieee754@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.7.11.tgz#c95839eb63757a31880aaec7b6512d4191ac640b" + integrity sha512-Mmqx/cS68K1tSrvRLtaV/Lp3NZWzXtOHUW2IvDvl2sihAwJh4ACE0eL6A8FvMyDG9abes3saB6dMimLOs+HMoQ== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.7.11.tgz#d7267a1ee9c4594fd3f7e37298818ec65687db63" + integrity sha512-vuGmgZjjp3zjcerQg+JA+tGOncOnJLWVkt8Aze5eWQLwTQGNgVLcyOTqgSCxWTR4J42ijHbBxnuRaL1Rv7XMdw== + dependencies: + "@xtuc/long" "4.2.1" + +"@webassemblyjs/utf8@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.7.11.tgz#06d7218ea9fdc94a6793aa92208160db3d26ee82" + integrity sha512-C6GFkc7aErQIAH+BMrIdVSmW+6HSe20wg57HEC1uqJP8E/xpMjXqQUxkQw07MhNDSDcGpxI9G5JSNOQCqJk4sA== + +"@webassemblyjs/wasm-edit@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.7.11.tgz#8c74ca474d4f951d01dbae9bd70814ee22a82005" + integrity sha512-FUd97guNGsCZQgeTPKdgxJhBXkUbMTY6hFPf2Y4OedXd48H97J+sOY2Ltaq6WGVpIH8o/TGOVNiVz/SbpEMJGg== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-buffer" "1.7.11" + "@webassemblyjs/helper-wasm-bytecode" "1.7.11" + "@webassemblyjs/helper-wasm-section" "1.7.11" + "@webassemblyjs/wasm-gen" "1.7.11" + "@webassemblyjs/wasm-opt" "1.7.11" + "@webassemblyjs/wasm-parser" "1.7.11" + "@webassemblyjs/wast-printer" "1.7.11" + +"@webassemblyjs/wasm-gen@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.7.11.tgz#9bbba942f22375686a6fb759afcd7ac9c45da1a8" + integrity sha512-U/KDYp7fgAZX5KPfq4NOupK/BmhDc5Kjy2GIqstMhvvdJRcER/kUsMThpWeRP8BMn4LXaKhSTggIJPOeYHwISA== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-wasm-bytecode" "1.7.11" + "@webassemblyjs/ieee754" "1.7.11" + "@webassemblyjs/leb128" "1.7.11" + "@webassemblyjs/utf8" "1.7.11" + +"@webassemblyjs/wasm-opt@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.7.11.tgz#b331e8e7cef8f8e2f007d42c3a36a0580a7d6ca7" + integrity sha512-XynkOwQyiRidh0GLua7SkeHvAPXQV/RxsUeERILmAInZegApOUAIJfRuPYe2F7RcjOC9tW3Cb9juPvAC/sCqvg== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-buffer" "1.7.11" + "@webassemblyjs/wasm-gen" "1.7.11" + "@webassemblyjs/wasm-parser" "1.7.11" + +"@webassemblyjs/wasm-parser@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.7.11.tgz#6e3d20fa6a3519f6b084ef9391ad58211efb0a1a" + integrity sha512-6lmXRTrrZjYD8Ng8xRyvyXQJYUQKYSXhJqXOBLw24rdiXsHAOlvw5PhesjdcaMadU/pyPQOJ5dHreMjBxwnQKg== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-api-error" "1.7.11" + "@webassemblyjs/helper-wasm-bytecode" "1.7.11" + "@webassemblyjs/ieee754" "1.7.11" + "@webassemblyjs/leb128" "1.7.11" + "@webassemblyjs/utf8" "1.7.11" + +"@webassemblyjs/wast-parser@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.7.11.tgz#25bd117562ca8c002720ff8116ef9072d9ca869c" + integrity sha512-lEyVCg2np15tS+dm7+JJTNhNWq9yTZvi3qEhAIIOaofcYlUp0UR5/tVqOwa/gXYr3gjwSZqw+/lS9dscyLelbQ== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/floating-point-hex-parser" "1.7.11" + "@webassemblyjs/helper-api-error" "1.7.11" + "@webassemblyjs/helper-code-frame" "1.7.11" + "@webassemblyjs/helper-fsm" "1.7.11" + "@xtuc/long" "4.2.1" + +"@webassemblyjs/wast-printer@1.7.11": + version "1.7.11" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.7.11.tgz#c4245b6de242cb50a2cc950174fdbf65c78d7813" + integrity sha512-m5vkAsuJ32QpkdkDOUPGSltrg8Cuk3KBx4YrmAGQwCZPRdUHXxG4phIOuuycLemHFr74sWL9Wthqss4fzdzSwg== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/wast-parser" "1.7.11" + "@xtuc/long" "4.2.1" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.1": + version "4.2.1" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.1.tgz#5c85d662f76fa1d34575766c5dcd6615abcd30d8" + integrity sha512-FZdkNBDqBRHKQ2MEbSC17xnPFOhZxeJ2YGSfr2BKf3sujG49Qe3bB+rGCwQfIaA7WHnGeGkSijX4FuBCdrzW/g== + +"@yarnpkg/lockfile@^1.0.2": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" + integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== + +JSONStream@^1.0.4, JSONStream@^1.3.4, JSONStream@^1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" + integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== + dependencies: + jsonparse "^1.2.0" + through ">=2.2.7 <3" + +abab@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.0.tgz#aba0ab4c5eee2d4c79d3487d85450fb2376ebb0f" + integrity sha512-sY5AXXVZv4Y1VACTtR11UJCPHHudgY5i26Qj5TypE6DKlIApbwb5uqhXcJ5UUGbvZNRh7EeIoW+LrJumBsKp7w== + +abbrev@1, abbrev@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +abbrev@~1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" + integrity sha1-kbR5JYinc4wl813W9jdSovh3YTU= + +accept@3.x.x, accept@^3.0.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/accept/-/accept-3.1.3.tgz#29c3e2b3a8f4eedbc2b690e472b9ebbdc7385e87" + integrity sha512-OgOEAidVEOKPup+Gv2+2wdH2AgVKI9LxsJ4hicdJ6cY0faUuZdZoi56kkXWlHp9qicN1nWQLmW5ZRGk+SBS5xg== + dependencies: + boom "7.x.x" + hoek "6.x.x" + +accepts@~1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" + integrity sha1-63d99gEXI6OxTopywIBcjoZ0a9I= + dependencies: + mime-types "~2.1.18" + negotiator "0.6.1" + +acorn-dynamic-import@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz#901ceee4c7faaef7e07ad2a47e890675da50a278" + integrity sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg== + dependencies: + acorn "^5.0.0" + +acorn-globals@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.0.tgz#e3b6f8da3c1552a95ae627571f7dd6923bb54103" + integrity sha512-hMtHj3s5RnuhvHPowpBYvJVj3rAar82JiDQHvGs1zO0l10ocX/xEdBShNHTJaboucJUsScghp74pH3s7EnHHQw== + dependencies: + acorn "^6.0.1" + acorn-walk "^6.0.1" + +acorn-jsx@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.1.tgz#32a064fd925429216a09b141102bfdd185fae40e" + integrity sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg== + +acorn-walk@^6.0.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.1.1.tgz#d363b66f5fac5f018ff9c3a1e7b6f8e310cc3913" + integrity sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw== + +acorn@^5.0.0, acorn@^5.5.3, acorn@^5.6.2: + version "5.7.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" + integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== + +acorn@^6.0.1, acorn@^6.0.2: + version "6.0.4" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.0.4.tgz#77377e7353b72ec5104550aa2d2097a2fd40b754" + integrity sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg== + +agent-base@4, agent-base@^4.1.0, agent-base@^4.2.0, agent-base@~4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" + integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg== + dependencies: + es6-promisify "^5.0.0" + +agentkeepalive@^3.4.1: + version "3.5.2" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-3.5.2.tgz#a113924dd3fa24a0bc3b78108c450c2abee00f67" + integrity sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ== + dependencies: + humanize-ms "^1.2.1" + +aggregate-error@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-1.0.0.tgz#888344dad0220a72e3af50906117f48771925fac" + integrity sha1-iINE2tAiCnLjr1CQYRf0h3GSX6w= + dependencies: + clean-stack "^1.0.0" + indent-string "^3.0.0" + +ajv-errors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.0.tgz#ecf021fa108fd17dfb5e6b383f2dd233e31ffc59" + integrity sha1-7PAh+hCP0X37Xms4Py3SM+Mf/Fk= + +ajv-keywords@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a" + integrity sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo= + +ajv@^6.1.0, ajv@^6.5.3, ajv@^6.5.5: + version "6.5.5" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.5.tgz#cf97cdade71c6399a92c6d6c4177381291b781a1" + integrity sha512-7q7gtRQDJSyuEHjuVgHoUa2VuemFiCMrfQc9Tc08XTAc4Zj/5U1buQJ0HU6i7fKjXU09SVgSmxa4sLvuvS8Iyg== + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ambi@^2.4.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/ambi/-/ambi-2.5.0.tgz#7c8e372be48891157e7cea01cb6f9143d1f74220" + integrity sha1-fI43K+SIkRV+fOoBy2+RQ9H3QiA= + dependencies: + editions "^1.1.1" + typechecker "^4.3.0" + +ammo@3.x.x: + version "3.0.3" + resolved "https://registry.yarnpkg.com/ammo/-/ammo-3.0.3.tgz#502aafa9d8bfca264143e226e5f322716e746b0c" + integrity sha512-vo76VJ44MkUBZL/BzpGXaKzMfroF4ZR6+haRuw9p+eSWfoNaH2AxVc8xmiEPC08jhzJSeM6w7/iMUGet8b4oBQ== + dependencies: + hoek "6.x.x" + +ansi-align@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-2.0.0.tgz#c36aeccba563b89ceb556f3690f0b1d9e3547f7f" + integrity sha1-w2rsy6VjuJzrVW82kPCx2eNUf38= + dependencies: + string-width "^2.0.0" + +ansi-escapes@^3.0.0, ansi-escapes@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" + integrity sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw== + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansicolors@^0.3.2, ansicolors@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979" + integrity sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk= + +ansistyles@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/ansistyles/-/ansistyles-0.1.3.tgz#5de60415bda071bb37127854c864f41b23254539" + integrity sha1-XeYEFb2gcbs3EnhUyGT0GyMlRTk= + +any-observable@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.3.0.tgz#af933475e5806a67d0d7df090dd5e8bef65d119b" + integrity sha512-/FQM1EDkTsf63Ub2C6O7GuYFDsSXUwsaZDurV0np41ocwq0jthUAYCmhBX9f+KwlaCgIuWyr/4WlUQUBfKfZog== + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +apollo-cache-control@0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/apollo-cache-control/-/apollo-cache-control-0.3.3.tgz#ad71d8f786e06f0275b2432004c15c2d37c48484" + integrity sha512-X6JhKfIaMLfl2jpsK/880BflXA+2lmm2sAsOZL4Bn2VrMsDtOssI1Ij9vNRbch9k9cA4WJvKed7Sql/wUIa1Eg== + dependencies: + apollo-server-env "2.2.0" + graphql-extensions "0.3.3" + +apollo-datasource@0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/apollo-datasource/-/apollo-datasource-0.2.1.tgz#3ecef4efe64f7a04a43862f32027d38ac09e142c" + integrity sha512-r185+JTa5KuF1INeTAk7AEP76zwMN6c8Ph1lmpzJMNwBUEzTGnLClrccCskCBx4SxfnkdKbuQdwn9JwCJUWrdg== + dependencies: + apollo-server-caching "0.2.1" + apollo-server-env "2.2.0" + +apollo-engine-reporting-protobuf@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.1.0.tgz#fbc220cac2a3b7800ffc155d7e54c21c56b7848e" + integrity sha512-GReJtAYTmpwg0drb9VgFtqObYYTCHkJhlHEYCeXY8bJV4fOgXsAZ7CIXR9nPKO0mBaoHIHaGYvXGcyCLrZ36VA== + dependencies: + protobufjs "^6.8.6" + +apollo-engine-reporting@0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/apollo-engine-reporting/-/apollo-engine-reporting-0.1.3.tgz#85ad6ffd71db8f877202ce8b3d7dbfa7cabfbcf9" + integrity sha512-VkjiifHMHIAxydXecT+ck0WtqpFIsMlylKnKeuNAXfIfAXHX/JYtLhbArTTyhDunLrphMiUewfFv9P0K+aX2jw== + dependencies: + apollo-engine-reporting-protobuf "0.1.0" + apollo-server-env "2.2.0" + async-retry "^1.2.1" + graphql-extensions "0.3.3" + lodash "^4.17.10" + +apollo-env@0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/apollo-env/-/apollo-env-0.2.5.tgz#162c785bccd2aea69350a7600fab4b7147fc9da5" + integrity sha512-Gc7TEbwCl7jJVutnn8TWfzNSkrrqyoo0DP92BQJFU9pZbJhpidoXf2Sw1YwOJl82rRKH3ujM3C8vdZLOgpFcFA== + dependencies: + core-js "^3.0.0-beta.3" + node-fetch "^2.2.0" + +apollo-link@^1.2.3: + version "1.2.4" + resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.4.tgz#ab4d21d2e428db848e88b5e8f4adc717b19c954b" + integrity sha512-B1z+9H2nTyWEhMXRFSnoZ1vSuAYP+V/EdUJvRx9uZ8yuIBZMm6reyVtr1n0BWlKeSFyPieKJy2RLzmITAAQAMQ== + dependencies: + apollo-utilities "^1.0.0" + zen-observable-ts "^0.8.11" + +apollo-server-caching@0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/apollo-server-caching/-/apollo-server-caching-0.2.1.tgz#7e67f8c8cac829e622b394f0fb82579cabbeadfd" + integrity sha512-+U9F3X297LL8Gqy6ypfDNEv/DfV/tDht9Dr2z3AMaEkNW1bwO6rmdDL01zYxDuVDVq6Z3qSiNCSO2pXE2F0zmA== + dependencies: + lru-cache "^5.0.0" + +apollo-server-core@2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/apollo-server-core/-/apollo-server-core-2.2.4.tgz#2dc0752067c10588a4d3b8445cdfd00591a7175b" + integrity sha512-HHienzcp4KbVatUahH22xepk58szaXU3B14dPlJdvE58V6fApdWneEg+2iCXPOiTs5dR5uxrayuqwQdzjZhK2g== + dependencies: + "@apollographql/apollo-tools" "^0.2.6" + "@apollographql/apollo-upload-server" "^5.0.3" + "@apollographql/graphql-playground-html" "^1.6.6" + "@types/ws" "^6.0.0" + apollo-cache-control "0.3.3" + apollo-datasource "0.2.1" + apollo-engine-reporting "0.1.3" + apollo-server-caching "0.2.1" + apollo-server-env "2.2.0" + apollo-server-errors "2.2.0" + apollo-server-plugin-base "0.1.4" + apollo-tracing "0.3.3" + graphql-extensions "0.3.4" + graphql-subscriptions "^1.0.0" + graphql-tag "^2.9.2" + graphql-tools "^4.0.0" + json-stable-stringify "^1.0.1" + lodash "^4.17.10" + subscriptions-transport-ws "^0.9.11" + ws "^6.0.0" + +apollo-server-env@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/apollo-server-env/-/apollo-server-env-2.2.0.tgz#5eec5dbf46581f663fd6692b2e05c7e8ae6d6034" + integrity sha512-wjJiI5nQWPBpNmpiLP389Ezpstp71szS6DHAeTgYLb/ulCw3CTuuA+0/E1bsThVWiQaDeHZE0sE3yI8q2zrYiA== + dependencies: + node-fetch "^2.1.2" + util.promisify "^1.0.0" + +apollo-server-errors@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/apollo-server-errors/-/apollo-server-errors-2.2.0.tgz#5b452a1d6ff76440eb0f127511dc58031a8f3cb5" + integrity sha512-gV9EZG2tovFtT1cLuCTavnJu2DaKxnXPRNGSTo+SDI6IAk6cdzyW0Gje5N2+3LybI0Wq5KAbW6VLei31S4MWmg== + +apollo-server-hapi@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/apollo-server-hapi/-/apollo-server-hapi-2.2.4.tgz#57c09c2d4e024ba56ce5a439ebe6e25d1b8d8ec8" + integrity sha512-Z8q/4CD5tWko/DnFd0wal68M6XaLoBxRKxQHxmZ67s73HKf01Wc5IYiVfdIsBGVzAgHpEXDBlN+1fgwgJxgi4Q== + dependencies: + "@apollographql/apollo-upload-server" "^5.0.3" + "@apollographql/graphql-playground-html" "^1.6.6" + accept "^3.0.2" + apollo-server-core "2.2.4" + boom "^7.1.0" + graphql-subscriptions "^1.0.0" + graphql-tools "^4.0.0" + +apollo-server-plugin-base@0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/apollo-server-plugin-base/-/apollo-server-plugin-base-0.1.4.tgz#b30eeb033c315e591cbf8b816708536c1c4f920e" + integrity sha512-hsRfTEvtCZkpgad3sXHPCWMO+FWugMgzFEmOOrSWzBbqzWTIRYPc9y0VgjvArl70dHcbgx+WBSc5HTLwFOF2fw== + +apollo-tracing@0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/apollo-tracing/-/apollo-tracing-0.3.3.tgz#b819942180480c1c4d89e613cf2eff8f6d8b595a" + integrity sha512-gsTYgDVjtMlnomPq46aky7yk8XshCQfj9rxalCCismLlMomVW44fq+8GKQnZIkFOwiAsazRy4dzZ0cBbygA9sA== + dependencies: + apollo-server-env "2.2.0" + graphql-extensions "0.3.3" + +apollo-utilities@^1.0.0, apollo-utilities@^1.0.1: + version "1.0.26" + resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.0.26.tgz#589c66bf4d16223531351cf667a230c787def1da" + integrity sha512-URw7o3phymliqYCYatcird2YRPUU2eWCNvip64U9gQrX56mEfK4m99yBIDCMTpmcvOFsKLii1sIEZsHIs/bvnw== + dependencies: + fast-json-stable-stringify "^2.0.0" + +append-transform@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991" + integrity sha1-126/jKlNJ24keja61EpLdKthGZE= + dependencies: + default-require-extensions "^1.0.0" + +aproba@^1.0.3, aproba@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +aproba@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" + integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== + +aproba@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.0.4.tgz#2713680775e7614c8ba186c065d4e2e52d1072c0" + integrity sha1-JxNoB3XnYUyLoYbAZdTi5S0QcsA= + +arch@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/arch/-/arch-2.1.1.tgz#8f5c2731aa35a30929221bb0640eed65175ec84e" + integrity sha512-BLM56aPo9vLLFVa8+/+pJLnrZ7QGGTVHWsCwieAWT9o9K8UeGaQbzZbGoabWLOo2ksBCztoXdqBZBplqLDDCSg== + +archy@^1.0.0, archy@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" + integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA= + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +argle@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/argle/-/argle-1.1.1.tgz#0cfe3bc032c36b2f48ba42b9c17f89f70607e994" + integrity sha1-DP47wDLDay9IukK5wX+J9wYH6ZQ= + dependencies: + lodash.isfunction "^3.0.8" + lodash.isnumber "^3.0.3" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +args@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/args/-/args-5.0.0.tgz#8a3e376f28550f9fbdfefcb097179f2f75848efe" + integrity sha512-eCZo33yLdQ3DiG/Ko5n11uPonyYofYd9F2cqWID8TKGZwK/Z2ZcUj/oZ1HNMeNL2lgraPnv3JBZumfbUMqmZtg== + dependencies: + camelcase "5.0.0" + chalk "2.4.1" + leven "2.1.0" + mri "1.1.1" + +argv@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/argv/-/argv-0.0.2.tgz#ecbd16f8949b157183711b1bda334f37840185ab" + integrity sha1-7L0W+JSbFXGDcRsb2jNPN4QBhas= + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + integrity sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8= + dependencies: + arr-flatten "^1.0.1" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-flatten@^1.0.1, arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + +array-differ@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" + integrity sha1-7/UuN1gknTO+QCuLuOVkuytdQDE= + +array-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" + integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= + +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= + +array-ify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" + integrity sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4= + +array-index@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-index/-/array-index-1.0.0.tgz#ec56a749ee103e4e08c790b9c353df16055b97f9" + integrity sha1-7FanSe4QPk4Ix5C5w1PfFgVbl/k= + dependencies: + debug "^2.2.0" + es6-symbol "^3.0.2" + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= + dependencies: + array-uniq "^1.0.1" + +array-uniq@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.2.tgz#5fcc373920775723cfd64d65c64bef53bf9eba6d" + integrity sha1-X8w3OSB3VyPP1k1lxkvvU7+eum0= + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + integrity sha1-odl8yvy8JiXMcPrc6zalDFiwGlM= + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + +arrify@^1.0.0, arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + +asap@^2.0.0, asap@~2.0.3, asap@~2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" + integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= + +asn1.js@^4.0.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + +assert-plus@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" + integrity sha1-104bh+ev/A24qttwIfP+SBAasjQ= + +assert@^1.1.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" + integrity sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE= + dependencies: + util "0.10.3" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +ast-types@0.x.x: + version "0.11.7" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.11.7.tgz#f318bf44e339db6a320be0009ded64ec1471f46c" + integrity sha512-2mP3TwtkY/aTv5X3ZsMpNAbOnyoC/aMJwJSoaELPkHId0nSQgFcnU4dRW3isxiz7+zBexk0ym3WNVjMiQBnJSw== + +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== + +async-each@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" + integrity sha1-GdOGodntxufByF04iu28xW0zYC0= + +async-limiter@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" + integrity sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg== + +async-retry@^1.2.1: + version "1.2.3" + resolved "https://registry.yarnpkg.com/async-retry/-/async-retry-1.2.3.tgz#a6521f338358d322b1a0012b79030c6f411d1ce0" + integrity sha512-tfDb02Th6CE6pJUF2gjW5ZVjsgwlucVXOEQMvEX9JgSJMs9gAX+Nz3xRuJBKuUYjTSYORqvDBORdAQ3LU59g7Q== + dependencies: + retry "0.12.0" + +async@^1.4.0, async@~1.5: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= + +async@^2.1.4, async@^2.5.0, async@^2.6.0, async@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" + integrity sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ== + dependencies: + lodash "^4.17.10" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + +atob@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +awilix@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/awilix/-/awilix-4.0.1.tgz#c858c1d0f45851a69ce2e77f18f85ec4cb57a8f9" + integrity sha512-PYISyECR2xK+ThMSVu319pUGLkhJc/HLnk1+YNsQHQ12yhTcrhkqclPIqM7xGNgr0HNbbyoQSJZ42jd5br0cuA== + dependencies: + camel-case "^3.0.0" + glob "^7.1.3" + +aws-sign2@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" + integrity sha1-FDQt0428yU0OW4fXY81jYSwOeU8= + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.2.1, aws4@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" + integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== + +axios-mock-adapter@^1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/axios-mock-adapter/-/axios-mock-adapter-1.15.0.tgz#fbc06825d8302c95c3334d21023bba996255d45d" + integrity sha1-+8BoJdgwLJXDM00hAju6mWJV1F0= + dependencies: + deep-equal "^1.0.1" + +axios@^0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.18.0.tgz#32d53e4851efdc0a11993b6cd000789d70c05102" + integrity sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI= + dependencies: + follow-redirects "^1.3.0" + is-buffer "^1.1.5" + +b64@4.x.x: + version "4.1.2" + resolved "https://registry.yarnpkg.com/b64/-/b64-4.1.2.tgz#7015372ba8101f7fb18da070717a93c28c8580d8" + integrity sha512-+GUspBxlH3CJaxMUGUE1EBoWM6RKgWiYwUDal0qdf8m3ArnXNN1KzKVo5HOnE/FSq4HHyWf3TlHLsZI8PKQgrQ== + dependencies: + hoek "6.x.x" + +babel-code-frame@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + integrity sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-core@^6.0.0, babel-core@^6.26.0: + version "6.26.3" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" + integrity sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA== + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.1" + debug "^2.6.9" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.8" + slash "^1.0.0" + source-map "^0.5.7" + +babel-generator@^6.18.0, babel-generator@^6.26.0: + version "6.26.1" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" + integrity sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA== + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.17.4" + source-map "^0.5.7" + trim-right "^1.0.1" + +babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + integrity sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI= + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-jest@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-23.6.0.tgz#a644232366557a2240a0c083da6b25786185a2f1" + integrity sha512-lqKGG6LYXYu+DQh/slrQ8nxXQkEkhugdXsU6St7GmhVS7Ilc/22ArwqXNJrf0QaOBjZB0360qZMwXqDYQHXaew== + dependencies: + babel-plugin-istanbul "^4.1.6" + babel-preset-jest "^23.2.0" + +babel-loader@^8.0.4: + version "8.0.4" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.0.4.tgz#7bbf20cbe4560629e2e41534147692d3fecbdce6" + integrity sha512-fhBhNkUToJcW9nV46v8w87AJOwAJDz84c1CL57n3Stj73FANM/b9TbCUK4YhdOwEyZ+OxhYpdeZDNzSI29Firw== + dependencies: + find-cache-dir "^1.0.0" + loader-utils "^1.0.2" + mkdirp "^0.5.1" + util.promisify "^1.0.0" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + integrity sha1-8830cDhYA1sqKVHG7F7fbGLyYw4= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-istanbul@^4.1.6: + version "4.1.6" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz#36c59b2192efce81c5b378321b74175add1c9a45" + integrity sha512-PWP9FQ1AhZhS01T/4qLSKoHGY/xvkZdVBGlKM/HuxxS3+sC66HhTNR7+MpbO/so/cz/wY94MeSWJuP1hXIPfwQ== + dependencies: + babel-plugin-syntax-object-rest-spread "^6.13.0" + find-up "^2.1.0" + istanbul-lib-instrument "^1.10.1" + test-exclude "^4.2.1" + +babel-plugin-jest-hoist@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-23.2.0.tgz#e61fae05a1ca8801aadee57a6d66b8cefaf44167" + integrity sha1-5h+uBaHKiAGq3uV6bWa4zvr0QWc= + +babel-plugin-syntax-object-rest-spread@^6.13.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" + integrity sha1-/WU28rzhODb/o6VFjEkDpZe7O/U= + +babel-preset-jest@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-23.2.0.tgz#8ec7a03a138f001a1a8fb1e8113652bf1a55da46" + integrity sha1-jsegOhOPABoaj7HoETZSvxpV2kY= + dependencies: + babel-plugin-jest-hoist "^23.2.0" + babel-plugin-syntax-object-rest-spread "^6.13.0" + +babel-register@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" + integrity sha1-btAhFz4vy0htestFxgCahW9kcHE= + dependencies: + babel-core "^6.26.0" + babel-runtime "^6.26.0" + core-js "^2.5.0" + home-or-tmp "^2.0.0" + lodash "^4.17.4" + mkdirp "^0.5.1" + source-map-support "^0.4.15" + +babel-runtime@6.26.0, babel-runtime@^6.22.0, babel-runtime@^6.23.0, babel-runtime@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4= + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + integrity sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI= + dependencies: + babel-runtime "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + lodash "^4.17.4" + +babel-traverse@^6.0.0, babel-traverse@^6.18.0, babel-traverse@^6.26.0, babel-traverse@^6.7.3: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + integrity sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4= + dependencies: + babel-code-frame "^6.26.0" + babel-messages "^6.23.0" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + debug "^2.6.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@^6.0.0, babel-types@^6.18.0, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + integrity sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc= + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babylon@^6.1.21, babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + integrity sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ== + +backo2@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" + integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= + +backo@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/backo/-/backo-1.1.0.tgz#a36c4468923f2d265c9e8a709ea56ecdaff807e6" + integrity sha1-o2xEaJI/LSZcnopwnqVuza/4B+Y= + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base-x@^3.0.2: + version "3.0.5" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.5.tgz#d3ada59afed05b921ab581ec3112e6444ba0795a" + integrity sha512-C3picSgzPSLE+jW3tcBzJoGwitOtazb5B+5YmAxZm2ybmTi9LNgAtDO/jjVEBZwHoXmDBZ9m/IELj3elJVRBcA== + dependencies: + safe-buffer "^5.0.1" + +base64-js@^1.0.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" + integrity sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw== + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + +better-sqlite3@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-5.0.1.tgz#5addb5dcf18c9374c570a1eab7694e67fc9437a3" + integrity sha512-dyZk+gDYNPw14maYX5LG/2SCUTiB7jCvETd+bBYqhFyji3oG+UQFN452sUWSjCHCmfg1JtMbLT7WmqB8GLq8Gw== + dependencies: + integer "^2.1.0" + tar "^4.4.6" + +big-time@2.x.x: + version "2.0.1" + resolved "https://registry.yarnpkg.com/big-time/-/big-time-2.0.1.tgz#68c7df8dc30f97e953f25a67a76ac9713c16c9de" + integrity sha1-aMffjcMPl+lT8lpnp2rJcTwWyd4= + +big.js@^3.1.3: + version "3.2.0" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" + integrity sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q== + +bigi@^1.1.0, bigi@^1.2.0: + version "1.4.2" + resolved "https://registry.yarnpkg.com/bigi/-/bigi-1.4.2.tgz#9c665a95f88b8b08fc05cfd731f561859d725825" + integrity sha1-nGZalfiLiwj8Bc/XMfVhhZ1yWCU= + +bignumber.js@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-8.0.1.tgz#5d419191370fb558c64e3e5f70d68e5947138832" + integrity sha512-zAySveTJXkgLYCBi0b14xzfnOs+f3G6x36I8w2a1+PFQpWk/dp0mI0F+ZZK2bu+3ELewDcSyP+Cfq++NcHX7sg== + +binary-extensions@^1.0.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14" + integrity sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg== + +bindings@^1.2.1, bindings@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.3.0.tgz#b346f6ecf6a95f5a815c5839fc7cdb22502f1ed7" + integrity sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw== + +bip32@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bip32/-/bip32-1.0.2.tgz#982e2ad2cae6fc6a2f53dda3e6c3be9364674b28" + integrity sha512-kedLYj8yvYzND+EfzeoMSlGiN7ImiRBF/MClJSZPkMfcU+OQO7ZpL5L/Yg+TunebBZIHhunstiQF//KLKSF5rg== + dependencies: + bs58check "^2.1.1" + create-hash "^1.2.0" + create-hmac "^1.1.7" + tiny-secp256k1 "^1.0.0" + typeforce "^1.11.5" + wif "^2.0.6" + +bip38@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/bip38/-/bip38-2.0.2.tgz#6f7762bc90b0bdf63b489ff95349354aecf9baee" + integrity sha512-22KDak0RDyghFbR0Si7wyq9IgY423YzGYzWLpGeofH3DaolOQqjD3mNN08eFoubKlbyclOQKFwtONMv2SD9V3A== + dependencies: + bigi "^1.2.0" + browserify-aes "^1.0.1" + bs58check "<3.0.0" + buffer-xor "^1.0.2" + create-hash "^1.1.1" + ecurve "^1.0.0" + scryptsy "^2.0.0" + +bip39@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/bip39/-/bip39-2.5.0.tgz#51cbd5179460504a63ea3c000db3f787ca051235" + integrity sha512-xwIx/8JKoT2+IPJpFEfXoWdYwP7UVAoUxxLNfGCfVowaJE7yg1Y5B1BVPqlUNsBq5/nGwmFkwRJ8xDW4sX8OdA== + dependencies: + create-hash "^1.1.0" + pbkdf2 "^3.0.9" + randombytes "^2.0.1" + safe-buffer "^5.0.1" + unorm "^1.3.3" + +bip66@^1.1.3: + version "1.1.5" + resolved "https://registry.yarnpkg.com/bip66/-/bip66-1.1.5.tgz#01fa8748785ca70955d5011217d1b3139969ca22" + integrity sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI= + dependencies: + safe-buffer "^5.0.1" + +bl@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/bl/-/bl-1.1.2.tgz#fdca871a99713aa00d19e3bbba41c44787a65398" + integrity sha1-/cqHGplxOqANGeO7ukHER4emU5g= + dependencies: + readable-stream "~2.0.5" + +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo= + dependencies: + inherits "~2.0.0" + +bluebird@^3.4.3, bluebird@^3.4.6, bluebird@^3.5.0, bluebird@^3.5.1, bluebird@^3.5.2, bluebird@^3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.3.tgz#7d01c6f9616c9a51ab0f8c549a79dfe6ec33efa7" + integrity sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw== + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.11.3, bn.js@^4.11.8, bn.js@^4.4.0: + version "4.11.8" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" + integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== + +body-parser@1.18.3, body-parser@^1.18.3: + version "1.18.3" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.18.3.tgz#5b292198ffdd553b3a0f20ded0592b956955c8b4" + integrity sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ= + dependencies: + bytes "3.0.0" + content-type "~1.0.4" + debug "2.6.9" + depd "~1.1.2" + http-errors "~1.6.3" + iconv-lite "0.4.23" + on-finished "~2.3.0" + qs "6.5.2" + raw-body "2.3.3" + type-is "~1.6.16" + +boom@2.x.x: + version "2.10.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" + integrity sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8= + dependencies: + hoek "2.x.x" + +boom@7.x.x, boom@^7.1.0, boom@^7.1.1, boom@^7.2.0: + version "7.2.2" + resolved "https://registry.yarnpkg.com/boom/-/boom-7.2.2.tgz#ac92101451aa5cea901aed07d881dd32b4f08345" + integrity sha512-IFUbOa8PS7xqmhIjpeStwT3d09hGkNYQ6aj2iELSTxcVs2u0aKn1NzhkdUQSzsRg1FVkj3uit3I6mXQCBixw+A== + dependencies: + hoek "6.x.x" + +boom@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02" + integrity sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw== + dependencies: + hoek "4.x.x" + +boom@^7.3.0: + version "7.3.0" + resolved "https://registry.yarnpkg.com/boom/-/boom-7.3.0.tgz#733a6d956d33b0b1999da3fe6c12996950d017b9" + integrity sha512-Swpoyi2t5+GhOEGw8rEsKvTxFLIDiiKoUc2gsoV6Lyr43LHBIzch3k2MvYUs8RTROrIkVJ3Al0TkaOGjnb+B6A== + dependencies: + hoek "6.x.x" + +bounce@1.x.x: + version "1.2.3" + resolved "https://registry.yarnpkg.com/bounce/-/bounce-1.2.3.tgz#2b286d36eb21d5f08fe672dd8cd37a109baad121" + integrity sha512-3G7B8CyBnip5EahCZJjnvQ1HLyArC6P5e+xcolo13BVI9ogFaDOsNMAE7FIWliHtIkYI8/nTRCvCY9tZa3Mu4g== + dependencies: + boom "7.x.x" + hoek "6.x.x" + +boxen@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" + integrity sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw== + dependencies: + ansi-align "^2.0.0" + camelcase "^4.0.0" + chalk "^2.0.1" + cli-boxes "^1.0.0" + string-width "^2.0.0" + term-size "^1.2.0" + widest-line "^2.0.0" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + integrity sha1-uneWLhLf+WnWt2cR6RS3N4V79qc= + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +braces@^2.3.0, braces@^2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= + +browser-fingerprint@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/browser-fingerprint/-/browser-fingerprint-0.0.1.tgz#8df3cdca25bf7d5b3542d61545d730053fce604a" + integrity sha1-jfPNyiW/fVs1QtYVRdcwBT/OYEo= + +browser-process-hrtime@^0.1.2: + version "0.1.3" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz#616f00faef1df7ec1b5bf9cfe2bdc3170f26c7b4" + integrity sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw== + +browser-resolve@^1.11.3: + version "1.11.3" + resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.3.tgz#9b7cbb3d0f510e4cb86bdbd796124d28b5890af6" + integrity sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ== + dependencies: + resolve "1.1.7" + +browserify-aes@^1.0.0, browserify-aes@^1.0.1, browserify-aes@^1.0.4, browserify-aes@^1.0.6: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + integrity sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ= + dependencies: + bn.js "^4.1.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" + integrity sha1-qk62jl17ZYuqa/alfmMMvXqT0pg= + dependencies: + bn.js "^4.1.1" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.2" + elliptic "^6.0.0" + inherits "^2.0.1" + parse-asn1 "^5.0.0" + +browserify-zlib@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== + dependencies: + pako "~1.0.5" + +browserslist@^4.1.0: + version "4.3.4" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.3.4.tgz#4477b737db6a1b07077275b24791e680d4300425" + integrity sha512-u5iz+ijIMUlmV8blX82VGFrB9ecnUg5qEt55CMZ/YJEhha+d8qpBfOFuutJ6F/VKRXjZoD33b6uvarpPxcl3RA== + dependencies: + caniuse-lite "^1.0.30000899" + electron-to-chromium "^1.3.82" + node-releases "^1.0.1" + +bs58@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" + integrity sha1-vhYedsNU9veIrkBx9j806MTwpCo= + dependencies: + base-x "^3.0.2" + +bs58check@<3.0.0, bs58check@^2.1.1, bs58check@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" + integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== + dependencies: + bs58 "^4.0.0" + create-hash "^1.1.0" + safe-buffer "^5.1.2" + +bser@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.0.0.tgz#9ac78d3ed5d915804fd87acb158bc797147a1719" + integrity sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk= + dependencies: + node-int64 "^0.4.0" + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +buffer-shims@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" + integrity sha1-mXjOMXOIxkmth5MCjDR37wRKi1E= + +buffer-writer@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/buffer-writer/-/buffer-writer-2.0.0.tgz#ce7eb81a38f7829db09c873f2fbb792c0c98ec04" + integrity sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw== + +buffer-xor@^1.0.2, buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk= + +buffer@^4.3.0: + version "4.9.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + integrity sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg= + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +bugsnag@^2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/bugsnag/-/bugsnag-2.4.3.tgz#c63129d6a95b9719774ac941537412300fc79044" + integrity sha512-7gjpRE+J0BBbwYvmZeYo2ZyX3nCDX+ITqHd5wNb+t6KBXwhvuEbyJrmsDE/U32ndsV441jwaGtJ1o2ppLoQXTg== + dependencies: + backo "^1.1.0" + cuid "^1.3.8" + json-stringify-safe "~5.0.1" + promise "7.x" + request "^2.81.0" + stack-trace "~0.0.9" + +builtin-modules@^1.0.0, builtin-modules@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= + +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= + +builtins@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/builtins/-/builtins-0.0.7.tgz#355219cd6cf18dbe7c01cc7fd2dce765cfdc549a" + integrity sha1-NVIZzWzxjb58Acx/0tznZc/cVJo= + +builtins@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" + integrity sha1-y5T662HIaWRR2zZTThQi+U8K7og= + +busboy@^0.2.14: + version "0.2.14" + resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.2.14.tgz#6c2a622efcf47c57bbbe1e2a9c37ad36c7925453" + integrity sha1-bCpiLvz0fFe7vh4qnDetNseSVFM= + dependencies: + dicer "0.2.5" + readable-stream "1.1.x" + +byline@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1" + integrity sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE= + +byte-size@^4.0.3: + version "4.0.4" + resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-4.0.4.tgz#29d381709f41aae0d89c631f1c81aec88cd40b23" + integrity sha512-82RPeneC6nqCdSwCX2hZUz3JPOvN5at/nTEw/CMf05Smu3Hrpo9Psb7LjN+k+XndNArG1EY8L4+BM3aTM4BCvw== + +bytebuffer@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/bytebuffer/-/bytebuffer-5.0.1.tgz#582eea4b1a873b6d020a48d58df85f0bba6cfddd" + integrity sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0= + dependencies: + long "~3" + +bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= + +cacache@^11.0.1, cacache@^11.0.2, cacache@^11.2.0: + version "11.3.1" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.1.tgz#d09d25f6c4aca7a6d305d141ae332613aa1d515f" + integrity sha512-2PEw4cRRDu+iQvBTTuttQifacYjLPhET+SYO/gEFMy8uhi+jlJREDAjSF5FWSdV/Aw5h18caHA7vMTw2c+wDzA== + dependencies: + bluebird "^3.5.1" + chownr "^1.0.1" + figgy-pudding "^3.1.0" + glob "^7.1.2" + graceful-fs "^4.1.11" + lru-cache "^4.1.3" + mississippi "^3.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.2" + ssri "^6.0.0" + unique-filename "^1.1.0" + y18n "^4.0.0" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +cacheable-request@^2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-2.1.4.tgz#0d808801b6342ad33c91df9d0b44dc09b91e5c3d" + integrity sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0= + dependencies: + clone-response "1.0.2" + get-stream "3.0.0" + http-cache-semantics "3.8.1" + keyv "3.0.0" + lowercase-keys "1.0.0" + normalize-url "2.0.1" + responselike "1.0.2" + +call-me-maybe@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" + integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= + +call@5.x.x: + version "5.0.3" + resolved "https://registry.yarnpkg.com/call/-/call-5.0.3.tgz#5dc82c698141c2d45c51a9c3c7e0697f43ac46a2" + integrity sha512-eX16KHiAYXugbFu6VifstSdwH6aMuWWb4s0qvpq1nR1b+Sf+u68jjttg8ixDBEldPqBi30bDU35OJQWKeTLKxg== + dependencies: + boom "7.x.x" + hoek "6.x.x" + +caller-callsite@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" + integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= + dependencies: + callsites "^2.0.0" + +caller-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" + integrity sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8= + dependencies: + callsites "^0.2.0" + +caller-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" + integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= + dependencies: + caller-callsite "^2.0.0" + +callsites@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + integrity sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo= + +callsites@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" + integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= + +camel-case@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" + integrity sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M= + dependencies: + no-case "^2.2.0" + upper-case "^1.1.1" + +camelcase-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc= + dependencies: + camelcase "^2.0.0" + map-obj "^1.0.0" + +camelcase-keys@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-4.2.0.tgz#a2aa5fb1af688758259c32c141426d78923b9b77" + integrity sha1-oqpfsa9oh1glnDLBQUJteJI7m3c= + dependencies: + camelcase "^4.1.0" + map-obj "^2.0.0" + quick-lru "^1.0.0" + +camelcase@5.0.0, camelcase@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42" + integrity sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA== + +camelcase@^2.0.0, camelcase@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= + +camelcase@^4.0.0, camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= + +caniuse-lite@^1.0.30000899: + version "1.0.30000910" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000910.tgz#755d5181d4b006e5a2b59b1ffa05d0a0470039f5" + integrity sha512-u/nxtHGAzCGZzIxt3dA/tpSPOcirBZFWKwz1EPz4aaupnBI2XR0Rbr74g0zc6Hzy41OEM4uMoZ38k56TpYAWjQ== + +capture-console@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/capture-console/-/capture-console-1.0.1.tgz#db63c39ac73239019badd7fbb10143eda380ff71" + integrity sha1-22PDmscyOQGbrdf7sQFD7aOA/3E= + dependencies: + argle "~1.1.1" + lodash.isfunction "~3.0.8" + randomstring "~1.1.5" + +capture-exit@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-1.2.0.tgz#1c5fcc489fd0ab00d4f1ac7ae1072e3173fbab6f" + integrity sha1-HF/MSJ/QqwDU8ax64QcuMXP7q28= + dependencies: + rsvp "^3.3.3" + +capture-stack-trace@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d" + integrity sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw== + +caseless@~0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7" + integrity sha1-cVuW6phBWTzDMGeSP17GDr2k99c= + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + +catbox-memory@3.x.x: + version "3.1.4" + resolved "https://registry.yarnpkg.com/catbox-memory/-/catbox-memory-3.1.4.tgz#114fd6da3b2630a5db2ff246db9ff2226148c2b0" + integrity sha512-1tDnll066au0HXBSDHS/YQ34MQ2omBsmnA9g/jseyq/M3m7UPrajVtPDZK/rXgikSC1dfjo9Pa+kQ1qcyG2d3g== + dependencies: + big-time "2.x.x" + boom "7.x.x" + hoek "6.x.x" + +catbox@10.x.x: + version "10.0.5" + resolved "https://registry.yarnpkg.com/catbox/-/catbox-10.0.5.tgz#53915f0558d14e679bf10c90f6a9f79af99147b7" + integrity sha512-5SpI/tEP3SiLE1qkkV+/hdVW48sHVBEbzPX4jBiwl6hsZh/gkl4bqfGLkvh7mjpMK5evJ0Rm/6NRlhF/Jsy9ow== + dependencies: + boom "7.x.x" + hoek "6.x.x" + joi "14.x.x" + +chalk@2.4.1, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.1, chalk@^2.3.2, chalk@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" + integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chardet@^0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" + integrity sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I= + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + +chokidar@^2.0.2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26" + integrity sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.0" + braces "^2.3.0" + glob-parent "^3.1.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + lodash.debounce "^4.0.8" + normalize-path "^2.1.1" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + upath "^1.0.5" + optionalDependencies: + fsevents "^1.2.2" + +chownr@^1.0.1, chownr@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" + integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== + +chownr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" + integrity sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE= + +chrome-trace-event@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.0.tgz#45a91bd2c20c9411f0963b5aaeb9a1b95e09cc48" + integrity sha512-xDbVgyfDTT2piup/h8dK/y4QZfJRSa73bw1WZ8b4XM1o7fsFubUVGYcE+1ANtOzJJELGpYoG2961z0Z6OAld9A== + dependencies: + tslib "^1.9.0" + +ci-info@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" + integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== + +cint@^8.2.1: + version "8.2.1" + resolved "https://registry.yarnpkg.com/cint/-/cint-8.2.1.tgz#70386b1b48e2773d0d63166a55aff94ef4456a12" + integrity sha1-cDhrG0jidz0NYxZqVa/5TvRFahI= + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +circular-json@^0.3.1: + version "0.3.3" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" + integrity sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A== + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +clean-stack@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-1.3.0.tgz#9e821501ae979986c46b1d66d2d432db2fd4ae31" + integrity sha1-noIVAa6XmYbEax1m0tQy2y/UrjE= + +cli-boxes@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-1.0.0.tgz#4fa917c3e59c94a004cd61f8ee509da651687143" + integrity sha1-T6kXw+WclKAEzWH47lCdplFocUM= + +cli-cursor@^2.0.0, cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= + dependencies: + restore-cursor "^2.0.0" + +cli-progress@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-progress/-/cli-progress-2.1.0.tgz#a212e7e6b685687644ca703904ea49c34ee302c8" + integrity sha512-mY0GFIADTooScUe8ERTiQjJoOvXv1z0SzA8gzKO8imLqB7tBwEnNN10gWHcKoltDL4gLdi1GGoPEbxxbvJtR4A== + dependencies: + colors "^1.1.2" + string-width "^2.1.1" + +cli-table3@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202" + integrity sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw== + dependencies: + object-assign "^4.1.0" + string-width "^2.1.1" + optionalDependencies: + colors "^1.1.2" + +cli-table@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.1.tgz#f53b05266a8b1a0b934b3d0821e6e2dc5914ae23" + integrity sha1-9TsFJmqLGguTSz0IIebi3FkUriM= + dependencies: + colors "1.0.3" + +cli-truncate@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574" + integrity sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ= + dependencies: + slice-ansi "0.0.4" + string-width "^1.0.1" + +cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= + +clipboardy@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/clipboardy/-/clipboardy-1.2.3.tgz#0526361bf78724c1f20be248d428e365433c07ef" + integrity sha512-2WNImOvCRe6r63Gk9pShfkwXsVtKCroMAevIbiae021mS850UkWPbevxsBz3tnvjZIEGvlwaqCPsw+4ulzNgJA== + dependencies: + arch "^2.1.0" + execa "^0.8.0" + +cliui@^3.0.3, cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + +cliui@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" + integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrap-ansi "^2.0.0" + +clone-deep@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-0.3.0.tgz#348c61ae9cdbe0edfe053d91ff4cc521d790ede8" + integrity sha1-NIxhrpzb4O3+BT2R/0zFIdeQ7eg= + dependencies: + for-own "^1.0.0" + is-plain-object "^2.0.1" + kind-of "^3.2.2" + shallow-clone "^0.1.2" + +clone-response@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" + integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= + dependencies: + mimic-response "^1.0.0" + +clone@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= + +cls-bluebird@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cls-bluebird/-/cls-bluebird-2.1.0.tgz#37ef1e080a8ffb55c2f4164f536f1919e7968aee" + integrity sha1-N+8eCAqP+1XC9BZPU28ZGeeWiu4= + dependencies: + is-bluebird "^1.0.2" + shimmer "^1.1.0" + +cmd-shim@^2.0.2, cmd-shim@~2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-2.0.2.tgz#6fcbda99483a8fd15d7d30a196ca69d688a2efdb" + integrity sha1-b8vamUg6j9FdfTChlspp1oii79s= + dependencies: + graceful-fs "^4.1.2" + mkdirp "~0.5.0" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + +codecov@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/codecov/-/codecov-3.1.0.tgz#340bd968d361f256976b5af782dd8ba9f82bc849" + integrity sha512-aWQc/rtHbcWEQLka6WmBAOpV58J2TwyXqlpAQGhQaSiEUoigTTUk6lLd2vB3kXkhnDyzyH74RXfmV4dq2txmdA== + dependencies: + argv "^0.0.2" + ignore-walk "^3.0.1" + js-yaml "^3.12.0" + request "^2.87.0" + urlgrey "^0.4.4" + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0, color-convert@^1.9.1: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +color-string@^1.5.2: + version "1.5.3" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc" + integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw== + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +color@3.0.x: + version "3.0.0" + resolved "https://registry.yarnpkg.com/color/-/color-3.0.0.tgz#d920b4328d534a3ac8295d68f7bd4ba6c427be9a" + integrity sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w== + dependencies: + color-convert "^1.9.1" + color-string "^1.5.2" + +colornames@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/colornames/-/colornames-1.1.1.tgz#f8889030685c7c4ff9e2a559f5077eb76a816f96" + integrity sha1-+IiQMGhcfE/54qVZ9Qd+t2qBb5Y= + +colors@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" + integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs= + +colors@^1.1.2, colors@^1.2.1, colors@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.2.tgz#2df8ff573dfbf255af562f8ce7181d6b971a359b" + integrity sha512-rhP0JSBGYvpcNQj4s5AdShMeE5ahMop96cTeDl/v9qQQm2fYClE2QXZRi8wLzc+GmXSxdIqqbOIAhyObEXDbfQ== + +colorspace@1.1.x: + version "1.1.1" + resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.1.1.tgz#9ac2491e1bc6f8fb690e2176814f8d091636d972" + integrity sha512-pI3btWyiuz7Ken0BWh9Elzsmv2bM9AhA7psXib4anUXy/orfZ/E0MbQwhSOG/9L8hLlalqrU0UhOuqxW1YjmVw== + dependencies: + color "3.0.x" + text-hex "1.0.x" + +columnify@^1.5.4, columnify@~1.5.4: + version "1.5.4" + resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.5.4.tgz#4737ddf1c7b69a8a7c340570782e947eec8e78bb" + integrity sha1-Rzfd8ce2mop8NAVweC6UfuyOeLs= + dependencies: + strip-ansi "^3.0.0" + wcwidth "^1.0.0" + +combined-stream@^1.0.5, combined-stream@^1.0.6, combined-stream@~1.0.5, combined-stream@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.7.tgz#2d1d24317afb8abe95d6d2c0b07b57813539d828" + integrity sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w== + dependencies: + delayed-stream "~1.0.0" + +commander@2.19.0, commander@^2.14.1, commander@^2.19.0, commander@^2.9.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" + integrity sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg== + +commander@~2.17.1: + version "2.17.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" + integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + +compare-func@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/compare-func/-/compare-func-1.3.2.tgz#99dd0ba457e1f9bc722b12c08ec33eeab31fa648" + integrity sha1-md0LpFfh+bxyKxLAjsM+6rMfpkg= + dependencies: + array-ify "^1.0.0" + dot-prop "^3.0.0" + +component-emitter@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +concat-stream@^1.5.0, concat-stream@^1.5.2, concat-stream@^1.6.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +config-chain@^1.1.11, config-chain@~1.1.11: + version "1.1.12" + resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa" + integrity sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA== + dependencies: + ini "^1.3.4" + proto-list "~1.2.1" + +configstore@^3.0.0, configstore@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-3.1.2.tgz#c6f25defaeef26df12dd33414b001fe81a543f8f" + integrity sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw== + dependencies: + dot-prop "^4.1.0" + graceful-fs "^4.1.2" + make-dir "^1.0.0" + unique-string "^1.0.0" + write-file-atomic "^2.0.0" + xdg-basedir "^3.0.0" + +console-browserify@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" + integrity sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA= + dependencies: + date-now "^0.1.4" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= + +contains-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" + integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= + +content-disposition@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" + integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ= + +content-type@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +content@4.x.x: + version "4.0.6" + resolved "https://registry.yarnpkg.com/content/-/content-4.0.6.tgz#76ffd96c5cbccf64fe3923cbb9c48b8bc04b273e" + integrity sha512-lR9ND3dXiMdmsE84K6l02rMdgiBVmtYWu1Vr/gfSGHcIcznBj2QxmSdUgDuNFOA+G9yrb1IIWkZ7aKtB6hDGyA== + dependencies: + boom "7.x.x" + +conventional-changelog-angular@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-5.0.2.tgz#39d945635e03b6d0c9d4078b1df74e06163dc66a" + integrity sha512-yx7m7lVrXmt4nKWQgWZqxSALEiAKZhOAcbxdUaU9575mB0CzXVbgrgpfSnSP7OqWDUTYGD0YVJ0MSRdyOPgAwA== + dependencies: + compare-func "^1.3.1" + q "^1.5.1" + +conventional-changelog-core@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/conventional-changelog-core/-/conventional-changelog-core-3.1.5.tgz#c2edf928539308b54fe1b90a2fc731abc021852c" + integrity sha512-iwqAotS4zk0wA4S84YY1JCUG7X3LxaRjJxuUo6GI4dZuIy243j5nOg/Ora35ExT4DOiw5dQbMMQvw2SUjh6moQ== + dependencies: + conventional-changelog-writer "^4.0.2" + conventional-commits-parser "^3.0.1" + dateformat "^3.0.0" + get-pkg-repo "^1.0.0" + git-raw-commits "2.0.0" + git-remote-origin-url "^2.0.0" + git-semver-tags "^2.0.2" + lodash "^4.2.1" + normalize-package-data "^2.3.5" + q "^1.5.1" + read-pkg "^3.0.0" + read-pkg-up "^3.0.0" + through2 "^2.0.0" + +conventional-changelog-preset-loader@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.0.2.tgz#81d1a07523913f3d17da3a49f0091f967ad345b0" + integrity sha512-pBY+qnUoJPXAXXqVGwQaVmcye05xi6z231QM98wHWamGAmu/ghkBprQAwmF5bdmyobdVxiLhPY3PrCfSeUNzRQ== + +conventional-changelog-writer@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-4.0.2.tgz#eb493ed84269e7a663da36e49af51c54639c9a67" + integrity sha512-d8/FQY/fix2xXEBUhOo8u3DCbyEw3UOQgYHxLsPDw+wHUDma/GQGAGsGtoH876WyNs32fViHmTOUrgRKVLvBug== + dependencies: + compare-func "^1.3.1" + conventional-commits-filter "^2.0.1" + dateformat "^3.0.0" + handlebars "^4.0.2" + json-stringify-safe "^5.0.1" + lodash "^4.2.1" + meow "^4.0.0" + semver "^5.5.0" + split "^1.0.0" + through2 "^2.0.0" + +conventional-commits-filter@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/conventional-commits-filter/-/conventional-commits-filter-2.0.1.tgz#55a135de1802f6510b6758e0a6aa9e0b28618db3" + integrity sha512-92OU8pz/977udhBjgPEbg3sbYzIxMDFTlQT97w7KdhR9igNqdJvy8smmedAAgn4tPiqseFloKkrVfbXCVd+E7A== + dependencies: + is-subset "^0.1.1" + modify-values "^1.0.0" + +conventional-commits-parser@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-3.0.1.tgz#fe1c49753df3f98edb2285a5e485e11ffa7f2e4c" + integrity sha512-P6U5UOvDeidUJ8ebHVDIoXzI7gMlQ1OF/id6oUvp8cnZvOXMt1n8nYl74Ey9YMn0uVQtxmCtjPQawpsssBWtGg== + dependencies: + JSONStream "^1.0.4" + is-text-path "^1.0.0" + lodash "^4.2.1" + meow "^4.0.0" + split2 "^2.0.0" + through2 "^2.0.0" + trim-off-newlines "^1.0.0" + +conventional-recommended-bump@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/conventional-recommended-bump/-/conventional-recommended-bump-4.0.4.tgz#05540584641d3da758c8863c09788fcaeb586872" + integrity sha512-9mY5Yoblq+ZMqJpBzgS+RpSq+SUfP2miOR3H/NR9drGf08WCrY9B6HAGJZEm6+ThsVP917VHAahSOjM6k1vhPg== + dependencies: + concat-stream "^1.6.0" + conventional-changelog-preset-loader "^2.0.2" + conventional-commits-filter "^2.0.1" + conventional-commits-parser "^3.0.1" + git-raw-commits "2.0.0" + git-semver-tags "^2.0.2" + meow "^4.0.0" + q "^1.5.1" + +convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.5.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" + integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== + dependencies: + safe-buffer "~5.1.1" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= + +cookie@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= + +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +core-js@^1.1.1: + version "1.2.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" + integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY= + +core-js@^2.4.0, core-js@^2.5.0, core-js@^2.5.7: + version "2.5.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" + integrity sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw== + +core-js@^3.0.0-beta.3: + version "3.0.0-beta.3" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.0.0-beta.3.tgz#b0f22009972b8c6c04550ebf38513ca4b3cc9559" + integrity sha512-kM/OfrnMThP5PwGAj5HhQLdjUqzjrllqN2EVnk/X9qrLsfYjR2hzZ+E/8CzH0xuosexZtqMTLQrk//BULrBj9w== + +core-js@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.3.0.tgz#fab83fbb0b2d8dc85fa636c4b9d34c75420c6d65" + integrity sha1-+rg/uwstjchfpjbEudNMdUIMbWU= + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +cosmiconfig@5.0.6: + version "5.0.6" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.6.tgz#dca6cf680a0bd03589aff684700858c81abeeb39" + integrity sha512-6DWfizHriCrFWURP1/qyhsiFvYdlJzbCzmtFWh744+KyWsJo5+kPzUZZaMRSSItoYc0pxFX7gEO7ZC1/gN/7AQ== + dependencies: + is-directory "^0.3.1" + js-yaml "^3.9.0" + parse-json "^4.0.0" + +cosmiconfig@^5.0.2, cosmiconfig@^5.0.6: + version "5.0.7" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.7.tgz#39826b292ee0d78eda137dfa3173bd1c21a43b04" + integrity sha512-PcLqxTKiDmNT6pSpy4N6KtuPwb53W+2tzNvwOZw0WH9N6O0vLIBq0x8aj8Oj75ere4YcGi48bDFCL+3fRJdlNA== + dependencies: + import-fresh "^2.0.0" + is-directory "^0.3.1" + js-yaml "^3.9.0" + parse-json "^4.0.0" + +create-ecdh@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" + integrity sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw== + dependencies: + bn.js "^4.1.0" + elliptic "^6.0.0" + +create-error-class@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" + integrity sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y= + dependencies: + capture-stack-trace "^1.0.0" + +create-hash@^1.1.0, create-hash@^1.1.1, create-hash@^1.1.2, create-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4, create-hmac@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +cross-env@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.2.0.tgz#6ecd4c015d5773e614039ee529076669b9d126f2" + integrity sha512-jtdNFfFW1hB7sMhr/H6rW1Z45LFqyI431m3qU6bFXcQ3Eh7LtBuG3h74o7ohHZ3crrRkkqHlo4jYHFPcjroANg== + dependencies: + cross-spawn "^6.0.5" + is-windows "^1.0.0" + +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^6.0.0, cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +cryptiles@2.x.x: + version "2.0.5" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" + integrity sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g= + dependencies: + boom "2.x.x" + +cryptiles@4.x.x: + version "4.1.3" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-4.1.3.tgz#2461d3390ea0b82c643a6ba79f0ed491b0934c25" + integrity sha512-gT9nyTMSUC1JnziQpPbxKGBbUg8VL7Zn2NB4E1cJYvuXdElHrwxrV9bmltZGDzet45zSDGyYceueke1TjynGzw== + dependencies: + boom "7.x.x" + +crypto-browserify@^3.11.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +crypto-random-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" + integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4= + +cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": + version "0.3.4" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.4.tgz#8cd52e8a3acfd68d3aed38ee0a640177d2f9d797" + integrity sha512-+7prCSORpXNeR4/fUP3rL+TzqtiFfhMvTd7uEqMdgPvLPt4+uzFUeufx5RHjGTACCargg/DiEt/moMQmvnfkog== + +cssstyle@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.1.1.tgz#18b038a9c44d65f7a8e428a653b9f6fe42faf5fb" + integrity sha512-364AI1l/M5TYcFH83JnOH/pSqgaNnKmYgKrm0didZMGKWjQB60dymwWy1rKUgL3J1ffdq9xVi2yGLHdSjjSNog== + dependencies: + cssom "0.3.x" + +cuid@^1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/cuid/-/cuid-1.3.8.tgz#4b875e0969bad764f7ec0706cf44f5fb0831f6b7" + integrity sha1-S4deCWm612T37AcGz0T1+wgx9rc= + dependencies: + browser-fingerprint "0.0.1" + core-js "^1.1.1" + node-fingerprint "0.0.2" + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= + dependencies: + array-find-index "^1.0.1" + +cycle@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/cycle/-/cycle-1.0.3.tgz#21e80b2be8580f98b468f379430662b046c34ad2" + integrity sha1-IegLK+hYD5i0aPN5QwZisEbDStI= + +cyclist@~0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" + integrity sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA= + +d@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" + integrity sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8= + dependencies: + es5-ext "^0.10.9" + +dargs@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/dargs/-/dargs-4.1.0.tgz#03a9dbb4b5c2f139bf14ae53f0b8a2a6a86f4e17" + integrity sha1-A6nbtLXC8Tm/FK5T8LiipqhvThc= + dependencies: + number-is-nan "^1.0.0" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + +data-uri-to-buffer@1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz#77163ea9c20d8641b4707e8f18abdf9a78f34835" + integrity sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ== + +data-urls@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe" + integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ== + dependencies: + abab "^2.0.0" + whatwg-mimetype "^2.2.0" + whatwg-url "^7.0.0" + +date-fns@^1.27.2: + version "1.29.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6" + integrity sha512-lbTXWZ6M20cWH8N9S6afb0SBm6tMk+uUg6z3MqHPKE9atmsY3kJkTm8vKe93izJ2B2+q5MV990sM2CHgtAZaOw== + +date-now@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" + integrity sha1-6vQ5/U1ISK105cx9vvIAZyueNFs= + +dateformat@^3.0.0, dateformat@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" + integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== + +dayjs-ext@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/dayjs-ext/-/dayjs-ext-2.2.0.tgz#2d1ed1e2a8dccc260122d4685e8422062edc5dbb" + integrity sha512-n7u711rSmAOPcx1xqj2WUSU/1PbWEst1VC/FeIQsC/ULQLNVlAUwYwRc8D1CdTWqZgliw/SVcox+xNyQl9Q4IA== + dependencies: + fast-plural-rules "^0.0.1" + timezone-support "^1.8.0" + +debug@2, debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@3.1.0, debug@=3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +debug@^3, debug@^3.1.0, debug@^3.2.5: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + +debug@^4.0.1, debug@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.0.tgz#373687bffa678b38b1cd91f861b63850035ddc87" + integrity sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg== + dependencies: + ms "^2.1.1" + +debuglog@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" + integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= + +decamelize-keys@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" + integrity sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk= + dependencies: + decamelize "^1.1.0" + map-obj "^1.0.0" + +decamelize@^1.1.0, decamelize@^1.1.1, decamelize@^1.1.2, decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= + dependencies: + mimic-response "^1.0.0" + +dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= + +deep-equal@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +deepmerge@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-2.2.1.tgz#5d3ff22a01c00f645405a2fbc17d0778a1801170" + integrity sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA== + +default-require-extensions@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8" + integrity sha1-836hXT4T/9m0N9M+GnW1+5eHTLg= + dependencies: + strip-bom "^2.0.0" + +defaults@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" + integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= + dependencies: + clone "^1.0.2" + +define-properties@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +degenerator@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-1.0.4.tgz#fcf490a37ece266464d9cc431ab98c5819ced095" + integrity sha1-/PSQo37OJmRk2cxDGrmMWBnO0JU= + dependencies: + ast-types "0.x.x" + escodegen "1.x.x" + esprima "3.x.x" + +del@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/del/-/del-3.0.0.tgz#53ecf699ffcbcb39637691ab13baf160819766e5" + integrity sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU= + dependencies: + globby "^6.1.0" + is-path-cwd "^1.0.0" + is-path-in-cwd "^1.0.0" + p-map "^1.1.1" + pify "^3.0.0" + rimraf "^2.2.8" + +delay@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/delay/-/delay-4.1.0.tgz#474cd28809da41d1a048a70a1d835f47ac377cd2" + integrity sha512-8Hea6/aOu3bPdDBQhSRUEUzF0QwuWmSPuIK+sxNdvcJtSfzb6HXrTd9DFJBCJcV9o83fFECqTgllqdnmUfq9+w== + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + +depcheck@^0.6.11: + version "0.6.11" + resolved "https://registry.yarnpkg.com/depcheck/-/depcheck-0.6.11.tgz#6b616f2cf8c44ddcfdc5d7c7f7759bc53b479262" + integrity sha512-wTVJ8cNilB8NfkzoBblcYqsB8LRfbjqKEwAOLD3YXIRigktSM7/lS9xQfVkAVujhjstmiQMZR0hkdHSnQxzb9A== + dependencies: + babel-traverse "^6.7.3" + babylon "^6.1.21" + builtin-modules "^1.1.1" + deprecate "^1.0.0" + deps-regex "^0.1.4" + js-yaml "^3.4.2" + lodash "^4.5.1" + minimatch "^3.0.2" + require-package-name "^2.0.1" + walkdir "0.0.11" + yargs "^8.0.2" + +depd@^1.1.0, depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +deprecate@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/deprecate/-/deprecate-1.1.0.tgz#bbd069d62b232175b4e8459b2650cd2bad51f4b8" + integrity sha512-b5dDNQYdy2vW9WXUD8+RQlfoxvqztLLhDE+T7Gd37I5E8My7nJkKu6FmhdDeRWJ8B+yjZKuwjCta8pgi8kgSqA== + +deprecated-decorator@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/deprecated-decorator/-/deprecated-decorator-0.1.6.tgz#00966317b7a12fe92f3cc831f7583af329b86c37" + integrity sha1-AJZjF7ehL+kvPMgx91g68ym4bDc= + +deps-regex@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deps-regex/-/deps-regex-0.1.4.tgz#518667b7691460a5e7e0a341be76eb7ce8090184" + integrity sha1-UYZnt2kUYKXn4KNBvnbrfOgJAYQ= + +des.js@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" + integrity sha1-wHTS4qpqipoH29YfmhXCzYPsjsw= + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + integrity sha1-920GQ1LN9Docts5hnE7jqUdd4gg= + dependencies: + repeating "^2.0.0" + +detect-indent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" + integrity sha1-OHHMCmoALow+Wzz38zYmRnXwa50= + +detect-libc@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= + +detect-newline@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" + integrity sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I= + +dezalgo@^1.0.0, dezalgo@^1.0.1, dezalgo@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.3.tgz#7f742de066fc748bc8db820569dddce49bf0d456" + integrity sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY= + dependencies: + asap "^2.0.0" + wrappy "1" + +diagnostics@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/diagnostics/-/diagnostics-1.1.1.tgz#cab6ac33df70c9d9a727490ae43ac995a769b22a" + integrity sha512-8wn1PmdunLJ9Tqbx+Fx/ZEuHfJf4NKSN2ZBj7SJC/OWRWha843+WsTjqMe1B5E3p28jqBlp+mJ2fPVxPyNgYKQ== + dependencies: + colorspace "1.1.x" + enabled "1.0.x" + kuler "1.0.x" + +dicer@0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/dicer/-/dicer-0.2.5.tgz#5996c086bb33218c812c090bddc09cd12facb70f" + integrity sha1-WZbAhrszIYyBLAkL3cCc0S+stw8= + dependencies: + readable-stream "1.1.x" + streamsearch "0.1.2" + +diff@^3.2.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +dir-glob@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034" + integrity sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag== + dependencies: + arrify "^1.0.1" + path-type "^3.0.0" + +directory-tree@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/directory-tree/-/directory-tree-2.1.1.tgz#db42ab3bda37b0e7de51654ce9709b49cea2ba55" + integrity sha512-9uaftXCRHRntOsmeSxTMLNp52N0tb5eSXkLTIdbDnuC85lleB6/Xub6CG4swSrkS5XXHA56OpTiRj5ntRlsjCg== + +docdash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/docdash/-/docdash-1.0.0.tgz#5b7df10fed3d341fc4416a8978c65ad561869d18" + integrity sha512-HhK72PT4z55og8FDqskO/tTYXxU+LovRz+9pCDHLnUoPchkxjdIJidS+96LqW3CLrRdBmnkDRrcVrDFGLIluTw== + +dockerfile-ast@0.0.12: + version "0.0.12" + resolved "https://registry.yarnpkg.com/dockerfile-ast/-/dockerfile-ast-0.0.12.tgz#6f25f6ad55eeecdd297ab68b08be1b32e64b5aeb" + integrity sha512-cIV8oXkAxpIuN5XgG0TGg07nLDgrj4olkfrdT77OTA3VypscsYHBUg/FjHxW9K3oA+CyH4Th/qtoMgTVpzSobw== + dependencies: + vscode-languageserver-types "^3.5.0" + +doctrine@1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" + integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== + dependencies: + esutils "^2.0.2" + +domain-browser@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== + +domexception@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" + integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug== + dependencies: + webidl-conversions "^4.0.2" + +dot-prop@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-3.0.0.tgz#1b708af094a49c9a0e7dbcad790aba539dac1177" + integrity sha1-G3CK8JSknJoOfbyteQq6U52sEXc= + dependencies: + is-obj "^1.0.0" + +dot-prop@^4.1.0, dot-prop@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" + integrity sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ== + dependencies: + is-obj "^1.0.0" + +dottie@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/dottie/-/dottie-2.0.1.tgz#697ad9d72004db7574d21f892466a3c285893659" + integrity sha512-ch5OQgvGDK2u8pSZeSYAQaV/lczImd7pMJ7BcEPXmnFVjy4yJIzP6CsODJUTH8mg1tyH1Z2abOiuJO3DjZ/GBw== + +drbg.js@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/drbg.js/-/drbg.js-1.0.1.tgz#3e36b6c42b37043823cdbc332d58f31e2445480b" + integrity sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs= + dependencies: + browserify-aes "^1.0.6" + create-hash "^1.1.2" + create-hmac "^1.1.4" + +ducky@2.6.11: + version "2.6.11" + resolved "https://registry.yarnpkg.com/ducky/-/ducky-2.6.11.tgz#b1ed769398a4b563d3dd55c0b28ab8b93bcfe3de" + integrity sha512-ubD7rFjOg29Y7UBVZNUzM0S5LuKfqA/wkszwgH/TuXH/Vgr3OFoVBpRb8qoCW3mwexS9bCMD1PEXJDzShzw5EQ== + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= + +duplexer@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + integrity sha1-rOb/gIwc5mtX0ev5eXessCM0z8E= + +duplexify@^3.4.2, duplexify@^3.5.3, duplexify@^3.6.0: + version "3.6.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.6.1.tgz#b1a7a29c4abfd639585efaecce80d666b1e34125" + integrity sha512-vM58DwdnKmty+FSPzT14K9JXb90H+j5emaR4KYbr2KTIz00WHGbWOe5ghQTx233ZCLZtrGDALzKwcjEtSt35mA== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +eachr@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/eachr/-/eachr-3.2.0.tgz#2c35e43ea086516f7997cf80b7aa64d55a4a4484" + integrity sha1-LDXkPqCGUW95l8+At6pk1VpKRIQ= + dependencies: + editions "^1.1.1" + typechecker "^4.3.0" + +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + +ecurve@^1.0.0: + version "1.0.6" + resolved "https://registry.yarnpkg.com/ecurve/-/ecurve-1.0.6.tgz#dfdabbb7149f8d8b78816be5a7d5b83fcf6de797" + integrity sha512-/BzEjNfiSuB7jIWKcS/z8FK9jNjmEWvUV2YZ4RLSmcDtP7Lq0m6FvDuSnJpBlDpGRpfRQeTLGLBI8H+kEv0r+w== + dependencies: + bigi "^1.1.0" + safe-buffer "^5.0.1" + +editions@^1.1.1, editions@^1.3.3, editions@^1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/editions/-/editions-1.3.4.tgz#3662cb592347c3168eb8e498a0ff73271d67f50b" + integrity sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg== + +editions@^2.0.2: + version "2.1.0" + resolved "https://registry.yarnpkg.com/editions/-/editions-2.1.0.tgz#5c6f6341ef19ee362a3bcbb907fe68e696dbc69e" + integrity sha512-yKrimWcvOXcYXtqsOeebbMLynm9qbYVd0005wveGU2biPxJaJoxA0jtaZrxiMe3mAanLr5lxoYFVz5zjv9JdnA== + dependencies: + errlop "^1.0.3" + semver "^5.6.0" + +editor@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/editor/-/editor-1.0.0.tgz#60c7f87bd62bcc6a894fa8ccd6afb7823a24f742" + integrity sha1-YMf4e9YrzGqJT6jM1q+3gjok90I= + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +elasticsearch@^15.2.0: + version "15.2.0" + resolved "https://registry.yarnpkg.com/elasticsearch/-/elasticsearch-15.2.0.tgz#234362b5aa743d9c0a925566569ea7813b8f2569" + integrity sha512-jOFcBoEh3Sn3gjUTozInODZTLriJtfppAUC7jnQCUE+OUj8o7GoAyC+L4h/L3ZxmXNFbQCunqVR+nmSofHdo9A== + dependencies: + agentkeepalive "^3.4.1" + chalk "^1.0.0" + lodash "^4.17.10" + +electron-to-chromium@^1.3.82: + version "1.3.84" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.84.tgz#2e55df59e818f150a9f61b53471ebf4f0feecc65" + integrity sha512-IYhbzJYOopiTaNWMBp7RjbecUBsbnbDneOP86f3qvS0G0xfzwNSvMJpTrvi5/Y1gU7tg2NAgeg8a8rCYvW9Whw== + +elegant-spinner@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" + integrity sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4= + +elliptic@^6.0.0, elliptic@^6.2.3, elliptic@^6.4.0: + version "6.4.1" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.1.tgz#c2d0b7776911b86722c632c3c06c60f2f819939a" + integrity sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ== + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + +email-validator@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/email-validator/-/email-validator-2.0.4.tgz#b8dfaa5d0dae28f1b03c95881d904d4e40bfe7ed" + integrity sha512-gYCwo7kh5S3IDyZPLZf6hSS0MnZT8QmJFqYvbqlDZSbwdZlY6QZWxJ4i/6UhITOJ4XzyI647Bm2MXKCLqnJ4nQ== + +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= + +enabled@1.0.x: + version "1.0.2" + resolved "https://registry.yarnpkg.com/enabled/-/enabled-1.0.2.tgz#965f6513d2c2d1c5f4652b64a2e3396467fc2f93" + integrity sha1-ll9lE9LC0cX0ZStkouM5ZGf8L5M= + dependencies: + env-variable "0.0.x" + +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= + +encoding@^0.1.11: + version "0.1.12" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" + integrity sha1-U4tm8+5izRq1HsMjgp0flIDHS+s= + dependencies: + iconv-lite "~0.4.13" + +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" + integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== + dependencies: + once "^1.4.0" + +enhanced-resolve@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f" + integrity sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng== + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.4.0" + tapable "^1.0.0" + +env-variable@0.0.x: + version "0.0.5" + resolved "https://registry.yarnpkg.com/env-variable/-/env-variable-0.0.5.tgz#913dd830bef11e96a039c038d4130604eba37f88" + integrity sha512-zoB603vQReOFvTg5xMl9I1P2PnHsHQQKTEowsKKD7nseUfJq6UWzK+4YtlWUO1nhiQUxe6XMkk+JleSZD1NZFA== + +envfile@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/envfile/-/envfile-2.3.0.tgz#0ced8f8846e45e2868623c54ecfe3d1914b1e3f4" + integrity sha512-xcwno0xGhSVhgBfFx9SxwYd6FNfTdq8SMFjrQ4FYsxYUNQMPJTXn7dERrX439F1V4Ukk9x/nL/5GcNZaIVUT7g== + dependencies: + ambi "^2.4.0" + eachr "^3.1.0" + editions "^1.3.3" + typechecker "^4.0.1" + +err-code@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/err-code/-/err-code-1.1.2.tgz#06e0116d3028f6aef4806849eb0ea6a748ae6960" + integrity sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA= + +errlop@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/errlop/-/errlop-1.0.3.tgz#dba29c90cf832c3d2ce469fe515d7e5eef2c6676" + integrity sha512-5VTnt0yikY4LlQEfCXVSqfE6oLj1HVM4zVSvAKMnoYjL/zrb6nqiLowZS4XlG7xENfyj7lpYWvT+wfSCr6dtlA== + dependencies: + editions "^1.3.4" + +errno@^0.1.3, errno@~0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" + integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== + dependencies: + prr "~1.0.1" + +error-ex@^1.2.0, error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.5.1, es-abstract@^1.6.1: + version "1.12.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165" + integrity sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA== + dependencies: + es-to-primitive "^1.1.1" + function-bind "^1.1.1" + has "^1.0.1" + is-callable "^1.1.3" + is-regex "^1.0.4" + +es-to-primitive@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" + integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14: + version "0.10.46" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.46.tgz#efd99f67c5a7ec789baa3daa7f79870388f7f572" + integrity sha512-24XxRvJXNFwEMpJb3nOkiRJKRoupmjYmOPVlI65Qy2SrtxwOTB+g6ODjBKOtwEHbYrhWRty9xxOWLNdClT2djw== + dependencies: + es6-iterator "~2.0.3" + es6-symbol "~3.1.1" + next-tick "1" + +es6-iterator@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-promise@^4.0.3: + version "4.2.5" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.5.tgz#da6d0d5692efb461e082c14817fe2427d8f5d054" + integrity sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg== + +es6-promise@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.0.2.tgz#010d5858423a5f118979665f46486a95c6ee2bb6" + integrity sha1-AQ1YWEI6XxGJeWZfRkhqlcbuK7Y= + +es6-promisify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" + integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= + dependencies: + es6-promise "^4.0.3" + +es6-symbol@^3.0.2, es6-symbol@^3.1.1, es6-symbol@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" + integrity sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc= + dependencies: + d "1" + es5-ext "~0.10.14" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.4, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +escodegen@1.x.x, escodegen@^1.9.1: + version "1.11.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.11.0.tgz#b27a9389481d5bfd5bec76f7bb1eb3f8f4556589" + integrity sha512-IeMV45ReixHS53K/OmfKAIztN/igDHzTJUhZM3k1jMhIZWjk45SMwAtBsEXiJp3vSPmTcu6CXn7mDvFHRN66fw== + dependencies: + esprima "^3.1.3" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +eslint-config-airbnb-base@^13.1.0: + version "13.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-13.1.0.tgz#b5a1b480b80dfad16433d6c4ad84e6605052c05c" + integrity sha512-XWwQtf3U3zIoKO1BbHh6aUhJZQweOwSt4c2JrPDg9FP3Ltv3+YfEv7jIDB8275tVnO/qOHbfuYg3kzw6Je7uWw== + dependencies: + eslint-restricted-globals "^0.1.1" + object.assign "^4.1.0" + object.entries "^1.0.4" + +eslint-config-prettier@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-3.3.0.tgz#41afc8d3b852e757f06274ed6c44ca16f939a57d" + integrity sha512-Bc3bh5bAcKNvs3HOpSi6EfGA2IIp7EzWcg2tS4vP7stnXu/J1opihHDM7jI9JCIckyIDTgZLSWn7J3HY0j2JfA== + dependencies: + get-stdin "^6.0.0" + +eslint-import-resolver-node@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a" + integrity sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q== + dependencies: + debug "^2.6.9" + resolve "^1.5.0" + +eslint-module-utils@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz#b270362cd88b1a48ad308976ce7fa54e98411746" + integrity sha1-snA2LNiLGkitMIl2zn+lTphBF0Y= + dependencies: + debug "^2.6.8" + pkg-dir "^1.0.0" + +eslint-plugin-es@^1.3.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-1.4.0.tgz#475f65bb20c993fc10e8c8fe77d1d60068072da6" + integrity sha512-XfFmgFdIUDgvaRAlaXUkxrRg5JSADoRC8IkKLc/cISeR3yHVMefFHQZpcyXXEUUPHfy5DwviBcrfqlyqEwlQVw== + dependencies: + eslint-utils "^1.3.0" + regexpp "^2.0.1" + +eslint-plugin-import@^2.14.0: + version "2.14.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.14.0.tgz#6b17626d2e3e6ad52cfce8807a845d15e22111a8" + integrity sha512-FpuRtniD/AY6sXByma2Wr0TXvXJ4nA/2/04VPlfpmUDPOpOY264x+ILiwnrk/k4RINgDAyFZByxqPUbSQ5YE7g== + dependencies: + contains-path "^0.1.0" + debug "^2.6.8" + doctrine "1.5.0" + eslint-import-resolver-node "^0.3.1" + eslint-module-utils "^2.2.0" + has "^1.0.1" + lodash "^4.17.4" + minimatch "^3.0.3" + read-pkg-up "^2.0.0" + resolve "^1.6.0" + +eslint-plugin-jest@^22.1.0: + version "22.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-22.1.0.tgz#9a4dfa3367563e8301560a7fb92ec309096dbca3" + integrity sha512-WcQd5LxEoAS20zuWEAd8CX0pVC+gGInZPcsoYvK5w7BrEJNmltyTxYYh1r0ct4GsahD2GvNySlcTcLtK2amFZA== + +eslint-plugin-node@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-8.0.0.tgz#fb9e8911f4543514f154bb6a5924b599aa645568" + integrity sha512-Y+ln8iQ52scz9+rSPnSWRaAxeWaoJZ4wIveDR0vLHkuSZGe44Vk1J4HX7WvEP5Cm+iXPE8ixo7OM7gAO3/OKpQ== + dependencies: + eslint-plugin-es "^1.3.1" + eslint-utils "^1.3.1" + ignore "^5.0.2" + minimatch "^3.0.4" + resolve "^1.8.1" + semver "^5.5.0" + +eslint-plugin-promise@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.0.1.tgz#2d074b653f35a23d1ba89d8e976a985117d1c6a2" + integrity sha512-Si16O0+Hqz1gDHsys6RtFRrW7cCTB6P7p3OJmKp3Y3dxpQE2qwOA7d3xnV+0mBmrPoi0RBnxlCKvqu70te6wjg== + +eslint-restricted-globals@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz#35f0d5cbc64c2e3ed62e93b4b1a7af05ba7ed4d7" + integrity sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc= + +eslint-scope@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.0.tgz#50bf3071e9338bcdc43331794a0cb533f0136172" + integrity sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-utils@^1.3.0, eslint-utils@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512" + integrity sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q== + +eslint-visitor-keys@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" + integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== + +eslint@^5.9.0: + version "5.9.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-5.9.0.tgz#b234b6d15ef84b5849c6de2af43195a2d59d408e" + integrity sha512-g4KWpPdqN0nth+goDNICNXGfJF7nNnepthp46CAlJoJtC5K/cLu3NgCM3AHu1CkJ5Hzt9V0Y0PBAO6Ay/gGb+w== + dependencies: + "@babel/code-frame" "^7.0.0" + ajv "^6.5.3" + chalk "^2.1.0" + cross-spawn "^6.0.5" + debug "^4.0.1" + doctrine "^2.1.0" + eslint-scope "^4.0.0" + eslint-utils "^1.3.1" + eslint-visitor-keys "^1.0.0" + espree "^4.0.0" + esquery "^1.0.1" + esutils "^2.0.2" + file-entry-cache "^2.0.0" + functional-red-black-tree "^1.0.1" + glob "^7.1.2" + globals "^11.7.0" + ignore "^4.0.6" + imurmurhash "^0.1.4" + inquirer "^6.1.0" + is-resolvable "^1.1.0" + js-yaml "^3.12.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.5" + minimatch "^3.0.4" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.2" + pluralize "^7.0.0" + progress "^2.0.0" + regexpp "^2.0.1" + require-uncached "^1.0.3" + semver "^5.5.1" + strip-ansi "^4.0.0" + strip-json-comments "^2.0.1" + table "^5.0.2" + text-table "^0.2.0" + +espree@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-4.1.0.tgz#728d5451e0fd156c04384a7ad89ed51ff54eb25f" + integrity sha512-I5BycZW6FCVIub93TeVY1s7vjhP9CY6cXCznIRfiig7nRviKZYdRnj/sHEWC6A7WE9RDWOFq9+7OsWSYz8qv2w== + dependencies: + acorn "^6.0.2" + acorn-jsx "^5.0.0" + eslint-visitor-keys "^1.0.0" + +esprima@3.x.x, esprima@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" + integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM= + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esquery@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" + integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA== + dependencies: + estraverse "^4.0.0" + +esrecurse@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== + dependencies: + estraverse "^4.1.0" + +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= + +esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= + +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= + +event-lite@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/event-lite/-/event-lite-0.1.2.tgz#838a3e0fdddef8cc90f128006c8e55a4e4e4c11b" + integrity sha512-HnSYx1BsJ87/p6swwzv+2v6B4X+uxUteoDfRxsAb1S1BePzQqOLevVmkdA15GHJVd9A9Ok6wygUR18Hu0YeV9g== + +eventemitter3@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163" + integrity sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA== + +events@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + integrity sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ= + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +exec-sh@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.2.tgz#2a5e7ffcbd7d0ba2755bdecb16e5a427dfbdec36" + integrity sha512-FIUCJz1RbuS0FKTdaAafAByGS0CPvU3R0MeHxgtl+djzCc//F8HakL8GzmVNZanasTbTAY/3DRFA0KpVqj/eAw== + dependencies: + merge "^1.2.0" + +execa@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.10.0.tgz#ff456a8f53f90f8eccc71a96d11bdfc7f082cb50" + integrity sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw== + dependencies: + cross-spawn "^6.0.0" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.8.0.tgz#d8d76bbc1b55217ed190fd6dd49d3c774ecfc8da" + integrity sha1-2NdrvBtVIX7RkP1t1J08d07PyNo= + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + integrity sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s= + dependencies: + is-posix-bracket "^0.1.0" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expand-home-dir@0.0.3, expand-home-dir@^0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/expand-home-dir/-/expand-home-dir-0.0.3.tgz#72de8a0486cc28a3bbd704635398825b5b62827d" + integrity sha1-ct6KBIbMKKO71wRjU5iCW1tign0= + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + integrity sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc= + dependencies: + fill-range "^2.1.0" + +expect@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-23.6.0.tgz#1e0c8d3ba9a581c87bd71fb9bc8862d443425f98" + integrity sha512-dgSoOHgmtn/aDGRVFWclQyPDKl2CQRq0hmIEoUAuQs/2rn2NcvCWcSCovm6BLeuB/7EZuLGu2QfnR+qRt5OM4w== + dependencies: + ansi-styles "^3.2.0" + jest-diff "^23.6.0" + jest-get-type "^22.1.0" + jest-matcher-utils "^23.6.0" + jest-message-util "^23.4.0" + jest-regex-util "^23.3.0" + +express@^4.16.4: + version "4.16.4" + resolved "https://registry.yarnpkg.com/express/-/express-4.16.4.tgz#fddef61926109e24c515ea97fd2f1bdbf62df12e" + integrity sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg== + dependencies: + accepts "~1.3.5" + array-flatten "1.1.1" + body-parser "1.18.3" + content-disposition "0.5.2" + content-type "~1.0.4" + cookie "0.3.1" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~1.1.2" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.1.1" + fresh "0.5.2" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.2" + path-to-regexp "0.1.7" + proxy-addr "~2.0.4" + qs "6.5.2" + range-parser "~1.2.0" + safe-buffer "5.1.2" + send "0.16.2" + serve-static "1.13.2" + setprototypeof "1.1.0" + statuses "~1.4.0" + type-is "~1.6.16" + utils-merge "1.0.1" + vary "~1.1.2" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@3, extend@~3.0.0, extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +external-editor@^2.0.4: + version "2.2.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" + integrity sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A== + dependencies: + chardet "^0.4.0" + iconv-lite "^0.4.17" + tmp "^0.0.33" + +external-editor@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27" + integrity sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + integrity sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE= + dependencies: + is-extglob "^1.0.0" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= + +fast-diff@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" + integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + +fast-glob@^2.0.2: + version "2.2.4" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.4.tgz#e54f4b66d378040e0e4d6a68ec36bbc5b04363c0" + integrity sha512-FjK2nCGI/McyzgNtTESqaWP3trPvHyRyoyY70hxjc3oKPNmDe8taohLZpoVKoUjW85tbU5txaYUZCNtVzygl1g== + dependencies: + "@mrmlnc/readdir-enhanced" "^2.2.1" + "@nodelib/fs.stat" "^1.1.2" + glob-parent "^3.1.0" + is-glob "^4.0.0" + merge2 "^1.2.3" + micromatch "^3.1.10" + +fast-json-parse@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/fast-json-parse/-/fast-json-parse-1.0.3.tgz#43e5c61ee4efa9265633046b770fb682a7577c4d" + integrity sha512-FRWsaZRWEJ1ESVNbDWmsAlqDk96gPQezzLghafp5J4GUKjbCz3OkAHuZs5TuPEtkbVQERysLp9xv6c24fBm8Aw== + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= + +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +fast-plural-rules@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/fast-plural-rules/-/fast-plural-rules-0.0.1.tgz#7032c8afa979e6dc65a452f0ef5b4ef31eca763b" + integrity sha512-0Cxx7LaH7+dNJEBozlisCxqaN5g68VTFT9PyLeFGBHmkPnQ3e46zss+r8pRC94KpzPlitL6m33GVdbMIDiUgqg== + +fast-redact@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-1.4.0.tgz#6123d2a23e6bdf76e82b3176d6f11698f2001797" + integrity sha512-WsYhPdWJY+6d/pFJbBNWGUd5ENrBAJ6e7yDWcYNoFZoIQUUbKxnIRGS4d0kZkQlMPB4cLK3r4A0BZXpFxdoGhg== + +fast-safe-stringify@2.0.x, fast-safe-stringify@^2.0.4, fast-safe-stringify@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz#04b26106cc56681f51a044cfc0d76cf0008ac2c2" + integrity sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg== + +fb-watchman@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.0.tgz#54e9abf7dfa2f26cd9b1636c588c1afc05de5d58" + integrity sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg= + dependencies: + bser "^2.0.0" + +fecha@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fecha/-/fecha-2.3.3.tgz#948e74157df1a32fd1b12c3a3c3cdcb6ec9d96cd" + integrity sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg== + +figgy-pudding@^3.1.0, figgy-pudding@^3.4.1, figgy-pudding@^3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790" + integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w== + +figures@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + integrity sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4= + dependencies: + escape-string-regexp "^1.0.5" + object-assign "^4.1.0" + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" + integrity sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E= + dependencies: + flat-cache "^1.2.1" + object-assign "^4.0.1" + +file-stream-rotator@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/file-stream-rotator/-/file-stream-rotator-0.4.1.tgz#09f67b86d6ea589d20b7852c51c59de55d916d6d" + integrity sha512-W3aa3QJEc8BS2MmdVpQiYLKHj3ijpto1gMDlsgCRSKfIUe6MwkcpODGPQ3vZfb0XvCeCqlu9CBQTN7oQri2TZQ== + dependencies: + moment "^2.11.2" + +file-uri-to-path@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + integrity sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY= + +fileset@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/fileset/-/fileset-2.0.3.tgz#8e7548a96d3cc2327ee5e674168723a333bba2a0" + integrity sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA= + dependencies: + glob "^7.0.3" + minimatch "^3.0.3" + +fill-range@^2.1.0: + version "2.2.4" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" + integrity sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q== + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^3.0.0" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +finalhandler@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.1.tgz#eebf4ed840079c83f4249038c9d703008301b105" + integrity sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.2" + statuses "~1.4.0" + unpipe "~1.0.0" + +find-cache-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f" + integrity sha1-kojj6ePMN0hxfTnq3hfPcfww7m8= + dependencies: + commondir "^1.0.1" + make-dir "^1.0.0" + pkg-dir "^2.0.0" + +find-cache-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.0.0.tgz#4c1faed59f45184530fb9d7fa123a4d04a98472d" + integrity sha512-LDUY6V1Xs5eFskUVYtIwatojt6+9xC9Chnlk/jYOOvn3FAFfSaWddxahDGyNHh0b2dMXa6YW2m0tk8TdVaXHlA== + dependencies: + commondir "^1.0.1" + make-dir "^1.0.0" + pkg-dir "^3.0.0" + +find-parent-dir@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/find-parent-dir/-/find-parent-dir-0.3.0.tgz#33c44b429ab2b2f0646299c5f9f718f376ff8d54" + integrity sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ= + +find-up@1.1.2, find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^2.0.0, find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +flat-cache@^1.2.1: + version "1.3.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.4.tgz#2c2ef77525cc2929007dfffa1dd314aa9c9dee6f" + integrity sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg== + dependencies: + circular-json "^0.3.1" + graceful-fs "^4.1.2" + rimraf "~2.6.2" + write "^0.2.1" + +flatstr@^1.0.5, flatstr@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/flatstr/-/flatstr-1.0.8.tgz#0e849229751f2b9f6a0919f8e81e1229e84ba901" + integrity sha512-YXblbv/vc1zuVVUtnKl1hPqqk7TalZCppnKE7Pr8FI/Rp48vzckS/4SJ4Y9O9RNiI82Vcw/FydmtqdQOg1Dpqw== + +flush-write-stream@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.3.tgz#c5d586ef38af6097650b49bc41b55fabb19f35bd" + integrity sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw== + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.4" + +follow-redirects@^1.3.0: + version "1.5.10" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" + integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== + dependencies: + debug "=3.1.0" + +for-in@^0.1.3: + version "0.1.8" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-0.1.8.tgz#d8773908e31256109952b1fdb9b3fa867d2775e1" + integrity sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE= + +for-in@^1.0.1, for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + integrity sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4= + dependencies: + for-in "^1.0.1" + +for-own@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-1.0.0.tgz#c63332f415cedc4b04dbfe70cf836494c53cb44b" + integrity sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs= + dependencies: + for-in "^1.0.1" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +form-data@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.0.0.tgz#6f0aebadcc5da16c13e1ecc11137d85f9b883b25" + integrity sha1-bwrrrcxdoWwT4ezBETfYX5uIOyU= + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.11" + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + +forwarded@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" + integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +from2@^2.1.0, from2@^2.1.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fs-extra@^7.0.0, fs-extra@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" + integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-minipass@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" + integrity sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ== + dependencies: + minipass "^2.2.1" + +fs-vacuum@~1.2.9: + version "1.2.10" + resolved "https://registry.yarnpkg.com/fs-vacuum/-/fs-vacuum-1.2.10.tgz#b7629bec07a4031a2548fdf99f5ecf1cc8b31e36" + integrity sha1-t2Kb7AekAxolSP35n17PHMizHjY= + dependencies: + graceful-fs "^4.1.2" + path-is-inside "^1.0.1" + rimraf "^2.5.2" + +fs-write-stream-atomic@^1.0.8, fs-write-stream-atomic@~1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + integrity sha1-tH31NJPvkR33VzHnCp3tAYnbQMk= + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@^1.2.2, fsevents@^1.2.3: + version "1.2.4" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" + integrity sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg== + dependencies: + nan "^2.9.2" + node-pre-gyp "^0.10.0" + +fstream-ignore@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" + integrity sha1-nDHa40dnAY/h0kmyTa2mfQktoQU= + dependencies: + fstream "^1.0.0" + inherits "2" + minimatch "^3.0.0" + +fstream-npm@~1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/fstream-npm/-/fstream-npm-1.2.1.tgz#08c4a452f789dcbac4c89a4563c902b2c862fd5b" + integrity sha512-iBHpm/LmD1qw0TlHMAqVd9rwdU6M+EHRUnPkXpRi5G/Hf0FIFH+oZFryodAU2MFNfGRh/CzhUFlMKV3pdeOTDw== + dependencies: + fstream-ignore "^1.0.0" + inherits "2" + +fstream@^1.0.0, fstream@^1.0.2, fstream@~1.0.10: + version "1.0.11" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" + integrity sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE= + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +ftp@~0.3.10: + version "0.3.10" + resolved "https://registry.yarnpkg.com/ftp/-/ftp-0.3.10.tgz#9197d861ad8142f3e63d5a83bfe4c59f7330885d" + integrity sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0= + dependencies: + readable-stream "1.1.x" + xregexp "2.0.0" + +function-bind@^1.1.0, function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +g-status@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/g-status/-/g-status-2.0.2.tgz#270fd32119e8fc9496f066fe5fe88e0a6bc78b97" + integrity sha512-kQoE9qH+T1AHKgSSD0Hkv98bobE90ILQcXAF4wvGgsr7uFqNvwmh8j+Lq3l0RVt3E3HjSbv2B9biEGcEtpHLCA== + dependencies: + arrify "^1.0.1" + matcher "^1.0.0" + simple-git "^1.85.0" + +gauge@~2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.6.0.tgz#d35301ad18e96902b4751dcbbe40f4218b942a46" + integrity sha1-01MBrRjpaQK0dR3LvkD0IYuUKkY= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-color "^0.1.7" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +gauge@~2.7.1, gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +generate-function@^2.0.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.3.1.tgz#f069617690c10c868e73b8465746764f97c3479f" + integrity sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ== + dependencies: + is-property "^1.0.2" + +generate-object-property@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" + integrity sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA= + dependencies: + is-property "^1.0.0" + +generic-pool@^3.4.0: + version "3.4.2" + resolved "https://registry.yarnpkg.com/generic-pool/-/generic-pool-3.4.2.tgz#92ff7196520d670839a67308092a12aadf2f6a59" + integrity sha512-H7cUpwCQSiJmAHM4c/aFu6fUfrhWXW1ncyh8ftxEPMu6AiYkHw9K8br720TGPZJbk5eOH2bynjZD1yPvdDAmag== + +genfun@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/genfun/-/genfun-5.0.0.tgz#9dd9710a06900a5c4a5bf57aca5da4e52fe76537" + integrity sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA== + +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + +get-own-enumerable-property-symbols@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.0.tgz#b877b49a5c16aefac3655f2ed2ea5b684df8d203" + integrity sha512-CIJYJC4GGF06TakLg8z4GQKvDsx9EMspVxOYih7LerEL/WosUnFIww45CGfxfeKHqlg3twgUrYRT1O3WQqjGCg== + +get-pkg-repo@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/get-pkg-repo/-/get-pkg-repo-1.4.0.tgz#c73b489c06d80cc5536c2c853f9e05232056972d" + integrity sha1-xztInAbYDMVTbCyFP54FIyBWly0= + dependencies: + hosted-git-info "^2.1.4" + meow "^3.3.0" + normalize-package-data "^2.3.0" + parse-github-repo-url "^1.3.0" + through2 "^2.0.0" + +get-port@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc" + integrity sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw= + +get-stdin@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= + +get-stdin@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398" + integrity sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g= + +get-stdin@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" + integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g== + +get-stream@3.0.0, get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= + +get-stream@^4.0.0, get-stream@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-uri@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-2.0.2.tgz#5c795e71326f6ca1286f2fc82575cd2bab2af578" + integrity sha512-ZD325dMZOgerGqF/rF6vZXyFGTAay62svjQIT+X/oU2PtxYpFxvSkbsdi+oxIrsNxlZVd4y8wUDqkaExWTI/Cw== + dependencies: + data-uri-to-buffer "1" + debug "2" + extend "3" + file-uri-to-path "1" + ftp "~0.3.10" + readable-stream "2" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + +git-raw-commits@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-2.0.0.tgz#d92addf74440c14bcc5c83ecce3fb7f8a79118b5" + integrity sha512-w4jFEJFgKXMQJ0H0ikBk2S+4KP2VEjhCvLCNqbNRQC8BgGWgLKNCO7a9K9LI+TVT7Gfoloje502sEnctibffgg== + dependencies: + dargs "^4.0.1" + lodash.template "^4.0.2" + meow "^4.0.0" + split2 "^2.0.0" + through2 "^2.0.0" + +git-remote-origin-url@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz#5282659dae2107145a11126112ad3216ec5fa65f" + integrity sha1-UoJlna4hBxRaERJhEq0yFuxfpl8= + dependencies: + gitconfiglocal "^1.0.0" + pify "^2.3.0" + +git-semver-tags@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/git-semver-tags/-/git-semver-tags-2.0.2.tgz#f506ec07caade191ac0c8d5a21bdb8131b4934e3" + integrity sha512-34lMF7Yo1xEmsK2EkbArdoU79umpvm0MfzaDkSNYSJqtM5QLAVTPWgpiXSVI5o/O9EvZPSrP4Zvnec/CqhSd5w== + dependencies: + meow "^4.0.0" + semver "^5.5.0" + +gitconfiglocal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz#41d045f3851a5ea88f03f24ca1c6178114464b9b" + integrity sha1-QdBF84UaXqiPA/JMocYXgRRGS5s= + dependencies: + ini "^1.3.2" + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + integrity sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q= + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + integrity sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg= + dependencies: + is-glob "^2.0.0" + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-to-regexp@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" + integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= + +glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@~7.1.0: + version "7.1.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" + integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global-dirs@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" + integrity sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU= + dependencies: + ini "^1.3.4" + +global-modules-path@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/global-modules-path/-/global-modules-path-2.3.0.tgz#b0e2bac6beac39745f7db5c59d26a36a0b94f7dc" + integrity sha512-HchvMJNYh9dGSCy8pOQ2O8u/hoXaL+0XhnrwH0RyLiSXMMTl9W3N6KUU73+JFOg5PGjtzl6VZzUQsnrpm7Szag== + +globals@^11.1.0, globals@^11.7.0: + version "11.9.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.9.0.tgz#bde236808e987f290768a93d065060d78e6ab249" + integrity sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg== + +globals@^9.18.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + integrity sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ== + +globalyzer@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/globalyzer/-/globalyzer-0.1.0.tgz#cb76da79555669a1519d5a8edf093afaa0bf1465" + integrity sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q== + +globby@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= + dependencies: + array-union "^1.0.1" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +globby@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/globby/-/globby-8.0.1.tgz#b5ad48b8aa80b35b814fc1281ecc851f1d2b5b50" + integrity sha512-oMrYrJERnKBLXNLVTqhm3vPEdJ/b2ZE28xN4YARiix1NOIOBPEpOUnm844K1iu/BkphCaf2WNFwMszv8Soi1pw== + dependencies: + array-union "^1.0.1" + dir-glob "^2.0.0" + fast-glob "^2.0.2" + glob "^7.1.2" + ignore "^3.3.5" + pify "^3.0.0" + slash "^1.0.0" + +globrex@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.1.tgz#cfe565cfa910707d0ef98eb0b9d78c3c055ca2ef" + integrity sha512-bqKcPhb+ZtrISivpu6oLmwIyINlPlzueO/BDCdfnzUeu7SYxnHTXmWP7uQI5PnQXc5yGXOscGBEGagloA2hcSw== + +good-console@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/good-console/-/good-console-7.1.0.tgz#ebcf948d7adb8898145bdc76f2f7cdd64641b4a0" + integrity sha1-68+UjXrbiJgUW9x28vfN1kZBtKA= + dependencies: + hoek "4.x.x" + joi "12.x.x" + json-stringify-safe "5.0.x" + moment "2.20.x" + +good-squeeze@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/good-squeeze/-/good-squeeze-5.1.0.tgz#265f3e8be6081aa44c55d484d1af375e166752b9" + integrity sha1-Jl8+i+YIGqRMVdSE0a83XhZnUrk= + dependencies: + fast-safe-stringify "2.0.x" + hoek "4.2.x" + +good@^8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/good/-/good-8.1.1.tgz#02b38a9bdab4862d9a4e7897b13a88f6663cd81f" + integrity sha512-iq6cmWjULCgiCSlSdt263G8vdQxaymi7R6kmS/lEf5nNsKv3StPGtZcTzHn2qzkk0b4hZt/y9sFFZrmF2sSm7w== + dependencies: + hoek "5.x.x" + joi "13.x.x" + oppsy "2.x.x" + pumpify "1.3.x" + +got@^6.7.1: + version "6.7.1" + resolved "https://registry.yarnpkg.com/got/-/got-6.7.1.tgz#240cd05785a9a18e561dc1b44b41c763ef1e8db0" + integrity sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA= + dependencies: + create-error-class "^3.0.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + is-redirect "^1.0.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + lowercase-keys "^1.0.0" + safe-buffer "^5.0.1" + timed-out "^4.0.0" + unzip-response "^2.0.1" + url-parse-lax "^1.0.0" + +got@^8.0.3: + version "8.3.2" + resolved "https://registry.yarnpkg.com/got/-/got-8.3.2.tgz#1d23f64390e97f776cac52e5b936e5f514d2e937" + integrity sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw== + dependencies: + "@sindresorhus/is" "^0.7.0" + cacheable-request "^2.1.1" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + into-stream "^3.1.0" + is-retry-allowed "^1.1.0" + isurl "^1.0.0-alpha5" + lowercase-keys "^1.0.0" + mimic-response "^1.0.0" + p-cancelable "^0.4.0" + p-timeout "^2.0.1" + pify "^3.0.0" + safe-buffer "^5.1.1" + timed-out "^4.0.1" + url-parse-lax "^3.0.0" + url-to-options "^1.0.1" + +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@~4.1.9: + version "4.1.15" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" + integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== + +graphlib@^2.1.1, graphlib@^2.1.5: + version "2.1.5" + resolved "https://registry.yarnpkg.com/graphlib/-/graphlib-2.1.5.tgz#6afe1afcc5148555ec799e499056795bd6938c87" + integrity sha512-XvtbqCcw+EM5SqQrIetIKKD+uZVNQtDPD1goIg7K73RuRZtVI5rYMdcCVSHm/AS1sCBZ7vt0p5WgXouucHQaOA== + dependencies: + lodash "^4.11.1" + +graphql-extensions@0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.3.3.tgz#277efe11976bbdfd59915551606a2d550247bb45" + integrity sha512-pudOaHq7Ok+rh1ElzlqFaoYZWGefUNsqn/jX6eKns7rl0VHuB4qZBfhpVLTpquJpM6Y19/hsCYZNPfnUVMFIiA== + dependencies: + "@apollographql/apollo-tools" "^0.2.6" + +graphql-extensions@0.3.4: + version "0.3.4" + resolved "https://registry.yarnpkg.com/graphql-extensions/-/graphql-extensions-0.3.4.tgz#a6636ba8b41d5f9ea917085e5d4518adbba0e21f" + integrity sha512-fOI+0p2+1xnwLQx3DvInSuPyGjwsW4RWxTI8caZ91NTFfsa0K3EBFBD71BNO3Ziw2P1nIa8Ip+WRT/Dx3GML0g== + dependencies: + "@apollographql/apollo-tools" "^0.2.6" + +graphql-subscriptions@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/graphql-subscriptions/-/graphql-subscriptions-1.0.0.tgz#475267694b3bd465af6477dbab4263a3f62702b8" + integrity sha512-+ytmryoHF1LVf58NKEaNPRUzYyXplm120ntxfPcgOBC7TnK7Tv/4VRHeh4FAR9iL+O1bqhZs4nkibxQ+OA5cDQ== + dependencies: + iterall "^1.2.1" + +graphql-tag@^2.9.2: + version "2.10.0" + resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.10.0.tgz#87da024be863e357551b2b8700e496ee2d4353ae" + integrity sha512-9FD6cw976TLLf9WYIUPCaaTpniawIjHWZSwIRZSjrfufJamcXbVVYfN2TWvJYbw0Xf2JjYbl1/f2+wDnBVw3/w== + +graphql-tools-types@^1.1.26: + version "1.1.26" + resolved "https://registry.yarnpkg.com/graphql-tools-types/-/graphql-tools-types-1.1.26.tgz#860d50c101eb1e0f096f0350fc1ce9d0517849fe" + integrity sha512-syqYHBoA/WiUgGBPCI/9Dwlo4EO6ezP5WbOHFjZqT5H8LpO4The18PtxdaP1bm94LkZhcEiW6XiBd+F/E9ym6A== + dependencies: + babel-runtime "6.26.0" + ducky "2.6.11" + graphql "0.13.2" + pure-uuid "1.5.3" + +graphql-tools@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/graphql-tools/-/graphql-tools-4.0.3.tgz#23b5cb52c519212b1b2e4630a361464396ad264b" + integrity sha512-NNZM0WSnVLX1zIMUxu7SjzLZ4prCp15N5L2T2ro02OVyydZ0fuCnZYRnx/yK9xjGWbZA0Q58yEO//Bv/psJWrg== + dependencies: + apollo-link "^1.2.3" + apollo-utilities "^1.0.1" + deprecated-decorator "^0.1.6" + iterall "^1.1.3" + uuid "^3.1.0" + +graphql@0.13.2: + version "0.13.2" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-0.13.2.tgz#4c740ae3c222823e7004096f832e7b93b2108270" + integrity sha512-QZ5BL8ZO/B20VA8APauGBg3GyEgZ19eduvpLWoq5x7gMmWnHoy8rlQWPLmWgFvo1yNgjSEFMesmS4R6pPr7xog== + dependencies: + iterall "^1.2.1" + +growly@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" + integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= + +handlebars@4.x.x, handlebars@^4.0.12, handlebars@^4.0.2, handlebars@^4.0.3: + version "4.0.12" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.12.tgz#2c15c8a96d46da5e266700518ba8cb8d919d5bc5" + integrity sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA== + dependencies: + async "^2.5.0" + optimist "^0.6.1" + source-map "^0.6.1" + optionalDependencies: + uglify-js "^3.1.4" + +hapi-api-version@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/hapi-api-version/-/hapi-api-version-2.1.0.tgz#96b29c1a652380e34b6d7ee12a1484c4a056a9c1" + integrity sha512-Pcm//wgcI2FUG8YYd9xYT60wFNM1nexJ6lonfdYsvkXr1/yREUlo0SUR1g7jUZ6Oa//K1HQlJhFpbmN+2DIVVw== + dependencies: + boom "^5.2.0" + hoek "^4.2.0" + joi "^10.6.0" + media-type "^0.3.0" + +hapi-pagination@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/hapi-pagination/-/hapi-pagination-2.0.1.tgz#aef33ec4510257612a0b9be3855f77aa6a9635a3" + integrity sha512-7X+d7DcQ/Lef8MZ5HxlMk7kRk0+6ne4aR5lDP6d9obFPZB4K/pfGqJWvhgQeVCkHwKYe0ts6StdCRPLo8EQ2Pw== + dependencies: + boom "^7.1.1" + hapi "^17.1.1" + hoek "^5.0.2" + joi "^13.0.2" + +"hapi-pagination@https://github.com/faustbrian/hapi-pagination": + version "2.0.0" + resolved "https://github.com/faustbrian/hapi-pagination#c3a666ee2404be11bab879f316239ad352329ca1" + dependencies: + boom "^7.1.1" + hapi "^17.1.1" + hoek "^5.0.2" + joi "^13.0.2" + +hapi-rate-limit@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/hapi-rate-limit/-/hapi-rate-limit-2.1.4.tgz#bd2b15465faea6d7c2b3aad05f015ee628cc0005" + integrity sha512-xNZColWoYdoOKXEIC6GX4LJ4TUqpzaR4u/XZdq40/O2JYovENhQPc3ChnWHdToKA0o0QkNsBXR8tTrBDoNjEEQ== + dependencies: + boom "^7.2.0" + hoek "^6.0.0" + +hapi-trailing-slash@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/hapi-trailing-slash/-/hapi-trailing-slash-3.0.1.tgz#e3b07a6aedbdb5a6a2351b3e3b179f3dbf29b2ab" + integrity sha512-EA+IVYyNKr/CO/pHlWEB9SRtzYOBXXjFb9l8vrJ0vS4hNcmYsajEk7FJk4R+HzmqR1wkJLW/gTAsOffSm9hPuw== + dependencies: + useragent "^2.2.1" + wreck "^14.0.2" + +hapi@^17.1.1, hapi@^17.8.1: + version "17.8.1" + resolved "https://registry.yarnpkg.com/hapi/-/hapi-17.8.1.tgz#63cc5bbc138b6ae0919e977764647a17556e4c87" + integrity sha512-0zfkl8YtJPfkOG+1KwFnZOk7/mmO2LrExJLWIJwzmwsyxLcQXNrnfwgk205xxxg9tnOO6OdCTQLkPG8Wn+McXw== + dependencies: + accept "3.x.x" + ammo "3.x.x" + boom "7.x.x" + bounce "1.x.x" + call "5.x.x" + catbox "10.x.x" + catbox-memory "3.x.x" + heavy "6.x.x" + hoek "6.x.x" + joi "14.x.x" + mimos "4.x.x" + podium "3.x.x" + shot "4.x.x" + somever "2.x.x" + statehood "6.x.x" + subtext "6.x.x" + teamwork "3.x.x" + topo "3.x.x" + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-2.0.6.tgz#cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d" + integrity sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0= + dependencies: + chalk "^1.1.1" + commander "^2.9.0" + is-my-json-valid "^2.12.4" + pinkie-promise "^2.0.0" + +har-validator@~5.1.0: + version "5.1.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" + integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== + dependencies: + ajv "^6.5.5" + har-schema "^2.0.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + +has-color@^0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" + integrity sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8= + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-symbol-support-x@^1.4.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" + integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw== + +has-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" + integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= + +has-to-string-tag-x@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" + integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw== + dependencies: + has-symbol-support-x "^1.4.1" + +has-unicode@^2.0.0, has-unicode@^2.0.1, has-unicode@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hasbin@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/hasbin/-/hasbin-1.2.3.tgz#78c5926893c80215c2b568ae1fd3fcab7a2696b0" + integrity sha1-eMWSaJPIAhXCtWiuH9P8q3omlrA= + dependencies: + async "~1.5" + +hash-base@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" + integrity sha1-X8hoaEfs1zSZQDMZprCj8/auSRg= + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.5" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.5.tgz#e38ab4b85dfb1e0c40fe9265c0e9b54854c23812" + integrity sha512-eWI5HG9Np+eHV1KQhisXWwM+4EPPYe5dFX1UZZH7k/E3JzDEazVH+VGlZi6R94ZqImq+A3D1mCEtrFIfg/E7sA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +hawk@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" + integrity sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ= + dependencies: + boom "2.x.x" + cryptiles "2.x.x" + hoek "2.x.x" + sntp "1.x.x" + +heavy@6.x.x: + version "6.1.2" + resolved "https://registry.yarnpkg.com/heavy/-/heavy-6.1.2.tgz#e5d56f18170a37b01d4381bc07fece5edc68520b" + integrity sha512-cJp884bqhiebNcEHydW0g6V1MUGYOXRPw9c7MFiHQnuGxtbWuSZpsbojwb2kxb3AA1/Rfs8CNiV9MMOF8pFRDg== + dependencies: + boom "7.x.x" + hoek "6.x.x" + joi "14.x.x" + +hmac-drbg@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +hoek@2.x.x: + version "2.16.3" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" + integrity sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0= + +hoek@4.2.x, hoek@4.x.x, hoek@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.1.tgz#9634502aa12c445dd5a7c5734b572bb8738aacbb" + integrity sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA== + +hoek@5.x.x, hoek@^5.0.2: + version "5.0.4" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-5.0.4.tgz#0f7fa270a1cafeb364a4b2ddfaa33f864e4157da" + integrity sha512-Alr4ZQgoMlnere5FZJsIyfIjORBqZll5POhDsF4q64dPuJR6rNxXdDxtHSQq8OXRurhmx+PWYEE8bXRROY8h0w== + +hoek@6.x.x: + version "6.0.4" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-6.0.4.tgz#8db638130825534575e8e4e80f97ca66108e6382" + integrity sha512-9D47elppcwrTx2x9B6TrovxnUtlTBYFcHGgo0+LRA1+YfUkCecT//41ovdh6zbl7whB9Hc2whRO1c6lzPoTgww== + +hoek@^6.0.0, hoek@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-6.1.1.tgz#dae8ca1c97b091b123281d87d4eba38d71580b7d" + integrity sha512-q60PigXXRtRFSe1+Eal3y/wlIq5weFsYPiyulkg1EAObgWhkDqSwj4xqgtd7qT3IpS6e4eLigyMWH6duPRI7QA== + +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + integrity sha1-42w/LSyufXRqhX440Y1fMqeILbg= + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + +hosted-git-info@^2.1.4, hosted-git-info@^2.1.5, hosted-git-info@^2.4.2, hosted-git-info@^2.6.0, hosted-git-info@^2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" + integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== + +hosted-git-info@~2.1.5: + version "2.1.5" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.1.5.tgz#0ba81d90da2e25ab34a332e6ec77936e1598118b" + integrity sha1-C6gdkNouJas0ozLm7HeTbhWYEYs= + +html-encoding-sniffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" + integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw== + dependencies: + whatwg-encoding "^1.0.1" + +http-cache-semantics@3.8.1, http-cache-semantics@^3.8.1: + version "3.8.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" + integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== + +http-errors@1.6.3, http-errors@~1.6.2, http-errors@~1.6.3: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +http-proxy-agent@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" + integrity sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg== + dependencies: + agent-base "4" + debug "3.1.0" + +http-signature@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" + integrity sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8= + dependencies: + assert-plus "^0.2.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= + +https-proxy-agent@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0" + integrity sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ== + dependencies: + agent-base "^4.1.0" + debug "^3.1.0" + +humanize-ms@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" + integrity sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0= + dependencies: + ms "^2.0.0" + +husky@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/husky/-/husky-1.2.0.tgz#d631dda1e4a9ee8ba69a10b0c51a0e2c66e711e5" + integrity sha512-/ib3+iycykXC0tYIxsyqierikVa9DA2DrT32UEirqNEFVqOj1bFMTgP3jAz8HM7FgC/C8pc/BTUa9MV2GEkZaA== + dependencies: + cosmiconfig "^5.0.6" + execa "^1.0.0" + find-up "^3.0.0" + get-stdin "^6.0.0" + is-ci "^1.2.1" + pkg-dir "^3.0.0" + please-upgrade-node "^3.1.1" + read-pkg "^4.0.1" + run-node "^1.0.0" + slash "^2.0.0" + +iconv-lite@0.4.23: + version "0.4.23" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" + integrity sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +iconv-lite@0.4.24, iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ieee754@^1.1.4, ieee754@^1.1.8: + version "1.1.12" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" + integrity sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA== + +iferr@^0.1.5, iferr@~0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= + +ignore-walk@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" + integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== + dependencies: + minimatch "^3.0.4" + +ignore@^3.3.5: + version "3.3.10" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" + integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== + +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +ignore@^5.0.2: + version "5.0.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.0.4.tgz#33168af4a21e99b00c5d41cbadb6a6cb49903a45" + integrity sha512-WLsTMEhsQuXpCiG173+f3aymI43SXa+fB1rSfbzyP4GkPP+ZFVuO0/3sFUGNBtifisPeDcl/uD/Y2NxZ7xFq4g== + +immediate@~3.0.5: + version "3.0.6" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" + integrity sha1-nbHb0Pr43m++D13V5Wu2BigN5ps= + +immutable@^4.0.0-rc.12: + version "4.0.0-rc.12" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.0.0-rc.12.tgz#ca59a7e4c19ae8d9bf74a97bdf0f6e2f2a5d0217" + integrity sha512-0M2XxkZLx/mi3t8NVwIm1g8nHoEmM9p9UBl/G9k4+hm0kBgOVdMV/B3CY5dQ8qG8qc80NN4gDV4HQv6FTJ5q7A== + +import-fresh@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" + integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= + dependencies: + caller-path "^2.0.0" + resolve-from "^3.0.0" + +import-lazy@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" + integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= + +import-local@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc" + integrity sha512-vAaZHieK9qjGo58agRBg+bhHX3hoTZU/Oa3GESWLz7t1U62fk63aHuDJJEteXoDeTCcPmUT+z38gkHPZkkmpmQ== + dependencies: + pkg-dir "^2.0.0" + resolve-cwd "^2.0.0" + +import-local@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" + integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== + dependencies: + pkg-dir "^3.0.0" + resolve-cwd "^2.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA= + dependencies: + repeating "^2.0.0" + +indent-string@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" + integrity sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok= + +indexof@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" + integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10= + +inert@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/inert/-/inert-5.1.2.tgz#0c26f15bc22aae7af9c1f1a164bf867c58c5f4a6" + integrity sha512-5jSCKrQ7ENfdECnzLatCejXSkJwVzKFXZW30fI6TNHFbDuigT8IilRfydI2H5j9ZTnH7vXKO4WUg2qph9bItow== + dependencies: + ammo "3.x.x" + boom "7.x.x" + bounce "1.x.x" + hoek "6.x.x" + joi "14.x.x" + lru-cache "4.1.x" + +inflection@1.12.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/inflection/-/inflection-1.12.0.tgz#a200935656d6f5f6bc4dc7502e1aecb703228416" + integrity sha1-ogCTVlbW9fa8TcdQLhrstwMihBY= + +inflight@^1.0.4, inflight@~1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE= + +ini@^1.3.0, ini@^1.3.2, ini@^1.3.4, ini@~1.3.0, ini@~1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + +init-package-json@^1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/init-package-json/-/init-package-json-1.10.3.tgz#45ffe2f610a8ca134f2bd1db5637b235070f6cbe" + integrity sha512-zKSiXKhQveNteyhcj1CoOP8tqp1QuxPIPBl8Bid99DGLFqA1p87M6lNgfjJHSBoWJJlidGOv5rWjyYKEB3g2Jw== + dependencies: + glob "^7.1.1" + npm-package-arg "^4.0.0 || ^5.0.0 || ^6.0.0" + promzard "^0.3.0" + read "~1.0.1" + read-package-json "1 || 2" + semver "2.x || 3.x || 4 || 5" + validate-npm-package-license "^3.0.1" + validate-npm-package-name "^3.0.0" + +init-package-json@~1.9.4: + version "1.9.6" + resolved "https://registry.yarnpkg.com/init-package-json/-/init-package-json-1.9.6.tgz#789fc2b74466a4952b9ea77c0575bc78ebd60a61" + integrity sha1-eJ/Ct0RmpJUrnqd8BXW8eOvWCmE= + dependencies: + glob "^7.1.1" + npm-package-arg "^4.0.0 || ^5.0.0" + promzard "^0.3.0" + read "~1.0.1" + read-package-json "1 || 2" + semver "2.x || 3.x || 4 || 5" + validate-npm-package-license "^3.0.1" + validate-npm-package-name "^3.0.0" + +inquirer@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.3.0.tgz#9dd2f2ad765dcab1ff0443b491442a20ba227dc9" + integrity sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ== + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.0" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^2.0.4" + figures "^2.0.0" + lodash "^4.3.0" + mute-stream "0.0.7" + run-async "^2.2.0" + rx-lite "^4.0.8" + rx-lite-aggregates "^4.0.8" + string-width "^2.1.0" + strip-ansi "^4.0.0" + through "^2.3.6" + +inquirer@^6.1.0, inquirer@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.0.tgz#51adcd776f661369dc1e894859c2560a224abdd8" + integrity sha512-QIEQG4YyQ2UYZGDC4srMZ7BjHOmNk1lR2JQj5UknBapklm6WHA+VVH7N+sUdX3A7NeCfGF8o4X1S3Ao7nAcIeg== + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.0" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^3.0.0" + figures "^2.0.0" + lodash "^4.17.10" + mute-stream "0.0.7" + run-async "^2.2.0" + rxjs "^6.1.0" + string-width "^2.1.0" + strip-ansi "^4.0.0" + through "^2.3.6" + +int64-buffer@^0.1.9: + version "0.1.10" + resolved "https://registry.yarnpkg.com/int64-buffer/-/int64-buffer-0.1.10.tgz#277b228a87d95ad777d07c13832022406a473423" + integrity sha1-J3siiofZWtd30HwTgyAiQGpHNCM= + +integer@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/integer/-/integer-2.1.0.tgz#29134ea2f7ba3362ed4dbe6bcca992b1f18ff276" + integrity sha512-vBtiSgrEiNocWvvZX1RVfeOKa2mCHLZQ2p9nkQkQZ/BvEiY+6CcUz0eyjvIiewjJoeNidzg2I+tpPJvpyspL1w== + +interpret@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" + integrity sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ= + +into-stream@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6" + integrity sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY= + dependencies: + from2 "^2.1.1" + p-is-promise "^1.1.0" + +invariant@^2.2.2, invariant@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== + dependencies: + loose-envify "^1.0.0" + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= + +invert-kv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" + integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== + +ip@^1.1.4, ip@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" + integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= + +ipaddr.js@1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.8.0.tgz#eaa33d6ddd7ace8f7f6fe0c9ca0440e706738b1e" + integrity sha1-6qM9bd16zo9/b+DJygRA5wZzix4= + +iron@5.x.x: + version "5.0.6" + resolved "https://registry.yarnpkg.com/iron/-/iron-5.0.6.tgz#7121d4a6e3ac2f65e4d02971646fea1995434744" + integrity sha512-zYUMOSkEXGBdwlV/AXF9zJC0aLuTJUKHkGeYS5I2g225M5i6SrxQyGJGhPgOR8BK1omL6N5i6TcwfsXbP8/Exw== + dependencies: + b64 "4.x.x" + boom "7.x.x" + cryptiles "4.x.x" + hoek "6.x.x" + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= + dependencies: + binary-extensions "^1.0.0" + +is-bluebird@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-bluebird/-/is-bluebird-1.0.2.tgz#096439060f4aa411abee19143a84d6a55346d6e2" + integrity sha1-CWQ5Bg9KpBGr7hkUOoTWpVNG1uI= + +is-buffer@^1.0.2, is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + integrity sha1-VAVy0096wxGfj3bDDLwbHgN6/74= + dependencies: + builtin-modules "^1.0.0" + +is-callable@^1.1.3, is-callable@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" + integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== + +is-ci@^1.0.10, is-ci@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" + integrity sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg== + dependencies: + ci-info "^1.5.0" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-directory@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= + +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + integrity sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE= + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + integrity sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ= + dependencies: + is-primitive "^2.0.0" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + integrity sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA= + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-finite@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + integrity sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-generator-fn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-1.0.0.tgz#969d49e1bb3329f6bb7f09089be26578b2ddd46a" + integrity sha1-lp1J4bszKfa7fwkIm+JleLLd1Go= + +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + integrity sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM= + dependencies: + is-extglob "^1.0.0" + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" + integrity sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A= + dependencies: + is-extglob "^2.1.1" + +is-installed-globally@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" + integrity sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA= + dependencies: + global-dirs "^0.1.0" + is-path-inside "^1.0.0" + +is-my-ip-valid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz#7b351b8e8edd4d3995d4d066680e664d94696824" + integrity sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ== + +is-my-json-valid@^2.12.4: + version "2.19.0" + resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.19.0.tgz#8fd6e40363cd06b963fa877d444bfb5eddc62175" + integrity sha512-mG0f/unGX1HZ5ep4uhRaPOS8EkAY8/j6mDRMJrutq4CqhoJWYp7qAlonIPy3TV7p3ju4TK9fo/PbnoksWmsp5Q== + dependencies: + generate-function "^2.0.0" + generate-object-property "^1.1.0" + is-my-ip-valid "^1.0.0" + jsonpointer "^4.0.0" + xtend "^4.0.0" + +is-npm@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" + integrity sha1-8vtjpl5JBbQGyGBydloaTceTufQ= + +is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + integrity sha1-Afy7s5NGOlSPL0ZszhbezknbkI8= + dependencies: + kind-of "^3.0.2" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + integrity sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ== + +is-obj@^1.0.0, is-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= + +is-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" + integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA= + +is-observable@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-1.1.0.tgz#b3e986c8f44de950867cab5403f5a3465005975e" + integrity sha512-NqCa4Sa2d+u7BWc6CukaObG3Fh+CU9bvixbpcXYhy2VvYS7vVGIdAgnIS5Ks3A/cqk4rebLJ9s8zBstT2aKnIA== + dependencies: + symbol-observable "^1.1.0" + +is-path-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + integrity sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0= + +is-path-in-cwd@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52" + integrity sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ== + dependencies: + is-path-inside "^1.0.0" + +is-path-inside@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" + integrity sha1-jvW33lBDej/cprToZe96pVy0gDY= + dependencies: + path-is-inside "^1.0.1" + +is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= + +is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-port-reachable@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-port-reachable/-/is-port-reachable-2.0.0.tgz#54d13d654917eb433ae3ee2dcbc3774f2cd44eb2" + integrity sha1-VNE9ZUkX60M64+4ty8N3TyzUTrI= + +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + integrity sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q= + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + integrity sha1-IHurkWOEmcB7Kt8kCkGochADRXU= + +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= + +is-property@^1.0.0, is-property@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + integrity sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ= + +is-reachable@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/is-reachable/-/is-reachable-2.4.0.tgz#a66c3c401c43545cd328a0380cbe9d38a05d31f9" + integrity sha512-V9aZ6Q7QU/fYZsnmroYGRydnub8WX5N6YuXSQ3/Bflg9Kk8SL+o1qH9oxkRaS9Dlq4q514kpvhIWUl0LcCEGWw== + dependencies: + arrify "^1.0.1" + got "^8.0.3" + is-port-reachable "^2.0.0" + p-any "^1.1.0" + p-timeout "^2.0.1" + pify "^3.0.0" + port-numbers "^2.0.20" + prepend-http "^2.0.0" + router-ips "^1.0.0" + url-parse "^1.2.0" + +is-redirect@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" + integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ= + +is-regex@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= + dependencies: + has "^1.0.1" + +is-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-1.0.0.tgz#fd2d883545c46bac5a633e7b9a09e87fa2cb5069" + integrity sha1-/S2INUXEa6xaYz57mgnof6LLUGk= + +is-resolvable@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" + integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== + +is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" + integrity sha1-EaBgVotnM5REAz0BJaYaINVk+zQ= + +is-stream@^1.0.0, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-subset@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-subset/-/is-subset-0.1.1.tgz#8a59117d932de1de00f245fcdd39ce43f1e939a6" + integrity sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY= + +is-symbol@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" + integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw== + dependencies: + has-symbols "^1.0.0" + +is-text-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-text-path/-/is-text-path-1.0.1.tgz#4e1aa0fb51bfbcb3e92688001397202c1775b66e" + integrity sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4= + dependencies: + text-extensions "^1.0.0" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= + +is-windows@^1.0.0, is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +is-wsl@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= + +is_js@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/is_js/-/is_js-0.9.0.tgz#0ab94540502ba7afa24c856aa985561669e9c52d" + integrity sha1-CrlFQFArp6+iTIVqqYVWFmnpxS0= + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isemail@2.x.x: + version "2.2.1" + resolved "https://registry.yarnpkg.com/isemail/-/isemail-2.2.1.tgz#0353d3d9a62951080c262c2aa0a42b8ea8e9e2a6" + integrity sha1-A1PT2aYpUQgMJiwqoKQrjqjp4qY= + +isemail@3.x.x: + version "3.2.0" + resolved "https://registry.yarnpkg.com/isemail/-/isemail-3.2.0.tgz#59310a021931a9fb06bbb51e155ce0b3f236832c" + integrity sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg== + dependencies: + punycode "2.x.x" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + +istanbul-api@^1.3.1: + version "1.3.7" + resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.3.7.tgz#a86c770d2b03e11e3f778cd7aedd82d2722092aa" + integrity sha512-4/ApBnMVeEPG3EkSzcw25wDe4N66wxwn+KKn6b47vyek8Xb3NBAcg4xfuQbS7BqcZuTX4wxfD5lVagdggR3gyA== + dependencies: + async "^2.1.4" + fileset "^2.0.2" + istanbul-lib-coverage "^1.2.1" + istanbul-lib-hook "^1.2.2" + istanbul-lib-instrument "^1.10.2" + istanbul-lib-report "^1.1.5" + istanbul-lib-source-maps "^1.2.6" + istanbul-reports "^1.5.1" + js-yaml "^3.7.0" + mkdirp "^0.5.1" + once "^1.4.0" + +istanbul-lib-coverage@^1.2.0, istanbul-lib-coverage@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz#ccf7edcd0a0bb9b8f729feeb0930470f9af664f0" + integrity sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ== + +istanbul-lib-hook@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.2.2.tgz#bc6bf07f12a641fbf1c85391d0daa8f0aea6bf86" + integrity sha512-/Jmq7Y1VeHnZEQ3TL10VHyb564mn6VrQXHchON9Jf/AEcmQ3ZIiyD1BVzNOKTZf/G3gE+kiGK6SmpF9y3qGPLw== + dependencies: + append-transform "^0.4.0" + +istanbul-lib-instrument@^1.10.1, istanbul-lib-instrument@^1.10.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz#1f55ed10ac3c47f2bdddd5307935126754d0a9ca" + integrity sha512-aWHxfxDqvh/ZlxR8BBaEPVSWDPUkGD63VjGQn3jcw8jCp7sHEMKcrj4xfJn/ABzdMEHiQNyvDQhqm5o8+SQg7A== + dependencies: + babel-generator "^6.18.0" + babel-template "^6.16.0" + babel-traverse "^6.18.0" + babel-types "^6.18.0" + babylon "^6.18.0" + istanbul-lib-coverage "^1.2.1" + semver "^5.3.0" + +istanbul-lib-report@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.5.tgz#f2a657fc6282f96170aaf281eb30a458f7f4170c" + integrity sha512-UsYfRMoi6QO/doUshYNqcKJqVmFe9w51GZz8BS3WB0lYxAllQYklka2wP9+dGZeHYaWIdcXUx8JGdbqaoXRXzw== + dependencies: + istanbul-lib-coverage "^1.2.1" + mkdirp "^0.5.1" + path-parse "^1.0.5" + supports-color "^3.1.2" + +istanbul-lib-source-maps@^1.2.4, istanbul-lib-source-maps@^1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.6.tgz#37b9ff661580f8fca11232752ee42e08c6675d8f" + integrity sha512-TtbsY5GIHgbMsMiRw35YBHGpZ1DVFEO19vxxeiDMYaeOFOCzfnYVxvl6pOUIZR4dtPhAGpSMup8OyF8ubsaqEg== + dependencies: + debug "^3.1.0" + istanbul-lib-coverage "^1.2.1" + mkdirp "^0.5.1" + rimraf "^2.6.1" + source-map "^0.5.3" + +istanbul-reports@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.5.1.tgz#97e4dbf3b515e8c484caea15d6524eebd3ff4e1a" + integrity sha512-+cfoZ0UXzWjhAdzosCPP3AN8vvef8XDkWtTfgaN+7L3YTpNYITnCaEkceo5SEYy644VkHka/P1FvkWvrG/rrJw== + dependencies: + handlebars "^4.0.3" + +isurl@^1.0.0-alpha5: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" + integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w== + dependencies: + has-to-string-tag-x "^1.2.0" + is-object "^1.0.1" + +items@2.x.x: + version "2.1.2" + resolved "https://registry.yarnpkg.com/items/-/items-2.1.2.tgz#0849354595805d586dac98e7e6e85556ea838558" + integrity sha512-kezcEqgB97BGeZZYtX/MA8AG410ptURstvnz5RAgyFZ8wQFPMxHY8GpTq+/ZHKT3frSlIthUq7EvLt9xn3TvXg== + +iterall@^1.1.3, iterall@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.2.2.tgz#92d70deb8028e0c39ff3164fdbf4d8b088130cd7" + integrity sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA== + +jest-changed-files@^23.4.2: + version "23.4.2" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-23.4.2.tgz#1eed688370cd5eebafe4ae93d34bb3b64968fe83" + integrity sha512-EyNhTAUWEfwnK0Is/09LxoqNDOn7mU7S3EHskG52djOFS/z+IT0jT3h3Ql61+dklcG7bJJitIWEMB4Sp1piHmA== + dependencies: + throat "^4.0.0" + +jest-cli@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-23.6.0.tgz#61ab917744338f443ef2baa282ddffdd658a5da4" + integrity sha512-hgeD1zRUp1E1zsiyOXjEn4LzRLWdJBV//ukAHGlx6s5mfCNJTbhbHjgxnDUXA8fsKWN/HqFFF6X5XcCwC/IvYQ== + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.1" + exit "^0.1.2" + glob "^7.1.2" + graceful-fs "^4.1.11" + import-local "^1.0.0" + is-ci "^1.0.10" + istanbul-api "^1.3.1" + istanbul-lib-coverage "^1.2.0" + istanbul-lib-instrument "^1.10.1" + istanbul-lib-source-maps "^1.2.4" + jest-changed-files "^23.4.2" + jest-config "^23.6.0" + jest-environment-jsdom "^23.4.0" + jest-get-type "^22.1.0" + jest-haste-map "^23.6.0" + jest-message-util "^23.4.0" + jest-regex-util "^23.3.0" + jest-resolve-dependencies "^23.6.0" + jest-runner "^23.6.0" + jest-runtime "^23.6.0" + jest-snapshot "^23.6.0" + jest-util "^23.4.0" + jest-validate "^23.6.0" + jest-watcher "^23.4.0" + jest-worker "^23.2.0" + micromatch "^2.3.11" + node-notifier "^5.2.1" + prompts "^0.1.9" + realpath-native "^1.0.0" + rimraf "^2.5.4" + slash "^1.0.0" + string-length "^2.0.0" + strip-ansi "^4.0.0" + which "^1.2.12" + yargs "^11.0.0" + +jest-config@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-23.6.0.tgz#f82546a90ade2d8c7026fbf6ac5207fc22f8eb1d" + integrity sha512-i8V7z9BeDXab1+VNo78WM0AtWpBRXJLnkT+lyT+Slx/cbP5sZJ0+NDuLcmBE5hXAoK0aUp7vI+MOxR+R4d8SRQ== + dependencies: + babel-core "^6.0.0" + babel-jest "^23.6.0" + chalk "^2.0.1" + glob "^7.1.1" + jest-environment-jsdom "^23.4.0" + jest-environment-node "^23.4.0" + jest-get-type "^22.1.0" + jest-jasmine2 "^23.6.0" + jest-regex-util "^23.3.0" + jest-resolve "^23.6.0" + jest-util "^23.4.0" + jest-validate "^23.6.0" + micromatch "^2.3.11" + pretty-format "^23.6.0" + +jest-diff@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-23.6.0.tgz#1500f3f16e850bb3d71233408089be099f610c7d" + integrity sha512-Gz9l5Ov+X3aL5L37IT+8hoCUsof1CVYBb2QEkOupK64XyRR3h+uRpYIm97K7sY8diFxowR8pIGEdyfMKTixo3g== + dependencies: + chalk "^2.0.1" + diff "^3.2.0" + jest-get-type "^22.1.0" + pretty-format "^23.6.0" + +jest-docblock@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-23.2.0.tgz#f085e1f18548d99fdd69b20207e6fd55d91383a7" + integrity sha1-8IXh8YVI2Z/dabICB+b9VdkTg6c= + dependencies: + detect-newline "^2.1.0" + +jest-each@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-23.6.0.tgz#ba0c3a82a8054387016139c733a05242d3d71575" + integrity sha512-x7V6M/WGJo6/kLoissORuvLIeAoyo2YqLOoCDkohgJ4XOXSqOtyvr8FbInlAWS77ojBsZrafbozWoKVRdtxFCg== + dependencies: + chalk "^2.0.1" + pretty-format "^23.6.0" + +jest-environment-jsdom@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-23.4.0.tgz#056a7952b3fea513ac62a140a2c368c79d9e6023" + integrity sha1-BWp5UrP+pROsYqFAosNox52eYCM= + dependencies: + jest-mock "^23.2.0" + jest-util "^23.4.0" + jsdom "^11.5.1" + +jest-environment-node@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-23.4.0.tgz#57e80ed0841dea303167cce8cd79521debafde10" + integrity sha1-V+gO0IQd6jAxZ8zozXlSHeuv3hA= + dependencies: + jest-mock "^23.2.0" + jest-util "^23.4.0" + +jest-extended@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/jest-extended/-/jest-extended-0.11.0.tgz#621a0f07c828166657416e590607eab8c3c3eeda" + integrity sha512-7VJQDyObjKRqaiaRvzSbWchwTvk7mQYPaEzPcK2Nwrna6ZSPe/AB9aPDjgH2oT0QONtF6FvM3GIvDdJhttJeaA== + dependencies: + expect "^23.6.0" + jest-get-type "^22.4.3" + jest-matcher-utils "^22.0.0" + +jest-get-type@^22.1.0, jest-get-type@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4" + integrity sha512-/jsz0Y+V29w1chdXVygEKSz2nBoHoYqNShPe+QgxSNjAuP1i8+k4LbQNrfoliKej0P45sivkSCh7yiD6ubHS3w== + +jest-haste-map@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-23.6.0.tgz#2e3eb997814ca696d62afdb3f2529f5bbc935e16" + integrity sha512-uyNhMyl6dr6HaXGHp8VF7cK6KpC6G9z9LiMNsst+rJIZ8l7wY0tk8qwjPmEghczojZ2/ZhtEdIabZ0OQRJSGGg== + dependencies: + fb-watchman "^2.0.0" + graceful-fs "^4.1.11" + invariant "^2.2.4" + jest-docblock "^23.2.0" + jest-serializer "^23.0.1" + jest-worker "^23.2.0" + micromatch "^2.3.11" + sane "^2.0.0" + +jest-jasmine2@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-23.6.0.tgz#840e937f848a6c8638df24360ab869cc718592e0" + integrity sha512-pe2Ytgs1nyCs8IvsEJRiRTPC0eVYd8L/dXJGU08GFuBwZ4sYH/lmFDdOL3ZmvJR8QKqV9MFuwlsAi/EWkFUbsQ== + dependencies: + babel-traverse "^6.0.0" + chalk "^2.0.1" + co "^4.6.0" + expect "^23.6.0" + is-generator-fn "^1.0.0" + jest-diff "^23.6.0" + jest-each "^23.6.0" + jest-matcher-utils "^23.6.0" + jest-message-util "^23.4.0" + jest-snapshot "^23.6.0" + jest-util "^23.4.0" + pretty-format "^23.6.0" + +jest-leak-detector@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-23.6.0.tgz#e4230fd42cf381a1a1971237ad56897de7e171de" + integrity sha512-f/8zA04rsl1Nzj10HIyEsXvYlMpMPcy0QkQilVZDFOaPbv2ur71X5u2+C4ZQJGyV/xvVXtCCZ3wQ99IgQxftCg== + dependencies: + pretty-format "^23.6.0" + +jest-matcher-utils@^22.0.0: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-22.4.3.tgz#4632fe428ebc73ebc194d3c7b65d37b161f710ff" + integrity sha512-lsEHVaTnKzdAPR5t4B6OcxXo9Vy4K+kRRbG5gtddY8lBEC+Mlpvm1CJcsMESRjzUhzkz568exMV1hTB76nAKbA== + dependencies: + chalk "^2.0.1" + jest-get-type "^22.4.3" + pretty-format "^22.4.3" + +jest-matcher-utils@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-23.6.0.tgz#726bcea0c5294261a7417afb6da3186b4b8cac80" + integrity sha512-rosyCHQfBcol4NsckTn01cdelzWLU9Cq7aaigDf8VwwpIRvWE/9zLgX2bON+FkEW69/0UuYslUe22SOdEf2nog== + dependencies: + chalk "^2.0.1" + jest-get-type "^22.1.0" + pretty-format "^23.6.0" + +jest-message-util@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-23.4.0.tgz#17610c50942349508d01a3d1e0bda2c079086a9f" + integrity sha1-F2EMUJQjSVCNAaPR4L2iwHkIap8= + dependencies: + "@babel/code-frame" "^7.0.0-beta.35" + chalk "^2.0.1" + micromatch "^2.3.11" + slash "^1.0.0" + stack-utils "^1.0.1" + +jest-mock-process@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/jest-mock-process/-/jest-mock-process-1.1.0.tgz#0a6f2751bbbd1acc4aa5a3d2fdf707b5d68931a2" + integrity sha512-9B15X9DoAmig5t3bGugOjtJnNHVGSYKALKN7G7/BB5BqRB35F8vKH10ns7ELlZ0XtVv1YfG6e0Yj+g7Qd6JILw== + dependencies: + jest "^23.4.2" + +jest-mock@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-23.2.0.tgz#ad1c60f29e8719d47c26e1138098b6d18b261134" + integrity sha1-rRxg8p6HGdR8JuETgJi20YsmETQ= + +jest-regex-util@^23.3.0: + version "23.3.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-23.3.0.tgz#5f86729547c2785c4002ceaa8f849fe8ca471bc5" + integrity sha1-X4ZylUfCeFxAAs6qj4Sf6MpHG8U= + +jest-resolve-dependencies@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-23.6.0.tgz#b4526af24c8540d9a3fab102c15081cf509b723d" + integrity sha512-EkQWkFWjGKwRtRyIwRwI6rtPAEyPWlUC2MpzHissYnzJeHcyCn1Hc8j7Nn1xUVrS5C6W5+ZL37XTem4D4pLZdA== + dependencies: + jest-regex-util "^23.3.0" + jest-snapshot "^23.6.0" + +jest-resolve@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-23.6.0.tgz#cf1d1a24ce7ee7b23d661c33ba2150f3aebfa0ae" + integrity sha512-XyoRxNtO7YGpQDmtQCmZjum1MljDqUCob7XlZ6jy9gsMugHdN2hY4+Acz9Qvjz2mSsOnPSH7skBmDYCHXVZqkA== + dependencies: + browser-resolve "^1.11.3" + chalk "^2.0.1" + realpath-native "^1.0.0" + +jest-runner@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-23.6.0.tgz#3894bd219ffc3f3cb94dc48a4170a2e6f23a5a38" + integrity sha512-kw0+uj710dzSJKU6ygri851CObtCD9cN8aNkg8jWJf4ewFyEa6kwmiH/r/M1Ec5IL/6VFa0wnAk6w+gzUtjJzA== + dependencies: + exit "^0.1.2" + graceful-fs "^4.1.11" + jest-config "^23.6.0" + jest-docblock "^23.2.0" + jest-haste-map "^23.6.0" + jest-jasmine2 "^23.6.0" + jest-leak-detector "^23.6.0" + jest-message-util "^23.4.0" + jest-runtime "^23.6.0" + jest-util "^23.4.0" + jest-worker "^23.2.0" + source-map-support "^0.5.6" + throat "^4.0.0" + +jest-runtime@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-23.6.0.tgz#059e58c8ab445917cd0e0d84ac2ba68de8f23082" + integrity sha512-ycnLTNPT2Gv+TRhnAYAQ0B3SryEXhhRj1kA6hBPSeZaNQkJ7GbZsxOLUkwg6YmvWGdX3BB3PYKFLDQCAE1zNOw== + dependencies: + babel-core "^6.0.0" + babel-plugin-istanbul "^4.1.6" + chalk "^2.0.1" + convert-source-map "^1.4.0" + exit "^0.1.2" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.1.11" + jest-config "^23.6.0" + jest-haste-map "^23.6.0" + jest-message-util "^23.4.0" + jest-regex-util "^23.3.0" + jest-resolve "^23.6.0" + jest-snapshot "^23.6.0" + jest-util "^23.4.0" + jest-validate "^23.6.0" + micromatch "^2.3.11" + realpath-native "^1.0.0" + slash "^1.0.0" + strip-bom "3.0.0" + write-file-atomic "^2.1.0" + yargs "^11.0.0" + +jest-serializer@^23.0.1: + version "23.0.1" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-23.0.1.tgz#a3776aeb311e90fe83fab9e533e85102bd164165" + integrity sha1-o3dq6zEekP6D+rnlM+hRAr0WQWU= + +jest-snapshot@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-23.6.0.tgz#f9c2625d1b18acda01ec2d2b826c0ce58a5aa17a" + integrity sha512-tM7/Bprftun6Cvj2Awh/ikS7zV3pVwjRYU2qNYS51VZHgaAMBs5l4o/69AiDHhQrj5+LA2Lq4VIvK7zYk/bswg== + dependencies: + babel-types "^6.0.0" + chalk "^2.0.1" + jest-diff "^23.6.0" + jest-matcher-utils "^23.6.0" + jest-message-util "^23.4.0" + jest-resolve "^23.6.0" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + pretty-format "^23.6.0" + semver "^5.5.0" + +jest-util@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-23.4.0.tgz#4d063cb927baf0a23831ff61bec2cbbf49793561" + integrity sha1-TQY8uSe68KI4Mf9hvsLLv0l5NWE= + dependencies: + callsites "^2.0.0" + chalk "^2.0.1" + graceful-fs "^4.1.11" + is-ci "^1.0.10" + jest-message-util "^23.4.0" + mkdirp "^0.5.1" + slash "^1.0.0" + source-map "^0.6.0" + +jest-validate@^23.5.0, jest-validate@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-23.6.0.tgz#36761f99d1ed33fcd425b4e4c5595d62b6597474" + integrity sha512-OFKapYxe72yz7agrDAWi8v2WL8GIfVqcbKRCLbRG9PAxtzF9b1SEDdTpytNDN12z2fJynoBwpMpvj2R39plI2A== + dependencies: + chalk "^2.0.1" + jest-get-type "^22.1.0" + leven "^2.1.0" + pretty-format "^23.6.0" + +jest-watcher@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-23.4.0.tgz#d2e28ce74f8dad6c6afc922b92cabef6ed05c91c" + integrity sha1-0uKM50+NrWxq/JIrksq+9u0FyRw= + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.1" + string-length "^2.0.0" + +jest-worker@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-23.2.0.tgz#faf706a8da36fae60eb26957257fa7b5d8ea02b9" + integrity sha1-+vcGqNo2+uYOsmlXJX+ntdjqArk= + dependencies: + merge-stream "^1.0.1" + +jest@^23.4.2, jest@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-23.6.0.tgz#ad5835e923ebf6e19e7a1d7529a432edfee7813d" + integrity sha512-lWzcd+HSiqeuxyhG+EnZds6iO3Y3ZEnMrfZq/OTGvF/C+Z4fPMCdhWTGSAiO2Oym9rbEXfwddHhh6jqrTF3+Lw== + dependencies: + import-local "^1.0.0" + jest-cli "^23.6.0" + +jju@^1.1.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/jju/-/jju-1.4.0.tgz#a3abe2718af241a2b2904f84a625970f389ae32a" + integrity sha1-o6vicYryQaKykE+EpiWXDzia4yo= + +jmespath@^0.15.0: + version "0.15.0" + resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" + integrity sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc= + +joi@12.x.x: + version "12.0.0" + resolved "https://registry.yarnpkg.com/joi/-/joi-12.0.0.tgz#46f55e68f4d9628f01bbb695902c8b307ad8d33a" + integrity sha512-z0FNlV4NGgjQN1fdtHYXf5kmgludM65fG/JlXzU6+rwkt9U5UWuXVYnXa2FpK0u6+qBuCmrm5byPNuiiddAHvQ== + dependencies: + hoek "4.x.x" + isemail "3.x.x" + topo "2.x.x" + +joi@13.x.x, joi@^13.0.2: + version "13.7.0" + resolved "https://registry.yarnpkg.com/joi/-/joi-13.7.0.tgz#cfd85ebfe67e8a1900432400b4d03bbd93fb879f" + integrity sha512-xuY5VkHfeOYK3Hdi91ulocfuFopwgbSORmIwzcwHKESQhC7w1kD5jaVSPnqDxS2I8t3RZ9omCKAxNwXN5zG1/Q== + dependencies: + hoek "5.x.x" + isemail "3.x.x" + topo "3.x.x" + +joi@14.x.x, joi@^14.3.0: + version "14.3.0" + resolved "https://registry.yarnpkg.com/joi/-/joi-14.3.0.tgz#55f7c5caa8256de74ccb12eb22ab1c19eea02db3" + integrity sha512-0HKd1z8MWogez4GaU0LkY1FgW30vR2Kwy414GISfCU41OYgUC2GWpNe5amsvBZtDqPtt7DohykfOOMIw1Z5hvQ== + dependencies: + hoek "6.x.x" + isemail "3.x.x" + topo "3.x.x" + +joi@^10.6.0: + version "10.6.0" + resolved "https://registry.yarnpkg.com/joi/-/joi-10.6.0.tgz#52587f02d52b8b75cdb0c74f0b164a191a0e1fc2" + integrity sha512-hBF3LcqyAid+9X/pwg+eXjD2QBZI5eXnBFJYaAkH4SK3mp9QSRiiQnDYlmlz5pccMvnLcJRS4whhDOTCkmsAdQ== + dependencies: + hoek "4.x.x" + isemail "2.x.x" + items "2.x.x" + topo "2.x.x" + +js-levenshtein@^1.1.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.4.tgz#3a56e3cbf589ca0081eb22cd9ba0b1290a16d26e" + integrity sha512-PxfGzSs0ztShKrUYPIn5r0MtyAhYcCwmndozzpz8YObbPnD1jFxzlBGbRnX2mIu6Z13xN6+PTu05TQFnZFlzow== + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls= + +js-yaml@^3.12.0, js-yaml@^3.4.2, js-yaml@^3.7.0, js-yaml@^3.9.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" + integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + +jsdom@^11.5.1: + version "11.12.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8" + integrity sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw== + dependencies: + abab "^2.0.0" + acorn "^5.5.3" + acorn-globals "^4.1.0" + array-equal "^1.0.0" + cssom ">= 0.3.2 < 0.4.0" + cssstyle "^1.0.0" + data-urls "^1.0.0" + domexception "^1.0.1" + escodegen "^1.9.1" + html-encoding-sniffer "^1.0.2" + left-pad "^1.3.0" + nwsapi "^2.0.7" + parse5 "4.0.0" + pn "^1.1.0" + request "^2.87.0" + request-promise-native "^1.0.5" + sax "^1.2.4" + symbol-tree "^3.2.2" + tough-cookie "^2.3.4" + w3c-hr-time "^1.0.1" + webidl-conversions "^4.0.2" + whatwg-encoding "^1.0.3" + whatwg-mimetype "^2.1.0" + whatwg-url "^6.4.1" + ws "^5.2.0" + xml-name-validator "^3.0.0" + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + integrity sha1-RsP+yMGJKxKwgz25vHYiF226s0s= + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= + +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= + +json-parse-better-errors@^1.0.0, json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-parse-helpfulerror@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/json-parse-helpfulerror/-/json-parse-helpfulerror-1.0.3.tgz#13f14ce02eed4e981297b64eb9e3b932e2dd13dc" + integrity sha1-E/FM4C7tTpgSl7ZOueO5MuLdE9w= + dependencies: + jju "^1.1.0" + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +json-stable-stringify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + integrity sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8= + dependencies: + jsonify "~0.0.0" + +json-stringify-safe@5.0.x, json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +json5@^0.5.0, json5@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE= + +json5@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" + integrity sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow== + dependencies: + minimist "^1.2.0" + +json5@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850" + integrity sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ== + dependencies: + minimist "^1.2.0" + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= + +jsonparse@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" + integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= + +jsonpointer@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" + integrity sha1-T9kss04OnbPInIYi7PUfm5eMbLk= + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +jszip@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.1.5.tgz#e3c2a6c6d706ac6e603314036d43cd40beefdf37" + integrity sha512-5W8NUaFRFRqTOL7ZDDrx5qWHJyBXy6velVudIzQUSoqAAYqzSh2Z7/m0Rf1QbmQJccegD0r+YZxBjzqoBiEeJQ== + dependencies: + core-js "~2.3.0" + es6-promise "~3.0.2" + lie "~3.1.0" + pako "~1.0.2" + readable-stream "~2.0.6" + +keyv@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373" + integrity sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA== + dependencies: + json-buffer "3.0.0" + +keyv@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" + integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== + dependencies: + json-buffer "3.0.0" + +kind-of@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-2.0.1.tgz#018ec7a4ce7e3a86cb9141be519d24c8faa981b5" + integrity sha1-AY7HpM5+OobLkUG+UZ0kyPqpgbU= + dependencies: + is-buffer "^1.0.2" + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0, kind-of@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== + +kleur@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-2.0.2.tgz#b704f4944d95e255d038f0cb05fb8a602c55a300" + integrity sha512-77XF9iTllATmG9lSlIv0qdQ2BQ/h9t0bJllHlbvsQ0zUWfU7Yi0S8L5JXzPZgkefIiajLmBJJ4BsMJmqcf7oxQ== + +kuler@1.0.x: + version "1.0.1" + resolved "https://registry.yarnpkg.com/kuler/-/kuler-1.0.1.tgz#ef7c784f36c9fb6e16dd3150d152677b2b0228a6" + integrity sha512-J9nVUucG1p/skKul6DU3PUZrhs0LPulNaeUOox0IyXDi8S4CztTHs1gQphhuZmzXG7VOQSf6NJfKuzteQLv9gQ== + dependencies: + colornames "^1.1.1" + +latest-version@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" + integrity sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU= + dependencies: + package-json "^4.0.0" + +lazy-cache@^0.2.3: + version "0.2.7" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-0.2.7.tgz#7feddf2dcb6edb77d11ef1d117ab5ffdf0ab1b65" + integrity sha1-f+3fLctu23fRHvHRF6tf/fCrG2U= + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= + dependencies: + invert-kv "^1.0.0" + +lcid@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" + integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== + dependencies: + invert-kv "^2.0.0" + +left-pad@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" + integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA== + +lerna@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/lerna/-/lerna-3.5.0.tgz#fd989b8992701e90e10aa5b3970d6f7a3512ba64" + integrity sha512-12kZb2yCJtx3rhLycepzHTbR6suqLaqky2hSldGQh9+B7FXFgvbQJXwzoi+Y7+1cstmKHHyockdRYFLiLmiEYA== + dependencies: + "@lerna/add" "^3.5.0" + "@lerna/bootstrap" "^3.5.0" + "@lerna/changed" "^3.5.0" + "@lerna/clean" "^3.5.0" + "@lerna/cli" "^3.2.0" + "@lerna/create" "^3.5.0" + "@lerna/diff" "^3.5.0" + "@lerna/exec" "^3.5.0" + "@lerna/import" "^3.5.0" + "@lerna/init" "^3.5.0" + "@lerna/link" "^3.5.0" + "@lerna/list" "^3.5.0" + "@lerna/publish" "^3.5.0" + "@lerna/run" "^3.5.0" + "@lerna/version" "^3.5.0" + import-local "^1.0.0" + npmlog "^4.1.2" + +leven@2.1.0, leven@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" + integrity sha1-wuep93IJTe6dNCAq6KzORoeHVYA= + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +libnpmaccess@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/libnpmaccess/-/libnpmaccess-3.0.1.tgz#5b3a9de621f293d425191aa2e779102f84167fa8" + integrity sha512-RlZ7PNarCBt+XbnP7R6PoVgOq9t+kou5rvhaInoNibhPO7eMlRfS0B8yjatgn2yaHIwWNyoJDolC/6Lc5L/IQA== + dependencies: + aproba "^2.0.0" + get-stream "^4.0.0" + npm-package-arg "^6.1.0" + npm-registry-fetch "^3.8.0" + +lie@~3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e" + integrity sha1-mkNrLMd0bKWd56QfpGmz77dr2H4= + dependencies: + immediate "~3.0.5" + +lint-staged@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-8.1.0.tgz#dbc3ae2565366d8f20efb9f9799d076da64863f2" + integrity sha512-yfSkyJy7EuVsaoxtUSEhrD81spdJOe/gMTGea3XaV7HyoRhTb9Gdlp6/JppRZERvKSEYXP9bjcmq6CA5oL2lYQ== + dependencies: + "@iamstarkov/listr-update-renderer" "0.4.1" + chalk "^2.3.1" + commander "^2.14.1" + cosmiconfig "5.0.6" + debug "^3.1.0" + dedent "^0.7.0" + del "^3.0.0" + execa "^1.0.0" + find-parent-dir "^0.3.0" + g-status "^2.0.2" + is-glob "^4.0.0" + is-windows "^1.0.2" + jest-validate "^23.5.0" + listr "^0.14.2" + lodash "^4.17.5" + log-symbols "^2.2.0" + micromatch "^3.1.8" + npm-which "^3.0.1" + p-map "^1.1.1" + path-is-inside "^1.0.2" + pify "^3.0.0" + please-upgrade-node "^3.0.2" + staged-git-files "1.1.2" + string-argv "^0.0.2" + stringify-object "^3.2.2" + +listr-silent-renderer@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e" + integrity sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4= + +listr-update-renderer@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz#4ea8368548a7b8aecb7e06d8c95cb45ae2ede6a2" + integrity sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA== + dependencies: + chalk "^1.1.3" + cli-truncate "^0.2.1" + elegant-spinner "^1.0.1" + figures "^1.7.0" + indent-string "^3.0.0" + log-symbols "^1.0.2" + log-update "^2.3.0" + strip-ansi "^3.0.1" + +listr-verbose-renderer@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz#f1132167535ea4c1261102b9f28dac7cba1e03db" + integrity sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw== + dependencies: + chalk "^2.4.1" + cli-cursor "^2.1.0" + date-fns "^1.27.2" + figures "^2.0.0" + +listr@^0.14.2: + version "0.14.3" + resolved "https://registry.yarnpkg.com/listr/-/listr-0.14.3.tgz#2fea909604e434be464c50bddba0d496928fa586" + integrity sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA== + dependencies: + "@samverschueren/stream-to-observable" "^0.3.0" + is-observable "^1.1.0" + is-promise "^2.1.0" + is-stream "^1.1.0" + listr-silent-renderer "^1.1.1" + listr-update-renderer "^0.5.0" + listr-verbose-renderer "^0.5.0" + p-map "^2.0.0" + rxjs "^6.3.3" + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +load-json-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" + integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + strip-bom "^3.0.0" + +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + +loader-runner@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.1.tgz#026f12fe7c3115992896ac02ba022ba92971b979" + integrity sha512-By6ZFY7ETWOc9RFaAIb23IjJVcM4dvJC/N57nmdz9RSkMXvAXGI7SyVlAw3v8vjtDRlqThgVDVmTnr9fqMlxkw== + +loader-utils@^1.0.2, loader-utils@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" + integrity sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0= + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +lockfile@~1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/lockfile/-/lockfile-1.0.4.tgz#07f819d25ae48f87e538e6578b6964a4981a5609" + integrity sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA== + dependencies: + signal-exit "^3.0.2" + +lodash._baseuniq@~4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8" + integrity sha1-DrtE5FaBSveQXGIS+iybLVG4Qeg= + dependencies: + lodash._createset "~4.0.0" + lodash._root "~3.0.0" + +lodash._createset@~4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26" + integrity sha1-D0ZZ+7CddRlPqeK4imZE02PJ/iY= + +lodash._reinterpolate@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= + +lodash._root@~3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692" + integrity sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI= + +lodash.assign@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" + integrity sha1-DZnzzNem0mHRm9rrkkUAXShYCOc= + +lodash.assignin@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2" + integrity sha1-uo31+4QesKPoBEIysOJjqNxqKKI= + +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= + +lodash.chunk@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.chunk/-/lodash.chunk-4.2.0.tgz#66e5ce1f76ed27b4303d8c6512e8d1216e8106bc" + integrity sha1-ZuXOH3btJ7QwPYxlEujRIW6BBrw= + +lodash.clone@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clone/-/lodash.clone-4.5.0.tgz#195870450f5a13192478df4bc3d23d2dea1907b6" + integrity sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y= + +lodash.clonedeep@^4.3.0, lodash.clonedeep@^4.5.0, lodash.clonedeep@~4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= + +lodash.clonedeepwith@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeepwith/-/lodash.clonedeepwith-4.5.0.tgz#6ee30573a03a1a60d670a62ef33c10cf1afdbdd4" + integrity sha1-buMFc6A6GmDWcKYu8zwQzxr9vdQ= + +lodash.compact@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash.compact/-/lodash.compact-3.0.1.tgz#540ce3837745975807471e16b4a2ba21e7256ca5" + integrity sha1-VAzjg3dFl1gHRx4WtKK6IeclbKU= + +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= + +lodash.fill@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/lodash.fill/-/lodash.fill-3.4.0.tgz#a3c74ae640d053adf0dc2079f8720788e8bfef85" + integrity sha1-o8dK5kDQU63w3CB5+HIHiOi/74U= + +lodash.first@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash.first/-/lodash.first-3.0.0.tgz#5dae180d7f818ee65fc5b210b104a7bbef98a16a" + integrity sha1-Xa4YDX+BjuZfxbIQsQSnu++YoWo= + +lodash.flatten@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" + integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8= + +lodash.get@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" + integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= + +lodash.groupby@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.groupby/-/lodash.groupby-4.6.0.tgz#0b08a1dcf68397c397855c3239783832df7403d1" + integrity sha1-Cwih3PaDl8OXhVwyOXg4Mt90A9E= + +lodash.head@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.head/-/lodash.head-4.0.1.tgz#e2aa322d3ec40cd6aae186082977d993b354ed9c" + integrity sha1-4qoyLT7EDNaq4YYIKXfZk7NU7Zw= + +lodash.isempty@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.isempty/-/lodash.isempty-4.4.0.tgz#6f86cbedd8be4ec987be9aaf33c9684db1b31e7e" + integrity sha1-b4bL7di+TsmHvpqvM8loTbGzHn4= + +lodash.isequal@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + integrity sha1-QVxEePK8wwEgwizhDtMib30+GOA= + +lodash.isfunction@^3.0.8, lodash.isfunction@~3.0.8: + version "3.0.9" + resolved "https://registry.yarnpkg.com/lodash.isfunction/-/lodash.isfunction-3.0.9.tgz#06de25df4db327ac931981d1bdb067e5af68d051" + integrity sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw== + +lodash.isnumber@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" + integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w= + +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE= + +lodash.last@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash.last/-/lodash.last-3.0.0.tgz#242f663112dd4c6e63728c60a3c909d1bdadbd4c" + integrity sha1-JC9mMRLdTG5jcoxgo8kJ0b2tvUw= + +lodash.orderby@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.orderby/-/lodash.orderby-4.6.0.tgz#e697f04ce5d78522f54d9338b32b81a3393e4eb3" + integrity sha1-5pfwTOXXhSL1TZM4syuBozk+TrM= + +lodash.pick@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" + integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM= + +lodash.sample@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/lodash.sample/-/lodash.sample-4.2.1.tgz#5e4291b0c753fa1abeb0aab8fb29df1b66f07f6d" + integrity sha1-XkKRsMdT+hq+sKq4+ynfG2bwf20= + +lodash.set@^4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23" + integrity sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM= + +lodash.shuffle@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.shuffle/-/lodash.shuffle-4.2.0.tgz#145b5053cf875f6f5c2a33f48b6e9948c6ec7b4b" + integrity sha1-FFtQU8+HX29cKjP0i26ZSMbse0s= + +lodash.snakecase@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz#39d714a35357147837aefd64b5dcbb16becd8f8d" + integrity sha1-OdcUo1NXFHg3rv1ktdy7Fr7Nj40= + +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= + +lodash.sumby@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.sumby/-/lodash.sumby-4.6.0.tgz#7d87737ddb216da2f7e5e7cd2dd9c403a7887346" + integrity sha1-fYdzfdshbaL35efNLdnEA6eIc0Y= + +lodash.take@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.take/-/lodash.take-4.1.1.tgz#0b4146dcb7a70c6153495187fc10b12b71fefadf" + integrity sha1-C0FG3LenDGFTSVGH/BCxK3H++t8= + +lodash.template@^4.0.2: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.4.0.tgz#e73a0385c8355591746e020b99679c690e68fba0" + integrity sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A= + dependencies: + lodash._reinterpolate "~3.0.0" + lodash.templatesettings "^4.0.0" + +lodash.templatesettings@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz#2b4d4e95ba440d915ff08bc899e4553666713316" + integrity sha1-K01OlbpEDZFf8IvImeRVNmZxMxY= + dependencies: + lodash._reinterpolate "~3.0.0" + +lodash.toarray@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561" + integrity sha1-JMS/zWsvuji/0FlNsRedjptlZWE= + +lodash.union@~4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88" + integrity sha1-SLtQiECfFvGCFmZkHETdGqrjzYg= + +lodash.uniq@^4.5.0, lodash.uniq@~4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= + +lodash.uniqby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz#d99c07a669e9e6d24e1362dfe266c67616af1302" + integrity sha1-2ZwHpmnp5tJOE2Lf4mbGdhavEwI= + +lodash.without@~4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.without/-/lodash.without-4.4.0.tgz#3cd4574a00b67bae373a94b748772640507b7aac" + integrity sha1-PNRXSgC2e643OpS3SHcmQFB7eqw= + +lodash@4.1.x: + version "4.1.0" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.1.0.tgz#299894283de01a9eefbedff4c4b9b00a6a2e6e96" + integrity sha1-KZiUKD3gGp7vvt/0xLmwCmoubpY= + +lodash@4.17.10: + version "4.17.10" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" + integrity sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg== + +lodash@^4, lodash@^4.11.1, lodash@^4.13.1, lodash@^4.15.0, lodash@^4.17.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.5.1: + version "4.17.11" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" + integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== + +log-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" + integrity sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg= + dependencies: + chalk "^1.0.0" + +log-symbols@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" + integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== + dependencies: + chalk "^2.0.1" + +log-update@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-2.3.0.tgz#88328fd7d1ce7938b29283746f0b1bc126b24708" + integrity sha1-iDKP19HOeTiykoN0bwsbwSayRwg= + dependencies: + ansi-escapes "^3.0.0" + cli-cursor "^2.0.0" + wrap-ansi "^3.0.1" + +logform@^1.6.0, logform@^1.9.1: + version "1.10.0" + resolved "https://registry.yarnpkg.com/logform/-/logform-1.10.0.tgz#c9d5598714c92b546e23f4e78147c40f1e02012e" + integrity sha512-em5ojIhU18fIMOw/333mD+ZLE2fis0EzXl1ZwHx4iQzmpQi6odNiY/t+ITNr33JZhT9/KEaH+UPIipr6a9EjWg== + dependencies: + colors "^1.2.1" + fast-safe-stringify "^2.0.4" + fecha "^2.3.3" + ms "^2.1.1" + triple-beam "^1.2.0" + +long@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" + integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== + +long@~3: + version "3.2.0" + resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b" + integrity sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s= + +loose-envify@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +loud-rejection@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lout@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/lout/-/lout-11.1.0.tgz#4c48b6b068b42197acb6420d79b856095d174589" + integrity sha512-HAowXHOraHWEPrYPuNc7mR8v1Sn1Gnmy8uvpXYDidVHsTMlrkxqUZ1liBXGOf4eN22kVB+eG29NWymPhZG/wKg== + dependencies: + boom "7.x.x" + handlebars "4.x.x" + hoek "5.x.x" + +lower-case@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" + integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw= + +lowercase-keys@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" + integrity sha1-TjNms55/VFfjXxMkvfb4jQv8cwY= + +lowercase-keys@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + +lru-cache@4.1.x, lru-cache@^4.0.0, lru-cache@^4.0.1, lru-cache@^4.1.2, lru-cache@^4.1.3: + version "4.1.4" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.4.tgz#51cc46e8e6d9530771c857e24ccc720ecdbcc031" + integrity sha512-EPstzZ23znHUVLKj+lcXO1KvZkrlw+ZirdwvOmnAnA/1PB4ggyXJ77LRkCqkff+ShQ+cqoxCxLQOh4cKITO5iA== + dependencies: + pseudomap "^1.0.2" + yallist "^3.0.2" + +lru-cache@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +lsmod@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lsmod/-/lsmod-1.0.0.tgz#9a00f76dca36eb23fa05350afe1b585d4299e64b" + integrity sha1-mgD3bco26yP6BTUK/htYXUKZ5ks= + +macos-release@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-1.1.0.tgz#831945e29365b470aa8724b0ab36c8f8959d10fb" + integrity sha512-mmLbumEYMi5nXReB9js3WGsB8UE6cDBWyIO62Z4DNx6GbRhDxHNjA1MlzSpJ2S2KM1wyiPRA0d19uHWYYvMHjA== + +make-dir@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== + dependencies: + pify "^3.0.0" + +make-fetch-happen@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-4.0.1.tgz#141497cb878f243ba93136c83d8aba12c216c083" + integrity sha512-7R5ivfy9ilRJ1EMKIOziwrns9fGeAD4bAha8EB7BIiBBLHm2KeTUGCrICFt2rbHfzheTLynv50GnNTK1zDTrcQ== + dependencies: + agentkeepalive "^3.4.1" + cacache "^11.0.1" + http-cache-semantics "^3.8.1" + http-proxy-agent "^2.1.0" + https-proxy-agent "^2.2.1" + lru-cache "^4.1.2" + mississippi "^3.0.0" + node-fetch-npm "^2.0.2" + promise-retry "^1.1.1" + socks-proxy-agent "^4.0.0" + ssri "^6.0.0" + +makeerror@1.0.x: + version "1.0.11" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" + integrity sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw= + dependencies: + tmpl "1.0.x" + +manakin@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/manakin/-/manakin-0.5.2.tgz#abe3df430ca6085f6983f6e4cf5af0298f4d30cc" + integrity sha512-pfDSB7QYoVg0Io4KMV9hhPoXpj6p0uBscgtyUSKCOFZe8bqgbpStfgnKIbF/ulnr6U3ICu4OqdyxAqBgOhZwBQ== + +map-age-cleaner@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" + integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== + dependencies: + p-defer "^1.0.0" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-obj@^1.0.0, map-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= + +map-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-2.0.0.tgz#a65cd29087a92598b8791257a523e021222ac1f9" + integrity sha1-plzSkIepJZi4eRJXpSPgISIqwfk= + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +matcher@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/matcher/-/matcher-1.1.1.tgz#51d8301e138f840982b338b116bb0c09af62c1c2" + integrity sha512-+BmqxWIubKTRKNWx/ahnCkk3mG8m7OturVlqq6HiojGJTd5hVYbgZm6WzcYPCoB+KBT4Vd6R7WSRG2OADNaCjg== + dependencies: + escape-string-regexp "^1.0.4" + +math-random@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac" + integrity sha1-izqsWIuKZuSXXjzepn97sylgH6w= + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +media-type@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/media-type/-/media-type-0.3.1.tgz#5d569cdd0c52d9c41c7c6451973edd267fb21bcb" + integrity sha1-XVac3QxS2cQcfGRRlz7dJn+yG8s= + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +mem@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" + integrity sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y= + dependencies: + mimic-fn "^1.0.0" + +mem@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-4.0.0.tgz#6437690d9471678f6cc83659c00cbafcd6b0cdaf" + integrity sha512-WQxG/5xYc3tMbYLXoXPm81ET2WDULiU5FxbuIoNbJqLOOI8zehXFdZuiUEgfdrU2mVB1pxBZUGlYORSrpuJreA== + dependencies: + map-age-cleaner "^0.1.1" + mimic-fn "^1.0.0" + p-is-promise "^1.1.0" + +memory-fs@^0.4.0, memory-fs@~0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +meow@^3.3.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= + dependencies: + camelcase-keys "^2.0.0" + decamelize "^1.1.2" + loud-rejection "^1.0.0" + map-obj "^1.0.1" + minimist "^1.1.3" + normalize-package-data "^2.3.4" + object-assign "^4.0.1" + read-pkg-up "^1.0.1" + redent "^1.0.0" + trim-newlines "^1.0.0" + +meow@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/meow/-/meow-4.0.1.tgz#d48598f6f4b1472f35bf6317a95945ace347f975" + integrity sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A== + dependencies: + camelcase-keys "^4.0.0" + decamelize-keys "^1.0.0" + loud-rejection "^1.0.0" + minimist "^1.1.3" + minimist-options "^3.0.1" + normalize-package-data "^2.3.4" + read-pkg-up "^3.0.0" + redent "^2.0.0" + trim-newlines "^2.0.0" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= + +merge-stream@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1" + integrity sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE= + dependencies: + readable-stream "^2.0.1" + +merge2@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.3.tgz#7ee99dbd69bb6481689253f018488a1b902b0ed5" + integrity sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA== + +merge@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" + integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ== + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +micromatch@^2.3.11: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + integrity sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU= + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + +micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +mime-db@1.x.x, mime-db@~1.37.0: + version "1.37.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.37.0.tgz#0b6a0ce6fdbe9576e25f1f2d2fde8830dc0ad0d8" + integrity sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg== + +mime-types@^2.1.11, mime-types@^2.1.12, mime-types@~2.1.18, mime-types@~2.1.19, mime-types@~2.1.7: + version "2.1.21" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.21.tgz#28995aa1ecb770742fe6ae7e58f9181c744b3f96" + integrity sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg== + dependencies: + mime-db "~1.37.0" + +mime@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" + integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== + +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== + +mimic-response@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +mimos@4.x.x: + version "4.0.2" + resolved "https://registry.yarnpkg.com/mimos/-/mimos-4.0.2.tgz#f2762d7c60118ce51c2231afa090bc335d21d0f8" + integrity sha512-5XBsDqBqzSN88XPPH/TFpOalWOjHJM5Z2d3AMx/30iq+qXvYKd/8MPhqBwZDOLtoaIWInR3nLzMQcxfGK9djXA== + dependencies: + hoek "6.x.x" + mime-db "1.x.x" + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= + +minimatch@3.0.4, minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist-options@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-3.0.2.tgz#fba4c8191339e13ecf4d61beb03f070103f3d954" + integrity sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ== + dependencies: + arrify "^1.0.1" + is-plain-obj "^1.1.0" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= + +minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= + +minimist@~0.0.1: + version "0.0.10" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= + +minipass@^2.2.1, minipass@^2.3.4, minipass@^2.3.5: + version "2.3.5" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" + integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.1.tgz#6734acc045a46e61d596a43bb9d9cd326e19cc42" + integrity sha512-TrfjCjk4jLhcJyGMYymBH6oTXcWjYbUAXTHDbtnWHjZC25h0cdajHuPE1zxb4DVmu8crfh+HwH/WMuyLG0nHBg== + dependencies: + minipass "^2.2.1" + +mississippi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" + integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^3.0.0" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + +mixin-deep@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" + integrity sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mixin-object@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/mixin-object/-/mixin-object-2.0.1.tgz#4fb949441dab182540f1fe035ba60e1947a5e57e" + integrity sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4= + dependencies: + for-in "^0.1.3" + is-extendable "^0.1.1" + +"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= + dependencies: + minimist "0.0.8" + +modify-values@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" + integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw== + +moment-timezone@^0.5.14: + version "0.5.23" + resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.23.tgz#7cbb00db2c14c71b19303cb47b0fb0a6d8651463" + integrity sha512-WHFH85DkCfiNMDX5D3X7hpNH3/PUhjTGcD0U1SgfBGZxJ3qUmJh5FdvaFjcClxOvB3rzdfj4oRffbI38jEnC1w== + dependencies: + moment ">= 2.9.0" + +moment@2.20.x: + version "2.20.1" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.20.1.tgz#d6eb1a46cbcc14a2b2f9434112c1ff8907f313fd" + integrity sha512-Yh9y73JRljxW5QxN08Fner68eFLxM5ynNOAw2LbIB1YAGeQzZT8QFSUvkAz609Zf+IHhhaUxqZK8dG3W/+HEvg== + +"moment@>= 2.9.0", moment@^2.11.2, moment@^2.20.0: + version "2.22.2" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.22.2.tgz#3c257f9839fc0e93ff53149632239eb90783ff66" + integrity sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y= + +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + integrity sha1-viwAX9oy4LKa8fBdfEszIUxwH5I= + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + +mri@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/mri/-/mri-1.1.1.tgz#85aa26d3daeeeedf80dc5984af95cc5ca5cad9f1" + integrity sha1-haom09ru7t+A3FmEr5XMXKXK2fE= + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@^2.0.0, ms@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +msgpack-lite@^0.1.26: + version "0.1.26" + resolved "https://registry.yarnpkg.com/msgpack-lite/-/msgpack-lite-0.1.26.tgz#dd3c50b26f059f25e7edee3644418358e2a9ad89" + integrity sha1-3TxQsm8FnyXn7e42REGDWOKprYk= + dependencies: + event-lite "^0.1.1" + ieee754 "^1.1.8" + int64-buffer "^0.1.9" + isarray "^1.0.0" + +multimatch@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" + integrity sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis= + dependencies: + array-differ "^1.0.0" + array-union "^1.0.1" + arrify "^1.0.0" + minimatch "^3.0.0" + +mute-stream@0.0.7, mute-stream@~0.0.4: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= + +nan@^2.10.0, nan@^2.2.1, nan@^2.9.2: + version "2.11.1" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.11.1.tgz#90e22bccb8ca57ea4cd37cc83d3819b52eea6766" + integrity sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA== + +nan@~2.10.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" + integrity sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +nconf@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/nconf/-/nconf-0.10.0.tgz#da1285ee95d0a922ca6cee75adcf861f48205ad2" + integrity sha512-fKiXMQrpP7CYWJQzKkPPx9hPgmq+YLDyxcG9N8RpiE9FoCkCbzD0NyW0YhE3xn3Aupe7nnDeIx4PFzYehpHT9Q== + dependencies: + async "^1.4.0" + ini "^1.3.0" + secure-keys "^1.0.0" + yargs "^3.19.0" + +needle@^2.2.1, needle@^2.2.4: + version "2.2.4" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" + integrity sha512-HyoqEb4wr/rsoaIDfTH2aVL9nWtQqba2/HvMv+++m8u0dz808MaagKILxtfeSN7QU7nvbQ79zk3vYOJp9zsNEA== + dependencies: + debug "^2.1.2" + iconv-lite "^0.4.4" + sax "^1.2.4" + +negotiator@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" + integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk= + +neo-async@^2.5.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.0.tgz#b9d15e4d71c6762908654b5183ed38b753340835" + integrity sha512-MFh0d/Wa7vkKO3Y3LlacqAEeHK0mckVqzDieUKTT+KGxi+zIpeVsFxymkIiRpbpDziHc290Xr9A1O4Om7otoRA== + +netmask@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/netmask/-/netmask-1.0.6.tgz#20297e89d86f6f6400f250d9f4f6b4c1945fcd35" + integrity sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU= + +next-tick@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +nigel@3.x.x: + version "3.0.4" + resolved "https://registry.yarnpkg.com/nigel/-/nigel-3.0.4.tgz#edcd82f2e9387fe34ba21e3127ae4891547c7945" + integrity sha512-3SZCCS/duVDGxFpTROHEieC+itDo4UqL9JNUyQJv3rljudQbK6aqus5B4470OxhESPJLN93Qqxg16rH7DUjbfQ== + dependencies: + hoek "6.x.x" + vise "3.x.x" + +no-case@^2.2.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" + integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ== + dependencies: + lower-case "^1.1.1" + +node-alias@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/node-alias/-/node-alias-1.0.4.tgz#1f1b916b56b9ea241c0135f97ced6940f556f292" + integrity sha1-HxuRa1a56iQcATX5fO1pQPVW8pI= + dependencies: + chalk "^1.1.1" + lodash "^4.2.0" + +node-emoji@^1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.8.1.tgz#6eec6bfb07421e2148c75c6bba72421f8530a826" + integrity sha512-+ktMAh1Jwas+TnGodfCfjUbJKoANqPaJFN0z0iqh41eqD8dvguNzcitVSBSVK1pidz0AqGbLKcoVuVLRVZ/aVg== + dependencies: + lodash.toarray "^4.4.0" + +node-fetch-npm@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/node-fetch-npm/-/node-fetch-npm-2.0.2.tgz#7258c9046182dca345b4208eda918daf33697ff7" + integrity sha512-nJIxm1QmAj4v3nfCvEeCrYSoVwXyxLnaPBK5W1W5DGEJwjlKuC2VEUycGw5oxk+4zZahRrB84PUJJgEmhFTDFw== + dependencies: + encoding "^0.1.11" + json-parse-better-errors "^1.0.0" + safe-buffer "^5.1.1" + +node-fetch@^2.1.2, node-fetch@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.3.0.tgz#1a1d940bbfb916a1d3e0219f037e89e71f8c5fa5" + integrity sha512-MOd8pV3fxENbryESLgVIeaGKrdl+uaYhCSSVkjeOb/31/njTpcis5aWfdqgNlHIrKOLRbMnfPINPOML2CIFeXA== + +node-fingerprint@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/node-fingerprint/-/node-fingerprint-0.0.2.tgz#31cbabeb71a67ae7dd5a7dc042e51c3c75868501" + integrity sha1-Mcur63GmeufdWn3AQuUcPHWGhQE= + +node-forge@^0.7.6: + version "0.7.6" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.6.tgz#fdf3b418aee1f94f0ef642cd63486c77ca9724ac" + integrity sha512-sol30LUpz1jQFBjOKwbjxijiE3b6pjd74YwfD0fJOKPjF+fONKb2Yg8rYgS6+bK6VDl+/wfr4IYpC7jDzLUIfw== + +node-gyp@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.8.0.tgz#540304261c330e80d0d5edce253a68cb3964218c" + integrity sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA== + dependencies: + fstream "^1.0.0" + glob "^7.0.3" + graceful-fs "^4.1.2" + mkdirp "^0.5.0" + nopt "2 || 3" + npmlog "0 || 1 || 2 || 3 || 4" + osenv "0" + request "^2.87.0" + rimraf "2" + semver "~5.3.0" + tar "^2.0.0" + which "1" + +node-gyp@~3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.4.0.tgz#dda558393b3ecbbe24c9e6b8703c71194c63fa36" + integrity sha1-3aVYOTs+y74kyea4cDxxGUxj+jY= + dependencies: + fstream "^1.0.0" + glob "^7.0.3" + graceful-fs "^4.1.2" + minimatch "^3.0.2" + mkdirp "^0.5.0" + nopt "2 || 3" + npmlog "0 || 1 || 2 || 3" + osenv "0" + path-array "^1.0.0" + request "2" + rimraf "2" + semver "2.x || 3.x || 4 || 5" + tar "^2.0.0" + which "1" + +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= + +node-libs-browser@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.1.0.tgz#5f94263d404f6e44767d726901fff05478d600df" + integrity sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg== + dependencies: + assert "^1.1.1" + browserify-zlib "^0.2.0" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^1.0.0" + https-browserify "^1.0.0" + os-browserify "^0.3.0" + path-browserify "0.0.0" + process "^0.11.10" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.3.3" + stream-browserify "^2.0.1" + stream-http "^2.7.2" + string_decoder "^1.0.0" + timers-browserify "^2.0.4" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.10.3" + vm-browserify "0.0.4" + +node-notifier@^5.2.1: + version "5.3.0" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.3.0.tgz#c77a4a7b84038733d5fb351aafd8a268bfe19a01" + integrity sha512-AhENzCSGZnZJgBARsUjnQ7DnZbzyP+HxlVXuD0xqAnvL8q+OqtSX7lGg9e8nHzwXkMMXNdVeqq4E2M3EUAqX6Q== + dependencies: + growly "^1.3.0" + semver "^5.5.0" + shellwords "^0.1.1" + which "^1.3.0" + +node-pre-gyp@^0.10.0, node-pre-gyp@^0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" + integrity sha512-d1xFs+C/IPS8Id0qPTZ4bUT8wWryfR/OzzAFxweG+uLN85oPzyo2Iw6bVlLQ/JOdgNonXLCoRyqDzDWq4iw72A== + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.1" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4" + +node-releases@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.0.4.tgz#2d585de8c6c81d00017e063e7810a63889aa6756" + integrity sha512-GqRV9GcHw8JCRDaP/JoeNMNzEGzHAknMvIHqMb2VeTOmg1Cf9+ej8bkV12tHfzWHQMCkQ5zUFgwFUkfraynNCw== + dependencies: + semver "^5.3.0" + +node-uuid@~1.4.7: + version "1.4.8" + resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.8.tgz#b040eb0923968afabf8d32fb1f17f1167fdab907" + integrity sha1-sEDrCSOWivq/jTL7HxfxFn/auQc= + +"nopt@2 || 3", nopt@~3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= + dependencies: + abbrev "1" + +nopt@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= + dependencies: + abbrev "1" + osenv "^0.1.4" + +normalize-git-url@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/normalize-git-url/-/normalize-git-url-3.0.2.tgz#8e5f14be0bdaedb73e07200310aa416c27350fc4" + integrity sha1-jl8Uvgva7bc+ByADEKpBbCc1D8Q= + +normalize-package-data@^2.0.0, normalize-package-data@^2.3.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.3.5, normalize-package-data@^2.4.0, "normalize-package-data@~1.0.1 || ^2.0.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" + integrity sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw== + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-package-data@~2.3.5: + version "2.3.8" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.3.8.tgz#d819eda2a9dedbd1ffa563ea4071d936782295bb" + integrity sha1-2Bntoqne29H/pWPqQHHZNngilbs= + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.0.1, normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-url@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6" + integrity sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw== + dependencies: + prepend-http "^2.0.0" + query-string "^5.0.1" + sort-keys "^2.0.0" + +npm-bundled@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.5.tgz#3c1732b7ba936b3a10325aef616467c0ccbcc979" + integrity sha512-m/e6jgWu8/v5niCUKQi9qQl8QdeEduFA96xHDDzFGqly0OOjI7c+60KM/2sppfnUU9JJagf+zs+yGhqSOFj71g== + +npm-cache-filename@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/npm-cache-filename/-/npm-cache-filename-1.0.2.tgz#ded306c5b0bfc870a9e9faf823bc5f283e05ae11" + integrity sha1-3tMGxbC/yHCp6fr4I7xfKD4FrhE= + +npm-check-updates@^2.15.0: + version "2.15.0" + resolved "https://registry.yarnpkg.com/npm-check-updates/-/npm-check-updates-2.15.0.tgz#7c0f540c048fc801bfd11add8708479a6b82c32e" + integrity sha512-0ZUokfgS+4uPVSVWP3CMie7kQwngiQag2e70CdcnUfBM7/tOUmxb0DDMfxqshw4MvgqlPsxSYprzKaBGlvXqnA== + dependencies: + bluebird "^3.4.3" + chalk "^1.1.3" + cint "^8.2.1" + cli-table "^0.3.1" + commander "^2.9.0" + fast-diff "^1.0.1" + find-up "1.1.2" + get-stdin "^5.0.1" + json-parse-helpfulerror "^1.0.3" + lodash "^4.15.0" + node-alias "^1.0.4" + npm "^3.10.6" + npmi "^2.0.1" + rc-config-loader "^2.0.1" + semver "^5.3.0" + semver-utils "^1.1.1" + spawn-please "^0.3.0" + update-notifier "^2.2.0" + +npm-install-checks@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-3.0.0.tgz#d4aecdfd51a53e3723b7b2f93b2ee28e307bc0d7" + integrity sha1-1K7N/VGlPjcjt7L5Oy7ijjB7wNc= + dependencies: + semver "^2.3.0 || 3.x || 4 || 5" + +npm-lifecycle@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/npm-lifecycle/-/npm-lifecycle-2.1.0.tgz#1eda2eedb82db929e3a0c50341ab0aad140ed569" + integrity sha512-QbBfLlGBKsktwBZLj6AviHC6Q9Y3R/AY4a2PYSIRhSKSS0/CxRyD/PfxEX6tPeOCXQgMSNdwGeECacstgptc+g== + dependencies: + byline "^5.0.0" + graceful-fs "^4.1.11" + node-gyp "^3.8.0" + resolve-from "^4.0.0" + slide "^1.1.6" + uid-number "0.0.6" + umask "^1.1.0" + which "^1.3.1" + +"npm-package-arg@^3.0.0 || ^4.0.0", npm-package-arg@^4.1.1, npm-package-arg@~4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-4.2.1.tgz#593303fdea85f7c422775f17f9eb7670f680e3ec" + integrity sha1-WTMD/eqF98Qid18X+et2cPaA4+w= + dependencies: + hosted-git-info "^2.1.5" + semver "^5.1.0" + +"npm-package-arg@^4.0.0 || ^5.0.0": + version "5.1.2" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-5.1.2.tgz#fb18d17bb61e60900d6312619919bd753755ab37" + integrity sha512-wJBsrf0qpypPT7A0LART18hCdyhpCMxeTtcb0X4IZO2jsP6Om7EHN1d9KSKiqD+KVH030RVNpWS9thk+pb7wzA== + dependencies: + hosted-git-info "^2.4.2" + osenv "^0.1.4" + semver "^5.1.0" + validate-npm-package-name "^3.0.0" + +"npm-package-arg@^4.0.0 || ^5.0.0 || ^6.0.0", npm-package-arg@^6.0.0, npm-package-arg@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-6.1.0.tgz#15ae1e2758a5027efb4c250554b85a737db7fcc1" + integrity sha512-zYbhP2k9DbJhA0Z3HKUePUgdB1x7MfIfKssC+WLPFMKTBZKpZh5m13PgexJjCq6KW7j17r0jHWcCpxEqnnncSA== + dependencies: + hosted-git-info "^2.6.0" + osenv "^0.1.5" + semver "^5.5.0" + validate-npm-package-name "^3.0.0" + +npm-packlist@^1.1.12, npm-packlist@^1.1.6: + version "1.1.12" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.12.tgz#22bde2ebc12e72ca482abd67afc51eb49377243a" + integrity sha512-WJKFOVMeAlsU/pjXuqVdzU0WfgtIBCupkEVwn+1Y0ERAbUfWw8R4GjgVbaKnUjRoD2FoQbHOCbOyT5Mbs9Lw4g== + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + +npm-path@^2.0.2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/npm-path/-/npm-path-2.0.4.tgz#c641347a5ff9d6a09e4d9bce5580c4f505278e64" + integrity sha512-IFsj0R9C7ZdR5cP+ET342q77uSRdtWOlWpih5eC+lu29tIDbNEgDbzgVJ5UFvYHWhxDZ5TFkJafFioO0pPQjCw== + dependencies: + which "^1.2.10" + +npm-pick-manifest@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-2.2.3.tgz#32111d2a9562638bb2c8f2bf27f7f3092c8fae40" + integrity sha512-+IluBC5K201+gRU85vFlUwX3PFShZAbAgDNp2ewJdWMVSppdo/Zih0ul2Ecky/X7b51J7LrrUAP+XOmOCvYZqA== + dependencies: + figgy-pudding "^3.5.1" + npm-package-arg "^6.0.0" + semver "^5.4.1" + +npm-registry-client@~7.2.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/npm-registry-client/-/npm-registry-client-7.2.1.tgz#c792266b088cc313f8525e7e35248626c723db75" + integrity sha1-x5ImawiMwxP4Ul5+NSSGJscj23U= + dependencies: + concat-stream "^1.5.2" + graceful-fs "^4.1.6" + normalize-package-data "~1.0.1 || ^2.0.0" + npm-package-arg "^3.0.0 || ^4.0.0" + once "^1.3.3" + request "^2.74.0" + retry "^0.10.0" + semver "2 >=2.2.1 || 3.x || 4 || 5" + slide "^1.1.3" + optionalDependencies: + npmlog "~2.0.0 || ~3.1.0" + +npm-registry-fetch@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-3.8.0.tgz#aa7d9a7c92aff94f48dba0984bdef4bd131c88cc" + integrity sha512-hrw8UMD+Nob3Kl3h8Z/YjmKamb1gf7D1ZZch2otrIXM3uFLB5vjEY6DhMlq80z/zZet6eETLbOXcuQudCB3Zpw== + dependencies: + JSONStream "^1.3.4" + bluebird "^3.5.1" + figgy-pudding "^3.4.1" + lru-cache "^4.1.3" + make-fetch-happen "^4.0.1" + npm-package-arg "^6.1.0" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + dependencies: + path-key "^2.0.0" + +npm-user-validate@~0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/npm-user-validate/-/npm-user-validate-0.1.5.tgz#52465d50c2d20294a57125b996baedbf56c5004b" + integrity sha1-UkZdUMLSApSlcSW5lrrtv1bFAEs= + +npm-which@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/npm-which/-/npm-which-3.0.1.tgz#9225f26ec3a285c209cae67c3b11a6b4ab7140aa" + integrity sha1-kiXybsOihcIJyuZ8OxGmtKtxQKo= + dependencies: + commander "^2.9.0" + npm-path "^2.0.2" + which "^1.2.10" + +npm@^3, npm@^3.10.6: + version "3.10.10" + resolved "https://registry.yarnpkg.com/npm/-/npm-3.10.10.tgz#5b1d577e4c8869d6c8603bc89e9cd1637303e46e" + integrity sha1-Wx1XfkyIadbIYDvInpzRY3MD5G4= + dependencies: + abbrev "~1.0.9" + ansicolors "~0.3.2" + ansistyles "~0.1.3" + aproba "~1.0.4" + archy "~1.0.0" + asap "~2.0.5" + chownr "~1.0.1" + cmd-shim "~2.0.2" + columnify "~1.5.4" + config-chain "~1.1.11" + dezalgo "~1.0.3" + editor "~1.0.0" + fs-vacuum "~1.2.9" + fs-write-stream-atomic "~1.0.8" + fstream "~1.0.10" + fstream-npm "~1.2.0" + glob "~7.1.0" + graceful-fs "~4.1.9" + has-unicode "~2.0.1" + hosted-git-info "~2.1.5" + iferr "~0.1.5" + inflight "~1.0.5" + inherits "~2.0.3" + ini "~1.3.4" + init-package-json "~1.9.4" + lockfile "~1.0.2" + lodash._baseuniq "~4.6.0" + lodash.clonedeep "~4.5.0" + lodash.union "~4.6.0" + lodash.uniq "~4.5.0" + lodash.without "~4.4.0" + mkdirp "~0.5.1" + node-gyp "~3.4.0" + nopt "~3.0.6" + normalize-git-url "~3.0.2" + normalize-package-data "~2.3.5" + npm-cache-filename "~1.0.2" + npm-install-checks "~3.0.0" + npm-package-arg "~4.2.0" + npm-registry-client "~7.2.1" + npm-user-validate "~0.1.5" + npmlog "~4.0.0" + once "~1.4.0" + opener "~1.4.2" + osenv "~0.1.3" + path-is-inside "~1.0.2" + read "~1.0.7" + read-cmd-shim "~1.0.1" + read-installed "~4.0.3" + read-package-json "~2.0.4" + read-package-tree "~5.1.5" + readable-stream "~2.1.5" + realize-package-specifier "~3.0.3" + request "~2.75.0" + retry "~0.10.0" + rimraf "~2.5.4" + semver "~5.3.0" + sha "~2.0.1" + slide "~1.1.6" + sorted-object "~2.0.1" + strip-ansi "~3.0.1" + tar "~2.2.1" + text-table "~0.2.0" + uid-number "0.0.6" + umask "~1.1.0" + unique-filename "~1.1.0" + unpipe "~1.0.0" + validate-npm-package-name "~2.2.2" + which "~1.2.11" + wrappy "~1.0.2" + write-file-atomic "~1.2.0" + +npmi@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/npmi/-/npmi-2.0.1.tgz#32607657e1bd47ca857ab4e9d98f0a0cff96bcea" + integrity sha1-MmB2V+G9R8qFerTp2Y8KDP+WvOo= + dependencies: + npm "^3" + semver "^4.1.0" + +"npmlog@0 || 1 || 2 || 3", "npmlog@~2.0.0 || ~3.1.0": + version "3.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-3.1.2.tgz#2d46fa874337af9498a2f12bb43d8d0be4a36873" + integrity sha1-LUb6h0M3r5SYovErtD2NC+SjaHM= + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.6.0" + set-blocking "~2.0.0" + +"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.2, npmlog@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +npmlog@~4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.0.2.tgz#d03950e0e78ce1527ba26d2a7592e9348ac3e75f" + integrity sha1-0DlQ4OeM4VJ7om0qdZLpNIrD518= + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.1" + set-blocking "~2.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +nwsapi@^2.0.7: + version "2.0.9" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.0.9.tgz#77ac0cdfdcad52b6a1151a84e73254edc33ed016" + integrity sha512-nlWFSCTYQcHk/6A9FFnfhKc14c3aFhfdNBXgo8Qgi9QTBu/qg3Ww+Uiz9wMzXd1T8GFxPc2QIHB6Qtf2XFryFQ== + +oauth-sign@~0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" + integrity sha1-Rqarfwrq2N6unsBWV4C31O/rnUM= + +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-assign@^4.0.1, object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-hash@^1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-1.3.1.tgz#fde452098a951cb145f039bb7d455449ddc126df" + integrity sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA== + +object-keys@^1.0.11, object-keys@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2" + integrity sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag== + +object-path@^0.11.4: + version "0.11.4" + resolved "https://registry.yarnpkg.com/object-path/-/object-path-0.11.4.tgz#370ae752fbf37de3ea70a861c23bba8915691949" + integrity sha1-NwrnUvvzfePqcKhhwju6iRVpGUk= + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + +object.assign@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + +object.entries@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.0.4.tgz#1bf9a4dd2288f5b33f3a993d257661f05d161a5f" + integrity sha1-G/mk3SKI9bM/Opk9JXZh8F0WGl8= + dependencies: + define-properties "^1.1.2" + es-abstract "^1.6.1" + function-bind "^1.1.0" + has "^1.0.1" + +object.getownpropertydescriptors@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" + integrity sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY= + dependencies: + define-properties "^1.1.2" + es-abstract "^1.5.1" + +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + integrity sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo= + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +once@^1.3.0, once@^1.3.1, once@^1.3.3, once@^1.4.0, once@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +one-time@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/one-time/-/one-time-0.0.4.tgz#f8cdf77884826fe4dff93e3a9cc37b1e4480742e" + integrity sha1-+M33eISCb+Tf+T46nMN7HkSAdC4= + +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= + dependencies: + mimic-fn "^1.0.0" + +opener@~1.4.2: + version "1.4.3" + resolved "https://registry.yarnpkg.com/opener/-/opener-1.4.3.tgz#5c6da2c5d7e5831e8ffa3964950f8d6674ac90b8" + integrity sha1-XG2ixdflgx6P+jlklQ+NZnSskLg= + +opn@^5.2.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/opn/-/opn-5.4.0.tgz#cb545e7aab78562beb11aa3bfabc7042e1761035" + integrity sha512-YF9MNdVy/0qvJvDtunAOzFw9iasOQHpVthTCvGzxt61Il64AYSGdK+rYwld7NAfk9qJ7dt+hymBNSc9LNYS+Sw== + dependencies: + is-wsl "^1.1.0" + +oppsy@2.x.x: + version "2.0.0" + resolved "https://registry.yarnpkg.com/oppsy/-/oppsy-2.0.0.tgz#3a194517adc24c3c61cdc56f35f4537e93a35e34" + integrity sha1-OhlFF63CTDxhzcVvNfRTfpOjXjQ= + dependencies: + hoek "5.x.x" + +optimist@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + +optionator@^0.8.1, optionator@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q= + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + +os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + +os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk= + dependencies: + lcid "^1.0.0" + +os-locale@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" + integrity sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA== + dependencies: + execa "^0.7.0" + lcid "^1.0.0" + mem "^1.1.0" + +os-locale@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.0.1.tgz#3b014fbf01d87f60a1e5348d80fe870dc82c4620" + integrity sha512-7g5e7dmXPtzcP4bgsZ8ixDVqA7oWYuEz4lOSujeWyliPai4gfVDiFIcwBg3aGCPnmSGfzOKTK3ccPn0CKv3DBw== + dependencies: + execa "^0.10.0" + lcid "^2.0.0" + mem "^4.0.0" + +os-name@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/os-name/-/os-name-2.0.1.tgz#b9a386361c17ae3a21736ef0599405c9a8c5dc5e" + integrity sha1-uaOGNhwXrjohc27wWZQFyajF3F4= + dependencies: + macos-release "^1.0.0" + win-release "^1.0.0" + +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +osenv@0, osenv@^0.1.4, osenv@^0.1.5, osenv@~0.1.3: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +otplib@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/otplib/-/otplib-10.0.1.tgz#d37fcd13203298c0b94937d55c5a3527ed877875" + integrity sha512-FtbKelYtio2af5LDBWz3bWS6T03taHJAIv3evMrXuvoM50z5jbWoEMabPCk0A0JqiLGBzAIDJWfR9gSsvRYZHA== + dependencies: + thirty-two "1.0.2" + +ow@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/ow/-/ow-0.8.0.tgz#d360d779c996f4132941a596c87f86ce8e812e62" + integrity sha512-hYgYZNcRfIZ2JppSTqh6mxdU1zkUXsGlwy4eBsRG91R6CiZk7cB+AfHl+SVKBdynQvAnNHNfu0ZrtJN1jj7Mow== + +p-any@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-any/-/p-any-1.1.0.tgz#1d03835c7eed1e34b8e539c47b7b60d0d015d4e1" + integrity sha512-Ef0tVa4CZ5pTAmKn+Cg3w8ABBXh+hHO1aV8281dKOoUHfX+3tjG2EaFcC+aZyagg9b4EYGsHEjz21DnEE8Og2g== + dependencies: + p-some "^2.0.0" + +p-cancelable@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.4.1.tgz#35f363d67d52081c8d9585e37bcceb7e0bbcb2a0" + integrity sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ== + +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-is-promise@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" + integrity sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4= + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-limit@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.0.0.tgz#e624ed54ee8c460a778b3c9f3670496ff8a57aec" + integrity sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A== + dependencies: + p-try "^2.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-map-series@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-map-series/-/p-map-series-1.0.0.tgz#bf98fe575705658a9e1351befb85ae4c1f07bdca" + integrity sha1-v5j+V1cFZYqeE1G++4WuTB8Hvco= + dependencies: + p-reduce "^1.0.0" + +p-map@^1.1.1, p-map@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" + integrity sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA== + +p-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.0.0.tgz#be18c5a5adeb8e156460651421aceca56c213a50" + integrity sha512-GO107XdrSUmtHxVoi60qc9tUl/KkNKm+X2CF4P9amalpGxv5YqVPJNfSb0wcA+syCopkZvYYIzW8OVTQW59x/w== + +p-pipe@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/p-pipe/-/p-pipe-1.2.0.tgz#4b1a11399a11520a67790ee5a0c1d5881d6befe9" + integrity sha1-SxoROZoRUgpneQ7loMHViB1r7+k= + +p-reduce@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" + integrity sha1-GMKw3ZNqRpClKfgjH1ig/bakffo= + +p-some@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/p-some/-/p-some-2.0.1.tgz#65d87c8b154edbcf5221d167778b6d2e150f6f06" + integrity sha1-Zdh8ixVO289SIdFnd4ttLhUPbwY= + dependencies: + aggregate-error "^1.0.0" + +p-timeout@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038" + integrity sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA== + dependencies: + p-finally "^1.0.0" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + +p-try@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" + integrity sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ== + +p-waterfall@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-waterfall/-/p-waterfall-1.0.0.tgz#7ed94b3ceb3332782353af6aae11aa9fc235bb00" + integrity sha1-ftlLPOszMngjU69qrhGqn8I1uwA= + dependencies: + p-reduce "^1.0.0" + +pac-proxy-agent@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/pac-proxy-agent/-/pac-proxy-agent-2.0.2.tgz#90d9f6730ab0f4d2607dcdcd4d3d641aa26c3896" + integrity sha512-cDNAN1Ehjbf5EHkNY5qnRhGPUCp6SnpyVof5fRzN800QV1Y2OkzbH9rmjZkbBRa8igof903yOnjIl6z0SlAhxA== + dependencies: + agent-base "^4.2.0" + debug "^3.1.0" + get-uri "^2.0.0" + http-proxy-agent "^2.1.0" + https-proxy-agent "^2.2.1" + pac-resolver "^3.0.0" + raw-body "^2.2.0" + socks-proxy-agent "^3.0.0" + +pac-resolver@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pac-resolver/-/pac-resolver-3.0.0.tgz#6aea30787db0a891704deb7800a722a7615a6f26" + integrity sha512-tcc38bsjuE3XZ5+4vP96OfhOugrX+JcnpUbhfuc4LuXBLQhoTthOstZeoQJBDnQUDYzYmdImKsbz0xSl1/9qeA== + dependencies: + co "^4.6.0" + degenerator "^1.0.4" + ip "^1.1.5" + netmask "^1.0.6" + thunkify "^2.1.2" + +package-json@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-4.0.1.tgz#8869a0401253661c4c4ca3da6c2121ed555f5eed" + integrity sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0= + dependencies: + got "^6.7.1" + registry-auth-token "^3.0.1" + registry-url "^3.0.3" + semver "^5.1.0" + +packet-reader@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/packet-reader/-/packet-reader-0.3.1.tgz#cd62e60af8d7fea8a705ec4ff990871c46871f27" + integrity sha1-zWLmCvjX/qinBexP+ZCHHEaHHyc= + +pacote@^9.1.0: + version "9.2.3" + resolved "https://registry.yarnpkg.com/pacote/-/pacote-9.2.3.tgz#48cfe87beb9177acd6594355a584a538835424b3" + integrity sha512-Y3+yY3nBRAxMlZWvr62XLJxOwCmG9UmkGZkFurWHoCjqF0cZL72cTOCRJTvWw8T4OhJS2RTg13x4oYYriauvEw== + dependencies: + bluebird "^3.5.2" + cacache "^11.2.0" + figgy-pudding "^3.5.1" + get-stream "^4.1.0" + glob "^7.1.3" + lru-cache "^4.1.3" + make-fetch-happen "^4.0.1" + minimatch "^3.0.4" + minipass "^2.3.5" + mississippi "^3.0.0" + mkdirp "^0.5.1" + normalize-package-data "^2.4.0" + npm-package-arg "^6.1.0" + npm-packlist "^1.1.12" + npm-pick-manifest "^2.2.3" + npm-registry-fetch "^3.8.0" + osenv "^0.1.5" + promise-inflight "^1.0.1" + promise-retry "^1.1.1" + protoduck "^5.0.1" + rimraf "^2.6.2" + safe-buffer "^5.1.2" + semver "^5.6.0" + ssri "^6.0.1" + tar "^4.4.6" + unique-filename "^1.1.1" + which "^1.3.1" + +pako@~1.0.2, pako@~1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" + integrity sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg== + +parallel-transform@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06" + integrity sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY= + dependencies: + cyclist "~0.2.2" + inherits "^2.0.3" + readable-stream "^2.1.5" + +parse-asn1@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.1.tgz#f6bf293818332bd0dab54efb16087724745e6ca8" + integrity sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw== + dependencies: + asn1.js "^4.0.0" + browserify-aes "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + +parse-github-repo-url@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz#9e7d8bb252a6cb6ba42595060b7bf6df3dbc1f50" + integrity sha1-nn2LslKmy2ukJZUGC3v23z28H1A= + +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + integrity sha1-ssN2z7EfNVE7rdFz7wu246OIORw= + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= + dependencies: + error-ex "^1.2.0" + +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +parse-ms@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-2.0.0.tgz#7b3640295100caf3fa0100ccceb56635b62f9d62" + integrity sha512-AddiXFSLLCqj+tCRJ9MrUtHZB4DWojO3tk0NVZ+g5MaMQHF2+p2ktqxuoXyPFLljz/aUK0Nfhd/uGWnhXVXEyA== + +parse5@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" + integrity sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA== + +parseurl@~1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" + integrity sha1-/CidTtiZMRlGDBViUyYs3I3mW/M= + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +path-array@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-array/-/path-array-1.0.1.tgz#7e2f0f35f07a2015122b868b7eac0eb2c4fec271" + integrity sha1-fi8PNfB6IBUSK4aLfqwOssT+wnE= + dependencies: + array-index "^1.0.0" + +path-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" + integrity sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo= + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-is-inside@^1.0.1, path-is-inside@^1.0.2, path-is-inside@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= + +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-parse@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +path-type@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" + integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= + dependencies: + pify "^2.0.0" + +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== + dependencies: + pify "^3.0.0" + +path@0.12.7: + version "0.12.7" + resolved "https://registry.yarnpkg.com/path/-/path-0.12.7.tgz#d4dc2a506c4ce2197eb481ebfcd5b36c0140b10f" + integrity sha1-1NwqUGxM4hl+tIHr/NWzbAFAsQ8= + dependencies: + process "^0.11.1" + util "^0.10.3" + +pbkdf2@^3.0.3, pbkdf2@^3.0.9: + version "3.0.17" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" + integrity sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + +pez@4.x.x: + version "4.0.5" + resolved "https://registry.yarnpkg.com/pez/-/pez-4.0.5.tgz#a975c49deff330d298d82851b39f81c2710556df" + integrity sha512-HvL8uiFIlkXbx/qw4B8jKDCWzo7Pnnd65Uvanf9OOCtb20MRcb9gtTVBf9NCnhETif1/nzbDHIjAWC/sUp7LIQ== + dependencies: + b64 "4.x.x" + boom "7.x.x" + content "4.x.x" + hoek "6.x.x" + nigel "3.x.x" + +pg-connection-string@0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-0.1.3.tgz#da1847b20940e42ee1492beaf65d49d91b245df7" + integrity sha1-2hhHsglA5C7hSSvq9l1J2RskXfc= + +pg-cursor@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/pg-cursor/-/pg-cursor-1.3.0.tgz#b220f1908976b7b40daa373c7ada5fca823ab0d9" + integrity sha1-siDxkIl2t7QNqjc8etpfyoI6sNk= + +pg-minify@0.5.5: + version "0.5.5" + resolved "https://registry.yarnpkg.com/pg-minify/-/pg-minify-0.5.5.tgz#6c961a61aa19f469d8edfe5a3c0da58760f3c339" + integrity sha512-7Pf9h6nV1RFqED1hkRosePqvpPwNUUtW06TT4+lHwzesxa5gffxkShTjYH6JXV5sSSfh5+2yHOTTWEkCyCQ0Eg== + +pg-pool@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-2.0.4.tgz#05ad0f2d9437d89c94ccc4f4d0a44ac65ade865b" + integrity sha512-Mi2AsmlFkVMpI28NreaDkz5DkfxLOG16C/HNwi091LDlOiDiQACtAroLxSd1vIS2imBqxdjjO9cQZg2CwsOPbw== + +pg-promise@^8.5.2: + version "8.5.2" + resolved "https://registry.yarnpkg.com/pg-promise/-/pg-promise-8.5.2.tgz#ea78fb7989ce05427cd064079e5539384b8e3654" + integrity sha512-7vMkZcKR9byVb9p4T/Hwsy3BliOAD7ieFcizd1eMeXhWxoU8DgF+MtQIpNLTD44dF6ojR1NYMgTnYDh1qSPgsQ== + dependencies: + manakin "0.5.2" + pg "7.6.1" + pg-minify "0.5.5" + spex "2.1.0" + +pg-query-stream@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/pg-query-stream/-/pg-query-stream-1.1.2.tgz#d089ff633b9ece40712f4f76da25ac253d88ec96" + integrity sha512-84hsUVjbrvXYIpVH+6FrKajfOnmTo7Wc/CXPtSyv41JmUnLcQ2lcVrkR7+m4VPtL28FdcZA7Q7ab4X0za4BhrQ== + dependencies: + pg-cursor "1.3.0" + +pg-types@~1.12.1: + version "1.12.1" + resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-1.12.1.tgz#d64087e3903b58ffaad279e7595c52208a14c3d2" + integrity sha1-1kCH45A7WP+q0nnnWVxSIIoUw9I= + dependencies: + postgres-array "~1.0.0" + postgres-bytea "~1.0.0" + postgres-date "~1.0.0" + postgres-interval "^1.1.0" + +pg@7.6.1: + version "7.6.1" + resolved "https://registry.yarnpkg.com/pg/-/pg-7.6.1.tgz#42c68aed37bf38b813616e3d21f4338f350c1b79" + integrity sha512-rAItIkYrRaNGinZN/Hs8F9R5mQjQSPlnzxPF+eCimSl92qnuNGR42gkpOQKP1bnvTwkSjRTBL+VNC5EcFhtCuQ== + dependencies: + buffer-writer "2.0.0" + packet-reader "0.3.1" + pg-connection-string "0.1.3" + pg-pool "~2.0.3" + pg-types "~1.12.1" + pgpass "1.x" + semver "4.3.2" + +pgpass@1.x: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.2.tgz#2a7bb41b6065b67907e91da1b07c1847c877b306" + integrity sha1-Knu0G2BltnkH6R2hsHwYR8h3swY= + dependencies: + split "^1.0.0" + +pify@3.0.0, pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + +pify@^2.0.0, pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + +pino-pretty@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pino-pretty/-/pino-pretty-2.3.0.tgz#b412d216f6261e354d69f5b1b12f22447fc45f05" + integrity sha512-Fj5L0hxYvBF0QfszXpaIdUHfedKGUmDP7hhQBdXjLlQLqphrRDUXRwEVYdonXaQpd5JZb22gjTHVMR8roIDBVA== + dependencies: + args "^5.0.0" + chalk "^2.3.2" + dateformat "^3.0.3" + fast-json-parse "^1.0.3" + jmespath "^0.15.0" + pump "^3.0.0" + readable-stream "^3.0.6" + split2 "^3.0.0" + +pino-std-serializers@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pino-std-serializers/-/pino-std-serializers-2.3.0.tgz#34eeaab97c055c28e22c0542ae55978e7e427786" + integrity sha512-klfGoOsP6sJH7ON796G4xoUSx2fkpFgKHO4YVVO2zmz31jR+etzc/QzGJILaOIiCD6HTCFgkPx+XN8nk+ruqPw== + +pino@^5.9.0: + version "5.9.0" + resolved "https://registry.yarnpkg.com/pino/-/pino-5.9.0.tgz#4a436289ea90cefd0fad1e3ca5726b6d58922c71" + integrity sha512-6sHy38gWsZbrmYq6vk343VCThy93ZdVfmLsHDVzbl/j621SjSaxCcS/ySmxK/hRmq8jpQb3n44dNRIeqbbQw6A== + dependencies: + fast-json-parse "^1.0.3" + fast-redact "^1.4.0" + fast-safe-stringify "^2.0.6" + flatstr "^1.0.5" + pino-std-serializers "^2.3.0" + pump "^3.0.0" + quick-format-unescaped "^3.0.0" + sonic-boom "^0.6.3" + +pkg-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" + integrity sha1-ektQio1bstYp1EcFb/TpyTFM89Q= + dependencies: + find-up "^1.0.0" + +pkg-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" + integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= + dependencies: + find-up "^2.1.0" + +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== + dependencies: + find-up "^3.0.0" + +please-upgrade-node@^3.0.2, please-upgrade-node@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.1.1.tgz#ed320051dfcc5024fae696712c8288993595e8ac" + integrity sha512-KY1uHnQ2NlQHqIJQpnh/i54rKkuxCEBx+voJIS/Mvb+L2iYd2NMotwduhKTMjfC1uKoX3VXOxLjIYG66dfJTVQ== + dependencies: + semver-compare "^1.0.0" + +pluralize@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" + integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow== + +pn@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" + integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== + +podium@3.x.x: + version "3.2.0" + resolved "https://registry.yarnpkg.com/podium/-/podium-3.2.0.tgz#2a7c579ddd5408f412d014c9ffac080c41d83477" + integrity sha512-rbwvxwVkI6gRRlxZQ1zUeafrpGxZ7QPHIheinehAvGATvGIPfWRkaTeWedc5P4YjXJXEV8ZbBxPtglNylF9hjw== + dependencies: + hoek "6.x.x" + joi "14.x.x" + +port-numbers@^2.0.20: + version "2.0.28" + resolved "https://registry.yarnpkg.com/port-numbers/-/port-numbers-2.0.28.tgz#63ebb75239922edbc0741a5d55750037d0a2d8a2" + integrity sha512-SfV6duh86RGuQz6DhE8QHVpWKLkkfBK2G+Woi0xDPGMMUquL8e6f+qWM/nuT3N/OZstawEDdm94Jdo65E23c9Q== + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + +postgres-array@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-1.0.3.tgz#c561fc3b266b21451fc6555384f4986d78ec80f5" + integrity sha512-5wClXrAP0+78mcsNX3/ithQ5exKvCyK5lr5NEEEeGwwM6NJdQgzIJBVxLvRW+huFpX92F2QnZ5CcokH0VhK2qQ== + +postgres-bytea@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35" + integrity sha1-AntTPAqokOJtFy1Hz5zOzFIazTU= + +postgres-date@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.3.tgz#e2d89702efdb258ff9d9cee0fe91bd06975257a8" + integrity sha1-4tiXAu/bJY/52c7g/pG9BpdSV6g= + +postgres-interval@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.1.2.tgz#bf71ff902635f21cb241a013fc421d81d1db15a9" + integrity sha512-fC3xNHeTskCxL1dC8KOtxXt7YeFmlbTYtn7ul8MkVERuTmf7pI4DrkAxcw3kh1fQ9uz4wQmd03a1mRiXUZChfQ== + dependencies: + xtend "^4.0.0" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= + +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= + +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= + +prettier@^1.15.2: + version "1.15.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.15.2.tgz#d31abe22afa4351efa14c7f8b94b58bb7452205e" + integrity sha512-YgPLFFA0CdKL4Eg2IHtUSjzj/BWgszDHiNQAe0VAIBse34148whfdzLagRL+QiKS+YfK5ftB6X4v/MBw8yCoug== + +pretty-format@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-22.4.3.tgz#f873d780839a9c02e9664c8a082e9ee79eaac16f" + integrity sha512-S4oT9/sT6MN7/3COoOy+ZJeA92VmOnveLHgrwBE3Z1W5N9S2A1QGNYiE1z75DAENbJrXXUb+OWXhpJcg05QKQQ== + dependencies: + ansi-regex "^3.0.0" + ansi-styles "^3.2.0" + +pretty-format@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-23.6.0.tgz#5eaac8eeb6b33b987b7fe6097ea6a8a146ab5760" + integrity sha512-zf9NV1NSlDLDjycnwm6hpFATCGl/K1lt0R/GdkAK2O5LN/rwJoB+Mh93gGJjut4YbmecbfgLWVGSTCr0Ewvvbw== + dependencies: + ansi-regex "^3.0.0" + ansi-styles "^3.2.0" + +pretty-ms@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-4.0.0.tgz#31baf41b94fd02227098aaa03bd62608eb0d6e92" + integrity sha512-qG66ahoLCwpLXD09ZPHSCbUWYTqdosB7SMP4OffgTgL2PBKXMuUsrk5Bwg8q4qPkjTXsKBMr+YK3Ltd/6F9s/Q== + dependencies: + parse-ms "^2.0.0" + +private@^0.1.6, private@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== + +process-nextick-args@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + integrity sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M= + +process-nextick-args@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" + integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== + +process@^0.11.1, process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= + +progress@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.1.tgz#c9242169342b1c29d275889c95734621b1952e31" + integrity sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg== + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= + +promise-retry@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-1.1.1.tgz#6739e968e3051da20ce6497fb2b50f6911df3d6d" + integrity sha1-ZznpaOMFHaIM5kl/srUPaRHfPW0= + dependencies: + err-code "^1.0.0" + retry "^0.10.0" + +promise@7.x, "promise@>=3.2 <8": + version "7.3.1" + resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" + integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg== + dependencies: + asap "~2.0.3" + +prompts@^0.1.9: + version "0.1.14" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-0.1.14.tgz#a8e15c612c5c9ec8f8111847df3337c9cbd443b2" + integrity sha512-rxkyiE9YH6zAz/rZpywySLKkpaj0NMVyNw1qhsubdbjjSgcayjTShDreZGlFMcGSu5sab3bAKPfFk78PB90+8w== + dependencies: + kleur "^2.0.1" + sisteransi "^0.1.1" + +promzard@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/promzard/-/promzard-0.3.0.tgz#26a5d6ee8c7dee4cb12208305acfb93ba382a9ee" + integrity sha1-JqXW7ox97kyxIggwWs+5O6OCqe4= + dependencies: + read "1" + +proto-list@~1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" + integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= + +protobufjs@^6.8.6: + version "6.8.8" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.8.8.tgz#c8b4f1282fd7a90e6f5b109ed11c84af82908e7c" + integrity sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/long" "^4.0.0" + "@types/node" "^10.1.0" + long "^4.0.0" + +protoduck@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/protoduck/-/protoduck-5.0.1.tgz#03c3659ca18007b69a50fd82a7ebcc516261151f" + integrity sha512-WxoCeDCoCBY55BMvj4cAEjdVUFGRWed9ZxPlqTKYyw1nDDTQ4pqmnIMAGfJlg7Dx35uB/M+PHJPTmGOvaCaPTg== + dependencies: + genfun "^5.0.0" + +proxy-addr@~2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.4.tgz#ecfc733bf22ff8c6f407fa275327b9ab67e48b93" + integrity sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA== + dependencies: + forwarded "~0.1.2" + ipaddr.js "1.8.0" + +proxy-agent@^2.0.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-2.3.1.tgz#3d49d863d46cf5f37ca8394848346ea02373eac6" + integrity sha512-CNKuhC1jVtm8KJYFTS2ZRO71VCBx3QSA92So/e6NrY6GoJonkx3Irnk4047EsCcswczwqAekRj3s8qLRGahSKg== + dependencies: + agent-base "^4.2.0" + debug "^3.1.0" + http-proxy-agent "^2.1.0" + https-proxy-agent "^2.2.1" + lru-cache "^4.1.2" + pac-proxy-agent "^2.0.1" + proxy-from-env "^1.0.0" + socks-proxy-agent "^3.0.0" + +proxy-from-env@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee" + integrity sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4= + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha1-0/wRS6BplaRexok/SEzrHXj19HY= + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= + +psl@^1.1.24: + version "1.1.29" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67" + integrity sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ== + +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@1.3.x: + version "1.3.6" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.3.6.tgz#00d40e5ded0a3bf1e0788b1c0cf426a42882ab64" + integrity sha512-BurGAcvezsINL5US9T9wGHHcLNrG6MCp//ECtxron3vcR+Rfx5Anqq7HbZXNJvFQli8FGVsWCAvywEJFV5Hx/Q== + dependencies: + duplexify "^3.5.3" + inherits "^2.0.3" + pump "^2.0.0" + +pumpify@^1.3.3: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + +punycode@2.x.x, punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +punycode@^1.2.4, punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +pure-uuid@1.5.3: + version "1.5.3" + resolved "https://registry.yarnpkg.com/pure-uuid/-/pure-uuid-1.5.3.tgz#cafee7e95b5ff96d7fb737346214967e009d5bce" + integrity sha512-Wqgq/EtTicstn7g9siPbZ4O1s2Zh9EY9Ccn/doRiDDfMRy6l9AuvJILOq4PeT84FTDOpzrmP3rEd/XVRpRa9Zw== + +q@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" + integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= + +qs@6.5.2, qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + +qs@~6.2.0: + version "6.2.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.2.3.tgz#1cfcb25c10a9b2b483053ff39f5dfc9233908cfe" + integrity sha1-HPyyXBCpsrSDBT/zn138kjOQjP4= + +query-string@^5.0.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" + integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== + dependencies: + decode-uri-component "^0.2.0" + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + +querystring-es3@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM= + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + +querystringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.0.tgz#7ded8dfbf7879dcc60d0a644ac6754b283ad17ef" + integrity sha512-sluvZZ1YiTLD5jsqZcDmFyV2EwToyXZBfpoVOmktMmW+VEnhgakFHnasVph65fOjGPTWN0Nw3+XQaSeMayr0kg== + +quick-format-unescaped@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-3.0.1.tgz#e1e8526f6aa56dc5452926111461e85755f79acf" + integrity sha512-Tnk4iJQ8x3V8ml3x9sLIf4tSDaVB9OJY/5gOrnxgK63CXKphhn8oYOPI4tqnXPQcZ3tCv7GFjeoYY5h6UAvuzg== + +quick-lru@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" + integrity sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g= + +random-seed@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/random-seed/-/random-seed-0.3.0.tgz#d945f2e1f38f49e8d58913431b8bf6bb937556cd" + integrity sha1-2UXy4fOPSejViRNDG4v2u5N1Vs0= + dependencies: + json-stringify-safe "^5.0.1" + +randomatic@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.1.1.tgz#b776efc59375984e36c537b2f51a1f0aff0da1ed" + integrity sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw== + dependencies: + is-number "^4.0.0" + kind-of "^6.0.0" + math-random "^1.0.1" + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80" + integrity sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A== + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +randomstring@~1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/randomstring/-/randomstring-1.1.5.tgz#6df0628f75cbd5932930d9fe3ab4e956a18518c3" + integrity sha1-bfBij3XL1ZMpMNn+OrTpVqGFGMM= + dependencies: + array-uniq "1.0.2" + +range-parser@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" + integrity sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4= + +raw-body@2.3.3, raw-body@^2.2.0: + version "2.3.3" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.3.3.tgz#1b324ece6b5706e153855bc1148c65bb7f6ea0c3" + integrity sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw== + dependencies: + bytes "3.0.0" + http-errors "1.6.3" + iconv-lite "0.4.23" + unpipe "1.0.0" + +rc-config-loader@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/rc-config-loader/-/rc-config-loader-2.0.2.tgz#46eb2f98fb5b2aa7b1119d66c0554de5133f1bc1" + integrity sha512-Nx9SNM47eNRqe0TdntOY600qWb8NDh+xU9sv5WnTscEtzfTB0ukihlqwuCLPteyJksvZ0sEVPoySNE01TKrmTQ== + dependencies: + debug "^3.1.0" + js-yaml "^3.12.0" + json5 "^1.0.1" + object-assign "^4.1.0" + object-keys "^1.0.12" + path-exists "^3.0.0" + require-from-string "^2.0.2" + +rc@^1.0.1, rc@^1.1.6, rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +read-cmd-shim@^1.0.1, read-cmd-shim@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.1.tgz#2d5d157786a37c055d22077c32c53f8329e91c7b" + integrity sha1-LV0Vd4ajfAVdIgd8MsU/gynpHHs= + dependencies: + graceful-fs "^4.1.2" + +read-installed@~4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/read-installed/-/read-installed-4.0.3.tgz#ff9b8b67f187d1e4c29b9feb31f6b223acd19067" + integrity sha1-/5uLZ/GH0eTCm5/rMfayI6zRkGc= + dependencies: + debuglog "^1.0.1" + read-package-json "^2.0.0" + readdir-scoped-modules "^1.0.0" + semver "2 || 3 || 4 || 5" + slide "~1.1.3" + util-extend "^1.0.1" + optionalDependencies: + graceful-fs "^4.1.2" + +"read-package-json@1 || 2", read-package-json@^2.0.0, read-package-json@~2.0.4: + version "2.0.13" + resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-2.0.13.tgz#2e82ebd9f613baa6d2ebe3aa72cefe3f68e41f4a" + integrity sha512-/1dZ7TRZvGrYqE0UAfN6qQb5GYBsNcqS1C0tNK601CFOJmtHI7NIGXwetEPU/OtoFHZL3hDxm4rolFFVE9Bnmg== + dependencies: + glob "^7.1.1" + json-parse-better-errors "^1.0.1" + normalize-package-data "^2.0.0" + slash "^1.0.0" + optionalDependencies: + graceful-fs "^4.1.2" + +read-package-tree@^5.1.6: + version "5.2.1" + resolved "https://registry.yarnpkg.com/read-package-tree/-/read-package-tree-5.2.1.tgz#6218b187d6fac82289ce4387bbbaf8eef536ad63" + integrity sha512-2CNoRoh95LxY47LvqrehIAfUVda2JbuFE/HaGYs42bNrGG+ojbw1h3zOcPcQ+1GQ3+rkzNndZn85u1XyZ3UsIA== + dependencies: + debuglog "^1.0.1" + dezalgo "^1.0.0" + once "^1.3.0" + read-package-json "^2.0.0" + readdir-scoped-modules "^1.0.0" + +read-package-tree@~5.1.5: + version "5.1.6" + resolved "https://registry.yarnpkg.com/read-package-tree/-/read-package-tree-5.1.6.tgz#4f03e83d0486856fb60d97c94882841c2a7b1b7a" + integrity sha512-FCX1aT3GWyY658wzDICef4p+n0dB+ENRct8E/Qyvppj6xVpOYerBHfUu7OP5Rt1/393Tdglguf5ju5DEX4wZNg== + dependencies: + debuglog "^1.0.1" + dezalgo "^1.0.0" + once "^1.3.0" + read-package-json "^2.0.0" + readdir-scoped-modules "^1.0.0" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg-up@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" + integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= + dependencies: + find-up "^2.0.0" + read-pkg "^2.0.0" + +read-pkg-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" + integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= + dependencies: + find-up "^2.0.0" + read-pkg "^3.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +read-pkg@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" + integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= + dependencies: + load-json-file "^2.0.0" + normalize-package-data "^2.3.2" + path-type "^2.0.0" + +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= + dependencies: + load-json-file "^4.0.0" + normalize-package-data "^2.3.2" + path-type "^3.0.0" + +read-pkg@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-4.0.1.tgz#963625378f3e1c4d48c85872b5a6ec7d5d093237" + integrity sha1-ljYlN48+HE1IyFhytabsfV0JMjc= + dependencies: + normalize-package-data "^2.3.2" + parse-json "^4.0.0" + pify "^3.0.0" + +read@1, read@~1.0.1, read@~1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" + integrity sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ= + dependencies: + mute-stream "~0.0.4" + +"readable-stream@1 || 2", readable-stream@2, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@1.1.x: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@^3.0.0, readable-stream@^3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.0.6.tgz#351302e4c68b5abd6a2ed55376a7f9a25be3057a" + integrity sha512-9E1oLoOWfhSXHGv6QlwXJim7uNzd9EVlWK+21tCU9Ju/kR0/p2AZYPz4qSchgO8PlLIH4FpZYfzwS+rEksZjIg== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readable-stream@~2.0.5, readable-stream@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e" + integrity sha1-j5A0HmilPMySh4jaz80Rs265t44= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~0.10.x" + util-deprecate "~1.0.1" + +readable-stream@~2.1.5: + version "2.1.5" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.1.5.tgz#66fa8b720e1438b364681f2ad1a63c618448c9d0" + integrity sha1-ZvqLcg4UOLNkaB8q0aY8YYRIydA= + dependencies: + buffer-shims "^1.0.0" + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~0.10.x" + util-deprecate "~1.0.1" + +readdir-scoped-modules@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.0.2.tgz#9fafa37d286be5d92cbaebdee030dc9b5f406747" + integrity sha1-n6+jfShr5dksuuve4DDcm19AZ0c= + dependencies: + debuglog "^1.0.1" + dezalgo "^1.0.0" + graceful-fs "^4.1.2" + once "^1.3.0" + +readdirp@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +realize-package-specifier@~3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/realize-package-specifier/-/realize-package-specifier-3.0.3.tgz#d0def882952b8de3f67eba5e91199661271f41f4" + integrity sha1-0N74gpUrjeP2frpekRmWYScfQfQ= + dependencies: + dezalgo "^1.0.1" + npm-package-arg "^4.1.1" + +realpath-native@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.0.2.tgz#cd51ce089b513b45cf9b1516c82989b51ccc6560" + integrity sha512-+S3zTvVt9yTntFrBpm7TQmQ3tzpCrnA1a/y+3cUHAc9ZR6aIjG0WNLR+Rj79QpJktY+VeW/TQtFlQ1bzsehI8g== + dependencies: + util.promisify "^1.0.0" + +recursive-readdir@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.2.tgz#9946fb3274e1628de6e36b2f6714953b4845094f" + integrity sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg== + dependencies: + minimatch "3.0.4" + +redent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94= + dependencies: + indent-string "^2.1.0" + strip-indent "^1.0.1" + +redent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-2.0.0.tgz#c1b2007b42d57eb1389079b3c8333639d5e1ccaa" + integrity sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo= + dependencies: + indent-string "^3.0.0" + strip-indent "^2.0.0" + +regenerate-unicode-properties@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-7.0.0.tgz#107405afcc4a190ec5ed450ecaa00ed0cafa7a4c" + integrity sha512-s5NGghCE4itSlUS+0WUj88G6cfMVMmH8boTPNvABf8od+2dhT9WDlWu8n01raQAJZMOK8Ch6jSexaRO7swd6aw== + dependencies: + regenerate "^1.4.0" + +regenerate@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" + integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== + +regenerator-runtime@^0.12.0: + version "0.12.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de" + integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg== + +regenerator-runtime@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.1.tgz#522ea2aafd9200a00eee143dc14219a35a0f3991" + integrity sha512-5KzMIyPLvfdPmvsdlYsHqITrDfK9k7bmvf97HvHSN4810i254ponbxCQ1NukpRWlu6en2MBWzAlhDExEKISwAA== + +regenerator-transform@^0.13.3: + version "0.13.3" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.13.3.tgz#264bd9ff38a8ce24b06e0636496b2c856b57bcbb" + integrity sha512-5ipTrZFSq5vU2YoGoww4uaRVAK4wyYC4TSICibbfEPOruUu8FFP7ErV0BjmbIOEpn3O/k9na9UEdYR/3m7N6uA== + dependencies: + private "^0.1.6" + +regex-cache@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + integrity sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ== + dependencies: + is-equal-shallow "^0.1.3" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexpp@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" + integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== + +regexpu-core@^4.1.3, regexpu-core@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.2.0.tgz#a3744fa03806cffe146dea4421a3e73bdcc47b1d" + integrity sha512-Z835VSnJJ46CNBttalHD/dB+Sj2ezmY6Xp38npwU87peK6mqOzOpV8eYktdkLTEkzzD+JsTcxd84ozd8I14+rw== + dependencies: + regenerate "^1.4.0" + regenerate-unicode-properties "^7.0.0" + regjsgen "^0.4.0" + regjsparser "^0.3.0" + unicode-match-property-ecmascript "^1.0.4" + unicode-match-property-value-ecmascript "^1.0.2" + +registry-auth-token@^3.0.1: + version "3.3.2" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20" + integrity sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ== + dependencies: + rc "^1.1.6" + safe-buffer "^5.0.1" + +registry-url@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942" + integrity sha1-PU74cPc93h138M+aOBQyRE4XSUI= + dependencies: + rc "^1.0.1" + +regjsgen@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.4.0.tgz#c1eb4c89a209263f8717c782591523913ede2561" + integrity sha512-X51Lte1gCYUdlwhF28+2YMO0U6WeN0GLpgpA7LK7mbdDnkQYiwvEpmpe0F/cv5L14EbxgrdayAG3JETBv0dbXA== + +regjsparser@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.3.0.tgz#3c326da7fcfd69fa0d332575a41c8c0cdf588c96" + integrity sha512-zza72oZBBHzt64G7DxdqrOo/30bhHkwMUoT0WqfGu98XLd7N+1tsy5MJ96Bk4MD0y74n629RhmrGW6XlnLLwCA== + dependencies: + jsesc "~0.5.0" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +repeat-element@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + +repeat-string@^1.5.2, repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= + dependencies: + is-finite "^1.0.0" + +request-ip@^2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/request-ip/-/request-ip-2.1.3.tgz#99ab2bafdeaf2002626e28083cb10597511d9e14" + integrity sha512-J3qdE/IhVM3BXkwMIVO4yFrvhJlU3H7JH16+6yHucadT4fePnR8dyh+vEs6FIx0S2x5TCt2ptiPfHcn0sqhbYQ== + dependencies: + is_js "^0.9.0" + +request-promise-core@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6" + integrity sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY= + dependencies: + lodash "^4.13.1" + +request-promise-native@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.5.tgz#5281770f68e0c9719e5163fd3fab482215f4fda5" + integrity sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU= + dependencies: + request-promise-core "1.1.1" + stealthy-require "^1.1.0" + tough-cookie ">=2.3.3" + +request-promise@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/request-promise/-/request-promise-4.2.2.tgz#d1ea46d654a6ee4f8ee6a4fea1018c22911904b4" + integrity sha1-0epG1lSm7k+O5qT+oQGMIpEZBLQ= + dependencies: + bluebird "^3.5.0" + request-promise-core "1.1.1" + stealthy-require "^1.1.0" + tough-cookie ">=2.3.3" + +request@2, request@^2.74.0, request@^2.81.0, request@^2.87.0: + version "2.88.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" + integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.0" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.4.3" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + +request@~2.75.0: + version "2.75.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.75.0.tgz#d2b8268a286da13eaa5d01adf5d18cc90f657d93" + integrity sha1-0rgmiihtoT6qXQGt9dGMyQ9lfZM= + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + bl "~1.1.2" + caseless "~0.11.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~2.0.0" + har-validator "~2.0.6" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + node-uuid "~1.4.7" + oauth-sign "~0.8.1" + qs "~6.2.0" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "~0.4.1" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= + +require-package-name@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/require-package-name/-/require-package-name-2.0.1.tgz#c11e97276b65b8e2923f75dabf5fb2ef0c3841b9" + integrity sha1-wR6XJ2tluOKSP3Xav1+y7ww4Qbk= + +require-uncached@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + integrity sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM= + dependencies: + caller-path "^0.1.0" + resolve-from "^1.0.0" + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= + +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= + dependencies: + resolve-from "^3.0.0" + +resolve-from@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" + integrity sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY= + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + integrity sha1-six699nWiBvItuZTM17rywoYh0g= + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= + +resolve@^1.3.2, resolve@^1.5.0, resolve@^1.6.0, resolve@^1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" + integrity sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA== + dependencies: + path-parse "^1.0.5" + +responselike@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= + dependencies: + lowercase-keys "^1.0.0" + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +retry-as-promised@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/retry-as-promised/-/retry-as-promised-2.3.2.tgz#cd974ee4fd9b5fe03cbf31871ee48221c07737b7" + integrity sha1-zZdO5P2bX+A8vzGHHuSCIcB3N7c= + dependencies: + bluebird "^3.4.6" + debug "^2.6.9" + +retry@0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= + +retry@^0.10.0, retry@~0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4" + integrity sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q= + +rimraf@2, rimraf@^2.2.8, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@~2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" + integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== + dependencies: + glob "^7.0.5" + +rimraf@~2.5.4: + version "2.5.4" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.5.4.tgz#96800093cbf1a0c86bd95b4625467535c29dfa04" + integrity sha1-loAAk8vxoMhr2VtGJUZ1NcKd+gQ= + dependencies: + glob "^7.0.5" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +router-ips@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/router-ips/-/router-ips-1.0.0.tgz#44e00858ebebc0133d58e40b2cd8a1fbb04203f5" + integrity sha1-ROAIWOvrwBM9WOQLLNih+7BCA/U= + +rsvp@^3.3.3: + version "3.6.2" + resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a" + integrity sha512-OfWGQTb9vnwRjwtA2QwpG2ICclHC3pgXZO5xt8H2EfgDquO0qVdSb5T88L4qJVAEugbS56pAuV4XZM58UX8ulw== + +run-async@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= + dependencies: + is-promise "^2.1.0" + +run-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/run-node/-/run-node-1.0.0.tgz#46b50b946a2aa2d4947ae1d886e9856fd9cabe5e" + integrity sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A== + +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + integrity sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec= + dependencies: + aproba "^1.1.1" + +rx-lite-aggregates@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" + integrity sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74= + dependencies: + rx-lite "*" + +rx-lite@*, rx-lite@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" + integrity sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ= + +rxjs@^6.1.0, rxjs@^6.3.3: + version "6.3.3" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.3.3.tgz#3c6a7fa420e844a81390fb1158a9ec614f4bad55" + integrity sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw== + dependencies: + tslib "^1.9.0" + +safe-buffer@5.1.2, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sane@^2.0.0: + version "2.5.2" + resolved "https://registry.yarnpkg.com/sane/-/sane-2.5.2.tgz#b4dc1861c21b427e929507a3e751e2a2cb8ab3fa" + integrity sha1-tNwYYcIbQn6SlQej51HiosuKs/o= + dependencies: + anymatch "^2.0.0" + capture-exit "^1.2.0" + exec-sh "^0.2.0" + fb-watchman "^2.0.0" + micromatch "^3.1.4" + minimist "^1.1.1" + walker "~1.0.5" + watch "~0.18.0" + optionalDependencies: + fsevents "^1.2.3" + +sax@>=0.6.0, sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +schema-utils@^0.4.4: + version "0.4.7" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187" + integrity sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ== + dependencies: + ajv "^6.1.0" + ajv-keywords "^3.1.0" + +schema-utils@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" + integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== + dependencies: + ajv "^6.1.0" + ajv-errors "^1.0.0" + ajv-keywords "^3.1.0" + +scryptsy@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/scryptsy/-/scryptsy-2.0.0.tgz#262c36f0231cfa7654e2363fa394cd2dec66f378" + integrity sha1-Jiw28CMc+nZU4jY/o5TNLexm83g= + +secp256k1@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-3.5.2.tgz#f95f952057310722184fe9c914e6b71281f2f2ae" + integrity sha512-iin3kojdybY6NArd+UFsoTuapOF7bnJNf2UbcWXaY3z+E1sJDipl60vtzB5hbO/uquBu7z0fd4VC4Irp+xoFVQ== + dependencies: + bindings "^1.2.1" + bip66 "^1.1.3" + bn.js "^4.11.3" + create-hash "^1.1.2" + drbg.js "^1.0.1" + elliptic "^6.2.3" + nan "^2.2.1" + safe-buffer "^5.1.0" + +secure-keys@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/secure-keys/-/secure-keys-1.0.0.tgz#f0c82d98a3b139a8776a8808050b824431087fca" + integrity sha1-8MgtmKOxOah3aogIBQuCRDEIf8o= + +semver-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" + integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= + +semver-diff@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" + integrity sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY= + dependencies: + semver "^5.0.3" + +semver-utils@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/semver-utils/-/semver-utils-1.1.4.tgz#cf0405e669a57488913909fc1c3f29bf2a4871e2" + integrity sha512-EjnoLE5OGmDAVV/8YDoN5KiajNadjzIp9BAHOhYeQHt7j0UWxjmgsx4YD48wp4Ue1Qogq38F1GNUJNqF1kKKxA== + +"semver@2 >=2.2.1 || 3.x || 4 || 5", "semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", "semver@^2.3.0 || 3.x || 4 || 5", semver@^5.0.1, semver@^5.0.3, semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" + integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== + +semver@4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.2.tgz#c7a07158a80bedd052355b770d82d6640f803be7" + integrity sha1-x6BxWKgL7dBSNVt3DYLWZA+AO+c= + +semver@^4.1.0: + version "4.3.6" + resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" + integrity sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto= + +semver@~5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + integrity sha1-myzl094C0XxgEq0yaqa00M9U+U8= + +send@0.16.2: + version "0.16.2" + resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" + integrity sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw== + dependencies: + debug "2.6.9" + depd "~1.1.2" + destroy "~1.0.4" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "~1.6.2" + mime "1.4.1" + ms "2.0.0" + on-finished "~2.3.0" + range-parser "~1.2.0" + statuses "~1.4.0" + +sequelize@^4.41.2: + version "4.41.2" + resolved "https://registry.yarnpkg.com/sequelize/-/sequelize-4.41.2.tgz#bb9ba30d72e9eeb883c9861cd0e2cac672010883" + integrity sha512-8vPf2R0o9iEmtzkqNzwFdblO+0Mu+RNxOdLeYGGqWGlp3cushLpQucAeSGPQgf2hQVZP5yOCM1ouZKTQ5FTlvA== + dependencies: + bluebird "^3.5.0" + cls-bluebird "^2.1.0" + debug "^3.1.0" + depd "^1.1.0" + dottie "^2.0.0" + generic-pool "^3.4.0" + inflection "1.12.0" + lodash "^4.17.1" + moment "^2.20.0" + moment-timezone "^0.5.14" + retry-as-promised "^2.3.2" + semver "^5.5.0" + terraformer-wkt-parser "^1.1.2" + toposort-class "^1.0.1" + uuid "^3.2.1" + validator "^10.4.0" + wkx "^0.4.1" + +serialize-javascript@^1.4.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.5.0.tgz#1aa336162c88a890ddad5384baebc93a655161fe" + integrity sha512-Ga8c8NjAAp46Br4+0oZ2WxJCwIzwP60Gq1YPgU+39PiTVxyed/iKE/zyZI6+UlVYH5Q4PaQdHhcegIFPZTUfoQ== + +serve-static@1.13.2: + version "1.13.2" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.13.2.tgz#095e8472fd5b46237db50ce486a43f4b86c6cec1" + integrity sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.2" + send "0.16.2" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +set-value@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" + integrity sha1-fbCPnT0i3H945Trzw79GZuzfzPE= + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.1" + to-object-path "^0.3.0" + +set-value@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" + integrity sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setimmediate@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU= + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +sha@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/sha/-/sha-2.0.1.tgz#6030822fbd2c9823949f8f72ed6411ee5cf25aae" + integrity sha1-YDCCL70smCOUn49y7WQR7lzyWq4= + dependencies: + graceful-fs "^4.1.2" + readable-stream "^2.0.2" + +shallow-clone@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-0.1.2.tgz#5909e874ba77106d73ac414cfec1ffca87d97060" + integrity sha1-WQnodLp3EG1zrEFM/sH/yofZcGA= + dependencies: + is-extendable "^0.1.1" + kind-of "^2.0.1" + lazy-cache "^0.2.3" + mixin-object "^2.0.1" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +shellwords@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" + integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== + +shimmer@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shimmer/-/shimmer-1.2.0.tgz#f966f7555789763e74d8841193685a5e78736665" + integrity sha512-xTCx2vohXC2EWWDqY/zb4+5Mu28D+HYNSOuFzsyRDRvI/e1ICb69afwaUwfjr+25ZXldbOLyp+iDUZHq8UnTag== + +shot@4.x.x: + version "4.0.7" + resolved "https://registry.yarnpkg.com/shot/-/shot-4.0.7.tgz#b05d2858634fedc18ece99e8f638fab7c9f9d4c4" + integrity sha512-RKaKAGKxJ11EjJl0cf2fYVSsd4KB5Cncb9J0v7w+0iIaXpxNqFWTYNDNhBX7f0XSyDrjOH9a4OWZ9Gp/ZML+ew== + dependencies: + hoek "6.x.x" + joi "14.x.x" + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= + +simple-git@^1.85.0: + version "1.107.0" + resolved "https://registry.yarnpkg.com/simple-git/-/simple-git-1.107.0.tgz#12cffaf261c14d6f450f7fdb86c21ccee968b383" + integrity sha512-t4OK1JRlp4ayKRfcW6owrWcRVLyHRUlhGd0uN6ZZTqfDq8a5XpcUdOKiGRNobHEuMtNqzp0vcJNvhYWwh5PsQA== + dependencies: + debug "^4.0.1" + +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= + dependencies: + is-arrayish "^0.3.1" + +sisteransi@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-0.1.1.tgz#5431447d5f7d1675aac667ccd0b865a4994cb3ce" + integrity sha512-PmGOd02bM9YO5ifxpw36nrNMBTptEtfRl4qUYl9SndkolplkrZZOW7PGHjrZL53QvMVj9nQ+TKqUnRsw4tJa4g== + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= + +slash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== + +slice-ansi@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" + integrity sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU= + +slice-ansi@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" + integrity sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg== + dependencies: + is-fullwidth-code-point "^2.0.0" + +sliced@0.0.x: + version "0.0.5" + resolved "https://registry.yarnpkg.com/sliced/-/sliced-0.0.5.tgz#5edc044ca4eb6f7816d50ba2fc63e25d8fe4707f" + integrity sha1-XtwETKTrb3gW1Qui/GPiXY/kcH8= + +slide@^1.1.3, slide@^1.1.5, slide@^1.1.6, slide@~1.1.3, slide@~1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" + integrity sha1-VusCfWW00tzmyy4tMsTUr8nh1wc= + +smart-buffer@^1.0.13: + version "1.1.15" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-1.1.15.tgz#7f114b5b65fab3e2a35aa775bb12f0d1c649bf16" + integrity sha1-fxFLW2X6s+KjWqd1uxLw0cZJvxY= + +smart-buffer@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.0.1.tgz#07ea1ca8d4db24eb4cac86537d7d18995221ace3" + integrity sha512-RFqinRVJVcCAL9Uh1oVqE6FZkqsyLiVOYEZ20TqIOjuX7iFVJ+zsbs4RIghnw/pTs7mZvt8ZHhvm1ZUrR4fykg== + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +sntp@1.x.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" + integrity sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg= + dependencies: + hoek "2.x.x" + +sntp@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-3.0.2.tgz#3f0b5de6115681dce82a9478691f0e5c552de5a3" + integrity sha512-MCAPpBPFjNp1fwDVCLSRuWuH9gONtb2R+lS1esC6Mp8lP6jy60FVUtP/Qr0jBvcWAVbhzx06y1b6ptXiy32dug== + dependencies: + boom "7.x.x" + bounce "1.x.x" + hoek "6.x.x" + teamwork "3.x.x" + +snyk-config@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/snyk-config/-/snyk-config-2.2.0.tgz#d400ce50e293ce5c3ade4cf46a53bea8205771e6" + integrity sha512-mq0wbP/AgjcmRq5i5jg2akVVV3iSYUPTowZwKn7DChRLDL8ySOzWAwan+ImXiyNbrWo87FNI/15O6MpOnTxOIg== + dependencies: + debug "^3.1.0" + lodash "^4.17.5" + nconf "^0.10.0" + +snyk-docker-plugin@1.12.3: + version "1.12.3" + resolved "https://registry.yarnpkg.com/snyk-docker-plugin/-/snyk-docker-plugin-1.12.3.tgz#a4a7c81a8e4e3c6a6cc303d4bc9aa98645274bca" + integrity sha512-ZbvaFCPCd0wxhqxjzU/iyf39tKlq2nvI9nPW32uZV3RGdHrkQH55BzCtBCF9d0dapxX+PKgae/4u2BKNw8hd9Q== + dependencies: + debug "^3" + dockerfile-ast "0.0.12" + tslib "^1" + +snyk-go-plugin@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/snyk-go-plugin/-/snyk-go-plugin-1.6.0.tgz#4b312db52fdde6d9b2ac75fe1f9712b88563737d" + integrity sha512-E6aYw7XAXSs2wJR3fU+vGQ1lVyjAw8PHIQYQwBwMkTHByhJIWPcu6Hy/jT5LcjJHlhYXlpOuk53HeLVK+kcXrQ== + dependencies: + graphlib "^2.1.1" + tmp "0.0.33" + toml "^2.3.2" + +snyk-gradle-plugin@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snyk-gradle-plugin/-/snyk-gradle-plugin-2.1.1.tgz#661591014508fdd1cbe5b91f4f8e6af50f68a9ac" + integrity sha512-aFeVC5y3XkJ5BxknHhtYo76as3xJbzSQlXACGZrQZGQ/w/UhNdM8VI1QB6Eq4uEzexleB/hcJwYxNmhI2CNCeA== + dependencies: + clone-deep "^0.3.0" + +snyk-module@1.9.1, snyk-module@^1.6.0, snyk-module@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/snyk-module/-/snyk-module-1.9.1.tgz#b2a78f736600b0ab680f1703466ed7309c980804" + integrity sha512-A+CCyBSa4IKok5uEhqT+hV/35RO6APFNLqk9DRRHg7xW2/j//nPX8wTSZUPF8QeRNEk/sX+6df7M1y6PBHGSHA== + dependencies: + debug "^3.1.0" + hosted-git-info "^2.7.1" + +snyk-mvn-plugin@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/snyk-mvn-plugin/-/snyk-mvn-plugin-2.0.0.tgz#875dcfe0d77b50396321552f2469ee69ca8d1416" + integrity sha512-9jAhZhv+7YcqtoQYCYlgMoxK+dWBKlk+wkX27Ebg3vNddNop9q5jZitRXTjsXwfSUZHRt+Ptw1f8vei9kjzZVg== + +snyk-nodejs-lockfile-parser@1.7.1: + version "1.7.1" + resolved "https://registry.yarnpkg.com/snyk-nodejs-lockfile-parser/-/snyk-nodejs-lockfile-parser-1.7.1.tgz#499fd29db9a9185e3cb90a314b204fa1244fffb6" + integrity sha512-0gHELqMhzUxb/t3Tg6d6G9LTDioOXCrEMt9aetOeV8wD/ZRL5VFNjwcdrm8qILLqzDFaFjFIyMc66c0OL4zFAQ== + dependencies: + "@yarnpkg/lockfile" "^1.0.2" + graphlib "^2.1.5" + lodash "4.17.10" + source-map-support "^0.5.7" + tslib "^1.9.3" + uuid "^3.3.2" + +snyk-nuget-plugin@1.6.5: + version "1.6.5" + resolved "https://registry.yarnpkg.com/snyk-nuget-plugin/-/snyk-nuget-plugin-1.6.5.tgz#0a5d53ba47a8bbdc82e245171446ec0485cc591b" + integrity sha512-3qIndzkxCxiaGvAwMkqChbChGdwhNePPyfi0WjhC/nJGwecqU3Fb/NeTW7lgyT+xoq/dFnzW0DgBJ4+AyNA2gA== + dependencies: + debug "^3.1.0" + jszip "^3.1.5" + lodash "^4.17.10" + xml2js "^0.4.17" + +snyk-php-plugin@1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/snyk-php-plugin/-/snyk-php-plugin-1.5.1.tgz#3785ee45f5e003919abc476a109ad4f34fabe631" + integrity sha512-g5QSHBsRJ2O4cNxKC4zlWwnQYiSgQ77Y6QgGmo3ihPX3VLZrc1amaZIpPsNe1jwXirnGj2rvR5Xw+jDjbzvHFw== + dependencies: + debug "^3.1.0" + lodash "^4.17.5" + path "0.12.7" + +snyk-policy@1.13.1: + version "1.13.1" + resolved "https://registry.yarnpkg.com/snyk-policy/-/snyk-policy-1.13.1.tgz#2366cc485e83a6b43f23f45b36085726e0bf448b" + integrity sha512-l9evS3Yk70xyvajjg+I6Ij7fr7gxpVRMZl0J1xNpWps/IVu4DSGih3aMmXi47VJozr4A/eFyj7R1lIr2GhqJCA== + dependencies: + debug "^3.1.0" + email-validator "^2.0.4" + js-yaml "^3.12.0" + lodash.clonedeep "^4.5.0" + semver "^5.6.0" + snyk-module "^1.9.1" + snyk-resolve "^1.0.1" + snyk-try-require "^1.3.1" + then-fs "^2.0.0" + +snyk-python-plugin@1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/snyk-python-plugin/-/snyk-python-plugin-1.9.0.tgz#2f444f9377880181c1fdbed6ab2890687fe10c99" + integrity sha512-zlyOHoCpmyVym9AwkboeepzEGrY3gHsM7eWP/nJ85TgCnQO5H5orKm3RL57PNbWRY+BnDmoQQ+udQgjym2+3sg== + dependencies: + tmp "0.0.33" + +snyk-resolve-deps@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/snyk-resolve-deps/-/snyk-resolve-deps-4.0.2.tgz#c3fa08a14fff6667628ec590061360de15f67ae6" + integrity sha512-nlw62wiWhGOTw3BD3jVIwrUkRR4iNxEkkO4Y/PWs8BsUWseGu1H6QgLesFXJb3qx7ANJ5UbUCJMgV+eL0Lf9cA== + dependencies: + ansicolors "^0.3.2" + debug "^3.2.5" + lodash.assign "^4.2.0" + lodash.assignin "^4.2.0" + lodash.clone "^4.5.0" + lodash.flatten "^4.4.0" + lodash.get "^4.4.2" + lodash.set "^4.3.2" + lru-cache "^4.0.0" + semver "^5.5.1" + snyk-module "^1.6.0" + snyk-resolve "^1.0.0" + snyk-tree "^1.0.0" + snyk-try-require "^1.1.1" + then-fs "^2.0.0" + +snyk-resolve@1.0.1, snyk-resolve@^1.0.0, snyk-resolve@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/snyk-resolve/-/snyk-resolve-1.0.1.tgz#eaa4a275cf7e2b579f18da5b188fe601b8eed9ab" + integrity sha512-7+i+LLhtBo1Pkth01xv+RYJU8a67zmJ8WFFPvSxyCjdlKIcsps4hPQFebhz+0gC5rMemlaeIV6cqwqUf9PEDpw== + dependencies: + debug "^3.1.0" + then-fs "^2.0.0" + +snyk-sbt-plugin@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/snyk-sbt-plugin/-/snyk-sbt-plugin-2.0.0.tgz#d7fa18bee77ecb045ecc7feb8915f83b75186582" + integrity sha512-bOUqsQ1Lysnwfnvf4QQIBfC0M0ZVuhlshTKd7pNwgAJ41YEPJNrPEpzOePl/HfKtwilEEwHh5YHvjYGegEKx0A== + +snyk-tree@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/snyk-tree/-/snyk-tree-1.0.0.tgz#0fb73176dbf32e782f19100294160448f9111cc8" + integrity sha1-D7cxdtvzLngvGRAClBYESPkRHMg= + dependencies: + archy "^1.0.0" + +snyk-try-require@1.3.1, snyk-try-require@^1.1.1, snyk-try-require@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/snyk-try-require/-/snyk-try-require-1.3.1.tgz#6e026f92e64af7fcccea1ee53d524841e418a212" + integrity sha1-bgJvkuZK9/zM6h7lPVJIQeQYohI= + dependencies: + debug "^3.1.0" + lodash.clonedeep "^4.3.0" + lru-cache "^4.0.0" + then-fs "^2.0.0" + +snyk@^1.111.1: + version "1.111.1" + resolved "https://registry.yarnpkg.com/snyk/-/snyk-1.111.1.tgz#ad259d062bf260b942dcacd77380167991ecd4aa" + integrity sha512-u65bSQnIfsrbFSWVb+otdG+9iIxGf4xlRd7P4SS2/ndeWMxgQflaDvz+77LYHRFuWYLydxqAE3gEeVQvkWoe3A== + dependencies: + "@snyk/dep-graph" "1.1.2" + "@snyk/gemfile" "1.1.0" + abbrev "^1.1.1" + ansi-escapes "^3.1.0" + chalk "^2.4.1" + configstore "^3.1.2" + debug "^3.1.0" + hasbin "^1.2.3" + inquirer "^3.0.0" + lodash "^4.17.5" + needle "^2.2.4" + opn "^5.2.0" + os-name "^2.0.1" + proxy-agent "^2.0.0" + proxy-from-env "^1.0.0" + recursive-readdir "^2.2.2" + semver "^5.5.0" + snyk-config "2.2.0" + snyk-docker-plugin "1.12.3" + snyk-go-plugin "1.6.0" + snyk-gradle-plugin "2.1.1" + snyk-module "1.9.1" + snyk-mvn-plugin "2.0.0" + snyk-nodejs-lockfile-parser "1.7.1" + snyk-nuget-plugin "1.6.5" + snyk-php-plugin "1.5.1" + snyk-policy "1.13.1" + snyk-python-plugin "1.9.0" + snyk-resolve "1.0.1" + snyk-resolve-deps "4.0.2" + snyk-sbt-plugin "2.0.0" + snyk-tree "^1.0.0" + snyk-try-require "1.3.1" + source-map-support "^0.5.9" + tempfile "^2.0.0" + then-fs "^2.0.0" + undefsafe "^2.0.0" + uuid "^3.2.1" + +socks-proxy-agent@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-3.0.1.tgz#2eae7cf8e2a82d34565761539a7f9718c5617659" + integrity sha512-ZwEDymm204mTzvdqyUqOdovVr2YRd2NYskrYrF2LXyZ9qDiMAoFESGK8CRphiO7rtbo2Y757k2Nia3x2hGtalA== + dependencies: + agent-base "^4.1.0" + socks "^1.1.10" + +socks-proxy-agent@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-4.0.1.tgz#5936bf8b707a993079c6f37db2091821bffa6473" + integrity sha512-Kezx6/VBguXOsEe5oU3lXYyKMi4+gva72TwJ7pQY5JfqUx2nMk7NXA6z/mpNqIlfQjWYVfeuNvQjexiTaTn6Nw== + dependencies: + agent-base "~4.2.0" + socks "~2.2.0" + +socks@^1.1.10: + version "1.1.10" + resolved "https://registry.yarnpkg.com/socks/-/socks-1.1.10.tgz#5b8b7fc7c8f341c53ed056e929b7bf4de8ba7b5a" + integrity sha1-W4t/x8jzQcU+0FbpKbe/Tei6e1o= + dependencies: + ip "^1.1.4" + smart-buffer "^1.0.13" + +socks@~2.2.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.2.2.tgz#f061219fc2d4d332afb4af93e865c84d3fa26e2b" + integrity sha512-g6wjBnnMOZpE0ym6e0uHSddz9p3a+WsBaaYQaBaSCJYvrC4IXykQR9MNGjLQf38e9iIIhp3b1/Zk8YZI3KGJ0Q== + dependencies: + ip "^1.1.5" + smart-buffer "^4.0.1" + +somever@2.x.x: + version "2.0.0" + resolved "https://registry.yarnpkg.com/somever/-/somever-2.0.0.tgz#7bdbed3bee8ece2c7c8a2e7d9a1c022bd98d6c89" + integrity sha512-9JaIPP+HxwYGqCDqqK3tRaTqdtQHoK6Qy3IrXhIt2q5x8fs8RcfU7BMWlFTCOgFazK8p88zIv1tHQXvAwtXMyw== + dependencies: + bounce "1.x.x" + hoek "6.x.x" + +sonic-boom@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-0.6.3.tgz#a02f9fc8d5ec42166e28c39760cc833552056595" + integrity sha512-TMhj6kDJk9LLzCTTL8+HPCfFn4MwkE4P6k2Up89Rz949+DSRw90V62upRKC99rJEOmu4E9ljH5Otu2JSRmx+bg== + dependencies: + flatstr "^1.0.8" + +sort-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" + integrity sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg= + dependencies: + is-plain-obj "^1.0.0" + +sorted-object@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/sorted-object/-/sorted-object-2.0.1.tgz#7d631f4bd3a798a24af1dffcfbfe83337a5df5fc" + integrity sha1-fWMfS9OnmKJK8d/8+/6DM3pd9fw= + +source-list-map@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== + +source-map-resolve@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" + integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== + dependencies: + atob "^2.1.1" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@^0.4.15: + version "0.4.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + integrity sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA== + dependencies: + source-map "^0.5.6" + +source-map-support@^0.5.6, source-map-support@^0.5.7, source-map-support@^0.5.9, source-map-support@~0.5.6: + version "0.5.9" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.9.tgz#41bc953b2534267ea2d605bccfa7bfa3111ced5f" + integrity sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + +source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +spawn-please@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/spawn-please/-/spawn-please-0.3.0.tgz#db338ec4cff63abc69f1d0e08cee9eb8bebd9d11" + integrity sha1-2zOOxM/2Orxp8dDgjO6euL69nRE= + +spdx-correct@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.2.tgz#19bb409e91b47b1ad54159243f7312a858db3c2e" + integrity sha512-q9hedtzyXHr5S0A1vEPoK/7l8NpfkFYTq6iCY+Pno2ZbdZR6WexZFtqeVGkGxW3TEJMN914Z55EnAGMmenlIQQ== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" + integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== + +spdx-expression-parse@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.2.tgz#a59efc09784c2a5bada13cfeaf5c75dd214044d2" + integrity sha512-qky9CVt0lVIECkEsYbNILVnPvycuEBkXoMFLRWsREkomQLevYhtRKC+R91a5TOAQ3bCMjikRwhyaRqj1VYatYg== + +spex@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/spex/-/spex-2.1.0.tgz#21939ab7722322c3a1d002870fab022daa79335f" + integrity sha512-nZ1LA8v1o0Maf9pdWKUXuUM855EqyE+DP0NT0ddZqXqXmr9xKlXjYWN97w+yWehTbM+Ox0aEvQ8Ufqk/OuLCOQ== + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +split2@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-2.2.0.tgz#186b2575bcf83e85b7d18465756238ee4ee42493" + integrity sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw== + dependencies: + through2 "^2.0.2" + +split2@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-3.0.0.tgz#55057cd560687a7ef6464471597404577ff1735d" + integrity sha512-Cp7G+nUfKJyHCrAI8kze3Q00PFGEG1pMgrAlTFlDbn+GW24evSZHJuMl+iUJx1w/NTRDeBiTgvwnf6YOt94FMw== + dependencies: + readable-stream "^3.0.0" + +split@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" + integrity sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg== + dependencies: + through "2" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +sql@^0.78.0, sql@~0.78.0: + version "0.78.0" + resolved "https://registry.yarnpkg.com/sql/-/sql-0.78.0.tgz#894585d56111dbb1768741a4d9935c82c8595949" + integrity sha1-iUWF1WER27F2h0Gk2ZNcgshZWUk= + dependencies: + lodash "4.1.x" + sliced "0.0.x" + +sqlite3@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/sqlite3/-/sqlite3-4.0.2.tgz#1bbeb68b03ead5d499e42a3a1b140064791c5a64" + integrity sha512-51ferIRwYOhzUEtogqOa/y9supADlAht98bF/gbIi6WkzRJX6Yioldxbzj1MV4yV+LgdKD/kkHwFTeFXOG4htA== + dependencies: + nan "~2.10.0" + node-pre-gyp "^0.10.3" + request "^2.87.0" + +sqlite3@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/sqlite3/-/sqlite3-4.0.4.tgz#1f75e3ededad6e26f7dd819929460ce44a49dfcd" + integrity sha512-CO8vZMyUXBPC+E3iXOCc7Tz2pAdq5BWfLcQmOokCOZW5S5sZ/paijiPOCdvzpdP83RroWHYa5xYlVqCxSqpnQg== + dependencies: + nan "~2.10.0" + node-pre-gyp "^0.10.3" + request "^2.87.0" + +sshpk@^1.7.0: + version "1.15.2" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.15.2.tgz#c946d6bd9b1a39d0e8635763f5242d6ed6dcb629" + integrity sha512-Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + +ssri@^6.0.0, ssri@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" + integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== + dependencies: + figgy-pudding "^3.5.1" + +stack-trace@0.0.10, stack-trace@0.0.x, stack-trace@~0.0.9: + version "0.0.10" + resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" + integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA= + +stack-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" + integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== + +staged-git-files@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/staged-git-files/-/staged-git-files-1.1.2.tgz#4326d33886dc9ecfa29a6193bf511ba90a46454b" + integrity sha512-0Eyrk6uXW6tg9PYkhi/V/J4zHp33aNyi2hOCmhFLqLTIhbgqWn5jlSzI+IU0VqrZq6+DbHcabQl/WP6P3BG0QA== + +statehood@6.x.x: + version "6.0.8" + resolved "https://registry.yarnpkg.com/statehood/-/statehood-6.0.8.tgz#c8c3363694b207ab692d17ab5b48eebf47e13e10" + integrity sha512-/uk2Iq5VXCAGmYnRTjez6gDfU8fROm1Um5WH2C9aNCdG7DAqD94dqZgeuqXrvVFnfDqxAtorUBLUtD9El/uJ6w== + dependencies: + boom "7.x.x" + bounce "1.x.x" + cryptiles "4.x.x" + hoek "6.x.x" + iron "5.x.x" + joi "14.x.x" + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +"statuses@>= 1.4.0 < 2": + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +statuses@~1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" + integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew== + +stealthy-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= + +stream-browserify@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" + integrity sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds= + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-each@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" + integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + +stream-http@^2.7.2: + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.3.6" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + +stream-shift@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" + integrity sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI= + +streamsearch@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" + integrity sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo= + +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= + +string-argv@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.0.2.tgz#dac30408690c21f3c3630a3ff3a05877bdcbd736" + integrity sha1-2sMECGkMIfPDYwo/86BYd73L1zY= + +string-length@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" + integrity sha1-1A27aGo6zpYMHP/KVivyxF+DY+0= + dependencies: + astral-regex "^1.0.0" + strip-ansi "^4.0.0" + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string_decoder@^1.0.0, string_decoder@^1.1.1, string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= + +stringify-object@^3.2.2: + version "3.3.0" + resolved "https://registry.yarnpkg.com/stringify-object/-/stringify-object-3.3.0.tgz#703065aefca19300d3ce88af4f5b3956d7556629" + integrity sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw== + dependencies: + get-own-enumerable-property-symbols "^3.0.0" + is-obj "^1.0.1" + is-regexp "^1.0.0" + +stringstream@~0.0.4: + version "0.0.6" + resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.6.tgz#7880225b0d4ad10e30927d167a1d6f2fd3b33a72" + integrity sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA== + +strip-ansi@^3.0.0, strip-ansi@^3.0.1, strip-ansi@~3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-bom@3.0.0, strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= + dependencies: + is-utf8 "^0.2.0" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + +strip-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI= + dependencies: + get-stdin "^4.0.1" + +strip-indent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" + integrity sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g= + +strip-json-comments@^2.0.1, strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +strong-log-transformer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strong-log-transformer/-/strong-log-transformer-2.0.0.tgz#fa6d8e0a9e62b3c168c3cad5ae5d00dc97ba26cc" + integrity sha512-FQmNqAXJgOX8ygOcvPLlGWBNT41mvNJ9ALoYf0GTwVt9t30mGTqpmp/oJx5gLcu52DXK10kS7dVWhx8aPXDTlg== + dependencies: + byline "^5.0.0" + duplexer "^0.1.1" + minimist "^1.2.0" + through "^2.3.4" + +subscriptions-transport-ws@^0.9.11: + version "0.9.15" + resolved "https://registry.yarnpkg.com/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.15.tgz#68a8b7ba0037d8c489fb2f5a102d1494db297d0d" + integrity sha512-f9eBfWdHsePQV67QIX+VRhf++dn1adyC/PZHP6XI5AfKnZ4n0FW+v5omxwdHVpd4xq2ZijaHEcmlQrhBY79ZWQ== + dependencies: + backo2 "^1.0.2" + eventemitter3 "^3.1.0" + iterall "^1.2.1" + symbol-observable "^1.0.4" + ws "^5.2.0" + +subtext@6.x.x: + version "6.0.11" + resolved "https://registry.yarnpkg.com/subtext/-/subtext-6.0.11.tgz#430de749b06fc5005d208ffd2668b5c7a1ca27ac" + integrity sha512-jap1ev33dbVTBPxpIyJ5OvD9/J4oWlx1qHQ8bBnKpiwItxXt3+7tvmNZqZeTEQVTjvkReHY1ZnP/7iltNdGnOA== + dependencies: + boom "7.x.x" + content "4.x.x" + hoek "6.x.x" + pez "4.x.x" + wreck "14.x.x" + +superheroes@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/superheroes/-/superheroes-2.0.0.tgz#8e18ea99b718973afb9b76afd213c7c0e0263537" + integrity sha512-yTQ2cZ5G/csR1WqF6NOVs3S/FYqj8Tc8TISSsyeBqddYnshX8fkeAfGA5WV4l3/yc7F/pMWVZWfFOzJrQ8Vpng== + dependencies: + unique-random-array "^1.0.0" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + +supports-color@^3.1.2: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= + dependencies: + has-flag "^1.0.0" + +supports-color@^5.3.0, supports-color@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +symbol-observable@^1.0.4, symbol-observable@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" + integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== + +symbol-tree@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6" + integrity sha1-rifbOPZgp64uHDt9G8KQgZuFGeY= + +table@^5.0.2: + version "5.1.0" + resolved "https://registry.yarnpkg.com/table/-/table-5.1.0.tgz#69a54644f6f01ad1628f8178715b408dc6bf11f7" + integrity sha512-e542in22ZLhD/fOIuXs/8yDZ9W61ltF8daM88rkRNtgTIct+vI2fTnAyu/Db2TCfEcI8i7mjZz6meLq0nW7TYg== + dependencies: + ajv "^6.5.3" + lodash "^4.17.10" + slice-ansi "1.0.0" + string-width "^2.1.1" + +tapable@^1.0.0, tapable@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.0.tgz#0d076a172e3d9ba088fd2272b2668fb8d194b78c" + integrity sha512-IlqtmLVaZA2qab8epUXbVWRn3aB1imbDMJtjB3nu4X0NqPkcY/JH9ZtCBWKHWPxs8Svi9tyo8w2dBoi07qZbBA== + +tar@^2.0.0, tar@~2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + integrity sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE= + dependencies: + block-stream "*" + fstream "^1.0.2" + inherits "2" + +tar@^4, tar@^4.4.6: + version "4.4.8" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d" + integrity sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ== + dependencies: + chownr "^1.1.1" + fs-minipass "^1.2.5" + minipass "^2.3.4" + minizlib "^1.1.1" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.2" + +teamwork@3.x.x: + version "3.0.3" + resolved "https://registry.yarnpkg.com/teamwork/-/teamwork-3.0.3.tgz#0c08748efe00c32c1eaf1128ef7f07ba0c7cc4ea" + integrity sha512-OCB56z+G70iA1A1OFoT+51TPzfcgN0ks75uN3yhxA+EU66WTz2BevNDK4YzMqfaL5tuAvxy4iFUn35/u8pxMaQ== + +temp-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" + integrity sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0= + +temp-write@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/temp-write/-/temp-write-3.4.0.tgz#8cff630fb7e9da05f047c74ce4ce4d685457d492" + integrity sha1-jP9jD7fp2gXwR8dM5M5NaFRX1JI= + dependencies: + graceful-fs "^4.1.2" + is-stream "^1.1.0" + make-dir "^1.0.0" + pify "^3.0.0" + temp-dir "^1.0.0" + uuid "^3.0.1" + +tempfile@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/tempfile/-/tempfile-2.0.0.tgz#6b0446856a9b1114d1856ffcbe509cccb0977265" + integrity sha1-awRGhWqbERTRhW/8vlCczLCXcmU= + dependencies: + temp-dir "^1.0.0" + uuid "^3.0.1" + +term-size@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" + integrity sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk= + dependencies: + execa "^0.7.0" + +terraformer-wkt-parser@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/terraformer-wkt-parser/-/terraformer-wkt-parser-1.2.0.tgz#c9d6ac3dff25f4c0bd344e961f42694961834c34" + integrity sha512-QU3iA54St5lF8Za1jg1oj4NYc8sn5tCZ08aNSWDeGzrsaV48eZk1iAVWasxhNspYBoCqdHuoot1pUTUrE1AJ4w== + dependencies: + "@types/geojson" "^1.0.0" + terraformer "~1.0.5" + +terraformer@~1.0.5: + version "1.0.9" + resolved "https://registry.yarnpkg.com/terraformer/-/terraformer-1.0.9.tgz#77851fef4a49c90b345dc53cf26809fdf29dcda6" + integrity sha512-YlmQ1fsMWTkKGDGibCRWgmLzrpDRUr63Q025LJ/taYQ6j1Yb8q9McKF7NBi6ACAyUXO6F/bl9w6v4MY307y5Ag== + optionalDependencies: + "@types/geojson" "^1.0.0" + +terser-webpack-plugin@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.1.0.tgz#cf7c25a1eee25bf121f4a587bb9e004e3f80e528" + integrity sha512-61lV0DSxMAZ8AyZG7/A4a3UPlrbOBo8NIQ4tJzLPAdGOQ+yoNC7l5ijEow27lBAL2humer01KLS6bGIMYQxKoA== + dependencies: + cacache "^11.0.2" + find-cache-dir "^2.0.0" + schema-utils "^1.0.0" + serialize-javascript "^1.4.0" + source-map "^0.6.1" + terser "^3.8.1" + webpack-sources "^1.1.0" + worker-farm "^1.5.2" + +terser@^3.8.1: + version "3.10.12" + resolved "https://registry.yarnpkg.com/terser/-/terser-3.10.12.tgz#06d40765e40b33fd97977c0896c75b2b5d42142d" + integrity sha512-3ODPC1eVt25EVNb04s/PkHxOmzKBQUF6bwwuR6h2DbEF8/j265Y1UkwNtOk9am/pRxfJ5HPapOlUlO6c16mKQQ== + dependencies: + commander "~2.17.1" + source-map "~0.6.1" + source-map-support "~0.5.6" + +test-exclude@^4.2.1: + version "4.2.3" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.2.3.tgz#a9a5e64474e4398339245a0a769ad7c2f4a97c20" + integrity sha512-SYbXgY64PT+4GAL2ocI3HwPa4Q4TBKm0cwAVeKOt/Aoc0gSpNRjJX8w0pA1LMKZ3LBmd8pYBqApFNQLII9kavA== + dependencies: + arrify "^1.0.1" + micromatch "^2.3.11" + object-assign "^4.1.0" + read-pkg-up "^1.0.1" + require-main-filename "^1.0.1" + +text-extensions@^1.0.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26" + integrity sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ== + +text-hex@1.0.x: + version "1.0.0" + resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5" + integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg== + +text-table@^0.2.0, text-table@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +then-fs@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/then-fs/-/then-fs-2.0.0.tgz#72f792dd9d31705a91ae19ebfcf8b3f968c81da2" + integrity sha1-cveS3Z0xcFqRrhnr/Piz+WjIHaI= + dependencies: + promise ">=3.2 <8" + +thirty-two@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/thirty-two/-/thirty-two-1.0.2.tgz#4ca2fffc02a51290d2744b9e3f557693ca6b627a" + integrity sha1-TKL//AKlEpDSdEueP1V2k8prYno= + +throat@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" + integrity sha1-iQN8vJLFarGJJua6TLsgDhVnKmo= + +through2@^2.0.0, through2@^2.0.2: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +through@2, "through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +thunkify@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/thunkify/-/thunkify-2.1.2.tgz#faa0e9d230c51acc95ca13a361ac05ca7e04553d" + integrity sha1-+qDp0jDFGsyVyhOjYawFyn4EVT0= + +timed-out@^4.0.0, timed-out@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= + +timers-browserify@^2.0.4: + version "2.0.10" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.10.tgz#1d28e3d2aadf1d5a5996c4e9f95601cd053480ae" + integrity sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg== + dependencies: + setimmediate "^1.0.4" + +timezone-support@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/timezone-support/-/timezone-support-1.8.0.tgz#b0498940df10c2c950c3f1fc65a291757aeb6d90" + integrity sha512-eGoH5aDwLOqgTzCRzpBJMuGgqEMn7SJz7wbHf8T8ADwxH9t24HT8aLIw+WksPIFe7Ou561cx9GEsBa6vuSEf7g== + dependencies: + commander "2.19.0" + +tiny-glob@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/tiny-glob/-/tiny-glob-0.2.3.tgz#9dba7fe22b1e4e2e7bb59815b10152bdf3d085b4" + integrity sha512-pkCxlClaL6MznxrgW4D2VDk5w6hz3SEOtXcJ9CPhxLjhpsvTd1g3qkMAqxoJNjKsCQlJj6w485ij5d5/Fb9jUQ== + dependencies: + globalyzer "^0.1.0" + globrex "^0.1.1" + +tiny-secp256k1@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tiny-secp256k1/-/tiny-secp256k1-1.0.1.tgz#fc6f96529c22b92be91e12de4040fdd9245f7835" + integrity sha512-Wz2kMPWtCI5XBftFeF3bUL8uz2+VlasniKwOkRPjvL7h1QVd9rbhrve/HWUu747kJKzVf1XHonzcdM4Ut8fvww== + dependencies: + bindings "^1.3.0" + bn.js "^4.11.8" + create-hmac "^1.1.7" + elliptic "^6.4.0" + nan "^2.10.0" + +tmp@0.0.33, tmp@0.0.x, tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +tmpl@1.0.x: + version "1.0.4" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" + integrity sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE= + +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= + +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + integrity sha1-uDVx+k2MJbguIxsG46MFXeTKGkc= + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +toml@^2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/toml/-/toml-2.3.3.tgz#8d683d729577cb286231dfc7a8affe58d31728fb" + integrity sha512-O7L5hhSQHxuufWUdcTRPfuTh3phKfAZ/dqfxZFoxPCj2RYmpaSGLEIs016FCXItQwNr08yefUB5TSjzRYnajTA== + +topo@2.x.x: + version "2.0.2" + resolved "https://registry.yarnpkg.com/topo/-/topo-2.0.2.tgz#cd5615752539057c0dc0491a621c3bc6fbe1d182" + integrity sha1-zVYVdSU5BXwNwEkaYhw7xvvh0YI= + dependencies: + hoek "4.x.x" + +topo@3.x.x: + version "3.0.3" + resolved "https://registry.yarnpkg.com/topo/-/topo-3.0.3.tgz#d5a67fb2e69307ebeeb08402ec2a2a6f5f7ad95c" + integrity sha512-IgpPtvD4kjrJ7CRA3ov2FhWQADwv+Tdqbsf1ZnPUSAtCJ9e1Z44MmoSGDXGk4IppoZA7jd/QRkNddlLJWlUZsQ== + dependencies: + hoek "6.x.x" + +toposort-class@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toposort-class/-/toposort-class-1.0.1.tgz#7ffd1f78c8be28c3ba45cd4e1a3f5ee193bd9988" + integrity sha1-f/0feMi+KMO6Rc1OGj9e4ZO9mYg= + +tough-cookie@>=2.3.3, tough-cookie@^2.3.4, tough-cookie@~2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" + integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ== + dependencies: + psl "^1.1.24" + punycode "^1.4.1" + +tough-cookie@~2.3.0: + version "2.3.4" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" + integrity sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA== + dependencies: + punycode "^1.4.1" + +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= + dependencies: + punycode "^2.1.0" + +trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + integrity sha1-WIeWa7WCpFA6QetST301ARgVphM= + +trim-newlines@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-2.0.0.tgz#b403d0b91be50c331dfc4b82eeceb22c3de16d20" + integrity sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA= + +trim-off-newlines@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz#9f9ba9d9efa8764c387698bcbfeb2c848f11adb3" + integrity sha1-n5up2e+odkw4dpi8v+sshI8RrbM= + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= + +triple-beam@^1.2.0, triple-beam@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9" + integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw== + +tslib@^1, tslib@^1.9.0, tslib@^1.9.3: + version "1.9.3" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" + integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== + +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + integrity sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY= + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tunnel-agent@~0.4.1: + version "0.4.3" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb" + integrity sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us= + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +type-is@~1.6.16: + version "1.6.16" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" + integrity sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.18" + +typechecker@^4.0.1, typechecker@^4.3.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/typechecker/-/typechecker-4.6.0.tgz#d245d9c2df21147d5e2a942fff170b68ece73c87" + integrity sha512-83OrXpyP3LNr7aRbLkt2nkjE/d7q8su8/uRvrKxCpswqVCVGOgyaKpaz8/MTjQqBYe4eLNuJ44pNakFZKqyPMA== + dependencies: + editions "^2.0.2" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + +typeforce@^1.11.5: + version "1.16.0" + resolved "https://registry.yarnpkg.com/typeforce/-/typeforce-1.16.0.tgz#060f871420f4ed90d411e0606bebc62a0889ad55" + integrity sha512-V60F7OHPH7vPlgIU73vYyeebKxWjQqCTlge+MvKlVn09PIhCOi/ZotowYdgREHB5S1dyHOr906ui6NheYXjlVQ== + +uglify-js@^3.1.4: + version "3.4.9" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.9.tgz#af02f180c1207d76432e473ed24a28f4a782bae3" + integrity sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q== + dependencies: + commander "~2.17.1" + source-map "~0.6.1" + +uid-number@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" + integrity sha1-DqEOgDXo61uOREnwbaHHMGY7qoE= + +umask@^1.1.0, umask@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/umask/-/umask-1.1.0.tgz#f29cebf01df517912bb58ff9c4e50fde8e33320d" + integrity sha1-8pzr8B31F5ErtY/5xOUP3o4zMg0= + +umzug@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/umzug/-/umzug-2.2.0.tgz#6160bdc1817e4a63a625946775063c638623e62e" + integrity sha512-xZLW76ax70pND9bx3wqwb8zqkFGzZIK8dIHD9WdNy/CrNfjWcwQgQkGCuUqcuwEBvUm+g07z+qWvY+pxDmMEEw== + dependencies: + babel-runtime "^6.23.0" + bluebird "^3.5.3" + +undefsafe@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.2.tgz#225f6b9e0337663e0d8e7cfd686fc2836ccace76" + integrity sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY= + dependencies: + debug "^2.2.0" + +unicode-canonical-property-names-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" + integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== + +unicode-match-property-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" + integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== + dependencies: + unicode-canonical-property-names-ecmascript "^1.0.4" + unicode-property-aliases-ecmascript "^1.0.4" + +unicode-match-property-value-ecmascript@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.0.2.tgz#9f1dc76926d6ccf452310564fd834ace059663d4" + integrity sha512-Rx7yODZC1L/T8XKo/2kNzVAQaRE88AaMvI1EF/Xnj3GW2wzN6fop9DDWuFAKUVFH7vozkz26DzP0qyWLKLIVPQ== + +unicode-property-aliases-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.4.tgz#5a533f31b4317ea76f17d807fa0d116546111dd0" + integrity sha512-2WSLa6OdYd2ng8oqiGIWnJqyFArvhn+5vgx5GTxMbUYjCYKUcuKS62YLFF0R/BDGlB1yzXjQOLtPAfHsgirEpg== + +union-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" + integrity sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ= + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^0.4.3" + +unique-filename@^1.1.0, unique-filename@^1.1.1, unique-filename@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + +unique-random-array@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/unique-random-array/-/unique-random-array-1.0.1.tgz#f29bda2a62be8860a703c4739c8f4fdb4d722cc7" + integrity sha512-z9J/SV8CUIhIRROcHe9YUoAT6XthUJt0oUyLGgobiXJprDP9O9dsErNevvSaAv5BkhwFEVPn6nIEOKeNE6Ck1Q== + dependencies: + unique-random "^1.0.0" + +unique-random@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unique-random/-/unique-random-1.0.0.tgz#ce3e224c8242cd33a0e77b0d7180d77e6b62d0c4" + integrity sha1-zj4iTIJCzTOg53sNcYDXfmti0MQ= + +unique-slug@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.1.tgz#5e9edc6d1ce8fb264db18a507ef9bd8544451ca6" + integrity sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg== + dependencies: + imurmurhash "^0.1.4" + +unique-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" + integrity sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo= + dependencies: + crypto-random-string "^1.0.0" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +unorm@^1.3.3: + version "1.4.1" + resolved "https://registry.yarnpkg.com/unorm/-/unorm-1.4.1.tgz#364200d5f13646ca8bcd44490271335614792300" + integrity sha1-NkIA1fE2RsqLzURJAnEzVhR5IwA= + +unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +unzip-response@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unzip-response/-/unzip-response-2.0.1.tgz#d2f0f737d16b0615e72a6935ed04214572d56f97" + integrity sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c= + +upath@^1.0.5: + version "1.1.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" + integrity sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw== + +update-notifier@^2.2.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-2.5.0.tgz#d0744593e13f161e406acb1d9408b72cad08aff6" + integrity sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw== + dependencies: + boxen "^1.2.1" + chalk "^2.0.1" + configstore "^3.0.0" + import-lazy "^2.1.0" + is-ci "^1.0.10" + is-installed-globally "^0.1.0" + is-npm "^1.0.0" + latest-version "^3.0.0" + semver-diff "^2.0.0" + xdg-basedir "^3.0.0" + +upper-case@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" + integrity sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg= + +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= + dependencies: + prepend-http "^1.0.1" + +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= + dependencies: + prepend-http "^2.0.0" + +url-parse@^1.2.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.4.tgz#cac1556e95faa0303691fec5cf9d5a1bc34648f8" + integrity sha512-/92DTTorg4JjktLNLe6GPS2/RvAd/RGr6LuktmWSMLEOa6rjnlrFXNgSbSmkNvCoL2T028A0a1JaJLzRMlFoHg== + dependencies: + querystringify "^2.0.0" + requires-port "^1.0.0" + +url-to-options@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" + integrity sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k= + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +urlgrey@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/urlgrey/-/urlgrey-0.4.4.tgz#892fe95960805e85519f1cd4389f2cb4cbb7652f" + integrity sha1-iS/pWWCAXoVRnxzUOJ8stMu3ZS8= + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +useragent@^2.2.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/useragent/-/useragent-2.3.0.tgz#217f943ad540cb2128658ab23fc960f6a88c9972" + integrity sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw== + dependencies: + lru-cache "4.1.x" + tmp "0.0.x" + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +util-extend@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/util-extend/-/util-extend-1.0.3.tgz#a7c216d267545169637b3b6edc6ca9119e2ff93f" + integrity sha1-p8IW0mdUUWljeztu3GypEZ4v+T8= + +util.promisify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" + integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== + dependencies: + define-properties "^1.1.2" + object.getownpropertydescriptors "^2.0.3" + +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity sha1-evsa/lCAUkZInj23/g7TeTNqwPk= + dependencies: + inherits "2.0.1" + +util@^0.10.3: + version "0.10.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" + integrity sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A== + dependencies: + inherits "2.0.3" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= + +uuid@^3.0.1, uuid@^3.1.0, uuid@^3.2.1, uuid@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" + integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== + +v8-compile-cache@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.2.tgz#a428b28bb26790734c4fc8bc9fa106fccebf6a6c" + integrity sha512-1wFuMUIM16MDJRCrpbpuEPTUGmM5QMUg0cr3KFwra2XgOgFcPGDQHDh3CszSCD2Zewc/dh/pamNEW8CbfDebUw== + +validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.3: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +validate-npm-package-name@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" + integrity sha1-X6kS2B630MdK/BQN5zF/DKffQ34= + dependencies: + builtins "^1.0.3" + +validate-npm-package-name@~2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-2.2.2.tgz#f65695b22f7324442019a3c7fa39a6e7fd299085" + integrity sha1-9laVsi9zJEQgGaPH+jmm5/0pkIU= + dependencies: + builtins "0.0.7" + +validator@^10.4.0: + version "10.9.0" + resolved "https://registry.yarnpkg.com/validator/-/validator-10.9.0.tgz#d10c11673b5061fb7ccf4c1114412411b2bac2a8" + integrity sha512-hZJcZSWz9poXBlAkjjcsNAdrZ6JbjD3kWlNjq/+vE7RLLS/+8PAj3qVVwrwsOz/WL8jPmZ1hYkRvtlUeZAm4ug== + +vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vise@3.x.x: + version "3.0.2" + resolved "https://registry.yarnpkg.com/vise/-/vise-3.0.2.tgz#9a8b7450f783aa776faa327fe47d7bfddb227266" + integrity sha512-X52VtdRQbSBXdjcazRiY3eRgV3vTQ0B+7Wh8uC9cVv7lKfML5m9+9NHlbcgCY0R9EAqD1v/v7o9mhGh2A3ANFg== + dependencies: + hoek "6.x.x" + +vision@^5.4.3: + version "5.4.3" + resolved "https://registry.yarnpkg.com/vision/-/vision-5.4.3.tgz#648663667f22dc6da17a00c049c2c1a97366d72f" + integrity sha512-4uVrdAKSjNF3WVf1Mjq//SfMclUgpHJtk0EBESyLFcZmrqJjUQ08DyCsRYqw31qEFK3bVm8UO9BlfodRwuyETg== + dependencies: + boom "7.x.x" + hoek "6.x.x" + items "2.x.x" + joi "14.x.x" + +vm-browserify@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" + integrity sha1-XX6kW7755Kb/ZflUOOCofDV9WnM= + dependencies: + indexof "0.0.1" + +vscode-languageserver-types@^3.5.0: + version "3.13.0" + resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.13.0.tgz#b704b024cef059f7b326611c99b9c8753c0a18b4" + integrity sha512-BnJIxS+5+8UWiNKCP7W3g9FlE7fErFw0ofP5BXJe7c2tl0VeWh+nNHFbwAS2vmVC4a5kYxHBjRy0UeOtziemVA== + +w3c-hr-time@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045" + integrity sha1-gqwr/2PZUOqeMYmlimViX+3xkEU= + dependencies: + browser-process-hrtime "^0.1.2" + +walkdir@0.0.11: + version "0.0.11" + resolved "https://registry.yarnpkg.com/walkdir/-/walkdir-0.0.11.tgz#a16d025eb931bd03b52f308caed0f40fcebe9532" + integrity sha1-oW0CXrkxvQO1LzCMrtD0D86+lTI= + +walker@~1.0.5: + version "1.0.7" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" + integrity sha1-L3+bj9ENZ3JisYqITijRlhjgKPs= + dependencies: + makeerror "1.0.x" + +watch@~0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/watch/-/watch-0.18.0.tgz#28095476c6df7c90c963138990c0a5423eb4b986" + integrity sha1-KAlUdsbffJDJYxOJkMClQj60uYY= + dependencies: + exec-sh "^0.2.0" + minimist "^1.2.0" + +watchpack@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" + integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA== + dependencies: + chokidar "^2.0.2" + graceful-fs "^4.1.2" + neo-async "^2.5.0" + +wcwidth@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" + integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= + dependencies: + defaults "^1.0.3" + +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== + +webpack-cli@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.1.2.tgz#17d7e01b77f89f884a2bbf9db545f0f6a648e746" + integrity sha512-Cnqo7CeqeSvC6PTdts+dywNi5CRlIPbLx1AoUPK2T6vC1YAugMG3IOoO9DmEscd+Dghw7uRlnzV1KwOe5IrtgQ== + dependencies: + chalk "^2.4.1" + cross-spawn "^6.0.5" + enhanced-resolve "^4.1.0" + global-modules-path "^2.3.0" + import-local "^2.0.0" + interpret "^1.1.0" + loader-utils "^1.1.0" + supports-color "^5.5.0" + v8-compile-cache "^2.0.2" + yargs "^12.0.2" + +webpack-merge@^4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.1.4.tgz#0fde38eabf2d5fd85251c24a5a8c48f8a3f4eb7b" + integrity sha512-TmSe1HZKeOPey3oy1Ov2iS3guIZjWvMT2BBJDzzT5jScHTjVC3mpjJofgueEzaEd6ibhxRDD6MIblDr8tzh8iQ== + dependencies: + lodash "^4.17.5" + +webpack-node-externals@^1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/webpack-node-externals/-/webpack-node-externals-1.7.2.tgz#6e1ee79ac67c070402ba700ef033a9b8d52ac4e3" + integrity sha512-ajerHZ+BJKeCLviLUUmnyd5B4RavLF76uv3cs6KNuO8W+HuQaEs0y0L7o40NQxdPy5w0pcv8Ew7yPUAQG0UdCg== + +webpack-sources@^1.1.0, webpack-sources@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.3.0.tgz#2a28dcb9f1f45fe960d8f1493252b5ee6530fa85" + integrity sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack@^4.26.1: + version "4.26.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.26.1.tgz#ff3a9283d363c07b3494dfa702d08f4f2ef6cb39" + integrity sha512-i2oOvEvuvLLSuSCkdVrknaxAhtUZ9g+nLSoHCWV0gDzqGX2DXaCrMmMUpbRsTSSLrUqAI56PoEiyMUZIZ1msug== + dependencies: + "@webassemblyjs/ast" "1.7.11" + "@webassemblyjs/helper-module-context" "1.7.11" + "@webassemblyjs/wasm-edit" "1.7.11" + "@webassemblyjs/wasm-parser" "1.7.11" + acorn "^5.6.2" + acorn-dynamic-import "^3.0.0" + ajv "^6.1.0" + ajv-keywords "^3.1.0" + chrome-trace-event "^1.0.0" + enhanced-resolve "^4.1.0" + eslint-scope "^4.0.0" + json-parse-better-errors "^1.0.2" + loader-runner "^2.3.0" + loader-utils "^1.1.0" + memory-fs "~0.4.1" + micromatch "^3.1.8" + mkdirp "~0.5.0" + neo-async "^2.5.0" + node-libs-browser "^2.0.0" + schema-utils "^0.4.4" + tapable "^1.1.0" + terser-webpack-plugin "^1.1.0" + watchpack "^1.5.0" + webpack-sources "^1.3.0" + +whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: + version "1.0.5" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" + integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== + dependencies: + iconv-lite "0.4.24" + +whatwg-mimetype@^2.1.0, whatwg-mimetype@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" + integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== + +whatwg-url@^6.4.1: + version "6.5.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8" + integrity sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +whatwg-url@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.0.0.tgz#fde926fa54a599f3adf82dff25a9f7be02dc6edd" + integrity sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which@1, which@^1.2.10, which@^1.2.12, which@^1.2.9, which@^1.3.0, which@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +which@~1.2.11: + version "1.2.14" + resolved "https://registry.yarnpkg.com/which/-/which-1.2.14.tgz#9a87c4378f03e827cecaf1acdf56c736c01c14e5" + integrity sha1-mofEN48D6CfOyvGs31bHNsAcFOU= + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + +widest-line@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" + integrity sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA== + dependencies: + string-width "^2.1.1" + +wif@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/wif/-/wif-2.0.6.tgz#08d3f52056c66679299726fade0d432ae74b4704" + integrity sha1-CNP1IFbGZnkplyb63g1DKudLRwQ= + dependencies: + bs58check "<3.0.0" + +win-release@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/win-release/-/win-release-1.1.1.tgz#5fa55e02be7ca934edfc12665632e849b72e5209" + integrity sha1-X6VeAr58qTTt/BJmVjLoSbcuUgk= + dependencies: + semver "^5.0.1" + +window-size@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.4.tgz#f8e1aa1ee5a53ec5bf151ffa09742a6ad7697876" + integrity sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY= + +winston-compat@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/winston-compat/-/winston-compat-0.1.4.tgz#599b4ce807ffe728713ecc25ede3f6b89425b739" + integrity sha512-mMEfFsSm6GmkFF+f4/0UJtG4N1vSaczGmXLVJYmS/+u2zUaIPcw2ZRuwUg2TvVBjswgiraN+vNnAG8z4fRUZ4w== + dependencies: + cycle "~1.0.3" + logform "^1.6.0" + triple-beam "^1.2.0" + +winston-daily-rotate-file@^3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/winston-daily-rotate-file/-/winston-daily-rotate-file-3.5.1.tgz#38249976dc5326afa7f3a1e4a39a8211f349e2fe" + integrity sha512-Y5CECbcJro55HWcWJSzI1DiQrbrfwwvKHdCCJn9wWsWCGfnCPDl5SWIokS2M0EvOKtbZUrlm5DPG522mvjdUBQ== + dependencies: + file-stream-rotator "^0.4.1" + object-hash "^1.3.0" + semver "^5.6.0" + triple-beam "^1.3.0" + winston-compat "^0.1.4" + winston-transport "^4.2.0" + +winston-transport@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.2.0.tgz#a20be89edf2ea2ca39ba25f3e50344d73e6520e5" + integrity sha512-0R1bvFqxSlK/ZKTH86nymOuKv/cT1PQBMuDdA7k7f0S9fM44dNH6bXnuxwXPrN8lefJgtZq08BKdyZ0DZIy/rg== + dependencies: + readable-stream "^2.3.6" + triple-beam "^1.2.0" + +winston@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/winston/-/winston-3.1.0.tgz#80724376aef164e024f316100d5b178d78ac5331" + integrity sha512-FsQfEE+8YIEeuZEYhHDk5cILo1HOcWkGwvoidLrDgPog0r4bser1lEIOco2dN9zpDJ1M88hfDgZvxe5z4xNcwg== + dependencies: + async "^2.6.0" + diagnostics "^1.1.1" + is-stream "^1.1.0" + logform "^1.9.1" + one-time "0.0.4" + readable-stream "^2.3.6" + stack-trace "0.0.x" + triple-beam "^1.3.0" + winston-transport "^4.2.0" + +wkx@^0.4.1: + version "0.4.5" + resolved "https://registry.yarnpkg.com/wkx/-/wkx-0.4.5.tgz#a85e15a6e69d1bfaec2f3c523be3dfa40ab861d0" + integrity sha512-01dloEcJZAJabLO5XdcRgqdKpmnxS0zIT02LhkdWOZX2Zs2tPM6hlZ4XG9tWaWur1Qd1OO4kJxUbe2+5BofvnA== + dependencies: + "@types/node" "*" + +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= + +wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= + +worker-farm@^1.5.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.6.0.tgz#aecc405976fab5a95526180846f0dba288f3a4a0" + integrity sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ== + dependencies: + errno "~0.1.7" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrap-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-3.0.1.tgz#288a04d87eda5c286e060dfe8f135ce8d007f8ba" + integrity sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo= + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + +wrappy@1, wrappy@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +wreck@14.x.x, wreck@^14.0.2: + version "14.1.3" + resolved "https://registry.yarnpkg.com/wreck/-/wreck-14.1.3.tgz#d4db8258b38a568c363ef7d23034c4db598a9213" + integrity sha512-hb/BUtjX3ObbwO3slCOLCenQ4EP8e+n8j6FmTne3VhEFp5XV1faSJojiyxVSvw34vgdeTG5baLTl4NmjwokLlw== + dependencies: + boom "7.x.x" + hoek "6.x.x" + +write-file-atomic@^2.0.0, write-file-atomic@^2.1.0, write-file-atomic@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" + integrity sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA== + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + +write-file-atomic@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.2.0.tgz#14c66d4e4cb3ca0565c28cf3b7a6f3e4d5938fab" + integrity sha1-FMZtTkyzygVlwozzt6bz5NWTj6s= + dependencies: + graceful-fs "^4.1.2" + imurmurhash "^0.1.4" + slide "^1.1.5" + +write-json-file@^2.2.0, write-json-file@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-2.3.0.tgz#2b64c8a33004d54b8698c76d585a77ceb61da32f" + integrity sha1-K2TIozAE1UuGmMdtWFp3zrYdoy8= + dependencies: + detect-indent "^5.0.0" + graceful-fs "^4.1.2" + make-dir "^1.0.0" + pify "^3.0.0" + sort-keys "^2.0.0" + write-file-atomic "^2.0.0" + +write-pkg@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/write-pkg/-/write-pkg-3.2.0.tgz#0e178fe97820d389a8928bc79535dbe68c2cff21" + integrity sha512-tX2ifZ0YqEFOF1wjRW2Pk93NLsj02+n1UP5RvO6rCs0K6R2g1padvf006cY74PQJKMGS2r42NK7FD0dG6Y6paw== + dependencies: + sort-keys "^2.0.0" + write-json-file "^2.2.0" + +write@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" + integrity sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c= + dependencies: + mkdirp "^0.5.1" + +ws@^5.2.0: + version "5.2.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" + integrity sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA== + dependencies: + async-limiter "~1.0.0" + +ws@^6.0.0: + version "6.1.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.1.2.tgz#3cc7462e98792f0ac679424148903ded3b9c3ad8" + integrity sha512-rfUqzvz0WxmSXtJpPMX2EeASXabOrSMk1ruMOV3JBTBjo4ac2lDjGGsbQSyxj8Odhw5fBib8ZKEjDNvgouNKYw== + dependencies: + async-limiter "~1.0.0" + +xcase@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/xcase/-/xcase-2.0.1.tgz#c7fa72caa0f440db78fd5673432038ac984450b9" + integrity sha1-x/pyyqD0QNt4/VZzQyA4rJhEULk= + +xdg-basedir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" + integrity sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ= + +xml-name-validator@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== + +xml2js@^0.4.17: + version "0.4.19" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.19.tgz#686c20f213209e94abf0d1bcf1efaa291c7827a7" + integrity sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q== + dependencies: + sax ">=0.6.0" + xmlbuilder "~9.0.1" + +xmlbuilder@~9.0.1: + version "9.0.7" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" + integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= + +xregexp@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/xregexp/-/xregexp-2.0.0.tgz#52a63e56ca0b84a7f3a5f3d61872f126ad7a5943" + integrity sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM= + +xstate@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/xstate/-/xstate-4.1.2.tgz#588bd4efee695ff15ac96e9074848d9566e2aceb" + integrity sha512-YjCpT+si6QfKTX5o7evf1/FvBUeSfvUxz7Eay/SlGFBtPm1ZSeCH4MGuTSgTtRaw63m40MbMj6jc+OF8JuQorg== + +xtend@^4.0.0, xtend@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= + +y18n@^3.2.0, y18n@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= + +"y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + +yallist@^3.0.0, yallist@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" + integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== + +yargs-parser@^11.1.1: + version "11.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-11.1.1.tgz#879a0865973bca9f6bab5cbdf3b1c67ec7d3bcf4" + integrity sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs-parser@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9" + integrity sha1-jQrELxbqVd69MyyvTEA4s+P139k= + dependencies: + camelcase "^4.1.0" + +yargs-parser@^9.0.2: + version "9.0.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077" + integrity sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc= + dependencies: + camelcase "^4.1.0" + +yargs@^11.0.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.1.0.tgz#90b869934ed6e871115ea2ff58b03f4724ed2d77" + integrity sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A== + dependencies: + cliui "^4.0.0" + decamelize "^1.1.1" + find-up "^2.1.0" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1" + yargs-parser "^9.0.2" + +yargs@^12.0.1, yargs@^12.0.2: + version "12.0.5" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13" + integrity sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw== + dependencies: + cliui "^4.0.0" + decamelize "^1.2.0" + find-up "^3.0.0" + get-caller-file "^1.0.1" + os-locale "^3.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1 || ^4.0.0" + yargs-parser "^11.1.1" + +yargs@^3.19.0: + version "3.32.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.32.0.tgz#03088e9ebf9e756b69751611d2a5ef591482c995" + integrity sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU= + dependencies: + camelcase "^2.0.1" + cliui "^3.0.3" + decamelize "^1.1.1" + os-locale "^1.4.0" + string-width "^1.0.1" + window-size "^0.1.4" + y18n "^3.2.0" + +yargs@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.2.tgz#6299a9055b1cefc969ff7e79c1d918dceb22c360" + integrity sha1-YpmpBVsc78lp/355wdkY3Osiw2A= + dependencies: + camelcase "^4.1.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + read-pkg-up "^2.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1" + yargs-parser "^7.0.0" + +zen-observable-ts@^0.8.11: + version "0.8.11" + resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.11.tgz#d54a27cd17dc4b4bb6bd008e5c096af7fcb068a9" + integrity sha512-8bs7rgGV4kz5iTb9isudkuQjtWwPnQ8lXq6/T76vrepYZVMsDEv6BXaEA+DHdJSK3KVLduagi9jSpSAJ5NgKHw== + dependencies: + zen-observable "^0.8.0" + +zen-observable@^0.8.0: + version "0.8.11" + resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.11.tgz#d3415885eeeb42ee5abb9821c95bb518fcd6d199" + integrity sha512-N3xXQVr4L61rZvGMpWe8XoCGX8vhU35dPyQ4fm5CY/KDlG0F75un14hjbckPXTDuKUY6V0dqR2giT6xN8Y4GEQ==