@bsv/sdk 2.0.13 → 2.0.14

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 (45) hide show
  1. package/README.md +2 -0
  2. package/dist/cjs/package.json +1 -1
  3. package/dist/cjs/src/identity/IdentityClient.js +3 -3
  4. package/dist/cjs/src/identity/IdentityClient.js.map +1 -1
  5. package/dist/cjs/src/identity/types/index.js +1 -1
  6. package/dist/cjs/src/identity/types/index.js.map +1 -1
  7. package/dist/cjs/src/storage/StorageUploader.js +315 -96
  8. package/dist/cjs/src/storage/StorageUploader.js.map +1 -1
  9. package/dist/cjs/src/storage/index.js +3 -1
  10. package/dist/cjs/src/storage/index.js.map +1 -1
  11. package/dist/cjs/src/wallet/WERR_REVIEW_ACTIONS.js +2 -2
  12. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
  13. package/dist/esm/src/identity/IdentityClient.js +3 -3
  14. package/dist/esm/src/identity/IdentityClient.js.map +1 -1
  15. package/dist/esm/src/identity/types/index.js +1 -1
  16. package/dist/esm/src/identity/types/index.js.map +1 -1
  17. package/dist/esm/src/storage/StorageUploader.js +319 -95
  18. package/dist/esm/src/storage/StorageUploader.js.map +1 -1
  19. package/dist/esm/src/storage/index.js +1 -1
  20. package/dist/esm/src/storage/index.js.map +1 -1
  21. package/dist/esm/src/wallet/WERR_REVIEW_ACTIONS.js +2 -2
  22. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
  23. package/dist/types/src/storage/StorageUploader.d.ts +94 -55
  24. package/dist/types/src/storage/StorageUploader.d.ts.map +1 -1
  25. package/dist/types/src/storage/index.d.ts +1 -1
  26. package/dist/types/src/storage/index.d.ts.map +1 -1
  27. package/dist/types/src/wallet/WERR_REVIEW_ACTIONS.d.ts +2 -2
  28. package/dist/types/src/wallet/Wallet.interfaces.d.ts +2 -2
  29. package/dist/types/tsconfig.types.tsbuildinfo +1 -1
  30. package/dist/umd/bundle.js +4 -4
  31. package/dist/umd/bundle.js.map +1 -1
  32. package/docs/index.md +3 -1
  33. package/docs/reference/identity.md +1 -1
  34. package/docs/reference/storage.md +214 -85
  35. package/docs/reference/transaction.md +2 -2
  36. package/docs/reference/wallet.md +4 -4
  37. package/package.json +1 -1
  38. package/src/identity/IdentityClient.ts +3 -3
  39. package/src/identity/__tests/IdentityClient.additional.test.ts +3 -3
  40. package/src/identity/types/index.ts +1 -1
  41. package/src/storage/StorageUploader.ts +427 -105
  42. package/src/storage/__tests/StorageUploader.test.ts +881 -64
  43. package/src/storage/index.ts +1 -1
  44. package/src/wallet/WERR_REVIEW_ACTIONS.ts +2 -2
  45. package/src/wallet/Wallet.interfaces.ts +2 -2
@@ -1,6 +1,13 @@
1
1
  import { WalletInterface } from '../wallet/Wallet.interfaces.js';
2
+ /** Default UHRP storage providers used when the caller passes no host list. */
3
+ export declare const DEFAULT_UHRP_SERVERS: string[];
2
4
  export interface UploaderConfig {
3
- storageURL: string;
5
+ /** Legacy single-host URL. Mutually exclusive with `storageURLs`. */
6
+ storageURL?: string;
7
+ /** Explicit provider list. Takes precedence over `storageURL`. */
8
+ storageURLs?: string[];
9
+ /** Minimum replicas to store the file on. Defaults to 1. */
10
+ resilienceLevel?: number;
4
11
  wallet: WalletInterface;
5
12
  }
6
13
  export interface UploadableFile {
@@ -10,94 +17,126 @@ export interface UploadableFile {
10
17
  export interface UploadFileResult {
11
18
  published: boolean;
12
19
  uhrpURL: string;
20
+ /** Providers that successfully hosted the file. */
21
+ hostedBy: string[];
13
22
  }
14
23
  export interface FindFileData {
15
24
  name: string;
16
25
  size: string;
17
26
  mimeType: string;
18
27
  expiryTime: number;
28
+ /** Providers that reported this UHRP URL. Omitted in single-host mode. */
29
+ hostedBy?: string[];
30
+ }
31
+ export interface RenewPerHostResult {
32
+ host: string;
33
+ status: 'success' | 'error';
34
+ prevExpiryTime?: number;
35
+ newExpiryTime?: number;
36
+ amount?: number;
37
+ error?: string;
19
38
  }
20
39
  export interface RenewFileResult {
21
40
  status: string;
22
41
  prevExpiryTime?: number;
23
42
  newExpiryTime?: number;
43
+ /** Total satoshis paid across every host that renewed. */
24
44
  amount?: number;
45
+ /** Per-host outcomes. Omitted in single-host mode. */
46
+ results?: RenewPerHostResult[];
47
+ }
48
+ export interface HostScopeOptions {
49
+ /** Restrict the operation to this subset of configured providers. */
50
+ hostedBy?: string[];
51
+ }
52
+ export interface EstimateCostResult {
53
+ /** Cheapest-first quotes from configured providers. */
54
+ quotes: Array<{
55
+ host: string;
56
+ amount: number;
57
+ }>;
58
+ resilienceLevel: number;
59
+ /** Sum of the cheapest `resilienceLevel` amounts (or all collected, if below threshold). */
60
+ totalForResilience: number;
61
+ /** False when `publishFile` would throw without uploading. */
62
+ meetsResilienceThreshold: boolean;
25
63
  }
26
64
  /**
27
- * The StorageUploader class provides client-side methods for:
28
- * - Uploading files with a specified retention period
29
- * - Finding file metadata by UHRP URL
30
- * - Listing all user uploads
31
- * - Renewing an existing advertisement's expiry time
65
+ * Thrown by `renewFile` when successful renewals fall below the resilience
66
+ * threshold. Per-host outcomes are attached so callers can reconcile which
67
+ * providers were billed.
68
+ */
69
+ export declare class RenewResiliencyError extends Error {
70
+ readonly results: RenewPerHostResult[];
71
+ readonly requiredSuccesses: number;
72
+ readonly successCount: number;
73
+ constructor(message: string, results: RenewPerHostResult[], requiredSuccesses: number, successCount: number);
74
+ }
75
+ /**
76
+ * Client for publishing, finding, listing, and renewing UHRP-hosted files
77
+ * across one or more storage providers.
32
78
  */
33
79
  export declare class StorageUploader {
34
80
  private readonly authFetch;
81
+ private readonly hosts;
82
+ private readonly resilienceLevel;
83
+ /** Primary host used for non-upload operations. */
35
84
  private readonly baseURL;
36
- /**
37
- * Creates a new StorageUploader instance.
38
- * @param {UploaderConfig} config - An object containing the storage server's URL and a wallet interface
39
- */
40
85
  constructor(config: UploaderConfig);
86
+ /** Returns `null` when the provider is unreachable or errors out. */
87
+ private getQuote;
88
+ /** Drives the authenticated `/upload` route; `AuthFetch` handles the 402 payment flow. */
89
+ private getUploadURL;
90
+ private putFile;
41
91
  /**
42
- * Requests information from the server to upload a file (including presigned URL and headers).
43
- * @private
44
- * @param {number} fileSize - The size of the file, in bytes
45
- * @param {number} retentionPeriod - The desired hosting time, in minutes
46
- * @returns {Promise<{ uploadURL: string; requiredHeaders: Record<string, string>; amount?: number }>}
47
- * @throws {Error} If the server returns a non-OK response or an error status
92
+ * Collects quotes in parallel batches, shrinking each batch to only the
93
+ * remaining quotes still needed so we never over-query once the quote
94
+ * budget is satisfied.
48
95
  */
49
- private getUploadInfo;
96
+ private collectQuotes;
50
97
  /**
51
- * Performs the actual file upload (HTTP PUT) to the presigned URL returned by the server.
52
- * @private
53
- * @param {string} uploadURL - The presigned URL where the file is to be uploaded
54
- * @param {UploadableFile} file - The file to upload, including its raw data and MIME type
55
- * @param {Record<string, string>} requiredHeaders - Additional headers required by the server (e.g. content-length)
56
- * @returns {Promise<UploadFileResult>} An object indicating whether publishing was successful and the resulting UHRP URL
57
- * @throws {Error} If the server returns a non-OK response
98
+ * Queries the unauthenticated `/quote` endpoint on up to `2 * resilienceLevel`
99
+ * providers and returns the cheapest-first quote list plus the aggregate
100
+ * cost `publishFile` would pay. No provider is billed.
58
101
  */
59
- private uploadFile;
102
+ estimateCost(params: {
103
+ fileSize: number;
104
+ retentionPeriod: number;
105
+ }): Promise<EstimateCostResult>;
60
106
  /**
61
- * Publishes a file to the storage server with the specified retention period.
62
- *
63
- * This will:
64
- * 1. Request an upload URL from the server.
65
- * 2. Perform an HTTP PUT to upload the file’s raw bytes.
66
- * 3. Return a UHRP URL referencing the file once published.
67
- *
68
- * @param {Object} params
69
- * @param {UploadableFile} params.file - The file data + type
70
- * @param {number} params.retentionPeriod - Number of minutes to host the file
71
- * @returns {Promise<UploadFileResult>} An object with the file's UHRP URL
72
- * @throws {Error} If the server or upload step returns a non-OK response
107
+ * Publishes a file across the cheapest configured providers, falling
108
+ * through to the next-cheapest quote if a paid upload fails. Throws when
109
+ * the resilience threshold cannot be met.
73
110
  */
74
111
  publishFile(params: {
75
112
  file: UploadableFile;
76
113
  retentionPeriod: number;
77
114
  }): Promise<UploadFileResult>;
115
+ private findFileAtHost;
116
+ private renewFileAtHost;
117
+ /** Intersects `hostedBy` with the configured host set; throws when empty. */
118
+ private resolveTargets;
78
119
  /**
79
- * Retrieves metadata for a file matching the given UHRP URL from the `/find` route.
80
- * @param {string} uhrpUrl - The UHRP URL, e.g. "uhrp://abcd..."
81
- * @returns {Promise<FindFileData>} An object with file name, size, MIME type, and expiry time
82
- * @throws {Error} If the server or the route returns an error
120
+ * Fans `/find` out across configured hosts (UHRP storage is host-local,
121
+ * so any one host may not know the file) and returns the record with the
122
+ * longest remaining expiry. Single-host configurations preserve the
123
+ * legacy error-message contract verbatim.
83
124
  */
84
- findFile(uhrpUrl: string): Promise<FindFileData>;
125
+ findFile(uhrpUrl: string, options?: HostScopeOptions): Promise<FindFileData>;
85
126
  /**
86
- * Lists all advertisements belonging to the user from the `/list` route.
87
- * @returns {Promise<any>} The array of uploads returned by the server
88
- * @throws {Error} If the server or the route returns an error
127
+ * Unions `/list` output across configured hosts, merging duplicate UHRP
128
+ * URLs by the longest expiry observed. One failing host does not hide
129
+ * the rest. Single-host configurations preserve the legacy error contract.
89
130
  */
90
- listUploads(): Promise<any>;
131
+ listUploads(options?: HostScopeOptions): Promise<any>;
132
+ private listUploadsAtHost;
91
133
  /**
92
- * Renews the hosting time for an existing file advertisement identified by uhrpUrl.
93
- * Calls the `/renew` route to add `additionalMinutes` to the GCS customTime
94
- * and re-mint the advertisement token on-chain.
95
- *
96
- * @param {string} uhrpUrl - The UHRP URL of the file (e.g., "uhrp://abcd1234...")
97
- * @param {number} additionalMinutes - The number of minutes to extend
98
- * @returns {Promise<RenewFileResult>} An object with the new and previous expiry times, plus any cost
99
- * @throws {Error} If the request fails or the server returns an error
134
+ * Fans `/renew` out across every configured host (each provider owns its
135
+ * own advertisement, so a single-host renewal would degrade resilience
136
+ * over time). Hosts that do not carry the file are not billed. Throws
137
+ * {@link RenewResiliencyError} when successful renewals fall below the
138
+ * resilience threshold.
100
139
  */
101
- renewFile(uhrpUrl: string, additionalMinutes: number): Promise<RenewFileResult>;
140
+ renewFile(uhrpUrl: string, additionalMinutes: number, options?: HostScopeOptions): Promise<RenewFileResult>;
102
141
  }
103
142
  //# sourceMappingURL=StorageUploader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"StorageUploader.d.ts","sourceRoot":"","sources":["../../../../src/storage/StorageUploader.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAGhE,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,eAAe,CAAA;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,UAAU,GAAG,MAAM,EAAE,CAAA;IAC3B,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;GAMG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAQ;IAEhC;;;OAGG;gBACU,MAAM,EAAE,cAAc;IAKnC;;;;;;;OAOG;YACW,aAAa;IAmC3B;;;;;;;;OAQG;YACW,UAAU;IA0BxB;;;;;;;;;;;;;OAaG;IACU,WAAW,CAAE,MAAM,EAAE;QAChC,IAAI,EAAE,cAAc,CAAA;QACpB,eAAe,EAAE,MAAM,CAAA;KACxB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAS7B;;;;;OAKG;IACU,QAAQ,CAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IA0B9D;;;;OAIG;IACU,WAAW,IAAK,OAAO,CAAC,GAAG,CAAC;IAkBzC;;;;;;;;;OASG;IACU,SAAS,CAAE,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;CAmC9F"}
1
+ {"version":3,"file":"StorageUploader.d.ts","sourceRoot":"","sources":["../../../../src/storage/StorageUploader.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
1
  export * as StorageUtils from './StorageUtils.js';
2
- export { StorageUploader } from './StorageUploader.js';
2
+ export { StorageUploader, DEFAULT_UHRP_SERVERS, RenewResiliencyError } from './StorageUploader.js';
3
3
  export { StorageDownloader } from './StorageDownloader.js';
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AAEjD,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAEtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/storage/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,YAAY,MAAM,mBAAmB,CAAA;AAEjD,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA;AAElG,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA"}
@@ -1,7 +1,7 @@
1
1
  import { AtomicBEEF, OutpointString, ReviewActionResult, SendWithResult, TXIDHexString } from './Wallet.interfaces.js';
2
2
  /**
3
3
  * When a `createAction` or `signAction` is completed in undelayed mode (`acceptDelayedBroadcast`: false),
4
- * any unsucccessful result will return the results by way of this exception to ensure attention is
4
+ * any unsuccessful result will return the results by way of this exception to ensure attention is
5
5
  * paid to processing errors.
6
6
  */
7
7
  export declare class WERR_REVIEW_ACTIONS extends Error {
@@ -13,7 +13,7 @@ export declare class WERR_REVIEW_ACTIONS extends Error {
13
13
  code: number;
14
14
  isError: boolean;
15
15
  /**
16
- * All parameters correspond to their comparable `createAction` or `signSction` results
16
+ * All parameters correspond to their comparable `createAction` or `signAction` results
17
17
  * with the exception of `reviewActionResults`;
18
18
  * which contains more details, particularly for double spend results.
19
19
  */
@@ -254,10 +254,10 @@ export interface SendWithResult {
254
254
  }
255
255
  /**
256
256
  * Indicates status of a new Action following a `createAction` or `signAction` in immediate mode:
257
- * When `acceptDelayedBroadcast` is falses.
257
+ * When `acceptDelayedBroadcast` is false.
258
258
  *
259
259
  * 'success': The action has been broadcast and accepted by the bitcoin processing network.
260
- * 'doulbeSpend': The action has been confirmed to double spend one or more inputs, and by the "first-seen-rule" is the loosing transaction.
260
+ * 'doubleSpend': The action has been confirmed to double spend one or more inputs, and by the "first-seen-rule" is the losing transaction.
261
261
  * 'invalidTx': The action was rejected by the processing network as an invalid bitcoin transaction.
262
262
  * 'serviceError': The broadcast services are currently unable to reach the bitcoin network. The action is now queued for delayed retries.
263
263
  */