Compare commits
138 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 |
+17
-80
@@ -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,89 +10,27 @@ pids
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
|
||||
.idea
|
||||
*.pem
|
||||
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
|
||||
|
||||
api/**/*.js
|
||||
api/**/*.js.map
|
||||
api/tests
|
||||
|
||||
hyperion-launcher.js
|
||||
hyperion-launcher.js.map
|
||||
|
||||
launcher.js
|
||||
launcher.js.map
|
||||
|
||||
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
|
||||
|
||||
scripts/hpm.js
|
||||
scripts/hpm.js.map
|
||||
|
||||
plugins/.state.json
|
||||
plugins/repos
|
||||
plugins/*.js
|
||||
.gitmodules
|
||||
# plugins
|
||||
plugins
|
||||
|
||||
# docker storage
|
||||
docker/redis/data
|
||||
docker/elasticsearch/data
|
||||
docker/rabbitmq/data
|
||||
docker/eosio/data
|
||||
|
||||
configuration_backups
|
||||
# transpiled output
|
||||
dist
|
||||
|
||||
scripts/hyp-config.js
|
||||
scripts/hyp-config.js.map
|
||||
# configuration
|
||||
config
|
||||
!config/chains/example.config.json
|
||||
|
||||
scripts/hyp-repair.js
|
||||
scripts/hyp-repair.js.map
|
||||
# logging
|
||||
logs
|
||||
|
||||
scripts/repair-cli/*.js
|
||||
scripts/repair-cli/*.js.map
|
||||
# chain state temp files
|
||||
state
|
||||
|
||||
@@ -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,99 +1,54 @@
|
||||
<!--suppress HtmlUnknownTarget, HtmlDeprecatedAttribute -->
|
||||
<br></br>
|
||||
<p align="center">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://eosrio.io/hyperion-white.png">
|
||||
<img alt="Hyperion Logo"
|
||||
src="https://eosrio.io/hyperion.png">
|
||||
</picture>
|
||||
</p>
|
||||
# Hyperion History API
|
||||
|
||||
<h4 align="center">
|
||||
Scalable Full History API Solution for
|
||||
<a href="https://antelope.io">
|
||||
Antelope
|
||||
</a>
|
||||
(former EOSIO) based blockchains
|
||||
</h4>
|
||||
<img alt="hyperion logo" height="64" src="https://eosrio.io/hyperion.png">
|
||||
<br/>
|
||||
Scalable Full History API Solution for EOSIO based blockchains
|
||||
|
||||
<br>
|
||||
Made with ♥ by [EOS Rio](https://eosrio.io/)
|
||||
|
||||
Made with ♥ by [Rio Blocks / EOS Rio](https://rioblocks.io/?lang=en)
|
||||
|
||||
### [Official documentation](https://hyperion.docs.eosrio.io)
|
||||
|
||||
### How to use
|
||||
|
||||
- [For Providers](https://hyperion.docs.eosrio.io/manual_installation/)
|
||||
|
||||
- [For Developers](https://hyperion.docs.eosrio.io/howtouse/)
|
||||
|
||||
### Official plugins:
|
||||
|
||||
- [Hyperion Lightweight Explorer](https://github.com/eosrio/hyperion-explorer-plugin)
|
||||
Official documentation: https://hyperion.docs.eosrio.io/
|
||||
|
||||
### 1. Overview
|
||||
|
||||
Hyperion is a full history solution for indexing, storing and retrieving Antelope blockchain's historical data.
|
||||
Antelope 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.
|
||||
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.
|
||||
|
||||
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
|
||||
|
||||
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, transaction ids are added to
|
||||
all inline actions, allowing to group by transaction without storing a full transaction index. Besides that if the inline
|
||||
action data is identical to the parent, it is considered a notification and thus removed from the database.
|
||||
No full block or transaction data is stored, all information can be reconstructed from actions and deltas, only a block
|
||||
header index is stored.
|
||||
|
||||
### 2. Architecture
|
||||
|
||||
The following components are required in order to have a fully functional Hyperion API deployment.
|
||||
* For small use cases, it is 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.
|
||||
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.
|
||||
|
||||
#### 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, although HDDs can be used for cold storage nodes.
|
||||
For production environments, a multi-node cluster is highly recommended.
|
||||
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.
|
||||
|
||||
#### 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](https://pm2.keymetrics.io) 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,
|
||||
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.
|
||||
|
||||
#### 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
|
||||
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
|
||||
|
||||
#### 2.4 RabbitMQ
|
||||
Use as messaging queue and data transport between the indexer stages
|
||||
|
||||
Used as messaging queue and data transport between the indexer stages and for real-time data streaming
|
||||
#### 2.5 EOSIO State History
|
||||
Nodeos plugin used to collect action traces and state deltas. Provides data via websocket to the indexer
|
||||
|
||||
#### 2.5 Redis
|
||||
### 3. How to use
|
||||
|
||||
Used for transient data storage across processes and for the preemptive transaction caching used on
|
||||
the `v2/history/get_transaction` and `v2/history/check_transaction` endpoints
|
||||
#### 3.1 [For Providers](https://eosrio.github.io/hyperion-docs/quickstart/)
|
||||
|
||||
#### 2.6 Leap State History
|
||||
|
||||
[Leap / Nodeos](https://github.com/AntelopeIO/leap/tree/main/plugins/state_history_plugin) plugin used
|
||||
to collect action traces and state deltas. Provides data via websocket to the indexer
|
||||
|
||||
#### 2.7 Hyperion Stream Client (optional)
|
||||
|
||||
Web and Node.js client for real-time streaming on enabled hyperion
|
||||
providers. [Documentation](https://hyperion.docs.eosrio.io/stream_client/)
|
||||
|
||||
#### 2.8 Hyperion Plugins (optional)
|
||||
|
||||
Hyperion includes a flexible plugin architecture to allow further customization.
|
||||
Plugins are managed by the `hpm` (hyperion plugin manager) command line tool.
|
||||
#### 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,835 +0,0 @@
|
||||
import {createHash} from "crypto";
|
||||
import * as _ from "lodash";
|
||||
import {FastifyInstance, FastifyReply, FastifyRequest, FastifySchema, HTTPMethods} from "fastify";
|
||||
import got from "got";
|
||||
import {checkDeltaFilter, checkFilter, hLog} from "../../helpers/common_functions";
|
||||
import {Socket} from "socket.io";
|
||||
|
||||
const deltaQueryFields = ['code', 'table', 'scope', 'payer'];
|
||||
|
||||
export async function streamPastDeltas(fastify: FastifyInstance, socket, data) {
|
||||
const search_body = {
|
||||
query: {bool: {must: []}},
|
||||
sort: {block_num: 'asc'},
|
||||
};
|
||||
await addBlockRangeOpts(data, search_body, fastify);
|
||||
deltaQueryFields.forEach(f => {
|
||||
addTermMatch(data, search_body, f);
|
||||
});
|
||||
|
||||
const onDemandDeltaFilters = [];
|
||||
if (data.filters.length > 0) {
|
||||
data.filters.forEach(f => {
|
||||
if (f.field && f.value) {
|
||||
if (f.field.startsWith('@') && !f.field.startsWith('data')) {
|
||||
const _q = {};
|
||||
_q[f.field] = f.value;
|
||||
search_body.query.bool.must.push({'term': _q});
|
||||
} else {
|
||||
onDemandDeltaFilters.push(f);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const responseQueue = [];
|
||||
|
||||
let counter = 0;
|
||||
let total = 0;
|
||||
let totalFiltered = 0;
|
||||
let longScroll = false;
|
||||
|
||||
// console.log(JSON.stringify(search_body, null, 2));
|
||||
|
||||
const init_response = await fastify.elastic.search({
|
||||
index: fastify.manager.chain + '-delta-*',
|
||||
scroll: '30s',
|
||||
size: fastify.manager.config.api.stream_scroll_batch || 500,
|
||||
body: search_body,
|
||||
});
|
||||
|
||||
const scrollLimit = fastify.manager.config.api.stream_scroll_limit;
|
||||
if (scrollLimit && scrollLimit !== -1 && init_response.body.hits.total.value > scrollLimit) {
|
||||
const errorMsg = `Requested ${init_response.body.hits.total.value} deltas, limit is ${scrollLimit}.`;
|
||||
socket.emit('message', {
|
||||
reqUUID: socket.data.reqUUID,
|
||||
type: 'delta_trace', mode: 'history', messages: [],
|
||||
error: errorMsg
|
||||
});
|
||||
return {status: false, error: errorMsg};
|
||||
}
|
||||
|
||||
if (init_response.body.hits.total.value > 10000) {
|
||||
total = init_response.body.hits.total.value;
|
||||
longScroll = true;
|
||||
hLog(`Attention! Long scroll (deltas) is running!`);
|
||||
}
|
||||
|
||||
// emit first block
|
||||
if (init_response.body.hits.hits.length > 0) {
|
||||
emitTraceInit(socket, init_response.body.hits.hits[0]._source.block_num, init_response.body.hits.total.value);
|
||||
}
|
||||
|
||||
responseQueue.push(init_response);
|
||||
|
||||
let lastTransmittedBlock = 0;
|
||||
let pendingScrollId = '';
|
||||
while (responseQueue.length) {
|
||||
let filterCount = 0;
|
||||
const {body} = responseQueue.shift();
|
||||
pendingScrollId = body['_scroll_id'];
|
||||
const enqueuedMessages = [];
|
||||
counter += body['hits']['hits'].length;
|
||||
|
||||
for (const doc of body['hits']['hits']) {
|
||||
let allow = false;
|
||||
if (onDemandDeltaFilters.length > 0) {
|
||||
allow = onDemandDeltaFilters.every(filter => {
|
||||
return checkDeltaFilter(filter, doc._source);
|
||||
});
|
||||
} else {
|
||||
allow = true;
|
||||
}
|
||||
if (allow) {
|
||||
enqueuedMessages.push(doc._source);
|
||||
} else {
|
||||
filterCount++;
|
||||
}
|
||||
// set last block
|
||||
if (doc._source.block_num > lastTransmittedBlock) {
|
||||
lastTransmittedBlock = doc._source.block_num;
|
||||
}
|
||||
}
|
||||
|
||||
totalFiltered += filterCount;
|
||||
|
||||
if (socket.connected) {
|
||||
if (enqueuedMessages.length > 0) {
|
||||
socket.emit('message', {
|
||||
reqUUID: socket.data.reqUUID,
|
||||
type: 'delta_trace',
|
||||
mode: 'history',
|
||||
messages: enqueuedMessages,
|
||||
filtered: filterCount
|
||||
});
|
||||
}
|
||||
} else {
|
||||
hLog('LOST CLIENT');
|
||||
break;
|
||||
}
|
||||
|
||||
if (longScroll) {
|
||||
hLog(`Progress: ${counter + totalFiltered}/${total}`);
|
||||
}
|
||||
|
||||
if (body['hits'].total.value === counter) {
|
||||
hLog(`${counter} past deltas streamed to ${socket.id} (${totalFiltered} filtered)`);
|
||||
break;
|
||||
}
|
||||
|
||||
const next_response = await fastify.elastic.scroll({
|
||||
body: {scroll_id: body['_scroll_id'], scroll: '30s'}
|
||||
});
|
||||
responseQueue.push(next_response);
|
||||
}
|
||||
|
||||
// destroy scroll context
|
||||
await fastify.elastic.clearScroll({scroll_id: pendingScrollId});
|
||||
return {status: true, lastTransmittedBlock};
|
||||
}
|
||||
|
||||
export function emitTraceInit(socket: Socket, firstBlock: number, totalResults: number) {
|
||||
socket.emit('message', {
|
||||
reqUUID: socket.data.reqUUID,
|
||||
type: 'trace_init',
|
||||
mode: 'history',
|
||||
first_block: firstBlock,
|
||||
results: totalResults
|
||||
});
|
||||
}
|
||||
|
||||
export async function streamPastActions(fastify: FastifyInstance, socket, data) {
|
||||
const search_body = {query: {bool: {must: []}}, sort: {global_sequence: 'asc'}};
|
||||
await addBlockRangeOpts(data, search_body, fastify);
|
||||
if (data.account !== '') {
|
||||
search_body.query.bool.must.push({
|
||||
bool: {
|
||||
should: [
|
||||
{term: {'notified': data.account}},
|
||||
{term: {'act.authorization.actor': data.account}},
|
||||
],
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (data.contract !== '*' && data.contract !== '') {
|
||||
search_body.query.bool.must.push({'term': {'act.account': data.contract}});
|
||||
}
|
||||
|
||||
if (data.action !== '*' && data.action !== '') {
|
||||
search_body.query.bool.must.push({'term': {'act.name': data.action}});
|
||||
}
|
||||
|
||||
const onDemandFilters = [];
|
||||
if (data.filters.length > 0) {
|
||||
data.filters.forEach(f => {
|
||||
if (f.field && f.value) {
|
||||
if (f.field.startsWith('@') && !f.field.startsWith('act.data')) {
|
||||
const _q = {};
|
||||
_q[f.field] = f.value;
|
||||
search_body.query.bool.must.push({'term': _q});
|
||||
} else {
|
||||
onDemandFilters.push(f);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const responseQueue = [];
|
||||
let counter = 0;
|
||||
let total = 0;
|
||||
let totalFiltered = 0;
|
||||
let longScroll = false;
|
||||
|
||||
const init_response = await fastify.elastic.search({
|
||||
index: fastify.manager.chain + '-action-*',
|
||||
scroll: '30s',
|
||||
size: fastify.manager.config.api.stream_scroll_batch || 500,
|
||||
body: search_body,
|
||||
});
|
||||
|
||||
const scrollLimit = fastify.manager.config.api.stream_scroll_limit;
|
||||
if (scrollLimit && scrollLimit !== -1 && init_response.body.hits.total.value > scrollLimit) {
|
||||
const errorMsg = `Requested ${init_response.body.hits.total.value} actions, limit is ${scrollLimit}.`;
|
||||
socket.emit('message', {
|
||||
reqUUID: socket.data.reqUUID,
|
||||
type: 'action_trace', mode: 'history', messages: [],
|
||||
error: `Requested ${init_response.body.hits.total.value} actions, limit is ${scrollLimit}.`
|
||||
});
|
||||
return {status: false, error: errorMsg};
|
||||
}
|
||||
|
||||
if (init_response.body.hits.total.value > 10000) {
|
||||
total = init_response.body.hits.total.value;
|
||||
longScroll = true;
|
||||
hLog(`Attention! Long scroll (actions) is running!`);
|
||||
}
|
||||
|
||||
// emit first block
|
||||
if (init_response.body.hits.hits.length > 0) {
|
||||
emitTraceInit(socket, init_response.body.hits.hits[0]._source.block_num, init_response.body.hits.total.value);
|
||||
}
|
||||
|
||||
responseQueue.push(init_response);
|
||||
|
||||
let lastTransmittedBlock = 0;
|
||||
let pendingScrollId = '';
|
||||
while (responseQueue.length) {
|
||||
let filterCount = 0;
|
||||
const {body} = responseQueue.shift();
|
||||
pendingScrollId = body['_scroll_id'];
|
||||
const enqueuedMessages = [];
|
||||
counter += body['hits']['hits'].length;
|
||||
|
||||
for (const doc of body['hits']['hits']) {
|
||||
let allow = false;
|
||||
if (onDemandFilters.length > 0) {
|
||||
allow = onDemandFilters.every(filter => {
|
||||
return checkFilter(filter, doc._source);
|
||||
});
|
||||
} else {
|
||||
allow = true;
|
||||
}
|
||||
if (allow) {
|
||||
enqueuedMessages.push(doc._source);
|
||||
} else {
|
||||
filterCount++;
|
||||
}
|
||||
// set last block
|
||||
if (doc._source.block_num > lastTransmittedBlock) {
|
||||
lastTransmittedBlock = doc._source.block_num;
|
||||
}
|
||||
}
|
||||
|
||||
totalFiltered += filterCount;
|
||||
|
||||
if (socket.connected) {
|
||||
if (enqueuedMessages.length > 0) {
|
||||
socket.emit('message', {
|
||||
reqUUID: socket.data.reqUUID,
|
||||
type: 'action_trace',
|
||||
mode: 'history',
|
||||
messages: enqueuedMessages,
|
||||
filtered: filterCount
|
||||
});
|
||||
}
|
||||
} else {
|
||||
hLog('LOST CLIENT');
|
||||
break;
|
||||
}
|
||||
|
||||
if (longScroll) {
|
||||
hLog(`Progress: ${counter + totalFiltered}/${total}`);
|
||||
}
|
||||
|
||||
if (body['hits'].total.value === counter) {
|
||||
hLog(`${counter} past actions streamed to ${socket.id} (${totalFiltered} filtered)`);
|
||||
break;
|
||||
}
|
||||
|
||||
const next_response = await fastify.elastic.scroll({
|
||||
body: {scroll_id: body['_scroll_id'], scroll: '30s'}
|
||||
});
|
||||
responseQueue.push(next_response);
|
||||
}
|
||||
|
||||
// destroy scroll context
|
||||
await fastify.elastic.clearScroll({scroll_id: pendingScrollId});
|
||||
return {status: true, lastTransmittedBlock};
|
||||
|
||||
}
|
||||
|
||||
export function addTermMatch(data, search_body, field) {
|
||||
if (data[field] && data[field] !== '*' && data[field] !== '') {
|
||||
const termQuery = {};
|
||||
termQuery[field] = data[field];
|
||||
search_body.query.bool.must.push({'term': termQuery});
|
||||
}
|
||||
}
|
||||
|
||||
export async function addBlockRangeOpts(data, search_body, fastify: FastifyInstance) {
|
||||
|
||||
let timeRange;
|
||||
let blockRange;
|
||||
let head;
|
||||
|
||||
if (typeof data['start_from'] === 'string' && data['start_from'] !== '') {
|
||||
if (!timeRange) {
|
||||
timeRange = {"@timestamp": {}};
|
||||
}
|
||||
timeRange["@timestamp"]['gte'] = data['start_from'];
|
||||
}
|
||||
|
||||
if (typeof data['read_until'] === 'string' && data['read_until'] !== '') {
|
||||
if (!timeRange) {
|
||||
timeRange = {"@timestamp": {}};
|
||||
}
|
||||
timeRange["@timestamp"]['lte'] = data['read_until'];
|
||||
}
|
||||
|
||||
if (typeof data['start_from'] === 'number' && data['start_from'] !== 0) {
|
||||
if (!blockRange) {
|
||||
blockRange = {"block_num": {}};
|
||||
}
|
||||
if (data['start_from'] < 0) {
|
||||
if (!head) {
|
||||
head = (await fastify.eosjs.rpc.get_info()).head_block_num;
|
||||
}
|
||||
blockRange["block_num"]['gte'] = head + data['start_from'];
|
||||
} else {
|
||||
blockRange["block_num"]['gte'] = data['start_from'];
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof data['read_until'] === 'number' && data['read_until'] !== 0) {
|
||||
if (!blockRange) {
|
||||
blockRange = {"block_num": {}};
|
||||
}
|
||||
if (data['read_until'] < 0) {
|
||||
if (!head) {
|
||||
head = (await fastify.eosjs.rpc.get_info()).head_block_num;
|
||||
}
|
||||
blockRange["block_num"]['lte'] = head + data['read_until'];
|
||||
} else {
|
||||
blockRange["block_num"]['lte'] = data['read_until'];
|
||||
}
|
||||
}
|
||||
|
||||
if (timeRange) {
|
||||
search_body.query.bool.must.push({
|
||||
range: timeRange,
|
||||
});
|
||||
}
|
||||
if (blockRange) {
|
||||
search_body.query.bool.must.push({
|
||||
range: blockRange,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function extendResponseSchema(responseProps: any) {
|
||||
const props = {
|
||||
query_time_ms: {type: "number"},
|
||||
cached: {type: "boolean"},
|
||||
hot_only: {type: "boolean"},
|
||||
lib: {type: "number"},
|
||||
last_indexed_block: {type: "number"},
|
||||
last_indexed_block_time: {type: "string"},
|
||||
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, required?: string[]) {
|
||||
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];
|
||||
}
|
||||
}
|
||||
const schema = {
|
||||
type: 'object',
|
||||
properties: params
|
||||
}
|
||||
if (required && required.length > 0) {
|
||||
schema["required"] = required;
|
||||
}
|
||||
return schema;
|
||||
}
|
||||
|
||||
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, expiration?: number) {
|
||||
if (fastify.manager.config.api.enable_caching) {
|
||||
let exp;
|
||||
if (expiration) {
|
||||
exp = expiration;
|
||||
} else {
|
||||
exp = fastify.manager.config.api.cache_life;
|
||||
}
|
||||
fastify.redis.set(hash, JSON.stringify(response), 'EX', exp).catch(console.log);
|
||||
}
|
||||
}
|
||||
|
||||
export function getRouteName(filename: string) {
|
||||
const arr = filename.split("/");
|
||||
return arr[arr.length - 2];
|
||||
}
|
||||
|
||||
export function addApiRoute(
|
||||
fastifyInstance: FastifyInstance,
|
||||
method: HTTPMethods | HTTPMethods[],
|
||||
routeName: string,
|
||||
routeBuilder: (fastify: FastifyInstance, route: string) => (request: FastifyRequest, reply: FastifyReply) => Promise<void>,
|
||||
schema: FastifySchema
|
||||
) {
|
||||
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) {
|
||||
[resp, hash] = await getCacheByHash(server.redis, route + JSON.stringify(key), 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 {
|
||||
const parsed = parseInt(query.track, 10);
|
||||
if (parsed > 0) {
|
||||
trackTotalHits = parsed;
|
||||
} else {
|
||||
throw new Error('failed to parse track param');
|
||||
}
|
||||
}
|
||||
}
|
||||
return trackTotalHits;
|
||||
}
|
||||
|
||||
function bigint2Milliseconds(input: bigint) {
|
||||
return parseFloat((parseInt(input.toString()) / 1000000).toFixed(3));
|
||||
}
|
||||
|
||||
const defaultRouteCacheMap = {
|
||||
get_resource_usage: 3600,
|
||||
get_creator: 3600 * 24,
|
||||
health: 10
|
||||
}
|
||||
|
||||
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.method === 'POST' ? request.body : request.query
|
||||
);
|
||||
|
||||
let lastIndexedBlockNumber = null;
|
||||
let lastIndexedBlockTime = null;
|
||||
const lastIndexedBlock = await fastify.redis.get(`${fastify.manager.chain}:last_idx_block`);
|
||||
if (lastIndexedBlock) {
|
||||
const arr = lastIndexedBlock.split("@");
|
||||
if (arr.length === 2) {
|
||||
lastIndexedBlockNumber = parseInt(arr[0], 10);
|
||||
lastIndexedBlockTime = arr[1];
|
||||
}
|
||||
}
|
||||
|
||||
if (cachedResponse && !request.query["ignoreCache"]) {
|
||||
// add cached query time
|
||||
cachedResponse['query_time_ms'] = bigint2Milliseconds(process.hrtime.bigint() - t0);
|
||||
if (lastIndexedBlock) {
|
||||
cachedResponse['last_indexed_block'] = lastIndexedBlockNumber;
|
||||
cachedResponse['last_indexed_block_time'] = lastIndexedBlockTime;
|
||||
}
|
||||
return cachedResponse;
|
||||
}
|
||||
|
||||
// call query function
|
||||
const response = await queryFunction(fastify, request);
|
||||
|
||||
// save response to cache
|
||||
if (hash) {
|
||||
let EX = null;
|
||||
if (defaultRouteCacheMap[route]) {
|
||||
EX = defaultRouteCacheMap[route];
|
||||
}
|
||||
setCacheByHash(fastify, hash, response, EX);
|
||||
}
|
||||
|
||||
// add normal query time
|
||||
if (response) {
|
||||
response['query_time_ms'] = bigint2Milliseconds(process.hrtime.bigint() - t0);
|
||||
if (lastIndexedBlock) {
|
||||
response['last_indexed_block'] = lastIndexedBlockNumber;
|
||||
response['last_indexed_block_time'] = lastIndexedBlockTime;
|
||||
}
|
||||
return response;
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
export function chainApiHandler(fastify: FastifyInstance) {
|
||||
return async (request: FastifyRequest, reply: FastifyReply) => {
|
||||
// check cache
|
||||
const [cachedData, hash, path] = fastify.cacheManager.getCachedData(request);
|
||||
if (cachedData) {
|
||||
// console.log('cache hit:', path, hash);
|
||||
reply.headers({'hyperion-cached': true}).send(cachedData);
|
||||
} else {
|
||||
// call actual request
|
||||
const apiResponse = await handleChainApiRedirect(request, reply, fastify);
|
||||
// console.log('cache miss:', path, hash);
|
||||
fastify.cacheManager.setCachedData(hash, path, apiResponse);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function handleChainApiRedirect(
|
||||
request: FastifyRequest,
|
||||
reply: FastifyReply,
|
||||
fastify: FastifyInstance
|
||||
): Promise<string> {
|
||||
const urlParts = request.url.split("?");
|
||||
let reqUrl = fastify.chain_api + urlParts[0];
|
||||
|
||||
// const pathComponents = urlParts[0].split('/');
|
||||
// const path = pathComponents.at(-1);
|
||||
|
||||
|
||||
if (urlParts[0] === '/v1/chain/push_transaction' && fastify.push_api && fastify.push_api !== "") {
|
||||
reqUrl = fastify.push_api + urlParts[0];
|
||||
}
|
||||
|
||||
const opts = {};
|
||||
|
||||
if (request.method === 'POST') {
|
||||
if (request.body) {
|
||||
if (typeof request.body === 'string') {
|
||||
opts['body'] = request.body;
|
||||
} else if (typeof request.body === 'object') {
|
||||
opts['body'] = JSON.stringify(request.body);
|
||||
}
|
||||
} else {
|
||||
opts['body'] = "";
|
||||
}
|
||||
} else if (request.method === 'GET') {
|
||||
opts['json'] = request.query;
|
||||
}
|
||||
|
||||
try {
|
||||
const apiResponse = await got.post(reqUrl, opts);
|
||||
reply.headers({"Content-Type": "application/json"});
|
||||
if (request.method === 'HEAD') {
|
||||
reply.headers({"Content-Length": apiResponse.body.length});
|
||||
reply.send("");
|
||||
return '';
|
||||
} else {
|
||||
reply.send(apiResponse.body);
|
||||
return apiResponse.body;
|
||||
}
|
||||
} catch (error) {
|
||||
|
||||
if (error.response) {
|
||||
reply.status(error.response.statusCode).send(error.response.body);
|
||||
} else {
|
||||
console.log(error);
|
||||
reply.status(500).send();
|
||||
}
|
||||
|
||||
if (fastify.manager.config.api.chain_api_error_log) {
|
||||
try {
|
||||
if (error.response) {
|
||||
const error_msg = JSON.parse(error.response.body).error.details[0].message;
|
||||
console.log(`endpoint: ${request.raw.url} | status: ${error.response.statusCode} | error: ${error_msg}`);
|
||||
} else {
|
||||
console.log(error);
|
||||
}
|
||||
// if (request.req.url === '/v1/chain/push_transaction') {
|
||||
// const packedTrx = JSON.parse(opts['body']).packed_trx;
|
||||
// const trxBuffer = Buffer.from(packedTrx, 'hex');
|
||||
// const trxData = await fastify.eosjs.api.deserializeTransactionWithActions(trxBuffer);
|
||||
// console.log(trxData);
|
||||
// }
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
export function addChainApiRoute(fastify: FastifyInstance, routeName, description, props?, required?) {
|
||||
const baseSchema = {
|
||||
description: description,
|
||||
summary: description,
|
||||
tags: ['chain']
|
||||
};
|
||||
addApiRoute(
|
||||
fastify,
|
||||
['GET', 'HEAD'],
|
||||
routeName,
|
||||
chainApiHandler,
|
||||
{
|
||||
...baseSchema,
|
||||
querystring: props ? {
|
||||
type: 'object',
|
||||
properties: props,
|
||||
required: required
|
||||
} : undefined
|
||||
}
|
||||
);
|
||||
addApiRoute(
|
||||
fastify,
|
||||
'POST',
|
||||
routeName,
|
||||
chainApiHandler,
|
||||
{
|
||||
...baseSchema,
|
||||
body: props ? {
|
||||
type: ['object', 'string'],
|
||||
properties: props,
|
||||
required: required
|
||||
} : undefined
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
export function addSharedSchemas(fastify: FastifyInstance) {
|
||||
fastify.addSchema({
|
||||
$id: "WholeNumber",
|
||||
title: "Integer",
|
||||
description: "Integer or String",
|
||||
anyOf: [
|
||||
{
|
||||
type: "string",
|
||||
pattern: "^\\d+$"
|
||||
},
|
||||
{
|
||||
type: "integer"
|
||||
}
|
||||
],
|
||||
});
|
||||
|
||||
fastify.addSchema({
|
||||
$id: "Symbol",
|
||||
type: "string",
|
||||
description: "A symbol composed of capital letters between 1-7.",
|
||||
pattern: "^([A-Z]{1,7})$",
|
||||
title: "Symbol"
|
||||
});
|
||||
|
||||
fastify.addSchema({
|
||||
$id: "Signature",
|
||||
type: "string",
|
||||
description: "String representation of an EOSIO compatible cryptographic signature",
|
||||
pattern: "^SIG_([RK]1|WA)_[1-9A-HJ-NP-Za-km-z]+$",
|
||||
title: "Signature"
|
||||
})
|
||||
|
||||
fastify.addSchema({
|
||||
$id: "AccountName",
|
||||
description: "String representation of an EOSIO compatible account name",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string",
|
||||
"description": "String representation of privileged EOSIO name type",
|
||||
"pattern": "^(eosio[\\.][a-z1-5]{1,6})([a-j]{1})?$",
|
||||
"title": "NamePrivileged"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "String representation of basic EOSIO name type, must be 12 characters and contain only a-z and 0-5",
|
||||
"pattern": "^([a-z]{1}[a-z1-5]{11})([a-j]{1})?$",
|
||||
"title": "NameBasic"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "String representation of EOSIO bid name type, 1-12 characters and only a-z and 0-5 are allowed",
|
||||
"pattern": "^([a-z1-5]{1,12})([a-j]{1})?$",
|
||||
"title": "NameBid"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "String representation of EOSIO name type",
|
||||
"pattern": "^([a-z1-5]{1}[a-z1-5\\.]{0,10}[a-z1-5]{1})([a-j]{1})?$",
|
||||
"title": "NameCatchAll"
|
||||
}
|
||||
],
|
||||
"title": "Name"
|
||||
});
|
||||
|
||||
fastify.addSchema({
|
||||
$id: "Expiration",
|
||||
"description": "Time that transaction must be confirmed by.",
|
||||
"type": "string",
|
||||
"pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}$",
|
||||
"title": "DateTime"
|
||||
});
|
||||
|
||||
fastify.addSchema({
|
||||
$id: "BlockExtensions",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"anyOf": [
|
||||
{"type": "integer"},
|
||||
{"type": "string"}
|
||||
]
|
||||
},
|
||||
"title": "Extension"
|
||||
})
|
||||
|
||||
fastify.addSchema({
|
||||
$id: "ActionItems",
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"minProperties": 5,
|
||||
"required": [
|
||||
"account",
|
||||
"name",
|
||||
"authorization",
|
||||
"data",
|
||||
"hex_data"
|
||||
],
|
||||
"properties": {
|
||||
"account": {$ref: 'AccountName#'},
|
||||
"name": {$ref: 'AccountName#'},
|
||||
"authorization": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"minProperties": 2,
|
||||
"required": [
|
||||
"actor",
|
||||
"permission"
|
||||
],
|
||||
"properties": {
|
||||
"actor": {$ref: 'AccountName#'},
|
||||
"permission": {$ref: 'AccountName#'}
|
||||
},
|
||||
"title": "Authority"
|
||||
}
|
||||
},
|
||||
"data": {
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
},
|
||||
"hex_data": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"title": "Action"
|
||||
});
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
import * as Fastify from "fastify";
|
||||
import {IncomingMessage, Server, ServerResponse} from "http";
|
||||
|
||||
// fastify plugins
|
||||
import * as fastifyElasticsearch from 'fastify-elasticsearch';
|
||||
import fastifySwagger from '@fastify/swagger';
|
||||
import fastifyCors from '@fastify/cors';
|
||||
import formBodyPlugin from '@fastify/formbody';
|
||||
import fastifyRedis from '@fastify/redis';
|
||||
import fastifyRateLimit 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(fastifyElasticsearch, params.fastify_elasticsearch);
|
||||
|
||||
if (params.fastify_swagger) {
|
||||
server.register(fastifySwagger, params.fastify_swagger);
|
||||
}
|
||||
|
||||
server.register(fastifyCors);
|
||||
|
||||
server.register(formBodyPlugin);
|
||||
|
||||
server.register(fastifyRedis, params.fastify_redis);
|
||||
|
||||
if (params.fastify_rate_limit) {
|
||||
server.register(fastifyRateLimit, params.fastify_rate_limit);
|
||||
}
|
||||
|
||||
server.register(fastify_eosjs, params.fastify_eosjs);
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
import {FastifyInstance, FastifyPluginOptions} from "fastify";
|
||||
import {Api} from "eosjs/dist";
|
||||
import fp from "fastify-plugin";
|
||||
|
||||
export default fp(async (fastify: FastifyInstance, options: FastifyPluginOptions): Promise<void> => {
|
||||
const rpc = fastify.manager.nodeosJsonRPC;
|
||||
const api = new Api({
|
||||
rpc,
|
||||
signatureProvider: null,
|
||||
chainId: options.chain_id,
|
||||
textDecoder: new TextDecoder(),
|
||||
textEncoder: new TextEncoder(),
|
||||
});
|
||||
fastify.decorate('eosjs', {api, rpc});
|
||||
}, {
|
||||
fastify: '>=2.0.0',
|
||||
name: 'fastify-eosjs'
|
||||
});
|
||||
@@ -1,39 +0,0 @@
|
||||
import {FastifyInstance} from "fastify";
|
||||
import {addApiRoute, chainApiHandler, getRouteName} from "../../../helpers/functions";
|
||||
|
||||
export default function (fastify: FastifyInstance, opts: any, next) {
|
||||
addApiRoute(
|
||||
fastify,
|
||||
'POST',
|
||||
getRouteName(__filename),
|
||||
chainApiHandler,
|
||||
{
|
||||
description: "This method expects a transaction in JSON format and will attempt to apply it to the blockchain.",
|
||||
summary: "This method expects a transaction in JSON format and will attempt to apply it to the blockchain.",
|
||||
tags: ['chain'],
|
||||
body: {
|
||||
type: ['object', 'string'],
|
||||
properties: {
|
||||
signatures: {
|
||||
"type": "array",
|
||||
"description": "array of signatures required to authorize transaction",
|
||||
"items": {$ref: 'Signature#'}
|
||||
},
|
||||
compression: {
|
||||
"type": "boolean",
|
||||
"description": "Compression used, usually false"
|
||||
},
|
||||
packed_context_free_data: {
|
||||
"type": "string",
|
||||
"description": "json to hex"
|
||||
},
|
||||
packed_trx: {
|
||||
"type": "string",
|
||||
"description": "Transaction object json to hex"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
next();
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
import {FastifyInstance} from "fastify";
|
||||
import {addApiRoute, chainApiHandler, getRouteName} from "../../../helpers/functions";
|
||||
|
||||
export default function (fastify: FastifyInstance, opts: any, next) {
|
||||
addApiRoute(
|
||||
fastify,
|
||||
'POST',
|
||||
getRouteName(__filename),
|
||||
chainApiHandler,
|
||||
{
|
||||
description: "This method expects a transaction in JSON format and will attempt to apply it to the blockchain.",
|
||||
summary: "This method expects a transaction in JSON format and will attempt to apply it to the blockchain.",
|
||||
tags: ['chain'],
|
||||
body: {
|
||||
type: ['array', 'object', 'string'],
|
||||
items: {
|
||||
type: ['object', 'string'],
|
||||
additionalProperties: false,
|
||||
minProperties: 8,
|
||||
required: [
|
||||
"expiration",
|
||||
"ref_block_num",
|
||||
"ref_block_prefix",
|
||||
"max_net_usage_words",
|
||||
"max_cpu_usage_ms",
|
||||
"delay_sec",
|
||||
"context_free_actions",
|
||||
"actions"
|
||||
],
|
||||
properties: {
|
||||
"expiration": {$ref: 'Expiration#'},
|
||||
"ref_block_num": {"type": "integer"},
|
||||
"ref_block_prefix": {"type": "integer"},
|
||||
"max_net_usage_words": {$ref: 'WholeNumber#'},
|
||||
"max_cpu_usage_ms": {$ref: 'WholeNumber#'},
|
||||
"delay_sec": {"type": "integer"},
|
||||
"context_free_actions": {
|
||||
"type": "array",
|
||||
"items": {$ref: 'ActionItems#'}
|
||||
},
|
||||
"actions": {
|
||||
"type": "array",
|
||||
"items": {$ref: 'ActionItems#'}
|
||||
},
|
||||
"transaction_extensions": {
|
||||
"type": "array",
|
||||
"items": {$ref: 'BlockExtensions#'}
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
next();
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
import {FastifyInstance} from "fastify";
|
||||
import {addApiRoute, chainApiHandler, getRouteName} from "../../../helpers/functions";
|
||||
|
||||
export default function (fastify: FastifyInstance, opts: any, next) {
|
||||
addApiRoute(
|
||||
fastify,
|
||||
'POST',
|
||||
getRouteName(__filename),
|
||||
chainApiHandler,
|
||||
{
|
||||
description: "This method expects a transaction in JSON format and will attempt to apply it to the blockchain.",
|
||||
summary: "This method expects a transaction in JSON format and will attempt to apply it to the blockchain.",
|
||||
tags: ['chain'],
|
||||
body: {
|
||||
type: ['object', 'string'],
|
||||
properties: {
|
||||
signatures: {
|
||||
"type": "array",
|
||||
"description": "array of signatures required to authorize transaction",
|
||||
"items": {$ref: 'Signature#'}
|
||||
},
|
||||
compression: {
|
||||
"type": "boolean",
|
||||
"description": "Compression used, usually false"
|
||||
},
|
||||
packed_context_free_data: {
|
||||
"type": "string",
|
||||
"description": "json to hex"
|
||||
},
|
||||
packed_trx: {
|
||||
"type": "string",
|
||||
"description": "Transaction object json to hex"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
next();
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
import {FastifyInstance, FastifyReply, FastifyRequest} from "fastify";
|
||||
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) => {
|
||||
reply.send(await timedQuery(getControlledAccounts, fastify, request, route));
|
||||
}
|
||||
}
|
||||
@@ -1,190 +0,0 @@
|
||||
import {FastifyInstance, FastifyReply, FastifyRequest} from "fastify";
|
||||
import {mergeActionMeta, timedQuery} from "../../../helpers/functions";
|
||||
import {GetInfoResult} from "eosjs/dist/eosjs-rpc-interfaces";
|
||||
|
||||
async function getTransaction(fastify: FastifyInstance, request: FastifyRequest) {
|
||||
|
||||
if (request.method === 'POST' && !request.body) {
|
||||
throw new Error("missing POST body");
|
||||
}
|
||||
|
||||
if (typeof request.body === 'string') {
|
||||
request.body = JSON.parse(request.body)
|
||||
}
|
||||
const body: any = request.body;
|
||||
const redis = fastify.redis;
|
||||
const trxId = body.id.toLowerCase();
|
||||
|
||||
const conf = fastify.manager.config;
|
||||
const cachedData = await redis.hgetall('trx_' + trxId);
|
||||
|
||||
const response: any = {
|
||||
"id": 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": undefined,
|
||||
"traces": []
|
||||
};
|
||||
|
||||
let hits;
|
||||
|
||||
// build get_info request with caching
|
||||
const $getInfo = new Promise<GetInfoResult>(resolve => {
|
||||
const key = `${fastify.manager.chain}_get_info`;
|
||||
fastify.redis.get(key).then(value => {
|
||||
if (value) {
|
||||
resolve(JSON.parse(value));
|
||||
} else {
|
||||
fastify.eosjs.rpc.get_info().then(value1 => {
|
||||
fastify.redis.set(key, JSON.stringify(value1), 'EX', 6);
|
||||
resolve(value1);
|
||||
}).catch((reason) => {
|
||||
console.log(reason);
|
||||
response.error = 'failed to get last_irreversible_block_num'
|
||||
resolve(null);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// reconstruct hits from cached data
|
||||
if (cachedData && Object.keys(cachedData).length > 0) {
|
||||
const gsArr = [];
|
||||
for (let cachedDataKey in cachedData) {
|
||||
gsArr.push(cachedData[cachedDataKey]);
|
||||
}
|
||||
gsArr.sort((a, b) => {
|
||||
return a.global_sequence - b.global_sequence;
|
||||
});
|
||||
hits = gsArr.map(value => {
|
||||
return {
|
||||
_source: JSON.parse(value)
|
||||
};
|
||||
});
|
||||
const promiseResults = await Promise.all([
|
||||
redis.ttl('trx_' + trxId),
|
||||
$getInfo
|
||||
]);
|
||||
response.cache_expires_in = promiseResults[0];
|
||||
response.last_irreversible_block = promiseResults[1].last_irreversible_block_num;
|
||||
}
|
||||
|
||||
// search on ES if cache is not present
|
||||
if (!hits) {
|
||||
const _size = conf.api.limits.get_trx_actions || 100;
|
||||
const blockHint = parseInt(body.block_num_hint, 10);
|
||||
let indexPattern = '';
|
||||
if (blockHint) {
|
||||
const idxPart = Math.ceil(blockHint / conf.settings.index_partition_size).toString().padStart(6, '0');
|
||||
indexPattern = fastify.manager.chain + `-action-${conf.settings.index_version}-${idxPart}`;
|
||||
} else {
|
||||
indexPattern = fastify.manager.chain + '-action-*';
|
||||
}
|
||||
let pResults;
|
||||
try {
|
||||
|
||||
// build search request
|
||||
const $search = fastify.elastic.search({
|
||||
index: indexPattern,
|
||||
size: _size,
|
||||
body: {
|
||||
query: {bool: {must: [{term: {trx_id: trxId}}]}},
|
||||
sort: {global_sequence: "asc"}
|
||||
}
|
||||
});
|
||||
|
||||
// execute in parallel
|
||||
pResults = await Promise.all([$getInfo, $search]);
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
if (e.meta.statusCode === 404) {
|
||||
return response;
|
||||
}
|
||||
}
|
||||
hits = pResults[1]['body']['hits']['hits'];
|
||||
response.last_irreversible_block = pResults[0].last_irreversible_block_num;
|
||||
}
|
||||
|
||||
|
||||
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": []
|
||||
};
|
||||
for (let action of actions) {
|
||||
action = action._source;
|
||||
mergeActionMeta(action);
|
||||
response.block_num = action.block_num;
|
||||
response.block_time = action['@timestamp'];
|
||||
for (const receipt of action.receipts) {
|
||||
if (action.act_digest) {
|
||||
receipt.act_digest = action.act_digest.toLowerCase();
|
||||
}
|
||||
response.traces.push({
|
||||
receipt: receipt,
|
||||
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: body.id
|
||||
});
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const errmsg = "Transaction " + 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) => {
|
||||
reply.send(await timedQuery(getTransaction, fastify, request, route));
|
||||
}
|
||||
}
|
||||
@@ -1,20 +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: ['history'],
|
||||
body: {
|
||||
type: ['object', 'string'],
|
||||
properties: {
|
||||
id: {description: 'transaction id', type: 'string'},
|
||||
block_num_hint: {description: 'block number hint', type: 'integer'},
|
||||
},
|
||||
required: ["id"]
|
||||
}
|
||||
});
|
||||
next();
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
import {FastifyInstance, FastifyReply, FastifyRequest} from "fastify";
|
||||
import {timedQuery} from "../../../helpers/functions";
|
||||
|
||||
async function getAbiSnapshot(fastify: FastifyInstance, request: FastifyRequest) {
|
||||
|
||||
const response = {
|
||||
block_num: null
|
||||
};
|
||||
|
||||
const query: any = request.query;
|
||||
|
||||
const code = query.contract;
|
||||
const block = query.block;
|
||||
const should_fetch = query.fetch;
|
||||
|
||||
const mustArray = [];
|
||||
|
||||
mustArray.push({"term": {"account": code}});
|
||||
|
||||
if (block) {
|
||||
mustArray.push({"range": {"block": {"lte": parseInt(block)}}});
|
||||
}
|
||||
|
||||
const results = await fastify.elastic.search({
|
||||
index: fastify.manager.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;
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
export function getAbiSnapshotHandler(fastify: FastifyInstance, route: string) {
|
||||
return async (request: FastifyRequest, reply: FastifyReply) => {
|
||||
reply.send(await timedQuery(getAbiSnapshot, fastify, request, route));
|
||||
}
|
||||
}
|
||||
@@ -1,160 +0,0 @@
|
||||
import {FastifyInstance, FastifySchema} from "fastify";
|
||||
import {getActionsHandler} from "./get_actions";
|
||||
import {addApiRoute, extendQueryStringSchema, extendResponseSchema, getRouteName} from "../../../helpers/functions";
|
||||
|
||||
export const getActionResponseSchema = {
|
||||
"@timestamp": {type: "string"},
|
||||
"timestamp": {type: "string"},
|
||||
"block_num": {type: "number"},
|
||||
"block_id": {type: "string"},
|
||||
"trx_id": {type: "string"},
|
||||
"act": {
|
||||
type: 'object',
|
||||
properties: {
|
||||
"account": {type: "string"},
|
||||
"name": {type: "string"},
|
||||
"authorization": {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "object",
|
||||
properties: {
|
||||
"actor": {type: "string"},
|
||||
"permission": {type: "string"},
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
additionalProperties: true
|
||||
},
|
||||
"receipts": {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "object",
|
||||
properties: {
|
||||
"receiver": {type: "string"},
|
||||
"global_sequence": {type: "number"},
|
||||
"recv_sequence": {type: "number"},
|
||||
"auth_sequence": {
|
||||
type: "array",
|
||||
items: {
|
||||
type: "object",
|
||||
properties: {
|
||||
"account": {type: "string"},
|
||||
"sequence": {type: "number"},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"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"},
|
||||
"producer": {type: "string"},
|
||||
"parent": {type: "number"},
|
||||
"action_ordinal": {type: 'number'},
|
||||
"creator_action_ordinal": {type: 'number'},
|
||||
"signatures": {type: "array", items: {type: 'string'}}
|
||||
};
|
||||
|
||||
export default function (fastify: FastifyInstance, opts: any, next) {
|
||||
const schema: FastifySchema = {
|
||||
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: ['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'
|
||||
},
|
||||
"hot_only": {
|
||||
description: 'search only the latest hot index',
|
||||
type: 'boolean'
|
||||
},
|
||||
"noBinary": {
|
||||
description: "exclude large binary data",
|
||||
type: 'boolean'
|
||||
},
|
||||
"checkLib": {
|
||||
description: "perform reversibility check",
|
||||
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: getActionResponseSchema
|
||||
}
|
||||
}
|
||||
})
|
||||
};
|
||||
addApiRoute(
|
||||
fastify,
|
||||
'GET',
|
||||
getRouteName(__filename),
|
||||
getActionsHandler,
|
||||
schema
|
||||
);
|
||||
next();
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
import {FastifyInstance, FastifyReply, FastifyRequest} from "fastify";
|
||||
import {timedQuery} from "../../../helpers/functions";
|
||||
import {getSkipLimit} from "../get_actions/functions";
|
||||
|
||||
async function getCreatedAccounts(fastify: FastifyInstance, request: FastifyRequest) {
|
||||
|
||||
|
||||
const query: any = request.query;
|
||||
const {skip, limit} = getSkipLimit(query);
|
||||
const maxActions = fastify.manager.config.api.limits.get_created_accounts;
|
||||
const results = await fastify.elastic.search({
|
||||
"index": fastify.manager.chain + '-action-*',
|
||||
"from": skip || 0,
|
||||
"size": (limit > maxActions ? maxActions : limit) || 100,
|
||||
"body": {
|
||||
"query": {
|
||||
"bool": {
|
||||
must: [
|
||||
{term: {"act.authorization.actor": 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);
|
||||
}
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
export function getCreatedAccountsHandler(fastify: FastifyInstance, route: string) {
|
||||
return async (request: FastifyRequest, reply: FastifyReply) => {
|
||||
reply.send(await timedQuery(getCreatedAccounts, fastify, request, route));
|
||||
}
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
import {FastifyInstance, FastifyReply, FastifyRequest} from "fastify";
|
||||
import {timedQuery} from "../../../helpers/functions";
|
||||
import {createHash} from "crypto";
|
||||
import {base58ToBinary, binaryToBase58} from "eosjs/dist/eosjs-numeric";
|
||||
import {Search} from "@elastic/elasticsearch/api/requestParams";
|
||||
|
||||
function convertToLegacyKey(block_signing_key: string) {
|
||||
if (block_signing_key.startsWith("PUB_K1_")) {
|
||||
const buf = base58ToBinary(37, block_signing_key.substr(7));
|
||||
const data = buf.slice(0, buf.length - 4);
|
||||
const merged = Buffer.concat([
|
||||
data,
|
||||
createHash('ripemd160')
|
||||
.update(data)
|
||||
.digest()
|
||||
.slice(0, 4)
|
||||
]);
|
||||
return "EOS" + binaryToBase58(merged);
|
||||
} else {
|
||||
return block_signing_key;
|
||||
}
|
||||
}
|
||||
|
||||
async function getSchedule(fastify: FastifyInstance, request: FastifyRequest) {
|
||||
const query: any = request.query;
|
||||
const response: any = {
|
||||
producers: []
|
||||
};
|
||||
if (query.mode === 'activated') {
|
||||
const searchParams: Search<any> = {
|
||||
track_total_hits: true,
|
||||
index: fastify.manager.chain + "-block-*",
|
||||
size: 1,
|
||||
body: {
|
||||
query: {bool: {must: []}},
|
||||
sort: {block_num: query.sort || "desc"}
|
||||
}
|
||||
};
|
||||
if (query.version) {
|
||||
searchParams.body.query.bool.must.push({"term": {"new_producers.version": {"value": query.version}}});
|
||||
} else {
|
||||
searchParams.body.query.bool.must.push({"exists": {"field": "new_producers.version"}});
|
||||
}
|
||||
const apiResponse = await fastify.elastic.search(searchParams);
|
||||
const results = apiResponse.body.hits.hits;
|
||||
if (results && results.length > 0) {
|
||||
response.timestamp = results[0]._source["@timestamp"];
|
||||
response.block_num = results[0]._source.block_num;
|
||||
response.version = results[0]._source.new_producers.version;
|
||||
response.producers = results[0]._source.new_producers.producers.map(prod => {
|
||||
return {
|
||||
...prod,
|
||||
legacy_key: convertToLegacyKey(prod.block_signing_key)
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// default "proposed" mode
|
||||
const searchParams: Search<any> = {
|
||||
track_total_hits: true,
|
||||
index: fastify.manager.chain + "-schedule-*",
|
||||
size: 1,
|
||||
body: {
|
||||
query: {bool: {must: []}},
|
||||
sort: {version: query.sort || "desc"}
|
||||
}
|
||||
};
|
||||
if (query.version) {
|
||||
searchParams.body.query.bool.must.push({"term": {"version": {"value": query.version}}});
|
||||
} else {
|
||||
searchParams.body.query.bool.must.push({"exists": {"field": "version"}});
|
||||
}
|
||||
if (query.producer) {
|
||||
searchParams.body.query.bool.must.push({"term": {"producers.name": {"value": query.producer}}});
|
||||
}
|
||||
if (query.key) {
|
||||
searchParams.body.query.bool.must.push({"term": {"producers.keys": {"value": query.key}}});
|
||||
}
|
||||
const apiResponse = await fastify.elastic.search(searchParams);
|
||||
const results = apiResponse.body.hits.hits;
|
||||
if (results && results.length > 0) {
|
||||
response.timestamp = results[0]._source["@timestamp"];
|
||||
response.proposal_block_num = results[0]._source.block_num;
|
||||
response.version = results[0]._source.version;
|
||||
response.producers = results[0]._source.producers;
|
||||
// sort producers by name
|
||||
// response.producers.sort((a, b) => {
|
||||
// if (a.name < b.name) {
|
||||
// return -1;
|
||||
// }
|
||||
// if (a.name > b.name) {
|
||||
// return 1;
|
||||
// }
|
||||
// return 0;
|
||||
// });
|
||||
}
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
export function getScheduleHandler(fastify: FastifyInstance, route: string) {
|
||||
return async (request: FastifyRequest, reply: FastifyReply) => {
|
||||
reply.send(await timedQuery(getSchedule, fastify, request, route));
|
||||
}
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
import {FastifyInstance, FastifyReply, FastifyRequest} from "fastify";
|
||||
import {mergeDeltaMeta, timedQuery} from "../../../helpers/functions";
|
||||
|
||||
async function getTableState(fastify: FastifyInstance, request: FastifyRequest) {
|
||||
const query: any = request.query;
|
||||
const response = {
|
||||
...query,
|
||||
results: [],
|
||||
next_key: null
|
||||
};
|
||||
const mustArray: any[] = [
|
||||
{"term": {"code": query.code}},
|
||||
{"term": {"table": query.table}}
|
||||
];
|
||||
if (query.block_num) {
|
||||
mustArray.push({"range": {"block_num": {"lte": query.block_num}}});
|
||||
}
|
||||
let after_key = "";
|
||||
if (query.after_key) {
|
||||
after_key = query.after_key;
|
||||
}
|
||||
const results = await fastify.elastic.search({
|
||||
index: fastify.manager.chain + '-delta-*',
|
||||
body: {
|
||||
"query": {
|
||||
"bool": {
|
||||
"must": mustArray
|
||||
}
|
||||
},
|
||||
"size": 0,
|
||||
"sort": [
|
||||
{"block_num": "desc"},
|
||||
{"primary_key": "desc"}
|
||||
],
|
||||
"aggs": {
|
||||
"scope_buckets": {
|
||||
"composite": {
|
||||
"size": 25,
|
||||
"after": {
|
||||
"scope_pk": after_key
|
||||
},
|
||||
"sources": [
|
||||
{
|
||||
"scope_pk": {
|
||||
"terms": {
|
||||
"script": {
|
||||
"source": "return doc['scope'].value + '-' + doc['primary_key'].value",
|
||||
"lang": "painless"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"aggs": {
|
||||
"last_doc": {
|
||||
"top_hits": {
|
||||
"size": 1,
|
||||
"sort": [{"block_num": "desc"}],
|
||||
"_source": {
|
||||
"excludes": ["code"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
const scope_buckets = results.body.aggregations.scope_buckets;
|
||||
if (scope_buckets && scope_buckets.buckets.length > 0) {
|
||||
if (scope_buckets.after_key) {
|
||||
response.next_key = scope_buckets.after_key.scope_pk;
|
||||
}
|
||||
response.results = scope_buckets.buckets.map(bucket => {
|
||||
const row = mergeDeltaMeta(bucket.last_doc.hits.hits[0]._source);
|
||||
delete row.table;
|
||||
return row;
|
||||
});
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
export function getTableStateHandler(fastify: FastifyInstance, route: string) {
|
||||
return async (request: FastifyRequest, reply: FastifyReply) => {
|
||||
reply.send(await timedQuery(getTableState, fastify, request, route));
|
||||
}
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
import {FastifyInstance, FastifyReply, FastifyRequest} from "fastify";
|
||||
import {mergeActionMeta, timedQuery} from "../../../helpers/functions";
|
||||
import {GetInfoResult} from "eosjs/dist/eosjs-rpc-interfaces";
|
||||
|
||||
async function getTransaction(fastify: FastifyInstance, request: FastifyRequest) {
|
||||
const redis = fastify.redis;
|
||||
const query: any = request.query;
|
||||
const trxId = query.id.toLowerCase();
|
||||
const conf = fastify.manager.config;
|
||||
const cachedData = await redis.hgetall('trx_' + trxId);
|
||||
const response = {
|
||||
query_time_ms: undefined,
|
||||
executed: false,
|
||||
cached: undefined,
|
||||
cache_expires_in: undefined,
|
||||
trx_id: query.id,
|
||||
lib: undefined,
|
||||
cached_lib: false,
|
||||
actions: undefined,
|
||||
generated: undefined,
|
||||
error: undefined
|
||||
};
|
||||
let hits;
|
||||
|
||||
// build get_info request with caching
|
||||
const $getInfo = new Promise<GetInfoResult>(resolve => {
|
||||
const key = `${fastify.manager.chain}_get_info`;
|
||||
fastify.redis.get(key).then(value => {
|
||||
if (value) {
|
||||
response.cached_lib = true;
|
||||
resolve(JSON.parse(value));
|
||||
} else {
|
||||
fastify.eosjs.rpc.get_info().then(value1 => {
|
||||
fastify.redis.set(key, JSON.stringify(value1), 'EX', 6);
|
||||
response.cached_lib = false;
|
||||
resolve(value1);
|
||||
}).catch((reason) => {
|
||||
console.log(reason);
|
||||
response.error = 'failed to get last_irreversible_block_num'
|
||||
resolve(null);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// reconstruct hits from cached data
|
||||
if (cachedData && Object.keys(cachedData).length > 0) {
|
||||
const gsArr = [];
|
||||
for (let cachedDataKey in cachedData) {
|
||||
gsArr.push(cachedData[cachedDataKey]);
|
||||
}
|
||||
gsArr.sort((a, b) => {
|
||||
return a.global_sequence - b.global_sequence;
|
||||
});
|
||||
hits = gsArr.map(value => {
|
||||
return {
|
||||
_source: JSON.parse(value)
|
||||
};
|
||||
});
|
||||
const promiseResults = await Promise.all([
|
||||
redis.ttl('trx_' + trxId),
|
||||
$getInfo
|
||||
]);
|
||||
response.cache_expires_in = promiseResults[0];
|
||||
response.lib = promiseResults[1].last_irreversible_block_num;
|
||||
}
|
||||
|
||||
// search on ES if cache is not present
|
||||
if (!hits) {
|
||||
const _size = conf.api.limits.get_trx_actions || 100;
|
||||
const blockHint = parseInt(query.block_hint, 10);
|
||||
let indexPattern = '';
|
||||
if (blockHint) {
|
||||
const idxPart = Math.ceil(blockHint / conf.settings.index_partition_size).toString().padStart(6, '0');
|
||||
indexPattern = fastify.manager.chain + `-action-${conf.settings.index_version}-${idxPart}`;
|
||||
} else {
|
||||
indexPattern = fastify.manager.chain + '-action-*';
|
||||
}
|
||||
let pResults;
|
||||
try {
|
||||
|
||||
// build search request
|
||||
const $search = fastify.elastic.search({
|
||||
index: indexPattern,
|
||||
size: _size,
|
||||
body: {
|
||||
query: {bool: {must: [{term: {trx_id: trxId}}]}},
|
||||
sort: {global_sequence: "asc"}
|
||||
}
|
||||
});
|
||||
|
||||
// execute in parallel
|
||||
pResults = await Promise.all([$getInfo, $search]);
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
if (e.meta.statusCode === 404) {
|
||||
response.error = 'no data near block_hint'
|
||||
return response;
|
||||
}
|
||||
}
|
||||
hits = pResults[1]['body']['hits']['hits'];
|
||||
response.lib = pResults[0].last_irreversible_block_num;
|
||||
}
|
||||
|
||||
if (hits.length > 0) {
|
||||
let highestBlockNum = 0;
|
||||
for (let action of hits) {
|
||||
if (action._source.block_num > highestBlockNum) {
|
||||
highestBlockNum = action._source.block_num;
|
||||
}
|
||||
}
|
||||
response.actions = [];
|
||||
for (let action of hits) {
|
||||
if (action._source.block_num === highestBlockNum) {
|
||||
mergeActionMeta(action._source);
|
||||
response.actions.push(action._source);
|
||||
}
|
||||
}
|
||||
response.executed = true;
|
||||
}
|
||||
return response;
|
||||
}
|
||||
|
||||
export function getTransactionHandler(fastify: FastifyInstance, route: string) {
|
||||
return async (request: FastifyRequest, reply: FastifyReply) => {
|
||||
reply.send(await timedQuery(getTransaction, fastify, request, route));
|
||||
}
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
import {FastifyInstance, FastifyReply, FastifyRequest} from "fastify";
|
||||
import {mergeActionMeta, timedQuery} from "../../../helpers/functions";
|
||||
|
||||
async function getTransaction(fastify: FastifyInstance, request: FastifyRequest) {
|
||||
const _size = fastify.manager.config.api.limits.get_trx_actions || 100;
|
||||
const query: any = request.query;
|
||||
|
||||
let indexPattern = fastify.manager.chain + '-action-*';
|
||||
if (query.hot_only) {
|
||||
indexPattern = fastify.manager.chain + '-action';
|
||||
}
|
||||
|
||||
const pResults = await Promise.all([
|
||||
fastify.eosjs.rpc.get_info(),
|
||||
fastify.elastic.search({
|
||||
index: indexPattern,
|
||||
size: _size,
|
||||
body: {
|
||||
query: {
|
||||
bool: {
|
||||
must: [
|
||||
{term: {trx_id: query.id.toLowerCase()}}
|
||||
]
|
||||
}
|
||||
},
|
||||
sort: {
|
||||
global_sequence: "asc"
|
||||
}
|
||||
}
|
||||
}),
|
||||
fastify.elastic.search({
|
||||
index: fastify.manager.chain + '-gentrx-*',
|
||||
size: _size,
|
||||
body: {
|
||||
query: {
|
||||
bool: {
|
||||
must: [
|
||||
{term: {trx_id: query.id.toLowerCase()}}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
]);
|
||||
|
||||
const results = pResults[1];
|
||||
const genTrxRes = pResults[2];
|
||||
|
||||
const response = {
|
||||
"executed": false,
|
||||
"hot_only": false,
|
||||
"trx_id": query.id,
|
||||
"lib": pResults[0].last_irreversible_block_num,
|
||||
"actions": [],
|
||||
"generated": undefined
|
||||
};
|
||||
|
||||
if (query.hot_only) {
|
||||
response.hot_only = true;
|
||||
}
|
||||
|
||||
const hits = results['body']['hits']['hits'];
|
||||
|
||||
if (hits.length > 0) {
|
||||
|
||||
// const producers = {};
|
||||
// for (let hit of hits) {
|
||||
// if (hit._source.producer) {
|
||||
// if (producers[hit._source.producer]) {
|
||||
// producers[hit._source.producer]++;
|
||||
// } else {
|
||||
// producers[hit._source.producer] = 1;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// let useBlockNumber;
|
||||
// if (Object.keys(producers).length > 1) {
|
||||
// // multiple producers of the same tx id, forked actions are present, attempt to clean-up
|
||||
// let trueProd = '';
|
||||
// let highestActCount = 0;
|
||||
// for (const prod in producers) {
|
||||
// if (producers.hasOwnProperty(prod)) {
|
||||
// if(producers[prod] === highestActCount) {
|
||||
// useBlockNumber = true;
|
||||
// } else if (producers[prod] > highestActCount) {
|
||||
// highestActCount = producers[prod];
|
||||
// trueProd = prod;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
let highestBlockNum = 0;
|
||||
for (let action of hits) {
|
||||
if (action._source.block_num > highestBlockNum) {
|
||||
highestBlockNum = action._source.block_num;
|
||||
}
|
||||
}
|
||||
|
||||
for (let action of hits) {
|
||||
if (action._source.block_num === highestBlockNum) {
|
||||
action = action._source;
|
||||
mergeActionMeta(action);
|
||||
response.actions.push(action);
|
||||
}
|
||||
}
|
||||
|
||||
response.executed = true;
|
||||
}
|
||||
|
||||
const hits2 = genTrxRes['body']['hits']['hits'];
|
||||
|
||||
if (hits2 && hits2.length > 0) {
|
||||
if (hits2[0]._source['@timestamp']) {
|
||||
hits2[0]._source['timestamp'] = hits2[0]._source['@timestamp'];
|
||||
delete hits2[0]._source['@timestamp'];
|
||||
}
|
||||
response.generated = hits2[0]._source;
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
export function getTransactionHandler(fastify: FastifyInstance, route: string) {
|
||||
return async (request: FastifyRequest, reply: FastifyReply) => {
|
||||
reply.send(await timedQuery(getTransaction, fastify, request, route));
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
import {FastifyInstance} from "fastify";
|
||||
import {getTransactionHandler} from "./get_transaction_legacy";
|
||||
import {addApiRoute, getRouteName} from "../../../helpers/functions";
|
||||
|
||||
export default function (fastify: FastifyInstance, opts: any, next) {
|
||||
const schema = {
|
||||
description: 'get all actions belonging to the same transaction',
|
||||
summary: 'get transaction by id',
|
||||
tags: ['history'],
|
||||
querystring: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
"id": {
|
||||
description: 'transaction id',
|
||||
type: 'string'
|
||||
}
|
||||
},
|
||||
required: ["id"]
|
||||
}
|
||||
};
|
||||
addApiRoute(
|
||||
fastify,
|
||||
'GET',
|
||||
getRouteName(__filename),
|
||||
getTransactionHandler,
|
||||
schema
|
||||
);
|
||||
next();
|
||||
}
|
||||
@@ -1,139 +0,0 @@
|
||||
import {FastifyInstance, FastifyReply, FastifyRequest} from "fastify";
|
||||
import {timedQuery} from "../../../helpers/functions";
|
||||
import {Numeric} from "eosjs/dist";
|
||||
import {getSkipLimit} from "../../v2-history/get_actions/functions";
|
||||
|
||||
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;
|
||||
if (typeof request.body === 'string' && request.method === 'POST') {
|
||||
request.body = JSON.parse(request.body);
|
||||
}
|
||||
|
||||
const body: any = request.body;
|
||||
const query: any = request.query;
|
||||
|
||||
const {skip, limit} = getSkipLimit(request.query);
|
||||
const maxDocs = fastify.manager.config.api.limits.get_key_accounts ?? 1000;
|
||||
|
||||
const public_Key = request.method === 'POST' ? body.public_key : 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.message);
|
||||
invalidKey();
|
||||
}
|
||||
} else {
|
||||
invalidKey();
|
||||
}
|
||||
|
||||
const response = {
|
||||
account_names: []
|
||||
} as any;
|
||||
|
||||
if (request.method === 'GET' && query.details) {
|
||||
response.permissions = [];
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
const permTableResults = await fastify.elastic.search({
|
||||
index: fastify.manager.chain + '-perm-*',
|
||||
size: (limit > maxDocs ? maxDocs : limit) || 100,
|
||||
from: skip || 0,
|
||||
body: {
|
||||
query: {
|
||||
bool: {
|
||||
must: [
|
||||
{
|
||||
term: {
|
||||
"auth.keys.key.keyword": publicKey
|
||||
}
|
||||
}
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (permTableResults.body.hits.hits.length > 0) {
|
||||
for (const perm of permTableResults.body.hits.hits) {
|
||||
response.account_names.push(perm._source.owner);
|
||||
if (request.method === 'GET' && query.details) {
|
||||
response.permissions.push(perm._source);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
|
||||
if (response.account_names.length > 0) {
|
||||
response.account_names = [...(new Set(response.account_names))];
|
||||
return response;
|
||||
}
|
||||
|
||||
// Fallback to action search
|
||||
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-*',
|
||||
size: (limit > maxDocs ? maxDocs : limit) || 100,
|
||||
from: skip || 0,
|
||||
body: _body
|
||||
});
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
export function getKeyAccountsHandler(fastify: FastifyInstance, route: string) {
|
||||
return async (request: FastifyRequest, reply: FastifyReply) => {
|
||||
reply.send(await timedQuery(getKeyAccounts, fastify, request, route));
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
import {FastifyInstance, FastifyReply, FastifyRequest} from "fastify";
|
||||
import {timedQuery} from "../../../helpers/functions";
|
||||
import {getSkipLimit} from "../../v2-history/get_actions/functions";
|
||||
|
||||
async function getVoters(fastify: FastifyInstance, request: FastifyRequest) {
|
||||
|
||||
const query: any = request.query;
|
||||
const {skip, limit} = getSkipLimit(request.query);
|
||||
|
||||
const response = {
|
||||
voter_count: 0,
|
||||
'voters': []
|
||||
};
|
||||
let queryStruct: any = {
|
||||
"bool": {
|
||||
"must": []
|
||||
}
|
||||
};
|
||||
|
||||
if (query.producer) {
|
||||
for (const bp of query.producer.split(",")) {
|
||||
queryStruct.bool.must.push({"term": {"producers": bp}});
|
||||
}
|
||||
}
|
||||
|
||||
if (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) => {
|
||||
reply.send(await timedQuery(getVoters, fastify, request, route));
|
||||
}
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
import {FastifyInstance, FastifyReply, FastifyRequest} from "fastify";
|
||||
import {timedQuery} from "../../../helpers/functions";
|
||||
|
||||
async function getLastSeq(fastify: FastifyInstance, date: string) {
|
||||
const req = await fastify.elastic.search({
|
||||
index: fastify.manager.chain + '-action-*',
|
||||
body: {
|
||||
"size": 1,
|
||||
"query": {
|
||||
"bool": {
|
||||
"must": [
|
||||
{"range": {"@timestamp": {"lt": date}}}
|
||||
]
|
||||
}
|
||||
},
|
||||
"_source": {
|
||||
"includes": ["global_sequence"]
|
||||
},
|
||||
"sort": [{"global_sequence": "desc"}]
|
||||
}
|
||||
});
|
||||
return req.body.hits.hits[0]._source.global_sequence;
|
||||
}
|
||||
|
||||
async function getTxCount(fastify: FastifyInstance, dateFrom: string, dateTo: string) {
|
||||
const req = await fastify.elastic.count({
|
||||
index: fastify.manager.chain + '-action-*',
|
||||
body: {
|
||||
"query": {
|
||||
"bool": {
|
||||
"must": [
|
||||
{"term": {"creator_action_ordinal": 0}},
|
||||
{"range": {"@timestamp": {"gt": dateFrom, "lt": dateTo}}}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return req.body.count;
|
||||
}
|
||||
|
||||
async function getUniqueActors(fastify: FastifyInstance, dateFrom: string, dateTo: string) {
|
||||
const req = await fastify.elastic.search({
|
||||
index: fastify.manager.chain + '-action-*',
|
||||
size: 0,
|
||||
body: {
|
||||
"aggs": {
|
||||
"unique_actors": {
|
||||
"cardinality": {
|
||||
"field": "act.authorization.actor"
|
||||
}
|
||||
}
|
||||
},
|
||||
"query": {
|
||||
"bool": {
|
||||
"filter": [{"range": {"@timestamp": {"gt": dateFrom, "lt": dateTo}}}]
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return req.body.aggregations.unique_actors.value;
|
||||
}
|
||||
|
||||
async function getActionUsage(fastify: FastifyInstance, request: FastifyRequest) {
|
||||
const query: any = request.query;
|
||||
let now = new Date();
|
||||
let expiration = 86400;
|
||||
if (query.end_date) {
|
||||
now = new Date(query.end_date);
|
||||
}
|
||||
now.setMinutes(0, 0, 0);
|
||||
let period;
|
||||
if (query.period === '1h') {
|
||||
period = 3600000;
|
||||
} else if (query.period === '24h' || query.period === '1d') {
|
||||
period = 86400000;
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
|
||||
if (!query.end_date) {
|
||||
expiration = Math.floor((period - (Date.now() - now.getTime())) / 1000);
|
||||
}
|
||||
|
||||
const response = {} as any;
|
||||
const periodStart = new Date(now.getTime() - period);
|
||||
const pStart = periodStart.toISOString();
|
||||
const pEnd = now.toISOString();
|
||||
|
||||
const cacheKey = `${fastify.manager.chain}_act_stats_${pStart}_${pEnd}_${query.unique_actors}`;
|
||||
const cachedValue = await fastify.redis.get(cacheKey);
|
||||
if (cachedValue) {
|
||||
const cachedResponse = JSON.parse(cachedValue);
|
||||
cachedResponse.cached = true;
|
||||
cachedResponse.cache_exp = expiration;
|
||||
return cachedResponse;
|
||||
}
|
||||
|
||||
const firstReq = await getLastSeq(fastify, pStart);
|
||||
const lastReq = await getLastSeq(fastify, pEnd);
|
||||
response.action_count = lastReq - firstReq;
|
||||
response.tx_count = await getTxCount(fastify, pStart, pEnd);
|
||||
|
||||
if (query.unique_actors) {
|
||||
response.unique_actors = await getUniqueActors(fastify, pStart, pEnd);
|
||||
}
|
||||
|
||||
response.period = query.period;
|
||||
response.from = pStart;
|
||||
response.to = pEnd;
|
||||
|
||||
await fastify.redis.set(cacheKey, JSON.stringify(response), 'EX', expiration);
|
||||
return response;
|
||||
}
|
||||
|
||||
export function getActionUsageHandler(fastify: FastifyInstance, route: string) {
|
||||
return async (request: FastifyRequest, reply: FastifyReply) => {
|
||||
reply.send(await timedQuery(getActionUsage, fastify, request, route));
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
import {FastifyInstance, FastifyReply, FastifyRequest} from "fastify";
|
||||
import {timedQuery} from "../../../helpers/functions";
|
||||
import {Search} from "@elastic/elasticsearch/api/requestParams";
|
||||
import {applyTimeFilter} from "../../v2-history/get_actions/functions";
|
||||
|
||||
async function getMissedBlocks(fastify: FastifyInstance, request: FastifyRequest) {
|
||||
const query: any = request.query;
|
||||
const response = {
|
||||
stats: {
|
||||
by_producer: {}
|
||||
},
|
||||
events: []
|
||||
};
|
||||
const searchParams: Search<any> = {
|
||||
track_total_hits: true,
|
||||
index: fastify.manager.chain + "-logs-*",
|
||||
size: 100,
|
||||
body: {
|
||||
query: {
|
||||
bool: {
|
||||
must: [
|
||||
{term: {"type": "missed_blocks"}}
|
||||
]
|
||||
}
|
||||
},
|
||||
sort: {
|
||||
"@timestamp": "desc"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let minBlocks = 0;
|
||||
if (query.min_blocks) {
|
||||
minBlocks = parseInt(query.min_blocks);
|
||||
searchParams.body.query.bool.must.push({range: {"missed_blocks.size": {gte: minBlocks}}})
|
||||
}
|
||||
|
||||
if (query.producer) {
|
||||
searchParams.body.query.bool.must.push({term: {"missed_blocks.producer": query.producer}});
|
||||
}
|
||||
|
||||
applyTimeFilter(query, searchParams.body.query);
|
||||
|
||||
const apiResponse = await fastify.elastic.search(searchParams);
|
||||
apiResponse.body.hits.hits.forEach(v => {
|
||||
const ev = v._source;
|
||||
response.events.push({
|
||||
"@timestamp": ev["@timestamp"],
|
||||
...ev.missed_blocks
|
||||
});
|
||||
if (!response.stats.by_producer[ev.missed_blocks.producer]) {
|
||||
response.stats.by_producer[ev.missed_blocks.producer] = ev.missed_blocks.size;
|
||||
} else {
|
||||
response.stats.by_producer[ev.missed_blocks.producer] += ev.missed_blocks.size;
|
||||
}
|
||||
});
|
||||
return response;
|
||||
}
|
||||
|
||||
export function getMissedBlocksHandler(fastify: FastifyInstance, route: string) {
|
||||
return async (request: FastifyRequest, reply: FastifyReply) => {
|
||||
reply.send(await timedQuery(getMissedBlocks, fastify, request, route));
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
import {FastifyInstance, FastifyReply, FastifyRequest} from "fastify";
|
||||
import {timedQuery} from "../../../helpers/functions";
|
||||
|
||||
const percentiles = [1, 5, 25, 50, 75, 95, 99];
|
||||
|
||||
async function getResourceUsage(fastify: FastifyInstance, request: FastifyRequest) {
|
||||
const query: any = request.query;
|
||||
const searchBody: any = {
|
||||
query: {
|
||||
bool: {
|
||||
must: [
|
||||
{term: {"act.account": query.code}},
|
||||
{term: {"act.name": query.action}},
|
||||
{term: {"action_ordinal": {"value": 1}}},
|
||||
{
|
||||
range: {
|
||||
"@timestamp": {
|
||||
gte: "now-2d/d",
|
||||
lt: "now/d"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
track_total_hits: true,
|
||||
size: 0,
|
||||
aggs: {
|
||||
cpu_extended_stats: {extended_stats: {field: "cpu_usage_us"}},
|
||||
net_extended_stats: {extended_stats: {field: "net_usage_words"}},
|
||||
cpu_percentiles: {
|
||||
percentiles: {
|
||||
field: "cpu_usage_us",
|
||||
percents: percentiles
|
||||
}
|
||||
},
|
||||
net_percentiles: {
|
||||
percentiles: {
|
||||
field: "net_usage_words",
|
||||
percents: percentiles
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (request.query['@transfer.to']) {
|
||||
searchBody.query.bool.must.push({term: {"@transfer.to": request.query['@transfer.to']}});
|
||||
}
|
||||
|
||||
const results = await fastify.elastic.search({
|
||||
index: fastify.manager.chain + "-action-*",
|
||||
body: searchBody
|
||||
});
|
||||
if (results.body) {
|
||||
const data = results.body.aggregations;
|
||||
return {
|
||||
cpu: {
|
||||
stats: data.cpu_extended_stats,
|
||||
percentiles: data.cpu_percentiles.values
|
||||
},
|
||||
net: {
|
||||
stats: data.net_extended_stats,
|
||||
percentiles: data.net_percentiles.values
|
||||
}
|
||||
};
|
||||
} else {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
export function getResourceUsageHandler(fastify: FastifyInstance, route: string) {
|
||||
return async (request: FastifyRequest, reply: FastifyReply) => {
|
||||
reply.send(await timedQuery(getResourceUsage, fastify, request, route));
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
import {FastifyInstance, FastifySchema} from "fastify";
|
||||
import {addApiRoute, getRouteName} from "../../../helpers/functions";
|
||||
import {healthHandler} from "./health";
|
||||
|
||||
export default function (fastify: FastifyInstance, opts: any, next) {
|
||||
const schema: FastifySchema = {
|
||||
tags: ['status'],
|
||||
summary: "API Service Health Report"
|
||||
};
|
||||
addApiRoute(
|
||||
fastify,
|
||||
'GET',
|
||||
getRouteName(__filename),
|
||||
healthHandler,
|
||||
schema
|
||||
);
|
||||
next();
|
||||
}
|
||||
@@ -1,292 +0,0 @@
|
||||
import {hLog, sleep} from '../helpers/common_functions';
|
||||
import {Server, Socket} from 'socket.io';
|
||||
import {createAdapter} from 'socket.io-redis';
|
||||
import {io} from 'socket.io-client';
|
||||
import {FastifyInstance} from "fastify";
|
||||
import IORedis from "ioredis";
|
||||
import {App, TemplatedApp} from 'uWebSockets.js';
|
||||
import {streamPastActions, streamPastDeltas} from "./helpers/functions";
|
||||
import {randomUUID} from "crypto";
|
||||
|
||||
export interface StreamDeltasRequest {
|
||||
code: string;
|
||||
table: string;
|
||||
scope: string;
|
||||
payer: string;
|
||||
start_from: number | string;
|
||||
read_until: number | string;
|
||||
}
|
||||
|
||||
export interface RequestFilter {
|
||||
field: string;
|
||||
value: string;
|
||||
}
|
||||
|
||||
export interface StreamActionsRequest {
|
||||
contract: string;
|
||||
account: string;
|
||||
action: string;
|
||||
filters: RequestFilter[];
|
||||
start_from: number | string;
|
||||
read_until: number | string;
|
||||
}
|
||||
|
||||
|
||||
export class SocketManager {
|
||||
|
||||
private io: Server;
|
||||
private relay;
|
||||
relay_restored = true;
|
||||
relay_down = false;
|
||||
private readonly url;
|
||||
private readonly server: FastifyInstance;
|
||||
private readonly uwsApp: TemplatedApp;
|
||||
private readonly chainId: string;
|
||||
private currentBlockNum: number;
|
||||
|
||||
constructor(fastify: FastifyInstance, url, redisOptions) {
|
||||
this.server = fastify;
|
||||
this.url = url;
|
||||
this.uwsApp = App({});
|
||||
|
||||
// WS Server for public access
|
||||
this.io = new Server({
|
||||
transports: ['websocket'],
|
||||
path: '/stream'
|
||||
});
|
||||
|
||||
this.io.attachApp(this.uwsApp);
|
||||
|
||||
this.chainId = this.server.manager.conn.chains[this.server.manager.chain].chain_id
|
||||
hLog(`[SocketManager] chain_id: ${this.chainId}`);
|
||||
const pubClient = new IORedis(redisOptions);
|
||||
const subClient = pubClient.duplicate();
|
||||
this.io.adapter(createAdapter({pubClient, subClient, key: this.chainId}));
|
||||
|
||||
this.io.on('connection', (socket: Socket) => {
|
||||
|
||||
if (socket.handshake.headers['x-forwarded-for']) {
|
||||
hLog(`[socket] ${socket.id} connected via ${socket.handshake.headers['x-forwarded-for']}`);
|
||||
}
|
||||
|
||||
socket.emit('message', {
|
||||
event: 'handshake',
|
||||
chain: fastify.manager.chain,
|
||||
});
|
||||
|
||||
if (this.relay) {
|
||||
this.relay.emit('event', {
|
||||
type: 'client_count',
|
||||
counter: this.io.sockets.sockets.size,
|
||||
});
|
||||
}
|
||||
|
||||
socket.on('delta_stream_request', async (data: StreamDeltasRequest, callback) => {
|
||||
if (typeof callback === 'function' && data) {
|
||||
try {
|
||||
// generate random uuid
|
||||
socket.data.reqUUID = randomUUID();
|
||||
const lastHistoryBlock = await new Promise<number>((resolve) => {
|
||||
// start sending realtime data
|
||||
this.emitToRelay(data, 'delta_request', socket, (emissionResult) => {
|
||||
callback(emissionResult);
|
||||
resolve(emissionResult.currentBlockNum);
|
||||
});
|
||||
});
|
||||
// push history data
|
||||
if (data.start_from) {
|
||||
data.read_until = lastHistoryBlock;
|
||||
console.log('Performing primary scroll request...');
|
||||
let ltb = 0;
|
||||
const hStreamResult = await streamPastDeltas(this.server, socket, data);
|
||||
if (hStreamResult.status === false) {
|
||||
return;
|
||||
} else {
|
||||
ltb = hStreamResult.lastTransmittedBlock;
|
||||
let attempts = 0;
|
||||
await sleep(500);
|
||||
while (ltb > 0 && lastHistoryBlock > ltb && attempts < 3) {
|
||||
attempts++;
|
||||
console.log(`Performing fill request from ${ltb}...`);
|
||||
data.start_from = hStreamResult.lastTransmittedBlock + 1;
|
||||
data.read_until = lastHistoryBlock;
|
||||
const r = await streamPastDeltas(this.server, socket, data);
|
||||
if (r.status === false) {
|
||||
console.log(r);
|
||||
return;
|
||||
} else {
|
||||
ltb = r.lastTransmittedBlock;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('action_stream_request', async (data: StreamActionsRequest, callback) => {
|
||||
if (typeof callback === 'function' && data) {
|
||||
try {
|
||||
// generate random uuid
|
||||
socket.data.reqUUID = randomUUID();
|
||||
const lastHistoryBlock = await new Promise<number>((resolve) => {
|
||||
// start sending realtime data
|
||||
this.emitToRelay(data, 'action_request', socket, (emissionResult) => {
|
||||
callback(emissionResult);
|
||||
resolve(emissionResult.currentBlockNum);
|
||||
});
|
||||
});
|
||||
// push history data
|
||||
if (data.start_from) {
|
||||
data.read_until = lastHistoryBlock;
|
||||
console.log('Performing primary scroll request...');
|
||||
let ltb = 0;
|
||||
const hStreamResult = await streamPastActions(this.server, socket, data);
|
||||
if (hStreamResult.status === false) {
|
||||
return;
|
||||
} else {
|
||||
ltb = hStreamResult.lastTransmittedBlock;
|
||||
let attempts = 0;
|
||||
await sleep(500);
|
||||
while (ltb > 0 && lastHistoryBlock > ltb && attempts < 3) {
|
||||
attempts++;
|
||||
console.log(`Performing fill request from ${hStreamResult.lastTransmittedBlock}...`);
|
||||
data.start_from = hStreamResult.lastTransmittedBlock + 1;
|
||||
data.read_until = lastHistoryBlock;
|
||||
const r = await streamPastActions(this.server, socket, data);
|
||||
if (r.status === false) {
|
||||
console.log(r);
|
||||
return;
|
||||
} else {
|
||||
ltb = r.lastTransmittedBlock;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
socket.on('disconnect', (reason) => {
|
||||
hLog(`[socket] ${socket.id} disconnected - ${reason}`);
|
||||
this.relay.emit('event', {
|
||||
type: 'client_disconnected',
|
||||
id: socket.id,
|
||||
reason,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
try {
|
||||
const port = this.server.manager.config.api.stream_port || 1234;
|
||||
this.uwsApp.listen(port, () => {
|
||||
hLog(`Socket.IO via uWS started on port ${port}`);
|
||||
});
|
||||
} catch (e) {
|
||||
hLog(e.message);
|
||||
}
|
||||
|
||||
hLog('Websocket manager loaded!');
|
||||
}
|
||||
|
||||
/*
|
||||
WS Relay will connect to the indexer
|
||||
*/
|
||||
startRelay() {
|
||||
hLog(`starting relay - ${this.url}`);
|
||||
this.relay = io(this.url, {path: '/router'});
|
||||
|
||||
this.relay.on('connect', () => {
|
||||
hLog('Relay Connected!');
|
||||
if (this.relay_down) {
|
||||
this.relay_restored = true;
|
||||
this.relay_down = false;
|
||||
this.io.emit('status', 'relay_restored');
|
||||
}
|
||||
});
|
||||
|
||||
this.relay.on('disconnect', () => {
|
||||
hLog('Relay disconnected!');
|
||||
this.io.emit('status', 'relay_down');
|
||||
this.relay_down = true;
|
||||
this.relay_restored = false;
|
||||
});
|
||||
|
||||
this.relay.on('delta', (traceData) => {
|
||||
this.emitToClient(traceData, 'delta_trace');
|
||||
});
|
||||
|
||||
this.relay.on('trace', (traceData) => {
|
||||
this.emitToClient(traceData, 'action_trace');
|
||||
});
|
||||
|
||||
this.relay.on('block', (blockData) => {
|
||||
try {
|
||||
// const decodedBlock = JSON.parse(blockData.content.toString());
|
||||
// console.log(blockData.serverTime, blockData.blockNum, decodedBlock);
|
||||
this.currentBlockNum = blockData.blockNum;
|
||||
} catch (e) {
|
||||
hLog(`Failed to decode incoming live block ${blockData.blockNum}: ${e.message}`);
|
||||
}
|
||||
});
|
||||
|
||||
this.addRelayForwarding('lib_update');
|
||||
|
||||
this.addRelayForwarding('fork_event');
|
||||
|
||||
// // Relay LIB info to clients;
|
||||
// this.relay.on('lib_update', (data) => {
|
||||
// if (this.server.manager.conn.chains[this.server.manager.chain].chain_id === data.chain_id) {
|
||||
// this.io.emit('lib_update', data);
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// // Relay fork info to clients;
|
||||
// this.relay.on('fork_event', (data) => {
|
||||
// if (this.server.manager.conn.chains[this.server.manager.chain].chain_id === data.chain_id) {
|
||||
// this.io.emit('fork_event', data);
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
// Relay events to clients
|
||||
addRelayForwarding(event: string) {
|
||||
this.relay.on(event, (data: any) => {
|
||||
if (data.chain_id && this.chainId === data.chain_id) {
|
||||
this.io.emit(event, data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
emitToClient(traceData, type) {
|
||||
if (this.io.sockets.sockets.has(traceData.client)) {
|
||||
this.io.sockets.sockets.get(traceData.client).emit('message', {
|
||||
type: type,
|
||||
reqUUID: traceData.req,
|
||||
mode: 'live',
|
||||
message: traceData.message,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
emitToRelay(data, type, socket, callback) {
|
||||
if (this.relay.connected) {
|
||||
this.relay.emit('event', {
|
||||
reqUUID: socket.data.reqUUID,
|
||||
type: type,
|
||||
client_socket: socket.id,
|
||||
request: data,
|
||||
}, (response) => {
|
||||
response['reqUUID'] = socket.data.reqUUID;
|
||||
response['currentBlockNum'] = this.currentBlockNum;
|
||||
callback(response);
|
||||
});
|
||||
} else {
|
||||
callback('STREAMING_OFFLINE');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,9 +6,6 @@
|
||||
"chain_name": "EXAMPLE Chain",
|
||||
"server_addr": "127.0.0.1",
|
||||
"server_port": 7000,
|
||||
"stream_port": 1234,
|
||||
"stream_scroll_limit": -1,
|
||||
"stream_scroll_batch": 500,
|
||||
"server_name": "127.0.0.1:7000",
|
||||
"provider_name": "Example Provider",
|
||||
"provider_url": "https://example.com",
|
||||
@@ -65,7 +62,7 @@
|
||||
"preview": false,
|
||||
"chain": "eos",
|
||||
"eosio_alias": "eosio",
|
||||
"parser": "3.2",
|
||||
"parser": "1.8",
|
||||
"auto_stop": 0,
|
||||
"index_version": "v1",
|
||||
"debug": false,
|
||||
@@ -79,7 +76,7 @@
|
||||
"auto_mode_switch": false,
|
||||
"hot_warm_policy": false,
|
||||
"custom_policy": "",
|
||||
"use_global_agent": false,
|
||||
"bypass_index_map": false,
|
||||
"index_partition_size": 10000000,
|
||||
"es_replicas": 0
|
||||
},
|
||||
@@ -122,7 +119,7 @@
|
||||
"voters": true
|
||||
},
|
||||
"index_deltas": true,
|
||||
"index_transfer_memo": true,
|
||||
"index_transfer_memo": false,
|
||||
"index_all_deltas": true,
|
||||
"deferred_trx": false,
|
||||
"failed_trx": false,
|
||||
@@ -3,13 +3,13 @@
|
||||
"host": "127.0.0.1:5672",
|
||||
"api": "127.0.0.1:15672",
|
||||
"protocol": "http",
|
||||
"user": "username",
|
||||
"pass": "password",
|
||||
"user": "guest",
|
||||
"pass": "guest",
|
||||
"vhost": "hyperion",
|
||||
"frameMax": "0x10000"
|
||||
},
|
||||
"elasticsearch": {
|
||||
"protocol": "http",
|
||||
"protocol": "https",
|
||||
"host": "127.0.0.1:9200",
|
||||
"ingest_nodes": [
|
||||
"127.0.0.1:9200"
|
||||
@@ -19,17 +19,18 @@
|
||||
},
|
||||
"redis": {
|
||||
"host": "127.0.0.1",
|
||||
"port": "6379"
|
||||
"port": 6379
|
||||
},
|
||||
"chains": {
|
||||
"eos": {
|
||||
"name": "EOS Mainnet",
|
||||
"chain_id": "aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906",
|
||||
"http": "http://127.0.0.1:8888",
|
||||
"ship": "ws://127.0.0.1:8080",
|
||||
"WS_ROUTER_HOST": "127.0.0.1",
|
||||
"ship": [
|
||||
"ws://127.0.0.1:8080"
|
||||
],
|
||||
"WS_ROUTER_PORT": 7001,
|
||||
"control_port": 7002
|
||||
"WS_ROUTER_HOST": "127.0.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
import {debugLog, hLog} from "../helpers/common_functions";
|
||||
import got, {HTTPError} from "got";
|
||||
import {connect, Connection} from 'amqplib';
|
||||
|
||||
export async function createConnection(config): Promise<Connection> {
|
||||
try {
|
||||
const amqp_url = getAmpqUrl(config);
|
||||
const conn: Connection = await connect(amqp_url);
|
||||
debugLog("[AMQP] connection established");
|
||||
return conn;
|
||||
} catch (e) {
|
||||
hLog("[AMQP] failed to connect!");
|
||||
hLog(e.message);
|
||||
await new Promise(resolve => setTimeout(resolve, 5000));
|
||||
return await createConnection(config);
|
||||
}
|
||||
}
|
||||
|
||||
export function getAmpqUrl(config): string {
|
||||
let frameMaxValue = '0x10000';
|
||||
if (config.frameMax) {
|
||||
frameMaxValue = config.frameMax;
|
||||
}
|
||||
const u = encodeURIComponent(config.user);
|
||||
const p = encodeURIComponent(config.pass);
|
||||
const v = encodeURIComponent(config.vhost)
|
||||
return `amqp://${u}:${p}@${config.host}/${v}?frameMax=${frameMaxValue}`;
|
||||
}
|
||||
|
||||
|
||||
async function createChannels(connection) {
|
||||
try {
|
||||
const channel = await connection.createChannel();
|
||||
const confirmChannel = await connection.createConfirmChannel();
|
||||
return [channel, confirmChannel];
|
||||
} catch (e) {
|
||||
hLog("[AMQP] failed to create channels");
|
||||
hLog(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function amqpConnect(onReconnect, config, onClose) {
|
||||
let connection = await createConnection(config);
|
||||
if (connection) {
|
||||
const channels = await createChannels(connection);
|
||||
if (channels) {
|
||||
connection.on('error', (err) => {
|
||||
hLog(err.message);
|
||||
});
|
||||
connection.on('close', () => {
|
||||
hLog('Connection closed!');
|
||||
onClose();
|
||||
setTimeout(async () => {
|
||||
hLog('Retrying in 5 seconds...');
|
||||
const _channels = await amqpConnect(onReconnect, config, onClose);
|
||||
onReconnect(_channels);
|
||||
return _channels;
|
||||
}, 5000);
|
||||
});
|
||||
return channels;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function checkQueueSize(q_name, config) {
|
||||
try {
|
||||
const v = encodeURIComponent(config.vhost);
|
||||
const apiUrl = `${config.protocol}://${config.api}/api/queues/${v}/${encodeURIComponent(q_name)}`;
|
||||
const opts = {
|
||||
username: config.user,
|
||||
password: config.pass
|
||||
};
|
||||
const data = await got.get(apiUrl, opts).json() as any;
|
||||
return data.messages;
|
||||
} catch (e) {
|
||||
hLog(`[WARNING] Checking queue size failed! - ${e.message}`);
|
||||
if (e.response && e.response.body) {
|
||||
if (e instanceof HTTPError) {
|
||||
hLog(e.response.body);
|
||||
} else {
|
||||
hLog(JSON.stringify(e.response.body, null, 2));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
import {debugLog, hLog} from "../helpers/common_functions";
|
||||
|
||||
import WebSocket from 'ws';
|
||||
|
||||
export class StateHistorySocket {
|
||||
private ws;
|
||||
private readonly shipUrl;
|
||||
private readonly max_payload_mb;
|
||||
retryOnDisconnect = true;
|
||||
connected = false;
|
||||
|
||||
constructor(ship_url, max_payload_mb) {
|
||||
this.shipUrl = ship_url;
|
||||
if (max_payload_mb) {
|
||||
this.max_payload_mb = max_payload_mb;
|
||||
} else {
|
||||
this.max_payload_mb = 256;
|
||||
}
|
||||
}
|
||||
|
||||
connect(onMessage, onDisconnect, onError, onConnected) {
|
||||
debugLog(`Connecting to ${this.shipUrl}...`);
|
||||
this.ws = new WebSocket(this.shipUrl, {
|
||||
perMessageDeflate: false,
|
||||
maxPayload: this.max_payload_mb * 1024 * 1024,
|
||||
});
|
||||
this.ws.on('open', () => {
|
||||
this.connected = true;
|
||||
hLog('Websocket connected!');
|
||||
if (onConnected) {
|
||||
onConnected();
|
||||
}
|
||||
});
|
||||
this.ws.on('message', (data) => onMessage(data));
|
||||
this.ws.on('close', () => {
|
||||
this.connected = false;
|
||||
hLog('Websocket disconnected!');
|
||||
if(this.retryOnDisconnect) {
|
||||
onDisconnect();
|
||||
}
|
||||
});
|
||||
this.ws.on('error', (err) => {
|
||||
hLog(`${this.shipUrl} :: ${err.message}`);
|
||||
});
|
||||
}
|
||||
|
||||
close(graceful: boolean) {
|
||||
if(graceful) {
|
||||
this.retryOnDisconnect = false;
|
||||
}
|
||||
this.ws.close();
|
||||
}
|
||||
|
||||
send(payload) {
|
||||
this.ws.send(payload);
|
||||
}
|
||||
}
|
||||
@@ -1,103 +0,0 @@
|
||||
import {IlmPutLifecycle} from "@elastic/elasticsearch/api/requestParams";
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
export const ILPs: IlmPutLifecycle[] = [
|
||||
{
|
||||
policy: "hyperion-rollover",
|
||||
body: {
|
||||
"policy": {
|
||||
"phases": {
|
||||
"hot": {
|
||||
"min_age": "0ms",
|
||||
"actions": {
|
||||
"rollover": {
|
||||
"max_size": "200gb",
|
||||
"max_age": "60d",
|
||||
"max_docs": 100000000
|
||||
},
|
||||
"set_priority": {
|
||||
"priority": 50
|
||||
}
|
||||
}
|
||||
},
|
||||
"warm": {
|
||||
"min_age": "2d",
|
||||
"actions": {
|
||||
"allocate": {
|
||||
"exclude": {
|
||||
"data": "hot"
|
||||
}
|
||||
},
|
||||
"set_priority": {
|
||||
"priority": 25
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
policy: "50G30D",
|
||||
body: {
|
||||
policy: {
|
||||
phases: {
|
||||
hot: {
|
||||
min_age: "0ms",
|
||||
actions: {
|
||||
rollover: {
|
||||
max_age: "30d",
|
||||
max_size: "50gb"
|
||||
},
|
||||
set_priority: {
|
||||
priority: 100
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
policy: "10G30D",
|
||||
body: {
|
||||
policy: {
|
||||
phases: {
|
||||
hot: {
|
||||
min_age: "0ms",
|
||||
actions: {
|
||||
rollover: {
|
||||
max_age: "30d",
|
||||
max_size: "10gb",
|
||||
max_docs: 100000000
|
||||
},
|
||||
set_priority: {
|
||||
priority: 100
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
policy: "200G",
|
||||
body: {
|
||||
policy: {
|
||||
phases: {
|
||||
hot: {
|
||||
min_age: "0ms",
|
||||
actions: {
|
||||
rollover: {
|
||||
max_size: "200gb"
|
||||
},
|
||||
set_priority: {
|
||||
priority: 100
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
@@ -1,545 +0,0 @@
|
||||
import {ConfigurationModule} from "../modules/config";
|
||||
|
||||
const shards = 2;
|
||||
const refresh = "1s";
|
||||
|
||||
export * from './index-lifecycle-policies';
|
||||
|
||||
// LZ4 Compression
|
||||
// const compression = 'default';
|
||||
// DEFLATE
|
||||
const compression = "best_compression";
|
||||
|
||||
const cm = new ConfigurationModule();
|
||||
const chain = cm.config.settings.chain;
|
||||
|
||||
// update number of replicas if set to larger than 0
|
||||
let replicas = 0;
|
||||
if (cm.config.settings.es_replicas) {
|
||||
replicas = cm.config.settings.es_replicas;
|
||||
}
|
||||
|
||||
const defaultIndexSettings = {
|
||||
"index": {
|
||||
"number_of_shards": shards,
|
||||
"refresh_interval": refresh,
|
||||
"number_of_replicas": replicas,
|
||||
"codec": compression
|
||||
}
|
||||
};
|
||||
|
||||
const actionSettings = {
|
||||
index: {
|
||||
codec: compression,
|
||||
refresh_interval: refresh,
|
||||
number_of_shards: shards * 2,
|
||||
number_of_replicas: replicas,
|
||||
sort: {
|
||||
field: "global_sequence",
|
||||
order: "desc"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// actionSettings.index["lifecycle"] = {
|
||||
// "name": defaultLifecyclePolicy,
|
||||
// "rollover_alias": chain + "-action"
|
||||
// };
|
||||
|
||||
if (cm.config.settings.hot_warm_policy) {
|
||||
actionSettings["routing"] = {"allocation": {"exclude": {"data": "warm"}}};
|
||||
}
|
||||
|
||||
const transferProps = {
|
||||
"properties": {
|
||||
"from": {"type": "keyword"},
|
||||
"to": {"type": "keyword"},
|
||||
"amount": {"type": "float"},
|
||||
"symbol": {"type": "keyword"},
|
||||
"memo": {"type": "text"}
|
||||
}
|
||||
};
|
||||
|
||||
export const action = {
|
||||
order: 0,
|
||||
index_patterns: [
|
||||
chain + "-action-*"
|
||||
],
|
||||
settings: actionSettings,
|
||||
mappings: {
|
||||
properties: {
|
||||
"@timestamp": {"type": "date"},
|
||||
"ds_error": {"type": "boolean"},
|
||||
"global_sequence": {"type": "long"},
|
||||
"account_ram_deltas.delta": {"type": "integer"},
|
||||
"account_ram_deltas.account": {"type": "keyword"},
|
||||
"act.authorization.permission": {"enabled": false},
|
||||
"act.authorization.actor": {"type": "keyword"},
|
||||
"act.account": {"type": "keyword"},
|
||||
"act.name": {"type": "keyword"},
|
||||
"act.data": {"enabled": false},
|
||||
"block_num": {"type": "long"},
|
||||
"block_id": {"type": "keyword"},
|
||||
"action_ordinal": {"type": "long"},
|
||||
"creator_action_ordinal": {"type": "long"},
|
||||
"cpu_usage_us": {"type": "integer"},
|
||||
"net_usage_words": {"type": "integer"},
|
||||
"code_sequence": {"type": "integer"},
|
||||
"abi_sequence": {"type": "integer"},
|
||||
"trx_id": {"type": "keyword"},
|
||||
"producer": {"type": "keyword"},
|
||||
"signatures": {"enabled": false},
|
||||
"inline_count": {"type": "short"},
|
||||
"max_inline": {"type": "short"},
|
||||
"inline_filtered": {"type": "boolean"},
|
||||
"receipts": {
|
||||
"properties": {
|
||||
"global_sequence": {"type": "long"},
|
||||
"recv_sequence": {"type": "long"},
|
||||
"receiver": {"type": "keyword"},
|
||||
"auth_sequence": {
|
||||
"properties": {
|
||||
"account": {"type": "keyword"},
|
||||
"sequence": {"type": "long"}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// eosio::newaccount
|
||||
"@newaccount": {
|
||||
"properties": {
|
||||
"active": {"type": "object"},
|
||||
"owner": {"type": "object"},
|
||||
"newact": {"type": "keyword"}
|
||||
}
|
||||
},
|
||||
|
||||
// eosio::updateauth
|
||||
"@updateauth": {
|
||||
"properties": {
|
||||
"permission": {"type": "keyword"},
|
||||
"parent": {"type": "keyword"},
|
||||
"auth": {"type": "object"}
|
||||
}
|
||||
},
|
||||
|
||||
// *::transfer
|
||||
"@transfer": transferProps,
|
||||
|
||||
// eosio::unstaketorex
|
||||
"@unstaketorex": {
|
||||
"properties": {
|
||||
"owner": {"type": "keyword"},
|
||||
"receiver": {"type": "keyword"},
|
||||
"amount": {"type": "float"}
|
||||
}
|
||||
},
|
||||
|
||||
// eosio::buyrex
|
||||
"@buyrex": {
|
||||
"properties": {
|
||||
"from": {"type": "keyword"},
|
||||
"amount": {"type": "float"}
|
||||
}
|
||||
},
|
||||
|
||||
// eosio::buyram
|
||||
"@buyram": {
|
||||
"properties": {
|
||||
"payer": {"type": "keyword"},
|
||||
"receiver": {"type": "keyword"},
|
||||
"quant": {"type": "float"}
|
||||
}
|
||||
},
|
||||
|
||||
// eosio::buyrambytes
|
||||
"@buyrambytes": {
|
||||
"properties": {
|
||||
"payer": {"type": "keyword"},
|
||||
"receiver": {"type": "keyword"},
|
||||
"bytes": {"type": "long"}
|
||||
}
|
||||
},
|
||||
|
||||
// eosio::delegatebw
|
||||
"@delegatebw": {
|
||||
"properties": {
|
||||
"from": {"type": "keyword"},
|
||||
"receiver": {"type": "keyword"},
|
||||
"stake_cpu_quantity": {"type": "float"},
|
||||
"stake_net_quantity": {"type": "float"},
|
||||
"transfer": {"type": "boolean"},
|
||||
"amount": {"type": "float"}
|
||||
}
|
||||
},
|
||||
|
||||
// eosio::undelegatebw
|
||||
"@undelegatebw": {
|
||||
"properties": {
|
||||
"from": {"type": "keyword"},
|
||||
"receiver": {"type": "keyword"},
|
||||
"unstake_cpu_quantity": {"type": "float"},
|
||||
"unstake_net_quantity": {"type": "float"},
|
||||
"amount": {"type": "float"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const deltaSettings = {
|
||||
index: {
|
||||
codec: compression,
|
||||
number_of_shards: shards * 2,
|
||||
refresh_interval: refresh,
|
||||
number_of_replicas: replicas,
|
||||
sort: {
|
||||
field: ["block_num", "scope", "primary_key"],
|
||||
order: ["desc", "asc", "asc"]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// deltaSettings.index["lifecycle"] = {
|
||||
// "name": defaultLifecyclePolicy,
|
||||
// "rollover_alias": chain + "-delta"
|
||||
// };
|
||||
|
||||
if (cm.config.settings.hot_warm_policy) {
|
||||
deltaSettings["routing"] = {"allocation": {"exclude": {"data": "warm"}}};
|
||||
}
|
||||
|
||||
export const delta = {
|
||||
"index_patterns": [chain + "-delta-*"],
|
||||
"settings": deltaSettings,
|
||||
"mappings": {
|
||||
"properties": {
|
||||
|
||||
// base fields
|
||||
"@timestamp": {"type": "date"},
|
||||
"present": {"type": "byte"},
|
||||
"ds_error": {"type": "boolean"},
|
||||
"block_id": {"type": "keyword"},
|
||||
"block_num": {"type": "long"},
|
||||
"deleted_at": {"type": "long"},
|
||||
"code": {"type": "keyword"},
|
||||
"scope": {"type": "keyword"},
|
||||
"table": {"type": "keyword"},
|
||||
"payer": {"type": "keyword"},
|
||||
"primary_key": {"type": "keyword"},
|
||||
"data": {"enabled": false},
|
||||
"value": {"enabled": false},
|
||||
|
||||
// eosio.msig::approvals
|
||||
"@approvals.proposal_name": {"type": "keyword"},
|
||||
"@approvals.provided_approvals": {"type": "object"},
|
||||
"@approvals.requested_approvals": {"type": "object"},
|
||||
|
||||
// eosio.msig::proposal
|
||||
"@proposal.proposal_name": {"type": "keyword"},
|
||||
"@proposal.transaction": {"enabled": false},
|
||||
|
||||
// *::accounts
|
||||
"@accounts.amount": {"type": "float"},
|
||||
"@accounts.symbol": {"type": "keyword"},
|
||||
|
||||
// eosio::voters
|
||||
"@voters.is_proxy": {"type": "boolean"},
|
||||
"@voters.producers": {"type": "keyword"},
|
||||
"@voters.last_vote_weight": {"type": "double"},
|
||||
"@voters.proxied_vote_weight": {"type": "double"},
|
||||
"@voters.staked": {"type": "float"},
|
||||
"@voters.proxy": {"type": "keyword"},
|
||||
|
||||
// eosio::producers
|
||||
"@producers.total_votes": {"type": "double"},
|
||||
"@producers.is_active": {"type": "boolean"},
|
||||
"@producers.unpaid_blocks": {"type": "long"},
|
||||
|
||||
// eosio::global
|
||||
"@global": {
|
||||
"properties": {
|
||||
"last_name_close": {"type": "date"},
|
||||
"last_pervote_bucket_fill": {"type": "date"},
|
||||
"last_producer_schedule_update": {"type": "date"},
|
||||
"perblock_bucket": {"type": "double"},
|
||||
"pervote_bucket": {"type": "double"},
|
||||
"total_activated_stake": {"type": "double"},
|
||||
"total_voteshare_change_rate": {"type": "double"},
|
||||
"total_unpaid_voteshare": {"type": "double"},
|
||||
"total_producer_vote_weight": {"type": "double"},
|
||||
"total_ram_bytes_reserved": {"type": "long"},
|
||||
"total_ram_stake": {"type": "long"},
|
||||
"total_unpaid_blocks": {"type": "long"},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const abi = {
|
||||
"index_patterns": [chain + "-abi-*"],
|
||||
"settings": defaultIndexSettings,
|
||||
"mappings": {
|
||||
"properties": {
|
||||
"@timestamp": {"type": "date"},
|
||||
"block": {"type": "long"},
|
||||
"account": {"type": "keyword"},
|
||||
"abi": {"enabled": false},
|
||||
"abi_hex": {"enabled": false},
|
||||
"actions": {"type": "keyword"},
|
||||
"tables": {"type": "keyword"}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const permissionLink = {
|
||||
"index_patterns": [chain + "-link-*"],
|
||||
"settings": defaultIndexSettings,
|
||||
"mappings": {
|
||||
"properties": {
|
||||
"block_num": {"type": "long"},
|
||||
"@timestamp": {"type": "date"},
|
||||
"present": {"type": "byte"},
|
||||
"account": {"type": "keyword"},
|
||||
"code": {"type": "keyword"},
|
||||
"action": {"type": "keyword"},
|
||||
"permission": {"type": "keyword"}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const permission = {
|
||||
"index_patterns": [chain + "-perm-*"],
|
||||
"settings": defaultIndexSettings,
|
||||
"mappings": {
|
||||
"properties": {
|
||||
"block_num": {"type": "long"},
|
||||
"present": {"type": "byte"},
|
||||
"owner": {"type": "keyword"},
|
||||
"name": {"type": "keyword"},
|
||||
"parent": {"type": "keyword"},
|
||||
"last_updated": {"type": "date"},
|
||||
"auth": {"type": "object"}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const resourceLimits = {
|
||||
"index_patterns": [chain + "-reslimits-*"],
|
||||
"settings": defaultIndexSettings,
|
||||
"mappings": {
|
||||
"properties": {
|
||||
"block_num": {"type": "long"},
|
||||
"@timestamp": {"type": "date"},
|
||||
"owner": {"type": "keyword"},
|
||||
"total_weight": {"type": "long"},
|
||||
"net_weight": {"type": "long"},
|
||||
"cpu_weight": {"type": "long"},
|
||||
"ram_bytes": {"type": "long"}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const generatedTransaction = {
|
||||
"index_patterns": [chain + "-gentrx-*"],
|
||||
"settings": defaultIndexSettings,
|
||||
"mappings": {
|
||||
"properties": {
|
||||
"block_num": {"type": "long"},
|
||||
"@timestamp": {"type": "date"},
|
||||
"sender": {"type": "keyword"},
|
||||
"sender_id": {"type": "keyword"},
|
||||
"payer": {"type": "keyword"},
|
||||
"trx_id": {"type": "keyword"},
|
||||
"actions": {"enabled": false},
|
||||
"packed_trx": {"enabled": false}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const failedTransaction = {
|
||||
"index_patterns": [chain + "-trxerr-*"],
|
||||
"settings": defaultIndexSettings,
|
||||
"mappings": {
|
||||
"properties": {
|
||||
"block_num": {"type": "long"},
|
||||
"@timestamp": {"type": "date"},
|
||||
"status": {"type": "short"}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const schedule = {
|
||||
"index_patterns": [chain + "-schedule-*"],
|
||||
"settings": {
|
||||
...defaultIndexSettings,
|
||||
sort: {
|
||||
field: "version",
|
||||
order: "desc"
|
||||
}
|
||||
},
|
||||
"mappings": {
|
||||
"properties": {
|
||||
"block_num": {"type": "long"},
|
||||
"version": {"type": "long"},
|
||||
"@timestamp": {"type": "date"},
|
||||
"producers.name": {"type": "keyword"},
|
||||
"producers.keys": {"type": "keyword"},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const resourceUsage = {
|
||||
"index_patterns": [chain + "-userres-*"],
|
||||
"settings": defaultIndexSettings,
|
||||
"mappings": {
|
||||
"properties": {
|
||||
"block_num": {"type": "long"},
|
||||
"@timestamp": {"type": "date"},
|
||||
"owner": {"type": "keyword"},
|
||||
"net_used": {"type": "long"},
|
||||
"net_total": {"type": "long"},
|
||||
"net_pct": {"type": "float"},
|
||||
"cpu_used": {"type": "long"},
|
||||
"cpu_total": {"type": "long"},
|
||||
"cpu_pct": {"type": "float"},
|
||||
"ram": {"type": "long"}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
export const logs = {
|
||||
"index_patterns": [chain + "-logs-*"],
|
||||
"settings": defaultIndexSettings
|
||||
};
|
||||
|
||||
export const block = {
|
||||
"index_patterns": [chain + "-block-*"],
|
||||
"settings": {
|
||||
"index": {
|
||||
"codec": compression,
|
||||
"number_of_shards": shards,
|
||||
"refresh_interval": refresh,
|
||||
"number_of_replicas": replicas,
|
||||
"sort.field": "block_num",
|
||||
"sort.order": "desc"
|
||||
}
|
||||
},
|
||||
"mappings": {
|
||||
"properties": {
|
||||
"@timestamp": {"type": "date"},
|
||||
"block_num": {"type": "long"},
|
||||
"block_id": {"type": "keyword"},
|
||||
"prev_id": {"type": "keyword"},
|
||||
"producer": {"type": "keyword"},
|
||||
"new_producers.producers.block_signing_key": {"enabled": false},
|
||||
"new_producers.producers.producer_name": {"type": "keyword"},
|
||||
"new_producers.version": {"type": "long"},
|
||||
"schedule_version": {"type": "double"},
|
||||
"cpu_usage": {"type": "integer"},
|
||||
"net_usage": {"type": "integer"}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const tableProposals = {
|
||||
"index_patterns": [chain + "-table-proposals-*"],
|
||||
"settings": {
|
||||
"index": {
|
||||
"codec": compression,
|
||||
"number_of_shards": shards,
|
||||
"refresh_interval": refresh,
|
||||
"number_of_replicas": replicas,
|
||||
"sort.field": "block_num",
|
||||
"sort.order": "desc"
|
||||
}
|
||||
},
|
||||
"mappings": {
|
||||
"properties": {
|
||||
"block_num": {"type": "long"},
|
||||
"present": {"type": "byte"},
|
||||
"proposal_name": {"type": "keyword"},
|
||||
"requested_approvals": {"type": "object"},
|
||||
"provided_approvals": {"type": "object"},
|
||||
"executed": {"type": "boolean"}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const tableAccounts = {
|
||||
"index_patterns": [chain + "-table-accounts-*"],
|
||||
"settings": {
|
||||
"index": {
|
||||
"codec": compression,
|
||||
"number_of_shards": shards,
|
||||
"refresh_interval": refresh,
|
||||
"number_of_replicas": replicas,
|
||||
"sort.field": "amount",
|
||||
"sort.order": "desc"
|
||||
}
|
||||
},
|
||||
"mappings": {
|
||||
"properties": {
|
||||
"block_num": {"type": "long"},
|
||||
"present": {"type": "byte"},
|
||||
"code": {"type": "keyword"},
|
||||
"scope": {"type": "keyword"},
|
||||
"amount": {"type": "float"},
|
||||
"symbol": {"type": "keyword"}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// noinspection JSUnusedGlobalSymbols
|
||||
export const tableDelBand = {
|
||||
"index_patterns": [chain + "-table-delband-*"],
|
||||
"settings": {
|
||||
"index": {
|
||||
"codec": compression,
|
||||
"number_of_shards": shards,
|
||||
"refresh_interval": refresh,
|
||||
"number_of_replicas": replicas,
|
||||
"sort.field": "total_weight",
|
||||
"sort.order": "desc"
|
||||
}
|
||||
},
|
||||
"mappings": {
|
||||
"properties": {
|
||||
"block_num": {"type": "long"},
|
||||
"from": {"type": "keyword"},
|
||||
"to": {"type": "keyword"},
|
||||
"total_weight": {"type": "float"},
|
||||
"net_weight": {"type": "float"},
|
||||
"cpu_weight": {"type": "float"}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const tableVoters = {
|
||||
"index_patterns": [chain + "-table-voters-*"],
|
||||
"settings": {
|
||||
"index": {
|
||||
"codec": compression,
|
||||
"number_of_shards": shards,
|
||||
"refresh_interval": refresh,
|
||||
"number_of_replicas": replicas,
|
||||
"sort.field": "last_vote_weight",
|
||||
"sort.order": "desc"
|
||||
}
|
||||
},
|
||||
"mappings": {
|
||||
"properties": {
|
||||
"block_num": {"type": "long"},
|
||||
"voter": {"type": "keyword"},
|
||||
"producers": {"type": "keyword"},
|
||||
"last_vote_weight": {"type": "double"},
|
||||
"is_proxy": {"type": "boolean"},
|
||||
"proxied_vote_weight": {"type": "double"},
|
||||
"staked": {"type": "double"},
|
||||
"proxy": {"type": "keyword"}
|
||||
}
|
||||
}
|
||||
};
|
||||
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
Executable → Regular
@@ -1,9 +1,9 @@
|
||||
const {addApiServer, addIndexer} = require('./definitions/ecosystem_settings');
|
||||
const {readdirSync, readFileSync} = require("fs");
|
||||
const path = require('path');
|
||||
const {addApiServer, addIndexer} = require('./scripts/ecosystem.helpers.cjs');
|
||||
const {readdirSync, readFileSync} = require("node:fs");
|
||||
const path = require('node:path');
|
||||
|
||||
const apps = [];
|
||||
const chainsRoot = path.join(path.resolve(), 'chains');
|
||||
const chainsRoot = path.join(path.resolve(), 'config', 'chains');
|
||||
readdirSync(chainsRoot)
|
||||
.filter(f => f.endsWith('.config.json') && !f.startsWith('example'))
|
||||
.forEach(value => {
|
||||
@@ -20,4 +20,5 @@ readdirSync(chainsRoot)
|
||||
}
|
||||
});
|
||||
|
||||
console.log(apps);
|
||||
module.exports = {apps};
|
||||
@@ -1,293 +0,0 @@
|
||||
import {ApiResponse, Client} from "@elastic/elasticsearch";
|
||||
import {Serialize} from "../addons/eosjs-native";
|
||||
import {existsSync} from "fs";
|
||||
import {join} from "path";
|
||||
|
||||
let config;
|
||||
const conf_path = join(__dirname, `../${process.env.CONFIG_JSON}`);
|
||||
if (existsSync(conf_path)) {
|
||||
try {
|
||||
config = require(conf_path);
|
||||
} catch (e) {
|
||||
console.log(e.message);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (!config) {
|
||||
console.log(`Configuration not found: ${conf_path}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
function getLastResult(results: ApiResponse) {
|
||||
if (results.body.hits?.hits?.length > 0) {
|
||||
return parseInt(results.body.hits.hits[0].sort[0], 10);
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getLastIndexedBlockByDelta(es_client: Client, chain: string) {
|
||||
const results: ApiResponse = await es_client.search({
|
||||
index: chain + '-delta-*',
|
||||
size: 1,
|
||||
body: {
|
||||
query: {bool: {filter: {match_all: {}}}},
|
||||
sort: [{block_num: {order: "desc"}}]
|
||||
}
|
||||
});
|
||||
return getLastResult(results);
|
||||
}
|
||||
|
||||
export async function getLastIndexedBlock(es_client: Client, chain: string) {
|
||||
const results: ApiResponse = await es_client.search({
|
||||
index: chain + '-block-*',
|
||||
size: 1,
|
||||
body: {
|
||||
query: {bool: {filter: {match_all: {}}}},
|
||||
sort: [{block_num: {order: "desc"}}]
|
||||
}
|
||||
});
|
||||
return getLastResult(results);
|
||||
}
|
||||
|
||||
export async function getLastIndexedBlockWithTotalBlocks(es_client: Client, chain: string): Promise<[number, number]> {
|
||||
const results: ApiResponse = await es_client.search({
|
||||
index: chain + '-block-*',
|
||||
size: 1,
|
||||
body: {
|
||||
query: {bool: {filter: {match_all: {}}}},
|
||||
sort: [{block_num: {order: "desc"}}],
|
||||
track_total_hits: true
|
||||
}
|
||||
});
|
||||
let lastBlock = getLastResult(results);
|
||||
let totalBlocks = results.body.hits.total.value || 1;
|
||||
return [lastBlock, totalBlocks];
|
||||
}
|
||||
|
||||
export async function getFirstIndexedBlock(es_client: Client, chain: string): Promise<number> {
|
||||
const results: ApiResponse = await es_client.search({
|
||||
index: chain + '-block-*',
|
||||
size: 1,
|
||||
body: {
|
||||
query: {bool: {filter: {match_all: {}}}},
|
||||
sort: [{block_num: {order: "asc"}}]
|
||||
}
|
||||
});
|
||||
return getLastResult(results);
|
||||
}
|
||||
|
||||
|
||||
export async function getLastIndexedABI(es_client: Client, chain: string) {
|
||||
const results: ApiResponse = await es_client.search({
|
||||
index: chain + '-abi-*',
|
||||
size: 1,
|
||||
body: {
|
||||
query: {
|
||||
match_all: {}
|
||||
},
|
||||
sort: [{block: {order: "desc"}}]
|
||||
}
|
||||
});
|
||||
return getLastResult(results);
|
||||
}
|
||||
|
||||
export async function getLastIndexedBlockByDeltaFromRange(es_client: Client, chain: string, first: number, last: number) {
|
||||
const results: ApiResponse = await es_client.search({
|
||||
index: chain + '-delta-*',
|
||||
size: 1,
|
||||
body: {
|
||||
query: {
|
||||
range: {
|
||||
block_num: {
|
||||
"gte": first,
|
||||
"lt": last,
|
||||
"boost": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
sort: [{block_num: {order: "desc"}}]
|
||||
}
|
||||
});
|
||||
return getLastResult(results);
|
||||
}
|
||||
|
||||
export async function getLastIndexedBlockFromRange(es_client: Client, chain: string, first: number, last: number) {
|
||||
const results = await es_client.search({
|
||||
index: chain + '-block-*',
|
||||
size: 1,
|
||||
body: {
|
||||
query: {
|
||||
range: {
|
||||
block_num: {
|
||||
"gte": first,
|
||||
"lt": last,
|
||||
"boost": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
sort: [{block_num: {order: "desc"}}]
|
||||
}
|
||||
});
|
||||
return getLastResult(results);
|
||||
}
|
||||
|
||||
export function messageAllWorkers(cl, payload) {
|
||||
for (const c in cl.workers) {
|
||||
if (cl.workers.hasOwnProperty(c)) {
|
||||
const _w = cl.workers[c];
|
||||
if (_w) {
|
||||
try {
|
||||
if (_w.isConnected()) {
|
||||
_w.send(payload);
|
||||
} else {
|
||||
hLog('Worker is not connected!');
|
||||
}
|
||||
} catch (e) {
|
||||
hLog('Failed to message worker!');
|
||||
hLog(e);
|
||||
}
|
||||
} else {
|
||||
hLog('Worker not found!');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function serialize(type, value, txtEnc, txtDec, types) {
|
||||
const buffer = new Serialize.SerialBuffer({
|
||||
textEncoder: txtEnc,
|
||||
textDecoder: txtDec
|
||||
});
|
||||
Serialize.getType(types, type).serialize(buffer, value);
|
||||
return buffer.asUint8Array();
|
||||
}
|
||||
|
||||
export function deserialize(type, array, txtEnc, txtDec, types) {
|
||||
const buffer = new Serialize.SerialBuffer({
|
||||
textEncoder: txtEnc,
|
||||
textDecoder: txtDec,
|
||||
array
|
||||
});
|
||||
return Serialize.getType(types, type).deserialize(buffer, new Serialize.SerializerState({bytesAsUint8Array: true}));
|
||||
}
|
||||
|
||||
function getNested(path_array, jsonObj) {
|
||||
const nextPath = path_array.shift();
|
||||
const nextValue = jsonObj[nextPath];
|
||||
if (!nextValue) {
|
||||
return null;
|
||||
} else {
|
||||
if (typeof nextValue !== 'object') {
|
||||
return nextValue;
|
||||
} else {
|
||||
if (Array.isArray(nextValue)) {
|
||||
return nextValue;
|
||||
} else {
|
||||
return getNested(path_array, nextValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function checkDeltaFilter(filter, _source) {
|
||||
if (filter.field && filter.value) {
|
||||
let fieldValue = getNested(filter.field.split("."), _source);
|
||||
if (!fieldValue) {
|
||||
const fArray = filter.field.split(".");
|
||||
if (fArray[0].startsWith('@')) {
|
||||
const tableName = fArray[0].replace('@', '');
|
||||
if (_source.table === tableName) {
|
||||
fArray[0] = 'data';
|
||||
fieldValue = getNested(fArray, _source);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fieldValue) {
|
||||
if (Array.isArray(fieldValue)) {
|
||||
return fieldValue.indexOf(filter.value) !== -1;
|
||||
} else {
|
||||
return fieldValue === filter.value;
|
||||
}
|
||||
} else {
|
||||
return !filter.value;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function checkFilter(filter, _source) {
|
||||
if (filter.field && filter.value) {
|
||||
let fieldValue = getNested(filter.field.split("."), _source);
|
||||
if (!fieldValue) {
|
||||
const fArray = filter.field.split(".");
|
||||
if (fArray[0].startsWith('@')) {
|
||||
const actName = fArray[0].replace('@', '');
|
||||
if (_source.act.name === actName) {
|
||||
fArray[0] = 'data';
|
||||
fArray.unshift('act');
|
||||
fieldValue = getNested(fArray, _source);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fieldValue) {
|
||||
if (Array.isArray(fieldValue)) {
|
||||
return fieldValue.indexOf(filter.value) !== -1;
|
||||
} else {
|
||||
return fieldValue === filter.value;
|
||||
}
|
||||
} else {
|
||||
return !filter.value;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function hLog(input: any, ...extra: any[]) {
|
||||
let role;
|
||||
if (process.env.worker_role) {
|
||||
const id = parseInt(process.env.worker_id);
|
||||
role = `[${process.pid} - ${(id < 10 ? '0' : '') + id.toString()}_${process.env.worker_role}]`;
|
||||
} else {
|
||||
if (process.env.script && process.env.script === './api/server.js') {
|
||||
role = `[${process.pid} - api]`;
|
||||
} else {
|
||||
role = `[${process.pid} - 00_master]`;
|
||||
}
|
||||
}
|
||||
if (process.env.TRACE_LOGS === 'true') {
|
||||
const e = new Error();
|
||||
const frame = e.stack.split("\n")[2];
|
||||
const where = frame.split(" ")[6].split(/[:()]/);
|
||||
const arr = where[1].split("/");
|
||||
const fileName = arr[arr.length - 1];
|
||||
const lineNumber = where[2];
|
||||
role += ` ${fileName}:${lineNumber}`;
|
||||
}
|
||||
console.log(role, input, ...extra);
|
||||
}
|
||||
|
||||
export function debugLog(text: any, ...extra: any[]) {
|
||||
if (config.settings.debug) {
|
||||
hLog(text, ...extra);
|
||||
}
|
||||
}
|
||||
|
||||
export async function sleep(ms): Promise<void> {
|
||||
return new Promise(resolve => setTimeout(resolve, ms));
|
||||
}
|
||||
|
||||
export async function waitUntilReady(executor: () => Promise<boolean>, attempts: number, interval: number, onError: () => void): Promise<void> {
|
||||
let i = 0;
|
||||
while (i < attempts) {
|
||||
if (await executor()) {
|
||||
return;
|
||||
}
|
||||
await sleep(interval);
|
||||
i++;
|
||||
}
|
||||
onError();
|
||||
}
|
||||
@@ -1,550 +0,0 @@
|
||||
import {Channel, Message} from "amqplib/callback_api";
|
||||
import {ConnectionManager} from "../connections/manager.class";
|
||||
import _ from "lodash";
|
||||
import {hLog} from "./common_functions";
|
||||
import {createHash} from "crypto";
|
||||
|
||||
type MaxBlockCb = (maxBlock: number) => void;
|
||||
type routerFunction = (blockNum: number) => string;
|
||||
type MMap = Map<string, any>;
|
||||
|
||||
function makeScriptedOp(id, body) {
|
||||
return [
|
||||
{update: {_id: id, retry_on_conflict: 3}},
|
||||
{script: {id: "updateByBlock", params: body}, scripted_upsert: true, upsert: {}}
|
||||
];
|
||||
}
|
||||
|
||||
function makeDelOp(id) {
|
||||
return [
|
||||
{delete: {_id: id}}
|
||||
];
|
||||
}
|
||||
|
||||
function flatMap(payloads: Message[], builder) {
|
||||
return _(payloads).map((payload: Message) => {
|
||||
const body = JSON.parse(payload.content.toString());
|
||||
return builder(payload, body);
|
||||
}).flatten()['value']();
|
||||
}
|
||||
|
||||
function buildAbiBulk(payloads, messageMap: MMap) {
|
||||
return flatMap(payloads, (payload, body) => {
|
||||
const id = body['block'] + body['account'];
|
||||
messageMap.set(id, _.omit(payload, ['content']));
|
||||
return [{index: {_id: id}}, body];
|
||||
});
|
||||
}
|
||||
|
||||
function buildActionBulk(payloads, messageMap: MMap, maxBlockCb: MaxBlockCb, routerFunc: routerFunction, indexName: string) {
|
||||
return flatMap(payloads, (payload, body) => {
|
||||
const id = body['global_sequence'];
|
||||
messageMap.set(id, _.omit(payload, ['content']));
|
||||
return [{
|
||||
index: {
|
||||
_id: id,
|
||||
_index: `${indexName}-${routerFunc(body.block_num)}`
|
||||
}
|
||||
}, body];
|
||||
});
|
||||
}
|
||||
|
||||
function buildBlockBulk(payloads, messageMap: MMap, maxBlockCb: MaxBlockCb, routerFunc: routerFunction, indexName: string) {
|
||||
return flatMap(payloads, (payload, body) => {
|
||||
const id = body['block_num'];
|
||||
messageMap.set(id, _.omit(payload, ['content']));
|
||||
return [{
|
||||
index: {_id: id}
|
||||
}, body];
|
||||
});
|
||||
}
|
||||
|
||||
function buildDeltaBulk(payloads, messageMap: MMap, maxBlockCb: MaxBlockCb, routerFunc: routerFunction, indexName: string) {
|
||||
let maxBlock = 0;
|
||||
const flat_map = flatMap(payloads, (payload, b) => {
|
||||
if (maxBlock < b.block_num) {
|
||||
maxBlock = b.block_num;
|
||||
}
|
||||
const id = `${b.block_num}-${b.code}-${b.scope}-${b.table}-${b.primary_key}`;
|
||||
messageMap.set(id, _.omit(payload, ['content']));
|
||||
return [{
|
||||
index: {
|
||||
_id: id,
|
||||
_index: `${indexName}-${routerFunc(b.block_num)}`
|
||||
}
|
||||
}, b];
|
||||
});
|
||||
maxBlockCb(maxBlock);
|
||||
return flat_map;
|
||||
}
|
||||
|
||||
function buildDynamicTableBulk(payloads, messageMap: MMap) {
|
||||
return flatMap(payloads, (payload, body) => {
|
||||
messageMap.set(payload.id, _.omit(payload, ['content']));
|
||||
if (payload.present === 0) {
|
||||
return makeDelOp(payload.id);
|
||||
} else {
|
||||
return makeScriptedOp(payload.id, body);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function buildTableProposalsBulk(payloads, messageMap: MMap) {
|
||||
return flatMap(payloads, (payload, body) => {
|
||||
const id = `${body.proposer}-${body.proposal_name}-${body.primary_key}`;
|
||||
messageMap.set(id, _.omit(payload, ['content']));
|
||||
return makeScriptedOp(id, body);
|
||||
});
|
||||
}
|
||||
|
||||
function buildTableAccountsBulk(payloads, messageMap: MMap) {
|
||||
return flatMap(payloads, (payload, body) => {
|
||||
const id = `${body.code}-${body.scope}-${body.symbol}`;
|
||||
messageMap.set(id, _.omit(payload, ['content']));
|
||||
return makeScriptedOp(id, body);
|
||||
});
|
||||
}
|
||||
|
||||
function buildTableVotersBulk(payloads, messageMap: MMap) {
|
||||
return flatMap(payloads, (payload, body) => {
|
||||
const id = `${body.voter}`;
|
||||
messageMap.set(id, _.omit(payload, ['content']));
|
||||
return makeScriptedOp(id, body);
|
||||
});
|
||||
}
|
||||
|
||||
function buildLinkBulk(payloads, messageMap: MMap) {
|
||||
return flatMap(payloads, (payload, body) => {
|
||||
const id = `${body.account}-${body.permission}-${body.code}-${body.action}`;
|
||||
messageMap.set(id, _.omit(payload, ['content']));
|
||||
return makeScriptedOp(id, body);
|
||||
});
|
||||
}
|
||||
|
||||
function buildPermBulk(payloads, messageMap: MMap) {
|
||||
return flatMap(payloads, (payload, body) => {
|
||||
const id = `${body.owner}-${body.name}`;
|
||||
messageMap.set(id, _.omit(payload, ['content']));
|
||||
return makeScriptedOp(id, body);
|
||||
});
|
||||
}
|
||||
|
||||
function buildResLimitBulk(payloads, messageMap: MMap) {
|
||||
return flatMap(payloads, (payload, body) => {
|
||||
const id = `${body.owner}`;
|
||||
messageMap.set(id, _.omit(payload, ['content']));
|
||||
return makeScriptedOp(id, body);
|
||||
});
|
||||
}
|
||||
|
||||
function buildResUsageBulk(payloads, messageMap: MMap) {
|
||||
return flatMap(payloads, (payload, body) => {
|
||||
const id = `${body.owner}`;
|
||||
messageMap.set(id, _.omit(payload, ['content']));
|
||||
return makeScriptedOp(id, body);
|
||||
});
|
||||
}
|
||||
|
||||
function buildScheduleBulk(payloads, messageMap: MMap) {
|
||||
return flatMap(payloads, (payload, body) => {
|
||||
const id = `${body.version}`;
|
||||
messageMap.set(id, _.omit(payload, ['content']));
|
||||
return makeScriptedOp(id, body);
|
||||
});
|
||||
}
|
||||
|
||||
function buildGenTrxBulk(payloads, messageMap: MMap) {
|
||||
return flatMap(payloads, (payload, body) => {
|
||||
const hash = createHash('sha256')
|
||||
.update(body.sender + body.sender_id + body.payer)
|
||||
.digest()
|
||||
.toString("hex");
|
||||
const id = `${body.block_num}-${hash}`;
|
||||
messageMap.set(id, _.omit(payload, ['content']));
|
||||
return [{index: {_id: id}}, body];
|
||||
});
|
||||
}
|
||||
|
||||
function buildTrxErrBulk(payloads, messageMap: MMap) {
|
||||
return flatMap(payloads, (payload, body) => {
|
||||
const id = body.trx_id.toLowerCase();
|
||||
delete body.trx_id;
|
||||
messageMap.set(id, _.omit(payload, ['content']));
|
||||
return [{index: {_id: id}}, body];
|
||||
});
|
||||
}
|
||||
|
||||
const generatorsMap = {
|
||||
permission: {
|
||||
index_name: 'perm',
|
||||
func: buildPermBulk
|
||||
},
|
||||
permission_link: {
|
||||
index_name: 'link',
|
||||
func: buildLinkBulk
|
||||
},
|
||||
resource_limits: {
|
||||
index_name: 'reslimits',
|
||||
func: buildResLimitBulk
|
||||
},
|
||||
resource_usage: {
|
||||
index_name: 'userres',
|
||||
func: buildResUsageBulk
|
||||
},
|
||||
schedule: {
|
||||
index_name: 'schedule',
|
||||
func: buildScheduleBulk
|
||||
},
|
||||
generated_transaction: {
|
||||
index_name: 'gentrx',
|
||||
func: buildGenTrxBulk
|
||||
},
|
||||
trx_error: {
|
||||
index_name: 'trxerr',
|
||||
func: buildTrxErrBulk
|
||||
},
|
||||
};
|
||||
|
||||
export class ElasticRoutes {
|
||||
public routes: any;
|
||||
cm: ConnectionManager;
|
||||
chain: string;
|
||||
ingestNodeCounters = {};
|
||||
|
||||
constructor(connectionManager: ConnectionManager) {
|
||||
this.routes = {generic: this.handleGenericRoute.bind(this)};
|
||||
this.cm = connectionManager;
|
||||
this.chain = this.cm.chain;
|
||||
this.registerRoutes();
|
||||
this.resetCounters();
|
||||
}
|
||||
|
||||
createGenericBuilder(collection, channel, counter, index_name, method) {
|
||||
return new Promise((resolve) => {
|
||||
const messageMap = new Map();
|
||||
let maxBlockNum;
|
||||
this.bulkAction({
|
||||
index: index_name,
|
||||
body: method(collection, messageMap, (maxBlock) => {
|
||||
maxBlockNum = maxBlock;
|
||||
})
|
||||
}).then((resp: any) => {
|
||||
if (resp.body.errors) {
|
||||
this.ackOrNack(resp, messageMap, channel);
|
||||
} else {
|
||||
if (maxBlockNum > 0) {
|
||||
ElasticRoutes.reportMaxBlock(maxBlockNum, index_name);
|
||||
}
|
||||
channel.ackAll();
|
||||
}
|
||||
resolve(messageMap.size);
|
||||
}).catch((err) => {
|
||||
try {
|
||||
channel.nackAll();
|
||||
hLog('NackAll', err);
|
||||
} finally {
|
||||
resolve(0);
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
async handleGenericRoute(payload: Message[], ch: Channel, cb: (indexed_size: number) => void): Promise<void> {
|
||||
const coll = {};
|
||||
for (const message of payload) {
|
||||
const type = message.properties.headers.type;
|
||||
if (!coll[type]) {
|
||||
coll[type] = [];
|
||||
}
|
||||
coll[type].push(message);
|
||||
}
|
||||
|
||||
const queue = [];
|
||||
const v = this.cm.config.settings.index_version;
|
||||
let counter = 0;
|
||||
|
||||
Object.keys(coll).forEach(value => {
|
||||
if (generatorsMap[value]) {
|
||||
const indexName = `${this.chain}-${generatorsMap[value].index_name}-${v}`;
|
||||
queue.push(this.createGenericBuilder(coll[value], ch, counter, indexName, generatorsMap[value].func));
|
||||
}
|
||||
});
|
||||
|
||||
await Promise.all(queue);
|
||||
cb(counter);
|
||||
}
|
||||
|
||||
resetCounters() {
|
||||
this.cm.ingestClients.forEach((val, idx) => {
|
||||
this.ingestNodeCounters[idx] = {
|
||||
status: true,
|
||||
docs: 0
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
ackOrNack(resp, messageMap, channel: Channel) {
|
||||
for (const item of resp.body.items) {
|
||||
let id, itemBody;
|
||||
if (item['index']) {
|
||||
id = item.index._id;
|
||||
itemBody = item.index;
|
||||
} else if (item['update']) {
|
||||
id = item.update._id;
|
||||
itemBody = item.update;
|
||||
} else if (item['delete']) {
|
||||
id = item.delete._id;
|
||||
itemBody = item.delete;
|
||||
} else {
|
||||
console.log(item);
|
||||
throw new Error('FATAL ERROR - CANNOT EXTRACT ID');
|
||||
}
|
||||
const message = messageMap.get(id);
|
||||
const status = itemBody.status;
|
||||
if (message) {
|
||||
switch (status) {
|
||||
case 200: {
|
||||
channel.ack(message);
|
||||
break;
|
||||
}
|
||||
case 201: {
|
||||
channel.ack(message);
|
||||
break;
|
||||
}
|
||||
case 404: {
|
||||
channel.ack(message);
|
||||
break;
|
||||
}
|
||||
case 409: {
|
||||
console.log(item);
|
||||
channel.nack(message);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
console.log(item, message.fields.deliveryTag);
|
||||
console.info(`nack id: ${id} - status: ${status}`);
|
||||
channel.nack(message);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log(item);
|
||||
throw new Error('Message not found');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onResponse(resp, messageMap, callback, payloads, channel: Channel, index_name: string, maxBlockNum: number) {
|
||||
if (resp.errors) {
|
||||
this.ackOrNack(resp, messageMap, channel);
|
||||
if (maxBlockNum > 0) {
|
||||
ElasticRoutes.reportMaxBlock(maxBlockNum, index_name);
|
||||
}
|
||||
} else {
|
||||
channel.ackAll();
|
||||
}
|
||||
callback(messageMap.size);
|
||||
}
|
||||
|
||||
onError(err, channel: Channel, callback) {
|
||||
try {
|
||||
channel.nackAll();
|
||||
if (err.meta.body) {
|
||||
hLog('NackAll:', JSON.stringify(err.meta.body.error, null, 2));
|
||||
} else {
|
||||
hLog('NackAll:', err);
|
||||
}
|
||||
} finally {
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
bulkAction(bulkData) {
|
||||
let minIdx = 0;
|
||||
if (this.cm.ingestClients.length > 1) {
|
||||
let min;
|
||||
this.cm.ingestClients.forEach((val, idx) => {
|
||||
if (!min) {
|
||||
min = this.ingestNodeCounters[idx].docs;
|
||||
} else {
|
||||
if (this.ingestNodeCounters[idx].docs < min) {
|
||||
min = this.ingestNodeCounters[idx].docs;
|
||||
minIdx = idx;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
this.ingestNodeCounters[minIdx].docs += bulkData.body.length;
|
||||
if (this.ingestNodeCounters[minIdx].docs > 10000) {
|
||||
this.resetCounters();
|
||||
}
|
||||
// print full request
|
||||
// console.log(JSON.stringify(bulkData));
|
||||
return this.cm.ingestClients[minIdx]['bulk'](bulkData);
|
||||
}
|
||||
|
||||
getIndexPartition(blockNum: number): string {
|
||||
return Math.ceil(blockNum / this.cm.config.settings.index_partition_size).toString().padStart(6, '0');
|
||||
}
|
||||
|
||||
// getIndexNameByBlock(block_num) {
|
||||
// if (!this.distributionMap) {
|
||||
// return null;
|
||||
// }
|
||||
// for (let i = this.distributionMap.length - 1; i >= 0; i--) {
|
||||
// const test = this.distributionMap[i].first_block <= block_num && this.distributionMap[i].last_block >= block_num;
|
||||
// if (test) {
|
||||
// return this.distributionMap[i].index;
|
||||
// }
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// addToIndexMap(map, idx, payload) {
|
||||
// if (idx) {
|
||||
// if (!map[idx]) {
|
||||
// map[idx] = [];
|
||||
// }
|
||||
// map[idx].push(payload);
|
||||
// }
|
||||
// }
|
||||
|
||||
private routeFactory(indexName: string, bulkGenerator, routerFunction) {
|
||||
return async (payloads, channel, cb) => {
|
||||
|
||||
let _index = `${this.chain}-${indexName}-${this.cm.config.settings.index_version}`;
|
||||
|
||||
// write directly to index
|
||||
const messageMap = new Map();
|
||||
let maxBlockNum;
|
||||
this.bulkAction({
|
||||
index: _index,
|
||||
body: bulkGenerator(payloads, messageMap, (maxBlock) => {
|
||||
maxBlockNum = maxBlock;
|
||||
}, routerFunction, _index)
|
||||
}).then(resp => {
|
||||
this.onResponse(resp, messageMap, cb, payloads, channel, _index, maxBlockNum);
|
||||
}).catch(err => {
|
||||
this.onError(err, channel, cb);
|
||||
});
|
||||
|
||||
// if (this.cm.config.indexer.rewrite) {
|
||||
//
|
||||
// // // write to remapped indices
|
||||
// // let payloadBlock = null;
|
||||
// // const indexMap = {};
|
||||
// // let pIdx = null;
|
||||
// // if (indexName === 'action' || indexName === 'delta') {
|
||||
// // for (const payload of payloads) {
|
||||
// // const blk = payload.properties.headers?.block_num;
|
||||
// // if (!payloadBlock) {
|
||||
// // payloadBlock = blk;
|
||||
// // pIdx = this.getIndexNameByBlock(blk);
|
||||
// // console.log(pIdx);
|
||||
// // this.addToIndexMap(indexMap, pIdx, payload);
|
||||
// // } else {
|
||||
// // const _idx = payloadBlock === blk ? pIdx : this.getIndexNameByBlock(blk);
|
||||
// // console.log(_idx);
|
||||
// // this.addToIndexMap(indexMap, _idx, payload);
|
||||
// // }
|
||||
// // }
|
||||
// // }
|
||||
// //
|
||||
// // // if no index was mapped to that range use the default alias
|
||||
// // if (Object.keys(indexMap).length === 0) {
|
||||
// // indexMap[_index] = payloads;
|
||||
// // }
|
||||
// //
|
||||
// // const queue = [];
|
||||
// // let counter = 0;
|
||||
// //
|
||||
// // for (const idxKey in indexMap) {
|
||||
// // queue.push(this.createGenericBuilder(indexMap[idxKey], channel, counter, idxKey, bulkGenerator));
|
||||
// // }
|
||||
// //
|
||||
// // const results = await Promise.all(queue);
|
||||
// // results.forEach(value => counter += value);
|
||||
// // cb(counter);
|
||||
//
|
||||
// } else {
|
||||
// // write directly to index
|
||||
// const messageMap = new Map();
|
||||
// let maxBlockNum;
|
||||
// this.bulkAction({
|
||||
// index: _index,
|
||||
// type: '_doc',
|
||||
// body: bulkGenerator(payloads, messageMap, (maxBlock) => {
|
||||
// maxBlockNum = maxBlock;
|
||||
// }, routerFunction, _index)
|
||||
// }).then(resp => {
|
||||
// this.onResponse(resp, messageMap, cb, payloads, channel, _index, maxBlockNum);
|
||||
// }).catch(err => {
|
||||
// this.onError(err, channel, cb);
|
||||
// });
|
||||
// }
|
||||
};
|
||||
}
|
||||
|
||||
private addRoute(indexType: string, bulkGenerator, routerFunction) {
|
||||
this.routes[indexType] = this.routeFactory(indexType, bulkGenerator, routerFunction);
|
||||
}
|
||||
|
||||
private registerRoutes() {
|
||||
this.registerDynamicTableRoute();
|
||||
const partitionRouter = this.getIndexPartition.bind(this);
|
||||
this.addRoute('abi', buildAbiBulk, null);
|
||||
this.addRoute('action', buildActionBulk, partitionRouter);
|
||||
this.addRoute('block', buildBlockBulk, partitionRouter);
|
||||
this.addRoute('delta', buildDeltaBulk, partitionRouter);
|
||||
this.addRoute('table-voters', buildTableVotersBulk, null);
|
||||
this.addRoute('table-accounts', buildTableAccountsBulk, null);
|
||||
this.addRoute('table-proposals', buildTableProposalsBulk, null);
|
||||
// this.addRoute('dynamic-table', buildDynamicTableBulk);
|
||||
}
|
||||
|
||||
private registerDynamicTableRoute() {
|
||||
this.routes['dynamic-table'] = async (payloads, channel, cb) => {
|
||||
const contractMap: Map<string, any[]> = new Map();
|
||||
let counter = 0;
|
||||
for (const payload of payloads) {
|
||||
const headers = payload?.properties?.headers;
|
||||
const item = {
|
||||
id: headers.id,
|
||||
block_num: headers.block_num,
|
||||
present: headers.present,
|
||||
content: payload.content,
|
||||
fields: payload.fields,
|
||||
properties: payload.properties
|
||||
};
|
||||
if (contractMap.has(headers.code)) {
|
||||
contractMap.get(headers.code).push(item);
|
||||
} else {
|
||||
contractMap.set(headers.code, [item]);
|
||||
}
|
||||
}
|
||||
const processingQueue = [];
|
||||
for (const entry of contractMap.entries()) {
|
||||
processingQueue.push(
|
||||
this.createGenericBuilder(
|
||||
entry[1],
|
||||
channel,
|
||||
counter,
|
||||
`${this.chain}-dt-${entry[0]}`,
|
||||
buildDynamicTableBulk
|
||||
)
|
||||
);
|
||||
}
|
||||
const results = await Promise.all(processingQueue);
|
||||
results.forEach(value => counter += value);
|
||||
cb(counter);
|
||||
};
|
||||
}
|
||||
|
||||
private static reportMaxBlock(maxBlockNum: number, index_name: string) {
|
||||
process.send({
|
||||
event: 'ingestor_block_report',
|
||||
index: index_name,
|
||||
proc: process.env.worker_role,
|
||||
block_num: maxBlockNum
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
#!/bin/bash
|
||||
node ./scripts/hpm.js "$@"
|
||||
# HPM_DEBUG=1 node ./scripts/hpm.js "$@"
|
||||
|
||||
node ./dist/tools/hpm.js "$@"
|
||||
|
||||
# HPM_DEBUG=1 node ./dist/tools/hpm.js "$@"
|
||||
|
||||
+2
-1
@@ -1,2 +1,3 @@
|
||||
#!/bin/bash
|
||||
node ./scripts/hyp-config.js "$@"
|
||||
|
||||
node ./dist/tools/hyp-config.js "$@"
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
#!/bin/bash
|
||||
node ./scripts/hyp-repair.js "$@"
|
||||
File diff suppressed because one or more lines are too long
@@ -1,27 +0,0 @@
|
||||
import {HyperionActionAct} from "./hyperion-action";
|
||||
|
||||
export interface ActionTrace {
|
||||
signatures: string[];
|
||||
'@timestamp': string;
|
||||
act: HyperionActionAct
|
||||
block_num: number;
|
||||
block_id: string;
|
||||
global_sequence: number;
|
||||
producer: string;
|
||||
trx_id: string;
|
||||
account_ram_deltas?: any[];
|
||||
console?: string;
|
||||
elapsed?: any;
|
||||
context_free?: any;
|
||||
level?: number;
|
||||
except: any;
|
||||
receipt: any;
|
||||
creator_action_ordinal: number;
|
||||
action_ordinal: number;
|
||||
cpu_usage_us: number;
|
||||
net_usage_words: number;
|
||||
error_code: any;
|
||||
max_inline: number;
|
||||
inline_count: number;
|
||||
inline_filtered: boolean;
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
export interface HyperionActionAct {
|
||||
account: string;
|
||||
name: string;
|
||||
authorization: any;
|
||||
data: any;
|
||||
}
|
||||
|
||||
export interface HyperionAction {
|
||||
action_ordinal: number;
|
||||
creator_action_ordinal: number;
|
||||
receipt: any[];
|
||||
receiver: string;
|
||||
act: HyperionActionAct;
|
||||
context_free: boolean;
|
||||
elapsed: string;
|
||||
console: string;
|
||||
account_ram_deltas: any[];
|
||||
except: any;
|
||||
error_code: any;
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
export interface HyperionDelta {
|
||||
'@timestamp': string;
|
||||
code: string;
|
||||
scope: string;
|
||||
table: string;
|
||||
primary_key: string;
|
||||
payer: string;
|
||||
present: boolean | number;
|
||||
block_num: number;
|
||||
block_id: string;
|
||||
data: any;
|
||||
}
|
||||
-54
@@ -1,54 +0,0 @@
|
||||
import cluster from "cluster";
|
||||
import {ConfigurationModule} from "./modules/config";
|
||||
import {HyperionWorker} from "./workers/hyperionWorker";
|
||||
import {hLog} from "./helpers/common_functions";
|
||||
|
||||
interface WorkerEnv {
|
||||
worker_role: string;
|
||||
worker_id: string;
|
||||
}
|
||||
|
||||
const hyperionWorkers = {
|
||||
ds_pool_worker: 'ds-pool',
|
||||
reader: 'state-reader',
|
||||
deserializer: 'deserializer',
|
||||
continuous_reader: 'state-reader',
|
||||
repair_reader: 'state-reader',
|
||||
ingestor: 'indexer',
|
||||
router: 'ws-router',
|
||||
delta_updater: 'delta-updater'
|
||||
};
|
||||
|
||||
async function launch() {
|
||||
const conf = new ConfigurationModule();
|
||||
const chain_name = conf.config.settings.chain;
|
||||
const env: WorkerEnv = {
|
||||
worker_id: process.env.worker_id,
|
||||
worker_role: process.env.worker_role
|
||||
};
|
||||
|
||||
process.on('SIGINT', function () {
|
||||
hLog("caught interrupt signal. Exiting now!");
|
||||
process.exit();
|
||||
});
|
||||
|
||||
if (cluster.isPrimary) {
|
||||
process.title = `${conf.proc_prefix}-${chain_name}-master`;
|
||||
const master = await import('./modules/master');
|
||||
new master.HyperionMaster().runMaster().catch((err) => {
|
||||
console.log(process.env['worker_role']);
|
||||
console.log(err);
|
||||
});
|
||||
} else {
|
||||
if (hyperionWorkers[env.worker_role] && !conf.disabledWorkers.has(env.worker_role)) {
|
||||
process.title = `${conf.proc_prefix}-${chain_name}-${env.worker_role}:${env.worker_id}`;
|
||||
const mod = (await import(`./workers/${hyperionWorkers[env.worker_role]}`)).default;
|
||||
const instance = new mod() as HyperionWorker;
|
||||
await instance.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
launch().catch((err) => {
|
||||
console.error(err);
|
||||
});
|
||||
-173
@@ -1,173 +0,0 @@
|
||||
# Attribution-NonCommercial-ShareAlike 4.0 International
|
||||
|
||||
Creative Commons Corporation (“Creative Commons”) is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an “as-is” basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible.
|
||||
|
||||
### Using Creative Commons Public Licenses
|
||||
|
||||
Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses.
|
||||
|
||||
* __Considerations for licensors:__ Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC-licensed material, or material used under an exception or limitation to copyright. [More considerations for licensors](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensors).
|
||||
|
||||
* __Considerations for the public:__ By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensor’s permission is not necessary for any reason–for example, because of any applicable exception or limitation to copyright–then that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. [More considerations for the public](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensees).
|
||||
|
||||
## Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public License
|
||||
|
||||
By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions.
|
||||
|
||||
### Section 1 – Definitions.
|
||||
|
||||
a. __Adapted Material__ means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image.
|
||||
|
||||
b. __Adapter's License__ means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License.
|
||||
|
||||
c. __BY-NC-SA Compatible License__ means a license listed at [creativecommons.org/compatiblelicenses](http://creativecommons.org/compatiblelicenses), approved by Creative Commons as essentially the equivalent of this Public License.
|
||||
|
||||
d. __Copyright and Similar Rights__ means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights.
|
||||
|
||||
e. __Effective Technological Measures__ means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements.
|
||||
|
||||
f. __Exceptions and Limitations__ means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material.
|
||||
|
||||
g. __License Elements__ means the license attributes listed in the name of a Creative Commons Public License. The License Elements of this Public License are Attribution, NonCommercial, and ShareAlike.
|
||||
|
||||
h. __Licensed Material__ means the artistic or literary work, database, or other material to which the Licensor applied this Public License.
|
||||
|
||||
i. __Licensed Rights__ means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license.
|
||||
|
||||
j. __Licensor__ means the individual(s) or entity(ies) granting rights under this Public License.
|
||||
|
||||
k. __NonCommercial__ means not primarily intended for or directed towards commercial advantage or monetary compensation. For purposes of this Public License, the exchange of the Licensed Material for other material subject to Copyright and Similar Rights by digital file-sharing or similar means is NonCommercial provided there is no payment of monetary compensation in connection with the exchange.
|
||||
|
||||
l. __Share__ means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them.
|
||||
|
||||
m. __Sui Generis Database Rights__ means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world.
|
||||
|
||||
n. __You__ means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning.
|
||||
|
||||
### Section 2 – Scope.
|
||||
|
||||
a. ___License grant.___
|
||||
|
||||
1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to:
|
||||
|
||||
A. reproduce and Share the Licensed Material, in whole or in part, for NonCommercial purposes only; and
|
||||
|
||||
B. produce, reproduce, and Share Adapted Material for NonCommercial purposes only.
|
||||
|
||||
2. __Exceptions and Limitations.__ For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions.
|
||||
|
||||
3. __Term.__ The term of this Public License is specified in Section 6(a).
|
||||
|
||||
4. __Media and formats; technical modifications allowed.__ The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material.
|
||||
|
||||
5. __Downstream recipients.__
|
||||
|
||||
A. __Offer from the Licensor – Licensed Material.__ Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License.
|
||||
|
||||
B. __Additional offer from the Licensor – Adapted Material.__ Every recipient of Adapted Material from You automatically receives an offer from the Licensor to exercise the Licensed Rights in the Adapted Material under the conditions of the Adapter’s License You apply.
|
||||
|
||||
C. __No downstream restrictions.__ You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material.
|
||||
|
||||
6. __No endorsement.__ Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i).
|
||||
|
||||
b. ___Other rights.___
|
||||
|
||||
1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise.
|
||||
|
||||
2. Patent and trademark rights are not licensed under this Public License.
|
||||
|
||||
3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties, including when the Licensed Material is used other than for NonCommercial purposes.
|
||||
|
||||
### Section 3 – License Conditions.
|
||||
|
||||
Your exercise of the Licensed Rights is expressly made subject to the following conditions.
|
||||
|
||||
a. ___Attribution.___
|
||||
|
||||
1. If You Share the Licensed Material (including in modified form), You must:
|
||||
|
||||
A. retain the following if it is supplied by the Licensor with the Licensed Material:
|
||||
|
||||
i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated);
|
||||
|
||||
ii. a copyright notice;
|
||||
|
||||
iii. a notice that refers to this Public License;
|
||||
|
||||
iv. a notice that refers to the disclaimer of warranties;
|
||||
|
||||
v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable;
|
||||
|
||||
B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and
|
||||
|
||||
C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License.
|
||||
|
||||
2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information.
|
||||
|
||||
3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable.
|
||||
|
||||
b. ___ShareAlike.___
|
||||
|
||||
In addition to the conditions in Section 3(a), if You Share Adapted Material You produce, the following conditions also apply.
|
||||
|
||||
1. The Adapter’s License You apply must be a Creative Commons license with the same License Elements, this version or later, or a BY-NC-SA Compatible License.
|
||||
|
||||
2. You must include the text of, or the URI or hyperlink to, the Adapter's License You apply. You may satisfy this condition in any reasonable manner based on the medium, means, and context in which You Share Adapted Material.
|
||||
|
||||
3. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, Adapted Material that restrict exercise of the rights granted under the Adapter's License You apply.
|
||||
|
||||
### Section 4 – Sui Generis Database Rights.
|
||||
|
||||
Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material:
|
||||
|
||||
a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database for NonCommercial purposes only;
|
||||
|
||||
b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material, including for purposes of Section 3(b); and
|
||||
|
||||
c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database.
|
||||
|
||||
For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights.
|
||||
|
||||
### Section 5 – Disclaimer of Warranties and Limitation of Liability.
|
||||
|
||||
a. __Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.__
|
||||
|
||||
b. __To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.__
|
||||
|
||||
c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability.
|
||||
|
||||
### Section 6 – Term and Termination.
|
||||
|
||||
a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically.
|
||||
|
||||
b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates:
|
||||
|
||||
1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or
|
||||
|
||||
2. upon express reinstatement by the Licensor.
|
||||
|
||||
For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License.
|
||||
|
||||
c. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License.
|
||||
|
||||
d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
|
||||
|
||||
### Section 7 – Other Terms and Conditions.
|
||||
|
||||
a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed.
|
||||
|
||||
b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License.
|
||||
|
||||
### Section 8 – Interpretation.
|
||||
|
||||
a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License.
|
||||
|
||||
b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions.
|
||||
|
||||
c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor.
|
||||
|
||||
d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority.
|
||||
|
||||
> Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at [creativecommons.org/policies](http://creativecommons.org/policies), Creative Commons does not authorize the use of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses.
|
||||
>
|
||||
> Creative Commons may be contacted at creativecommons.org
|
||||
@@ -1,20 +0,0 @@
|
||||
const hyperionModule = {
|
||||
chain: '*',
|
||||
contract: 'eosio',
|
||||
action: 'buyram',
|
||||
defineQueryPrefix: 'buyram',
|
||||
parser_version: ['3.2', '2.1', '1.8', '1.7'],
|
||||
handler: (action) => {
|
||||
const data = action['act']['data'];
|
||||
action['@buyram'] = {
|
||||
payer: data['payer'],
|
||||
receiver: data['receiver'],
|
||||
};
|
||||
if (data['quant']) {
|
||||
action['@buyram']['quant'] = parseFloat(data['quant'].split(' ')[0]);
|
||||
}
|
||||
delete action['act']['data'];
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = {hyperionModule};
|
||||
@@ -1,20 +0,0 @@
|
||||
const hyperionModule = {
|
||||
chain: "*",
|
||||
contract: 'eosio',
|
||||
action: 'buyrex',
|
||||
defineQueryPrefix: 'buyrex',
|
||||
parser_version: ['3.2', '2.1','1.8','1.7'],
|
||||
handler: (action) => {
|
||||
const data = action['act']['data'];
|
||||
let qtd = null;
|
||||
if (data['amount']) {
|
||||
qtd = parseFloat(data['amount'].split(' ')[0]);
|
||||
}
|
||||
action['@buyrex'] = {
|
||||
amount: qtd,
|
||||
from: data['from']
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = {hyperionModule};
|
||||
@@ -1,34 +0,0 @@
|
||||
const config = require(`../../${process.env.CONFIG_JSON}`);
|
||||
|
||||
const hyperionModule = {
|
||||
chain: '*',
|
||||
contract: '*',
|
||||
action: 'transfer',
|
||||
parser_version: ['3.2', '2.1', '1.8', '1.7'],
|
||||
defineQueryPrefix: 'transfer',
|
||||
handler: (action) => {
|
||||
let qtd = null;
|
||||
const data = action['act']['data'];
|
||||
if (data['quantity'] && typeof data['quantity'] === 'string') {
|
||||
qtd = data['quantity'].split(' ');
|
||||
} else if (data['value'] && typeof data['value'] === 'string') {
|
||||
qtd = data['value'].split(' ');
|
||||
}
|
||||
if (qtd) {
|
||||
action['@transfer'] = {
|
||||
from: String(data['from']),
|
||||
to: String(data['to']),
|
||||
amount: parseFloat(qtd[0]),
|
||||
symbol: qtd[1],
|
||||
};
|
||||
delete data['from'];
|
||||
delete data['to'];
|
||||
if (config.features['index_transfer_memo']) {
|
||||
action['@transfer']['memo'] = data['memo'];
|
||||
delete data['memo'];
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = {hyperionModule};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user