@glowlabs-org/utils 0.1.4 → 0.2.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.
package/dist/esm/index.js CHANGED
@@ -5,7 +5,7 @@ import require$$3 from 'http';
5
5
  import require$$4 from 'https';
6
6
  import require$$0$1 from 'url';
7
7
  import require$$6 from 'fs';
8
- import crypto from 'crypto';
8
+ import require$$8 from 'crypto';
9
9
  import require$$4$1 from 'assert';
10
10
  import zlib from 'zlib';
11
11
  import { EventEmitter } from 'events';
@@ -16,7 +16,7 @@ import Decimal from 'decimal.js';
16
16
 
17
17
  const GENESIS_TIMESTAMP = 1700352000;
18
18
 
19
- function bind$1(fn, thisArg) {
19
+ function bind$2(fn, thisArg) {
20
20
  return function wrap() {
21
21
  return fn.apply(thisArg, arguments);
22
22
  };
@@ -156,6 +156,27 @@ const isPlainObject = (val) => {
156
156
  return (prototype === null || prototype === Object.prototype || Object.getPrototypeOf(prototype) === null) && !(toStringTag$1 in val) && !(iterator in val);
157
157
  };
158
158
 
159
+ /**
160
+ * Determine if a value is an empty object (safely handles Buffers)
161
+ *
162
+ * @param {*} val The value to test
163
+ *
164
+ * @returns {boolean} True if value is an empty object, otherwise false
165
+ */
166
+ const isEmptyObject = (val) => {
167
+ // Early return for non-objects or Buffers to prevent RangeError
168
+ if (!isObject(val) || isBuffer$1(val)) {
169
+ return false;
170
+ }
171
+
172
+ try {
173
+ return Object.keys(val).length === 0 && Object.getPrototypeOf(val) === Object.prototype;
174
+ } catch (e) {
175
+ // Fallback for any other objects that might cause RangeError with Object.keys()
176
+ return false;
177
+ }
178
+ };
179
+
159
180
  /**
160
181
  * Determine if a value is a Date
161
182
  *
@@ -278,6 +299,11 @@ function forEach(obj, fn, {allOwnKeys = false} = {}) {
278
299
  fn.call(null, obj[i], i, obj);
279
300
  }
280
301
  } else {
302
+ // Buffer check
303
+ if (isBuffer$1(obj)) {
304
+ return;
305
+ }
306
+
281
307
  // Iterate over object keys
282
308
  const keys = allOwnKeys ? Object.getOwnPropertyNames(obj) : Object.keys(obj);
283
309
  const len = keys.length;
@@ -291,6 +317,10 @@ function forEach(obj, fn, {allOwnKeys = false} = {}) {
291
317
  }
292
318
 
293
319
  function findKey(obj, key) {
320
+ if (isBuffer$1(obj)){
321
+ return null;
322
+ }
323
+
294
324
  key = key.toLowerCase();
295
325
  const keys = Object.keys(obj);
296
326
  let i = keys.length;
@@ -365,7 +395,7 @@ function merge(/* obj1, obj2, obj3, ... */) {
365
395
  const extend = (a, b, thisArg, {allOwnKeys}= {}) => {
366
396
  forEach(b, (val, key) => {
367
397
  if (thisArg && isFunction$1(val)) {
368
- a[key] = bind$1(val, thisArg);
398
+ a[key] = bind$2(val, thisArg);
369
399
  } else {
370
400
  a[key] = val;
371
401
  }
@@ -644,6 +674,11 @@ const toJSONObject = (obj) => {
644
674
  return;
645
675
  }
646
676
 
677
+ //Buffer check
678
+ if (isBuffer$1(source)) {
679
+ return source;
680
+ }
681
+
647
682
  if(!('toJSON' in source)) {
648
683
  stack[i] = source;
649
684
  const target = isArray(source) ? [] : {};
@@ -715,6 +750,7 @@ var utils$1 = {
715
750
  isBoolean,
716
751
  isObject,
717
752
  isPlainObject,
753
+ isEmptyObject,
718
754
  isReadableStream,
719
755
  isRequest,
720
756
  isResponse,
@@ -12515,7 +12551,7 @@ var abs$1 = Math.abs;
12515
12551
  var floor$1 = Math.floor;
12516
12552
 
12517
12553
  /** @type {import('./max')} */
12518
- var max$1 = Math.max;
12554
+ var max$2 = Math.max;
12519
12555
 
12520
12556
  /** @type {import('./min')} */
12521
12557
  var min$1 = Math.min;
@@ -12672,110 +12708,92 @@ function requireObject_getPrototypeOf () {
12672
12708
  return Object_getPrototypeOf;
12673
12709
  }
12674
12710
 
12675
- var implementation;
12676
- var hasRequiredImplementation;
12677
-
12678
- function requireImplementation () {
12679
- if (hasRequiredImplementation) return implementation;
12680
- hasRequiredImplementation = 1;
12681
-
12682
- /* eslint no-invalid-this: 1 */
12683
-
12684
- var ERROR_MESSAGE = 'Function.prototype.bind called on incompatible ';
12685
- var toStr = Object.prototype.toString;
12686
- var max = Math.max;
12687
- var funcType = '[object Function]';
12711
+ /* eslint no-invalid-this: 1 */
12688
12712
 
12689
- var concatty = function concatty(a, b) {
12690
- var arr = [];
12691
-
12692
- for (var i = 0; i < a.length; i += 1) {
12693
- arr[i] = a[i];
12694
- }
12695
- for (var j = 0; j < b.length; j += 1) {
12696
- arr[j + a.length] = b[j];
12697
- }
12713
+ var ERROR_MESSAGE = 'Function.prototype.bind called on incompatible ';
12714
+ var toStr = Object.prototype.toString;
12715
+ var max$1 = Math.max;
12716
+ var funcType = '[object Function]';
12698
12717
 
12699
- return arr;
12700
- };
12718
+ var concatty = function concatty(a, b) {
12719
+ var arr = [];
12701
12720
 
12702
- var slicy = function slicy(arrLike, offset) {
12703
- var arr = [];
12704
- for (var i = offset, j = 0; i < arrLike.length; i += 1, j += 1) {
12705
- arr[j] = arrLike[i];
12706
- }
12707
- return arr;
12708
- };
12721
+ for (var i = 0; i < a.length; i += 1) {
12722
+ arr[i] = a[i];
12723
+ }
12724
+ for (var j = 0; j < b.length; j += 1) {
12725
+ arr[j + a.length] = b[j];
12726
+ }
12709
12727
 
12710
- var joiny = function (arr, joiner) {
12711
- var str = '';
12712
- for (var i = 0; i < arr.length; i += 1) {
12713
- str += arr[i];
12714
- if (i + 1 < arr.length) {
12715
- str += joiner;
12716
- }
12717
- }
12718
- return str;
12719
- };
12728
+ return arr;
12729
+ };
12720
12730
 
12721
- implementation = function bind(that) {
12722
- var target = this;
12723
- if (typeof target !== 'function' || toStr.apply(target) !== funcType) {
12724
- throw new TypeError(ERROR_MESSAGE + target);
12725
- }
12726
- var args = slicy(arguments, 1);
12727
-
12728
- var bound;
12729
- var binder = function () {
12730
- if (this instanceof bound) {
12731
- var result = target.apply(
12732
- this,
12733
- concatty(args, arguments)
12734
- );
12735
- if (Object(result) === result) {
12736
- return result;
12737
- }
12738
- return this;
12739
- }
12740
- return target.apply(
12741
- that,
12742
- concatty(args, arguments)
12743
- );
12731
+ var slicy = function slicy(arrLike, offset) {
12732
+ var arr = [];
12733
+ for (var i = offset, j = 0; i < arrLike.length; i += 1, j += 1) {
12734
+ arr[j] = arrLike[i];
12735
+ }
12736
+ return arr;
12737
+ };
12744
12738
 
12745
- };
12739
+ var joiny = function (arr, joiner) {
12740
+ var str = '';
12741
+ for (var i = 0; i < arr.length; i += 1) {
12742
+ str += arr[i];
12743
+ if (i + 1 < arr.length) {
12744
+ str += joiner;
12745
+ }
12746
+ }
12747
+ return str;
12748
+ };
12746
12749
 
12747
- var boundLength = max(0, target.length - args.length);
12748
- var boundArgs = [];
12749
- for (var i = 0; i < boundLength; i++) {
12750
- boundArgs[i] = '$' + i;
12751
- }
12750
+ var implementation$1 = function bind(that) {
12751
+ var target = this;
12752
+ if (typeof target !== 'function' || toStr.apply(target) !== funcType) {
12753
+ throw new TypeError(ERROR_MESSAGE + target);
12754
+ }
12755
+ var args = slicy(arguments, 1);
12756
+
12757
+ var bound;
12758
+ var binder = function () {
12759
+ if (this instanceof bound) {
12760
+ var result = target.apply(
12761
+ this,
12762
+ concatty(args, arguments)
12763
+ );
12764
+ if (Object(result) === result) {
12765
+ return result;
12766
+ }
12767
+ return this;
12768
+ }
12769
+ return target.apply(
12770
+ that,
12771
+ concatty(args, arguments)
12772
+ );
12752
12773
 
12753
- bound = Function('binder', 'return function (' + joiny(boundArgs, ',') + '){ return binder.apply(this,arguments); }')(binder);
12774
+ };
12754
12775
 
12755
- if (target.prototype) {
12756
- var Empty = function Empty() {};
12757
- Empty.prototype = target.prototype;
12758
- bound.prototype = new Empty();
12759
- Empty.prototype = null;
12760
- }
12776
+ var boundLength = max$1(0, target.length - args.length);
12777
+ var boundArgs = [];
12778
+ for (var i = 0; i < boundLength; i++) {
12779
+ boundArgs[i] = '$' + i;
12780
+ }
12761
12781
 
12762
- return bound;
12763
- };
12764
- return implementation;
12765
- }
12782
+ bound = Function('binder', 'return function (' + joiny(boundArgs, ',') + '){ return binder.apply(this,arguments); }')(binder);
12766
12783
 
12767
- var functionBind;
12768
- var hasRequiredFunctionBind;
12784
+ if (target.prototype) {
12785
+ var Empty = function Empty() {};
12786
+ Empty.prototype = target.prototype;
12787
+ bound.prototype = new Empty();
12788
+ Empty.prototype = null;
12789
+ }
12769
12790
 
12770
- function requireFunctionBind () {
12771
- if (hasRequiredFunctionBind) return functionBind;
12772
- hasRequiredFunctionBind = 1;
12791
+ return bound;
12792
+ };
12773
12793
 
12774
- var implementation = requireImplementation();
12794
+ var implementation = implementation$1;
12775
12795
 
12776
- functionBind = Function.prototype.bind || implementation;
12777
- return functionBind;
12778
- }
12796
+ var functionBind = Function.prototype.bind || implementation;
12779
12797
 
12780
12798
  var functionCall;
12781
12799
  var hasRequiredFunctionCall;
@@ -12820,7 +12838,7 @@ function requireActualApply () {
12820
12838
  if (hasRequiredActualApply) return actualApply;
12821
12839
  hasRequiredActualApply = 1;
12822
12840
 
12823
- var bind = requireFunctionBind();
12841
+ var bind = functionBind;
12824
12842
 
12825
12843
  var $apply = requireFunctionApply();
12826
12844
  var $call = requireFunctionCall();
@@ -12838,7 +12856,7 @@ function requireCallBindApplyHelpers () {
12838
12856
  if (hasRequiredCallBindApplyHelpers) return callBindApplyHelpers;
12839
12857
  hasRequiredCallBindApplyHelpers = 1;
12840
12858
 
12841
- var bind = requireFunctionBind();
12859
+ var bind = functionBind;
12842
12860
  var $TypeError = requireType();
12843
12861
 
12844
12862
  var $call = requireFunctionCall();
@@ -12927,21 +12945,12 @@ function requireGetProto () {
12927
12945
  return getProto$1;
12928
12946
  }
12929
12947
 
12930
- var hasown;
12931
- var hasRequiredHasown;
12932
-
12933
- function requireHasown () {
12934
- if (hasRequiredHasown) return hasown;
12935
- hasRequiredHasown = 1;
12948
+ var call = Function.prototype.call;
12949
+ var $hasOwn = Object.prototype.hasOwnProperty;
12950
+ var bind$1 = functionBind;
12936
12951
 
12937
- var call = Function.prototype.call;
12938
- var $hasOwn = Object.prototype.hasOwnProperty;
12939
- var bind = requireFunctionBind();
12940
-
12941
- /** @type {import('.')} */
12942
- hasown = bind.call(call, $hasOwn);
12943
- return hasown;
12944
- }
12952
+ /** @type {import('.')} */
12953
+ var hasown = bind$1.call(call, $hasOwn);
12945
12954
 
12946
12955
  var undefined$1;
12947
12956
 
@@ -12957,7 +12966,7 @@ var $URIError = uri;
12957
12966
 
12958
12967
  var abs = abs$1;
12959
12968
  var floor = floor$1;
12960
- var max = max$1;
12969
+ var max = max$2;
12961
12970
  var min = min$1;
12962
12971
  var pow = pow$1;
12963
12972
  var round = round$1;
@@ -13183,8 +13192,8 @@ var LEGACY_ALIASES = {
13183
13192
  '%WeakSetPrototype%': ['WeakSet', 'prototype']
13184
13193
  };
13185
13194
 
13186
- var bind = requireFunctionBind();
13187
- var hasOwn$1 = requireHasown();
13195
+ var bind = functionBind;
13196
+ var hasOwn$2 = hasown;
13188
13197
  var $concat = bind.call($call, Array.prototype.concat);
13189
13198
  var $spliceApply = bind.call($apply, Array.prototype.splice);
13190
13199
  var $replace = bind.call($call, String.prototype.replace);
@@ -13213,12 +13222,12 @@ var stringToPath = function stringToPath(string) {
13213
13222
  var getBaseIntrinsic = function getBaseIntrinsic(name, allowMissing) {
13214
13223
  var intrinsicName = name;
13215
13224
  var alias;
13216
- if (hasOwn$1(LEGACY_ALIASES, intrinsicName)) {
13225
+ if (hasOwn$2(LEGACY_ALIASES, intrinsicName)) {
13217
13226
  alias = LEGACY_ALIASES[intrinsicName];
13218
13227
  intrinsicName = '%' + alias[0] + '%';
13219
13228
  }
13220
13229
 
13221
- if (hasOwn$1(INTRINSICS, intrinsicName)) {
13230
+ if (hasOwn$2(INTRINSICS, intrinsicName)) {
13222
13231
  var value = INTRINSICS[intrinsicName];
13223
13232
  if (value === needsEval) {
13224
13233
  value = doEval(intrinsicName);
@@ -13282,14 +13291,14 @@ var getIntrinsic = function GetIntrinsic(name, allowMissing) {
13282
13291
  intrinsicBaseName += '.' + part;
13283
13292
  intrinsicRealName = '%' + intrinsicBaseName + '%';
13284
13293
 
13285
- if (hasOwn$1(INTRINSICS, intrinsicRealName)) {
13294
+ if (hasOwn$2(INTRINSICS, intrinsicRealName)) {
13286
13295
  value = INTRINSICS[intrinsicRealName];
13287
13296
  } else if (value != null) {
13288
13297
  if (!(part in value)) {
13289
13298
  if (!allowMissing) {
13290
13299
  throw new $TypeError$1('base intrinsic for ' + name + ' exists, but the property is not available.');
13291
13300
  }
13292
- return void 0;
13301
+ return void undefined$1;
13293
13302
  }
13294
13303
  if ($gOPD && (i + 1) >= parts.length) {
13295
13304
  var desc = $gOPD(value, part);
@@ -13308,7 +13317,7 @@ var getIntrinsic = function GetIntrinsic(name, allowMissing) {
13308
13317
  value = value[part];
13309
13318
  }
13310
13319
  } else {
13311
- isOwn = hasOwn$1(value, part);
13320
+ isOwn = hasOwn$2(value, part);
13312
13321
  value = value[part];
13313
13322
  }
13314
13323
 
@@ -13341,7 +13350,7 @@ var GetIntrinsic = getIntrinsic;
13341
13350
  var $defineProperty = GetIntrinsic('%Object.defineProperty%', true);
13342
13351
 
13343
13352
  var hasToStringTag = requireShams()();
13344
- var hasOwn = requireHasown();
13353
+ var hasOwn$1 = hasown;
13345
13354
  var $TypeError = requireType();
13346
13355
 
13347
13356
  var toStringTag = hasToStringTag ? Symbol.toStringTag : null;
@@ -13356,7 +13365,7 @@ var esSetTostringtag = function setToStringTag(object, value) {
13356
13365
  ) {
13357
13366
  throw new $TypeError('if provided, the `overrideIfSet` and `nonConfigurable` options must be booleans');
13358
13367
  }
13359
- if (toStringTag && (overrideIfSet || !hasOwn(object, toStringTag))) {
13368
+ if (toStringTag && (overrideIfSet || !hasOwn$1(object, toStringTag))) {
13360
13369
  if ($defineProperty) {
13361
13370
  $defineProperty(object, toStringTag, {
13362
13371
  configurable: !nonConfigurable,
@@ -13371,11 +13380,9 @@ var esSetTostringtag = function setToStringTag(object, value) {
13371
13380
  };
13372
13381
 
13373
13382
  // populates missing values
13374
- var populate$1 = function(dst, src) {
13375
-
13376
- Object.keys(src).forEach(function(prop)
13377
- {
13378
- dst[prop] = dst[prop] || src[prop];
13383
+ var populate$1 = function (dst, src) {
13384
+ Object.keys(src).forEach(function (prop) {
13385
+ dst[prop] = dst[prop] || src[prop]; // eslint-disable-line no-param-reassign
13379
13386
  });
13380
13387
 
13381
13388
  return dst;
@@ -13389,24 +13396,20 @@ var https$1 = require$$4;
13389
13396
  var parseUrl$2 = require$$0$1.parse;
13390
13397
  var fs = require$$6;
13391
13398
  var Stream = stream.Stream;
13399
+ var crypto = require$$8;
13392
13400
  var mime = mimeTypes;
13393
13401
  var asynckit = asynckit$1;
13394
13402
  var setToStringTag = esSetTostringtag;
13403
+ var hasOwn = hasown;
13395
13404
  var populate = populate$1;
13396
13405
 
13397
- // Public API
13398
- var form_data = FormData$1;
13399
-
13400
- // make it a Stream
13401
- util.inherits(FormData$1, CombinedStream);
13402
-
13403
13406
  /**
13404
13407
  * Create readable "multipart/form-data" streams.
13405
13408
  * Can be used to submit forms
13406
13409
  * and file uploads to other web applications.
13407
13410
  *
13408
13411
  * @constructor
13409
- * @param {Object} options - Properties to be added/overriden for FormData and CombinedStream
13412
+ * @param {object} options - Properties to be added/overriden for FormData and CombinedStream
13410
13413
  */
13411
13414
  function FormData$1(options) {
13412
13415
  if (!(this instanceof FormData$1)) {
@@ -13419,35 +13422,39 @@ function FormData$1(options) {
13419
13422
 
13420
13423
  CombinedStream.call(this);
13421
13424
 
13422
- options = options || {};
13423
- for (var option in options) {
13425
+ options = options || {}; // eslint-disable-line no-param-reassign
13426
+ for (var option in options) { // eslint-disable-line no-restricted-syntax
13424
13427
  this[option] = options[option];
13425
13428
  }
13426
13429
  }
13427
13430
 
13431
+ // make it a Stream
13432
+ util.inherits(FormData$1, CombinedStream);
13433
+
13428
13434
  FormData$1.LINE_BREAK = '\r\n';
13429
13435
  FormData$1.DEFAULT_CONTENT_TYPE = 'application/octet-stream';
13430
13436
 
13431
- FormData$1.prototype.append = function(field, value, options) {
13432
-
13433
- options = options || {};
13437
+ FormData$1.prototype.append = function (field, value, options) {
13438
+ options = options || {}; // eslint-disable-line no-param-reassign
13434
13439
 
13435
13440
  // allow filename as single option
13436
- if (typeof options == 'string') {
13437
- options = {filename: options};
13441
+ if (typeof options === 'string') {
13442
+ options = { filename: options }; // eslint-disable-line no-param-reassign
13438
13443
  }
13439
13444
 
13440
13445
  var append = CombinedStream.prototype.append.bind(this);
13441
13446
 
13442
13447
  // all that streamy business can't handle numbers
13443
- if (typeof value == 'number') {
13444
- value = '' + value;
13448
+ if (typeof value === 'number' || value == null) {
13449
+ value = String(value); // eslint-disable-line no-param-reassign
13445
13450
  }
13446
13451
 
13447
13452
  // https://github.com/felixge/node-form-data/issues/38
13448
13453
  if (Array.isArray(value)) {
13449
- // Please convert your array into string
13450
- // the way web server expects it
13454
+ /*
13455
+ * Please convert your array into string
13456
+ * the way web server expects it
13457
+ */
13451
13458
  this._error(new Error('Arrays are not supported.'));
13452
13459
  return;
13453
13460
  }
@@ -13463,15 +13470,17 @@ FormData$1.prototype.append = function(field, value, options) {
13463
13470
  this._trackLength(header, value, options);
13464
13471
  };
13465
13472
 
13466
- FormData$1.prototype._trackLength = function(header, value, options) {
13473
+ FormData$1.prototype._trackLength = function (header, value, options) {
13467
13474
  var valueLength = 0;
13468
13475
 
13469
- // used w/ getLengthSync(), when length is known.
13470
- // e.g. for streaming directly from a remote server,
13471
- // w/ a known file a size, and not wanting to wait for
13472
- // incoming file to finish to get its size.
13476
+ /*
13477
+ * used w/ getLengthSync(), when length is known.
13478
+ * e.g. for streaming directly from a remote server,
13479
+ * w/ a known file a size, and not wanting to wait for
13480
+ * incoming file to finish to get its size.
13481
+ */
13473
13482
  if (options.knownLength != null) {
13474
- valueLength += +options.knownLength;
13483
+ valueLength += Number(options.knownLength);
13475
13484
  } else if (Buffer.isBuffer(value)) {
13476
13485
  valueLength = value.length;
13477
13486
  } else if (typeof value === 'string') {
@@ -13481,12 +13490,10 @@ FormData$1.prototype._trackLength = function(header, value, options) {
13481
13490
  this._valueLength += valueLength;
13482
13491
 
13483
13492
  // @check why add CRLF? does this account for custom/multiple CRLFs?
13484
- this._overheadLength +=
13485
- Buffer.byteLength(header) +
13486
- FormData$1.LINE_BREAK.length;
13493
+ this._overheadLength += Buffer.byteLength(header) + FormData$1.LINE_BREAK.length;
13487
13494
 
13488
13495
  // empty or either doesn't have path or not an http response or not a stream
13489
- if (!value || ( !value.path && !(value.readable && Object.prototype.hasOwnProperty.call(value, 'httpVersion')) && !(value instanceof Stream))) {
13496
+ if (!value || (!value.path && !(value.readable && hasOwn(value, 'httpVersion')) && !(value instanceof Stream))) {
13490
13497
  return;
13491
13498
  }
13492
13499
 
@@ -13496,9 +13503,8 @@ FormData$1.prototype._trackLength = function(header, value, options) {
13496
13503
  }
13497
13504
  };
13498
13505
 
13499
- FormData$1.prototype._lengthRetriever = function(value, callback) {
13500
- if (Object.prototype.hasOwnProperty.call(value, 'fd')) {
13501
-
13506
+ FormData$1.prototype._lengthRetriever = function (value, callback) {
13507
+ if (hasOwn(value, 'fd')) {
13502
13508
  // take read range into a account
13503
13509
  // `end` = Infinity –> read file till the end
13504
13510
  //
@@ -13507,54 +13513,52 @@ FormData$1.prototype._lengthRetriever = function(value, callback) {
13507
13513
  // Fix it when node fixes it.
13508
13514
  // https://github.com/joyent/node/issues/7819
13509
13515
  if (value.end != undefined && value.end != Infinity && value.start != undefined) {
13510
-
13511
13516
  // when end specified
13512
13517
  // no need to calculate range
13513
13518
  // inclusive, starts with 0
13514
- callback(null, value.end + 1 - (value.start ? value.start : 0));
13519
+ callback(null, value.end + 1 - (value.start ? value.start : 0)); // eslint-disable-line callback-return
13515
13520
 
13516
- // not that fast snoopy
13521
+ // not that fast snoopy
13517
13522
  } else {
13518
13523
  // still need to fetch file size from fs
13519
- fs.stat(value.path, function(err, stat) {
13520
-
13521
- var fileSize;
13522
-
13524
+ fs.stat(value.path, function (err, stat) {
13523
13525
  if (err) {
13524
13526
  callback(err);
13525
13527
  return;
13526
13528
  }
13527
13529
 
13528
13530
  // update final size based on the range options
13529
- fileSize = stat.size - (value.start ? value.start : 0);
13531
+ var fileSize = stat.size - (value.start ? value.start : 0);
13530
13532
  callback(null, fileSize);
13531
13533
  });
13532
13534
  }
13533
13535
 
13534
- // or http response
13535
- } else if (Object.prototype.hasOwnProperty.call(value, 'httpVersion')) {
13536
- callback(null, +value.headers['content-length']);
13536
+ // or http response
13537
+ } else if (hasOwn(value, 'httpVersion')) {
13538
+ callback(null, Number(value.headers['content-length'])); // eslint-disable-line callback-return
13537
13539
 
13538
- // or request stream http://github.com/mikeal/request
13539
- } else if (Object.prototype.hasOwnProperty.call(value, 'httpModule')) {
13540
+ // or request stream http://github.com/mikeal/request
13541
+ } else if (hasOwn(value, 'httpModule')) {
13540
13542
  // wait till response come back
13541
- value.on('response', function(response) {
13543
+ value.on('response', function (response) {
13542
13544
  value.pause();
13543
- callback(null, +response.headers['content-length']);
13545
+ callback(null, Number(response.headers['content-length']));
13544
13546
  });
13545
13547
  value.resume();
13546
13548
 
13547
- // something else
13549
+ // something else
13548
13550
  } else {
13549
- callback('Unknown stream');
13551
+ callback('Unknown stream'); // eslint-disable-line callback-return
13550
13552
  }
13551
13553
  };
13552
13554
 
13553
- FormData$1.prototype._multiPartHeader = function(field, value, options) {
13554
- // custom header specified (as string)?
13555
- // it becomes responsible for boundary
13556
- // (e.g. to handle extra CRLFs on .NET servers)
13557
- if (typeof options.header == 'string') {
13555
+ FormData$1.prototype._multiPartHeader = function (field, value, options) {
13556
+ /*
13557
+ * custom header specified (as string)?
13558
+ * it becomes responsible for boundary
13559
+ * (e.g. to handle extra CRLFs on .NET servers)
13560
+ */
13561
+ if (typeof options.header === 'string') {
13558
13562
  return options.header;
13559
13563
  }
13560
13564
 
@@ -13562,7 +13566,7 @@ FormData$1.prototype._multiPartHeader = function(field, value, options) {
13562
13566
  var contentType = this._getContentType(value, options);
13563
13567
 
13564
13568
  var contents = '';
13565
- var headers = {
13569
+ var headers = {
13566
13570
  // add custom disposition as third element or keep it two elements if not
13567
13571
  'Content-Disposition': ['form-data', 'name="' + field + '"'].concat(contentDisposition || []),
13568
13572
  // if no content type. allow it to be empty array
@@ -13570,18 +13574,18 @@ FormData$1.prototype._multiPartHeader = function(field, value, options) {
13570
13574
  };
13571
13575
 
13572
13576
  // allow custom headers.
13573
- if (typeof options.header == 'object') {
13577
+ if (typeof options.header === 'object') {
13574
13578
  populate(headers, options.header);
13575
13579
  }
13576
13580
 
13577
13581
  var header;
13578
- for (var prop in headers) {
13579
- if (Object.prototype.hasOwnProperty.call(headers, prop)) {
13582
+ for (var prop in headers) { // eslint-disable-line no-restricted-syntax
13583
+ if (hasOwn(headers, prop)) {
13580
13584
  header = headers[prop];
13581
13585
 
13582
13586
  // skip nullish headers.
13583
13587
  if (header == null) {
13584
- continue;
13588
+ continue; // eslint-disable-line no-restricted-syntax, no-continue
13585
13589
  }
13586
13590
 
13587
13591
  // convert all headers to arrays.
@@ -13599,49 +13603,45 @@ FormData$1.prototype._multiPartHeader = function(field, value, options) {
13599
13603
  return '--' + this.getBoundary() + FormData$1.LINE_BREAK + contents + FormData$1.LINE_BREAK;
13600
13604
  };
13601
13605
 
13602
- FormData$1.prototype._getContentDisposition = function(value, options) {
13603
-
13604
- var filename
13605
- , contentDisposition
13606
- ;
13606
+ FormData$1.prototype._getContentDisposition = function (value, options) { // eslint-disable-line consistent-return
13607
+ var filename;
13607
13608
 
13608
13609
  if (typeof options.filepath === 'string') {
13609
13610
  // custom filepath for relative paths
13610
13611
  filename = path.normalize(options.filepath).replace(/\\/g, '/');
13611
- } else if (options.filename || value.name || value.path) {
13612
- // custom filename take precedence
13613
- // formidable and the browser add a name property
13614
- // fs- and request- streams have path property
13615
- filename = path.basename(options.filename || value.name || value.path);
13616
- } else if (value.readable && Object.prototype.hasOwnProperty.call(value, 'httpVersion')) {
13612
+ } else if (options.filename || (value && (value.name || value.path))) {
13613
+ /*
13614
+ * custom filename take precedence
13615
+ * formidable and the browser add a name property
13616
+ * fs- and request- streams have path property
13617
+ */
13618
+ filename = path.basename(options.filename || (value && (value.name || value.path)));
13619
+ } else if (value && value.readable && hasOwn(value, 'httpVersion')) {
13617
13620
  // or try http response
13618
13621
  filename = path.basename(value.client._httpMessage.path || '');
13619
13622
  }
13620
13623
 
13621
13624
  if (filename) {
13622
- contentDisposition = 'filename="' + filename + '"';
13625
+ return 'filename="' + filename + '"';
13623
13626
  }
13624
-
13625
- return contentDisposition;
13626
13627
  };
13627
13628
 
13628
- FormData$1.prototype._getContentType = function(value, options) {
13629
-
13629
+ FormData$1.prototype._getContentType = function (value, options) {
13630
13630
  // use custom content-type above all
13631
13631
  var contentType = options.contentType;
13632
13632
 
13633
13633
  // or try `name` from formidable, browser
13634
- if (!contentType && value.name) {
13634
+ if (!contentType && value && value.name) {
13635
13635
  contentType = mime.lookup(value.name);
13636
13636
  }
13637
13637
 
13638
13638
  // or try `path` from fs-, request- streams
13639
- if (!contentType && value.path) {
13639
+ if (!contentType && value && value.path) {
13640
13640
  contentType = mime.lookup(value.path);
13641
13641
  }
13642
13642
 
13643
13643
  // or if it's http-reponse
13644
- if (!contentType && value.readable && Object.prototype.hasOwnProperty.call(value, 'httpVersion')) {
13644
+ if (!contentType && value && value.readable && hasOwn(value, 'httpVersion')) {
13645
13645
  contentType = value.headers['content-type'];
13646
13646
  }
13647
13647
 
@@ -13651,18 +13651,18 @@ FormData$1.prototype._getContentType = function(value, options) {
13651
13651
  }
13652
13652
 
13653
13653
  // fallback to the default content type if `value` is not simple value
13654
- if (!contentType && typeof value == 'object') {
13654
+ if (!contentType && value && typeof value === 'object') {
13655
13655
  contentType = FormData$1.DEFAULT_CONTENT_TYPE;
13656
13656
  }
13657
13657
 
13658
13658
  return contentType;
13659
13659
  };
13660
13660
 
13661
- FormData$1.prototype._multiPartFooter = function() {
13662
- return function(next) {
13661
+ FormData$1.prototype._multiPartFooter = function () {
13662
+ return function (next) {
13663
13663
  var footer = FormData$1.LINE_BREAK;
13664
13664
 
13665
- var lastPart = (this._streams.length === 0);
13665
+ var lastPart = this._streams.length === 0;
13666
13666
  if (lastPart) {
13667
13667
  footer += this._lastBoundary();
13668
13668
  }
@@ -13671,18 +13671,18 @@ FormData$1.prototype._multiPartFooter = function() {
13671
13671
  }.bind(this);
13672
13672
  };
13673
13673
 
13674
- FormData$1.prototype._lastBoundary = function() {
13674
+ FormData$1.prototype._lastBoundary = function () {
13675
13675
  return '--' + this.getBoundary() + '--' + FormData$1.LINE_BREAK;
13676
13676
  };
13677
13677
 
13678
- FormData$1.prototype.getHeaders = function(userHeaders) {
13678
+ FormData$1.prototype.getHeaders = function (userHeaders) {
13679
13679
  var header;
13680
13680
  var formHeaders = {
13681
13681
  'content-type': 'multipart/form-data; boundary=' + this.getBoundary()
13682
13682
  };
13683
13683
 
13684
- for (header in userHeaders) {
13685
- if (Object.prototype.hasOwnProperty.call(userHeaders, header)) {
13684
+ for (header in userHeaders) { // eslint-disable-line no-restricted-syntax
13685
+ if (hasOwn(userHeaders, header)) {
13686
13686
  formHeaders[header.toLowerCase()] = userHeaders[header];
13687
13687
  }
13688
13688
  }
@@ -13690,11 +13690,14 @@ FormData$1.prototype.getHeaders = function(userHeaders) {
13690
13690
  return formHeaders;
13691
13691
  };
13692
13692
 
13693
- FormData$1.prototype.setBoundary = function(boundary) {
13693
+ FormData$1.prototype.setBoundary = function (boundary) {
13694
+ if (typeof boundary !== 'string') {
13695
+ throw new TypeError('FormData boundary must be a string');
13696
+ }
13694
13697
  this._boundary = boundary;
13695
13698
  };
13696
13699
 
13697
- FormData$1.prototype.getBoundary = function() {
13700
+ FormData$1.prototype.getBoundary = function () {
13698
13701
  if (!this._boundary) {
13699
13702
  this._generateBoundary();
13700
13703
  }
@@ -13702,60 +13705,55 @@ FormData$1.prototype.getBoundary = function() {
13702
13705
  return this._boundary;
13703
13706
  };
13704
13707
 
13705
- FormData$1.prototype.getBuffer = function() {
13706
- var dataBuffer = new Buffer.alloc(0);
13708
+ FormData$1.prototype.getBuffer = function () {
13709
+ var dataBuffer = new Buffer.alloc(0); // eslint-disable-line new-cap
13707
13710
  var boundary = this.getBoundary();
13708
13711
 
13709
13712
  // Create the form content. Add Line breaks to the end of data.
13710
13713
  for (var i = 0, len = this._streams.length; i < len; i++) {
13711
13714
  if (typeof this._streams[i] !== 'function') {
13712
-
13713
13715
  // Add content to the buffer.
13714
- if(Buffer.isBuffer(this._streams[i])) {
13715
- dataBuffer = Buffer.concat( [dataBuffer, this._streams[i]]);
13716
- }else {
13717
- dataBuffer = Buffer.concat( [dataBuffer, Buffer.from(this._streams[i])]);
13716
+ if (Buffer.isBuffer(this._streams[i])) {
13717
+ dataBuffer = Buffer.concat([dataBuffer, this._streams[i]]);
13718
+ } else {
13719
+ dataBuffer = Buffer.concat([dataBuffer, Buffer.from(this._streams[i])]);
13718
13720
  }
13719
13721
 
13720
13722
  // Add break after content.
13721
- if (typeof this._streams[i] !== 'string' || this._streams[i].substring( 2, boundary.length + 2 ) !== boundary) {
13722
- dataBuffer = Buffer.concat( [dataBuffer, Buffer.from(FormData$1.LINE_BREAK)] );
13723
+ if (typeof this._streams[i] !== 'string' || this._streams[i].substring(2, boundary.length + 2) !== boundary) {
13724
+ dataBuffer = Buffer.concat([dataBuffer, Buffer.from(FormData$1.LINE_BREAK)]);
13723
13725
  }
13724
13726
  }
13725
13727
  }
13726
13728
 
13727
13729
  // Add the footer and return the Buffer object.
13728
- return Buffer.concat( [dataBuffer, Buffer.from(this._lastBoundary())] );
13730
+ return Buffer.concat([dataBuffer, Buffer.from(this._lastBoundary())]);
13729
13731
  };
13730
13732
 
13731
- FormData$1.prototype._generateBoundary = function() {
13733
+ FormData$1.prototype._generateBoundary = function () {
13732
13734
  // This generates a 50 character boundary similar to those used by Firefox.
13733
- // They are optimized for boyer-moore parsing.
13734
- var boundary = '--------------------------';
13735
- for (var i = 0; i < 24; i++) {
13736
- boundary += Math.floor(Math.random() * 10).toString(16);
13737
- }
13738
13735
 
13739
- this._boundary = boundary;
13736
+ // They are optimized for boyer-moore parsing.
13737
+ this._boundary = '--------------------------' + crypto.randomBytes(12).toString('hex');
13740
13738
  };
13741
13739
 
13742
13740
  // Note: getLengthSync DOESN'T calculate streams length
13743
- // As workaround one can calculate file size manually
13744
- // and add it as knownLength option
13745
- FormData$1.prototype.getLengthSync = function() {
13741
+ // As workaround one can calculate file size manually and add it as knownLength option
13742
+ FormData$1.prototype.getLengthSync = function () {
13746
13743
  var knownLength = this._overheadLength + this._valueLength;
13747
13744
 
13748
- // Don't get confused, there are 3 "internal" streams for each keyval pair
13749
- // so it basically checks if there is any value added to the form
13745
+ // Don't get confused, there are 3 "internal" streams for each keyval pair so it basically checks if there is any value added to the form
13750
13746
  if (this._streams.length) {
13751
13747
  knownLength += this._lastBoundary().length;
13752
13748
  }
13753
13749
 
13754
13750
  // https://github.com/form-data/form-data/issues/40
13755
13751
  if (!this.hasKnownLength()) {
13756
- // Some async length retrievers are present
13757
- // therefore synchronous length calculation is false.
13758
- // Please use getLength(callback) to get proper length
13752
+ /*
13753
+ * Some async length retrievers are present
13754
+ * therefore synchronous length calculation is false.
13755
+ * Please use getLength(callback) to get proper length
13756
+ */
13759
13757
  this._error(new Error('Cannot calculate proper length in synchronous way.'));
13760
13758
  }
13761
13759
 
@@ -13765,7 +13763,7 @@ FormData$1.prototype.getLengthSync = function() {
13765
13763
  // Public API to check if length of added values is known
13766
13764
  // https://github.com/form-data/form-data/issues/196
13767
13765
  // https://github.com/form-data/form-data/issues/262
13768
- FormData$1.prototype.hasKnownLength = function() {
13766
+ FormData$1.prototype.hasKnownLength = function () {
13769
13767
  var hasKnownLength = true;
13770
13768
 
13771
13769
  if (this._valuesToMeasure.length) {
@@ -13775,7 +13773,7 @@ FormData$1.prototype.hasKnownLength = function() {
13775
13773
  return hasKnownLength;
13776
13774
  };
13777
13775
 
13778
- FormData$1.prototype.getLength = function(cb) {
13776
+ FormData$1.prototype.getLength = function (cb) {
13779
13777
  var knownLength = this._overheadLength + this._valueLength;
13780
13778
 
13781
13779
  if (this._streams.length) {
@@ -13787,13 +13785,13 @@ FormData$1.prototype.getLength = function(cb) {
13787
13785
  return;
13788
13786
  }
13789
13787
 
13790
- asynckit.parallel(this._valuesToMeasure, this._lengthRetriever, function(err, values) {
13788
+ asynckit.parallel(this._valuesToMeasure, this._lengthRetriever, function (err, values) {
13791
13789
  if (err) {
13792
13790
  cb(err);
13793
13791
  return;
13794
13792
  }
13795
13793
 
13796
- values.forEach(function(length) {
13794
+ values.forEach(function (length) {
13797
13795
  knownLength += length;
13798
13796
  });
13799
13797
 
@@ -13801,31 +13799,26 @@ FormData$1.prototype.getLength = function(cb) {
13801
13799
  });
13802
13800
  };
13803
13801
 
13804
- FormData$1.prototype.submit = function(params, cb) {
13805
- var request
13806
- , options
13807
- , defaults = {method: 'post'}
13808
- ;
13809
-
13810
- // parse provided url if it's string
13811
- // or treat it as options object
13812
- if (typeof params == 'string') {
13802
+ FormData$1.prototype.submit = function (params, cb) {
13803
+ var request;
13804
+ var options;
13805
+ var defaults = { method: 'post' };
13813
13806
 
13814
- params = parseUrl$2(params);
13807
+ // parse provided url if it's string or treat it as options object
13808
+ if (typeof params === 'string') {
13809
+ params = parseUrl$2(params); // eslint-disable-line no-param-reassign
13810
+ /* eslint sort-keys: 0 */
13815
13811
  options = populate({
13816
13812
  port: params.port,
13817
13813
  path: params.pathname,
13818
13814
  host: params.hostname,
13819
13815
  protocol: params.protocol
13820
13816
  }, defaults);
13821
-
13822
- // use custom params
13823
- } else {
13824
-
13817
+ } else { // use custom params
13825
13818
  options = populate(params, defaults);
13826
13819
  // if no port provided use default one
13827
13820
  if (!options.port) {
13828
- options.port = options.protocol == 'https:' ? 443 : 80;
13821
+ options.port = options.protocol === 'https:' ? 443 : 80;
13829
13822
  }
13830
13823
  }
13831
13824
 
@@ -13833,14 +13826,14 @@ FormData$1.prototype.submit = function(params, cb) {
13833
13826
  options.headers = this.getHeaders(params.headers);
13834
13827
 
13835
13828
  // https if specified, fallback to http in any other case
13836
- if (options.protocol == 'https:') {
13829
+ if (options.protocol === 'https:') {
13837
13830
  request = https$1.request(options);
13838
13831
  } else {
13839
13832
  request = http$1.request(options);
13840
13833
  }
13841
13834
 
13842
13835
  // get content length and fire away
13843
- this.getLength(function(err, length) {
13836
+ this.getLength(function (err, length) {
13844
13837
  if (err && err !== 'Unknown stream') {
13845
13838
  this._error(err);
13846
13839
  return;
@@ -13859,7 +13852,7 @@ FormData$1.prototype.submit = function(params, cb) {
13859
13852
  request.removeListener('error', callback);
13860
13853
  request.removeListener('response', onResponse);
13861
13854
 
13862
- return cb.call(this, error, responce);
13855
+ return cb.call(this, error, responce); // eslint-disable-line no-invalid-this
13863
13856
  };
13864
13857
 
13865
13858
  onResponse = callback.bind(this, null);
@@ -13872,7 +13865,7 @@ FormData$1.prototype.submit = function(params, cb) {
13872
13865
  return request;
13873
13866
  };
13874
13867
 
13875
- FormData$1.prototype._error = function(err) {
13868
+ FormData$1.prototype._error = function (err) {
13876
13869
  if (!this.error) {
13877
13870
  this.error = err;
13878
13871
  this.pause();
@@ -13885,6 +13878,9 @@ FormData$1.prototype.toString = function () {
13885
13878
  };
13886
13879
  setToStringTag(FormData$1, 'FormData');
13887
13880
 
13881
+ // Public API
13882
+ var form_data = FormData$1;
13883
+
13888
13884
  var FormData$2 = /*@__PURE__*/getDefaultExportFromCjs(form_data);
13889
13885
 
13890
13886
  /**
@@ -14002,6 +13998,10 @@ function toFormData$1(obj, formData, options) {
14002
13998
  return value.toISOString();
14003
13999
  }
14004
14000
 
14001
+ if (utils$1.isBoolean(value)) {
14002
+ return value.toString();
14003
+ }
14004
+
14005
14005
  if (!useBlob && utils$1.isBlob(value)) {
14006
14006
  throw new AxiosError$1('Blob is not supported. Use a Buffer instead.');
14007
14007
  }
@@ -14304,7 +14304,7 @@ const generateString = (size = 16, alphabet = ALPHABET.ALPHA_DIGIT) => {
14304
14304
  let str = '';
14305
14305
  const {length} = alphabet;
14306
14306
  const randomValues = new Uint32Array(size);
14307
- crypto.randomFillSync(randomValues);
14307
+ require$$8.randomFillSync(randomValues);
14308
14308
  for (let i = 0; i < size; i++) {
14309
14309
  str += alphabet[randomValues[i] % length];
14310
14310
  }
@@ -14384,7 +14384,7 @@ var platform = {
14384
14384
  };
14385
14385
 
14386
14386
  function toURLEncodedForm(data, options) {
14387
- return toFormData$1(data, new platform.classes.URLSearchParams(), Object.assign({
14387
+ return toFormData$1(data, new platform.classes.URLSearchParams(), {
14388
14388
  visitor: function(value, key, path, helpers) {
14389
14389
  if (platform.isNode && utils$1.isBuffer(value)) {
14390
14390
  this.append(key, value.toString('base64'));
@@ -14392,8 +14392,9 @@ function toURLEncodedForm(data, options) {
14392
14392
  }
14393
14393
 
14394
14394
  return helpers.defaultVisitor.apply(this, arguments);
14395
- }
14396
- }, options));
14395
+ },
14396
+ ...options
14397
+ });
14397
14398
  }
14398
14399
 
14399
14400
  /**
@@ -15929,7 +15930,7 @@ followRedirects$1.exports.wrap = wrap;
15929
15930
  var followRedirectsExports = followRedirects$1.exports;
15930
15931
  var followRedirects = /*@__PURE__*/getDefaultExportFromCjs(followRedirectsExports);
15931
15932
 
15932
- const VERSION$1 = "1.9.0";
15933
+ const VERSION$1 = "1.11.0";
15933
15934
 
15934
15935
  function parseProtocol(url) {
15935
15936
  const match = /^([-+\w]{1,25})(:?\/\/|:)/.exec(url);
@@ -16347,7 +16348,7 @@ function throttle(fn, freq) {
16347
16348
  clearTimeout(timer);
16348
16349
  timer = null;
16349
16350
  }
16350
- fn.apply(null, args);
16351
+ fn(...args);
16351
16352
  };
16352
16353
 
16353
16354
  const throttled = (...args) => {
@@ -17221,7 +17222,7 @@ function mergeConfig$1(config1, config2) {
17221
17222
  headers: (a, b , prop) => mergeDeepProperties(headersToObject(a), headersToObject(b),prop, true)
17222
17223
  };
17223
17224
 
17224
- utils$1.forEach(Object.keys(Object.assign({}, config1, config2)), function computeConfigValue(prop) {
17225
+ utils$1.forEach(Object.keys({...config1, ...config2}), function computeConfigValue(prop) {
17225
17226
  const merge = mergeMap[prop] || mergeDeepProperties;
17226
17227
  const configValue = merge(config1[prop], config2[prop], prop);
17227
17228
  (utils$1.isUndefined(configValue) && merge !== mergeDirectKeys) || (config[prop] = configValue);
@@ -17754,7 +17755,7 @@ var fetchAdapter = isFetchSupported && (async (config) => {
17754
17755
  credentials: isCredentialsSupported ? withCredentials : undefined
17755
17756
  });
17756
17757
 
17757
- let response = await fetch(request);
17758
+ let response = await fetch(request, fetchOptions);
17758
17759
 
17759
17760
  const isStreamResponse = supportsResponseStream && (responseType === 'stream' || responseType === 'response');
17760
17761
 
@@ -18197,8 +18198,8 @@ let Axios$1 = class Axios {
18197
18198
 
18198
18199
  if (!synchronousRequestInterceptors) {
18199
18200
  const chain = [dispatchRequest.bind(this), undefined];
18200
- chain.unshift.apply(chain, requestInterceptorChain);
18201
- chain.push.apply(chain, responseInterceptorChain);
18201
+ chain.unshift(...requestInterceptorChain);
18202
+ chain.push(...responseInterceptorChain);
18202
18203
  len = chain.length;
18203
18204
 
18204
18205
  promise = Promise.resolve(config);
@@ -18530,7 +18531,7 @@ Object.entries(HttpStatusCode$1).forEach(([key, value]) => {
18530
18531
  */
18531
18532
  function createInstance(defaultConfig) {
18532
18533
  const context = new Axios$1(defaultConfig);
18533
- const instance = bind$1(Axios$1.prototype.request, context);
18534
+ const instance = bind$2(Axios$1.prototype.request, context);
18534
18535
 
18535
18536
  // Copy axios.prototype to instance
18536
18537
  utils$1.extend(instance, Axios$1.prototype, context, {allOwnKeys: true});
@@ -18769,25 +18770,21 @@ async function createWeeklyReportLegacy(args) {
18769
18770
  if (farm.carbonCreditsProduced > 0 &&
18770
18771
  usdgWeight <= 0 &&
18771
18772
  rewardSplit.usdgSplitPercent > 0) {
18772
- console.log(farm.carbonCreditsProduced, usdgWeight, rewardSplit.usdgSplitPercent);
18773
18773
  throw new Error("USDG weight is less than 0 and carbon credits produced is greater than 0");
18774
18774
  }
18775
18775
  if (farm.weeklyPayment > 0 &&
18776
18776
  glowWeight <= 0 &&
18777
18777
  rewardSplit.glowSplitPercent > 0) {
18778
- console.log(farm.weeklyPayment, glowWeight, rewardSplit.glowSplitPercent);
18779
18778
  throw new Error("Glow weight is less than 0 and weekly payment is greater than 0");
18780
18779
  }
18781
18780
  if (farm.carbonCreditsProduced > 0 &&
18782
18781
  usdgWeight <= 0 &&
18783
18782
  rewardSplit.usdgSplitPercent > 0) {
18784
- console.log(farm.carbonCreditsProduced, usdgWeight.toString(), rewardSplit.usdgSplitPercent);
18785
18783
  throw new Error(`USDG weight is less than or equal to 0 and carbon credits produced is greater than 0 for farm ${farm.shortId}`);
18786
18784
  }
18787
18785
  if (farm.weeklyPayment > 0 &&
18788
18786
  glowWeight <= 0 &&
18789
18787
  rewardSplit.glowSplitPercent > 0) {
18790
- console.log(farm.weeklyPayment, glowWeight.toString(), rewardSplit.glowSplitPercent);
18791
18788
  throw new Error(`Glow weight is less than or equal to 0 and weekly payment is greater than 0 for farm ${farm.shortId}`);
18792
18789
  }
18793
18790
  addValueToMapLegacy(rewardSplit.walletAddress, value, mapLegacy);
@@ -18896,30 +18893,85 @@ async function createWeeklyReportLegacy(args) {
18896
18893
  }
18897
18894
  async function createWeeklyReport({ week, gcaUrls, apiUrl, }) {
18898
18895
  const map = new Map();
18896
+ // Fetch active farms for the week (source of truth) and audits for the week.
18899
18897
  const [apiResponse, auditsRes] = await Promise.all([
18900
18898
  fetchFarmsForWeek(week, gcaUrls, apiUrl),
18901
18899
  axios.get(`${HUB_URL}/api/audits?omitDocuments=true&weekNumber=${week}`),
18902
18900
  ]);
18903
- const farms = apiResponse.filteredFarms;
18904
- const audits = auditsRes.data;
18901
+ const farms = apiResponse.filteredFarms; // List of farms active this week.
18902
+ const audits = auditsRes.data; // Audits potentially containing adjusted credits.
18905
18903
  const rawData = apiResponse.rawData;
18904
+ // Map to store the final adjusted credit (as bigint) for each active farm shortId.
18906
18905
  const shortIdToAdjustedCredit = new Map();
18906
+ // Set to track shortIds that have been assigned a credit from a valid audit to prevent duplicates.
18907
+ const processedAuditShortIds = new Set();
18908
+ // Set of shortIds from the active farms list for quick lookup.
18909
+ const farmShortIds = new Set(farms.map((f) => String(f.shortId)));
18910
+ // Process each audit to extract adjusted credit values for active farms.
18907
18911
  for (const audit of audits) {
18908
18912
  const activeShortIds = audit.activeShortIds ?? [];
18909
18913
  const adjustedCredit = audit.summary?.carbonFootprintAndProduction?.adjustedWeeklyCarbonCredit?.trim();
18914
+ // Basic validation: Ensure the audit has a valid numeric credit and lists associated shortIds.
18910
18915
  if (!adjustedCredit || !NUMERIC_REGEX.test(adjustedCredit))
18911
18916
  throw new Error(`Invalid adjustedWeeklyCarbonCredit for audit ${audit.id}`);
18912
18917
  if (activeShortIds.length === 0)
18913
- throw new Error(`audit ${audit.id} has empty activeShortIds`);
18914
- const splitValue = new Decimal(adjustedCredit).div(activeShortIds.length);
18918
+ throw new Error(`Audit ${audit.id} has empty activeShortIds`);
18919
+ // Separate the shortIds listed in the audit into those that are active this week and those that are not.
18920
+ const auditActiveFarmSids = [];
18921
+ const auditInactiveFarmSids = [];
18922
+ for (const sid of activeShortIds) {
18923
+ const sidString = String(sid);
18924
+ if (farmShortIds.has(sidString)) {
18925
+ auditActiveFarmSids.push(sidString);
18926
+ }
18927
+ else {
18928
+ auditInactiveFarmSids.push(sidString);
18929
+ }
18930
+ }
18931
+ // --- Audit Validity Checks ---
18932
+ // Data Integrity Check: An audit for credit distribution should not mix active and inactive farms for the current week.
18933
+ if (auditActiveFarmSids.length > 0 && auditInactiveFarmSids.length > 0) {
18934
+ throw new Error(`Audit ${audit.id} for week ${week} contains a mix of active farms (${auditActiveFarmSids.join(", ")}) and inactive farms (${auditInactiveFarmSids.join(", ")}). Audits should only contain active farms when distributing credits.`);
18935
+ }
18936
+ // Skip Audit: If the audit only contains shortIds that are not active this week, it's irrelevant for this report.
18937
+ if (auditActiveFarmSids.length === 0) {
18938
+ continue; // Move to the next audit.
18939
+ }
18940
+ // --- Process Valid Audit for Active Farms ---
18941
+ // Calculate the credit share per active farm within this audit.
18942
+ const splitValue = new Decimal(adjustedCredit).div(auditActiveFarmSids.length // Divide only by the count of *active* farms found in this audit.
18943
+ );
18944
+ // Sanity Check: Ensure the calculated split is not zero.
18915
18945
  if (splitValue.isZero())
18916
- throw new Error(`Zero adjustedWeeklyCarbonCredit split in audit ${audit.id}`);
18946
+ throw new Error(`Zero adjustedWeeklyCarbonCredit split for active farms in audit ${audit.id}`);
18947
+ // Convert the decimal split value to a bigint using the defined precision.
18917
18948
  const splitBigInt = toBigInt(splitValue, USDG_WEIGHT_DECIMAL_PRECISION);
18918
- for (const sid of activeShortIds)
18919
- shortIdToAdjustedCredit.set(String(sid), splitBigInt);
18949
+ // Dust Check: Ensure that the conversion to bigint didn't truncate the value to zero.
18950
+ if (splitBigInt === BigInt(0)) {
18951
+ throw new Error(`Adjusted credit split for audit ${audit.id} resulted in zero BigInt after conversion for precision ${USDG_WEIGHT_DECIMAL_PRECISION}. Original split value: ${splitValue.toString()}. This might indicate dust loss.`);
18952
+ }
18953
+ // Distribute the calculated split value to each active farm associated with this audit.
18954
+ for (const sidString of auditActiveFarmSids) {
18955
+ // Duplicate Check: Ensure this shortId hasn't already received credit from another valid audit this week.
18956
+ if (processedAuditShortIds.has(sidString)) {
18957
+ throw new Error(`ShortId ${sidString} found in multiple valid audits for week ${week}`);
18958
+ }
18959
+ processedAuditShortIds.add(sidString); // Mark this shortId as processed.
18960
+ // Store the adjusted credit for this active farm.
18961
+ shortIdToAdjustedCredit.set(sidString, splitBigInt);
18962
+ }
18963
+ } // End of loop through audits.
18964
+ // Final Validation: Ensure every farm considered active for this week received an adjusted credit value from a valid audit.
18965
+ for (const farmId of farmShortIds) {
18966
+ if (!shortIdToAdjustedCredit.has(farmId)) {
18967
+ throw new Error(`Farm ${farmId} is active for week ${week} but has no corresponding adjusted credit found in any valid audit.`);
18968
+ }
18920
18969
  }
18921
- let totalCreditsProduced18dp = BigInt(0);
18970
+ // --- Start Calculation of Merkle Tree Weights ---
18971
+ let totalCreditsProduced18dp = BigInt(0); // Raw total from farm data, for reporting/comparison.
18972
+ // Iterate through each active farm to calculate its contribution to the Merkle tree leaves.
18922
18973
  for (const farm of farms) {
18974
+ // Basic checks for farm data consistency.
18923
18975
  if (farm.status === "Unassigned") {
18924
18976
  throw new Error(`farm ${farm.shortId} is unassigned`);
18925
18977
  }
@@ -18929,7 +18981,9 @@ async function createWeeklyReport({ week, gcaUrls, apiUrl, }) {
18929
18981
  console.log(`Farm: ${farm.shortId} has ${farm.carbonCreditsProduced} carbon credits produced`);
18930
18982
  throw new Error("Carbon credits produced is less than 0 for farm " + farm.shortId);
18931
18983
  }
18984
+ // Accumulate the reported carbon credits (18 decimal places).
18932
18985
  totalCreditsProduced18dp += parseUnits(customToFixed(farm.carbonCreditsProduced, 18), 18);
18986
+ // Validate reward split percentages add up to 1 (within tolerance).
18933
18987
  const sumGlow = farm.rewardSplits.reduce((acc, r) => acc + r.glowSplitPercent, 0);
18934
18988
  const sumUSDG = farm.rewardSplits.reduce((acc, r) => acc + r.usdgSplitPercent, 0);
18935
18989
  const percentTolerance = 1e-12;
@@ -18937,57 +18991,76 @@ async function createWeeklyReport({ week, gcaUrls, apiUrl, }) {
18937
18991
  throw new Error(`Glow splits ≠1 for farm ${farm.shortId}`);
18938
18992
  if (Math.abs(sumUSDG - 1) > percentTolerance)
18939
18993
  throw new Error(`USDG splits ≠1 for farm ${farm.shortId}`);
18994
+ // Get the base GLOW payment for the farm, converted to bigint with appropriate precision.
18940
18995
  const glowBase = parseUnits(customToFixed(farm.weeklyPayment, GLOW_WEIGHT_DECIMAL_PRECISION), GLOW_WEIGHT_DECIMAL_PRECISION);
18996
+ // Retrieve the pre-calculated adjusted credit for this farm. Should always exist due to prior checks.
18941
18997
  const adjustedCreditBigInt = shortIdToAdjustedCredit.get(String(farm.shortId)) ?? BigInt(0);
18998
+ // Sanity check (likely redundant due to earlier checks, but safe).
18942
18999
  if (adjustedCreditBigInt <= BigInt(0))
18943
19000
  throw new Error(`Adjusted credit is less than or equal to 0 for farm ${farm.shortId}`);
19001
+ // Process each reward split recipient for this farm.
18944
19002
  for (const split of farm.rewardSplits) {
19003
+ // Calculate the GLOW weight for this recipient based on the farm's weekly payment and split percentage.
18945
19004
  const glowWeight = multiplyBigIntByDecimalPercentage(glowBase, GLOW_WEIGHT_DECIMAL_PRECISION, split.glowSplitPercent);
19005
+ // Calculate the USDG weight for this recipient based on the farm's *adjusted* credit and split percentage.
18946
19006
  const usdgWeight = multiplyBigIntByDecimalPercentage(adjustedCreditBigInt, USDG_WEIGHT_DECIMAL_PRECISION, split.usdgSplitPercent);
19007
+ // Dust Loss Checks: Ensure non-zero percentages didn't result in zero weight due to precision limits.
18947
19008
  if (split.usdgSplitPercent > 0 &&
18948
19009
  adjustedCreditBigInt > BigInt(0) &&
18949
19010
  usdgWeight === BigInt(0))
18950
- throw new Error(`USDG dust lost for farm ${farm.shortId}`);
19011
+ throw new Error(`USDG dust lost for farm ${farm.shortId} wallet ${split.walletAddress}`);
18951
19012
  if (split.glowSplitPercent > 0 &&
18952
19013
  glowBase > BigInt(0) &&
18953
19014
  glowWeight === BigInt(0))
18954
- throw new Error(`Glow dust lost for farm ${farm.shortId}`);
19015
+ throw new Error(`Glow dust lost for farm ${farm.shortId} wallet ${split.walletAddress}`);
19016
+ // Overflow Check: Ensure individual leaf weights don't exceed the maximum allowed.
18955
19017
  if (glowWeight > MAX_WEIGHT || usdgWeight > MAX_WEIGHT)
18956
19018
  throw new Error(`Leaf weight overflow on wallet ${split.walletAddress}`);
19019
+ // Accumulate the calculated weights into the map for the recipient wallet.
18957
19020
  accumulateLeafWeights(split.walletAddress, { wallet: split.walletAddress, glowWeight, usdgWeight }, map);
18958
19021
  }
18959
19022
  }
19023
+ // --- Finalize Merkle Tree and Generate Report Data ---
19024
+ // Convert the accumulated weights map into the final list of leaves for the tree.
18960
19025
  const finalizedLeaves = Array.from(map.values()).map(({ wallet, glowWeight, usdgWeight }) => ({
18961
19026
  wallet,
18962
- glowWeight: glowWeight.toString(),
19027
+ glowWeight: glowWeight.toString(), // Convert BigInts to strings for hashing/reporting.
18963
19028
  usdgWeight: usdgWeight.toString(),
18964
19029
  }));
19030
+ // Hash each leaf according to the defined structure.
18965
19031
  const hashedLeaves = finalizedLeaves.map((leaf) => hashLeaf({
18966
19032
  address: leaf.wallet,
18967
19033
  glowWeight: leaf.glowWeight,
18968
- usdcWeight: leaf.usdgWeight,
19034
+ usdcWeight: leaf.usdgWeight, // Note: Parameter name inconsistency (usdc vs usdg)
18969
19035
  }));
19036
+ // Build the Merkle tree.
18970
19037
  const merkleTree = new MerkleTree(hashedLeaves, ethers.utils.keccak256, {
18971
- sort: true,
19038
+ sort: true, // Ensure consistent tree structure.
18972
19039
  });
18973
- const merkleRoot = merkleTree.getHexRoot();
19040
+ const merkleRoot = merkleTree.getHexRoot(); // Get the root hash.
19041
+ // Calculate the total weights across all finalized leaves.
18974
19042
  const totalGlowWeight = finalizedLeaves.reduce((acc, { glowWeight }) => acc.add(glowWeight), ethers.BigNumber.from(0));
18975
19043
  const totalUSDGWeight = finalizedLeaves.reduce((acc, { usdgWeight }) => acc.add(usdgWeight), ethers.BigNumber.from(0));
19044
+ // Total Weight Overflow Checks: Ensure sums don't exceed maximum.
18976
19045
  if (totalGlowWeight.toBigInt() > MAX_WEIGHT)
18977
19046
  throw new Error("Total glow weight overflow");
18978
19047
  if (totalUSDGWeight.toBigInt() > MAX_WEIGHT)
18979
19048
  throw new Error("Total USDG weight overflow");
19049
+ // Generate Merkle proofs for each leaf and verify them.
18980
19050
  const leavesWithProofs = finalizedLeaves.map((leaf) => {
18981
19051
  const hashed = hashLeaf({
18982
19052
  address: leaf.wallet,
18983
19053
  glowWeight: leaf.glowWeight,
18984
- usdcWeight: leaf.usdgWeight,
19054
+ usdcWeight: leaf.usdgWeight, // Note: Parameter name inconsistency
18985
19055
  });
18986
19056
  const proof = merkleTree.getHexProof(hashed);
18987
19057
  if (!merkleTree.verify(proof, hashed, merkleRoot))
19058
+ // Verify proof against the calculated root.
18988
19059
  throw new Error("Invalid proof for " + leaf.wallet);
18989
19060
  return { ...leaf, proof };
18990
19061
  });
19062
+ // --- Sanity Checks on Final Weights ---
19063
+ // Verify that summing weights from leavesWithProofs matches the earlier reduce calculation.
18991
19064
  const glowSumProofLoop = leavesWithProofs.reduce((acc, l) => acc.add(l.glowWeight), ethers.BigNumber.from(0));
18992
19065
  if (!glowSumProofLoop.eq(totalGlowWeight)) {
18993
19066
  console.error("Glow Weight Sum Mismatch (Post-73):");
@@ -19002,43 +19075,55 @@ async function createWeeklyReport({ week, gcaUrls, apiUrl, }) {
19002
19075
  console.error("Sum from reduce:", totalUSDGWeight.toString());
19003
19076
  throw new Error("USDG sum mismatch");
19004
19077
  }
19078
+ // Calculate the total expected credits based on the adjusted values used.
19005
19079
  const totalExpectedCredits = farms.reduce((acc, f) => {
19006
19080
  const adj = shortIdToAdjustedCredit.get(String(f.shortId)) ?? BigInt(0);
19007
19081
  return acc.plus(fromBigInt(adj, USDG_WEIGHT_DECIMAL_PRECISION));
19008
19082
  }, new Decimal(0));
19083
+ // Convert total USDG weight back to human-readable decimal for deviation check.
19009
19084
  const totalUSDGWeightHuman = new Decimal(formatUnits(BigInt(totalUSDGWeight.toString()), USDG_WEIGHT_DECIMAL_PRECISION));
19010
- if (greaterThanMaxDeviation(totalExpectedCredits.toNumber(), totalUSDGWeightHuman.toNumber(), 0.001)) {
19085
+ // Check deviation between total adjusted credits used and the final sum of USDG weights.
19086
+ if (greaterThanMaxDeviation(totalExpectedCredits.toNumber(), totalUSDGWeightHuman.toNumber(), 0.001 // 0.1% tolerance
19087
+ )) {
19011
19088
  console.error("Deviation Check Failed (Post-73): Expected Credits vs USDG Weight");
19012
19089
  console.error("Total Expected Credits:", totalExpectedCredits.toNumber());
19013
19090
  console.error("Total USDG Weight:", totalUSDGWeightHuman.toNumber());
19014
19091
  console.error("Allowed Deviation:", 0.001);
19015
19092
  throw new Error("totalExpectedCredits vs USDG weight deviation >0.1% ");
19016
19093
  }
19094
+ // Convert total Glow weight back to human-readable decimal.
19017
19095
  const totalGlowWeightHuman = new Decimal(formatUnits(BigInt(totalGlowWeight.toString()), GLOW_WEIGHT_DECIMAL_PRECISION));
19096
+ // Sum the original weekly protocol fee payments from farm data.
19018
19097
  const totalProtocolFeePayments = farms.reduce((acc, f) => acc + f.weeklyPayment, 0);
19019
- if (greaterThanMaxDeviation(totalGlowWeightHuman.toNumber(), totalProtocolFeePayments, 0.001)) {
19098
+ // Check deviation between total glow weight and total protocol fees paid.
19099
+ if (greaterThanMaxDeviation(totalGlowWeightHuman.toNumber(), totalProtocolFeePayments, 0.001 // 0.1% tolerance
19100
+ )) {
19020
19101
  console.error("Deviation Check Failed (Post-73): Glow Weight vs Protocol Fees");
19021
19102
  console.error("Total Glow Weight:", totalGlowWeightHuman.toNumber());
19022
19103
  console.error("Total Protocol Fees:", totalProtocolFeePayments);
19023
19104
  console.error("Allowed Deviation:", 0.001);
19024
19105
  throw new Error("totalGlowWeight vs protocol fees deviation >0.1% ");
19025
19106
  }
19107
+ // --- Prepare Output Data ---
19108
+ // Key statistics for the report.
19026
19109
  const headlineStats = {
19027
19110
  weekNumber: week,
19028
- totalCreditsProduced: formatUnits(totalCreditsProduced18dp, 18),
19111
+ totalCreditsProduced: formatUnits(totalCreditsProduced18dp, 18), // Original reported total
19029
19112
  totalCreditsProducedBN: totalCreditsProduced18dp.toString(),
19030
- totalGlowWeightInFinalized: totalGlowWeight.toString(),
19031
- totalGlowWeightHuman: totalGlowWeightHuman.toString(),
19113
+ totalGlowWeightInFinalized: totalGlowWeight.toString(), // Total weight as BigNumber string
19114
+ totalGlowWeightHuman: totalGlowWeightHuman.toString(), // Total weight as human-readable decimal
19032
19115
  totalUSDGWeightInFinalized: totalUSDGWeight.toString(),
19033
19116
  totalUSDGWeightHuman: totalUSDGWeightHuman.toString(),
19034
19117
  root: merkleRoot,
19035
19118
  glowWeightDecimals: GLOW_WEIGHT_DECIMAL_PRECISION,
19036
19119
  usdgWeightDecimals: USDG_WEIGHT_DECIMAL_PRECISION,
19037
19120
  };
19121
+ // List of shortIds and their final adjusted credit value (human-readable).
19038
19122
  const shortIdAdjustedList = Array.from(shortIdToAdjustedCredit.entries()).map(([shortId, creditBigInt]) => ({
19039
19123
  shortId,
19040
19124
  adjustedCredit: fromBigInt(creditBigInt, USDG_WEIGHT_DECIMAL_PRECISION).toString(),
19041
19125
  }));
19126
+ // Detailed comparison between originally reported credits and adjusted credits for each farm.
19042
19127
  const creditsDeviationList = farms.map((farm) => {
19043
19128
  const adj = shortIdToAdjustedCredit.get(String(farm.shortId)) ?? BigInt(0);
19044
19129
  const adjusted = fromBigInt(adj, USDG_WEIGHT_DECIMAL_PRECISION);
@@ -19046,6 +19131,7 @@ async function createWeeklyReport({ week, gcaUrls, apiUrl, }) {
19046
19131
  let deviation;
19047
19132
  let absDeviation;
19048
19133
  let deviationPercent;
19134
+ // Handle division by zero if produced is zero.
19049
19135
  if (produced.isZero() && adjusted.isZero()) {
19050
19136
  deviation = new Decimal(0);
19051
19137
  absDeviation = new Decimal(0);
@@ -19055,7 +19141,7 @@ async function createWeeklyReport({ week, gcaUrls, apiUrl, }) {
19055
19141
  deviation = produced.minus(adjusted);
19056
19142
  absDeviation = deviation.abs();
19057
19143
  deviationPercent = deviation
19058
- .div(produced.isZero() ? 1 : produced)
19144
+ .div(produced.isZero() ? 1 : produced) // Avoid division by zero
19059
19145
  .mul(100);
19060
19146
  }
19061
19147
  return {
@@ -19067,16 +19153,569 @@ async function createWeeklyReport({ week, gcaUrls, apiUrl, }) {
19067
19153
  deviationPercent: deviationPercent.toNumber(),
19068
19154
  };
19069
19155
  });
19156
+ // Return all calculated data.
19070
19157
  return {
19071
19158
  headlineStats,
19072
- finalizedLeaves,
19073
- leavesWithProofs,
19074
- farms,
19075
- rawData,
19076
- shortIdAdjustedList,
19077
- creditsDeviationList,
19159
+ finalizedLeaves, // Leaves without proofs (for potential use cases)
19160
+ leavesWithProofs, // Leaves with proofs (primary data for distribution)
19161
+ farms, // Original filtered farm data
19162
+ rawData, // Raw GCA responses
19163
+ shortIdAdjustedList, // List of adjusted credits per farm
19164
+ creditsDeviationList, // Detailed deviation report per farm
19165
+ };
19166
+ }
19167
+
19168
+ const FORWARDER_ABI = [
19169
+ {
19170
+ inputs: [{ internalType: "address", name: "_forwarder", type: "address" }],
19171
+ stateMutability: "nonpayable",
19172
+ type: "constructor",
19173
+ },
19174
+ {
19175
+ inputs: [{ internalType: "address", name: "target", type: "address" }],
19176
+ name: "AddressEmptyCode",
19177
+ type: "error",
19178
+ },
19179
+ {
19180
+ inputs: [{ internalType: "address", name: "account", type: "address" }],
19181
+ name: "AddressInsufficientBalance",
19182
+ type: "error",
19183
+ },
19184
+ { inputs: [], name: "FailedInnerCall", type: "error" },
19185
+ {
19186
+ inputs: [{ internalType: "address", name: "token", type: "address" }],
19187
+ name: "SafeERC20FailedOperation",
19188
+ type: "error",
19189
+ },
19190
+ {
19191
+ anonymous: false,
19192
+ inputs: [
19193
+ { indexed: true, internalType: "address", name: "from", type: "address" },
19194
+ { indexed: true, internalType: "address", name: "to", type: "address" },
19195
+ {
19196
+ indexed: true,
19197
+ internalType: "address",
19198
+ name: "token",
19199
+ type: "address",
19200
+ },
19201
+ {
19202
+ indexed: false,
19203
+ internalType: "uint256",
19204
+ name: "amount",
19205
+ type: "uint256",
19206
+ },
19207
+ {
19208
+ indexed: false,
19209
+ internalType: "string",
19210
+ name: "message",
19211
+ type: "string",
19212
+ },
19213
+ ],
19214
+ name: "Forward",
19215
+ type: "event",
19216
+ },
19217
+ {
19218
+ inputs: [],
19219
+ name: "FORWARD_ADDRESS",
19220
+ outputs: [{ internalType: "address", name: "", type: "address" }],
19221
+ stateMutability: "view",
19222
+ type: "function",
19223
+ },
19224
+ {
19225
+ inputs: [
19226
+ { internalType: "address", name: "token", type: "address" },
19227
+ { internalType: "address", name: "to", type: "address" },
19228
+ { internalType: "uint256", name: "amount", type: "uint256" },
19229
+ { internalType: "string", name: "message", type: "string" },
19230
+ ],
19231
+ name: "forward",
19232
+ outputs: [],
19233
+ stateMutability: "nonpayable",
19234
+ type: "function",
19235
+ },
19236
+ ];
19237
+
19238
+ const ERC20_ABI = [
19239
+ {
19240
+ inputs: [
19241
+ { name: "spender", type: "address" },
19242
+ { name: "amount", type: "uint256" },
19243
+ ],
19244
+ name: "approve",
19245
+ outputs: [{ name: "", type: "bool" }],
19246
+ stateMutability: "nonpayable",
19247
+ type: "function",
19248
+ },
19249
+ {
19250
+ inputs: [
19251
+ { name: "owner", type: "address" },
19252
+ { name: "spender", type: "address" },
19253
+ ],
19254
+ name: "allowance",
19255
+ outputs: [{ name: "", type: "uint256" }],
19256
+ stateMutability: "view",
19257
+ type: "function",
19258
+ },
19259
+ {
19260
+ inputs: [
19261
+ { name: "to", type: "address" },
19262
+ { name: "amount", type: "uint256" },
19263
+ ],
19264
+ name: "transfer",
19265
+ outputs: [{ name: "", type: "bool" }],
19266
+ stateMutability: "nonpayable",
19267
+ type: "function",
19268
+ },
19269
+ {
19270
+ inputs: [{ name: "account", type: "address" }],
19271
+ name: "balanceOf",
19272
+ outputs: [{ name: "", type: "uint256" }],
19273
+ stateMutability: "view",
19274
+ type: "function",
19275
+ },
19276
+ {
19277
+ inputs: [
19278
+ { name: "account", type: "address" },
19279
+ { name: "amount", type: "uint256" },
19280
+ ],
19281
+ name: "mint",
19282
+ outputs: [{ name: "", type: "bool" }],
19283
+ stateMutability: "nonpayable",
19284
+ type: "function",
19285
+ },
19286
+ ];
19287
+
19288
+ // Contract-specific addresses
19289
+ const mainnetAddresses = {
19290
+ USDG: "0xe010ec500720bE9EF3F82129E7eD2Ee1FB7955F2",
19291
+ GLW: "0xf4fbC617A5733EAAF9af08E1Ab816B103388d8B6",
19292
+ USDC: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
19293
+ FORWARDER: "0x0000000000000000000000000000000000000000", // TODO: Update with actual mainnet address
19294
+ FOUNDATION_WALLET: "0x0000000000000000000000000000000000000000", // TODO: Update with actual mainnet foundation wallet
19295
+ };
19296
+ const sepoliaAddresses = {
19297
+ USDG: "0xda78313A3fF949890112c1B746AB1c75d1b1c17B",
19298
+ GLW: "0x2039161fcE4C8e5CF5FE64e17Fd290E8dFF3c9BD",
19299
+ USDC: "0x93c898be98cd2618ba84a6dccf5003d3bbe40356",
19300
+ FORWARDER: "0x9c1d61303D46BFAb1eC5F25c12A1Bf4cB3d06416",
19301
+ FOUNDATION_WALLET: "0x5e230FED487c86B90f6508104149F087d9B1B0A7",
19302
+ };
19303
+ const getAddresses = (CHAIN_ID) => {
19304
+ switch (CHAIN_ID) {
19305
+ case 1:
19306
+ return mainnetAddresses;
19307
+ case 11155111:
19308
+ return sepoliaAddresses;
19309
+ default:
19310
+ console.warn(`Unsupported chain ID: ${CHAIN_ID}, falling back to mainnet addresses`);
19311
+ return mainnetAddresses;
19312
+ }
19313
+ };
19314
+
19315
+ var ForwarderError;
19316
+ (function (ForwarderError) {
19317
+ ForwarderError["CONTRACT_NOT_AVAILABLE"] = "Contract not available";
19318
+ ForwarderError["SIGNER_NOT_AVAILABLE"] = "Signer not available";
19319
+ ForwarderError["UNKNOWN_ERROR"] = "Unknown error";
19320
+ ForwarderError["INVALID_FORWARD_TYPE"] = "Invalid forward type";
19321
+ ForwarderError["MISSING_REQUIRED_PARAMS"] = "Missing required parameters";
19322
+ })(ForwarderError || (ForwarderError = {}));
19323
+ // Utility to extract the most useful revert reason from an ethers error object
19324
+ function parseEthersError(error) {
19325
+ if (!error)
19326
+ return "Unknown error";
19327
+ const possibleError = error;
19328
+ // If the error originates from a callStatic it will often be found at `error?.error?.body`
19329
+ if (possibleError?.error?.body) {
19330
+ try {
19331
+ const body = JSON.parse(possibleError.error.body);
19332
+ // Hardhat style errors
19333
+ if (body?.error?.message)
19334
+ return body.error.message;
19335
+ }
19336
+ catch { }
19337
+ }
19338
+ // Found on MetaMask/Alchemy shape errors
19339
+ if (possibleError?.data?.message)
19340
+ return possibleError.data.message;
19341
+ if (possibleError?.error?.message)
19342
+ return possibleError.error.message;
19343
+ // Standard ethers v5 message
19344
+ if (possibleError?.reason)
19345
+ return possibleError.reason;
19346
+ if (possibleError?.message)
19347
+ return possibleError.message;
19348
+ return ForwarderError.UNKNOWN_ERROR;
19349
+ }
19350
+ // Type-guard style helper to ensure a signer exists throughout the rest of the function.
19351
+ function assertSigner(maybeSigner) {
19352
+ if (!maybeSigner) {
19353
+ throw new Error(ForwarderError.SIGNER_NOT_AVAILABLE);
19354
+ }
19355
+ }
19356
+ function useForwarder(signer, CHAIN_ID) {
19357
+ // Use dynamic addresses based on chain configuration
19358
+ const ADDRESSES = getAddresses(CHAIN_ID);
19359
+ // Framework-agnostic processing flag
19360
+ let isProcessing = false;
19361
+ const setIsProcessing = (value) => {
19362
+ isProcessing = value;
19363
+ };
19364
+ // Returns a contract instance for Forwarder
19365
+ function getForwarderContract() {
19366
+ assertSigner(signer);
19367
+ return new ethers.Contract(ADDRESSES.FORWARDER, FORWARDER_ABI, signer);
19368
+ }
19369
+ /**
19370
+ * Construct the message for the forward call based on type and parameters
19371
+ */
19372
+ function constructForwardMessage(params) {
19373
+ const { type, applicationId, farmId, regionId, userAddress } = params;
19374
+ switch (type) {
19375
+ case "PayProtocolFeeAndMintGCTLAndStake":
19376
+ if (!applicationId) {
19377
+ throw new Error(ForwarderError.MISSING_REQUIRED_PARAMS);
19378
+ }
19379
+ return `PayProtocolFeeAndMintGCTLAndStake::${applicationId}`;
19380
+ case "PayProtocolFee":
19381
+ if (!applicationId) {
19382
+ throw new Error(ForwarderError.MISSING_REQUIRED_PARAMS);
19383
+ }
19384
+ return `PayProtocolFee::${applicationId}`;
19385
+ case "MintGCTLAndStake":
19386
+ if (!regionId) {
19387
+ throw new Error(ForwarderError.MISSING_REQUIRED_PARAMS);
19388
+ }
19389
+ return `MintGCTLAndStake::${regionId}`;
19390
+ case "MintGCTL":
19391
+ if (!userAddress) {
19392
+ throw new Error(ForwarderError.MISSING_REQUIRED_PARAMS);
19393
+ }
19394
+ return `MintGCTL::${userAddress}`;
19395
+ case "BuySolarFarm":
19396
+ if (!farmId) {
19397
+ throw new Error(ForwarderError.MISSING_REQUIRED_PARAMS);
19398
+ }
19399
+ return `BuySolarFarm::${farmId}`;
19400
+ default:
19401
+ throw new Error(ForwarderError.INVALID_FORWARD_TYPE);
19402
+ }
19403
+ }
19404
+ /**
19405
+ * Get the appropriate token contract based on currency
19406
+ */
19407
+ function getTokenContract(currency = "USDC") {
19408
+ assertSigner(signer);
19409
+ let tokenAddress;
19410
+ switch (currency) {
19411
+ case "USDC":
19412
+ tokenAddress = ADDRESSES.USDC;
19413
+ break;
19414
+ case "GLW":
19415
+ tokenAddress = ADDRESSES.GLW;
19416
+ break;
19417
+ case "USDG":
19418
+ tokenAddress = ADDRESSES.USDG;
19419
+ break;
19420
+ default:
19421
+ throw new Error(`Currency ${currency} not yet supported. Only USDC, GLW, and USDG are currently supported.`);
19422
+ }
19423
+ return new ethers.Contract(tokenAddress, ERC20_ABI, signer);
19424
+ }
19425
+ /**
19426
+ * Check current token allowance for the forwarder contract
19427
+ * @param owner The wallet address to check allowance for
19428
+ * @param currency The currency to check allowance for
19429
+ */
19430
+ async function checkTokenAllowance(owner, currency = "USDC") {
19431
+ assertSigner(signer);
19432
+ try {
19433
+ const tokenContract = getTokenContract(currency);
19434
+ if (!tokenContract)
19435
+ throw new Error(ForwarderError.CONTRACT_NOT_AVAILABLE);
19436
+ const allowance = await tokenContract.allowance(owner, ADDRESSES.FORWARDER);
19437
+ return allowance;
19438
+ }
19439
+ catch (error) {
19440
+ throw new Error(parseEthersError(error));
19441
+ }
19442
+ }
19443
+ /**
19444
+ * Check user's token balance
19445
+ * @param owner The wallet address to check balance for
19446
+ * @param currency The currency to check balance for
19447
+ */
19448
+ async function checkTokenBalance(owner, currency = "USDC") {
19449
+ assertSigner(signer);
19450
+ try {
19451
+ const tokenContract = getTokenContract(currency);
19452
+ if (!tokenContract)
19453
+ throw new Error(ForwarderError.CONTRACT_NOT_AVAILABLE);
19454
+ const balance = await tokenContract.balanceOf(owner);
19455
+ return balance;
19456
+ }
19457
+ catch (error) {
19458
+ throw new Error(parseEthersError(error));
19459
+ }
19460
+ }
19461
+ /**
19462
+ * Approve tokens for the forwarder contract
19463
+ * @param amount Amount to approve (BigNumber)
19464
+ * @param currency The currency to approve
19465
+ */
19466
+ async function approveToken(amount, currency = "USDC") {
19467
+ assertSigner(signer);
19468
+ try {
19469
+ const tokenContract = getTokenContract(currency);
19470
+ if (!tokenContract)
19471
+ throw new Error(ForwarderError.CONTRACT_NOT_AVAILABLE);
19472
+ setIsProcessing(true);
19473
+ // Approve only the specific amount needed
19474
+ const approveTx = await tokenContract.approve(ADDRESSES.FORWARDER, amount);
19475
+ await approveTx.wait();
19476
+ return true;
19477
+ }
19478
+ catch (error) {
19479
+ throw new Error(parseEthersError(error));
19480
+ }
19481
+ finally {
19482
+ setIsProcessing(false);
19483
+ }
19484
+ }
19485
+ /**
19486
+ * Forward tokens through the forwarder contract with type-specific handling
19487
+ * @param params Forward parameters including type, amount, and required fields
19488
+ */
19489
+ async function forwardTokens(params) {
19490
+ assertSigner(signer);
19491
+ try {
19492
+ const forwarderContract = getForwarderContract();
19493
+ if (!forwarderContract)
19494
+ throw new Error(ForwarderError.CONTRACT_NOT_AVAILABLE);
19495
+ setIsProcessing(true);
19496
+ const { amount, currency = "USDC" } = params;
19497
+ const tokenContract = getTokenContract(currency);
19498
+ if (!tokenContract)
19499
+ throw new Error(ForwarderError.CONTRACT_NOT_AVAILABLE);
19500
+ const owner = await signer.getAddress();
19501
+ // Construct the appropriate message for this forward type
19502
+ const message = constructForwardMessage(params);
19503
+ // Check allowance and approve if necessary
19504
+ const allowance = await tokenContract.allowance(owner, ADDRESSES.FORWARDER);
19505
+ if (allowance.lt(amount)) {
19506
+ try {
19507
+ const approveTx = await tokenContract.approve(ADDRESSES.FORWARDER, ethers.constants.MaxUint256);
19508
+ await approveTx.wait();
19509
+ }
19510
+ catch (approveError) {
19511
+ throw new Error(parseEthersError(approveError) || "Token approval failed");
19512
+ }
19513
+ }
19514
+ // Get the token address based on currency
19515
+ let tokenAddress;
19516
+ switch (currency) {
19517
+ case "USDC":
19518
+ tokenAddress = ADDRESSES.USDC;
19519
+ break;
19520
+ case "USDG":
19521
+ tokenAddress = ADDRESSES.USDG;
19522
+ break;
19523
+ case "GLW":
19524
+ tokenAddress = ADDRESSES.GLW;
19525
+ break;
19526
+ default:
19527
+ throw new Error(`Unsupported currency for forwarding: ${currency}`);
19528
+ }
19529
+ // Run a static call first to surface any revert reason
19530
+ try {
19531
+ await forwarderContract.callStatic.forward(tokenAddress, ADDRESSES.FOUNDATION_WALLET, amount, message, { from: owner });
19532
+ }
19533
+ catch (staticError) {
19534
+ throw new Error(parseEthersError(staticError));
19535
+ }
19536
+ // Execute the forward transaction
19537
+ const tx = await forwarderContract.forward(tokenAddress, ADDRESSES.FOUNDATION_WALLET, amount, message);
19538
+ await tx.wait();
19539
+ return tx.hash;
19540
+ }
19541
+ catch (txError) {
19542
+ throw new Error(parseEthersError(txError));
19543
+ }
19544
+ finally {
19545
+ setIsProcessing(false);
19546
+ }
19547
+ }
19548
+ /**
19549
+ * Forward tokens for protocol fee payment and GCTL minting with staking
19550
+ */
19551
+ async function payProtocolFeeAndMintGCTLAndStake(amount, userAddress, applicationId, regionId, currency = "USDC") {
19552
+ assertSigner(signer);
19553
+ // GCTL minting only supports USDC and USDG
19554
+ if (currency === "GLW") {
19555
+ throw new Error("GCTL minting is not supported with GLW payment. Use USDC or USDG.");
19556
+ }
19557
+ return forwardTokens({
19558
+ amount,
19559
+ userAddress,
19560
+ type: "PayProtocolFeeAndMintGCTLAndStake",
19561
+ currency,
19562
+ applicationId,
19563
+ regionId,
19564
+ });
19565
+ }
19566
+ /**
19567
+ * Forward tokens for protocol fee payment only
19568
+ */
19569
+ async function payProtocolFee(amount, userAddress, applicationId, currency = "USDC") {
19570
+ assertSigner(signer);
19571
+ return forwardTokens({
19572
+ amount,
19573
+ userAddress,
19574
+ type: "PayProtocolFee",
19575
+ currency,
19576
+ applicationId,
19577
+ });
19578
+ }
19579
+ /**
19580
+ * Forward USDC to mint GCTL and stake to a region
19581
+ */
19582
+ async function mintGCTLAndStake(amount, userAddress, regionId) {
19583
+ assertSigner(signer);
19584
+ return forwardTokens({
19585
+ amount,
19586
+ userAddress,
19587
+ type: "MintGCTLAndStake",
19588
+ currency: "USDC",
19589
+ regionId,
19590
+ });
19591
+ }
19592
+ /**
19593
+ * Forward USDC to mint GCTL (existing functionality, keeping for compatibility)
19594
+ */
19595
+ async function mintGCTL(amount, userAddress) {
19596
+ assertSigner(signer);
19597
+ return forwardTokens({
19598
+ amount,
19599
+ userAddress,
19600
+ type: "MintGCTL",
19601
+ currency: "USDC",
19602
+ });
19603
+ }
19604
+ /**
19605
+ * Forward tokens to buy a solar farm
19606
+ */
19607
+ async function buySolarFarm(amount, userAddress, farmId, currency = "USDC") {
19608
+ assertSigner(signer);
19609
+ return forwardTokens({
19610
+ amount,
19611
+ userAddress,
19612
+ type: "BuySolarFarm",
19613
+ currency,
19614
+ farmId,
19615
+ });
19616
+ }
19617
+ /**
19618
+ * Estimate gas for forwarding with type-specific handling
19619
+ * @param params Forward parameters
19620
+ * @param ethPriceInUSD Current ETH price in USD (for cost estimation)
19621
+ */
19622
+ async function estimateGasForForward(params, ethPriceInUSD) {
19623
+ assertSigner(signer);
19624
+ try {
19625
+ const forwarderContract = getForwarderContract();
19626
+ if (!forwarderContract)
19627
+ throw new Error(ForwarderError.CONTRACT_NOT_AVAILABLE);
19628
+ const { amount, currency = "USDC" } = params;
19629
+ // Construct the appropriate message for this forward type
19630
+ const message = constructForwardMessage(params);
19631
+ // Get token address
19632
+ let tokenAddress;
19633
+ switch (currency) {
19634
+ case "USDC":
19635
+ tokenAddress = ADDRESSES.USDC;
19636
+ break;
19637
+ case "USDG":
19638
+ tokenAddress = ADDRESSES.USDG;
19639
+ break;
19640
+ case "GLW":
19641
+ tokenAddress = ADDRESSES.GLW;
19642
+ break;
19643
+ default:
19644
+ throw new Error(`Unsupported currency for gas estimation: ${currency}`);
19645
+ }
19646
+ const gasPrice = await signer.getGasPrice();
19647
+ const estimatedGas = await forwarderContract.estimateGas.forward(tokenAddress, ADDRESSES.FOUNDATION_WALLET, amount, message);
19648
+ const estimatedCost = estimatedGas.mul(gasPrice);
19649
+ if (ethPriceInUSD) {
19650
+ const estimatedCostInEth = ethers.utils.formatEther(estimatedCost);
19651
+ const estimatedCostInUSD = (parseFloat(estimatedCostInEth) * ethPriceInUSD).toFixed(2);
19652
+ return estimatedCostInUSD;
19653
+ }
19654
+ else {
19655
+ throw new Error("Could not fetch the ETH price to calculate cost in USD.");
19656
+ }
19657
+ }
19658
+ catch (error) {
19659
+ throw new Error(parseEthersError(error));
19660
+ }
19661
+ }
19662
+ /**
19663
+ * Mint test USDC (only works on testnets with mintable USDC contracts)
19664
+ * @param amount Amount of USDC to mint (BigNumber, 6 decimals)
19665
+ * @param recipient Address to mint USDC to
19666
+ */
19667
+ async function mintTestUSDC(amount, recipient) {
19668
+ assertSigner(signer);
19669
+ if (CHAIN_ID !== 11155111) {
19670
+ throw new Error("Minting test USDC is only supported on Sepolia");
19671
+ }
19672
+ try {
19673
+ const usdcContract = getTokenContract("USDC"); // Use getTokenContract for consistency
19674
+ if (!usdcContract)
19675
+ throw new Error(ForwarderError.CONTRACT_NOT_AVAILABLE);
19676
+ setIsProcessing(true);
19677
+ // Try to call mint function (common for test tokens)
19678
+ const tx = await usdcContract.mint(recipient, amount);
19679
+ await tx.wait();
19680
+ return tx.hash;
19681
+ }
19682
+ catch (error) {
19683
+ // If mint function doesn't exist or fails, provide helpful error
19684
+ const errorMessage = parseEthersError(error);
19685
+ if (errorMessage.includes("mint")) {
19686
+ throw new Error("This USDC contract doesn't support minting");
19687
+ }
19688
+ throw new Error(errorMessage);
19689
+ }
19690
+ finally {
19691
+ setIsProcessing(false);
19692
+ }
19693
+ }
19694
+ return {
19695
+ // New methods for different forward types
19696
+ forwardTokens,
19697
+ payProtocolFeeAndMintGCTLAndStake,
19698
+ payProtocolFee,
19699
+ mintGCTLAndStake,
19700
+ mintGCTL,
19701
+ buySolarFarm,
19702
+ // Token operations
19703
+ approveToken,
19704
+ checkTokenAllowance,
19705
+ checkTokenBalance,
19706
+ // Utility methods
19707
+ estimateGasForForward,
19708
+ mintTestUSDC,
19709
+ constructForwardMessage,
19710
+ // State
19711
+ get isProcessing() {
19712
+ return isProcessing;
19713
+ },
19714
+ addresses: ADDRESSES,
19715
+ // Signer availability
19716
+ isSignerAvailable: !!signer,
19078
19717
  };
19079
19718
  }
19080
19719
 
19081
- export { GENESIS_TIMESTAMP, createWeeklyReport, createWeeklyReportLegacy };
19720
+ export { GENESIS_TIMESTAMP, createWeeklyReport, createWeeklyReportLegacy, useForwarder };
19082
19721
  //# sourceMappingURL=index.js.map