@fileverse/api 0.0.9 → 0.0.11
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 +5 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/cloudflare.js +310 -32
- package/dist/cloudflare.js.map +1 -1
- package/dist/commands/index.js +96 -7
- package/dist/commands/index.js.map +1 -1
- package/dist/index.js +124 -29
- package/dist/index.js.map +1 -1
- package/dist/worker.js +99 -54
- package/dist/worker.js.map +1 -1
- package/package.json +1 -1
- package/public/llm.txt +204 -478
package/dist/index.js
CHANGED
|
@@ -669,7 +669,9 @@ var init_files_model = __esm({
|
|
|
669
669
|
linkKey: fileRaw.linkKey,
|
|
670
670
|
linkKeyNonce: fileRaw.linkKeyNonce,
|
|
671
671
|
commentKey: fileRaw.commentKey,
|
|
672
|
-
link: fileRaw.link
|
|
672
|
+
link: fileRaw.link,
|
|
673
|
+
derivedKey: fileRaw.derivedKey,
|
|
674
|
+
secretKey: fileRaw.secretKey
|
|
673
675
|
};
|
|
674
676
|
}
|
|
675
677
|
static async findAll(portalAddress, limit, skip) {
|
|
@@ -753,10 +755,20 @@ var init_files_model = __esm({
|
|
|
753
755
|
const _id = uuidv7();
|
|
754
756
|
const sql = `
|
|
755
757
|
INSERT INTO ${this.TABLE}
|
|
756
|
-
(_id, title, content, ddocId, portalAddress)
|
|
757
|
-
VALUES (?, ?, ?, ?, ?)
|
|
758
|
+
(_id, title, content, ddocId, portalAddress, linkKey, linkKeyNonce, derivedKey, secretKey)
|
|
759
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
758
760
|
`;
|
|
759
|
-
await QueryBuilder.execute(sql, [
|
|
761
|
+
await QueryBuilder.execute(sql, [
|
|
762
|
+
_id,
|
|
763
|
+
input.title,
|
|
764
|
+
input.content,
|
|
765
|
+
input.ddocId,
|
|
766
|
+
input.portalAddress,
|
|
767
|
+
input.linkKey ?? null,
|
|
768
|
+
input.linkKeyNonce ?? null,
|
|
769
|
+
input.derivedKey ?? null,
|
|
770
|
+
input.secretKey ?? null
|
|
771
|
+
]);
|
|
760
772
|
const created = await this.findById(_id, input.portalAddress);
|
|
761
773
|
if (!created) {
|
|
762
774
|
throw new Error("Failed to create file");
|
|
@@ -1136,6 +1148,29 @@ var init_events_model = __esm({
|
|
|
1136
1148
|
`;
|
|
1137
1149
|
await QueryBuilder.execute(sql, [Date.now(), _id]);
|
|
1138
1150
|
}
|
|
1151
|
+
static async markSubmitted(_id) {
|
|
1152
|
+
const sql = `
|
|
1153
|
+
UPDATE ${this.TABLE}
|
|
1154
|
+
SET status = 'submitted',
|
|
1155
|
+
lockedAt = NULL
|
|
1156
|
+
WHERE _id = ?
|
|
1157
|
+
`;
|
|
1158
|
+
await QueryBuilder.execute(sql, [_id]);
|
|
1159
|
+
}
|
|
1160
|
+
static async findNextSubmitted(lockedFileIds) {
|
|
1161
|
+
const exclusionClause = lockedFileIds.length > 0 ? `AND fileId NOT IN (${lockedFileIds.map(() => "?").join(", ")})` : "";
|
|
1162
|
+
const sql = `
|
|
1163
|
+
SELECT * FROM ${this.TABLE}
|
|
1164
|
+
WHERE status = 'submitted'
|
|
1165
|
+
AND userOpHash IS NOT NULL
|
|
1166
|
+
${exclusionClause}
|
|
1167
|
+
ORDER BY timestamp ASC
|
|
1168
|
+
LIMIT 1
|
|
1169
|
+
`;
|
|
1170
|
+
const params = [...lockedFileIds];
|
|
1171
|
+
const row = await QueryBuilder.selectOne(sql, params);
|
|
1172
|
+
return row ? this.parseEvent(row) : void 0;
|
|
1173
|
+
}
|
|
1139
1174
|
static async markProcessed(_id) {
|
|
1140
1175
|
const sql = `
|
|
1141
1176
|
UPDATE ${this.TABLE}
|
|
@@ -2550,7 +2585,7 @@ import { fromUint8Array, toUint8Array } from "js-base64";
|
|
|
2550
2585
|
import { toAESKey, aesEncrypt } from "@fileverse/crypto/webcrypto";
|
|
2551
2586
|
import axios from "axios";
|
|
2552
2587
|
import { encodeFunctionData, parseEventLogs } from "viem";
|
|
2553
|
-
var deriveKeyFromAg2Hash,
|
|
2588
|
+
var deriveKeyFromAg2Hash, getExistingEncryptionMaterial, getNaclSecretKey, generateLinkKeyMaterial, jsonToFile, appendAuthTagIvToBlob, encryptFile, getNonceAppendedCipherText, jsonToBytes, buildLinklock, encryptTitleWithFileKey, uploadFileToIPFS, getEditFileTrxCalldata, getAddFileTrxCalldata, prepareCallData, prepareDeleteFileCallData, createEncryptedContentFile, buildFileMetadata, parseFileEventLog, uploadAllFilesToIPFS;
|
|
2554
2589
|
var init_file_utils = __esm({
|
|
2555
2590
|
"src/sdk/file-utils.ts"() {
|
|
2556
2591
|
"use strict";
|
|
@@ -2563,16 +2598,18 @@ var init_file_utils = __esm({
|
|
|
2563
2598
|
info: Buffer.from("encryptionKey")
|
|
2564
2599
|
});
|
|
2565
2600
|
};
|
|
2566
|
-
decryptSecretKey = async (docId, nonce, encryptedSecretKey) => {
|
|
2567
|
-
const derivedKey = await deriveKeyFromAg2Hash(docId, toUint8Array(nonce));
|
|
2568
|
-
return tweetnacl.secretbox.open(toUint8Array(encryptedSecretKey), toUint8Array(nonce), derivedKey);
|
|
2569
|
-
};
|
|
2570
2601
|
getExistingEncryptionMaterial = async (existingEncryptedSecretKey, existingNonce, docId) => {
|
|
2571
|
-
const
|
|
2602
|
+
const derivedKey = await deriveKeyFromAg2Hash(docId, toUint8Array(existingNonce));
|
|
2603
|
+
const secretKey = tweetnacl.secretbox.open(
|
|
2604
|
+
toUint8Array(existingEncryptedSecretKey),
|
|
2605
|
+
toUint8Array(existingNonce),
|
|
2606
|
+
derivedKey
|
|
2607
|
+
);
|
|
2572
2608
|
return {
|
|
2573
2609
|
encryptedSecretKey: existingEncryptedSecretKey,
|
|
2574
2610
|
nonce: toUint8Array(existingNonce),
|
|
2575
|
-
secretKey
|
|
2611
|
+
secretKey,
|
|
2612
|
+
derivedKey: new Uint8Array(derivedKey)
|
|
2576
2613
|
};
|
|
2577
2614
|
};
|
|
2578
2615
|
getNaclSecretKey = async (ddocId) => {
|
|
@@ -2580,19 +2617,19 @@ var init_file_utils = __esm({
|
|
|
2580
2617
|
const nonce = tweetnacl.randomBytes(tweetnacl.secretbox.nonceLength);
|
|
2581
2618
|
const derivedKey = await deriveKeyFromAg2Hash(ddocId, nonce);
|
|
2582
2619
|
const encryptedSecretKey = fromUint8Array(tweetnacl.secretbox(secretKey, nonce, derivedKey), true);
|
|
2583
|
-
return { nonce, encryptedSecretKey, secretKey };
|
|
2620
|
+
return { nonce, encryptedSecretKey, secretKey, derivedKey: new Uint8Array(derivedKey) };
|
|
2584
2621
|
};
|
|
2585
2622
|
generateLinkKeyMaterial = async (params) => {
|
|
2586
2623
|
if (params.linkKeyNonce && params.linkKey) {
|
|
2587
|
-
const { encryptedSecretKey: encryptedSecretKey2, nonce: nonce2, secretKey: secretKey2 } = await getExistingEncryptionMaterial(
|
|
2624
|
+
const { encryptedSecretKey: encryptedSecretKey2, nonce: nonce2, secretKey: secretKey2, derivedKey: derivedKey2 } = await getExistingEncryptionMaterial(
|
|
2588
2625
|
params.linkKey,
|
|
2589
2626
|
params.linkKeyNonce,
|
|
2590
2627
|
params.ddocId
|
|
2591
2628
|
);
|
|
2592
|
-
if (secretKey2) return { encryptedSecretKey: encryptedSecretKey2, nonce: nonce2, secretKey: secretKey2 };
|
|
2629
|
+
if (secretKey2) return { encryptedSecretKey: encryptedSecretKey2, nonce: nonce2, secretKey: secretKey2, derivedKey: derivedKey2 };
|
|
2593
2630
|
}
|
|
2594
|
-
const { secretKey, nonce, encryptedSecretKey } = await getNaclSecretKey(params.ddocId);
|
|
2595
|
-
return { secretKey, nonce, encryptedSecretKey };
|
|
2631
|
+
const { secretKey, nonce, encryptedSecretKey, derivedKey } = await getNaclSecretKey(params.ddocId);
|
|
2632
|
+
return { secretKey, nonce, encryptedSecretKey, derivedKey };
|
|
2596
2633
|
};
|
|
2597
2634
|
jsonToFile = (json2, fileName) => {
|
|
2598
2635
|
const blob = new Blob([JSON.stringify(json2)], {
|
|
@@ -2845,11 +2882,9 @@ var init_file_manager = __esm({
|
|
|
2845
2882
|
}
|
|
2846
2883
|
async submitAddFileTrx(file2) {
|
|
2847
2884
|
logger.debug(`Preparing to add file ${file2.ddocId}`);
|
|
2848
|
-
const
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
linkKeyNonce: file2.linkKeyNonce
|
|
2852
|
-
});
|
|
2885
|
+
const encryptedSecretKey = file2.linkKey;
|
|
2886
|
+
const nonce = toUint8Array2(file2.linkKeyNonce);
|
|
2887
|
+
const secretKey = toUint8Array2(file2.secretKey);
|
|
2853
2888
|
const yJSContent = markdownToYjs(file2.content);
|
|
2854
2889
|
const { encryptedFile, key } = await createEncryptedContentFile(yJSContent);
|
|
2855
2890
|
logger.debug(`Generated encrypted content file for file ${file2.ddocId}`);
|
|
@@ -2893,13 +2928,59 @@ var init_file_manager = __esm({
|
|
|
2893
2928
|
metadata
|
|
2894
2929
|
};
|
|
2895
2930
|
}
|
|
2896
|
-
async
|
|
2897
|
-
logger.debug(`
|
|
2898
|
-
const
|
|
2931
|
+
async submitUpdateFile(file2) {
|
|
2932
|
+
logger.debug(`Submitting update for file ${file2.ddocId} with onChainFileId ${file2.onChainFileId}`);
|
|
2933
|
+
const encryptedSecretKey = file2.linkKey;
|
|
2934
|
+
const nonce = toUint8Array2(file2.linkKeyNonce);
|
|
2935
|
+
const secretKey = toUint8Array2(file2.secretKey);
|
|
2936
|
+
const yjsContent = markdownToYjs(file2.content);
|
|
2937
|
+
const { encryptedFile, key } = await createEncryptedContentFile(yjsContent);
|
|
2938
|
+
const commentKey = toUint8Array2(file2.commentKey);
|
|
2939
|
+
const { appLock, ownerLock } = this.createLocks(key, encryptedSecretKey, commentKey);
|
|
2940
|
+
const linkLock = buildLinklock(secretKey, toUint8Array2(key), commentKey);
|
|
2941
|
+
const encryptedTitle = await encryptTitleWithFileKey({
|
|
2942
|
+
title: file2.title || "Untitled",
|
|
2943
|
+
key
|
|
2944
|
+
});
|
|
2945
|
+
const metadata = buildFileMetadata({
|
|
2946
|
+
encryptedTitle,
|
|
2947
|
+
encryptedFileSize: encryptedFile.size,
|
|
2948
|
+
appLock,
|
|
2949
|
+
ownerLock,
|
|
2899
2950
|
ddocId: file2.ddocId,
|
|
2900
|
-
|
|
2901
|
-
|
|
2951
|
+
nonce: fromUint8Array2(nonce),
|
|
2952
|
+
owner: this.agentClient.getAgentAddress()
|
|
2902
2953
|
});
|
|
2954
|
+
const authParams = await this.getAuthParams();
|
|
2955
|
+
const { metadataHash, contentHash, gateHash } = await uploadAllFilesToIPFS(
|
|
2956
|
+
{ metadata, encryptedFile, linkLock, ddocId: file2.ddocId },
|
|
2957
|
+
authParams
|
|
2958
|
+
);
|
|
2959
|
+
const callData = prepareCallData({
|
|
2960
|
+
metadataHash,
|
|
2961
|
+
contentHash,
|
|
2962
|
+
gateHash,
|
|
2963
|
+
appFileId: file2.ddocId,
|
|
2964
|
+
fileId: file2.onChainFileId
|
|
2965
|
+
});
|
|
2966
|
+
const userOpHash = await this.sendFileOperation(callData);
|
|
2967
|
+
logger.debug(`Submitted update user op for file ${file2.ddocId}`);
|
|
2968
|
+
return { userOpHash, metadata };
|
|
2969
|
+
}
|
|
2970
|
+
async submitDeleteFile(file2) {
|
|
2971
|
+
logger.debug(`Submitting delete for file ${file2.ddocId} with onChainFileId ${file2.onChainFileId}`);
|
|
2972
|
+
const callData = prepareDeleteFileCallData({
|
|
2973
|
+
onChainFileId: file2.onChainFileId
|
|
2974
|
+
});
|
|
2975
|
+
const userOpHash = await this.sendFileOperation(callData);
|
|
2976
|
+
logger.debug(`Submitted delete user op for file ${file2.ddocId}`);
|
|
2977
|
+
return { userOpHash };
|
|
2978
|
+
}
|
|
2979
|
+
async updateFile(file2) {
|
|
2980
|
+
logger.debug(`Updating file ${file2.ddocId} with onChainFileId ${file2.onChainFileId}`);
|
|
2981
|
+
const encryptedSecretKey = file2.linkKey;
|
|
2982
|
+
const nonce = toUint8Array2(file2.linkKeyNonce);
|
|
2983
|
+
const secretKey = toUint8Array2(file2.secretKey);
|
|
2903
2984
|
logger.debug(`Generating encrypted content file for file ${file2.ddocId} with onChainFileId ${file2.onChainFileId}`);
|
|
2904
2985
|
const yjsContent = markdownToYjs(file2.content);
|
|
2905
2986
|
const { encryptedFile, key } = await createEncryptedContentFile(yjsContent);
|
|
@@ -2996,6 +3077,7 @@ var init_publish = __esm({
|
|
|
2996
3077
|
init_smart_agent();
|
|
2997
3078
|
init_file_manager();
|
|
2998
3079
|
init_config();
|
|
3080
|
+
init_pimlico_utils();
|
|
2999
3081
|
createFileManager = async (portalSeed, portalAddress, ucanSecret, privateAccountKey) => {
|
|
3000
3082
|
const keyPair = ucans2.EdKeypair.fromSecretKey(fromUint8Array3(ucanSecret), {
|
|
3001
3083
|
exportable: true
|
|
@@ -3570,7 +3652,9 @@ CREATE TABLE IF NOT EXISTS files (
|
|
|
3570
3652
|
commentKey TEXT,
|
|
3571
3653
|
linkKey TEXT,
|
|
3572
3654
|
linkKeyNonce TEXT,
|
|
3573
|
-
link TEXT
|
|
3655
|
+
link TEXT,
|
|
3656
|
+
derivedKey TEXT,
|
|
3657
|
+
secretKey TEXT
|
|
3574
3658
|
);
|
|
3575
3659
|
CREATE INDEX IF NOT EXISTS idx_files_createdAt ON files(createdAt);
|
|
3576
3660
|
CREATE INDEX IF NOT EXISTS idx_files_syncStatus ON files(syncStatus);
|
|
@@ -3601,7 +3685,7 @@ CREATE TABLE IF NOT EXISTS events (
|
|
|
3601
3685
|
type TEXT NOT NULL CHECK (type IN ('create', 'update', 'delete')),
|
|
3602
3686
|
timestamp BIGINT NOT NULL,
|
|
3603
3687
|
fileId TEXT NOT NULL,
|
|
3604
|
-
status TEXT NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'processing', 'processed', 'failed')),
|
|
3688
|
+
status TEXT NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'processing', 'submitted', 'processed', 'failed')),
|
|
3605
3689
|
retryCount INTEGER NOT NULL DEFAULT 0,
|
|
3606
3690
|
lastError TEXT,
|
|
3607
3691
|
lockedAt BIGINT,
|
|
@@ -3764,7 +3848,9 @@ init_esm_shims();
|
|
|
3764
3848
|
init_esm_shims();
|
|
3765
3849
|
init_models();
|
|
3766
3850
|
init_constants2();
|
|
3851
|
+
init_file_utils();
|
|
3767
3852
|
import { generate } from "short-uuid";
|
|
3853
|
+
import { fromUint8Array as fromUint8Array4 } from "js-base64";
|
|
3768
3854
|
async function listFiles(params) {
|
|
3769
3855
|
const { limit, skip, portalAddress } = params;
|
|
3770
3856
|
const effectiveLimit = limit || DEFAULT_LIST_LIMIT;
|
|
@@ -3817,11 +3903,20 @@ var createFile = async (input) => {
|
|
|
3817
3903
|
throw new Error("title, content, and portalAddress are required");
|
|
3818
3904
|
}
|
|
3819
3905
|
const ddocId = generate();
|
|
3906
|
+
const { encryptedSecretKey, nonce, secretKey, derivedKey } = await generateLinkKeyMaterial({
|
|
3907
|
+
ddocId,
|
|
3908
|
+
linkKey: void 0,
|
|
3909
|
+
linkKeyNonce: void 0
|
|
3910
|
+
});
|
|
3820
3911
|
const file2 = await FilesModel.create({
|
|
3821
3912
|
title: input.title,
|
|
3822
3913
|
content: input.content,
|
|
3823
3914
|
ddocId,
|
|
3824
|
-
portalAddress: input.portalAddress
|
|
3915
|
+
portalAddress: input.portalAddress,
|
|
3916
|
+
linkKey: encryptedSecretKey,
|
|
3917
|
+
linkKeyNonce: fromUint8Array4(nonce),
|
|
3918
|
+
derivedKey: fromUint8Array4(derivedKey),
|
|
3919
|
+
secretKey: fromUint8Array4(secretKey)
|
|
3825
3920
|
});
|
|
3826
3921
|
await EventsModel.create({ type: "create", fileId: file2._id, portalAddress: file2.portalAddress });
|
|
3827
3922
|
return file2;
|