1 | # @stacks/storage
|
2 |
|
3 | Store and fetch files with [Gaia](https://docs.stacks.co/build-apps/references/gaia), the decentralized storage system.
|
4 |
|
5 | ## Installation
|
6 |
|
7 | ```
|
8 | npm install @stacks/storage
|
9 | ```
|
10 |
|
11 | ## Usage
|
12 |
|
13 | ### Initiate a session
|
14 | Users must authenticate to an app before the storage package will work to save or retrieve data on their behalf.
|
15 |
|
16 | See also [authentication guide](https://docs.stacks.co/build-apps/references/authentication) using [connect](https://github.com/hirosystems/connect#readme) for web apps
|
17 |
|
18 | The storage capabilities will work in cases `userSession.isUserSignedIn()` returns `true`
|
19 |
|
20 | ### Initiating a storage client
|
21 |
|
22 | ```typescript
|
23 | import { UserSession, AppConfig } from '@stacks/auth';
|
24 | import { Storage } from '@stacks/storage';
|
25 |
|
26 | const privateKey = '896adae13a1bf88db0b2ec94339b62382ec6f34cd7e2ff8abae7ec271e05f9d8';
|
27 | const appConfig = new AppConfig();
|
28 | const userSession = new UserSession({ appConfig });
|
29 | userSession.store.getSessionData().userData = <any> {
|
30 | appPrivateKey: privateKey,
|
31 | };
|
32 | const storage = new Storage({ userSession });
|
33 | ```
|
34 |
|
35 | Note that you can also use an existing `userSession` object created during the authentication process.
|
36 |
|
37 | ### Put file
|
38 |
|
39 | ```typescript
|
40 | const myData = JSON.stringify({
|
41 | hello: "world",
|
42 | num: 1
|
43 | });
|
44 |
|
45 | const fileUrl = await storage.putFile('my_data.json', myData);
|
46 | // You'll need to save an entirely new string of modified data using putFile with the same fileName every time you want to update a record.
|
47 | // There is no separate update method.
|
48 | ```
|
49 |
|
50 | Store data at a different path
|
51 |
|
52 | ```typescript
|
53 | const fileUrl = await storage.putFile('path/my_data.json', myData);
|
54 | ```
|
55 |
|
56 | Put file with options
|
57 |
|
58 | ```typescript
|
59 | const putFileOptions = {
|
60 | // override the default content type
|
61 | contentType: 'application/json',
|
62 | // override encrypting data by default
|
63 | // you can also set encrypt to a private key to specify a custom encryption key
|
64 | encrypt: false,
|
65 | // ignore automatic conflict prevention using etags
|
66 | dangerouslyIgnoreEtag: true
|
67 | }
|
68 |
|
69 | const fileUrl = await storage.putFile('my_data.json', myData, putFileOptions);
|
70 | ```
|
71 |
|
72 | ### Get file
|
73 |
|
74 | ```typescript
|
75 | const fileContent = await storage.getFile('my_data.json');
|
76 | console.log(fileContent);
|
77 | ```
|
78 |
|
79 | Get file with options
|
80 |
|
81 | ```typescript
|
82 | const getFileOptions = {
|
83 | decrypt: false,
|
84 | // by default files stored are signed and can be verified for authenticity
|
85 | verify: false
|
86 | }
|
87 |
|
88 | const fileContent = await storage.getFile('my_data.json', getFileOptions);
|
89 | console.log(fileContent);
|
90 | ```
|
91 |
|
92 | Get file for other user
|
93 |
|
94 | ```typescript
|
95 | // Retrieve public data saved by users other than the one with the active session
|
96 | // User should have registered username via BNS
|
97 | const options = {
|
98 | username: 'yukan.id',
|
99 | // app: 'https://example.org',
|
100 | decrypt: false,
|
101 | };
|
102 | // Set an additional app property within options to retrieve data for a user as saved by an app hosted at a separate domain
|
103 |
|
104 | const fileContent = await storage.getFile('my_data.json', options);
|
105 | console.log(fileContent);
|
106 | ```
|
107 |
|
108 | ### Delete file
|
109 |
|
110 | ```typescript
|
111 | await storage.deleteFile('my_data.json');
|
112 | ```
|
113 |
|
114 | Delete the file and the corresponding signature file if signed
|
115 |
|
116 | ```typescript
|
117 | await storage.deleteFile('my_data.json', { wasSigned: true });
|
118 | ```
|
119 |
|
120 | ### List file
|
121 |
|
122 | List all files in the user's Gaia hub
|
123 |
|
124 | ```typescript
|
125 | const files: Promise<string | undefined | ArrayBuffer | null>[] = [];
|
126 | const options = { decrypt: false };
|
127 | await storage.listFiles((filename: string) => {
|
128 | if (filename === 'my_data.json') {
|
129 | files.push(storage.getFile(filename, options));
|
130 | // return false to stop iterating through files
|
131 | return false;
|
132 | } else {
|
133 | // return true to continue iterating
|
134 | return true;
|
135 | }
|
136 | });
|
137 | const fileContents = await Promise.all(files);
|
138 | ```
|