@fileverse/api 0.0.20 → 0.0.22
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 +30 -34
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/index.js +16 -131
- package/dist/commands/index.js.map +1 -1
- package/dist/index.js +133 -374
- package/dist/index.js.map +1 -1
- package/dist/worker.js +106 -297
- package/dist/worker.js.map +1 -1
- package/package.json +6 -5
- package/public/llm.txt +478 -204
- package/dist/cloudflare.js +0 -18276
- package/dist/cloudflare.js.map +0 -1
package/dist/worker.js
CHANGED
|
@@ -111,12 +111,7 @@ var init_config = __esm({
|
|
|
111
111
|
init_constants();
|
|
112
112
|
projectEnvPath = path2.join(process.cwd(), "config", ".env");
|
|
113
113
|
userEnvPath = path2.join(os.homedir(), ".fileverse", ".env");
|
|
114
|
-
|
|
115
|
-
try {
|
|
116
|
-
loadConfig(false);
|
|
117
|
-
} catch {
|
|
118
|
-
}
|
|
119
|
-
}
|
|
114
|
+
loadConfig(false);
|
|
120
115
|
config = {
|
|
121
116
|
...STATIC_CONFIG,
|
|
122
117
|
get SERVICE_NAME() {
|
|
@@ -649,9 +644,7 @@ var init_files_model = __esm({
|
|
|
649
644
|
linkKey: fileRaw.linkKey,
|
|
650
645
|
linkKeyNonce: fileRaw.linkKeyNonce,
|
|
651
646
|
commentKey: fileRaw.commentKey,
|
|
652
|
-
link: fileRaw.link
|
|
653
|
-
derivedKey: fileRaw.derivedKey,
|
|
654
|
-
secretKey: fileRaw.secretKey
|
|
647
|
+
link: fileRaw.link
|
|
655
648
|
};
|
|
656
649
|
}
|
|
657
650
|
static async findAll(portalAddress, limit, skip) {
|
|
@@ -735,20 +728,10 @@ var init_files_model = __esm({
|
|
|
735
728
|
const _id = uuidv7();
|
|
736
729
|
const sql = `
|
|
737
730
|
INSERT INTO ${this.TABLE}
|
|
738
|
-
(_id, title, content, ddocId, portalAddress
|
|
739
|
-
VALUES (?, ?, ?, ?,
|
|
731
|
+
(_id, title, content, ddocId, portalAddress)
|
|
732
|
+
VALUES (?, ?, ?, ?, ?)
|
|
740
733
|
`;
|
|
741
|
-
await QueryBuilder.execute(sql, [
|
|
742
|
-
_id,
|
|
743
|
-
input.title,
|
|
744
|
-
input.content,
|
|
745
|
-
input.ddocId,
|
|
746
|
-
input.portalAddress,
|
|
747
|
-
input.linkKey ?? null,
|
|
748
|
-
input.linkKeyNonce ?? null,
|
|
749
|
-
input.derivedKey ?? null,
|
|
750
|
-
input.secretKey ?? null
|
|
751
|
-
]);
|
|
734
|
+
await QueryBuilder.execute(sql, [_id, input.title, input.content, input.ddocId, input.portalAddress]);
|
|
752
735
|
const created = await this.findById(_id, input.portalAddress);
|
|
753
736
|
if (!created) {
|
|
754
737
|
throw new Error("Failed to create file");
|
|
@@ -981,29 +964,6 @@ var init_events_model = __esm({
|
|
|
981
964
|
`;
|
|
982
965
|
await QueryBuilder.execute(sql, [Date.now(), _id]);
|
|
983
966
|
}
|
|
984
|
-
static async markSubmitted(_id) {
|
|
985
|
-
const sql = `
|
|
986
|
-
UPDATE ${this.TABLE}
|
|
987
|
-
SET status = 'submitted',
|
|
988
|
-
lockedAt = NULL
|
|
989
|
-
WHERE _id = ?
|
|
990
|
-
`;
|
|
991
|
-
await QueryBuilder.execute(sql, [_id]);
|
|
992
|
-
}
|
|
993
|
-
static async findNextSubmitted(lockedFileIds) {
|
|
994
|
-
const exclusionClause = lockedFileIds.length > 0 ? `AND fileId NOT IN (${lockedFileIds.map(() => "?").join(", ")})` : "";
|
|
995
|
-
const sql = `
|
|
996
|
-
SELECT * FROM ${this.TABLE}
|
|
997
|
-
WHERE status = 'submitted'
|
|
998
|
-
AND userOpHash IS NOT NULL
|
|
999
|
-
${exclusionClause}
|
|
1000
|
-
ORDER BY timestamp ASC
|
|
1001
|
-
LIMIT 1
|
|
1002
|
-
`;
|
|
1003
|
-
const params = [...lockedFileIds];
|
|
1004
|
-
const row = await QueryBuilder.selectOne(sql, params);
|
|
1005
|
-
return row ? this.parseEvent(row) : void 0;
|
|
1006
|
-
}
|
|
1007
967
|
static async markProcessed(_id) {
|
|
1008
968
|
const sql = `
|
|
1009
969
|
UPDATE ${this.TABLE}
|
|
@@ -1206,114 +1166,13 @@ var init_key_store = __esm({
|
|
|
1206
1166
|
}
|
|
1207
1167
|
});
|
|
1208
1168
|
|
|
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
|
-
|
|
1310
1169
|
// src/sdk/auth-token-provider.ts
|
|
1170
|
+
import * as ucans from "@ucans/ucans";
|
|
1311
1171
|
var AuthTokenProvider;
|
|
1312
1172
|
var init_auth_token_provider = __esm({
|
|
1313
1173
|
"src/sdk/auth-token-provider.ts"() {
|
|
1314
1174
|
"use strict";
|
|
1315
1175
|
init_esm_shims();
|
|
1316
|
-
init_ucan();
|
|
1317
1176
|
AuthTokenProvider = class {
|
|
1318
1177
|
DEFAULT_OPTIONS = {
|
|
1319
1178
|
namespace: "file",
|
|
@@ -1327,7 +1186,7 @@ var init_auth_token_provider = __esm({
|
|
|
1327
1186
|
this.portalAddress = portalAddress;
|
|
1328
1187
|
}
|
|
1329
1188
|
async getAuthToken(audienceDid, options = this.DEFAULT_OPTIONS) {
|
|
1330
|
-
|
|
1189
|
+
const ucan = await ucans.build({
|
|
1331
1190
|
audience: audienceDid,
|
|
1332
1191
|
issuer: this.keyPair,
|
|
1333
1192
|
lifetimeInSeconds: 7 * 86400,
|
|
@@ -1341,6 +1200,7 @@ var init_auth_token_provider = __esm({
|
|
|
1341
1200
|
}
|
|
1342
1201
|
]
|
|
1343
1202
|
});
|
|
1203
|
+
return ucans.encode(ucan);
|
|
1344
1204
|
}
|
|
1345
1205
|
};
|
|
1346
1206
|
}
|
|
@@ -1672,29 +1532,19 @@ var init_pimlico_utils = __esm({
|
|
|
1672
1532
|
version: "0.7"
|
|
1673
1533
|
}
|
|
1674
1534
|
});
|
|
1675
|
-
signerToSmartAccount = async (signer) => {
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
version: "0.7"
|
|
1685
|
-
},
|
|
1686
|
-
version: "1.4.1"
|
|
1687
|
-
});
|
|
1688
|
-
console.log("[pimlico] safe smart account created");
|
|
1689
|
-
return account;
|
|
1690
|
-
};
|
|
1535
|
+
signerToSmartAccount = async (signer) => await toSafeSmartAccount({
|
|
1536
|
+
client: getPublicClient(),
|
|
1537
|
+
owners: [signer],
|
|
1538
|
+
entryPoint: {
|
|
1539
|
+
address: entryPoint07Address,
|
|
1540
|
+
version: "0.7"
|
|
1541
|
+
},
|
|
1542
|
+
version: "1.4.1"
|
|
1543
|
+
});
|
|
1691
1544
|
getSmartAccountClient = async (signer, authToken, portalAddress) => {
|
|
1692
|
-
console.log("[pimlico] signerToSmartAccount start");
|
|
1693
1545
|
const smartAccount = await signerToSmartAccount(signer);
|
|
1694
|
-
console.log("[pimlico] creating pimlico client");
|
|
1695
1546
|
const pimlicoClient = getPimlicoClient(authToken, portalAddress, smartAccount.address);
|
|
1696
|
-
|
|
1697
|
-
const result = createSmartAccountClient({
|
|
1547
|
+
return createSmartAccountClient({
|
|
1698
1548
|
account: smartAccount,
|
|
1699
1549
|
chain: CHAIN,
|
|
1700
1550
|
paymaster: pimlicoClient,
|
|
@@ -1712,8 +1562,6 @@ var init_pimlico_utils = __esm({
|
|
|
1712
1562
|
estimateFeesPerGas: async () => (await pimlicoClient.getUserOperationGasPrice()).fast
|
|
1713
1563
|
}
|
|
1714
1564
|
});
|
|
1715
|
-
console.log("[pimlico] smart account client created");
|
|
1716
|
-
return result;
|
|
1717
1565
|
};
|
|
1718
1566
|
getNonce = () => hexToBigInt(
|
|
1719
1567
|
toHex(toBytes(generatePrivateKey()).slice(0, 24), {
|
|
@@ -1749,17 +1597,13 @@ var init_smart_agent = __esm({
|
|
|
1749
1597
|
MAX_CALL_GAS_LIMIT = 5e5;
|
|
1750
1598
|
authOptions = { namespace: "proxy", segment: "ACCESS", scheme: "pimlico" };
|
|
1751
1599
|
async initializeAgentClient(keyMaterial) {
|
|
1752
|
-
console.log("[agent] creating account from key");
|
|
1753
1600
|
const agentAccount = privateKeyToAccount(toHex2(keyMaterial));
|
|
1754
|
-
console.log("[agent] getting auth token");
|
|
1755
1601
|
const authToken = await this.authTokenProvider.getAuthToken(STATIC_CONFIG.PROXY_SERVER_DID, this.authOptions);
|
|
1756
|
-
console.log("[agent] getting smart account client");
|
|
1757
1602
|
const smartAccountClient = await getSmartAccountClient(
|
|
1758
1603
|
agentAccount,
|
|
1759
1604
|
authToken,
|
|
1760
1605
|
this.authTokenProvider.portalAddress
|
|
1761
1606
|
);
|
|
1762
|
-
console.log("[agent] smart account client ready");
|
|
1763
1607
|
this.smartAccountAgent = smartAccountClient;
|
|
1764
1608
|
}
|
|
1765
1609
|
getSmartAccountAgent() {
|
|
@@ -1799,19 +1643,17 @@ var init_smart_agent = __esm({
|
|
|
1799
1643
|
]);
|
|
1800
1644
|
}
|
|
1801
1645
|
async sendUserOperation(request, customGasLimit) {
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
}
|
|
1813
|
-
console.log("[agent] user operation sent");
|
|
1814
|
-
return hash;
|
|
1646
|
+
try {
|
|
1647
|
+
const smartAccountAgent = this.getSmartAccountAgent();
|
|
1648
|
+
const callData = await this.getCallData(request);
|
|
1649
|
+
return await smartAccountAgent.sendUserOperation({
|
|
1650
|
+
callData,
|
|
1651
|
+
callGasLimit: BigInt(customGasLimit || this.MAX_CALL_GAS_LIMIT),
|
|
1652
|
+
nonce: getNonce()
|
|
1653
|
+
});
|
|
1654
|
+
} catch (error) {
|
|
1655
|
+
throw error;
|
|
1656
|
+
}
|
|
1815
1657
|
}
|
|
1816
1658
|
async executeUserOperationRequest(request, timeout, customGasLimit) {
|
|
1817
1659
|
const userOpHash = await this.sendUserOperation(request, customGasLimit);
|
|
@@ -2526,20 +2368,60 @@ var init_file_encryption = __esm({
|
|
|
2526
2368
|
});
|
|
2527
2369
|
|
|
2528
2370
|
// src/sdk/file-utils.ts
|
|
2371
|
+
import { getArgon2idHash } from "@fileverse/crypto/argon";
|
|
2529
2372
|
import { bytesToBase64, generateRandomBytes as generateRandomBytes2 } from "@fileverse/crypto/utils";
|
|
2530
2373
|
import { derivePBKDF2Key, encryptAesCBC } from "@fileverse/crypto/kdf";
|
|
2531
2374
|
import { secretBoxEncrypt } from "@fileverse/crypto/nacl";
|
|
2375
|
+
import hkdf from "futoin-hkdf";
|
|
2532
2376
|
import tweetnacl from "tweetnacl";
|
|
2533
|
-
import { fromUint8Array, toUint8Array
|
|
2377
|
+
import { fromUint8Array, toUint8Array } from "js-base64";
|
|
2534
2378
|
import { toAESKey, aesEncrypt } from "@fileverse/crypto/webcrypto";
|
|
2379
|
+
import axios from "axios";
|
|
2535
2380
|
import { encodeFunctionData, parseEventLogs } from "viem";
|
|
2536
|
-
var jsonToFile, appendAuthTagIvToBlob, encryptFile, getNonceAppendedCipherText, jsonToBytes, buildLinklock, encryptTitleWithFileKey, uploadFileToIPFS, getEditFileTrxCalldata, getAddFileTrxCalldata, prepareCallData, prepareDeleteFileCallData, createEncryptedContentFile, buildFileMetadata, parseFileEventLog, uploadAllFilesToIPFS;
|
|
2381
|
+
var deriveKeyFromAg2Hash, decryptSecretKey, getExistingEncryptionMaterial, getNaclSecretKey, generateLinkKeyMaterial, jsonToFile, appendAuthTagIvToBlob, encryptFile, getNonceAppendedCipherText, jsonToBytes, buildLinklock, encryptTitleWithFileKey, uploadFileToIPFS, getEditFileTrxCalldata, getAddFileTrxCalldata, prepareCallData, prepareDeleteFileCallData, createEncryptedContentFile, buildFileMetadata, parseFileEventLog, uploadAllFilesToIPFS;
|
|
2537
2382
|
var init_file_utils = __esm({
|
|
2538
2383
|
"src/sdk/file-utils.ts"() {
|
|
2539
2384
|
"use strict";
|
|
2540
2385
|
init_esm_shims();
|
|
2541
2386
|
init_file_encryption();
|
|
2542
2387
|
init_constants3();
|
|
2388
|
+
deriveKeyFromAg2Hash = async (pass, salt) => {
|
|
2389
|
+
const key = await getArgon2idHash(pass, salt);
|
|
2390
|
+
return hkdf(Buffer.from(key), tweetnacl.secretbox.keyLength, {
|
|
2391
|
+
info: Buffer.from("encryptionKey")
|
|
2392
|
+
});
|
|
2393
|
+
};
|
|
2394
|
+
decryptSecretKey = async (docId, nonce, encryptedSecretKey) => {
|
|
2395
|
+
const derivedKey = await deriveKeyFromAg2Hash(docId, toUint8Array(nonce));
|
|
2396
|
+
return tweetnacl.secretbox.open(toUint8Array(encryptedSecretKey), toUint8Array(nonce), derivedKey);
|
|
2397
|
+
};
|
|
2398
|
+
getExistingEncryptionMaterial = async (existingEncryptedSecretKey, existingNonce, docId) => {
|
|
2399
|
+
const secretKey = await decryptSecretKey(docId, existingNonce, existingEncryptedSecretKey);
|
|
2400
|
+
return {
|
|
2401
|
+
encryptedSecretKey: existingEncryptedSecretKey,
|
|
2402
|
+
nonce: toUint8Array(existingNonce),
|
|
2403
|
+
secretKey
|
|
2404
|
+
};
|
|
2405
|
+
};
|
|
2406
|
+
getNaclSecretKey = async (ddocId) => {
|
|
2407
|
+
const { secretKey } = tweetnacl.box.keyPair();
|
|
2408
|
+
const nonce = tweetnacl.randomBytes(tweetnacl.secretbox.nonceLength);
|
|
2409
|
+
const derivedKey = await deriveKeyFromAg2Hash(ddocId, nonce);
|
|
2410
|
+
const encryptedSecretKey = fromUint8Array(tweetnacl.secretbox(secretKey, nonce, derivedKey), true);
|
|
2411
|
+
return { nonce, encryptedSecretKey, secretKey };
|
|
2412
|
+
};
|
|
2413
|
+
generateLinkKeyMaterial = async (params) => {
|
|
2414
|
+
if (params.linkKeyNonce && params.linkKey) {
|
|
2415
|
+
const { encryptedSecretKey: encryptedSecretKey2, nonce: nonce2, secretKey: secretKey2 } = await getExistingEncryptionMaterial(
|
|
2416
|
+
params.linkKey,
|
|
2417
|
+
params.linkKeyNonce,
|
|
2418
|
+
params.ddocId
|
|
2419
|
+
);
|
|
2420
|
+
if (secretKey2) return { encryptedSecretKey: encryptedSecretKey2, nonce: nonce2, secretKey: secretKey2 };
|
|
2421
|
+
}
|
|
2422
|
+
const { secretKey, nonce, encryptedSecretKey } = await getNaclSecretKey(params.ddocId);
|
|
2423
|
+
return { secretKey, nonce, encryptedSecretKey };
|
|
2424
|
+
};
|
|
2543
2425
|
jsonToFile = (json, fileName) => {
|
|
2544
2426
|
const blob = new Blob([JSON.stringify(json)], {
|
|
2545
2427
|
type: "application/json"
|
|
@@ -2569,8 +2451,8 @@ var init_file_utils = __esm({
|
|
|
2569
2451
|
const encryptedBlob = new Blob([ciphertext], { type: file.type });
|
|
2570
2452
|
const encryptedBlobWithAuthTagIv = await appendAuthTagIvToBlob(
|
|
2571
2453
|
encryptedBlob,
|
|
2572
|
-
|
|
2573
|
-
|
|
2454
|
+
toUint8Array(authTag),
|
|
2455
|
+
toUint8Array(iv)
|
|
2574
2456
|
);
|
|
2575
2457
|
return {
|
|
2576
2458
|
encryptedFile: new File([encryptedBlobWithAuthTagIv], file.name),
|
|
@@ -2616,7 +2498,7 @@ var init_file_utils = __esm({
|
|
|
2616
2498
|
};
|
|
2617
2499
|
};
|
|
2618
2500
|
encryptTitleWithFileKey = async (args) => {
|
|
2619
|
-
const key = await toAESKey(
|
|
2501
|
+
const key = await toAESKey(toUint8Array(args.key));
|
|
2620
2502
|
if (!key) throw new Error("Key is undefined");
|
|
2621
2503
|
const titleBytes = new TextEncoder().encode(args.title);
|
|
2622
2504
|
const encryptedTitle = await aesEncrypt(key, titleBytes, "base64");
|
|
@@ -2630,21 +2512,16 @@ var init_file_utils = __esm({
|
|
|
2630
2512
|
body.append("ipfsType", ipfsType);
|
|
2631
2513
|
body.append("appFileId", appFileId);
|
|
2632
2514
|
body.append("sourceApp", "ddoc");
|
|
2633
|
-
const
|
|
2634
|
-
|
|
2515
|
+
const uploadEndpoint = UPLOAD_SERVER_URL + "upload";
|
|
2516
|
+
const response = await axios.post(uploadEndpoint, body, {
|
|
2635
2517
|
headers: {
|
|
2636
2518
|
Authorization: `Bearer ${token}`,
|
|
2637
2519
|
contract: contractAddress,
|
|
2638
2520
|
invoker,
|
|
2639
|
-
chain:
|
|
2640
|
-
}
|
|
2641
|
-
body
|
|
2521
|
+
chain: process.env.chainId
|
|
2522
|
+
}
|
|
2642
2523
|
});
|
|
2643
|
-
|
|
2644
|
-
throw new Error(`Upload failed: ${response.status} ${response.statusText}`);
|
|
2645
|
-
}
|
|
2646
|
-
const data = await response.json();
|
|
2647
|
-
return data.ipfsHash;
|
|
2524
|
+
return response.data.ipfsHash;
|
|
2648
2525
|
};
|
|
2649
2526
|
getEditFileTrxCalldata = (args) => {
|
|
2650
2527
|
return encodeFunctionData({
|
|
@@ -2739,7 +2616,7 @@ var init_file_utils = __esm({
|
|
|
2739
2616
|
});
|
|
2740
2617
|
|
|
2741
2618
|
// src/sdk/file-manager.ts
|
|
2742
|
-
import { fromUint8Array as fromUint8Array2, toUint8Array as
|
|
2619
|
+
import { fromUint8Array as fromUint8Array2, toUint8Array as toUint8Array2 } from "js-base64";
|
|
2743
2620
|
import { generateAESKey, exportAESKey } from "@fileverse/crypto/webcrypto";
|
|
2744
2621
|
import { markdownToYjs } from "@fileverse/content-processor";
|
|
2745
2622
|
var FileManager;
|
|
@@ -2760,8 +2637,8 @@ var init_file_manager = __esm({
|
|
|
2760
2637
|
}
|
|
2761
2638
|
createLocks(key, encryptedSecretKey, commentKey) {
|
|
2762
2639
|
const appLock = {
|
|
2763
|
-
lockedFileKey: this.keyStore.encryptData(
|
|
2764
|
-
lockedLinkKey: this.keyStore.encryptData(
|
|
2640
|
+
lockedFileKey: this.keyStore.encryptData(toUint8Array2(key)),
|
|
2641
|
+
lockedLinkKey: this.keyStore.encryptData(toUint8Array2(encryptedSecretKey)),
|
|
2765
2642
|
lockedChatKey: this.keyStore.encryptData(commentKey)
|
|
2766
2643
|
};
|
|
2767
2644
|
return { appLock, ownerLock: { ...appLock } };
|
|
@@ -2795,28 +2672,22 @@ var init_file_manager = __esm({
|
|
|
2795
2672
|
return this.agentClient.getAuthParams();
|
|
2796
2673
|
}
|
|
2797
2674
|
async submitAddFileTrx(file) {
|
|
2798
|
-
console.log("Submitting add file trx");
|
|
2799
2675
|
logger.debug(`Preparing to add file ${file.ddocId}`);
|
|
2800
|
-
const encryptedSecretKey =
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2676
|
+
const { encryptedSecretKey, nonce, secretKey } = await generateLinkKeyMaterial({
|
|
2677
|
+
ddocId: file.ddocId,
|
|
2678
|
+
linkKey: file.linkKey,
|
|
2679
|
+
linkKeyNonce: file.linkKeyNonce
|
|
2680
|
+
});
|
|
2804
2681
|
const yJSContent = markdownToYjs(file.content);
|
|
2805
|
-
console.log("Generated yjs content");
|
|
2806
2682
|
const { encryptedFile, key } = await createEncryptedContentFile(yJSContent);
|
|
2807
|
-
console.log("Generated encrypted content file");
|
|
2808
2683
|
logger.debug(`Generated encrypted content file for file ${file.ddocId}`);
|
|
2809
2684
|
const commentKey = await exportAESKey(await generateAESKey(128));
|
|
2810
|
-
console.log("Generated comment key");
|
|
2811
2685
|
const { appLock, ownerLock } = this.createLocks(key, encryptedSecretKey, commentKey);
|
|
2812
|
-
|
|
2813
|
-
const linkLock = buildLinklock(secretKey, toUint8Array3(key), commentKey);
|
|
2814
|
-
console.log("Built link lock");
|
|
2686
|
+
const linkLock = buildLinklock(secretKey, toUint8Array2(key), commentKey);
|
|
2815
2687
|
const encryptedTitle = await encryptTitleWithFileKey({
|
|
2816
2688
|
title: file.title || "Untitled",
|
|
2817
2689
|
key
|
|
2818
2690
|
});
|
|
2819
|
-
console.log("Built encrypted title");
|
|
2820
2691
|
const metadata = buildFileMetadata({
|
|
2821
2692
|
encryptedTitle,
|
|
2822
2693
|
encryptedFileSize: encryptedFile.size,
|
|
@@ -2826,15 +2697,11 @@ var init_file_manager = __esm({
|
|
|
2826
2697
|
nonce: fromUint8Array2(nonce),
|
|
2827
2698
|
owner: this.agentClient.getAgentAddress()
|
|
2828
2699
|
});
|
|
2829
|
-
console.log("Built metadata");
|
|
2830
2700
|
const authParams = await this.getAuthParams();
|
|
2831
|
-
console.log("Got auth params");
|
|
2832
|
-
console.log("Uploading files to IPFS");
|
|
2833
2701
|
const { metadataHash, contentHash, gateHash } = await uploadAllFilesToIPFS(
|
|
2834
2702
|
{ metadata, encryptedFile, linkLock, ddocId: file.ddocId },
|
|
2835
2703
|
authParams
|
|
2836
2704
|
);
|
|
2837
|
-
console.log("Uploaded files to IPFS");
|
|
2838
2705
|
logger.debug(`Uploaded files to IPFS for file ${file.ddocId}`);
|
|
2839
2706
|
const callData = prepareCallData({
|
|
2840
2707
|
metadataHash,
|
|
@@ -2843,10 +2710,8 @@ var init_file_manager = __esm({
|
|
|
2843
2710
|
appFileId: file.ddocId,
|
|
2844
2711
|
fileId: file.fileId
|
|
2845
2712
|
});
|
|
2846
|
-
console.log("Prepared call data");
|
|
2847
2713
|
logger.debug(`Prepared call data for file ${file.ddocId}`);
|
|
2848
2714
|
const userOpHash = await this.sendFileOperation(callData);
|
|
2849
|
-
console.log("Submitted user op");
|
|
2850
2715
|
logger.debug(`Submitted user op for file ${file.ddocId}`);
|
|
2851
2716
|
return {
|
|
2852
2717
|
userOpHash,
|
|
@@ -2856,65 +2721,19 @@ var init_file_manager = __esm({
|
|
|
2856
2721
|
metadata
|
|
2857
2722
|
};
|
|
2858
2723
|
}
|
|
2859
|
-
async submitUpdateFile(file) {
|
|
2860
|
-
logger.debug(`Submitting update for file ${file.ddocId} with onChainFileId ${file.onChainFileId}`);
|
|
2861
|
-
const encryptedSecretKey = file.linkKey;
|
|
2862
|
-
const nonce = toUint8Array3(file.linkKeyNonce);
|
|
2863
|
-
const secretKey = toUint8Array3(file.secretKey);
|
|
2864
|
-
const yjsContent = markdownToYjs(file.content);
|
|
2865
|
-
const { encryptedFile, key } = await createEncryptedContentFile(yjsContent);
|
|
2866
|
-
const commentKey = toUint8Array3(file.commentKey);
|
|
2867
|
-
const { appLock, ownerLock } = this.createLocks(key, encryptedSecretKey, commentKey);
|
|
2868
|
-
const linkLock = buildLinklock(secretKey, toUint8Array3(key), commentKey);
|
|
2869
|
-
const encryptedTitle = await encryptTitleWithFileKey({
|
|
2870
|
-
title: file.title || "Untitled",
|
|
2871
|
-
key
|
|
2872
|
-
});
|
|
2873
|
-
const metadata = buildFileMetadata({
|
|
2874
|
-
encryptedTitle,
|
|
2875
|
-
encryptedFileSize: encryptedFile.size,
|
|
2876
|
-
appLock,
|
|
2877
|
-
ownerLock,
|
|
2878
|
-
ddocId: file.ddocId,
|
|
2879
|
-
nonce: fromUint8Array2(nonce),
|
|
2880
|
-
owner: this.agentClient.getAgentAddress()
|
|
2881
|
-
});
|
|
2882
|
-
const authParams = await this.getAuthParams();
|
|
2883
|
-
const { metadataHash, contentHash, gateHash } = await uploadAllFilesToIPFS(
|
|
2884
|
-
{ metadata, encryptedFile, linkLock, ddocId: file.ddocId },
|
|
2885
|
-
authParams
|
|
2886
|
-
);
|
|
2887
|
-
const callData = prepareCallData({
|
|
2888
|
-
metadataHash,
|
|
2889
|
-
contentHash,
|
|
2890
|
-
gateHash,
|
|
2891
|
-
appFileId: file.ddocId,
|
|
2892
|
-
fileId: file.onChainFileId
|
|
2893
|
-
});
|
|
2894
|
-
const userOpHash = await this.sendFileOperation(callData);
|
|
2895
|
-
logger.debug(`Submitted update user op for file ${file.ddocId}`);
|
|
2896
|
-
return { userOpHash, metadata };
|
|
2897
|
-
}
|
|
2898
|
-
async submitDeleteFile(file) {
|
|
2899
|
-
logger.debug(`Submitting delete for file ${file.ddocId} with onChainFileId ${file.onChainFileId}`);
|
|
2900
|
-
const callData = prepareDeleteFileCallData({
|
|
2901
|
-
onChainFileId: file.onChainFileId
|
|
2902
|
-
});
|
|
2903
|
-
const userOpHash = await this.sendFileOperation(callData);
|
|
2904
|
-
logger.debug(`Submitted delete user op for file ${file.ddocId}`);
|
|
2905
|
-
return { userOpHash };
|
|
2906
|
-
}
|
|
2907
2724
|
async updateFile(file) {
|
|
2908
2725
|
logger.debug(`Updating file ${file.ddocId} with onChainFileId ${file.onChainFileId}`);
|
|
2909
|
-
const encryptedSecretKey =
|
|
2910
|
-
|
|
2911
|
-
|
|
2726
|
+
const { encryptedSecretKey, nonce, secretKey } = await generateLinkKeyMaterial({
|
|
2727
|
+
ddocId: file.ddocId,
|
|
2728
|
+
linkKey: file.linkKey,
|
|
2729
|
+
linkKeyNonce: file.linkKeyNonce
|
|
2730
|
+
});
|
|
2912
2731
|
logger.debug(`Generating encrypted content file for file ${file.ddocId} with onChainFileId ${file.onChainFileId}`);
|
|
2913
2732
|
const yjsContent = markdownToYjs(file.content);
|
|
2914
2733
|
const { encryptedFile, key } = await createEncryptedContentFile(yjsContent);
|
|
2915
|
-
const commentKey =
|
|
2734
|
+
const commentKey = toUint8Array2(file.commentKey);
|
|
2916
2735
|
const { appLock, ownerLock } = this.createLocks(key, encryptedSecretKey, commentKey);
|
|
2917
|
-
const linkLock = buildLinklock(secretKey,
|
|
2736
|
+
const linkLock = buildLinklock(secretKey, toUint8Array2(key), commentKey);
|
|
2918
2737
|
const encryptedTitle = await encryptTitleWithFileKey({
|
|
2919
2738
|
title: file.title || "Untitled",
|
|
2920
2739
|
key
|
|
@@ -2966,10 +2785,11 @@ var init_file_manager = __esm({
|
|
|
2966
2785
|
});
|
|
2967
2786
|
|
|
2968
2787
|
// src/domain/portal/publish.ts
|
|
2969
|
-
import { fromUint8Array as fromUint8Array3, toUint8Array as
|
|
2788
|
+
import { fromUint8Array as fromUint8Array3, toUint8Array as toUint8Array3 } from "js-base64";
|
|
2970
2789
|
import { stringToBytes } from "viem";
|
|
2971
2790
|
import { deriveHKDFKey } from "@fileverse/crypto/kdf";
|
|
2972
2791
|
import { generateKeyPairFromSeed } from "@stablelib/ed25519";
|
|
2792
|
+
import * as ucans2 from "@ucans/ucans";
|
|
2973
2793
|
async function getPortalData(fileId) {
|
|
2974
2794
|
const file = await FilesModel.findByIdIncludingDeleted(fileId);
|
|
2975
2795
|
if (!file) {
|
|
@@ -3001,23 +2821,17 @@ var init_publish = __esm({
|
|
|
3001
2821
|
init_infra();
|
|
3002
2822
|
init_key_store();
|
|
3003
2823
|
init_auth_token_provider();
|
|
3004
|
-
init_ucan();
|
|
3005
2824
|
init_smart_agent();
|
|
3006
2825
|
init_file_manager();
|
|
3007
2826
|
init_config();
|
|
3008
|
-
init_pimlico_utils();
|
|
3009
2827
|
createFileManager = async (portalSeed, portalAddress, ucanSecret, privateAccountKey) => {
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
2828
|
+
const keyPair = ucans2.EdKeypair.fromSecretKey(fromUint8Array3(ucanSecret), {
|
|
2829
|
+
exportable: true
|
|
2830
|
+
});
|
|
3013
2831
|
const authTokenProvider = new AuthTokenProvider(keyPair, portalAddress);
|
|
3014
|
-
|
|
3015
|
-
const keyStore = new KeyStore(toUint8Array4(portalSeed), portalAddress, authTokenProvider);
|
|
3016
|
-
console.log("Created key store");
|
|
2832
|
+
const keyStore = new KeyStore(toUint8Array3(portalSeed), portalAddress, authTokenProvider);
|
|
3017
2833
|
const agentClient = new AgentClient(authTokenProvider);
|
|
3018
|
-
console.log("Created agent client");
|
|
3019
2834
|
await agentClient.initializeAgentClient(privateAccountKey);
|
|
3020
|
-
console.log("Initialized agent client");
|
|
3021
2835
|
return new FileManager(keyStore, agentClient);
|
|
3022
2836
|
};
|
|
3023
2837
|
executeOperation = async (fileManager, file, operation) => {
|
|
@@ -3034,7 +2848,7 @@ var init_publish = __esm({
|
|
|
3034
2848
|
handleExistingFileOp = async (fileId, operation) => {
|
|
3035
2849
|
try {
|
|
3036
2850
|
const { file, portalDetails, apiKey } = await getPortalData(fileId);
|
|
3037
|
-
const apiKeySeed =
|
|
2851
|
+
const apiKeySeed = toUint8Array3(apiKey);
|
|
3038
2852
|
const { privateAccountKey, ucanSecret } = deriveCollaboratorKeys(apiKeySeed);
|
|
3039
2853
|
const fileManager = await createFileManager(
|
|
3040
2854
|
portalDetails.portalSeed,
|
|
@@ -3050,22 +2864,19 @@ var init_publish = __esm({
|
|
|
3050
2864
|
};
|
|
3051
2865
|
handleNewFileOp = async (fileId) => {
|
|
3052
2866
|
const { file, portalDetails, apiKey } = await getPortalData(fileId);
|
|
3053
|
-
|
|
3054
|
-
const apiKeySeed = toUint8Array4(apiKey);
|
|
2867
|
+
const apiKeySeed = toUint8Array3(apiKey);
|
|
3055
2868
|
const { privateAccountKey, ucanSecret } = deriveCollaboratorKeys(apiKeySeed);
|
|
3056
|
-
console.log("Derived collaborator keys");
|
|
3057
2869
|
const fileManager = await createFileManager(
|
|
3058
2870
|
portalDetails.portalSeed,
|
|
3059
2871
|
portalDetails.portalAddress,
|
|
3060
2872
|
ucanSecret,
|
|
3061
2873
|
privateAccountKey
|
|
3062
2874
|
);
|
|
3063
|
-
console.log("Created file manager");
|
|
3064
2875
|
return fileManager.submitAddFileTrx(file);
|
|
3065
2876
|
};
|
|
3066
2877
|
getProxyAuthParams = async (fileId) => {
|
|
3067
2878
|
const { portalDetails, apiKey } = await getPortalData(fileId);
|
|
3068
|
-
const apiKeySeed =
|
|
2879
|
+
const apiKeySeed = toUint8Array3(apiKey);
|
|
3069
2880
|
const { privateAccountKey, ucanSecret } = deriveCollaboratorKeys(apiKeySeed);
|
|
3070
2881
|
const fileManager = await createFileManager(
|
|
3071
2882
|
portalDetails.portalSeed,
|
|
@@ -3574,9 +3385,7 @@ CREATE TABLE IF NOT EXISTS files (
|
|
|
3574
3385
|
commentKey TEXT,
|
|
3575
3386
|
linkKey TEXT,
|
|
3576
3387
|
linkKeyNonce TEXT,
|
|
3577
|
-
link TEXT
|
|
3578
|
-
derivedKey TEXT,
|
|
3579
|
-
secretKey TEXT
|
|
3388
|
+
link TEXT
|
|
3580
3389
|
);
|
|
3581
3390
|
CREATE INDEX IF NOT EXISTS idx_files_createdAt ON files(createdAt);
|
|
3582
3391
|
CREATE INDEX IF NOT EXISTS idx_files_syncStatus ON files(syncStatus);
|
|
@@ -3607,7 +3416,7 @@ CREATE TABLE IF NOT EXISTS events (
|
|
|
3607
3416
|
type TEXT NOT NULL CHECK (type IN ('create', 'update', 'delete')),
|
|
3608
3417
|
timestamp BIGINT NOT NULL,
|
|
3609
3418
|
fileId TEXT NOT NULL,
|
|
3610
|
-
status TEXT NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'processing', '
|
|
3419
|
+
status TEXT NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'processing', 'processed', 'failed')),
|
|
3611
3420
|
retryCount INTEGER NOT NULL DEFAULT 0,
|
|
3612
3421
|
lastError TEXT,
|
|
3613
3422
|
lockedAt BIGINT,
|