@avacuscc/sdk 0.2.0 → 0.2.1

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 +1 @@
1
- export { A as AVACUS_ENDPOINTS, a as AuthState, b as AvacusEnvironment, c as BASE_CONNECT_SIGNED_MSG, d as BASE_GAS_SPONSOR_SIGNED_MSG, e as BASE_REDIRECT_SIGNED_MSG, D as DEFAULT_BASE_SIGNED_MESSAGE, H as HttpAdapter, R as RequestOptions, f as ResolvedClientSettings, h as SignMessageFn, i as SnsAuthClient, j as SnsAuthClientOptions, k as SnsAuthTokenPayload, l as SnsAuthenticateParams, m as SnsAvatar, n as SnsCreateUserDeviceParams, o as SnsCreateUserParams, p as SnsCreateUserPayload, q as SnsCreateUserResult, r as SnsCreateUserWithSignatureParams, s as SnsDevice, t as SnsGetNonceParams, u as SnsGetProfilesParams, v as SnsLoginParams, w as SnsLoginResult, x as SnsNonceResponse, y as SnsProfile, S as SnsService, z as SnsServiceName, C as SnsServiceOptions, F as loginWithSns } from './sns-Zwan9DNM.js';
1
+ export { A as AVACUS_ENDPOINTS, a as AvacusEnvironment, b as BASE_CONNECT_SIGNED_MSG, c as BASE_GAS_SPONSOR_SIGNED_MSG, d as BASE_REDIRECT_SIGNED_MSG, D as DEFAULT_BASE_SIGNED_MESSAGE, R as ResolvedClientSettings, f as SignMessageFn, g as SnsAuthClient, h as SnsAuthClientOptions, i as SnsAuthTokenPayload, j as SnsAuthenticateParams, k as SnsAvatar, l as SnsCreateUserDeviceParams, m as SnsCreateUserParams, n as SnsCreateUserPayload, o as SnsCreateUserResult, p as SnsCreateUserWithSignatureParams, q as SnsDevice, r as SnsGetNonceParams, s as SnsGetProfilesParams, t as SnsLoginParams, u as SnsLoginResult, v as SnsNonceResponse, w as SnsProfile, S as SnsService, x as SnsServiceName, y as SnsServiceOptions, C as loginWithSns } from './sns-NuV2JpAA.js';
@@ -25,7 +25,6 @@ __export(sns_exports, {
25
25
  BASE_GAS_SPONSOR_SIGNED_MSG: () => BASE_GAS_SPONSOR_SIGNED_MSG,
26
26
  BASE_REDIRECT_SIGNED_MSG: () => BASE_REDIRECT_SIGNED_MSG,
27
27
  DEFAULT_BASE_SIGNED_MESSAGE: () => DEFAULT_BASE_SIGNED_MESSAGE,
28
- HttpAdapter: () => HttpAdapter,
29
28
  SnsAuthClient: () => SnsAuthClient,
30
29
  SnsService: () => SnsService,
31
30
  loginWithSns: () => loginWithSns
@@ -419,7 +418,6 @@ var SnsAuthClient = class extends SnsService {
419
418
  BASE_GAS_SPONSOR_SIGNED_MSG,
420
419
  BASE_REDIRECT_SIGNED_MSG,
421
420
  DEFAULT_BASE_SIGNED_MESSAGE,
422
- HttpAdapter,
423
421
  SnsAuthClient,
424
422
  SnsService,
425
423
  loginWithSns
@@ -1,21 +1,389 @@
1
- import {
2
- AVACUS_ENDPOINTS,
3
- BASE_CONNECT_SIGNED_MSG,
4
- BASE_GAS_SPONSOR_SIGNED_MSG,
5
- BASE_REDIRECT_SIGNED_MSG,
6
- DEFAULT_BASE_SIGNED_MESSAGE,
7
- HttpAdapter,
8
- SnsAuthClient,
9
- SnsService,
10
- loginWithSns
11
- } from "./chunk-XWC6XZPN.mjs";
1
+ // packages/sdk/src/adapters/http.ts
2
+ var HttpAdapter = class {
3
+ /**
4
+ * Creates a reusable HTTP transport bound to one service base URL.
5
+ *
6
+ * @param baseUrl Absolute base URL for the target service namespace.
7
+ * @param headers Default headers sent with every request.
8
+ * @param authState Shared mutable auth state so multiple adapters can reuse the same JWT.
9
+ */
10
+ constructor(baseUrl, headers = {}, authState = {}) {
11
+ this.baseUrl = baseUrl;
12
+ this.headers = headers;
13
+ this.authState = authState;
14
+ }
15
+ baseUrl;
16
+ headers;
17
+ authState;
18
+ /**
19
+ * Stores the JWT access token used by authenticated requests.
20
+ *
21
+ * @param accessToken JWT returned by the authentication flow.
22
+ */
23
+ setAccessToken(accessToken) {
24
+ this.authState.accessToken = accessToken;
25
+ }
26
+ /**
27
+ * Removes the currently stored JWT access token from shared auth state.
28
+ */
29
+ clearAccessToken() {
30
+ delete this.authState.accessToken;
31
+ }
32
+ /**
33
+ * Returns the currently stored JWT access token, if any.
34
+ */
35
+ getAccessToken() {
36
+ return this.authState.accessToken;
37
+ }
38
+ /**
39
+ * Sends an HTTP GET request to a path relative to this adapter base URL.
40
+ *
41
+ * @param path Relative endpoint path.
42
+ * @param options Request behavior such as auth requirement and extra headers.
43
+ */
44
+ async get(path, options = {}) {
45
+ const response = await fetch(this.buildUrl(path), {
46
+ method: "GET",
47
+ headers: this.buildHeaders(options)
48
+ });
49
+ return this.parseResponse(response, "GET", path);
50
+ }
51
+ /**
52
+ * Sends an HTTP POST request with a JSON body to a path relative to this adapter base URL.
53
+ *
54
+ * @param path Relative endpoint path.
55
+ * @param body Serializable request payload.
56
+ * @param options Request behavior such as auth requirement and extra headers.
57
+ */
58
+ async post(path, body, options = {}) {
59
+ const response = await fetch(this.buildUrl(path), {
60
+ method: "POST",
61
+ headers: this.buildHeaders({
62
+ ...options,
63
+ headers: {
64
+ "Content-Type": "application/json",
65
+ ...options.headers
66
+ }
67
+ }),
68
+ body: body === void 0 ? void 0 : JSON.stringify(body)
69
+ });
70
+ return this.parseResponse(response, "POST", path);
71
+ }
72
+ /**
73
+ * Sends an HTTP PUT request with a JSON body to a path relative to this adapter base URL.
74
+ *
75
+ * @param path Relative endpoint path.
76
+ * @param body Serializable request payload.
77
+ * @param options Request behavior such as auth requirement and extra headers.
78
+ */
79
+ async put(path, body, options = {}) {
80
+ const response = await fetch(this.buildUrl(path), {
81
+ method: "PUT",
82
+ headers: this.buildHeaders({
83
+ ...options,
84
+ headers: {
85
+ "Content-Type": "application/json",
86
+ ...options.headers
87
+ }
88
+ }),
89
+ body: body === void 0 ? void 0 : JSON.stringify(body)
90
+ });
91
+ return this.parseResponse(response, "PUT", path);
92
+ }
93
+ /**
94
+ * Sends an HTTP DELETE request with an optional JSON body to a path relative to this adapter base URL.
95
+ *
96
+ * @param path Relative endpoint path.
97
+ * @param body Optional serializable request payload.
98
+ * @param options Request behavior such as auth requirement and extra headers.
99
+ */
100
+ async delete(path, body, options = {}) {
101
+ const headers = body === void 0 ? this.buildHeaders(options) : this.buildHeaders({
102
+ ...options,
103
+ headers: {
104
+ "Content-Type": "application/json",
105
+ ...options.headers
106
+ }
107
+ });
108
+ const response = await fetch(this.buildUrl(path), {
109
+ method: "DELETE",
110
+ headers,
111
+ body: body === void 0 ? void 0 : JSON.stringify(body)
112
+ });
113
+ return this.parseResponse(response, "DELETE", path);
114
+ }
115
+ /**
116
+ * Builds the final request headers by combining default headers, per-request
117
+ * headers, and an authorization header when the request requires auth.
118
+ */
119
+ buildHeaders(options) {
120
+ const accessToken = this.authState.accessToken;
121
+ if (options.auth && !accessToken) {
122
+ throw new Error("This request requires authentication. Call login() first.");
123
+ }
124
+ return {
125
+ ...this.headers,
126
+ ...options.headers,
127
+ ...options.auth && accessToken ? {
128
+ Authorization: `Bearer ${accessToken}`
129
+ } : {}
130
+ };
131
+ }
132
+ /**
133
+ * Resolves a relative path against the adapter base URL.
134
+ */
135
+ buildUrl(path) {
136
+ const normalizedPath = path.startsWith("/") ? path.slice(1) : path;
137
+ return new URL(normalizedPath, this.baseUrl);
138
+ }
139
+ /**
140
+ * Parses a JSON response and converts non-2xx responses into descriptive errors.
141
+ */
142
+ async parseResponse(response, method, path) {
143
+ const bodyText = await response.text();
144
+ if (!response.ok) {
145
+ throw new Error(
146
+ `HTTP ${response.status} ${response.statusText} for ${method} ${path}: ${bodyText}`
147
+ );
148
+ }
149
+ try {
150
+ return JSON.parse(bodyText);
151
+ } catch (error) {
152
+ throw new Error(
153
+ `Invalid JSON response for ${method} ${path}: ${bodyText}`,
154
+ { cause: error }
155
+ );
156
+ }
157
+ }
158
+ };
159
+
160
+ // packages/sdk/src/config.ts
161
+ var AVACUS_ENDPOINTS = {
162
+ prod: "https://apis.avacus.cc/",
163
+ dev: "https://apis.d.avscc.unit-hosting.net/",
164
+ stg: "https://apis.avacus.cc/stg/"
165
+ };
166
+ function resolveAvacusBaseUrl(options) {
167
+ if (options.baseUrl) {
168
+ return options.baseUrl;
169
+ }
170
+ return AVACUS_ENDPOINTS[options.env ?? "prod"];
171
+ }
172
+ function resolveClientSettings(options = {}) {
173
+ return {
174
+ env: options.env ?? "prod",
175
+ baseUrl: resolveAvacusBaseUrl(options),
176
+ headers: options.headers
177
+ };
178
+ }
179
+ function isKnownAvacusBaseUrl(baseUrl) {
180
+ return Object.values(AVACUS_ENDPOINTS).includes(baseUrl);
181
+ }
182
+ function resolveServiceUrl(baseUrl, servicePath) {
183
+ const normalizedServicePath = servicePath.endsWith("/") ? servicePath : `${servicePath}/`;
184
+ return new URL(normalizedServicePath, baseUrl).toString();
185
+ }
186
+
187
+ // packages/sdk/src/services/sns.ts
188
+ var DEFAULT_BASE_SIGNED_MESSAGE = "Hi there from Avacus Wallet! Please sign this message to prove that you can access to secure chat. To stop hackers access to your secure chat, do not sign this message outside Avacus Wallet, and here's a unique message ID they can't guess: ";
189
+ var BASE_CONNECT_SIGNED_MSG = "Hi there from Avacus Connect! Please sign this message to prove that you can access our service. For security reasons, do not sign this message outside Avacus Connect, and here's a unique message ID they can't guess: ";
190
+ var BASE_REDIRECT_SIGNED_MSG = "Hi there from Avacus Redirect! Please sign this message to prove that you can access our service. For security reasons, do not sign this message outside Avacus Redirect, and here's a unique message ID they can't guess: ";
191
+ var BASE_GAS_SPONSOR_SIGNED_MSG = "Hi there from Avacus Gas Sponsor! Please sign this message to prove that you can access our service. For security reasons, do not sign this message outside Avacus Gas Sponsor, and here's a unique message ID they can't guess: ";
192
+ var BASE_SIGNED_MESSAGE_BY_SERVICE = {
193
+ connect: BASE_CONNECT_SIGNED_MSG,
194
+ redirect: BASE_REDIRECT_SIGNED_MSG,
195
+ "gas-sponsor": BASE_GAS_SPONSOR_SIGNED_MSG
196
+ };
197
+ var SnsService = class {
198
+ /**
199
+ * Creates the SNS service using a service-scoped HTTP adapter.
200
+ *
201
+ * @param http Adapter already configured for the SNS base path.
202
+ * @param options Optional SNS-specific behavior.
203
+ */
204
+ constructor(http, options = {}) {
205
+ this.http = http;
206
+ this.options = options;
207
+ }
208
+ http;
209
+ options;
210
+ /**
211
+ * Requests a one-time nonce used to construct the login signature message.
212
+ * This endpoint is public and does not require a JWT token.
213
+ *
214
+ * @param params Wallet identity used by the backend to mint a nonce.
215
+ */
216
+ async getNonce(params) {
217
+ const searchParams = new URLSearchParams({
218
+ wallet_address: params.walletAddress
219
+ });
220
+ return this.http.get(`v1/public/users/nonce?${searchParams.toString()}`);
221
+ }
222
+ /**
223
+ * Exchanges a signed message payload for an SNS auth token.
224
+ * This is the low-level authentication endpoint behind `login()`.
225
+ *
226
+ * @param params Payload expected by the SNS auth API.
227
+ */
228
+ async requestAuthToken(params) {
229
+ return this.http.post("v2/public/users/request_auth_token", params);
230
+ }
231
+ /**
232
+ * Returns public user profiles for a batch of wallet addresses and/or user IDs.
233
+ * This endpoint is public and does not require authentication.
234
+ *
235
+ * @param params Query payload with wallet addresses and/or user IDs.
236
+ */
237
+ async getPublicProfiles(params) {
238
+ return this.http.post("v1/public/users/profiles", {
239
+ wallets: params.wallets,
240
+ user_ids: params.userIds,
241
+ include_devices: params.includeDevices
242
+ });
243
+ }
244
+ /**
245
+ * Creates a new SNS user account using only the inputs the application already knows:
246
+ * wallet address, signer callback, and optional user profile metadata.
247
+ * The SDK internally fetches a nonce, builds the canonical message, requests
248
+ * the signature, and submits the create-user payload.
249
+ *
250
+ * @param params User creation payload in SDK-friendly camelCase format.
251
+ */
252
+ async createUser(params) {
253
+ const { walletAddress, signMessage } = params;
254
+ const { nonce } = await this.getNonce({ walletAddress });
255
+ const message = this.buildLoginMessage(nonce);
256
+ const signature = await signMessage(message);
257
+ return this.createUserWithSignature({
258
+ walletAddress,
259
+ message,
260
+ signature,
261
+ publicKey: params.publicKey,
262
+ displayName: params.displayName,
263
+ description: params.description,
264
+ device: params.device
265
+ });
266
+ }
267
+ /**
268
+ * Low-level create-user API for callers that already have a prepared message
269
+ * and signature and want direct control over the exact payload.
270
+ *
271
+ * @param params Signed create-user payload.
272
+ */
273
+ async createUserWithSignature(params) {
274
+ const result = await this.http.post(
275
+ "v1/public/users",
276
+ {
277
+ wallet_address: params.walletAddress,
278
+ message: params.message,
279
+ signature: params.signature,
280
+ public_key: params.publicKey,
281
+ display_name: params.displayName,
282
+ description: params.description,
283
+ device: params.device ? {
284
+ device_token: params.device.deviceToken,
285
+ app_name: params.device.appName,
286
+ app_version: params.device.appVersion,
287
+ platform: params.device.platform
288
+ } : void 0
289
+ }
290
+ );
291
+ const accessToken = extractAccessToken(result);
292
+ if (accessToken) {
293
+ this.http.setAccessToken(accessToken);
294
+ }
295
+ return result;
296
+ }
297
+ /**
298
+ * Adapts camelCase SDK parameters to the snake_case payload expected by the backend.
299
+ *
300
+ * @param params Wallet address, signed message, and signature returned by the signer.
301
+ */
302
+ async authenticate(params) {
303
+ return this.requestAuthToken({
304
+ wallet_address: params.walletAddress,
305
+ message: params.message,
306
+ signature: params.signature,
307
+ service_name: params.serviceName
308
+ });
309
+ }
310
+ /**
311
+ * Executes the full SNS login flow:
312
+ * 1. fetch nonce
313
+ * 2. build login message
314
+ * 3. sign message via injected signer callback
315
+ * 4. exchange signature for JWT
316
+ * 5. persist token in shared HTTP auth state
317
+ *
318
+ * @param params Wallet address and async signing callback.
319
+ */
320
+ async login(params) {
321
+ const { walletAddress, signMessage, serviceName } = params;
322
+ const { nonce } = await this.getNonce({ walletAddress });
323
+ const message = this.buildLoginMessage(nonce, serviceName);
324
+ const signature = await signMessage(message);
325
+ const result = await this.authenticate({
326
+ walletAddress,
327
+ message,
328
+ signature,
329
+ serviceName
330
+ });
331
+ const accessToken = extractAccessToken(result);
332
+ if (accessToken) {
333
+ this.http.setAccessToken(accessToken);
334
+ }
335
+ return result;
336
+ }
337
+ /**
338
+ * Builds the exact message string that the wallet must sign during login.
339
+ */
340
+ buildLoginMessage(nonce, serviceName) {
341
+ const baseMessage = serviceName != null ? BASE_SIGNED_MESSAGE_BY_SERVICE[serviceName] : this.options.baseSignedMessage ?? DEFAULT_BASE_SIGNED_MESSAGE;
342
+ return `${baseMessage}${nonce}`;
343
+ }
344
+ };
345
+ function extractAccessToken(result) {
346
+ if ("data" in result && typeof result.data === "object" && result.data !== null) {
347
+ const token = result.data.token;
348
+ if (typeof token === "string" && token.length > 0) {
349
+ return token;
350
+ }
351
+ }
352
+ return void 0;
353
+ }
354
+ async function loginWithSns(sns, params) {
355
+ return sns.login(params);
356
+ }
357
+
358
+ // packages/sdk/src/sns.ts
359
+ var SnsAuthClient = class extends SnsService {
360
+ settings;
361
+ usingCustomBaseUrl;
362
+ constructor(options = {}) {
363
+ const settings = resolveClientSettings(options);
364
+ const http = new HttpAdapter(
365
+ resolveServiceUrl(settings.baseUrl, "1/secure-chat/"),
366
+ settings.headers
367
+ );
368
+ super(http, {
369
+ baseSignedMessage: options.baseSignedMessage
370
+ });
371
+ this.settings = settings;
372
+ this.usingCustomBaseUrl = !isKnownAvacusBaseUrl(settings.baseUrl);
373
+ }
374
+ getSettings() {
375
+ return { ...this.settings };
376
+ }
377
+ isUsingCustomBaseUrl() {
378
+ return this.usingCustomBaseUrl;
379
+ }
380
+ };
12
381
  export {
13
382
  AVACUS_ENDPOINTS,
14
383
  BASE_CONNECT_SIGNED_MSG,
15
384
  BASE_GAS_SPONSOR_SIGNED_MSG,
16
385
  BASE_REDIRECT_SIGNED_MSG,
17
386
  DEFAULT_BASE_SIGNED_MESSAGE,
18
- HttpAdapter,
19
387
  SnsAuthClient,
20
388
  SnsService,
21
389
  loginWithSns