@artblocks/abx-storage 0.1.0-alpha.9 → 0.1.1

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 (48) hide show
  1. package/CHANGELOG.md +161 -0
  2. package/dist/arweave.d.ts +34 -47
  3. package/dist/arweave.d.ts.map +1 -1
  4. package/dist/arweave.js +64 -160
  5. package/dist/arweave.js.map +1 -1
  6. package/dist/backend.d.ts +1 -4
  7. package/dist/backend.d.ts.map +1 -1
  8. package/dist/backend.js +4 -33
  9. package/dist/backend.js.map +1 -1
  10. package/dist/content-index.d.ts.map +1 -1
  11. package/dist/content-index.js +3 -1
  12. package/dist/content-index.js.map +1 -1
  13. package/dist/content-plan.d.ts +78 -0
  14. package/dist/content-plan.d.ts.map +1 -0
  15. package/dist/content-plan.js +68 -0
  16. package/dist/content-plan.js.map +1 -0
  17. package/dist/fs.d.ts.map +1 -1
  18. package/dist/fs.js +3 -1
  19. package/dist/fs.js.map +1 -1
  20. package/dist/index.d.ts +7 -2
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +7 -2
  23. package/dist/index.js.map +1 -1
  24. package/dist/ipfs.d.ts +17 -1
  25. package/dist/ipfs.d.ts.map +1 -1
  26. package/dist/ipfs.js +60 -2
  27. package/dist/ipfs.js.map +1 -1
  28. package/dist/migrate.d.ts +37 -0
  29. package/dist/migrate.d.ts.map +1 -0
  30. package/dist/migrate.js +55 -0
  31. package/dist/migrate.js.map +1 -0
  32. package/dist/probe.d.ts +66 -0
  33. package/dist/probe.d.ts.map +1 -0
  34. package/dist/probe.js +155 -0
  35. package/dist/probe.js.map +1 -0
  36. package/dist/readiness.d.ts +72 -6
  37. package/dist/readiness.d.ts.map +1 -1
  38. package/dist/readiness.js +62 -34
  39. package/dist/readiness.js.map +1 -1
  40. package/dist/upload-readiness.d.ts +89 -0
  41. package/dist/upload-readiness.d.ts.map +1 -0
  42. package/dist/upload-readiness.js +85 -0
  43. package/dist/upload-readiness.js.map +1 -0
  44. package/dist/upload.d.ts +28 -0
  45. package/dist/upload.d.ts.map +1 -0
  46. package/dist/upload.js +41 -0
  47. package/dist/upload.js.map +1 -0
  48. package/package.json +17 -9
package/CHANGELOG.md ADDED
@@ -0,0 +1,161 @@
1
+ # @artblocks/abx-storage
2
+
3
+ ## 0.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies [7947ba9]
8
+ - @artblocks/abx-sdk@0.2.0
9
+
10
+ ## 0.1.0
11
+
12
+ ### Patch Changes
13
+
14
+ - 8f35dae: Prepare package metadata, release notes, and public-facing source comments for the initial public
15
+ source release.
16
+ - Updated dependencies [21e3d6c]
17
+ - Updated dependencies [22abce8]
18
+ - Updated dependencies [4d5e2b1]
19
+ - Updated dependencies [56973c4]
20
+ - Updated dependencies [2290b0a]
21
+ - Updated dependencies [b9197bc]
22
+ - Updated dependencies [8ccbede]
23
+ - Updated dependencies [d925eb1]
24
+ - Updated dependencies [ea57f7a]
25
+ - Updated dependencies [3ddba71]
26
+ - Updated dependencies [8f35dae]
27
+ - Updated dependencies [719b9fe]
28
+ - Updated dependencies [9065128]
29
+ - Updated dependencies [c2400a7]
30
+ - Updated dependencies [3d7fe3c]
31
+ - Updated dependencies [7b462e2]
32
+ - Updated dependencies [ddb2e0b]
33
+ - Updated dependencies [4512962]
34
+ - Updated dependencies [76cfc6a]
35
+ - Updated dependencies [5522192]
36
+ - @artblocks/abx-sdk@0.1.0
37
+
38
+ ## 0.1.0-alpha.49
39
+
40
+ ### Patch Changes
41
+
42
+ - Updated dependencies [719b9fe]
43
+ - @artblocks/abx-sdk@0.1.0-alpha.49
44
+
45
+ ## 0.1.0-alpha.48
46
+
47
+ ### Patch Changes
48
+
49
+ - Updated dependencies [4d5e2b1]
50
+ - @artblocks/abx-sdk@0.1.0-alpha.48
51
+
52
+ ## 0.1.0-alpha.47
53
+
54
+ ### Patch Changes
55
+
56
+ - Updated dependencies [56973c4]
57
+ - @artblocks/abx-sdk@0.1.0-alpha.47
58
+
59
+ ## 0.1.0-alpha.46
60
+
61
+ ### Patch Changes
62
+
63
+ - Updated dependencies [ddb2e0b]
64
+ - Updated dependencies [76cfc6a]
65
+ - @artblocks/abx-sdk@0.1.0-alpha.46
66
+
67
+ ## 0.1.0-alpha.45
68
+
69
+ ### Patch Changes
70
+
71
+ - Updated dependencies [d925eb1]
72
+ - @artblocks/abx-sdk@0.1.0-alpha.45
73
+
74
+ ## 0.1.0-alpha.44
75
+
76
+ ### Patch Changes
77
+
78
+ - Updated dependencies [22abce8]
79
+ - @artblocks/abx-sdk@0.1.0-alpha.44
80
+
81
+ ## 0.1.0-alpha.43
82
+
83
+ ### Patch Changes
84
+
85
+ - Updated dependencies [2290b0a]
86
+ - @artblocks/abx-sdk@0.1.0-alpha.43
87
+
88
+ ## 0.1.0-alpha.42
89
+
90
+ ### Patch Changes
91
+
92
+ - Updated dependencies [ea57f7a]
93
+ - @artblocks/abx-sdk@0.1.0-alpha.42
94
+
95
+ ## 0.1.0-alpha.41
96
+
97
+ ### Patch Changes
98
+
99
+ - Updated dependencies [8ccbede]
100
+ - @artblocks/abx-sdk@0.1.0-alpha.41
101
+
102
+ ## 0.1.0-alpha.40
103
+
104
+ ### Patch Changes
105
+
106
+ - Updated dependencies [b9197bc]
107
+ - @artblocks/abx-sdk@0.1.0-alpha.40
108
+
109
+ ## 0.1.0-alpha.39
110
+
111
+ ### Patch Changes
112
+
113
+ - Updated dependencies [3d7fe3c]
114
+ - Updated dependencies [7b462e2]
115
+ - @artblocks/abx-sdk@0.1.0-alpha.39
116
+
117
+ ## 0.1.0-alpha.38
118
+
119
+ ### Patch Changes
120
+
121
+ - Updated dependencies [c2400a7]
122
+ - @artblocks/abx-sdk@0.1.0-alpha.38
123
+
124
+ ## 0.1.0-alpha.37
125
+
126
+ ### Patch Changes
127
+
128
+ - Updated dependencies [4512962]
129
+ - @artblocks/abx-sdk@0.1.0-alpha.37
130
+
131
+ ## 0.1.0-alpha.36
132
+
133
+ ### Patch Changes
134
+
135
+ - Updated dependencies [5522192]
136
+ - @artblocks/abx-sdk@0.1.0-alpha.36
137
+
138
+ ## 0.1.0-alpha.35
139
+
140
+ ### Patch Changes
141
+
142
+ - Updated dependencies [21e3d6c]
143
+ - Updated dependencies [a73922c]
144
+ - @artblocks/abx-sdk@0.1.0-alpha.35
145
+
146
+ ## 0.1.0-alpha.34
147
+
148
+ ### Patch Changes
149
+
150
+ - Updated dependencies [3ddba71]
151
+ - Updated dependencies [9065128]
152
+ - @artblocks/abx-sdk@0.1.0-alpha.34
153
+
154
+ ## 0.1.0-alpha.33
155
+
156
+ ### Patch Changes
157
+
158
+ - 9242a05: Prepare package metadata, release notes, and public-facing source comments for the initial public
159
+ source release.
160
+ - Updated dependencies [9242a05]
161
+ - @artblocks/abx-sdk@0.1.0-alpha.33
package/dist/arweave.d.ts CHANGED
@@ -10,10 +10,16 @@ import { type ArweaveJwk } from './arweave-identity.js';
10
10
  * Upload must go through a bundler that signs an ANS-104 data item, so the uploader is a
11
11
  * **swappable provider** behind {@link ArweaveUploader}:
12
12
  *
13
- * - **`turbo`** (default, recommended) — {@link TurboUploader}, backed by ArDrive Turbo. Uploads
14
- * under 100 KiB are **free with no setup**; larger uploads draw on prepaid credits you top up
15
- * with a card (or crypto). Lazy-loads the optional `@ardrive/turbo-sdk` only when an upload or
16
- * top-up actually runs, so the retrieve-only resolver path stays dependency-free.
13
+ * - **`turbo`** (default, recommended) — backed by ArDrive Turbo. Uploads under 100 KiB are
14
+ * **free with no setup**; larger uploads draw on prepaid credits you top up with a card (or
15
+ * crypto). The actual Turbo/arbundles implementation lives in the SEPARATE, OPTIONAL
16
+ * `@artblocks/abx-storage-arweave` package — `@ardrive/turbo-sdk` depends on
17
+ * `x402-fetch` -> `x402` -> `wagmi`, which drags in the entire browser wallet-connector
18
+ * ecosystem, so a default CLI/SDK install must never pull it in. `buildUploader` below
19
+ * `await import()`s it only when an upload/balance/top-up actually runs — never for retrieval
20
+ * (get/locator/health) and never merely because `arweave` is the configured backend — and
21
+ * throws a clear "install this package" error if it isn't present. `npm install
22
+ * @artblocks/abx-storage-arweave` to use it.
17
23
  * - **`http-bundler`** — {@link HttpBundlerUploader}, a dep-free token-authenticated POST to a
18
24
  * managed endpoint you run/point at (the escape hatch / bring-your-own-bundler).
19
25
  *
@@ -161,15 +167,6 @@ export declare function isEthIdentity(id: TurboIdentity): id is Extract<TurboIde
161
167
  /** The credit-holding / signing address for an identity — Arweave `base64url(sha256(n))` or an
162
168
  * EVM `0x…`. Pure derivation, no network. Its balance is what `abx storage balance` reports. */
163
169
  export declare function turboIdentityAddress(id: TurboIdentity): string;
164
- /**
165
- * The Arweave data-item id from a Turbo `uploadFile` response. Normally `res.id`; but Turbo
166
- * **deduplicates identical bytes** — a re-upload of the same data item (same signer + tags + bytes →
167
- * same deterministic id) returns a plain-text `"Data item with ID <id> has already been uploaded to
168
- * this service!"` instead of the usual JSON. Both are success: the bytes ARE on Turbo. We extract
169
- * the 43-char base64url txid so idempotent re-uploads (retries, redeploys, duplicate images in a
170
- * series) resolve to the real locator instead of throwing. Returns null if no id is present.
171
- */
172
- export declare function turboUploadId(res: unknown): string | null;
173
170
  /** Dep-free uploader for token-authenticated managed Arweave upload endpoints. */
174
171
  export declare class HttpBundlerUploader implements ArweaveUploader {
175
172
  private readonly cfg;
@@ -181,31 +178,6 @@ export declare class HttpBundlerUploader implements ArweaveUploader {
181
178
  id: string;
182
179
  }>;
183
180
  }
184
- /**
185
- * ArDrive Turbo uploader — the recommended Arweave path. Lazy-loads the optional
186
- * `@ardrive/turbo-sdk` only when an upload / balance / top-up actually runs (the retrieve-only
187
- * resolver never touches it). The signing {@link TurboIdentity} is multi-chain: the CLI-managed
188
- * Arweave JWK (default), an `.env` EVM key, or a remote browser wallet — each both signs uploads
189
- * and holds the prepaid credits at its own address.
190
- */
191
- export declare class TurboUploader implements ArweaveUploader {
192
- private readonly identity;
193
- constructor(identity: TurboIdentity);
194
- private sdk;
195
- /** arbundles (the signing lib Turbo uses) — for `InjectedEthereumSigner`, which turbo-sdk does NOT
196
- * re-export. Optional dep, loaded only on the remote-wallet upload path. */
197
- private arbundles;
198
- private clientPromise?;
199
- private client;
200
- /** Authenticate a Turbo client for the selected identity. Arweave uses the JWK directly; an EVM
201
- * identity uses an arbundles `EthereumSigner` (local key) or `InjectedEthereumSigner` (remote
202
- * wallet) — the SDK re-exports both, so no direct arbundles dependency. */
203
- private buildClient;
204
- upload(bytes: Uint8Array, contentType: string): Promise<{
205
- id: string;
206
- }>;
207
- readonly funding: ArweaveFunding;
208
- }
209
181
  /** The upload route for a config: explicit `provider`, else `http-bundler` when an `uploadUrl`
210
182
  * is set, else the recommended `turbo`. */
211
183
  export declare function arweaveProvider(cfg: ArweaveConfig): ArweaveProvider;
@@ -214,7 +186,7 @@ export declare function arweaveProvider(cfg: ArweaveConfig): ArweaveProvider;
214
186
  * none — capability negotiation, so `abx storage topup`/`balance` dispatch through one verb and
215
187
  * a crypto-only provider says "fund the wallet directly" rather than pretending.
216
188
  */
217
- export declare function arweaveFunding(cfg: ArweaveConfig): ArweaveFunding;
189
+ export declare function arweaveFunding(cfg: ArweaveConfig): Promise<ArweaveFunding>;
218
190
  export declare class ArweaveBackend implements StorageBackend {
219
191
  private readonly cfg;
220
192
  readonly id = "arweave";
@@ -223,13 +195,17 @@ export declare class ArweaveBackend implements StorageBackend {
223
195
  private readonly injectedUploader?;
224
196
  constructor(cfg: ArweaveConfig, dataDir?: string, uploader?: ArweaveUploader);
225
197
  /** Built lazily on first use — retrieval (get/locator/health, the resolver path) needs only the
226
- * gateway, never an upload identity or the Turbo SDK. `mint` (passed by the write ops) lets a
227
- * managed default create its key here; reads/probes pass false so they never mint. */
198
+ * gateway, never an upload identity or the optional Turbo package. `mint` (passed by the write
199
+ * ops) lets a managed default create its key here; reads/probes pass false so they never mint.
200
+ * `??=` short-circuits on an already-built or explicitly injected uploader, so the `turbo` path
201
+ * never awaits (and so never triggers) `buildUploader`'s `@artblocks/abx-storage-arweave` import
202
+ * unless one is actually needed. */
228
203
  private uploader;
229
204
  /** Funding capability of the active provider, or null if it has none (e.g. http-bundler) or
230
- * can't yet be built (e.g. Turbo without an identity key). The CLI uses {@link arweaveFunding}
231
- * directly for an actionable error; this accessor is the safe boolean-ish capability probe. */
232
- funding(): ArweaveFunding | null;
205
+ * can't yet be built (e.g. Turbo without an identity key, or the optional package not installed).
206
+ * The CLI uses {@link arweaveFunding} directly for an actionable error; this accessor is the safe
207
+ * boolean-ish capability probe. */
208
+ funding(): Promise<ArweaveFunding | null>;
233
209
  put(hash: Hex, content: StoredContent): Promise<void>;
234
210
  get(hash: Hex): Promise<StoredContent | null>;
235
211
  has(hash: Hex): Promise<boolean>;
@@ -256,8 +232,17 @@ export declare class ArweaveBackend implements StorageBackend {
256
232
  * secrets). `ABX_ARWEAVE_ETH_SIGNER_KEY` selects an EVM Turbo identity (the CLI usually sets this
257
233
  * from the resolved signing key instead). */
258
234
  export declare function arweaveConfigFromEnv(): ArweaveConfig;
259
- /** Where the CLI keeps the Turbo identity it creates and manages on first upload. */
260
- export declare function arweaveKeyFilePath(): string;
235
+ /**
236
+ * Where the CLI keeps the Turbo identity it creates and manages on first upload.
237
+ *
238
+ * `dataDir`, when given, is the CALLER'S already-resolved data directory (the CLI passes its own
239
+ * `dataDir()` — see `config.ts`) — pass it whenever one is available so this can't disagree with
240
+ * wherever the caller's SQLite projection / content index live (the data-directory coherence
241
+ * criterion). Omit it only for a caller with no data-dir context of its own (e.g. an SDK
242
+ * integrator reading `arweaveConfigFromEnv()` directly), which falls back to the same centralized
243
+ * `resolveDataDir()` every other unparameterized call site uses.
244
+ */
245
+ export declare function arweaveKeyFilePath(dataDir?: string): string;
261
246
  /**
262
247
  * The ONE place either layer resolves an Arweave identity: `ARWEAVE_JWK` (an explicit, inline
263
248
  * secret) if set, else the CLI-managed key file.
@@ -268,6 +253,8 @@ export declare function arweaveKeyFilePath(): string;
268
253
  * with "Arweave via Turbo needs an identity". The message said storage was never configured; the
269
254
  * truth was that two layers disagreed about where the identity lives, and it named neither the file
270
255
  * nor the mismatch. They reimplemented this lookup themselves to get moving.
256
+ *
257
+ * `dataDir` forwards straight to {@link arweaveKeyFilePath} — see its doc comment.
271
258
  */
272
- export declare function resolveArweaveJwk(): ArweaveJwk | undefined;
259
+ export declare function resolveArweaveJwk(dataDir?: string): ArweaveJwk | undefined;
273
260
  //# sourceMappingURL=arweave.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"arweave.d.ts","sourceRoot":"","sources":["../src/arweave.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"arweave.d.ts","sourceRoot":"","sources":["../src/arweave.ts"],"names":[],"mappings":"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"}
package/dist/arweave.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import { existsSync, readFileSync } from 'node:fs';
2
2
  import { resolve as resolvePath } from 'node:path';
3
+ import { resolveDataDir } from '@artblocks/abx-sdk/node';
3
4
  import { privateKeyToAccount } from 'viem/accounts';
4
5
  import { ContentIndex } from './content-index.js';
5
6
  import { arweaveAddress } from './arweave-identity.js';
@@ -122,7 +123,6 @@ export function isEthIdentity(id) {
122
123
  return id.kind === 'ethereum' || id.kind === 'ethereum-remote';
123
124
  }
124
125
  const withHexPrefix = (k) => (k.startsWith('0x') ? k : `0x${k}`);
125
- const stripHexPrefix = (k) => (k.startsWith('0x') ? k.slice(2) : k);
126
126
  /** The credit-holding / signing address for an identity — Arweave `base64url(sha256(n))` or an
127
127
  * EVM `0x…`. Pure derivation, no network. Its balance is what `abx storage balance` reports. */
128
128
  export function turboIdentityAddress(id) {
@@ -136,42 +136,11 @@ export function turboIdentityAddress(id) {
136
136
  }
137
137
  }
138
138
  const trim = (u) => u.replace(/\/+$/, '');
139
- /** Coerce a Turbo `uploadFile` response to text. It's normally an object, but the idempotent
140
- * "already uploaded" path returns a plain string (which JSON/stream layers may surface as a
141
- * char-indexed object) — Object.values(...).join('') recovers it either way. */
142
- function turboResponseText(res) {
143
- if (typeof res === 'string')
144
- return res;
145
- if (res && typeof res === 'object') {
146
- if ('id' in res && res.id)
147
- return String(res.id);
148
- try {
149
- return Object.values(res).join('');
150
- }
151
- catch {
152
- return '';
153
- }
154
- }
155
- return '';
156
- }
157
- /**
158
- * The Arweave data-item id from a Turbo `uploadFile` response. Normally `res.id`; but Turbo
159
- * **deduplicates identical bytes** — a re-upload of the same data item (same signer + tags + bytes →
160
- * same deterministic id) returns a plain-text `"Data item with ID <id> has already been uploaded to
161
- * this service!"` instead of the usual JSON. Both are success: the bytes ARE on Turbo. We extract
162
- * the 43-char base64url txid so idempotent re-uploads (retries, redeploys, duplicate images in a
163
- * series) resolve to the real locator instead of throwing. Returns null if no id is present.
164
- */
165
- export function turboUploadId(res) {
166
- if (res && typeof res === 'object' && 'id' in res && res.id) {
167
- return String(res.id);
168
- }
169
- const m = turboResponseText(res).match(/\bID\s+([A-Za-z0-9_-]{43})\b/);
170
- return m ? m[1] : null;
171
- }
172
- /** Optional deps, loaded lazily via indirect specifiers so they're not required to install/build. */
173
- const TURBO_SDK_PACKAGE = '@ardrive/turbo-sdk';
174
- const ARBUNDLES_PACKAGE = '@dha-team/arbundles';
139
+ /** The optional package carrying the Turbo/arbundles implementation — loaded lazily
140
+ * via an INDIRECT specifier (a variable, not a string literal) so TypeScript resolves the
141
+ * `import()` below as `any` instead of trying to resolve real types for a package this file
142
+ * deliberately has no build-time dependency on (see the module doc and {@link buildUploader}). */
143
+ const TURBO_ARWEAVE_PACKAGE = '@artblocks/abx-storage-arweave';
175
144
  const WINC_PER_CREDIT = 1e12;
176
145
  const wincToCredits = (winc) => {
177
146
  const n = Number(winc) / WINC_PER_CREDIT;
@@ -200,115 +169,34 @@ export class HttpBundlerUploader {
200
169
  return { id: String(id) };
201
170
  }
202
171
  }
203
- /**
204
- * ArDrive Turbo uploader — the recommended Arweave path. Lazy-loads the optional
205
- * `@ardrive/turbo-sdk` only when an upload / balance / top-up actually runs (the retrieve-only
206
- * resolver never touches it). The signing {@link TurboIdentity} is multi-chain: the CLI-managed
207
- * Arweave JWK (default), an `.env` EVM key, or a remote browser wallet — each both signs uploads
208
- * and holds the prepaid credits at its own address.
209
- */
210
- export class TurboUploader {
211
- identity;
212
- constructor(identity) {
213
- this.identity = identity;
214
- if (identity.kind === 'arweave' && !identity.jwk?.n) {
215
- throw new Error('Turbo needs an Arweave identity key (JWK). The CLI manages one at `.abx-self-host/arweave-key.json` — or set ARWEAVE_JWK, or use `--provider http-bundler`.');
216
- }
217
- if (identity.kind === 'ethereum' && !identity.privateKey) {
218
- throw new Error('Turbo Ethereum identity needs a private key.');
219
- }
220
- }
221
- async sdk() {
222
- try {
223
- // Indirect specifier: keeps the OPTIONAL dep out of the type graph so the package
224
- // type-checks and runs without it installed (the retrieve-only resolver path never calls this).
225
- return await import(/* @vite-ignore */ TURBO_SDK_PACKAGE);
226
- }
227
- catch {
228
- throw new Error("The Turbo provider needs the optional '@ardrive/turbo-sdk' package — install it (`pnpm add @ardrive/turbo-sdk`), or switch with `--backend arweave --provider http-bundler --upload-url <bundler>`.");
229
- }
230
- }
231
- /** arbundles (the signing lib Turbo uses) — for `InjectedEthereumSigner`, which turbo-sdk does NOT
232
- * re-export. Optional dep, loaded only on the remote-wallet upload path. */
233
- async arbundles() {
234
- try {
235
- return await import(/* @vite-ignore */ ARBUNDLES_PACKAGE);
236
- }
237
- catch {
238
- throw new Error("The browser-wallet Arweave upload lane needs the optional '@dha-team/arbundles' package — install it (`pnpm add @dha-team/arbundles`), or use `--storage-signer eth` with a key in .env, or the managed Arweave key.");
239
- }
240
- }
241
- clientPromise;
242
- client() {
243
- return (this.clientPromise ??= this.buildClient());
244
- }
245
- /** Authenticate a Turbo client for the selected identity. Arweave uses the JWK directly; an EVM
246
- * identity uses an arbundles `EthereumSigner` (local key) or `InjectedEthereumSigner` (remote
247
- * wallet) — the SDK re-exports both, so no direct arbundles dependency. */
248
- async buildClient() {
249
- const m = await this.sdk();
250
- const id = this.identity;
251
- if (id.kind === 'arweave') {
252
- return m.TurboFactory.authenticated({ privateKey: id.jwk, token: 'arweave' });
253
- }
254
- if (id.kind === 'ethereum') {
255
- const signer = new m.EthereumSigner(stripHexPrefix(id.privateKey));
256
- return m.TurboFactory.authenticated({ signer, token: 'ethereum' });
257
- }
258
- // ethereum-remote: drive arbundles' own InjectedEthereumSigner via a provider shim that
259
- // round-trips each signMessage to the browser wallet. arbundles calls `signer.signMessage(msg)`
260
- // with a STRING challenge (setPublicKey → pubkey recovery, one prompt) and a Uint8Array per data
261
- // item, and expects back a `0x…` hex signature (it does `sig.slice(2)`). ethers'
262
- // signMessage(string) ≡ signMessage(utf8Bytes(string)), so normalizing to bytes is faithful.
263
- // NOTE: turbo-sdk re-exports EthereumSigner but NOT InjectedEthereumSigner — import it from
264
- // arbundles (the same package turbo signs with) directly.
265
- const { InjectedEthereumSigner } = await this.arbundles();
266
- const signMessage = id.signMessage;
267
- const provider = {
268
- getSigner: () => ({
269
- signMessage: (message) => signMessage(typeof message === 'string' ? new TextEncoder().encode(message) : Uint8Array.from(message)),
270
- }),
271
- };
272
- const signer = new InjectedEthereumSigner(provider);
273
- await signer.setPublicKey();
274
- return m.TurboFactory.authenticated({ signer, token: 'ethereum' });
275
- }
276
- async upload(bytes, contentType) {
277
- const turbo = await this.client();
278
- const { Readable } = await import('node:stream');
279
- const buf = Buffer.from(bytes);
280
- const res = await turbo.uploadFile({
281
- fileStreamFactory: () => Readable.from(buf),
282
- fileSizeFactory: () => buf.byteLength,
283
- dataItemOpts: { tags: [{ name: 'Content-Type', value: contentType }] },
284
- });
285
- const id = turboUploadId(res);
286
- if (!id)
287
- throw new Error(`Turbo upload returned no transaction id (response: ${turboResponseText(res).slice(0, 200)})`);
288
- return { id };
289
- }
290
- funding = {
291
- address: async () => turboIdentityAddress(this.identity),
292
- balance: async () => {
293
- const turbo = await this.client();
294
- const { winc } = (await turbo.getBalance());
295
- return { winc: String(winc), credits: wincToCredits(winc) };
296
- },
297
- topup: async ({ usd }) => {
298
- const [turbo, m] = await Promise.all([this.client(), this.sdk()]);
299
- const session = (await turbo.createCheckoutSession({ amount: m.USD(usd), owner: turboIdentityAddress(this.identity) }));
300
- if (!session?.url)
301
- throw new Error('Turbo top-up returned no checkout URL');
302
- return { url: String(session.url), winc: String(session.winc ?? '') };
303
- },
304
- };
305
- }
306
172
  /** The upload route for a config: explicit `provider`, else `http-bundler` when an `uploadUrl`
307
173
  * is set, else the recommended `turbo`. */
308
174
  export function arweaveProvider(cfg) {
309
175
  return cfg.provider ?? (cfg.uploadUrl ? 'http-bundler' : 'turbo');
310
176
  }
311
- function buildUploader(cfg, opts = {}) {
177
+ /**
178
+ * Loads the optional `@artblocks/abx-storage-arweave` package and constructs its `TurboUploader`
179
+ * for `id` — the ONLY place this file reaches for that package, and only on this call path (never
180
+ * for retrieval/health). A clean install of `@artblocks/abx-cli` / `@artblocks/abx-storage` never
181
+ * installs it; this throws the actionable "install it, or switch provider" error the
182
+ * unavailable-adapter case needs.
183
+ *
184
+ * `TURBO_ARWEAVE_PACKAGE` is a variable, not a string literal, specifically so TypeScript types the
185
+ * `import()` result as `any` instead of trying (and failing) to resolve real declarations for a
186
+ * package this file has no build-time dependency on — this package's build/typecheck/test never
187
+ * needs `@artblocks/abx-storage-arweave` to be installed at all.
188
+ */
189
+ async function loadTurboUploader(id) {
190
+ let mod;
191
+ try {
192
+ mod = await import(/* @vite-ignore */ TURBO_ARWEAVE_PACKAGE);
193
+ }
194
+ catch {
195
+ throw new Error("The Turbo provider needs the optional '@artblocks/abx-storage-arweave' package — install it (`npm install @artblocks/abx-storage-arweave`), or switch with `--backend arweave --provider http-bundler --upload-url <bundler>`.");
196
+ }
197
+ return new mod.TurboUploader(id);
198
+ }
199
+ async function buildUploader(cfg, opts = {}) {
312
200
  if (arweaveProvider(cfg) === 'http-bundler') {
313
201
  return new HttpBundlerUploader({ uploadUrl: cfg.uploadUrl, token: cfg.token });
314
202
  }
@@ -319,15 +207,15 @@ function buildUploader(cfg, opts = {}) {
319
207
  if (!id) {
320
208
  throw new Error('Arweave via Turbo needs an identity. Run an upload through the CLI (it creates a managed key at `.abx-self-host/arweave-key.json`), set ARWEAVE_JWK, sign with an EVM key/wallet (`--storage-signer eth`), or use `--provider http-bundler --upload-url <bundler>`.');
321
209
  }
322
- return new TurboUploader(id);
210
+ return loadTurboUploader(id);
323
211
  }
324
212
  /**
325
213
  * The funding capability for a config's provider, or throw a clear reason if that provider has
326
214
  * none — capability negotiation, so `abx storage topup`/`balance` dispatch through one verb and
327
215
  * a crypto-only provider says "fund the wallet directly" rather than pretending.
328
216
  */
329
- export function arweaveFunding(cfg) {
330
- const f = buildUploader(cfg).funding;
217
+ export async function arweaveFunding(cfg) {
218
+ const f = (await buildUploader(cfg)).funding;
331
219
  if (!f)
332
220
  throw new Error(`The '${arweaveProvider(cfg)}' Arweave provider has no prepaid balance — fund its wallet directly.`);
333
221
  return f;
@@ -344,24 +232,29 @@ export class ArweaveBackend {
344
232
  this.injectedUploader = uploader;
345
233
  }
346
234
  /** Built lazily on first use — retrieval (get/locator/health, the resolver path) needs only the
347
- * gateway, never an upload identity or the Turbo SDK. `mint` (passed by the write ops) lets a
348
- * managed default create its key here; reads/probes pass false so they never mint. */
349
- uploader(mint = false) {
350
- return (this.uploaderInstance ??= this.injectedUploader ?? buildUploader(this.cfg, { mint }));
235
+ * gateway, never an upload identity or the optional Turbo package. `mint` (passed by the write
236
+ * ops) lets a managed default create its key here; reads/probes pass false so they never mint.
237
+ * `??=` short-circuits on an already-built or explicitly injected uploader, so the `turbo` path
238
+ * never awaits (and so never triggers) `buildUploader`'s `@artblocks/abx-storage-arweave` import
239
+ * unless one is actually needed. */
240
+ async uploader(mint = false) {
241
+ return (this.uploaderInstance ??= this.injectedUploader ?? (await buildUploader(this.cfg, { mint })));
351
242
  }
352
243
  /** Funding capability of the active provider, or null if it has none (e.g. http-bundler) or
353
- * can't yet be built (e.g. Turbo without an identity key). The CLI uses {@link arweaveFunding}
354
- * directly for an actionable error; this accessor is the safe boolean-ish capability probe. */
355
- funding() {
244
+ * can't yet be built (e.g. Turbo without an identity key, or the optional package not installed).
245
+ * The CLI uses {@link arweaveFunding} directly for an actionable error; this accessor is the safe
246
+ * boolean-ish capability probe. */
247
+ async funding() {
356
248
  try {
357
- return this.uploader(false).funding ?? null;
249
+ return (await this.uploader(false)).funding ?? null;
358
250
  }
359
251
  catch {
360
252
  return null;
361
253
  }
362
254
  }
363
255
  async put(hash, content) {
364
- const { id } = await this.uploader(true).upload(content.bytes, content.contentType);
256
+ const uploader = await this.uploader(true);
257
+ const { id } = await uploader.upload(content.bytes, content.contentType);
365
258
  this.index.set(hash, { pointer: id, contentType: content.contentType });
366
259
  }
367
260
  async get(hash) {
@@ -393,7 +286,7 @@ export class ArweaveBackend {
393
286
  * permanent, content-addressed root → integrity for the whole set, no per-file keccak needed.
394
287
  */
395
288
  async putDirectory(entries) {
396
- const up = this.uploader(true);
289
+ const up = await this.uploader(true);
397
290
  const paths = {};
398
291
  for (const e of entries) {
399
292
  const { id } = await up.upload(e.bytes, e.contentType);
@@ -446,10 +339,19 @@ export function arweaveConfigFromEnv() {
446
339
  ethSignerKey: process.env.ABX_ARWEAVE_ETH_SIGNER_KEY,
447
340
  };
448
341
  }
449
- /** Where the CLI keeps the Turbo identity it creates and manages on first upload. */
450
- export function arweaveKeyFilePath() {
451
- const dataDir = process.env.ABX_DATA_DIR ?? resolvePath(process.cwd(), '.abx-self-host');
452
- return process.env.ABX_ARWEAVE_KEY_FILE ?? resolvePath(dataDir, 'arweave-key.json');
342
+ /**
343
+ * Where the CLI keeps the Turbo identity it creates and manages on first upload.
344
+ *
345
+ * `dataDir`, when given, is the CALLER'S already-resolved data directory (the CLI passes its own
346
+ * `dataDir()` — see `config.ts`) — pass it whenever one is available so this can't disagree with
347
+ * wherever the caller's SQLite projection / content index live (the data-directory coherence
348
+ * criterion). Omit it only for a caller with no data-dir context of its own (e.g. an SDK
349
+ * integrator reading `arweaveConfigFromEnv()` directly), which falls back to the same centralized
350
+ * `resolveDataDir()` every other unparameterized call site uses.
351
+ */
352
+ export function arweaveKeyFilePath(dataDir) {
353
+ const dir = dataDir ?? resolveDataDir().dir;
354
+ return process.env.ABX_ARWEAVE_KEY_FILE ?? resolvePath(dir, 'arweave-key.json');
453
355
  }
454
356
  /**
455
357
  * The ONE place either layer resolves an Arweave identity: `ARWEAVE_JWK` (an explicit, inline
@@ -461,12 +363,14 @@ export function arweaveKeyFilePath() {
461
363
  * with "Arweave via Turbo needs an identity". The message said storage was never configured; the
462
364
  * truth was that two layers disagreed about where the identity lives, and it named neither the file
463
365
  * nor the mismatch. They reimplemented this lookup themselves to get moving.
366
+ *
367
+ * `dataDir` forwards straight to {@link arweaveKeyFilePath} — see its doc comment.
464
368
  */
465
- export function resolveArweaveJwk() {
369
+ export function resolveArweaveJwk(dataDir) {
466
370
  const fromEnv = parseJwkEnv(process.env.ARWEAVE_JWK);
467
371
  if (fromEnv)
468
372
  return fromEnv;
469
- const file = arweaveKeyFilePath();
373
+ const file = arweaveKeyFilePath(dataDir);
470
374
  if (!existsSync(file))
471
375
  return undefined;
472
376
  const raw = readFileSync(file, 'utf8');