@storacha/encrypt-upload-client 0.0.8-0

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.
Files changed (41) hide show
  1. package/README.md +82 -0
  2. package/dist/config/constants.d.ts +3 -0
  3. package/dist/config/constants.d.ts.map +1 -0
  4. package/dist/config/constants.js +3 -0
  5. package/dist/config/env.d.ts +8 -0
  6. package/dist/config/env.d.ts.map +1 -0
  7. package/dist/config/env.js +22 -0
  8. package/dist/config/service.d.ts +14 -0
  9. package/dist/config/service.d.ts.map +1 -0
  10. package/dist/config/service.js +34 -0
  11. package/dist/core/client.d.ts +50 -0
  12. package/dist/core/client.d.ts.map +1 -0
  13. package/dist/core/client.js +78 -0
  14. package/dist/core/encrypted-metadata.d.ts +28 -0
  15. package/dist/core/encrypted-metadata.d.ts.map +1 -0
  16. package/dist/core/encrypted-metadata.js +166 -0
  17. package/dist/core/errors.d.ts +8 -0
  18. package/dist/core/errors.d.ts.map +1 -0
  19. package/dist/core/errors.js +14 -0
  20. package/dist/crypto-adapters/node-crypto-adapter.d.ts +17 -0
  21. package/dist/crypto-adapters/node-crypto-adapter.d.ts.map +1 -0
  22. package/dist/crypto-adapters/node-crypto-adapter.js +66 -0
  23. package/dist/handlers/decrypt-handler.d.ts +11 -0
  24. package/dist/handlers/decrypt-handler.d.ts.map +1 -0
  25. package/dist/handlers/decrypt-handler.js +127 -0
  26. package/dist/handlers/encrypt-handler.d.ts +3 -0
  27. package/dist/handlers/encrypt-handler.d.ts.map +1 -0
  28. package/dist/handlers/encrypt-handler.js +87 -0
  29. package/dist/index.d.ts +4 -0
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +4 -0
  32. package/dist/protocols/lit.d.ts +18 -0
  33. package/dist/protocols/lit.d.ts.map +1 -0
  34. package/dist/protocols/lit.js +106 -0
  35. package/dist/types.d.ts +82 -0
  36. package/dist/types.d.ts.map +1 -0
  37. package/dist/types.js +2 -0
  38. package/dist/utils.d.ts +15 -0
  39. package/dist/utils.d.ts.map +1 -0
  40. package/dist/utils.js +50 -0
  41. package/package.json +127 -0
@@ -0,0 +1,127 @@
1
+ import { Wallet } from 'ethers';
2
+ import { CID } from 'multiformats';
3
+ import { CarIndexer } from '@ipld/car';
4
+ import { exporter } from 'ipfs-unixfs-exporter';
5
+ import { MemoryBlockstore } from 'blockstore-core';
6
+ import { base64 } from 'multiformats/bases/base64';
7
+ import * as Lit from '../protocols/lit.js';
8
+ import * as Type from '../types.js';
9
+ import * as EncryptedMetadata from '../core/encrypted-metadata.js';
10
+ import { createDecryptWrappedInvocation } from '../utils.js';
11
+ /**
12
+ *
13
+ * @param {import('@storacha/client').Client} storachaClient - The Storacha client
14
+ * @param {import('@lit-protocol/lit-node-client').LitNodeClient} litClient - The Lit client
15
+ * @param {Type.CryptoAdapter} cryptoAdapter - The crypto adapter responsible for performing
16
+ * encryption and decryption operations.
17
+ * @param {URL} gatewayURL - The IPFS gateway URL
18
+ * @param {Wallet} wallet - The wallet to use to decrypt the file
19
+ * @param {Type.AnyLink} cid - The link to the file to retrieve
20
+ * @param {Uint8Array} delegationCAR - The delegation that gives permission to decrypt the file
21
+ */
22
+ export const retrieveAndDecrypt = async (storachaClient, litClient, cryptoAdapter, gatewayURL, wallet, cid, delegationCAR) => {
23
+ const encryptedMetadataCar = await getCarFileFromGateway(gatewayURL, cid.toString());
24
+ const { encryptedDataCID, identityBoundCiphertext, plaintextKeyHash, accessControlConditions, } = extractEncryptedMetadata(encryptedMetadataCar);
25
+ const spaceDID = /** @type {`did:key:${string}`} */ (accessControlConditions[0].parameters[1]);
26
+ const encryptedData = await getEncryptedDataFromCar(encryptedMetadataCar, encryptedDataCID);
27
+ /**
28
+ * TODO: check if the wallet has capacity credits, if not get it
29
+ */
30
+ // TODO: store the session signature (https://developer.litprotocol.com/intro/first-request/generating-session-sigs#nodejs)
31
+ const sessionSigs = await Lit.getSessionSigs(litClient, {
32
+ wallet,
33
+ dataToEncryptHash: plaintextKeyHash,
34
+ expiration: new Date(Date.now() + 1000 * 60 * 5).toISOString(), // 5 min
35
+ accessControlConditions:
36
+ /** @type import('@lit-protocol/types').AccessControlConditions */ (
37
+ /** @type {unknown} */ (accessControlConditions)),
38
+ });
39
+ const wrappedInvocationJSON = await createDecryptWrappedInvocation({
40
+ delegationCAR,
41
+ spaceDID,
42
+ resourceCID: cid,
43
+ issuer: storachaClient.agent.issuer,
44
+ audience: storachaClient.defaultProvider(),
45
+ expiration: new Date(Date.now() + 1000 * 60 * 10).getTime(), // 10 min
46
+ });
47
+ const decryptKey = await Lit.executeUcanValidatoinAction(litClient, {
48
+ sessionSigs,
49
+ spaceDID,
50
+ identityBoundCiphertext,
51
+ plaintextKeyHash,
52
+ accessControlConditions,
53
+ wrappedInvocationJSON,
54
+ });
55
+ return decryptFileWithKey(cryptoAdapter, decryptKey, encryptedData);
56
+ };
57
+ /**
58
+ * @param {Type.CryptoAdapter} cryptoAdapter - The crypto adapter responsible for performing
59
+ * encryption and decryption operations.
60
+ * @param {string} combinedKey
61
+ * @param {Uint8Array} content
62
+ */
63
+ export function decryptFileWithKey(cryptoAdapter, combinedKey, content) {
64
+ // Split the decrypted data back into key and initializationVector
65
+ const decryptedKeyData = base64.decode(combinedKey);
66
+ const symmetricKey = decryptedKeyData.subarray(0, 32);
67
+ const initializationVector = decryptedKeyData.subarray(32);
68
+ // Create a ReadableStream from the Uint8Array
69
+ const contentStream = new ReadableStream({
70
+ start(controller) {
71
+ controller.enqueue(content);
72
+ controller.close();
73
+ },
74
+ });
75
+ const decryptedStream = cryptoAdapter.decryptStream(contentStream, symmetricKey, initializationVector);
76
+ return decryptedStream;
77
+ }
78
+ /**
79
+ *
80
+ * @param {URL} gatewayURL
81
+ * @param {string} cid
82
+ */
83
+ const getCarFileFromGateway = async (gatewayURL, cid) => {
84
+ const url = new URL(`/ipfs/${cid}?format=car`, gatewayURL);
85
+ const response = await fetch(url);
86
+ if (!response.ok) {
87
+ throw new Error(`Failed to fetch: ${response.status} ${response.statusText}`);
88
+ }
89
+ const car = new Uint8Array(await response.arrayBuffer());
90
+ return car;
91
+ };
92
+ /**
93
+ *
94
+ * @param {Uint8Array} car
95
+ */
96
+ const extractEncryptedMetadata = (car) => {
97
+ const encryptedContentResult = EncryptedMetadata.extract(car);
98
+ if (encryptedContentResult.error) {
99
+ throw encryptedContentResult.error;
100
+ }
101
+ let encryptedContent = encryptedContentResult.ok.toJSON();
102
+ return encryptedContent;
103
+ };
104
+ /**
105
+ *
106
+ * @param {Uint8Array} car
107
+ * @param {string} encryptedDataCID
108
+ */
109
+ const getEncryptedDataFromCar = async (car, encryptedDataCID) => {
110
+ // NOTE: convert CAR to a block store
111
+ const iterable = await CarIndexer.fromBytes(car);
112
+ const blockstore = new MemoryBlockstore();
113
+ for await (const { cid, blockLength, blockOffset } of iterable) {
114
+ const blockBytes = car.slice(blockOffset, blockOffset + blockLength);
115
+ await blockstore.put(cid, blockBytes);
116
+ }
117
+ // NOTE: get the encrypted Data from the CAR file
118
+ const encryptedDataEntry = await exporter(CID.parse(encryptedDataCID), blockstore);
119
+ const encryptedDataBytes = new Uint8Array(Number(encryptedDataEntry.size));
120
+ let offset = 0;
121
+ for await (const chunk of encryptedDataEntry.content()) {
122
+ encryptedDataBytes.set(chunk, offset);
123
+ offset += chunk.length;
124
+ }
125
+ return encryptedDataBytes;
126
+ };
127
+ //# sourceMappingURL=decrypt-handler.js.map
@@ -0,0 +1,3 @@
1
+ export function encryptAndUpload(storachaClient: import("@storacha/client").Client, litClient: import("@lit-protocol/lit-node-client").LitNodeClient, cryptoAdapter: Type.CryptoAdapter, file: Type.BlobLike): Promise<Type.AnyLink>;
2
+ import * as Type from '../types.js';
3
+ //# sourceMappingURL=encrypt-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encrypt-handler.d.ts","sourceRoot":"","sources":["../../src/handlers/encrypt-handler.js"],"names":[],"mappings":"AAkBO,iDAPI,OAAO,kBAAkB,EAAE,MAAM,aACjC,OAAO,+BAA+B,EAAE,aAAa,iBACrD,IAAI,CAAC,aAAa,QAElB,IAAI,CAAC,QAAQ,GACX,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CA4BjC;sBAxCqB,aAAa"}
@@ -0,0 +1,87 @@
1
+ import { CARWriterStream } from 'carstream';
2
+ import { base64 } from 'multiformats/bases/base64';
3
+ import { createFileEncoderStream } from '@storacha/upload-client/unixfs';
4
+ import * as Type from '../types.js';
5
+ import * as Lit from '../protocols/lit.js';
6
+ import * as EncryptedMetadata from '../core/encrypted-metadata.js';
7
+ /**
8
+ * Encrypt and upload a file to the Storacha network
9
+ *
10
+ * @param {import('@storacha/client').Client} storachaClient - The Storacha client
11
+ * @param {import('@lit-protocol/lit-node-client').LitNodeClient} litClient - The Lit client
12
+ * @param {Type.CryptoAdapter} cryptoAdapter - The crypto adapter responsible for performing
13
+ * encryption and decryption operations.
14
+ * @param {Type.BlobLike} file - The file to upload
15
+ * @returns {Promise<Type.AnyLink>} - The link to the uploaded file
16
+ */
17
+ export const encryptAndUpload = async (storachaClient, litClient, cryptoAdapter, file) => {
18
+ const spaceDID = /** @type {Type.SpaceDID | undefined} */ (storachaClient.agent.currentSpace());
19
+ if (!spaceDID)
20
+ throw new Error('No space selected!');
21
+ const accessControlConditions = Lit.getAccessControlConditions(spaceDID);
22
+ const encryptedPayload = await encryptFile(litClient, cryptoAdapter, file, accessControlConditions);
23
+ const rootCid = await uploadEncryptedMetadata(storachaClient, encryptedPayload, accessControlConditions);
24
+ return rootCid;
25
+ };
26
+ /**
27
+ * Upload encrypted metadata to the Storacha network
28
+ *
29
+ * @param {import('@storacha/client').Client} storachaClient - The Storacha client
30
+ * @param {Type.EncryptedPayload} encryptedPayload - The encrypted payload
31
+ * @param {import('@lit-protocol/types').AccessControlConditions} accessControlConditions - The access control conditions
32
+ * @returns {Promise<Type.AnyLink>} - The link to the uploaded metadata
33
+ */
34
+ const uploadEncryptedMetadata = async (storachaClient, encryptedPayload, accessControlConditions) => {
35
+ const { identityBoundCiphertext, plaintextKeyHash, encryptedBlobLike } = encryptedPayload;
36
+ return storachaClient.uploadCAR({
37
+ stream() {
38
+ /** @type {any} */
39
+ let root;
40
+ return createFileEncoderStream(encryptedBlobLike)
41
+ .pipeThrough(new TransformStream({
42
+ transform(block, controller) {
43
+ root = block;
44
+ controller.enqueue(block);
45
+ },
46
+ async flush(controller) {
47
+ if (!root)
48
+ throw new Error('missing root block');
49
+ /** @type {Type.EncryptedMetadataInput} */
50
+ const uploadData = {
51
+ encryptedDataCID: root.cid.toString(),
52
+ identityBoundCiphertext,
53
+ plaintextKeyHash,
54
+ accessControlConditions: /** @type {[Record<string, any>]} */ (
55
+ /** @type {unknown} */ (accessControlConditions)),
56
+ };
57
+ const encryptedMetadata = EncryptedMetadata.create(uploadData);
58
+ const { cid, bytes } = await encryptedMetadata.archiveBlock();
59
+ controller.enqueue({ cid, bytes });
60
+ },
61
+ }))
62
+ .pipeThrough(new CARWriterStream());
63
+ },
64
+ });
65
+ };
66
+ /**
67
+ * Encrypt a file
68
+ *
69
+ * @param {import('@lit-protocol/lit-node-client').LitNodeClient} litClient - The Lit client
70
+ * @param {Type.CryptoAdapter} cryptoAdapter - The crypto adapter responsible for performing
71
+ * encryption and decryption operations.
72
+ * @param {Type.BlobLike} file - The file to encrypt
73
+ * @param {import('@lit-protocol/types').AccessControlConditions} accessControlConditions - The access control conditions
74
+ * @returns {Promise<Type.EncryptedPayload>} - The encrypted file
75
+ */
76
+ const encryptFile = async (litClient, cryptoAdapter, file, accessControlConditions) => {
77
+ const { key, iv, encryptedStream } = cryptoAdapter.encryptStream(file);
78
+ // Combine key and initializationVector for Lit encryption
79
+ const dataToEncrypt = base64.encode(new Uint8Array([...key, ...iv]));
80
+ const { ciphertext, dataToEncryptHash } = await Lit.encryptString({ dataToEncrypt, accessControlConditions }, litClient);
81
+ return {
82
+ identityBoundCiphertext: ciphertext,
83
+ plaintextKeyHash: dataToEncryptHash,
84
+ encryptedBlobLike: { stream: () => encryptedStream },
85
+ };
86
+ };
87
+ //# sourceMappingURL=encrypt-handler.js.map
@@ -0,0 +1,4 @@
1
+ export { Wallet } from "ethers";
2
+ export { create } from "./core/client.js";
3
+ export { NodeCryptoAdapter } from "./crypto-adapters/node-crypto-adapter.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { Wallet } from 'ethers';
2
+ export { create } from './core/client.js';
3
+ export { NodeCryptoAdapter } from './crypto-adapters/node-crypto-adapter.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Get a LitClient instance.
3
+ */
4
+ export function getLitClient(): Promise<LitNodeClient>;
5
+ /**
6
+ * @param {LitNodeClient} litClient
7
+ * @param {Type.SessionSignatureOptions} param0
8
+ * @returns {Promise<import('@lit-protocol/types').SessionSigsMap>}
9
+ */
10
+ export function getSessionSigs(litClient: LitNodeClient, { wallet, accessControlConditions, dataToEncryptHash, expiration, capabilityAuthSigs, }: Type.SessionSignatureOptions): Promise<import("@lit-protocol/types").SessionSigsMap>;
11
+ export { encryptString } from "@lit-protocol/encryption";
12
+ export function getAccessControlConditions(spaceDID: import("@ucanto/core/schema").Schema<`did:key:${string}` & `did:${string}` & import("multiformats").Phantom<{
13
+ protocol: "did:";
14
+ }>, any>): import("@lit-protocol/types").AccessControlConditions;
15
+ export function executeUcanValidatoinAction(litClient: LitNodeClient, options: Type.ExecuteUcanValidationOptions): Promise<any>;
16
+ import { LitNodeClient } from '@lit-protocol/lit-node-client';
17
+ import * as Type from '../types.js';
18
+ //# sourceMappingURL=lit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lit.d.ts","sourceRoot":"","sources":["../../src/protocols/lit.js"],"names":[],"mappings":"AAsCA;;GAEG;AACH,uDAQC;AAED;;;;GAIG;AACH,0CAJW,aAAa,2FACb,IAAI,CAAC,uBAAuB,GAC1B,OAAO,CAAC,OAAO,qBAAqB,EAAE,cAAc,CAAC,CAsDjE;;AAtFM;;WAFM,OAAO,qBAAqB,EAAE,uBAAuB,CAgBjE;AAgFM,uDAJI,aAAa,WACb,IAAI,CAAC,4BAA4B,gBA4B3C;8BA7I6B,+BAA+B;sBAUvC,aAAa"}
@@ -0,0 +1,106 @@
1
+ import { LitNodeClient } from '@lit-protocol/lit-node-client';
2
+ import { LIT_ABILITY } from '@lit-protocol/constants';
3
+ import { generateAuthSig, LitActionResource, createSiweMessage, LitAccessControlConditionResource, } from '@lit-protocol/auth-helpers';
4
+ import env from '../config/env.js';
5
+ import * as Type from '../types.js';
6
+ import { STORACHA_LIT_ACTION_CID } from '../config/constants.js';
7
+ export { encryptString } from '@lit-protocol/encryption';
8
+ /**
9
+ * Create access control conditions required to use Lit Protocol.
10
+ * This ensures that the Storacha Lit Action is used to validate decryption permissions for the specified space DID.
11
+ *
12
+ * @param {Type.SpaceDID} spaceDID - The DID of the space
13
+ * @returns {import('@lit-protocol/types').AccessControlConditions} - The access control conditions
14
+ */
15
+ export const getAccessControlConditions = (spaceDID) => {
16
+ return [
17
+ {
18
+ contractAddress: '',
19
+ standardContractType: '',
20
+ chain: 'ethereum',
21
+ method: '',
22
+ parameters: [':currentActionIpfsId', spaceDID],
23
+ returnValueTest: {
24
+ comparator: '=',
25
+ value: STORACHA_LIT_ACTION_CID,
26
+ },
27
+ },
28
+ ];
29
+ };
30
+ /**
31
+ * Get a LitClient instance.
32
+ */
33
+ export async function getLitClient() {
34
+ const litNodeClient = new LitNodeClient({
35
+ litNetwork: env.LIT_NETWORK,
36
+ debug: env.LIT_DEBUG,
37
+ });
38
+ await litNodeClient.connect();
39
+ return litNodeClient;
40
+ }
41
+ /**
42
+ * @param {LitNodeClient} litClient
43
+ * @param {Type.SessionSignatureOptions} param0
44
+ * @returns {Promise<import('@lit-protocol/types').SessionSigsMap>}
45
+ */
46
+ export async function getSessionSigs(litClient, { wallet, accessControlConditions, dataToEncryptHash, expiration, capabilityAuthSigs, }) {
47
+ const accsResourceString = await LitAccessControlConditionResource.generateResourceString(accessControlConditions, dataToEncryptHash);
48
+ const sessionSigs = await litClient.getSessionSigs({
49
+ chain: 'ethereum',
50
+ capabilityAuthSigs,
51
+ expiration,
52
+ resourceAbilityRequests: [
53
+ {
54
+ resource: new LitAccessControlConditionResource(accsResourceString),
55
+ ability: LIT_ABILITY.AccessControlConditionDecryption,
56
+ },
57
+ {
58
+ resource: new LitActionResource('*'),
59
+ ability: LIT_ABILITY.LitActionExecution,
60
+ },
61
+ ],
62
+ authNeededCallback: async ({ uri, expiration, resourceAbilityRequests, }) => {
63
+ const toSign = await createSiweMessage({
64
+ uri,
65
+ expiration,
66
+ resources: resourceAbilityRequests,
67
+ walletAddress: wallet.address,
68
+ nonce: await litClient.getLatestBlockhash(),
69
+ litNodeClient: litClient,
70
+ });
71
+ return await generateAuthSig({
72
+ signer: wallet,
73
+ toSign,
74
+ });
75
+ },
76
+ });
77
+ return sessionSigs;
78
+ }
79
+ /**
80
+ *
81
+ * @param {LitNodeClient} litClient
82
+ * @param {Type.ExecuteUcanValidationOptions} options
83
+ * @returns
84
+ */
85
+ export const executeUcanValidatoinAction = async (litClient, options) => {
86
+ const { sessionSigs, ...jsParams } = options;
87
+ const litActionResponse = await litClient.executeJs({
88
+ ipfsId: STORACHA_LIT_ACTION_CID,
89
+ sessionSigs,
90
+ jsParams,
91
+ });
92
+ if (!litActionResponse.response) {
93
+ throw new Error('Error getting lit action response.');
94
+ }
95
+ const parsedResponse = JSON.parse(
96
+ /** @type string*/ (litActionResponse.response));
97
+ const decryptedData = parsedResponse.decryptedString;
98
+ if (!decryptedData) {
99
+ let errorMsg;
100
+ if (parsedResponse.error)
101
+ errorMsg = parsedResponse.error;
102
+ throw new Error(`Decrypted data does not exist! Error message: ${errorMsg}`);
103
+ }
104
+ return decryptedData;
105
+ };
106
+ //# sourceMappingURL=lit.js.map
@@ -0,0 +1,82 @@
1
+ import { Wallet } from 'ethers';
2
+ import { UnknownLink } from 'multiformats';
3
+ import { Client as StorachaClient } from '@storacha/client';
4
+ import { Result, Failure, Block } from '@ucanto/interface';
5
+ import { LitNodeClient } from '@lit-protocol/lit-node-client';
6
+ import { AccessControlConditions, AuthSig, SessionSigsMap } from '@lit-protocol/types';
7
+ import type { BlobLike, AnyLink, Signer, DID, SigAlg } from '@storacha/client/types';
8
+ export type { IPLDBlock } from '@ucanto/interface';
9
+ export type { SpaceDID } from '@storacha/capabilities/utils';
10
+ export type { UnknownFormat } from '@storacha/capabilities/types';
11
+ export type { Result, UnknownLink };
12
+ export type { BlobLike, AnyLink };
13
+ export interface EncryptedClient {
14
+ uploadEncryptedFile(file: BlobLike): Promise<AnyLink>;
15
+ retrieveAndDecryptFile(wallet: Wallet, cid: AnyLink, delegationCAR: Uint8Array): Promise<ReadableStream>;
16
+ }
17
+ export type EncryptedClientOptions = {
18
+ storachaClient: StorachaClient;
19
+ cryptoAdapter: CryptoAdapter;
20
+ litClient?: LitNodeClient;
21
+ gatewayURL?: URL;
22
+ };
23
+ export interface CryptoAdapter {
24
+ encryptStream(data: BlobLike): EncryptOutput;
25
+ decryptStream(encryptedData: ReadableStream, key: Uint8Array, iv: Uint8Array): ReadableStream;
26
+ }
27
+ export interface EncryptOutput {
28
+ key: Uint8Array;
29
+ iv: Uint8Array;
30
+ encryptedStream: ReadableStream;
31
+ }
32
+ export type EncryptedPayload = {
33
+ identityBoundCiphertext: string;
34
+ plaintextKeyHash: string;
35
+ encryptedBlobLike: BlobLike;
36
+ };
37
+ export type GenericAccessControlCondition = [Record<string, any>];
38
+ export interface EncryptedMetadataInput {
39
+ encryptedDataCID: string;
40
+ identityBoundCiphertext: string;
41
+ plaintextKeyHash: string;
42
+ accessControlConditions: GenericAccessControlCondition;
43
+ }
44
+ export interface EncryptedMetadata {
45
+ encryptedDataCID: UnknownLink;
46
+ identityBoundCiphertext: Uint8Array;
47
+ plaintextKeyHash: Uint8Array;
48
+ accessControlConditions: GenericAccessControlCondition;
49
+ }
50
+ export interface EncryptedMetadataView extends EncryptedMetadata {
51
+ /** Encode it to a CAR file. */
52
+ archive(): Promise<Result<Uint8Array>>;
53
+ archiveBlock(): Promise<Block>;
54
+ toJSON(): EncryptedMetadataInput;
55
+ }
56
+ export interface DecodeFailure extends Failure {
57
+ name: 'DecodeFailure';
58
+ }
59
+ export interface SessionSignatureOptions {
60
+ wallet: Wallet;
61
+ accessControlConditions: AccessControlConditions;
62
+ dataToEncryptHash: string;
63
+ expiration?: string;
64
+ capabilityAuthSigs?: AuthSig[];
65
+ }
66
+ export interface CreateDecryptWrappedInvocationOptions {
67
+ delegationCAR: Uint8Array;
68
+ issuer: Signer<DID, SigAlg>;
69
+ audience: `did:${string}:${string}`;
70
+ spaceDID: `did:key:${string}`;
71
+ resourceCID: AnyLink;
72
+ expiration: number;
73
+ }
74
+ export interface ExecuteUcanValidationOptions {
75
+ sessionSigs: SessionSigsMap;
76
+ spaceDID: `did:key:${string}`;
77
+ identityBoundCiphertext: string;
78
+ plaintextKeyHash: string;
79
+ accessControlConditions: AccessControlConditions;
80
+ wrappedInvocationJSON: string;
81
+ }
82
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1,15 @@
1
+ /**
2
+ *
3
+ * @param {string} str
4
+ * @returns {Uint8Array}
5
+ */
6
+ export function stringToBytes(str: string): Uint8Array;
7
+ /**
8
+ *
9
+ * @param {Uint8Array} bytes
10
+ * @returns {string}
11
+ */
12
+ export function bytesToString(bytes: Uint8Array): string;
13
+ export function createDecryptWrappedInvocation({ delegationCAR, issuer, spaceDID, resourceCID, audience, expiration, }: Type.CreateDecryptWrappedInvocationOptions): Promise<import("@ucanto/server").ToString<Uint8Array<ArrayBufferLike>, string>>;
14
+ import * as Type from './types.js';
15
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.js"],"names":[],"mappings":"AA+CA;;;;GAIG;AACH,mCAHW,MAAM,GACJ,UAAU,CAItB;AAED;;;;GAIG;AACH,qCAHW,UAAU,GACR,MAAM,CAIlB;AApDM,wHAFI,IAAI,CAAC,qCAAqC,mFAoCpD;sBAxCqB,YAAY"}
package/dist/utils.js ADDED
@@ -0,0 +1,50 @@
1
+ import { DID } from '@ucanto/server';
2
+ import * as dagJSON from '@ipld/dag-json';
3
+ import { extract } from '@ucanto/core/delegation';
4
+ import * as Space from '@storacha/capabilities/space';
5
+ import * as Type from './types.js';
6
+ /**
7
+ *
8
+ * @param {Type.CreateDecryptWrappedInvocationOptions} param0
9
+ */
10
+ export const createDecryptWrappedInvocation = async ({ delegationCAR, issuer, spaceDID, resourceCID, audience, expiration, }) => {
11
+ const delegation = await extract(delegationCAR);
12
+ if (delegation.error) {
13
+ throw delegation.error;
14
+ }
15
+ const invocationOptions = {
16
+ issuer,
17
+ audience: DID.parse(audience),
18
+ with: spaceDID,
19
+ nb: {
20
+ resource: resourceCID,
21
+ },
22
+ expiration: expiration,
23
+ proofs: [delegation.ok],
24
+ };
25
+ const decryptWrappedInvocation = await Space.decrypt
26
+ .invoke(invocationOptions)
27
+ .delegate();
28
+ const carEncoded = await decryptWrappedInvocation.archive();
29
+ if (carEncoded.error) {
30
+ throw carEncoded.error;
31
+ }
32
+ return dagJSON.stringify(carEncoded.ok);
33
+ };
34
+ /**
35
+ *
36
+ * @param {string} str
37
+ * @returns {Uint8Array}
38
+ */
39
+ export function stringToBytes(str) {
40
+ return new TextEncoder().encode(str);
41
+ }
42
+ /**
43
+ *
44
+ * @param {Uint8Array} bytes
45
+ * @returns {string}
46
+ */
47
+ export function bytesToString(bytes) {
48
+ return new TextDecoder().decode(bytes);
49
+ }
50
+ //# sourceMappingURL=utils.js.map
package/package.json ADDED
@@ -0,0 +1,127 @@
1
+ {
2
+ "name": "@storacha/encrypt-upload-client",
3
+ "type": "module",
4
+ "version": "0.0.8-0",
5
+ "license": "Apache-2.0 OR MIT",
6
+ "description": "Client for upload and download encrypted files",
7
+ "author": "Storacha",
8
+ "publishConfig": {
9
+ "access": "public"
10
+ },
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "https://github.com/storacha/upload-service.git",
14
+ "directory": "packages/encrypt-upload-client"
15
+ },
16
+ "keywords": [
17
+ "storacha",
18
+ "lit protocol",
19
+ "web3",
20
+ "storage",
21
+ "upload",
22
+ "store",
23
+ "encrypt",
24
+ "decrypt",
25
+ "IPLD",
26
+ "UCAN",
27
+ "IPFS"
28
+ ],
29
+ "main": "dist/index.js",
30
+ "types": "dist/index.d.ts",
31
+ "files": [
32
+ "dist",
33
+ "!dist/**/*.js.map"
34
+ ],
35
+ "exports": {
36
+ ".": {
37
+ "types": "./dist/index.d.ts",
38
+ "import": "./dist/index.js"
39
+ },
40
+ "./crypto/adapters": {
41
+ "types": "./dist/crypto-adapters/node-crypto-adapter.d.ts",
42
+ "import": "./dist/crypto-adapters/node-crypto-adapter.js"
43
+ },
44
+ "./types": "./dist/types.js"
45
+ },
46
+ "dependencies": {
47
+ "@ipld/car": "^5.4.0",
48
+ "@ipld/dag-cbor": "^9.0.6",
49
+ "@ipld/dag-json": "^10.2.3",
50
+ "@ipld/dag-ucan": "^3.4.5",
51
+ "@ipld/schema": "^6.0.6",
52
+ "@lit-protocol/auth-helpers": "^7.0.2",
53
+ "@lit-protocol/constants": "^7.0.2",
54
+ "@lit-protocol/contracts-sdk": "^7.0.2",
55
+ "@lit-protocol/encryption": "^7.0.2",
56
+ "@lit-protocol/lit-auth-client": "^7.0.3",
57
+ "@lit-protocol/lit-node-client": "^7.0.2",
58
+ "@ucanto/client": "^9.0.1",
59
+ "@ucanto/core": "^10.3.1",
60
+ "@ucanto/interface": "^10.2.0",
61
+ "@ucanto/principal": "^9.0.2",
62
+ "@ucanto/server": "^10.2.0",
63
+ "@ucanto/transport": "^9.1.1",
64
+ "@ucanto/validator": "^9.1.0",
65
+ "blockstore-core": "^3.0.0",
66
+ "carstream": "^2.1.0",
67
+ "dotenv": "^16.4.7",
68
+ "ethers": "5.7.1",
69
+ "ipfs-unixfs-exporter": "^10.0.0",
70
+ "multiformats": "^13.3.2",
71
+ "@storacha/capabilities": "^1.4.0",
72
+ "@storacha/upload-client": "^1.0.9",
73
+ "@storacha/client": "^1.2.4"
74
+ },
75
+ "devDependencies": {
76
+ "@lit-protocol/types": "^7.0.8",
77
+ "esbuild": "^0.25.1",
78
+ "typescript": "^5.7.3",
79
+ "@storacha/eslint-config": "^0.0.0"
80
+ },
81
+ "eslintConfig": {
82
+ "extends": [
83
+ "@storacha/eslint-config"
84
+ ],
85
+ "parserOptions": {
86
+ "project": "./tsconfig.json"
87
+ },
88
+ "env": {
89
+ "es2022": true,
90
+ "mocha": true,
91
+ "browser": true,
92
+ "node": true
93
+ },
94
+ "ignorePatterns": [
95
+ "dist",
96
+ "docs",
97
+ "docs-generated",
98
+ "coverage",
99
+ "src/types.js",
100
+ "*.min.js"
101
+ ]
102
+ },
103
+ "depcheck": {
104
+ "ignorePatterns": [
105
+ "dist"
106
+ ],
107
+ "ignores": [
108
+ "@typescript-eslint/eslint-plugin",
109
+ "@typescript-eslint/parser",
110
+ "assert",
111
+ "c8"
112
+ ]
113
+ },
114
+ "engines": {
115
+ "node": ">=18"
116
+ },
117
+ "engineStrict": true,
118
+ "scripts": {
119
+ "dev": "tsc --build --watch --preserveWatchOutput",
120
+ "clean": "rm -rf dist *.tsbuildinfo",
121
+ "lint": "tsc --build && eslint '**/*.{js,ts}' --ignore-pattern 'lit-actions/**' && prettier --check '**/*.{js,ts,yml,json}' --ignore-path ../../.gitignore",
122
+ "lint:fix": "tsc --build && eslint '**/*.{js,ts}' --fix && prettier --write '**/*.{js,ts,yml,json}' --ignore-path ../../.gitignore",
123
+ "build-actions": "node lit-actions/esbuild.js",
124
+ "attw": "attw --pack .",
125
+ "rc": "npm version prerelease --preid rc"
126
+ }
127
+ }