@rosen-bridge/bitcoin-scanner 0.1.0-52fc0239

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/.eslintignore +1 -0
  2. package/CHANGELOG.md +11 -0
  3. package/README.md +24 -0
  4. package/dist/index.d.ts +9 -0
  5. package/dist/index.d.ts.map +1 -0
  6. package/dist/index.js +9 -0
  7. package/dist/network/BitcoinRpcNetwork.d.ts +30 -0
  8. package/dist/network/BitcoinRpcNetwork.d.ts.map +1 -0
  9. package/dist/network/BitcoinRpcNetwork.js +88 -0
  10. package/dist/network/DogeRpcNetwork.d.ts +30 -0
  11. package/dist/network/DogeRpcNetwork.d.ts.map +1 -0
  12. package/dist/network/DogeRpcNetwork.js +88 -0
  13. package/dist/network/EsploraNetwork.d.ts +28 -0
  14. package/dist/network/EsploraNetwork.d.ts.map +1 -0
  15. package/dist/network/EsploraNetwork.js +64 -0
  16. package/dist/scanner/BitcoinEsploraScanner.d.ts +6 -0
  17. package/dist/scanner/BitcoinEsploraScanner.d.ts.map +1 -0
  18. package/dist/scanner/BitcoinEsploraScanner.js +7 -0
  19. package/dist/scanner/BitcoinRpcScanner.d.ts +6 -0
  20. package/dist/scanner/BitcoinRpcScanner.d.ts.map +1 -0
  21. package/dist/scanner/BitcoinRpcScanner.js +7 -0
  22. package/dist/scanner/DogeEsploraScanner.d.ts +6 -0
  23. package/dist/scanner/DogeEsploraScanner.d.ts.map +1 -0
  24. package/dist/scanner/DogeEsploraScanner.js +7 -0
  25. package/dist/scanner/DogeRpcScanner.d.ts +6 -0
  26. package/dist/scanner/DogeRpcScanner.d.ts.map +1 -0
  27. package/dist/scanner/DogeRpcScanner.js +7 -0
  28. package/dist/types.d.ts +142 -0
  29. package/dist/types.d.ts.map +1 -0
  30. package/dist/types.js +2 -0
  31. package/lib/index.ts +8 -0
  32. package/lib/network/BitcoinRpcNetwork.ts +111 -0
  33. package/lib/network/DogeRpcNetwork.ts +112 -0
  34. package/lib/network/EsploraNetwork.ts +92 -0
  35. package/lib/scanner/BitcoinEsploraScanner.ts +15 -0
  36. package/lib/scanner/BitcoinRpcScanner.ts +16 -0
  37. package/lib/scanner/DogeEsploraScanner.ts +15 -0
  38. package/lib/scanner/DogeRpcScanner.ts +16 -0
  39. package/lib/types.ts +155 -0
  40. package/package.json +35 -0
  41. package/tests/bitcoinEsploraTestData.ts +1773 -0
  42. package/tests/bitcoinRpcTestData.ts +305 -0
  43. package/tests/dogeRpcTestData.ts +659 -0
  44. package/tests/mocked/axiosEsplora.mock.ts +28 -0
  45. package/tests/mocked/axiosRpc.mock.ts +28 -0
  46. package/tests/network/BitcoinRpcNetwork.spec.ts +112 -0
  47. package/tests/network/DogeRpcNetwork.spec.ts +111 -0
  48. package/tests/network/EsploraNetwork.spec.ts +106 -0
  49. package/tsconfig.build.json +11 -0
  50. package/tsconfig.build.tsbuildinfo +1 -0
  51. package/tsconfig.json +11 -0
  52. package/vitest.config.ts +18 -0
@@ -0,0 +1,142 @@
1
+ export interface EsploraBlock {
2
+ id: string;
3
+ height: number;
4
+ version: number;
5
+ timestamp: number;
6
+ tx_count: number;
7
+ size: number;
8
+ weight: number;
9
+ merkle_root: string;
10
+ previousblockhash: string;
11
+ mediantime: number;
12
+ nonce: number;
13
+ bits: number;
14
+ difficulty: number;
15
+ }
16
+ export interface EsploraTxInput {
17
+ txid: string;
18
+ vout: number;
19
+ prevout: {
20
+ scriptpubkey: string;
21
+ scriptpubkey_asm: string;
22
+ scriptpubkey_type: string;
23
+ scriptpubkey_address: string;
24
+ value: number;
25
+ };
26
+ scriptsig: string;
27
+ scriptsig_asm: string;
28
+ is_coinbase: false;
29
+ sequence: number;
30
+ }
31
+ export interface EsploraTxOutput {
32
+ scriptpubkey: string;
33
+ scriptpubkey_asm: string;
34
+ scriptpubkey_type: string;
35
+ scriptpubkey_address: string;
36
+ value: number;
37
+ }
38
+ export interface BitcoinEsploraTransaction {
39
+ txid: string;
40
+ version: number;
41
+ locktime: number;
42
+ vin: Array<EsploraTxInput>;
43
+ vout: Array<EsploraTxOutput>;
44
+ size: number;
45
+ weight: number;
46
+ fee: number;
47
+ status: {
48
+ confirmed: true;
49
+ block_height: number;
50
+ block_hash: string;
51
+ block_time: number;
52
+ };
53
+ }
54
+ export type JsonRpcResult = {
55
+ id: string;
56
+ result: unknown;
57
+ };
58
+ export type JsonRpcError = {
59
+ id: string;
60
+ error: {
61
+ code: number;
62
+ message?: string;
63
+ data?: unknown;
64
+ };
65
+ };
66
+ export interface BlockHeader {
67
+ hash: string;
68
+ height: number;
69
+ time: number;
70
+ nTx: number;
71
+ previousblockhash: string;
72
+ }
73
+ export interface BlockChainInfo {
74
+ blocks: number;
75
+ bestblockhash: string;
76
+ }
77
+ export interface BitcoinRpcTxInput {
78
+ txid: string;
79
+ vout: number;
80
+ scriptSig: {
81
+ asm: string;
82
+ hex: string;
83
+ };
84
+ txinwitness: Array<string>;
85
+ sequence: number;
86
+ }
87
+ export interface BitcoinRpcTxOutput {
88
+ value: number;
89
+ n: number;
90
+ scriptPubKey: {
91
+ asm: string;
92
+ hex: string;
93
+ };
94
+ }
95
+ export interface BitcoinRpcTransaction {
96
+ txid: string;
97
+ hash: string;
98
+ version: number;
99
+ size: number;
100
+ vsize: number;
101
+ weight: number;
102
+ locktime: number;
103
+ vin: Array<BitcoinRpcTxInput>;
104
+ vout: Array<BitcoinRpcTxOutput>;
105
+ hex: string;
106
+ }
107
+ export interface DogeBlockSummary {
108
+ hash: string;
109
+ height: number;
110
+ time: number;
111
+ previousblockhash: string;
112
+ tx: Array<string>;
113
+ }
114
+ export interface DogeRpcTxInput {
115
+ txid: string;
116
+ vout: number;
117
+ scriptSig: {
118
+ asm: string;
119
+ hex: string;
120
+ };
121
+ sequence: number;
122
+ }
123
+ export interface DogeRpcTxOutput {
124
+ value: number;
125
+ n: number;
126
+ scriptPubKey: {
127
+ asm: string;
128
+ hex: string;
129
+ type: string;
130
+ };
131
+ }
132
+ export interface DogeRpcTransaction {
133
+ txid: string;
134
+ hash: string;
135
+ version: number;
136
+ size: number;
137
+ vsize: number;
138
+ locktime: number;
139
+ vin: Array<DogeRpcTxInput>;
140
+ vout: Array<DogeRpcTxOutput>;
141
+ }
142
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../lib/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9saWIvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBpbnRlcmZhY2UgRXNwbG9yYUJsb2NrIHtcbiAgaWQ6IHN0cmluZztcbiAgaGVpZ2h0OiBudW1iZXI7XG4gIHZlcnNpb246IG51bWJlcjtcbiAgdGltZXN0YW1wOiBudW1iZXI7XG4gIHR4X2NvdW50OiBudW1iZXI7XG4gIHNpemU6IG51bWJlcjtcbiAgd2VpZ2h0OiBudW1iZXI7XG4gIG1lcmtsZV9yb290OiBzdHJpbmc7XG4gIHByZXZpb3VzYmxvY2toYXNoOiBzdHJpbmc7XG4gIG1lZGlhbnRpbWU6IG51bWJlcjtcbiAgbm9uY2U6IG51bWJlcjtcbiAgYml0czogbnVtYmVyO1xuICBkaWZmaWN1bHR5OiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgRXNwbG9yYVR4SW5wdXQge1xuICB0eGlkOiBzdHJpbmc7XG4gIHZvdXQ6IG51bWJlcjtcbiAgcHJldm91dDoge1xuICAgIHNjcmlwdHB1YmtleTogc3RyaW5nO1xuICAgIHNjcmlwdHB1YmtleV9hc206IHN0cmluZztcbiAgICBzY3JpcHRwdWJrZXlfdHlwZTogc3RyaW5nO1xuICAgIHNjcmlwdHB1YmtleV9hZGRyZXNzOiBzdHJpbmc7XG4gICAgdmFsdWU6IG51bWJlcjtcbiAgfTtcbiAgc2NyaXB0c2lnOiBzdHJpbmc7XG4gIHNjcmlwdHNpZ19hc206IHN0cmluZztcbiAgaXNfY29pbmJhc2U6IGZhbHNlO1xuICBzZXF1ZW5jZTogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEVzcGxvcmFUeE91dHB1dCB7XG4gIHNjcmlwdHB1YmtleTogc3RyaW5nO1xuICBzY3JpcHRwdWJrZXlfYXNtOiBzdHJpbmc7XG4gIHNjcmlwdHB1YmtleV90eXBlOiBzdHJpbmc7XG4gIHNjcmlwdHB1YmtleV9hZGRyZXNzOiBzdHJpbmc7XG4gIHZhbHVlOiBudW1iZXI7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQml0Y29pbkVzcGxvcmFUcmFuc2FjdGlvbiB7XG4gIHR4aWQ6IHN0cmluZztcbiAgdmVyc2lvbjogbnVtYmVyO1xuICBsb2NrdGltZTogbnVtYmVyO1xuICB2aW46IEFycmF5PEVzcGxvcmFUeElucHV0PjtcbiAgdm91dDogQXJyYXk8RXNwbG9yYVR4T3V0cHV0PjtcbiAgc2l6ZTogbnVtYmVyO1xuICB3ZWlnaHQ6IG51bWJlcjtcbiAgZmVlOiBudW1iZXI7XG4gIHN0YXR1czoge1xuICAgIGNvbmZpcm1lZDogdHJ1ZTtcbiAgICBibG9ja19oZWlnaHQ6IG51bWJlcjtcbiAgICBibG9ja19oYXNoOiBzdHJpbmc7XG4gICAgYmxvY2tfdGltZTogbnVtYmVyO1xuICB9O1xufVxuXG5leHBvcnQgdHlwZSBKc29uUnBjUmVzdWx0ID0ge1xuICBpZDogc3RyaW5nO1xuICByZXN1bHQ6IHVua25vd247XG59O1xuXG5leHBvcnQgdHlwZSBKc29uUnBjRXJyb3IgPSB7XG4gIGlkOiBzdHJpbmc7XG4gIGVycm9yOiB7XG4gICAgY29kZTogbnVtYmVyO1xuICAgIG1lc3NhZ2U/OiBzdHJpbmc7XG4gICAgZGF0YT86IHVua25vd247XG4gIH07XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIEJsb2NrSGVhZGVyIHtcbiAgaGFzaDogc3RyaW5nO1xuICBoZWlnaHQ6IG51bWJlcjtcbiAgdGltZTogbnVtYmVyO1xuICBuVHg6IG51bWJlcjtcbiAgcHJldmlvdXNibG9ja2hhc2g6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBCbG9ja0NoYWluSW5mbyB7XG4gIGJsb2NrczogbnVtYmVyO1xuICBiZXN0YmxvY2toYXNoOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQml0Y29pblJwY1R4SW5wdXQge1xuICB0eGlkOiBzdHJpbmc7XG4gIHZvdXQ6IG51bWJlcjtcbiAgc2NyaXB0U2lnOiB7XG4gICAgYXNtOiBzdHJpbmc7XG4gICAgaGV4OiBzdHJpbmc7XG4gIH07XG4gIHR4aW53aXRuZXNzOiBBcnJheTxzdHJpbmc+O1xuICBzZXF1ZW5jZTogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJpdGNvaW5ScGNUeE91dHB1dCB7XG4gIHZhbHVlOiBudW1iZXI7XG4gIG46IG51bWJlcjtcbiAgc2NyaXB0UHViS2V5OiB7XG4gICAgYXNtOiBzdHJpbmc7XG4gICAgaGV4OiBzdHJpbmc7XG4gIH07XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQml0Y29pblJwY1RyYW5zYWN0aW9uIHtcbiAgdHhpZDogc3RyaW5nO1xuICBoYXNoOiBzdHJpbmc7XG4gIHZlcnNpb246IG51bWJlcjtcbiAgc2l6ZTogbnVtYmVyO1xuICB2c2l6ZTogbnVtYmVyO1xuICB3ZWlnaHQ6IG51bWJlcjtcbiAgbG9ja3RpbWU6IG51bWJlcjtcbiAgdmluOiBBcnJheTxCaXRjb2luUnBjVHhJbnB1dD47XG4gIHZvdXQ6IEFycmF5PEJpdGNvaW5ScGNUeE91dHB1dD47XG4gIGhleDogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIERvZ2VCbG9ja1N1bW1hcnkge1xuICBoYXNoOiBzdHJpbmc7XG4gIGhlaWdodDogbnVtYmVyO1xuICB0aW1lOiBudW1iZXI7XG4gIHByZXZpb3VzYmxvY2toYXNoOiBzdHJpbmc7XG4gIHR4OiBBcnJheTxzdHJpbmc+O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIERvZ2VScGNUeElucHV0IHtcbiAgdHhpZDogc3RyaW5nO1xuICB2b3V0OiBudW1iZXI7XG4gIHNjcmlwdFNpZzoge1xuICAgIGFzbTogc3RyaW5nO1xuICAgIGhleDogc3RyaW5nO1xuICB9O1xuICBzZXF1ZW5jZTogbnVtYmVyO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIERvZ2VScGNUeE91dHB1dCB7XG4gIHZhbHVlOiBudW1iZXI7XG4gIG46IG51bWJlcjtcbiAgc2NyaXB0UHViS2V5OiB7XG4gICAgYXNtOiBzdHJpbmc7XG4gICAgaGV4OiBzdHJpbmc7XG4gICAgdHlwZTogc3RyaW5nO1xuICB9O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIERvZ2VScGNUcmFuc2FjdGlvbiB7XG4gIHR4aWQ6IHN0cmluZztcbiAgaGFzaDogc3RyaW5nO1xuICB2ZXJzaW9uOiBudW1iZXI7XG4gIHNpemU6IG51bWJlcjtcbiAgdnNpemU6IG51bWJlcjtcbiAgbG9ja3RpbWU6IG51bWJlcjtcbiAgdmluOiBBcnJheTxEb2dlUnBjVHhJbnB1dD47XG4gIHZvdXQ6IEFycmF5PERvZ2VScGNUeE91dHB1dD47XG59XG4iXX0=
package/lib/index.ts ADDED
@@ -0,0 +1,8 @@
1
+ export { BitcoinEsploraScanner } from './scanner/BitcoinEsploraScanner';
2
+ export * from './types';
3
+ export { DogeEsploraScanner } from './scanner/DogeEsploraScanner';
4
+ export { EsploraNetwork } from './network/EsploraNetwork';
5
+ export * from './scanner/BitcoinRpcScanner';
6
+ export * from './scanner/DogeRpcScanner';
7
+ export * from './network/BitcoinRpcNetwork';
8
+ export * from './network/DogeRpcNetwork';
@@ -0,0 +1,111 @@
1
+ import axios, { Axios } from '@rosen-bridge/rate-limited-axios';
2
+ import {
3
+ AbstractNetworkConnector,
4
+ Block,
5
+ } from '@rosen-bridge/scanner-interfaces';
6
+ import { BitcoinRpcTransaction, BlockHeader, JsonRpcResult } from '../types';
7
+
8
+ import { randomBytes } from 'crypto';
9
+
10
+ export class BitcoinRpcNetwork extends AbstractNetworkConnector<BitcoinRpcTransaction> {
11
+ private readonly url: string;
12
+ private readonly timeout: number;
13
+ private client: Axios;
14
+
15
+ constructor(
16
+ url: string,
17
+ timeout: number,
18
+ auth?: {
19
+ username: string;
20
+ password: string;
21
+ }
22
+ ) {
23
+ super();
24
+ this.url = url;
25
+ this.timeout = timeout;
26
+ this.client = axios.create({
27
+ baseURL: this.url,
28
+ timeout: this.timeout,
29
+ headers: { 'Content-Type': 'application/json' },
30
+ auth: auth,
31
+ });
32
+ }
33
+
34
+ private generateRandomId = () => randomBytes(32).toString('hex');
35
+
36
+ /**
37
+ * Returns block at height
38
+ * @param height
39
+ * @returns Block
40
+ */
41
+ getBlockAtHeight = async (height: number): Promise<Block> => {
42
+ const randomId1 = this.generateRandomId();
43
+ // get block hash using block height
44
+ const blockHashResponse = await this.client.post<JsonRpcResult>('', {
45
+ method: 'getblockhash',
46
+ id: randomId1,
47
+ params: [height],
48
+ });
49
+ if (blockHashResponse.data.id !== randomId1)
50
+ throw Error(`UnexpectedBehavior: Request and response id are different`);
51
+ const blockHash = blockHashResponse.data.result;
52
+
53
+ const randomId2 = this.generateRandomId();
54
+ // get block headers using block hash
55
+ const blockHeaderResponse = await this.client.post<JsonRpcResult>('', {
56
+ method: 'getblockheader',
57
+ id: randomId2,
58
+ params: [blockHash, true],
59
+ });
60
+ if (blockHeaderResponse.data.id !== randomId2)
61
+ throw Error(`UnexpectedBehavior: Request and response id are different`);
62
+ const blockHeader: BlockHeader = blockHeaderResponse.data
63
+ .result as BlockHeader;
64
+ return {
65
+ parentHash: blockHeader.previousblockhash,
66
+ hash: blockHeader.hash,
67
+ height: blockHeader.height,
68
+ timestamp: blockHeader.time,
69
+ txCount: blockHeader.nTx,
70
+ };
71
+ };
72
+
73
+ /**
74
+ * Returns current network height
75
+ * @returns current height
76
+ */
77
+ getCurrentHeight = async (): Promise<number> => {
78
+ const randomId = this.generateRandomId();
79
+ const result = await this.client.post<JsonRpcResult>('', {
80
+ method: 'getblockchaininfo',
81
+ id: randomId,
82
+ params: [],
83
+ });
84
+ if (result.data.id !== randomId)
85
+ throw Error(`UnexpectedBehavior: Request and response id are different`);
86
+ return (result.data.result as { blocks: number }).blocks;
87
+ };
88
+
89
+ /**
90
+ * Return transactions in a block with specified hash
91
+ * @param blockHash
92
+ * @returns
93
+ */
94
+ getBlockTxs = async (
95
+ blockHash: string
96
+ ): Promise<Array<BitcoinRpcTransaction>> => {
97
+ const randomId = this.generateRandomId();
98
+ const blockHashResponse = await this.client.post<JsonRpcResult>('', {
99
+ method: 'getblock',
100
+ id: randomId,
101
+ params: [blockHash, 2], // verbosity should be 2 in order to retrieve full transaction info
102
+ });
103
+ if (blockHashResponse.data.id !== randomId)
104
+ throw Error(`UnexpectedBehavior: Request and response id are different`);
105
+ const blockTxs = (
106
+ blockHashResponse.data.result as { tx: Array<BitcoinRpcTransaction> }
107
+ ).tx;
108
+
109
+ return blockTxs;
110
+ };
111
+ }
@@ -0,0 +1,112 @@
1
+ import axios, { Axios } from '@rosen-bridge/rate-limited-axios';
2
+ import {
3
+ AbstractNetworkConnector,
4
+ Block,
5
+ } from '@rosen-bridge/scanner-interfaces';
6
+ import { DogeRpcTransaction, JsonRpcResult, DogeBlockSummary } from '../types';
7
+
8
+ import { randomBytes } from 'crypto';
9
+
10
+ export class DogeRpcNetwork extends AbstractNetworkConnector<DogeRpcTransaction> {
11
+ private readonly url: string;
12
+ private readonly timeout: number;
13
+ private client: Axios;
14
+
15
+ constructor(
16
+ url: string,
17
+ timeout: number,
18
+ auth?: {
19
+ username: string;
20
+ password: string;
21
+ }
22
+ ) {
23
+ super();
24
+ this.url = url;
25
+ this.timeout = timeout;
26
+ this.client = axios.create({
27
+ baseURL: this.url,
28
+ timeout: this.timeout,
29
+ headers: { 'Content-Type': 'application/json' },
30
+ auth: auth,
31
+ });
32
+ }
33
+
34
+ private generateRandomId = () => randomBytes(32).toString('hex');
35
+
36
+ /**
37
+ * Returns block at height
38
+ * @param height
39
+ * @returns Block
40
+ */
41
+ getBlockAtHeight = async (height: number): Promise<Block> => {
42
+ const randomId1 = this.generateRandomId();
43
+ // get block hash using block height
44
+ const blockHashResponse = await this.client.post<JsonRpcResult>('', {
45
+ method: 'getblockhash',
46
+ id: randomId1,
47
+ params: [height],
48
+ });
49
+ if (blockHashResponse.data.id !== randomId1)
50
+ throw Error(`UnexpectedBehavior: Request and response id are different`);
51
+ const blockHash = blockHashResponse.data.result;
52
+
53
+ const randomId2 = this.generateRandomId();
54
+ // get block headers using block hash
55
+ const blockSummaryResponse = await this.client.post<JsonRpcResult>('', {
56
+ method: 'getblock',
57
+ id: randomId2,
58
+ params: [blockHash, 1],
59
+ });
60
+ if (blockSummaryResponse.data.id !== randomId2)
61
+ throw Error(`UnexpectedBehavior: Request and response id are different`);
62
+ const blockSummary: DogeBlockSummary = blockSummaryResponse.data
63
+ .result as DogeBlockSummary;
64
+
65
+ return {
66
+ parentHash: blockSummary.previousblockhash,
67
+ hash: blockSummary.hash,
68
+ height: blockSummary.height,
69
+ timestamp: blockSummary.time,
70
+ txCount: blockSummary.tx.length,
71
+ };
72
+ };
73
+
74
+ /**
75
+ * Returns current network height
76
+ * @returns current height
77
+ */
78
+ getCurrentHeight = async (): Promise<number> => {
79
+ const randomId = this.generateRandomId();
80
+ const result = await this.client.post<JsonRpcResult>('', {
81
+ method: 'getblockchaininfo',
82
+ id: randomId,
83
+ params: [],
84
+ });
85
+ if (result.data.id !== randomId)
86
+ throw Error(`UnexpectedBehavior: Request and response id are different`);
87
+ return (result.data.result as { blocks: number }).blocks;
88
+ };
89
+
90
+ /**
91
+ * Return transactions in a block with specified hash
92
+ * @param blockHash
93
+ * @returns
94
+ */
95
+ getBlockTxs = async (
96
+ blockHash: string
97
+ ): Promise<Array<DogeRpcTransaction>> => {
98
+ const randomId = this.generateRandomId();
99
+ const blockHashResponse = await this.client.post<JsonRpcResult>('', {
100
+ method: 'getblock',
101
+ id: randomId,
102
+ params: [blockHash, 2], // verbosity should be 2 in order to retrieve full transaction info
103
+ });
104
+ if (blockHashResponse.data.id !== randomId)
105
+ throw Error(`UnexpectedBehavior: Request and response id are different`);
106
+ const blockTxs = (
107
+ blockHashResponse.data.result as { tx: Array<DogeRpcTransaction> }
108
+ ).tx;
109
+
110
+ return blockTxs;
111
+ };
112
+ }
@@ -0,0 +1,92 @@
1
+ import axios, { Axios } from '@rosen-bridge/rate-limited-axios';
2
+ import {
3
+ AbstractNetworkConnector,
4
+ Block,
5
+ } from '@rosen-bridge/scanner-interfaces';
6
+ import { BitcoinEsploraTransaction, EsploraBlock } from '../types';
7
+
8
+ export class EsploraNetwork extends AbstractNetworkConnector<BitcoinEsploraTransaction> {
9
+ private readonly url: string;
10
+ private readonly timeout: number;
11
+ private readonly ESPLORA_BLOCK_TXS_LIMIT = 25;
12
+ private client: Axios;
13
+ private apiPrefix: string;
14
+
15
+ constructor(url: string, timeout: number, apiPrefix?: string) {
16
+ super();
17
+ this.url = url;
18
+ this.timeout = timeout;
19
+ this.client = axios.create({
20
+ baseURL: this.url,
21
+ timeout: this.timeout,
22
+ headers: { 'Content-Type': 'application/json' },
23
+ });
24
+ this.apiPrefix = apiPrefix || '/api';
25
+ }
26
+
27
+ /**
28
+ * Returns block at height
29
+ * @param height
30
+ * @returns Block
31
+ */
32
+ getBlockAtHeight = async (height: number): Promise<Block> => {
33
+ // get block hash using block height
34
+ const blockHash = (
35
+ await this.client.get<string>(`${this.apiPrefix}/block-height/${height}`)
36
+ ).data;
37
+
38
+ // get block headers using block hash
39
+ const blockHeader = (
40
+ await this.client.get<EsploraBlock>(
41
+ `${this.apiPrefix}/block/${blockHash}`
42
+ )
43
+ ).data;
44
+ return {
45
+ parentHash: blockHeader.previousblockhash,
46
+ hash: blockHeader.id,
47
+ height: blockHeader.height,
48
+ timestamp: blockHeader.timestamp,
49
+ txCount: blockHeader.tx_count,
50
+ };
51
+ };
52
+
53
+ /**
54
+ * Returns current network height
55
+ * @returns current height
56
+ */
57
+ getCurrentHeight = (): Promise<number> => {
58
+ return this.client
59
+ .get<number>(`${this.apiPrefix}/blocks/tip/height`)
60
+ .then((res) => res.data);
61
+ };
62
+
63
+ /**
64
+ * Return transactions in a block with specified hash
65
+ * @param blockHash
66
+ * @returns
67
+ */
68
+ getBlockTxs = async (
69
+ blockHash: string
70
+ ): Promise<Array<BitcoinEsploraTransaction>> => {
71
+ const txCount = (
72
+ await this.client.get<EsploraBlock>(
73
+ `${this.apiPrefix}/block/${blockHash}`
74
+ )
75
+ ).data.tx_count;
76
+
77
+ const blockTxs: Array<BitcoinEsploraTransaction> = [];
78
+ let offset = 0;
79
+
80
+ while (offset < txCount) {
81
+ const txs = (
82
+ await this.client.get<Array<BitcoinEsploraTransaction>>(
83
+ `${this.apiPrefix}/block/${blockHash}/txs/${offset}`
84
+ )
85
+ ).data;
86
+ blockTxs.push(...txs);
87
+ offset += this.ESPLORA_BLOCK_TXS_LIMIT;
88
+ }
89
+
90
+ return blockTxs;
91
+ };
92
+ }
@@ -0,0 +1,15 @@
1
+ import { GeneralScanner, ScannerConfig } from '@rosen-bridge/abstract-scanner';
2
+ import { BitcoinEsploraTransaction } from '../types';
3
+ export class BitcoinEsploraScanner extends GeneralScanner<BitcoinEsploraTransaction> {
4
+ constructor(config: ScannerConfig<BitcoinEsploraTransaction>) {
5
+ super(
6
+ 'bitcoin',
7
+ config.dataSource,
8
+ config.initialHeight,
9
+ config.network,
10
+ config.blockRetrieveGap,
11
+ config.logger,
12
+ config.suffix
13
+ );
14
+ }
15
+ }
@@ -0,0 +1,16 @@
1
+ import { GeneralScanner, ScannerConfig } from '@rosen-bridge/abstract-scanner';
2
+ import { BitcoinRpcTransaction } from '../types';
3
+
4
+ export class BitcoinRpcScanner extends GeneralScanner<BitcoinRpcTransaction> {
5
+ constructor(config: ScannerConfig<BitcoinRpcTransaction>) {
6
+ super(
7
+ 'bitcoin',
8
+ config.dataSource,
9
+ config.initialHeight,
10
+ config.network,
11
+ config.blockRetrieveGap,
12
+ config.logger,
13
+ config.suffix
14
+ );
15
+ }
16
+ }
@@ -0,0 +1,15 @@
1
+ import { GeneralScanner, ScannerConfig } from '@rosen-bridge/abstract-scanner';
2
+ import { BitcoinEsploraTransaction } from '../types';
3
+ export class DogeEsploraScanner extends GeneralScanner<BitcoinEsploraTransaction> {
4
+ constructor(config: ScannerConfig<BitcoinEsploraTransaction>) {
5
+ super(
6
+ 'doge',
7
+ config.dataSource,
8
+ config.initialHeight,
9
+ config.network,
10
+ config.blockRetrieveGap,
11
+ config.logger,
12
+ config.suffix
13
+ );
14
+ }
15
+ }
@@ -0,0 +1,16 @@
1
+ import { GeneralScanner, ScannerConfig } from '@rosen-bridge/abstract-scanner';
2
+ import { DogeRpcTransaction } from '../types';
3
+
4
+ export class DogeRpcScanner extends GeneralScanner<DogeRpcTransaction> {
5
+ constructor(config: ScannerConfig<DogeRpcTransaction>) {
6
+ super(
7
+ 'doge',
8
+ config.dataSource,
9
+ config.initialHeight,
10
+ config.network,
11
+ config.blockRetrieveGap,
12
+ config.logger,
13
+ config.suffix
14
+ );
15
+ }
16
+ }