@reclaimprotocol/attestor-core 5.0.1-beta.2 → 5.0.1-beta.22

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 (145) hide show
  1. package/browser/resources/attestor-browser.min.mjs +4512 -0
  2. package/lib/avs/abis/avsDirectoryABI.js +338 -341
  3. package/lib/avs/abis/delegationABI.js +1 -4
  4. package/lib/avs/abis/registryABI.js +719 -722
  5. package/lib/avs/client/create-claim-on-avs.js +129 -157
  6. package/lib/avs/config.js +18 -24
  7. package/lib/avs/contracts/ReclaimServiceManager.js +1 -0
  8. package/lib/avs/contracts/common.js +1 -0
  9. package/lib/avs/contracts/factories/ReclaimServiceManager__factory.js +1139 -1156
  10. package/lib/avs/contracts/factories/index.js +4 -4
  11. package/lib/avs/contracts/index.js +2 -6
  12. package/lib/avs/types/index.js +1 -0
  13. package/lib/avs/utils/contracts.js +30 -50
  14. package/lib/avs/utils/register.js +75 -70
  15. package/lib/avs/utils/tasks.js +38 -45
  16. package/lib/client/create-claim.js +402 -431
  17. package/lib/client/tunnels/make-rpc-tcp-tunnel.js +46 -48
  18. package/lib/client/tunnels/make-rpc-tls-tunnel.js +125 -121
  19. package/lib/client/utils/attestor-pool.js +23 -22
  20. package/lib/client/utils/client-socket.js +86 -109
  21. package/lib/client/utils/message-handler.js +79 -89
  22. package/lib/config/index.js +40 -58
  23. package/lib/external-rpc/benchmark.js +61 -74
  24. package/lib/external-rpc/event-bus.js +12 -15
  25. package/lib/external-rpc/handle-incoming-msg.js +216 -225
  26. package/lib/external-rpc/jsc-polyfills/1.js +70 -68
  27. package/lib/external-rpc/jsc-polyfills/2.js +17 -12
  28. package/lib/external-rpc/jsc-polyfills/event.js +10 -15
  29. package/lib/external-rpc/jsc-polyfills/index.js +2 -2
  30. package/lib/external-rpc/jsc-polyfills/ws.js +77 -79
  31. package/lib/external-rpc/setup-browser.js +28 -28
  32. package/lib/external-rpc/setup-jsc.js +17 -17
  33. package/lib/external-rpc/types.js +1 -0
  34. package/lib/external-rpc/utils.js +89 -89
  35. package/lib/external-rpc/zk.js +55 -50
  36. package/lib/index.js +2 -6
  37. package/lib/mechain/abis/governanceABI.js +457 -460
  38. package/lib/mechain/abis/taskABI.js +502 -505
  39. package/lib/mechain/client/create-claim-on-mechain.js +24 -29
  40. package/lib/mechain/constants/index.js +3 -8
  41. package/lib/mechain/types/index.js +1 -0
  42. package/lib/proto/api.js +4200 -4087
  43. package/lib/proto/tee-bundle.js +1261 -1241
  44. package/lib/providers/http/index.js +616 -603
  45. package/lib/providers/http/patch-parse5-tree.js +27 -29
  46. package/lib/providers/http/utils.js +289 -248
  47. package/lib/providers/index.js +3 -6
  48. package/lib/server/create-server.js +89 -91
  49. package/lib/server/handlers/claimTeeBundle.js +231 -211
  50. package/lib/server/handlers/claimTunnel.js +66 -73
  51. package/lib/server/handlers/completeClaimOnChain.js +20 -25
  52. package/lib/server/handlers/createClaimOnChain.js +21 -27
  53. package/lib/server/handlers/createTaskOnMechain.js +40 -50
  54. package/lib/server/handlers/createTunnel.js +85 -90
  55. package/lib/server/handlers/disconnectTunnel.js +4 -7
  56. package/lib/server/handlers/fetchCertificateBytes.js +37 -53
  57. package/lib/server/handlers/index.js +21 -24
  58. package/lib/server/handlers/init.js +27 -28
  59. package/lib/server/handlers/toprf.js +13 -16
  60. package/lib/server/socket.js +97 -100
  61. package/lib/server/tunnels/make-tcp-tunnel.js +161 -186
  62. package/lib/server/utils/apm.js +32 -25
  63. package/lib/server/utils/assert-valid-claim-request.js +305 -334
  64. package/lib/server/utils/config-env.js +2 -2
  65. package/lib/server/utils/dns.js +12 -18
  66. package/lib/server/utils/gcp-attestation.js +233 -181
  67. package/lib/server/utils/generics.d.ts +1 -1
  68. package/lib/server/utils/generics.js +43 -37
  69. package/lib/server/utils/iso.js +253 -256
  70. package/lib/server/utils/keep-alive.js +36 -36
  71. package/lib/server/utils/nitro-attestation.js +295 -220
  72. package/lib/server/utils/oprf-raw.js +48 -55
  73. package/lib/server/utils/process-handshake.js +200 -218
  74. package/lib/server/utils/proxy-session.js +5 -5
  75. package/lib/server/utils/tee-oprf-mpc-verification.js +82 -78
  76. package/lib/server/utils/tee-oprf-verification.js +165 -142
  77. package/lib/server/utils/tee-transcript-reconstruction.js +176 -129
  78. package/lib/server/utils/tee-verification.js +397 -334
  79. package/lib/server/utils/validation.js +30 -37
  80. package/lib/types/bgp.js +1 -0
  81. package/lib/types/claims.js +1 -0
  82. package/lib/types/client.js +1 -0
  83. package/lib/types/general.js +1 -0
  84. package/lib/types/handlers.js +1 -0
  85. package/lib/types/providers.d.ts +3 -2
  86. package/lib/types/providers.gen.js +9 -15
  87. package/lib/types/providers.js +1 -0
  88. package/lib/types/rpc.js +1 -0
  89. package/lib/types/signatures.d.ts +1 -2
  90. package/lib/types/signatures.js +1 -0
  91. package/lib/types/tunnel.js +1 -0
  92. package/lib/types/zk.js +1 -0
  93. package/lib/utils/auth.js +54 -66
  94. package/lib/utils/b64-json.js +15 -15
  95. package/lib/utils/bgp-listener.js +107 -111
  96. package/lib/utils/claims.js +89 -80
  97. package/lib/utils/env.js +13 -17
  98. package/lib/utils/error.js +43 -47
  99. package/lib/utils/generics.js +284 -235
  100. package/lib/utils/http-parser.js +232 -187
  101. package/lib/utils/logger.js +80 -71
  102. package/lib/utils/prepare-packets.js +69 -67
  103. package/lib/utils/redactions.js +163 -121
  104. package/lib/utils/retries.js +22 -24
  105. package/lib/utils/signatures/eth.js +29 -28
  106. package/lib/utils/signatures/index.js +5 -10
  107. package/lib/utils/socket-base.js +84 -88
  108. package/lib/utils/tls.js +28 -28
  109. package/lib/utils/ws.js +19 -19
  110. package/lib/utils/zk.js +542 -582
  111. package/package.json +12 -5
  112. package/lib/external-rpc/global.d.js +0 -0
  113. package/lib/scripts/build-browser.d.ts +0 -1
  114. package/lib/scripts/build-jsc.d.ts +0 -1
  115. package/lib/scripts/build-lib.d.ts +0 -1
  116. package/lib/scripts/check-avs-registration.d.ts +0 -1
  117. package/lib/scripts/check-avs-registration.js +0 -28
  118. package/lib/scripts/fallbacks/crypto.d.ts +0 -1
  119. package/lib/scripts/fallbacks/crypto.js +0 -4
  120. package/lib/scripts/fallbacks/empty.d.ts +0 -3
  121. package/lib/scripts/fallbacks/empty.js +0 -4
  122. package/lib/scripts/fallbacks/re2.d.ts +0 -1
  123. package/lib/scripts/fallbacks/re2.js +0 -7
  124. package/lib/scripts/fallbacks/snarkjs.d.ts +0 -1
  125. package/lib/scripts/fallbacks/snarkjs.js +0 -10
  126. package/lib/scripts/fallbacks/stwo.d.ts +0 -6
  127. package/lib/scripts/fallbacks/stwo.js +0 -159
  128. package/lib/scripts/generate-provider-types.d.ts +0 -5
  129. package/lib/scripts/generate-provider-types.js +0 -101
  130. package/lib/scripts/generate-receipt.d.ts +0 -9
  131. package/lib/scripts/generate-receipt.js +0 -101
  132. package/lib/scripts/generate-toprf-keys.d.ts +0 -1
  133. package/lib/scripts/generate-toprf-keys.js +0 -24
  134. package/lib/scripts/jsc-cli-rpc.d.ts +0 -1
  135. package/lib/scripts/jsc-cli-rpc.js +0 -35
  136. package/lib/scripts/register-avs-operator.d.ts +0 -1
  137. package/lib/scripts/register-avs-operator.js +0 -3
  138. package/lib/scripts/start-server.d.ts +0 -1
  139. package/lib/scripts/start-server.js +0 -11
  140. package/lib/scripts/update-avs-metadata.d.ts +0 -1
  141. package/lib/scripts/update-avs-metadata.js +0 -20
  142. package/lib/scripts/utils.d.ts +0 -1
  143. package/lib/scripts/utils.js +0 -10
  144. package/lib/scripts/whitelist-operator.d.ts +0 -1
  145. package/lib/scripts/whitelist-operator.js +0 -16
@@ -1,53 +1,51 @@
1
1
  import { AttestorError } from "../../utils/index.js";
2
- const makeRpcTcpTunnel = ({
3
- tunnelId,
4
- client,
5
- onClose,
6
- onMessage
7
- }) => {
8
- let closed = false;
9
- client.addEventListener("tunnel-message", onMessageListener);
10
- client.addEventListener("tunnel-disconnect-event", onDisconnectListener);
11
- client.addEventListener("connection-terminated", onConnectionTerminatedListener);
12
- return {
13
- async write(message) {
14
- await client.sendMessage({ tunnelMessage: { tunnelId, message } });
15
- },
16
- async close(err) {
17
- if (closed) {
18
- return;
19
- }
20
- onErrorRecv(err);
21
- await client.rpc("disconnectTunnel", { id: tunnelId });
2
+ /**
3
+ * Makes a tunnel communication wrapper for a TCP tunnel.
4
+ *
5
+ * It listens for messages and disconnect events from the server,
6
+ * and appropriately calls the `onMessage` and `onClose` callbacks.
7
+ */
8
+ export const makeRpcTcpTunnel = ({ tunnelId, client, onClose, onMessage, }) => {
9
+ let closed = false;
10
+ client.addEventListener('tunnel-message', onMessageListener);
11
+ client.addEventListener('tunnel-disconnect-event', onDisconnectListener);
12
+ client.addEventListener('connection-terminated', onConnectionTerminatedListener);
13
+ return {
14
+ async write(message) {
15
+ await client.sendMessage({ tunnelMessage: { tunnelId, message } });
16
+ },
17
+ async close(err) {
18
+ if (closed) {
19
+ return;
20
+ }
21
+ onErrorRecv(err);
22
+ await client.rpc('disconnectTunnel', { id: tunnelId });
23
+ }
24
+ };
25
+ function onMessageListener({ data }) {
26
+ if (data.tunnelId !== tunnelId) {
27
+ return;
28
+ }
29
+ onMessage?.(data.message);
22
30
  }
23
- };
24
- function onMessageListener({ data }) {
25
- if (data.tunnelId !== tunnelId) {
26
- return;
31
+ function onDisconnectListener({ data }) {
32
+ if (data.tunnelId !== tunnelId) {
33
+ return;
34
+ }
35
+ onErrorRecv(data.error?.code
36
+ ? AttestorError.fromProto(data.error)
37
+ : undefined);
27
38
  }
28
- onMessage?.(data.message);
29
- }
30
- function onDisconnectListener({ data }) {
31
- if (data.tunnelId !== tunnelId) {
32
- return;
39
+ function onConnectionTerminatedListener({ data }) {
40
+ onErrorRecv(data);
41
+ }
42
+ function onErrorRecv(err) {
43
+ client.logger?.debug({ tunnelId, err }, 'TCP tunnel closed');
44
+ client.removeEventListener('tunnel-message', onMessageListener);
45
+ client.removeEventListener('tunnel-disconnect-event', onDisconnectListener);
46
+ client.removeEventListener('connection-terminated', onConnectionTerminatedListener);
47
+ onClose?.(err);
48
+ onClose = undefined;
49
+ closed = true;
33
50
  }
34
- onErrorRecv(
35
- data.error?.code ? AttestorError.fromProto(data.error) : void 0
36
- );
37
- }
38
- function onConnectionTerminatedListener({ data }) {
39
- onErrorRecv(data);
40
- }
41
- function onErrorRecv(err) {
42
- client.logger?.debug({ tunnelId, err }, "TCP tunnel closed");
43
- client.removeEventListener("tunnel-message", onMessageListener);
44
- client.removeEventListener("tunnel-disconnect-event", onDisconnectListener);
45
- client.removeEventListener("connection-terminated", onConnectionTerminatedListener);
46
- onClose?.(err);
47
- onClose = void 0;
48
- closed = true;
49
- }
50
- };
51
- export {
52
- makeRpcTcpTunnel
53
51
  };
@@ -1,127 +1,131 @@
1
- import { concatenateUint8Arrays, makeTLSClient } from "@reclaimprotocol/tls";
2
- import { makeRpcTcpTunnel } from "../../client/tunnels/make-rpc-tcp-tunnel.js";
1
+ import { concatenateUint8Arrays, makeTLSClient } from '@reclaimprotocol/tls';
2
+ import { makeRpcTcpTunnel } from "./make-rpc-tcp-tunnel.js";
3
3
  import { DEFAULT_HTTPS_PORT } from "../../config/index.js";
4
4
  import { generateRpcMessageId, generateTunnelId } from "../../utils/index.js";
5
- const makeRpcTlsTunnel = async ({
6
- onMessage,
7
- onClose,
8
- tlsOpts,
9
- request,
10
- connect,
11
- logger
12
- }) => {
13
- const transcript = [];
14
- const tunnelId = request.id || generateTunnelId();
15
- let tunnel;
16
- let client;
17
- let handshakeResolve;
18
- let handshakeReject;
19
- const waitForHandshake = new Promise((resolve, reject) => {
20
- handshakeResolve = resolve;
21
- handshakeReject = reject;
22
- });
23
- const tls = makeTLSClient({
24
- host: request.host,
25
- ...tlsOpts,
26
- logger,
27
- onHandshake() {
28
- handshakeResolve?.();
29
- },
30
- onApplicationData(plaintext) {
31
- return onMessage?.(plaintext);
32
- },
33
- onTlsEnd: onConnectionClose,
34
- async write(packet, ctx) {
35
- const message = concatenateUint8Arrays([
36
- packet.header,
37
- packet.content
38
- ]);
39
- transcript.push({
40
- sender: "client",
41
- message: { ...ctx, data: message }
42
- });
43
- if (!tunnel) {
44
- const createTunnelReqId = generateRpcMessageId();
45
- client = connect([
46
- {
47
- id: createTunnelReqId,
48
- createTunnelRequest: {
49
- host: request.host || "",
50
- port: request.port || DEFAULT_HTTPS_PORT,
51
- geoLocation: request.geoLocation || "",
52
- proxySessionId: request.proxySessionId || "",
53
- id: tunnelId
5
+ /**
6
+ * Makes a TLS tunnel that connects to the server via RPC protocol
7
+ */
8
+ export const makeRpcTlsTunnel = async ({ onMessage, onClose, tlsOpts, request, connect, logger }) => {
9
+ const transcript = [];
10
+ const tunnelId = request.id || generateTunnelId();
11
+ let tunnel;
12
+ let client;
13
+ let handshakeResolve;
14
+ let handshakeReject;
15
+ const waitForHandshake = new Promise((resolve, reject) => {
16
+ handshakeResolve = resolve;
17
+ handshakeReject = reject;
18
+ });
19
+ const tls = makeTLSClient({
20
+ host: request.host,
21
+ ...tlsOpts,
22
+ logger,
23
+ onHandshake() {
24
+ handshakeResolve?.();
25
+ },
26
+ onApplicationData(plaintext) {
27
+ return onMessage?.(plaintext);
28
+ },
29
+ onTlsEnd: onConnectionClose,
30
+ async write(packet, ctx) {
31
+ const message = concatenateUint8Arrays([
32
+ packet.header,
33
+ packet.content
34
+ ]);
35
+ transcript.push({
36
+ sender: 'client',
37
+ message: { ...ctx, data: message }
38
+ });
39
+ if (!tunnel) {
40
+ // sends the packet as the initial message
41
+ // to the plaintext tunnel. Prevents another
42
+ // round trip to the server as we send the packet
43
+ // in the same message as the tunnel creation.
44
+ const createTunnelReqId = generateRpcMessageId();
45
+ client = connect([
46
+ {
47
+ id: createTunnelReqId,
48
+ createTunnelRequest: {
49
+ host: request.host || '',
50
+ port: request.port || DEFAULT_HTTPS_PORT,
51
+ geoLocation: request.geoLocation || '',
52
+ proxySessionId: request.proxySessionId || '',
53
+ id: tunnelId
54
+ },
55
+ },
56
+ { tunnelMessage: { tunnelId, message } }
57
+ ]);
58
+ try {
59
+ await makeTunnel();
60
+ // wait for tunnel to be successfully created
61
+ await client.waitForResponse(createTunnelReqId);
62
+ }
63
+ catch (err) {
64
+ onConnectionClose(err);
65
+ }
66
+ return;
67
+ }
68
+ return tunnel.write(message);
69
+ },
70
+ onRead(packet, ctx) {
71
+ transcript.push({
72
+ sender: 'server',
73
+ message: {
74
+ ...ctx,
75
+ data: concatenateUint8Arrays([
76
+ packet.header,
77
+ // the TLS package sends us the decrypted
78
+ // content, so we need to get the orginal
79
+ // ciphertext received from the server
80
+ // as that's part of the true transcript.
81
+ ctx.type === 'ciphertext'
82
+ ? ctx.ciphertext
83
+ : packet.content
84
+ ])
85
+ }
86
+ });
87
+ },
88
+ });
89
+ await tls.startHandshake();
90
+ // wait for handshake completion
91
+ await waitForHandshake;
92
+ handshakeResolve = handshakeReject = undefined;
93
+ return {
94
+ transcript,
95
+ tls,
96
+ write(data) {
97
+ return tls.write(data);
98
+ },
99
+ async close(err) {
100
+ onConnectionClose(err);
101
+ try {
102
+ await tunnel.close(err);
54
103
  }
55
- },
56
- { tunnelMessage: { tunnelId, message } }
57
- ]);
58
- try {
59
- await makeTunnel();
60
- await client.waitForResponse(createTunnelReqId);
61
- } catch (err) {
62
- onConnectionClose(err);
63
- }
64
- return;
65
- }
66
- return tunnel.write(message);
67
- },
68
- onRead(packet, ctx) {
69
- transcript.push({
70
- sender: "server",
71
- message: {
72
- ...ctx,
73
- data: concatenateUint8Arrays([
74
- packet.header,
75
- // the TLS package sends us the decrypted
76
- // content, so we need to get the orginal
77
- // ciphertext received from the server
78
- // as that's part of the true transcript.
79
- ctx.type === "ciphertext" ? ctx.ciphertext : packet.content
80
- ])
81
- }
82
- });
104
+ catch (err) {
105
+ logger?.error({ err }, 'err in close tunnel');
106
+ }
107
+ },
108
+ };
109
+ function onConnectionClose(err) {
110
+ onClose?.(err);
111
+ // once the TLS connection is closed, we no longer
112
+ // want to send `onClose` events back to the caller
113
+ // of this function.
114
+ onClose = undefined;
115
+ handshakeReject?.(err || new Error('TLS connection closed'));
83
116
  }
84
- });
85
- await tls.startHandshake();
86
- await waitForHandshake;
87
- handshakeResolve = handshakeReject = void 0;
88
- return {
89
- transcript,
90
- tls,
91
- write(data) {
92
- return tls.write(data);
93
- },
94
- async close(err) {
95
- onConnectionClose(err);
96
- try {
97
- await tunnel.close(err);
98
- } catch (err2) {
99
- logger?.error({ err: err2 }, "err in close tunnel");
100
- }
117
+ async function makeTunnel() {
118
+ tunnel = await makeRpcTcpTunnel({
119
+ tunnelId,
120
+ client: client,
121
+ onMessage(data) {
122
+ tls.handleReceivedBytes(data);
123
+ },
124
+ onClose(err) {
125
+ tls.end(err);
126
+ },
127
+ });
128
+ logger?.debug('plaintext tunnel created');
129
+ return tunnel;
101
130
  }
102
- };
103
- function onConnectionClose(err) {
104
- onClose?.(err);
105
- onClose = void 0;
106
- handshakeReject?.(
107
- err || new Error("TLS connection closed")
108
- );
109
- }
110
- async function makeTunnel() {
111
- tunnel = await makeRpcTcpTunnel({
112
- tunnelId,
113
- client,
114
- onMessage(data) {
115
- tls.handleReceivedBytes(data);
116
- },
117
- onClose(err) {
118
- tls.end(err);
119
- }
120
- });
121
- logger?.debug("plaintext tunnel created");
122
- return tunnel;
123
- }
124
- };
125
- export {
126
- makeRpcTlsTunnel
127
131
  };
@@ -1,24 +1,25 @@
1
- import { AttestorClient } from "../../client/utils/client-socket.js";
1
+ import { AttestorClient } from "./client-socket.js";
2
2
  const POOL = {};
3
- function getAttestorClientFromPool(url, getCreateOpts = () => ({})) {
4
- const key = url.toString();
5
- let client = POOL[key];
6
- let createReason;
7
- if (client?.isClosed) {
8
- createReason = "closed";
9
- } else if (!client) {
10
- createReason = "non-existent";
11
- }
12
- if (createReason) {
13
- const createOpts = getCreateOpts();
14
- createOpts?.logger?.info(
15
- { key, createReason },
16
- "creating new client"
17
- );
18
- client = POOL[key] = new AttestorClient({ ...createOpts, url });
19
- }
20
- return client;
3
+ /**
4
+ * Get a attestor client from the pool,
5
+ * if it doesn't exist, create one.
6
+ * @param [getCreateOpts] - Function to get the options for creating a new client.
7
+ * called synchronously, in the same tick as this function.
8
+ */
9
+ export function getAttestorClientFromPool(url, getCreateOpts = () => ({})) {
10
+ const key = url.toString();
11
+ let client = POOL[key];
12
+ let createReason;
13
+ if (client?.isClosed) {
14
+ createReason = 'closed';
15
+ }
16
+ else if (!client) {
17
+ createReason = 'non-existent';
18
+ }
19
+ if (createReason) {
20
+ const createOpts = getCreateOpts();
21
+ createOpts?.logger?.info({ key, createReason }, 'creating new client');
22
+ client = (POOL[key] = new AttestorClient({ ...createOpts, url }));
23
+ }
24
+ return client;
21
25
  }
22
- export {
23
- getAttestorClientFromPool
24
- };
@@ -1,120 +1,97 @@
1
- import { encodeBase64 } from "ethers";
1
+ import { encodeBase64 } from 'ethers';
2
2
  import { DEFAULT_METADATA, DEFAULT_RPC_TIMEOUT_MS } from "../../config/index.js";
3
3
  import { RPCMessages } from "../../proto/api.js";
4
4
  import { AttestorError, generateRpcMessageId, getRpcRequestType, logger as LOGGER, packRpcMessages } from "../../utils/index.js";
5
5
  import { AttestorSocket } from "../../utils/socket-base.js";
6
6
  import { makeWebSocket as defaultMakeWebSocket } from "../../utils/ws.js";
7
- class AttestorClient extends AttestorSocket {
8
- waitForInitPromise;
9
- initResponse;
10
- constructor({
11
- url,
12
- initMessages = [],
13
- signatureType = DEFAULT_METADATA.signatureType,
14
- logger = LOGGER,
15
- authRequest,
16
- makeWebSocket = defaultMakeWebSocket
17
- }) {
18
- const initRequest = {
19
- ...DEFAULT_METADATA,
20
- signatureType,
21
- auth: authRequest
22
- };
23
- const msg = packRpcMessages({ initRequest }, ...initMessages);
24
- const initRequestBytes = RPCMessages.encode(msg).finish();
25
- const initRequestB64 = encodeBase64(initRequestBytes);
26
- url = new URL(url.toString());
27
- url.searchParams.set("messages", initRequestB64);
28
- super(
29
- makeWebSocket(url),
30
- initRequest,
31
- logger
32
- );
33
- const initReqId = msg.messages[0].id;
34
- this.waitForInitPromise = this.waitForResponse(initReqId, DEFAULT_RPC_TIMEOUT_MS).then((res) => {
35
- logger.info("client initialised");
36
- this.isInitialised = true;
37
- this.initResponse = res;
38
- });
39
- this.waitForInitPromise.catch(() => {
40
- });
41
- this.addEventListener("connection-terminated", (ev) => logger.info({ err: ev.data }, "connection terminated"));
42
- }
43
- async rpc(type, request, timeoutMs = DEFAULT_RPC_TIMEOUT_MS) {
44
- const msgId = generateRpcMessageId();
45
- this.logger.debug({ type, id: msgId }, "sending rpc request");
46
- const now = Date.now();
47
- try {
48
- const rslt = this.waitForResponse(msgId, timeoutMs);
49
- await this.sendMessage({ id: msgId, [getRpcRequestType(type)]: request });
50
- return await rslt;
51
- } finally {
52
- const timeTakenMs = Date.now() - now;
53
- this.logger.debug({ type, timeTakenMs }, "received rpc response");
54
- }
55
- }
56
- waitForResponse(id, timeoutMs = DEFAULT_RPC_TIMEOUT_MS) {
57
- if (this.isClosed) {
58
- throw new AttestorError(
59
- "ERROR_NETWORK_ERROR",
60
- "Client connection already closed"
61
- );
7
+ export class AttestorClient extends AttestorSocket {
8
+ waitForInitPromise;
9
+ initResponse;
10
+ constructor({ url, initMessages = [], signatureType = DEFAULT_METADATA.signatureType, logger = LOGGER, authRequest, makeWebSocket = defaultMakeWebSocket }) {
11
+ const initRequest = {
12
+ ...DEFAULT_METADATA,
13
+ signatureType,
14
+ auth: authRequest
15
+ };
16
+ const msg = packRpcMessages({ initRequest }, ...initMessages);
17
+ const initRequestBytes = RPCMessages.encode(msg).finish();
18
+ const initRequestB64 = encodeBase64(initRequestBytes);
19
+ url = new URL(url.toString());
20
+ url.searchParams.set('messages', initRequestB64);
21
+ super(makeWebSocket(url), initRequest, logger);
22
+ const initReqId = msg.messages[0].id;
23
+ this.waitForInitPromise = this
24
+ .waitForResponse(initReqId, DEFAULT_RPC_TIMEOUT_MS)
25
+ .then(res => {
26
+ logger.info('client initialised');
27
+ this.isInitialised = true;
28
+ this.initResponse = res;
29
+ });
30
+ // swallow the error if anything bad happens, and we've no
31
+ // catch block to handle it
32
+ this.waitForInitPromise
33
+ .catch(() => { });
34
+ this.addEventListener('connection-terminated', ev => (logger.info({ err: ev.data }, 'connection terminated')));
62
35
  }
63
- return new Promise((resolve, reject) => {
64
- const handler = (event) => {
65
- if (event.data.id !== id) {
66
- return;
36
+ async rpc(type, request, timeoutMs = DEFAULT_RPC_TIMEOUT_MS) {
37
+ const msgId = generateRpcMessageId();
38
+ this.logger.debug({ type, id: msgId }, 'sending rpc request');
39
+ const now = Date.now();
40
+ try {
41
+ const rslt = this.waitForResponse(msgId, timeoutMs);
42
+ await this.sendMessage({ id: msgId, [getRpcRequestType(type)]: request });
43
+ return await rslt;
67
44
  }
68
- removeHandlers();
69
- if ("error" in event.data) {
70
- reject(event.data.error);
71
- return;
45
+ finally {
46
+ const timeTakenMs = Date.now() - now;
47
+ this.logger.debug({ type, timeTakenMs }, 'received rpc response');
72
48
  }
73
- resolve(event.data.data);
74
- };
75
- const terminateHandler = (event) => {
76
- removeHandlers();
77
- if (event.data.code === "ERROR_NO_ERROR") {
78
- reject(
79
- new AttestorError(
80
- "ERROR_NETWORK_ERROR",
81
- event.data.message,
82
- event.data.data
83
- )
84
- );
85
- return;
49
+ }
50
+ waitForResponse(id, timeoutMs = DEFAULT_RPC_TIMEOUT_MS) {
51
+ if (this.isClosed) {
52
+ throw new AttestorError('ERROR_NETWORK_ERROR', 'Client connection already closed');
86
53
  }
87
- reject(event.data);
88
- };
89
- const timeout = setTimeout(() => {
90
- removeHandlers();
91
- reject(
92
- new AttestorError(
93
- "ERROR_TIMEOUT",
94
- `RPC request timed out after ${timeoutMs}ms`,
95
- { id }
96
- )
97
- );
98
- }, timeoutMs);
99
- const removeHandlers = () => {
100
- clearTimeout(timeout);
101
- this.removeEventListener("rpc-response", handler);
102
- this.removeEventListener("connection-terminated", terminateHandler);
103
- };
104
- this.addEventListener("rpc-response", handler);
105
- this.addEventListener("connection-terminated", terminateHandler);
106
- });
107
- }
108
- waitForInit = () => {
109
- if (this.isClosed) {
110
- throw new AttestorError(
111
- "ERROR_NETWORK_ERROR",
112
- "Client connection already closed"
113
- );
54
+ // setup a promise to wait for the response
55
+ return new Promise((resolve, reject) => {
56
+ const handler = (event) => {
57
+ if (event.data.id !== id) {
58
+ return;
59
+ }
60
+ removeHandlers();
61
+ if ('error' in event.data) {
62
+ reject(event.data.error);
63
+ return;
64
+ }
65
+ // @ts-expect-error
66
+ resolve(event.data.data);
67
+ };
68
+ const terminateHandler = (event) => {
69
+ removeHandlers();
70
+ // if the connection was terminated, reject the promise
71
+ // but update the error code to reflect the network error
72
+ if (event.data.code === 'ERROR_NO_ERROR') {
73
+ reject(new AttestorError('ERROR_NETWORK_ERROR', event.data.message, event.data.data));
74
+ return;
75
+ }
76
+ reject(event.data);
77
+ };
78
+ const timeout = setTimeout(() => {
79
+ removeHandlers();
80
+ reject(new AttestorError('ERROR_TIMEOUT', `RPC request timed out after ${timeoutMs}ms`, { id }));
81
+ }, timeoutMs);
82
+ const removeHandlers = () => {
83
+ clearTimeout(timeout);
84
+ this.removeEventListener('rpc-response', handler);
85
+ this.removeEventListener('connection-terminated', terminateHandler);
86
+ };
87
+ this.addEventListener('rpc-response', handler);
88
+ this.addEventListener('connection-terminated', terminateHandler);
89
+ });
114
90
  }
115
- return this.waitForInitPromise;
116
- };
91
+ waitForInit = () => {
92
+ if (this.isClosed) {
93
+ throw new AttestorError('ERROR_NETWORK_ERROR', 'Client connection already closed');
94
+ }
95
+ return this.waitForInitPromise;
96
+ };
117
97
  }
118
- export {
119
- AttestorClient
120
- };