@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 +1 -1
- package/dist/index.d.mts +11 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +101 -96
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +101 -96
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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.
|
|
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
|
|
1319
|
-
const
|
|
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
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
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
|
|