@ardrive/turbo-sdk 1.31.1 → 1.32.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 (77) hide show
  1. package/README.md +28 -0
  2. package/bundles/web.bundle.min.js +437 -258
  3. package/lib/cjs/cli/commands/uploadFile.js +1 -0
  4. package/lib/cjs/cli/commands/uploadFolder.js +1 -0
  5. package/lib/cjs/cli/options.js +19 -0
  6. package/lib/cjs/cli/utils.js +25 -0
  7. package/lib/cjs/common/factory.js +1 -0
  8. package/lib/cjs/common/payment.js +1 -1
  9. package/lib/cjs/common/token/ario.js +1 -1
  10. package/lib/cjs/common/token/arweave.js +1 -1
  11. package/lib/cjs/common/token/baseEth.js +17 -1
  12. package/lib/cjs/common/token/ethereum.js +13 -4
  13. package/lib/cjs/common/token/kyve.js +1 -1
  14. package/lib/cjs/common/token/solana.js +1 -1
  15. package/lib/cjs/common/turbo.js +3 -1
  16. package/lib/cjs/common/upload.js +124 -6
  17. package/lib/cjs/node/upload.js +2 -1
  18. package/lib/cjs/types.js +20 -1
  19. package/lib/cjs/version.js +1 -1
  20. package/lib/cjs/web/upload.js +2 -2
  21. package/lib/esm/cli/commands/uploadFile.js +2 -1
  22. package/lib/esm/cli/commands/uploadFolder.js +2 -1
  23. package/lib/esm/cli/options.js +19 -0
  24. package/lib/esm/cli/utils.js +25 -1
  25. package/lib/esm/common/factory.js +1 -0
  26. package/lib/esm/common/payment.js +1 -1
  27. package/lib/esm/common/token/ario.js +1 -1
  28. package/lib/esm/common/token/arweave.js +1 -1
  29. package/lib/esm/common/token/baseEth.js +17 -1
  30. package/lib/esm/common/token/ethereum.js +13 -4
  31. package/lib/esm/common/token/kyve.js +1 -1
  32. package/lib/esm/common/token/solana.js +1 -1
  33. package/lib/esm/common/turbo.js +3 -1
  34. package/lib/esm/common/upload.js +124 -6
  35. package/lib/esm/node/upload.js +2 -1
  36. package/lib/esm/types.js +17 -0
  37. package/lib/esm/version.js +1 -1
  38. package/lib/esm/web/upload.js +2 -2
  39. package/lib/types/cli/commands/uploadFile.d.ts.map +1 -1
  40. package/lib/types/cli/commands/uploadFolder.d.ts.map +1 -1
  41. package/lib/types/cli/options.d.ts +43 -0
  42. package/lib/types/cli/options.d.ts.map +1 -1
  43. package/lib/types/cli/types.d.ts +4 -0
  44. package/lib/types/cli/types.d.ts.map +1 -1
  45. package/lib/types/cli/utils.d.ts +4 -1
  46. package/lib/types/cli/utils.d.ts.map +1 -1
  47. package/lib/types/common/factory.d.ts +4 -1
  48. package/lib/types/common/factory.d.ts.map +1 -1
  49. package/lib/types/common/token/ario.d.ts +1 -1
  50. package/lib/types/common/token/ario.d.ts.map +1 -1
  51. package/lib/types/common/token/arweave.d.ts +1 -1
  52. package/lib/types/common/token/arweave.d.ts.map +1 -1
  53. package/lib/types/common/token/baseEth.d.ts +1 -0
  54. package/lib/types/common/token/baseEth.d.ts.map +1 -1
  55. package/lib/types/common/token/ethereum.d.ts +2 -1
  56. package/lib/types/common/token/ethereum.d.ts.map +1 -1
  57. package/lib/types/common/token/kyve.d.ts +1 -1
  58. package/lib/types/common/token/kyve.d.ts.map +1 -1
  59. package/lib/types/common/token/solana.d.ts +1 -1
  60. package/lib/types/common/token/solana.d.ts.map +1 -1
  61. package/lib/types/common/turbo.d.ts +2 -2
  62. package/lib/types/common/turbo.d.ts.map +1 -1
  63. package/lib/types/common/upload.d.ts +16 -3
  64. package/lib/types/common/upload.d.ts.map +1 -1
  65. package/lib/types/node/factory.d.ts +4 -1
  66. package/lib/types/node/factory.d.ts.map +1 -1
  67. package/lib/types/node/upload.d.ts +4 -1
  68. package/lib/types/node/upload.d.ts.map +1 -1
  69. package/lib/types/types.d.ts +19 -4
  70. package/lib/types/types.d.ts.map +1 -1
  71. package/lib/types/version.d.ts +1 -1
  72. package/lib/types/version.d.ts.map +1 -1
  73. package/lib/types/web/factory.d.ts +4 -1
  74. package/lib/types/web/factory.d.ts.map +1 -1
  75. package/lib/types/web/upload.d.ts +4 -1
  76. package/lib/types/web/upload.d.ts.map +1 -1
  77. package/package.json +1 -1
@@ -15,7 +15,7 @@
15
15
  */
16
16
  import bs58 from 'bs58';
17
17
  import { readFileSync, statSync } from 'fs';
18
- import { TurboFactory, defaultTurboConfiguration, developmentTurboConfiguration, fiatCurrencyTypes, isCurrency, isTokenType, privateKeyFromKyveMnemonic, } from '../node/index.js';
18
+ import { ExistingBalanceFunding, OnDemandFunding, TurboFactory, defaultTurboConfiguration, developmentTurboConfiguration, fiatCurrencyTypes, isCurrency, isTokenType, privateKeyFromKyveMnemonic, tokenToBaseMap, } from '../node/index.js';
19
19
  import { defaultProdAoConfigs, tokenToDevAoConfigMap, tokenToDevGatewayMap, } from '../utils/common.js';
20
20
  import { NoWalletProvidedError } from './errors.js';
21
21
  export function exitWithErrorLog(error) {
@@ -245,6 +245,30 @@ export function parseTags(tagsArr) {
245
245
  export function getTagsFromOptions(options) {
246
246
  return parseTags(options.tags);
247
247
  }
248
+ export function onDemandOptionsFromOptions(options) {
249
+ if (!options.onDemand) {
250
+ return { fundingMode: new ExistingBalanceFunding() };
251
+ }
252
+ const value = options.maxCryptoTopUpValue;
253
+ let maxTokenAmount = undefined;
254
+ if (value !== undefined) {
255
+ if (isNaN(+value) || +value <= 0) {
256
+ throw new Error('maxTokenAmount must be a positive number');
257
+ }
258
+ const token = tokenFromOptions(options);
259
+ maxTokenAmount = tokenToBaseMap[token](value).toString();
260
+ }
261
+ if (options.topUpBufferMultiplier !== undefined &&
262
+ (isNaN(options.topUpBufferMultiplier) || options.topUpBufferMultiplier < 1)) {
263
+ throw new Error('topUpBufferMultiplier must be a number >= 1');
264
+ }
265
+ return {
266
+ fundingMode: new OnDemandFunding({
267
+ maxTokenAmount,
268
+ topUpBufferMultiplier: options.topUpBufferMultiplier,
269
+ }),
270
+ };
271
+ }
248
272
  export function currencyFromOptions(options) {
249
273
  const currency = options.currency?.toLowerCase();
250
274
  if (!isCurrency(currency)) {
@@ -106,6 +106,7 @@ export class TurboBaseFactory {
106
106
  signer: turboSigner,
107
107
  logger,
108
108
  token,
109
+ paymentService,
109
110
  });
110
111
  return new TurboAuthenticatedClient({
111
112
  uploadService,
@@ -287,7 +287,7 @@ export class TurboAuthenticatedPaymentService extends TurboUnauthenticatedPaymen
287
287
  const txId = fundTx.id;
288
288
  try {
289
289
  // Let transaction settle some time
290
- await this.tokenTools.pollForTxBeingAvailable({ txId });
290
+ await this.tokenTools.pollTxAvailability({ txId });
291
291
  }
292
292
  catch (e) {
293
293
  this.logger.error(`Failed to poll for transaction being available from ${this.token} gateway... Attempting to submit fund tx to Turbo...`, e);
@@ -63,7 +63,7 @@ export class ARIOToken {
63
63
  });
64
64
  return { id: txId, target, reward: '0' };
65
65
  }
66
- async pollForTxBeingAvailable() {
66
+ async pollTxAvailability() {
67
67
  // AO finality should be instant -- but we'll wait initial backoff to
68
68
  // provide infra some time to crank without reading the whole result
69
69
  return sleep(this.pollingOptions.initialBackoffMs);
@@ -72,7 +72,7 @@ export class ArweaveToken {
72
72
  await this.submitTx(tx);
73
73
  return { id, target, reward: tx.reward };
74
74
  }
75
- async pollForTxBeingAvailable({ txId, }) {
75
+ async pollTxAvailability({ txId }) {
76
76
  const { maxAttempts, pollingIntervalMs, initialBackoffMs } = this.pollingOptions;
77
77
  this.logger.debug('Polling for transaction...', { txId });
78
78
  await sleep(initialBackoffMs);
@@ -2,7 +2,7 @@ import { defaultProdGatewayUrls } from '../../utils/common.js';
2
2
  import { EthereumToken } from './ethereum.js';
3
3
  export class BaseEthToken extends EthereumToken {
4
4
  constructor({ logger, gatewayUrl = defaultProdGatewayUrls['base-eth'], pollingOptions = {
5
- initialBackoffMs: 1_000,
5
+ initialBackoffMs: 2_500,
6
6
  maxAttempts: 10,
7
7
  pollingIntervalMs: 2_500,
8
8
  }, } = {}) {
@@ -12,4 +12,20 @@ export class BaseEthToken extends EthereumToken {
12
12
  pollingOptions,
13
13
  });
14
14
  }
15
+ async getTxAvailability(txId) {
16
+ const tx = await this.rpcProvider.getTransactionReceipt(txId);
17
+ if (tx) {
18
+ const confirmations = await tx.confirmations();
19
+ if (confirmations >= 1) {
20
+ this.logger.debug('Transaction is available on chain', {
21
+ txId,
22
+ tx,
23
+ confirmations,
24
+ });
25
+ return true;
26
+ }
27
+ }
28
+ this.logger.debug('Transaction not yet available on chain', { txId, tx });
29
+ return false;
30
+ }
15
31
  }
@@ -43,13 +43,22 @@ export class EthereumToken {
43
43
  target,
44
44
  };
45
45
  }
46
- async pollForTxBeingAvailable({ txId, }) {
46
+ async getTxAvailability(txId) {
47
+ const tx = await this.rpcProvider.getTransaction(txId);
48
+ if (tx) {
49
+ this.logger.debug('Transaction is available on chain', { txId, tx });
50
+ return true;
51
+ }
52
+ this.logger.debug('Transaction not yet available on chain', { txId });
53
+ return false;
54
+ }
55
+ async pollTxAvailability({ txId }) {
47
56
  await new Promise((resolve) => setTimeout(resolve, this.pollingOptions.initialBackoffMs));
48
57
  let attempts = 0;
49
58
  while (attempts < this.pollingOptions.maxAttempts) {
50
59
  try {
51
- const tx = await this.rpcProvider.getTransaction(txId);
52
- if (tx) {
60
+ const txIsAvailable = await this.getTxAvailability(txId);
61
+ if (txIsAvailable) {
53
62
  return;
54
63
  }
55
64
  }
@@ -59,6 +68,6 @@ export class EthereumToken {
59
68
  await new Promise((resolve) => setTimeout(resolve, this.pollingOptions.pollingIntervalMs));
60
69
  attempts++;
61
70
  }
62
- throw new Error('Transaction not found after polling!');
71
+ throw new Error(`Transaction ${txId} not found after polling!`);
63
72
  }
64
73
  }
@@ -58,7 +58,7 @@ export class KyveToken {
58
58
  });
59
59
  return { id: txHash, target };
60
60
  }
61
- async pollForTxBeingAvailable({ txId, }) {
61
+ async pollTxAvailability({ txId }) {
62
62
  const { maxAttempts, pollingIntervalMs, initialBackoffMs } = this.pollingOptions;
63
63
  this.logger.debug('Polling for transaction...', {
64
64
  txId,
@@ -66,7 +66,7 @@ export class SolanaToken {
66
66
  lastValidBlockHeight: tx.lastValidBlockHeight,
67
67
  }, 'finalized');
68
68
  }
69
- async pollForTxBeingAvailable({ txId, }) {
69
+ async pollTxAvailability({ txId }) {
70
70
  const { maxAttempts, pollingIntervalMs, initialBackoffMs } = this.pollingOptions;
71
71
  this.logger.debug('Polling for transaction...', {
72
72
  txId,
@@ -156,7 +156,7 @@ export class TurboAuthenticatedClient extends TurboUnauthenticatedClient {
156
156
  /**
157
157
  * Signs and uploads raw data to the Turbo Upload Service.
158
158
  */
159
- upload({ data, dataItemOpts, signal, events, chunkByteCount, chunkingMode, maxChunkConcurrency, }) {
159
+ upload({ data, dataItemOpts, signal, events, chunkByteCount, chunkingMode, maxChunkConcurrency, maxFinalizeMs, fundingMode, }) {
160
160
  return this.uploadService.upload({
161
161
  data,
162
162
  dataItemOpts,
@@ -165,6 +165,8 @@ export class TurboAuthenticatedClient extends TurboUnauthenticatedClient {
165
165
  chunkByteCount,
166
166
  chunkingMode,
167
167
  maxChunkConcurrency,
168
+ fundingMode,
169
+ maxFinalizeMs,
168
170
  });
169
171
  }
170
172
  uploadFile(params) {
@@ -14,13 +14,16 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import { CanceledError } from 'axios';
17
+ import { BigNumber } from 'bignumber.js';
17
18
  import { pLimit } from 'plimit-lit';
19
+ import { ExistingBalanceFunding, OnDemandFunding, } from '../types.js';
18
20
  import { defaultRetryConfig } from '../utils/axiosClient.js';
19
21
  import { isBlob, sleep } from '../utils/common.js';
20
22
  import { FailedRequestError } from '../utils/errors.js';
21
23
  import { ChunkedUploader } from './chunked.js';
22
24
  import { TurboEventEmitter, createStreamWithUploadEvents } from './events.js';
23
25
  import { TurboHTTPService } from './http.js';
26
+ import { exponentMap, tokenToBaseMap } from './index.js';
24
27
  import { TurboWinstonLogger } from './logger.js';
25
28
  function isTurboUploadFileWithStreamFactoryParams(params) {
26
29
  return 'fileStreamFactory' in params;
@@ -85,14 +88,16 @@ export class TurboUnauthenticatedUploadService {
85
88
  }
86
89
  // NOTE: to avoid redundancy, we use inheritance here - but generally prefer composition over inheritance
87
90
  export class TurboAuthenticatedBaseUploadService extends TurboUnauthenticatedUploadService {
88
- constructor({ url = defaultUploadServiceURL, retryConfig, signer, logger, token, }) {
91
+ constructor({ url = defaultUploadServiceURL, retryConfig, signer, logger, token, paymentService, }) {
89
92
  super({ url, retryConfig, logger, token });
93
+ this.enabledOnDemandTokens = ['ario', 'solana', 'base-eth'];
90
94
  this.signer = signer;
95
+ this.paymentService = paymentService;
91
96
  }
92
97
  /**
93
98
  * Signs and uploads raw data to the Turbo Upload Service.
94
99
  */
95
- upload({ data, dataItemOpts, signal, events, chunkByteCount, chunkingMode, maxChunkConcurrency, }) {
100
+ upload({ data, dataItemOpts, signal, events, chunkByteCount, chunkingMode, maxChunkConcurrency, fundingMode, maxFinalizeMs, }) {
96
101
  // This function is intended to be usable in both Node and browser environments.
97
102
  if (isBlob(data)) {
98
103
  const streamFactory = () => data.stream();
@@ -103,6 +108,11 @@ export class TurboAuthenticatedBaseUploadService extends TurboUnauthenticatedUpl
103
108
  signal,
104
109
  dataItemOpts,
105
110
  events,
111
+ chunkByteCount,
112
+ chunkingMode,
113
+ maxChunkConcurrency,
114
+ fundingMode,
115
+ maxFinalizeMs,
106
116
  });
107
117
  }
108
118
  const dataBuffer = (() => {
@@ -123,6 +133,8 @@ export class TurboAuthenticatedBaseUploadService extends TurboUnauthenticatedUpl
123
133
  chunkByteCount,
124
134
  chunkingMode,
125
135
  maxChunkConcurrency,
136
+ fundingMode,
137
+ maxFinalizeMs,
126
138
  });
127
139
  }
128
140
  resolveUploadFileConfig(params) {
@@ -154,7 +166,7 @@ export class TurboAuthenticatedBaseUploadService extends TurboUnauthenticatedUpl
154
166
  };
155
167
  }
156
168
  async uploadFile(params) {
157
- const { signal, dataItemOpts, events, fileStreamFactory, fileSizeFactory } = this.resolveUploadFileConfig(params);
169
+ const { signal, dataItemOpts, events, fileStreamFactory, fileSizeFactory, fundingMode = new ExistingBalanceFunding(), } = this.resolveUploadFileConfig(params);
158
170
  let retries = 0;
159
171
  const maxRetries = this.retryConfig.retries ?? 3;
160
172
  const retryDelay = this.retryConfig.retryDelay ??
@@ -163,6 +175,7 @@ export class TurboAuthenticatedBaseUploadService extends TurboUnauthenticatedUpl
163
175
  let lastStatusCode = undefined; // Store the last status code for throwing
164
176
  const emitter = new TurboEventEmitter(events);
165
177
  // avoid duplicating signing on failures here - these errors will immediately be thrown
178
+ let cryptoFundResult;
166
179
  // TODO: move the retry implementation to the http class, and avoid awaiting here. This will standardize the retry logic across all upload methods.
167
180
  while (retries < maxRetries) {
168
181
  if (signal?.aborted) {
@@ -175,6 +188,14 @@ export class TurboAuthenticatedBaseUploadService extends TurboUnauthenticatedUpl
175
188
  dataItemOpts,
176
189
  emitter,
177
190
  });
191
+ if (fundingMode instanceof OnDemandFunding &&
192
+ cryptoFundResult === undefined) {
193
+ const totalByteCount = dataItemSizeFactory();
194
+ cryptoFundResult = await this.onDemand({
195
+ totalByteCount,
196
+ onDemandFunding: fundingMode,
197
+ });
198
+ }
178
199
  // Now that we have the signed data item, we can upload it using the uploadSignedDataItem method
179
200
  // which will create a new emitter with upload events. We await
180
201
  // this result due to the wrapped retry logic of this method.
@@ -198,7 +219,7 @@ export class TurboAuthenticatedBaseUploadService extends TurboUnauthenticatedUpl
198
219
  signal,
199
220
  events,
200
221
  });
201
- return response;
222
+ return { ...response, cryptoFundResult };
202
223
  }
203
224
  const response = await this.uploadSignedDataItem({
204
225
  dataItemStreamFactory,
@@ -207,7 +228,7 @@ export class TurboAuthenticatedBaseUploadService extends TurboUnauthenticatedUpl
207
228
  signal,
208
229
  events,
209
230
  });
210
- return response;
231
+ return { ...response, cryptoFundResult };
211
232
  }
212
233
  catch (error) {
213
234
  // Store the last encountered error and status for re-throwing after retries
@@ -285,7 +306,7 @@ export class TurboAuthenticatedBaseUploadService extends TurboUnauthenticatedUpl
285
306
  */
286
307
  async uploadFolder(params) {
287
308
  this.logger.debug('Uploading folder...', { params });
288
- const { dataItemOpts, signal, manifestOptions = {}, maxConcurrentUploads = 1, throwOnFailure = true, maxChunkConcurrency, chunkByteCount, chunkingMode, maxFinalizeMs, } = params;
309
+ const { dataItemOpts, signal, manifestOptions = {}, maxConcurrentUploads = 1, throwOnFailure = true, maxChunkConcurrency, chunkByteCount, chunkingMode, fundingMode = new ExistingBalanceFunding(), maxFinalizeMs, } = params;
289
310
  const { disableManifest, indexFile, fallbackFile } = manifestOptions;
290
311
  const paths = {};
291
312
  const response = {
@@ -327,6 +348,16 @@ export class TurboAuthenticatedBaseUploadService extends TurboUnauthenticatedUpl
327
348
  };
328
349
  const files = await this.getFiles(params);
329
350
  const limit = pLimit(maxConcurrentUploads);
351
+ let cryptoFundResult;
352
+ if (fundingMode instanceof OnDemandFunding) {
353
+ const totalByteCount = files.reduce((acc, file) => {
354
+ return acc + this.getFileSize(file) + 1200; // allow extra per file for ANS-104 headers
355
+ }, 0);
356
+ cryptoFundResult = await this.onDemand({
357
+ totalByteCount,
358
+ onDemandFunding: fundingMode,
359
+ });
360
+ }
330
361
  await Promise.all(files.map((file) => limit(() => uploadFile(file))));
331
362
  this.logger.debug('Finished uploading files', {
332
363
  numFiles: files.length,
@@ -366,6 +397,7 @@ export class TurboAuthenticatedBaseUploadService extends TurboUnauthenticatedUpl
366
397
  ...response,
367
398
  manifest,
368
399
  manifestResponse,
400
+ cryptoFundResult,
369
401
  };
370
402
  }
371
403
  async shareCredits({ approvedAddress, approvedWincAmount, expiresBySeconds, }) {
@@ -420,4 +452,90 @@ export class TurboAuthenticatedBaseUploadService extends TurboUnauthenticatedUpl
420
452
  }
421
453
  return revokedApprovals;
422
454
  }
455
+ /**
456
+ * Triggers an upload that will top-up the wallet with Credits for the amount before uploading.
457
+ * First, it calculates the expected cost of the upload. Next, it checks the wallet for existing
458
+ * balance. If the balance is insufficient, it will attempt the top-up with the wallet in the specified `token`
459
+ * and await for the balance to be credited.
460
+ * Note: Only `ario`, `solana`, and `base-eth` tokens are currently supported for on-demand uploads.
461
+ */
462
+ async onDemand({ totalByteCount, onDemandFunding, }) {
463
+ const { maxTokenAmount, topUpBufferMultiplier } = onDemandFunding;
464
+ const currentBalance = await this.paymentService.getBalance();
465
+ const wincPriceForOneGiB = (await this.paymentService.getUploadCosts({
466
+ bytes: [2 ** 30],
467
+ }))[0].winc;
468
+ const expectedWincPrice = new BigNumber(wincPriceForOneGiB)
469
+ .multipliedBy(totalByteCount)
470
+ .dividedBy(2 ** 30)
471
+ .toFixed(0, BigNumber.ROUND_UP);
472
+ if (BigNumber(currentBalance.effectiveBalance).isGreaterThanOrEqualTo(expectedWincPrice)) {
473
+ this.logger.debug('Sufficient balance for on demand upload', {
474
+ currentBalance,
475
+ expectedWincPrice,
476
+ });
477
+ return undefined;
478
+ }
479
+ this.logger.debug('Insufficient balance for on demand upload', {
480
+ currentBalance,
481
+ expectedWincPrice,
482
+ });
483
+ if (!this.enabledOnDemandTokens.includes(this.token)) {
484
+ throw new Error(`On-demand uploads are not supported for token: ${this.token}`);
485
+ }
486
+ const topUpWincAmount = BigNumber(expectedWincPrice)
487
+ .minus(currentBalance.effectiveBalance)
488
+ .multipliedBy(topUpBufferMultiplier) // add buffer to avoid underpayment
489
+ .toFixed(0, BigNumber.ROUND_UP);
490
+ const wincPriceForOneToken = (await this.paymentService.getWincForToken({
491
+ tokenAmount: tokenToBaseMap[this.token](1),
492
+ })).winc;
493
+ const topUpTokenAmount = new BigNumber(topUpWincAmount)
494
+ .dividedBy(wincPriceForOneToken)
495
+ .multipliedBy(tokenToBaseMap[this.token](1))
496
+ .toFixed(0, BigNumber.ROUND_UP);
497
+ if (maxTokenAmount !== undefined) {
498
+ if (new BigNumber(topUpTokenAmount).isGreaterThan(maxTokenAmount)) {
499
+ throw new Error(`Top up token amount ${new BigNumber(topUpTokenAmount).div(exponentMap[this.token])} is greater than the maximum allowed amount of ${maxTokenAmount}`);
500
+ }
501
+ }
502
+ this.logger.debug(`Topping up wallet with ${topUpTokenAmount} ${this.token} for ${topUpWincAmount} winc`);
503
+ const topUpResponse = await this.paymentService.topUpWithTokens({
504
+ tokenAmount: topUpTokenAmount,
505
+ });
506
+ this.logger.debug('Top up transaction submitted', { topUpResponse });
507
+ const pollingOptions = {
508
+ pollIntervalMs: 3 * 1000, // poll every 3 seconds
509
+ timeoutMs: 120 * 1000, // wait up to 2 minutes
510
+ };
511
+ let tries = 1;
512
+ const maxTries = Math.ceil(pollingOptions.timeoutMs / pollingOptions.pollIntervalMs) - 1; // -1 because we already tried once with the initial request
513
+ while (topUpResponse.status !== 'confirmed' && tries < maxTries) {
514
+ this.logger.debug('Tx not yet confirmed, waiting to poll again', {
515
+ tries,
516
+ maxTries,
517
+ });
518
+ await sleep(pollingOptions.pollIntervalMs);
519
+ tries++;
520
+ try {
521
+ const submitFundResult = await this.paymentService.submitFundTransaction({
522
+ txId: topUpResponse.id,
523
+ });
524
+ if (submitFundResult.status === 'confirmed') {
525
+ this.logger.debug('Top-up transaction confirmed and balance updated', { submitFundResult });
526
+ topUpResponse.status = 'confirmed';
527
+ break;
528
+ }
529
+ }
530
+ catch (error) {
531
+ this.logger.warn('Error fetching fund transaction during polling', {
532
+ message: error instanceof Error ? error.message : error,
533
+ });
534
+ }
535
+ }
536
+ if (tries >= maxTries) {
537
+ this.logger.warn('Timed out waiting for fund tx to confirm after top-up. Will continue to attempt upload but it may fail if balance is insufficient.');
538
+ }
539
+ return topUpResponse;
540
+ }
423
541
  }
@@ -20,13 +20,14 @@ import { Readable } from 'stream';
20
20
  import { TurboAuthenticatedBaseUploadService, defaultUploadServiceURL, } from '../common/upload.js';
21
21
  import { isNodeUploadFolderParams, } from '../types.js';
22
22
  export class TurboAuthenticatedUploadService extends TurboAuthenticatedBaseUploadService {
23
- constructor({ url = defaultUploadServiceURL, retryConfig, signer, logger, token, }) {
23
+ constructor({ url = defaultUploadServiceURL, retryConfig, signer, logger, token, paymentService, }) {
24
24
  super({
25
25
  url,
26
26
  retryConfig,
27
27
  logger,
28
28
  token,
29
29
  signer,
30
+ paymentService,
30
31
  });
31
32
  }
32
33
  async getAbsoluteFilePathsFromFolder(folderPath) {
package/lib/esm/types.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { BigNumber } from 'bignumber.js';
1
2
  export const fiatCurrencyTypes = [
2
3
  'usd',
3
4
  'eur',
@@ -23,6 +24,22 @@ export const tokenTypes = [
23
24
  'pol',
24
25
  'base-eth',
25
26
  ];
27
+ export class ExistingBalanceFunding {
28
+ }
29
+ export class OnDemandFunding {
30
+ constructor({ maxTokenAmount, topUpBufferMultiplier = 1.1, }) {
31
+ if (maxTokenAmount !== undefined &&
32
+ new BigNumber(maxTokenAmount).isLessThan(0)) {
33
+ throw new Error('maxTokenAmount must be non-negative');
34
+ }
35
+ this.maxTokenAmount =
36
+ maxTokenAmount !== undefined ? new BigNumber(maxTokenAmount) : undefined;
37
+ if (topUpBufferMultiplier < 1) {
38
+ throw new Error('topUpBufferMultiplier must be >= 1');
39
+ }
40
+ this.topUpBufferMultiplier = topUpBufferMultiplier;
41
+ }
42
+ }
26
43
  export const multipartPendingStatus = [
27
44
  'ASSEMBLING',
28
45
  'VALIDATING',
@@ -14,4 +14,4 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  // AUTOMATICALLY GENERATED FILE - DO NOT TOUCH
17
- export const version = '1.31.1';
17
+ export const version = '1.32.0';
@@ -16,8 +16,8 @@
16
16
  import { TurboAuthenticatedBaseUploadService, defaultUploadServiceURL, } from '../common/upload.js';
17
17
  import { isWebUploadFolderParams, } from '../types.js';
18
18
  export class TurboAuthenticatedUploadService extends TurboAuthenticatedBaseUploadService {
19
- constructor({ url = defaultUploadServiceURL, retryConfig, signer, logger, token, }) {
20
- super({ url, retryConfig, logger, token, signer });
19
+ constructor({ url = defaultUploadServiceURL, retryConfig, signer, logger, token, paymentService, }) {
20
+ super({ url, retryConfig, logger, token, signer, paymentService });
21
21
  }
22
22
  getFiles(params) {
23
23
  if (!isWebUploadFolderParams(params)) {
@@ -1 +1 @@
1
- {"version":3,"file":"uploadFile.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/uploadFile.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAQhD,wBAAsB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB1E"}
1
+ {"version":3,"file":"uploadFile.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/uploadFile.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAShD,wBAAsB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoB1E"}
@@ -1 +1 @@
1
- {"version":3,"file":"uploadFolder.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/uploadFolder.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAQlD,wBAAsB,YAAY,CAChC,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAkCf"}
1
+ {"version":3,"file":"uploadFolder.d.ts","sourceRoot":"","sources":["../../../../src/cli/commands/uploadFolder.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AASlD,wBAAsB,YAAY,CAChC,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAmCf"}
@@ -173,6 +173,19 @@ export declare const optionMap: {
173
173
  readonly description: "Chunking mode to use for the upload. Can be \"auto\", \"force\" or \"disabled\". Defaults to \"auto\".";
174
174
  readonly default: "auto";
175
175
  };
176
+ readonly onDemand: {
177
+ readonly alias: "--on-demand";
178
+ readonly description: "Enable on-demand crypto top-ups during upload if balance is insufficient";
179
+ readonly default: false;
180
+ };
181
+ readonly topUpBufferMultiplier: {
182
+ readonly alias: "--top-up-buffer-multiplier <topUpBufferMultiplier>";
183
+ readonly description: "Multiplier to apply to the estimated top-up amount to avoid underpayment during on-demand top-ups. Defaults to 1.1 (10% buffer).";
184
+ };
185
+ readonly maxCryptoTopUpValue: {
186
+ readonly alias: "--max-crypto-top-up-value <maxCryptoTopUpValue>";
187
+ readonly description: "Maximum crypto top-up value to use for the upload. Defaults to no limit.";
188
+ };
176
189
  };
177
190
  export declare const walletOptions: ({
178
191
  readonly alias: "-w, --wallet-file <filePath>";
@@ -259,6 +272,16 @@ export declare const uploadOptions: ({
259
272
  readonly alias: "--chunking-mode <chunkingMode>";
260
273
  readonly description: "Chunking mode to use for the upload. Can be \"auto\", \"force\" or \"disabled\". Defaults to \"auto\".";
261
274
  readonly default: "auto";
275
+ } | {
276
+ readonly alias: "--on-demand";
277
+ readonly description: "Enable on-demand crypto top-ups during upload if balance is insufficient";
278
+ readonly default: false;
279
+ } | {
280
+ readonly alias: "--top-up-buffer-multiplier <topUpBufferMultiplier>";
281
+ readonly description: "Multiplier to apply to the estimated top-up amount to avoid underpayment during on-demand top-ups. Defaults to 1.1 (10% buffer).";
282
+ } | {
283
+ readonly alias: "--max-crypto-top-up-value <maxCryptoTopUpValue>";
284
+ readonly description: "Maximum crypto top-up value to use for the upload. Defaults to no limit.";
262
285
  })[];
263
286
  export declare const uploadFolderOptions: ({
264
287
  readonly description: "An array of additional tags for the write action, in \"--tags name1 value1 name2 value2\" format";
@@ -314,6 +337,16 @@ export declare const uploadFolderOptions: ({
314
337
  readonly alias: "--chunking-mode <chunkingMode>";
315
338
  readonly description: "Chunking mode to use for the upload. Can be \"auto\", \"force\" or \"disabled\". Defaults to \"auto\".";
316
339
  readonly default: "auto";
340
+ } | {
341
+ readonly alias: "--on-demand";
342
+ readonly description: "Enable on-demand crypto top-ups during upload if balance is insufficient";
343
+ readonly default: false;
344
+ } | {
345
+ readonly alias: "--top-up-buffer-multiplier <topUpBufferMultiplier>";
346
+ readonly description: "Multiplier to apply to the estimated top-up amount to avoid underpayment during on-demand top-ups. Defaults to 1.1 (10% buffer).";
347
+ } | {
348
+ readonly alias: "--max-crypto-top-up-value <maxCryptoTopUpValue>";
349
+ readonly description: "Maximum crypto top-up value to use for the upload. Defaults to no limit.";
317
350
  })[];
318
351
  export declare const uploadFileOptions: ({
319
352
  readonly description: "An array of additional tags for the write action, in \"--tags name1 value1 name2 value2\" format";
@@ -356,6 +389,16 @@ export declare const uploadFileOptions: ({
356
389
  readonly alias: "--chunking-mode <chunkingMode>";
357
390
  readonly description: "Chunking mode to use for the upload. Can be \"auto\", \"force\" or \"disabled\". Defaults to \"auto\".";
358
391
  readonly default: "auto";
392
+ } | {
393
+ readonly alias: "--on-demand";
394
+ readonly description: "Enable on-demand crypto top-ups during upload if balance is insufficient";
395
+ readonly default: false;
396
+ } | {
397
+ readonly alias: "--top-up-buffer-multiplier <topUpBufferMultiplier>";
398
+ readonly description: "Multiplier to apply to the estimated top-up amount to avoid underpayment during on-demand top-ups. Defaults to 1.1 (10% buffer).";
399
+ } | {
400
+ readonly alias: "--max-crypto-top-up-value <maxCryptoTopUpValue>";
401
+ readonly description: "Maximum crypto top-up value to use for the upload. Defaults to no limit.";
359
402
  })[];
360
403
  export declare const shareCreditsOptions: ({
361
404
  readonly alias: "-a, --address <nativeAddress>";
@@ -1 +1 @@
1
- {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../../src/cli/options.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyKZ,CAAC;AAEX,eAAO,MAAM,aAAa;;;;;;;;;IAIzB,CAAC;AAEF,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAUzB,CAAC;AAEF,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAUzB,CAAC;AAEF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAO/B,CAAC;AAEF,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAAyC,CAAC;AAExE,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;IAK/B,CAAC;AAEF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;IAAwC,CAAC;AAE1E,eAAO,MAAM,iBAAiB;;;;;;;;;;;;IAAuB,CAAC"}
1
+ {"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../../src/cli/options.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyLZ,CAAC;AAEX,eAAO,MAAM,aAAa;;;;;;;;;IAIzB,CAAC;AAEF,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAUzB,CAAC;AAQF,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAWzB,CAAC;AAEF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAO/B,CAAC;AAEF,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAAyC,CAAC;AAExE,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;IAK/B,CAAC;AAEF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;IAAwC,CAAC;AAE1E,eAAO,MAAM,iBAAiB;;;;;;;;;;;;IAAuB,CAAC"}
@@ -48,6 +48,10 @@ export type UploadOptions = WalletOptions & {
48
48
  maxFinalizeMs: string | undefined;
49
49
  chunkByteCount: string | undefined;
50
50
  chunkingMode: TurboChunkingMode | undefined;
51
+ onDemand: boolean;
52
+ maxCryptoTopUpValue: string | undefined;
53
+ topUpBufferMultiplier: number | undefined;
54
+ feeMultiplier: number | undefined;
51
55
  };
52
56
  export type UploadFolderOptions = UploadOptions & {
53
57
  folderPath: string | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/cli/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/cli/types.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { Command, OptionValues } from 'commander';
2
- import { Currency, TokenType, TurboAuthenticatedClient, TurboChunkingParams, TurboUnauthenticatedConfiguration } from '../node/index.js';
2
+ import { Currency, ExistingBalanceFunding, OnDemandFunding, TokenType, TurboAuthenticatedClient, TurboChunkingParams, TurboUnauthenticatedConfiguration } from '../node/index.js';
3
3
  import { AddressOptions, GlobalOptions, TokenPriceOptions, UploadFolderOptions, UploadOptions, WalletOptions } from './types.js';
4
4
  export declare function exitWithErrorLog(error: unknown): void;
5
5
  export declare function runCommand<T extends OptionValues>(command: Command, action: (options: T) => Promise<void>): Promise<void>;
@@ -42,6 +42,9 @@ export declare function getTagsFromOptions(options: UploadOptions): {
42
42
  name: string;
43
43
  value: string;
44
44
  }[];
45
+ export declare function onDemandOptionsFromOptions(options: UploadOptions): {
46
+ fundingMode: OnDemandFunding | ExistingBalanceFunding;
47
+ };
45
48
  export declare function currencyFromOptions<T extends GlobalOptions & {
46
49
  currency?: string;
47
50
  }>(options: T): Currency | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/cli/utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/cli/utils.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { GetTurboSignerParams, TurboAuthenticatedConfiguration, TurboAuthenticatedUploadServiceConfiguration, TurboAuthenticatedUploadServiceInterface, TurboUnauthenticatedConfiguration } from '../types.js';
2
2
  import { TurboWinstonLogger } from './logger.js';
3
+ import { TurboAuthenticatedPaymentService } from './payment.js';
3
4
  import { TurboDataItemAbstractSigner } from './signer.js';
4
5
  import { TurboAuthenticatedClient, TurboUnauthenticatedClient } from './turbo.js';
5
6
  export declare abstract class TurboBaseFactory {
@@ -8,7 +9,9 @@ export declare abstract class TurboBaseFactory {
8
9
  static setLogFormat(format: string): void;
9
10
  static unauthenticated({ paymentServiceConfig, uploadServiceConfig, token, }?: TurboUnauthenticatedConfiguration): TurboUnauthenticatedClient;
10
11
  protected abstract getSigner({ providedPrivateKey, providedSigner, providedWalletAdapter, logger, token, }: GetTurboSignerParams): TurboDataItemAbstractSigner;
11
- protected abstract getAuthenticatedUploadService(config: TurboAuthenticatedUploadServiceConfiguration): TurboAuthenticatedUploadServiceInterface;
12
+ protected abstract getAuthenticatedUploadService(config: TurboAuthenticatedUploadServiceConfiguration & {
13
+ paymentService: TurboAuthenticatedPaymentService;
14
+ }): TurboAuthenticatedUploadServiceInterface;
12
15
  protected getAuthenticatedTurbo({ privateKey, signer: providedSigner, paymentServiceConfig, uploadServiceConfig, token, gatewayUrl, tokenMap, tokenTools, logger, walletAdapter, processId, cuUrl, }: TurboAuthenticatedConfiguration & {
13
16
  logger: TurboWinstonLogger;
14
17
  }): TurboAuthenticatedClient;