Compare commits
469 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2bc18837ee | |||
| 0c25e25efa | |||
| 96dc2a3b7d | |||
| 8c158b00cf | |||
| 3f26ef3dbb | |||
| cb66494871 | |||
| 956989557b | |||
| 1d7371ab71 | |||
| 75186ddaf1 | |||
| 7c0c187841 | |||
| ba01979cfe | |||
| 4466df5d1a | |||
| 451bd18f44 | |||
| 27c497ecfa | |||
| c96818908d | |||
| de9a42bc02 | |||
| 13759e4314 | |||
| 9a347615b4 | |||
| d3af0322c8 | |||
| 65639a2372 | |||
| 2a2912e907 | |||
| e65bebae11 | |||
| a60c0f2c1e | |||
| f0c45826b9 | |||
| 97bf46bd82 | |||
| 49e591ee55 | |||
| 11b87d37b6 | |||
| 82cf383b71 | |||
| 470f0be873 | |||
| 3c72b0919d | |||
| 38d7e835d5 | |||
| 1d865d5c5d | |||
| b9e7c21cac | |||
| 448d4a629f | |||
| 62ee9b2ac7 | |||
| 6d0c91c6a4 | |||
| 73876475ea | |||
| 7d14977702 | |||
| 9cdf8db87a | |||
| 68c1497e74 | |||
| a7df9fb826 | |||
| c570b6e4c4 | |||
| 884d944937 | |||
| 5711353471 | |||
| bd8fe99594 | |||
| 9cfea6bb72 | |||
| 6825b743b6 | |||
| 12fc936075 | |||
| 2e5bd27e1b | |||
| a3420a27c0 | |||
| 7212ca8397 | |||
| c1366bad75 | |||
| ba273f96d1 | |||
| 03ce188b96 | |||
| 8633c19792 | |||
| 7eb46ece9d | |||
| 862817bbe3 | |||
| 917a17b392 | |||
| 3f26e0d518 | |||
| 139a3b85e8 | |||
| b82382fc5e | |||
| 67b1da2c82 | |||
| fc0e57ca57 | |||
| 13ad1445e5 | |||
| 4c127a4d39 | |||
| 03a56359da | |||
| 6afb85fd57 | |||
| 2c95cfbcf5 | |||
| 8552dbf31e | |||
| f545aad172 | |||
| 5e68b54610 | |||
| 1e79521ccc | |||
| 18ef675b88 | |||
| 0947f43b38 | |||
| 0d5d438378 | |||
| e678678fef | |||
| 0eaba697eb | |||
| 80bd4adc8c | |||
| 81ae93b1bd | |||
| 49d3b3434c | |||
| 350d2107fe | |||
| eda6655600 | |||
| 8ed55f003d | |||
| db3c18fdf9 | |||
| 2d58c18048 | |||
| e21e3dd314 | |||
| d854b339f9 | |||
| 3026ab9d25 | |||
| 9a7ee17508 | |||
| 41dce730db | |||
| 4bbc92d888 | |||
| b08448812e | |||
| 82f31f82ba | |||
| 2a82e5842a | |||
| f27f5ca2a9 | |||
| cc87fab9cd | |||
| 5242a757ac | |||
| d2a16e6059 | |||
| 99c43af7bf | |||
| a8452d7906 | |||
| b8104a1f0c | |||
| d3b4e75513 | |||
| 204bb63bd7 | |||
| 034dccfbab | |||
| aafd4a3d63 | |||
| cbe37827fc | |||
| aa3487b238 | |||
| c090822d3b | |||
| 0564efd4ac | |||
| cd7620c09b | |||
| c7078f6973 | |||
| 9508b34edb | |||
| 0a577ebbf3 | |||
| b9ba061967 | |||
| 9ba24d4acd | |||
| bf4d84cc1d | |||
| 10e369685a | |||
| b402f183bd | |||
| cdd39ff2f1 | |||
| 5a05b068fe | |||
| 7cea98e3fb | |||
| 1c85c2b3cd | |||
| cbefd0272d | |||
| fc57c7fb41 | |||
| 31969f0c8b | |||
| d8bad499b4 | |||
| 7e2e09af23 | |||
| f4dea4305d | |||
| 65c55c7ebb | |||
| fc1566a6c1 | |||
| 85581e288e | |||
| 35e93ef98e | |||
| 218943cfe4 | |||
| 996b36dd15 | |||
| a9f8e545b4 | |||
| 0cfac309a7 | |||
| 9d7bf75c25 | |||
| ea80bf8c92 | |||
| 417bb96294 | |||
| a5f14071d3 | |||
| 1f18f54933 | |||
| fdd75e8393 | |||
| 7223ecd8a0 | |||
| 6169d54474 | |||
| 7d3b7451ea | |||
| b7ab2f055f | |||
| 8cdd29fda9 | |||
| d67bbe9c21 | |||
| ee708a22f1 | |||
| 27141e6e89 | |||
| 0386bc7ce8 | |||
| 1f0e696308 | |||
| 1748035656 | |||
| 3b58aa28c7 | |||
| 8bffd2d1e7 | |||
| 01570f1a96 | |||
| 6e3510ebb1 | |||
| 985cd7e189 | |||
| 6853f7e897 | |||
| 28c163a500 | |||
| b7798e41f4 | |||
| 404808f1b7 | |||
| 565a34b366 | |||
| 11b7b28212 | |||
| 7ca25d6791 | |||
| fc99cc2e3f | |||
| 2bb5b801b4 | |||
| 8e1d0db9cb | |||
| 8d96e4f525 | |||
| 00f063e2e4 | |||
| d5b12d89bd | |||
| ad8a3bedb7 | |||
| 20a0b1d4a2 | |||
| d13e186fdc | |||
| 50400787f1 | |||
| b451619555 | |||
| b82dddac7b | |||
| f372f792e5 | |||
| d6533332c6 | |||
| 96d9a5aca0 | |||
| f2c8b9bdf9 | |||
| d122d79022 | |||
| aab5c66c89 | |||
| 4f0d7b18f3 | |||
| e6d66181e1 | |||
| 4ac735dd73 | |||
| 341769d92a | |||
| c7a841e6cd | |||
| 71831f0948 | |||
| ca2ae004f2 | |||
| 908a0e5636 | |||
| aaada8cfb7 | |||
| c721eea8a6 | |||
| 769d942fc5 | |||
| d44be3b2ee | |||
| 888171efe6 | |||
| c3acca1516 | |||
| 02472751a5 | |||
| 27dd37bb4c | |||
| 61d9309a2d | |||
| 3a7d422445 | |||
| 64452c8cd6 | |||
| e91ece0a39 | |||
| c53ef3ee61 | |||
| 86c00f68b5 | |||
| 3a3e6acd7a | |||
| ceecc977e2 | |||
| ba637daa14 | |||
| ba18937cd5 | |||
| 3bf0226c8e | |||
| 9b990926c3 | |||
| 163f68f795 | |||
| b6ae493894 | |||
| 40cffc34fb | |||
| 40f01c6783 | |||
| c3447674e6 | |||
| df9697f8fa | |||
| 135a4152f0 | |||
| 11614daa3a | |||
| 627d889f78 | |||
| a2c2c4cf8a | |||
| 89aa03bdba | |||
| 01fd572376 | |||
| 5b351452f8 | |||
| ac8872bf22 | |||
| e065c1c6ef | |||
| 64548cf3e1 | |||
| 2fbc9ecda4 | |||
| eae3f16b44 | |||
| 2129945d4d | |||
| 6cd4a4d315 | |||
| e562fb3104 | |||
| 8214a4ad82 | |||
| fabcc5e96c | |||
| 41eab518e0 | |||
| d6d1c05bbf | |||
| 50fe19bce1 | |||
| 61a81e68e8 | |||
| 5b54b043f6 | |||
| a186d63b6d | |||
| d48c439dfb | |||
| 1409453556 | |||
| a633142e3d | |||
| 73cca21fae | |||
| d261cd4bc1 | |||
| 47e833a92e | |||
| 953633dd33 | |||
| a183eb420a | |||
| fe3692b387 | |||
| 983673d775 | |||
| dd6594a6d5 | |||
| 40ce288d20 | |||
| da0ff2f3c8 | |||
| 74ccb53358 | |||
| f498774496 | |||
| 99e957f418 | |||
| 106f45a7ee | |||
| 257c26d7b8 | |||
| 4ff6e3d209 | |||
| f4be437bbd | |||
| c11155456c | |||
| 49ef6696ca | |||
| 0f38ca6a6f | |||
| 9ae9e420ad | |||
| 34931afbdf | |||
| cb2b8bfdef | |||
| 8d8dee60a1 | |||
| 4c9f6e80f2 | |||
| d2633cdded | |||
| 6a10502240 | |||
| 582f423a1e | |||
| 5a09572e22 | |||
| e001770045 | |||
| 4c8d625eca | |||
| d725bda2b7 | |||
| fc48586365 | |||
| 74f146ae2a | |||
| e7e60f4e51 | |||
| 59e8e51a8d | |||
| f445fc9dd0 | |||
| 64e727bbff | |||
| 0655806ab4 | |||
| b310b4327e | |||
| 5e78f79c4f | |||
| 4838379bce | |||
| 13504e3d20 | |||
| 595599294a | |||
| c5d9cf4a96 | |||
| 23cb750527 | |||
| fec31246da | |||
| c411b17431 | |||
| 94cdc6b9a5 | |||
| 26884b9c27 | |||
| a2496283e5 | |||
| 4f66e6143e | |||
| 11a93481ef | |||
| 33d93a9f60 | |||
| 5caf21d656 | |||
| f7a499cb97 | |||
| 96f00f4969 | |||
| 9aaca9bca9 | |||
| 0c272f9bb4 | |||
| 4354482e0d | |||
| 9d2aacfdfa | |||
| 64e71cce82 | |||
| 5b3fbd0eb7 | |||
| 649a584f05 | |||
| 1f4016693e | |||
| ebaaaf4bb7 | |||
| 8bfa6e1c66 | |||
| 920ad417d4 | |||
| f0366232e2 | |||
| c8ce39131e | |||
| f1ee6acdf4 | |||
| daba656a5a | |||
| f17016160b | |||
| f3c6a07ab4 | |||
| 86d618e84c | |||
| 57b71cc82e | |||
| 39c74e28dd | |||
| 13b2932a00 | |||
| df4517d90b | |||
| a996185802 | |||
| 3c0df91013 | |||
| 034c8860a2 | |||
| 4e61626858 | |||
| a64af59725 | |||
| 4a762b64bc | |||
| b018a8fc34 | |||
| 00df96e05c | |||
| d22540167b | |||
| 957ec2a0c8 | |||
| da29a1d562 | |||
| 77af9982e6 | |||
| 9624a1e860 | |||
| 60baffb2f8 | |||
| 581d43e44d | |||
| b469964370 | |||
| a1fa6d20e8 | |||
| 9dd78d4f49 | |||
| ed5fdebbd3 | |||
| 78b5647e59 | |||
| a7ea1314ab | |||
| 35630441b8 | |||
| e6091f630b | |||
| 0e3096c2ab | |||
| bf6ba4f815 | |||
| 3dbd7a3ec3 | |||
| 9d1c749670 | |||
| fc24298531 | |||
| 33b82a1d76 | |||
| 8e2d6f240f | |||
| a8b08dd1ee | |||
| 3d79a3c568 | |||
| d74cd49a78 | |||
| 756e554bfc | |||
| 206a818563 | |||
| c34e9adde0 | |||
| 80438ba8c4 | |||
| d08244d5c5 | |||
| dae915edf8 | |||
| f54b91088f | |||
| 7ab8a16895 | |||
| 1d2d20ebde | |||
| adc79b5754 | |||
| 9b9f04530d | |||
| 6b182ec9c0 | |||
| 3b3e0615c7 | |||
| 83ceee1626 | |||
| 471d60e0b3 | |||
| 185d11dbd5 | |||
| 8996203cf9 | |||
| 24b700021f | |||
| fe549376cd | |||
| 36c8183c9d | |||
| fa1b16baf7 | |||
| 2b86ac8e58 | |||
| 77baa27210 | |||
| 211a210575 | |||
| f11a108cb9 | |||
| 4fd064949a | |||
| eac9221204 | |||
| 3051b618e5 | |||
| 73e3865f7b | |||
| 05d50842e2 | |||
| 6eb90312ef | |||
| 0fe292ffef | |||
| 11d88be525 | |||
| 42e402f721 | |||
| 09c279d472 | |||
| 34c9986834 | |||
| 1f33017578 | |||
| c0fac8ba7d | |||
| 0c4000626e | |||
| 044c1b62f3 | |||
| 8e8b20c871 | |||
| 1834b6d812 | |||
| d063b46621 | |||
| 87464a6687 | |||
| 2a2904949f | |||
| bd6985d414 | |||
| 97ed78782f | |||
| 90a0359430 | |||
| 191e1cd69d | |||
| e3523e7e24 | |||
| dac4ae69bc | |||
| 51078fe4aa | |||
| 20f2a44b48 | |||
| e436e822a6 | |||
| 149e5fcecf | |||
| 43d31b950c | |||
| 511893dcda | |||
| 5f36caab08 | |||
| 9bf61f1cab | |||
| 39513f1716 | |||
| 8424329b49 | |||
| d2f095700a | |||
| 2079195f82 | |||
| 478bb57fd8 | |||
| 410526856e | |||
| 017a6e5852 | |||
| 15197ccfd7 | |||
| da0dd9a51e | |||
| cbb2b3390f | |||
| f470caad2a | |||
| 855e1355f8 | |||
| da1efd54ab | |||
| 4bff17dca4 | |||
| d3a76f45ed | |||
| eeeec411a1 | |||
| 90b9fffc4a | |||
| 952390b262 | |||
| adca13c45d | |||
| 19f2e0decd | |||
| 66e0ef9922 | |||
| ee0f8e6584 | |||
| b26dba6653 | |||
| be95e0bb5b | |||
| 7442663647 | |||
| 258bd34b2b | |||
| 8fba5569b6 | |||
| 1b3135b68e | |||
| 2085649285 | |||
| b53464c824 | |||
| 8f3ad3e6aa | |||
| 39d92b8533 | |||
| 4dd5d4b387 | |||
| a1cb97eb32 | |||
| 5b7586f870 | |||
| 3966c93b14 | |||
| 3b7ac6702f | |||
| 7b0a666211 | |||
| 901e6de4c9 | |||
| 36a19670ff | |||
| 976372aa40 | |||
| 2bdcef524a | |||
| f0b78ad063 | |||
| b8640c7dc8 | |||
| cc600263b4 | |||
| 35bbe827dc | |||
| c312850240 | |||
| 84267a0b13 | |||
| 9ee7746cd2 | |||
| 70cf9f34c4 | |||
| 2a22055870 | |||
| 8376845e49 | |||
| ea2ad7c28e | |||
| 42bd0d3992 | |||
| a9819b26ee |
+21
-94
@@ -1,9 +1,8 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
node_modules/
|
||||
.npm
|
||||
.idea
|
||||
package-lock.json
|
||||
*.tsbuildinfo
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
@@ -11,99 +10,27 @@ pids
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# TypeScript v1 declaration files
|
||||
typings/
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
|
||||
# next.js build output
|
||||
.next
|
||||
|
||||
.idea
|
||||
*.pem
|
||||
ecosystem.config.js
|
||||
package-lock.json
|
||||
connections.json
|
||||
connections.json2
|
||||
api_access.log
|
||||
api_error.log
|
||||
explorer
|
||||
api/explorer
|
||||
.ecosystem.config.js.swp
|
||||
|
||||
chains/*
|
||||
!chains/example.config.json
|
||||
# plugins
|
||||
plugins
|
||||
|
||||
api/**/*.js
|
||||
api/**/*.js.map
|
||||
api/tests
|
||||
# docker storage
|
||||
docker/redis/data
|
||||
docker/elasticsearch/data
|
||||
docker/rabbitmq/data
|
||||
docker/eosio/data
|
||||
|
||||
hyperion-explorer/
|
||||
# transpiled output
|
||||
dist
|
||||
|
||||
hyperion-launcher.js
|
||||
hyperion-launcher.js.map
|
||||
# configuration
|
||||
config
|
||||
!config/chains/example.config.json
|
||||
|
||||
launcher.js
|
||||
launcher.js.map
|
||||
# logging
|
||||
logs
|
||||
|
||||
connections/**/*.js
|
||||
connections/**/*.js.map
|
||||
|
||||
definitions/**/*.js
|
||||
definitions/**/*.js.map
|
||||
|
||||
workers/**/*.js
|
||||
workers/**/*.js.map
|
||||
|
||||
helpers/**/*.js
|
||||
helpers/**/*.js.map
|
||||
|
||||
interfaces/**/*.js
|
||||
interfaces/**/*.js.map
|
||||
|
||||
modules/**/*.js
|
||||
modules/**/*.js.map
|
||||
|
||||
addons/**/*.js
|
||||
addons/**/*.js.map
|
||||
# chain state temp files
|
||||
state
|
||||
|
||||
-195
@@ -1,195 +0,0 @@
|
||||
### nodeos config.ini
|
||||
```
|
||||
state-history-dir = "state-history"
|
||||
trace-history = true
|
||||
chain-state-history = true
|
||||
state-history-endpoint = 127.0.0.1:8080
|
||||
plugin = eosio::state_history_plugin
|
||||
```
|
||||
|
||||
### NodeJS
|
||||
|
||||
```bash
|
||||
curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash -
|
||||
sudo apt-get install -y nodejs
|
||||
```
|
||||
|
||||
### PM2
|
||||
|
||||
```bash
|
||||
sudo npm install pm2@latest -g
|
||||
sudo pm2 startup
|
||||
```
|
||||
|
||||
### Elasticsearch Installation
|
||||
|
||||
* Follow instructions on https://www.elastic.co/guide/en/elasticsearch/reference/current/deb.html (Ubuntu/Debian)
|
||||
|
||||
Edit `/etc/elasticsearch/elasticsearch.yml`
|
||||
|
||||
```
|
||||
cluster.name: myCluster
|
||||
bootstrap.memory_lock: true
|
||||
```
|
||||
|
||||
Edit `/etc/elasticsearch/jvm.options`
|
||||
```
|
||||
# Set your heap size, avoid allocating more than 31GB, even if you have enought RAM.
|
||||
# Test on your specific machine by changing -Xmx32g in the following command:
|
||||
# java -Xmx32g -XX:+UseCompressedOops -XX:+PrintFlagsFinal Oops | grep Oops
|
||||
-Xms16g
|
||||
-Xmx16g
|
||||
```
|
||||
|
||||
Disable swap on /etc/fstab
|
||||
|
||||
Allow memlock:
|
||||
run `sudo systemctl edit elasticsearch` and add the following lines
|
||||
|
||||
|
||||
```
|
||||
[Service]
|
||||
LimitMEMLOCK=infinity
|
||||
```
|
||||
|
||||
Start elasticsearch and check the logs (verify if the memory lock was successful)
|
||||
|
||||
```bash
|
||||
sudo service elasticsearch start
|
||||
sudo less /var/log/elasticsearch/myCluster.log
|
||||
sudo systemctl enable elasticsearch
|
||||
```
|
||||
|
||||
Test the REST API `curl http://localhost:9200`
|
||||
|
||||
```
|
||||
{
|
||||
"name" : "ip-172-31-5-121",
|
||||
"cluster_name" : "hyperion",
|
||||
"cluster_uuid" : "....",
|
||||
"version" : {
|
||||
"number" : "7.1.0",
|
||||
"build_flavor" : "default",
|
||||
"build_type" : "deb",
|
||||
"build_hash" : "606a173",
|
||||
"build_date" : "2019-05-16T00:43:15.323135Z",
|
||||
"build_snapshot" : false,
|
||||
"lucene_version" : "8.0.0",
|
||||
"minimum_wire_compatibility_version" : "6.8.0",
|
||||
"minimum_index_compatibility_version" : "6.0.0-beta1"
|
||||
},
|
||||
"tagline" : "You Know, for Search"
|
||||
}
|
||||
```
|
||||
|
||||
### Kibana Installation
|
||||
|
||||
```bash
|
||||
wget https://artifacts.elastic.co/downloads/kibana/kibana-7.4.0-amd64.deb
|
||||
sudo apt install ./kibana-7.4.0-amd64.deb
|
||||
sudo systemctl enable kibana
|
||||
```
|
||||
|
||||
Open and test Kibana on `http://localhost:5601`
|
||||
|
||||
### RabbitMQ Installation
|
||||
|
||||
`https://www.rabbitmq.com/install-debian.html#installation-methods`
|
||||
|
||||
```bash
|
||||
sudo apt install rabbitmq-server
|
||||
sudo rabbitmq-plugins enable rabbitmq_management
|
||||
sudo rabbitmqctl add_vhost /hyperion
|
||||
sudo rabbitmqctl add_user my_user my_password
|
||||
sudo rabbitmqctl set_user_tags my_user administrator
|
||||
sudo rabbitmqctl set_permissions -p /hyperion my_user ".*" ".*" ".*"
|
||||
```
|
||||
|
||||
Check access to the WebUI `http://localhost:15672`
|
||||
|
||||
### Redis Installation
|
||||
|
||||
```bash
|
||||
sudo apt install redis-server
|
||||
```
|
||||
|
||||
Edit `/etc/redis/redis.conf` and change supervised to `systemd`
|
||||
|
||||
```bash
|
||||
sudo systemctl restart redis.service
|
||||
```
|
||||
|
||||
### Hyperion Indexer
|
||||
|
||||
```bash
|
||||
git clone https://github.com/eosrio/Hyperion-History-API.git
|
||||
cd Hyperion-History-API
|
||||
npm install
|
||||
cp example-ecosystem.config.js ecosystem.config.js
|
||||
```
|
||||
|
||||
Edit `ecosystem.config.js`
|
||||
|
||||
|
||||
### Setup Indices and Aliases
|
||||
|
||||
Load templates first by starting the Hyperion Indexer in preview mode `PREVIEW: 'true'`
|
||||
|
||||
Indices and aliases are created automatically using the `CREATE_INDICES` option (set it to your version suffix e.g, v1, v2, v3)
|
||||
If you want to create them manually, use the commands bellow on the kibana dev console
|
||||
```
|
||||
PUT mainnet-action-v1-000001
|
||||
PUT mainnet-abi-v1-000001
|
||||
PUT mainnet-block-v1-000001
|
||||
|
||||
POST _aliases
|
||||
{
|
||||
"actions": [
|
||||
{
|
||||
"add": {
|
||||
"index": "mainnet-abi-v1-000001",
|
||||
"alias": "mainnet-abi"
|
||||
}
|
||||
},
|
||||
{
|
||||
"add": {
|
||||
"index": "mainnet-action-v1-000001",
|
||||
"alias": "mainnet-action"
|
||||
}
|
||||
},
|
||||
{
|
||||
"add": {
|
||||
"index": "mainnet-block-v1-000001",
|
||||
"alias": "mainnet-block"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Before indexing actions into elasticsearch its required to do a ABI scan pass
|
||||
|
||||
Start with
|
||||
```
|
||||
ABI_CACHE_MODE: 'true',
|
||||
FETCH_BLOCK: 'false',
|
||||
FETCH_TRACES: 'false',
|
||||
INDEX_DELTAS: 'false',
|
||||
INDEX_ALL_DELTAS: 'false',
|
||||
```
|
||||
|
||||
When indexing is finished, change the settings back and restart the indexer. In case you do not have much contract updates, you do not need to run a full pass.
|
||||
|
||||
Tune your configs to your specific hardware using the following settings:
|
||||
```
|
||||
BATCH_SIZE
|
||||
READERS
|
||||
DESERIALIZERS
|
||||
DS_MULT
|
||||
ES_IDX_QUEUES
|
||||
ES_AD_IDX_QUEUES
|
||||
READ_PREFETCH
|
||||
BLOCK_PREFETCH
|
||||
INDEX_PREFETCH
|
||||
```
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019-2022 Rio Blocks
|
||||
|
||||
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.
|
||||
@@ -1,177 +1,54 @@
|
||||
# Hyperion History API - Private
|
||||
# Hyperion History API
|
||||
|
||||
<img alt="hyperion logo" height="64" src="https://eosrio.io/hyperion.png">
|
||||
<br/>
|
||||
Scalable Full History API Solution for EOSIO based blockchains
|
||||
|
||||
Made with ♥ by [EOS Rio](https://eosrio.io/)
|
||||
|
||||
### Introducing an storage-optimized action format for EOSIO
|
||||
Official documentation: https://hyperion.docs.eosrio.io/
|
||||
|
||||
The original *history_plugin* bundled with eosio, that provided the v1 api, stored inline action traces nested inside their root actions. This led to an excessive amount of data being stored and also transferred whenever a user requested the action history for a given account. Also inline actions are used as a "event" mechanism to notify parties on a transaction. Based on those Hyperion implements some changes
|
||||
### 1. Overview
|
||||
|
||||
1. actions are stored in a flattened format
|
||||
2. a parent field is added to the inline actions to point to the parent global sequence
|
||||
3. if the inline action data is identical to the parent it is considered a notification and thus removed from the database
|
||||
4. no blocks or transaction data is stored, all information can be reconstructed from actions
|
||||
Hyperion is a full history solution for indexing, storing and retrieving EOSIO blockchain`s historical data. EOSIO protocol is highly scalable reaching up to tens of thousands of transactions per second demanding high performance indexing and optimized storage and querying solutions. Hyperion is developed to tackle those challenges providing open source software to be operated by block producers, infrastructure providers and dApp developers.
|
||||
|
||||
With those changes the API format focus on delivering faster search times, lower bandwidth overhead and easier usability for UI/UX developers.
|
||||
Focused on delivering faster search times, lower bandwidth overhead and easier usability for UI/UX developers, Hyperion implements an improved data structure
|
||||
actions are stored in a flattened format
|
||||
a parent field is added to the inline actions to point to the parent global sequence
|
||||
if the inline action data is identical to the parent it is considered a notification and thus removed from the database
|
||||
no blocks or transaction data is stored, all information can be reconstructed from actions
|
||||
|
||||
#### Action Data Structure (work in progress)
|
||||
|
||||
- `@timestamp` - block time
|
||||
- `global_sequence` - unique action global_sequence, used as index id
|
||||
- `parent` - points to the parent action (in the case of an inline action) or equal to 0 if root level
|
||||
- `block_num` - block number where the action was processed
|
||||
- `trx_id` - transaction id
|
||||
- `producer` - block producer
|
||||
- `act`
|
||||
- `account` - contract account
|
||||
- `name` - contract method name
|
||||
- `authorization` - array of signers
|
||||
- `actor` - signing actor
|
||||
- `permission` - signing permission
|
||||
- `data` - action data input object
|
||||
- `account_ram_deltas` - array of ram deltas and payers
|
||||
- `account`
|
||||
- `delta`
|
||||
- `notified` - array of accounts that were notified (via inline action events)
|
||||
### 2. Architecture
|
||||
The following components are required in order to have a fully functional Hyperion API deployment,
|
||||
for small use cases its absolutely fine to run all components on a single machine. For larger chains and
|
||||
production environments we recommend setting them up into different servers under a high-speed local network.
|
||||
|
||||
## Dependencies
|
||||
#### 2.1 Elasticsearch Cluster
|
||||
The ES cluster is responsible for storing all indexed data.
|
||||
Direct access to the Hyperion API and Indexer must be provided. We recommend nodes in the
|
||||
cluster to have at least 32 GB of RAM and 8 cpu cores. SSD/NVME drives are recommended for
|
||||
maximum indexing throughput. For production environments a multi-node cluster is highly recommended.
|
||||
|
||||
This setup has only been tested with Ubuntu 18.04, but should work with other OS versions too
|
||||
#### 2.2 Hyperion Indexer
|
||||
The Indexer is a Node.js based app that process data from the state history plugin and allows it to be indexed.
|
||||
The PM2 process manager is used to launch and operate the indexer. The configuration flexibility is very extensive,
|
||||
so system recommendations will depend on the use case and data load. It will require access to at least one ES node,
|
||||
RabbitMQ and the state history node.
|
||||
|
||||
- [Elasticsearch 7.5.X](https://www.elastic.co/downloads/elasticsearch)
|
||||
- [RabbitMQ](https://www.rabbitmq.com/install-debian.html)
|
||||
- [Redis](https://redis.io/topics/quickstart)
|
||||
- [Node.js v13](https://github.com/nodesource/distributions/blob/master/README.md#installation-instructions)
|
||||
- [PM2](http://pm2.keymetrics.io/docs/usage/quick-start/)
|
||||
- Nodeos w/ state_history_plugin and chain_api_plugin
|
||||
|
||||
> The indexer requires redis, pm2 and node.js to be on the same machine. Other dependencies might be installed on other machines, preferably over a very high speed and low latency network. Indexing speed will vary greatly depending on this configuration.
|
||||
|
||||
## Setup Instructions
|
||||
#### 2.3 Hyperion API
|
||||
Parallelizable API server that provides the V2 and V1 (legacy history plugin) endpoints.
|
||||
It is launched by PM2 and can also operate in cluster mode. It requires direct access to
|
||||
at least one ES node for the queries and all other services for full healthcheck
|
||||
|
||||
Install, configure and test all dependencies above before continuing
|
||||
#### 2.4 RabbitMQ
|
||||
Use as messaging queue and data transport between the indexer stages
|
||||
|
||||
Read the step-by-step instructions here - [INSTALL.md](https://github.com/eosrio/Hyperion-History-API/blob/master/INSTALL.md)
|
||||
#### 2.5 EOSIO State History
|
||||
Nodeos plugin used to collect action traces and state deltas. Provides data via websocket to the indexer
|
||||
|
||||
#### 1. Clone & Install packages
|
||||
```bash
|
||||
git clone https://github.com/eosrio/Hyperion-History-API.git
|
||||
cd Hyperion-History-API
|
||||
npm install
|
||||
```
|
||||
### 3. How to use
|
||||
|
||||
#### 2. Edit configs
|
||||
```
|
||||
cp example-ecosystem.config.js ecosystem.config.js
|
||||
nano ecosystem.config.js
|
||||
#### 3.1 [For Providers](https://eosrio.github.io/hyperion-docs/quickstart/)
|
||||
|
||||
# Enter connection details here (chain name must match on the ecosystem file)
|
||||
cp example-connections.json connections.json
|
||||
nano connections.json
|
||||
```
|
||||
|
||||
connections.json Reference
|
||||
```
|
||||
{
|
||||
"amqp": {
|
||||
"host": "127.0.0.1:5672", // RabbitMQ Server
|
||||
"api": "127.0.0.1:15672", // RabbitMQ API Endpoint
|
||||
"user": "username",
|
||||
"pass": "password",
|
||||
"vhost": "hyperion" // RabbitMQ vhost
|
||||
},
|
||||
"elasticsearch": {
|
||||
"host": "127.0.0.1:9200", // Elasticsearch HTTP API Endpoint
|
||||
"ingest_nodes": ["127.0.0.1:9200"], // List of ES ingest nodes
|
||||
"user": "elastic",
|
||||
"pass": "password"
|
||||
},
|
||||
"redis": {
|
||||
"host": "127.0.0.1",
|
||||
"port": "6379"
|
||||
},
|
||||
"chains": {
|
||||
"eos": { // Chain name (must match on the ecosystem file)
|
||||
"http": "http://127.0.0.1:8888", // Nodeos Chain API Endpoint
|
||||
"ship": "ws://127.0.0.1:8080" // Nodeos State History Endpoint
|
||||
},
|
||||
"other_chain": {...}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
ecosystem.config.js Reference
|
||||
```
|
||||
CHAIN: 'eos', // chain prefix for indexing
|
||||
ABI_CACHE_MODE: 'false', // only cache historical ABIs to redis
|
||||
DEBUG: 'false', // debug mode - display extra logs for debugging
|
||||
LIVE_READER: 'true', // enable continuous reading after reaching the head block
|
||||
FETCH_DELTAS: 'false', // read table deltas
|
||||
CREATE_INDICES: 'v1', // index suffix to be created, set to false to use existing aliases
|
||||
START_ON: 0, // start indexing on block (0=disable)
|
||||
STOP_ON: 0, // stop indexing on block (0=disable)
|
||||
AUTO_STOP: 0, // automatically stop Indexer after X seconds if no more blocks are being processed (0=disable)
|
||||
REWRITE: 'false', // force rewrite the target replay range
|
||||
PURGE_QUEUES: 'false', // clear rabbitmq queues before starting the indexer
|
||||
BATCH_SIZE: 2000, // parallel reader batch size in blocks
|
||||
QUEUE_THRESH: 8000, // queue size limit on rabbitmq
|
||||
LIVE_ONLY: 'false', // only reads realtime data serially
|
||||
FETCH_BLOCK: 'true', // Request full blocks from the state history plugin
|
||||
FETCH_TRACES: 'true', // Request traces from the state history plugin
|
||||
PREVIEW: 'false', // preview mode - prints worker map and exit
|
||||
DISABLE_READING: 'false', // completely disable block reading, for lagged queue processing
|
||||
READERS: 3, // parallel state history readers
|
||||
DESERIALIZERS: 4, // deserialization queues
|
||||
DS_MULT: 4, // deserialization threads per queue
|
||||
ES_IDX_QUEUES: 4, // elastic indexers per queue
|
||||
ES_AD_IDX_QUEUES: 2, // multiplier for action indexing queues
|
||||
READ_PREFETCH: 50, // Stage 1 prefecth size
|
||||
BLOCK_PREFETCH: 5, // Stage 2 prefecth size
|
||||
INDEX_PREFETCH: 500, // Stage 3 prefetch size
|
||||
ENABLE_INDEXING: 'true', // enable elasticsearch indexing
|
||||
INDEX_DELTAS: 'true', // index common table deltas (see delta on definitions/mappings)
|
||||
INDEX_ALL_DELTAS: 'false' // index all table deltas (WARNING)
|
||||
```
|
||||
|
||||
#### 3. Starting
|
||||
|
||||
`./run.sh Indexer`
|
||||
or
|
||||
```
|
||||
pm2 start --only Indexer --update-env
|
||||
pm2 logs Indexer
|
||||
```
|
||||
|
||||
#### 4. Stopping
|
||||
|
||||
Stop reading and wait for queues to flush
|
||||
```
|
||||
pm2 trigger Indexer stop
|
||||
```
|
||||
|
||||
Force stop
|
||||
```
|
||||
pm2 stop Indexer
|
||||
```
|
||||
|
||||
#### 5. Starting the API node
|
||||
|
||||
`./run.sh API`
|
||||
or
|
||||
```
|
||||
pm2 start --only API --update-env
|
||||
pm2 logs API
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
Documentation is automatically generated by Swagger/OpenAPI.
|
||||
|
||||
Example: [OpenAPI Docs](https://eos.hyperion.eosrio.io/v2/docs)
|
||||
|
||||
### Roadmap
|
||||
|
||||
- Table deltas storage & queries (in progress)
|
||||
- Real-time streaming support (in progress)
|
||||
- Plugin system (in progress)
|
||||
- Control GUI
|
||||
#### 3.2 [For Developers](https://eosrio.github.io/hyperion-docs/howtouse/)
|
||||
|
||||
-50
@@ -1,50 +0,0 @@
|
||||
import { Abi, PushTransactionArgs } from './eosjs-rpc-interfaces';
|
||||
/** Arguments to `getRequiredKeys` */
|
||||
export interface AuthorityProviderArgs {
|
||||
/** Transaction that needs to be signed */
|
||||
transaction: any;
|
||||
/** Public keys associated with the private keys that the `SignatureProvider` holds */
|
||||
availableKeys: string[];
|
||||
}
|
||||
/** Get subset of `availableKeys` needed to meet authorities in `transaction` */
|
||||
export interface AuthorityProvider {
|
||||
/** Get subset of `availableKeys` needed to meet authorities in `transaction` */
|
||||
getRequiredKeys: (args: AuthorityProviderArgs) => Promise<string[]>;
|
||||
}
|
||||
/** Retrieves raw ABIs for a specified accountName */
|
||||
export interface AbiProvider {
|
||||
/** Retrieve the BinaryAbi */
|
||||
getRawAbi: (accountName: string) => Promise<BinaryAbi>;
|
||||
}
|
||||
/** Structure for the raw form of ABIs */
|
||||
export interface BinaryAbi {
|
||||
/** account which has deployed the ABI */
|
||||
accountName: string;
|
||||
/** abi in binary form */
|
||||
abi: Uint8Array;
|
||||
}
|
||||
/** Holds a fetched abi */
|
||||
export interface CachedAbi {
|
||||
/** abi in binary form */
|
||||
rawAbi: Uint8Array;
|
||||
/** abi in structured form */
|
||||
abi: Abi;
|
||||
}
|
||||
/** Arguments to `sign` */
|
||||
export interface SignatureProviderArgs {
|
||||
/** Chain transaction is for */
|
||||
chainId: string;
|
||||
/** Public keys associated with the private keys needed to sign the transaction */
|
||||
requiredKeys: string[];
|
||||
/** Transaction to sign */
|
||||
serializedTransaction: Uint8Array;
|
||||
/** ABIs for all contracts with actions included in `serializedTransaction` */
|
||||
abis: BinaryAbi[];
|
||||
}
|
||||
/** Signs transactions */
|
||||
export interface SignatureProvider {
|
||||
/** Public keys associated with the private keys that the `SignatureProvider` holds */
|
||||
getAvailableKeys: () => Promise<string[]>;
|
||||
/** Sign a transaction */
|
||||
sign: (args: SignatureProviderArgs) => Promise<PushTransactionArgs>;
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
"use strict";
|
||||
// copyright defined in eosjs/LICENSE.txt
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
//# sourceMappingURL=eosjs-api-interfaces.js.map
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"eosjs-api-interfaces.js","sourceRoot":"","sources":["../src/eosjs-api-interfaces.ts"],"names":[],"mappings":";AAAA,yCAAyC"}
|
||||
Vendored
-92
@@ -1,92 +0,0 @@
|
||||
/**
|
||||
* @module API
|
||||
*/
|
||||
import { AbiProvider, AuthorityProvider, BinaryAbi, CachedAbi, SignatureProvider } from './eosjs-api-interfaces';
|
||||
import { JsonRpc } from './eosjs-jsonrpc';
|
||||
import { Abi, PushTransactionArgs } from './eosjs-rpc-interfaces';
|
||||
import * as ser from './eosjs-serialize';
|
||||
export declare class Api {
|
||||
/** Issues RPC calls */
|
||||
rpc: JsonRpc;
|
||||
/** Get subset of `availableKeys` needed to meet authorities in a `transaction` */
|
||||
authorityProvider: AuthorityProvider;
|
||||
/** Supplies ABIs in raw form (binary) */
|
||||
abiProvider: AbiProvider;
|
||||
/** Signs transactions */
|
||||
signatureProvider: SignatureProvider;
|
||||
/** Identifies chain */
|
||||
chainId: string;
|
||||
textEncoder: TextEncoder;
|
||||
textDecoder: TextDecoder;
|
||||
/** Converts abi files between binary and structured form (`abi.abi.json`) */
|
||||
abiTypes: Map<string, ser.Type>;
|
||||
/** Converts transactions between binary and structured form (`transaction.abi.json`) */
|
||||
transactionTypes: Map<string, ser.Type>;
|
||||
/** Holds information needed to serialize contract actions */
|
||||
contracts: Map<string, ser.Contract>;
|
||||
/** Fetched abis */
|
||||
cachedAbis: Map<string, CachedAbi>;
|
||||
/**
|
||||
* @param args
|
||||
* * `rpc`: Issues RPC calls
|
||||
* * `authorityProvider`: Get public keys needed to meet authorities in a transaction
|
||||
* * `abiProvider`: Supplies ABIs in raw form (binary)
|
||||
* * `signatureProvider`: Signs transactions
|
||||
* * `chainId`: Identifies chain
|
||||
* * `textEncoder`: `TextEncoder` instance to use. Pass in `null` if running in a browser
|
||||
* * `textDecoder`: `TextDecoder` instance to use. Pass in `null` if running in a browser
|
||||
*/
|
||||
constructor(args: {
|
||||
rpc: JsonRpc;
|
||||
authorityProvider?: AuthorityProvider;
|
||||
abiProvider?: AbiProvider;
|
||||
signatureProvider: SignatureProvider;
|
||||
chainId?: string;
|
||||
textEncoder?: TextEncoder;
|
||||
textDecoder?: TextDecoder;
|
||||
});
|
||||
/** Decodes an abi as Uint8Array into json. */
|
||||
rawAbiToJson(rawAbi: Uint8Array): Abi;
|
||||
/** Get abi in both binary and structured forms. Fetch when needed. */
|
||||
getCachedAbi(accountName: string, reload?: boolean): Promise<CachedAbi>;
|
||||
/** Get abi in structured form. Fetch when needed. */
|
||||
getAbi(accountName: string, reload?: boolean): Promise<Abi>;
|
||||
/** Get abis needed by a transaction */
|
||||
getTransactionAbis(transaction: any, reload?: boolean): Promise<BinaryAbi[]>;
|
||||
/** Get data needed to serialize actions in a contract */
|
||||
getContract(accountName: string, reload?: boolean): Promise<ser.Contract>;
|
||||
/** Convert `value` to binary form. `type` must be a built-in abi type or in `transaction.abi.json`. */
|
||||
serialize(buffer: ser.SerialBuffer, type: string, value: any): void;
|
||||
/** Convert data in `buffer` to structured form. `type` must be a built-in abi type or in `transaction.abi.json`. */
|
||||
deserialize(buffer: ser.SerialBuffer, type: string): any;
|
||||
/** Convert a transaction to binary */
|
||||
serializeTransaction(transaction: any): Uint8Array;
|
||||
/** Convert a transaction from binary. Leaves actions in hex. */
|
||||
deserializeTransaction(transaction: Uint8Array): any;
|
||||
/** Convert actions to hex */
|
||||
serializeActions(actions: ser.Action[]): Promise<ser.SerializedAction[]>;
|
||||
/** Convert actions from hex */
|
||||
deserializeActions(actions: ser.Action[]): Promise<ser.Action[]>;
|
||||
/** Convert a transaction from binary. Also deserializes actions. */
|
||||
deserializeTransactionWithActions(transaction: Uint8Array | string): Promise<any>;
|
||||
/**
|
||||
* Create and optionally broadcast a transaction.
|
||||
*
|
||||
* Named Parameters:
|
||||
* * `broadcast`: broadcast this transaction?
|
||||
* * `sign`: sign this transaction?
|
||||
* * If both `blocksBehind` and `expireSeconds` are present,
|
||||
* then fetch the block which is `blocksBehind` behind head block,
|
||||
* use it as a reference for TAPoS, and expire the transaction `expireSeconds` after that block's time.
|
||||
* @returns node response if `broadcast`, `{signatures, serializedTransaction}` if `!broadcast`
|
||||
*/
|
||||
transact(transaction: any, { broadcast, sign, blocksBehind, expireSeconds }?: {
|
||||
broadcast?: boolean;
|
||||
sign?: boolean;
|
||||
blocksBehind?: number;
|
||||
expireSeconds?: number;
|
||||
}): Promise<any>;
|
||||
/** Broadcast a signed transaction */
|
||||
pushSignedTransaction({ signatures, serializedTransaction }: PushTransactionArgs): Promise<any>;
|
||||
private hasRequiredTaposFields;
|
||||
}
|
||||
@@ -1,427 +0,0 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @module API
|
||||
*/
|
||||
// copyright defined in eosjs/LICENSE.txt
|
||||
var __assign = (this && this.__assign) || function () {
|
||||
__assign = Object.assign || function(t) {
|
||||
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
||||
s = arguments[i];
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
||||
t[p] = s[p];
|
||||
}
|
||||
return t;
|
||||
};
|
||||
return __assign.apply(this, arguments);
|
||||
};
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
var __rest = (this && this.__rest) || function (s, e) {
|
||||
var t = {};
|
||||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
||||
t[p] = s[p];
|
||||
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
||||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
|
||||
t[p[i]] = s[p[i]];
|
||||
return t;
|
||||
};
|
||||
var __read = (this && this.__read) || function (o, n) {
|
||||
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
||||
if (!m) return o;
|
||||
var i = m.call(o), r, ar = [], e;
|
||||
try {
|
||||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
||||
}
|
||||
catch (error) { e = { error: error }; }
|
||||
finally {
|
||||
try {
|
||||
if (r && !r.done && (m = i["return"])) m.call(i);
|
||||
}
|
||||
finally { if (e) throw e.error; }
|
||||
}
|
||||
return ar;
|
||||
};
|
||||
var __spread = (this && this.__spread) || function () {
|
||||
for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
|
||||
return ar;
|
||||
};
|
||||
var __values = (this && this.__values) || function (o) {
|
||||
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
|
||||
if (m) return m.call(o);
|
||||
return {
|
||||
next: function () {
|
||||
if (o && i >= o.length) o = void 0;
|
||||
return { value: o && o[i++], done: !o };
|
||||
}
|
||||
};
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var ser = require("./eosjs-serialize");
|
||||
var abiAbi = require('./src/abi.abi.json');
|
||||
var transactionAbi = require('./src/transaction.abi.json');
|
||||
var Api = /** @class */ (function () {
|
||||
/**
|
||||
* @param args
|
||||
* * `rpc`: Issues RPC calls
|
||||
* * `authorityProvider`: Get public keys needed to meet authorities in a transaction
|
||||
* * `abiProvider`: Supplies ABIs in raw form (binary)
|
||||
* * `signatureProvider`: Signs transactions
|
||||
* * `chainId`: Identifies chain
|
||||
* * `textEncoder`: `TextEncoder` instance to use. Pass in `null` if running in a browser
|
||||
* * `textDecoder`: `TextDecoder` instance to use. Pass in `null` if running in a browser
|
||||
*/
|
||||
function Api(args) {
|
||||
/** Holds information needed to serialize contract actions */
|
||||
this.contracts = new Map();
|
||||
/** Fetched abis */
|
||||
this.cachedAbis = new Map();
|
||||
this.rpc = args.rpc;
|
||||
this.authorityProvider = args.authorityProvider || args.rpc;
|
||||
this.abiProvider = args.abiProvider || args.rpc;
|
||||
this.signatureProvider = args.signatureProvider;
|
||||
this.chainId = args.chainId;
|
||||
this.textEncoder = args.textEncoder;
|
||||
this.textDecoder = args.textDecoder;
|
||||
this.abiTypes = ser.getTypesFromAbi(ser.createInitialTypes(), abiAbi);
|
||||
this.transactionTypes = ser.getTypesFromAbi(ser.createInitialTypes(), transactionAbi);
|
||||
}
|
||||
/** Decodes an abi as Uint8Array into json. */
|
||||
Api.prototype.rawAbiToJson = function (rawAbi) {
|
||||
var buffer = new ser.SerialBuffer({
|
||||
textEncoder: this.textEncoder,
|
||||
textDecoder: this.textDecoder,
|
||||
array: rawAbi,
|
||||
});
|
||||
if (!ser.supportedAbiVersion(buffer.getString())) {
|
||||
throw new Error('Unsupported abi version');
|
||||
}
|
||||
buffer.restartRead();
|
||||
return this.abiTypes.get('abi_def').deserialize(buffer);
|
||||
};
|
||||
/** Get abi in both binary and structured forms. Fetch when needed. */
|
||||
Api.prototype.getCachedAbi = function (accountName, reload) {
|
||||
if (reload === void 0) { reload = false; }
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var cachedAbi, rawAbi, abi, e_1;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (!reload && this.cachedAbis.get(accountName)) {
|
||||
return [2 /*return*/, this.cachedAbis.get(accountName)];
|
||||
}
|
||||
_a.label = 1;
|
||||
case 1:
|
||||
_a.trys.push([1, 3, , 4]);
|
||||
return [4 /*yield*/, this.abiProvider.getRawAbi(accountName)];
|
||||
case 2:
|
||||
rawAbi = (_a.sent()).abi;
|
||||
abi = this.rawAbiToJson(rawAbi);
|
||||
cachedAbi = { rawAbi: rawAbi, abi: abi };
|
||||
return [3 /*break*/, 4];
|
||||
case 3:
|
||||
e_1 = _a.sent();
|
||||
e_1.message = "fetching abi for " + accountName + ": " + e_1.message;
|
||||
throw e_1;
|
||||
case 4:
|
||||
if (!cachedAbi) {
|
||||
throw new Error("Missing abi for " + accountName);
|
||||
}
|
||||
this.cachedAbis.set(accountName, cachedAbi);
|
||||
return [2 /*return*/, cachedAbi];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/** Get abi in structured form. Fetch when needed. */
|
||||
Api.prototype.getAbi = function (accountName, reload) {
|
||||
if (reload === void 0) { reload = false; }
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, this.getCachedAbi(accountName, reload)];
|
||||
case 1: return [2 /*return*/, (_a.sent()).abi];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/** Get abis needed by a transaction */
|
||||
Api.prototype.getTransactionAbis = function (transaction, reload) {
|
||||
if (reload === void 0) { reload = false; }
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var accounts, uniqueAccounts, actionPromises;
|
||||
var _this = this;
|
||||
return __generator(this, function (_a) {
|
||||
accounts = transaction.actions.map(function (action) { return action.account; });
|
||||
uniqueAccounts = new Set(accounts);
|
||||
actionPromises = __spread(uniqueAccounts).map(function (account) { return __awaiter(_this, void 0, void 0, function () {
|
||||
var _a;
|
||||
return __generator(this, function (_b) {
|
||||
switch (_b.label) {
|
||||
case 0:
|
||||
_a = {
|
||||
accountName: account
|
||||
};
|
||||
return [4 /*yield*/, this.getCachedAbi(account, reload)];
|
||||
case 1: return [2 /*return*/, (_a.abi = (_b.sent()).rawAbi,
|
||||
_a)];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
return [2 /*return*/, Promise.all(actionPromises)];
|
||||
});
|
||||
});
|
||||
};
|
||||
/** Get data needed to serialize actions in a contract */
|
||||
Api.prototype.getContract = function (accountName, reload) {
|
||||
if (reload === void 0) { reload = false; }
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var e_2, _a, abi, types, actions, _b, _c, _d, name_1, type, result;
|
||||
return __generator(this, function (_e) {
|
||||
switch (_e.label) {
|
||||
case 0:
|
||||
if (!reload && this.contracts.get(accountName)) {
|
||||
return [2 /*return*/, this.contracts.get(accountName)];
|
||||
}
|
||||
return [4 /*yield*/, this.getAbi(accountName, reload)];
|
||||
case 1:
|
||||
abi = _e.sent();
|
||||
types = ser.getTypesFromAbi(ser.createInitialTypes(), abi);
|
||||
actions = new Map();
|
||||
try {
|
||||
for (_b = __values(abi.actions), _c = _b.next(); !_c.done; _c = _b.next()) {
|
||||
_d = _c.value, name_1 = _d.name, type = _d.type;
|
||||
actions.set(name_1, ser.getType(types, type));
|
||||
}
|
||||
}
|
||||
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
||||
finally {
|
||||
try {
|
||||
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
||||
}
|
||||
finally { if (e_2) throw e_2.error; }
|
||||
}
|
||||
result = { types: types, actions: actions };
|
||||
this.contracts.set(accountName, result);
|
||||
return [2 /*return*/, result];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/** Convert `value` to binary form. `type` must be a built-in abi type or in `transaction.abi.json`. */
|
||||
Api.prototype.serialize = function (buffer, type, value) {
|
||||
this.transactionTypes.get(type).serialize(buffer, value);
|
||||
};
|
||||
/** Convert data in `buffer` to structured form. `type` must be a built-in abi type or in `transaction.abi.json`. */
|
||||
Api.prototype.deserialize = function (buffer, type) {
|
||||
return this.transactionTypes.get(type).deserialize(buffer);
|
||||
};
|
||||
/** Convert a transaction to binary */
|
||||
Api.prototype.serializeTransaction = function (transaction) {
|
||||
var buffer = new ser.SerialBuffer({ textEncoder: this.textEncoder, textDecoder: this.textDecoder });
|
||||
this.serialize(buffer, 'transaction', __assign({ max_net_usage_words: 0, max_cpu_usage_ms: 0, delay_sec: 0, context_free_actions: [], actions: [], transaction_extensions: [] }, transaction));
|
||||
return buffer.asUint8Array();
|
||||
};
|
||||
/** Convert a transaction from binary. Leaves actions in hex. */
|
||||
Api.prototype.deserializeTransaction = function (transaction) {
|
||||
var buffer = new ser.SerialBuffer({ textEncoder: this.textEncoder, textDecoder: this.textDecoder });
|
||||
buffer.pushArray(transaction);
|
||||
return this.deserialize(buffer, 'transaction');
|
||||
};
|
||||
/** Convert actions to hex */
|
||||
Api.prototype.serializeActions = function (actions) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var _this = this;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, Promise.all(actions.map(function (_a) {
|
||||
var account = _a.account, name = _a.name, authorization = _a.authorization, data = _a.data;
|
||||
return __awaiter(_this, void 0, void 0, function () {
|
||||
var contract;
|
||||
return __generator(this, function (_b) {
|
||||
switch (_b.label) {
|
||||
case 0: return [4 /*yield*/, this.getContract(account)];
|
||||
case 1:
|
||||
contract = _b.sent();
|
||||
return [2 /*return*/, ser.serializeAction(contract, account, name, authorization, data, this.textEncoder, this.textDecoder)];
|
||||
}
|
||||
});
|
||||
});
|
||||
}))];
|
||||
case 1: return [2 /*return*/, _a.sent()];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/** Convert actions from hex */
|
||||
Api.prototype.deserializeActions = function (actions) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var _this = this;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, Promise.all(actions.map(function (_a) {
|
||||
var account = _a.account, name = _a.name, authorization = _a.authorization, data = _a.data;
|
||||
return __awaiter(_this, void 0, void 0, function () {
|
||||
var contract;
|
||||
return __generator(this, function (_b) {
|
||||
switch (_b.label) {
|
||||
case 0: return [4 /*yield*/, this.getContract(account)];
|
||||
case 1:
|
||||
contract = _b.sent();
|
||||
return [2 /*return*/, ser.deserializeAction(contract, account, name, authorization, data, this.textEncoder, this.textDecoder)];
|
||||
}
|
||||
});
|
||||
});
|
||||
}))];
|
||||
case 1: return [2 /*return*/, _a.sent()];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/** Convert a transaction from binary. Also deserializes actions. */
|
||||
Api.prototype.deserializeTransactionWithActions = function (transaction) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var deserializedTransaction, deserializedActions;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
if (typeof transaction === 'string') {
|
||||
transaction = ser.hexToUint8Array(transaction);
|
||||
}
|
||||
deserializedTransaction = this.deserializeTransaction(transaction);
|
||||
return [4 /*yield*/, this.deserializeActions(deserializedTransaction.actions)];
|
||||
case 1:
|
||||
deserializedActions = _a.sent();
|
||||
return [2 /*return*/, __assign({}, deserializedTransaction, { actions: deserializedActions })];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/**
|
||||
* Create and optionally broadcast a transaction.
|
||||
*
|
||||
* Named Parameters:
|
||||
* * `broadcast`: broadcast this transaction?
|
||||
* * `sign`: sign this transaction?
|
||||
* * If both `blocksBehind` and `expireSeconds` are present,
|
||||
* then fetch the block which is `blocksBehind` behind head block,
|
||||
* use it as a reference for TAPoS, and expire the transaction `expireSeconds` after that block's time.
|
||||
* @returns node response if `broadcast`, `{signatures, serializedTransaction}` if `!broadcast`
|
||||
*/
|
||||
Api.prototype.transact = function (transaction, _a) {
|
||||
var _b = _a === void 0 ? {} : _a, _c = _b.broadcast, broadcast = _c === void 0 ? true : _c, _d = _b.sign, sign = _d === void 0 ? true : _d, blocksBehind = _b.blocksBehind, expireSeconds = _b.expireSeconds;
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var info, refBlock, abis, _e, _f, serializedTransaction, pushTransactionArgs, availableKeys, requiredKeys;
|
||||
return __generator(this, function (_g) {
|
||||
switch (_g.label) {
|
||||
case 0:
|
||||
if (!!this.chainId) return [3 /*break*/, 2];
|
||||
return [4 /*yield*/, this.rpc.get_info()];
|
||||
case 1:
|
||||
info = _g.sent();
|
||||
this.chainId = info.chain_id;
|
||||
_g.label = 2;
|
||||
case 2:
|
||||
if (!(typeof blocksBehind === 'number' && expireSeconds)) return [3 /*break*/, 6];
|
||||
if (!!info) return [3 /*break*/, 4];
|
||||
return [4 /*yield*/, this.rpc.get_info()];
|
||||
case 3:
|
||||
info = _g.sent();
|
||||
_g.label = 4;
|
||||
case 4: return [4 /*yield*/, this.rpc.get_block(info.head_block_num - blocksBehind)];
|
||||
case 5:
|
||||
refBlock = _g.sent();
|
||||
transaction = __assign({}, ser.transactionHeader(refBlock, expireSeconds), transaction);
|
||||
_g.label = 6;
|
||||
case 6:
|
||||
if (!this.hasRequiredTaposFields(transaction)) {
|
||||
throw new Error('Required configuration or TAPOS fields are not present');
|
||||
}
|
||||
return [4 /*yield*/, this.getTransactionAbis(transaction)];
|
||||
case 7:
|
||||
abis = _g.sent();
|
||||
_e = [{}, transaction];
|
||||
_f = {};
|
||||
return [4 /*yield*/, this.serializeActions(transaction.actions)];
|
||||
case 8:
|
||||
transaction = __assign.apply(void 0, _e.concat([(_f.actions = _g.sent(), _f)]));
|
||||
serializedTransaction = this.serializeTransaction(transaction);
|
||||
pushTransactionArgs = { serializedTransaction: serializedTransaction, signatures: [] };
|
||||
if (!sign) return [3 /*break*/, 12];
|
||||
return [4 /*yield*/, this.signatureProvider.getAvailableKeys()];
|
||||
case 9:
|
||||
availableKeys = _g.sent();
|
||||
return [4 /*yield*/, this.authorityProvider.getRequiredKeys({ transaction: transaction, availableKeys: availableKeys })];
|
||||
case 10:
|
||||
requiredKeys = _g.sent();
|
||||
return [4 /*yield*/, this.signatureProvider.sign({
|
||||
chainId: this.chainId,
|
||||
requiredKeys: requiredKeys,
|
||||
serializedTransaction: serializedTransaction,
|
||||
abis: abis,
|
||||
})];
|
||||
case 11:
|
||||
pushTransactionArgs = _g.sent();
|
||||
_g.label = 12;
|
||||
case 12:
|
||||
if (broadcast) {
|
||||
return [2 /*return*/, this.pushSignedTransaction(pushTransactionArgs)];
|
||||
}
|
||||
return [2 /*return*/, pushTransactionArgs];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/** Broadcast a signed transaction */
|
||||
Api.prototype.pushSignedTransaction = function (_a) {
|
||||
var signatures = _a.signatures, serializedTransaction = _a.serializedTransaction;
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
return __generator(this, function (_b) {
|
||||
return [2 /*return*/, this.rpc.push_transaction({
|
||||
signatures: signatures,
|
||||
serializedTransaction: serializedTransaction,
|
||||
})];
|
||||
});
|
||||
});
|
||||
};
|
||||
// eventually break out into TransactionValidator class
|
||||
Api.prototype.hasRequiredTaposFields = function (_a) {
|
||||
var expiration = _a.expiration, ref_block_num = _a.ref_block_num, ref_block_prefix = _a.ref_block_prefix, transaction = __rest(_a, ["expiration", "ref_block_num", "ref_block_prefix"]);
|
||||
return !!(expiration && ref_block_num && ref_block_prefix);
|
||||
};
|
||||
return Api;
|
||||
}()); // Api
|
||||
exports.Api = Api;
|
||||
//# sourceMappingURL=eosjs-api.js.map
|
||||
File diff suppressed because one or more lines are too long
-63
@@ -1,63 +0,0 @@
|
||||
/**
|
||||
* @module JSON-RPC
|
||||
*/
|
||||
import { AbiProvider, AuthorityProvider, AuthorityProviderArgs, BinaryAbi } from './eosjs-api-interfaces';
|
||||
import { GetAbiResult, GetBlockResult, GetCodeResult, GetInfoResult, GetRawCodeAndAbiResult, PushTransactionArgs } from "./eosjs-rpc-interfaces";
|
||||
/** Make RPC calls */
|
||||
export declare class JsonRpc implements AuthorityProvider, AbiProvider {
|
||||
endpoint: string;
|
||||
fetchBuiltin: (input?: Request | string, init?: RequestInit) => Promise<Response>;
|
||||
/**
|
||||
* @param args
|
||||
* * `fetch`:
|
||||
* * browsers: leave `null` or `undefined`
|
||||
* * node: provide an implementation
|
||||
*/
|
||||
constructor(endpoint: string, args?: {
|
||||
fetch?: (input?: string | Request, init?: RequestInit) => Promise<Response>;
|
||||
});
|
||||
/** Post `body` to `endpoint + path`. Throws detailed error information in `RpcError` when available. */
|
||||
fetch(path: string, body: any): Promise<any>;
|
||||
/** Raw call to `/v1/chain/get_abi` */
|
||||
get_abi(accountName: string): Promise<GetAbiResult>;
|
||||
/** Raw call to `/v1/chain/get_account` */
|
||||
get_account(accountName: string): Promise<any>;
|
||||
/** Raw call to `/v1/chain/get_block_header_state` */
|
||||
get_block_header_state(blockNumOrId: number | string): Promise<any>;
|
||||
/** Raw call to `/v1/chain/get_block` */
|
||||
get_block(blockNumOrId: number | string): Promise<GetBlockResult>;
|
||||
/** Raw call to `/v1/chain/get_code` */
|
||||
get_code(accountName: string): Promise<GetCodeResult>;
|
||||
/** Raw call to `/v1/chain/get_currency_balance` */
|
||||
get_currency_balance(code: string, account: string, symbol?: string): Promise<any>;
|
||||
/** Raw call to `/v1/chain/get_currency_stats` */
|
||||
get_currency_stats(code: string, symbol: string): Promise<any>;
|
||||
/** Raw call to `/v1/chain/get_info` */
|
||||
get_info(): Promise<GetInfoResult>;
|
||||
/** Raw call to `/v1/chain/get_producer_schedule` */
|
||||
get_producer_schedule(): Promise<any>;
|
||||
/** Raw call to `/v1/chain/get_producers` */
|
||||
get_producers(json?: boolean, lowerBound?: string, limit?: number): Promise<any>;
|
||||
/** Raw call to `/v1/chain/get_raw_code_and_abi` */
|
||||
get_raw_code_and_abi(accountName: string): Promise<GetRawCodeAndAbiResult>;
|
||||
/** calls `/v1/chain/get_raw_code_and_abi` and pulls out unneeded raw wasm code */
|
||||
getRawAbi(accountName: string): Promise<BinaryAbi>;
|
||||
/** Raw call to `/v1/chain/get_table_rows` */
|
||||
get_table_rows({ json, code, scope, table, table_key, lower_bound, upper_bound, index_position, key_type, limit, reverse, show_payer, }: any): Promise<any>;
|
||||
/** Raw call to `/v1/chain/get_table_by_scope` */
|
||||
get_table_by_scope({ code, table, lower_bound, upper_bound, limit, }: any): Promise<any>;
|
||||
/** Get subset of `availableKeys` needed to meet authorities in `transaction`. Implements `AuthorityProvider` */
|
||||
getRequiredKeys(args: AuthorityProviderArgs): Promise<string[]>;
|
||||
/** Push a serialized transaction */
|
||||
push_transaction({ signatures, serializedTransaction }: PushTransactionArgs): Promise<any>;
|
||||
/** Raw call to `/v1/db_size/get` */
|
||||
db_size_get(): Promise<any>;
|
||||
/** Raw call to `/v1/history/get_actions` */
|
||||
history_get_actions(accountName: string, pos?: number, offset?: number): Promise<any>;
|
||||
/** Raw call to `/v1/history/get_transaction` */
|
||||
history_get_transaction(id: string, blockNumHint?: number): Promise<any>;
|
||||
/** Raw call to `/v1/history/get_key_accounts` */
|
||||
history_get_key_accounts(publicKey: string): Promise<any>;
|
||||
/** Raw call to `/v1/history/get_controlled_accounts` */
|
||||
history_get_controlled_accounts(controllingAccount: string): Promise<any>;
|
||||
}
|
||||
@@ -1,402 +0,0 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @module JSON-RPC
|
||||
*/
|
||||
// copyright defined in eosjs/LICENSE.txt
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
var __values = (this && this.__values) || function (o) {
|
||||
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
|
||||
if (m) return m.call(o);
|
||||
return {
|
||||
next: function () {
|
||||
if (o && i >= o.length) o = void 0;
|
||||
return { value: o && o[i++], done: !o };
|
||||
}
|
||||
};
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var eosjs_numeric_1 = require("./eosjs-numeric");
|
||||
var eosjs_rpcerror_1 = require("./eosjs-rpcerror");
|
||||
function arrayToHex(data) {
|
||||
var e_1, _a;
|
||||
var result = '';
|
||||
try {
|
||||
for (var data_1 = __values(data), data_1_1 = data_1.next(); !data_1_1.done; data_1_1 = data_1.next()) {
|
||||
var x = data_1_1.value;
|
||||
result += ('00' + x.toString(16)).slice(-2);
|
||||
}
|
||||
}
|
||||
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
||||
finally {
|
||||
try {
|
||||
if (data_1_1 && !data_1_1.done && (_a = data_1.return)) _a.call(data_1);
|
||||
}
|
||||
finally { if (e_1) throw e_1.error; }
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/** Make RPC calls */
|
||||
var JsonRpc = /** @class */ (function () {
|
||||
/**
|
||||
* @param args
|
||||
* * `fetch`:
|
||||
* * browsers: leave `null` or `undefined`
|
||||
* * node: provide an implementation
|
||||
*/
|
||||
function JsonRpc(endpoint, args) {
|
||||
if (args === void 0) { args = {}; }
|
||||
this.endpoint = endpoint;
|
||||
if (args.fetch) {
|
||||
this.fetchBuiltin = args.fetch;
|
||||
}
|
||||
else {
|
||||
this.fetchBuiltin = global.fetch;
|
||||
}
|
||||
}
|
||||
/** Post `body` to `endpoint + path`. Throws detailed error information in `RpcError` when available. */
|
||||
JsonRpc.prototype.fetch = function (path, body) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var response, json, f, e_2;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
_a.trys.push([0, 3, , 4]);
|
||||
f = this.fetchBuiltin;
|
||||
return [4 /*yield*/, f(this.endpoint + path, {
|
||||
body: JSON.stringify(body),
|
||||
method: 'POST',
|
||||
})];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
return [4 /*yield*/, response.json()];
|
||||
case 2:
|
||||
json = _a.sent();
|
||||
if (json.processed && json.processed.except) {
|
||||
throw new eosjs_rpcerror_1.RpcError(json);
|
||||
}
|
||||
return [3 /*break*/, 4];
|
||||
case 3:
|
||||
e_2 = _a.sent();
|
||||
e_2.isFetchError = true;
|
||||
throw e_2;
|
||||
case 4:
|
||||
if (!response.ok) {
|
||||
throw new eosjs_rpcerror_1.RpcError(json);
|
||||
}
|
||||
return [2 /*return*/, json];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/** Raw call to `/v1/chain/get_abi` */
|
||||
JsonRpc.prototype.get_abi = function (accountName) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, this.fetch('/v1/chain/get_abi', { account_name: accountName })];
|
||||
case 1: return [2 /*return*/, _a.sent()];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/** Raw call to `/v1/chain/get_account` */
|
||||
JsonRpc.prototype.get_account = function (accountName) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, this.fetch('/v1/chain/get_account', { account_name: accountName })];
|
||||
case 1: return [2 /*return*/, _a.sent()];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/** Raw call to `/v1/chain/get_block_header_state` */
|
||||
JsonRpc.prototype.get_block_header_state = function (blockNumOrId) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, this.fetch('/v1/chain/get_block_header_state', { block_num_or_id: blockNumOrId })];
|
||||
case 1: return [2 /*return*/, _a.sent()];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/** Raw call to `/v1/chain/get_block` */
|
||||
JsonRpc.prototype.get_block = function (blockNumOrId) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, this.fetch('/v1/chain/get_block', { block_num_or_id: blockNumOrId })];
|
||||
case 1: return [2 /*return*/, _a.sent()];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/** Raw call to `/v1/chain/get_code` */
|
||||
JsonRpc.prototype.get_code = function (accountName) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, this.fetch('/v1/chain/get_code', { account_name: accountName })];
|
||||
case 1: return [2 /*return*/, _a.sent()];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/** Raw call to `/v1/chain/get_currency_balance` */
|
||||
JsonRpc.prototype.get_currency_balance = function (code, account, symbol) {
|
||||
if (symbol === void 0) { symbol = null; }
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, this.fetch('/v1/chain/get_currency_balance', { code: code, account: account, symbol: symbol })];
|
||||
case 1: return [2 /*return*/, _a.sent()];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/** Raw call to `/v1/chain/get_currency_stats` */
|
||||
JsonRpc.prototype.get_currency_stats = function (code, symbol) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, this.fetch('/v1/chain/get_currency_stats', { code: code, symbol: symbol })];
|
||||
case 1: return [2 /*return*/, _a.sent()];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/** Raw call to `/v1/chain/get_info` */
|
||||
JsonRpc.prototype.get_info = function () {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, this.fetch('/v1/chain/get_info', {})];
|
||||
case 1: return [2 /*return*/, _a.sent()];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/** Raw call to `/v1/chain/get_producer_schedule` */
|
||||
JsonRpc.prototype.get_producer_schedule = function () {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, this.fetch('/v1/chain/get_producer_schedule', {})];
|
||||
case 1: return [2 /*return*/, _a.sent()];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/** Raw call to `/v1/chain/get_producers` */
|
||||
JsonRpc.prototype.get_producers = function (json, lowerBound, limit) {
|
||||
if (json === void 0) { json = true; }
|
||||
if (lowerBound === void 0) { lowerBound = ''; }
|
||||
if (limit === void 0) { limit = 50; }
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, this.fetch('/v1/chain/get_producers', { json: json, lower_bound: lowerBound, limit: limit })];
|
||||
case 1: return [2 /*return*/, _a.sent()];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/** Raw call to `/v1/chain/get_raw_code_and_abi` */
|
||||
JsonRpc.prototype.get_raw_code_and_abi = function (accountName) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, this.fetch('/v1/chain/get_raw_code_and_abi', { account_name: accountName })];
|
||||
case 1: return [2 /*return*/, _a.sent()];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/** calls `/v1/chain/get_raw_code_and_abi` and pulls out unneeded raw wasm code */
|
||||
// TODO: use `/v1/chain/get_raw_abi` directly when it becomes available
|
||||
JsonRpc.prototype.getRawAbi = function (accountName) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var rawCodeAndAbi, abi;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, this.get_raw_code_and_abi(accountName)];
|
||||
case 1:
|
||||
rawCodeAndAbi = _a.sent();
|
||||
abi = eosjs_numeric_1.base64ToBinary(rawCodeAndAbi.abi);
|
||||
return [2 /*return*/, { accountName: rawCodeAndAbi.account_name, abi: abi }];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/** Raw call to `/v1/chain/get_table_rows` */
|
||||
JsonRpc.prototype.get_table_rows = function (_a) {
|
||||
var _b = _a.json, json = _b === void 0 ? true : _b, code = _a.code, scope = _a.scope, table = _a.table, _c = _a.table_key, table_key = _c === void 0 ? '' : _c, _d = _a.lower_bound, lower_bound = _d === void 0 ? '' : _d, _e = _a.upper_bound, upper_bound = _e === void 0 ? '' : _e, _f = _a.index_position, index_position = _f === void 0 ? 1 : _f, _g = _a.key_type, key_type = _g === void 0 ? '' : _g, _h = _a.limit, limit = _h === void 0 ? 10 : _h, _j = _a.reverse, reverse = _j === void 0 ? false : _j, _k = _a.show_payer, show_payer = _k === void 0 ? false : _k;
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
return __generator(this, function (_l) {
|
||||
switch (_l.label) {
|
||||
case 0: return [4 /*yield*/, this.fetch('/v1/chain/get_table_rows', {
|
||||
json: json,
|
||||
code: code,
|
||||
scope: scope,
|
||||
table: table,
|
||||
table_key: table_key,
|
||||
lower_bound: lower_bound,
|
||||
upper_bound: upper_bound,
|
||||
index_position: index_position,
|
||||
key_type: key_type,
|
||||
limit: limit,
|
||||
reverse: reverse,
|
||||
show_payer: show_payer,
|
||||
})];
|
||||
case 1: return [2 /*return*/, _l.sent()];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/** Raw call to `/v1/chain/get_table_by_scope` */
|
||||
JsonRpc.prototype.get_table_by_scope = function (_a) {
|
||||
var code = _a.code, table = _a.table, _b = _a.lower_bound, lower_bound = _b === void 0 ? '' : _b, _c = _a.upper_bound, upper_bound = _c === void 0 ? '' : _c, _d = _a.limit, limit = _d === void 0 ? 10 : _d;
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
return __generator(this, function (_e) {
|
||||
switch (_e.label) {
|
||||
case 0: return [4 /*yield*/, this.fetch('/v1/chain/get_table_by_scope', {
|
||||
code: code,
|
||||
table: table,
|
||||
lower_bound: lower_bound,
|
||||
upper_bound: upper_bound,
|
||||
limit: limit,
|
||||
})];
|
||||
case 1: return [2 /*return*/, _e.sent()];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/** Get subset of `availableKeys` needed to meet authorities in `transaction`. Implements `AuthorityProvider` */
|
||||
JsonRpc.prototype.getRequiredKeys = function (args) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var _a;
|
||||
return __generator(this, function (_b) {
|
||||
switch (_b.label) {
|
||||
case 0:
|
||||
_a = eosjs_numeric_1.convertLegacyPublicKeys;
|
||||
return [4 /*yield*/, this.fetch('/v1/chain/get_required_keys', {
|
||||
transaction: args.transaction,
|
||||
available_keys: args.availableKeys,
|
||||
})];
|
||||
case 1: return [2 /*return*/, _a.apply(void 0, [(_b.sent()).required_keys])];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/** Push a serialized transaction */
|
||||
JsonRpc.prototype.push_transaction = function (_a) {
|
||||
var signatures = _a.signatures, serializedTransaction = _a.serializedTransaction;
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
return __generator(this, function (_b) {
|
||||
switch (_b.label) {
|
||||
case 0: return [4 /*yield*/, this.fetch('/v1/chain/push_transaction', {
|
||||
signatures: signatures,
|
||||
compression: 0,
|
||||
packed_context_free_data: '',
|
||||
packed_trx: arrayToHex(serializedTransaction),
|
||||
})];
|
||||
case 1: return [2 /*return*/, _b.sent()];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/** Raw call to `/v1/db_size/get` */
|
||||
JsonRpc.prototype.db_size_get = function () {
|
||||
return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, this.fetch('/v1/db_size/get', {})];
|
||||
case 1: return [2 /*return*/, _a.sent()];
|
||||
}
|
||||
}); });
|
||||
};
|
||||
/** Raw call to `/v1/history/get_actions` */
|
||||
JsonRpc.prototype.history_get_actions = function (accountName, pos, offset) {
|
||||
if (pos === void 0) { pos = null; }
|
||||
if (offset === void 0) { offset = null; }
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, this.fetch('/v1/history/get_actions', { account_name: accountName, pos: pos, offset: offset })];
|
||||
case 1: return [2 /*return*/, _a.sent()];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/** Raw call to `/v1/history/get_transaction` */
|
||||
JsonRpc.prototype.history_get_transaction = function (id, blockNumHint) {
|
||||
if (blockNumHint === void 0) { blockNumHint = null; }
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, this.fetch('/v1/history/get_transaction', { id: id, block_num_hint: blockNumHint })];
|
||||
case 1: return [2 /*return*/, _a.sent()];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/** Raw call to `/v1/history/get_key_accounts` */
|
||||
JsonRpc.prototype.history_get_key_accounts = function (publicKey) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, this.fetch('/v1/history/get_key_accounts', { public_key: publicKey })];
|
||||
case 1: return [2 /*return*/, _a.sent()];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
/** Raw call to `/v1/history/get_controlled_accounts` */
|
||||
JsonRpc.prototype.history_get_controlled_accounts = function (controllingAccount) {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, this.fetch('/v1/history/get_controlled_accounts', { controlling_account: controllingAccount })];
|
||||
case 1: return [2 /*return*/, _a.sent()];
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
return JsonRpc;
|
||||
}()); // JsonRpc
|
||||
exports.JsonRpc = JsonRpc;
|
||||
//# sourceMappingURL=eosjs-jsonrpc.js.map
|
||||
File diff suppressed because one or more lines are too long
Vendored
-20
@@ -1,20 +0,0 @@
|
||||
/**
|
||||
* @module JS-Sig
|
||||
*/
|
||||
import { SignatureProvider, SignatureProviderArgs } from './eosjs-api-interfaces';
|
||||
/** Signs transactions using in-process private keys */
|
||||
export declare class JsSignatureProvider implements SignatureProvider {
|
||||
/** map public to private keys */
|
||||
keys: Map<string, string>;
|
||||
/** public keys */
|
||||
availableKeys: string[];
|
||||
/** @param privateKeys private keys to sign with */
|
||||
constructor(privateKeys: string[]);
|
||||
/** Public keys associated with the private keys that the `SignatureProvider` holds */
|
||||
getAvailableKeys(): Promise<string[]>;
|
||||
/** Sign a transaction */
|
||||
sign({ chainId, requiredKeys, serializedTransaction }: SignatureProviderArgs): Promise<{
|
||||
signatures: any[];
|
||||
serializedTransaction: Uint8Array;
|
||||
}>;
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @module JS-Sig
|
||||
*/
|
||||
// copyright defined in eosjs/LICENSE.txt
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
var __values = (this && this.__values) || function (o) {
|
||||
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
|
||||
if (m) return m.call(o);
|
||||
return {
|
||||
next: function () {
|
||||
if (o && i >= o.length) o = void 0;
|
||||
return { value: o && o[i++], done: !o };
|
||||
}
|
||||
};
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var ecc = require("eosjs-ecc");
|
||||
var eosjs_numeric_1 = require("./eosjs-numeric");
|
||||
/** Signs transactions using in-process private keys */
|
||||
var JsSignatureProvider = /** @class */ (function () {
|
||||
/** @param privateKeys private keys to sign with */
|
||||
function JsSignatureProvider(privateKeys) {
|
||||
var e_1, _a;
|
||||
/** map public to private keys */
|
||||
this.keys = new Map();
|
||||
/** public keys */
|
||||
this.availableKeys = [];
|
||||
try {
|
||||
for (var privateKeys_1 = __values(privateKeys), privateKeys_1_1 = privateKeys_1.next(); !privateKeys_1_1.done; privateKeys_1_1 = privateKeys_1.next()) {
|
||||
var k = privateKeys_1_1.value;
|
||||
var pub = eosjs_numeric_1.convertLegacyPublicKey(ecc.PrivateKey.fromString(k).toPublic().toString());
|
||||
this.keys.set(pub, k);
|
||||
this.availableKeys.push(pub);
|
||||
}
|
||||
}
|
||||
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
||||
finally {
|
||||
try {
|
||||
if (privateKeys_1_1 && !privateKeys_1_1.done && (_a = privateKeys_1.return)) _a.call(privateKeys_1);
|
||||
}
|
||||
finally { if (e_1) throw e_1.error; }
|
||||
}
|
||||
}
|
||||
/** Public keys associated with the private keys that the `SignatureProvider` holds */
|
||||
JsSignatureProvider.prototype.getAvailableKeys = function () {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
return [2 /*return*/, this.availableKeys];
|
||||
});
|
||||
});
|
||||
};
|
||||
/** Sign a transaction */
|
||||
JsSignatureProvider.prototype.sign = function (_a) {
|
||||
var chainId = _a.chainId, requiredKeys = _a.requiredKeys, serializedTransaction = _a.serializedTransaction;
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
var signBuf, signatures;
|
||||
var _this = this;
|
||||
return __generator(this, function (_b) {
|
||||
signBuf = Buffer.concat([
|
||||
new Buffer(chainId, 'hex'), new Buffer(serializedTransaction), new Buffer(new Uint8Array(32)),
|
||||
]);
|
||||
signatures = requiredKeys.map(function (pub) { return ecc.Signature.sign(signBuf, _this.keys.get(eosjs_numeric_1.convertLegacyPublicKey(pub))).toString(); });
|
||||
return [2 /*return*/, { signatures: signatures, serializedTransaction: serializedTransaction }];
|
||||
});
|
||||
});
|
||||
};
|
||||
return JsSignatureProvider;
|
||||
}());
|
||||
exports.JsSignatureProvider = JsSignatureProvider;
|
||||
//# sourceMappingURL=eosjs-jssig.js.map
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"eosjs-jssig.js","sourceRoot":"","sources":["../src/eosjs-jssig.ts"],"names":[],"mappings":";AAAA;;GAEG;AACH,yCAAyC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEzC,+BAAiC;AAEjC,iDAAyD;AAEzD,uDAAuD;AACvD;IAOI,mDAAmD;IACnD,6BAAY,WAAqB;;QAPjC,iCAAiC;QAC1B,SAAI,GAAG,IAAI,GAAG,EAAkB,CAAC;QAExC,kBAAkB;QACX,kBAAa,GAAG,EAAc,CAAC;;YAIlC,KAAgB,IAAA,gBAAA,SAAA,WAAW,CAAA,wCAAA,iEAAE;gBAAxB,IAAM,CAAC,wBAAA;gBACR,IAAM,GAAG,GAAG,sCAAsB,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;gBACvF,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;gBACtB,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;aAChC;;;;;;;;;IACL,CAAC;IAED,sFAAsF;IACzE,8CAAgB,GAA7B;;;gBACI,sBAAO,IAAI,CAAC,aAAa,EAAC;;;KAC7B;IAED,yBAAyB;IACZ,kCAAI,GAAjB,UAAkB,EAAuE;YAArE,oBAAO,EAAE,8BAAY,EAAE,gDAAqB;;;;;gBACtD,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC;oBAC1B,IAAI,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,IAAI,MAAM,CAAC,qBAAqB,CAAC,EAAE,IAAI,MAAM,CAAC,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;iBAChG,CAAC,CAAC;gBACG,UAAU,GAAG,YAAY,CAAC,GAAG,CAC/B,UAAC,GAAG,IAAK,OAAA,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,KAAI,CAAC,IAAI,CAAC,GAAG,CAAC,sCAAsB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,EAAlF,CAAkF,CAC9F,CAAC;gBACF,sBAAO,EAAE,UAAU,YAAA,EAAE,qBAAqB,uBAAA,EAAE,EAAC;;;KAChD;IACL,0BAAC;AAAD,CAAC,AA/BD,IA+BC;AA/BY,kDAAmB"}
|
||||
-75
@@ -1,75 +0,0 @@
|
||||
/**
|
||||
* @module Numeric
|
||||
*/
|
||||
/** Is `bignum` a negative number? */
|
||||
export declare function isNegative(bignum: Uint8Array): boolean;
|
||||
/** Negate `bignum` */
|
||||
export declare function negate(bignum: Uint8Array): void;
|
||||
/**
|
||||
* Convert an unsigned decimal number in `s` to a bignum
|
||||
* @param size bignum size (bytes)
|
||||
*/
|
||||
export declare function decimalToBinary(size: number, s: string): Uint8Array;
|
||||
/**
|
||||
* Convert a signed decimal number in `s` to a bignum
|
||||
* @param size bignum size (bytes)
|
||||
*/
|
||||
export declare function signedDecimalToBinary(size: number, s: string): Uint8Array;
|
||||
/**
|
||||
* Convert `bignum` to an unsigned decimal number
|
||||
* @param minDigits 0-pad result to this many digits
|
||||
*/
|
||||
export declare function binaryToDecimal(bignum: Uint8Array, minDigits?: number): string;
|
||||
/**
|
||||
* Convert `bignum` to a signed decimal number
|
||||
* @param minDigits 0-pad result to this many digits
|
||||
*/
|
||||
export declare function signedBinaryToDecimal(bignum: Uint8Array, minDigits?: number): string;
|
||||
/**
|
||||
* Convert an unsigned base-58 number in `s` to a bignum
|
||||
* @param size bignum size (bytes)
|
||||
*/
|
||||
export declare function base58ToBinary(size: number, s: string): Uint8Array;
|
||||
/**
|
||||
* Convert `bignum` to a base-58 number
|
||||
* @param minDigits 0-pad result to this many digits
|
||||
*/
|
||||
export declare function binaryToBase58(bignum: Uint8Array, minDigits?: number): string;
|
||||
/** Convert an unsigned base-64 number in `s` to a bignum */
|
||||
export declare function base64ToBinary(s: string): Uint8Array;
|
||||
/** Key types this library supports */
|
||||
export declare enum KeyType {
|
||||
k1 = 0,
|
||||
r1 = 1
|
||||
}
|
||||
/** Public key data size, excluding type field */
|
||||
export declare const publicKeyDataSize = 33;
|
||||
/** Private key data size, excluding type field */
|
||||
export declare const privateKeyDataSize = 32;
|
||||
/** Signature data size, excluding type field */
|
||||
export declare const signatureDataSize = 65;
|
||||
/** Public key, private key, or signature in binary form */
|
||||
export interface Key {
|
||||
type: KeyType;
|
||||
data: Uint8Array;
|
||||
}
|
||||
/** Convert key in `s` to binary form */
|
||||
export declare function stringToPublicKey(s: string): Key;
|
||||
/** Convert `key` to string (base-58) form */
|
||||
export declare function publicKeyToString(key: Key): string;
|
||||
/** If a key is in the legacy format (`EOS` prefix), then convert it to the new format (`PUB_K1_`).
|
||||
* Leaves other formats untouched
|
||||
*/
|
||||
export declare function convertLegacyPublicKey(s: string): string;
|
||||
/** If a key is in the legacy format (`EOS` prefix), then convert it to the new format (`PUB_K1_`).
|
||||
* Leaves other formats untouched
|
||||
*/
|
||||
export declare function convertLegacyPublicKeys(keys: string[]): string[];
|
||||
/** Convert key in `s` to binary form */
|
||||
export declare function stringToPrivateKey(s: string): Key;
|
||||
/** Convert `key` to string (base-58) form */
|
||||
export declare function privateKeyToString(key: Key): string;
|
||||
/** Convert key in `s` to binary form */
|
||||
export declare function stringToSignature(s: string): Key;
|
||||
/** Convert `signature` to string (base-58) form */
|
||||
export declare function signatureToString(signature: Key): string;
|
||||
@@ -1,468 +0,0 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @module Numeric
|
||||
*/
|
||||
// copyright defined in eosjs/LICENSE.txt
|
||||
var __read = (this && this.__read) || function (o, n) {
|
||||
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
||||
if (!m) return o;
|
||||
var i = m.call(o), r, ar = [], e;
|
||||
try {
|
||||
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
||||
} catch (error) {
|
||||
e = {error: error};
|
||||
} finally {
|
||||
try {
|
||||
if (r && !r.done && (m = i["return"])) m.call(i);
|
||||
} finally {
|
||||
if (e) throw e.error;
|
||||
}
|
||||
}
|
||||
return ar;
|
||||
};
|
||||
var __spread = (this && this.__spread) || function () {
|
||||
for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
|
||||
return ar;
|
||||
};
|
||||
var __values = (this && this.__values) || function (o) {
|
||||
var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
|
||||
if (m) return m.call(o);
|
||||
return {
|
||||
next: function () {
|
||||
if (o && i >= o.length) o = void 0;
|
||||
return {value: o && o[i++], done: !o};
|
||||
}
|
||||
};
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", {value: true});
|
||||
// const ripemd160 = require('./ripemd').RIPEMD160.hash as (a: Uint8Array) => ArrayBuffer;
|
||||
var crypto = require('crypto');
|
||||
|
||||
function ripemd160(data) {
|
||||
var hash = crypto.createHash('ripemd160');
|
||||
hash.update(data);
|
||||
return hash.digest('hex');
|
||||
}
|
||||
|
||||
var base58Chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
|
||||
var base64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
||||
|
||||
var bs58 = require('base-x')(base58Chars);
|
||||
|
||||
function create_base58_map() {
|
||||
var base58M = Array(256).fill(-1);
|
||||
for (var i = 0; i < base58Chars.length; ++i) {
|
||||
base58M[base58Chars.charCodeAt(i)] = i;
|
||||
}
|
||||
return base58M;
|
||||
}
|
||||
|
||||
var base58Map = create_base58_map();
|
||||
|
||||
function create_base64_map() {
|
||||
var base64M = Array(256).fill(-1);
|
||||
for (var i = 0; i < base64Chars.length; ++i) {
|
||||
base64M[base64Chars.charCodeAt(i)] = i;
|
||||
}
|
||||
base64M['='.charCodeAt(0)] = 0;
|
||||
return base64M;
|
||||
}
|
||||
|
||||
var base64Map = create_base64_map();
|
||||
|
||||
/** Is `bignum` a negative number? */
|
||||
function isNegative(bignum) {
|
||||
return (bignum[bignum.length - 1] & 0x80) !== 0;
|
||||
}
|
||||
|
||||
exports.isNegative = isNegative;
|
||||
|
||||
/** Negate `bignum` */
|
||||
function negate(bignum) {
|
||||
var carry = 1;
|
||||
for (var i = 0; i < bignum.length; ++i) {
|
||||
var x = (~bignum[i] & 0xff) + carry;
|
||||
bignum[i] = x;
|
||||
carry = x >> 8;
|
||||
}
|
||||
}
|
||||
|
||||
exports.negate = negate;
|
||||
|
||||
/**
|
||||
* Convert an unsigned decimal number in `s` to a bignum
|
||||
* @param size bignum size (bytes)
|
||||
*/
|
||||
function decimalToBinary(size, s) {
|
||||
var result = new Uint8Array(size);
|
||||
for (var i = 0; i < s.length; ++i) {
|
||||
var srcDigit = s.charCodeAt(i);
|
||||
if (srcDigit < '0'.charCodeAt(0) || srcDigit > '9'.charCodeAt(0)) {
|
||||
throw new Error('invalid number');
|
||||
}
|
||||
var carry = srcDigit - '0'.charCodeAt(0);
|
||||
for (var j = 0; j < size; ++j) {
|
||||
var x = result[j] * 10 + carry;
|
||||
result[j] = x;
|
||||
carry = x >> 8;
|
||||
}
|
||||
if (carry) {
|
||||
throw new Error('number is out of range');
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
exports.decimalToBinary = decimalToBinary;
|
||||
|
||||
/**
|
||||
* Convert a signed decimal number in `s` to a bignum
|
||||
* @param size bignum size (bytes)
|
||||
*/
|
||||
function signedDecimalToBinary(size, s) {
|
||||
var negative = s[0] === '-';
|
||||
if (negative) {
|
||||
s = s.substr(1);
|
||||
}
|
||||
var result = decimalToBinary(size, s);
|
||||
if (negative) {
|
||||
negate(result);
|
||||
if (!isNegative(result)) {
|
||||
throw new Error('number is out of range');
|
||||
}
|
||||
} else if (isNegative(result)) {
|
||||
throw new Error('number is out of range');
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
exports.signedDecimalToBinary = signedDecimalToBinary;
|
||||
|
||||
/**
|
||||
* Convert `bignum` to an unsigned decimal number
|
||||
* @param minDigits 0-pad result to this many digits
|
||||
*/
|
||||
function binaryToDecimal(bignum, minDigits) {
|
||||
if (minDigits === void 0) {
|
||||
minDigits = 1;
|
||||
}
|
||||
var result = Array(minDigits).fill('0'.charCodeAt(0));
|
||||
for (var i = bignum.length - 1; i >= 0; --i) {
|
||||
var carry = bignum[i];
|
||||
for (var j = 0; j < result.length; ++j) {
|
||||
var x = ((result[j] - '0'.charCodeAt(0)) << 8) + carry;
|
||||
result[j] = '0'.charCodeAt(0) + x % 10;
|
||||
carry = (x / 10) | 0;
|
||||
}
|
||||
while (carry) {
|
||||
result.push('0'.charCodeAt(0) + carry % 10);
|
||||
carry = (carry / 10) | 0;
|
||||
}
|
||||
}
|
||||
result.reverse();
|
||||
return String.fromCharCode.apply(String, __spread(result));
|
||||
}
|
||||
|
||||
exports.binaryToDecimal = binaryToDecimal;
|
||||
|
||||
/**
|
||||
* Convert `bignum` to a signed decimal number
|
||||
* @param minDigits 0-pad result to this many digits
|
||||
*/
|
||||
function signedBinaryToDecimal(bignum, minDigits) {
|
||||
if (minDigits === void 0) {
|
||||
minDigits = 1;
|
||||
}
|
||||
if (isNegative(bignum)) {
|
||||
var x = bignum.slice();
|
||||
negate(x);
|
||||
return '-' + binaryToDecimal(x, minDigits);
|
||||
}
|
||||
return binaryToDecimal(bignum, minDigits);
|
||||
}
|
||||
|
||||
exports.signedBinaryToDecimal = signedBinaryToDecimal;
|
||||
|
||||
/**
|
||||
* Convert an unsigned base-58 number in `s` to a bignum
|
||||
* @param size bignum size (bytes)
|
||||
*/
|
||||
function base58ToBinary(size, s) {
|
||||
var result = new Uint8Array(size);
|
||||
for (var i = 0; i < s.length; ++i) {
|
||||
var carry = base58Map[s.charCodeAt(i)];
|
||||
if (carry < 0) {
|
||||
throw new Error('invalid base-58 value');
|
||||
}
|
||||
for (var j = 0; j < size; ++j) {
|
||||
var x = result[j] * 58 + carry;
|
||||
result[j] = x;
|
||||
carry = x >> 8;
|
||||
}
|
||||
if (carry) {
|
||||
throw new Error('base-58 value is out of range');
|
||||
}
|
||||
}
|
||||
result.reverse();
|
||||
return result;
|
||||
}
|
||||
|
||||
exports.base58ToBinary = base58ToBinary;
|
||||
|
||||
/**
|
||||
* Convert `bignum` to a base-58 number
|
||||
* @param minDigits 0-pad result to this many digits
|
||||
*/
|
||||
function binaryToBase58(bignum, minDigits) {
|
||||
return bs58.encode(Buffer.from(bignum));
|
||||
// if (minDigits === void 0) {
|
||||
// minDigits = 1;
|
||||
// }
|
||||
// var e_1, _a, e_2, _b;
|
||||
// var result = [];
|
||||
// try {
|
||||
// for (var bignum_1 = __values(bignum), bignum_1_1 = bignum_1.next(); !bignum_1_1.done; bignum_1_1 = bignum_1.next()) {
|
||||
// var byte = bignum_1_1.value;
|
||||
// var carry = byte;
|
||||
// for (var j = 0; j < result.length; ++j) {
|
||||
// var x = (base58Map[result[j]] << 8) + carry;
|
||||
// result[j] = base58Chars.charCodeAt(x % 58);
|
||||
// carry = (x / 58) | 0;
|
||||
// }
|
||||
// while (carry) {
|
||||
// result.push(base58Chars.charCodeAt(carry % 58));
|
||||
// carry = (carry / 58) | 0;
|
||||
// }
|
||||
// }
|
||||
// } catch (e_1_1) {
|
||||
// e_1 = {error: e_1_1};
|
||||
// } finally {
|
||||
// try {
|
||||
// if (bignum_1_1 && !bignum_1_1.done && (_a = bignum_1.return)) _a.call(bignum_1);
|
||||
// } finally {
|
||||
// if (e_1) throw e_1.error;
|
||||
// }
|
||||
// }
|
||||
// try {
|
||||
// for (var bignum_2 = __values(bignum), bignum_2_1 = bignum_2.next(); !bignum_2_1.done; bignum_2_1 = bignum_2.next()) {
|
||||
// var byte = bignum_2_1.value;
|
||||
// if (byte) {
|
||||
// break;
|
||||
// } else {
|
||||
// result.push('1'.charCodeAt(0));
|
||||
// }
|
||||
// }
|
||||
// } catch (e_2_1) {
|
||||
// e_2 = {error: e_2_1};
|
||||
// } finally {
|
||||
// try {
|
||||
// if (bignum_2_1 && !bignum_2_1.done && (_b = bignum_2.return)) _b.call(bignum_2);
|
||||
// } finally {
|
||||
// if (e_2) throw e_2.error;
|
||||
// }
|
||||
// }
|
||||
// result.reverse();
|
||||
// return String.fromCharCode.apply(String, __spread(result));
|
||||
}
|
||||
|
||||
exports.binaryToBase58 = binaryToBase58;
|
||||
|
||||
/** Convert an unsigned base-64 number in `s` to a bignum */
|
||||
function base64ToBinary(s) {
|
||||
var len = s.length;
|
||||
if ((len & 3) === 1 && s[len - 1] === '=') {
|
||||
len -= 1;
|
||||
} // fc appends an extra '='
|
||||
if ((len & 3) !== 0) {
|
||||
throw new Error('base-64 value is not padded correctly');
|
||||
}
|
||||
var groups = len >> 2;
|
||||
var bytes = groups * 3;
|
||||
if (len > 0 && s[len - 1] === '=') {
|
||||
if (s[len - 2] === '=') {
|
||||
bytes -= 2;
|
||||
} else {
|
||||
bytes -= 1;
|
||||
}
|
||||
}
|
||||
var result = new Uint8Array(bytes);
|
||||
for (var group = 0; group < groups; ++group) {
|
||||
var digit0 = base64Map[s.charCodeAt(group * 4 + 0)];
|
||||
var digit1 = base64Map[s.charCodeAt(group * 4 + 1)];
|
||||
var digit2 = base64Map[s.charCodeAt(group * 4 + 2)];
|
||||
var digit3 = base64Map[s.charCodeAt(group * 4 + 3)];
|
||||
result[group * 3 + 0] = (digit0 << 2) | (digit1 >> 4);
|
||||
if (group * 3 + 1 < bytes) {
|
||||
result[group * 3 + 1] = ((digit1 & 15) << 4) | (digit2 >> 2);
|
||||
}
|
||||
if (group * 3 + 2 < bytes) {
|
||||
result[group * 3 + 2] = ((digit2 & 3) << 6) | digit3;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
exports.base64ToBinary = base64ToBinary;
|
||||
/** Key types this library supports */
|
||||
var KeyType;
|
||||
(function (KeyType) {
|
||||
KeyType[KeyType["k1"] = 0] = "k1";
|
||||
KeyType[KeyType["r1"] = 1] = "r1";
|
||||
})(KeyType = exports.KeyType || (exports.KeyType = {}));
|
||||
/** Public key data size, excluding type field */
|
||||
exports.publicKeyDataSize = 33;
|
||||
/** Private key data size, excluding type field */
|
||||
exports.privateKeyDataSize = 32;
|
||||
/** Signature data size, excluding type field */
|
||||
exports.signatureDataSize = 65;
|
||||
|
||||
function digestSuffixRipemd160(data, suffix) {
|
||||
var d = new Uint8Array(data.length + suffix.length);
|
||||
for (var i = 0; i < data.length; ++i) {
|
||||
d[i] = data[i];
|
||||
}
|
||||
for (var i = 0; i < suffix.length; ++i) {
|
||||
d[data.length + i] = suffix.charCodeAt(i);
|
||||
}
|
||||
return ripemd160(d);
|
||||
}
|
||||
|
||||
function stringToKey(s, type, size, suffix) {
|
||||
var whole = base58ToBinary(size + 4, s);
|
||||
var result = {type: type, data: new Uint8Array(whole.buffer, 0, size)};
|
||||
var digest = new Uint8Array(digestSuffixRipemd160(result.data, suffix));
|
||||
if (digest[0] !== whole[size + 0] || digest[1] !== whole[size + 1]
|
||||
|| digest[2] !== whole[size + 2] || digest[3] !== whole[size + 3]) {
|
||||
throw new Error('checksum doesn\'t match');
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function keyToString(key, suffix, prefix) {
|
||||
var digest = new Uint8Array(digestSuffixRipemd160(key.data, suffix));
|
||||
var whole = new Uint8Array(key.data.length + 4);
|
||||
for (var i = 0; i < key.data.length; ++i) {
|
||||
whole[i] = key.data[i];
|
||||
}
|
||||
for (var i = 0; i < 4; ++i) {
|
||||
whole[i + key.data.length] = digest[i];
|
||||
}
|
||||
return prefix + binaryToBase58(whole);
|
||||
}
|
||||
|
||||
/** Convert key in `s` to binary form */
|
||||
function stringToPublicKey(s) {
|
||||
if (typeof s !== 'string') {
|
||||
throw new Error('expected string containing public key');
|
||||
}
|
||||
if (s.substr(0, 3) === 'EOS') {
|
||||
var whole = base58ToBinary(exports.publicKeyDataSize + 4, s.substr(3));
|
||||
var key = {type: KeyType.k1, data: new Uint8Array(exports.publicKeyDataSize)};
|
||||
for (var i = 0; i < exports.publicKeyDataSize; ++i) {
|
||||
key.data[i] = whole[i];
|
||||
}
|
||||
var digest = new Uint8Array(ripemd160(key.data));
|
||||
if (digest[0] !== whole[exports.publicKeyDataSize] || digest[1] !== whole[34]
|
||||
|| digest[2] !== whole[35] || digest[3] !== whole[36]) {
|
||||
throw new Error('checksum doesn\'t match');
|
||||
}
|
||||
return key;
|
||||
} else if (s.substr(0, 7) === 'PUB_K1_') {
|
||||
return stringToKey(s.substr(7), KeyType.k1, exports.publicKeyDataSize, 'K1');
|
||||
} else if (s.substr(0, 7) === 'PUB_R1_') {
|
||||
return stringToKey(s.substr(7), KeyType.r1, exports.publicKeyDataSize, 'R1');
|
||||
} else {
|
||||
throw new Error('unrecognized public key format');
|
||||
}
|
||||
}
|
||||
|
||||
exports.stringToPublicKey = stringToPublicKey;
|
||||
|
||||
/** Convert `key` to string (base-58) form */
|
||||
function publicKeyToString(key) {
|
||||
if (key.type === KeyType.k1 && key.data.length === exports.publicKeyDataSize) {
|
||||
return keyToString(key, 'K1', 'PUB_K1_');
|
||||
} else if (key.type === KeyType.r1 && key.data.length === exports.publicKeyDataSize) {
|
||||
return keyToString(key, 'R1', 'PUB_R1_');
|
||||
} else {
|
||||
throw new Error('unrecognized public key format');
|
||||
}
|
||||
}
|
||||
|
||||
exports.publicKeyToString = publicKeyToString;
|
||||
|
||||
/** If a key is in the legacy format (`EOS` prefix), then convert it to the new format (`PUB_K1_`).
|
||||
* Leaves other formats untouched
|
||||
*/
|
||||
function convertLegacyPublicKey(s) {
|
||||
if (s.substr(0, 3) === 'EOS') {
|
||||
return publicKeyToString(stringToPublicKey(s));
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
exports.convertLegacyPublicKey = convertLegacyPublicKey;
|
||||
|
||||
/** If a key is in the legacy format (`EOS` prefix), then convert it to the new format (`PUB_K1_`).
|
||||
* Leaves other formats untouched
|
||||
*/
|
||||
function convertLegacyPublicKeys(keys) {
|
||||
return keys.map(convertLegacyPublicKey);
|
||||
}
|
||||
|
||||
exports.convertLegacyPublicKeys = convertLegacyPublicKeys;
|
||||
|
||||
/** Convert key in `s` to binary form */
|
||||
function stringToPrivateKey(s) {
|
||||
if (typeof s !== 'string') {
|
||||
throw new Error('expected string containing private key');
|
||||
}
|
||||
if (s.substr(0, 7) === 'PVT_R1_') {
|
||||
return stringToKey(s.substr(7), KeyType.r1, exports.privateKeyDataSize, 'R1');
|
||||
} else {
|
||||
throw new Error('unrecognized private key format');
|
||||
}
|
||||
}
|
||||
|
||||
exports.stringToPrivateKey = stringToPrivateKey;
|
||||
|
||||
/** Convert `key` to string (base-58) form */
|
||||
function privateKeyToString(key) {
|
||||
if (key.type === KeyType.r1) {
|
||||
return keyToString(key, 'R1', 'PVT_R1_');
|
||||
} else {
|
||||
throw new Error('unrecognized private key format');
|
||||
}
|
||||
}
|
||||
|
||||
exports.privateKeyToString = privateKeyToString;
|
||||
|
||||
/** Convert key in `s` to binary form */
|
||||
function stringToSignature(s) {
|
||||
if (typeof s !== 'string') {
|
||||
throw new Error('expected string containing signature');
|
||||
}
|
||||
if (s.substr(0, 7) === 'SIG_K1_') {
|
||||
return stringToKey(s.substr(7), KeyType.k1, exports.signatureDataSize, 'K1');
|
||||
} else if (s.substr(0, 7) === 'SIG_R1_') {
|
||||
return stringToKey(s.substr(7), KeyType.r1, exports.signatureDataSize, 'R1');
|
||||
} else {
|
||||
throw new Error('unrecognized signature format');
|
||||
}
|
||||
}
|
||||
|
||||
exports.stringToSignature = stringToSignature;
|
||||
|
||||
/** Convert `signature` to string (base-58) form */
|
||||
function signatureToString(signature) {
|
||||
if (signature.type === KeyType.k1) {
|
||||
return keyToString(signature, 'K1', 'SIG_K1_');
|
||||
} else if (signature.type === KeyType.r1) {
|
||||
return keyToString(signature, 'R1', 'SIG_R1_');
|
||||
} else {
|
||||
throw new Error('unrecognized signature format');
|
||||
}
|
||||
}
|
||||
|
||||
exports.signatureToString = signatureToString;
|
||||
//# sourceMappingURL=eosjs-numeric.js.map
|
||||
File diff suppressed because one or more lines are too long
-103
@@ -1,103 +0,0 @@
|
||||
/** Structured format for abis */
|
||||
export interface Abi {
|
||||
version: string;
|
||||
types: Array<{
|
||||
new_type_name: string;
|
||||
type: string;
|
||||
}>;
|
||||
structs: Array<{
|
||||
name: string;
|
||||
base: string;
|
||||
fields: Array<{
|
||||
name: string;
|
||||
type: string;
|
||||
}>;
|
||||
}>;
|
||||
actions: Array<{
|
||||
name: string;
|
||||
type: string;
|
||||
ricardian_contract: string;
|
||||
}>;
|
||||
tables: Array<{
|
||||
name: string;
|
||||
type: string;
|
||||
index_type: string;
|
||||
key_names: string[];
|
||||
key_types: string[];
|
||||
}>;
|
||||
ricardian_clauses: Array<{
|
||||
id: string;
|
||||
body: string;
|
||||
}>;
|
||||
error_messages: Array<{
|
||||
error_code: string;
|
||||
error_msg: string;
|
||||
}>;
|
||||
abi_extensions: Array<{
|
||||
tag: number;
|
||||
value: string;
|
||||
}>;
|
||||
variants?: Array<{
|
||||
name: string;
|
||||
types: string[];
|
||||
}>;
|
||||
}
|
||||
/** Return value of `/v1/chain/get_abi` */
|
||||
export interface GetAbiResult {
|
||||
account_name: string;
|
||||
abi: Abi;
|
||||
}
|
||||
/** Subset of `GetBlockResult` needed to calculate TAPoS fields in transactions */
|
||||
export interface BlockTaposInfo {
|
||||
timestamp: string;
|
||||
block_num: number;
|
||||
ref_block_prefix: number;
|
||||
}
|
||||
/** Return value of `/v1/chain/get_block` */
|
||||
export interface GetBlockResult {
|
||||
timestamp: string;
|
||||
producer: string;
|
||||
confirmed: number;
|
||||
previous: string;
|
||||
transaction_mroot: string;
|
||||
action_mroot: string;
|
||||
schedule_version: number;
|
||||
producer_signature: string;
|
||||
id: string;
|
||||
block_num: number;
|
||||
ref_block_prefix: number;
|
||||
}
|
||||
/** Return value of `/v1/chain/get_code` */
|
||||
export interface GetCodeResult {
|
||||
account_name: string;
|
||||
code_hash: string;
|
||||
wast: string;
|
||||
wasm: string;
|
||||
abi: Abi;
|
||||
}
|
||||
/** Return value of `/v1/chain/get_info` */
|
||||
export interface GetInfoResult {
|
||||
server_version: string;
|
||||
chain_id: string;
|
||||
head_block_num: number;
|
||||
last_irreversible_block_num: number;
|
||||
last_irreversible_block_id: string;
|
||||
head_block_id: string;
|
||||
head_block_time: string;
|
||||
head_block_producer: string;
|
||||
virtual_block_cpu_limit: number;
|
||||
virtual_block_net_limit: number;
|
||||
block_cpu_limit: number;
|
||||
block_net_limit: number;
|
||||
}
|
||||
/** Return value of `/v1/chain/get_raw_code_and_abi` */
|
||||
export interface GetRawCodeAndAbiResult {
|
||||
account_name: string;
|
||||
wasm: string;
|
||||
abi: string;
|
||||
}
|
||||
/** Arguments for `push_transaction` */
|
||||
export interface PushTransactionArgs {
|
||||
signatures: string[];
|
||||
serializedTransaction: Uint8Array;
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
"use strict";
|
||||
// copyright defined in eosjs/LICENSE.txt
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
//# sourceMappingURL=eosjs-rpc-interfaces.js.map
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"eosjs-rpc-interfaces.js","sourceRoot":"","sources":["../src/eosjs-rpc-interfaces.ts"],"names":[],"mappings":";AAAA,yCAAyC"}
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
/**
|
||||
* @module RPC-Error
|
||||
*/
|
||||
/** Holds detailed error information */
|
||||
export declare class RpcError extends Error {
|
||||
/** Detailed error information */
|
||||
json: any;
|
||||
constructor(json: any);
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
"use strict";
|
||||
/**
|
||||
* @module RPC-Error
|
||||
*/
|
||||
// copyright defined in eosjs/LICENSE.txt
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
/** Holds detailed error information */
|
||||
var RpcError = /** @class */ (function (_super) {
|
||||
__extends(RpcError, _super);
|
||||
function RpcError(json) {
|
||||
var _this = this;
|
||||
if (json.error && json.error.details && json.error.details.length && json.error.details[0].message) {
|
||||
_this = _super.call(this, json.error.details[0].message) || this;
|
||||
}
|
||||
else if (json.processed && json.processed.except && json.processed.except.message) {
|
||||
_this = _super.call(this, json.processed.except.message) || this;
|
||||
}
|
||||
else {
|
||||
_this = _super.call(this, json.message) || this;
|
||||
}
|
||||
Object.setPrototypeOf(_this, RpcError.prototype);
|
||||
_this.json = json;
|
||||
return _this;
|
||||
}
|
||||
return RpcError;
|
||||
}(Error));
|
||||
exports.RpcError = RpcError;
|
||||
//# sourceMappingURL=eosjs-rpcerror.js.map
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"eosjs-rpcerror.js","sourceRoot":"","sources":["../src/eosjs-rpcerror.ts"],"names":[],"mappings":";AAAA;;GAEG;AACH,yCAAyC;;;;;;;;;;;;;;;AAEzC,uCAAuC;AACvC;IAA8B,4BAAK;IAI/B,kBAAY,IAAS;QAArB,iBAUC;QATG,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE;YAChG,QAAA,kBAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAC;SACxC;aAAM,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,EAAE;YACjF,QAAA,kBAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,SAAC;SACxC;aAAM;YACH,QAAA,kBAAM,IAAI,CAAC,OAAO,CAAC,SAAC;SACvB;QACD,MAAM,CAAC,cAAc,CAAC,KAAI,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;QAChD,KAAI,CAAC,IAAI,GAAG,IAAI,CAAC;;IACrB,CAAC;IACL,eAAC;AAAD,CAAC,AAfD,CAA8B,KAAK,GAelC;AAfY,4BAAQ"}
|
||||
-241
@@ -1,241 +0,0 @@
|
||||
/**
|
||||
* @module Serialize
|
||||
*/
|
||||
import { Abi, BlockTaposInfo } from './eosjs-rpc-interfaces';
|
||||
/** A field in an abi */
|
||||
export interface Field {
|
||||
/** Field name */
|
||||
name: string;
|
||||
/** Type name in string form */
|
||||
typeName: string;
|
||||
/** Type of the field */
|
||||
type: Type;
|
||||
}
|
||||
/** Options for serialize() and deserialize() */
|
||||
export interface SerializerOptions {
|
||||
bytesAsUint8Array?: boolean;
|
||||
}
|
||||
/** State for serialize() and deserialize() */
|
||||
export declare class SerializerState {
|
||||
options: SerializerOptions;
|
||||
/** Have any binary extensions been skipped? */
|
||||
skippedBinaryExtension: boolean;
|
||||
constructor(options?: SerializerOptions);
|
||||
}
|
||||
/** A type in an abi */
|
||||
export interface Type {
|
||||
/** Type name */
|
||||
name: string;
|
||||
/** Type name this is an alias of, if any */
|
||||
aliasOfName: string;
|
||||
/** Type this is an array of, if any */
|
||||
arrayOf: Type;
|
||||
/** Type this is an optional of, if any */
|
||||
optionalOf: Type;
|
||||
/** Marks binary extension fields */
|
||||
extensionOf?: Type;
|
||||
/** Base name of this type, if this is a struct */
|
||||
baseName: string;
|
||||
/** Base of this type, if this is a struct */
|
||||
base: Type;
|
||||
/** Contained fields, if this is a struct */
|
||||
fields: Field[];
|
||||
/** Convert `data` to binary form and store in `buffer` */
|
||||
serialize: (buffer: SerialBuffer, data: any, state?: SerializerState, allowExtensions?: boolean) => void;
|
||||
/** Convert data in `buffer` from binary form */
|
||||
deserialize: (buffer: SerialBuffer, state?: SerializerState, allowExtensions?: boolean) => any;
|
||||
}
|
||||
/** Structural representation of a symbol */
|
||||
export interface Symbol {
|
||||
/** Name of the symbol, not including precision */
|
||||
name: string;
|
||||
/** Number of digits after the decimal point */
|
||||
precision: number;
|
||||
}
|
||||
export interface Contract {
|
||||
actions: Map<string, Type>;
|
||||
types: Map<string, Type>;
|
||||
}
|
||||
export interface Authorization {
|
||||
actor: string;
|
||||
permission: string;
|
||||
}
|
||||
/** Action with data in structured form */
|
||||
export interface Action {
|
||||
account: string;
|
||||
name: string;
|
||||
authorization: Authorization[];
|
||||
data: any;
|
||||
}
|
||||
/** Action with data in serialized hex form */
|
||||
export interface SerializedAction {
|
||||
account: string;
|
||||
name: string;
|
||||
authorization: Authorization[];
|
||||
data: string;
|
||||
}
|
||||
/** Serialize and deserialize data */
|
||||
export declare class SerialBuffer {
|
||||
/** Amount of valid data in `array` */
|
||||
length: number;
|
||||
/** Data in serialized (binary) form */
|
||||
array: Uint8Array;
|
||||
/** Current position while reading (deserializing) */
|
||||
readPos: number;
|
||||
textEncoder: TextEncoder;
|
||||
textDecoder: TextDecoder;
|
||||
/**
|
||||
* @param __namedParameters
|
||||
* * `array`: `null` if serializing, or binary data to deserialize
|
||||
* * `textEncoder`: `TextEncoder` instance to use. Pass in `null` if running in a browser
|
||||
* * `textDecoder`: `TextDecider` instance to use. Pass in `null` if running in a browser
|
||||
*/
|
||||
constructor({ textEncoder, textDecoder, array }?: {
|
||||
textEncoder?: TextEncoder;
|
||||
textDecoder?: TextDecoder;
|
||||
array?: Uint8Array;
|
||||
});
|
||||
/** Resize `array` if needed to have at least `size` bytes free */
|
||||
reserve(size: number): void;
|
||||
/** Is there data available to read? */
|
||||
haveReadData(): boolean;
|
||||
/** Restart reading from the beginning */
|
||||
restartRead(): void;
|
||||
/** Return data with excess storage trimmed away */
|
||||
asUint8Array(): Uint8Array;
|
||||
/** Append bytes */
|
||||
pushArray(v: number[] | Uint8Array): void;
|
||||
/** Append bytes */
|
||||
push(...v: number[]): void;
|
||||
/** Get a single byte */
|
||||
get(): number;
|
||||
/** Append bytes in `v`. Throws if `len` doesn't match `v.length` */
|
||||
pushUint8ArrayChecked(v: Uint8Array, len: number): void;
|
||||
/** Get `len` bytes */
|
||||
getUint8Array(len: number): Uint8Array;
|
||||
/** Append a `uint16` */
|
||||
pushUint16(v: number): void;
|
||||
/** Get a `uint16` */
|
||||
getUint16(): number;
|
||||
/** Append a `uint32` */
|
||||
pushUint32(v: number): void;
|
||||
/** Get a `uint32` */
|
||||
getUint32(): number;
|
||||
/** Append a `uint64`. *Caution*: `number` only has 53 bits of precision */
|
||||
pushNumberAsUint64(v: number): void;
|
||||
/**
|
||||
* Get a `uint64` as a `number`. *Caution*: `number` only has 53 bits of precision; some values will change.
|
||||
* `numeric.binaryToDecimal(serialBuffer.getUint8Array(8))` recommended instead
|
||||
*/
|
||||
getUint64AsNumber(): number;
|
||||
/** Append a `varuint32` */
|
||||
pushVaruint32(v: number): void;
|
||||
/** Get a `varuint32` */
|
||||
getVaruint32(): number;
|
||||
/** Append a `varint32` */
|
||||
pushVarint32(v: number): void;
|
||||
/** Get a `varint32` */
|
||||
getVarint32(): number;
|
||||
/** Append a `float32` */
|
||||
pushFloat32(v: number): void;
|
||||
/** Get a `float32` */
|
||||
getFloat32(): number;
|
||||
/** Append a `float64` */
|
||||
pushFloat64(v: number): void;
|
||||
/** Get a `float64` */
|
||||
getFloat64(): number;
|
||||
/** Append a `name` */
|
||||
pushName(s: string): void;
|
||||
/** Get a `name` */
|
||||
getName(): string;
|
||||
/** Append length-prefixed binary data */
|
||||
pushBytes(v: number[] | Uint8Array): void;
|
||||
/** Get length-prefixed binary data */
|
||||
getBytes(): Uint8Array;
|
||||
/** Append a string */
|
||||
pushString(v: string): void;
|
||||
/** Get a string */
|
||||
getString(): string;
|
||||
/** Append a `symbol_code`. Unlike `symbol`, `symbol_code` doesn't include a precision. */
|
||||
pushSymbolCode(name: string): void;
|
||||
/** Get a `symbol_code`. Unlike `symbol`, `symbol_code` doesn't include a precision. */
|
||||
getSymbolCode(): string;
|
||||
/** Append a `symbol` */
|
||||
pushSymbol({ name, precision }: {
|
||||
name: string;
|
||||
precision: number;
|
||||
}): void;
|
||||
/** Get a `symbol` */
|
||||
getSymbol(): {
|
||||
name: string;
|
||||
precision: number;
|
||||
};
|
||||
/** Append an asset */
|
||||
pushAsset(s: string): void;
|
||||
/** Get an asset */
|
||||
getAsset(): string;
|
||||
/** Append a public key */
|
||||
pushPublicKey(s: string): void;
|
||||
/** Get a public key */
|
||||
getPublicKey(): string;
|
||||
/** Append a private key */
|
||||
pushPrivateKey(s: string): void;
|
||||
/** Get a private key */
|
||||
getPrivateKey(): string;
|
||||
/** Append a signature */
|
||||
pushSignature(s: string): void;
|
||||
/** Get a signature */
|
||||
getSignature(): string;
|
||||
}
|
||||
/** Is this a supported ABI version? */
|
||||
export declare function supportedAbiVersion(version: string): boolean;
|
||||
/** Convert date in ISO format to `time_point` (miliseconds since epoch) */
|
||||
export declare function dateToTimePoint(date: string): number;
|
||||
/** Convert `time_point` (miliseconds since epoch) to date in ISO format */
|
||||
export declare function timePointToDate(us: number): string;
|
||||
/** Convert date in ISO format to `time_point_sec` (seconds since epoch) */
|
||||
export declare function dateToTimePointSec(date: string): number;
|
||||
/** Convert `time_point_sec` (seconds since epoch) to to date in ISO format */
|
||||
export declare function timePointSecToDate(sec: number): string;
|
||||
/** Convert date in ISO format to `block_timestamp_type` (half-seconds since a different epoch) */
|
||||
export declare function dateToBlockTimestamp(date: string): number;
|
||||
/** Convert `block_timestamp_type` (half-seconds since a different epoch) to to date in ISO format */
|
||||
export declare function blockTimestampToDate(slot: number): string;
|
||||
/** Convert `string` to `Symbol`. format: `precision,NAME`. */
|
||||
export declare function stringToSymbol(s: string): {
|
||||
name: string;
|
||||
precision: number;
|
||||
};
|
||||
/** Convert `Symbol` to `string`. format: `precision,NAME`. */
|
||||
export declare function symbolToString({ name, precision }: {
|
||||
name: string;
|
||||
precision: number;
|
||||
}): string;
|
||||
/** Convert binary data to hex */
|
||||
export declare function arrayToHex(data: Uint8Array): string;
|
||||
/** Convert hex to binary data */
|
||||
export declare function hexToUint8Array(hex: string): Uint8Array;
|
||||
/** Create the set of types built-in to the abi format */
|
||||
export declare function createInitialTypes(): Map<string, Type>;
|
||||
/** Get type from `types` */
|
||||
export declare function getType(types: Map<string, Type>, name: string): Type;
|
||||
/**
|
||||
* Get types from abi
|
||||
* @param initialTypes Set of types to build on.
|
||||
* In most cases, it's best to fill this from a fresh call to `getTypesFromAbi()`.
|
||||
*/
|
||||
export declare function getTypesFromAbi(initialTypes: Map<string, Type>, abi: Abi): Map<string, Type>;
|
||||
/** TAPoS: Return transaction fields which reference `refBlock` and expire `expireSeconds` after `refBlock.timestamp` */
|
||||
export declare function transactionHeader(refBlock: BlockTaposInfo, expireSeconds: number): {
|
||||
expiration: string;
|
||||
ref_block_num: number;
|
||||
ref_block_prefix: number;
|
||||
};
|
||||
/** Convert action data to serialized form (hex) */
|
||||
export declare function serializeActionData(contract: Contract, account: string, name: string, data: any, textEncoder: TextEncoder, textDecoder: TextDecoder): string;
|
||||
/** Return action in serialized form */
|
||||
export declare function serializeAction(contract: Contract, account: string, name: string, authorization: Authorization[], data: any, textEncoder: TextEncoder, textDecoder: TextDecoder): SerializedAction;
|
||||
/** Deserialize action data. If `data` is a `string`, then it's assumed to be in hex. */
|
||||
export declare function deserializeActionData(contract: Contract, account: string, name: string, data: string | Uint8Array | number[], textEncoder: TextEncoder, textDecoder: TextDecoder): any;
|
||||
/** Deserialize action. If `data` is a `string`, then it's assumed to be in hex. */
|
||||
export declare function deserializeAction(contract: Contract, account: string, name: string, authorization: Authorization[], data: string | Uint8Array | number[], textEncoder: TextEncoder, textDecoder: TextDecoder): Action;
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
Vendored
-8
@@ -1,8 +0,0 @@
|
||||
import { Api } from './eosjs-api';
|
||||
import * as ApiInterfaces from './eosjs-api-interfaces';
|
||||
import { JsonRpc } from './eosjs-jsonrpc';
|
||||
import * as Numeric from './eosjs-numeric';
|
||||
import * as RpcInterfaces from './eosjs-rpc-interfaces';
|
||||
import { RpcError } from './eosjs-rpcerror';
|
||||
import * as Serialize from './eosjs-serialize';
|
||||
export { Api, ApiInterfaces, JsonRpc, Numeric, RpcInterfaces, RpcError, Serialize };
|
||||
@@ -1,17 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var eosjs_api_1 = require("./eosjs-api");
|
||||
exports.Api = eosjs_api_1.Api;
|
||||
var ApiInterfaces = require("./eosjs-api-interfaces");
|
||||
exports.ApiInterfaces = ApiInterfaces;
|
||||
var eosjs_jsonrpc_1 = require("./eosjs-jsonrpc");
|
||||
exports.JsonRpc = eosjs_jsonrpc_1.JsonRpc;
|
||||
var Numeric = require("./eosjs-numeric");
|
||||
exports.Numeric = Numeric;
|
||||
var RpcInterfaces = require("./eosjs-rpc-interfaces");
|
||||
exports.RpcInterfaces = RpcInterfaces;
|
||||
var eosjs_rpcerror_1 = require("./eosjs-rpcerror");
|
||||
exports.RpcError = eosjs_rpcerror_1.RpcError;
|
||||
var Serialize = require("./eosjs-serialize");
|
||||
exports.Serialize = Serialize;
|
||||
//# sourceMappingURL=index.js.map
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,yCAAkC;AAQzB,cARA,eAAG,CAQA;AAPZ,sDAAwD;AAO1C,sCAAa;AAN3B,iDAA0C;AAMb,kBANpB,uBAAO,CAMoB;AALpC,yCAA2C;AAKL,0BAAO;AAJ7C,sDAAwD;AAIT,sCAAa;AAH5D,mDAA4C;AAGkB,mBAHrD,yBAAQ,CAGqD;AAFtE,6CAA+C;AAEyB,8BAAS"}
|
||||
@@ -1,401 +0,0 @@
|
||||
// https://gist.githubusercontent.com/wlzla000/bac83df6d3c51916c4dd0bc947e46947/raw/7ee3462b095ab22580ddaf191f44a590da6fe33b/RIPEMD-160.js
|
||||
|
||||
/*
|
||||
RIPEMD-160.js
|
||||
|
||||
developed
|
||||
by K. (https://github.com/wlzla000)
|
||||
on December 27-29, 2017,
|
||||
|
||||
licensed under
|
||||
|
||||
|
||||
the MIT license
|
||||
|
||||
Copyright (c) 2017 K.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
|
||||
|
||||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
var RIPEMD160 = function () {
|
||||
function RIPEMD160() {
|
||||
// https://webcache.googleusercontent.com/search?q=cache:CnLOgolTHYEJ:https://www.cosic.esat.kuleuven.be/publications/article-317.pdf
|
||||
// http://shodhganga.inflibnet.ac.in/bitstream/10603/22978/13/13_appendix.pdf
|
||||
|
||||
_classCallCheck(this, RIPEMD160);
|
||||
}
|
||||
|
||||
_createClass(RIPEMD160, null, [{
|
||||
key: "get_n_pad_bytes",
|
||||
value: function get_n_pad_bytes(message_size /* in bytes, 1 byte is 8 bits. */) {
|
||||
// Obtain the number of bytes needed to pad the message.
|
||||
// It does not contain the size of the message size information.
|
||||
/*
|
||||
https://webcache.googleusercontent.com/search?q=cache:CnLOgolTHYEJ:https://www.cosic.esat.kuleuven.be/publications/article-317.pdf
|
||||
The Cryptographic Hash Function RIPEMD-160
|
||||
written by
|
||||
Bart Preneel,
|
||||
Hans Dobbertin,
|
||||
Antoon Bosselaers
|
||||
in
|
||||
1997.
|
||||
--------------------------------------------------
|
||||
§5 Description of RIPEMD-160
|
||||
......
|
||||
In order to guarantee that the total input size is a
|
||||
multiple of 512 bits, the input is padded in the same
|
||||
way as for all the members of the MD4-family: one
|
||||
appends a single 1 followed by a string of 0s (the
|
||||
number of 0s lies between 0 and 511); the last 64 bits
|
||||
of the extended input contain the binary representation
|
||||
of the input size in bits, least significant byte first.
|
||||
*/
|
||||
/*
|
||||
https://tools.ietf.org/rfc/rfc1186.txt
|
||||
RFC 1186: MD4 Message Digest Algorithm.
|
||||
written by
|
||||
Ronald Linn Rivest
|
||||
in
|
||||
October 1990.
|
||||
--------------------------------------------------
|
||||
§3 MD4 Algorithm Description
|
||||
......
|
||||
Step 1. Append padding bits
|
||||
The message is "padded" (extended) so that its length
|
||||
(in bits) is congruent to 448, modulo 512. That is, the
|
||||
message is extended so that it is just 64 bits shy of
|
||||
being a multiple of 512 bits long. Padding is always
|
||||
performed, even if the length of the message is already
|
||||
congruent to 448, modulo 512 (in which case 512 bits of
|
||||
padding are added).
|
||||
Padding is performed as follows: a single "1" bit is
|
||||
appended to the message, and then enough zero bits are
|
||||
appended so that the length in bits of the padded
|
||||
message becomes congruent to 448, modulo 512.
|
||||
Step 2. Append length
|
||||
A 64-bit representation of b (the length of the message
|
||||
before the padding bits were added) is appended to the
|
||||
result of the previous step. In the unlikely event that
|
||||
b is greater than 2^64, then only the low-order 64 bits
|
||||
of b are used. (These bits are appended as two 32-bit
|
||||
words and appended low-order word first in accordance
|
||||
with the previous conventions.)
|
||||
At this point the resulting message (after padding with
|
||||
bits and with b) has a length that is an exact multiple
|
||||
of 512 bits. Equivalently, this message has a length
|
||||
that is an exact multiple of 16 (32-bit) words. Let
|
||||
M[0 ... N-1] denote the words of the resulting message,
|
||||
where N is a multiple of 16.
|
||||
*/
|
||||
// https://crypto.stackexchange.com/a/32407/54568
|
||||
/*
|
||||
Example case # 1
|
||||
[0 bit: message.]
|
||||
[1 bit: 1.]
|
||||
[447 bits: 0.]
|
||||
[64 bits: message size information.]
|
||||
Example case # 2
|
||||
[512-bits: message]
|
||||
[1 bit: 1.]
|
||||
[447 bits: 0.]
|
||||
[64 bits: message size information.]
|
||||
Example case # 3
|
||||
[(512 - 64 = 448) bits: message.]
|
||||
[1 bit: 1.]
|
||||
[511 bits: 0.]
|
||||
[64 bits: message size information.]
|
||||
Example case # 4
|
||||
[(512 - 65 = 447) bits: message.]
|
||||
[1 bit: 1.]
|
||||
[0 bit: 0.]
|
||||
[64 bits: message size information.]
|
||||
*/
|
||||
// The number of padding zero bits:
|
||||
// 511 - [{(message size in bits) + 64} (mod 512)]
|
||||
return 64 - (message_size + 8 & 63 /* 63 */);
|
||||
}
|
||||
}, {
|
||||
key: "pad",
|
||||
value: function pad(message /* An ArrayBuffer. */) {
|
||||
var message_size = message.byteLength;
|
||||
var n_pad = RIPEMD160.get_n_pad_bytes(message_size);
|
||||
|
||||
// `Number.MAX_SAFE_INTEGER` is ((2 ** 53) - 1) and
|
||||
// bitwise operation in Javascript is done on 32-bits operands.
|
||||
var divmod = function divmod(dividend, divisor) {
|
||||
return [Math.floor(dividend / divisor), dividend % divisor];
|
||||
};
|
||||
/*
|
||||
To shift
|
||||
00000000 000????? ???????? ???????? ???????? ???????? ???????? ????????
|
||||
t o
|
||||
00000000 ???????? ???????? ???????? ???????? ???????? ???????? ?????000
|
||||
--------------------------------------------------------------------------------
|
||||
Method #1
|
||||
00000000 000????? ???????? ???????? ???????? ???????? ???????? ????????
|
||||
[00000000 000AAAAA AAAAAAAA AAAAAAAA] (<A> captured)
|
||||
[00000000 AAAAAAAA AAAAAAAA AAAAA000] (<A> shifted)
|
||||
(<B> captured) [BBBBBBBB BBBBBBBB BBBBBBBB BBBBBBBB]
|
||||
(<B> shifted) [BBB][BBBBBBBB BBBBBBBB BBBBBBBB BBBBB000]
|
||||
[00000000 AAAAAAAA AAAAAAAA AAAAABBB] (<A> & <B_2> merged)
|
||||
[00000000 AAAAAAAA AAAAAAAA AAAAABBB][BBBBBBBB BBBBBBBB BBBBBBBB BBBBB000]
|
||||
00000000 ???????? ???????? ???????? ???????? ???????? ???????? ?????000
|
||||
const uint32_max_plus_1 = 0x100000000; // (2 ** 32)
|
||||
const [
|
||||
msg_byte_size_most, // Value range [0, (2 ** 21) - 1].
|
||||
msg_byte_size_least // Value range [0, (2 ** 32) - 1].
|
||||
] = divmod(message_size, uint32_max_plus_1);
|
||||
const [
|
||||
carry, // Value range [0, 7].
|
||||
msg_bit_size_least // Value range [0, (2 ** 32) - 8].
|
||||
] = divmod(message_byte_size_least * 8, uint32_max_plus_1);
|
||||
const message_bit_size_most = message_byte_size_most * 8
|
||||
+ carry; // Value range [0, (2 ** 24) - 1].
|
||||
--------------------------------------------------------------------------------
|
||||
Method #2
|
||||
00000000 000????? ???????? ???????? ???????? ???????? ???????? ????????
|
||||
[00000 000AAAAA AAAAAAAA AAAAAAAA AAA] (<A> captured)
|
||||
(<B> captured) [000BBBBB BBBBBBBB BBBBBBBB BBBBBBBB]
|
||||
(<B> shifted) [BBBBBBBB BBBBBBBB BBBBBBBB BBBBB000]
|
||||
[00000000 AAAAAAAA AAAAAAAA AAAAAAAA][BBBBBBBB BBBBBBBB BBBBBBBB BBBBB000]
|
||||
00000000 ???????? ???????? ???????? ???????? ???????? ???????? ?????000
|
||||
*/
|
||||
|
||||
var _divmod$map = divmod(message_size, 536870912 /* (2 ** 29) */).map(function (x, index) {
|
||||
return index ? x * 8 : x;
|
||||
}),
|
||||
_divmod$map2 = _slicedToArray(_divmod$map, 2),
|
||||
msg_bit_size_most = _divmod$map2[0],
|
||||
msg_bit_size_least = _divmod$map2[1];
|
||||
|
||||
// `ArrayBuffer.transfer()` is not supported.
|
||||
|
||||
|
||||
var padded = new Uint8Array(message_size + n_pad + 8);
|
||||
padded.set(new Uint8Array(message), 0);
|
||||
var data_view = new DataView(padded.buffer);
|
||||
data_view.setUint8(message_size, 128);
|
||||
data_view.setUint32(message_size + n_pad, msg_bit_size_least, true // Little-endian
|
||||
);
|
||||
data_view.setUint32(message_size + n_pad + 4, msg_bit_size_most, true // Little-endian
|
||||
);
|
||||
|
||||
return padded.buffer;
|
||||
}
|
||||
}, {
|
||||
key: "f",
|
||||
value: function f(j, x, y, z) {
|
||||
if (0 <= j && j <= 15) {
|
||||
// Exclusive-OR
|
||||
return x ^ y ^ z;
|
||||
}
|
||||
if (16 <= j && j <= 31) {
|
||||
// Multiplexing (muxing)
|
||||
return x & y | ~x & z;
|
||||
}
|
||||
if (32 <= j && j <= 47) {
|
||||
return (x | ~y) ^ z;
|
||||
}
|
||||
if (48 <= j && j <= 63) {
|
||||
// Multiplexing (muxing)
|
||||
return x & z | y & ~z;
|
||||
}
|
||||
if (64 <= j && j <= 79) {
|
||||
return x ^ (y | ~z);
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: "K",
|
||||
value: function K(j) {
|
||||
if (0 <= j && j <= 15) {
|
||||
return 0x00000000;
|
||||
}
|
||||
if (16 <= j && j <= 31) {
|
||||
// Math.floor((2 ** 30) * Math.SQRT2)
|
||||
return 0x5A827999;
|
||||
}
|
||||
if (32 <= j && j <= 47) {
|
||||
// Math.floor((2 ** 30) * Math.sqrt(3))
|
||||
return 0x6ED9EBA1;
|
||||
}
|
||||
if (48 <= j && j <= 63) {
|
||||
// Math.floor((2 ** 30) * Math.sqrt(5))
|
||||
return 0x8F1BBCDC;
|
||||
}
|
||||
if (64 <= j && j <= 79) {
|
||||
// Math.floor((2 ** 30) * Math.sqrt(7))
|
||||
return 0xA953FD4E;
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: "KP",
|
||||
value: function KP(j) // K'
|
||||
{
|
||||
if (0 <= j && j <= 15) {
|
||||
// Math.floor((2 ** 30) * Math.cbrt(2))
|
||||
return 0x50A28BE6;
|
||||
}
|
||||
if (16 <= j && j <= 31) {
|
||||
// Math.floor((2 ** 30) * Math.cbrt(3))
|
||||
return 0x5C4DD124;
|
||||
}
|
||||
if (32 <= j && j <= 47) {
|
||||
// Math.floor((2 ** 30) * Math.cbrt(5))
|
||||
return 0x6D703EF3;
|
||||
}
|
||||
if (48 <= j && j <= 63) {
|
||||
// Math.floor((2 ** 30) * Math.cbrt(7))
|
||||
return 0x7A6D76E9;
|
||||
}
|
||||
if (64 <= j && j <= 79) {
|
||||
return 0x00000000;
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: "add_modulo32",
|
||||
value: function add_modulo32() /* ...... */{
|
||||
// 1. Modulo addition (addition modulo) is associative.
|
||||
// https://proofwiki.org/wiki/Modulo_Addition_is_Associative
|
||||
// 2. Bitwise operation in Javascript
|
||||
// is done on 32-bits operands
|
||||
// and results in a 32-bits value.
|
||||
return Array.from(arguments).reduce(function (a, b) {
|
||||
return a + b;
|
||||
}, 0) | 0;
|
||||
}
|
||||
}, {
|
||||
key: "rol32",
|
||||
value: function rol32(value, count) {
|
||||
// Cyclic left shift (rotate) on 32-bits value.
|
||||
return value << count | value >>> 32 - count;
|
||||
}
|
||||
}, {
|
||||
key: "hash",
|
||||
value: function hash(message /* An ArrayBuffer. */) {
|
||||
////////// Padding //////////
|
||||
|
||||
// The padded message.
|
||||
var padded = RIPEMD160.pad(message);
|
||||
|
||||
////////// Compression //////////
|
||||
|
||||
// Message word selectors.
|
||||
var r = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2, 4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13];
|
||||
var rP = [// r'
|
||||
5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14, 12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11];
|
||||
|
||||
// Amounts for 'rotate left' operation.
|
||||
var s = [11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12, 9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6];
|
||||
var sP = [// s'
|
||||
8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11];
|
||||
|
||||
// The size, in bytes, of a word.
|
||||
var word_size = 4;
|
||||
|
||||
// The size, in bytes, of a 16-words block.
|
||||
var block_size = 64;
|
||||
|
||||
// The number of the 16-words blocks.
|
||||
var t = padded.byteLength / block_size;
|
||||
|
||||
// The message after padding consists of t 16-word blocks that
|
||||
// are denoted with X_i[j], with 0≤i≤(t − 1) and 0≤j≤15.
|
||||
var X = new Array(t).fill(undefined).map(function (_, i) {
|
||||
return function (j) {
|
||||
return new DataView(padded, i * block_size, block_size).getUint32(j * word_size, true // Little-endian
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
// The result of RIPEMD-160 is contained in five 32-bit words,
|
||||
// which form the internal state of the algorithm. The final
|
||||
// content of these five 32-bit words is converted to a 160-bit
|
||||
// string, again using the little-endian convention.
|
||||
var h = [0x67452301, // h_0
|
||||
0xEFCDAB89, // h_1
|
||||
0x98BADCFE, // h_2
|
||||
0x10325476, // h_3
|
||||
0xC3D2E1F0 // h_4
|
||||
];
|
||||
|
||||
for (var i = 0; i < t; ++i) {
|
||||
var A = h[0],
|
||||
B = h[1],
|
||||
C = h[2],
|
||||
D = h[3],
|
||||
E = h[4];
|
||||
var AP = A,
|
||||
BP = B,
|
||||
CP = C,
|
||||
DP = D,
|
||||
EP = E;
|
||||
for (var j = 0; j < 80; ++j) {
|
||||
// Left rounds
|
||||
var _T = RIPEMD160.add_modulo32(RIPEMD160.rol32(RIPEMD160.add_modulo32(A, RIPEMD160.f(j, B, C, D), X[i](r[j]), RIPEMD160.K(j)), s[j]), E);
|
||||
A = E;
|
||||
E = D;
|
||||
D = RIPEMD160.rol32(C, 10);
|
||||
C = B;
|
||||
B = _T;
|
||||
|
||||
// Right rounds
|
||||
_T = RIPEMD160.add_modulo32(RIPEMD160.rol32(RIPEMD160.add_modulo32(AP, RIPEMD160.f(79 - j, BP, CP, DP), X[i](rP[j]), RIPEMD160.KP(j)), sP[j]), EP);
|
||||
AP = EP;
|
||||
EP = DP;
|
||||
DP = RIPEMD160.rol32(CP, 10);
|
||||
CP = BP;
|
||||
BP = _T;
|
||||
}
|
||||
var T = RIPEMD160.add_modulo32(h[1], C, DP);
|
||||
h[1] = RIPEMD160.add_modulo32(h[2], D, EP);
|
||||
h[2] = RIPEMD160.add_modulo32(h[3], E, AP);
|
||||
h[3] = RIPEMD160.add_modulo32(h[4], A, BP);
|
||||
h[4] = RIPEMD160.add_modulo32(h[0], B, CP);
|
||||
h[0] = T;
|
||||
}
|
||||
|
||||
// The final output string then consists of the concatenatation
|
||||
// of h_0, h_1, h_2, h_3, and h_4 after converting each h_i to a
|
||||
// 4-byte string using the little-endian convention.
|
||||
var result = new ArrayBuffer(20);
|
||||
var data_view = new DataView(result);
|
||||
h.forEach(function (h_i, i) {
|
||||
return data_view.setUint32(i * 4, h_i, true);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}]);
|
||||
|
||||
return RIPEMD160;
|
||||
}();
|
||||
|
||||
module.exports = {
|
||||
RIPEMD160: RIPEMD160
|
||||
};
|
||||
Vendored
-3
@@ -1,3 +0,0 @@
|
||||
import { JsonRpc } from './eosjs-jsonrpc';
|
||||
import { RpcError } from './eosjs-rpcerror';
|
||||
export { JsonRpc, RpcError };
|
||||
@@ -1,7 +0,0 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var eosjs_jsonrpc_1 = require("./eosjs-jsonrpc");
|
||||
exports.JsonRpc = eosjs_jsonrpc_1.JsonRpc;
|
||||
var eosjs_rpcerror_1 = require("./eosjs-rpcerror");
|
||||
exports.RpcError = eosjs_rpcerror_1.RpcError;
|
||||
//# sourceMappingURL=rpc-web.js.map
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"rpc-web.js","sourceRoot":"","sources":["../src/rpc-web.ts"],"names":[],"mappings":";;AAAA,iDAA0C;AAGjC,kBAHA,uBAAO,CAGA;AAFhB,mDAA4C;AAE1B,mBAFT,yBAAQ,CAES"}
|
||||
@@ -1,193 +0,0 @@
|
||||
{
|
||||
"version": "eosio::abi/1.1",
|
||||
"structs": [
|
||||
{
|
||||
"name": "extensions_entry",
|
||||
"base": "",
|
||||
"fields": [
|
||||
{
|
||||
"name": "tag",
|
||||
"type": "uint16"
|
||||
},
|
||||
{
|
||||
"name": "value",
|
||||
"type": "bytes"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "type_def",
|
||||
"base": "",
|
||||
"fields": [
|
||||
{
|
||||
"name": "new_type_name",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "type",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "field_def",
|
||||
"base": "",
|
||||
"fields": [
|
||||
{
|
||||
"name": "name",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "type",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "struct_def",
|
||||
"base": "",
|
||||
"fields": [
|
||||
{
|
||||
"name": "name",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "base",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "fields",
|
||||
"type": "field_def[]"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "action_def",
|
||||
"base": "",
|
||||
"fields": [
|
||||
{
|
||||
"name": "name",
|
||||
"type": "name"
|
||||
},
|
||||
{
|
||||
"name": "type",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "ricardian_contract",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "table_def",
|
||||
"base": "",
|
||||
"fields": [
|
||||
{
|
||||
"name": "name",
|
||||
"type": "name"
|
||||
},
|
||||
{
|
||||
"name": "index_type",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "key_names",
|
||||
"type": "string[]"
|
||||
},
|
||||
{
|
||||
"name": "key_types",
|
||||
"type": "string[]"
|
||||
},
|
||||
{
|
||||
"name": "type",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "clause_pair",
|
||||
"base": "",
|
||||
"fields": [
|
||||
{
|
||||
"name": "id",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "body",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "error_message",
|
||||
"base": "",
|
||||
"fields": [
|
||||
{
|
||||
"name": "error_code",
|
||||
"type": "uint64"
|
||||
},
|
||||
{
|
||||
"name": "error_msg",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "variant_def",
|
||||
"base": "",
|
||||
"fields": [
|
||||
{
|
||||
"name": "name",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "types",
|
||||
"type": "string[]"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "abi_def",
|
||||
"base": "",
|
||||
"fields": [
|
||||
{
|
||||
"name": "version",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "types",
|
||||
"type": "type_def[]"
|
||||
},
|
||||
{
|
||||
"name": "structs",
|
||||
"type": "struct_def[]"
|
||||
},
|
||||
{
|
||||
"name": "actions",
|
||||
"type": "action_def[]"
|
||||
},
|
||||
{
|
||||
"name": "tables",
|
||||
"type": "table_def[]"
|
||||
},
|
||||
{
|
||||
"name": "ricardian_clauses",
|
||||
"type": "clause_pair[]"
|
||||
},
|
||||
{
|
||||
"name": "error_messages",
|
||||
"type": "error_message[]"
|
||||
},
|
||||
{
|
||||
"name": "abi_extensions",
|
||||
"type": "extensions_entry[]"
|
||||
},
|
||||
{
|
||||
"name": "variants",
|
||||
"type": "variant_def[]$"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
{
|
||||
"version": "eosio::abi/1.0",
|
||||
"types": [
|
||||
{
|
||||
"new_type_name": "account_name",
|
||||
"type": "name"
|
||||
},
|
||||
{
|
||||
"new_type_name": "action_name",
|
||||
"type": "name"
|
||||
},
|
||||
{
|
||||
"new_type_name": "permission_name",
|
||||
"type": "name"
|
||||
}
|
||||
],
|
||||
"structs": [
|
||||
{
|
||||
"name": "permission_level",
|
||||
"base": "",
|
||||
"fields": [
|
||||
{
|
||||
"name": "actor",
|
||||
"type": "account_name"
|
||||
},
|
||||
{
|
||||
"name": "permission",
|
||||
"type": "permission_name"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "action",
|
||||
"base": "",
|
||||
"fields": [
|
||||
{
|
||||
"name": "account",
|
||||
"type": "account_name"
|
||||
},
|
||||
{
|
||||
"name": "name",
|
||||
"type": "action_name"
|
||||
},
|
||||
{
|
||||
"name": "authorization",
|
||||
"type": "permission_level[]"
|
||||
},
|
||||
{
|
||||
"name": "data",
|
||||
"type": "bytes"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "extension",
|
||||
"base": "",
|
||||
"fields": [
|
||||
{
|
||||
"name": "type",
|
||||
"type": "uint16"
|
||||
},
|
||||
{
|
||||
"name": "data",
|
||||
"type": "bytes"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "transaction_header",
|
||||
"base": "",
|
||||
"fields": [
|
||||
{
|
||||
"name": "expiration",
|
||||
"type": "time_point_sec"
|
||||
},
|
||||
{
|
||||
"name": "ref_block_num",
|
||||
"type": "uint16"
|
||||
},
|
||||
{
|
||||
"name": "ref_block_prefix",
|
||||
"type": "uint32"
|
||||
},
|
||||
{
|
||||
"name": "max_net_usage_words",
|
||||
"type": "varuint32"
|
||||
},
|
||||
{
|
||||
"name": "max_cpu_usage_ms",
|
||||
"type": "uint8"
|
||||
},
|
||||
{
|
||||
"name": "delay_sec",
|
||||
"type": "varuint32"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "transaction",
|
||||
"base": "transaction_header",
|
||||
"fields": [
|
||||
{
|
||||
"name": "context_free_actions",
|
||||
"type": "action[]"
|
||||
},
|
||||
{
|
||||
"name": "actions",
|
||||
"type": "action[]"
|
||||
},
|
||||
{
|
||||
"name": "transaction_extensions",
|
||||
"type": "extension[]"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
export {};
|
||||
@@ -1,259 +0,0 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
var _this = this;
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var text_encoding_1 = require("text-encoding");
|
||||
var eosjs_api_1 = require("../eosjs-api");
|
||||
var eosjs_jsonrpc_1 = require("../eosjs-jsonrpc");
|
||||
var eosjs_jssig_1 = require("../eosjs-jssig");
|
||||
var transaction = {
|
||||
expiration: '2018-09-04T18:42:49',
|
||||
ref_block_num: 38096,
|
||||
ref_block_prefix: 505360011,
|
||||
max_net_usage_words: 0,
|
||||
max_cpu_usage_ms: 0,
|
||||
delay_sec: 0,
|
||||
context_free_actions: [],
|
||||
actions: [
|
||||
{
|
||||
account: 'testeostoken',
|
||||
name: 'transfer',
|
||||
authorization: [
|
||||
{
|
||||
actor: 'thegazelle',
|
||||
permission: 'active',
|
||||
},
|
||||
],
|
||||
data: {
|
||||
from: 'thegazelle',
|
||||
to: 'remasteryoda',
|
||||
quantity: '1.0000 EOS',
|
||||
memo: 'For a secure future.',
|
||||
},
|
||||
hex_data: "00808a517dc354cb6012f557656ca4ba102700000000000004454f530000000014466f722\n 06120736563757265206675747572652e",
|
||||
},
|
||||
{
|
||||
account: 'testeostoken',
|
||||
name: 'transfer',
|
||||
authorization: [
|
||||
{
|
||||
actor: 'thegazelle',
|
||||
permission: 'active',
|
||||
},
|
||||
],
|
||||
data: {
|
||||
from: 'thegazelle',
|
||||
to: 'remasteryoda',
|
||||
quantity: '2.0000 EOS',
|
||||
memo: 'For a second secure future (multiverse?)',
|
||||
},
|
||||
hex_data: "00808a517dc354cb6012f557656ca4ba204e00000000000004454f530000000028466f722061207365636f6e642073656\n 37572652066757475726520286d756c746976657273653f29",
|
||||
},
|
||||
],
|
||||
transaction_extensions: [],
|
||||
};
|
||||
var serializedTx = [
|
||||
41, 210, 142, 91, 208, 148, 139, 46, 31, 30, 0, 0, 0, 0, 2, 48, 21, 164,
|
||||
25, 83, 149, 177, 202, 0, 0, 0, 87, 45, 60, 205, 205, 1, 0, 128, 138, 81,
|
||||
125, 195, 84, 203, 0, 0, 0, 0, 168, 237, 50, 50, 0, 48, 21, 164, 25, 83,
|
||||
149, 177, 202, 0, 0, 0, 87, 45, 60, 205, 205, 1, 0, 128, 138, 81, 125,
|
||||
195, 84, 203, 0, 0, 0, 0, 168, 237, 50, 50, 0, 0,
|
||||
];
|
||||
var deserializedTx = {
|
||||
actions: [
|
||||
{
|
||||
account: 'testeostoken',
|
||||
authorization: [{ actor: 'thegazelle', permission: 'active' }],
|
||||
data: '',
|
||||
name: 'transfer',
|
||||
},
|
||||
{
|
||||
account: 'testeostoken',
|
||||
authorization: [{ actor: 'thegazelle', permission: 'active' }],
|
||||
data: '',
|
||||
name: 'transfer',
|
||||
},
|
||||
],
|
||||
context_free_actions: [],
|
||||
delay_sec: 0,
|
||||
expiration: '2018-09-04T18:42:49.000',
|
||||
max_cpu_usage_ms: 0,
|
||||
max_net_usage_words: 0,
|
||||
ref_block_num: 38096,
|
||||
ref_block_prefix: 505360011,
|
||||
transaction_extensions: [],
|
||||
};
|
||||
var serializedActions = [
|
||||
{
|
||||
account: 'testeostoken',
|
||||
authorization: [{ actor: 'thegazelle', permission: 'active' }],
|
||||
data: "00808A517DC354CB6012F557656CA4BA102700000000000004454F530000000014466F72206120736563757265206675747572652E",
|
||||
name: 'transfer',
|
||||
},
|
||||
{
|
||||
account: 'testeostoken',
|
||||
authorization: [{ actor: 'thegazelle', permission: 'active' }],
|
||||
data: "00808A517DC354CB6012F557656CA4BA204E00000000000004454F530000000028466F722061207365636F6E64207365637572652066757475726520286D756C746976657273653F29",
|
||||
name: 'transfer',
|
||||
},
|
||||
];
|
||||
var deserializedActions = [
|
||||
{
|
||||
account: 'testeostoken',
|
||||
authorization: [{ actor: 'thegazelle', permission: 'active' }],
|
||||
data: {
|
||||
from: 'thegazelle',
|
||||
memo: 'For a secure future.',
|
||||
quantity: '1.0000 EOS',
|
||||
to: 'remasteryoda',
|
||||
},
|
||||
name: 'transfer',
|
||||
},
|
||||
{
|
||||
account: 'testeostoken',
|
||||
authorization: [{ actor: 'thegazelle', permission: 'active' }],
|
||||
data: {
|
||||
from: 'thegazelle',
|
||||
memo: 'For a second secure future (multiverse?)',
|
||||
quantity: '2.0000 EOS',
|
||||
to: 'remasteryoda',
|
||||
},
|
||||
name: 'transfer',
|
||||
},
|
||||
];
|
||||
describe('eosjs-api', function () {
|
||||
var api;
|
||||
var fetch = function (input, init) { return __awaiter(_this, void 0, void 0, function () {
|
||||
var _this = this;
|
||||
return __generator(this, function (_a) {
|
||||
return [2 /*return*/, ({
|
||||
ok: true,
|
||||
json: function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
if (input === '/v1/chain/get_raw_code_and_abi') {
|
||||
return [2 /*return*/, {
|
||||
account_name: 'testeostoken',
|
||||
abi: "DmVvc2lvOjphYmkvMS4wAQxhY2NvdW50X25hbWUEbmFtZQUIdHJhbnNmZXIABARmcm9tDGFjY291bnRfbmFtZQJ0bwxhY2NvdW50X25hbWUIcXVhbnRpdHkFYXNzZXQEbWVtbwZzdHJpbmcGY3JlYXRlAAIGaXNzdWVyDGFjY291bnRfbmFtZQ5tYXhpbXVtX3N1cHBseQVhc3NldAVpc3N1ZQADAnRvDGFjY291bnRfbmFtZQhxdWFudGl0eQVhc3NldARtZW1vBnN0cmluZwdhY2NvdW50AAEHYmFsYW5jZQVhc3NldA5jdXJyZW5jeV9zdGF0cwADBnN1cHBseQVhc3NldAptYXhfc3VwcGx5BWFzc2V0Bmlzc3VlcgxhY2NvdW50X25hbWUDAAAAVy08zc0IdHJhbnNmZXLnBSMjIFRyYW5zZmVyIFRlcm1zICYgQ29uZGl0aW9ucwoKSSwge3tmcm9tfX0sIGNlcnRpZnkgdGhlIGZvbGxvd2luZyB0byBiZSB0cnVlIHRvIHRoZSBiZXN0IG9mIG15IGtub3dsZWRnZToKCjEuIEkgY2VydGlmeSB0aGF0IHt7cXVhbnRpdHl9fSBpcyBub3QgdGhlIHByb2NlZWRzIG9mIGZyYXVkdWxlbnQgb3IgdmlvbGVudCBhY3Rpdml0aWVzLgoyLiBJIGNlcnRpZnkgdGhhdCwgdG8gdGhlIGJlc3Qgb2YgbXkga25vd2xlZGdlLCB7e3RvfX0gaXMgbm90IHN1cHBvcnRpbmcgaW5pdGlhdGlvbiBvZiB2aW9sZW5jZSBhZ2FpbnN0IG90aGVycy4KMy4gSSBoYXZlIGRpc2Nsb3NlZCBhbnkgY29udHJhY3R1YWwgdGVybXMgJiBjb25kaXRpb25zIHdpdGggcmVzcGVjdCB0byB7e3F1YW50aXR5fX0gdG8ge3t0b319LgoKSSB1bmRlcnN0YW5kIHRoYXQgZnVuZHMgdHJhbnNmZXJzIGFyZSBub3QgcmV2ZXJzaWJsZSBhZnRlciB0aGUge3t0cmFuc2FjdGlvbi5kZWxheX19IHNlY29uZHMgb3Igb3RoZXIgZGVsYXkgYXMgY29uZmlndXJlZCBieSB7e2Zyb219fSdzIHBlcm1pc3Npb25zLgoKSWYgdGhpcyBhY3Rpb24gZmFpbHMgdG8gYmUgaXJyZXZlcnNpYmx5IGNvbmZpcm1lZCBhZnRlciByZWNlaXZpbmcgZ29vZHMgb3Igc2VydmljZXMgZnJvbSAne3t0b319JywgSSBhZ3JlZSB0byBlaXRoZXIgcmV0dXJuIHRoZSBnb29kcyBvciBzZXJ2aWNlcyBvciByZXNlbmQge3txdWFudGl0eX19IGluIGEgdGltZWx5IG1hbm5lci4KAAAAAAClMXYFaXNzdWUAAAAAAKhs1EUGY3JlYXRlAAIAAAA4T00RMgNpNjQBCGN1cnJlbmN5AQZ1aW50NjQHYWNjb3VudAAAAAAAkE3GA2k2NAEIY3VycmVuY3kBBnVpbnQ2NA5jdXJyZW5jeV9zdGF0cwAAAA===",
|
||||
}];
|
||||
}
|
||||
return [2 /*return*/, transaction];
|
||||
});
|
||||
}); },
|
||||
})];
|
||||
});
|
||||
}); };
|
||||
beforeEach(function () {
|
||||
var rpc = new eosjs_jsonrpc_1.JsonRpc('', { fetch: fetch });
|
||||
var signatureProvider = new eosjs_jssig_1.JsSignatureProvider(['5JtUScZK2XEp3g9gh7F8bwtPTRAkASmNrrftmx4AxDKD5K4zDnr']);
|
||||
var chainId = '038f4b0fc8ff18a4f0842a8f0564611f6e96e8535901dd45e43ac8691a1c4dca';
|
||||
api = new eosjs_api_1.Api({
|
||||
rpc: rpc, signatureProvider: signatureProvider, chainId: chainId, textDecoder: new text_encoding_1.TextDecoder(), textEncoder: new text_encoding_1.TextEncoder(),
|
||||
});
|
||||
});
|
||||
it('Doesnt crash', function () {
|
||||
expect(api).toBeTruthy();
|
||||
});
|
||||
it('getAbi returns an abi', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, api.getAbi('testeostoken')];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
expect(response).toBeTruthy();
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('getTransactionAbis returns abis by transactions', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, api.getTransactionAbis(transaction)];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
expect(response[0].abi.length).toBeGreaterThan(0);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('getContract returns a contract', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, api.getContract('testeostoken')];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
expect(response.actions).toBeTruthy();
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('deserializeTransaction converts tx from binary', function () {
|
||||
var tx = api.deserializeTransaction(serializedTx);
|
||||
expect(tx).toEqual(deserializedTx);
|
||||
});
|
||||
it('serializeActions converts actions to hex', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, api.serializeActions(transaction.actions)];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
expect(response).toEqual(serializedActions);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('deserializeActions converts actions from hex', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, api.deserializeActions(serializedActions)];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
expect(response).toEqual(deserializedActions);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('hasRequiredTaposFields returns true, if required fields are present', function () {
|
||||
var response = api.hasRequiredTaposFields(transaction);
|
||||
expect(response).toEqual(true);
|
||||
});
|
||||
});
|
||||
//# sourceMappingURL=eosjs-api.test.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
export {};
|
||||
@@ -1,880 +0,0 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
var _this = this;
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var eosjs_jsonrpc_1 = require("../eosjs-jsonrpc");
|
||||
var eosjs_rpcerror_1 = require("../eosjs-rpcerror");
|
||||
describe('JSON RPC', function () {
|
||||
var endpoint = 'http://localhost';
|
||||
var fetchMock = fetch;
|
||||
var jsonRpc;
|
||||
beforeEach(function () {
|
||||
fetchMock.resetMocks();
|
||||
jsonRpc = new eosjs_jsonrpc_1.JsonRpc(endpoint);
|
||||
});
|
||||
it('throws error bad status', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var actMessage, expMessage, accountName, expReturn, e_1;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
actMessage = '';
|
||||
expMessage = 'Not Found';
|
||||
accountName = 'myaccountaaa';
|
||||
expReturn = { data: '12345', message: expMessage };
|
||||
fetchMock.once(JSON.stringify(expReturn), { status: 404 });
|
||||
_a.label = 1;
|
||||
case 1:
|
||||
_a.trys.push([1, 3, , 4]);
|
||||
return [4 /*yield*/, jsonRpc.get_abi(accountName)];
|
||||
case 2:
|
||||
_a.sent();
|
||||
return [3 /*break*/, 4];
|
||||
case 3:
|
||||
e_1 = _a.sent();
|
||||
expect(e_1).toBeInstanceOf(eosjs_rpcerror_1.RpcError);
|
||||
actMessage = e_1.message;
|
||||
return [3 /*break*/, 4];
|
||||
case 4:
|
||||
expect(actMessage).toEqual(expMessage);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('throws error unprocessed', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var actMessage, expMessage, accountName, expReturn, e_2;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
actMessage = '';
|
||||
expMessage = 'Not Processed';
|
||||
accountName = 'myaccountaaa';
|
||||
expReturn = {
|
||||
data: '12345',
|
||||
processed: {
|
||||
except: {
|
||||
message: expMessage,
|
||||
},
|
||||
},
|
||||
};
|
||||
fetchMock.once(JSON.stringify(expReturn));
|
||||
_a.label = 1;
|
||||
case 1:
|
||||
_a.trys.push([1, 3, , 4]);
|
||||
return [4 /*yield*/, jsonRpc.get_abi(accountName)];
|
||||
case 2:
|
||||
_a.sent();
|
||||
return [3 /*break*/, 4];
|
||||
case 3:
|
||||
e_2 = _a.sent();
|
||||
expect(e_2).toBeInstanceOf(eosjs_rpcerror_1.RpcError);
|
||||
actMessage = e_2.message;
|
||||
return [3 /*break*/, 4];
|
||||
case 4:
|
||||
expect(actMessage).toEqual(expMessage);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('calls provided fetch instead of default', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var expPath, accountName, expReturn, expParams, mockResp, myFetch;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
expPath = '/v1/chain/get_abi';
|
||||
accountName = 'myaccountaaa';
|
||||
expReturn = { data: '12345' };
|
||||
expParams = {
|
||||
body: JSON.stringify({
|
||||
account_name: accountName,
|
||||
}),
|
||||
method: 'POST',
|
||||
};
|
||||
mockResp = {
|
||||
json: function () {
|
||||
return expReturn;
|
||||
},
|
||||
ok: true,
|
||||
};
|
||||
myFetch = jest.fn();
|
||||
myFetch.mockReturnValue(mockResp);
|
||||
jsonRpc = new eosjs_jsonrpc_1.JsonRpc(endpoint, { fetch: myFetch });
|
||||
return [4 /*yield*/, jsonRpc.get_abi(accountName)];
|
||||
case 1:
|
||||
_a.sent();
|
||||
expect(myFetch).toBeCalledWith(endpoint + expPath, expParams);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('calls get_abi', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var expPath, accountName, expReturn, expParams, response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
expPath = '/v1/chain/get_abi';
|
||||
accountName = 'myaccountaaa';
|
||||
expReturn = { data: '12345' };
|
||||
expParams = {
|
||||
body: JSON.stringify({
|
||||
account_name: accountName,
|
||||
}),
|
||||
method: 'POST',
|
||||
};
|
||||
fetchMock.once(JSON.stringify(expReturn));
|
||||
return [4 /*yield*/, jsonRpc.get_abi(accountName)];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
expect(response).toEqual(expReturn);
|
||||
expect(fetch).toBeCalledWith(endpoint + expPath, expParams);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('calls get_account', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var expPath, accountName, expReturn, expParams, response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
expPath = '/v1/chain/get_account';
|
||||
accountName = 'myaccountaaa';
|
||||
expReturn = { data: '12345' };
|
||||
expParams = {
|
||||
body: JSON.stringify({
|
||||
account_name: accountName,
|
||||
}),
|
||||
method: 'POST',
|
||||
};
|
||||
fetchMock.once(JSON.stringify(expReturn));
|
||||
return [4 /*yield*/, jsonRpc.get_account(accountName)];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
expect(response).toEqual(expReturn);
|
||||
expect(fetch).toBeCalledWith(endpoint + expPath, expParams);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('calls get_block_header_state', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var expPath, blockNumOrId, expReturn, expParams, response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
expPath = '/v1/chain/get_block_header_state';
|
||||
blockNumOrId = 1234;
|
||||
expReturn = { data: '12345' };
|
||||
expParams = {
|
||||
body: JSON.stringify({
|
||||
block_num_or_id: blockNumOrId,
|
||||
}),
|
||||
method: 'POST',
|
||||
};
|
||||
fetchMock.once(JSON.stringify(expReturn));
|
||||
return [4 /*yield*/, jsonRpc.get_block_header_state(blockNumOrId)];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
expect(response).toEqual(expReturn);
|
||||
expect(fetch).toBeCalledWith(endpoint + expPath, expParams);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('calls get_block', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var expPath, blockNumOrId, expReturn, expParams, response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
expPath = '/v1/chain/get_block';
|
||||
blockNumOrId = 1234;
|
||||
expReturn = { data: '12345' };
|
||||
expParams = {
|
||||
body: JSON.stringify({
|
||||
block_num_or_id: blockNumOrId,
|
||||
}),
|
||||
method: 'POST',
|
||||
};
|
||||
fetchMock.once(JSON.stringify(expReturn));
|
||||
return [4 /*yield*/, jsonRpc.get_block(blockNumOrId)];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
expect(response).toEqual(expReturn);
|
||||
expect(fetch).toBeCalledWith(endpoint + expPath, expParams);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('calls get_code', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var expPath, accountName, expReturn, expParams, response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
expPath = '/v1/chain/get_code';
|
||||
accountName = 'myaccountaaa';
|
||||
expReturn = { data: '12345' };
|
||||
expParams = {
|
||||
body: JSON.stringify({
|
||||
account_name: accountName,
|
||||
}),
|
||||
method: 'POST',
|
||||
};
|
||||
fetchMock.once(JSON.stringify(expReturn));
|
||||
return [4 /*yield*/, jsonRpc.get_code(accountName)];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
expect(response).toEqual(expReturn);
|
||||
expect(fetch).toBeCalledWith(endpoint + expPath, expParams);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('calls get_currency_balance with all params', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var expPath, code, account, symbol, expReturn, expParams, response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
expPath = '/v1/chain/get_currency_balance';
|
||||
code = 'morse';
|
||||
account = 'myaccountaaa';
|
||||
symbol = 'EOS';
|
||||
expReturn = { data: '12345' };
|
||||
expParams = {
|
||||
body: JSON.stringify({
|
||||
code: code,
|
||||
account: account,
|
||||
symbol: symbol,
|
||||
}),
|
||||
method: 'POST',
|
||||
};
|
||||
fetchMock.once(JSON.stringify(expReturn));
|
||||
return [4 /*yield*/, jsonRpc.get_currency_balance(code, account, symbol)];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
expect(response).toEqual(expReturn);
|
||||
expect(fetch).toBeCalledWith(endpoint + expPath, expParams);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('calls get_currency_balance with default params', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var expPath, code, account, symbol, expReturn, expParams, response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
expPath = '/v1/chain/get_currency_balance';
|
||||
code = 'morse';
|
||||
account = 'myaccountaaa';
|
||||
symbol = null;
|
||||
expReturn = { data: '12345' };
|
||||
expParams = {
|
||||
body: JSON.stringify({
|
||||
code: code,
|
||||
account: account,
|
||||
symbol: symbol,
|
||||
}),
|
||||
method: 'POST',
|
||||
};
|
||||
fetchMock.once(JSON.stringify(expReturn));
|
||||
return [4 /*yield*/, jsonRpc.get_currency_balance(code, account)];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
expect(response).toEqual(expReturn);
|
||||
expect(fetch).toBeCalledWith(endpoint + expPath, expParams);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('calls get_currency_stats with all params', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var expPath, code, symbol, expReturn, expParams, response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
expPath = '/v1/chain/get_currency_stats';
|
||||
code = 'morse';
|
||||
symbol = 'EOS';
|
||||
expReturn = { data: '12345' };
|
||||
expParams = {
|
||||
body: JSON.stringify({
|
||||
code: code,
|
||||
symbol: symbol,
|
||||
}),
|
||||
method: 'POST',
|
||||
};
|
||||
fetchMock.once(JSON.stringify(expReturn));
|
||||
return [4 /*yield*/, jsonRpc.get_currency_stats(code, symbol)];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
expect(response).toEqual(expReturn);
|
||||
expect(fetch).toBeCalledWith(endpoint + expPath, expParams);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('calls get_info', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var expPath, expReturn, expParams, response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
expPath = '/v1/chain/get_info';
|
||||
expReturn = { data: '12345' };
|
||||
expParams = {
|
||||
body: JSON.stringify({}),
|
||||
method: 'POST',
|
||||
};
|
||||
fetchMock.once(JSON.stringify(expReturn));
|
||||
return [4 /*yield*/, jsonRpc.get_info()];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
expect(response).toEqual(expReturn);
|
||||
expect(fetch).toBeCalledWith(endpoint + expPath, expParams);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('calls get_producer_schedule', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var expPath, expReturn, expParams, response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
expPath = '/v1/chain/get_producer_schedule';
|
||||
expReturn = { data: '12345' };
|
||||
expParams = {
|
||||
body: JSON.stringify({}),
|
||||
method: 'POST',
|
||||
};
|
||||
fetchMock.once(JSON.stringify(expReturn));
|
||||
return [4 /*yield*/, jsonRpc.get_producer_schedule()];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
expect(response).toEqual(expReturn);
|
||||
expect(fetch).toBeCalledWith(endpoint + expPath, expParams);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('calls get_producers with all params', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var expPath, json, lowerBound, limit, expReturn, expParams, response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
expPath = '/v1/chain/get_producers';
|
||||
json = false;
|
||||
lowerBound = 'zero';
|
||||
limit = 10;
|
||||
expReturn = { data: '12345' };
|
||||
expParams = {
|
||||
body: JSON.stringify({
|
||||
json: json,
|
||||
lower_bound: lowerBound,
|
||||
limit: limit,
|
||||
}),
|
||||
method: 'POST',
|
||||
};
|
||||
fetchMock.once(JSON.stringify(expReturn));
|
||||
return [4 /*yield*/, jsonRpc.get_producers(json, lowerBound, limit)];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
expect(response).toEqual(expReturn);
|
||||
expect(fetch).toBeCalledWith(endpoint + expPath, expParams);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('calls get_producers with default params', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var expPath, json, lowerBound, limit, expReturn, expParams, response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
expPath = '/v1/chain/get_producers';
|
||||
json = true;
|
||||
lowerBound = '';
|
||||
limit = 50;
|
||||
expReturn = { data: '12345' };
|
||||
expParams = {
|
||||
body: JSON.stringify({
|
||||
json: json,
|
||||
lower_bound: lowerBound,
|
||||
limit: limit,
|
||||
}),
|
||||
method: 'POST',
|
||||
};
|
||||
fetchMock.once(JSON.stringify(expReturn));
|
||||
return [4 /*yield*/, jsonRpc.get_producers()];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
expect(response).toEqual(expReturn);
|
||||
expect(fetch).toBeCalledWith(endpoint + expPath, expParams);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('calls get_raw_code_and_abi', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var expPath, accountName, expReturn, expParams, response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
expPath = '/v1/chain/get_raw_code_and_abi';
|
||||
accountName = 'myaccountaaa';
|
||||
expReturn = { data: '12345' };
|
||||
expParams = {
|
||||
body: JSON.stringify({
|
||||
account_name: accountName,
|
||||
}),
|
||||
method: 'POST',
|
||||
};
|
||||
fetchMock.once(JSON.stringify(expReturn));
|
||||
return [4 /*yield*/, jsonRpc.get_raw_code_and_abi(accountName)];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
expect(response).toEqual(expReturn);
|
||||
expect(fetch).toBeCalledWith(endpoint + expPath, expParams);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('calls get_table_rows with all params', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var expPath, json, code, scope, table, tableKey, lowerBound, upperBound, limit, indexPosition, keyType, expReturn, reverse, showPayer, callParams, expParams, response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
expPath = '/v1/chain/get_table_rows';
|
||||
json = false;
|
||||
code = 'morse';
|
||||
scope = 'minty';
|
||||
table = 'coffee';
|
||||
tableKey = 'front_door';
|
||||
lowerBound = 'zero';
|
||||
upperBound = 'five';
|
||||
limit = 20;
|
||||
indexPosition = 1;
|
||||
keyType = 'str';
|
||||
expReturn = { data: '12345' };
|
||||
reverse = false;
|
||||
showPayer = false;
|
||||
callParams = {
|
||||
json: json,
|
||||
code: code,
|
||||
scope: scope,
|
||||
table: table,
|
||||
table_key: tableKey,
|
||||
lower_bound: lowerBound,
|
||||
upper_bound: upperBound,
|
||||
index_position: indexPosition,
|
||||
key_type: keyType,
|
||||
limit: limit,
|
||||
reverse: reverse,
|
||||
show_payer: showPayer,
|
||||
};
|
||||
expParams = {
|
||||
body: JSON.stringify(callParams),
|
||||
method: 'POST',
|
||||
};
|
||||
fetchMock.once(JSON.stringify(expReturn));
|
||||
return [4 /*yield*/, jsonRpc.get_table_rows(callParams)];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
expect(response).toEqual(expReturn);
|
||||
expect(fetch).toBeCalledWith(endpoint + expPath, expParams);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('calls get_table_rows with default params', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var expPath, json, code, scope, table, tableKey, lowerBound, upperBound, limit, indexPosition, keyType, reverse, showPayer, expReturn, callParams, expParams, response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
expPath = '/v1/chain/get_table_rows';
|
||||
json = true;
|
||||
code = 'morse';
|
||||
scope = 'minty';
|
||||
table = 'coffee';
|
||||
tableKey = '';
|
||||
lowerBound = '';
|
||||
upperBound = '';
|
||||
limit = 10;
|
||||
indexPosition = 1;
|
||||
keyType = '';
|
||||
reverse = false;
|
||||
showPayer = false;
|
||||
expReturn = { data: '12345' };
|
||||
callParams = {
|
||||
code: code,
|
||||
scope: scope,
|
||||
table: table,
|
||||
};
|
||||
expParams = {
|
||||
body: JSON.stringify({
|
||||
json: json,
|
||||
code: code,
|
||||
scope: scope,
|
||||
table: table,
|
||||
table_key: tableKey,
|
||||
lower_bound: lowerBound,
|
||||
upper_bound: upperBound,
|
||||
index_position: indexPosition,
|
||||
key_type: keyType,
|
||||
limit: limit,
|
||||
reverse: reverse,
|
||||
show_payer: showPayer,
|
||||
}),
|
||||
method: 'POST',
|
||||
};
|
||||
fetchMock.once(JSON.stringify(expReturn));
|
||||
return [4 /*yield*/, jsonRpc.get_table_rows(callParams)];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
expect(response).toEqual(expReturn);
|
||||
expect(fetch).toBeCalledWith(endpoint + expPath, expParams);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('calls get_table_by_scope with all params', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var expPath, code, table, lowerBound, upperBound, limit, expReturn, callParams, expParams, response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
expPath = '/v1/chain/get_table_by_scope';
|
||||
code = 'morse';
|
||||
table = 'coffee';
|
||||
lowerBound = 'minty';
|
||||
upperBound = 'minty';
|
||||
limit = 20;
|
||||
expReturn = { data: '12345' };
|
||||
callParams = {
|
||||
code: code,
|
||||
table: table,
|
||||
lower_bound: lowerBound,
|
||||
upper_bound: upperBound,
|
||||
limit: limit,
|
||||
};
|
||||
expParams = {
|
||||
body: JSON.stringify(callParams),
|
||||
method: 'POST',
|
||||
};
|
||||
fetchMock.once(JSON.stringify(expReturn));
|
||||
return [4 /*yield*/, jsonRpc.get_table_by_scope(callParams)];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
expect(response).toEqual(expReturn);
|
||||
expect(fetch).toBeCalledWith(endpoint + expPath, expParams);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('calls get_table_by_scope with default params', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var expPath, code, table, lowerBound, upperBound, limit, expReturn, callParams, expParams, response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
expPath = '/v1/chain/get_table_by_scope';
|
||||
code = 'morse';
|
||||
table = 'coffee';
|
||||
lowerBound = '';
|
||||
upperBound = '';
|
||||
limit = 10;
|
||||
expReturn = { data: '12345' };
|
||||
callParams = {
|
||||
code: code,
|
||||
table: table,
|
||||
};
|
||||
expParams = {
|
||||
body: JSON.stringify({
|
||||
code: code,
|
||||
table: table,
|
||||
lower_bound: lowerBound,
|
||||
upper_bound: upperBound,
|
||||
limit: limit,
|
||||
}),
|
||||
method: 'POST',
|
||||
};
|
||||
fetchMock.once(JSON.stringify(expReturn));
|
||||
return [4 /*yield*/, jsonRpc.get_table_by_scope(callParams)];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
expect(response).toEqual(expReturn);
|
||||
expect(fetch).toBeCalledWith(endpoint + expPath, expParams);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('calls getRequiredKeys', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var expPath, keys, expReturn, callParams, expParams, response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
expPath = '/v1/chain/get_required_keys';
|
||||
keys = ['key1', 'key2', 'key3'];
|
||||
expReturn = { required_keys: keys };
|
||||
callParams = {
|
||||
transaction: 'mytxn',
|
||||
availableKeys: keys,
|
||||
};
|
||||
expParams = {
|
||||
body: JSON.stringify({
|
||||
transaction: callParams.transaction,
|
||||
available_keys: callParams.availableKeys,
|
||||
}),
|
||||
method: 'POST',
|
||||
};
|
||||
fetchMock.once(JSON.stringify(expReturn));
|
||||
return [4 /*yield*/, jsonRpc.getRequiredKeys(callParams)];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
expect(response).toEqual(expReturn.required_keys);
|
||||
expect(fetch).toBeCalledWith(endpoint + expPath, expParams);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('calls push_transaction', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var expPath, signatures, serializedTransaction, limit, expReturn, callParams, expParams, response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
expPath = '/v1/chain/push_transaction';
|
||||
signatures = [
|
||||
'George Washington',
|
||||
'John Hancock',
|
||||
'Abraham Lincoln',
|
||||
];
|
||||
serializedTransaction = new Uint8Array([
|
||||
0, 16, 32, 128, 255,
|
||||
]);
|
||||
limit = 50;
|
||||
expReturn = { data: '12345' };
|
||||
callParams = {
|
||||
signatures: signatures,
|
||||
serializedTransaction: serializedTransaction,
|
||||
};
|
||||
expParams = {
|
||||
body: JSON.stringify({
|
||||
signatures: signatures,
|
||||
compression: 0,
|
||||
packed_context_free_data: '',
|
||||
packed_trx: '00102080ff',
|
||||
}),
|
||||
method: 'POST',
|
||||
};
|
||||
fetchMock.once(JSON.stringify(expReturn));
|
||||
return [4 /*yield*/, jsonRpc.push_transaction(callParams)];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
expect(response).toEqual(expReturn);
|
||||
expect(fetch).toBeCalledWith(endpoint + expPath, expParams);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('calls db_size_get', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var expPath, expReturn, expParams, response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
expPath = '/v1/db_size/get';
|
||||
expReturn = { data: '12345' };
|
||||
expParams = {
|
||||
body: JSON.stringify({}),
|
||||
method: 'POST',
|
||||
};
|
||||
fetchMock.once(JSON.stringify(expReturn));
|
||||
return [4 /*yield*/, jsonRpc.db_size_get()];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
expect(response).toEqual(expReturn);
|
||||
expect(fetch).toBeCalledWith(endpoint + expPath, expParams);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('calls history_get_actions with all params', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var expPath, accountName, pos, offset, expReturn, expParams, response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
expPath = '/v1/history/get_actions';
|
||||
accountName = 'myaccountaaa';
|
||||
pos = 5;
|
||||
offset = 10;
|
||||
expReturn = { data: '12345' };
|
||||
expParams = {
|
||||
body: JSON.stringify({
|
||||
account_name: accountName,
|
||||
pos: pos,
|
||||
offset: offset,
|
||||
}),
|
||||
method: 'POST',
|
||||
};
|
||||
fetchMock.once(JSON.stringify(expReturn));
|
||||
return [4 /*yield*/, jsonRpc.history_get_actions(accountName, pos, offset)];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
expect(response).toEqual(expReturn);
|
||||
expect(fetch).toBeCalledWith(endpoint + expPath, expParams);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('calls history_get_actions with default params', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var expPath, accountName, pos, offset, expReturn, expParams, response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
expPath = '/v1/history/get_actions';
|
||||
accountName = 'myaccountaaa';
|
||||
pos = null;
|
||||
offset = null;
|
||||
expReturn = { data: '12345' };
|
||||
expParams = {
|
||||
body: JSON.stringify({
|
||||
account_name: accountName,
|
||||
pos: pos,
|
||||
offset: offset,
|
||||
}),
|
||||
method: 'POST',
|
||||
};
|
||||
fetchMock.once(JSON.stringify(expReturn));
|
||||
return [4 /*yield*/, jsonRpc.history_get_actions(accountName)];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
expect(response).toEqual(expReturn);
|
||||
expect(fetch).toBeCalledWith(endpoint + expPath, expParams);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('calls history_get_transaction with all params', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var expPath, id, blockNumHint, expReturn, expParams, response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
expPath = '/v1/history/get_transaction';
|
||||
id = 'myaccountaaa';
|
||||
blockNumHint = 20;
|
||||
expReturn = { data: '12345' };
|
||||
expParams = {
|
||||
body: JSON.stringify({
|
||||
id: id,
|
||||
block_num_hint: blockNumHint,
|
||||
}),
|
||||
method: 'POST',
|
||||
};
|
||||
fetchMock.once(JSON.stringify(expReturn));
|
||||
return [4 /*yield*/, jsonRpc.history_get_transaction(id, blockNumHint)];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
expect(response).toEqual(expReturn);
|
||||
expect(fetch).toBeCalledWith(endpoint + expPath, expParams);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('calls history_get_transaction with default params', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var expPath, id, blockNumHint, expReturn, expParams, response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
expPath = '/v1/history/get_transaction';
|
||||
id = 'myaccountaaa';
|
||||
blockNumHint = null;
|
||||
expReturn = { data: '12345' };
|
||||
expParams = {
|
||||
body: JSON.stringify({
|
||||
id: id,
|
||||
block_num_hint: blockNumHint,
|
||||
}),
|
||||
method: 'POST',
|
||||
};
|
||||
fetchMock.once(JSON.stringify(expReturn));
|
||||
return [4 /*yield*/, jsonRpc.history_get_transaction(id)];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
expect(response).toEqual(expReturn);
|
||||
expect(fetch).toBeCalledWith(endpoint + expPath, expParams);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('calls history_get_key_accounts', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var expPath, publicKey, expReturn, expParams, response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
expPath = '/v1/history/get_key_accounts';
|
||||
publicKey = 'key12345';
|
||||
expReturn = { data: '12345' };
|
||||
expParams = {
|
||||
body: JSON.stringify({
|
||||
public_key: publicKey,
|
||||
}),
|
||||
method: 'POST',
|
||||
};
|
||||
fetchMock.once(JSON.stringify(expReturn));
|
||||
return [4 /*yield*/, jsonRpc.history_get_key_accounts(publicKey)];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
expect(response).toEqual(expReturn);
|
||||
expect(fetch).toBeCalledWith(endpoint + expPath, expParams);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('calls history_get_controlled_accounts', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var expPath, controllingAccount, expReturn, expParams, response;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
expPath = '/v1/history/get_controlled_accounts';
|
||||
controllingAccount = 'key12345';
|
||||
expReturn = { data: '12345' };
|
||||
expParams = {
|
||||
body: JSON.stringify({
|
||||
controlling_account: controllingAccount,
|
||||
}),
|
||||
method: 'POST',
|
||||
};
|
||||
fetchMock.once(JSON.stringify(expReturn));
|
||||
return [4 /*yield*/, jsonRpc.history_get_controlled_accounts(controllingAccount)];
|
||||
case 1:
|
||||
response = _a.sent();
|
||||
expect(response).toEqual(expReturn);
|
||||
expect(fetch).toBeCalledWith(endpoint + expPath, expParams);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
});
|
||||
//# sourceMappingURL=eosjs-jsonrpc.test.js.map
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
|
||||
export {};
|
||||
@@ -1,92 +0,0 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
var _this = this;
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var ecc = require("eosjs-ecc");
|
||||
var eosjs_jssig_1 = require("../eosjs-jssig");
|
||||
describe('JsSignatureProvider', function () {
|
||||
var privateKeys = ['key1', 'key2', 'key3'];
|
||||
var publicKeys = [
|
||||
'PUB_K1_8iD9ABKFH5b9JyFgb5PE51BdCV74qGN9UMfg9V3TwaExCQWxJm',
|
||||
'PUB_K1_8f2o2LLQ3phteqyazxirQZnQzQFpnjLnXiUFEJcsSYhnjWNvSX',
|
||||
'PUB_K1_5imfbmmHC83VRxLRTcvovviAc6LPpyszcDuKtkwka9e9Jg37Hp',
|
||||
];
|
||||
it('builds public keys from private when constructed', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var eccPkFromString, provider, actualPublicKeys;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
eccPkFromString = jest.spyOn(ecc.PrivateKey, 'fromString');
|
||||
eccPkFromString.mockImplementation(function (k) { return ecc.PrivateKey.fromHex(ecc.sha256(k)); });
|
||||
provider = new eosjs_jssig_1.JsSignatureProvider(privateKeys);
|
||||
return [4 /*yield*/, provider.getAvailableKeys()];
|
||||
case 1:
|
||||
actualPublicKeys = _a.sent();
|
||||
expect(eccPkFromString).toHaveBeenCalledTimes(privateKeys.length);
|
||||
expect(actualPublicKeys).toEqual(publicKeys);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('signs a transaction', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var eccSignatureSign, provider, chainId, requiredKeys, serializedTransaction, abis, signOutput;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
eccSignatureSign = jest.spyOn(ecc.Signature, 'sign');
|
||||
eccSignatureSign.mockImplementation(function (buffer, signKey) { return signKey; });
|
||||
provider = new eosjs_jssig_1.JsSignatureProvider(privateKeys);
|
||||
chainId = '12345';
|
||||
requiredKeys = [
|
||||
publicKeys[0],
|
||||
publicKeys[2],
|
||||
];
|
||||
serializedTransaction = new Uint8Array([
|
||||
0, 16, 32, 128, 255,
|
||||
]);
|
||||
abis = [];
|
||||
return [4 /*yield*/, provider.sign({ chainId: chainId, requiredKeys: requiredKeys, serializedTransaction: serializedTransaction, abis: abis })];
|
||||
case 1:
|
||||
signOutput = _a.sent();
|
||||
expect(eccSignatureSign).toHaveBeenCalledTimes(2);
|
||||
expect(signOutput).toEqual({ signatures: [privateKeys[0], privateKeys[2]], serializedTransaction: serializedTransaction });
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
});
|
||||
//# sourceMappingURL=eosjs-jssig.test.js.map
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"eosjs-jssig.test.js","sourceRoot":"","sources":["../../src/tests/eosjs-jssig.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iBA0CA;;AA1CA,+BAAiC;AACjC,8CAAqD;AAErD,QAAQ,CAAC,qBAAqB,EAAE;IAC5B,IAAM,WAAW,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,IAAM,UAAU,GAAG;QACf,2DAA2D;QAC3D,2DAA2D;QAC3D,2DAA2D;KAC9D,CAAC;IAEF,EAAE,CAAC,kDAAkD,EAAE;;;;;oBAC7C,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;oBACjE,eAAe,CAAC,kBAAkB,CAAC,UAAC,CAAC,IAAK,OAAA,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAArC,CAAqC,CAAC,CAAC;oBAC3E,QAAQ,GAAG,IAAI,iCAAmB,CAAC,WAAW,CAAC,CAAC;oBAC7B,qBAAM,QAAQ,CAAC,gBAAgB,EAAE,EAAA;;oBAApD,gBAAgB,GAAG,SAAiC;oBAE1D,MAAM,CAAC,eAAe,CAAC,CAAC,qBAAqB,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;oBAClE,MAAM,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;;;;SAChD,CAAC,CAAC;IAEH,EAAE,CAAC,qBAAqB,EAAE;;;;;oBAChB,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;oBAC3D,gBAAgB,CAAC,kBAAkB,CAAC,UAAC,MAAM,EAAE,OAAO,IAAK,OAAA,OAAO,EAAP,CAAO,CAAC,CAAC;oBAE5D,QAAQ,GAAG,IAAI,iCAAmB,CAAC,WAAW,CAAC,CAAC;oBAChD,OAAO,GAAG,OAAO,CAAC;oBAClB,YAAY,GAAG;wBACjB,UAAU,CAAC,CAAC,CAAC;wBACb,UAAU,CAAC,CAAC,CAAC;qBAChB,CAAC;oBACI,qBAAqB,GAAG,IAAI,UAAU,CAAC;wBACzC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG;qBACtB,CAAC,CAAC;oBACG,IAAI,GAAU,EAAE,CAAC;oBAEJ,qBAAM,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,SAAA,EAAE,YAAY,cAAA,EAAE,qBAAqB,uBAAA,EAAE,IAAI,MAAA,EAAE,CAAC,EAAA;;oBAAxF,UAAU,GAAG,SAA2E;oBAE9F,MAAM,CAAC,gBAAgB,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;oBAClD,MAAM,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,qBAAqB,uBAAA,EAAE,CAAC,CAAC;;;;SACvG,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
||||
-1
@@ -1 +0,0 @@
|
||||
declare const tests: any;
|
||||
@@ -1,140 +0,0 @@
|
||||
"use strict";
|
||||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||
return new (P || (P = Promise))(function (resolve, reject) {
|
||||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
||||
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||
});
|
||||
};
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
while (_) try {
|
||||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||
switch (op[0]) {
|
||||
case 0: case 1: t = op; break;
|
||||
case 4: _.label++; return { value: op[1], done: false };
|
||||
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||
default:
|
||||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||
if (t[2]) _.ops.pop();
|
||||
_.trys.pop(); continue;
|
||||
}
|
||||
op = body.call(thisArg, _);
|
||||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||
}
|
||||
};
|
||||
var _this = this;
|
||||
var tests = require('./node');
|
||||
describe('Node JS environment', function () {
|
||||
var transactionResponse;
|
||||
var transactionSignatures;
|
||||
var failedAsPlanned;
|
||||
it('transacts with configuration object', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, tests.transactWithConfig()];
|
||||
case 1:
|
||||
transactionResponse = _a.sent();
|
||||
expect(Object.keys(transactionResponse)).toContain('transaction_id');
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('transacts with manually configured TAPOS fields', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, tests.transactWithoutConfig()];
|
||||
case 1:
|
||||
transactionResponse = _a.sent();
|
||||
expect(Object.keys(transactionResponse)).toContain('transaction_id');
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); }, 10000);
|
||||
it('transacts without broadcasting, returning signatures and packed transaction', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, tests.transactWithoutBroadcast()];
|
||||
case 1:
|
||||
transactionSignatures = _a.sent();
|
||||
expect(Object.keys(transactionSignatures)).toContain('signatures');
|
||||
expect(Object.keys(transactionSignatures)).toContain('serializedTransaction');
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('broadcasts packed transaction, given valid signatures', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, tests.transactWithoutBroadcast()];
|
||||
case 1:
|
||||
transactionSignatures = _a.sent();
|
||||
return [4 /*yield*/, tests.broadcastResult(transactionSignatures)];
|
||||
case 2:
|
||||
transactionResponse = _a.sent();
|
||||
expect(Object.keys(transactionResponse)).toContain('transaction_id');
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('throws appropriate error message without configuration object or TAPOS in place', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var e_1;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
_a.trys.push([0, 2, , 3]);
|
||||
failedAsPlanned = true;
|
||||
return [4 /*yield*/, tests.transactShouldFail()];
|
||||
case 1:
|
||||
_a.sent();
|
||||
failedAsPlanned = false;
|
||||
return [3 /*break*/, 3];
|
||||
case 2:
|
||||
e_1 = _a.sent();
|
||||
if (e_1.message !== 'Required configuration or TAPOS fields are not present') {
|
||||
failedAsPlanned = false;
|
||||
}
|
||||
return [3 /*break*/, 3];
|
||||
case 3:
|
||||
expect(failedAsPlanned).toEqual(true);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
it('throws an an error with RpcError structure for invalid RPC calls', function () { return __awaiter(_this, void 0, void 0, function () {
|
||||
var e_2;
|
||||
return __generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0:
|
||||
_a.trys.push([0, 2, , 3]);
|
||||
failedAsPlanned = true;
|
||||
return [4 /*yield*/, tests.rpcShouldFail()];
|
||||
case 1:
|
||||
_a.sent();
|
||||
failedAsPlanned = false;
|
||||
return [3 /*break*/, 3];
|
||||
case 2:
|
||||
e_2 = _a.sent();
|
||||
if (!e_2.json || !e_2.json.error || !(e_2.json.error.hasOwnProperty('details'))) {
|
||||
failedAsPlanned = false;
|
||||
}
|
||||
return [3 /*break*/, 3];
|
||||
case 3:
|
||||
expect(failedAsPlanned).toEqual(true);
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
}); });
|
||||
});
|
||||
//# sourceMappingURL=node.test.js.map
|
||||
@@ -1 +0,0 @@
|
||||
{"version":3,"file":"node.test.js","sourceRoot":"","sources":["../../src/tests/node.test.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iBAuDA;AAvDA,IAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;AAEhC,QAAQ,CAAC,qBAAqB,EAAE;IAC5B,IAAI,mBAAwB,CAAC;IAC7B,IAAI,qBAA0B,CAAC;IAC/B,IAAI,eAAwB,CAAC;IAE7B,EAAE,CAAC,qCAAqC,EAAE;;;wBAChB,qBAAM,KAAK,CAAC,kBAAkB,EAAE,EAAA;;oBAAtD,mBAAmB,GAAG,SAAgC,CAAC;oBACvD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;;;;SACxE,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE;;;wBAC5B,qBAAM,KAAK,CAAC,qBAAqB,EAAE,EAAA;;oBAAzD,mBAAmB,GAAG,SAAmC,CAAC;oBAC1D,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;;;;SACxE,EAAE,KAAK,CAAC,CAAC;IAEV,EAAE,CAAC,6EAA6E,EAAE;;;wBACtD,qBAAM,KAAK,CAAC,wBAAwB,EAAE,EAAA;;oBAA9D,qBAAqB,GAAG,SAAsC,CAAC;oBAC/D,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;oBACnE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;;;;SACjF,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE;;;wBAChC,qBAAM,KAAK,CAAC,wBAAwB,EAAE,EAAA;;oBAA9D,qBAAqB,GAAG,SAAsC,CAAC;oBACzC,qBAAM,KAAK,CAAC,eAAe,CAAC,qBAAqB,CAAC,EAAA;;oBAAxE,mBAAmB,GAAG,SAAkD,CAAC;oBACzE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;;;;SACxE,CAAC,CAAC;IAEH,EAAE,CAAC,iFAAiF,EAAE;;;;;;oBAE9E,eAAe,GAAG,IAAI,CAAC;oBACvB,qBAAM,KAAK,CAAC,kBAAkB,EAAE,EAAA;;oBAAhC,SAAgC,CAAC;oBACjC,eAAe,GAAG,KAAK,CAAC;;;;oBAExB,IAAI,GAAC,CAAC,OAAO,KAAK,wDAAwD,EAAE;wBACxE,eAAe,GAAG,KAAK,CAAC;qBAC3B;;;oBAEL,MAAM,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;;;;SACzC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE;;;;;;oBAE/D,eAAe,GAAG,IAAI,CAAC;oBACvB,qBAAM,KAAK,CAAC,aAAa,EAAE,EAAA;;oBAA3B,SAA2B,CAAC;oBAC5B,eAAe,GAAG,KAAK,CAAC;;;;oBAExB,IAAI,CAAC,GAAC,CAAC,IAAI,IAAI,CAAC,GAAC,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,GAAC,CAAC,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,EAAE;wBACvE,eAAe,GAAG,KAAK,CAAC;qBAC3B;;;oBAEL,MAAM,CAAC,eAAe,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;;;;SACzC,CAAC,CAAC;AACP,CAAC,CAAC,CAAC"}
|
||||
@@ -1,182 +0,0 @@
|
||||
import {createHash} from "crypto";
|
||||
import * as _ from "lodash";
|
||||
import {FastifyInstance, FastifyReply, FastifyRequest, HTTPMethod, RouteSchema} from "fastify";
|
||||
import {ServerResponse} from "http";
|
||||
|
||||
export function extendResponseSchema(responseProps: any) {
|
||||
const props = {
|
||||
query_time_ms: {type: "number"},
|
||||
cached: {type: "boolean"},
|
||||
lib: {type: "number"},
|
||||
total: {
|
||||
type: "object",
|
||||
properties: {
|
||||
value: {type: "number"},
|
||||
relation: {type: "string"}
|
||||
}
|
||||
}
|
||||
};
|
||||
for (const p in responseProps) {
|
||||
if (responseProps.hasOwnProperty(p)) {
|
||||
props[p] = responseProps[p];
|
||||
}
|
||||
}
|
||||
return {
|
||||
200: {
|
||||
type: 'object',
|
||||
properties: props
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function extendQueryStringSchema(queryParams: any) {
|
||||
const params = {
|
||||
limit: {
|
||||
description: 'limit of [n] results per page',
|
||||
type: 'integer',
|
||||
minimum: 1
|
||||
},
|
||||
skip: {
|
||||
description: 'skip [n] results',
|
||||
type: 'integer',
|
||||
minimum: 0
|
||||
}
|
||||
};
|
||||
for (const p in queryParams) {
|
||||
if (queryParams.hasOwnProperty(p)) {
|
||||
params[p] = queryParams[p];
|
||||
}
|
||||
}
|
||||
return {
|
||||
type: 'object',
|
||||
properties: params
|
||||
}
|
||||
}
|
||||
|
||||
export async function getCacheByHash(redis, key, chain) {
|
||||
const hash = createHash('sha256');
|
||||
const query_hash = hash.update(chain + "-" + key).digest('hex');
|
||||
return [await redis.get(query_hash), query_hash];
|
||||
}
|
||||
|
||||
export function mergeActionMeta(action) {
|
||||
const name = action.act.name;
|
||||
if (action['@' + name]) {
|
||||
action['act']['data'] = _.merge(action['@' + name], action['act']['data']);
|
||||
delete action['@' + name];
|
||||
}
|
||||
action['timestamp'] = action['@timestamp'];
|
||||
// delete action['@timestamp'];
|
||||
}
|
||||
|
||||
export function mergeDeltaMeta(delta: any) {
|
||||
const name = delta.table;
|
||||
if (delta["@" + name]) {
|
||||
delta['data'] = _.merge(delta['@' + name], delta['data']);
|
||||
delete delta['@' + name];
|
||||
}
|
||||
delta['timestamp'] = delta['@timestamp'];
|
||||
delete delta['@timestamp'];
|
||||
return delta;
|
||||
}
|
||||
|
||||
export function setCacheByHash(fastify, hash, response) {
|
||||
if (fastify.manager.config.api.enable_caching) {
|
||||
fastify.redis
|
||||
.set(hash,
|
||||
JSON.stringify(response),
|
||||
'EX',
|
||||
fastify.manager.config.api.cache_life)
|
||||
.catch(console.log);
|
||||
}
|
||||
}
|
||||
|
||||
export function getRouteName(filename: string) {
|
||||
const arr = filename.split("/");
|
||||
return arr[arr.length - 2];
|
||||
}
|
||||
|
||||
export function addApiRoute(
|
||||
fastifyInstance: FastifyInstance,
|
||||
method: HTTPMethod | HTTPMethod[],
|
||||
routeName: string,
|
||||
routeBuilder: (fastify: FastifyInstance, route: string) => (request: FastifyRequest, reply: FastifyReply<ServerResponse>) => Promise<void>, schema: RouteSchema) {
|
||||
fastifyInstance.route({
|
||||
url: '/' + routeName,
|
||||
method,
|
||||
handler: routeBuilder(fastifyInstance, routeName),
|
||||
schema
|
||||
});
|
||||
}
|
||||
|
||||
export async function getCachedResponse(server: FastifyInstance, route: string, key: any) {
|
||||
const chain = server.manager.chain;
|
||||
let resp, hash;
|
||||
if (server.manager.config.api.enable_caching) {
|
||||
const keystring = JSON.stringify(key);
|
||||
[resp, hash] = await getCacheByHash(server.redis, route + keystring, chain);
|
||||
if (resp) {
|
||||
resp = JSON.parse(resp);
|
||||
resp['cached'] = true;
|
||||
return [resp, hash];
|
||||
} else {
|
||||
return [null, hash];
|
||||
}
|
||||
} else {
|
||||
return [null, null];
|
||||
}
|
||||
}
|
||||
|
||||
export function getTrackTotalHits(query) {
|
||||
let trackTotalHits: number | boolean = 10000;
|
||||
if (query?.track) {
|
||||
if (query.track === 'true') {
|
||||
trackTotalHits = true;
|
||||
} else if (query.track === 'false') {
|
||||
trackTotalHits = false;
|
||||
} else {
|
||||
trackTotalHits = parseInt(query.track, 10);
|
||||
if (isNaN(trackTotalHits)) {
|
||||
throw new Error('failed to parse track param');
|
||||
}
|
||||
}
|
||||
}
|
||||
return trackTotalHits;
|
||||
}
|
||||
|
||||
function bigint2Milliseconds(input: bigint) {
|
||||
return parseFloat((parseInt(input.toString()) / 1000000).toFixed(3));
|
||||
}
|
||||
|
||||
export async function timedQuery(
|
||||
queryFunction: (fastify: FastifyInstance, request: FastifyRequest) => Promise<any>,
|
||||
fastify: FastifyInstance, request: FastifyRequest, route: string): Promise<any> {
|
||||
|
||||
// get reference time in nanoseconds
|
||||
const t0 = process.hrtime.bigint();
|
||||
|
||||
// check for cached data, return the response hash if caching is enabled
|
||||
const [cachedResponse, hash] = await getCachedResponse(fastify, route, request.query);
|
||||
|
||||
if (cachedResponse) {
|
||||
// add cached query time
|
||||
cachedResponse['query_time_ms'] = bigint2Milliseconds(process.hrtime.bigint() - t0);
|
||||
return cachedResponse;
|
||||
}
|
||||
|
||||
// call query function
|
||||
const response = await queryFunction(fastify, request);
|
||||
|
||||
// save response to cash
|
||||
if (hash) {
|
||||
setCacheByHash(fastify, hash, response);
|
||||
}
|
||||
|
||||
// add normal query time
|
||||
if (response) {
|
||||
response['query_time_ms'] = bigint2Milliseconds(process.hrtime.bigint() - t0);
|
||||
return response;
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
import * as Fastify from "fastify";
|
||||
import {IncomingMessage, Server, ServerResponse} from "http";
|
||||
|
||||
// fastify plugins
|
||||
import * as fastify_elasticsearch from 'fastify-elasticsearch';
|
||||
import * as fastify_oas from 'fastify-oas';
|
||||
import * as fastify_cors from 'fastify-cors';
|
||||
import * as fastify_formbody from 'fastify-formbody';
|
||||
import * as fastify_redis from 'fastify-redis';
|
||||
import * as fastify_rate_limit from 'fastify-rate-limit';
|
||||
|
||||
// custom plugins
|
||||
import fastify_eosjs from "./plugins/fastify-eosjs";
|
||||
|
||||
export function registerPlugins(server: Fastify.FastifyInstance<Server, IncomingMessage, ServerResponse>, params: any) {
|
||||
server.register(fastify_elasticsearch, params.fastify_elasticsearch);
|
||||
server.register(fastify_oas, params.fastify_oas);
|
||||
server.register(fastify_cors);
|
||||
server.register(fastify_formbody);
|
||||
server.register(fastify_redis, params.fastify_redis);
|
||||
server.register(fastify_eosjs, params.fastify_eosjs);
|
||||
server.register(fastify_rate_limit, params.fastify_rate_limit);
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
const fp = require('fastify-plugin');
|
||||
const {Api} = require("eosjs");
|
||||
const {ConnectionManager} = require('../../connections/manager');
|
||||
const manager = new ConnectionManager();
|
||||
|
||||
module.exports = fp(async (fastify, options, next) => {
|
||||
const rpc = manager.nodeosJsonRPC;
|
||||
const chain_data = await rpc.get_info();
|
||||
const api = new Api({
|
||||
rpc,
|
||||
signatureProvider: null,
|
||||
chainId: chain_data.chain_id,
|
||||
textDecoder: new TextDecoder(),
|
||||
textEncoder: new TextEncoder(),
|
||||
});
|
||||
fastify.decorate('eosjs', {api, rpc});
|
||||
next();
|
||||
}, {
|
||||
fastify: '>=2.0.0',
|
||||
name: 'fastify-eosjs'
|
||||
});
|
||||
@@ -1,20 +0,0 @@
|
||||
import * as fp from 'fastify-plugin';
|
||||
import {FastifyInstance} from "fastify";
|
||||
import {Api} from "eosjs/dist";
|
||||
|
||||
export default fp(async (fastify: FastifyInstance, options, next) => {
|
||||
const rpc = fastify.manager.nodeosJsonRPC;
|
||||
const chain_data = await rpc.get_info();
|
||||
const api = new Api({
|
||||
rpc,
|
||||
signatureProvider: null,
|
||||
chainId: chain_data.chain_id,
|
||||
textDecoder: new TextDecoder(),
|
||||
textEncoder: new TextEncoder(),
|
||||
});
|
||||
fastify.decorate('eosjs', {api, rpc});
|
||||
next();
|
||||
}, {
|
||||
fastify: '>=2.0.0',
|
||||
name: 'fastify-eosjs'
|
||||
});
|
||||
@@ -1,30 +0,0 @@
|
||||
const fp = require('fastify-plugin');
|
||||
const WebSocket = require('ws');
|
||||
|
||||
module.exports = fp((fastify, opts, next) => {
|
||||
|
||||
const wss = new WebSocket.Server({
|
||||
server: fastify.server
|
||||
});
|
||||
|
||||
const ws = new WebSocket('ws://127.0.0.1:7001', [], {
|
||||
perMessageDeflate: false
|
||||
});
|
||||
|
||||
ws.on('open', function open() {
|
||||
console.log('router connected');
|
||||
});
|
||||
|
||||
fastify.decorate('wss', wss);
|
||||
fastify.decorate('ws', ws);
|
||||
|
||||
fastify.addHook('onClose', (fastify, done) => {
|
||||
fastify.ws.close(done);
|
||||
fastify.wss.close(done);
|
||||
});
|
||||
|
||||
next();
|
||||
}, {
|
||||
fastify: '2.x',
|
||||
name: 'fastify-websocket'
|
||||
});
|
||||
@@ -1,56 +0,0 @@
|
||||
import * as fastify_static from "fastify-static";
|
||||
import {join} from "path";
|
||||
import {FastifyInstance, FastifyReply, FastifyRequest} from "fastify";
|
||||
import {ServerResponse} from "http";
|
||||
import {createReadStream} from "fs";
|
||||
import * as AutoLoad from "fastify-autoload";
|
||||
|
||||
function addRedirect(server: FastifyInstance, url: string, redirectTo: string) {
|
||||
server.route({
|
||||
url,
|
||||
method: 'GET',
|
||||
schema: {hide: true},
|
||||
handler: async (request, reply) => {
|
||||
reply.redirect(redirectTo);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function addRoute(server: FastifyInstance, handlersPath: string, prefix: string) {
|
||||
server.register(AutoLoad, {
|
||||
dir: join(__dirname, 'routes', handlersPath),
|
||||
ignorePattern: /.*(handler|schema).js/,
|
||||
options: {prefix}
|
||||
});
|
||||
}
|
||||
|
||||
export function registerRoutes(server: FastifyInstance) {
|
||||
|
||||
// Register fastify api routes
|
||||
addRoute(server, 'v2', '/v2');
|
||||
addRoute(server, 'v2-history', '/v2/history');
|
||||
addRoute(server, 'v2-state', '/v2/state');
|
||||
addRoute(server, 'v1-history', '/v1/history');
|
||||
// addRoute(server,'v1-chain', '/v1/chain');
|
||||
|
||||
// Serve integrated explorer
|
||||
if(server.manager.config.api.enable_explorer) {
|
||||
server.register(fastify_static, {
|
||||
root: join(__dirname, '..', 'hyperion-explorer', 'dist'),
|
||||
redirect: true,
|
||||
wildcard: true,
|
||||
prefix: '/v2/explore'
|
||||
});
|
||||
}
|
||||
|
||||
// steam client lib
|
||||
server.get('/stream-client.js', (request: FastifyRequest, reply: FastifyReply<ServerResponse>) => {
|
||||
const stream = createReadStream('./client_bundle.js');
|
||||
reply.type('application/javascript').send(stream);
|
||||
});
|
||||
|
||||
// Redirect routes to documentation
|
||||
addRedirect(server, '/v2', '/v2/docs');
|
||||
addRedirect(server, '/v2/history', '/v2/docs/index.html#/history');
|
||||
addRedirect(server, '/v2/state', '/v2/docs/index.html#/state');
|
||||
}
|
||||
@@ -1,227 +0,0 @@
|
||||
const async = require('async');
|
||||
const {Serialize} = require('eosjs');
|
||||
const {ConnectionManager} = require('../../connections/manager');
|
||||
let abi, types;
|
||||
let connected = false;
|
||||
let tables = new Map();
|
||||
const textEncoder = new TextEncoder();
|
||||
const textDecoder = new TextDecoder();
|
||||
const ws_opts = {compress: true, binary: true, mask: true, fin: true};
|
||||
const maxMessagesInFlight = 1;
|
||||
const blockReadingQueue = async.cargo(async.ensureAsync(processIncomingBlockArray), maxMessagesInFlight);
|
||||
|
||||
class BlockStore {
|
||||
localBlocks;
|
||||
pendingBlocks;
|
||||
pendingRequests;
|
||||
constructor() {
|
||||
this.pendingRequests = [];
|
||||
this.localBlocks = new Map();
|
||||
this.pendingBlocks = new Map();
|
||||
}
|
||||
|
||||
addBlock(num, data) {
|
||||
if (this.pendingBlocks.has(num)) {
|
||||
this.localBlocks.set(num, data);
|
||||
this.pendingBlocks.get(num)['callback']();
|
||||
this.pendingBlocks.delete(num);
|
||||
}
|
||||
}
|
||||
|
||||
requestRange(from_block, to_block, onBlock, onCompletion) {
|
||||
// console.log(`Requesting blocks from ${from_block} to ${to_block}`);
|
||||
const range = to_block - from_block;
|
||||
// console.log(`Range size: ${range}`);
|
||||
let requested = range;
|
||||
for (let i = 0; i < range; i++) {
|
||||
const blk_num = from_block + i;
|
||||
// console.log('Looking on local cache for block ' + blk_num);
|
||||
if (this.localBlocks.has(blk_num)) {
|
||||
onBlock(this.localBlocks.get(blk_num), true);
|
||||
requested--;
|
||||
} else {
|
||||
this.pendingBlocks.set(blk_num, {
|
||||
callback: () => {
|
||||
onBlock(this.localBlocks.get(blk_num), false);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
if (requested > 0) {
|
||||
requestBlockRange(from_block, to_block);
|
||||
const checker = setInterval(() => {
|
||||
if (this.pendingBlocks.size === 0) {
|
||||
onCompletion();
|
||||
clearInterval(checker);
|
||||
}
|
||||
}, 30);
|
||||
} else {
|
||||
onCompletion();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const blockStore = new BlockStore();
|
||||
|
||||
const baseRequest = {
|
||||
max_messages_in_flight: maxMessagesInFlight,
|
||||
have_positions: [],
|
||||
irreversible_only: false,
|
||||
fetch_block: true,
|
||||
fetch_traces: true,
|
||||
fetch_deltas: false
|
||||
};
|
||||
|
||||
const manager = new ConnectionManager();
|
||||
const shipClient = manager.shipClient;
|
||||
startWS();
|
||||
|
||||
function createSerialBuffer(array_data) {
|
||||
return new Serialize.SerialBuffer({textEncoder, textDecoder, array: array_data});
|
||||
}
|
||||
|
||||
|
||||
function serialize(type, value) {
|
||||
const buffer = createSerialBuffer();
|
||||
Serialize.getType(types, type).serialize(buffer, value);
|
||||
return buffer.asUint8Array();
|
||||
}
|
||||
|
||||
function deserialize(type, array) {
|
||||
const buffer = new Serialize.SerialBuffer({textEncoder, textDecoder, array});
|
||||
const sState = new Serialize.SerializerState({bytesAsUint8Array: true});
|
||||
return Serialize.getType(types, type).deserialize(buffer, sState);
|
||||
}
|
||||
|
||||
function processIncomingBlockArray(payload, cb) {
|
||||
processIncomingBlocks(payload).then(() => {
|
||||
cb();
|
||||
}).catch((err) => {
|
||||
console.log('FATAL ERROR READING BLOCKS', err);
|
||||
process.exit(1);
|
||||
})
|
||||
}
|
||||
|
||||
function handleLostConnection() {
|
||||
console.log('connection lost');
|
||||
connected = false;
|
||||
startWS();
|
||||
}
|
||||
|
||||
function ackBlocks(num) {
|
||||
shipClient.send(serialize('request',
|
||||
['get_blocks_ack_request_v0', {num_messages: num}]
|
||||
), ws_opts, (err) => {
|
||||
if (err) console.warn(err);
|
||||
});
|
||||
}
|
||||
|
||||
async function processIncomingBlocks(block_array) {
|
||||
if (abi) {
|
||||
ackBlocks(block_array.length);
|
||||
for (const block of block_array) {
|
||||
try {
|
||||
await onMessage(block);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
await onMessage(block_array[0]);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function processFirstABI(data) {
|
||||
abi = JSON.parse(data);
|
||||
types = Serialize.getTypesFromAbi(Serialize.createInitialTypes(), abi);
|
||||
abi.tables.map(table => tables.set(table.name, table.type));
|
||||
}
|
||||
|
||||
function deserializeType(obj) {
|
||||
return deserialize(obj[0], obj[1], textEncoder, textDecoder, types);
|
||||
}
|
||||
|
||||
function onMessage(data) {
|
||||
if (abi) {
|
||||
const res = deserialize('result', data)[1];
|
||||
if (res['this_block']) {
|
||||
const blk_num = res['this_block']['block_num'];
|
||||
const block_data = {
|
||||
block: null,
|
||||
traces: [],
|
||||
deltas: []
|
||||
};
|
||||
if (res.block && res.block.length) {
|
||||
block_data.block = deserialize('signed_block', res.block, textEncoder, textDecoder, types);
|
||||
if (block_data.block === null) {
|
||||
console.log(res);
|
||||
} else {
|
||||
block_data.block.id = res['this_block']['block_id'];
|
||||
block_data.block.block_num = blk_num;
|
||||
block_data.block.transactions = [];
|
||||
|
||||
if (res['traces'] && res['traces'].length) {
|
||||
const trx_traces = deserialize('transaction_trace[]', res['traces'], textEncoder, textDecoder, types).map(trace => trace[1]);
|
||||
for (const trace of trx_traces) {
|
||||
trace.partial = trace.partial[1];
|
||||
trace.actions = [];
|
||||
for (const action_trace of trace.action_traces) {
|
||||
// console.log(action_trace);
|
||||
// action_trace.receipt = action_trace.receipt[1];
|
||||
const action = action_trace[1];
|
||||
action.receipt = action.receipt[1];
|
||||
action['act']['data'] = Buffer.from(action['act']['data']).toString('hex');
|
||||
trace.actions.push(action);
|
||||
}
|
||||
delete trace.action_traces;
|
||||
if (trace.actions[0]['act']['account'] === 'eosio' && trace.actions[0]['act']['name'] === 'onblock') {
|
||||
// ingore onblock
|
||||
} else {
|
||||
block_data.block.transactions.push(trace);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// if (res['deltas'] && res['deltas'].length) {
|
||||
// block_data.deltas = deserialize('table_delta[]', res['deltas'], textEncoder, textDecoder, types);
|
||||
// }
|
||||
blockStore.addBlock(blk_num, block_data.block);
|
||||
}
|
||||
} else {
|
||||
processFirstABI(data);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
function send(req_data) {
|
||||
shipClient.send(serialize('request', req_data, textEncoder, textDecoder, types));
|
||||
}
|
||||
|
||||
function requestBlockRange(start, finish) {
|
||||
const request = baseRequest;
|
||||
request.start_block_num = start;
|
||||
request.end_block_num = finish;
|
||||
// console.log(request);
|
||||
if (connected) {
|
||||
send(['get_blocks_request_v0', request]);
|
||||
} else {
|
||||
startWS(() => {
|
||||
send(['get_blocks_request_v0', request]);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function startWS(onConnect) {
|
||||
if (onConnect) {
|
||||
shipClient.connect(blockReadingQueue.push, handleLostConnection, null, onConnect);
|
||||
} else {
|
||||
shipClient.connect(blockReadingQueue.push, handleLostConnection);
|
||||
}
|
||||
connected = true;
|
||||
}
|
||||
|
||||
module.exports = {blockStore};
|
||||
@@ -1,72 +0,0 @@
|
||||
const {getCacheByHash} = require("../../helpers/functions");
|
||||
const {getAbiSnapshotSchema} = require("../../schemas");
|
||||
|
||||
const enable_caching = process.env.ENABLE_CACHING === 'true';
|
||||
let cache_life = 30;
|
||||
if (process.env.CACHE_LIFE) {
|
||||
cache_life = parseInt(process.env.CACHE_LIFE);
|
||||
}
|
||||
|
||||
async function getAbiSnapshot(fastify, request) {
|
||||
const t0 = Date.now();
|
||||
const {redis, elastic} = fastify;
|
||||
const [cachedResponse, hash] = await getCacheByHash(redis, JSON.stringify(request.query));
|
||||
if (cachedResponse) {
|
||||
return JSON.parse(cachedResponse);
|
||||
}
|
||||
|
||||
const response = {
|
||||
query_time: 0,
|
||||
block_num: null
|
||||
};
|
||||
|
||||
const code = request.query.contract;
|
||||
const block = request.query.block;
|
||||
const should_fetch = request.query.fetch;
|
||||
|
||||
if (should_fetch) {
|
||||
console.log(should_fetch);
|
||||
}
|
||||
|
||||
const mustArray = [];
|
||||
|
||||
mustArray.push({"term": {"account": code}});
|
||||
|
||||
if (block) {
|
||||
mustArray.push({"range": {"block": {"lte": parseInt(block)}}});
|
||||
}
|
||||
|
||||
const results = await elastic.search({
|
||||
index: process.env.CHAIN + '-abi',
|
||||
size: 1,
|
||||
body: {
|
||||
query: {bool: {must: mustArray}},
|
||||
sort: [{block: {order: "desc"}}]
|
||||
}
|
||||
});
|
||||
if (results['body']['hits']['hits'].length > 0) {
|
||||
if (should_fetch) {
|
||||
response['abi'] = JSON.parse(results['body']['hits']['hits'][0]['_source']['abi']);
|
||||
} else {
|
||||
response['present'] = true;
|
||||
}
|
||||
response.block_num = results['body']['hits']['hits'][0]['_source']['block'];
|
||||
} else {
|
||||
response['present'] = false;
|
||||
response['error'] = 'abi not found for ' + code + ' until block ' + block;
|
||||
}
|
||||
response['query_time'] = Date.now() - t0;
|
||||
if (enable_caching) {
|
||||
redis.set(hash, JSON.stringify(response), 'EX', cache_life);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
module.exports = function (fastify, opts, next) {
|
||||
fastify.get('/get_abi_snapshot', {
|
||||
schema: getAbiSnapshotSchema.GET
|
||||
}, async (request, reply) => {
|
||||
reply.send(await getAbiSnapshot(fastify, request));
|
||||
});
|
||||
next()
|
||||
};
|
||||
@@ -1,378 +0,0 @@
|
||||
const prettyjson = require("prettyjson");
|
||||
const {getActionsSchema} = require("../../schemas");
|
||||
const {getCacheByHash, mergeActionMeta} = require("../../helpers/functions");
|
||||
|
||||
const maxActions = 1000;
|
||||
const route = '/get_actions';
|
||||
|
||||
const terms = [
|
||||
"notified.keyword",
|
||||
"act.authorization.actor"
|
||||
];
|
||||
|
||||
const extendedActions = new Set([
|
||||
"transfer",
|
||||
"newaccount",
|
||||
"updateauth",
|
||||
"buyram",
|
||||
"buyrambytes"
|
||||
]);
|
||||
|
||||
const primaryTerms = [
|
||||
"notified",
|
||||
"block_num",
|
||||
"global_sequence",
|
||||
"producer",
|
||||
"@timestamp",
|
||||
"creator_action_ordinal",
|
||||
"action_ordinal",
|
||||
"cpu_usage_us",
|
||||
"net_usage_words"
|
||||
];
|
||||
|
||||
const enable_caching = process.env.ENABLE_CACHING === 'true';
|
||||
let cache_life = 30;
|
||||
if (process.env.CACHE_LIFE) {
|
||||
cache_life = parseInt(process.env.CACHE_LIFE);
|
||||
}
|
||||
|
||||
function getTrackTotalHits(query) {
|
||||
let trackTotalHits = 15000;
|
||||
if (query.track) {
|
||||
if (query.track === 'true') {
|
||||
trackTotalHits = true;
|
||||
} else if (query.track === 'false') {
|
||||
trackTotalHits = false;
|
||||
} else {
|
||||
trackTotalHits = parseInt(query.track, 10);
|
||||
if (trackTotalHits !== trackTotalHits) {
|
||||
throw new Error('failed to parse track param');
|
||||
}
|
||||
}
|
||||
}
|
||||
return trackTotalHits;
|
||||
}
|
||||
|
||||
function addSortedBy(query, queryBody, sort_direction) {
|
||||
if (query['sortedBy']) {
|
||||
const opts = query['sortedBy'].split(":");
|
||||
const sortedByObj = {};
|
||||
sortedByObj[opts[0]] = opts[1];
|
||||
queryBody['sort'] = sortedByObj;
|
||||
} else {
|
||||
queryBody['sort'] = {
|
||||
"global_sequence": sort_direction
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function processMultiVars(queryStruct, parts, field) {
|
||||
const must = [];
|
||||
const mustNot = [];
|
||||
|
||||
parts.forEach(part => {
|
||||
if (part.startsWith("!")) {
|
||||
mustNot.push(part.replace("!", ""));
|
||||
} else {
|
||||
must.push(part);
|
||||
}
|
||||
});
|
||||
|
||||
if (must.length > 1) {
|
||||
queryStruct.bool.must.push({
|
||||
bool: {
|
||||
should: must.map(elem => {
|
||||
const _q = {};
|
||||
_q[field] = elem;
|
||||
return {term: _q}
|
||||
})
|
||||
}
|
||||
});
|
||||
} else if (must.length === 1) {
|
||||
const mustQuery = {};
|
||||
mustQuery[field] = must[0];
|
||||
queryStruct.bool.must.push({term: mustQuery});
|
||||
}
|
||||
|
||||
if (mustNot.length > 1) {
|
||||
queryStruct.bool.must_not.push({
|
||||
bool: {
|
||||
should: mustNot.map(elem => {
|
||||
const _q = {};
|
||||
_q[field] = elem;
|
||||
return {term: _q}
|
||||
})
|
||||
}
|
||||
});
|
||||
} else if (mustNot.length === 1) {
|
||||
const mustNotQuery = {};
|
||||
mustNotQuery[field] = mustNot[0].replace("!", "");
|
||||
queryStruct.bool.must_not.push({term: mustNotQuery});
|
||||
}
|
||||
}
|
||||
|
||||
function addRangeQuery(queryStruct, prop, pkey, query) {
|
||||
const _termQuery = {};
|
||||
const parts = query[prop].split("-");
|
||||
_termQuery[pkey] = {
|
||||
"gte": parts[0],
|
||||
"lte": parts[1]
|
||||
};
|
||||
queryStruct.bool.must.push({range: _termQuery});
|
||||
}
|
||||
|
||||
function applyTimeFilter(query, queryStruct) {
|
||||
if (query['after'] || query['before']) {
|
||||
let _lte = "now";
|
||||
let _gte = 0;
|
||||
if (query['before']) {
|
||||
_lte = query['before'];
|
||||
if (!_lte.endsWith("Z")) {
|
||||
_lte += "Z";
|
||||
}
|
||||
}
|
||||
if (query['after']) {
|
||||
_gte = query['after'];
|
||||
if (!_gte.endsWith("Z")) {
|
||||
_gte += "Z";
|
||||
}
|
||||
}
|
||||
if (!queryStruct.bool['filter']) {
|
||||
queryStruct.bool['filter'] = [];
|
||||
}
|
||||
queryStruct.bool['filter'].push({
|
||||
range: {
|
||||
"@timestamp": {
|
||||
"gte": _gte,
|
||||
"lte": _lte
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function applyGenericFilters(query, queryStruct) {
|
||||
for (const prop in query) {
|
||||
if (Object.prototype.hasOwnProperty.call(query, prop)) {
|
||||
const pair = prop.split(".");
|
||||
if (pair.length > 1 || primaryTerms.includes(pair[0])) {
|
||||
let pkey;
|
||||
if (pair.length > 1) {
|
||||
pkey = extendedActions.has(pair[0]) ? "@" + prop : prop;
|
||||
} else {
|
||||
pkey = prop;
|
||||
}
|
||||
if (query[prop].indexOf("-") !== -1) {
|
||||
addRangeQuery(queryStruct, prop, pkey, query);
|
||||
} else {
|
||||
const _termQuery = {};
|
||||
const parts = query[prop].split(",");
|
||||
if (parts.length > 1) {
|
||||
processMultiVars(queryStruct, parts, prop);
|
||||
} else if (parts.length === 1) {
|
||||
const andParts = parts[0].split(" ");
|
||||
if (andParts.length > 1) {
|
||||
andParts.forEach(value => {
|
||||
const _q = {};
|
||||
console.log(value);
|
||||
_q[pkey] = value;
|
||||
queryStruct.bool.must.push({term: _q});
|
||||
});
|
||||
} else {
|
||||
if (parts[0].startsWith("!")) {
|
||||
_termQuery[pkey] = parts[0].replace("!", "");
|
||||
queryStruct.bool.must_not.push({term: _termQuery});
|
||||
} else {
|
||||
_termQuery[pkey] = parts[0];
|
||||
queryStruct.bool.must.push({term: _termQuery});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function makeShouldArray(query) {
|
||||
const should_array = [];
|
||||
for (const entry of terms) {
|
||||
const tObj = {term: {}};
|
||||
tObj.term[entry] = query.account;
|
||||
should_array.push(tObj);
|
||||
}
|
||||
return should_array;
|
||||
}
|
||||
|
||||
function applyCodeActionFilters(query, queryStruct) {
|
||||
let filterObj = [];
|
||||
if (query.filter) {
|
||||
for (const filter of query.filter.split(',')) {
|
||||
if (filter !== '*:*') {
|
||||
const _arr = [];
|
||||
const parts = filter.split(':');
|
||||
if (parts.length === 2) {
|
||||
[code, method] = parts;
|
||||
if (code && code !== "*") {
|
||||
_arr.push({'term': {'act.account': code}});
|
||||
}
|
||||
if (method && method !== "*") {
|
||||
_arr.push({'term': {'act.name': method}});
|
||||
}
|
||||
}
|
||||
if (_arr.length > 0) {
|
||||
filterObj.push({bool: {must: _arr}});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (filterObj.length > 0) {
|
||||
queryStruct.bool['should'] = filterObj;
|
||||
queryStruct.bool['minimum_should_match'] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getSkipLimit(query) {
|
||||
let skip, limit;
|
||||
skip = parseInt(query.skip, 10);
|
||||
if (skip < 0) {
|
||||
throw new Error('invalid skip parameter');
|
||||
}
|
||||
limit = parseInt(query.limit, 10);
|
||||
if (limit < 1) {
|
||||
throw new Error('invalid limit parameter');
|
||||
}
|
||||
return {skip, limit};
|
||||
}
|
||||
|
||||
function getSortDir(query) {
|
||||
let sort_direction = 'desc';
|
||||
if (query.sort) {
|
||||
if (query.sort === 'asc' || query.sort === '1') {
|
||||
sort_direction = 'asc';
|
||||
} else if (query.sort === 'desc' || query.sort === '-1') {
|
||||
sort_direction = 'desc'
|
||||
} else {
|
||||
throw new Error('invalid sort direction');
|
||||
}
|
||||
}
|
||||
return sort_direction;
|
||||
}
|
||||
|
||||
function applyAccountFilters(query, queryStruct) {
|
||||
if (query.account) {
|
||||
queryStruct.bool.must.push({"bool": {should: makeShouldArray(query)}});
|
||||
}
|
||||
}
|
||||
|
||||
async function getActions(fastify, request) {
|
||||
const t0 = Date.now();
|
||||
const {redis, elastic, eosjs} = fastify;
|
||||
const query = request.query;
|
||||
let cachedResponse, hash;
|
||||
if (enable_caching) {
|
||||
[cachedResponse, hash] = await getCacheByHash(redis, route + JSON.stringify(query));
|
||||
if (cachedResponse) {
|
||||
cachedResponse = JSON.parse(cachedResponse);
|
||||
cachedResponse['query_time'] = Date.now() - t0;
|
||||
cachedResponse['cached'] = true;
|
||||
return cachedResponse;
|
||||
}
|
||||
}
|
||||
|
||||
const queryStruct = {
|
||||
"bool": {
|
||||
must: [],
|
||||
must_not: [],
|
||||
boost: 1.0
|
||||
}
|
||||
};
|
||||
|
||||
const {skip, limit} = getSkipLimit(query);
|
||||
|
||||
const sort_direction = getSortDir(query);
|
||||
|
||||
applyAccountFilters(query, queryStruct);
|
||||
|
||||
applyGenericFilters(query, queryStruct);
|
||||
|
||||
applyTimeFilter(query, queryStruct);
|
||||
|
||||
applyCodeActionFilters(query, queryStruct);
|
||||
|
||||
// allow precise counting of total hits
|
||||
const trackTotalHits = getTrackTotalHits(query);
|
||||
|
||||
// Prepare query body
|
||||
const query_body = {
|
||||
"track_total_hits": trackTotalHits,
|
||||
"query": queryStruct
|
||||
};
|
||||
|
||||
// Include sorting
|
||||
addSortedBy(query, query_body, sort_direction);
|
||||
|
||||
// console.log(prettyjson.render(queryStruct));
|
||||
|
||||
// Perform search
|
||||
const pResults = await Promise.all([eosjs.rpc.get_info(), elastic['search']({
|
||||
"index": process.env.CHAIN + '-action-*',
|
||||
"from": skip || 0,
|
||||
"size": (limit > maxActions ? maxActions : limit) || 10,
|
||||
"body": query_body
|
||||
})]);
|
||||
|
||||
const results = pResults[1]['body']['hits'];
|
||||
const response = {
|
||||
query_time: null,
|
||||
cached: false,
|
||||
lib: pResults[0].last_irreversible_block_num,
|
||||
total: results['total']
|
||||
};
|
||||
|
||||
if (query.simple) {
|
||||
response['simple_actions'] = [];
|
||||
} else {
|
||||
response['actions'] = [];
|
||||
}
|
||||
|
||||
if (results['hits'].length > 0) {
|
||||
const actions = results['hits'];
|
||||
for (let action of actions) {
|
||||
action = action._source;
|
||||
mergeActionMeta(action);
|
||||
if (query.simple) {
|
||||
response.simple_actions.push({
|
||||
block: action['block_num'],
|
||||
irreversible: action['block_num'] < pResults[0].last_irreversible_block_num,
|
||||
timestamp: action['@timestamp'],
|
||||
transaction_id: action['trx_id'],
|
||||
actors: action['act']['authorization'].map(a => `${a.actor}@${a.permission}`).join(","),
|
||||
notified: action['notified'].join(','),
|
||||
contract: action['act']['account'],
|
||||
action: action['act']['name'],
|
||||
data: action['act']['data']
|
||||
});
|
||||
} else {
|
||||
response.actions.push(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
response['query_time'] = Date.now() - t0;
|
||||
|
||||
if (enable_caching) {
|
||||
redis.set(hash, JSON.stringify(response), 'EX', cache_life);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
module.exports = function (fastify, opts, next) {
|
||||
fastify.get('/get_actions', {
|
||||
schema: getActionsSchema.GET
|
||||
}, async (request) => {
|
||||
return await getActions(fastify, request);
|
||||
});
|
||||
next()
|
||||
};
|
||||
@@ -1,49 +0,0 @@
|
||||
const {getBlocksSchema} = require("../../schemas");
|
||||
const {blockStore} = require('../blockStore');
|
||||
|
||||
async function getBlocks(fastify, request, reply) {
|
||||
const t0 = Date.now();
|
||||
let from_block, to_block;
|
||||
const {eosjs} = fastify;
|
||||
if (request.query.from) {
|
||||
from_block = parseInt(request.query.from);
|
||||
if (request.query.to) {
|
||||
to_block = parseInt(request.query.to);
|
||||
} else {
|
||||
to_block = from_block + 1;
|
||||
}
|
||||
} else {
|
||||
const head = (await eosjs.rpc.get_info()).head_block_num;
|
||||
from_block = head;
|
||||
to_block = head + 1;
|
||||
}
|
||||
|
||||
if (to_block > from_block) {
|
||||
if (to_block - from_block > 20) {
|
||||
reply.status(403).send('request over limit');
|
||||
} else {
|
||||
const response = {query_time: null, cached: false, blocks: []};
|
||||
console.log('Local Block store size:', blockStore.localBlocks.size);
|
||||
blockStore.requestRange(from_block, to_block, (block, cached) => {
|
||||
if (cached) {
|
||||
response.cached = true;
|
||||
}
|
||||
response.blocks.push(block);
|
||||
}, () => {
|
||||
response['query_time'] = Date.now() - t0;
|
||||
reply.send(response);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
reply.status(403).send('invalid block range');
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = function (fastify, opts, next) {
|
||||
fastify.get('/get_blocks', {
|
||||
schema: getBlocksSchema.GET
|
||||
}, async (request, reply) => {
|
||||
await getBlocks(fastify, request, reply);
|
||||
});
|
||||
next();
|
||||
};
|
||||
@@ -1,62 +0,0 @@
|
||||
const {getCreatedAccountsSchema} = require("../../schemas");
|
||||
const {getCacheByHash} = require("../../helpers/functions");
|
||||
|
||||
const route = '/get_created_accounts';
|
||||
|
||||
async function getCreatedAccounts(fastify, request) {
|
||||
const t0 = Date.now();
|
||||
const {redis, elastic} = fastify;
|
||||
const [cachedResponse, hash] = await getCacheByHash(redis, JSON.stringify(request.query));
|
||||
if (cachedResponse) {
|
||||
return cachedResponse;
|
||||
}
|
||||
const results = await elastic['search']({
|
||||
"index": process.env.CHAIN + '-action-*',
|
||||
"body": {
|
||||
"query": {
|
||||
"bool": {
|
||||
must: [
|
||||
{term: {"act.authorization.actor": request.query.account.toLowerCase()}},
|
||||
{term: {"act.name": "newaccount"}},
|
||||
{term: {"act.account": "eosio"}}
|
||||
]
|
||||
}
|
||||
},
|
||||
sort: {
|
||||
"global_sequence": "desc"
|
||||
}
|
||||
}
|
||||
});
|
||||
const response = {
|
||||
"accounts": []
|
||||
};
|
||||
if (results['body']['hits']['hits'].length > 0) {
|
||||
const actions = results['body']['hits']['hits'];
|
||||
for (let action of actions) {
|
||||
action = action._source;
|
||||
const _tmp = {};
|
||||
if (action['act']['data']['newact']) {
|
||||
_tmp['name'] = action['act']['data']['newact'];
|
||||
} else if (action['@newaccount']['newact']) {
|
||||
_tmp['name'] = action['@newaccount']['newact'];
|
||||
} else {
|
||||
console.log(action);
|
||||
}
|
||||
_tmp['trx_id'] = action['trx_id'];
|
||||
_tmp['timestamp'] = action['@timestamp'];
|
||||
response.accounts.push(_tmp);
|
||||
}
|
||||
}
|
||||
response['query_time'] = Date.now() - t0;
|
||||
redis.set(hash, JSON.stringify(response), 'EX', 30);
|
||||
return response;
|
||||
}
|
||||
|
||||
module.exports = function (fastify, opts, next) {
|
||||
fastify.get(route, {
|
||||
schema: getCreatedAccountsSchema.GET
|
||||
}, async (request) => {
|
||||
return await getCreatedAccounts(fastify, request);
|
||||
});
|
||||
next()
|
||||
};
|
||||
@@ -1,108 +0,0 @@
|
||||
const {getCreatorSchema} = require("../../schemas");
|
||||
const {getCacheByHash} = require("../../helpers/functions");
|
||||
|
||||
const route = '/get_creator';
|
||||
|
||||
async function getActionByGS(client, gs) {
|
||||
console.log(gs);
|
||||
const results = await client['search']({
|
||||
index: process.env.CHAIN + '-action-*',
|
||||
body: {
|
||||
query: {
|
||||
bool: {
|
||||
must: [
|
||||
{term: {"global_sequence": gs}}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return results['body']['hits']['hits'][0]['_source'];
|
||||
}
|
||||
|
||||
async function getCreator(fastify, request) {
|
||||
const {redis, elastic, eosjs} = fastify;
|
||||
const [cachedResponse, hash] = await getCacheByHash(redis, route + JSON.stringify(request.query) + 'v3');
|
||||
if (cachedResponse) {
|
||||
return cachedResponse;
|
||||
}
|
||||
const newact = request.query.account;
|
||||
const response = {
|
||||
account: newact,
|
||||
creator: '',
|
||||
timestamp: '',
|
||||
block_num: 0,
|
||||
trx_id: '',
|
||||
};
|
||||
let account_data = null;
|
||||
try {
|
||||
account_data = await eosjs.rpc.get_account(newact);
|
||||
} catch (e) {
|
||||
const err = new Error();
|
||||
err.statusCode = 404;
|
||||
err.message = 'account not found';
|
||||
throw err;
|
||||
}
|
||||
response.timestamp = account_data['created'];
|
||||
const queryBody = {
|
||||
size: 1000,
|
||||
query: {
|
||||
bool: {
|
||||
must: [
|
||||
{term: {"act.name": "newaccount"}},
|
||||
{term: {"act.account": "eosio"}},
|
||||
{term: {"@timestamp": account_data['created']}}
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
const results = await elastic['search']({
|
||||
"index": process.env.CHAIN + '-action-*',
|
||||
"body": queryBody
|
||||
});
|
||||
for (const action of results['body']['hits']['hits']) {
|
||||
const actData = action._source.act.data;
|
||||
let valid = false;
|
||||
response.block_num = action._source.block_num;
|
||||
if (actData.newact === newact) {
|
||||
response.creator = actData.creator;
|
||||
response['trx_id'] = action._source['trx_id'];
|
||||
valid = true;
|
||||
} else {
|
||||
if (action._source['@newaccount']) {
|
||||
if (action._source['@newaccount']['newact'] === newact) {
|
||||
response.creator = actData.creator;
|
||||
response['trx_id'] = action._source['trx_id'];
|
||||
valid = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if (action._source.parent !== 0 && valid) {
|
||||
//
|
||||
// // Find indirect creator by global seq
|
||||
// const creationAction = await getActionByGS(elastic, action._source.parent);
|
||||
//
|
||||
// if (creationAction.act.name === 'transfer') {
|
||||
// response['indirect_creator'] = creationAction['@transfer']['from'];
|
||||
// response['trx_id'] = creationAction['trx_id'];
|
||||
// } else {
|
||||
// response['indirect_creator'] = creationAction.act.authorization[0].actor;
|
||||
// response['trx_id'] = creationAction['trx_id'];
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
redis.set(hash, JSON.stringify(response), 'EX', 600);
|
||||
return response;
|
||||
}
|
||||
|
||||
module.exports = function (fastify, opts, next) {
|
||||
fastify.get(route, {
|
||||
schema: getCreatorSchema.GET
|
||||
}, async (request) => {
|
||||
return await getCreator(fastify, request);
|
||||
});
|
||||
next()
|
||||
};
|
||||
@@ -1,99 +0,0 @@
|
||||
const {getDeltasSchema} = require("../../schemas");
|
||||
const {getCacheByHash} = require("../../helpers/functions");
|
||||
|
||||
const route = '/get_deltas';
|
||||
const maxDeltas = 200;
|
||||
|
||||
async function getDeltas(fastify, request) {
|
||||
const t0 = Date.now();
|
||||
console.log(request.query);
|
||||
const {redis, elastic} = fastify;
|
||||
const [cachedResponse, hash] = await getCacheByHash(redis, route + JSON.stringify(request.query) + 'v2');
|
||||
|
||||
// if (cachedResponse) {
|
||||
// return cachedResponse;
|
||||
// }
|
||||
|
||||
let skip, limit;
|
||||
let sort_direction = 'desc';
|
||||
const mustArray = [];
|
||||
for (const param in request.query) {
|
||||
if (Object.prototype.hasOwnProperty.call(request.query, param)) {
|
||||
console.log(param, request.query[param]);
|
||||
const value = request.query[param];
|
||||
switch (param) {
|
||||
case 'limit': {
|
||||
limit = parseInt(value, 10);
|
||||
if (limit < 1) {
|
||||
return 'invalid limit parameter';
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'skip': {
|
||||
skip = parseInt(value, 10);
|
||||
if (skip < 0) {
|
||||
return 'invalid skip parameter';
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'sort': {
|
||||
if (value === 'asc' || value === '1') {
|
||||
sort_direction = 'asc';
|
||||
} else if (value === 'desc' || value === '-1') {
|
||||
sort_direction = 'desc'
|
||||
} else {
|
||||
return 'invalid sort direction';
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
const values = request.query[param].split(",");
|
||||
const terms = {};
|
||||
terms[param] = values;
|
||||
const shouldArray = {terms: terms};
|
||||
const boolStruct = {bool: {should: [shouldArray]}};
|
||||
mustArray.push(boolStruct);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let prefix = process.env.CHAIN;
|
||||
if (process.env.CHAIN === 'mainnet') {
|
||||
prefix = 'eos';
|
||||
}
|
||||
|
||||
const results = await elastic.search({
|
||||
"index": prefix + '-delta-*',
|
||||
"from": skip || 0,
|
||||
"size": (limit > maxDeltas ? maxDeltas : limit) || 10,
|
||||
"body": {
|
||||
query: {bool: {must: mustArray}},
|
||||
sort: {
|
||||
"block_num": sort_direction
|
||||
}
|
||||
}
|
||||
});
|
||||
const response = {
|
||||
query_time: null,
|
||||
total: results['body']['hits']['total'],
|
||||
deltas: results['body']['hits']['hits'].map((d) => {
|
||||
delete d._source.present;
|
||||
return d._source;
|
||||
})
|
||||
};
|
||||
response['query_time'] = Date.now() - t0;
|
||||
// redis.set(hash, JSON.stringify(response));
|
||||
return response;
|
||||
}
|
||||
|
||||
module.exports = function (fastify, opts, next) {
|
||||
fastify.get(route, {
|
||||
schema: getDeltasSchema.GET
|
||||
}, async (request) => {
|
||||
return await getDeltas(fastify, request);
|
||||
});
|
||||
next()
|
||||
};
|
||||
@@ -1,200 +0,0 @@
|
||||
const {getCacheByHash} = require("../../helpers/functions");
|
||||
|
||||
const {getTransactedAccountsSchema} = require("../../schemas");
|
||||
|
||||
async function getTransactedAccounts(fastify, request) {
|
||||
const t0 = Date.now();
|
||||
const {redis, elastic} = fastify;
|
||||
const [cachedResponse, hash] = await getCacheByHash(redis, JSON.stringify(request.query));
|
||||
if (cachedResponse) {
|
||||
return cachedResponse;
|
||||
}
|
||||
const {account, min, max, direction, limit, contract, symbol} = request.query;
|
||||
let _limit = 100;
|
||||
if (limit) {
|
||||
_limit = parseInt(limit, 10);
|
||||
if (_limit > 500) {
|
||||
_limit = 500;
|
||||
}
|
||||
}
|
||||
let _min;
|
||||
if (min) {
|
||||
_min = parseInt(min, 10);
|
||||
if (_min < 0) {
|
||||
_min = 0;
|
||||
}
|
||||
}
|
||||
let _max;
|
||||
if (max) {
|
||||
_max = parseInt(max, 10);
|
||||
if (_max < 0) {
|
||||
_max = null;
|
||||
}
|
||||
}
|
||||
|
||||
const response = {
|
||||
query_time: null,
|
||||
account: account
|
||||
};
|
||||
|
||||
const must_array = [
|
||||
{term: {"notified": account}},
|
||||
{term: {"act.name": "transfer"}}
|
||||
];
|
||||
|
||||
if (min || max) {
|
||||
const _range = {
|
||||
"@transfer.amount": {}
|
||||
};
|
||||
if (min) {
|
||||
_range["@transfer.amount"]["gte"] = _min;
|
||||
}
|
||||
if (max) {
|
||||
_range["@transfer.amount"]["lt"] = _max;
|
||||
}
|
||||
must_array.push({range: _range});
|
||||
}
|
||||
|
||||
if (contract) {
|
||||
must_array.push({term: {"act.account": contract}});
|
||||
response['contract'] = contract;
|
||||
}
|
||||
|
||||
if (symbol) {
|
||||
must_array.push({term: {"@transfer.symbol": symbol}});
|
||||
response['symbol'] = symbol;
|
||||
}
|
||||
|
||||
const sum_agg = {
|
||||
"total_amount": {
|
||||
sum: {
|
||||
field: "@transfer.amount"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let filter_array = [];
|
||||
if (request.query['after'] || request.query['before']) {
|
||||
let _lte = "now";
|
||||
let _gte = 0;
|
||||
if (request.query['before']) {
|
||||
_lte = request.query['before'];
|
||||
}
|
||||
if (request.query['after']) {
|
||||
_gte = request.query['after'];
|
||||
}
|
||||
filter_array.push({
|
||||
range: {
|
||||
"@timestamp": {
|
||||
"gte": _gte,
|
||||
"lte": _lte
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
filter_array.push({
|
||||
range: {
|
||||
"block_num": {
|
||||
"gte": 0
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (direction === 'out' || direction === 'both') {
|
||||
const outResults = await elastic.search({
|
||||
index: process.env.CHAIN + '-action-*',
|
||||
body: {
|
||||
size: 0,
|
||||
aggs: {
|
||||
"receivers": {
|
||||
terms: {
|
||||
field: "@transfer.to",
|
||||
size: _limit,
|
||||
order: {
|
||||
"total_amount": "desc"
|
||||
}
|
||||
},
|
||||
aggs: sum_agg
|
||||
}
|
||||
},
|
||||
query: {
|
||||
bool: {
|
||||
must: must_array,
|
||||
filter: filter_array,
|
||||
must_not: [
|
||||
{term: {"@transfer.to": account}}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
response['total_out'] = 0;
|
||||
response['outputs'] = outResults['body']['aggregations']['receivers']['buckets'].map((bucket) => {
|
||||
const _sum = parseFloat(bucket.total_amount.value.toFixed(4));
|
||||
response['total_out'] += _sum;
|
||||
return {
|
||||
account: bucket.key,
|
||||
sum: _sum,
|
||||
transfers: bucket['doc_count'],
|
||||
average: parseFloat((bucket.total_amount.value / bucket['doc_count']).toFixed(4))
|
||||
};
|
||||
});
|
||||
response['total_out'] = parseFloat(response['total_out'].toFixed(4));
|
||||
}
|
||||
|
||||
if (direction === 'in' || direction === 'both') {
|
||||
const inResults = await elastic.search({
|
||||
index: process.env.CHAIN + '-action-*',
|
||||
body: {
|
||||
size: 0,
|
||||
aggs: {
|
||||
"senders": {
|
||||
terms: {
|
||||
field: "@transfer.from",
|
||||
size: _limit,
|
||||
order: {
|
||||
"total_amount": "desc"
|
||||
}
|
||||
},
|
||||
aggs: sum_agg
|
||||
}
|
||||
},
|
||||
query: {
|
||||
bool: {
|
||||
must: must_array,
|
||||
filter: filter_array,
|
||||
must_not: [
|
||||
{term: {"@transfer.from": account}}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
response['total_in'] = 0;
|
||||
response['inputs'] = inResults['body']['aggregations']['senders']['buckets'].map((bucket) => {
|
||||
const _sum = parseFloat(bucket.total_amount.value.toFixed(4));
|
||||
response['total_in'] += _sum;
|
||||
return {
|
||||
account: bucket.key,
|
||||
sum: _sum,
|
||||
transfers: bucket['doc_count'],
|
||||
average: parseFloat((bucket.total_amount.value / bucket['doc_count']).toFixed(4))
|
||||
};
|
||||
});
|
||||
response['total_in'] = parseFloat(response['total_in'].toFixed(4));
|
||||
}
|
||||
|
||||
response['query_time'] = Date.now() - t0;
|
||||
redis.set(hash, JSON.stringify(response), 'EX', 600);
|
||||
return response;
|
||||
}
|
||||
|
||||
module.exports = function (fastify, opts, next) {
|
||||
fastify.get('/get_transacted_accounts', {
|
||||
schema: getTransactedAccountsSchema.GET
|
||||
}, async (request, reply) => {
|
||||
reply.send(await getTransactedAccounts(fastify, request));
|
||||
});
|
||||
next()
|
||||
};
|
||||
@@ -1,55 +0,0 @@
|
||||
const {getTransactionSchema} = require("../../schemas");
|
||||
const _ = require('lodash');
|
||||
const {getCacheByHash} = require("../../helpers/functions");
|
||||
|
||||
async function getTransaction(fastify, request) {
|
||||
const {redis, elastic, eosjs} = fastify;
|
||||
const [cachedResponse, hash] = await getCacheByHash(redis, JSON.stringify(request.query));
|
||||
if (cachedResponse) {
|
||||
return cachedResponse;
|
||||
}
|
||||
const pResults = await Promise.all([eosjs.rpc.get_info(), elastic['search']({
|
||||
"index": process.env.CHAIN + '-action-*',
|
||||
"body": {
|
||||
"query": {
|
||||
"bool": {
|
||||
must: [
|
||||
{term: {"trx_id": request.query.id.toLowerCase()}}
|
||||
]
|
||||
}
|
||||
},
|
||||
"sort": {
|
||||
"global_sequence": "asc"
|
||||
}
|
||||
}
|
||||
})]);
|
||||
const results = pResults[1];
|
||||
const response = {
|
||||
"trx_id": request.query.id,
|
||||
"lib": pResults[0].last_irreversible_block_num,
|
||||
"actions": []
|
||||
};
|
||||
const hits = results['body']['hits']['hits'];
|
||||
if (hits.length > 0) {
|
||||
for (let action of hits) {
|
||||
action = action._source;
|
||||
const name = action.act.name;
|
||||
if (action['@' + name]) {
|
||||
action['act']['data'] = _.merge(action['@' + name], action['act']['data']);
|
||||
delete action['@' + name];
|
||||
}
|
||||
response.actions.push(action);
|
||||
}
|
||||
}
|
||||
redis.set(hash, JSON.stringify(response), 'EX', 30);
|
||||
return response;
|
||||
}
|
||||
|
||||
module.exports = function (fastify, opts, next) {
|
||||
fastify.get('/get_transaction', {
|
||||
schema: getTransactionSchema.GET
|
||||
}, async (request, reply) => {
|
||||
reply.send(await getTransaction(fastify, request));
|
||||
});
|
||||
next()
|
||||
};
|
||||
@@ -1,98 +0,0 @@
|
||||
const {getTransfersSchema} = require("../../schemas");
|
||||
const _ = require('lodash');
|
||||
const {getCacheByHash} = require("../../helpers/functions");
|
||||
const route = '/get_transfers';
|
||||
|
||||
const maxActions = 1000;
|
||||
|
||||
function processActions(results) {
|
||||
const action_traces = results['body']['hits']['hits'];
|
||||
const actions = [];
|
||||
let sum = 0;
|
||||
for (const aTrace of action_traces) {
|
||||
const action = aTrace['_source'];
|
||||
const name = action.act.name;
|
||||
if (action['@' + name]) {
|
||||
if (action['@transfer']) {
|
||||
sum += parseFloat(action['@transfer']['amount']);
|
||||
}
|
||||
action['act']['data'] = _.merge(action['@' + name], action['act']['data']);
|
||||
delete action['@' + name];
|
||||
}
|
||||
actions.push(action);
|
||||
}
|
||||
return [sum, actions];
|
||||
}
|
||||
|
||||
async function getTransfers(fastify, request) {
|
||||
const {redis, elastic} = fastify;
|
||||
const [cachedResponse, hash] = await getCacheByHash(redis, route + JSON.stringify(request.query));
|
||||
if (cachedResponse) {
|
||||
return cachedResponse;
|
||||
}
|
||||
const must_array = [];
|
||||
must_array.push({"term": {"act.name": {"value": "transfer"}}});
|
||||
if (request.query['from']) {
|
||||
must_array.push({"term": {"@transfer.from": {"value": request.query['from'].toLowerCase()}}});
|
||||
}
|
||||
if (request.query['to']) {
|
||||
must_array.push({"term": {"@transfer.to": {"value": request.query['to'].toLowerCase()}}});
|
||||
}
|
||||
if (request.query['symbol']) {
|
||||
must_array.push({"term": {"@transfer.symbol": {"value": request.query['symbol'].toUpperCase()}}});
|
||||
}
|
||||
if (request.query['contract']) {
|
||||
must_array.push({"term": {"act.account": {"value": request.query['contract'].toLowerCase()}}});
|
||||
}
|
||||
if (request.query['after'] || request.query['before']) {
|
||||
let _lte = "now";
|
||||
let _gte = 0;
|
||||
if (request.query['before']) {
|
||||
_lte = request.query['before'];
|
||||
}
|
||||
if (request.query['after']) {
|
||||
_gte = request.query['after'];
|
||||
}
|
||||
must_array.push({
|
||||
range: {
|
||||
"@timestamp": {
|
||||
"gte": _gte,
|
||||
"lte": _lte
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
let limit, skip;
|
||||
limit = parseInt(request.query.limit, 10);
|
||||
if (limit < 1) {
|
||||
return 'invalid limit parameter';
|
||||
}
|
||||
skip = parseInt(request.query.skip, 10);
|
||||
if (skip < 0) {
|
||||
return 'invalid skip parameter';
|
||||
}
|
||||
const body = {"query": {"bool": {"must": must_array}}};
|
||||
const results = await elastic.search({
|
||||
"index": process.env.CHAIN + '-action-*',
|
||||
"from": skip || 0,
|
||||
"size": (limit > maxActions ? maxActions : limit) || 10,
|
||||
"body": body
|
||||
});
|
||||
const [sum, _actions] = processActions(results);
|
||||
const response = {
|
||||
"action_count": results['body']['hits']['total']['value'],
|
||||
"total_amount": sum,
|
||||
"actions": _actions
|
||||
};
|
||||
redis.set(hash, JSON.stringify(response), 'EX', 30);
|
||||
return response;
|
||||
}
|
||||
|
||||
module.exports = function (fastify, opts, next) {
|
||||
fastify.get(route, {
|
||||
schema: getTransfersSchema.GET
|
||||
}, async (request, reply) => {
|
||||
reply.send(await getTransfers(fastify, request));
|
||||
});
|
||||
next()
|
||||
};
|
||||
@@ -1,65 +0,0 @@
|
||||
const {getAccountSchema} = require("../../schemas");
|
||||
const {getCacheByHash} = require("../../helpers/functions");
|
||||
const route = '/get_account';
|
||||
const got = require('got');
|
||||
|
||||
const localApi = `http://${process.env.SERVER_ADDR}:${process.env.SERVER_PORT}/v2`;
|
||||
const getTokensApi = localApi + '/state/get_tokens';
|
||||
const getActionsApi = localApi + '/history/get_actions';
|
||||
|
||||
const enable_caching = process.env.ENABLE_CACHING === 'true';
|
||||
let cache_life = 30;
|
||||
if (process.env.CACHE_LIFE) {
|
||||
cache_life = parseInt(process.env.CACHE_LIFE);
|
||||
}
|
||||
|
||||
async function getAccount(fastify, request) {
|
||||
const t0 = Date.now();
|
||||
const {redis, elastic, eosjs} = fastify;
|
||||
|
||||
// let cachedResponse, hash;
|
||||
// if(enable_caching) {
|
||||
// [cachedResponse, hash] = await getCacheByHash(redis, route + JSON.stringify(request.query));
|
||||
// if (cachedResponse) {
|
||||
// cachedResponse = JSON.parse(cachedResponse);
|
||||
// cachedResponse['query_time'] = Date.now() - t0;
|
||||
// cachedResponse['cached'] = true;
|
||||
// return cachedResponse;
|
||||
// }
|
||||
// }
|
||||
|
||||
const response = {
|
||||
query_time: null,
|
||||
cached: false,
|
||||
account: null,
|
||||
actions: null,
|
||||
tokens: null,
|
||||
links: null
|
||||
};
|
||||
|
||||
const account = request.query.account;
|
||||
const reqQueue = [];
|
||||
reqQueue.push(eosjs.rpc.get_account(account));
|
||||
|
||||
// fetch recent actions
|
||||
reqQueue.push(got.get(`${getActionsApi}?account=${account}&limit=10`));
|
||||
|
||||
// fetch account tokens
|
||||
reqQueue.push(got.get(`${getTokensApi}?account=${account}`));
|
||||
|
||||
const results = await Promise.all(reqQueue);
|
||||
response.account = results[0];
|
||||
response.actions = JSON.parse(results[1].body).actions;
|
||||
response.tokens = JSON.parse(results[2].body).tokens;
|
||||
response['query_time'] = Date.now() - t0;
|
||||
return response;
|
||||
}
|
||||
|
||||
module.exports = function (fastify, opts, next) {
|
||||
fastify.get(route, {
|
||||
schema: getAccountSchema.GET
|
||||
}, async (request) => {
|
||||
return await getAccount(fastify, request);
|
||||
});
|
||||
next()
|
||||
};
|
||||
@@ -1,97 +0,0 @@
|
||||
const {getKeyAccountsSchema} = require("../../schemas");
|
||||
const {getCacheByHash} = require("../../helpers/functions");
|
||||
const numeric = require('eosjs/dist/eosjs-numeric');
|
||||
|
||||
function invalidKey() {
|
||||
const err = new Error();
|
||||
err.statusCode = 400;
|
||||
err.message = 'invalid public key';
|
||||
throw err;
|
||||
}
|
||||
|
||||
async function getKeyAccounts(fastify, public_Key) {
|
||||
|
||||
const {redis, elastic} = fastify;
|
||||
let publicKey;
|
||||
|
||||
if (public_Key.startsWith("PUB_")) {
|
||||
publicKey = public_Key;
|
||||
} else if (public_Key.startsWith("EOS")) {
|
||||
try {
|
||||
publicKey = numeric.convertLegacyPublicKey(public_Key);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
invalidKey();
|
||||
}
|
||||
} else {
|
||||
invalidKey();
|
||||
}
|
||||
|
||||
const [cachedResponse, hash] = await getCacheByHash(redis, JSON.stringify(publicKey));
|
||||
if (cachedResponse) {
|
||||
return cachedResponse;
|
||||
}
|
||||
const _body = {
|
||||
query: {
|
||||
bool: {
|
||||
should: [
|
||||
{term: {"@updateauth.auth.keys.key.keyword": publicKey}},
|
||||
{term: {"@newaccount.active.keys.key.keyword": publicKey}},
|
||||
{term: {"@newaccount.owner.keys.key.keyword": publicKey}}
|
||||
],
|
||||
minimum_should_match: 1
|
||||
}
|
||||
},
|
||||
sort: [{"global_sequence": {"order": "desc"}}]
|
||||
};
|
||||
|
||||
const results = await elastic.search({
|
||||
index: process.env.CHAIN + '-action-*',
|
||||
body: _body
|
||||
});
|
||||
|
||||
const response = {
|
||||
account_names: []
|
||||
};
|
||||
if (results['body']['hits']['hits'].length > 0) {
|
||||
response.account_names = results['body']['hits']['hits'].map((v) => {
|
||||
if (v._source.act.name === 'newaccount') {
|
||||
if (v._source['@newaccount'].newact) {
|
||||
return v._source['@newaccount'].newact;
|
||||
} else if (v._source.act.data.newact) {
|
||||
return v._source.act.data.newact;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else if (v._source.act.name === 'updateauth') {
|
||||
return v._source.act.data.account;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (response.account_names.length > 0) {
|
||||
response.account_names = [...(new Set(response.account_names))];
|
||||
redis.set(hash, JSON.stringify(response), 'EX', 30);
|
||||
return response;
|
||||
} else {
|
||||
const err = new Error();
|
||||
err.statusCode = 404;
|
||||
err.message = 'no accounts associated with ' + public_Key;
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = function (fastify, opts, next) {
|
||||
fastify.get('/get_key_accounts', {
|
||||
schema: getKeyAccountsSchema.GET
|
||||
}, async (request) => {
|
||||
return getKeyAccounts(fastify, request.query.public_key);
|
||||
});
|
||||
fastify.post('/get_key_accounts', {
|
||||
schema: getKeyAccountsSchema.POST
|
||||
}, async (request) => {
|
||||
return getKeyAccounts(fastify, request.body.public_key);
|
||||
});
|
||||
next();
|
||||
};
|
||||
@@ -1,146 +0,0 @@
|
||||
const {getProposalsSchema} = require("../../schemas");
|
||||
const {getCacheByHash} = require("../../helpers/functions");
|
||||
const route = '/get_proposals';
|
||||
|
||||
const maxActions = 1000;
|
||||
|
||||
const enable_caching = process.env.ENABLE_CACHING === 'true';
|
||||
let cache_life = 30;
|
||||
if (process.env.CACHE_LIFE) {
|
||||
cache_life = parseInt(process.env.CACHE_LIFE);
|
||||
}
|
||||
|
||||
function getTrackOpt(request) {
|
||||
let trackTotalHits = 10000;
|
||||
if (request.query.track) {
|
||||
if (request.query.track === 'true') {
|
||||
trackTotalHits = true;
|
||||
} else if (request.query.track === 'false') {
|
||||
trackTotalHits = false;
|
||||
} else {
|
||||
trackTotalHits = parseInt(request.query.track, 10);
|
||||
if (trackTotalHits !== trackTotalHits) {
|
||||
throw new Error('failed to parse track param');
|
||||
}
|
||||
}
|
||||
}
|
||||
return trackTotalHits;
|
||||
}
|
||||
|
||||
async function getProposals(fastify, request) {
|
||||
|
||||
const t0 = Date.now();
|
||||
const {redis, elastic, eosjs} = fastify;
|
||||
let cachedResponse, hash;
|
||||
if (enable_caching) {
|
||||
[cachedResponse, hash] = await getCacheByHash(redis, route + JSON.stringify(request.query));
|
||||
if (cachedResponse) {
|
||||
cachedResponse = JSON.parse(cachedResponse);
|
||||
cachedResponse['query_time'] = Date.now() - t0;
|
||||
cachedResponse['cached'] = true;
|
||||
return cachedResponse;
|
||||
}
|
||||
}
|
||||
|
||||
// Pagination
|
||||
let skip, limit;
|
||||
skip = parseInt(request.query.skip, 10);
|
||||
if (skip < 0) {
|
||||
return 'invalid skip parameter';
|
||||
}
|
||||
limit = parseInt(request.query.limit, 10);
|
||||
if (limit < 1) {
|
||||
return 'invalid limit parameter';
|
||||
}
|
||||
|
||||
let queryStruct = {
|
||||
"bool": {
|
||||
"must": []
|
||||
}
|
||||
};
|
||||
|
||||
// Filter by account
|
||||
if (request.query.account) {
|
||||
queryStruct.bool.must.push({
|
||||
"bool": {
|
||||
"should": [
|
||||
{"term": {"requested_approvals.actor": request.query.account}},
|
||||
{"term": {"provided_approvals.actor": request.query.account}}
|
||||
]
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Filter by proposer account
|
||||
if (request.query.proposer) {
|
||||
queryStruct.bool.must.push({"term": {"proposer": request.query.proposer}});
|
||||
}
|
||||
|
||||
// Filter by proposal name
|
||||
if (request.query.proposal) {
|
||||
queryStruct.bool.must.push({"term": {"proposal_name": request.query.proposal}});
|
||||
}
|
||||
|
||||
// Filter by execution status
|
||||
if (typeof request.query.executed !== 'undefined') {
|
||||
queryStruct.bool.must.push({"term": {"executed": request.query.executed}});
|
||||
}
|
||||
|
||||
// Filter by requested actors
|
||||
if (request.query.requested) {
|
||||
queryStruct.bool.must.push({"term": {"requested_approvals.actor": request.query.requested}});
|
||||
}
|
||||
|
||||
// Filter by provided actors
|
||||
if (request.query.provided) {
|
||||
queryStruct.bool.must.push({"term": {"provided_approvals.actor": request.query.provided}});
|
||||
}
|
||||
|
||||
// If no filter switch to full match
|
||||
if (queryStruct.bool.must.length === 0) {
|
||||
queryStruct = {
|
||||
"match_all": {}
|
||||
};
|
||||
}
|
||||
|
||||
console.log(JSON.stringify(queryStruct));
|
||||
|
||||
const results = await elastic.search({
|
||||
"index": process.env.CHAIN + '-table-proposals-*',
|
||||
"from": skip || 0,
|
||||
"size": (limit > maxActions ? maxActions : limit) || 10,
|
||||
"body": {
|
||||
"track_total_hits": getTrackOpt(request),
|
||||
"query": queryStruct,
|
||||
"sort": [{"block_num": "desc"}]
|
||||
}
|
||||
});
|
||||
|
||||
const response = {
|
||||
query_time: null,
|
||||
cached: false,
|
||||
total: results['body']['hits']['total'],
|
||||
proposals: []
|
||||
};
|
||||
|
||||
const hits = results['body']['hits']['hits'];
|
||||
for (const hit of hits) {
|
||||
const prop = hit._source;
|
||||
response.proposals.push(prop);
|
||||
}
|
||||
|
||||
response['query_time'] = Date.now() - t0;
|
||||
if (enable_caching) {
|
||||
redis.set(hash, JSON.stringify(response), 'EX', cache_life);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
module.exports = function (fastify, opts, next) {
|
||||
fastify.get(route, {
|
||||
schema: getProposalsSchema.GET
|
||||
}, async (request) => {
|
||||
return await getProposals(fastify, request);
|
||||
});
|
||||
next();
|
||||
};
|
||||
@@ -1,94 +0,0 @@
|
||||
const {getTokensSchema} = require("../../schemas");
|
||||
const {getCacheByHash} = require("../../helpers/functions");
|
||||
const route = '/get_tokens';
|
||||
|
||||
const enable_caching = process.env.ENABLE_CACHING === 'true';
|
||||
let cache_life = 30;
|
||||
if(process.env.CACHE_LIFE) {
|
||||
cache_life = parseInt(process.env.CACHE_LIFE);
|
||||
}
|
||||
|
||||
async function getTokens(fastify, request) {
|
||||
const t0 = Date.now();
|
||||
const {redis, elastic, eosjs} = fastify;
|
||||
|
||||
let cachedResponse, hash;
|
||||
if(enable_caching) {
|
||||
[cachedResponse, hash] = await getCacheByHash(redis, route + JSON.stringify(request.query));
|
||||
if (cachedResponse) {
|
||||
cachedResponse = JSON.parse(cachedResponse);
|
||||
cachedResponse['query_time'] = Date.now() - t0;
|
||||
cachedResponse['cached'] = true;
|
||||
return cachedResponse;
|
||||
}
|
||||
}
|
||||
|
||||
const response = {
|
||||
query_time: null,
|
||||
cached: false,
|
||||
'account': request.query.account,
|
||||
'tokens': []
|
||||
};
|
||||
|
||||
const results = await elastic.search({
|
||||
"index": process.env.CHAIN + '-action-*',
|
||||
"body": {
|
||||
size: 0,
|
||||
query: {
|
||||
bool: {
|
||||
// must_not: {term: {"act.account": "eosio.token"}},
|
||||
filter: [
|
||||
{term: {"notified": request.query.account}},
|
||||
{terms: {"act.name": ["transfer", "issue"]}}
|
||||
]
|
||||
}
|
||||
},
|
||||
aggs: {
|
||||
tokens: {
|
||||
terms: {
|
||||
field: "act.account",
|
||||
size: 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
for (const bucket of results['body']['aggregations']['tokens']['buckets']) {
|
||||
let token_data;
|
||||
try {
|
||||
token_data = await eosjs.rpc.get_currency_balance(bucket['key'], request.query.account);
|
||||
} catch (e) {
|
||||
console.log(`get_currency_balance error - contract:${bucket['key']} - account:${request.query.account}`);
|
||||
continue;
|
||||
}
|
||||
for (const entry of token_data) {
|
||||
let precision = 0;
|
||||
const [amount, symbol] = entry.split(" ");
|
||||
const amount_arr = amount.split(".");
|
||||
if (amount_arr.length === 2) {
|
||||
precision = amount_arr[1].length;
|
||||
}
|
||||
response.tokens.push({
|
||||
symbol: symbol,
|
||||
precision: precision,
|
||||
amount: parseFloat(amount),
|
||||
contract: bucket['key']
|
||||
});
|
||||
}
|
||||
}
|
||||
response['query_time'] = Date.now() - t0;
|
||||
if(enable_caching) {
|
||||
redis.set(hash, JSON.stringify(response), 'EX', cache_life);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
module.exports = function (fastify, opts, next) {
|
||||
fastify.get(route, {
|
||||
schema: getTokensSchema.GET
|
||||
}, async (request) => {
|
||||
return await getTokens(fastify, request);
|
||||
});
|
||||
next()
|
||||
};
|
||||
@@ -1,90 +0,0 @@
|
||||
const {getVotersSchema} = require("../../schemas");
|
||||
const {getCacheByHash} = require("../../helpers/functions");
|
||||
const route = '/get_voters';
|
||||
|
||||
const maxActions = 1000;
|
||||
|
||||
async function getVoters(fastify, request) {
|
||||
|
||||
const t0 = Date.now();
|
||||
const {redis, elastic} = fastify;
|
||||
const [cachedResponse, hash] = await getCacheByHash(redis, route + JSON.stringify(request.query));
|
||||
if (cachedResponse) {
|
||||
return cachedResponse;
|
||||
}
|
||||
|
||||
let skip, limit;
|
||||
|
||||
skip = parseInt(request.query.skip, 10);
|
||||
if (skip < 0) {
|
||||
return 'invalid skip parameter';
|
||||
}
|
||||
limit = parseInt(request.query.limit, 10);
|
||||
if (limit < 1) {
|
||||
return 'invalid limit parameter';
|
||||
}
|
||||
|
||||
const response = {
|
||||
query_time: null,
|
||||
voter_count: 0,
|
||||
'voters': []
|
||||
};
|
||||
let queryStruct = {
|
||||
"bool": {
|
||||
"must": []
|
||||
}
|
||||
};
|
||||
|
||||
if (request.query.producer) {
|
||||
for (const bp of request.query.producer.split(",")) {
|
||||
queryStruct.bool.must.push({"term": {"producers": bp}});
|
||||
}
|
||||
}
|
||||
|
||||
if (request.query.proxy === 'true') {
|
||||
queryStruct.bool.must.push({"term": {"is_proxy": true}});
|
||||
}
|
||||
|
||||
if (queryStruct.bool.must.length === 0) {
|
||||
queryStruct = {
|
||||
"match_all": {}
|
||||
};
|
||||
}
|
||||
|
||||
let prefix = process.env.CHAIN;
|
||||
if (process.env.CHAIN === 'mainnet') {
|
||||
prefix = 'eos';
|
||||
}
|
||||
|
||||
const results = await elastic.search({
|
||||
"index": prefix + '-table-voters-*',
|
||||
"from": skip || 0,
|
||||
"size": (limit > maxActions ? maxActions : limit) || 10,
|
||||
"body": {
|
||||
"query": queryStruct,
|
||||
"sort": [{"last_vote_weight": "desc"}]
|
||||
}
|
||||
});
|
||||
const hits = results['body']['hits']['hits'];
|
||||
for (const hit of hits) {
|
||||
const voter = hit._source;
|
||||
response.voters.push({
|
||||
account: voter.voter,
|
||||
weight: voter.last_vote_weight,
|
||||
last_vote: voter.block_num
|
||||
});
|
||||
}
|
||||
response.voter_count = results['body']['hits']['total']['value'];
|
||||
response['query_time'] = Date.now() - t0;
|
||||
redis.set(hash, JSON.stringify(response), 'EX', 30);
|
||||
return response;
|
||||
}
|
||||
|
||||
module.exports = function (fastify, opts, next) {
|
||||
fastify.get(route, {
|
||||
schema: getVotersSchema.GET
|
||||
}, async (request) => {
|
||||
return await getVoters(fastify, request);
|
||||
});
|
||||
next();
|
||||
};
|
||||
@@ -1,134 +0,0 @@
|
||||
const schema = {
|
||||
description: 'Returns an object containing various details about a specific block on the blockchain.',
|
||||
summary: 'Returns an object containing various details about a specific block on the blockchain.',
|
||||
tags: ['state'],
|
||||
body: {
|
||||
type: ['object', 'string'],
|
||||
properties: {
|
||||
"block_num_or_id": {
|
||||
description: 'Provide a block number or a block id',
|
||||
type: 'string'
|
||||
},
|
||||
},
|
||||
required: ["block_num_or_id"]
|
||||
}
|
||||
};
|
||||
|
||||
const route = '/get_block';
|
||||
const {blockStore} = require('../blockStore');
|
||||
const {getCacheByHash} = require("../../helpers/functions");
|
||||
|
||||
let last_get_info = 0;
|
||||
let chain_info;
|
||||
|
||||
async function getInfo(eosjs) {
|
||||
if (Date.now() - last_get_info > 1000) {
|
||||
chain_info = await eosjs.rpc.get_info();
|
||||
last_get_info = Date.now();
|
||||
}
|
||||
}
|
||||
|
||||
async function processBlockData(block, eosjs) {
|
||||
// Calculate total usage
|
||||
let total_cpu = 0;
|
||||
let total_net = 0;
|
||||
block.transactions.forEach((trx) => {
|
||||
total_cpu += trx['cpu_usage_us'];
|
||||
total_net += trx['net_usage_words'];
|
||||
});
|
||||
block['total_cpu_usage_us'] = total_cpu;
|
||||
block['total_net_usage_words'] = total_net;
|
||||
|
||||
// check irreversibility
|
||||
await getInfo(eosjs);
|
||||
block['last_irreversible_block_num'] = chain_info.last_irreversible_block_num;
|
||||
block['irreversible'] = block['block_num'] <= block['last_irreversible_block_num'];
|
||||
return block;
|
||||
}
|
||||
|
||||
async function getBlock(fastify, request, reply) {
|
||||
const {eosjs, redis} = fastify;
|
||||
let block_num_or_id;
|
||||
try {
|
||||
if (typeof request.body === 'object') {
|
||||
block_num_or_id = request.body['block_num_or_id'];
|
||||
} else {
|
||||
block_num_or_id = JSON.parse(request.body)['block_num_or_id'];
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(request.body);
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
if (parseInt(block_num_or_id) === 0) {
|
||||
await getInfo(eosjs);
|
||||
block_num_or_id = chain_info.head_block_num;
|
||||
}
|
||||
|
||||
if (block_num_or_id) {
|
||||
let cachedResponse, hash;
|
||||
const key = route + '_' + block_num_or_id;
|
||||
[cachedResponse, hash] = await getCacheByHash(redis, key);
|
||||
if (cachedResponse) {
|
||||
cachedResponse = JSON.parse(cachedResponse);
|
||||
if (cachedResponse['irreversible']) {
|
||||
reply.send(cachedResponse);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
let blockdata = await eosjs.rpc.get_block(block_num_or_id);
|
||||
blockdata = await processBlockData(blockdata, eosjs);
|
||||
const blockstring = JSON.stringify(blockdata);
|
||||
if (blockdata['irreversible']) {
|
||||
redis.set(hash, blockstring, 'EX', 86400);
|
||||
} else {
|
||||
redis.set(hash, blockstring, 'EX', 10);
|
||||
}
|
||||
reply.send(blockdata);
|
||||
} catch (e) {
|
||||
reply.code(400).send({
|
||||
"code": 400,
|
||||
"message": "Unknown Block",
|
||||
"error": {
|
||||
"code": 3100002,
|
||||
"name": "unknown_block_exception",
|
||||
"what": "Unknown block",
|
||||
"details": [
|
||||
{
|
||||
"message": "Could not find block: " + block_num_or_id,
|
||||
"file": "chain_plugin.cpp",
|
||||
"line_number": 1852,
|
||||
"method": "get_block"
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
} else {
|
||||
reply.code(400).send({});
|
||||
}
|
||||
|
||||
// TODO: fallback to state history
|
||||
// let from_block;
|
||||
// if (request.body['block_num_or_id']) {
|
||||
// from_block = parseInt(request.body['block_num_or_id']);
|
||||
// let response;
|
||||
// console.log('Local Block store size:', blockStore.localBlocks.size);
|
||||
// blockStore.requestRange(from_block, from_block + 1, (block) => {
|
||||
// response = block;
|
||||
// }, () => {
|
||||
// reply.send(response);
|
||||
// });
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
module.exports = function (fastify, opts, next) {
|
||||
fastify.post(route, {schema}, async (request, reply) => {
|
||||
await getBlock(fastify, request, reply);
|
||||
});
|
||||
next();
|
||||
};
|
||||
@@ -1,72 +0,0 @@
|
||||
import {FastifyInstance, FastifyReply, FastifyRequest} from "fastify";
|
||||
import {ServerResponse} from "http";
|
||||
import {timedQuery} from "../../../helpers/functions";
|
||||
import {ApiResponse} from "@elastic/elasticsearch";
|
||||
|
||||
async function getControlledAccounts(fastify: FastifyInstance, request: FastifyRequest) {
|
||||
if (typeof request.body === 'string') {
|
||||
request.body = JSON.parse(request.body)
|
||||
}
|
||||
let controlling_account = request.body.controlling_account;
|
||||
const results: ApiResponse = await fastify.elastic.search({
|
||||
index: fastify.manager.chain + '-action-*',
|
||||
size: 100,
|
||||
body: {
|
||||
query: {
|
||||
bool: {
|
||||
should: [
|
||||
{
|
||||
term: {"@updateauth.auth.accounts.permission.actor": controlling_account}},
|
||||
{
|
||||
bool: {
|
||||
must: [
|
||||
{term: {"act.account": "eosio"}},
|
||||
{term: {"act.name": "newaccount"}},
|
||||
{term: {"act.authorization.actor": controlling_account}}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
minimum_should_match: 1
|
||||
}
|
||||
},
|
||||
sort: [
|
||||
{"global_sequence": {"order": "desc"}}
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
const response = {
|
||||
controlled_accounts: []
|
||||
};
|
||||
|
||||
const hits = results.body.hits.hits;
|
||||
|
||||
if (hits.length > 0) {
|
||||
response.controlled_accounts = hits.map((v) => {
|
||||
if (v._source.act.name === 'newaccount') {
|
||||
if (v._source['@newaccount'].newact) {
|
||||
return v._source['@newaccount'].newact;
|
||||
} else if (v._source.act.data.newact) {
|
||||
return v._source.act.data.newact;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else if (v._source.act.name === 'updateauth') {
|
||||
return v._source.act.data.account;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (response.controlled_accounts.length > 0) {
|
||||
response.controlled_accounts = [...(new Set(response.controlled_accounts))];
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
export function getControlledAccountsHandler(fastify: FastifyInstance, route: string) {
|
||||
return async (request: FastifyRequest, reply: FastifyReply<ServerResponse>) => {
|
||||
reply.send(await timedQuery(getControlledAccounts, fastify, request, route));
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
import {FastifyInstance} from "fastify";
|
||||
import {getKeyAccountsHandler} from "../../v2-state/get_key_accounts/get_key_accounts";
|
||||
import {addApiRoute, getRouteName} from "../../../helpers/functions";
|
||||
|
||||
export default function (fastify: FastifyInstance, opts: any, next) {
|
||||
|
||||
// POST
|
||||
addApiRoute(fastify, 'POST', getRouteName(__filename), getKeyAccountsHandler, {
|
||||
description: 'get accounts by public key',
|
||||
summary: 'get accounts by public key',
|
||||
tags: ['accounts', 'state'],
|
||||
body: {
|
||||
type: 'object',
|
||||
properties: {"public_key": {description: 'public key', type: 'string'}},
|
||||
required: ["public_key"]
|
||||
},
|
||||
response: {
|
||||
200: {
|
||||
type: 'object',
|
||||
properties: {"account_names": {type: "array", items: {type: "string"}}}
|
||||
}
|
||||
}
|
||||
});
|
||||
next();
|
||||
}
|
||||
@@ -1,192 +0,0 @@
|
||||
import {FastifyInstance, FastifyReply, FastifyRequest} from "fastify";
|
||||
import {ServerResponse} from "http";
|
||||
import {mergeActionMeta, timedQuery} from "../../../helpers/functions";
|
||||
import {createHash} from "crypto";
|
||||
|
||||
async function getTransaction(fastify: FastifyInstance, request: FastifyRequest) {
|
||||
if (typeof request.body === 'string') {
|
||||
request.body = JSON.parse(request.body)
|
||||
}
|
||||
const pResults = await Promise.all([fastify.eosjs.rpc.get_info(), fastify.elastic['search']({
|
||||
"index": fastify.manager.chain + '-action-*',
|
||||
"body": {
|
||||
"query": {
|
||||
"bool": {
|
||||
must: [
|
||||
{term: {"trx_id": request.body.id.toLowerCase()}}
|
||||
]
|
||||
}
|
||||
},
|
||||
"sort": {
|
||||
"global_sequence": "asc"
|
||||
}
|
||||
}
|
||||
})]);
|
||||
const results = pResults[1];
|
||||
const response: any = {
|
||||
"id": request.body.id,
|
||||
"trx": {
|
||||
"receipt": {
|
||||
"status": "executed",
|
||||
"cpu_usage_us": 0,
|
||||
"net_usage_words": 0,
|
||||
"trx": [1, {
|
||||
"signatures": "",
|
||||
"compression": "none",
|
||||
"packed_context_free_data": "",
|
||||
"packed_trx": ""
|
||||
}]
|
||||
},
|
||||
"trx": {}
|
||||
},
|
||||
"block_num": 0,
|
||||
"block_time": "",
|
||||
"last_irreversible_block": pResults[0].last_irreversible_block_num,
|
||||
"traces": []
|
||||
};
|
||||
|
||||
const hits = results['body']['hits']['hits'];
|
||||
|
||||
if (hits.length > 0) {
|
||||
const actions = hits;
|
||||
response.trx.trx = {
|
||||
"expiration": "",
|
||||
"ref_block_num": 0,
|
||||
"ref_block_prefix": 0,
|
||||
"max_net_usage_words": 0,
|
||||
"max_cpu_usage_ms": 0,
|
||||
"delay_sec": 0,
|
||||
"context_free_actions": [],
|
||||
"actions": [],
|
||||
"transaction_extensions": [],
|
||||
"signatures": [],
|
||||
"context_free_data": []
|
||||
};
|
||||
let traces = {};
|
||||
let seqNum = 0;
|
||||
for (let action of actions) {
|
||||
action = action._source;
|
||||
mergeActionMeta(action);
|
||||
action.act['hex_data'] = Buffer.from(JSON.stringify(action.act.data)).toString('hex');
|
||||
if (action.parent === 0) {
|
||||
response.trx.trx.actions.push(action.act);
|
||||
}
|
||||
response.block_num = action.block_num;
|
||||
response.block_time = action['@timestamp'];
|
||||
seqNum += 1;
|
||||
let trace = {
|
||||
receipt: {
|
||||
receiver: action.act.account,
|
||||
global_sequence: String(action.global_sequence),
|
||||
auth_sequence: [
|
||||
action.act.authorization[0].actor,
|
||||
seqNum
|
||||
],
|
||||
act_digest: '',
|
||||
recv_sequence: seqNum,
|
||||
code_sequence: 1,
|
||||
abi_sequence: 1
|
||||
},
|
||||
act: action.act,
|
||||
account_ram_deltas: action.account_ram_deltas || [],
|
||||
context_free: false,
|
||||
block_num: action.block_num,
|
||||
block_time: action['@timestamp'],
|
||||
console: "",
|
||||
elapsed: 0,
|
||||
except: null,
|
||||
inline_traces: [],
|
||||
producer_block_id: "",
|
||||
trx_id: request.body.id,
|
||||
notified: action.notified
|
||||
};
|
||||
let hash = createHash('sha256');
|
||||
hash.update(JSON.stringify(action.act));
|
||||
trace.receipt.act_digest = hash.digest('hex');
|
||||
traces[action.global_sequence] = trace;
|
||||
}
|
||||
|
||||
actions.forEach(action => {
|
||||
action = action._source;
|
||||
for (let i = 0; i < traces[action.global_sequence].notified.length; i++) {
|
||||
if (traces[action.global_sequence].notified[i] === action.act.account) {
|
||||
traces[action.global_sequence].notified.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (action.parent !== 0 && action.parent) {
|
||||
if (traces[action.parent]) {
|
||||
for (let i = 0; i < traces[action.parent].notified.length; i++) {
|
||||
if (traces[action.parent].notified[i] === action.act.account) {
|
||||
traces[action.parent].notified.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
traces[action.parent].inline_traces.push(traces[action.global_sequence]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
actions.forEach(action => {
|
||||
action = action._source;
|
||||
response.traces.push(traces[action.global_sequence]);
|
||||
traces[action.global_sequence].notified.forEach((note, index) => {
|
||||
seqNum += 1;
|
||||
let trace = {
|
||||
receipt: {
|
||||
receiver: note,
|
||||
global_sequence: String(action.global_sequence + index + 1),
|
||||
auth_sequence: [
|
||||
action.act.authorization[0].actor,
|
||||
seqNum
|
||||
],
|
||||
act_digest: traces[action.global_sequence].receipt.act_digest,
|
||||
recv_sequence: seqNum,
|
||||
code_sequence: 1,
|
||||
abi_sequence: 1
|
||||
},
|
||||
account_ram_deltas: action.account_ram_deltas || [],
|
||||
act: action.act,
|
||||
block_num: action.block_num,
|
||||
block_time: action['@timestamp'],
|
||||
console: "",
|
||||
context_free: false,
|
||||
elapsed: 0,
|
||||
except: null,
|
||||
inline_traces: [],
|
||||
producer_block_id: "",
|
||||
trx_id: request.body.id,
|
||||
};
|
||||
traces[action.global_sequence].inline_traces.unshift(trace);
|
||||
response.traces.push(trace);
|
||||
});
|
||||
delete traces[action.global_sequence].notified;
|
||||
});
|
||||
} else {
|
||||
const errmsg = "Transaction " + request.body.id.toLowerCase() + " not found in history and no block hint was given";
|
||||
return {
|
||||
code: 500,
|
||||
message: "Internal Service Error",
|
||||
error: {
|
||||
code: 3040011,
|
||||
name: "tx_not_found",
|
||||
what: "The transaction can not be found",
|
||||
details: [
|
||||
{
|
||||
message: errmsg,
|
||||
file: "",
|
||||
line_number: 1,
|
||||
method: "get_transaction"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
export function getTransactionHandler(fastify: FastifyInstance, route: string) {
|
||||
return async (request: FastifyRequest, reply: FastifyReply<ServerResponse>) => {
|
||||
reply.send(await timedQuery(getTransaction, fastify, request, route));
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
import {FastifyInstance} from "fastify";
|
||||
import {addApiRoute, getRouteName} from "../../../helpers/functions";
|
||||
import {getTransactionHandler} from "./get_transaction";
|
||||
|
||||
export default function (fastify: FastifyInstance, opts: any, next) {
|
||||
addApiRoute(fastify, 'POST', getRouteName(__filename), getTransactionHandler, {
|
||||
description: 'get all actions belonging to the same transaction',
|
||||
summary: 'get transaction by id',
|
||||
tags: ['transactions', 'history'],
|
||||
body: {
|
||||
type: ['object', 'string'],
|
||||
properties: {id: {description: 'transaction id', type: 'string'}},
|
||||
required: ["id"]
|
||||
}
|
||||
});
|
||||
next();
|
||||
}
|
||||
@@ -1,213 +0,0 @@
|
||||
import {extendedActions, primaryTerms, terms} from "./definitions";
|
||||
|
||||
export function addSortedBy(query, queryBody, sort_direction) {
|
||||
if (query['sortedBy']) {
|
||||
const opts = query['sortedBy'].split(":");
|
||||
const sortedByObj = {};
|
||||
sortedByObj[opts[0]] = opts[1];
|
||||
queryBody['sort'] = sortedByObj;
|
||||
} else {
|
||||
queryBody['sort'] = {
|
||||
"global_sequence": sort_direction
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export function processMultiVars(queryStruct, parts, field) {
|
||||
const must = [];
|
||||
const mustNot = [];
|
||||
|
||||
parts.forEach(part => {
|
||||
if (part.startsWith("!")) {
|
||||
mustNot.push(part.replace("!", ""));
|
||||
} else {
|
||||
must.push(part);
|
||||
}
|
||||
});
|
||||
|
||||
if (must.length > 1) {
|
||||
queryStruct.bool.must.push({
|
||||
bool: {
|
||||
should: must.map(elem => {
|
||||
const _q = {};
|
||||
_q[field] = elem;
|
||||
return {term: _q}
|
||||
})
|
||||
}
|
||||
});
|
||||
} else if (must.length === 1) {
|
||||
const mustQuery = {};
|
||||
mustQuery[field] = must[0];
|
||||
queryStruct.bool.must.push({term: mustQuery});
|
||||
}
|
||||
|
||||
if (mustNot.length > 1) {
|
||||
queryStruct.bool.must_not.push({
|
||||
bool: {
|
||||
should: mustNot.map(elem => {
|
||||
const _q = {};
|
||||
_q[field] = elem;
|
||||
return {term: _q}
|
||||
})
|
||||
}
|
||||
});
|
||||
} else if (mustNot.length === 1) {
|
||||
const mustNotQuery = {};
|
||||
mustNotQuery[field] = mustNot[0].replace("!", "");
|
||||
queryStruct.bool.must_not.push({term: mustNotQuery});
|
||||
}
|
||||
}
|
||||
|
||||
function addRangeQuery(queryStruct, prop, pkey, query) {
|
||||
const _termQuery = {};
|
||||
const parts = query[prop].split("-");
|
||||
_termQuery[pkey] = {
|
||||
"gte": parts[0],
|
||||
"lte": parts[1]
|
||||
};
|
||||
queryStruct.bool.must.push({range: _termQuery});
|
||||
}
|
||||
|
||||
export function applyTimeFilter(query, queryStruct) {
|
||||
if (query['after'] || query['before']) {
|
||||
let _lte = "now";
|
||||
let _gte = "0";
|
||||
if (query['before']) {
|
||||
_lte = query['before'];
|
||||
if (!_lte.endsWith("Z")) {
|
||||
_lte += "Z";
|
||||
}
|
||||
}
|
||||
if (query['after']) {
|
||||
_gte = query['after'];
|
||||
if (!_gte.endsWith("Z")) {
|
||||
_gte += "Z";
|
||||
}
|
||||
}
|
||||
if (!queryStruct.bool['filter']) {
|
||||
queryStruct.bool['filter'] = [];
|
||||
}
|
||||
queryStruct.bool['filter'].push({
|
||||
range: {
|
||||
"@timestamp": {
|
||||
"gte": _gte,
|
||||
"lte": _lte
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function applyGenericFilters(query, queryStruct) {
|
||||
for (const prop in query) {
|
||||
if (Object.prototype.hasOwnProperty.call(query, prop)) {
|
||||
const pair = prop.split(".");
|
||||
if (pair.length > 1 || primaryTerms.includes(pair[0])) {
|
||||
let pkey;
|
||||
if (pair.length > 1) {
|
||||
pkey = extendedActions.has(pair[0]) ? "@" + prop : prop;
|
||||
} else {
|
||||
pkey = prop;
|
||||
}
|
||||
if (query[prop].indexOf("-") !== -1) {
|
||||
addRangeQuery(queryStruct, prop, pkey, query);
|
||||
} else {
|
||||
const _termQuery = {};
|
||||
const parts = query[prop].split(",");
|
||||
if (parts.length > 1) {
|
||||
processMultiVars(queryStruct, parts, prop);
|
||||
} else if (parts.length === 1) {
|
||||
const andParts = parts[0].split(" ");
|
||||
if (andParts.length > 1) {
|
||||
andParts.forEach(value => {
|
||||
const _q = {};
|
||||
console.log(value);
|
||||
_q[pkey] = value;
|
||||
queryStruct.bool.must.push({term: _q});
|
||||
});
|
||||
} else {
|
||||
if (parts[0].startsWith("!")) {
|
||||
_termQuery[pkey] = parts[0].replace("!", "");
|
||||
queryStruct.bool.must_not.push({term: _termQuery});
|
||||
} else {
|
||||
_termQuery[pkey] = parts[0];
|
||||
queryStruct.bool.must.push({term: _termQuery});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function makeShouldArray(query) {
|
||||
const should_array = [];
|
||||
for (const entry of terms) {
|
||||
const tObj = {term: {}};
|
||||
tObj.term[entry] = query.account;
|
||||
should_array.push(tObj);
|
||||
}
|
||||
return should_array;
|
||||
}
|
||||
|
||||
export function applyCodeActionFilters(query, queryStruct) {
|
||||
let filterObj = [];
|
||||
if (query.filter) {
|
||||
for (const filter of query.filter.split(',')) {
|
||||
if (filter !== '*:*') {
|
||||
const _arr = [];
|
||||
const parts = filter.split(':');
|
||||
if (parts.length === 2) {
|
||||
const [code, method] = parts;
|
||||
if (code && code !== "*") {
|
||||
_arr.push({'term': {'act.account': code}});
|
||||
}
|
||||
if (method && method !== "*") {
|
||||
_arr.push({'term': {'act.name': method}});
|
||||
}
|
||||
}
|
||||
if (_arr.length > 0) {
|
||||
filterObj.push({bool: {must: _arr}});
|
||||
}
|
||||
}
|
||||
}
|
||||
if (filterObj.length > 0) {
|
||||
queryStruct.bool['should'] = filterObj;
|
||||
queryStruct.bool['minimum_should_match'] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function getSkipLimit(query) {
|
||||
let skip, limit;
|
||||
skip = parseInt(query.skip, 10);
|
||||
if (skip < 0) {
|
||||
throw new Error('invalid skip parameter');
|
||||
}
|
||||
limit = parseInt(query.limit, 10);
|
||||
if (limit < 1) {
|
||||
throw new Error('invalid limit parameter');
|
||||
}
|
||||
return {skip, limit};
|
||||
}
|
||||
|
||||
export function getSortDir(query) {
|
||||
let sort_direction = 'desc';
|
||||
if (query.sort) {
|
||||
if (query.sort === 'asc' || query.sort === '1') {
|
||||
sort_direction = 'asc';
|
||||
} else if (query.sort === 'desc' || query.sort === '-1') {
|
||||
sort_direction = 'desc'
|
||||
} else {
|
||||
throw new Error('invalid sort direction');
|
||||
}
|
||||
}
|
||||
return sort_direction;
|
||||
}
|
||||
|
||||
export function applyAccountFilters(query, queryStruct) {
|
||||
if (query.account) {
|
||||
queryStruct.bool.must.push({"bool": {should: makeShouldArray(query)}});
|
||||
}
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
import {FastifyInstance, FastifyReply, FastifyRequest} from "fastify";
|
||||
import {ServerResponse} from "http";
|
||||
import {getTrackTotalHits, mergeActionMeta, timedQuery} from "../../../helpers/functions";
|
||||
import {
|
||||
addSortedBy,
|
||||
applyAccountFilters,
|
||||
applyCodeActionFilters,
|
||||
applyGenericFilters,
|
||||
applyTimeFilter,
|
||||
getSkipLimit,
|
||||
getSortDir
|
||||
} from "./functions";
|
||||
|
||||
async function getActions(fastify: FastifyInstance, request: FastifyRequest) {
|
||||
const query = request.query;
|
||||
const queryStruct = {
|
||||
"bool": {
|
||||
must: [],
|
||||
must_not: [],
|
||||
boost: 1.0
|
||||
}
|
||||
};
|
||||
|
||||
const {skip, limit} = getSkipLimit(query);
|
||||
const sort_direction = getSortDir(query);
|
||||
applyAccountFilters(query, queryStruct);
|
||||
applyGenericFilters(query, queryStruct);
|
||||
applyTimeFilter(query, queryStruct);
|
||||
applyCodeActionFilters(query, queryStruct);
|
||||
// allow precise counting of total hits
|
||||
const trackTotalHits = getTrackTotalHits(query);
|
||||
|
||||
// Prepare query body
|
||||
const query_body = {
|
||||
"track_total_hits": trackTotalHits,
|
||||
"query": queryStruct
|
||||
};
|
||||
|
||||
// Include sorting
|
||||
addSortedBy(query, query_body, sort_direction);
|
||||
|
||||
// Perform search
|
||||
const maxActions = fastify.manager.config.api.limits.get_actions;
|
||||
const pResults = await Promise.all([
|
||||
fastify.eosjs.rpc.get_info(),
|
||||
fastify.elastic.search({
|
||||
"index": fastify.manager.chain + '-action-*',
|
||||
"from": skip || 0,
|
||||
"size": (limit > maxActions ? maxActions : limit) || 10,
|
||||
"body": query_body
|
||||
})
|
||||
]);
|
||||
|
||||
const results = pResults[1]['body']['hits'];
|
||||
const response: any = {
|
||||
cached: false,
|
||||
lib: pResults[0].last_irreversible_block_num,
|
||||
total: results['total']
|
||||
};
|
||||
|
||||
if (query.simple) {
|
||||
response['simple_actions'] = [];
|
||||
} else {
|
||||
response['actions'] = [];
|
||||
}
|
||||
|
||||
if (results['hits'].length > 0) {
|
||||
const actions = results['hits'];
|
||||
for (let action of actions) {
|
||||
action = action._source;
|
||||
mergeActionMeta(action);
|
||||
if (query.simple) {
|
||||
response.simple_actions.push({
|
||||
block: action['block_num'],
|
||||
irreversible: action['block_num'] < pResults[0].last_irreversible_block_num,
|
||||
timestamp: action['@timestamp'],
|
||||
transaction_id: action['trx_id'],
|
||||
actors: action['act']['authorization'].map(a => `${a.actor}@${a.permission}`).join(","),
|
||||
notified: action['notified'].join(','),
|
||||
contract: action['act']['account'],
|
||||
action: action['act']['name'],
|
||||
data: action['act']['data']
|
||||
});
|
||||
} else {
|
||||
response.actions.push(action);
|
||||
}
|
||||
}
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
export function getActionsHandler(fastify: FastifyInstance, route: string) {
|
||||
return async (request: FastifyRequest, reply: FastifyReply<ServerResponse>) => {
|
||||
reply.send(await timedQuery(getActions, fastify, request, route));
|
||||
}
|
||||
}
|
||||
@@ -1,117 +0,0 @@
|
||||
import {FastifyInstance, RouteSchema} from "fastify";
|
||||
import {getActionsHandler} from "./get_actions";
|
||||
import {addApiRoute, extendQueryStringSchema, extendResponseSchema, getRouteName} from "../../../helpers/functions";
|
||||
|
||||
export default function (fastify: FastifyInstance, opts: any, next) {
|
||||
const schema: RouteSchema = {
|
||||
description: 'get actions based on notified account. this endpoint also accepts generic filters based on indexed fields' +
|
||||
' (e.g. act.authorization.actor=eosio or act.name=delegatebw), if included they will be combined with a AND operator',
|
||||
summary: 'get root actions',
|
||||
tags: ['actions', 'history'],
|
||||
querystring: extendQueryStringSchema({
|
||||
"account": {
|
||||
description: 'notified account',
|
||||
type: 'string',
|
||||
minLength: 1,
|
||||
maxLength: 12
|
||||
},
|
||||
"track": {
|
||||
description: 'total results to track (count) [number or true]',
|
||||
type: 'string'
|
||||
},
|
||||
"filter": {
|
||||
description: 'code:name filter',
|
||||
type: 'string',
|
||||
minLength: 3
|
||||
},
|
||||
"sort": {
|
||||
description: 'sort direction',
|
||||
enum: ['desc', 'asc', '1', '-1'],
|
||||
type: 'string'
|
||||
},
|
||||
"after": {
|
||||
description: 'filter after specified date (ISO8601)',
|
||||
type: 'string'
|
||||
},
|
||||
"before": {
|
||||
description: 'filter before specified date (ISO8601)',
|
||||
type: 'string'
|
||||
},
|
||||
"simple": {
|
||||
description: 'simplified output mode',
|
||||
type: 'boolean'
|
||||
}
|
||||
}),
|
||||
response: extendResponseSchema({
|
||||
"simple_actions": {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "object",
|
||||
properties: {
|
||||
"block": {type: "number"},
|
||||
"timestamp": {type: "string"},
|
||||
"irreversible": {type: "boolean"},
|
||||
"contract": {type: "string"},
|
||||
"action": {type: "string"},
|
||||
"actors": {type: "string"},
|
||||
"notified": {type: "string"},
|
||||
"transaction_id": {type: "string"},
|
||||
"data": {
|
||||
additionalProperties: true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"actions": {
|
||||
type: "array",
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
"@timestamp": {type: "string"},
|
||||
"timestamp": {type: "string"},
|
||||
"block_num": {type: "number"},
|
||||
"trx_id": {type: "string"},
|
||||
"act": {
|
||||
type: 'object',
|
||||
properties: {
|
||||
"account": {type: "string"},
|
||||
"name": {type: "string"}
|
||||
},
|
||||
additionalProperties: true
|
||||
},
|
||||
"notified": {
|
||||
type: "array", items: {type: "string"}
|
||||
},
|
||||
"cpu_usage_us": {type: "number"},
|
||||
"net_usage_words": {type: "number"},
|
||||
"account_ram_deltas": {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "object",
|
||||
properties: {
|
||||
"account": {type: "string"},
|
||||
"delta": {type: "number"}
|
||||
},
|
||||
additionalProperties: true
|
||||
}
|
||||
},
|
||||
"global_sequence": {type: "number"},
|
||||
"receiver": {type: 'string'},
|
||||
"producer": {type: "string"},
|
||||
"parent": {type: "number"},
|
||||
"action_ordinal": {type: 'number'},
|
||||
"creator_action_ordinal": {type: 'number'}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
};
|
||||
addApiRoute(
|
||||
fastify,
|
||||
'GET',
|
||||
getRouteName(__filename),
|
||||
getActionsHandler,
|
||||
schema
|
||||
);
|
||||
next();
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
import {FastifyInstance, FastifyReply, FastifyRequest} from "fastify";
|
||||
import {ServerResponse} from "http";
|
||||
import {mergeActionMeta, timedQuery} from "../../../helpers/functions";
|
||||
|
||||
async function getTransaction(fastify: FastifyInstance, request: FastifyRequest) {
|
||||
const pResults = await Promise.all([
|
||||
fastify.eosjs.rpc.get_info(),
|
||||
fastify.elastic.search({
|
||||
"index": fastify.manager.chain + '-action-*',
|
||||
"body": {
|
||||
"query": {
|
||||
"bool": {
|
||||
must: [
|
||||
{term: {"trx_id": request.query.id.toLowerCase()}}
|
||||
]
|
||||
}
|
||||
},
|
||||
"sort": {
|
||||
"global_sequence": "asc"
|
||||
}
|
||||
}
|
||||
})
|
||||
]);
|
||||
const results = pResults[1];
|
||||
const response = {
|
||||
"trx_id": request.query.id,
|
||||
"lib": pResults[0].last_irreversible_block_num,
|
||||
"actions": []
|
||||
};
|
||||
const hits = results['body']['hits']['hits'];
|
||||
if (hits.length > 0) {
|
||||
for (let action of hits) {
|
||||
action = action._source;
|
||||
mergeActionMeta(action);
|
||||
response.actions.push(action);
|
||||
}
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
export function getTransactionHandler(fastify: FastifyInstance, route: string) {
|
||||
return async (request: FastifyRequest, reply: FastifyReply<ServerResponse>) => {
|
||||
reply.send(await timedQuery(getTransaction, fastify, request, route));
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
import {FastifyInstance, FastifyReply, FastifyRequest} from "fastify";
|
||||
import {ServerResponse} from "http";
|
||||
import got from "got";
|
||||
import {timedQuery} from "../../../helpers/functions";
|
||||
|
||||
async function getAccount(fastify: FastifyInstance, request: FastifyRequest) {
|
||||
|
||||
const response = {
|
||||
query_time: null,
|
||||
cached: false,
|
||||
account: null,
|
||||
actions: null,
|
||||
tokens: null,
|
||||
links: null
|
||||
};
|
||||
|
||||
const account = request.query.account;
|
||||
const reqQueue = [];
|
||||
reqQueue.push(fastify.eosjs.rpc.get_account(account));
|
||||
|
||||
const localApi = `http://${fastify.manager.config.api.server_addr}:${fastify.manager.config.api.server_port}/v2`;
|
||||
const getTokensApi = localApi + '/state/get_tokens';
|
||||
const getActionsApi = localApi + '/history/get_actions';
|
||||
|
||||
// fetch recent actions
|
||||
reqQueue.push(got.get(`${getActionsApi}?account=${account}&limit=10`));
|
||||
|
||||
// fetch account tokens
|
||||
reqQueue.push(got.get(`${getTokensApi}?account=${account}`));
|
||||
|
||||
const results = await Promise.all(reqQueue);
|
||||
response.account = results[0];
|
||||
response.actions = JSON.parse(results[1].body).actions;
|
||||
response.tokens = JSON.parse(results[2].body).tokens;
|
||||
return response;
|
||||
}
|
||||
|
||||
export function getAccountHandler(fastify: FastifyInstance, route: string) {
|
||||
return async (request: FastifyRequest, reply: FastifyReply<ServerResponse>) => {
|
||||
reply.send(await timedQuery(getAccount, fastify, request, route));
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
import {FastifyInstance} from "fastify";
|
||||
import {getAccountHandler} from "./get_account";
|
||||
import {addApiRoute, getRouteName} from "../../../helpers/functions";
|
||||
|
||||
export default function (fastify: FastifyInstance, opts: any, next) {
|
||||
const schema = {
|
||||
description: 'get account data',
|
||||
summary: 'get account summary',
|
||||
tags: ['accounts', 'state'],
|
||||
querystring: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
"account": {
|
||||
description: 'account name',
|
||||
type: 'string'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
addApiRoute(
|
||||
fastify,
|
||||
'GET',
|
||||
getRouteName(__filename),
|
||||
getAccountHandler,
|
||||
schema
|
||||
);
|
||||
next();
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
import {FastifyInstance, FastifyReply, FastifyRequest} from "fastify";
|
||||
import {ServerResponse} from "http";
|
||||
import {timedQuery} from "../../../helpers/functions";
|
||||
import {Numeric} from "eosjs/dist";
|
||||
|
||||
function invalidKey() {
|
||||
const err: any = new Error();
|
||||
err.statusCode = 400;
|
||||
err.message = 'invalid public key';
|
||||
throw err;
|
||||
}
|
||||
|
||||
async function getKeyAccounts(fastify: FastifyInstance, request: FastifyRequest) {
|
||||
|
||||
let publicKey;
|
||||
const public_Key = request.req.method === 'POST' ? request.body.public_key : request.query.public_key;
|
||||
|
||||
if (public_Key.startsWith("PUB_")) {
|
||||
publicKey = public_Key;
|
||||
} else if (public_Key.startsWith("EOS")) {
|
||||
try {
|
||||
publicKey = Numeric.convertLegacyPublicKey(public_Key);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
invalidKey();
|
||||
}
|
||||
} else {
|
||||
invalidKey();
|
||||
}
|
||||
|
||||
const _body = {
|
||||
query: {
|
||||
bool: {
|
||||
should: [
|
||||
{term: {"@updateauth.auth.keys.key.keyword": publicKey}},
|
||||
{term: {"@newaccount.active.keys.key.keyword": publicKey}},
|
||||
{term: {"@newaccount.owner.keys.key.keyword": publicKey}}
|
||||
],
|
||||
minimum_should_match: 1
|
||||
}
|
||||
},
|
||||
sort: [{"global_sequence": {"order": "desc"}}]
|
||||
};
|
||||
|
||||
const results = await fastify.elastic.search({
|
||||
index: fastify.manager.chain + '-action-*',
|
||||
body: _body
|
||||
});
|
||||
|
||||
const response = {
|
||||
account_names: []
|
||||
};
|
||||
if (results['body']['hits']['hits'].length > 0) {
|
||||
response.account_names = results['body']['hits']['hits'].map((v) => {
|
||||
if (v._source.act.name === 'newaccount') {
|
||||
if (v._source['@newaccount'].newact) {
|
||||
return v._source['@newaccount'].newact;
|
||||
} else if (v._source.act.data.newact) {
|
||||
return v._source.act.data.newact;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else if (v._source.act.name === 'updateauth') {
|
||||
return v._source.act.data.account;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (response.account_names.length > 0) {
|
||||
response.account_names = [...(new Set(response.account_names))];
|
||||
return response;
|
||||
} else {
|
||||
const err: any = new Error();
|
||||
err.statusCode = 404;
|
||||
err.message = 'no accounts associated with ' + public_Key;
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
export function getKeyAccountsHandler(fastify: FastifyInstance, route: string) {
|
||||
return async (request: FastifyRequest, reply: FastifyReply<ServerResponse>) => {
|
||||
reply.send(await timedQuery(getKeyAccounts, fastify, request, route));
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
import {FastifyInstance} from "fastify";
|
||||
import {getKeyAccountsHandler} from "./get_key_accounts";
|
||||
import {addApiRoute, getRouteName} from "../../../helpers/functions";
|
||||
|
||||
export default function (fastify: FastifyInstance, opts: any, next) {
|
||||
|
||||
// GET
|
||||
const getSchema = {
|
||||
description: 'get accounts by public key',
|
||||
summary: 'get accounts by public key',
|
||||
tags: ['accounts', 'state'],
|
||||
querystring: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
"public_key": {
|
||||
description: 'public key',
|
||||
type: 'string'
|
||||
},
|
||||
},
|
||||
required: ["public_key"]
|
||||
},
|
||||
response: {
|
||||
200: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
"account_names": {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
addApiRoute(fastify, 'GET', getRouteName(__filename), getKeyAccountsHandler, getSchema);
|
||||
|
||||
// POST
|
||||
const postSchema = {
|
||||
description: 'get accounts by public key',
|
||||
summary: 'get accounts by public key',
|
||||
tags: ['accounts', 'state'],
|
||||
body: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
"public_key": {
|
||||
description: 'public key',
|
||||
type: 'string'
|
||||
},
|
||||
},
|
||||
required: ["public_key"]
|
||||
},
|
||||
response: {
|
||||
200: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
"account_names": {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
addApiRoute(fastify, 'POST', getRouteName(__filename), getKeyAccountsHandler, postSchema);
|
||||
next();
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
import {FastifyInstance, FastifyReply, FastifyRequest} from "fastify";
|
||||
import {ServerResponse} from "http";
|
||||
import {getTrackTotalHits, timedQuery} from "../../../helpers/functions";
|
||||
import {ApiResponse} from "@elastic/elasticsearch";
|
||||
import {getSkipLimit} from "../../v2-history/get_actions/functions";
|
||||
|
||||
async function getLinks(fastify: FastifyInstance, request: FastifyRequest) {
|
||||
const query = request.query;
|
||||
const {account, code, action, permissions} = query;
|
||||
const {skip, limit} = getSkipLimit(query);
|
||||
|
||||
const queryStruct = {
|
||||
"bool": {
|
||||
must: []
|
||||
}
|
||||
};
|
||||
|
||||
if (account) {
|
||||
queryStruct.bool.must.push({'term': {'account': account}});
|
||||
}
|
||||
|
||||
if (code) {
|
||||
queryStruct.bool.must.push({'term': {'code': code}});
|
||||
}
|
||||
|
||||
if (action) {
|
||||
queryStruct.bool.must.push({'term': {'action': action}});
|
||||
}
|
||||
|
||||
if (permissions) {
|
||||
queryStruct.bool.must.push({'term': {'permissions': permissions}});
|
||||
}
|
||||
|
||||
// Prepare query body
|
||||
const query_body = {
|
||||
track_total_hits: getTrackTotalHits(query),
|
||||
query: queryStruct,
|
||||
sort: {block_num: 'desc'}
|
||||
};
|
||||
|
||||
const maxLinks = fastify.manager.config.api.limits.get_links;
|
||||
const results: ApiResponse = await fastify.elastic.search({
|
||||
index: fastify.manager.chain + '-link-*',
|
||||
from: skip || 0,
|
||||
size: (limit > maxLinks ? maxLinks : limit) || 10,
|
||||
body: query_body
|
||||
});
|
||||
const hits = results.body.hits.hits;
|
||||
const response: any = {
|
||||
cached: false,
|
||||
total: results.body.hits.total,
|
||||
links: []
|
||||
};
|
||||
for (const hit of hits) {
|
||||
const link = hit._source;
|
||||
link.timestamp = link['@timestamp'];
|
||||
delete link['@timestamp'];
|
||||
response.links.push(link);
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
export function getLinksHandler(fastify: FastifyInstance, route: string) {
|
||||
return async (request: FastifyRequest, reply: FastifyReply<ServerResponse>) => {
|
||||
reply.send(await timedQuery(getLinks, fastify, request, route));
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
import {ServerResponse} from "http";
|
||||
import {timedQuery} from "../../../helpers/functions";
|
||||
import {FastifyInstance, FastifyReply, FastifyRequest} from "fastify";
|
||||
|
||||
|
||||
async function getTokens(fastify: FastifyInstance, request: FastifyRequest) {
|
||||
|
||||
const response = {
|
||||
query_time: null,
|
||||
cached: false,
|
||||
'account': request.query.account,
|
||||
'tokens': []
|
||||
};
|
||||
|
||||
const results = await fastify.elastic.search({
|
||||
"index": fastify.manager.chain + '-action-*',
|
||||
"body": {
|
||||
size: 0,
|
||||
query: {
|
||||
bool: {
|
||||
filter: [
|
||||
{term: {"notified": request.query.account}},
|
||||
{terms: {"act.name": ["transfer", "issue"]}}
|
||||
]
|
||||
}
|
||||
},
|
||||
aggs: {
|
||||
tokens: {
|
||||
terms: {
|
||||
field: "act.account",
|
||||
size: 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
for (const bucket of results['body']['aggregations']['tokens']['buckets']) {
|
||||
let token_data;
|
||||
try {
|
||||
token_data = await fastify.eosjs.rpc.get_currency_balance(bucket['key'], request.query.account);
|
||||
} catch (e) {
|
||||
console.log(`get_currency_balance error - contract:${bucket['key']} - account:${request.query.account}`);
|
||||
continue;
|
||||
}
|
||||
for (const entry of token_data) {
|
||||
let precision = 0;
|
||||
const [amount, symbol] = entry.split(" ");
|
||||
const amount_arr = amount.split(".");
|
||||
if (amount_arr.length === 2) {
|
||||
precision = amount_arr[1].length;
|
||||
}
|
||||
response.tokens.push({
|
||||
symbol: symbol,
|
||||
precision: precision,
|
||||
amount: parseFloat(amount),
|
||||
contract: bucket['key']
|
||||
});
|
||||
}
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
export function getTokensHandler(fastify: FastifyInstance, route: string) {
|
||||
return async (request: FastifyRequest, reply: FastifyReply<ServerResponse>) => {
|
||||
reply.send(await timedQuery(getTokens, fastify, request, route));
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
import {FastifyInstance} from "fastify";
|
||||
import {addApiRoute, getRouteName} from "../../../helpers/functions";
|
||||
import {getTokensHandler} from "./get_tokens";
|
||||
|
||||
export default function (fastify: FastifyInstance, opts: any, next) {
|
||||
const schema = {
|
||||
description: 'get account data',
|
||||
summary: 'get account summary',
|
||||
tags: ['accounts', 'state'],
|
||||
querystring: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
"account": {
|
||||
description: 'account name',
|
||||
type: 'string'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
addApiRoute(
|
||||
fastify,
|
||||
'GET',
|
||||
getRouteName(__filename),
|
||||
getTokensHandler,
|
||||
schema
|
||||
);
|
||||
next();
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
import {FastifyInstance, FastifyReply, FastifyRequest} from "fastify";
|
||||
import {ServerResponse} from "http";
|
||||
import {timedQuery} from "../../../helpers/functions";
|
||||
|
||||
async function getVoters(fastify: FastifyInstance, request: FastifyRequest) {
|
||||
|
||||
let skip, limit;
|
||||
|
||||
skip = parseInt(request.query.skip, 10);
|
||||
if (skip < 0) {
|
||||
return 'invalid skip parameter';
|
||||
}
|
||||
limit = parseInt(request.query.limit, 10);
|
||||
if (limit < 1) {
|
||||
return 'invalid limit parameter';
|
||||
}
|
||||
|
||||
const response = {
|
||||
query_time: null,
|
||||
voter_count: 0,
|
||||
'voters': []
|
||||
};
|
||||
let queryStruct: any = {
|
||||
"bool": {
|
||||
"must": []
|
||||
}
|
||||
};
|
||||
|
||||
if (request.query.producer) {
|
||||
for (const bp of request.query.producer.split(",")) {
|
||||
queryStruct.bool.must.push({"term": {"producers": bp}});
|
||||
}
|
||||
}
|
||||
|
||||
if (request.query.proxy === 'true') {
|
||||
queryStruct.bool.must.push({"term": {"is_proxy": true}});
|
||||
}
|
||||
|
||||
if (queryStruct.bool.must.length === 0) {
|
||||
queryStruct = {
|
||||
"match_all": {}
|
||||
};
|
||||
}
|
||||
|
||||
const maxDocs = fastify.manager.config.api.limits.get_voters ?? 100;
|
||||
const results = await fastify.elastic.search({
|
||||
"index": fastify.manager.chain + '-table-voters-*',
|
||||
"from": skip || 0,
|
||||
"size": (limit > maxDocs ? maxDocs : limit) || 10,
|
||||
"body": {
|
||||
"query": queryStruct,
|
||||
"sort": [{"last_vote_weight": "desc"}]
|
||||
}
|
||||
});
|
||||
const hits = results['body']['hits']['hits'];
|
||||
for (const hit of hits) {
|
||||
const voter = hit._source;
|
||||
response.voters.push({
|
||||
account: voter.voter,
|
||||
weight: voter.last_vote_weight,
|
||||
last_vote: voter.block_num
|
||||
});
|
||||
}
|
||||
response.voter_count = results['body']['hits']['total']['value'];
|
||||
return response;
|
||||
}
|
||||
|
||||
export function getVotersHandler(fastify: FastifyInstance, route: string) {
|
||||
return async (request: FastifyRequest, reply: FastifyReply<ServerResponse>) => {
|
||||
reply.send(await timedQuery(getVoters, fastify, request, route));
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
import {FastifyInstance} from "fastify";
|
||||
import {getVotersHandler} from "./get_voters";
|
||||
import {addApiRoute, getRouteName} from "../../../helpers/functions";
|
||||
|
||||
export default function (fastify: FastifyInstance, opts: any, next) {
|
||||
const schema = {
|
||||
description: 'get voters',
|
||||
summary: 'get voters',
|
||||
tags: ['accounts', 'state'],
|
||||
querystring: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
"producer": {
|
||||
description: 'filter by voted producer (comma separated)',
|
||||
type: 'string'
|
||||
},
|
||||
"skip": {
|
||||
description: 'skip [n] actions (pagination)',
|
||||
type: 'integer',
|
||||
minimum: 0
|
||||
},
|
||||
"limit": {
|
||||
description: 'limit of [n] actions per page',
|
||||
type: 'integer',
|
||||
minimum: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
addApiRoute(
|
||||
fastify,
|
||||
'GET',
|
||||
getRouteName(__filename),
|
||||
getVotersHandler,
|
||||
schema
|
||||
);
|
||||
next();
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
import {FastifyInstance, FastifyReply, FastifyRequest} from "fastify";
|
||||
import {ServerResponse} from "http";
|
||||
import {connect} from "amqplib";
|
||||
import {timedQuery} from "../../../helpers/functions";
|
||||
import {getLastIndexedBlock} from "../../../../helpers/common_functions";
|
||||
|
||||
async function checkRabbit(fastify: FastifyInstance) {
|
||||
try {
|
||||
const connection = await connect(fastify.manager.ampqUrl);
|
||||
await connection.close();
|
||||
return createHealth('RabbitMq', 'OK');
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
return createHealth('RabbitMq', 'Error');
|
||||
}
|
||||
}
|
||||
|
||||
async function checkNodeos(fastify: FastifyInstance) {
|
||||
const rpc = fastify.manager.nodeosJsonRPC;
|
||||
try {
|
||||
const results = await rpc.get_info();
|
||||
if (results) {
|
||||
const diff = (new Date().getTime()) - (new Date(results.head_block_time).getTime());
|
||||
return createHealth('NodeosRPC', 'OK', {
|
||||
head_block_num: results.head_block_num,
|
||||
head_block_time: results.head_block_time,
|
||||
time_offset: diff,
|
||||
last_irreversible_block: results.last_irreversible_block_num,
|
||||
chain_id: results.chain_id
|
||||
});
|
||||
} else {
|
||||
return createHealth('NodeosRPC', 'Error');
|
||||
}
|
||||
} catch (e) {
|
||||
return createHealth('NodeosRPC', 'Error');
|
||||
}
|
||||
}
|
||||
|
||||
async function checkElastic(fastify: FastifyInstance) {
|
||||
try {
|
||||
let esStatus = await fastify.elastic.cat.health({format: 'json', v: true});
|
||||
let lastIndexedBlock = await getLastIndexedBlock(fastify.elastic, fastify.manager.chain);
|
||||
const data = {
|
||||
last_indexed_block: lastIndexedBlock,
|
||||
active_shards: esStatus.body[0]['active_shards_percent']
|
||||
};
|
||||
let stat = 'OK';
|
||||
esStatus.body.forEach(status => {
|
||||
if (status.status === 'yellow' && stat !== 'Error') {
|
||||
stat = 'Warning'
|
||||
} else if (status.status === 'red') {
|
||||
stat = 'Error'
|
||||
}
|
||||
});
|
||||
return createHealth('Elasticsearch', stat, data);
|
||||
} catch (e) {
|
||||
console.log(e, 'Elasticsearch Error');
|
||||
return createHealth('Elasticsearch', 'Error');
|
||||
}
|
||||
}
|
||||
|
||||
function createHealth(name: string, status, data?: any) {
|
||||
let time = Date.now();
|
||||
return {
|
||||
service: name,
|
||||
status: status,
|
||||
service_data: data,
|
||||
time: time
|
||||
}
|
||||
}
|
||||
|
||||
async function getHealthQuery(fastify: FastifyInstance, request: FastifyRequest) {
|
||||
let response = {
|
||||
version: fastify.manager.current_version,
|
||||
version_hash: fastify.manager.getServerHash(),
|
||||
host: fastify.manager.config.api.server_name,
|
||||
features: fastify.manager.config.features,
|
||||
health: []
|
||||
};
|
||||
response.health.push(await checkRabbit(fastify));
|
||||
response.health.push(await checkNodeos(fastify));
|
||||
response.health.push(await checkElastic(fastify));
|
||||
return response;
|
||||
}
|
||||
|
||||
export function healthHandler(fastify: FastifyInstance, route: string) {
|
||||
return async (request: FastifyRequest, reply: FastifyReply<ServerResponse>) => {
|
||||
reply.send(await timedQuery(getHealthQuery, fastify, request, route));
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
exports.GET = {
|
||||
description: 'fetch contract abi at specific block',
|
||||
summary: 'fetch abi at specific block',
|
||||
tags: ['history'],
|
||||
querystring: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
"contract": {
|
||||
description: 'contract account',
|
||||
type: 'string',
|
||||
minLength: 1,
|
||||
maxLength: 12
|
||||
},
|
||||
"block": {
|
||||
description: 'target block',
|
||||
type: 'integer',
|
||||
minimum: 1
|
||||
},
|
||||
"fetch": {
|
||||
description: 'should fetch the ABI',
|
||||
type: 'boolean'
|
||||
}
|
||||
},
|
||||
required: ["contract"]
|
||||
}
|
||||
};
|
||||
@@ -1,14 +0,0 @@
|
||||
exports.GET = {
|
||||
description: 'get account data',
|
||||
summary: 'get account summary',
|
||||
tags: ['accounts', 'state'],
|
||||
querystring: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
"account": {
|
||||
description: 'account name',
|
||||
type: 'string'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,132 +0,0 @@
|
||||
exports.GET = {
|
||||
description: 'get actions based on notified account. this endpoint also accepts generic filters based on indexed fields' +
|
||||
' (e.g. act.authorization.actor=eosio or act.name=delegatebw), if included they will be combined with a AND operator',
|
||||
summary: 'get root actions',
|
||||
tags: ['actions', 'history'],
|
||||
querystring: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
"account": {
|
||||
description: 'notified account',
|
||||
type: 'string',
|
||||
minLength: 1,
|
||||
maxLength: 12
|
||||
},
|
||||
"track": {
|
||||
description: 'total results to track (count) [number or true]',
|
||||
type: 'string'
|
||||
},
|
||||
"filter": {
|
||||
description: 'code:name filter',
|
||||
type: 'string',
|
||||
minLength: 3
|
||||
},
|
||||
"skip": {
|
||||
description: 'skip [n] actions (pagination)',
|
||||
type: 'integer',
|
||||
minimum: 0
|
||||
},
|
||||
"limit": {
|
||||
description: 'limit of [n] actions per page',
|
||||
type: 'integer',
|
||||
minimum: 1
|
||||
},
|
||||
"sort": {
|
||||
description: 'sort direction',
|
||||
enum: ['desc', 'asc', '1', '-1'],
|
||||
type: 'string'
|
||||
},
|
||||
"after": {
|
||||
description: 'filter after specified date (ISO8601)',
|
||||
type: 'string'
|
||||
},
|
||||
"before": {
|
||||
description: 'filter before specified date (ISO8601)',
|
||||
type: 'string'
|
||||
},
|
||||
"simple": {
|
||||
description: 'simplified output mode',
|
||||
type: 'boolean'
|
||||
}
|
||||
}
|
||||
},
|
||||
response: {
|
||||
200: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
"query_time": {
|
||||
type: "number"
|
||||
},
|
||||
"cached": {type: "boolean"},
|
||||
"lib": {
|
||||
type: "number"
|
||||
},
|
||||
"total": {
|
||||
type: "object",
|
||||
properties: {
|
||||
"value": {type: "number"},
|
||||
"relation": {type: "string"}
|
||||
}
|
||||
},
|
||||
"simple_actions": {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "object",
|
||||
properties: {
|
||||
"block": {type: "number"},
|
||||
"timestamp": {type: "string"},
|
||||
"irreversible": {type: "boolean"},
|
||||
"contract": {type: "string"},
|
||||
"action": {type: "string"},
|
||||
"actors": {type: "string"},
|
||||
"notified": {type: "string"},
|
||||
"transaction_id": {type: "string"},
|
||||
"data": {
|
||||
additionalProperties: true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"actions": {
|
||||
type: "array",
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
"act": {
|
||||
type: 'object',
|
||||
properties: {
|
||||
"account": {type: "string"},
|
||||
"name": {type: "string"}
|
||||
},
|
||||
additionalProperties: true
|
||||
},
|
||||
"cpu_usage_us": {type: "number"},
|
||||
"net_usage_words": {type: "number"},
|
||||
"account_ram_deltas": {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "object",
|
||||
properties: {
|
||||
"account": {type: "string"},
|
||||
"delta": {type: "number"}
|
||||
},
|
||||
additionalProperties: true
|
||||
}
|
||||
},
|
||||
"global_sequence": {type: "number"},
|
||||
"receiver": {type: 'string'},
|
||||
"@timestamp": {type: "string"},
|
||||
"block_num": {type: "number"},
|
||||
"producer": {type: "string"},
|
||||
"trx_id": {type: "string"},
|
||||
"parent": {type: "number"},
|
||||
"action_ordinal": {type: 'number'},
|
||||
"creator_action_ordinal": {type: 'number'},
|
||||
"notified": {type: "array", items: {type: "string"}}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,20 +0,0 @@
|
||||
exports.GET = {
|
||||
description: 'get block range',
|
||||
summary: 'get block range',
|
||||
tags: ['history'],
|
||||
querystring: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
"from": {
|
||||
description: 'starting block',
|
||||
type: 'integer',
|
||||
minimum: 1
|
||||
},
|
||||
"to": {
|
||||
description: 'last block',
|
||||
type: 'integer',
|
||||
minimum: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,44 +0,0 @@
|
||||
exports.GET = {
|
||||
description: 'get all accounts created by one creator',
|
||||
summary: 'get created accounts',
|
||||
tags: ['accounts', 'history'],
|
||||
querystring: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
"account": {
|
||||
description: 'creator account',
|
||||
type: 'string',
|
||||
minLength: 1,
|
||||
maxLength: 12
|
||||
}
|
||||
}
|
||||
},
|
||||
response: {
|
||||
200: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
"query_time": {
|
||||
type: "number"
|
||||
},
|
||||
"total": {
|
||||
type: "object",
|
||||
properties: {
|
||||
"value": {type: "number"},
|
||||
"relation": {type: "string"}
|
||||
}
|
||||
},
|
||||
"accounts": {
|
||||
type: "array",
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
'name': {type: 'string'},
|
||||
'timestamp': {type: 'string'},
|
||||
'trx_id': {type: 'string'}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,41 +0,0 @@
|
||||
exports.GET = {
|
||||
description: 'get account creator',
|
||||
summary: 'get account creator',
|
||||
tags: ['accounts', 'history'],
|
||||
querystring: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
"account": {
|
||||
description: 'created account',
|
||||
type: 'string',
|
||||
minLength: 1,
|
||||
maxLength: 12
|
||||
}
|
||||
}
|
||||
},
|
||||
response: {
|
||||
200: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
"account": {
|
||||
type: "string"
|
||||
},
|
||||
"creator": {
|
||||
type: "string"
|
||||
},
|
||||
"timestamp": {
|
||||
type: "string"
|
||||
},
|
||||
"block_num": {
|
||||
type: "integer"
|
||||
},
|
||||
"trx_id": {
|
||||
type: "string"
|
||||
},
|
||||
"indirect_creator": {
|
||||
type: "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,26 +0,0 @@
|
||||
exports.GET = {
|
||||
description: 'get state deltas',
|
||||
summary: 'get state deltas',
|
||||
tags: ['history'],
|
||||
querystring: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
"code": {
|
||||
description: 'contract account',
|
||||
type: 'string'
|
||||
},
|
||||
"scope": {
|
||||
description: 'table scope',
|
||||
type: 'string'
|
||||
},
|
||||
"table": {
|
||||
description: 'table name',
|
||||
type: 'string'
|
||||
},
|
||||
"payer": {
|
||||
description: 'payer account',
|
||||
type: 'string'
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,58 +0,0 @@
|
||||
module.exports = {
|
||||
GET: {
|
||||
description: 'get accounts by public key',
|
||||
summary: 'get accounts by public key',
|
||||
tags: ['accounts','state'],
|
||||
querystring: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
"public_key": {
|
||||
description: 'public key',
|
||||
type: 'string'
|
||||
},
|
||||
},
|
||||
required: ["public_key"]
|
||||
},
|
||||
response: {
|
||||
200: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
"account_names": {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
POST: {
|
||||
description: 'get accounts by public key',
|
||||
summary: 'get accounts by public key',
|
||||
tags: ['accounts','state'],
|
||||
body: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
"public_key": {
|
||||
description: 'public key',
|
||||
type: 'string'
|
||||
},
|
||||
},
|
||||
required: ["public_key"]
|
||||
},
|
||||
response: {
|
||||
200: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
"account_names": {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,48 +0,0 @@
|
||||
exports.GET = {
|
||||
description: 'get proposals',
|
||||
summary: 'get proposals',
|
||||
tags: ['state'],
|
||||
querystring: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
"proposer": {
|
||||
description: 'filter by proposer',
|
||||
type: 'string'
|
||||
},
|
||||
"proposal": {
|
||||
description: 'filter by proposal name',
|
||||
type: 'string'
|
||||
},
|
||||
"account": {
|
||||
description: 'filter by either requested or provided account',
|
||||
type: 'string'
|
||||
},
|
||||
"requested": {
|
||||
description: 'filter by requested account',
|
||||
type: 'string'
|
||||
},
|
||||
"provided": {
|
||||
description: 'filter by provided account',
|
||||
type: 'string'
|
||||
},
|
||||
"executed": {
|
||||
description: 'filter by execution status',
|
||||
type: 'boolean'
|
||||
},
|
||||
"track": {
|
||||
description: 'total results to track (count) [number or true]',
|
||||
type: 'string'
|
||||
},
|
||||
"skip": {
|
||||
description: 'skip [n] actions (pagination)',
|
||||
type: 'integer',
|
||||
minimum: 0
|
||||
},
|
||||
"limit": {
|
||||
description: 'limit of [n] actions per page',
|
||||
type: 'integer',
|
||||
minimum: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,37 +0,0 @@
|
||||
exports.GET = {
|
||||
description: 'get tokens from account',
|
||||
summary: 'get tokens from account',
|
||||
tags: ['accounts', 'state'],
|
||||
querystring: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
"account": {
|
||||
description: 'account',
|
||||
type: 'string'
|
||||
},
|
||||
},
|
||||
required: ["account"]
|
||||
},
|
||||
response: {
|
||||
200: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
"query_time": {type: "number"},
|
||||
"cached": {type: "boolean"},
|
||||
"account": {type: "string"},
|
||||
"tokens": {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "object",
|
||||
properties: {
|
||||
"symbol": {type: "string"},
|
||||
"precision": {type: "number"},
|
||||
"amount": {type: "number"},
|
||||
"contract": {type: "string"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,52 +0,0 @@
|
||||
exports.GET = {
|
||||
description: 'get all account that interacted with the source account provided',
|
||||
summary: 'get interactions based on transfers',
|
||||
tags: ['history'],
|
||||
querystring: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
"account": {
|
||||
description: 'source account',
|
||||
type: 'string'
|
||||
},
|
||||
"symbol": {
|
||||
description: 'token symbol',
|
||||
type: 'string',
|
||||
minLength: 1,
|
||||
maxLength: 7
|
||||
},
|
||||
"contract": {
|
||||
description: 'token contract',
|
||||
type: 'string',
|
||||
minLength: 1,
|
||||
maxLength: 12
|
||||
},
|
||||
"direction": {
|
||||
description: 'search direction',
|
||||
enum: ['in', 'out', 'both'],
|
||||
type: 'string'
|
||||
},
|
||||
"min": {
|
||||
description: 'minimum value',
|
||||
type: 'number'
|
||||
},
|
||||
"max": {
|
||||
description: 'maximum value',
|
||||
type: 'number'
|
||||
},
|
||||
"limit": {
|
||||
description: 'query limit',
|
||||
type: 'number'
|
||||
},
|
||||
"after": {
|
||||
description: 'filter after specified date (ISO8601) or block number',
|
||||
type: 'string'
|
||||
},
|
||||
"before": {
|
||||
description: 'filter before specified date (ISO8601) or block number',
|
||||
type: 'string'
|
||||
}
|
||||
},
|
||||
required: ["account", "direction"]
|
||||
}
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user