@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.
- package/README.md +21 -0
- package/build/domains/abis/INoto.json +448 -0
- package/build/domains/abis/INotoPrivate.json +347 -0
- package/build/domains/abis/IZetoFungible.json +197 -0
- package/build/domains/abis/PentePrivacyGroup.json +613 -0
- package/build/domains/abis/Zeto_Anon.json +1263 -0
- package/build/domains/noto.d.ts +117 -0
- package/build/domains/noto.js +292 -0
- package/build/domains/pente.d.ts +84 -0
- package/build/domains/pente.js +191 -0
- package/build/domains/zeto.d.ts +83 -0
- package/build/domains/zeto.js +201 -0
- package/build/index.d.ts +9 -0
- package/build/index.js +28 -0
- package/build/interfaces/algorithms.d.ts +3 -0
- package/build/interfaces/algorithms.js +9 -0
- package/build/interfaces/blockchainevent.d.ts +15 -0
- package/build/interfaces/blockchainevent.js +2 -0
- package/build/interfaces/blockindex.d.ts +30 -0
- package/build/interfaces/blockindex.js +2 -0
- package/build/interfaces/domains.d.ts +9 -0
- package/build/interfaces/domains.js +2 -0
- package/build/interfaces/index.d.ts +15 -0
- package/build/interfaces/index.js +31 -0
- package/build/interfaces/keymanager.d.ts +32 -0
- package/build/interfaces/keymanager.js +2 -0
- package/build/interfaces/logger.d.ts +8 -0
- package/build/interfaces/logger.js +2 -0
- package/build/interfaces/paladin.d.ts +14 -0
- package/build/interfaces/paladin.js +2 -0
- package/build/interfaces/privacygroups.d.ts +76 -0
- package/build/interfaces/privacygroups.js +2 -0
- package/build/interfaces/query.d.ts +33 -0
- package/build/interfaces/query.js +2 -0
- package/build/interfaces/registry.d.ts +26 -0
- package/build/interfaces/registry.js +2 -0
- package/build/interfaces/states.d.ts +61 -0
- package/build/interfaces/states.js +2 -0
- package/build/interfaces/transaction.d.ts +159 -0
- package/build/interfaces/transaction.js +12 -0
- package/build/interfaces/transport.d.ts +32 -0
- package/build/interfaces/transport.js +2 -0
- package/build/interfaces/verifiers.d.ts +6 -0
- package/build/interfaces/verifiers.js +10 -0
- package/build/interfaces/websocket.d.ts +57 -0
- package/build/interfaces/websocket.js +2 -0
- package/build/paladin.d.ts +265 -0
- package/build/paladin.js +739 -0
- package/build/transaction.d.ts +8 -0
- package/build/transaction.js +17 -0
- package/build/utils.d.ts +5 -0
- package/build/utils.js +49 -0
- package/build/verifier.d.ts +16 -0
- package/build/verifier.js +24 -0
- package/build/websocket.d.ts +35 -0
- package/build/websocket.js +177 -0
- package/build.gradle +75 -0
- package/package.json +32 -0
- package/scripts/abi.mjs +19 -0
- package/scripts/contracts.mjs +20 -0
- package/scripts/download.mjs +27 -0
- package/scripts/util.mjs +42 -0
- package/src/domains/noto.ts +420 -0
- package/src/domains/pente.ts +287 -0
- package/src/domains/zeto.ts +282 -0
- package/src/index.ts +10 -0
- package/src/interfaces/algorithms.ts +6 -0
- package/src/interfaces/blockchainevent.ts +18 -0
- package/src/interfaces/blockindex.ts +33 -0
- package/src/interfaces/domains.ts +10 -0
- package/src/interfaces/index.ts +15 -0
- package/src/interfaces/keymanager.ts +35 -0
- package/src/interfaces/logger.ts +8 -0
- package/src/interfaces/paladin.ts +17 -0
- package/src/interfaces/privacygroups.ts +86 -0
- package/src/interfaces/query.ts +37 -0
- package/src/interfaces/registry.ts +27 -0
- package/src/interfaces/states.ts +77 -0
- package/src/interfaces/transaction.ts +179 -0
- package/src/interfaces/transport.ts +35 -0
- package/src/interfaces/verifiers.ts +6 -0
- package/src/interfaces/websocket.ts +67 -0
- package/src/paladin.ts +1295 -0
- package/src/transaction.ts +17 -0
- package/src/utils.ts +24 -0
- package/src/verifier.ts +27 -0
- package/src/websocket.ts +217 -0
- 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
|
+
};
|
package/src/verifier.ts
ADDED
|
@@ -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
|
+
}
|
package/src/websocket.ts
ADDED
|
@@ -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
|
+
}
|