@aomi-labs/client 0.1.10 → 0.1.12

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/cli.js CHANGED
@@ -729,6 +729,22 @@ function createSseSubscriber({
729
729
  // src/client.ts
730
730
  var SESSION_ID_HEADER = "X-Session-Id";
731
731
  var API_KEY_HEADER = "X-API-Key";
732
+ function joinApiPath(baseUrl, path) {
733
+ const normalizedBase = baseUrl === "/" ? "" : baseUrl.replace(/\/+$/, "");
734
+ const normalizedPath = path.startsWith("/") ? path : `/${path}`;
735
+ return `${normalizedBase}${normalizedPath}` || normalizedPath;
736
+ }
737
+ function buildApiUrl(baseUrl, path, query) {
738
+ const url = joinApiPath(baseUrl, path);
739
+ if (!query) return url;
740
+ const params = new URLSearchParams();
741
+ for (const [key, value] of Object.entries(query)) {
742
+ if (value === void 0) continue;
743
+ params.set(key, value);
744
+ }
745
+ const queryString = params.toString();
746
+ return queryString ? `${url}?${queryString}` : url;
747
+ }
732
748
  function toQueryString(payload) {
733
749
  const params = new URLSearchParams();
734
750
  for (const [key, value] of Object.entries(payload)) {
@@ -777,11 +793,10 @@ var AomiClient = class {
777
793
  * Fetch current session state (messages, processing status, title).
778
794
  */
779
795
  async fetchState(sessionId, userState) {
780
- const url = new URL("/api/state", this.baseUrl);
781
- if (userState) {
782
- url.searchParams.set("user_state", JSON.stringify(userState));
783
- }
784
- const response = await fetch(url.toString(), {
796
+ const url = buildApiUrl(this.baseUrl, "/api/state", {
797
+ user_state: userState ? JSON.stringify(userState) : void 0
798
+ });
799
+ const response = await fetch(url, {
785
800
  headers: withSessionHeader(sessionId)
786
801
  });
787
802
  if (!response.ok) {
@@ -851,7 +866,9 @@ var AomiClient = class {
851
866
  * List all threads for a wallet address.
852
867
  */
853
868
  async listThreads(publicKey) {
854
- const url = `${this.baseUrl}/api/sessions?public_key=${encodeURIComponent(publicKey)}`;
869
+ const url = buildApiUrl(this.baseUrl, "/api/sessions", {
870
+ public_key: publicKey
871
+ });
855
872
  const response = await fetch(url);
856
873
  if (!response.ok) {
857
874
  throw new Error(`Failed to fetch threads: HTTP ${response.status}`);
@@ -862,7 +879,10 @@ var AomiClient = class {
862
879
  * Get a single thread by ID.
863
880
  */
864
881
  async getThread(sessionId) {
865
- const url = `${this.baseUrl}/api/sessions/${encodeURIComponent(sessionId)}`;
882
+ const url = buildApiUrl(
883
+ this.baseUrl,
884
+ `/api/sessions/${encodeURIComponent(sessionId)}`
885
+ );
866
886
  const response = await fetch(url, {
867
887
  headers: withSessionHeader(sessionId)
868
888
  });
@@ -877,7 +897,7 @@ var AomiClient = class {
877
897
  async createThread(threadId, publicKey) {
878
898
  const body = {};
879
899
  if (publicKey) body.public_key = publicKey;
880
- const url = `${this.baseUrl}/api/sessions`;
900
+ const url = buildApiUrl(this.baseUrl, "/api/sessions");
881
901
  const response = await fetch(url, {
882
902
  method: "POST",
883
903
  headers: withSessionHeader(threadId, {
@@ -894,7 +914,10 @@ var AomiClient = class {
894
914
  * Delete a thread by ID.
895
915
  */
896
916
  async deleteThread(sessionId) {
897
- const url = `${this.baseUrl}/api/sessions/${encodeURIComponent(sessionId)}`;
917
+ const url = buildApiUrl(
918
+ this.baseUrl,
919
+ `/api/sessions/${encodeURIComponent(sessionId)}`
920
+ );
898
921
  const response = await fetch(url, {
899
922
  method: "DELETE",
900
923
  headers: withSessionHeader(sessionId)
@@ -907,7 +930,10 @@ var AomiClient = class {
907
930
  * Rename a thread.
908
931
  */
909
932
  async renameThread(sessionId, newTitle) {
910
- const url = `${this.baseUrl}/api/sessions/${encodeURIComponent(sessionId)}`;
933
+ const url = buildApiUrl(
934
+ this.baseUrl,
935
+ `/api/sessions/${encodeURIComponent(sessionId)}`
936
+ );
911
937
  const response = await fetch(url, {
912
938
  method: "PATCH",
913
939
  headers: withSessionHeader(sessionId, {
@@ -923,7 +949,10 @@ var AomiClient = class {
923
949
  * Archive a thread.
924
950
  */
925
951
  async archiveThread(sessionId) {
926
- const url = `${this.baseUrl}/api/sessions/${encodeURIComponent(sessionId)}/archive`;
952
+ const url = buildApiUrl(
953
+ this.baseUrl,
954
+ `/api/sessions/${encodeURIComponent(sessionId)}/archive`
955
+ );
927
956
  const response = await fetch(url, {
928
957
  method: "POST",
929
958
  headers: withSessionHeader(sessionId)
@@ -936,7 +965,10 @@ var AomiClient = class {
936
965
  * Unarchive a thread.
937
966
  */
938
967
  async unarchiveThread(sessionId) {
939
- const url = `${this.baseUrl}/api/sessions/${encodeURIComponent(sessionId)}/unarchive`;
968
+ const url = buildApiUrl(
969
+ this.baseUrl,
970
+ `/api/sessions/${encodeURIComponent(sessionId)}/unarchive`
971
+ );
940
972
  const response = await fetch(url, {
941
973
  method: "POST",
942
974
  headers: withSessionHeader(sessionId)
@@ -952,11 +984,10 @@ var AomiClient = class {
952
984
  * Get system events for a session.
953
985
  */
954
986
  async getSystemEvents(sessionId, count) {
955
- const url = new URL("/api/events", this.baseUrl);
956
- if (count !== void 0) {
957
- url.searchParams.set("count", String(count));
958
- }
959
- const response = await fetch(url.toString(), {
987
+ const url = buildApiUrl(this.baseUrl, "/api/events", {
988
+ count: count !== void 0 ? String(count) : void 0
989
+ });
990
+ const response = await fetch(url, {
960
991
  headers: withSessionHeader(sessionId)
961
992
  });
962
993
  if (!response.ok) {
@@ -973,16 +1004,15 @@ var AomiClient = class {
973
1004
  */
974
1005
  async getApps(sessionId, options) {
975
1006
  var _a3;
976
- const url = new URL("/api/control/apps", this.baseUrl);
977
- if (options == null ? void 0 : options.publicKey) {
978
- url.searchParams.set("public_key", options.publicKey);
979
- }
1007
+ const url = buildApiUrl(this.baseUrl, "/api/control/apps", {
1008
+ public_key: options == null ? void 0 : options.publicKey
1009
+ });
980
1010
  const apiKey = (_a3 = options == null ? void 0 : options.apiKey) != null ? _a3 : this.apiKey;
981
1011
  const headers = new Headers(withSessionHeader(sessionId));
982
1012
  if (apiKey) {
983
1013
  headers.set(API_KEY_HEADER, apiKey);
984
1014
  }
985
- const response = await fetch(url.toString(), { headers });
1015
+ const response = await fetch(url, { headers });
986
1016
  if (!response.ok) {
987
1017
  throw new Error(`Failed to get apps: HTTP ${response.status}`);
988
1018
  }
@@ -993,13 +1023,13 @@ var AomiClient = class {
993
1023
  */
994
1024
  async getModels(sessionId, options) {
995
1025
  var _a3;
996
- const url = new URL("/api/control/models", this.baseUrl);
1026
+ const url = buildApiUrl(this.baseUrl, "/api/control/models");
997
1027
  const apiKey = (_a3 = options == null ? void 0 : options.apiKey) != null ? _a3 : this.apiKey;
998
1028
  const headers = new Headers(withSessionHeader(sessionId));
999
1029
  if (apiKey) {
1000
1030
  headers.set(API_KEY_HEADER, apiKey);
1001
1031
  }
1002
- const response = await fetch(url.toString(), {
1032
+ const response = await fetch(url, {
1003
1033
  headers
1004
1034
  });
1005
1035
  if (!response.ok) {
@@ -1208,8 +1238,29 @@ function normalizeEip712Payload(payload) {
1208
1238
  const description = typeof args.description === "string" ? args.description : void 0;
1209
1239
  return { typed_data: typedData, description };
1210
1240
  }
1241
+ function toViemSignTypedDataArgs(payload) {
1242
+ var _a3;
1243
+ const typedData = payload.typed_data;
1244
+ const primaryType = typeof (typedData == null ? void 0 : typedData.primaryType) === "string" && typedData.primaryType.trim().length > 0 ? typedData.primaryType : void 0;
1245
+ if (!typedData || !primaryType) {
1246
+ return null;
1247
+ }
1248
+ return {
1249
+ domain: asRecord(typedData.domain),
1250
+ types: Object.fromEntries(
1251
+ Object.entries((_a3 = typedData.types) != null ? _a3 : {}).filter(
1252
+ ([typeName]) => typeName !== "EIP712Domain"
1253
+ )
1254
+ ),
1255
+ primaryType,
1256
+ message: asRecord(typedData.message)
1257
+ };
1258
+ }
1211
1259
 
1212
1260
  // src/session.ts
1261
+ function isRecord(value) {
1262
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1263
+ }
1213
1264
  function sortJson(value) {
1214
1265
  if (Array.isArray(value)) {
1215
1266
  return value.map((entry) => sortJson(entry));
@@ -1432,6 +1483,30 @@ var ClientSession = class extends TypedEventEmitter {
1432
1483
  this.publicKey = address;
1433
1484
  }
1434
1485
  }
1486
+ addExtValue(key, value) {
1487
+ var _a3;
1488
+ const current = (_a3 = this.userState) != null ? _a3 : {};
1489
+ const currentExt = isRecord(current["ext"]) ? current["ext"] : {};
1490
+ this.resolveUserState(__spreadProps(__spreadValues({}, current), {
1491
+ ext: __spreadProps(__spreadValues({}, currentExt), {
1492
+ [key]: value
1493
+ })
1494
+ }));
1495
+ }
1496
+ removeExtValue(key) {
1497
+ if (!this.userState) return;
1498
+ const currentExt = this.userState["ext"];
1499
+ if (!isRecord(currentExt)) return;
1500
+ const nextExt = __spreadValues({}, currentExt);
1501
+ delete nextExt[key];
1502
+ const nextState = __spreadValues({}, this.userState);
1503
+ if (Object.keys(nextExt).length === 0) {
1504
+ delete nextState["ext"];
1505
+ } else {
1506
+ nextState["ext"] = nextExt;
1507
+ }
1508
+ this.resolveUserState(nextState);
1509
+ }
1435
1510
  resolveWallet(address, chainId) {
1436
1511
  this.resolveUserState({ address, chainId: chainId != null ? chainId : 1, isConnected: true });
1437
1512
  }
@@ -3492,26 +3567,18 @@ async function signCommand(runtime) {
3492
3567
  chain,
3493
3568
  transport: http(resolvedRpcUrl)
3494
3569
  });
3495
- const typedData = pendingTx.payload.typed_data;
3496
- if (!typedData) {
3570
+ const signArgs = toViemSignTypedDataArgs(
3571
+ pendingTx.payload
3572
+ );
3573
+ if (!signArgs) {
3497
3574
  fatal("EIP-712 request is missing typed_data payload.");
3498
3575
  }
3499
3576
  if (pendingTx.description) {
3500
3577
  console.log(`Desc: ${pendingTx.description}`);
3501
3578
  }
3502
- if (typedData.primaryType) {
3503
- console.log(`Type: ${typedData.primaryType}`);
3504
- }
3579
+ console.log(`Type: ${signArgs.primaryType}`);
3505
3580
  console.log();
3506
- const { domain, types, primaryType, message } = typedData;
3507
- const sigTypes = __spreadValues({}, types);
3508
- delete sigTypes["EIP712Domain"];
3509
- const signature = await walletClient.signTypedData({
3510
- domain,
3511
- types: sigTypes,
3512
- primaryType,
3513
- message
3514
- });
3581
+ const signature = await walletClient.signTypedData(signArgs);
3515
3582
  console.log(`\u2705 Signed! Signature: ${signature.slice(0, 20)}...`);
3516
3583
  signedRecords = [{
3517
3584
  id: pendingTx.id,
package/dist/index.cjs CHANGED
@@ -72,6 +72,7 @@ __export(index_exports, {
72
72
  resolveAlchemyConfig: () => resolveAlchemyConfig,
73
73
  resolveDefaultProvider: () => resolveDefaultProvider,
74
74
  resolvePimlicoConfig: () => resolvePimlicoConfig,
75
+ toViemSignTypedDataArgs: () => toViemSignTypedDataArgs,
75
76
  unwrapSystemEvent: () => unwrapSystemEvent
76
77
  });
77
78
  module.exports = __toCommonJS(index_exports);
@@ -253,6 +254,22 @@ function createSseSubscriber({
253
254
  // src/client.ts
254
255
  var SESSION_ID_HEADER = "X-Session-Id";
255
256
  var API_KEY_HEADER = "X-API-Key";
257
+ function joinApiPath(baseUrl, path) {
258
+ const normalizedBase = baseUrl === "/" ? "" : baseUrl.replace(/\/+$/, "");
259
+ const normalizedPath = path.startsWith("/") ? path : `/${path}`;
260
+ return `${normalizedBase}${normalizedPath}` || normalizedPath;
261
+ }
262
+ function buildApiUrl(baseUrl, path, query) {
263
+ const url = joinApiPath(baseUrl, path);
264
+ if (!query) return url;
265
+ const params = new URLSearchParams();
266
+ for (const [key, value] of Object.entries(query)) {
267
+ if (value === void 0) continue;
268
+ params.set(key, value);
269
+ }
270
+ const queryString = params.toString();
271
+ return queryString ? `${url}?${queryString}` : url;
272
+ }
256
273
  function toQueryString(payload) {
257
274
  const params = new URLSearchParams();
258
275
  for (const [key, value] of Object.entries(payload)) {
@@ -301,11 +318,10 @@ var AomiClient = class {
301
318
  * Fetch current session state (messages, processing status, title).
302
319
  */
303
320
  async fetchState(sessionId, userState) {
304
- const url = new URL("/api/state", this.baseUrl);
305
- if (userState) {
306
- url.searchParams.set("user_state", JSON.stringify(userState));
307
- }
308
- const response = await fetch(url.toString(), {
321
+ const url = buildApiUrl(this.baseUrl, "/api/state", {
322
+ user_state: userState ? JSON.stringify(userState) : void 0
323
+ });
324
+ const response = await fetch(url, {
309
325
  headers: withSessionHeader(sessionId)
310
326
  });
311
327
  if (!response.ok) {
@@ -375,7 +391,9 @@ var AomiClient = class {
375
391
  * List all threads for a wallet address.
376
392
  */
377
393
  async listThreads(publicKey) {
378
- const url = `${this.baseUrl}/api/sessions?public_key=${encodeURIComponent(publicKey)}`;
394
+ const url = buildApiUrl(this.baseUrl, "/api/sessions", {
395
+ public_key: publicKey
396
+ });
379
397
  const response = await fetch(url);
380
398
  if (!response.ok) {
381
399
  throw new Error(`Failed to fetch threads: HTTP ${response.status}`);
@@ -386,7 +404,10 @@ var AomiClient = class {
386
404
  * Get a single thread by ID.
387
405
  */
388
406
  async getThread(sessionId) {
389
- const url = `${this.baseUrl}/api/sessions/${encodeURIComponent(sessionId)}`;
407
+ const url = buildApiUrl(
408
+ this.baseUrl,
409
+ `/api/sessions/${encodeURIComponent(sessionId)}`
410
+ );
390
411
  const response = await fetch(url, {
391
412
  headers: withSessionHeader(sessionId)
392
413
  });
@@ -401,7 +422,7 @@ var AomiClient = class {
401
422
  async createThread(threadId, publicKey) {
402
423
  const body = {};
403
424
  if (publicKey) body.public_key = publicKey;
404
- const url = `${this.baseUrl}/api/sessions`;
425
+ const url = buildApiUrl(this.baseUrl, "/api/sessions");
405
426
  const response = await fetch(url, {
406
427
  method: "POST",
407
428
  headers: withSessionHeader(threadId, {
@@ -418,7 +439,10 @@ var AomiClient = class {
418
439
  * Delete a thread by ID.
419
440
  */
420
441
  async deleteThread(sessionId) {
421
- const url = `${this.baseUrl}/api/sessions/${encodeURIComponent(sessionId)}`;
442
+ const url = buildApiUrl(
443
+ this.baseUrl,
444
+ `/api/sessions/${encodeURIComponent(sessionId)}`
445
+ );
422
446
  const response = await fetch(url, {
423
447
  method: "DELETE",
424
448
  headers: withSessionHeader(sessionId)
@@ -431,7 +455,10 @@ var AomiClient = class {
431
455
  * Rename a thread.
432
456
  */
433
457
  async renameThread(sessionId, newTitle) {
434
- const url = `${this.baseUrl}/api/sessions/${encodeURIComponent(sessionId)}`;
458
+ const url = buildApiUrl(
459
+ this.baseUrl,
460
+ `/api/sessions/${encodeURIComponent(sessionId)}`
461
+ );
435
462
  const response = await fetch(url, {
436
463
  method: "PATCH",
437
464
  headers: withSessionHeader(sessionId, {
@@ -447,7 +474,10 @@ var AomiClient = class {
447
474
  * Archive a thread.
448
475
  */
449
476
  async archiveThread(sessionId) {
450
- const url = `${this.baseUrl}/api/sessions/${encodeURIComponent(sessionId)}/archive`;
477
+ const url = buildApiUrl(
478
+ this.baseUrl,
479
+ `/api/sessions/${encodeURIComponent(sessionId)}/archive`
480
+ );
451
481
  const response = await fetch(url, {
452
482
  method: "POST",
453
483
  headers: withSessionHeader(sessionId)
@@ -460,7 +490,10 @@ var AomiClient = class {
460
490
  * Unarchive a thread.
461
491
  */
462
492
  async unarchiveThread(sessionId) {
463
- const url = `${this.baseUrl}/api/sessions/${encodeURIComponent(sessionId)}/unarchive`;
493
+ const url = buildApiUrl(
494
+ this.baseUrl,
495
+ `/api/sessions/${encodeURIComponent(sessionId)}/unarchive`
496
+ );
464
497
  const response = await fetch(url, {
465
498
  method: "POST",
466
499
  headers: withSessionHeader(sessionId)
@@ -476,11 +509,10 @@ var AomiClient = class {
476
509
  * Get system events for a session.
477
510
  */
478
511
  async getSystemEvents(sessionId, count) {
479
- const url = new URL("/api/events", this.baseUrl);
480
- if (count !== void 0) {
481
- url.searchParams.set("count", String(count));
482
- }
483
- const response = await fetch(url.toString(), {
512
+ const url = buildApiUrl(this.baseUrl, "/api/events", {
513
+ count: count !== void 0 ? String(count) : void 0
514
+ });
515
+ const response = await fetch(url, {
484
516
  headers: withSessionHeader(sessionId)
485
517
  });
486
518
  if (!response.ok) {
@@ -497,16 +529,15 @@ var AomiClient = class {
497
529
  */
498
530
  async getApps(sessionId, options) {
499
531
  var _a;
500
- const url = new URL("/api/control/apps", this.baseUrl);
501
- if (options == null ? void 0 : options.publicKey) {
502
- url.searchParams.set("public_key", options.publicKey);
503
- }
532
+ const url = buildApiUrl(this.baseUrl, "/api/control/apps", {
533
+ public_key: options == null ? void 0 : options.publicKey
534
+ });
504
535
  const apiKey = (_a = options == null ? void 0 : options.apiKey) != null ? _a : this.apiKey;
505
536
  const headers = new Headers(withSessionHeader(sessionId));
506
537
  if (apiKey) {
507
538
  headers.set(API_KEY_HEADER, apiKey);
508
539
  }
509
- const response = await fetch(url.toString(), { headers });
540
+ const response = await fetch(url, { headers });
510
541
  if (!response.ok) {
511
542
  throw new Error(`Failed to get apps: HTTP ${response.status}`);
512
543
  }
@@ -517,13 +548,13 @@ var AomiClient = class {
517
548
  */
518
549
  async getModels(sessionId, options) {
519
550
  var _a;
520
- const url = new URL("/api/control/models", this.baseUrl);
551
+ const url = buildApiUrl(this.baseUrl, "/api/control/models");
521
552
  const apiKey = (_a = options == null ? void 0 : options.apiKey) != null ? _a : this.apiKey;
522
553
  const headers = new Headers(withSessionHeader(sessionId));
523
554
  if (apiKey) {
524
555
  headers.set(API_KEY_HEADER, apiKey);
525
556
  }
526
- const response = await fetch(url.toString(), {
557
+ const response = await fetch(url, {
527
558
  headers
528
559
  });
529
560
  if (!response.ok) {
@@ -732,8 +763,29 @@ function normalizeEip712Payload(payload) {
732
763
  const description = typeof args.description === "string" ? args.description : void 0;
733
764
  return { typed_data: typedData, description };
734
765
  }
766
+ function toViemSignTypedDataArgs(payload) {
767
+ var _a;
768
+ const typedData = payload.typed_data;
769
+ const primaryType = typeof (typedData == null ? void 0 : typedData.primaryType) === "string" && typedData.primaryType.trim().length > 0 ? typedData.primaryType : void 0;
770
+ if (!typedData || !primaryType) {
771
+ return null;
772
+ }
773
+ return {
774
+ domain: asRecord(typedData.domain),
775
+ types: Object.fromEntries(
776
+ Object.entries((_a = typedData.types) != null ? _a : {}).filter(
777
+ ([typeName]) => typeName !== "EIP712Domain"
778
+ )
779
+ ),
780
+ primaryType,
781
+ message: asRecord(typedData.message)
782
+ };
783
+ }
735
784
 
736
785
  // src/session.ts
786
+ function isRecord(value) {
787
+ return typeof value === "object" && value !== null && !Array.isArray(value);
788
+ }
737
789
  function sortJson(value) {
738
790
  if (Array.isArray(value)) {
739
791
  return value.map((entry) => sortJson(entry));
@@ -956,6 +1008,30 @@ var ClientSession = class extends TypedEventEmitter {
956
1008
  this.publicKey = address;
957
1009
  }
958
1010
  }
1011
+ addExtValue(key, value) {
1012
+ var _a;
1013
+ const current = (_a = this.userState) != null ? _a : {};
1014
+ const currentExt = isRecord(current["ext"]) ? current["ext"] : {};
1015
+ this.resolveUserState(__spreadProps(__spreadValues({}, current), {
1016
+ ext: __spreadProps(__spreadValues({}, currentExt), {
1017
+ [key]: value
1018
+ })
1019
+ }));
1020
+ }
1021
+ removeExtValue(key) {
1022
+ if (!this.userState) return;
1023
+ const currentExt = this.userState["ext"];
1024
+ if (!isRecord(currentExt)) return;
1025
+ const nextExt = __spreadValues({}, currentExt);
1026
+ delete nextExt[key];
1027
+ const nextState = __spreadValues({}, this.userState);
1028
+ if (Object.keys(nextExt).length === 0) {
1029
+ delete nextState["ext"];
1030
+ } else {
1031
+ nextState["ext"] = nextExt;
1032
+ }
1033
+ this.resolveUserState(nextState);
1034
+ }
959
1035
  resolveWallet(address, chainId) {
960
1036
  this.resolveUserState({ address, chainId: chainId != null ? chainId : 1, isConnected: true });
961
1037
  }
@@ -1939,6 +2015,7 @@ async function createPimlicoAAState(options) {
1939
2015
  resolveAlchemyConfig,
1940
2016
  resolveDefaultProvider,
1941
2017
  resolvePimlicoConfig,
2018
+ toViemSignTypedDataArgs,
1942
2019
  unwrapSystemEvent
1943
2020
  });
1944
2021
  //# sourceMappingURL=index.cjs.map