unwallet-client-sdk 0.15.0 → 0.17.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.d.mts +70 -24
- package/dist/index.d.ts +70 -24
- package/dist/index.js +357 -114
- package/dist/index.mjs +346 -114
- package/package.json +6 -3
package/dist/index.d.mts
CHANGED
|
@@ -1,20 +1,66 @@
|
|
|
1
1
|
declare const VALID_ENVS: readonly ["prod", "dev"];
|
|
2
|
-
|
|
3
2
|
type Env = (typeof VALID_ENVS)[number];
|
|
4
3
|
interface Config {
|
|
5
|
-
clientID: string;
|
|
6
4
|
env?: Env;
|
|
7
|
-
|
|
8
|
-
interface UnWalletConfig {
|
|
9
|
-
frontend: UnWalletFrontendConfig;
|
|
10
|
-
xapi: UnWalletXAPIConfig;
|
|
11
|
-
}
|
|
12
|
-
interface UnWalletFrontendConfig {
|
|
13
|
-
baseURL: string;
|
|
5
|
+
clientID: string;
|
|
14
6
|
}
|
|
15
7
|
interface UnWalletXAPIConfig {
|
|
16
8
|
url: string;
|
|
9
|
+
connectionTimeout: number;
|
|
17
10
|
}
|
|
11
|
+
|
|
12
|
+
interface EIP712TypedData {
|
|
13
|
+
types: Record<string, Array<EIP712TypedDataField>>;
|
|
14
|
+
primaryType: string;
|
|
15
|
+
domain: EIP712TypedDataDomain;
|
|
16
|
+
message: Record<string, any>;
|
|
17
|
+
}
|
|
18
|
+
interface EIP712TypedDataDomain {
|
|
19
|
+
name?: string;
|
|
20
|
+
version?: string;
|
|
21
|
+
chainId?: number;
|
|
22
|
+
verifyingContract?: string;
|
|
23
|
+
salt?: string;
|
|
24
|
+
}
|
|
25
|
+
interface EIP712TypedDataField {
|
|
26
|
+
name: string;
|
|
27
|
+
type: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
declare const VALID_UW_ERROR_CODES: readonly ["CONNECTION_TIMEOUT", "CONNECTION_FAILED", "CONNECTION_NOT_OPENED", "CONNECTION_CLOSED", "INVALID_REQUEST", "REQUEST_IN_PROGRESS", "REQUEST_REJECTED", "INVALID_RESPONSE"];
|
|
31
|
+
type UWErrorCode = (typeof VALID_UW_ERROR_CODES)[number];
|
|
32
|
+
declare class UWError extends Error {
|
|
33
|
+
readonly code: UWErrorCode;
|
|
34
|
+
constructor(code: UWErrorCode, message?: string);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
declare const VALID_X_RESPONSE_TYPES: readonly ["connectionID", "signature", "transactionID", "error"];
|
|
38
|
+
type XResponseType = (typeof VALID_X_RESPONSE_TYPES)[number];
|
|
39
|
+
interface XResponse {
|
|
40
|
+
readonly type: XResponseType;
|
|
41
|
+
readonly value: string;
|
|
42
|
+
}
|
|
43
|
+
interface XResponseHandler {
|
|
44
|
+
resolve: (resp: XResponse) => void;
|
|
45
|
+
reject: (err: UWError) => void;
|
|
46
|
+
}
|
|
47
|
+
declare class XConnection {
|
|
48
|
+
private socket;
|
|
49
|
+
private responseHandler;
|
|
50
|
+
readonly id: string;
|
|
51
|
+
constructor(args: {
|
|
52
|
+
socket: WebSocket;
|
|
53
|
+
id: string;
|
|
54
|
+
});
|
|
55
|
+
private initListeners;
|
|
56
|
+
get readyState(): number;
|
|
57
|
+
get hasResponseHandler(): boolean;
|
|
58
|
+
setResponseHandler(handler: XResponseHandler | null): void;
|
|
59
|
+
static init(config: UnWalletXAPIConfig): Promise<XConnection>;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
declare const VALID_AUTHORIZATION_RESPONSE_MODES: readonly ["fragment", "form_post"];
|
|
63
|
+
type AuthorizationResponseMode = (typeof VALID_AUTHORIZATION_RESPONSE_MODES)[number];
|
|
18
64
|
interface SignResult {
|
|
19
65
|
digest: string;
|
|
20
66
|
signature: string;
|
|
@@ -22,19 +68,19 @@ interface SignResult {
|
|
|
22
68
|
interface SendTransactionResult {
|
|
23
69
|
transactionID: string;
|
|
24
70
|
}
|
|
25
|
-
|
|
26
71
|
declare class UnWallet {
|
|
27
|
-
private
|
|
28
|
-
private
|
|
29
|
-
private
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
72
|
+
private env;
|
|
73
|
+
private clientID;
|
|
74
|
+
private xConnection;
|
|
75
|
+
constructor(args: {
|
|
76
|
+
env: Env;
|
|
77
|
+
clientID: string;
|
|
78
|
+
xConnection: XConnection;
|
|
79
|
+
});
|
|
35
80
|
static init(config: Config): Promise<UnWallet>;
|
|
81
|
+
private get unWalletConfig();
|
|
36
82
|
authorize(args: {
|
|
37
|
-
responseMode?:
|
|
83
|
+
responseMode?: AuthorizationResponseMode;
|
|
38
84
|
redirectURL: string;
|
|
39
85
|
nonce?: string;
|
|
40
86
|
isVirtual?: boolean;
|
|
@@ -44,6 +90,10 @@ declare class UnWallet {
|
|
|
44
90
|
message: string;
|
|
45
91
|
ticketToken: string;
|
|
46
92
|
}): Promise<SignResult>;
|
|
93
|
+
signEIP712TypedData(args: {
|
|
94
|
+
typedData: EIP712TypedData;
|
|
95
|
+
ticketToken: string;
|
|
96
|
+
}): Promise<SignResult>;
|
|
47
97
|
sendTransaction(args: {
|
|
48
98
|
chainID: number;
|
|
49
99
|
toAddress: string;
|
|
@@ -51,10 +101,6 @@ declare class UnWallet {
|
|
|
51
101
|
data?: string;
|
|
52
102
|
ticketToken: string;
|
|
53
103
|
}): Promise<SendTransactionResult>;
|
|
54
|
-
private getConnectionID;
|
|
55
|
-
private sendWSMessage;
|
|
56
|
-
private handleWSMessage;
|
|
57
|
-
private openWindow;
|
|
58
104
|
}
|
|
59
105
|
|
|
60
|
-
export { type Config, type SendTransactionResult, type SignResult, UnWallet };
|
|
106
|
+
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,20 +1,66 @@
|
|
|
1
1
|
declare const VALID_ENVS: readonly ["prod", "dev"];
|
|
2
|
-
|
|
3
2
|
type Env = (typeof VALID_ENVS)[number];
|
|
4
3
|
interface Config {
|
|
5
|
-
clientID: string;
|
|
6
4
|
env?: Env;
|
|
7
|
-
|
|
8
|
-
interface UnWalletConfig {
|
|
9
|
-
frontend: UnWalletFrontendConfig;
|
|
10
|
-
xapi: UnWalletXAPIConfig;
|
|
11
|
-
}
|
|
12
|
-
interface UnWalletFrontendConfig {
|
|
13
|
-
baseURL: string;
|
|
5
|
+
clientID: string;
|
|
14
6
|
}
|
|
15
7
|
interface UnWalletXAPIConfig {
|
|
16
8
|
url: string;
|
|
9
|
+
connectionTimeout: number;
|
|
17
10
|
}
|
|
11
|
+
|
|
12
|
+
interface EIP712TypedData {
|
|
13
|
+
types: Record<string, Array<EIP712TypedDataField>>;
|
|
14
|
+
primaryType: string;
|
|
15
|
+
domain: EIP712TypedDataDomain;
|
|
16
|
+
message: Record<string, any>;
|
|
17
|
+
}
|
|
18
|
+
interface EIP712TypedDataDomain {
|
|
19
|
+
name?: string;
|
|
20
|
+
version?: string;
|
|
21
|
+
chainId?: number;
|
|
22
|
+
verifyingContract?: string;
|
|
23
|
+
salt?: string;
|
|
24
|
+
}
|
|
25
|
+
interface EIP712TypedDataField {
|
|
26
|
+
name: string;
|
|
27
|
+
type: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
declare const VALID_UW_ERROR_CODES: readonly ["CONNECTION_TIMEOUT", "CONNECTION_FAILED", "CONNECTION_NOT_OPENED", "CONNECTION_CLOSED", "INVALID_REQUEST", "REQUEST_IN_PROGRESS", "REQUEST_REJECTED", "INVALID_RESPONSE"];
|
|
31
|
+
type UWErrorCode = (typeof VALID_UW_ERROR_CODES)[number];
|
|
32
|
+
declare class UWError extends Error {
|
|
33
|
+
readonly code: UWErrorCode;
|
|
34
|
+
constructor(code: UWErrorCode, message?: string);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
declare const VALID_X_RESPONSE_TYPES: readonly ["connectionID", "signature", "transactionID", "error"];
|
|
38
|
+
type XResponseType = (typeof VALID_X_RESPONSE_TYPES)[number];
|
|
39
|
+
interface XResponse {
|
|
40
|
+
readonly type: XResponseType;
|
|
41
|
+
readonly value: string;
|
|
42
|
+
}
|
|
43
|
+
interface XResponseHandler {
|
|
44
|
+
resolve: (resp: XResponse) => void;
|
|
45
|
+
reject: (err: UWError) => void;
|
|
46
|
+
}
|
|
47
|
+
declare class XConnection {
|
|
48
|
+
private socket;
|
|
49
|
+
private responseHandler;
|
|
50
|
+
readonly id: string;
|
|
51
|
+
constructor(args: {
|
|
52
|
+
socket: WebSocket;
|
|
53
|
+
id: string;
|
|
54
|
+
});
|
|
55
|
+
private initListeners;
|
|
56
|
+
get readyState(): number;
|
|
57
|
+
get hasResponseHandler(): boolean;
|
|
58
|
+
setResponseHandler(handler: XResponseHandler | null): void;
|
|
59
|
+
static init(config: UnWalletXAPIConfig): Promise<XConnection>;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
declare const VALID_AUTHORIZATION_RESPONSE_MODES: readonly ["fragment", "form_post"];
|
|
63
|
+
type AuthorizationResponseMode = (typeof VALID_AUTHORIZATION_RESPONSE_MODES)[number];
|
|
18
64
|
interface SignResult {
|
|
19
65
|
digest: string;
|
|
20
66
|
signature: string;
|
|
@@ -22,19 +68,19 @@ interface SignResult {
|
|
|
22
68
|
interface SendTransactionResult {
|
|
23
69
|
transactionID: string;
|
|
24
70
|
}
|
|
25
|
-
|
|
26
71
|
declare class UnWallet {
|
|
27
|
-
private
|
|
28
|
-
private
|
|
29
|
-
private
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
72
|
+
private env;
|
|
73
|
+
private clientID;
|
|
74
|
+
private xConnection;
|
|
75
|
+
constructor(args: {
|
|
76
|
+
env: Env;
|
|
77
|
+
clientID: string;
|
|
78
|
+
xConnection: XConnection;
|
|
79
|
+
});
|
|
35
80
|
static init(config: Config): Promise<UnWallet>;
|
|
81
|
+
private get unWalletConfig();
|
|
36
82
|
authorize(args: {
|
|
37
|
-
responseMode?:
|
|
83
|
+
responseMode?: AuthorizationResponseMode;
|
|
38
84
|
redirectURL: string;
|
|
39
85
|
nonce?: string;
|
|
40
86
|
isVirtual?: boolean;
|
|
@@ -44,6 +90,10 @@ declare class UnWallet {
|
|
|
44
90
|
message: string;
|
|
45
91
|
ticketToken: string;
|
|
46
92
|
}): Promise<SignResult>;
|
|
93
|
+
signEIP712TypedData(args: {
|
|
94
|
+
typedData: EIP712TypedData;
|
|
95
|
+
ticketToken: string;
|
|
96
|
+
}): Promise<SignResult>;
|
|
47
97
|
sendTransaction(args: {
|
|
48
98
|
chainID: number;
|
|
49
99
|
toAddress: string;
|
|
@@ -51,10 +101,6 @@ declare class UnWallet {
|
|
|
51
101
|
data?: string;
|
|
52
102
|
ticketToken: string;
|
|
53
103
|
}): Promise<SendTransactionResult>;
|
|
54
|
-
private getConnectionID;
|
|
55
|
-
private sendWSMessage;
|
|
56
|
-
private handleWSMessage;
|
|
57
|
-
private openWindow;
|
|
58
104
|
}
|
|
59
105
|
|
|
60
|
-
export { type Config, type SendTransactionResult, type SignResult, UnWallet };
|
|
106
|
+
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,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,25 +17,46 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/index.ts
|
|
21
31
|
var index_exports = {};
|
|
22
32
|
__export(index_exports, {
|
|
33
|
+
UWError: () => UWError,
|
|
23
34
|
UnWallet: () => UnWallet
|
|
24
35
|
});
|
|
25
36
|
module.exports = __toCommonJS(index_exports);
|
|
26
37
|
|
|
38
|
+
// src/error.ts
|
|
39
|
+
var _UWError = class _UWError extends Error {
|
|
40
|
+
constructor(code, message) {
|
|
41
|
+
super(message !== void 0 ? `${code}: ${message}` : code);
|
|
42
|
+
this.code = code;
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
_UWError.prototype.name = "UWError";
|
|
46
|
+
var UWError = _UWError;
|
|
47
|
+
|
|
27
48
|
// src/unwallet.ts
|
|
28
49
|
var import_ethers = require("ethers");
|
|
50
|
+
var import_omit = __toESM(require("lodash/omit"));
|
|
29
51
|
|
|
30
|
-
// src/
|
|
52
|
+
// src/config.ts
|
|
31
53
|
var UNWALLET_CONFIG_PROD = {
|
|
32
54
|
frontend: {
|
|
33
55
|
baseURL: "https://id.unwallet.world"
|
|
34
56
|
},
|
|
35
57
|
xapi: {
|
|
36
|
-
url: "wss://xapi.id.unwallet.world"
|
|
58
|
+
url: "wss://xapi.id.unwallet.world",
|
|
59
|
+
connectionTimeout: 1e4
|
|
37
60
|
}
|
|
38
61
|
};
|
|
39
62
|
var UNWALLET_CONFIG_DEV = {
|
|
@@ -41,75 +64,186 @@ var UNWALLET_CONFIG_DEV = {
|
|
|
41
64
|
baseURL: "http://localhost:4200"
|
|
42
65
|
},
|
|
43
66
|
xapi: {
|
|
44
|
-
url: "wss://xapi.id.test.unwallet.dev"
|
|
67
|
+
url: "wss://xapi.id.test.unwallet.dev",
|
|
68
|
+
connectionTimeout: 1e4
|
|
45
69
|
}
|
|
46
70
|
};
|
|
71
|
+
function getUnWalletConfigByEnv(env) {
|
|
72
|
+
switch (env) {
|
|
73
|
+
case "prod":
|
|
74
|
+
return UNWALLET_CONFIG_PROD;
|
|
75
|
+
case "dev":
|
|
76
|
+
return UNWALLET_CONFIG_DEV;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
47
79
|
|
|
48
|
-
// src/
|
|
49
|
-
var
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
this.
|
|
61
|
-
|
|
62
|
-
this.reject = () => {
|
|
63
|
-
};
|
|
80
|
+
// src/x.ts
|
|
81
|
+
var import_v4 = require("zod/v4");
|
|
82
|
+
var VALID_X_RESPONSE_TYPES = [
|
|
83
|
+
"connectionID",
|
|
84
|
+
"signature",
|
|
85
|
+
"transactionID",
|
|
86
|
+
"error"
|
|
87
|
+
];
|
|
88
|
+
var XConnection = class _XConnection {
|
|
89
|
+
constructor(args) {
|
|
90
|
+
this.responseHandler = null;
|
|
91
|
+
this.socket = args.socket;
|
|
92
|
+
this.id = args.id;
|
|
93
|
+
this.initListeners();
|
|
64
94
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
95
|
+
initListeners() {
|
|
96
|
+
this.socket.onopen = null;
|
|
97
|
+
this.socket.onmessage = (event) => {
|
|
98
|
+
if (this.responseHandler === null) {
|
|
99
|
+
return;
|
|
69
100
|
}
|
|
70
|
-
let
|
|
101
|
+
let resp;
|
|
71
102
|
{
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
case "dev":
|
|
77
|
-
unWalletConfig = UNWALLET_CONFIG_DEV;
|
|
78
|
-
break;
|
|
103
|
+
const result = safeParseMessageEventDataToXResponse(event.data);
|
|
104
|
+
if (!result.success) {
|
|
105
|
+
this.responseHandler.reject(result.error);
|
|
106
|
+
return;
|
|
79
107
|
}
|
|
108
|
+
resp = result.data;
|
|
80
109
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
110
|
+
switch (resp.type) {
|
|
111
|
+
case "error":
|
|
112
|
+
switch (resp.value) {
|
|
113
|
+
case "rejected":
|
|
114
|
+
this.responseHandler.reject(new UWError("REQUEST_REJECTED"));
|
|
115
|
+
break;
|
|
116
|
+
default:
|
|
117
|
+
this.responseHandler.reject(
|
|
118
|
+
new UWError(
|
|
119
|
+
"INVALID_RESPONSE",
|
|
120
|
+
`unexpected error response value: ${resp.value}`
|
|
121
|
+
)
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
break;
|
|
125
|
+
default:
|
|
126
|
+
this.responseHandler.resolve(resp);
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
this.socket.onerror = null;
|
|
130
|
+
this.socket.onclose = (event) => {
|
|
131
|
+
if (this.responseHandler === null) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
this.responseHandler.reject(
|
|
135
|
+
new UWError("CONNECTION_CLOSED", event.reason)
|
|
136
|
+
);
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
get readyState() {
|
|
140
|
+
return this.socket.readyState;
|
|
141
|
+
}
|
|
142
|
+
get hasResponseHandler() {
|
|
143
|
+
return this.responseHandler !== null;
|
|
144
|
+
}
|
|
145
|
+
setResponseHandler(handler) {
|
|
146
|
+
this.responseHandler = handler;
|
|
147
|
+
}
|
|
148
|
+
static async init(config) {
|
|
149
|
+
const socket = new WebSocket(config.url);
|
|
150
|
+
const id = await new Promise((resolve, reject) => {
|
|
151
|
+
setInterval(
|
|
152
|
+
() => reject(new UWError("CONNECTION_TIMEOUT")),
|
|
153
|
+
config.connectionTimeout
|
|
154
|
+
);
|
|
155
|
+
socket.onopen = () => socket.send(JSON.stringify({ action: "getConnectionID" }));
|
|
156
|
+
socket.onmessage = (event) => {
|
|
157
|
+
let resp;
|
|
158
|
+
{
|
|
159
|
+
const result = safeParseMessageEventDataToXResponse(event.data);
|
|
160
|
+
if (!result.success) {
|
|
161
|
+
reject(result.error);
|
|
94
162
|
return;
|
|
95
163
|
}
|
|
96
|
-
|
|
97
|
-
}
|
|
164
|
+
resp = result.data;
|
|
165
|
+
}
|
|
166
|
+
if (resp.type !== "connectionID") {
|
|
167
|
+
reject(
|
|
168
|
+
new UWError(
|
|
169
|
+
"INVALID_RESPONSE",
|
|
170
|
+
`unexpected response type: ${resp.type}`
|
|
171
|
+
)
|
|
172
|
+
);
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
resolve(resp.value);
|
|
176
|
+
};
|
|
177
|
+
socket.onerror = () => reject(new UWError("CONNECTION_FAILED"));
|
|
178
|
+
socket.onclose = (event) => reject(new UWError("CONNECTION_CLOSED", event.reason));
|
|
179
|
+
});
|
|
180
|
+
return new _XConnection({ socket, id });
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
function safeParseMessageEventDataToXResponse(data) {
|
|
184
|
+
const result = import_v4.z.string().refine(
|
|
185
|
+
(val) => {
|
|
186
|
+
try {
|
|
187
|
+
JSON.parse(val);
|
|
188
|
+
} catch (e) {
|
|
189
|
+
return false;
|
|
98
190
|
}
|
|
99
|
-
|
|
191
|
+
return true;
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
abort: true,
|
|
195
|
+
message: "Invalid JSON string"
|
|
196
|
+
}
|
|
197
|
+
).transform((val) => JSON.parse(val)).pipe(
|
|
198
|
+
import_v4.z.object({
|
|
199
|
+
type: import_v4.z.enum(VALID_X_RESPONSE_TYPES),
|
|
200
|
+
value: import_v4.z.string()
|
|
201
|
+
})
|
|
202
|
+
).safeParse(data);
|
|
203
|
+
if (!result.success) {
|
|
204
|
+
return {
|
|
205
|
+
success: false,
|
|
206
|
+
error: new UWError(
|
|
207
|
+
"INVALID_RESPONSE",
|
|
208
|
+
`invalid message event data: ${result.error.message}`
|
|
209
|
+
)
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
return {
|
|
213
|
+
success: true,
|
|
214
|
+
data: result.data
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// src/unwallet.ts
|
|
219
|
+
var UnWallet = class _UnWallet {
|
|
220
|
+
constructor(args) {
|
|
221
|
+
this.env = args.env;
|
|
222
|
+
this.clientID = args.clientID;
|
|
223
|
+
this.xConnection = args.xConnection;
|
|
224
|
+
}
|
|
225
|
+
static async init(config) {
|
|
226
|
+
const env = config.env !== void 0 ? config.env : "prod";
|
|
227
|
+
return new _UnWallet({
|
|
228
|
+
env,
|
|
229
|
+
clientID: config.clientID,
|
|
230
|
+
xConnection: await XConnection.init(getUnWalletConfigByEnv(env).xapi)
|
|
100
231
|
});
|
|
101
232
|
}
|
|
233
|
+
get unWalletConfig() {
|
|
234
|
+
return getUnWalletConfigByEnv(this.env);
|
|
235
|
+
}
|
|
102
236
|
authorize(args) {
|
|
103
|
-
|
|
104
|
-
args.
|
|
105
|
-
}
|
|
106
|
-
let url = new URL(
|
|
107
|
-
`${this.unWalletConfig.frontend.baseURL}/${args.isVirtual === false ? "" : "v"}authorize`
|
|
237
|
+
const url = new URL(
|
|
238
|
+
`${this.unWalletConfig.frontend.baseURL}/${args.isVirtual !== void 0 ? args.isVirtual ? "v" : "" : "v"}authorize`
|
|
108
239
|
);
|
|
109
240
|
{
|
|
110
241
|
url.searchParams.set("response_type", "id_token");
|
|
111
|
-
url.searchParams.set(
|
|
112
|
-
|
|
242
|
+
url.searchParams.set(
|
|
243
|
+
"response_mode",
|
|
244
|
+
args.responseMode !== void 0 ? args.responseMode : "fragment"
|
|
245
|
+
);
|
|
246
|
+
url.searchParams.set("client_id", this.clientID);
|
|
113
247
|
url.searchParams.set("scope", "openid");
|
|
114
248
|
url.searchParams.set("redirect_uri", args.redirectURL);
|
|
115
249
|
if (args.nonce !== void 0) {
|
|
@@ -119,42 +253,180 @@ var UnWallet = class _UnWallet {
|
|
|
119
253
|
url.searchParams.set("chain_id", args.chainID.toString());
|
|
120
254
|
}
|
|
121
255
|
}
|
|
122
|
-
location.assign(url
|
|
256
|
+
location.assign(url);
|
|
123
257
|
}
|
|
124
258
|
sign(args) {
|
|
125
259
|
return new Promise((resolve, reject) => {
|
|
126
|
-
this.
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
260
|
+
if (this.xConnection.readyState !== WebSocket.OPEN) {
|
|
261
|
+
reject(new UWError("CONNECTION_NOT_OPENED"));
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
if (this.xConnection.hasResponseHandler) {
|
|
265
|
+
reject(new UWError("REQUEST_IN_PROGRESS"));
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
const digest = import_ethers.ethers.sha256(import_ethers.ethers.toUtf8Bytes(args.message));
|
|
269
|
+
this.xConnection.setResponseHandler({
|
|
270
|
+
resolve: (resp) => {
|
|
271
|
+
this.xConnection.setResponseHandler(null);
|
|
272
|
+
if (resp.type !== "signature") {
|
|
273
|
+
reject(
|
|
274
|
+
new UWError(
|
|
275
|
+
"INVALID_RESPONSE",
|
|
276
|
+
`unexpected response type: ${resp.type}`
|
|
277
|
+
)
|
|
278
|
+
);
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
resolve({
|
|
282
|
+
digest,
|
|
283
|
+
signature: resp.value
|
|
284
|
+
});
|
|
285
|
+
},
|
|
286
|
+
reject: (err) => {
|
|
287
|
+
this.xConnection.setResponseHandler(null);
|
|
288
|
+
reject(err);
|
|
289
|
+
}
|
|
290
|
+
});
|
|
133
291
|
const url = new URL(`${this.unWalletConfig.frontend.baseURL}/x/sign`);
|
|
134
292
|
{
|
|
135
|
-
url.searchParams.set("connectionID", this.
|
|
136
|
-
url.searchParams.set("clientID", this.
|
|
293
|
+
url.searchParams.set("connectionID", this.xConnection.id);
|
|
294
|
+
url.searchParams.set("clientID", this.clientID);
|
|
137
295
|
url.searchParams.set("message", args.message);
|
|
138
296
|
url.searchParams.set("ticketToken", args.ticketToken);
|
|
139
297
|
}
|
|
140
|
-
|
|
298
|
+
openWindow(url);
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
signEIP712TypedData(args) {
|
|
302
|
+
return new Promise((resolve, reject) => {
|
|
303
|
+
if (this.xConnection.readyState !== WebSocket.OPEN) {
|
|
304
|
+
reject(new UWError("CONNECTION_NOT_OPENED"));
|
|
305
|
+
return;
|
|
306
|
+
}
|
|
307
|
+
if (this.xConnection.hasResponseHandler) {
|
|
308
|
+
reject(new UWError("REQUEST_IN_PROGRESS"));
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
const types = (0, import_omit.default)(args.typedData.types, "EIP712Domain");
|
|
312
|
+
let primaryType;
|
|
313
|
+
{
|
|
314
|
+
try {
|
|
315
|
+
primaryType = import_ethers.ethers.TypedDataEncoder.getPrimaryType(types);
|
|
316
|
+
} catch (e) {
|
|
317
|
+
if (import_ethers.ethers.isError(e, "INVALID_ARGUMENT")) {
|
|
318
|
+
reject(
|
|
319
|
+
new UWError("INVALID_REQUEST", `invalid typed data: ${e.message}`)
|
|
320
|
+
);
|
|
321
|
+
return;
|
|
322
|
+
}
|
|
323
|
+
reject(e);
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
if (primaryType !== args.typedData.primaryType) {
|
|
328
|
+
reject(
|
|
329
|
+
new UWError(
|
|
330
|
+
"INVALID_REQUEST",
|
|
331
|
+
`invalid typed data: primary type must be ${primaryType}`
|
|
332
|
+
)
|
|
333
|
+
);
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
let digest;
|
|
337
|
+
{
|
|
338
|
+
try {
|
|
339
|
+
digest = import_ethers.ethers.TypedDataEncoder.hash(
|
|
340
|
+
args.typedData.domain,
|
|
341
|
+
types,
|
|
342
|
+
args.typedData.message
|
|
343
|
+
);
|
|
344
|
+
} catch (e) {
|
|
345
|
+
if (import_ethers.ethers.isError(e, "INVALID_ARGUMENT")) {
|
|
346
|
+
reject(
|
|
347
|
+
new UWError("INVALID_REQUEST", `invalid typed data: ${e.message}`)
|
|
348
|
+
);
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
reject(e);
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
this.xConnection.setResponseHandler({
|
|
356
|
+
resolve: (resp) => {
|
|
357
|
+
this.xConnection.setResponseHandler(null);
|
|
358
|
+
if (resp.type !== "signature") {
|
|
359
|
+
reject(
|
|
360
|
+
new UWError(
|
|
361
|
+
"INVALID_RESPONSE",
|
|
362
|
+
`unexpected response type: ${resp.type}`
|
|
363
|
+
)
|
|
364
|
+
);
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
resolve({
|
|
368
|
+
digest,
|
|
369
|
+
signature: resp.value
|
|
370
|
+
});
|
|
371
|
+
},
|
|
372
|
+
reject: (err) => {
|
|
373
|
+
this.xConnection.setResponseHandler(null);
|
|
374
|
+
reject(err);
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
const url = new URL(
|
|
378
|
+
`${this.unWalletConfig.frontend.baseURL}/x/signEIP712TypedData`
|
|
379
|
+
);
|
|
380
|
+
{
|
|
381
|
+
url.searchParams.set("connectionID", this.xConnection.id);
|
|
382
|
+
url.searchParams.set("clientID", this.clientID);
|
|
383
|
+
url.searchParams.set("typedData", JSON.stringify(args.typedData));
|
|
384
|
+
url.searchParams.set("ticketToken", args.ticketToken);
|
|
385
|
+
}
|
|
386
|
+
openWindow(url);
|
|
141
387
|
});
|
|
142
388
|
}
|
|
143
389
|
sendTransaction(args) {
|
|
144
390
|
return new Promise((resolve, reject) => {
|
|
391
|
+
if (this.xConnection.readyState !== WebSocket.OPEN) {
|
|
392
|
+
reject(new UWError("CONNECTION_NOT_OPENED"));
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
if (this.xConnection.hasResponseHandler) {
|
|
396
|
+
reject(new UWError("REQUEST_IN_PROGRESS"));
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
145
399
|
if (args.value === void 0 && args.data === void 0) {
|
|
146
|
-
|
|
400
|
+
reject(
|
|
401
|
+
new UWError("INVALID_REQUEST", "either value or data is required")
|
|
402
|
+
);
|
|
403
|
+
return;
|
|
147
404
|
}
|
|
148
|
-
this.
|
|
149
|
-
resolve(
|
|
150
|
-
|
|
151
|
-
|
|
405
|
+
this.xConnection.setResponseHandler({
|
|
406
|
+
resolve: (resp) => {
|
|
407
|
+
this.xConnection.setResponseHandler(null);
|
|
408
|
+
if (resp.type !== "transactionID") {
|
|
409
|
+
reject(
|
|
410
|
+
new UWError(
|
|
411
|
+
"INVALID_RESPONSE",
|
|
412
|
+
`unexpected response type: ${resp.type}`
|
|
413
|
+
)
|
|
414
|
+
);
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
resolve({ transactionID: resp.value });
|
|
418
|
+
},
|
|
419
|
+
reject: (err) => {
|
|
420
|
+
this.xConnection.setResponseHandler(null);
|
|
421
|
+
reject(err);
|
|
422
|
+
}
|
|
423
|
+
});
|
|
152
424
|
const url = new URL(
|
|
153
425
|
`${this.unWalletConfig.frontend.baseURL}/x/sendTransaction`
|
|
154
426
|
);
|
|
155
427
|
{
|
|
156
|
-
url.searchParams.set("connectionID", this.
|
|
157
|
-
url.searchParams.set("clientID", this.
|
|
428
|
+
url.searchParams.set("connectionID", this.xConnection.id);
|
|
429
|
+
url.searchParams.set("clientID", this.clientID);
|
|
158
430
|
url.searchParams.set("chainID", args.chainID.toString());
|
|
159
431
|
url.searchParams.set("toAddress", args.toAddress);
|
|
160
432
|
url.searchParams.set(
|
|
@@ -167,52 +439,23 @@ var UnWallet = class _UnWallet {
|
|
|
167
439
|
);
|
|
168
440
|
url.searchParams.set("ticketToken", args.ticketToken);
|
|
169
441
|
}
|
|
170
|
-
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
getConnectionID() {
|
|
174
|
-
this.sendWSMessage({
|
|
175
|
-
action: "getConnectionID"
|
|
442
|
+
openWindow(url);
|
|
176
443
|
});
|
|
177
444
|
}
|
|
178
|
-
sendWSMessage(msg) {
|
|
179
|
-
this.ws.send(JSON.stringify(msg));
|
|
180
|
-
}
|
|
181
|
-
handleWSMessage(msg) {
|
|
182
|
-
switch (msg.type) {
|
|
183
|
-
case "signature":
|
|
184
|
-
this.resolve(msg.value);
|
|
185
|
-
break;
|
|
186
|
-
case "transactionID":
|
|
187
|
-
this.resolve(msg.value);
|
|
188
|
-
break;
|
|
189
|
-
case "error":
|
|
190
|
-
switch (msg.value) {
|
|
191
|
-
case "rejected":
|
|
192
|
-
this.reject("canceled");
|
|
193
|
-
break;
|
|
194
|
-
default:
|
|
195
|
-
throw new Error(msg.value);
|
|
196
|
-
}
|
|
197
|
-
break;
|
|
198
|
-
default:
|
|
199
|
-
throw new Error(`unexpected message type: ${msg.type}`);
|
|
200
|
-
}
|
|
201
|
-
this.initPromiseArgs();
|
|
202
|
-
}
|
|
203
|
-
openWindow(url) {
|
|
204
|
-
const width = screen.width / 2;
|
|
205
|
-
const height = screen.height;
|
|
206
|
-
const left = screen.width / 4;
|
|
207
|
-
const top = 0;
|
|
208
|
-
window.open(
|
|
209
|
-
url.toString(),
|
|
210
|
-
"_blank",
|
|
211
|
-
`width=${width},height=${height},left=${left},top=${top}`
|
|
212
|
-
);
|
|
213
|
-
}
|
|
214
445
|
};
|
|
446
|
+
function openWindow(url) {
|
|
447
|
+
const width = screen.width / 2;
|
|
448
|
+
const height = screen.height;
|
|
449
|
+
const left = screen.width / 4;
|
|
450
|
+
const top = 0;
|
|
451
|
+
window.open(
|
|
452
|
+
url.toString(),
|
|
453
|
+
"_blank",
|
|
454
|
+
`width=${width},height=${height},left=${left},top=${top}`
|
|
455
|
+
);
|
|
456
|
+
}
|
|
215
457
|
// Annotate the CommonJS export names for ESM import in node:
|
|
216
458
|
0 && (module.exports = {
|
|
459
|
+
UWError,
|
|
217
460
|
UnWallet
|
|
218
461
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -1,13 +1,25 @@
|
|
|
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
|
+
|
|
1
11
|
// src/unwallet.ts
|
|
2
12
|
import { ethers } from "ethers";
|
|
13
|
+
import omit from "lodash/omit";
|
|
3
14
|
|
|
4
|
-
// src/
|
|
15
|
+
// src/config.ts
|
|
5
16
|
var UNWALLET_CONFIG_PROD = {
|
|
6
17
|
frontend: {
|
|
7
18
|
baseURL: "https://id.unwallet.world"
|
|
8
19
|
},
|
|
9
20
|
xapi: {
|
|
10
|
-
url: "wss://xapi.id.unwallet.world"
|
|
21
|
+
url: "wss://xapi.id.unwallet.world",
|
|
22
|
+
connectionTimeout: 1e4
|
|
11
23
|
}
|
|
12
24
|
};
|
|
13
25
|
var UNWALLET_CONFIG_DEV = {
|
|
@@ -15,75 +27,186 @@ var UNWALLET_CONFIG_DEV = {
|
|
|
15
27
|
baseURL: "http://localhost:4200"
|
|
16
28
|
},
|
|
17
29
|
xapi: {
|
|
18
|
-
url: "wss://xapi.id.test.unwallet.dev"
|
|
30
|
+
url: "wss://xapi.id.test.unwallet.dev",
|
|
31
|
+
connectionTimeout: 1e4
|
|
19
32
|
}
|
|
20
33
|
};
|
|
34
|
+
function getUnWalletConfigByEnv(env) {
|
|
35
|
+
switch (env) {
|
|
36
|
+
case "prod":
|
|
37
|
+
return UNWALLET_CONFIG_PROD;
|
|
38
|
+
case "dev":
|
|
39
|
+
return UNWALLET_CONFIG_DEV;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
21
42
|
|
|
22
|
-
// src/
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
this.
|
|
35
|
-
|
|
36
|
-
this.reject = () => {
|
|
37
|
-
};
|
|
43
|
+
// src/x.ts
|
|
44
|
+
import { z } from "zod/v4";
|
|
45
|
+
var VALID_X_RESPONSE_TYPES = [
|
|
46
|
+
"connectionID",
|
|
47
|
+
"signature",
|
|
48
|
+
"transactionID",
|
|
49
|
+
"error"
|
|
50
|
+
];
|
|
51
|
+
var XConnection = class _XConnection {
|
|
52
|
+
constructor(args) {
|
|
53
|
+
this.responseHandler = null;
|
|
54
|
+
this.socket = args.socket;
|
|
55
|
+
this.id = args.id;
|
|
56
|
+
this.initListeners();
|
|
38
57
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
58
|
+
initListeners() {
|
|
59
|
+
this.socket.onopen = null;
|
|
60
|
+
this.socket.onmessage = (event) => {
|
|
61
|
+
if (this.responseHandler === null) {
|
|
62
|
+
return;
|
|
43
63
|
}
|
|
44
|
-
let
|
|
64
|
+
let resp;
|
|
45
65
|
{
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
case "dev":
|
|
51
|
-
unWalletConfig = UNWALLET_CONFIG_DEV;
|
|
52
|
-
break;
|
|
66
|
+
const result = safeParseMessageEventDataToXResponse(event.data);
|
|
67
|
+
if (!result.success) {
|
|
68
|
+
this.responseHandler.reject(result.error);
|
|
69
|
+
return;
|
|
53
70
|
}
|
|
71
|
+
resp = result.data;
|
|
54
72
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
73
|
+
switch (resp.type) {
|
|
74
|
+
case "error":
|
|
75
|
+
switch (resp.value) {
|
|
76
|
+
case "rejected":
|
|
77
|
+
this.responseHandler.reject(new UWError("REQUEST_REJECTED"));
|
|
78
|
+
break;
|
|
79
|
+
default:
|
|
80
|
+
this.responseHandler.reject(
|
|
81
|
+
new UWError(
|
|
82
|
+
"INVALID_RESPONSE",
|
|
83
|
+
`unexpected error response value: ${resp.value}`
|
|
84
|
+
)
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
break;
|
|
88
|
+
default:
|
|
89
|
+
this.responseHandler.resolve(resp);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
this.socket.onerror = null;
|
|
93
|
+
this.socket.onclose = (event) => {
|
|
94
|
+
if (this.responseHandler === null) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
this.responseHandler.reject(
|
|
98
|
+
new UWError("CONNECTION_CLOSED", event.reason)
|
|
99
|
+
);
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
get readyState() {
|
|
103
|
+
return this.socket.readyState;
|
|
104
|
+
}
|
|
105
|
+
get hasResponseHandler() {
|
|
106
|
+
return this.responseHandler !== null;
|
|
107
|
+
}
|
|
108
|
+
setResponseHandler(handler) {
|
|
109
|
+
this.responseHandler = handler;
|
|
110
|
+
}
|
|
111
|
+
static async init(config) {
|
|
112
|
+
const socket = new WebSocket(config.url);
|
|
113
|
+
const id = await new Promise((resolve, reject) => {
|
|
114
|
+
setInterval(
|
|
115
|
+
() => reject(new UWError("CONNECTION_TIMEOUT")),
|
|
116
|
+
config.connectionTimeout
|
|
117
|
+
);
|
|
118
|
+
socket.onopen = () => socket.send(JSON.stringify({ action: "getConnectionID" }));
|
|
119
|
+
socket.onmessage = (event) => {
|
|
120
|
+
let resp;
|
|
121
|
+
{
|
|
122
|
+
const result = safeParseMessageEventDataToXResponse(event.data);
|
|
123
|
+
if (!result.success) {
|
|
124
|
+
reject(result.error);
|
|
68
125
|
return;
|
|
69
126
|
}
|
|
70
|
-
|
|
71
|
-
}
|
|
127
|
+
resp = result.data;
|
|
128
|
+
}
|
|
129
|
+
if (resp.type !== "connectionID") {
|
|
130
|
+
reject(
|
|
131
|
+
new UWError(
|
|
132
|
+
"INVALID_RESPONSE",
|
|
133
|
+
`unexpected response type: ${resp.type}`
|
|
134
|
+
)
|
|
135
|
+
);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
resolve(resp.value);
|
|
139
|
+
};
|
|
140
|
+
socket.onerror = () => reject(new UWError("CONNECTION_FAILED"));
|
|
141
|
+
socket.onclose = (event) => reject(new UWError("CONNECTION_CLOSED", event.reason));
|
|
142
|
+
});
|
|
143
|
+
return new _XConnection({ socket, id });
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
function safeParseMessageEventDataToXResponse(data) {
|
|
147
|
+
const result = z.string().refine(
|
|
148
|
+
(val) => {
|
|
149
|
+
try {
|
|
150
|
+
JSON.parse(val);
|
|
151
|
+
} catch (e) {
|
|
152
|
+
return false;
|
|
72
153
|
}
|
|
73
|
-
|
|
154
|
+
return true;
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
abort: true,
|
|
158
|
+
message: "Invalid JSON string"
|
|
159
|
+
}
|
|
160
|
+
).transform((val) => JSON.parse(val)).pipe(
|
|
161
|
+
z.object({
|
|
162
|
+
type: z.enum(VALID_X_RESPONSE_TYPES),
|
|
163
|
+
value: z.string()
|
|
164
|
+
})
|
|
165
|
+
).safeParse(data);
|
|
166
|
+
if (!result.success) {
|
|
167
|
+
return {
|
|
168
|
+
success: false,
|
|
169
|
+
error: new UWError(
|
|
170
|
+
"INVALID_RESPONSE",
|
|
171
|
+
`invalid message event data: ${result.error.message}`
|
|
172
|
+
)
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
return {
|
|
176
|
+
success: true,
|
|
177
|
+
data: result.data
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// src/unwallet.ts
|
|
182
|
+
var UnWallet = class _UnWallet {
|
|
183
|
+
constructor(args) {
|
|
184
|
+
this.env = args.env;
|
|
185
|
+
this.clientID = args.clientID;
|
|
186
|
+
this.xConnection = args.xConnection;
|
|
187
|
+
}
|
|
188
|
+
static async init(config) {
|
|
189
|
+
const env = config.env !== void 0 ? config.env : "prod";
|
|
190
|
+
return new _UnWallet({
|
|
191
|
+
env,
|
|
192
|
+
clientID: config.clientID,
|
|
193
|
+
xConnection: await XConnection.init(getUnWalletConfigByEnv(env).xapi)
|
|
74
194
|
});
|
|
75
195
|
}
|
|
196
|
+
get unWalletConfig() {
|
|
197
|
+
return getUnWalletConfigByEnv(this.env);
|
|
198
|
+
}
|
|
76
199
|
authorize(args) {
|
|
77
|
-
|
|
78
|
-
args.
|
|
79
|
-
}
|
|
80
|
-
let url = new URL(
|
|
81
|
-
`${this.unWalletConfig.frontend.baseURL}/${args.isVirtual === false ? "" : "v"}authorize`
|
|
200
|
+
const url = new URL(
|
|
201
|
+
`${this.unWalletConfig.frontend.baseURL}/${args.isVirtual !== void 0 ? args.isVirtual ? "v" : "" : "v"}authorize`
|
|
82
202
|
);
|
|
83
203
|
{
|
|
84
204
|
url.searchParams.set("response_type", "id_token");
|
|
85
|
-
url.searchParams.set(
|
|
86
|
-
|
|
205
|
+
url.searchParams.set(
|
|
206
|
+
"response_mode",
|
|
207
|
+
args.responseMode !== void 0 ? args.responseMode : "fragment"
|
|
208
|
+
);
|
|
209
|
+
url.searchParams.set("client_id", this.clientID);
|
|
87
210
|
url.searchParams.set("scope", "openid");
|
|
88
211
|
url.searchParams.set("redirect_uri", args.redirectURL);
|
|
89
212
|
if (args.nonce !== void 0) {
|
|
@@ -93,42 +216,180 @@ var UnWallet = class _UnWallet {
|
|
|
93
216
|
url.searchParams.set("chain_id", args.chainID.toString());
|
|
94
217
|
}
|
|
95
218
|
}
|
|
96
|
-
location.assign(url
|
|
219
|
+
location.assign(url);
|
|
97
220
|
}
|
|
98
221
|
sign(args) {
|
|
99
222
|
return new Promise((resolve, reject) => {
|
|
100
|
-
this.
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
223
|
+
if (this.xConnection.readyState !== WebSocket.OPEN) {
|
|
224
|
+
reject(new UWError("CONNECTION_NOT_OPENED"));
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
if (this.xConnection.hasResponseHandler) {
|
|
228
|
+
reject(new UWError("REQUEST_IN_PROGRESS"));
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
const digest = ethers.sha256(ethers.toUtf8Bytes(args.message));
|
|
232
|
+
this.xConnection.setResponseHandler({
|
|
233
|
+
resolve: (resp) => {
|
|
234
|
+
this.xConnection.setResponseHandler(null);
|
|
235
|
+
if (resp.type !== "signature") {
|
|
236
|
+
reject(
|
|
237
|
+
new UWError(
|
|
238
|
+
"INVALID_RESPONSE",
|
|
239
|
+
`unexpected response type: ${resp.type}`
|
|
240
|
+
)
|
|
241
|
+
);
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
resolve({
|
|
245
|
+
digest,
|
|
246
|
+
signature: resp.value
|
|
247
|
+
});
|
|
248
|
+
},
|
|
249
|
+
reject: (err) => {
|
|
250
|
+
this.xConnection.setResponseHandler(null);
|
|
251
|
+
reject(err);
|
|
252
|
+
}
|
|
253
|
+
});
|
|
107
254
|
const url = new URL(`${this.unWalletConfig.frontend.baseURL}/x/sign`);
|
|
108
255
|
{
|
|
109
|
-
url.searchParams.set("connectionID", this.
|
|
110
|
-
url.searchParams.set("clientID", this.
|
|
256
|
+
url.searchParams.set("connectionID", this.xConnection.id);
|
|
257
|
+
url.searchParams.set("clientID", this.clientID);
|
|
111
258
|
url.searchParams.set("message", args.message);
|
|
112
259
|
url.searchParams.set("ticketToken", args.ticketToken);
|
|
113
260
|
}
|
|
114
|
-
|
|
261
|
+
openWindow(url);
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
signEIP712TypedData(args) {
|
|
265
|
+
return new Promise((resolve, reject) => {
|
|
266
|
+
if (this.xConnection.readyState !== WebSocket.OPEN) {
|
|
267
|
+
reject(new UWError("CONNECTION_NOT_OPENED"));
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
if (this.xConnection.hasResponseHandler) {
|
|
271
|
+
reject(new UWError("REQUEST_IN_PROGRESS"));
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
const types = omit(args.typedData.types, "EIP712Domain");
|
|
275
|
+
let primaryType;
|
|
276
|
+
{
|
|
277
|
+
try {
|
|
278
|
+
primaryType = ethers.TypedDataEncoder.getPrimaryType(types);
|
|
279
|
+
} catch (e) {
|
|
280
|
+
if (ethers.isError(e, "INVALID_ARGUMENT")) {
|
|
281
|
+
reject(
|
|
282
|
+
new UWError("INVALID_REQUEST", `invalid typed data: ${e.message}`)
|
|
283
|
+
);
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
reject(e);
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
if (primaryType !== args.typedData.primaryType) {
|
|
291
|
+
reject(
|
|
292
|
+
new UWError(
|
|
293
|
+
"INVALID_REQUEST",
|
|
294
|
+
`invalid typed data: primary type must be ${primaryType}`
|
|
295
|
+
)
|
|
296
|
+
);
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
let digest;
|
|
300
|
+
{
|
|
301
|
+
try {
|
|
302
|
+
digest = ethers.TypedDataEncoder.hash(
|
|
303
|
+
args.typedData.domain,
|
|
304
|
+
types,
|
|
305
|
+
args.typedData.message
|
|
306
|
+
);
|
|
307
|
+
} catch (e) {
|
|
308
|
+
if (ethers.isError(e, "INVALID_ARGUMENT")) {
|
|
309
|
+
reject(
|
|
310
|
+
new UWError("INVALID_REQUEST", `invalid typed data: ${e.message}`)
|
|
311
|
+
);
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
reject(e);
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
this.xConnection.setResponseHandler({
|
|
319
|
+
resolve: (resp) => {
|
|
320
|
+
this.xConnection.setResponseHandler(null);
|
|
321
|
+
if (resp.type !== "signature") {
|
|
322
|
+
reject(
|
|
323
|
+
new UWError(
|
|
324
|
+
"INVALID_RESPONSE",
|
|
325
|
+
`unexpected response type: ${resp.type}`
|
|
326
|
+
)
|
|
327
|
+
);
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
resolve({
|
|
331
|
+
digest,
|
|
332
|
+
signature: resp.value
|
|
333
|
+
});
|
|
334
|
+
},
|
|
335
|
+
reject: (err) => {
|
|
336
|
+
this.xConnection.setResponseHandler(null);
|
|
337
|
+
reject(err);
|
|
338
|
+
}
|
|
339
|
+
});
|
|
340
|
+
const url = new URL(
|
|
341
|
+
`${this.unWalletConfig.frontend.baseURL}/x/signEIP712TypedData`
|
|
342
|
+
);
|
|
343
|
+
{
|
|
344
|
+
url.searchParams.set("connectionID", this.xConnection.id);
|
|
345
|
+
url.searchParams.set("clientID", this.clientID);
|
|
346
|
+
url.searchParams.set("typedData", JSON.stringify(args.typedData));
|
|
347
|
+
url.searchParams.set("ticketToken", args.ticketToken);
|
|
348
|
+
}
|
|
349
|
+
openWindow(url);
|
|
115
350
|
});
|
|
116
351
|
}
|
|
117
352
|
sendTransaction(args) {
|
|
118
353
|
return new Promise((resolve, reject) => {
|
|
354
|
+
if (this.xConnection.readyState !== WebSocket.OPEN) {
|
|
355
|
+
reject(new UWError("CONNECTION_NOT_OPENED"));
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
if (this.xConnection.hasResponseHandler) {
|
|
359
|
+
reject(new UWError("REQUEST_IN_PROGRESS"));
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
119
362
|
if (args.value === void 0 && args.data === void 0) {
|
|
120
|
-
|
|
363
|
+
reject(
|
|
364
|
+
new UWError("INVALID_REQUEST", "either value or data is required")
|
|
365
|
+
);
|
|
366
|
+
return;
|
|
121
367
|
}
|
|
122
|
-
this.
|
|
123
|
-
resolve(
|
|
124
|
-
|
|
125
|
-
|
|
368
|
+
this.xConnection.setResponseHandler({
|
|
369
|
+
resolve: (resp) => {
|
|
370
|
+
this.xConnection.setResponseHandler(null);
|
|
371
|
+
if (resp.type !== "transactionID") {
|
|
372
|
+
reject(
|
|
373
|
+
new UWError(
|
|
374
|
+
"INVALID_RESPONSE",
|
|
375
|
+
`unexpected response type: ${resp.type}`
|
|
376
|
+
)
|
|
377
|
+
);
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
resolve({ transactionID: resp.value });
|
|
381
|
+
},
|
|
382
|
+
reject: (err) => {
|
|
383
|
+
this.xConnection.setResponseHandler(null);
|
|
384
|
+
reject(err);
|
|
385
|
+
}
|
|
386
|
+
});
|
|
126
387
|
const url = new URL(
|
|
127
388
|
`${this.unWalletConfig.frontend.baseURL}/x/sendTransaction`
|
|
128
389
|
);
|
|
129
390
|
{
|
|
130
|
-
url.searchParams.set("connectionID", this.
|
|
131
|
-
url.searchParams.set("clientID", this.
|
|
391
|
+
url.searchParams.set("connectionID", this.xConnection.id);
|
|
392
|
+
url.searchParams.set("clientID", this.clientID);
|
|
132
393
|
url.searchParams.set("chainID", args.chainID.toString());
|
|
133
394
|
url.searchParams.set("toAddress", args.toAddress);
|
|
134
395
|
url.searchParams.set(
|
|
@@ -141,51 +402,22 @@ var UnWallet = class _UnWallet {
|
|
|
141
402
|
);
|
|
142
403
|
url.searchParams.set("ticketToken", args.ticketToken);
|
|
143
404
|
}
|
|
144
|
-
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
getConnectionID() {
|
|
148
|
-
this.sendWSMessage({
|
|
149
|
-
action: "getConnectionID"
|
|
405
|
+
openWindow(url);
|
|
150
406
|
});
|
|
151
407
|
}
|
|
152
|
-
sendWSMessage(msg) {
|
|
153
|
-
this.ws.send(JSON.stringify(msg));
|
|
154
|
-
}
|
|
155
|
-
handleWSMessage(msg) {
|
|
156
|
-
switch (msg.type) {
|
|
157
|
-
case "signature":
|
|
158
|
-
this.resolve(msg.value);
|
|
159
|
-
break;
|
|
160
|
-
case "transactionID":
|
|
161
|
-
this.resolve(msg.value);
|
|
162
|
-
break;
|
|
163
|
-
case "error":
|
|
164
|
-
switch (msg.value) {
|
|
165
|
-
case "rejected":
|
|
166
|
-
this.reject("canceled");
|
|
167
|
-
break;
|
|
168
|
-
default:
|
|
169
|
-
throw new Error(msg.value);
|
|
170
|
-
}
|
|
171
|
-
break;
|
|
172
|
-
default:
|
|
173
|
-
throw new Error(`unexpected message type: ${msg.type}`);
|
|
174
|
-
}
|
|
175
|
-
this.initPromiseArgs();
|
|
176
|
-
}
|
|
177
|
-
openWindow(url) {
|
|
178
|
-
const width = screen.width / 2;
|
|
179
|
-
const height = screen.height;
|
|
180
|
-
const left = screen.width / 4;
|
|
181
|
-
const top = 0;
|
|
182
|
-
window.open(
|
|
183
|
-
url.toString(),
|
|
184
|
-
"_blank",
|
|
185
|
-
`width=${width},height=${height},left=${left},top=${top}`
|
|
186
|
-
);
|
|
187
|
-
}
|
|
188
408
|
};
|
|
409
|
+
function openWindow(url) {
|
|
410
|
+
const width = screen.width / 2;
|
|
411
|
+
const height = screen.height;
|
|
412
|
+
const left = screen.width / 4;
|
|
413
|
+
const top = 0;
|
|
414
|
+
window.open(
|
|
415
|
+
url.toString(),
|
|
416
|
+
"_blank",
|
|
417
|
+
`width=${width},height=${height},left=${left},top=${top}`
|
|
418
|
+
);
|
|
419
|
+
}
|
|
189
420
|
export {
|
|
421
|
+
UWError,
|
|
190
422
|
UnWallet
|
|
191
423
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "unwallet-client-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"description": "unWallet client-side SDK",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "SIVIRA",
|
|
@@ -29,17 +29,20 @@
|
|
|
29
29
|
}
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"ethers": "6.14.
|
|
32
|
+
"ethers": "6.14.1",
|
|
33
|
+
"lodash": "4.17.21",
|
|
34
|
+
"zod": "3.25.13"
|
|
33
35
|
},
|
|
34
36
|
"devDependencies": {
|
|
35
37
|
"@commitlint/cli": "19.8.1",
|
|
36
38
|
"@commitlint/config-conventional": "19.8.1",
|
|
37
39
|
"@commitlint/types": "19.8.1",
|
|
38
40
|
"@tsconfig/strictest": "2.0.5",
|
|
41
|
+
"@types/lodash": "4.17.17",
|
|
39
42
|
"commitizen": "4.3.1",
|
|
40
43
|
"cz-conventional-changelog": "3.3.0",
|
|
41
44
|
"husky": "9.1.7",
|
|
42
|
-
"tsup": "8.
|
|
45
|
+
"tsup": "8.5.0"
|
|
43
46
|
},
|
|
44
47
|
"scripts": {
|
|
45
48
|
"build": "tsup",
|