unwallet-client-sdk 0.20.0 → 0.21.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/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # unWallet client-side SDK
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/unwallet-client-sdk.svg?logo=npm)](https://npm.im/unwallet-client-sdk)
4
+ [![test](https://github.com/SIVIRA/unwallet-client-sdk-js/actions/workflows/test.yaml/badge.svg)](https://github.com/SIVIRA/unwallet-client-sdk-js/actions/workflows/test.yaml)
5
+ [![codecov](https://codecov.io/gh/SIVIRA/unwallet-client-sdk-js/graph/badge.svg?token=15NG0897GZ)](https://codecov.io/gh/SIVIRA/unwallet-client-sdk-js)
4
6
 
5
7
  :warning: This SDK works correctly only on web browsers.
6
8
 
package/dist/index.cjs CHANGED
@@ -3,13 +3,13 @@ let viem = require("viem");
3
3
  let zod = require("zod");
4
4
  //#region src/error.ts
5
5
  var UWError = class extends Error {
6
+ static {
7
+ this.prototype.name = "UWError";
8
+ }
6
9
  constructor(code, message) {
7
10
  super(message !== void 0 ? `${code}: ${message}` : code);
8
11
  this.code = code;
9
12
  }
10
- static {
11
- this.prototype.name = "UWError";
12
- }
13
13
  };
14
14
  //#endregion
15
15
  //#region src/config.ts
@@ -17,71 +17,117 @@ function getUnWalletConfigByEnv(env) {
17
17
  switch (env) {
18
18
  case "prod": return {
19
19
  frontend: { baseURL: "https://id.unwallet.world" },
20
- xapi: {
20
+ xAPI: {
21
21
  url: "wss://xapi.id.unwallet.world",
22
22
  connectionTimeout: 1e4
23
23
  }
24
24
  };
25
25
  case "dev": return {
26
26
  frontend: { baseURL: "http://localhost:4200" },
27
- xapi: {
27
+ xAPI: {
28
28
  url: "wss://xapi.id.test.unwallet.dev",
29
29
  connectionTimeout: 1e4
30
30
  }
31
31
  };
32
32
  }
33
33
  }
34
- //#endregion
35
- //#region src/x.ts
36
- const X_RESPONSE_TYPES = [
37
- "connectionID",
38
- "signature",
39
- "transactionID",
40
- "error"
41
- ];
34
+ const xRequestSchema = zod.z.object({ action: zod.z.enum(["getConnectionID"]) });
35
+ zod.z.string().refine((val) => {
36
+ try {
37
+ JSON.parse(val);
38
+ } catch {
39
+ return false;
40
+ }
41
+ return true;
42
+ }, {
43
+ abort: true,
44
+ message: "Invalid JSON string"
45
+ }).transform((val) => JSON.parse(val)).pipe(xRequestSchema);
46
+ const xResponseSchema = zod.z.object({
47
+ type: zod.z.enum([
48
+ "connectionID",
49
+ "signature",
50
+ "transactionID",
51
+ "error"
52
+ ]),
53
+ value: zod.z.string()
54
+ });
55
+ const xResponsePayloadSchema = zod.z.string().refine((val) => {
56
+ try {
57
+ JSON.parse(val);
58
+ } catch (e) {
59
+ return false;
60
+ }
61
+ return true;
62
+ }, {
63
+ abort: true,
64
+ message: "Invalid JSON string"
65
+ }).transform((val) => JSON.parse(val)).pipe(xResponseSchema);
42
66
  var XConnection = class XConnection {
43
67
  constructor(args) {
44
68
  this.responseHandler = null;
45
- this.socket = args.socket;
46
69
  this.id = args.id;
70
+ this.socket = args.socket;
71
+ this.options = args.options ?? {};
47
72
  this.initListeners();
48
73
  }
49
- static async init(config) {
74
+ static async init(config, opts) {
50
75
  const socket = new WebSocket(config.url);
51
76
  const id = await new Promise((resolve, reject) => {
52
- setInterval(() => reject(new UWError("CONNECTION_TIMEOUT")), config.connectionTimeout);
77
+ const timeoutID = setTimeout(() => abortHandshake(new UWError("CONNECTION_TIMEOUT")), config.connectionTimeout);
78
+ const detachListeners = () => {
79
+ socket.onopen = null;
80
+ socket.onmessage = null;
81
+ socket.onerror = null;
82
+ socket.onclose = null;
83
+ };
84
+ const completeHandshake = (id) => {
85
+ clearTimeout(timeoutID);
86
+ detachListeners();
87
+ resolve(id);
88
+ };
89
+ const abortHandshake = (err) => {
90
+ clearTimeout(timeoutID);
91
+ detachListeners();
92
+ socket.close();
93
+ reject(err);
94
+ };
53
95
  socket.onopen = () => socket.send(JSON.stringify({ action: "getConnectionID" }));
54
96
  socket.onmessage = (event) => {
55
97
  let resp;
56
98
  {
57
- const result = safeParseMessageEventDataToXResponse(event.data);
99
+ const result = safeParseXResponsePayload(event.data);
58
100
  if (!result.success) {
59
- reject(result.error);
101
+ abortHandshake(result.error);
60
102
  return;
61
103
  }
62
104
  resp = result.data;
63
105
  }
64
106
  if (resp.type !== "connectionID") {
65
- reject(new UWError("INVALID_RESPONSE", `unexpected response type: ${resp.type}`));
107
+ abortHandshake(newUnexpectedXResponseTypeError(resp));
66
108
  return;
67
109
  }
68
- resolve(resp.value);
110
+ completeHandshake(resp.value);
69
111
  };
70
- socket.onerror = () => reject(new UWError("CONNECTION_FAILED"));
71
- socket.onclose = (event) => reject(new UWError("CONNECTION_CLOSED", event.reason));
112
+ socket.onerror = () => abortHandshake(new UWError("CONNECTION_FAILED"));
113
+ socket.onclose = (event) => abortHandshake(newConnectionClosedError(event));
72
114
  });
73
115
  return new XConnection({
74
116
  id,
75
- socket
117
+ socket,
118
+ options: opts
76
119
  });
77
120
  }
78
121
  initListeners() {
79
122
  this.socket.onopen = null;
80
123
  this.socket.onmessage = (event) => {
81
- if (this.responseHandler === null) return;
124
+ if (this.responseHandler === null) {
125
+ this.options.debugHandlers?.onMessageEventDropped?.(event);
126
+ return;
127
+ }
82
128
  let resp;
83
129
  {
84
- const result = safeParseMessageEventDataToXResponse(event.data);
130
+ const result = safeParseXResponsePayload(event.data);
85
131
  if (!result.success) {
86
132
  this.responseHandler.reject(result.error);
87
133
  return;
@@ -94,7 +140,7 @@ var XConnection = class XConnection {
94
140
  case "rejected":
95
141
  this.responseHandler.reject(new UWError("REQUEST_REJECTED"));
96
142
  break;
97
- default: this.responseHandler.reject(new UWError("INVALID_RESPONSE", `unexpected error response value: ${resp.value}`));
143
+ default: this.responseHandler.reject(new UWError("INVALID_RESPONSE", `unexpected error value: ${resp.value}`));
98
144
  }
99
145
  break;
100
146
  default: this.responseHandler.resolve(resp);
@@ -102,8 +148,11 @@ var XConnection = class XConnection {
102
148
  };
103
149
  this.socket.onerror = null;
104
150
  this.socket.onclose = (event) => {
105
- if (this.responseHandler === null) return;
106
- this.responseHandler.reject(new UWError("CONNECTION_CLOSED", event.reason));
151
+ if (this.responseHandler === null) {
152
+ this.options.debugHandlers?.onCloseEventDropped?.(event);
153
+ return;
154
+ }
155
+ this.responseHandler.reject(newConnectionClosedError(event));
107
156
  };
108
157
  }
109
158
  get readyState() {
@@ -115,31 +164,29 @@ var XConnection = class XConnection {
115
164
  setResponseHandler(handler) {
116
165
  this.responseHandler = handler;
117
166
  }
167
+ close() {
168
+ this.socket.close();
169
+ }
118
170
  };
119
- function safeParseMessageEventDataToXResponse(data) {
120
- const result = zod.z.string().refine((val) => {
121
- try {
122
- JSON.parse(val);
123
- } catch (e) {
124
- return false;
125
- }
126
- return true;
127
- }, {
128
- abort: true,
129
- message: "Invalid JSON string"
130
- }).transform((val) => JSON.parse(val)).pipe(zod.z.object({
131
- type: zod.z.enum(X_RESPONSE_TYPES),
132
- value: zod.z.string()
133
- })).safeParse(data);
171
+ function safeParseXResponsePayload(data) {
172
+ const result = xResponsePayloadSchema.safeParse(data);
134
173
  if (!result.success) return {
135
174
  success: false,
136
- error: new UWError("INVALID_RESPONSE", `invalid message event data: ${result.error.message}`)
175
+ error: new UWError("INVALID_RESPONSE", `invalid payload: ${zod.z.prettifyError(result.error)}`)
137
176
  };
138
177
  return {
139
178
  success: true,
140
179
  data: result.data
141
180
  };
142
181
  }
182
+ function newUnexpectedXResponseTypeError(resp) {
183
+ let msg = `unexpected type: ${resp.type}`;
184
+ if (resp.type === "error") msg += ` (value: ${resp.value})`;
185
+ return new UWError("INVALID_RESPONSE", msg);
186
+ }
187
+ function newConnectionClosedError(event) {
188
+ return new UWError("CONNECTION_CLOSED", event.reason.length > 0 ? event.reason : void 0);
189
+ }
143
190
  //#endregion
144
191
  //#region src/unwallet.ts
145
192
  var UnWallet = class UnWallet {
@@ -153,14 +200,14 @@ var UnWallet = class UnWallet {
153
200
  return new UnWallet({
154
201
  env,
155
202
  clientID: config.clientID,
156
- xConnection: await XConnection.init(getUnWalletConfigByEnv(env).xapi)
203
+ xConnection: await XConnection.init(getUnWalletConfigByEnv(env).xAPI)
157
204
  });
158
205
  }
159
206
  get unWalletConfig() {
160
207
  return getUnWalletConfigByEnv(this.env);
161
208
  }
162
209
  authorize(args) {
163
- const url = new URL(`${this.unWalletConfig.frontend.baseURL}/${args.isVirtual !== void 0 ? args.isVirtual ? "v" : "" : "v"}authorize`);
210
+ const url = new URL(`${this.unWalletConfig.frontend.baseURL}/${args.isVirtual === false ? "" : "v"}authorize`);
164
211
  url.searchParams.set("response_type", "id_token");
165
212
  url.searchParams.set("response_mode", args.responseMode ?? "fragment");
166
213
  url.searchParams.set("client_id", this.clientID);
@@ -185,7 +232,7 @@ var UnWallet = class UnWallet {
185
232
  resolve: (resp) => {
186
233
  this.xConnection.setResponseHandler(null);
187
234
  if (resp.type !== "signature") {
188
- reject(new UWError("INVALID_RESPONSE", `unexpected response type: ${resp.type}`));
235
+ reject(newUnexpectedXResponseTypeError(resp));
189
236
  return;
190
237
  }
191
238
  resolve({
@@ -224,7 +271,7 @@ var UnWallet = class UnWallet {
224
271
  try {
225
272
  (0, viem.validateTypedData)(typedData);
226
273
  } catch (e) {
227
- reject(new UWError("INVALID_REQUEST", `invalid typed data: ${e.message}`));
274
+ reject(new UWError("INVALID_REQUEST", `invalid typed data: ${e instanceof viem.BaseError ? e.shortMessage : String(e)}`));
228
275
  return;
229
276
  }
230
277
  const digest = (0, viem.hashTypedData)(typedData);
@@ -232,7 +279,7 @@ var UnWallet = class UnWallet {
232
279
  resolve: (resp) => {
233
280
  this.xConnection.setResponseHandler(null);
234
281
  if (resp.type !== "signature") {
235
- reject(new UWError("INVALID_RESPONSE", `unexpected response type: ${resp.type}`));
282
+ reject(newUnexpectedXResponseTypeError(resp));
236
283
  return;
237
284
  }
238
285
  resolve({
@@ -271,7 +318,7 @@ var UnWallet = class UnWallet {
271
318
  resolve: (resp) => {
272
319
  this.xConnection.setResponseHandler(null);
273
320
  if (resp.type !== "transactionID") {
274
- reject(new UWError("INVALID_RESPONSE", `unexpected response type: ${resp.type}`));
321
+ reject(newUnexpectedXResponseTypeError(resp));
275
322
  return;
276
323
  }
277
324
  resolve({ transactionID: resp.value });
@@ -292,6 +339,9 @@ var UnWallet = class UnWallet {
292
339
  openWindow(url);
293
340
  });
294
341
  }
342
+ close() {
343
+ this.xConnection.close();
344
+ }
295
345
  };
296
346
  function openWindow(url) {
297
347
  const width = screen.width / 2;
package/dist/index.d.cts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { Address, Hex } from "viem";
2
+ import { z } from "zod";
2
3
  //#region src/config.d.ts
3
4
  type Env = "prod" | "dev";
4
5
  interface Config {
@@ -37,29 +38,43 @@ declare class UWError extends Error {
37
38
  }
38
39
  //#endregion
39
40
  //#region src/x.d.ts
40
- declare const X_RESPONSE_TYPES: readonly ["connectionID", "signature", "transactionID", "error"];
41
- type XResponseType = (typeof X_RESPONSE_TYPES)[number];
42
- interface XResponse {
43
- readonly type: XResponseType;
44
- readonly value: string;
45
- }
46
- interface XResponseHandler {
41
+ declare const xResponseSchema: z.ZodObject<{
42
+ type: z.ZodEnum<{
43
+ connectionID: "connectionID";
44
+ error: "error";
45
+ signature: "signature";
46
+ transactionID: "transactionID";
47
+ }>;
48
+ value: z.ZodString;
49
+ }, z.core.$strip>;
50
+ type XResponse = z.infer<typeof xResponseSchema>;
51
+ type XResponseHandler = {
47
52
  resolve: (resp: XResponse) => void;
48
53
  reject: (err: UWError) => void;
49
- }
54
+ };
55
+ type XConnectionOptions = {
56
+ debugHandlers?: XConnectionDebugHandlers;
57
+ };
58
+ type XConnectionDebugHandlers = {
59
+ onMessageEventDropped?: (event: MessageEvent) => void;
60
+ onCloseEventDropped?: (event: CloseEvent) => void;
61
+ };
50
62
  declare class XConnection {
51
63
  readonly id: string;
52
- private socket;
64
+ private readonly socket;
65
+ private readonly options;
53
66
  private responseHandler;
54
67
  constructor(args: {
55
68
  id: string;
56
69
  socket: WebSocket;
70
+ options?: XConnectionOptions | undefined;
57
71
  });
58
- static init(config: UnWalletXAPIConfig): Promise<XConnection>;
72
+ static init(config: UnWalletXAPIConfig, opts?: XConnectionOptions): Promise<XConnection>;
59
73
  private initListeners;
60
74
  get readyState(): number;
61
75
  get hasResponseHandler(): boolean;
62
76
  setResponseHandler(handler: XResponseHandler | null): void;
77
+ close(): void;
63
78
  }
64
79
  //#endregion
65
80
  //#region src/unwallet.d.ts
@@ -104,6 +119,7 @@ declare class UnWallet {
104
119
  data?: string;
105
120
  ticketToken: string;
106
121
  }): Promise<SendTransactionResult>;
122
+ close(): void;
107
123
  }
108
124
  //#endregion
109
125
  export { type AuthorizationResponseMode, type Config, type EIP712TypedData, type EIP712TypedDataDomain, type EIP712TypedDataField, type Env, type SendTransactionResult, type SignResult, UWError, type UWErrorCode, UnWallet };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { Address, Hex } from "viem";
2
+ import { z } from "zod";
2
3
  //#region src/config.d.ts
3
4
  type Env = "prod" | "dev";
4
5
  interface Config {
@@ -37,29 +38,43 @@ declare class UWError extends Error {
37
38
  }
38
39
  //#endregion
39
40
  //#region src/x.d.ts
40
- declare const X_RESPONSE_TYPES: readonly ["connectionID", "signature", "transactionID", "error"];
41
- type XResponseType = (typeof X_RESPONSE_TYPES)[number];
42
- interface XResponse {
43
- readonly type: XResponseType;
44
- readonly value: string;
45
- }
46
- interface XResponseHandler {
41
+ declare const xResponseSchema: z.ZodObject<{
42
+ type: z.ZodEnum<{
43
+ connectionID: "connectionID";
44
+ error: "error";
45
+ signature: "signature";
46
+ transactionID: "transactionID";
47
+ }>;
48
+ value: z.ZodString;
49
+ }, z.core.$strip>;
50
+ type XResponse = z.infer<typeof xResponseSchema>;
51
+ type XResponseHandler = {
47
52
  resolve: (resp: XResponse) => void;
48
53
  reject: (err: UWError) => void;
49
- }
54
+ };
55
+ type XConnectionOptions = {
56
+ debugHandlers?: XConnectionDebugHandlers;
57
+ };
58
+ type XConnectionDebugHandlers = {
59
+ onMessageEventDropped?: (event: MessageEvent) => void;
60
+ onCloseEventDropped?: (event: CloseEvent) => void;
61
+ };
50
62
  declare class XConnection {
51
63
  readonly id: string;
52
- private socket;
64
+ private readonly socket;
65
+ private readonly options;
53
66
  private responseHandler;
54
67
  constructor(args: {
55
68
  id: string;
56
69
  socket: WebSocket;
70
+ options?: XConnectionOptions | undefined;
57
71
  });
58
- static init(config: UnWalletXAPIConfig): Promise<XConnection>;
72
+ static init(config: UnWalletXAPIConfig, opts?: XConnectionOptions): Promise<XConnection>;
59
73
  private initListeners;
60
74
  get readyState(): number;
61
75
  get hasResponseHandler(): boolean;
62
76
  setResponseHandler(handler: XResponseHandler | null): void;
77
+ close(): void;
63
78
  }
64
79
  //#endregion
65
80
  //#region src/unwallet.d.ts
@@ -104,6 +119,7 @@ declare class UnWallet {
104
119
  data?: string;
105
120
  ticketToken: string;
106
121
  }): Promise<SendTransactionResult>;
122
+ close(): void;
107
123
  }
108
124
  //#endregion
109
125
  export { type AuthorizationResponseMode, type Config, type EIP712TypedData, type EIP712TypedDataDomain, type EIP712TypedDataField, type Env, type SendTransactionResult, type SignResult, UWError, type UWErrorCode, UnWallet };
package/dist/index.js CHANGED
@@ -1,14 +1,14 @@
1
- import { hashTypedData, sha256, toBytes, validateTypedData } from "viem";
1
+ import { BaseError, hashTypedData, sha256, toBytes, validateTypedData } from "viem";
2
2
  import { z } from "zod";
3
3
  //#region src/error.ts
4
4
  var UWError = class extends Error {
5
+ static {
6
+ this.prototype.name = "UWError";
7
+ }
5
8
  constructor(code, message) {
6
9
  super(message !== void 0 ? `${code}: ${message}` : code);
7
10
  this.code = code;
8
11
  }
9
- static {
10
- this.prototype.name = "UWError";
11
- }
12
12
  };
13
13
  //#endregion
14
14
  //#region src/config.ts
@@ -16,71 +16,117 @@ function getUnWalletConfigByEnv(env) {
16
16
  switch (env) {
17
17
  case "prod": return {
18
18
  frontend: { baseURL: "https://id.unwallet.world" },
19
- xapi: {
19
+ xAPI: {
20
20
  url: "wss://xapi.id.unwallet.world",
21
21
  connectionTimeout: 1e4
22
22
  }
23
23
  };
24
24
  case "dev": return {
25
25
  frontend: { baseURL: "http://localhost:4200" },
26
- xapi: {
26
+ xAPI: {
27
27
  url: "wss://xapi.id.test.unwallet.dev",
28
28
  connectionTimeout: 1e4
29
29
  }
30
30
  };
31
31
  }
32
32
  }
33
- //#endregion
34
- //#region src/x.ts
35
- const X_RESPONSE_TYPES = [
36
- "connectionID",
37
- "signature",
38
- "transactionID",
39
- "error"
40
- ];
33
+ const xRequestSchema = z.object({ action: z.enum(["getConnectionID"]) });
34
+ z.string().refine((val) => {
35
+ try {
36
+ JSON.parse(val);
37
+ } catch {
38
+ return false;
39
+ }
40
+ return true;
41
+ }, {
42
+ abort: true,
43
+ message: "Invalid JSON string"
44
+ }).transform((val) => JSON.parse(val)).pipe(xRequestSchema);
45
+ const xResponseSchema = z.object({
46
+ type: z.enum([
47
+ "connectionID",
48
+ "signature",
49
+ "transactionID",
50
+ "error"
51
+ ]),
52
+ value: z.string()
53
+ });
54
+ const xResponsePayloadSchema = z.string().refine((val) => {
55
+ try {
56
+ JSON.parse(val);
57
+ } catch (e) {
58
+ return false;
59
+ }
60
+ return true;
61
+ }, {
62
+ abort: true,
63
+ message: "Invalid JSON string"
64
+ }).transform((val) => JSON.parse(val)).pipe(xResponseSchema);
41
65
  var XConnection = class XConnection {
42
66
  constructor(args) {
43
67
  this.responseHandler = null;
44
- this.socket = args.socket;
45
68
  this.id = args.id;
69
+ this.socket = args.socket;
70
+ this.options = args.options ?? {};
46
71
  this.initListeners();
47
72
  }
48
- static async init(config) {
73
+ static async init(config, opts) {
49
74
  const socket = new WebSocket(config.url);
50
75
  const id = await new Promise((resolve, reject) => {
51
- setInterval(() => reject(new UWError("CONNECTION_TIMEOUT")), config.connectionTimeout);
76
+ const timeoutID = setTimeout(() => abortHandshake(new UWError("CONNECTION_TIMEOUT")), config.connectionTimeout);
77
+ const detachListeners = () => {
78
+ socket.onopen = null;
79
+ socket.onmessage = null;
80
+ socket.onerror = null;
81
+ socket.onclose = null;
82
+ };
83
+ const completeHandshake = (id) => {
84
+ clearTimeout(timeoutID);
85
+ detachListeners();
86
+ resolve(id);
87
+ };
88
+ const abortHandshake = (err) => {
89
+ clearTimeout(timeoutID);
90
+ detachListeners();
91
+ socket.close();
92
+ reject(err);
93
+ };
52
94
  socket.onopen = () => socket.send(JSON.stringify({ action: "getConnectionID" }));
53
95
  socket.onmessage = (event) => {
54
96
  let resp;
55
97
  {
56
- const result = safeParseMessageEventDataToXResponse(event.data);
98
+ const result = safeParseXResponsePayload(event.data);
57
99
  if (!result.success) {
58
- reject(result.error);
100
+ abortHandshake(result.error);
59
101
  return;
60
102
  }
61
103
  resp = result.data;
62
104
  }
63
105
  if (resp.type !== "connectionID") {
64
- reject(new UWError("INVALID_RESPONSE", `unexpected response type: ${resp.type}`));
106
+ abortHandshake(newUnexpectedXResponseTypeError(resp));
65
107
  return;
66
108
  }
67
- resolve(resp.value);
109
+ completeHandshake(resp.value);
68
110
  };
69
- socket.onerror = () => reject(new UWError("CONNECTION_FAILED"));
70
- socket.onclose = (event) => reject(new UWError("CONNECTION_CLOSED", event.reason));
111
+ socket.onerror = () => abortHandshake(new UWError("CONNECTION_FAILED"));
112
+ socket.onclose = (event) => abortHandshake(newConnectionClosedError(event));
71
113
  });
72
114
  return new XConnection({
73
115
  id,
74
- socket
116
+ socket,
117
+ options: opts
75
118
  });
76
119
  }
77
120
  initListeners() {
78
121
  this.socket.onopen = null;
79
122
  this.socket.onmessage = (event) => {
80
- if (this.responseHandler === null) return;
123
+ if (this.responseHandler === null) {
124
+ this.options.debugHandlers?.onMessageEventDropped?.(event);
125
+ return;
126
+ }
81
127
  let resp;
82
128
  {
83
- const result = safeParseMessageEventDataToXResponse(event.data);
129
+ const result = safeParseXResponsePayload(event.data);
84
130
  if (!result.success) {
85
131
  this.responseHandler.reject(result.error);
86
132
  return;
@@ -93,7 +139,7 @@ var XConnection = class XConnection {
93
139
  case "rejected":
94
140
  this.responseHandler.reject(new UWError("REQUEST_REJECTED"));
95
141
  break;
96
- default: this.responseHandler.reject(new UWError("INVALID_RESPONSE", `unexpected error response value: ${resp.value}`));
142
+ default: this.responseHandler.reject(new UWError("INVALID_RESPONSE", `unexpected error value: ${resp.value}`));
97
143
  }
98
144
  break;
99
145
  default: this.responseHandler.resolve(resp);
@@ -101,8 +147,11 @@ var XConnection = class XConnection {
101
147
  };
102
148
  this.socket.onerror = null;
103
149
  this.socket.onclose = (event) => {
104
- if (this.responseHandler === null) return;
105
- this.responseHandler.reject(new UWError("CONNECTION_CLOSED", event.reason));
150
+ if (this.responseHandler === null) {
151
+ this.options.debugHandlers?.onCloseEventDropped?.(event);
152
+ return;
153
+ }
154
+ this.responseHandler.reject(newConnectionClosedError(event));
106
155
  };
107
156
  }
108
157
  get readyState() {
@@ -114,31 +163,29 @@ var XConnection = class XConnection {
114
163
  setResponseHandler(handler) {
115
164
  this.responseHandler = handler;
116
165
  }
166
+ close() {
167
+ this.socket.close();
168
+ }
117
169
  };
118
- function safeParseMessageEventDataToXResponse(data) {
119
- const result = z.string().refine((val) => {
120
- try {
121
- JSON.parse(val);
122
- } catch (e) {
123
- return false;
124
- }
125
- return true;
126
- }, {
127
- abort: true,
128
- message: "Invalid JSON string"
129
- }).transform((val) => JSON.parse(val)).pipe(z.object({
130
- type: z.enum(X_RESPONSE_TYPES),
131
- value: z.string()
132
- })).safeParse(data);
170
+ function safeParseXResponsePayload(data) {
171
+ const result = xResponsePayloadSchema.safeParse(data);
133
172
  if (!result.success) return {
134
173
  success: false,
135
- error: new UWError("INVALID_RESPONSE", `invalid message event data: ${result.error.message}`)
174
+ error: new UWError("INVALID_RESPONSE", `invalid payload: ${z.prettifyError(result.error)}`)
136
175
  };
137
176
  return {
138
177
  success: true,
139
178
  data: result.data
140
179
  };
141
180
  }
181
+ function newUnexpectedXResponseTypeError(resp) {
182
+ let msg = `unexpected type: ${resp.type}`;
183
+ if (resp.type === "error") msg += ` (value: ${resp.value})`;
184
+ return new UWError("INVALID_RESPONSE", msg);
185
+ }
186
+ function newConnectionClosedError(event) {
187
+ return new UWError("CONNECTION_CLOSED", event.reason.length > 0 ? event.reason : void 0);
188
+ }
142
189
  //#endregion
143
190
  //#region src/unwallet.ts
144
191
  var UnWallet = class UnWallet {
@@ -152,14 +199,14 @@ var UnWallet = class UnWallet {
152
199
  return new UnWallet({
153
200
  env,
154
201
  clientID: config.clientID,
155
- xConnection: await XConnection.init(getUnWalletConfigByEnv(env).xapi)
202
+ xConnection: await XConnection.init(getUnWalletConfigByEnv(env).xAPI)
156
203
  });
157
204
  }
158
205
  get unWalletConfig() {
159
206
  return getUnWalletConfigByEnv(this.env);
160
207
  }
161
208
  authorize(args) {
162
- const url = new URL(`${this.unWalletConfig.frontend.baseURL}/${args.isVirtual !== void 0 ? args.isVirtual ? "v" : "" : "v"}authorize`);
209
+ const url = new URL(`${this.unWalletConfig.frontend.baseURL}/${args.isVirtual === false ? "" : "v"}authorize`);
163
210
  url.searchParams.set("response_type", "id_token");
164
211
  url.searchParams.set("response_mode", args.responseMode ?? "fragment");
165
212
  url.searchParams.set("client_id", this.clientID);
@@ -184,7 +231,7 @@ var UnWallet = class UnWallet {
184
231
  resolve: (resp) => {
185
232
  this.xConnection.setResponseHandler(null);
186
233
  if (resp.type !== "signature") {
187
- reject(new UWError("INVALID_RESPONSE", `unexpected response type: ${resp.type}`));
234
+ reject(newUnexpectedXResponseTypeError(resp));
188
235
  return;
189
236
  }
190
237
  resolve({
@@ -223,7 +270,7 @@ var UnWallet = class UnWallet {
223
270
  try {
224
271
  validateTypedData(typedData);
225
272
  } catch (e) {
226
- reject(new UWError("INVALID_REQUEST", `invalid typed data: ${e.message}`));
273
+ reject(new UWError("INVALID_REQUEST", `invalid typed data: ${e instanceof BaseError ? e.shortMessage : String(e)}`));
227
274
  return;
228
275
  }
229
276
  const digest = hashTypedData(typedData);
@@ -231,7 +278,7 @@ var UnWallet = class UnWallet {
231
278
  resolve: (resp) => {
232
279
  this.xConnection.setResponseHandler(null);
233
280
  if (resp.type !== "signature") {
234
- reject(new UWError("INVALID_RESPONSE", `unexpected response type: ${resp.type}`));
281
+ reject(newUnexpectedXResponseTypeError(resp));
235
282
  return;
236
283
  }
237
284
  resolve({
@@ -270,7 +317,7 @@ var UnWallet = class UnWallet {
270
317
  resolve: (resp) => {
271
318
  this.xConnection.setResponseHandler(null);
272
319
  if (resp.type !== "transactionID") {
273
- reject(new UWError("INVALID_RESPONSE", `unexpected response type: ${resp.type}`));
320
+ reject(newUnexpectedXResponseTypeError(resp));
274
321
  return;
275
322
  }
276
323
  resolve({ transactionID: resp.value });
@@ -291,6 +338,9 @@ var UnWallet = class UnWallet {
291
338
  openWindow(url);
292
339
  });
293
340
  }
341
+ close() {
342
+ this.xConnection.close();
343
+ }
294
344
  };
295
345
  function openWindow(url) {
296
346
  const width = screen.width / 2;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "unwallet-client-sdk",
3
- "version": "0.20.0",
3
+ "version": "0.21.0",
4
4
  "description": "unWallet client-side SDK",
5
5
  "license": "MIT",
6
6
  "author": "SIVIRA",
@@ -19,9 +19,9 @@
19
19
  }
20
20
  }
21
21
  },
22
- "main": "dist/index.cjs",
23
- "module": "dist/index.js",
24
- "types": "dist/index.d.ts",
22
+ "main": "./dist/index.cjs",
23
+ "module": "./dist/index.js",
24
+ "types": "./dist/index.d.ts",
25
25
  "sideEffects": false,
26
26
  "type": "module",
27
27
  "repository": {
@@ -37,10 +37,14 @@
37
37
  "@commitlint/config-conventional": "21.2.0",
38
38
  "@commitlint/types": "21.2.0",
39
39
  "@tsconfig/strictest": "2.0.8",
40
+ "@vitest/coverage-v8": "4.1.10",
40
41
  "czg": "1.13.1",
41
42
  "husky": "9.1.7",
42
- "publint": "0.3.22",
43
- "tsdown": "0.22.14"
43
+ "msw": "2.15.0",
44
+ "publint": "0.3.23",
45
+ "tsdown": "0.22.14",
46
+ "typescript": "7.0.2",
47
+ "vitest": "4.1.10"
44
48
  },
45
49
  "scripts": {}
46
50
  }