@dainprotocol/service-sdk 1.2.3 → 1.2.4
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.
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Client Authentication for DAIN Services
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* For SERVICE-SIDE keypair authentication (services/agents), see /src/service/auth.ts
|
|
4
|
+
* Supports two authentication modes:
|
|
5
|
+
* 1. JWT - For end users (browser-side), NO keypairs/orgId/agentId
|
|
6
|
+
* 2. API Key - For server-to-server auth (Node.js server-side only)
|
|
8
7
|
*/
|
|
9
8
|
/**
|
|
10
|
-
* JWT Authentication Config (Users)
|
|
9
|
+
* JWT Authentication Config (End Users - Browser)
|
|
11
10
|
*/
|
|
12
|
-
export interface
|
|
11
|
+
export interface DainClientAuthConfigJWT {
|
|
13
12
|
/** JWT access token from DAIN ID OAuth */
|
|
14
13
|
jwt: string;
|
|
15
14
|
/** Smart Account ID (optional, will be extracted from JWT if not provided) */
|
|
@@ -19,6 +18,18 @@ export interface DainClientAuthConfig {
|
|
|
19
18
|
/** Webhook URL for async operations (optional) */
|
|
20
19
|
webhookUrl?: string;
|
|
21
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* API Key Authentication Config (Server-to-Server - Node.js only)
|
|
23
|
+
*/
|
|
24
|
+
export interface DainClientAuthConfigAPIKey {
|
|
25
|
+
/** API Key for server-side authentication */
|
|
26
|
+
apiKey: string;
|
|
27
|
+
/** Smart Account PDA on Solana (optional) */
|
|
28
|
+
smartAccountPDA?: string;
|
|
29
|
+
/** Webhook URL for async operations (optional) */
|
|
30
|
+
webhookUrl?: string;
|
|
31
|
+
}
|
|
32
|
+
export type DainClientAuthConfig = DainClientAuthConfigJWT | DainClientAuthConfigAPIKey;
|
|
22
33
|
/**
|
|
23
34
|
* DainClientAuth - JWT-only authentication for users
|
|
24
35
|
*
|
|
@@ -28,8 +39,9 @@ export interface DainClientAuthConfig {
|
|
|
28
39
|
* For SERVICE-SIDE authentication with keypairs, use the service SDK's built-in auth.
|
|
29
40
|
*/
|
|
30
41
|
export declare class DainClientAuth {
|
|
31
|
-
private jwt
|
|
32
|
-
private
|
|
42
|
+
private jwt?;
|
|
43
|
+
private apiKey?;
|
|
44
|
+
private smartAccountId?;
|
|
33
45
|
private smartAccountPDA?;
|
|
34
46
|
private webhookUrl?;
|
|
35
47
|
constructor(config: DainClientAuthConfig);
|
|
@@ -50,17 +62,25 @@ export declare class DainClientAuth {
|
|
|
50
62
|
*/
|
|
51
63
|
getHeaders(_signature: string, _timestamp: string): Record<string, string>;
|
|
52
64
|
/**
|
|
53
|
-
* Check if using JWT authentication
|
|
65
|
+
* Check if using JWT authentication
|
|
54
66
|
*/
|
|
55
67
|
isJWT(): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Check if using API Key authentication
|
|
70
|
+
*/
|
|
71
|
+
isAPIKey(): boolean;
|
|
56
72
|
/**
|
|
57
73
|
* Get JWT token
|
|
58
74
|
*/
|
|
59
|
-
getJWT(): string;
|
|
75
|
+
getJWT(): string | undefined;
|
|
76
|
+
/**
|
|
77
|
+
* Get API Key
|
|
78
|
+
*/
|
|
79
|
+
getAPIKey(): string | undefined;
|
|
60
80
|
/**
|
|
61
81
|
* Get smart account ID
|
|
62
82
|
*/
|
|
63
|
-
getSmartAccountId(): string;
|
|
83
|
+
getSmartAccountId(): string | undefined;
|
|
64
84
|
/**
|
|
65
85
|
* Get smart account PDA
|
|
66
86
|
*/
|
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
//File: src/client/client-auth.ts
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Client Authentication for DAIN Services
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* For SERVICE-SIDE keypair authentication (services/agents), see /src/service/auth.ts
|
|
6
|
+
* Supports two authentication modes:
|
|
7
|
+
* 1. JWT - For end users (browser-side), NO keypairs/orgId/agentId
|
|
8
|
+
* 2. API Key - For server-to-server auth (Node.js server-side only)
|
|
10
9
|
*/
|
|
11
10
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
11
|
exports.DainClientAuth = void 0;
|
|
12
|
+
function isJWTConfig(config) {
|
|
13
|
+
return 'jwt' in config;
|
|
14
|
+
}
|
|
15
|
+
function isAPIKeyConfig(config) {
|
|
16
|
+
return 'apiKey' in config;
|
|
17
|
+
}
|
|
13
18
|
/**
|
|
14
19
|
* DainClientAuth - JWT-only authentication for users
|
|
15
20
|
*
|
|
@@ -20,24 +25,34 @@ exports.DainClientAuth = void 0;
|
|
|
20
25
|
*/
|
|
21
26
|
class DainClientAuth {
|
|
22
27
|
jwt;
|
|
28
|
+
apiKey;
|
|
23
29
|
smartAccountId;
|
|
24
30
|
smartAccountPDA;
|
|
25
31
|
webhookUrl;
|
|
26
32
|
constructor(config) {
|
|
27
|
-
if (
|
|
28
|
-
|
|
33
|
+
if (isJWTConfig(config)) {
|
|
34
|
+
// JWT Authentication (End Users)
|
|
35
|
+
this.jwt = config.jwt;
|
|
36
|
+
// Extract smartAccountId from config or decode from JWT
|
|
37
|
+
if (config.smartAccountId) {
|
|
38
|
+
this.smartAccountId = config.smartAccountId;
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
const payload = this.decodeJWTPayload(config.jwt);
|
|
42
|
+
this.smartAccountId = payload.smart_account_id || payload.sub;
|
|
43
|
+
}
|
|
44
|
+
this.smartAccountPDA = config.smartAccountPDA;
|
|
45
|
+
this.webhookUrl = config.webhookUrl;
|
|
29
46
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
this.
|
|
47
|
+
else if (isAPIKeyConfig(config)) {
|
|
48
|
+
// API Key Authentication (Server-to-Server)
|
|
49
|
+
this.apiKey = config.apiKey;
|
|
50
|
+
this.smartAccountPDA = config.smartAccountPDA;
|
|
51
|
+
this.webhookUrl = config.webhookUrl;
|
|
34
52
|
}
|
|
35
53
|
else {
|
|
36
|
-
|
|
37
|
-
this.smartAccountId = payload.smart_account_id || payload.sub;
|
|
54
|
+
throw new Error('Invalid authentication config - must provide either jwt or apiKey');
|
|
38
55
|
}
|
|
39
|
-
this.smartAccountPDA = config.smartAccountPDA;
|
|
40
|
-
this.webhookUrl = config.webhookUrl;
|
|
41
56
|
}
|
|
42
57
|
/**
|
|
43
58
|
* Decode JWT payload (without verification)
|
|
@@ -61,9 +76,15 @@ class DainClientAuth {
|
|
|
61
76
|
* Get headers for HTTP requests
|
|
62
77
|
*/
|
|
63
78
|
getHeaders(_signature, _timestamp) {
|
|
64
|
-
const headers = {
|
|
65
|
-
|
|
66
|
-
|
|
79
|
+
const headers = {};
|
|
80
|
+
if (this.jwt) {
|
|
81
|
+
// JWT Authentication
|
|
82
|
+
headers["Authorization"] = `Bearer ${this.jwt}`;
|
|
83
|
+
}
|
|
84
|
+
else if (this.apiKey) {
|
|
85
|
+
// API Key Authentication
|
|
86
|
+
headers["X-DAIN-API-KEY"] = this.apiKey;
|
|
87
|
+
}
|
|
67
88
|
if (this.smartAccountPDA) {
|
|
68
89
|
headers["X-DAIN-SMART-ACCOUNT-PDA"] = this.smartAccountPDA;
|
|
69
90
|
}
|
|
@@ -74,10 +95,16 @@ class DainClientAuth {
|
|
|
74
95
|
}
|
|
75
96
|
// ===== Getter Methods =====
|
|
76
97
|
/**
|
|
77
|
-
* Check if using JWT authentication
|
|
98
|
+
* Check if using JWT authentication
|
|
78
99
|
*/
|
|
79
100
|
isJWT() {
|
|
80
|
-
return
|
|
101
|
+
return !!this.jwt;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Check if using API Key authentication
|
|
105
|
+
*/
|
|
106
|
+
isAPIKey() {
|
|
107
|
+
return !!this.apiKey;
|
|
81
108
|
}
|
|
82
109
|
/**
|
|
83
110
|
* Get JWT token
|
|
@@ -85,6 +112,12 @@ class DainClientAuth {
|
|
|
85
112
|
getJWT() {
|
|
86
113
|
return this.jwt;
|
|
87
114
|
}
|
|
115
|
+
/**
|
|
116
|
+
* Get API Key
|
|
117
|
+
*/
|
|
118
|
+
getAPIKey() {
|
|
119
|
+
return this.apiKey;
|
|
120
|
+
}
|
|
88
121
|
/**
|
|
89
122
|
* Get smart account ID
|
|
90
123
|
*/
|
|
@@ -129,14 +162,26 @@ class DainClientAuth {
|
|
|
129
162
|
* Serialize auth config
|
|
130
163
|
*/
|
|
131
164
|
serialize() {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
165
|
+
if (this.jwt) {
|
|
166
|
+
const data = {
|
|
167
|
+
authMethod: 'jwt',
|
|
168
|
+
jwt: this.jwt,
|
|
169
|
+
smartAccountId: this.smartAccountId,
|
|
170
|
+
smartAccountPDA: this.smartAccountPDA,
|
|
171
|
+
webhookUrl: this.webhookUrl
|
|
172
|
+
};
|
|
173
|
+
return Buffer.from(JSON.stringify(data)).toString('base64');
|
|
174
|
+
}
|
|
175
|
+
else if (this.apiKey) {
|
|
176
|
+
const data = {
|
|
177
|
+
authMethod: 'apiKey',
|
|
178
|
+
apiKey: this.apiKey,
|
|
179
|
+
smartAccountPDA: this.smartAccountPDA,
|
|
180
|
+
webhookUrl: this.webhookUrl
|
|
181
|
+
};
|
|
182
|
+
return Buffer.from(JSON.stringify(data)).toString('base64');
|
|
183
|
+
}
|
|
184
|
+
throw new Error('No authentication method available');
|
|
140
185
|
}
|
|
141
186
|
/**
|
|
142
187
|
* Deserialize auth config
|
|
@@ -144,15 +189,24 @@ class DainClientAuth {
|
|
|
144
189
|
static deserialize(serialized) {
|
|
145
190
|
try {
|
|
146
191
|
const data = JSON.parse(Buffer.from(serialized, 'base64').toString());
|
|
147
|
-
if (data.authMethod
|
|
148
|
-
|
|
192
|
+
if (data.authMethod === 'jwt') {
|
|
193
|
+
return new DainClientAuth({
|
|
194
|
+
jwt: data.jwt,
|
|
195
|
+
smartAccountId: data.smartAccountId,
|
|
196
|
+
smartAccountPDA: data.smartAccountPDA,
|
|
197
|
+
webhookUrl: data.webhookUrl
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
else if (data.authMethod === 'apiKey') {
|
|
201
|
+
return new DainClientAuth({
|
|
202
|
+
apiKey: data.apiKey,
|
|
203
|
+
smartAccountPDA: data.smartAccountPDA,
|
|
204
|
+
webhookUrl: data.webhookUrl
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
throw new Error('Invalid auth method - must be jwt or apiKey');
|
|
149
209
|
}
|
|
150
|
-
return new DainClientAuth({
|
|
151
|
-
jwt: data.jwt,
|
|
152
|
-
smartAccountId: data.smartAccountId,
|
|
153
|
-
smartAccountPDA: data.smartAccountPDA,
|
|
154
|
-
webhookUrl: data.webhookUrl
|
|
155
|
-
});
|
|
156
210
|
}
|
|
157
211
|
catch (error) {
|
|
158
212
|
throw new Error('Failed to deserialize DainClientAuth: ' + error.message);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client-auth.js","sourceRoot":"","sources":["../../src/client/client-auth.ts"],"names":[],"mappings":";AAAA,iCAAiC;AACjC
|
|
1
|
+
{"version":3,"file":"client-auth.js","sourceRoot":"","sources":["../../src/client/client-auth.ts"],"names":[],"mappings":"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"}
|