@siafoundation/sia-storage 0.0.8
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/README.md +175 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/index.node.cjs +96 -0
- package/dist/index.node.cjs.map +1 -0
- package/dist/index.node.d.ts +291 -0
- package/package.json +51 -0
- package/wasm/sia_storage_wasm.d.ts +592 -0
- package/wasm/sia_storage_wasm.js +1995 -0
- package/wasm/sia_storage_wasm_bg.wasm +0 -0
- package/wasm/sia_storage_wasm_bg.wasm.d.ts +91 -0
package/README.md
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# sia-storage
|
|
2
|
+
|
|
3
|
+
TypeScript SDK for building decentralized storage apps on the [Sia](https://sia.tech) network. Works in Node.js, Bun, and the browser.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @siafoundation/sia-storage
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick start
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { initSia, Builder, generateRecoveryPhrase } from '@siafoundation/sia-storage'
|
|
15
|
+
|
|
16
|
+
await initSia()
|
|
17
|
+
|
|
18
|
+
const appMeta = {
|
|
19
|
+
appId: '0'.repeat(64), // 32-byte app identifier (hex)
|
|
20
|
+
name: 'My App',
|
|
21
|
+
description: 'An app on the Sia network',
|
|
22
|
+
serviceUrl: 'https://myapp.com',
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const builder = new Builder('https://sia.storage', appMeta)
|
|
26
|
+
await builder.requestConnection()
|
|
27
|
+
// Show builder.responseUrl() to the user — they visit it to authorize.
|
|
28
|
+
await builder.waitForApproval()
|
|
29
|
+
|
|
30
|
+
const phrase = generateRecoveryPhrase()
|
|
31
|
+
const sdk = await builder.register(phrase)
|
|
32
|
+
|
|
33
|
+
// Persist the app key so the user doesn't re-auth next time.
|
|
34
|
+
const appKeyHex = sdk.appKey().export().toHex()
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Reconnecting a returning user:
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
import { Builder, AppKey } from '@siafoundation/sia-storage'
|
|
41
|
+
|
|
42
|
+
const sdk = await new Builder('https://sia.storage', appMeta)
|
|
43
|
+
.connected(new AppKey(Uint8Array.fromHex(appKeyHex)))
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Uploading
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
import { PinnedObject } from '@siafoundation/sia-storage'
|
|
50
|
+
|
|
51
|
+
const object = await sdk.upload(new PinnedObject(), file.stream(), { maxInflight: 10 })
|
|
52
|
+
await sdk.pinObject(object)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Downloading:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
const stream = sdk.download(object)
|
|
59
|
+
for await (const chunk of stream) { /* ... */ }
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
For many small files, share slabs via `uploadPacked`:
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
const packed = sdk.uploadPacked({ maxInflight: 10 })
|
|
66
|
+
await packed.add(fileA.stream())
|
|
67
|
+
await packed.add(fileB.stream())
|
|
68
|
+
for (const obj of await packed.finalize()) await sdk.pinObject(obj)
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Framework notes
|
|
72
|
+
|
|
73
|
+
The browser build is WebAssembly — most bundlers handle it directly, a few need a small hint.
|
|
74
|
+
|
|
75
|
+
**Vite** — production builds work as-is. For `vite dev`, exclude the package from the dep pre-bundler so its `import.meta.url`-relative WASM path resolves correctly:
|
|
76
|
+
|
|
77
|
+
```js
|
|
78
|
+
// vite.config.js
|
|
79
|
+
export default defineConfig({
|
|
80
|
+
optimizeDeps: { exclude: ['@siafoundation/sia-storage'] },
|
|
81
|
+
})
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Without this, the dev server fetches the `.wasm` from `/node_modules/.vite/deps/` where it doesn't exist, the SPA fallback returns `index.html`, and `WebAssembly.instantiate` fails with a `magic word … found 3c 21 64 6f` error.
|
|
85
|
+
|
|
86
|
+
**Next.js (App Router)** — load from a Client Component, dynamically imported so the WebAssembly module isn't pulled into the server prerender:
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
'use client'
|
|
90
|
+
import dynamic from 'next/dynamic'
|
|
91
|
+
const Storage = dynamic(() => import('./storage'), { ssr: false })
|
|
92
|
+
export default function Page() { return <Storage /> }
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**Webpack**:
|
|
96
|
+
|
|
97
|
+
```js
|
|
98
|
+
// webpack.config.js
|
|
99
|
+
module.exports = { experiments: { asyncWebAssembly: true, topLevelAwait: true } }
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**Rollup / esbuild** — copy the WebAssembly asset into your output directory:
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
cp node_modules/@siafoundation/sia-storage/wasm/sia_storage_wasm_bg.wasm dist/
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Node vs browser
|
|
109
|
+
|
|
110
|
+
Near-identical surfaces. Real differences:
|
|
111
|
+
|
|
112
|
+
- App identifier: `appMeta.appId: string (hex)` on browser, `appMeta.id: Buffer(32)` on Node.
|
|
113
|
+
- Numeric sizes are `number` on browser, `bigint` on Node. Byte arrays are `Uint8Array` on browser, `Buffer` on Node (`Buffer` is a `Uint8Array` subclass; both accept either as input).
|
|
114
|
+
|
|
115
|
+
## API
|
|
116
|
+
|
|
117
|
+
### Top-level
|
|
118
|
+
|
|
119
|
+
| | |
|
|
120
|
+
|---|---|
|
|
121
|
+
| `initSia()` | Initialize. Call once before using the SDK. |
|
|
122
|
+
| `generateRecoveryPhrase()` | 12-word BIP-39 phrase. |
|
|
123
|
+
| `validateRecoveryPhrase(phrase)` | Throws on invalid. |
|
|
124
|
+
| `setLogger(callback, level)` | Receive SDK logs. |
|
|
125
|
+
| `encodedSize(size, dataShards, parityShards)` | Encoded size after erasure coding. |
|
|
126
|
+
|
|
127
|
+
### `Sdk`
|
|
128
|
+
|
|
129
|
+
Returned from `Builder.register()` or `Builder.connected()`.
|
|
130
|
+
|
|
131
|
+
| | |
|
|
132
|
+
|---|---|
|
|
133
|
+
| `appKey()` | The `AppKey` for this session. |
|
|
134
|
+
| `upload(object, stream, options?)` | Upload from a `ReadableStream`. Progress via `options.onShardUploaded`. |
|
|
135
|
+
| `download(object, options?)` | Returns a `ReadableStream`. Progress via `options.onShardDownloaded`. |
|
|
136
|
+
| `uploadPacked(options?)` | `PackedUpload` for batching small files into shared slabs. |
|
|
137
|
+
| `object(key)` / `deleteObject(key)` / `pinObject(object)` | Object CRUD. |
|
|
138
|
+
| `updateObjectMetadata(object)` | Push local metadata changes to the indexer. |
|
|
139
|
+
| `shareObject(object, validUntil)` / `sharedObject(url)` | Create / consume share URLs. |
|
|
140
|
+
| `objectEvents(cursor?, limit)` | Paginated change feed. |
|
|
141
|
+
| `hosts()` / `slab(id)` / `account()` / `pruneSlabs()` | Indexer reads. |
|
|
142
|
+
|
|
143
|
+
### `Builder`
|
|
144
|
+
|
|
145
|
+
`new Builder(indexerUrl, appMeta)`
|
|
146
|
+
|
|
147
|
+
| | |
|
|
148
|
+
|---|---|
|
|
149
|
+
| `requestConnection()` | Start the approval flow. |
|
|
150
|
+
| `responseUrl()` | URL to show the user. |
|
|
151
|
+
| `waitForApproval()` | Resolves once the user approves. |
|
|
152
|
+
| `register(phrase)` | Finish onboarding with a new recovery phrase → `Sdk`. |
|
|
153
|
+
| `connected(appKey)` | Reconnect with a saved `AppKey` → `Sdk \| null`. |
|
|
154
|
+
|
|
155
|
+
### `AppKey`
|
|
156
|
+
|
|
157
|
+
`new AppKey(seed)` — 32-byte `Uint8Array`.
|
|
158
|
+
|
|
159
|
+
`publicKey()` · `sign(message)` · `verifySignature(message, signature)` · `export()`
|
|
160
|
+
|
|
161
|
+
### `PinnedObject`
|
|
162
|
+
|
|
163
|
+
`new PinnedObject()` for new uploads, or `sdk.object(key)`.
|
|
164
|
+
|
|
165
|
+
`id()` · `size()` · `encodedSize()` · `slabs()` · `metadata()` · `updateMetadata(bytes)` · `createdAt()` · `updatedAt()` · `seal(appKey)` · `PinnedObject.open(appKey, sealed)`
|
|
166
|
+
|
|
167
|
+
### `PackedUpload`
|
|
168
|
+
|
|
169
|
+
From `sdk.uploadPacked()`.
|
|
170
|
+
|
|
171
|
+
`add(stream)` · `finalize()` · `cancel()` · `remaining()` · `length()` · `slabs()`
|
|
172
|
+
|
|
173
|
+
## License
|
|
174
|
+
|
|
175
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { Account, AppKey, AppMetadata, Builder, DownloadOptions, Host, HostQuery, ObjectEvent, PackedUpload, PinnedObject, PinnedSlab, Sdk, SealedObject, Sector, ShardProgress, Slab, UploadOptions, encodedSize, generateRecoveryPhrase, setLogger, validateRecoveryPhrase } from '../wasm/sia_storage_wasm.js';
|
|
2
|
+
|
|
3
|
+
/** Initialize the WASM module. Safe to call multiple times. */
|
|
4
|
+
declare function initSia(): Promise<void>;
|
|
5
|
+
|
|
6
|
+
export { initSia };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import wasmInit from "../wasm/sia_storage_wasm.js";
|
|
3
|
+
import {
|
|
4
|
+
AppKey,
|
|
5
|
+
Builder,
|
|
6
|
+
ObjectEvent,
|
|
7
|
+
PackedUpload,
|
|
8
|
+
PinnedObject,
|
|
9
|
+
Sdk,
|
|
10
|
+
encodedSize,
|
|
11
|
+
generateRecoveryPhrase,
|
|
12
|
+
setLogger,
|
|
13
|
+
validateRecoveryPhrase
|
|
14
|
+
} from "../wasm/sia_storage_wasm.js";
|
|
15
|
+
var initPromise = null;
|
|
16
|
+
async function initSia() {
|
|
17
|
+
if (!initPromise) initPromise = wasmInit();
|
|
18
|
+
await initPromise;
|
|
19
|
+
}
|
|
20
|
+
export {
|
|
21
|
+
AppKey,
|
|
22
|
+
Builder,
|
|
23
|
+
ObjectEvent,
|
|
24
|
+
PackedUpload,
|
|
25
|
+
PinnedObject,
|
|
26
|
+
Sdk,
|
|
27
|
+
encodedSize,
|
|
28
|
+
generateRecoveryPhrase,
|
|
29
|
+
initSia,
|
|
30
|
+
setLogger,
|
|
31
|
+
validateRecoveryPhrase
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Browser entry; lazily initializes WASM on first use.\n\nimport wasmInit from '../wasm/sia_storage_wasm.js'\n\nlet initPromise: Promise<unknown> | null = null\n\n/** Initialize the WASM module. Safe to call multiple times. */\nexport async function initSia(): Promise<void> {\n if (!initPromise) initPromise = wasmInit()\n await initPromise\n}\n\nexport {\n AppKey,\n Builder,\n ObjectEvent,\n PackedUpload,\n PinnedObject,\n Sdk,\n encodedSize,\n generateRecoveryPhrase,\n setLogger,\n validateRecoveryPhrase,\n} from '../wasm/sia_storage_wasm.js'\nexport type {\n Account,\n AppMetadata,\n DownloadOptions,\n Host,\n HostQuery,\n PinnedSlab,\n Sector,\n SealedObject,\n ShardProgress,\n Slab,\n UploadOptions,\n} from '../wasm/sia_storage_wasm.js'\n"],"mappings":";AAEA,OAAO,cAAc;AAUrB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAnBP,IAAI,cAAuC;AAG3C,eAAsB,UAAyB;AAC7C,MAAI,CAAC,YAAa,eAAc,SAAS;AACzC,QAAM;AACR;","names":[]}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.node.ts
|
|
21
|
+
var index_node_exports = {};
|
|
22
|
+
__export(index_node_exports, {
|
|
23
|
+
AppKey: () => AppKey,
|
|
24
|
+
Builder: () => Builder,
|
|
25
|
+
ObjectEvent: () => ObjectEvent,
|
|
26
|
+
PackedUpload: () => PackedUpload,
|
|
27
|
+
PinnedObject: () => PinnedObject,
|
|
28
|
+
Sdk: () => Sdk,
|
|
29
|
+
encodedSize: () => encodedSize,
|
|
30
|
+
generateRecoveryPhrase: () => generateRecoveryPhrase,
|
|
31
|
+
initSia: () => initSia,
|
|
32
|
+
setLogger: () => setLogger,
|
|
33
|
+
validateRecoveryPhrase: () => validateRecoveryPhrase
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(index_node_exports);
|
|
36
|
+
|
|
37
|
+
// src/node/load.ts
|
|
38
|
+
var addon = null;
|
|
39
|
+
function loadNativeAddon() {
|
|
40
|
+
if (addon) return addon;
|
|
41
|
+
const platform = process.platform;
|
|
42
|
+
const arch = process.arch;
|
|
43
|
+
try {
|
|
44
|
+
if (platform === "darwin" && arch === "arm64") {
|
|
45
|
+
addon = require("@siafoundation/sia-storage-darwin-arm64");
|
|
46
|
+
} else if (platform === "darwin" && arch === "x64") {
|
|
47
|
+
addon = require("@siafoundation/sia-storage-darwin-x64");
|
|
48
|
+
} else if (platform === "linux" && arch === "x64") {
|
|
49
|
+
addon = require("@siafoundation/sia-storage-linux-x64-gnu");
|
|
50
|
+
} else if (platform === "linux" && arch === "arm64") {
|
|
51
|
+
addon = require("@siafoundation/sia-storage-linux-arm64-gnu");
|
|
52
|
+
} else if (platform === "win32" && arch === "x64") {
|
|
53
|
+
addon = require("@siafoundation/sia-storage-win32-x64-msvc");
|
|
54
|
+
}
|
|
55
|
+
} catch {
|
|
56
|
+
}
|
|
57
|
+
if (!addon) {
|
|
58
|
+
throw new Error(
|
|
59
|
+
`@siafoundation/sia-storage: Native addon not found for ${platform}-${arch}. Install @siafoundation/sia-storage-${platform}-${arch} or use the browser/WASM build.`
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
return addon;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// src/node/napi.ts
|
|
66
|
+
var addon2 = loadNativeAddon();
|
|
67
|
+
var {
|
|
68
|
+
AppKey,
|
|
69
|
+
Builder,
|
|
70
|
+
Sdk,
|
|
71
|
+
PinnedObject,
|
|
72
|
+
PackedUpload,
|
|
73
|
+
ObjectEvent,
|
|
74
|
+
generateRecoveryPhrase,
|
|
75
|
+
validateRecoveryPhrase,
|
|
76
|
+
setLogger,
|
|
77
|
+
encodedSize
|
|
78
|
+
} = addon2;
|
|
79
|
+
async function initSia() {
|
|
80
|
+
loadNativeAddon();
|
|
81
|
+
}
|
|
82
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
83
|
+
0 && (module.exports = {
|
|
84
|
+
AppKey,
|
|
85
|
+
Builder,
|
|
86
|
+
ObjectEvent,
|
|
87
|
+
PackedUpload,
|
|
88
|
+
PinnedObject,
|
|
89
|
+
Sdk,
|
|
90
|
+
encodedSize,
|
|
91
|
+
generateRecoveryPhrase,
|
|
92
|
+
initSia,
|
|
93
|
+
setLogger,
|
|
94
|
+
validateRecoveryPhrase
|
|
95
|
+
});
|
|
96
|
+
//# sourceMappingURL=index.node.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.node.ts","../src/node/load.ts","../src/node/napi.ts"],"sourcesContent":["export * from './node/napi'\nexport type * from './node/napi'\n","import type * as Addon from './napi.generated'\n\nlet addon: typeof Addon | null = null\n\nexport function loadNativeAddon(): typeof Addon {\n if (addon) return addon\n\n const platform = process.platform\n const arch = process.arch\n\n try {\n if (platform === 'darwin' && arch === 'arm64') {\n addon = require('@siafoundation/sia-storage-darwin-arm64')\n } else if (platform === 'darwin' && arch === 'x64') {\n addon = require('@siafoundation/sia-storage-darwin-x64')\n } else if (platform === 'linux' && arch === 'x64') {\n addon = require('@siafoundation/sia-storage-linux-x64-gnu')\n } else if (platform === 'linux' && arch === 'arm64') {\n addon = require('@siafoundation/sia-storage-linux-arm64-gnu')\n } else if (platform === 'win32' && arch === 'x64') {\n addon = require('@siafoundation/sia-storage-win32-x64-msvc')\n }\n } catch {}\n\n if (!addon) {\n throw new Error(\n `@siafoundation/sia-storage: Native addon not found for ${platform}-${arch}. ` +\n `Install @siafoundation/sia-storage-${platform}-${arch} or use the browser/WASM build.`,\n )\n }\n\n return addon\n}\n","import { loadNativeAddon } from './load'\n\nconst addon = loadNativeAddon()\n\nexport const {\n AppKey,\n Builder,\n Sdk,\n PinnedObject,\n PackedUpload,\n ObjectEvent,\n generateRecoveryPhrase,\n validateRecoveryPhrase,\n setLogger,\n encodedSize,\n} = addon\n\nexport type * from './napi.generated'\n\n/** Force-load the native addon to surface missing-binary errors at startup. */\nexport async function initSia(): Promise<void> {\n loadNativeAddon()\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEA,IAAI,QAA6B;AAE1B,SAAS,kBAAgC;AAC9C,MAAI,MAAO,QAAO;AAElB,QAAM,WAAW,QAAQ;AACzB,QAAM,OAAO,QAAQ;AAErB,MAAI;AACF,QAAI,aAAa,YAAY,SAAS,SAAS;AAC7C,cAAQ,QAAQ,yCAAyC;AAAA,IAC3D,WAAW,aAAa,YAAY,SAAS,OAAO;AAClD,cAAQ,QAAQ,uCAAuC;AAAA,IACzD,WAAW,aAAa,WAAW,SAAS,OAAO;AACjD,cAAQ,QAAQ,0CAA0C;AAAA,IAC5D,WAAW,aAAa,WAAW,SAAS,SAAS;AACnD,cAAQ,QAAQ,4CAA4C;AAAA,IAC9D,WAAW,aAAa,WAAW,SAAS,OAAO;AACjD,cAAQ,QAAQ,2CAA2C;AAAA,IAC7D;AAAA,EACF,QAAQ;AAAA,EAAC;AAET,MAAI,CAAC,OAAO;AACV,UAAM,IAAI;AAAA,MACR,0DAA0D,QAAQ,IAAI,IAAI,wCAClC,QAAQ,IAAI,IAAI;AAAA,IAC1D;AAAA,EACF;AAEA,SAAO;AACT;;;AC9BA,IAAMA,SAAQ,gBAAgB;AAEvB,IAAM;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,IAAIA;AAKJ,eAAsB,UAAyB;AAC7C,kBAAgB;AAClB;","names":["addon"]}
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
/* auto-generated by NAPI-RS */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
/**
|
|
4
|
+
* An AppKey is used to sign requests to the indexer.
|
|
5
|
+
*
|
|
6
|
+
* AppKeys can be registered with an indexer during
|
|
7
|
+
* onboarding with a Builder. They are derived from
|
|
8
|
+
* a BIP-39 recovery phrase, which can be generated
|
|
9
|
+
* using `generateRecoveryPhrase`.
|
|
10
|
+
*
|
|
11
|
+
* It must be stored securely by the application and
|
|
12
|
+
* never shared publicly.
|
|
13
|
+
*/
|
|
14
|
+
export declare class AppKey {
|
|
15
|
+
/** Imports an AppKey from the provided byte array. */
|
|
16
|
+
constructor(key: Buffer)
|
|
17
|
+
/** Exports the AppKey as a 32-byte buffer. */
|
|
18
|
+
export(): Buffer
|
|
19
|
+
/** Signs a message using the AppKey. */
|
|
20
|
+
sign(message: Buffer): Buffer
|
|
21
|
+
/** Returns the public key corresponding to the AppKey. */
|
|
22
|
+
publicKey(): string
|
|
23
|
+
/** Verifies a signature for a given message using the AppKey. */
|
|
24
|
+
verifySignature(message: Buffer, signature: Buffer): boolean
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export declare class Builder {
|
|
28
|
+
/** Creates a new SDK builder with the provided indexer URL. */
|
|
29
|
+
constructor(indexerUrl: string, appMeta: AppMetadata)
|
|
30
|
+
/**
|
|
31
|
+
* Attempts to connect using the provided app key.
|
|
32
|
+
* Returns the SDK if the app key is valid, otherwise returns null.
|
|
33
|
+
*/
|
|
34
|
+
connected(appKey: AppKey): Promise<Sdk | null>
|
|
35
|
+
/** Requests connection approval for the application. */
|
|
36
|
+
requestConnection(): Promise<void>
|
|
37
|
+
/** Returns the response URL for the connection request. */
|
|
38
|
+
responseUrl(): string
|
|
39
|
+
/** Waits for the connection request to be approved. */
|
|
40
|
+
waitForApproval(): Promise<void>
|
|
41
|
+
/** Registers the application with the indexer using the provided mnemonic. */
|
|
42
|
+
register(mnemonic: string): Promise<Sdk>
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** An object event from the indexer. */
|
|
46
|
+
export declare class ObjectEvent {
|
|
47
|
+
get id(): string
|
|
48
|
+
get deleted(): boolean
|
|
49
|
+
get updatedAt(): Date
|
|
50
|
+
get object(): PinnedObject | null
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* A packed upload allows multiple objects to be uploaded together in a single
|
|
55
|
+
* upload. This can be more efficient than individual uploads for many small
|
|
56
|
+
* objects since they share slabs.
|
|
57
|
+
*/
|
|
58
|
+
export declare class PackedUpload {
|
|
59
|
+
/**
|
|
60
|
+
* Returns the number of bytes remaining until reaching the optimal
|
|
61
|
+
* packed size. Adding objects larger than this will start a new slab.
|
|
62
|
+
*/
|
|
63
|
+
remaining(): bigint
|
|
64
|
+
/** Returns the number of bytes added so far. */
|
|
65
|
+
length(): bigint
|
|
66
|
+
/** Returns the number of slabs in the upload. */
|
|
67
|
+
slabs(): bigint
|
|
68
|
+
/**
|
|
69
|
+
* Adds a new object to the upload. The data will be read until EOF and
|
|
70
|
+
* packed into the upload. Call `finalize()` after all objects have been added.
|
|
71
|
+
*/
|
|
72
|
+
add(stream: ReadableStream): Promise<bigint>
|
|
73
|
+
/** Cancels the upload. */
|
|
74
|
+
cancel(): Promise<void>
|
|
75
|
+
/**
|
|
76
|
+
* Finalizes the upload and returns the resulting objects. Each object
|
|
77
|
+
* must be pinned separately with `sdk.pinObject()`.
|
|
78
|
+
*/
|
|
79
|
+
finalize(): Promise<Array<PinnedObject>>
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** An object pinned to an indexer. */
|
|
83
|
+
export declare class PinnedObject {
|
|
84
|
+
/** Creates a new empty object. */
|
|
85
|
+
constructor()
|
|
86
|
+
/** Opens a sealed object using the provided app key. */
|
|
87
|
+
static open(appKey: AppKey, sealed: SealedObject): PinnedObject
|
|
88
|
+
/** Seals the object for offline storage. */
|
|
89
|
+
seal(appKey: AppKey): SealedObject
|
|
90
|
+
/** Returns the object's ID. */
|
|
91
|
+
id(): string
|
|
92
|
+
/** Returns the total size of the object. */
|
|
93
|
+
size(): bigint
|
|
94
|
+
/** Returns the total encoded size after erasure coding. */
|
|
95
|
+
encodedSize(): bigint
|
|
96
|
+
/** Returns the slabs that make up the object. */
|
|
97
|
+
slabs(): Array<Slab>
|
|
98
|
+
/** Returns the metadata associated with the object. */
|
|
99
|
+
metadata(): Buffer
|
|
100
|
+
/** Updates the metadata associated with the object. */
|
|
101
|
+
updateMetadata(metadata: Buffer): void
|
|
102
|
+
/** Returns the time the object was created (ms since epoch). */
|
|
103
|
+
createdAt(): Date
|
|
104
|
+
/** Returns the time the object was last updated (ms since epoch). */
|
|
105
|
+
updatedAt(): Date
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export declare class Sdk {
|
|
109
|
+
/** Returns the application key used by the SDK. */
|
|
110
|
+
appKey(): AppKey
|
|
111
|
+
/**
|
|
112
|
+
* Creates a new packed upload for efficiently uploading multiple small
|
|
113
|
+
* objects together. Returns a `PackedUpload` handle.
|
|
114
|
+
*/
|
|
115
|
+
uploadPacked(options?: UploadOptions): PackedUpload
|
|
116
|
+
/**
|
|
117
|
+
* Uploads data to the Sia network.
|
|
118
|
+
*
|
|
119
|
+
* Pass a new `PinnedObject` for new uploads. To resume a previous upload,
|
|
120
|
+
* pass the object returned from the earlier call. Appending data changes
|
|
121
|
+
* an object's ID. It must be re-pinned afterward and any references to
|
|
122
|
+
* the previous ID must be updated.
|
|
123
|
+
*/
|
|
124
|
+
upload(object: PinnedObject, stream: ReadableStream, options?: UploadOptions): Promise<PinnedObject>
|
|
125
|
+
/**
|
|
126
|
+
* Downloads an object from the Sia network, returning a `ReadableStream`
|
|
127
|
+
* of the object's data.
|
|
128
|
+
*/
|
|
129
|
+
download(object: PinnedObject, options?: DownloadOptions | undefined | null): ReadableStream
|
|
130
|
+
/** Returns a list of all usable hosts. */
|
|
131
|
+
hosts(): Promise<Array<Host>>
|
|
132
|
+
/** Returns object events from the indexer for syncing. */
|
|
133
|
+
objectEvents(cursor: ObjectsCursor | undefined | null, limit: number): Promise<Array<ObjectEvent>>
|
|
134
|
+
/** Updates the metadata of an object stored in the indexer. */
|
|
135
|
+
updateObjectMetadata(object: PinnedObject): Promise<void>
|
|
136
|
+
/** Deletes an object from the indexer. */
|
|
137
|
+
deleteObject(key: string): Promise<void>
|
|
138
|
+
/** Returns metadata about a specific object. */
|
|
139
|
+
object(key: string): Promise<PinnedObject>
|
|
140
|
+
/** Returns metadata about a slab. */
|
|
141
|
+
slab(slabId: string): Promise<PinnedSlab>
|
|
142
|
+
/** Unpins slabs not used by any object on the account. */
|
|
143
|
+
pruneSlabs(): Promise<void>
|
|
144
|
+
/** Returns the current account. */
|
|
145
|
+
account(): Promise<Account>
|
|
146
|
+
/** Creates a signed URL for sharing an object. */
|
|
147
|
+
shareObject(object: PinnedObject, validUntil: Date): string
|
|
148
|
+
/** Retrieves a shared object from a signed URL. */
|
|
149
|
+
sharedObject(sharedUrl: string): Promise<PinnedObject>
|
|
150
|
+
/** Pins an object to the indexer. */
|
|
151
|
+
pinObject(object: PinnedObject): Promise<void>
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/** An account registered on the indexer. */
|
|
155
|
+
export interface Account {
|
|
156
|
+
accountKey: string
|
|
157
|
+
maxPinnedData: bigint
|
|
158
|
+
remainingStorage: bigint
|
|
159
|
+
pinnedData: bigint
|
|
160
|
+
pinnedSize: bigint
|
|
161
|
+
ready: boolean
|
|
162
|
+
app: App
|
|
163
|
+
lastUsed: Date
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/** The protocol used in a network address. */
|
|
167
|
+
export declare const enum AddressProtocol {
|
|
168
|
+
SiaMux = 'SiaMux',
|
|
169
|
+
Quic = 'Quic'
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/** Application info. */
|
|
173
|
+
export interface App {
|
|
174
|
+
id: string
|
|
175
|
+
name: string
|
|
176
|
+
description: string
|
|
177
|
+
serviceUrl?: string
|
|
178
|
+
logoUrl?: string
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/** Metadata about an application connecting to the indexer. */
|
|
182
|
+
export interface AppMetadata {
|
|
183
|
+
id: Buffer
|
|
184
|
+
name: string
|
|
185
|
+
description: string
|
|
186
|
+
serviceUrl: string
|
|
187
|
+
logoUrl?: string
|
|
188
|
+
callbackUrl?: string
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/** Download options. */
|
|
192
|
+
export interface DownloadOptions {
|
|
193
|
+
maxInflight?: number
|
|
194
|
+
offset?: bigint
|
|
195
|
+
length?: bigint
|
|
196
|
+
onShardDownloaded?: (progress: ShardProgress) => void
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/** Calculates the encoded size of data given the original size and erasure coding parameters. */
|
|
200
|
+
export declare function encodedSize(size: bigint, dataShards: number, parityShards: number): bigint
|
|
201
|
+
|
|
202
|
+
/** Generates a new BIP-39 12-word recovery phrase. */
|
|
203
|
+
export declare function generateRecoveryPhrase(): string
|
|
204
|
+
|
|
205
|
+
/** Information about a storage provider on the Sia network. */
|
|
206
|
+
export interface Host {
|
|
207
|
+
publicKey: string
|
|
208
|
+
addresses: Array<NetAddress>
|
|
209
|
+
countryCode: string
|
|
210
|
+
latitude: number
|
|
211
|
+
longitude: number
|
|
212
|
+
goodForUpload: boolean
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/** A network address of a storage provider on the Sia network. */
|
|
216
|
+
export interface NetAddress {
|
|
217
|
+
protocol: AddressProtocol
|
|
218
|
+
address: string
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/** A cursor for paginating through objects. */
|
|
222
|
+
export interface ObjectsCursor {
|
|
223
|
+
id: string
|
|
224
|
+
after: Date
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/** A sector stored on a specific host. */
|
|
228
|
+
export interface PinnedSector {
|
|
229
|
+
root: string
|
|
230
|
+
hostKey: string
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/** A pinned slab from the indexer. */
|
|
234
|
+
export interface PinnedSlab {
|
|
235
|
+
id: string
|
|
236
|
+
encryptionKey: Buffer
|
|
237
|
+
minShards: number
|
|
238
|
+
sectors: Array<PinnedSector>
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/** A sealed object for offline storage. */
|
|
242
|
+
export interface SealedObject {
|
|
243
|
+
id: string
|
|
244
|
+
encryptedDataKey: Buffer
|
|
245
|
+
encryptedMetadataKey: Buffer
|
|
246
|
+
slabs: Array<Slab>
|
|
247
|
+
encryptedMetadata: Buffer
|
|
248
|
+
dataSignature: Buffer
|
|
249
|
+
metadataSignature: Buffer
|
|
250
|
+
createdAt: Date
|
|
251
|
+
updatedAt: Date
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* Sets a logging callback to receive log messages from the SDK.
|
|
256
|
+
*
|
|
257
|
+
* The callback receives formatted log messages as strings.
|
|
258
|
+
* `level` should be one of: "off", "error", "warn", "info", "debug", "trace".
|
|
259
|
+
*/
|
|
260
|
+
export declare function setLogger(callback: (message: string) => void, level: "off" | "error" | "warn" | "info" | "debug" | "trace"): void
|
|
261
|
+
|
|
262
|
+
/** Progress information about a successfully uploaded or downloaded shard. */
|
|
263
|
+
export interface ShardProgress {
|
|
264
|
+
hostKey: string
|
|
265
|
+
shardSize: number
|
|
266
|
+
shardIndex: number
|
|
267
|
+
slabIndex: number
|
|
268
|
+
elapsedMs: number
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/** A slab representing a contiguous erasure-coded segment of a file. */
|
|
272
|
+
export interface Slab {
|
|
273
|
+
encryptionKey: Buffer
|
|
274
|
+
minShards: number
|
|
275
|
+
sectors: Array<PinnedSector>
|
|
276
|
+
offset: number
|
|
277
|
+
length: number
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/** Upload options. */
|
|
281
|
+
export interface UploadOptions {
|
|
282
|
+
maxInflight?: number
|
|
283
|
+
dataShards?: number
|
|
284
|
+
parityShards?: number
|
|
285
|
+
onShardUploaded?: (progress: ShardProgress) => void
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/** Validates a BIP-39 recovery phrase. */
|
|
289
|
+
export declare function validateRecoveryPhrase(phrase: string): void
|
|
290
|
+
|
|
291
|
+
export declare function initSia(): Promise<void>
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@siafoundation/sia-storage",
|
|
3
|
+
"version": "0.0.8",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"wasm"
|
|
10
|
+
],
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"browser": "./dist/index.js",
|
|
15
|
+
"bun": "./dist/index.node.cjs",
|
|
16
|
+
"node": {
|
|
17
|
+
"types": "./dist/index.node.d.ts",
|
|
18
|
+
"require": "./dist/index.node.cjs",
|
|
19
|
+
"import": "./dist/index.node.cjs"
|
|
20
|
+
},
|
|
21
|
+
"default": "./dist/index.js"
|
|
22
|
+
},
|
|
23
|
+
"./wasm": "./wasm/sia_storage_wasm.js",
|
|
24
|
+
"./wasm/*": "./wasm/*"
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "bun run build-wasm && tsup && bun run scripts/build-node-types.ts",
|
|
28
|
+
"build-wasm": "bun run scripts/build-wasm.ts",
|
|
29
|
+
"setup": "bun run scripts/setup-rust.ts",
|
|
30
|
+
"setup-napi-test": "bun run scripts/setup-napi-test.ts",
|
|
31
|
+
"test": "bun test src/tests/install-integration.test.ts",
|
|
32
|
+
"test:browser": "bun test src/tests/vite-integration.test.ts src/tests/esbuild-integration.test.ts src/tests/webpack-integration.test.ts src/tests/rollup-integration.test.ts src/tests/nextjs-integration.test.ts",
|
|
33
|
+
"test:all": "bun test",
|
|
34
|
+
"prepublishOnly": "bun run build && bun test",
|
|
35
|
+
"publish-npm": "bun run scripts/publish.ts"
|
|
36
|
+
},
|
|
37
|
+
"optionalDependencies": {
|
|
38
|
+
"@siafoundation/sia-storage-darwin-arm64": "0.0.8",
|
|
39
|
+
"@siafoundation/sia-storage-darwin-x64": "0.0.8",
|
|
40
|
+
"@siafoundation/sia-storage-linux-x64-gnu": "0.0.8",
|
|
41
|
+
"@siafoundation/sia-storage-linux-arm64-gnu": "0.0.8",
|
|
42
|
+
"@siafoundation/sia-storage-win32-x64-msvc": "0.0.8"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/bun": "^1.3.12",
|
|
46
|
+
"@types/node": "^25.3.5",
|
|
47
|
+
"playwright": "^1.58.2",
|
|
48
|
+
"tsup": "^8.4.0",
|
|
49
|
+
"typescript": "~5.9.3"
|
|
50
|
+
}
|
|
51
|
+
}
|