@lfdecentralizedtrust/paladin-sdk 0.13.0-rc.1

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 (88) hide show
  1. package/README.md +21 -0
  2. package/build/domains/abis/INoto.json +448 -0
  3. package/build/domains/abis/INotoPrivate.json +347 -0
  4. package/build/domains/abis/IZetoFungible.json +197 -0
  5. package/build/domains/abis/PentePrivacyGroup.json +613 -0
  6. package/build/domains/abis/Zeto_Anon.json +1263 -0
  7. package/build/domains/noto.d.ts +117 -0
  8. package/build/domains/noto.js +292 -0
  9. package/build/domains/pente.d.ts +84 -0
  10. package/build/domains/pente.js +191 -0
  11. package/build/domains/zeto.d.ts +83 -0
  12. package/build/domains/zeto.js +201 -0
  13. package/build/index.d.ts +9 -0
  14. package/build/index.js +28 -0
  15. package/build/interfaces/algorithms.d.ts +3 -0
  16. package/build/interfaces/algorithms.js +9 -0
  17. package/build/interfaces/blockchainevent.d.ts +15 -0
  18. package/build/interfaces/blockchainevent.js +2 -0
  19. package/build/interfaces/blockindex.d.ts +30 -0
  20. package/build/interfaces/blockindex.js +2 -0
  21. package/build/interfaces/domains.d.ts +9 -0
  22. package/build/interfaces/domains.js +2 -0
  23. package/build/interfaces/index.d.ts +15 -0
  24. package/build/interfaces/index.js +31 -0
  25. package/build/interfaces/keymanager.d.ts +32 -0
  26. package/build/interfaces/keymanager.js +2 -0
  27. package/build/interfaces/logger.d.ts +8 -0
  28. package/build/interfaces/logger.js +2 -0
  29. package/build/interfaces/paladin.d.ts +14 -0
  30. package/build/interfaces/paladin.js +2 -0
  31. package/build/interfaces/privacygroups.d.ts +76 -0
  32. package/build/interfaces/privacygroups.js +2 -0
  33. package/build/interfaces/query.d.ts +33 -0
  34. package/build/interfaces/query.js +2 -0
  35. package/build/interfaces/registry.d.ts +26 -0
  36. package/build/interfaces/registry.js +2 -0
  37. package/build/interfaces/states.d.ts +61 -0
  38. package/build/interfaces/states.js +2 -0
  39. package/build/interfaces/transaction.d.ts +159 -0
  40. package/build/interfaces/transaction.js +12 -0
  41. package/build/interfaces/transport.d.ts +32 -0
  42. package/build/interfaces/transport.js +2 -0
  43. package/build/interfaces/verifiers.d.ts +6 -0
  44. package/build/interfaces/verifiers.js +10 -0
  45. package/build/interfaces/websocket.d.ts +57 -0
  46. package/build/interfaces/websocket.js +2 -0
  47. package/build/paladin.d.ts +265 -0
  48. package/build/paladin.js +739 -0
  49. package/build/transaction.d.ts +8 -0
  50. package/build/transaction.js +17 -0
  51. package/build/utils.d.ts +5 -0
  52. package/build/utils.js +49 -0
  53. package/build/verifier.d.ts +16 -0
  54. package/build/verifier.js +24 -0
  55. package/build/websocket.d.ts +35 -0
  56. package/build/websocket.js +177 -0
  57. package/build.gradle +75 -0
  58. package/package.json +32 -0
  59. package/scripts/abi.mjs +19 -0
  60. package/scripts/contracts.mjs +20 -0
  61. package/scripts/download.mjs +27 -0
  62. package/scripts/util.mjs +42 -0
  63. package/src/domains/noto.ts +420 -0
  64. package/src/domains/pente.ts +287 -0
  65. package/src/domains/zeto.ts +282 -0
  66. package/src/index.ts +10 -0
  67. package/src/interfaces/algorithms.ts +6 -0
  68. package/src/interfaces/blockchainevent.ts +18 -0
  69. package/src/interfaces/blockindex.ts +33 -0
  70. package/src/interfaces/domains.ts +10 -0
  71. package/src/interfaces/index.ts +15 -0
  72. package/src/interfaces/keymanager.ts +35 -0
  73. package/src/interfaces/logger.ts +8 -0
  74. package/src/interfaces/paladin.ts +17 -0
  75. package/src/interfaces/privacygroups.ts +86 -0
  76. package/src/interfaces/query.ts +37 -0
  77. package/src/interfaces/registry.ts +27 -0
  78. package/src/interfaces/states.ts +77 -0
  79. package/src/interfaces/transaction.ts +179 -0
  80. package/src/interfaces/transport.ts +35 -0
  81. package/src/interfaces/verifiers.ts +6 -0
  82. package/src/interfaces/websocket.ts +67 -0
  83. package/src/paladin.ts +1295 -0
  84. package/src/transaction.ts +17 -0
  85. package/src/utils.ts +24 -0
  86. package/src/verifier.ts +27 -0
  87. package/src/websocket.ts +217 -0
  88. package/tsconfig.json +14 -0
@@ -0,0 +1,17 @@
1
+ import PaladinClient from "./paladin";
2
+
3
+ // Represents an in-flight transaction
4
+ export class TransactionFuture {
5
+ constructor(
6
+ protected paladin: PaladinClient,
7
+ public readonly id: string | Promise<string>
8
+ ) {}
9
+
10
+ toString() {
11
+ return this.id;
12
+ }
13
+
14
+ async waitForReceipt(waitMs = 5000, full = false) {
15
+ return this.paladin.pollForReceipt(await this.id, waitMs, full);
16
+ }
17
+ }
package/src/utils.ts ADDED
@@ -0,0 +1,24 @@
1
+ import * as uuid from "uuid";
2
+ import { IStateBase, IStateEncoded } from "./interfaces";
3
+
4
+ export function encodeHex(data: string) {
5
+ return "0x" + Buffer.from(data, "utf8").toString("hex");
6
+ }
7
+
8
+ export function decodeHex(data: string) {
9
+ return Buffer.from(data.slice(2), "hex").toString("utf8");
10
+ }
11
+
12
+ export function newTransactionId() {
13
+ return encodeHex(uuid.v4()) + "00000000000000000000000000000000";
14
+ }
15
+
16
+ export const encodeStates = (states: IStateBase[]): IStateEncoded[] => {
17
+ return states.map((state) => ({
18
+ id: state.id,
19
+ domain: state.domain,
20
+ schema: state.schema,
21
+ contractAddress: state.contractAddress,
22
+ data: encodeHex(JSON.stringify(state.data)),
23
+ }));
24
+ };
@@ -0,0 +1,27 @@
1
+ import { Algorithms, Verifiers } from "./interfaces";
2
+ import PaladinClient from "./paladin";
3
+
4
+ export class PaladinVerifier {
5
+ constructor(private paladin: PaladinClient, public readonly lookup: string) {}
6
+
7
+ toString() {
8
+ return this.lookup;
9
+ }
10
+
11
+ split() {
12
+ const [identity, node] = this.lookup.split("@");
13
+ return { 0: identity, 1: node, identity, node };
14
+ }
15
+
16
+ resolve(algorithm: Algorithms, verifierType: Verifiers) {
17
+ return this.paladin.ptx.resolveVerifier(
18
+ this.lookup,
19
+ algorithm,
20
+ verifierType
21
+ );
22
+ }
23
+
24
+ address() {
25
+ return this.resolve(Algorithms.ECDSA_SECP256K1, Verifiers.ETH_ADDRESS);
26
+ }
27
+ }
@@ -0,0 +1,217 @@
1
+ import { IncomingMessage } from "http";
2
+ import { Transform } from "stream";
3
+ import WebSocket from "ws";
4
+ import { Logger } from "./interfaces/logger";
5
+ import {
6
+ PrivacyGroupWebSocketEvent,
7
+ WebSocketClientOptions,
8
+ WebSocketEvent,
9
+ WebSocketEventCallback
10
+ } from "./interfaces/websocket";
11
+
12
+ abstract class PaladinWebSocketClientBase<
13
+ TMessageTypes extends string,
14
+ TEvent
15
+ > {
16
+ private logger: Logger;
17
+ private socket: WebSocket | undefined;
18
+ private closed? = () => {};
19
+ private pingTimer?: NodeJS.Timeout;
20
+ private disconnectTimer?: NodeJS.Timeout;
21
+ private reconnectTimer?: NodeJS.Timeout;
22
+ private disconnectDetected = false;
23
+ private counter = 1;
24
+
25
+ constructor(
26
+ private options: WebSocketClientOptions<TMessageTypes>,
27
+ private callback: WebSocketEventCallback<TEvent>
28
+ ) {
29
+ this.logger = options.logger ?? console;
30
+ this.connect();
31
+ }
32
+
33
+ private connect() {
34
+ // Ensure we've cleaned up any old socket
35
+ this.close();
36
+ if (this.reconnectTimer) {
37
+ clearTimeout(this.reconnectTimer);
38
+ delete this.reconnectTimer;
39
+ }
40
+
41
+ const auth =
42
+ this.options.username && this.options.password
43
+ ? `${this.options.username}:${this.options.password}`
44
+ : undefined;
45
+ const socket = (this.socket = new WebSocket(this.options.url, {
46
+ ...this.options.socketOptions,
47
+ auth,
48
+ handshakeTimeout: this.options.heartbeatInterval,
49
+ }));
50
+ this.closed = undefined;
51
+
52
+ socket
53
+ .on("open", () => {
54
+ if (this.disconnectDetected) {
55
+ this.disconnectDetected = false;
56
+ this.logger.log("Connection restored");
57
+ } else {
58
+ this.logger.log("Connected");
59
+ }
60
+ this.schedulePing();
61
+ for (const sub of this.options.subscriptions ?? []) {
62
+ // Automatically connect subscriptions
63
+ this.subscribe(sub.type, sub.name);
64
+ this.logger.log(`Started listening on subscription ${sub.name}`);
65
+ }
66
+ if (this.options?.afterConnect !== undefined) {
67
+ this.options.afterConnect(this);
68
+ }
69
+ })
70
+ .on("error", (err) => {
71
+ this.logger.error("Error", err.stack);
72
+ })
73
+ .on("close", () => {
74
+ if (this.closed) {
75
+ this.logger.log("Closed");
76
+ this.closed(); // do this after all logging
77
+ } else {
78
+ this.disconnectDetected = true;
79
+ this.reconnect("Closed by peer");
80
+ }
81
+ })
82
+ .on("pong", () => {
83
+ this.logger.debug && this.logger.debug(`WS received pong`);
84
+ this.schedulePing();
85
+ })
86
+ .on("unexpected-response", (req, res: IncomingMessage) => {
87
+ let responseData = "";
88
+ res.pipe(
89
+ new Transform({
90
+ transform(chunk, encoding, callback) {
91
+ responseData += chunk;
92
+ callback();
93
+ },
94
+ flush: () => {
95
+ this.reconnect(
96
+ `Websocket connect error [${res.statusCode}]: ${responseData}`
97
+ );
98
+ },
99
+ })
100
+ );
101
+ })
102
+ .on("message", (data) => {
103
+ const event: TEvent = JSON.parse(data.toString());
104
+ this.callback(this, event);
105
+ });
106
+ }
107
+
108
+ private clearPingTimers() {
109
+ if (this.disconnectTimer) {
110
+ clearTimeout(this.disconnectTimer);
111
+ delete this.disconnectTimer;
112
+ }
113
+ if (this.pingTimer) {
114
+ clearTimeout(this.pingTimer);
115
+ delete this.pingTimer;
116
+ }
117
+ }
118
+
119
+ private schedulePing() {
120
+ this.clearPingTimers();
121
+ const heartbeatInterval = this.options.heartbeatInterval ?? 30000;
122
+ this.disconnectTimer = setTimeout(
123
+ () => this.reconnect("Heartbeat timeout"),
124
+ Math.ceil(heartbeatInterval * 1.5) // 50% grace period
125
+ );
126
+ this.pingTimer = setTimeout(() => {
127
+ this.logger.debug && this.logger.debug(`WS sending ping`);
128
+ this.socket?.ping("ping", true, (err) => {
129
+ if (err) this.reconnect(err.message);
130
+ });
131
+ }, heartbeatInterval);
132
+ }
133
+
134
+ private reconnect(msg: string) {
135
+ if (!this.reconnectTimer) {
136
+ this.close();
137
+ this.logger.error(`Websocket closed: ${msg}`);
138
+ if (this.options.reconnectDelay === -1) {
139
+ // do not attempt to reconnect
140
+ } else {
141
+ this.reconnectTimer = setTimeout(
142
+ () => this.connect(),
143
+ this.options.reconnectDelay ?? 5000
144
+ );
145
+ }
146
+ }
147
+ }
148
+
149
+ send(json: object) {
150
+ if (this.socket !== undefined) {
151
+ this.socket.send(JSON.stringify(json));
152
+ }
153
+ }
154
+
155
+ sendRpc(method: string, params: any[]) {
156
+ this.send({
157
+ jsonrpc: "2.0",
158
+ id: this.counter++,
159
+ method,
160
+ params,
161
+ });
162
+ }
163
+
164
+ async close(wait?: boolean): Promise<void> {
165
+ const closedPromise = new Promise<void>((resolve) => {
166
+ this.closed = resolve;
167
+ });
168
+ this.clearPingTimers();
169
+ if (this.socket) {
170
+ try {
171
+ this.socket.close();
172
+ } catch (e: any) {
173
+ this.logger.warn(`Failed to clean up websocket: ${e.message}`);
174
+ }
175
+ if (wait) await closedPromise;
176
+ this.socket = undefined;
177
+ }
178
+ }
179
+
180
+ abstract subscribe(type: TMessageTypes, name: string): void;
181
+ abstract ack(subscription: string): void;
182
+ abstract nack(subscription: string): void;
183
+ }
184
+
185
+ export class PaladinWebSocketClient extends PaladinWebSocketClientBase<
186
+ "receipts" | "blockchainevents",
187
+ WebSocketEvent
188
+ > {
189
+ subscribe(type: "receipts" | "blockchainevents", name: string) {
190
+ this.sendRpc("ptx_subscribe", [type, name]);
191
+ }
192
+
193
+ ack(subscription: string) {
194
+ this.sendRpc("ptx_ack", [subscription]);
195
+ }
196
+
197
+ nack(subscription: string) {
198
+ this.sendRpc("ptx_nack", [subscription]);
199
+ }
200
+ }
201
+
202
+ export class PrivacyGroupWebSocketClient extends PaladinWebSocketClientBase<
203
+ "messages",
204
+ PrivacyGroupWebSocketEvent
205
+ > {
206
+ subscribe(type: "messages", name: string) {
207
+ this.sendRpc("pgroup_subscribe", [type, name]);
208
+ }
209
+
210
+ ack(subscription: string) {
211
+ this.sendRpc("pgroup_ack", [subscription]);
212
+ }
213
+
214
+ nack(subscription: string) {
215
+ this.sendRpc("pgroup_nack", [subscription]);
216
+ }
217
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es2020",
4
+ "module": "commonjs",
5
+ "outDir": "./build",
6
+ "esModuleInterop": true,
7
+ "forceConsistentCasingInFileNames": true,
8
+ "noImplicitAny": false,
9
+ "strict": true,
10
+ "skipLibCheck": true,
11
+ "declaration": true,
12
+ "resolveJsonModule": true
13
+ }
14
+ }