@ardrive/turbo-sdk 1.27.0-alpha.2 → 1.27.0-alpha.4

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 (41) hide show
  1. package/README.md +45 -1
  2. package/bundles/web.bundle.min.js +83 -46
  3. package/lib/cjs/cli/cli.js +8 -2
  4. package/lib/cjs/cli/commands/fiatEstimate.js +34 -0
  5. package/lib/cjs/cli/commands/price.js +7 -0
  6. package/lib/cjs/cli/commands/tokenPrice.js +1 -7
  7. package/lib/cjs/cli/commands/topUp.js +1 -5
  8. package/lib/cjs/cli/utils.js +19 -0
  9. package/lib/cjs/common/payment.js +23 -0
  10. package/lib/cjs/common/turbo.js +11 -11
  11. package/lib/cjs/common/upload.js +37 -1
  12. package/lib/cjs/version.js +1 -1
  13. package/lib/esm/cli/cli.js +8 -2
  14. package/lib/esm/cli/commands/fiatEstimate.js +31 -0
  15. package/lib/esm/cli/commands/price.js +8 -1
  16. package/lib/esm/cli/commands/tokenPrice.js +2 -8
  17. package/lib/esm/cli/commands/topUp.js +2 -6
  18. package/lib/esm/cli/utils.js +18 -1
  19. package/lib/esm/common/payment.js +23 -0
  20. package/lib/esm/common/turbo.js +11 -11
  21. package/lib/esm/common/upload.js +37 -1
  22. package/lib/esm/version.js +1 -1
  23. package/lib/types/cli/commands/fiatEstimate.d.ts +3 -0
  24. package/lib/types/cli/commands/fiatEstimate.d.ts.map +1 -0
  25. package/lib/types/cli/commands/price.d.ts.map +1 -1
  26. package/lib/types/cli/commands/tokenPrice.d.ts.map +1 -1
  27. package/lib/types/cli/commands/topUp.d.ts.map +1 -1
  28. package/lib/types/cli/types.d.ts +4 -0
  29. package/lib/types/cli/types.d.ts.map +1 -1
  30. package/lib/types/cli/utils.d.ts +7 -3
  31. package/lib/types/cli/utils.d.ts.map +1 -1
  32. package/lib/types/common/payment.d.ts +5 -1
  33. package/lib/types/common/payment.d.ts.map +1 -1
  34. package/lib/types/common/turbo.d.ts +56 -3
  35. package/lib/types/common/turbo.d.ts.map +1 -1
  36. package/lib/types/common/upload.d.ts +5 -2
  37. package/lib/types/common/upload.d.ts.map +1 -1
  38. package/lib/types/types.d.ts +18 -2
  39. package/lib/types/types.d.ts.map +1 -1
  40. package/lib/types/version.d.ts +1 -1
  41. package/package.json +5 -5
package/README.md CHANGED
@@ -352,6 +352,34 @@ const { winc, actualTokenAmount, equivalentWincTokenAmount } =
352
352
  });
353
353
  ```
354
354
 
355
+ #### `getFiatEstimateForBytes({ byteCount, currency })`
356
+
357
+ Get the current price from the Turbo Payment Service, denominated in the specified fiat currency, for uploading a specified number of bytes to Turbo.
358
+
359
+ ```typescript
360
+ const turbo = TurboFactory.unauthenticated();
361
+ const { amount } = await turbo.getFiatEstimateForBytes({
362
+ byteCount: 1024 * 1024 * 1024,
363
+ currency: 'usd', // specify the currency for the price
364
+ });
365
+
366
+ console.log(amount); // Estimated usd price for 1 GiB
367
+ ```
368
+
369
+ <details>
370
+ <summary>Example Output</summary>
371
+
372
+ ```json
373
+ {
374
+ "byteCount": 1073741824,
375
+ "amount": 20.58,
376
+ "currency": "usd",
377
+ "winc": "2402378997310"
378
+ }
379
+ ```
380
+
381
+ </details>
382
+
355
383
  #### `getTokenPriceForBytes({ byteCount })`
356
384
 
357
385
  Get the current price from the Turbo Payment Service, denominated in the specified token, for uploading a specified number of bytes to Turbo.
@@ -994,6 +1022,7 @@ Command Options:
994
1022
 
995
1023
  - `--value <value>` - Value to get the price for. e.g: 10.50 for $10.50 USD, 1024 for 1 KiB, 1.1 for 1.1 AR
996
1024
  - `--type <type>` - Type of price to get. e.g: 'bytes', 'arweave', 'usd', 'kyve'. Default: 'bytes'
1025
+ - `--currency <currency>` - Currency unit of the reported price (e.g: 'usd', 'eur', 'gbp').
997
1026
 
998
1027
  e.g:
999
1028
 
@@ -1009,13 +1038,28 @@ turbo price --value 1024 --type bytes
1009
1038
  turbo price --value 1.1 --type arweave
1010
1039
  ```
1011
1040
 
1041
+ ##### `fiat-estimate`
1042
+
1043
+ Get the current fiat estimation from the Turbo Payment Service, denominated in the specified fiat currency, for uploading a specified number of bytes to Turbo.
1044
+
1045
+ Command Options:
1046
+
1047
+ - `--byte-count <byteCount>` - Byte count of data to get the fiat estimate for
1048
+ - `--currency <currency>` - Currency unit of the reported price (e.g: 'usd', 'eur', 'gbp')
1049
+
1050
+ e.g:
1051
+
1052
+ ```shell
1053
+ turbo fiat-estimate --byte-count 102400 --currency usd
1054
+ ```
1055
+
1012
1056
  ##### `token-price`
1013
1057
 
1014
1058
  Get the current price from the Turbo Payment Service, denominated in the specified token, for uploading a specified number of bytes to Turbo.
1015
1059
 
1016
1060
  Command Options:
1017
1061
 
1018
- - `--byte-count <byteCount>` - Byte value to get the token price for
1062
+ - `--byte-count <byteCount>` - Byte count of data to get the token price for
1019
1063
 
1020
1064
  e.g:
1021
1065
 
@@ -111649,39 +111649,39 @@ function dew$63() {
111649
111649
  return Link2;
111650
111650
  }(events_1.EventEmitter);
111651
111651
  exports$83.Link = Link;
111652
- var File = function() {
111653
- function File2(link2, node, flags, fd) {
111652
+ var File2 = function() {
111653
+ function File3(link2, node, flags, fd) {
111654
111654
  this.position = 0;
111655
111655
  this.link = link2;
111656
111656
  this.node = node;
111657
111657
  this.flags = flags;
111658
111658
  this.fd = fd;
111659
111659
  }
111660
- File2.prototype.getString = function(encoding) {
111660
+ File3.prototype.getString = function(encoding) {
111661
111661
  return this.node.getString();
111662
111662
  };
111663
- File2.prototype.setString = function(str) {
111663
+ File3.prototype.setString = function(str) {
111664
111664
  this.node.setString(str);
111665
111665
  };
111666
- File2.prototype.getBuffer = function() {
111666
+ File3.prototype.getBuffer = function() {
111667
111667
  return this.node.getBuffer();
111668
111668
  };
111669
- File2.prototype.setBuffer = function(buf) {
111669
+ File3.prototype.setBuffer = function(buf) {
111670
111670
  this.node.setBuffer(buf);
111671
111671
  };
111672
- File2.prototype.getSize = function() {
111672
+ File3.prototype.getSize = function() {
111673
111673
  return this.node.getSize();
111674
111674
  };
111675
- File2.prototype.truncate = function(len) {
111675
+ File3.prototype.truncate = function(len) {
111676
111676
  this.node.truncate(len);
111677
111677
  };
111678
- File2.prototype.seekTo = function(position) {
111678
+ File3.prototype.seekTo = function(position) {
111679
111679
  this.position = position;
111680
111680
  };
111681
- File2.prototype.stats = function() {
111681
+ File3.prototype.stats = function() {
111682
111682
  return Stats_1.default.build(this.node);
111683
111683
  };
111684
- File2.prototype.write = function(buf, offset2, length, position) {
111684
+ File3.prototype.write = function(buf, offset2, length, position) {
111685
111685
  if (offset2 === void 0) {
111686
111686
  offset2 = 0;
111687
111687
  }
@@ -111696,7 +111696,7 @@ function dew$63() {
111696
111696
  this.position = position + bytes4;
111697
111697
  return bytes4;
111698
111698
  };
111699
- File2.prototype.read = function(buf, offset2, length, position) {
111699
+ File3.prototype.read = function(buf, offset2, length, position) {
111700
111700
  if (offset2 === void 0) {
111701
111701
  offset2 = 0;
111702
111702
  }
@@ -111709,15 +111709,15 @@ function dew$63() {
111709
111709
  this.position = position + bytes4;
111710
111710
  return bytes4;
111711
111711
  };
111712
- File2.prototype.chmod = function(perm) {
111712
+ File3.prototype.chmod = function(perm) {
111713
111713
  this.node.chmod(perm);
111714
111714
  };
111715
- File2.prototype.chown = function(uid, gid) {
111715
+ File3.prototype.chown = function(uid, gid) {
111716
111716
  this.node.chown(uid, gid);
111717
111717
  };
111718
- return File2;
111718
+ return File3;
111719
111719
  }();
111720
- exports$83.File = File;
111720
+ exports$83.File = File2;
111721
111721
  return exports$83;
111722
111722
  }
111723
111723
  function dew$53() {
@@ -122098,11 +122098,11 @@ var require_file = __commonJS({
122098
122098
  var os2 = (init_os(), __toCommonJS(os_exports));
122099
122099
  var tailFile = require_tail_file();
122100
122100
  module3.exports = /* @__PURE__ */ function(_TransportStream) {
122101
- function File() {
122101
+ function File2() {
122102
122102
  var _this;
122103
122103
  var options = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
122104
- _classCallCheck(this, File);
122105
- _this = _callSuper(this, File, [options]);
122104
+ _classCallCheck(this, File2);
122105
+ _this = _callSuper(this, File2, [options]);
122106
122106
  _this.name = options.name || "file";
122107
122107
  function throwIf(target) {
122108
122108
  for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
@@ -122152,8 +122152,8 @@ var require_file = __commonJS({
122152
122152
  _this.open();
122153
122153
  return _this;
122154
122154
  }
122155
- _inherits(File, _TransportStream);
122156
- return _createClass(File, [{
122155
+ _inherits(File2, _TransportStream);
122156
+ return _createClass(File2, [{
122157
122157
  key: "finishIfEnding",
122158
122158
  value: function finishIfEnding() {
122159
122159
  var _this2 = this;
@@ -314072,7 +314072,7 @@ var import_winston = __toESM(require_winston(), 1);
314072
314072
  init_dirname();
314073
314073
  init_buffer2();
314074
314074
  init_process2();
314075
- var version16 = "1.27.0-alpha.1";
314075
+ var version16 = "1.27.0-alpha.3";
314076
314076
 
314077
314077
  // src/common/logger.ts
314078
314078
  var TurboWinstonLogger = class _TurboWinstonLogger {
@@ -367056,6 +367056,23 @@ var TurboUnauthenticatedPaymentService = class {
367056
367056
  }
367057
367057
  return response;
367058
367058
  }
367059
+ async getFiatEstimateForBytes({
367060
+ byteCount,
367061
+ currency
367062
+ }) {
367063
+ const wincPriceForGivenBytes = await this.getUploadCosts({
367064
+ bytes: [byteCount]
367065
+ });
367066
+ const { winc: wincPriceForOneGiB, fiat: fiatPricesForOneGiB } = await this.getFiatRates();
367067
+ const fiatPriceForGivenBytes = new BigNumber5(wincPriceForGivenBytes[0].winc).dividedBy(new BigNumber5(wincPriceForOneGiB)).times(fiatPricesForOneGiB[currency]);
367068
+ const formattedFiatPrice = currency === "jpy" ? +fiatPriceForGivenBytes.integerValue(BigNumber5.ROUND_CEIL) : +fiatPriceForGivenBytes.decimalPlaces(2, BigNumber5.ROUND_CEIL);
367069
+ return {
367070
+ byteCount,
367071
+ amount: formattedFiatPrice,
367072
+ currency,
367073
+ winc: wincPriceForGivenBytes[0].winc
367074
+ };
367075
+ }
367059
367076
  async getTokenPriceForBytes({
367060
367077
  byteCount
367061
367078
  }) {
@@ -367517,6 +367534,12 @@ function createStreamWithSigningEvents({
367517
367534
  }
367518
367535
 
367519
367536
  // src/common/upload.ts
367537
+ function isTurboUploadFileWithStreamFactoryParams(params) {
367538
+ return "fileStreamFactory" in params;
367539
+ }
367540
+ function isTurboUploadFileWithFileOrPathParams(params) {
367541
+ return "file" in params;
367542
+ }
367520
367543
  var creditSharingTagNames = {
367521
367544
  shareCredits: "x-approve-payment",
367522
367545
  sharedWincAmount: "x-amount",
@@ -367623,13 +367646,29 @@ var TurboAuthenticatedBaseUploadService = class extends TurboUnauthenticatedUplo
367623
367646
  events
367624
367647
  });
367625
367648
  }
367626
- async uploadFile({
367627
- fileStreamFactory,
367628
- fileSizeFactory,
367629
- signal,
367630
- dataItemOpts,
367631
- events = {}
367632
- }) {
367649
+ resolveUploadFileConfig(params) {
367650
+ let fileStreamFactory;
367651
+ let fileSizeFactory;
367652
+ if (isTurboUploadFileWithStreamFactoryParams(params)) {
367653
+ fileStreamFactory = params.fileStreamFactory;
367654
+ fileSizeFactory = params.fileSizeFactory;
367655
+ } else if (isTurboUploadFileWithFileOrPathParams(params)) {
367656
+ const file = params.file;
367657
+ fileStreamFactory = file instanceof File ? () => this.getFileStreamForFile(file) : () => this.getFileStreamForFile(file);
367658
+ fileSizeFactory = () => this.getFileSize(params.file);
367659
+ } else {
367660
+ throw new TypeError(
367661
+ "Invalid upload file params. Must be either TurboUploadFileWithStreamFactoryParams or TurboUploadFileWithFileOrPathParams"
367662
+ );
367663
+ }
367664
+ return {
367665
+ fileStreamFactory,
367666
+ fileSizeFactory,
367667
+ ...params
367668
+ };
367669
+ }
367670
+ async uploadFile(params) {
367671
+ const { signal, dataItemOpts, events, fileStreamFactory, fileSizeFactory } = this.resolveUploadFileConfig(params);
367633
367672
  let retries = 0;
367634
367673
  const maxRetries = this.retryConfig.retries ?? 3;
367635
367674
  const retryDelay = this.retryConfig.retryDelay ?? ((retryNumber) => retryNumber * 1e3);
@@ -367732,6 +367771,7 @@ ${lastError instanceof Error ? lastError.message : lastError}`;
367732
367771
  }
367733
367772
  /**
367734
367773
  * TODO: add events to the uploadFolder method
367774
+ * TODO: create resolveUploadFolderConfig() function
367735
367775
  * could be a predicate with a resolveConfig() function, eg: events: ({...file ctx}) => ({
367736
367776
  * onProgress: (progress) => {
367737
367777
  * console.log('progress', progress);
@@ -367963,6 +368003,18 @@ var TurboUnauthenticatedClient = class {
367963
368003
  getWincForToken(params) {
367964
368004
  return this.paymentService.getWincForToken(params);
367965
368005
  }
368006
+ /**
368007
+ * Determines the fiat estimate for a given byte count in a specific currency, including all Turbo cost adjustments and fees.
368008
+ */
368009
+ getFiatEstimateForBytes({
368010
+ byteCount,
368011
+ currency
368012
+ }) {
368013
+ return this.paymentService.getFiatEstimateForBytes({
368014
+ byteCount,
368015
+ currency
368016
+ });
368017
+ }
367966
368018
  /**
367967
368019
  * Determines the price in the instantiated token to upload one data item of a specific size in bytes, including all Turbo cost adjustments and fees.
367968
368020
  */
@@ -368046,23 +368098,8 @@ var TurboAuthenticatedClient = class extends TurboUnauthenticatedClient {
368046
368098
  }) {
368047
368099
  return this.uploadService.upload({ data, dataItemOpts, signal, events });
368048
368100
  }
368049
- /**
368050
- * Signs and uploads raw file data to the Turbo Upload Service.
368051
- */
368052
- uploadFile({
368053
- fileStreamFactory,
368054
- fileSizeFactory,
368055
- signal,
368056
- dataItemOpts,
368057
- events
368058
- }) {
368059
- return this.uploadService.uploadFile({
368060
- fileStreamFactory,
368061
- fileSizeFactory,
368062
- signal,
368063
- dataItemOpts,
368064
- events
368065
- });
368101
+ uploadFile(params) {
368102
+ return this.uploadService.uploadFile(params);
368066
368103
  }
368067
368104
  uploadFolder(p9) {
368068
368105
  return this.uploadService.uploadFolder(p9);
@@ -20,6 +20,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
20
20
  // eslint-disable-next-line header/header -- This is a CLI file
21
21
  const commander_1 = require("commander");
22
22
  const version_js_1 = require("../version.js");
23
+ const fiatEstimate_js_1 = require("./commands/fiatEstimate.js");
23
24
  const index_js_1 = require("./commands/index.js");
24
25
  const listShares_js_1 = require("./commands/listShares.js");
25
26
  const revokeCredits_js_1 = require("./commands/revokeCredits.js");
@@ -49,14 +50,19 @@ const utils_js_1 = require("./utils.js");
49
50
  });
50
51
  (0, utils_js_1.applyOptions)(commander_1.program
51
52
  .command('price')
52
- .description('Get the current Credits estimate for byte, crypto, or fiat value'), [options_js_1.optionMap.value, options_js_1.optionMap.type]).action(async (_commandOptions, command) => {
53
+ .description('Get the current Credits estimate for byte, crypto, or fiat value'), [options_js_1.optionMap.value, options_js_1.optionMap.type, options_js_1.optionMap.currency]).action(async (_commandOptions, command) => {
53
54
  await (0, utils_js_1.runCommand)(command, index_js_1.price);
54
55
  });
55
56
  (0, utils_js_1.applyOptions)(commander_1.program
56
57
  .command('token-price')
57
- .description('Get the current token price for provided byte value'), [options_js_1.optionMap.byteCount]).action(async (_commandOptions, command) => {
58
+ .description('Get the current token price for provided byte count'), [options_js_1.optionMap.byteCount]).action(async (_commandOptions, command) => {
58
59
  await (0, utils_js_1.runCommand)(command, tokenPrice_js_1.tokenPrice);
59
60
  });
61
+ (0, utils_js_1.applyOptions)(commander_1.program
62
+ .command('fiat-estimate')
63
+ .description('Get the current token price for provided byte count'), [options_js_1.optionMap.byteCount, options_js_1.optionMap.currency]).action(async (_commandOptions, command) => {
64
+ await (0, utils_js_1.runCommand)(command, fiatEstimate_js_1.fiatEstimate);
65
+ });
60
66
  (0, utils_js_1.applyOptions)(commander_1.program
61
67
  .command('share-credits')
62
68
  .description('Create a Turbo credit share approval'), options_js_1.shareCreditsOptions).action(async (_commandOptions, command) => {
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fiatEstimate = fiatEstimate;
4
+ /**
5
+ * Copyright (C) 2022-2024 Permanent Data Solutions, Inc.
6
+ *
7
+ * Licensed under the Apache License, Version 2.0 (the "License");
8
+ * you may not use this file except in compliance with the License.
9
+ * You may obtain a copy of the License at
10
+ *
11
+ * http://www.apache.org/licenses/LICENSE-2.0
12
+ *
13
+ * Unless required by applicable law or agreed to in writing, software
14
+ * distributed under the License is distributed on an "AS IS" BASIS,
15
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ * See the License for the specific language governing permissions and
17
+ * limitations under the License.
18
+ */
19
+ const index_js_1 = require("../../node/index.js");
20
+ const utils_js_1 = require("../utils.js");
21
+ async function fiatEstimate(options) {
22
+ const byteCount = (0, utils_js_1.requiredByteCountFromOptions)(options);
23
+ const currency = (0, utils_js_1.currencyFromOptions)(options) ?? 'usd';
24
+ const turbo = index_js_1.TurboFactory.unauthenticated((0, utils_js_1.configFromOptions)(options));
25
+ const result = await turbo.getFiatEstimateForBytes({
26
+ byteCount,
27
+ currency,
28
+ });
29
+ const output = {
30
+ ...result,
31
+ message: `The current price estimate for ${byteCount} bytes is ${result.amount} ${currency}`,
32
+ };
33
+ console.log(JSON.stringify(output, null, 2));
34
+ }
@@ -22,12 +22,19 @@ const factory_js_1 = require("../../node/factory.js");
22
22
  const types_js_1 = require("../../types.js");
23
23
  const constants_js_1 = require("../constants.js");
24
24
  const utils_js_1 = require("../utils.js");
25
+ const fiatEstimate_js_1 = require("./fiatEstimate.js");
25
26
  async function price(options) {
26
27
  const value = options.value;
27
28
  if (value === undefined || +value <= 0 || isNaN(+value)) {
28
29
  throw new Error('Must provide a positive number --value to get price');
29
30
  }
30
31
  const type = options.type ?? 'bytes';
32
+ const currency = (0, utils_js_1.currencyFromOptions)(options);
33
+ if (currency !== undefined && type === 'bytes') {
34
+ // User supplied --type bytes --currency <currency> --value <bytes>
35
+ // This is a special case where we will provide a fiat estimate for the bytes value
36
+ return (0, fiatEstimate_js_1.fiatEstimate)({ ...options, byteCount: value });
37
+ }
31
38
  const winc = await (async () => {
32
39
  if ((0, index_js_1.isTokenType)(type)) {
33
40
  const turbo = factory_js_1.TurboFactory.unauthenticated({
@@ -21,13 +21,7 @@ const factory_js_1 = require("../../node/factory.js");
21
21
  const types_js_1 = require("../../types.js");
22
22
  const utils_js_1 = require("../utils.js");
23
23
  async function tokenPrice(options) {
24
- const byteCount = options.byteCount !== undefined ? +options.byteCount : undefined;
25
- if (byteCount === undefined ||
26
- byteCount <= 0 ||
27
- isNaN(byteCount) ||
28
- !Number.isInteger(byteCount)) {
29
- throw new Error('Must provide a positive number for byte to get price.\nFor example, to get the SOL price for 100 MiB use the following:\nturbo token-price --token solana --byte-count 1048576000');
30
- }
24
+ const byteCount = (0, utils_js_1.requiredByteCountFromOptions)(options);
31
25
  const token = options.token;
32
26
  if (!(0, index_js_1.isTokenType)(token)) {
33
27
  throw new Error(`Invalid token type ${token}. Must be one of ${types_js_1.tokenTypes.join(', ')}`);
@@ -19,7 +19,6 @@ exports.topUp = topUp;
19
19
  const child_process_1 = require("child_process");
20
20
  const currency_js_1 = require("../../common/currency.js");
21
21
  const factory_js_1 = require("../../node/factory.js");
22
- const types_js_1 = require("../../types.js");
23
22
  const common_js_1 = require("../../utils/common.js");
24
23
  const utils_js_1 = require("../utils.js");
25
24
  function openUrl(url) {
@@ -43,10 +42,7 @@ async function topUp(options) {
43
42
  if (value === undefined) {
44
43
  throw new Error('Must provide a --value to top up');
45
44
  }
46
- const currency = (options.currency ?? 'usd').toLowerCase();
47
- if (!(0, types_js_1.isCurrency)(currency)) {
48
- throw new Error(`Invalid fiat currency type ${currency}!\nPlease use one of these:\n${JSON.stringify(types_js_1.fiatCurrencyTypes, null, 2)}`);
49
- }
45
+ const currency = (0, utils_js_1.currencyFromOptions)(options) ?? 'usd';
50
46
  // TODO: Pay in CLI prompts via --cli options
51
47
  const { url, paymentAmount, winc } = await (async () => {
52
48
  const amount = currency_js_1.currencyMap[currency](+value);
@@ -18,6 +18,8 @@ exports.paidByFromOptions = paidByFromOptions;
18
18
  exports.getUploadFolderOptions = getUploadFolderOptions;
19
19
  exports.parseTags = parseTags;
20
20
  exports.getTagsFromOptions = getTagsFromOptions;
21
+ exports.currencyFromOptions = currencyFromOptions;
22
+ exports.requiredByteCountFromOptions = requiredByteCountFromOptions;
21
23
  /**
22
24
  * Copyright (C) 2022-2024 Permanent Data Solutions, Inc.
23
25
  *
@@ -258,3 +260,20 @@ function parseTags(tagsArr) {
258
260
  function getTagsFromOptions(options) {
259
261
  return parseTags(options.tags);
260
262
  }
263
+ function currencyFromOptions(options) {
264
+ const currency = options.currency?.toLowerCase();
265
+ if (!(0, index_js_1.isCurrency)(currency)) {
266
+ throw new Error(`Invalid fiat currency type ${currency}!\nPlease use one of these:\n${JSON.stringify(index_js_1.fiatCurrencyTypes, null, 2)}`);
267
+ }
268
+ return currency;
269
+ }
270
+ function requiredByteCountFromOptions({ byteCount, }) {
271
+ const byteCountValue = byteCount !== undefined ? +byteCount : undefined;
272
+ if (byteCountValue === undefined ||
273
+ isNaN(byteCountValue) ||
274
+ !Number.isInteger(byteCountValue) ||
275
+ byteCountValue <= 0) {
276
+ throw new Error('Must provide a positive number for byte count.');
277
+ }
278
+ return byteCountValue;
279
+ }
@@ -178,6 +178,29 @@ class TurboUnauthenticatedPaymentService {
178
178
  }
179
179
  return response;
180
180
  }
181
+ async getFiatEstimateForBytes({ byteCount, currency, }) {
182
+ // Step 1: Get the estimated winc cost for the given byte count -- W
183
+ const wincPriceForGivenBytes = await this.getUploadCosts({
184
+ bytes: [byteCount],
185
+ });
186
+ // Step 2: Get the winc-to-fiat conversion rates for 1 GiB
187
+ const { winc: wincPriceForOneGiB, fiat: fiatPricesForOneGiB } = await this.getFiatRates();
188
+ // Step 3: Convert the WINC cost of the given bytes into fiat:
189
+ // (W / W1GiB) * Fiat1GiB = FiatCostForBytes
190
+ const fiatPriceForGivenBytes = new bignumber_js_1.BigNumber(wincPriceForGivenBytes[0].winc)
191
+ .dividedBy(new bignumber_js_1.BigNumber(wincPriceForOneGiB))
192
+ .times(fiatPricesForOneGiB[currency]);
193
+ // Step 4: Format and round up so the estimated cost is always enough to cover the upload
194
+ const formattedFiatPrice = currency === 'jpy'
195
+ ? +fiatPriceForGivenBytes.integerValue(bignumber_js_1.BigNumber.ROUND_CEIL) // no decimals for JPY
196
+ : +fiatPriceForGivenBytes.decimalPlaces(2, bignumber_js_1.BigNumber.ROUND_CEIL); // 2 decimal precision
197
+ return {
198
+ byteCount,
199
+ amount: formattedFiatPrice,
200
+ currency,
201
+ winc: wincPriceForGivenBytes[0].winc,
202
+ };
203
+ }
181
204
  async getTokenPriceForBytes({ byteCount, }) {
182
205
  const wincPriceForOneToken = (await this.getWincForToken({
183
206
  tokenAmount: index_js_1.tokenToBaseMap[this.token](1),
@@ -78,6 +78,15 @@ class TurboUnauthenticatedClient {
78
78
  getWincForToken(params) {
79
79
  return this.paymentService.getWincForToken(params);
80
80
  }
81
+ /**
82
+ * Determines the fiat estimate for a given byte count in a specific currency, including all Turbo cost adjustments and fees.
83
+ */
84
+ getFiatEstimateForBytes({ byteCount, currency, }) {
85
+ return this.paymentService.getFiatEstimateForBytes({
86
+ byteCount,
87
+ currency,
88
+ });
89
+ }
81
90
  /**
82
91
  * Determines the price in the instantiated token to upload one data item of a specific size in bytes, including all Turbo cost adjustments and fees.
83
92
  */
@@ -146,17 +155,8 @@ class TurboAuthenticatedClient extends TurboUnauthenticatedClient {
146
155
  upload({ data, dataItemOpts, signal, events, }) {
147
156
  return this.uploadService.upload({ data, dataItemOpts, signal, events });
148
157
  }
149
- /**
150
- * Signs and uploads raw file data to the Turbo Upload Service.
151
- */
152
- uploadFile({ fileStreamFactory, fileSizeFactory, signal, dataItemOpts, events, }) {
153
- return this.uploadService.uploadFile({
154
- fileStreamFactory,
155
- fileSizeFactory,
156
- signal,
157
- dataItemOpts,
158
- events,
159
- });
158
+ uploadFile(params) {
159
+ return this.uploadService.uploadFile(params);
160
160
  }
161
161
  uploadFolder(p) {
162
162
  return this.uploadService.uploadFolder(p);
@@ -24,6 +24,12 @@ const errors_js_1 = require("../utils/errors.js");
24
24
  const events_js_1 = require("./events.js");
25
25
  const http_js_1 = require("./http.js");
26
26
  const logger_js_1 = require("./logger.js");
27
+ function isTurboUploadFileWithStreamFactoryParams(params) {
28
+ return 'fileStreamFactory' in params;
29
+ }
30
+ function isTurboUploadFileWithFileOrPathParams(params) {
31
+ return 'file' in params;
32
+ }
27
33
  exports.creditSharingTagNames = {
28
34
  shareCredits: 'x-approve-payment',
29
35
  sharedWincAmount: 'x-amount',
@@ -119,7 +125,36 @@ class TurboAuthenticatedBaseUploadService extends TurboUnauthenticatedUploadServ
119
125
  events,
120
126
  });
121
127
  }
122
- async uploadFile({ fileStreamFactory, fileSizeFactory, signal, dataItemOpts, events = {}, }) {
128
+ resolveUploadFileConfig(params) {
129
+ let fileStreamFactory;
130
+ let fileSizeFactory;
131
+ if (isTurboUploadFileWithStreamFactoryParams(params)) {
132
+ fileStreamFactory = params.fileStreamFactory;
133
+ fileSizeFactory = params.fileSizeFactory;
134
+ }
135
+ else if (isTurboUploadFileWithFileOrPathParams(params)) {
136
+ const file = params.file;
137
+ /**
138
+ * this is pretty gross, but it's the only way to get the type inference to work without overhauling
139
+ * the abstract method to accept a generic, which we would need to perform a check on anyways.
140
+ */
141
+ fileStreamFactory =
142
+ file instanceof File
143
+ ? () => this.getFileStreamForFile(file)
144
+ : () => this.getFileStreamForFile(file);
145
+ fileSizeFactory = () => this.getFileSize(params.file);
146
+ }
147
+ else {
148
+ throw new TypeError('Invalid upload file params. Must be either TurboUploadFileWithStreamFactoryParams or TurboUploadFileWithFileOrPathParams');
149
+ }
150
+ return {
151
+ fileStreamFactory,
152
+ fileSizeFactory,
153
+ ...params,
154
+ };
155
+ }
156
+ async uploadFile(params) {
157
+ const { signal, dataItemOpts, events, fileStreamFactory, fileSizeFactory } = this.resolveUploadFileConfig(params);
123
158
  let retries = 0;
124
159
  const maxRetries = this.retryConfig.retries ?? 3;
125
160
  const retryDelay = this.retryConfig.retryDelay ??
@@ -223,6 +258,7 @@ class TurboAuthenticatedBaseUploadService extends TurboUnauthenticatedUploadServ
223
258
  }
224
259
  /**
225
260
  * TODO: add events to the uploadFolder method
261
+ * TODO: create resolveUploadFolderConfig() function
226
262
  * could be a predicate with a resolveConfig() function, eg: events: ({...file ctx}) => ({
227
263
  * onProgress: (progress) => {
228
264
  * console.log('progress', progress);
@@ -17,4 +17,4 @@
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.version = void 0;
19
19
  // AUTOMATICALLY GENERATED FILE - DO NOT TOUCH
20
- exports.version = '1.27.0-alpha.2';
20
+ exports.version = '1.27.0-alpha.4';
@@ -18,6 +18,7 @@
18
18
  // eslint-disable-next-line header/header -- This is a CLI file
19
19
  import { program } from 'commander';
20
20
  import { version } from '../version.js';
21
+ import { fiatEstimate } from './commands/fiatEstimate.js';
21
22
  import { balance, cryptoFund, price, topUp, uploadFile, uploadFolder, } from './commands/index.js';
22
23
  import { listShares } from './commands/listShares.js';
23
24
  import { revokeCredits } from './commands/revokeCredits.js';
@@ -47,14 +48,19 @@ applyOptions(program.command('upload-file').description('Upload a file using Tur
47
48
  });
48
49
  applyOptions(program
49
50
  .command('price')
50
- .description('Get the current Credits estimate for byte, crypto, or fiat value'), [optionMap.value, optionMap.type]).action(async (_commandOptions, command) => {
51
+ .description('Get the current Credits estimate for byte, crypto, or fiat value'), [optionMap.value, optionMap.type, optionMap.currency]).action(async (_commandOptions, command) => {
51
52
  await runCommand(command, price);
52
53
  });
53
54
  applyOptions(program
54
55
  .command('token-price')
55
- .description('Get the current token price for provided byte value'), [optionMap.byteCount]).action(async (_commandOptions, command) => {
56
+ .description('Get the current token price for provided byte count'), [optionMap.byteCount]).action(async (_commandOptions, command) => {
56
57
  await runCommand(command, tokenPrice);
57
58
  });
59
+ applyOptions(program
60
+ .command('fiat-estimate')
61
+ .description('Get the current token price for provided byte count'), [optionMap.byteCount, optionMap.currency]).action(async (_commandOptions, command) => {
62
+ await runCommand(command, fiatEstimate);
63
+ });
58
64
  applyOptions(program
59
65
  .command('share-credits')
60
66
  .description('Create a Turbo credit share approval'), shareCreditsOptions).action(async (_commandOptions, command) => {
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Copyright (C) 2022-2024 Permanent Data Solutions, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { TurboFactory } from '../../node/index.js';
17
+ import { configFromOptions, currencyFromOptions, requiredByteCountFromOptions, } from '../utils.js';
18
+ export async function fiatEstimate(options) {
19
+ const byteCount = requiredByteCountFromOptions(options);
20
+ const currency = currencyFromOptions(options) ?? 'usd';
21
+ const turbo = TurboFactory.unauthenticated(configFromOptions(options));
22
+ const result = await turbo.getFiatEstimateForBytes({
23
+ byteCount,
24
+ currency,
25
+ });
26
+ const output = {
27
+ ...result,
28
+ message: `The current price estimate for ${byteCount} bytes is ${result.amount} ${currency}`,
29
+ };
30
+ console.log(JSON.stringify(output, null, 2));
31
+ }