@morseai/sdk 0.1.0-beta.7 → 0.1.0-beta.9

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/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  TypeScript SDK for creating and accessing encrypted signals in the MORSE platform.
8
8
 
9
- **Version:** 0.1.0-beta.7 (Beta Release)
9
+ **Version:** 0.1.0-beta.9 (Beta Release)
10
10
 
11
11
  > ⚠️ **Beta Notice**: This is a beta release. The API is stable but may have minor changes before the 1.0.0 release. Please report any issues you encounter.
12
12
 
package/dist/index.d.mts CHANGED
@@ -73,6 +73,16 @@ interface CreateSignalOptionsEncrypted {
73
73
  enabled: boolean;
74
74
  network: string;
75
75
  };
76
+ /**
77
+ * Domain for key derivation (optional, defaults to "morseai.tech")
78
+ * Should match the domain used when opening the signal
79
+ */
80
+ domain?: string;
81
+ /**
82
+ * Chain ID for key derivation (optional, defaults to 8453 for Base)
83
+ * Should match the chain ID used when opening the signal
84
+ */
85
+ chainId?: number;
76
86
  /**
77
87
  * Specific expiration date and time (ISO 8601 format).
78
88
  * Use this for custom expiration dates.
@@ -182,6 +192,7 @@ interface SignalErrorResponse {
182
192
  interface WalletAuth {
183
193
  address: string;
184
194
  signMessage: (message: string) => Promise<string>;
195
+ signTypedData?: (domain: any, types: any, value: any) => Promise<string>;
185
196
  }
186
197
  interface RateLimitConfig {
187
198
  enabled?: boolean;
package/dist/index.d.ts CHANGED
@@ -73,6 +73,16 @@ interface CreateSignalOptionsEncrypted {
73
73
  enabled: boolean;
74
74
  network: string;
75
75
  };
76
+ /**
77
+ * Domain for key derivation (optional, defaults to "morseai.tech")
78
+ * Should match the domain used when opening the signal
79
+ */
80
+ domain?: string;
81
+ /**
82
+ * Chain ID for key derivation (optional, defaults to 8453 for Base)
83
+ * Should match the chain ID used when opening the signal
84
+ */
85
+ chainId?: number;
76
86
  /**
77
87
  * Specific expiration date and time (ISO 8601 format).
78
88
  * Use this for custom expiration dates.
@@ -182,6 +192,7 @@ interface SignalErrorResponse {
182
192
  interface WalletAuth {
183
193
  address: string;
184
194
  signMessage: (message: string) => Promise<string>;
195
+ signTypedData?: (domain: any, types: any, value: any) => Promise<string>;
185
196
  }
186
197
  interface RateLimitConfig {
187
198
  enabled?: boolean;
package/dist/index.js CHANGED
@@ -481,50 +481,6 @@ function mapErrorResponse(error) {
481
481
  return new MorseSDKError(error.message || "Unknown error");
482
482
  }
483
483
 
484
- // src/logger.ts
485
- var Logger = class {
486
- constructor() {
487
- this.level = "warn";
488
- this.levels = {
489
- none: 0,
490
- error: 1,
491
- warn: 2,
492
- info: 3,
493
- debug: 4
494
- };
495
- }
496
- setLevel(level) {
497
- this.level = level;
498
- }
499
- getLevel() {
500
- return this.level;
501
- }
502
- shouldLog(level) {
503
- return this.levels[level] <= this.levels[this.level];
504
- }
505
- error(message, ...args) {
506
- if (this.shouldLog("error")) {
507
- console.error(`[MorseSDK] ${message}`, ...args);
508
- }
509
- }
510
- warn(message, ...args) {
511
- if (this.shouldLog("warn")) {
512
- console.warn(`[MorseSDK] ${message}`, ...args);
513
- }
514
- }
515
- info(message, ...args) {
516
- if (this.shouldLog("info")) {
517
- console.info(`[MorseSDK] ${message}`, ...args);
518
- }
519
- }
520
- debug(message, ...args) {
521
- if (this.shouldLog("debug")) {
522
- console.debug(`[MorseSDK] ${message}`, ...args);
523
- }
524
- }
525
- };
526
- var logger = new Logger();
527
-
528
484
  // src/crypto.ts
529
485
  var CIPHER_VERSION = "aes-gcm-256-v1";
530
486
  function getCrypto() {
@@ -834,13 +790,6 @@ var MorseSDKV1 = class {
834
790
  const windowMs = config.rateLimit?.windowMs || 6e4;
835
791
  this.rateLimiter = new RateLimiter({ maxRequests, windowMs });
836
792
  }
837
- logger.debug("MorseSDKV1 initialized", {
838
- apiVersion: config.apiVersion || "v1",
839
- timeout: this.timeout,
840
- retries: this.retries,
841
- rateLimitEnabled: this.rateLimiter !== null,
842
- hasApiKey: !!config.apiKey
843
- });
844
793
  }
845
794
  base64ToUint8Array(base64) {
846
795
  if (typeof Buffer !== "undefined") {
@@ -920,10 +869,6 @@ var MorseSDKV1 = class {
920
869
  await this.rateLimiter.checkLimit();
921
870
  } catch (error) {
922
871
  if (error instanceof RateLimitError) {
923
- logger.warn("Rate limit exceeded", {
924
- url,
925
- retryAfterMs: error.retryAfterMs
926
- });
927
872
  if (this.config.onError) {
928
873
  this.config.onError(error);
929
874
  }
@@ -932,11 +877,6 @@ var MorseSDKV1 = class {
932
877
  throw error;
933
878
  }
934
879
  }
935
- logger.debug("Making request", {
936
- url,
937
- method: options.method || "GET",
938
- hasBody: !!options.body
939
- });
940
880
  const requestOptions = {
941
881
  ...options,
942
882
  headers: {
@@ -968,12 +908,6 @@ var MorseSDKV1 = class {
968
908
  code: "VALIDATION_ERROR",
969
909
  message: `HTTP ${response.status}: ${response.statusText}`
970
910
  }));
971
- logger.error("Request failed", {
972
- status: response.status,
973
- code: error.code,
974
- message: error.message,
975
- attempt: attempt + 1
976
- });
977
911
  const mappedError = mapErrorResponse(error);
978
912
  if (this.config.onError) {
979
913
  this.config.onError(mappedError);
@@ -981,7 +915,6 @@ var MorseSDKV1 = class {
981
915
  throw mappedError;
982
916
  }
983
917
  const data = await response.json();
984
- logger.debug("Request successful", { url, attempt: attempt + 1 });
985
918
  return data;
986
919
  } catch (error) {
987
920
  lastError = error;
@@ -994,7 +927,6 @@ var MorseSDKV1 = class {
994
927
  }
995
928
  if (error instanceof NetworkError || error.name?.includes("Error")) {
996
929
  if (attempt < this.retries) {
997
- logger.warn(`Request failed, retrying... (${attempt + 1}/${this.retries})`, { url });
998
930
  await new Promise((resolve) => setTimeout(resolve, this.retryDelay * (attempt + 1)));
999
931
  continue;
1000
932
  }
@@ -1005,7 +937,6 @@ var MorseSDKV1 = class {
1005
937
  }
1006
938
  if (error.message?.includes("fetch") || error.message?.includes("network")) {
1007
939
  if (attempt < this.retries) {
1008
- logger.warn(`Network error, retrying... (${attempt + 1}/${this.retries})`, { url });
1009
940
  await new Promise((resolve) => setTimeout(resolve, this.retryDelay * (attempt + 1)));
1010
941
  continue;
1011
942
  }
@@ -1040,11 +971,6 @@ var MorseSDKV1 = class {
1040
971
  if (!options.hasFile && !options.hasMessage) {
1041
972
  throw new Error("Either hasFile or hasMessage must be true");
1042
973
  }
1043
- logger.info("Creating signal", {
1044
- hasFile: options.hasFile,
1045
- hasMessage: options.hasMessage,
1046
- mode: options.mode
1047
- });
1048
974
  const tempSignalId = "temp-" + Date.now();
1049
975
  const authMessage = await this.createAuthMessage("create", `signal ${tempSignalId}`);
1050
976
  const signature = await this.signMessage(wallet, authMessage);
@@ -1063,13 +989,11 @@ var MorseSDKV1 = class {
1063
989
  body: JSON.stringify(requestBody)
1064
990
  }
1065
991
  );
1066
- logger.info("Signal created", { signalId: result.signalId });
1067
992
  return result;
1068
993
  }
1069
994
  async openSignal(wallet, signalId) {
1070
995
  validateSignalId(signalId);
1071
996
  validateWalletAddress(wallet.address);
1072
- logger.info("Opening signal", { signalId });
1073
997
  const authMessage = await this.createAuthMessage("open", `signal ${signalId}`);
1074
998
  const signature = await this.signMessage(wallet, authMessage);
1075
999
  const requestBody = {
@@ -1087,7 +1011,6 @@ var MorseSDKV1 = class {
1087
1011
  body: JSON.stringify(requestBody)
1088
1012
  }
1089
1013
  );
1090
- logger.info("Signal opened", { signalId, hasFile: !!result.file });
1091
1014
  return result;
1092
1015
  }
1093
1016
  async openSignalDecrypted(wallet, signalId, keyBase64) {
@@ -1315,19 +1238,59 @@ var MorseSDKV1 = class {
1315
1238
  }
1316
1239
  const walletTarget = wallet.address;
1317
1240
  const walletCreator = wallet.address;
1318
- const domain = "morse.app";
1319
- const chainId = 8453;
1241
+ const keyService = new WalletKeyService(API_BASE_URL, this.config.apiKey, this.config.apiVersion || "v1");
1242
+ const creatorKeyResponse = await keyService.getPublicKey(wallet.address);
1243
+ let domain;
1244
+ let chainId;
1245
+ if (creatorKeyResponse.exists && creatorKeyResponse.certificate) {
1246
+ domain = creatorKeyResponse.certificate.domain || options.domain || "morseai.tech";
1247
+ chainId = creatorKeyResponse.certificate.chainId ?? (options.chainId ?? 8453);
1248
+ } else {
1249
+ domain = options.domain || "morseai.tech";
1250
+ chainId = options.chainId ?? 8453;
1251
+ const { deriveKeyPairFromWalletSignature: deriveKeyPairFromWalletSignature2, createKeyCertificate: createKeyCertificate2 } = await Promise.resolve().then(() => (init_crypto_x25519(), crypto_x25519_exports));
1252
+ const creatorKeypair = await deriveKeyPairFromWalletSignature2(
1253
+ wallet.address,
1254
+ domain,
1255
+ chainId,
1256
+ wallet.signMessage
1257
+ );
1258
+ const publicKeyBase64 = Buffer.from(creatorKeypair.publicKey).toString("base64");
1259
+ const expiresAtMsCert = Date.now() + 30 * 24 * 60 * 60 * 1e3;
1260
+ let signTypedDataFn;
1261
+ if (wallet.signTypedData) {
1262
+ signTypedDataFn = wallet.signTypedData;
1263
+ } else {
1264
+ throw new Error(
1265
+ "signTypedData is required for publishing public key. Please ensure your WalletAuth includes signTypedData. If using createWalletFromPrivateKey, update to the latest version of the SDK."
1266
+ );
1267
+ }
1268
+ const certificate = await createKeyCertificate2(
1269
+ wallet.address,
1270
+ publicKeyBase64,
1271
+ domain,
1272
+ chainId,
1273
+ expiresAtMsCert,
1274
+ signTypedDataFn
1275
+ );
1276
+ await keyService.publishPublicKey(certificate);
1277
+ }
1320
1278
  const keyBytes = this.base64ToUint8Array(keyBase64);
1321
- const sealedBox = await sealDataKey(
1322
- keyBytes,
1323
- walletTarget.toLowerCase(),
1324
- walletCreator.toLowerCase(),
1325
- expiresAtMs,
1326
- signalId,
1327
- domain,
1328
- chainId,
1329
- wallet.signMessage
1330
- );
1279
+ let sealedBox;
1280
+ try {
1281
+ sealedBox = await sealDataKey(
1282
+ keyBytes,
1283
+ walletTarget.toLowerCase(),
1284
+ walletCreator.toLowerCase(),
1285
+ expiresAtMs,
1286
+ signalId,
1287
+ domain,
1288
+ chainId,
1289
+ wallet.signMessage
1290
+ );
1291
+ } catch (sealError) {
1292
+ throw new Error(`Failed to seal encryption key: ${sealError.message || String(sealError)}`);
1293
+ }
1331
1294
  let encryptedText;
1332
1295
  let payloadNonce;
1333
1296
  let fileOptions;
@@ -1487,7 +1450,6 @@ var MorseSDKV1 = class {
1487
1450
  async burnSignal(wallet, signalId) {
1488
1451
  validateSignalId(signalId);
1489
1452
  validateWalletAddress(wallet.address);
1490
- logger.info("Burning signal", { signalId });
1491
1453
  const authMessage = await this.createAuthMessage("burn", `signal ${signalId}`);
1492
1454
  const signature = await this.signMessage(wallet, authMessage);
1493
1455
  const requestBody = {
@@ -1505,7 +1467,6 @@ var MorseSDKV1 = class {
1505
1467
  body: JSON.stringify(requestBody)
1506
1468
  }
1507
1469
  );
1508
- logger.info("Signal burned successfully", { signalId });
1509
1470
  return result;
1510
1471
  }
1511
1472
  };
@@ -1523,14 +1484,9 @@ var MorseSDK = class {
1523
1484
  this.contract = new MorseSDKV1(config);
1524
1485
  break;
1525
1486
  default:
1526
- logger.warn(`Unknown API version: ${this.apiVersion}, defaulting to v1`);
1527
1487
  this.contract = new MorseSDKV1(config);
1528
1488
  this.apiVersion = "v1";
1529
1489
  }
1530
- logger.debug("MorseSDK initialized", {
1531
- apiVersion: this.apiVersion,
1532
- contractVersion: this.contract.version
1533
- });
1534
1490
  }
1535
1491
  getConfig() {
1536
1492
  return { ...this.config };
@@ -1613,6 +1569,11 @@ function createWalletFromPrivateKey(config) {
1613
1569
  const wallet = new Wallet(privateKey);
1614
1570
  const signature = await wallet.signMessage(message);
1615
1571
  return signature;
1572
+ },
1573
+ signTypedData: async (domain, types, value) => {
1574
+ const wallet = new Wallet(privateKey);
1575
+ const signature = await wallet.signTypedData(domain, types, value);
1576
+ return signature;
1616
1577
  }
1617
1578
  };
1618
1579
  }
@@ -1657,6 +1618,50 @@ async function createBrowserWallet(ethereum, address) {
1657
1618
  };
1658
1619
  }
1659
1620
 
1621
+ // src/logger.ts
1622
+ var Logger = class {
1623
+ constructor() {
1624
+ this.level = "warn";
1625
+ this.levels = {
1626
+ none: 0,
1627
+ error: 1,
1628
+ warn: 2,
1629
+ info: 3,
1630
+ debug: 4
1631
+ };
1632
+ }
1633
+ setLevel(level) {
1634
+ this.level = level;
1635
+ }
1636
+ getLevel() {
1637
+ return this.level;
1638
+ }
1639
+ shouldLog(level) {
1640
+ return this.levels[level] <= this.levels[this.level];
1641
+ }
1642
+ error(message, ...args) {
1643
+ if (this.shouldLog("error")) {
1644
+ console.error(`[MorseSDK] ${message}`, ...args);
1645
+ }
1646
+ }
1647
+ warn(message, ...args) {
1648
+ if (this.shouldLog("warn")) {
1649
+ console.warn(`[MorseSDK] ${message}`, ...args);
1650
+ }
1651
+ }
1652
+ info(message, ...args) {
1653
+ if (this.shouldLog("info")) {
1654
+ console.info(`[MorseSDK] ${message}`, ...args);
1655
+ }
1656
+ }
1657
+ debug(message, ...args) {
1658
+ if (this.shouldLog("debug")) {
1659
+ console.debug(`[MorseSDK] ${message}`, ...args);
1660
+ }
1661
+ }
1662
+ };
1663
+ var logger = new Logger();
1664
+
1660
1665
  // src/index.ts
1661
1666
  init_crypto_x25519();
1662
1667