@fileverse/api 0.0.12 → 0.0.14
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/index.js +20 -8
- package/dist/cli/index.js.map +1 -1
- package/dist/cloudflare.js +166 -47
- package/dist/cloudflare.js.map +1 -1
- package/dist/commands/index.js +21 -9
- package/dist/commands/index.js.map +1 -1
- package/dist/index.js +159 -44
- package/dist/index.js.map +1 -1
- package/dist/worker.js +145 -30
- package/dist/worker.js.map +1 -1
- package/package.json +1 -2
package/dist/worker.js
CHANGED
|
@@ -1206,13 +1206,114 @@ var init_key_store = __esm({
|
|
|
1206
1206
|
}
|
|
1207
1207
|
});
|
|
1208
1208
|
|
|
1209
|
+
// src/sdk/ucan.ts
|
|
1210
|
+
import { sign, extractPublicKeyFromSecretKey } from "@stablelib/ed25519";
|
|
1211
|
+
import { toUint8Array } from "js-base64";
|
|
1212
|
+
function base58btcEncode(bytes) {
|
|
1213
|
+
const digits = [0];
|
|
1214
|
+
for (const byte of bytes) {
|
|
1215
|
+
let carry = byte;
|
|
1216
|
+
for (let j = 0; j < digits.length; j++) {
|
|
1217
|
+
carry += digits[j] << 8;
|
|
1218
|
+
digits[j] = carry % 58;
|
|
1219
|
+
carry = carry / 58 | 0;
|
|
1220
|
+
}
|
|
1221
|
+
while (carry > 0) {
|
|
1222
|
+
digits.push(carry % 58);
|
|
1223
|
+
carry = carry / 58 | 0;
|
|
1224
|
+
}
|
|
1225
|
+
}
|
|
1226
|
+
let result = "";
|
|
1227
|
+
for (let i = 0; i < bytes.length && bytes[i] === 0; i++) {
|
|
1228
|
+
result += BASE58_ALPHABET[0];
|
|
1229
|
+
}
|
|
1230
|
+
for (let i = digits.length - 1; i >= 0; i--) {
|
|
1231
|
+
result += BASE58_ALPHABET[digits[i]];
|
|
1232
|
+
}
|
|
1233
|
+
return result;
|
|
1234
|
+
}
|
|
1235
|
+
function base64urlEncode(data) {
|
|
1236
|
+
const bytes = typeof data === "string" ? new TextEncoder().encode(data) : data;
|
|
1237
|
+
let binary = "";
|
|
1238
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
1239
|
+
binary += String.fromCharCode(bytes[i]);
|
|
1240
|
+
}
|
|
1241
|
+
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
1242
|
+
}
|
|
1243
|
+
async function buildAndEncode(params) {
|
|
1244
|
+
const {
|
|
1245
|
+
issuer,
|
|
1246
|
+
audience,
|
|
1247
|
+
capabilities = [],
|
|
1248
|
+
lifetimeInSeconds = 30,
|
|
1249
|
+
expiration,
|
|
1250
|
+
notBefore,
|
|
1251
|
+
facts,
|
|
1252
|
+
proofs = []
|
|
1253
|
+
} = params;
|
|
1254
|
+
const currentTime = Math.floor(Date.now() / 1e3);
|
|
1255
|
+
const exp = expiration ?? currentTime + lifetimeInSeconds;
|
|
1256
|
+
const header = { alg: issuer.jwtAlg, typ: "JWT", ucv: "0.8.1" };
|
|
1257
|
+
const att = capabilities.map((cap) => ({
|
|
1258
|
+
with: `${cap.with.scheme}:${cap.with.hierPart}`,
|
|
1259
|
+
can: [cap.can.namespace, ...cap.can.segments].join("/")
|
|
1260
|
+
}));
|
|
1261
|
+
const payload = {
|
|
1262
|
+
iss: issuer.did(),
|
|
1263
|
+
aud: audience,
|
|
1264
|
+
exp,
|
|
1265
|
+
att,
|
|
1266
|
+
prf: proofs
|
|
1267
|
+
};
|
|
1268
|
+
if (notBefore !== void 0) payload.nbf = notBefore;
|
|
1269
|
+
if (facts !== void 0) payload.fct = facts;
|
|
1270
|
+
const encodedHeader = base64urlEncode(JSON.stringify(header));
|
|
1271
|
+
const encodedPayload = base64urlEncode(JSON.stringify(payload));
|
|
1272
|
+
const signedData = `${encodedHeader}.${encodedPayload}`;
|
|
1273
|
+
const sig = await issuer.sign(new TextEncoder().encode(signedData));
|
|
1274
|
+
const signature = base64urlEncode(sig);
|
|
1275
|
+
return `${signedData}.${signature}`;
|
|
1276
|
+
}
|
|
1277
|
+
var BASE58_ALPHABET, EDWARDS_DID_PREFIX, EdKeypair;
|
|
1278
|
+
var init_ucan = __esm({
|
|
1279
|
+
"src/sdk/ucan.ts"() {
|
|
1280
|
+
"use strict";
|
|
1281
|
+
init_esm_shims();
|
|
1282
|
+
BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
1283
|
+
EDWARDS_DID_PREFIX = new Uint8Array([237, 1]);
|
|
1284
|
+
EdKeypair = class _EdKeypair {
|
|
1285
|
+
jwtAlg = "EdDSA";
|
|
1286
|
+
secretKey;
|
|
1287
|
+
publicKey;
|
|
1288
|
+
constructor(secretKey, publicKey) {
|
|
1289
|
+
this.secretKey = secretKey;
|
|
1290
|
+
this.publicKey = publicKey;
|
|
1291
|
+
}
|
|
1292
|
+
static fromSecretKey(key) {
|
|
1293
|
+
const secretKey = toUint8Array(key);
|
|
1294
|
+
const publicKey = extractPublicKeyFromSecretKey(secretKey);
|
|
1295
|
+
return new _EdKeypair(secretKey, publicKey);
|
|
1296
|
+
}
|
|
1297
|
+
did() {
|
|
1298
|
+
const bytes = new Uint8Array(EDWARDS_DID_PREFIX.length + this.publicKey.length);
|
|
1299
|
+
bytes.set(EDWARDS_DID_PREFIX);
|
|
1300
|
+
bytes.set(this.publicKey, EDWARDS_DID_PREFIX.length);
|
|
1301
|
+
return "did:key:z" + base58btcEncode(bytes);
|
|
1302
|
+
}
|
|
1303
|
+
async sign(msg) {
|
|
1304
|
+
return sign(this.secretKey, msg);
|
|
1305
|
+
}
|
|
1306
|
+
};
|
|
1307
|
+
}
|
|
1308
|
+
});
|
|
1309
|
+
|
|
1209
1310
|
// src/sdk/auth-token-provider.ts
|
|
1210
|
-
import * as ucans from "@ucans/ucans";
|
|
1211
1311
|
var AuthTokenProvider;
|
|
1212
1312
|
var init_auth_token_provider = __esm({
|
|
1213
1313
|
"src/sdk/auth-token-provider.ts"() {
|
|
1214
1314
|
"use strict";
|
|
1215
1315
|
init_esm_shims();
|
|
1316
|
+
init_ucan();
|
|
1216
1317
|
AuthTokenProvider = class {
|
|
1217
1318
|
DEFAULT_OPTIONS = {
|
|
1218
1319
|
namespace: "file",
|
|
@@ -1226,7 +1327,7 @@ var init_auth_token_provider = __esm({
|
|
|
1226
1327
|
this.portalAddress = portalAddress;
|
|
1227
1328
|
}
|
|
1228
1329
|
async getAuthToken(audienceDid, options = this.DEFAULT_OPTIONS) {
|
|
1229
|
-
|
|
1330
|
+
return buildAndEncode({
|
|
1230
1331
|
audience: audienceDid,
|
|
1231
1332
|
issuer: this.keyPair,
|
|
1232
1333
|
lifetimeInSeconds: 7 * 86400,
|
|
@@ -1240,7 +1341,6 @@ var init_auth_token_provider = __esm({
|
|
|
1240
1341
|
}
|
|
1241
1342
|
]
|
|
1242
1343
|
});
|
|
1243
|
-
return ucans.encode(ucan);
|
|
1244
1344
|
}
|
|
1245
1345
|
};
|
|
1246
1346
|
}
|
|
@@ -2414,7 +2514,7 @@ import { derivePBKDF2Key, encryptAesCBC } from "@fileverse/crypto/kdf";
|
|
|
2414
2514
|
import { secretBoxEncrypt } from "@fileverse/crypto/nacl";
|
|
2415
2515
|
import hkdf from "futoin-hkdf";
|
|
2416
2516
|
import tweetnacl from "tweetnacl";
|
|
2417
|
-
import { fromUint8Array, toUint8Array } from "js-base64";
|
|
2517
|
+
import { fromUint8Array, toUint8Array as toUint8Array2 } from "js-base64";
|
|
2418
2518
|
import { toAESKey, aesEncrypt } from "@fileverse/crypto/webcrypto";
|
|
2419
2519
|
import axios from "axios";
|
|
2420
2520
|
import { encodeFunctionData, parseEventLogs } from "viem";
|
|
@@ -2454,8 +2554,8 @@ var init_file_utils = __esm({
|
|
|
2454
2554
|
const encryptedBlob = new Blob([ciphertext], { type: file.type });
|
|
2455
2555
|
const encryptedBlobWithAuthTagIv = await appendAuthTagIvToBlob(
|
|
2456
2556
|
encryptedBlob,
|
|
2457
|
-
|
|
2458
|
-
|
|
2557
|
+
toUint8Array2(authTag),
|
|
2558
|
+
toUint8Array2(iv)
|
|
2459
2559
|
);
|
|
2460
2560
|
return {
|
|
2461
2561
|
encryptedFile: new File([encryptedBlobWithAuthTagIv], file.name),
|
|
@@ -2501,7 +2601,7 @@ var init_file_utils = __esm({
|
|
|
2501
2601
|
};
|
|
2502
2602
|
};
|
|
2503
2603
|
encryptTitleWithFileKey = async (args) => {
|
|
2504
|
-
const key = await toAESKey(
|
|
2604
|
+
const key = await toAESKey(toUint8Array2(args.key));
|
|
2505
2605
|
if (!key) throw new Error("Key is undefined");
|
|
2506
2606
|
const titleBytes = new TextEncoder().encode(args.title);
|
|
2507
2607
|
const encryptedTitle = await aesEncrypt(key, titleBytes, "base64");
|
|
@@ -2619,7 +2719,7 @@ var init_file_utils = __esm({
|
|
|
2619
2719
|
});
|
|
2620
2720
|
|
|
2621
2721
|
// src/sdk/file-manager.ts
|
|
2622
|
-
import { fromUint8Array as fromUint8Array2, toUint8Array as
|
|
2722
|
+
import { fromUint8Array as fromUint8Array2, toUint8Array as toUint8Array3 } from "js-base64";
|
|
2623
2723
|
import { generateAESKey, exportAESKey } from "@fileverse/crypto/webcrypto";
|
|
2624
2724
|
import { markdownToYjs } from "@fileverse/content-processor";
|
|
2625
2725
|
var FileManager;
|
|
@@ -2640,8 +2740,8 @@ var init_file_manager = __esm({
|
|
|
2640
2740
|
}
|
|
2641
2741
|
createLocks(key, encryptedSecretKey, commentKey) {
|
|
2642
2742
|
const appLock = {
|
|
2643
|
-
lockedFileKey: this.keyStore.encryptData(
|
|
2644
|
-
lockedLinkKey: this.keyStore.encryptData(
|
|
2743
|
+
lockedFileKey: this.keyStore.encryptData(toUint8Array3(key)),
|
|
2744
|
+
lockedLinkKey: this.keyStore.encryptData(toUint8Array3(encryptedSecretKey)),
|
|
2645
2745
|
lockedChatKey: this.keyStore.encryptData(commentKey)
|
|
2646
2746
|
};
|
|
2647
2747
|
return { appLock, ownerLock: { ...appLock } };
|
|
@@ -2675,20 +2775,28 @@ var init_file_manager = __esm({
|
|
|
2675
2775
|
return this.agentClient.getAuthParams();
|
|
2676
2776
|
}
|
|
2677
2777
|
async submitAddFileTrx(file) {
|
|
2778
|
+
console.log("Submitting add file trx");
|
|
2678
2779
|
logger.debug(`Preparing to add file ${file.ddocId}`);
|
|
2679
2780
|
const encryptedSecretKey = file.linkKey;
|
|
2680
|
-
const nonce =
|
|
2681
|
-
const secretKey =
|
|
2781
|
+
const nonce = toUint8Array3(file.linkKeyNonce);
|
|
2782
|
+
const secretKey = toUint8Array3(file.secretKey);
|
|
2783
|
+
console.log("Got encrypted secret key, nonce, and secret key");
|
|
2682
2784
|
const yJSContent = markdownToYjs(file.content);
|
|
2785
|
+
console.log("Generated yjs content");
|
|
2683
2786
|
const { encryptedFile, key } = await createEncryptedContentFile(yJSContent);
|
|
2787
|
+
console.log("Generated encrypted content file");
|
|
2684
2788
|
logger.debug(`Generated encrypted content file for file ${file.ddocId}`);
|
|
2685
2789
|
const commentKey = await exportAESKey(await generateAESKey(128));
|
|
2790
|
+
console.log("Generated comment key");
|
|
2686
2791
|
const { appLock, ownerLock } = this.createLocks(key, encryptedSecretKey, commentKey);
|
|
2687
|
-
|
|
2792
|
+
console.log("Built app lock and owner lock");
|
|
2793
|
+
const linkLock = buildLinklock(secretKey, toUint8Array3(key), commentKey);
|
|
2794
|
+
console.log("Built link lock");
|
|
2688
2795
|
const encryptedTitle = await encryptTitleWithFileKey({
|
|
2689
2796
|
title: file.title || "Untitled",
|
|
2690
2797
|
key
|
|
2691
2798
|
});
|
|
2799
|
+
console.log("Built encrypted title");
|
|
2692
2800
|
const metadata = buildFileMetadata({
|
|
2693
2801
|
encryptedTitle,
|
|
2694
2802
|
encryptedFileSize: encryptedFile.size,
|
|
@@ -2698,11 +2806,15 @@ var init_file_manager = __esm({
|
|
|
2698
2806
|
nonce: fromUint8Array2(nonce),
|
|
2699
2807
|
owner: this.agentClient.getAgentAddress()
|
|
2700
2808
|
});
|
|
2809
|
+
console.log("Built metadata");
|
|
2701
2810
|
const authParams = await this.getAuthParams();
|
|
2811
|
+
console.log("Got auth params");
|
|
2812
|
+
console.log("Uploading files to IPFS");
|
|
2702
2813
|
const { metadataHash, contentHash, gateHash } = await uploadAllFilesToIPFS(
|
|
2703
2814
|
{ metadata, encryptedFile, linkLock, ddocId: file.ddocId },
|
|
2704
2815
|
authParams
|
|
2705
2816
|
);
|
|
2817
|
+
console.log("Uploaded files to IPFS");
|
|
2706
2818
|
logger.debug(`Uploaded files to IPFS for file ${file.ddocId}`);
|
|
2707
2819
|
const callData = prepareCallData({
|
|
2708
2820
|
metadataHash,
|
|
@@ -2711,8 +2823,10 @@ var init_file_manager = __esm({
|
|
|
2711
2823
|
appFileId: file.ddocId,
|
|
2712
2824
|
fileId: file.fileId
|
|
2713
2825
|
});
|
|
2826
|
+
console.log("Prepared call data");
|
|
2714
2827
|
logger.debug(`Prepared call data for file ${file.ddocId}`);
|
|
2715
2828
|
const userOpHash = await this.sendFileOperation(callData);
|
|
2829
|
+
console.log("Submitted user op");
|
|
2716
2830
|
logger.debug(`Submitted user op for file ${file.ddocId}`);
|
|
2717
2831
|
return {
|
|
2718
2832
|
userOpHash,
|
|
@@ -2725,13 +2839,13 @@ var init_file_manager = __esm({
|
|
|
2725
2839
|
async submitUpdateFile(file) {
|
|
2726
2840
|
logger.debug(`Submitting update for file ${file.ddocId} with onChainFileId ${file.onChainFileId}`);
|
|
2727
2841
|
const encryptedSecretKey = file.linkKey;
|
|
2728
|
-
const nonce =
|
|
2729
|
-
const secretKey =
|
|
2842
|
+
const nonce = toUint8Array3(file.linkKeyNonce);
|
|
2843
|
+
const secretKey = toUint8Array3(file.secretKey);
|
|
2730
2844
|
const yjsContent = markdownToYjs(file.content);
|
|
2731
2845
|
const { encryptedFile, key } = await createEncryptedContentFile(yjsContent);
|
|
2732
|
-
const commentKey =
|
|
2846
|
+
const commentKey = toUint8Array3(file.commentKey);
|
|
2733
2847
|
const { appLock, ownerLock } = this.createLocks(key, encryptedSecretKey, commentKey);
|
|
2734
|
-
const linkLock = buildLinklock(secretKey,
|
|
2848
|
+
const linkLock = buildLinklock(secretKey, toUint8Array3(key), commentKey);
|
|
2735
2849
|
const encryptedTitle = await encryptTitleWithFileKey({
|
|
2736
2850
|
title: file.title || "Untitled",
|
|
2737
2851
|
key
|
|
@@ -2773,14 +2887,14 @@ var init_file_manager = __esm({
|
|
|
2773
2887
|
async updateFile(file) {
|
|
2774
2888
|
logger.debug(`Updating file ${file.ddocId} with onChainFileId ${file.onChainFileId}`);
|
|
2775
2889
|
const encryptedSecretKey = file.linkKey;
|
|
2776
|
-
const nonce =
|
|
2777
|
-
const secretKey =
|
|
2890
|
+
const nonce = toUint8Array3(file.linkKeyNonce);
|
|
2891
|
+
const secretKey = toUint8Array3(file.secretKey);
|
|
2778
2892
|
logger.debug(`Generating encrypted content file for file ${file.ddocId} with onChainFileId ${file.onChainFileId}`);
|
|
2779
2893
|
const yjsContent = markdownToYjs(file.content);
|
|
2780
2894
|
const { encryptedFile, key } = await createEncryptedContentFile(yjsContent);
|
|
2781
|
-
const commentKey =
|
|
2895
|
+
const commentKey = toUint8Array3(file.commentKey);
|
|
2782
2896
|
const { appLock, ownerLock } = this.createLocks(key, encryptedSecretKey, commentKey);
|
|
2783
|
-
const linkLock = buildLinklock(secretKey,
|
|
2897
|
+
const linkLock = buildLinklock(secretKey, toUint8Array3(key), commentKey);
|
|
2784
2898
|
const encryptedTitle = await encryptTitleWithFileKey({
|
|
2785
2899
|
title: file.title || "Untitled",
|
|
2786
2900
|
key
|
|
@@ -2832,11 +2946,10 @@ var init_file_manager = __esm({
|
|
|
2832
2946
|
});
|
|
2833
2947
|
|
|
2834
2948
|
// src/domain/portal/publish.ts
|
|
2835
|
-
import { fromUint8Array as fromUint8Array3, toUint8Array as
|
|
2949
|
+
import { fromUint8Array as fromUint8Array3, toUint8Array as toUint8Array4 } from "js-base64";
|
|
2836
2950
|
import { stringToBytes } from "viem";
|
|
2837
2951
|
import { deriveHKDFKey } from "@fileverse/crypto/kdf";
|
|
2838
2952
|
import { generateKeyPairFromSeed } from "@stablelib/ed25519";
|
|
2839
|
-
import * as ucans2 from "@ucans/ucans";
|
|
2840
2953
|
async function getPortalData(fileId) {
|
|
2841
2954
|
const file = await FilesModel.findByIdIncludingDeleted(fileId);
|
|
2842
2955
|
if (!file) {
|
|
@@ -2868,16 +2981,15 @@ var init_publish = __esm({
|
|
|
2868
2981
|
init_infra();
|
|
2869
2982
|
init_key_store();
|
|
2870
2983
|
init_auth_token_provider();
|
|
2984
|
+
init_ucan();
|
|
2871
2985
|
init_smart_agent();
|
|
2872
2986
|
init_file_manager();
|
|
2873
2987
|
init_config();
|
|
2874
2988
|
init_pimlico_utils();
|
|
2875
2989
|
createFileManager = async (portalSeed, portalAddress, ucanSecret, privateAccountKey) => {
|
|
2876
|
-
const keyPair =
|
|
2877
|
-
exportable: true
|
|
2878
|
-
});
|
|
2990
|
+
const keyPair = EdKeypair.fromSecretKey(fromUint8Array3(ucanSecret));
|
|
2879
2991
|
const authTokenProvider = new AuthTokenProvider(keyPair, portalAddress);
|
|
2880
|
-
const keyStore = new KeyStore(
|
|
2992
|
+
const keyStore = new KeyStore(toUint8Array4(portalSeed), portalAddress, authTokenProvider);
|
|
2881
2993
|
const agentClient = new AgentClient(authTokenProvider);
|
|
2882
2994
|
await agentClient.initializeAgentClient(privateAccountKey);
|
|
2883
2995
|
return new FileManager(keyStore, agentClient);
|
|
@@ -2896,7 +3008,7 @@ var init_publish = __esm({
|
|
|
2896
3008
|
handleExistingFileOp = async (fileId, operation) => {
|
|
2897
3009
|
try {
|
|
2898
3010
|
const { file, portalDetails, apiKey } = await getPortalData(fileId);
|
|
2899
|
-
const apiKeySeed =
|
|
3011
|
+
const apiKeySeed = toUint8Array4(apiKey);
|
|
2900
3012
|
const { privateAccountKey, ucanSecret } = deriveCollaboratorKeys(apiKeySeed);
|
|
2901
3013
|
const fileManager = await createFileManager(
|
|
2902
3014
|
portalDetails.portalSeed,
|
|
@@ -2912,19 +3024,22 @@ var init_publish = __esm({
|
|
|
2912
3024
|
};
|
|
2913
3025
|
handleNewFileOp = async (fileId) => {
|
|
2914
3026
|
const { file, portalDetails, apiKey } = await getPortalData(fileId);
|
|
2915
|
-
|
|
3027
|
+
console.log("Got portal data");
|
|
3028
|
+
const apiKeySeed = toUint8Array4(apiKey);
|
|
2916
3029
|
const { privateAccountKey, ucanSecret } = deriveCollaboratorKeys(apiKeySeed);
|
|
3030
|
+
console.log("Derived collaborator keys");
|
|
2917
3031
|
const fileManager = await createFileManager(
|
|
2918
3032
|
portalDetails.portalSeed,
|
|
2919
3033
|
portalDetails.portalAddress,
|
|
2920
3034
|
ucanSecret,
|
|
2921
3035
|
privateAccountKey
|
|
2922
3036
|
);
|
|
3037
|
+
console.log("Created file manager");
|
|
2923
3038
|
return fileManager.submitAddFileTrx(file);
|
|
2924
3039
|
};
|
|
2925
3040
|
getProxyAuthParams = async (fileId) => {
|
|
2926
3041
|
const { portalDetails, apiKey } = await getPortalData(fileId);
|
|
2927
|
-
const apiKeySeed =
|
|
3042
|
+
const apiKeySeed = toUint8Array4(apiKey);
|
|
2928
3043
|
const { privateAccountKey, ucanSecret } = deriveCollaboratorKeys(apiKeySeed);
|
|
2929
3044
|
const fileManager = await createFileManager(
|
|
2930
3045
|
portalDetails.portalSeed,
|