unwallet-client-sdk 0.18.2 → 0.20.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/dist/index.js CHANGED
@@ -1,400 +1,302 @@
1
- // src/error.ts
2
- var _UWError = class _UWError extends Error {
3
- constructor(code, message) {
4
- super(message !== void 0 ? `${code}: ${message}` : code);
5
- this.code = code;
6
- }
7
- };
8
- _UWError.prototype.name = "UWError";
9
- var UWError = _UWError;
10
-
11
- // src/unwallet.ts
12
- import {
13
- hashTypedData,
14
- toBytes,
15
- sha256,
16
- validateTypedData
17
- } from "viem";
18
-
19
- // src/config.ts
20
- var UNWALLET_CONFIG_PROD = {
21
- frontend: {
22
- baseURL: "https://id.unwallet.world"
23
- },
24
- xapi: {
25
- url: "wss://xapi.id.unwallet.world",
26
- connectionTimeout: 1e4
27
- }
28
- };
29
- var UNWALLET_CONFIG_DEV = {
30
- frontend: {
31
- baseURL: "http://localhost:4200"
32
- },
33
- xapi: {
34
- url: "wss://xapi.id.test.unwallet.dev",
35
- connectionTimeout: 1e4
36
- }
1
+ import { hashTypedData, sha256, toBytes, validateTypedData } from "viem";
2
+ import { z } from "zod";
3
+ //#region src/error.ts
4
+ var UWError = class extends Error {
5
+ constructor(code, message) {
6
+ super(message !== void 0 ? `${code}: ${message}` : code);
7
+ this.code = code;
8
+ }
9
+ static {
10
+ this.prototype.name = "UWError";
11
+ }
37
12
  };
13
+ //#endregion
14
+ //#region src/config.ts
38
15
  function getUnWalletConfigByEnv(env) {
39
- switch (env) {
40
- case "prod":
41
- return UNWALLET_CONFIG_PROD;
42
- case "dev":
43
- return UNWALLET_CONFIG_DEV;
44
- }
16
+ switch (env) {
17
+ case "prod": return {
18
+ frontend: { baseURL: "https://id.unwallet.world" },
19
+ xapi: {
20
+ url: "wss://xapi.id.unwallet.world",
21
+ connectionTimeout: 1e4
22
+ }
23
+ };
24
+ case "dev": return {
25
+ frontend: { baseURL: "http://localhost:4200" },
26
+ xapi: {
27
+ url: "wss://xapi.id.test.unwallet.dev",
28
+ connectionTimeout: 1e4
29
+ }
30
+ };
31
+ }
45
32
  }
46
-
47
- // src/x.ts
48
- import { z } from "zod";
49
- var VALID_X_RESPONSE_TYPES = [
50
- "connectionID",
51
- "signature",
52
- "transactionID",
53
- "error"
33
+ //#endregion
34
+ //#region src/x.ts
35
+ const X_RESPONSE_TYPES = [
36
+ "connectionID",
37
+ "signature",
38
+ "transactionID",
39
+ "error"
54
40
  ];
55
- var XConnection = class _XConnection {
56
- constructor(args) {
57
- this.responseHandler = null;
58
- this.socket = args.socket;
59
- this.id = args.id;
60
- this.initListeners();
61
- }
62
- initListeners() {
63
- this.socket.onopen = null;
64
- this.socket.onmessage = (event) => {
65
- if (this.responseHandler === null) {
66
- return;
67
- }
68
- let resp;
69
- {
70
- const result = safeParseMessageEventDataToXResponse(event.data);
71
- if (!result.success) {
72
- this.responseHandler.reject(result.error);
73
- return;
74
- }
75
- resp = result.data;
76
- }
77
- switch (resp.type) {
78
- case "error":
79
- switch (resp.value) {
80
- case "rejected":
81
- this.responseHandler.reject(new UWError("REQUEST_REJECTED"));
82
- break;
83
- default:
84
- this.responseHandler.reject(
85
- new UWError(
86
- "INVALID_RESPONSE",
87
- `unexpected error response value: ${resp.value}`
88
- )
89
- );
90
- }
91
- break;
92
- default:
93
- this.responseHandler.resolve(resp);
94
- }
95
- };
96
- this.socket.onerror = null;
97
- this.socket.onclose = (event) => {
98
- if (this.responseHandler === null) {
99
- return;
100
- }
101
- this.responseHandler.reject(
102
- new UWError("CONNECTION_CLOSED", event.reason)
103
- );
104
- };
105
- }
106
- get readyState() {
107
- return this.socket.readyState;
108
- }
109
- get hasResponseHandler() {
110
- return this.responseHandler !== null;
111
- }
112
- setResponseHandler(handler) {
113
- this.responseHandler = handler;
114
- }
115
- static async init(config) {
116
- const socket = new WebSocket(config.url);
117
- const id = await new Promise((resolve, reject) => {
118
- setInterval(
119
- () => reject(new UWError("CONNECTION_TIMEOUT")),
120
- config.connectionTimeout
121
- );
122
- socket.onopen = () => socket.send(JSON.stringify({ action: "getConnectionID" }));
123
- socket.onmessage = (event) => {
124
- let resp;
125
- {
126
- const result = safeParseMessageEventDataToXResponse(event.data);
127
- if (!result.success) {
128
- reject(result.error);
129
- return;
130
- }
131
- resp = result.data;
132
- }
133
- if (resp.type !== "connectionID") {
134
- reject(
135
- new UWError(
136
- "INVALID_RESPONSE",
137
- `unexpected response type: ${resp.type}`
138
- )
139
- );
140
- return;
141
- }
142
- resolve(resp.value);
143
- };
144
- socket.onerror = () => reject(new UWError("CONNECTION_FAILED"));
145
- socket.onclose = (event) => reject(new UWError("CONNECTION_CLOSED", event.reason));
146
- });
147
- return new _XConnection({ socket, id });
148
- }
41
+ var XConnection = class XConnection {
42
+ constructor(args) {
43
+ this.responseHandler = null;
44
+ this.socket = args.socket;
45
+ this.id = args.id;
46
+ this.initListeners();
47
+ }
48
+ static async init(config) {
49
+ const socket = new WebSocket(config.url);
50
+ const id = await new Promise((resolve, reject) => {
51
+ setInterval(() => reject(new UWError("CONNECTION_TIMEOUT")), config.connectionTimeout);
52
+ socket.onopen = () => socket.send(JSON.stringify({ action: "getConnectionID" }));
53
+ socket.onmessage = (event) => {
54
+ let resp;
55
+ {
56
+ const result = safeParseMessageEventDataToXResponse(event.data);
57
+ if (!result.success) {
58
+ reject(result.error);
59
+ return;
60
+ }
61
+ resp = result.data;
62
+ }
63
+ if (resp.type !== "connectionID") {
64
+ reject(new UWError("INVALID_RESPONSE", `unexpected response type: ${resp.type}`));
65
+ return;
66
+ }
67
+ resolve(resp.value);
68
+ };
69
+ socket.onerror = () => reject(new UWError("CONNECTION_FAILED"));
70
+ socket.onclose = (event) => reject(new UWError("CONNECTION_CLOSED", event.reason));
71
+ });
72
+ return new XConnection({
73
+ id,
74
+ socket
75
+ });
76
+ }
77
+ initListeners() {
78
+ this.socket.onopen = null;
79
+ this.socket.onmessage = (event) => {
80
+ if (this.responseHandler === null) return;
81
+ let resp;
82
+ {
83
+ const result = safeParseMessageEventDataToXResponse(event.data);
84
+ if (!result.success) {
85
+ this.responseHandler.reject(result.error);
86
+ return;
87
+ }
88
+ resp = result.data;
89
+ }
90
+ switch (resp.type) {
91
+ case "error":
92
+ switch (resp.value) {
93
+ case "rejected":
94
+ this.responseHandler.reject(new UWError("REQUEST_REJECTED"));
95
+ break;
96
+ default: this.responseHandler.reject(new UWError("INVALID_RESPONSE", `unexpected error response value: ${resp.value}`));
97
+ }
98
+ break;
99
+ default: this.responseHandler.resolve(resp);
100
+ }
101
+ };
102
+ this.socket.onerror = null;
103
+ this.socket.onclose = (event) => {
104
+ if (this.responseHandler === null) return;
105
+ this.responseHandler.reject(new UWError("CONNECTION_CLOSED", event.reason));
106
+ };
107
+ }
108
+ get readyState() {
109
+ return this.socket.readyState;
110
+ }
111
+ get hasResponseHandler() {
112
+ return this.responseHandler !== null;
113
+ }
114
+ setResponseHandler(handler) {
115
+ this.responseHandler = handler;
116
+ }
149
117
  };
150
118
  function safeParseMessageEventDataToXResponse(data) {
151
- const result = z.string().refine(
152
- (val) => {
153
- try {
154
- JSON.parse(val);
155
- } catch (e) {
156
- return false;
157
- }
158
- return true;
159
- },
160
- {
161
- abort: true,
162
- message: "Invalid JSON string"
163
- }
164
- ).transform((val) => JSON.parse(val)).pipe(
165
- z.object({
166
- type: z.enum(VALID_X_RESPONSE_TYPES),
167
- value: z.string()
168
- })
169
- ).safeParse(data);
170
- if (!result.success) {
171
- return {
172
- success: false,
173
- error: new UWError(
174
- "INVALID_RESPONSE",
175
- `invalid message event data: ${result.error.message}`
176
- )
177
- };
178
- }
179
- return {
180
- success: true,
181
- data: result.data
182
- };
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);
133
+ if (!result.success) return {
134
+ success: false,
135
+ error: new UWError("INVALID_RESPONSE", `invalid message event data: ${result.error.message}`)
136
+ };
137
+ return {
138
+ success: true,
139
+ data: result.data
140
+ };
183
141
  }
184
-
185
- // src/unwallet.ts
186
- var UnWallet = class _UnWallet {
187
- constructor(args) {
188
- this.env = args.env;
189
- this.clientID = args.clientID;
190
- this.xConnection = args.xConnection;
191
- }
192
- static async init(config) {
193
- const env = config.env !== void 0 ? config.env : "prod";
194
- return new _UnWallet({
195
- env,
196
- clientID: config.clientID,
197
- xConnection: await XConnection.init(getUnWalletConfigByEnv(env).xapi)
198
- });
199
- }
200
- get unWalletConfig() {
201
- return getUnWalletConfigByEnv(this.env);
202
- }
203
- authorize(args) {
204
- const url = new URL(
205
- `${this.unWalletConfig.frontend.baseURL}/${args.isVirtual !== void 0 ? args.isVirtual ? "v" : "" : "v"}authorize`
206
- );
207
- {
208
- url.searchParams.set("response_type", "id_token");
209
- url.searchParams.set(
210
- "response_mode",
211
- args.responseMode !== void 0 ? args.responseMode : "fragment"
212
- );
213
- url.searchParams.set("client_id", this.clientID);
214
- url.searchParams.set("scope", "openid");
215
- url.searchParams.set("redirect_uri", args.redirectURL);
216
- if (args.nonce !== void 0) {
217
- url.searchParams.set("nonce", args.nonce);
218
- }
219
- if (args.chainID !== void 0) {
220
- url.searchParams.set("chain_id", args.chainID.toString());
221
- }
222
- }
223
- location.assign(url);
224
- }
225
- sign(args) {
226
- return new Promise((resolve, reject) => {
227
- if (this.xConnection.readyState !== WebSocket.OPEN) {
228
- reject(new UWError("CONNECTION_NOT_OPENED"));
229
- return;
230
- }
231
- if (this.xConnection.hasResponseHandler) {
232
- reject(new UWError("REQUEST_IN_PROGRESS"));
233
- return;
234
- }
235
- const digest = sha256(toBytes(args.message));
236
- this.xConnection.setResponseHandler({
237
- resolve: (resp) => {
238
- this.xConnection.setResponseHandler(null);
239
- if (resp.type !== "signature") {
240
- reject(
241
- new UWError(
242
- "INVALID_RESPONSE",
243
- `unexpected response type: ${resp.type}`
244
- )
245
- );
246
- return;
247
- }
248
- resolve({
249
- digest,
250
- signature: resp.value
251
- });
252
- },
253
- reject: (err) => {
254
- this.xConnection.setResponseHandler(null);
255
- reject(err);
256
- }
257
- });
258
- const url = new URL(`${this.unWalletConfig.frontend.baseURL}/x/sign`);
259
- {
260
- url.searchParams.set("connectionID", this.xConnection.id);
261
- url.searchParams.set("clientID", this.clientID);
262
- url.searchParams.set("message", args.message);
263
- url.searchParams.set("ticketToken", args.ticketToken);
264
- }
265
- openWindow(url);
266
- });
267
- }
268
- signEIP712TypedData(args) {
269
- return new Promise((resolve, reject) => {
270
- if (this.xConnection.readyState !== WebSocket.OPEN) {
271
- reject(new UWError("CONNECTION_NOT_OPENED"));
272
- return;
273
- }
274
- if (this.xConnection.hasResponseHandler) {
275
- reject(new UWError("REQUEST_IN_PROGRESS"));
276
- return;
277
- }
278
- const { EIP712Domain: _, ...typedDataTypes } = args.typedData.types;
279
- const typedData = {
280
- ...args.typedData,
281
- types: typedDataTypes
282
- };
283
- try {
284
- validateTypedData(typedData);
285
- } catch (e) {
286
- reject(
287
- new UWError(
288
- "INVALID_REQUEST",
289
- `invalid typed data: ${e.message}`
290
- )
291
- );
292
- return;
293
- }
294
- const digest = hashTypedData(typedData);
295
- this.xConnection.setResponseHandler({
296
- resolve: (resp) => {
297
- this.xConnection.setResponseHandler(null);
298
- if (resp.type !== "signature") {
299
- reject(
300
- new UWError(
301
- "INVALID_RESPONSE",
302
- `unexpected response type: ${resp.type}`
303
- )
304
- );
305
- return;
306
- }
307
- resolve({
308
- digest,
309
- signature: resp.value
310
- });
311
- },
312
- reject: (err) => {
313
- this.xConnection.setResponseHandler(null);
314
- reject(err);
315
- }
316
- });
317
- const url = new URL(
318
- `${this.unWalletConfig.frontend.baseURL}/x/signEIP712TypedData`
319
- );
320
- {
321
- url.searchParams.set("connectionID", this.xConnection.id);
322
- url.searchParams.set("clientID", this.clientID);
323
- url.searchParams.set("typedData", JSON.stringify(args.typedData));
324
- url.searchParams.set("ticketToken", args.ticketToken);
325
- }
326
- openWindow(url);
327
- });
328
- }
329
- sendTransaction(args) {
330
- return new Promise((resolve, reject) => {
331
- if (this.xConnection.readyState !== WebSocket.OPEN) {
332
- reject(new UWError("CONNECTION_NOT_OPENED"));
333
- return;
334
- }
335
- if (this.xConnection.hasResponseHandler) {
336
- reject(new UWError("REQUEST_IN_PROGRESS"));
337
- return;
338
- }
339
- if (args.value === void 0 && args.data === void 0) {
340
- reject(
341
- new UWError("INVALID_REQUEST", "either value or data is required")
342
- );
343
- return;
344
- }
345
- this.xConnection.setResponseHandler({
346
- resolve: (resp) => {
347
- this.xConnection.setResponseHandler(null);
348
- if (resp.type !== "transactionID") {
349
- reject(
350
- new UWError(
351
- "INVALID_RESPONSE",
352
- `unexpected response type: ${resp.type}`
353
- )
354
- );
355
- return;
356
- }
357
- resolve({ transactionID: resp.value });
358
- },
359
- reject: (err) => {
360
- this.xConnection.setResponseHandler(null);
361
- reject(err);
362
- }
363
- });
364
- const url = new URL(
365
- `${this.unWalletConfig.frontend.baseURL}/x/sendTransaction`
366
- );
367
- {
368
- url.searchParams.set("connectionID", this.xConnection.id);
369
- url.searchParams.set("clientID", this.clientID);
370
- url.searchParams.set("chainID", args.chainID.toString());
371
- url.searchParams.set("toAddress", args.toAddress);
372
- url.searchParams.set(
373
- "value",
374
- args.value !== void 0 ? args.value : "0x0"
375
- );
376
- url.searchParams.set(
377
- "data",
378
- args.data !== void 0 ? args.data : "0x"
379
- );
380
- url.searchParams.set("ticketToken", args.ticketToken);
381
- }
382
- openWindow(url);
383
- });
384
- }
142
+ //#endregion
143
+ //#region src/unwallet.ts
144
+ var UnWallet = class UnWallet {
145
+ constructor(args) {
146
+ this.env = args.env;
147
+ this.clientID = args.clientID;
148
+ this.xConnection = args.xConnection;
149
+ }
150
+ static async init(config) {
151
+ const env = config.env ?? "prod";
152
+ return new UnWallet({
153
+ env,
154
+ clientID: config.clientID,
155
+ xConnection: await XConnection.init(getUnWalletConfigByEnv(env).xapi)
156
+ });
157
+ }
158
+ get unWalletConfig() {
159
+ return getUnWalletConfigByEnv(this.env);
160
+ }
161
+ authorize(args) {
162
+ const url = new URL(`${this.unWalletConfig.frontend.baseURL}/${args.isVirtual !== void 0 ? args.isVirtual ? "v" : "" : "v"}authorize`);
163
+ url.searchParams.set("response_type", "id_token");
164
+ url.searchParams.set("response_mode", args.responseMode ?? "fragment");
165
+ url.searchParams.set("client_id", this.clientID);
166
+ url.searchParams.set("scope", "openid");
167
+ url.searchParams.set("redirect_uri", args.redirectURL);
168
+ if (args.nonce !== void 0) url.searchParams.set("nonce", args.nonce);
169
+ if (args.chainID !== void 0) url.searchParams.set("chain_id", args.chainID.toString());
170
+ location.assign(url);
171
+ }
172
+ sign(args) {
173
+ return new Promise((resolve, reject) => {
174
+ if (this.xConnection.readyState !== WebSocket.OPEN) {
175
+ reject(new UWError("CONNECTION_NOT_OPENED"));
176
+ return;
177
+ }
178
+ if (this.xConnection.hasResponseHandler) {
179
+ reject(new UWError("REQUEST_IN_PROGRESS"));
180
+ return;
181
+ }
182
+ const digest = sha256(toBytes(args.message));
183
+ this.xConnection.setResponseHandler({
184
+ resolve: (resp) => {
185
+ this.xConnection.setResponseHandler(null);
186
+ if (resp.type !== "signature") {
187
+ reject(new UWError("INVALID_RESPONSE", `unexpected response type: ${resp.type}`));
188
+ return;
189
+ }
190
+ resolve({
191
+ digest,
192
+ signature: resp.value
193
+ });
194
+ },
195
+ reject: (err) => {
196
+ this.xConnection.setResponseHandler(null);
197
+ reject(err);
198
+ }
199
+ });
200
+ const url = new URL(`${this.unWalletConfig.frontend.baseURL}/x/sign`);
201
+ url.searchParams.set("connectionID", this.xConnection.id);
202
+ url.searchParams.set("clientID", this.clientID);
203
+ url.searchParams.set("message", args.message);
204
+ url.searchParams.set("ticketToken", args.ticketToken);
205
+ openWindow(url);
206
+ });
207
+ }
208
+ signEIP712TypedData(args) {
209
+ return new Promise((resolve, reject) => {
210
+ if (this.xConnection.readyState !== WebSocket.OPEN) {
211
+ reject(new UWError("CONNECTION_NOT_OPENED"));
212
+ return;
213
+ }
214
+ if (this.xConnection.hasResponseHandler) {
215
+ reject(new UWError("REQUEST_IN_PROGRESS"));
216
+ return;
217
+ }
218
+ const { EIP712Domain: _, ...typedDataTypes } = args.typedData.types;
219
+ const typedData = {
220
+ ...args.typedData,
221
+ types: typedDataTypes
222
+ };
223
+ try {
224
+ validateTypedData(typedData);
225
+ } catch (e) {
226
+ reject(new UWError("INVALID_REQUEST", `invalid typed data: ${e.message}`));
227
+ return;
228
+ }
229
+ const digest = hashTypedData(typedData);
230
+ this.xConnection.setResponseHandler({
231
+ resolve: (resp) => {
232
+ this.xConnection.setResponseHandler(null);
233
+ if (resp.type !== "signature") {
234
+ reject(new UWError("INVALID_RESPONSE", `unexpected response type: ${resp.type}`));
235
+ return;
236
+ }
237
+ resolve({
238
+ digest,
239
+ signature: resp.value
240
+ });
241
+ },
242
+ reject: (err) => {
243
+ this.xConnection.setResponseHandler(null);
244
+ reject(err);
245
+ }
246
+ });
247
+ const url = new URL(`${this.unWalletConfig.frontend.baseURL}/x/signEIP712TypedData`);
248
+ url.searchParams.set("connectionID", this.xConnection.id);
249
+ url.searchParams.set("clientID", this.clientID);
250
+ url.searchParams.set("typedData", JSON.stringify(args.typedData));
251
+ url.searchParams.set("ticketToken", args.ticketToken);
252
+ openWindow(url);
253
+ });
254
+ }
255
+ sendTransaction(args) {
256
+ return new Promise((resolve, reject) => {
257
+ if (this.xConnection.readyState !== WebSocket.OPEN) {
258
+ reject(new UWError("CONNECTION_NOT_OPENED"));
259
+ return;
260
+ }
261
+ if (this.xConnection.hasResponseHandler) {
262
+ reject(new UWError("REQUEST_IN_PROGRESS"));
263
+ return;
264
+ }
265
+ if (args.value === void 0 && args.data === void 0) {
266
+ reject(new UWError("INVALID_REQUEST", "either value or data is required"));
267
+ return;
268
+ }
269
+ this.xConnection.setResponseHandler({
270
+ resolve: (resp) => {
271
+ this.xConnection.setResponseHandler(null);
272
+ if (resp.type !== "transactionID") {
273
+ reject(new UWError("INVALID_RESPONSE", `unexpected response type: ${resp.type}`));
274
+ return;
275
+ }
276
+ resolve({ transactionID: resp.value });
277
+ },
278
+ reject: (err) => {
279
+ this.xConnection.setResponseHandler(null);
280
+ reject(err);
281
+ }
282
+ });
283
+ const url = new URL(`${this.unWalletConfig.frontend.baseURL}/x/sendTransaction`);
284
+ url.searchParams.set("connectionID", this.xConnection.id);
285
+ url.searchParams.set("clientID", this.clientID);
286
+ url.searchParams.set("chainID", args.chainID.toString());
287
+ url.searchParams.set("toAddress", args.toAddress);
288
+ url.searchParams.set("value", args.value ?? "0x0");
289
+ url.searchParams.set("data", args.data ?? "0x");
290
+ url.searchParams.set("ticketToken", args.ticketToken);
291
+ openWindow(url);
292
+ });
293
+ }
385
294
  };
386
295
  function openWindow(url) {
387
- const width = screen.width / 2;
388
- const height = screen.height;
389
- const left = screen.width / 4;
390
- const top = 0;
391
- window.open(
392
- url.toString(),
393
- "_blank",
394
- `width=${width},height=${height},left=${left},top=${top}`
395
- );
296
+ const width = screen.width / 2;
297
+ const height = screen.height;
298
+ const left = screen.width / 4;
299
+ window.open(url.toString(), "_blank", `width=${width},height=${height},left=${left},top=0`);
396
300
  }
397
- export {
398
- UWError,
399
- UnWallet
400
- };
301
+ //#endregion
302
+ export { UWError, UnWallet };