@xelis/sdk 0.3.4 → 0.5.0

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.
package/daemon/rpc.d.ts CHANGED
@@ -1,34 +1,32 @@
1
- import { Balance, Block, TopoHeightRangeParams, GetInfoResult, HeightRangeParams, GetLastBalanceResult, P2PStatusResult, RPCMethod, RPCResponse, Transaction, GetLastBalanceParams, GetBalanceAtTopoHeightParams, GetAccountsParams, GetBlockAtTopoHeightParams, GetBlockByHashParams, GetBlocksAtHeightParams, GetTopBlockParams } from './types';
2
- declare class RPC {
3
- endpoint: string;
4
- constructor(endpoint: string);
5
- post<T>(method: RPCMethod, params?: any): Promise<RPCResponse<T>>;
6
- getVersion(): Promise<RPCResponse<string>>;
7
- getInfo(): Promise<RPCResponse<GetInfoResult>>;
8
- getHeight(): Promise<RPCResponse<number>>;
9
- getTopoHeight(): Promise<RPCResponse<number>>;
10
- getStableHeight(): Promise<RPCResponse<number>>;
11
- getBlockTemplate(address: string): Promise<RPCResponse<string>>;
12
- getBlockAtTopoHeight(params: GetBlockAtTopoHeightParams): Promise<RPCResponse<Block>>;
13
- getBlocksAtHeight(params: GetBlocksAtHeightParams): Promise<RPCResponse<Block[]>>;
14
- getBlockByHash(params: GetBlockByHashParams): Promise<RPCResponse<Block>>;
15
- getTopBlock(params: GetTopBlockParams): Promise<RPCResponse<Block>>;
16
- getNonce(address: string): Promise<RPCResponse<number>>;
17
- getLastBalance(params: GetLastBalanceParams): Promise<RPCResponse<GetLastBalanceResult>>;
18
- getBalanceAtTopoHeight(params: GetBalanceAtTopoHeightParams): Promise<RPCResponse<Balance>>;
19
- getAssets(): Promise<RPCResponse<string[]>>;
20
- countTransactions(): Promise<RPCResponse<number>>;
21
- countAssets(): Promise<RPCResponse<number>>;
22
- getTips(): Promise<RPCResponse<string[]>>;
23
- p2pStatus(): Promise<RPCResponse<P2PStatusResult>>;
24
- getDAGOrder(params: TopoHeightRangeParams): Promise<RPCResponse<string[]>>;
25
- getMemPool(): Promise<RPCResponse<Transaction[]>>;
26
- getTransaction(hash: string): Promise<RPCResponse<Transaction>>;
27
- getTransactions(txHashes: string[]): Promise<RPCResponse<Transaction[]>>;
28
- getBlocksRangeByTopoheight(params: TopoHeightRangeParams): Promise<RPCResponse<Block[]>>;
29
- getBlocksRangeByHeight(params: HeightRangeParams): Promise<RPCResponse<Block[]>>;
30
- getAccounts(params: GetAccountsParams): Promise<RPCResponse<string[]>>;
31
- submitBlock(blockTemplate: string): Promise<RPCResponse<boolean>>;
32
- submitTransaction(hexData: string): Promise<RPCResponse<boolean>>;
1
+ import { Balance, Block, TopoHeightRangeParams, GetInfoResult, HeightRangeParams, GetLastBalanceResult, P2PStatusResult, Transaction, GetLastBalanceParams, GetBalanceAtTopoHeightParams, GetAccountsParams, GetBlockAtTopoHeightParams, GetBlockByHashParams, GetBlocksAtHeightParams, GetTopBlockParams } from './types';
2
+ import { RPC as BaseRPC } from '../lib/rpc';
3
+ declare class RPC extends BaseRPC {
4
+ getVersion(): Promise<import("../lib/types").RPCResponse<string>>;
5
+ getInfo(): Promise<import("../lib/types").RPCResponse<GetInfoResult>>;
6
+ getHeight(): Promise<import("../lib/types").RPCResponse<number>>;
7
+ getTopoHeight(): Promise<import("../lib/types").RPCResponse<number>>;
8
+ getStableHeight(): Promise<import("../lib/types").RPCResponse<number>>;
9
+ getBlockTemplate(address: string): Promise<import("../lib/types").RPCResponse<string>>;
10
+ getBlockAtTopoHeight(params: GetBlockAtTopoHeightParams): Promise<import("../lib/types").RPCResponse<Block>>;
11
+ getBlocksAtHeight(params: GetBlocksAtHeightParams): Promise<import("../lib/types").RPCResponse<Block[]>>;
12
+ getBlockByHash(params: GetBlockByHashParams): Promise<import("../lib/types").RPCResponse<Block>>;
13
+ getTopBlock(params: GetTopBlockParams): Promise<import("../lib/types").RPCResponse<Block>>;
14
+ getNonce(address: string): Promise<import("../lib/types").RPCResponse<number>>;
15
+ getLastBalance(params: GetLastBalanceParams): Promise<import("../lib/types").RPCResponse<GetLastBalanceResult>>;
16
+ getBalanceAtTopoHeight(params: GetBalanceAtTopoHeightParams): Promise<import("../lib/types").RPCResponse<Balance>>;
17
+ getAssets(): Promise<import("../lib/types").RPCResponse<string[]>>;
18
+ countTransactions(): Promise<import("../lib/types").RPCResponse<number>>;
19
+ countAssets(): Promise<import("../lib/types").RPCResponse<number>>;
20
+ getTips(): Promise<import("../lib/types").RPCResponse<string[]>>;
21
+ p2pStatus(): Promise<import("../lib/types").RPCResponse<P2PStatusResult>>;
22
+ getDAGOrder(params: TopoHeightRangeParams): Promise<import("../lib/types").RPCResponse<string[]>>;
23
+ getMemPool(): Promise<import("../lib/types").RPCResponse<Transaction[]>>;
24
+ getTransaction(hash: string): Promise<import("../lib/types").RPCResponse<Transaction>>;
25
+ getTransactions(txHashes: string[]): Promise<import("../lib/types").RPCResponse<Transaction[]>>;
26
+ getBlocksRangeByTopoheight(params: TopoHeightRangeParams): Promise<import("../lib/types").RPCResponse<Block[]>>;
27
+ getBlocksRangeByHeight(params: HeightRangeParams): Promise<import("../lib/types").RPCResponse<Block[]>>;
28
+ getAccounts(params: GetAccountsParams): Promise<import("../lib/types").RPCResponse<string[]>>;
29
+ submitBlock(blockTemplate: string): Promise<import("../lib/types").RPCResponse<boolean>>;
30
+ submitTransaction(hexData: string): Promise<import("../lib/types").RPCResponse<boolean>>;
33
31
  }
34
32
  export default RPC;
package/daemon/rpc.js CHANGED
@@ -1,27 +1,6 @@
1
1
  import { RPCMethod } from './types';
2
- class RPC {
3
- constructor(endpoint) {
4
- this.endpoint = endpoint;
5
- }
6
- async post(method, params) {
7
- try {
8
- const body = JSON.stringify({ id: 1, jsonrpc: '2.0', method: method, params });
9
- const res = await fetch(this.endpoint, { method: `POST`, body });
10
- if (res.ok) {
11
- const data = await res.json();
12
- if (data.error) {
13
- return Promise.reject(new Error(data.error.message));
14
- }
15
- return Promise.resolve(data);
16
- }
17
- else {
18
- return Promise.reject(new Error(`${res.status} - ${res.statusText}`));
19
- }
20
- }
21
- catch (err) {
22
- return Promise.reject(err);
23
- }
24
- }
2
+ import { RPC as BaseRPC } from '../lib/rpc';
3
+ class RPC extends BaseRPC {
25
4
  getVersion() {
26
5
  return this.post(RPCMethod.GetVersion);
27
6
  }
package/daemon/types.d.ts CHANGED
@@ -1,18 +1,3 @@
1
- export interface RPCRequest {
2
- id: number;
3
- jsonrpc: string;
4
- method: string;
5
- params: string;
6
- }
7
- export interface RPCError {
8
- code: number;
9
- message: string;
10
- }
11
- export interface RPCResponse<T> {
12
- id: number;
13
- result: T;
14
- error?: RPCError;
15
- }
16
1
  export interface GetInfoResult {
17
2
  block_time_target: number;
18
3
  difficulty: number;
@@ -1,28 +1,12 @@
1
- /// <reference types="node" />
2
1
  import { MessageEvent } from 'ws';
3
- import WebSocket from 'isomorphic-ws';
4
- import { Block, RPCResponse, GetInfoResult, RPCEvent, RPCEventResult, Transaction, TopoHeightRangeParams, P2PStatusResult, Balance, GetBalanceAtTopoHeightParams, GetLastBalanceResult, HeightRangeParams, BlockOrdered, GetLastBalanceParams, GetAccountsParams, GetBlockAtTopoHeightParams, GetBlockByHashParams, GetBlocksAtHeightParams, GetTopBlockParams } from './types';
5
- declare class WS {
6
- endpoint: string;
7
- socket?: WebSocket;
8
- timeout: number;
9
- connected: boolean;
10
- unsubscribeSuspense: number;
11
- private events;
12
- constructor();
13
- connect(endpoint: string): Promise<unknown>;
14
- close(code?: number | undefined, data?: string | Buffer | undefined): void;
15
- onClose(cb: (event: WebSocket.CloseEvent) => void): void;
16
- onError(cb: (err: WebSocket.ErrorEvent) => void): void;
17
- private clearEvent;
18
- closeAllListens(event: RPCEvent): Promise<void>;
19
- listenEvent<T>(event: RPCEvent, onData: (msgEvent: MessageEvent, data?: T, err?: Error) => void): Promise<() => Promise<void>>;
2
+ import { Block, GetInfoResult, RPCEventResult, Transaction, TopoHeightRangeParams, P2PStatusResult, Balance, GetBalanceAtTopoHeightParams, GetLastBalanceResult, HeightRangeParams, BlockOrdered, GetLastBalanceParams, GetAccountsParams, GetBlockAtTopoHeightParams, GetBlockByHashParams, GetBlocksAtHeightParams, GetTopBlockParams } from './types';
3
+ import { WS as BaseWS } from '../lib/websocket';
4
+ declare class WS extends BaseWS {
20
5
  onNewBlock(onData: (msgEvent: MessageEvent, data?: Block & RPCEventResult, err?: Error) => void): Promise<() => Promise<void>>;
21
6
  onTransactionAddedInMempool(onData: (msgEvent: MessageEvent, data?: Transaction & RPCEventResult, err?: Error) => void): Promise<() => Promise<void>>;
22
7
  onTransactionExecuted(onData: (msgEvent: MessageEvent, data?: Transaction & RPCEventResult, err?: Error) => void): Promise<() => Promise<void>>;
23
8
  onBlockOrdered(onData: (msgEvent: MessageEvent, data?: BlockOrdered & RPCEventResult, err?: Error) => void): Promise<() => Promise<void>>;
24
- call<T>(method: string, params?: any): Promise<RPCResponse<T>>;
25
- dataCall<T>(method: string, params?: any): Promise<T>;
9
+ getVersion(): Promise<string>;
26
10
  getInfo(): Promise<GetInfoResult>;
27
11
  getHeight(): Promise<number>;
28
12
  getTopoHeight(): Promise<number>;
@@ -1,140 +1,6 @@
1
- import WebSocket from 'isomorphic-ws';
2
- import to from 'await-to-js';
3
1
  import { RPCEvent, RPCMethod } from './types';
4
- function createRequestMethod(method, params) {
5
- const id = Math.floor(Date.now() * Math.random());
6
- const request = { id: id, jsonrpc: `2.0`, method };
7
- if (params)
8
- request.params = params;
9
- const data = JSON.stringify(request);
10
- return { data, id };
11
- }
12
- class WS {
13
- constructor() {
14
- this.endpoint = "";
15
- this.timeout = 3000;
16
- this.connected = false;
17
- this.events = {};
18
- this.unsubscribeSuspense = 1000;
19
- }
20
- connect(endpoint) {
21
- if (this.socket && this.socket.readyState !== WebSocket.CLOSED) {
22
- this.socket.close();
23
- }
24
- return new Promise((resolve, reject) => {
25
- this.socket = new WebSocket(endpoint);
26
- this.endpoint = endpoint;
27
- this.socket.addEventListener(`open`, (event) => {
28
- this.connected = true;
29
- resolve(event);
30
- });
31
- this.socket.addEventListener(`close`, () => {
32
- this.connected = false;
33
- reject();
34
- });
35
- this.socket.addEventListener(`error`, (err) => {
36
- this.connected = false;
37
- reject(err);
38
- });
39
- });
40
- }
41
- close(code, data) {
42
- this.socket && this.socket.close(code, data);
43
- }
44
- onClose(cb) {
45
- if (!this.socket)
46
- return;
47
- this.socket.addEventListener(`close`, (event) => {
48
- cb(event);
49
- });
50
- }
51
- onError(cb) {
52
- if (!this.socket)
53
- return;
54
- this.socket.addEventListener(`error`, (err) => {
55
- cb(err);
56
- });
57
- }
58
- clearEvent(event) {
59
- this.events[event].listeners.forEach(listener => {
60
- this.socket && this.socket.removeEventListener(`message`, listener);
61
- });
62
- Reflect.deleteProperty(this.events, event);
63
- }
64
- async closeAllListens(event) {
65
- if (this.events[event]) {
66
- const [err, _] = await to(this.call(`unsubscribe`, { notify: event }));
67
- if (err)
68
- return Promise.reject(err);
69
- this.clearEvent(event);
70
- }
71
- return Promise.resolve();
72
- }
73
- async listenEvent(event, onData) {
74
- const onMessage = (msgEvent) => {
75
- if (this.events[event]) {
76
- const { id } = this.events[event];
77
- if (typeof msgEvent.data === `string`) {
78
- try {
79
- const data = JSON.parse(msgEvent.data);
80
- if (data.id === id) {
81
- if (data.error) {
82
- onData(msgEvent, undefined, new Error(data.error.message));
83
- }
84
- else {
85
- onData(msgEvent, data.result, undefined);
86
- }
87
- }
88
- }
89
- catch (_a) {
90
- // can't parse json -- do nothing
91
- }
92
- }
93
- }
94
- };
95
- if (this.events[event]) {
96
- const { unsubscribeTimeoutId } = this.events[event];
97
- if (unsubscribeTimeoutId) {
98
- // clear timeout to unsubscribe
99
- // because we got a new registered event and want to cancel the pending unsubscribe grace period
100
- clearTimeout(unsubscribeTimeoutId);
101
- }
102
- this.events[event].listeners.push(onMessage);
103
- }
104
- else {
105
- // important if multiple listenEvent are called without await atleast we store listener before getting id
106
- this.events[event] = { listeners: [onMessage] };
107
- const [err, res] = await to(this.call(`subscribe`, { notify: event }));
108
- if (err) {
109
- this.clearEvent(event);
110
- return Promise.reject(err);
111
- }
112
- this.events[event].id = res.id;
113
- }
114
- this.socket && this.socket.addEventListener(`message`, onMessage);
115
- const closeListen = () => {
116
- const eventData = this.events[event];
117
- if (eventData) {
118
- const listeners = eventData.listeners;
119
- for (let i = 0; i < listeners.length; i++) {
120
- if (listeners[i] === onMessage) {
121
- listeners.splice(i, 1);
122
- break;
123
- }
124
- }
125
- if (listeners.length === 0) {
126
- this.events[event].unsubscribeTimeoutId = setTimeout(async () => {
127
- // no more listener so we unsubscribe from daemon websocket
128
- this.call(`unsubscribe`, { notify: event });
129
- Reflect.deleteProperty(this.events, event);
130
- }, this.unsubscribeSuspense);
131
- }
132
- }
133
- this.socket && this.socket.removeEventListener(`message`, onMessage);
134
- return Promise.resolve();
135
- };
136
- return Promise.resolve(closeListen);
137
- }
2
+ import { WS as BaseWS } from '../lib/websocket';
3
+ class WS extends BaseWS {
138
4
  onNewBlock(onData) {
139
5
  return this.listenEvent(RPCEvent.NewBlock, onData);
140
6
  }
@@ -147,39 +13,8 @@ class WS {
147
13
  onBlockOrdered(onData) {
148
14
  return this.listenEvent(RPCEvent.BlockOrdered, onData);
149
15
  }
150
- call(method, params) {
151
- return new Promise((resolve, reject) => {
152
- const { data, id } = createRequestMethod(method, params);
153
- let timeoutId = null;
154
- const onMessage = (msgEvent) => {
155
- if (typeof msgEvent.data === `string`) {
156
- const data = JSON.parse(msgEvent.data);
157
- if (data.id === id) {
158
- clearTimeout(timeoutId);
159
- this.socket && this.socket.removeEventListener(`message`, onMessage);
160
- if (data.error)
161
- return reject(new Error(data.error.message));
162
- else
163
- resolve(data);
164
- }
165
- }
166
- };
167
- // make sure you listen before sending data
168
- this.socket && this.socket.addEventListener(`message`, onMessage); // we don't use { once: true } option because of timeout feature
169
- timeoutId = setTimeout(() => {
170
- this.socket && this.socket.removeEventListener(`message`, onMessage);
171
- reject(new Error(`timeout`));
172
- }, this.timeout);
173
- this.socket && this.socket.send(data);
174
- });
175
- }
176
- dataCall(method, params) {
177
- return new Promise(async (resolve, reject) => {
178
- const [err, res] = await to(this.call(method, params));
179
- if (err)
180
- return reject(err);
181
- return resolve(res.result);
182
- });
16
+ getVersion() {
17
+ return this.dataCall(RPCMethod.GetVersion);
183
18
  }
184
19
  getInfo() {
185
20
  return this.dataCall(RPCMethod.GetInfo);
package/lib/rpc.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ import { RPCResponse } from './types';
2
+ export declare class RPC {
3
+ endpoint: string;
4
+ constructor(endpoint: string);
5
+ post<T>(method: string, params?: any): Promise<RPCResponse<T>>;
6
+ }
package/lib/rpc.js ADDED
@@ -0,0 +1,24 @@
1
+ export class RPC {
2
+ constructor(endpoint) {
3
+ this.endpoint = endpoint;
4
+ }
5
+ async post(method, params) {
6
+ try {
7
+ const body = JSON.stringify({ id: 1, jsonrpc: '2.0', method: method, params });
8
+ const res = await fetch(this.endpoint, { method: `POST`, body });
9
+ if (res.ok) {
10
+ const data = await res.json();
11
+ if (data.error) {
12
+ return Promise.reject(new Error(data.error.message));
13
+ }
14
+ return Promise.resolve(data);
15
+ }
16
+ else {
17
+ return Promise.reject(new Error(`${res.status} - ${res.statusText}`));
18
+ }
19
+ }
20
+ catch (err) {
21
+ return Promise.reject(err);
22
+ }
23
+ }
24
+ }
package/lib/types.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ export interface RPCRequest {
2
+ id: number;
3
+ jsonrpc: string;
4
+ method: string;
5
+ params: string;
6
+ }
7
+ export interface RPCError {
8
+ code: number;
9
+ message: string;
10
+ }
11
+ export interface RPCResponse<T> {
12
+ id: number;
13
+ result: T;
14
+ error?: RPCError;
15
+ }
package/lib/types.js ADDED
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,22 @@
1
+ /// <reference types="node" />
2
+ import { MessageEvent } from 'ws';
3
+ import WebSocket from 'isomorphic-ws';
4
+ import { RPCResponse } from './types';
5
+ export declare class WS {
6
+ endpoint: string;
7
+ socket?: WebSocket;
8
+ timeout: number;
9
+ connected: boolean;
10
+ unsubscribeSuspense: number;
11
+ private events;
12
+ constructor();
13
+ connect(endpoint: string): Promise<unknown>;
14
+ close(code?: number | undefined, data?: string | Buffer | undefined): void;
15
+ onClose(cb: (event: WebSocket.CloseEvent) => void): void;
16
+ onError(cb: (err: WebSocket.ErrorEvent) => void): void;
17
+ private clearEvent;
18
+ closeAllListens(event: string): Promise<void>;
19
+ listenEvent<T>(event: string, onData: (msgEvent: MessageEvent, data?: T, err?: Error) => void): Promise<() => Promise<void>>;
20
+ call<T>(method: string, params?: any): Promise<RPCResponse<T>>;
21
+ dataCall<T>(method: string, params?: any): Promise<T>;
22
+ }
@@ -0,0 +1,171 @@
1
+ import WebSocket from 'isomorphic-ws';
2
+ import to from 'await-to-js';
3
+ function createRequestMethod(method, params) {
4
+ const id = Math.floor(Date.now() * Math.random());
5
+ const request = { id: id, jsonrpc: `2.0`, method };
6
+ if (params)
7
+ request.params = params;
8
+ const data = JSON.stringify(request);
9
+ return { data, id };
10
+ }
11
+ export class WS {
12
+ constructor() {
13
+ this.endpoint = "";
14
+ this.timeout = 3000;
15
+ this.connected = false;
16
+ this.events = {};
17
+ this.unsubscribeSuspense = 1000;
18
+ }
19
+ connect(endpoint) {
20
+ if (this.socket && this.socket.readyState !== WebSocket.CLOSED) {
21
+ this.socket.close();
22
+ }
23
+ return new Promise((resolve, reject) => {
24
+ this.socket = new WebSocket(endpoint);
25
+ this.endpoint = endpoint;
26
+ this.socket.addEventListener(`open`, (event) => {
27
+ this.connected = true;
28
+ resolve(event);
29
+ });
30
+ this.socket.addEventListener(`close`, () => {
31
+ this.connected = false;
32
+ reject();
33
+ });
34
+ this.socket.addEventListener(`error`, (err) => {
35
+ this.connected = false;
36
+ reject(err);
37
+ });
38
+ });
39
+ }
40
+ close(code, data) {
41
+ this.socket && this.socket.close(code, data);
42
+ }
43
+ onClose(cb) {
44
+ if (!this.socket)
45
+ return;
46
+ this.socket.addEventListener(`close`, (event) => {
47
+ cb(event);
48
+ });
49
+ }
50
+ onError(cb) {
51
+ if (!this.socket)
52
+ return;
53
+ this.socket.addEventListener(`error`, (err) => {
54
+ cb(err);
55
+ });
56
+ }
57
+ clearEvent(event) {
58
+ this.events[event].listeners.forEach(listener => {
59
+ this.socket && this.socket.removeEventListener(`message`, listener);
60
+ });
61
+ Reflect.deleteProperty(this.events, event);
62
+ }
63
+ async closeAllListens(event) {
64
+ if (this.events[event]) {
65
+ const [err, _] = await to(this.call(`unsubscribe`, { notify: event }));
66
+ if (err)
67
+ return Promise.reject(err);
68
+ this.clearEvent(event);
69
+ }
70
+ return Promise.resolve();
71
+ }
72
+ async listenEvent(event, onData) {
73
+ const onMessage = (msgEvent) => {
74
+ if (this.events[event]) {
75
+ const { id } = this.events[event];
76
+ if (typeof msgEvent.data === `string`) {
77
+ try {
78
+ const data = JSON.parse(msgEvent.data);
79
+ if (data.id === id) {
80
+ if (data.error) {
81
+ onData(msgEvent, undefined, new Error(data.error.message));
82
+ }
83
+ else {
84
+ onData(msgEvent, data.result, undefined);
85
+ }
86
+ }
87
+ }
88
+ catch (_a) {
89
+ // can't parse json -- do nothing
90
+ }
91
+ }
92
+ }
93
+ };
94
+ if (this.events[event]) {
95
+ const { unsubscribeTimeoutId } = this.events[event];
96
+ if (unsubscribeTimeoutId) {
97
+ // clear timeout to unsubscribe
98
+ // because we got a new registered event and want to cancel the pending unsubscribe grace period
99
+ clearTimeout(unsubscribeTimeoutId);
100
+ }
101
+ this.events[event].listeners.push(onMessage);
102
+ }
103
+ else {
104
+ // important if multiple listenEvent are called without await atleast we store listener before getting id
105
+ this.events[event] = { listeners: [onMessage] };
106
+ const [err, res] = await to(this.call(`subscribe`, { notify: event }));
107
+ if (err) {
108
+ this.clearEvent(event);
109
+ return Promise.reject(err);
110
+ }
111
+ this.events[event].id = res.id;
112
+ }
113
+ this.socket && this.socket.addEventListener(`message`, onMessage);
114
+ const closeListen = () => {
115
+ const eventData = this.events[event];
116
+ if (eventData) {
117
+ const listeners = eventData.listeners;
118
+ for (let i = 0; i < listeners.length; i++) {
119
+ if (listeners[i] === onMessage) {
120
+ listeners.splice(i, 1);
121
+ break;
122
+ }
123
+ }
124
+ if (listeners.length === 0) {
125
+ this.events[event].unsubscribeTimeoutId = setTimeout(async () => {
126
+ // no more listener so we unsubscribe from daemon websocket
127
+ this.call(`unsubscribe`, { notify: event });
128
+ Reflect.deleteProperty(this.events, event);
129
+ }, this.unsubscribeSuspense);
130
+ }
131
+ }
132
+ this.socket && this.socket.removeEventListener(`message`, onMessage);
133
+ return Promise.resolve();
134
+ };
135
+ return Promise.resolve(closeListen);
136
+ }
137
+ call(method, params) {
138
+ return new Promise((resolve, reject) => {
139
+ const { data, id } = createRequestMethod(method, params);
140
+ let timeoutId = null;
141
+ const onMessage = (msgEvent) => {
142
+ if (typeof msgEvent.data === `string`) {
143
+ const data = JSON.parse(msgEvent.data);
144
+ if (data.id === id) {
145
+ clearTimeout(timeoutId);
146
+ this.socket && this.socket.removeEventListener(`message`, onMessage);
147
+ if (data.error)
148
+ return reject(new Error(data.error.message));
149
+ else
150
+ resolve(data);
151
+ }
152
+ }
153
+ };
154
+ // make sure you listen before sending data
155
+ this.socket && this.socket.addEventListener(`message`, onMessage); // we don't use { once: true } option because of timeout feature
156
+ timeoutId = setTimeout(() => {
157
+ this.socket && this.socket.removeEventListener(`message`, onMessage);
158
+ reject(new Error(`timeout`));
159
+ }, this.timeout);
160
+ this.socket && this.socket.send(data);
161
+ });
162
+ }
163
+ dataCall(method, params) {
164
+ return new Promise(async (resolve, reject) => {
165
+ const [err, res] = await to(this.call(method, params));
166
+ if (err)
167
+ return reject(err);
168
+ return resolve(res.result);
169
+ });
170
+ }
171
+ }
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.3.4",
2
+ "version": "0.5.0",
3
3
  "name": "@xelis/sdk",
4
4
  "description": "Xelis software development kit for JS",
5
5
  "repository": {
@@ -0,0 +1,16 @@
1
+ import { Transaction } from '../daemon/types';
2
+ import { GetAddressParams, SplitAddressParams, SplitAddressResult, BuildTransactionParams, BuildTransactionResult, ListTransactionParams } from './types';
3
+ import { RPC as BaseRPC } from '../lib/rpc';
4
+ declare class RPC extends BaseRPC {
5
+ getVersion(): Promise<import("../lib/types").RPCResponse<string>>;
6
+ getNonce(): Promise<import("../lib/types").RPCResponse<number>>;
7
+ getTopoheight(): Promise<import("../lib/types").RPCResponse<number>>;
8
+ getAddress(params?: GetAddressParams): Promise<import("../lib/types").RPCResponse<string>>;
9
+ splitAddress(params: SplitAddressParams): Promise<import("../lib/types").RPCResponse<SplitAddressResult>>;
10
+ getBalance(asset?: string): Promise<import("../lib/types").RPCResponse<number>>;
11
+ getTrackedAssets(): Promise<import("../lib/types").RPCResponse<string[]>>;
12
+ getTransaction(hash: string): Promise<import("../lib/types").RPCResponse<Transaction>>;
13
+ buildTransaction(params: BuildTransactionParams): Promise<import("../lib/types").RPCResponse<BuildTransactionResult>>;
14
+ listTransactions(params?: ListTransactionParams): Promise<import("../lib/types").RPCResponse<Transaction[]>>;
15
+ }
16
+ export default RPC;
package/wallet/rpc.js ADDED
@@ -0,0 +1,35 @@
1
+ import { RPCMethod } from './types';
2
+ import { RPC as BaseRPC } from '../lib/rpc';
3
+ class RPC extends BaseRPC {
4
+ getVersion() {
5
+ return this.post(RPCMethod.GetVersion);
6
+ }
7
+ getNonce() {
8
+ return this.post(RPCMethod.GetNonce);
9
+ }
10
+ getTopoheight() {
11
+ return this.post(RPCMethod.GetTopoheight);
12
+ }
13
+ getAddress(params) {
14
+ return this.post(RPCMethod.GetAddress, params);
15
+ }
16
+ splitAddress(params) {
17
+ return this.post(RPCMethod.SplitAddress, params);
18
+ }
19
+ getBalance(asset) {
20
+ return this.post(RPCMethod.GetBalance, { asset });
21
+ }
22
+ getTrackedAssets() {
23
+ return this.post(RPCMethod.GetTrackedAssets);
24
+ }
25
+ getTransaction(hash) {
26
+ return this.post(RPCMethod.GetTransaction, { hash });
27
+ }
28
+ buildTransaction(params) {
29
+ return this.post(RPCMethod.BuildTransaction, params);
30
+ }
31
+ listTransactions(params) {
32
+ return this.post(RPCMethod.ListTransactions, params);
33
+ }
34
+ }
35
+ export default RPC;
@@ -0,0 +1,42 @@
1
+ import { TransactionData, Transaction } from '../daemon/types';
2
+ export interface GetAddressParams {
3
+ integrated_data?: string;
4
+ }
5
+ export interface SplitAddressParams {
6
+ address: string;
7
+ }
8
+ export interface SplitAddressResult {
9
+ address: string;
10
+ integrated_data: string;
11
+ }
12
+ export interface BuildTransactionParams {
13
+ tx_type: TransactionData;
14
+ broadcast: boolean;
15
+ fee?: number;
16
+ }
17
+ export interface BuildTransactionResult {
18
+ hash: string;
19
+ data: Transaction;
20
+ }
21
+ export interface ListTransactionParams {
22
+ min_topoheight?: number;
23
+ max_topoheight?: number;
24
+ address?: string;
25
+ accept_incoming?: boolean;
26
+ accept_outgoing?: boolean;
27
+ accept_coinbase?: boolean;
28
+ accept_burn?: boolean;
29
+ }
30
+ export declare enum RPCMethod {
31
+ GetVersion = "get_version",
32
+ GetNetwork = "get_network",
33
+ GetNonce = "get_nonce",
34
+ GetTopoheight = "get_topoheight",
35
+ GetAddress = "get_address",
36
+ SplitAddress = "split_address",
37
+ GetBalance = "get_balance",
38
+ GetTrackedAssets = "get_tracked_assets",
39
+ GetTransaction = "get_transaction",
40
+ BuildTransaction = "build_transaction",
41
+ ListTransactions = "list_transactions"
42
+ }
@@ -0,0 +1,14 @@
1
+ export var RPCMethod;
2
+ (function (RPCMethod) {
3
+ RPCMethod["GetVersion"] = "get_version";
4
+ RPCMethod["GetNetwork"] = "get_network";
5
+ RPCMethod["GetNonce"] = "get_nonce";
6
+ RPCMethod["GetTopoheight"] = "get_topoheight";
7
+ RPCMethod["GetAddress"] = "get_address";
8
+ RPCMethod["SplitAddress"] = "split_address";
9
+ RPCMethod["GetBalance"] = "get_balance";
10
+ RPCMethod["GetTrackedAssets"] = "get_tracked_assets";
11
+ RPCMethod["GetTransaction"] = "get_transaction";
12
+ RPCMethod["BuildTransaction"] = "build_transaction";
13
+ RPCMethod["ListTransactions"] = "list_transactions";
14
+ })(RPCMethod || (RPCMethod = {}));
@@ -0,0 +1,17 @@
1
+ import { WS as BaseWS } from '../lib/websocket';
2
+ import { Transaction } from '../daemon/types';
3
+ import { BuildTransactionParams, BuildTransactionResult, GetAddressParams, ListTransactionParams, SplitAddressParams, SplitAddressResult } from './types';
4
+ declare class WS extends BaseWS {
5
+ getVersion(): Promise<string>;
6
+ getNetwork(): Promise<string>;
7
+ getNonce(): Promise<number>;
8
+ getTopoheight(): Promise<number>;
9
+ getAddress(params?: GetAddressParams): Promise<string>;
10
+ splitAddress(params: SplitAddressParams): Promise<SplitAddressResult>;
11
+ getBalance(asset?: string): Promise<number>;
12
+ getTrackedAssets(): Promise<string[]>;
13
+ getTransaction(hash: string): Promise<Transaction>;
14
+ buildTransaction(params: BuildTransactionParams): Promise<BuildTransactionResult>;
15
+ listTransactions(params?: ListTransactionParams): Promise<Transaction[]>;
16
+ }
17
+ export default WS;
@@ -0,0 +1,38 @@
1
+ import { WS as BaseWS } from '../lib/websocket';
2
+ import { RPCMethod } from './types';
3
+ class WS extends BaseWS {
4
+ getVersion() {
5
+ return this.dataCall(RPCMethod.GetVersion);
6
+ }
7
+ getNetwork() {
8
+ return this.dataCall(RPCMethod.GetNetwork);
9
+ }
10
+ getNonce() {
11
+ return this.dataCall(RPCMethod.GetNonce);
12
+ }
13
+ getTopoheight() {
14
+ return this.dataCall(RPCMethod.GetTopoheight);
15
+ }
16
+ getAddress(params) {
17
+ return this.dataCall(RPCMethod.GetAddress, params);
18
+ }
19
+ splitAddress(params) {
20
+ return this.dataCall(RPCMethod.SplitAddress, params);
21
+ }
22
+ getBalance(asset) {
23
+ return this.dataCall(RPCMethod.GetBalance, { asset });
24
+ }
25
+ getTrackedAssets() {
26
+ return this.dataCall(RPCMethod.GetTrackedAssets);
27
+ }
28
+ getTransaction(hash) {
29
+ return this.dataCall(RPCMethod.GetTransaction, { hash });
30
+ }
31
+ buildTransaction(params) {
32
+ return this.dataCall(RPCMethod.BuildTransaction, params);
33
+ }
34
+ listTransactions(params) {
35
+ return this.dataCall(RPCMethod.GetTransaction, params);
36
+ }
37
+ }
38
+ export default WS;
File without changes
File without changes