Skip to content

Commit 276216c

Browse files
authored
Merge pull request #2 from SmartArray/1.4.1
2 parents a788106 + 2a2516f commit 276216c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+22498
-2
lines changed

.eslintignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
**/node_modules/**
2+
**/dist

.eslintrc.json

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"parserOptions": {
3+
"ecmaVersion": 8,
4+
"sourceType": "module"
5+
},
6+
"rules": {
7+
"semi": "error"
8+
}
9+
}

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
**/node_modules

LICENSE.txt

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Copyright (c) 2020 DigiByte Foundation NZ Limited
2+
3+
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:
4+
5+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6+
7+
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.

README.md

+88-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,88 @@
1-
# digibyte-rosetta-nodeapi
2-
Coinbase Rosetta Node API Implementation
1+
<p align="center">
2+
<a href="https://www.rosetta-api.org">
3+
<img width="90%" alt="Rosetta" src="https://www.rosetta-api.org/img/rosetta_header.png">
4+
</a>
5+
</p>
6+
<h3 align="center">
7+
Rosetta SDK
8+
</h3>
9+
<p align="center">
10+
NodeJS Rosetta SDK to create and interact with Rosetta API Implementations
11+
</p>
12+
<p align="center">
13+
<!--<a href="https://circleci.com/gh/DigiByte-Core/digibyte-rosetta-nodeapi/tree/master"><img src="https://circleci.com/gh/DigiByte-Core/digibyte-rosetta-nodeapi/tree/master.svg?style=shield" /></a>-->
14+
<a href="https://coveralls.io/github/DigiByte-Core/digibyte-rosetta-nodeapi"><img src="https://coveralls.io/repos/github/DigiByte-Core/digibyte-rosetta-nodeapi/badge.svg" /></a>
15+
<a href="https://github.com/DigiByte-Core/digibyte-rosetta-nodeapi/blob/master/LICENSE.txt"><img src="https://img.shields.io/github/license/DigiByte-Core/digibyte-rosetta-nodeapi.svg" /></a>
16+
</p>
17+
18+
# RosettaSDK (JS) [experimental]
19+
Supported Rosetta Protocol Version: 1.4.1
20+
21+
This project is a port of the official Go reference implementation. All features, except a [few exceptions](docs/api_limitations.md), have been ported to JS.
22+
23+
⚠️ WARNING ⚠️
24+
Due to the lack of funding, I wasn't able to continue the work on `rosetta-node-sdk`.
25+
26+
## Motivation
27+
Coinbase's [Official Go Reference Implementation](https://github.com/coinbase/rosetta-sdk-go.git) is a thouroughly tested and wonderful SDK Implementation. However, as many developers are better suited to use NodeJS/Javascript, DigiByte decided to port the reference implementation to NodeJS while maintaining support for all it's core components.
28+
29+
## Documentation
30+
31+
### Prerequisites
32+
- NodeJS >= 10.6
33+
- NPM >= 6.10.0
34+
35+
The code was written on a Mac, so assuming all should work smoothly on Linux-based computers. However, there is no reason not to run this library on Windows-based machines. If you find an OS-related problem, please open an issue and it will be resolved.
36+
37+
### Installation
38+
```bash
39+
npm install --save rosetta-node-sdk
40+
```
41+
42+
### Tests
43+
This project is thoroughly tested using > 300 automated tests. Run `npm run test` to see how they all work out.
44+
45+
### Usage
46+
All Core components are accessible as follows:
47+
```Javascript
48+
const RosettaSDK = require('rosetta-node-sdk');
49+
const {
50+
Asserter,
51+
Server,
52+
Reconciler,
53+
Client,
54+
Fetcher,
55+
Syncer,
56+
Parser,
57+
SyncerEvents,
58+
Errors,
59+
60+
Utils,
61+
InternalModels,
62+
63+
logger,
64+
65+
version, // '1.4.1'
66+
} = RosettaSDK;
67+
```
68+
69+
### Components
70+
- **Asserter** - Syntactical and semantical type validator. This Asserter can be used to validate Requests/Responses. Constructors exist that ease the creation of an asserter. For example, `NewClientWithResponses` can be used in order to create a server validator by only passing the network responses.
71+
- **Server** - The Server Component eases the development of a custom server implementation. Examples on how to build such a server are located in [examples](./examples).
72+
- **Reconciler** - Use the Reconciler in order to validate that the balances computed by parsing the blocks are the equal to the balances computed by a node.
73+
- **Client** - Client request library [`rosetta-node-sdk-client`](https://github.com/SmartArray/rosetta-node-sdk-client)
74+
- **Fetcher** - Convenience Wrapper Class for `Client`
75+
- **Syncer** - Makes use of `Fetcher` class in order to download blocks in logical order.
76+
- **Parser** - Parses and groups BalanceOperations of a block.
77+
- **SyncerEvents** - Syncer Events. Mainly `BLOCK_ADDED`, `BLOCK_REMOVED`, `SYNC_CANCELLED`
78+
- **Errors** - Error Classes for the different components: `AsserterError`, `FetcherError`, `InputError`, `ParserError`, `InternalError`, `ReconcilerError`, `SyncerError`.
79+
- **Utils** - Utility functions, commonly used internally by the core components.
80+
- **InternalModels** - Models, that are commonly used internally.
81+
- **logger** - Default Logger Singleton Class.
82+
- **version** - Specifies the version of this SDK. This semver is equal to the Rosetta API SDK for convencience.
83+
84+
### ToDos
85+
- [ ] Setup CI (`npm run test` will execute 313 tests)
86+
- [ ] Support `keys` (cryptographic API)
87+
- [ ] Documentation
88+
- [ ] Test Reconciler in live environment

docs/api_limitations.md

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# API Limitations
2+
This Rosetta JS SDK contains a port of every essential core component that is available in the offical Go reference implementation, except a few exceptions:
3+
4+
☑️ Asserter
5+
☑️ Controllers
6+
☑️ Fetcher
7+
☑️ Parser
8+
☑️ Reconciler
9+
☑️ Server
10+
❌ Keys (may be ported to NodeJS in future)
11+
12+
# Client Package
13+
This project makes extensive use of the Rosetta Client Library [`rosetta-node-sdk-client`](https://github.com/SmartArray/rosetta-node-sdk-client), that was generated with the OpenAPI Generator.
14+
It does not contain TypeScript Wrappers. So if you want to use Typescript Classes for your server implementation, you should generate your own using the OpenAPI Generator Toolsuite.

examples/basic/README.md

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Basic Example Server
2+
is directory demonstrates how to write a Rosetta Node server and how
3+
to use either the Client package or Fetcher package to communicate
4+
with that server.
5+
6+
Each subdirectory contains a separate project.
7+
The projects were all ported from Go, to maintain maintability.
8+
9+
## Steps
10+
1. Run `node server`
11+
2. Run `node client` (in a new terminal window)
12+
2. Run `node fetcher` (in a new terminal window)

examples/basic/client/index.js

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/**
2+
* Copyright (c) 2020 DigiByte Foundation NZ Limited
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy of
5+
* this software and associated documentation files (the "Software"), to deal in
6+
* the Software without restriction, including without limitation the rights to
7+
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8+
* the Software, and to permit persons to whom the Software is furnished to do so,
9+
* subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in all
12+
* copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16+
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18+
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20+
*/
21+
22+
const RosettaSDK = require('../../..');
23+
const RosettaClient = RosettaSDK.Client;
24+
25+
// Create an instance of APIClient and configure it.
26+
const APIClient = new RosettaClient.ApiClient();
27+
APIClient.basePath = 'http://localhost:8080';
28+
APIClient.agent = 'rosetta-sdk-node';
29+
APIClient.timeout = 10 * 1000; // 10 seconds
30+
31+
async function startClient() {
32+
// Step1: Create an instance of RosettaSDK Client
33+
const networkAPI = new RosettaClient.NetworkApi(APIClient).promises;
34+
35+
// Step 2: Get all available networks
36+
const metadataRequest = new RosettaClient.MetadataRequest();
37+
const networkList = await networkAPI.networkList(metadataRequest);
38+
if (networkList.network_identifiers.length == 0) {
39+
console.error('Server did not respond with any network identifier');
40+
return;
41+
}
42+
43+
// Step 3: Print the primary network
44+
const primaryNetwork = networkList.network_identifiers[0];
45+
console.log(`Primary Network: ${primaryNetwork}`);
46+
47+
// Step 4: Fetch the network status
48+
const networkRequest = new RosettaClient.NetworkRequest(primaryNetwork);
49+
const networkStatus = await networkAPI.networkStatus(networkRequest);
50+
51+
// Step 5: Print Network Status
52+
console.log(`Network Status: ${networkStatus}`);
53+
54+
// Step 6: Asserter (ToDo?)
55+
// Response Assertions are already handled by the server.
56+
57+
// Step 7: Fetch the Network Options
58+
const networkOptions = await networkAPI.networkOptions(networkRequest);
59+
60+
// Step 8: Print Network Options
61+
console.log(`Network Options: ${networkOptions}`);
62+
63+
// Step 9: Asserter (ToDo?), refer to step 6.
64+
// Step 10: ClientAsserter, refer to step 6.
65+
// ...
66+
67+
// Step 11: Fetch current block
68+
const blockIdentifier = RosettaClient.PartialBlockIdentifier.constructFromObject({
69+
hash: networkStatus.current_block_identifier,
70+
});
71+
const blockRequest = new RosettaClient.BlockRequest(primaryNetwork, blockIdentifier);
72+
const block = await networkAPI.block(blockRequest);
73+
74+
// Step 12: Print the block
75+
console.log(`Current Block: ${block}`);
76+
77+
// Step 13: Assert the block response is valid, refer to step 6
78+
79+
// Step 14: Print transactions in that block
80+
block.OtherTransactions.forEach(tx => {
81+
console.log(` Transaction: ${tx}`);
82+
});
83+
};
84+
85+
startClient()
86+
.catch(e => console.error(e));

examples/basic/fetcher/index.js

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/**
2+
* Copyright (c) 2020 DigiByte Foundation NZ Limited
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy of
5+
* this software and associated documentation files (the "Software"), to deal in
6+
* the Software without restriction, including without limitation the rights to
7+
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8+
* the Software, and to permit persons to whom the Software is furnished to do so,
9+
* subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in all
12+
* copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16+
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18+
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20+
*/
21+
22+
const RosettaSDK = require('../../..');
23+
24+
// Create an instance of Fetcher
25+
const fetcher = new RosettaSDK.Fetcher({
26+
server: {
27+
protocol: 'http',
28+
host: 'localhost',
29+
port: '8080',
30+
},
31+
});
32+
33+
const main = (async function () {
34+
const { primaryNetwork, networkStatus } = await fetcher.initializeAsserter();
35+
36+
console.log(`Primary Network: ${JSON.stringify(primaryNetwork)}`);
37+
console.log(`Network Status: ${JSON.stringify(networkStatus)}`);
38+
39+
const block = await fetcher.blockRetry(
40+
primaryNetwork,
41+
new RosettaSDK.Utils.constructPartialBlockIdentifier(networkStatus.current_block_identifier),
42+
);
43+
44+
console.log(`Current Block: ${JSON.stringify(block)}`);
45+
46+
const blockMap = fetcher.blockRange(
47+
primaryNetwork,
48+
networkStatus.genesis_block_identifier.index,
49+
networkStatus.genesis_block_identifier.index + 10,
50+
);
51+
52+
console.log(`Current Range: ${JSON.stringify(blockMap)}`);
53+
});
54+
55+
main().catch(e => {
56+
console.error(e);
57+
})

examples/basic/server/index.js

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* Copyright (c) 2020 DigiByte Foundation NZ Limited
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy of
5+
* this software and associated documentation files (the "Software"), to deal in
6+
* the Software without restriction, including without limitation the rights to
7+
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8+
* the Software, and to permit persons to whom the Software is furnished to do so,
9+
* subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in all
12+
* copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16+
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18+
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20+
*/
21+
22+
const RosettaSDK = require('../../..');
23+
24+
const ServiceHandlers = require('./services');
25+
const networkIdentifier = require('./network');
26+
27+
const asserter = RosettaSDK.Asserter.NewServer(
28+
['Transfer', 'Reward'],
29+
false,
30+
[networkIdentifier],
31+
);
32+
33+
/* Create a server configuration */
34+
const Server = new RosettaSDK.Server({
35+
URL_PORT: 8080,
36+
});
37+
38+
// Register global asserter
39+
Server.useAsserter(asserter);
40+
41+
/* Data API: Network */
42+
Server.register('/network/list', ServiceHandlers.Network.networkList);
43+
Server.register('/network/options', ServiceHandlers.Network.networkOptions);
44+
Server.register('/network/status', ServiceHandlers.Network.networkStatus);
45+
46+
/* Data API: Block */
47+
Server.register('/block', ServiceHandlers.Block.block);
48+
Server.register('/block/transaction', ServiceHandlers.Block.blockTransaction);

examples/basic/server/network.js

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* Copyright (c) 2020 DigiByte Foundation NZ Limited
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy of
5+
* this software and associated documentation files (the "Software"), to deal in
6+
* the Software without restriction, including without limitation the rights to
7+
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
8+
* the Software, and to permit persons to whom the Software is furnished to do so,
9+
* subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in all
12+
* copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
16+
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
17+
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
18+
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20+
*/
21+
22+
const RosettaSDK = require('../../..');
23+
const networkIdentifier = new RosettaSDK.Client.NetworkIdentifier('Rosetta', 'Testnet');
24+
25+
module.exports = networkIdentifier;

0 commit comments

Comments
 (0)