diff --git a/.env-sample b/.env-sample index 574c891bf..a9362b4fe 100644 --- a/.env-sample +++ b/.env-sample @@ -91,11 +91,6 @@ MAKER_FEE_SPLIT=0.125 # Leaving the default value (20%) will grant the DevFund contributor badge. DEVFUND = 0.2 -# Bond size as percentage (%) -DEFAULT_BOND_SIZE = 3 -MIN_BOND_SIZE = 1 -MAX_BOND_SIZE = 15 - # Time out penalty for canceling takers in SECONDS PENALTY_TIMEOUT = 60 # Time between routing attempts of buyer invoice in MINUTES @@ -109,9 +104,11 @@ DISABLE_ORDER_LOGS = False # Coordinator activity limits MAX_PUBLIC_ORDERS = 100 -# Trade limits in satoshis -MIN_TRADE = 20000 -MAX_TRADE = 5000000 +# Coordinator Order size limits in Satoshi +# Minimum order size (must be bigger than DB constrain in /robosats/settings.py MIN_TRADE, currently 20_000 Sats) +MIN_ORDER_SIZE = 20000 +# Minimum order size (must be smaller than DB constrain in /robosats/settings.py MAX_TRADE, currently 5_000_000 Sats) +MAX_ORDER_SIZE = 5000000 # For CLTV_expiry calculation # Assume 8 min/block assumed @@ -123,16 +120,6 @@ MAX_MINING_NETWORK_SPEEDUP_EXPECTED = 1.7 EXP_MAKER_BOND_INVOICE = 300 EXP_TAKER_BOND_INVOICE = 200 -# Time a order is public in the book HOURS -DEFAULT_PUBLIC_ORDER_DURATION = 24 -MAX_PUBLIC_ORDER_DURATION = 24 -MIN_PUBLIC_ORDER_DURATION = 0.166 - -# Default time to provide a valid invoice and the trade escrow MINUTES -INVOICE_AND_ESCROW_DURATION = 180 -# Time to confim chat and confirm fiat (time to Fiat Sent confirmation) HOURS -FIAT_EXCHANGE_DURATION = 24 - # ROUTING # Proportional routing fee limit (fraction of total payout: % / 100) PROPORTIONAL_ROUTING_FEE_LIMIT = 0.001 diff --git a/Dockerfile b/Dockerfile index 53ebadf02..78a834ea7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.11.4-slim-bullseye +FROM python:3.11.6-slim-bullseye ARG DEBIAN_FRONTEND=noninteractive RUN mkdir -p /usr/src/robosats diff --git a/api/logics.py b/api/logics.py index ad556e3d5..c37a7f996 100644 --- a/api/logics.py +++ b/api/logics.py @@ -18,8 +18,8 @@ ESCROW_USERNAME = config("ESCROW_USERNAME") PENALTY_TIMEOUT = int(config("PENALTY_TIMEOUT")) -MIN_TRADE = int(config("MIN_TRADE")) -MAX_TRADE = int(config("MAX_TRADE")) +MIN_ORDER_SIZE = config("MIN_ORDER_SIZE", cast=int, default=20_000) +MAX_ORDER_SIZE = config("MAX_ORDER_SIZE", cast=int, default=5_000_000) EXP_MAKER_BOND_INVOICE = int(config("EXP_MAKER_BOND_INVOICE")) EXP_TAKER_BOND_INVOICE = int(config("EXP_TAKER_BOND_INVOICE")) @@ -29,9 +29,6 @@ config("MAX_MINING_NETWORK_SPEEDUP_EXPECTED") ) -INVOICE_AND_ESCROW_DURATION = int(config("INVOICE_AND_ESCROW_DURATION")) -FIAT_EXCHANGE_DURATION = int(config("FIAT_EXCHANGE_DURATION")) - class Logics: @classmethod @@ -90,20 +87,20 @@ def validate_already_maker_or_taker(cls, user): def validate_order_size(cls, order): """Validates if order size in Sats is within limits at t0""" if not order.has_range: - if order.t0_satoshis > MAX_TRADE: + if order.t0_satoshis > MAX_ORDER_SIZE: return False, { "bad_request": "Your order is too big. It is worth " + "{:,}".format(order.t0_satoshis) + " Sats now, but the limit is " - + "{:,}".format(MAX_TRADE) + + "{:,}".format(MAX_ORDER_SIZE) + " Sats" } - if order.t0_satoshis < MIN_TRADE: + if order.t0_satoshis < MIN_ORDER_SIZE: return False, { "bad_request": "Your order is too small. It is worth " + "{:,}".format(order.t0_satoshis) + " Sats now, but the limit is " - + "{:,}".format(MIN_TRADE) + + "{:,}".format(MIN_ORDER_SIZE) + " Sats" } elif order.has_range: @@ -117,20 +114,20 @@ def validate_order_size(cls, order): return False, { "bad_request": "Maximum range amount must be at least 50 percent higher than the minimum amount" } - elif max_sats > MAX_TRADE: + elif max_sats > MAX_ORDER_SIZE: return False, { "bad_request": "Your order maximum amount is too big. It is worth " + "{:,}".format(int(max_sats)) + " Sats now, but the limit is " - + "{:,}".format(MAX_TRADE) + + "{:,}".format(MAX_ORDER_SIZE) + " Sats" } - elif min_sats < MIN_TRADE: + elif min_sats < MIN_ORDER_SIZE: return False, { "bad_request": "Your order minimum amount is too small. It is worth " + "{:,}".format(int(min_sats)) + " Sats now, but the limit is " - + "{:,}".format(MIN_TRADE) + + "{:,}".format(MIN_ORDER_SIZE) + " Sats" } elif min_sats < max_sats / 15: @@ -590,7 +587,7 @@ def compute_swap_fee_rate(balance): shape = str(config("SWAP_FEE_SHAPE")) if shape == "linear": - MIN_SWAP_FEE = float(config("MIN_SWAP_FEE")) + MIN_SWAP_FEE = config("MIN_SWAP_FEE", cast=float, default=0.01) MIN_POINT = float(config("MIN_POINT")) MAX_SWAP_FEE = float(config("MAX_SWAP_FEE")) MAX_POINT = float(config("MAX_POINT")) @@ -603,7 +600,7 @@ def compute_swap_fee_rate(balance): ) elif shape == "exponential": - MIN_SWAP_FEE = float(config("MIN_SWAP_FEE")) + MIN_SWAP_FEE = config("MIN_SWAP_FEE", cast=float, default=0.01) MAX_SWAP_FEE = float(config("MAX_SWAP_FEE")) SWAP_LAMBDA = float(config("SWAP_LAMBDA")) swap_fee_rate = MIN_SWAP_FEE + (MAX_SWAP_FEE - MIN_SWAP_FEE) * math.exp( diff --git a/api/migrations/0043_order_latitude_order_longitude.py b/api/migrations/0043_order_latitude_order_longitude.py new file mode 100644 index 000000000..fe59aad31 --- /dev/null +++ b/api/migrations/0043_order_latitude_order_longitude.py @@ -0,0 +1,39 @@ +# Generated by Django 4.2.5 on 2023-10-03 20:12 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("api", "0042_alter_order_logs_alter_robot_avatar"), + ] + + operations = [ + migrations.AddField( + model_name="order", + name="latitude", + field=models.DecimalField( + decimal_places=6, + max_digits=8, + null=True, + validators=[ + django.core.validators.MinValueValidator(-90), + django.core.validators.MaxValueValidator(90), + ], + ), + ), + migrations.AddField( + model_name="order", + name="longitude", + field=models.DecimalField( + decimal_places=6, + max_digits=9, + null=True, + validators=[ + django.core.validators.MinValueValidator(-180), + django.core.validators.MaxValueValidator(180), + ], + ), + ), + ] diff --git a/api/migrations/0044_alter_markettick_fee_and_more.py b/api/migrations/0044_alter_markettick_fee_and_more.py new file mode 100644 index 000000000..c49a27366 --- /dev/null +++ b/api/migrations/0044_alter_markettick_fee_and_more.py @@ -0,0 +1,53 @@ +# Generated by Django 4.2.6 on 2023-10-11 10:48 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("api", "0043_order_latitude_order_longitude"), + ] + + operations = [ + migrations.AlterField( + model_name="markettick", + name="fee", + field=models.DecimalField( + decimal_places=4, + default=0, + max_digits=4, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(1), + ], + ), + ), + migrations.AlterField( + model_name="onchainpayment", + name="num_satoshis", + field=models.PositiveBigIntegerField( + null=True, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(7500000.0), + ], + ), + ), + migrations.AlterField( + model_name="onchainpayment", + name="sent_satoshis", + field=models.PositiveBigIntegerField( + null=True, + validators=[ + django.core.validators.MinValueValidator(0), + django.core.validators.MaxValueValidator(7500000.0), + ], + ), + ), + migrations.AlterField( + model_name="onchainpayment", + name="swap_fee_rate", + field=models.DecimalField(decimal_places=2, default=1, max_digits=4), + ), + ] diff --git a/api/models/ln_payment.py b/api/models/ln_payment.py index 949b1e214..76a73be3a 100644 --- a/api/models/ln_payment.py +++ b/api/models/ln_payment.py @@ -1,4 +1,4 @@ -from decouple import config +from django.conf import settings from django.contrib.auth.models import User from django.core.validators import MaxValueValidator, MinValueValidator from django.db import models @@ -78,7 +78,7 @@ class FailureReason(models.IntegerChoices): num_satoshis = models.PositiveBigIntegerField( validators=[ MinValueValidator(100), - MaxValueValidator(1.5 * config("MAX_TRADE", cast=int, default=1_000_000)), + MaxValueValidator(1.5 * settings.MAX_TRADE), ] ) # Routing budget in PPM diff --git a/api/models/market_tick.py b/api/models/market_tick.py index 662080a62..ac09d3608 100644 --- a/api/models/market_tick.py +++ b/api/models/market_tick.py @@ -51,7 +51,7 @@ class MarketTick(models.Model): fee = models.DecimalField( max_digits=4, decimal_places=4, - default=config("FEE", cast=float, default=0), + default=0, validators=[MinValueValidator(0), MaxValueValidator(1)], ) @@ -71,7 +71,11 @@ def log_a_tick(order): premium = 100 * (price / market_exchange_rate - 1) market_tick = MarketTick.objects.create( - price=price, volume=volume, premium=premium, currency=order.currency + price=price, + volume=volume, + premium=premium, + currency=order.currency, + fee=config("FEE", cast=float, default=0), ) return market_tick diff --git a/api/models/onchain_payment.py b/api/models/onchain_payment.py index f3efc9477..c69599730 100644 --- a/api/models/onchain_payment.py +++ b/api/models/onchain_payment.py @@ -1,4 +1,4 @@ -from decouple import config +from django.conf import settings from django.contrib.auth.models import User from django.core.validators import MaxValueValidator, MinValueValidator from django.db import models @@ -7,9 +7,6 @@ from control.models import BalanceLog -MAX_TRADE = config("MAX_TRADE", cast=int, default=1_000_000) -MIN_SWAP_AMOUNT = config("MIN_SWAP_AMOUNT", cast=int, default=1_000_000) - class OnchainPayment(models.Model): class Concepts(models.IntegerChoices): @@ -48,17 +45,11 @@ def get_balance(): num_satoshis = models.PositiveBigIntegerField( null=True, - validators=[ - MinValueValidator(0.5 * MIN_SWAP_AMOUNT), - MaxValueValidator(1.5 * MAX_TRADE), - ], + validators=[MinValueValidator(0), MaxValueValidator(1.5 * settings.MAX_TRADE)], ) sent_satoshis = models.PositiveBigIntegerField( null=True, - validators=[ - MinValueValidator(0.5 * MIN_SWAP_AMOUNT), - MaxValueValidator(1.5 * MAX_TRADE), - ], + validators=[MinValueValidator(0), MaxValueValidator(1.5 * settings.MAX_TRADE)], ) # fee in sats/vbyte with mSats decimals fee_msat suggested_mining_fee_rate = models.DecimalField( @@ -91,7 +82,7 @@ def get_balance(): swap_fee_rate = models.DecimalField( max_digits=4, decimal_places=2, - default=config("MIN_SWAP_FEE", cast=float, default=0.01) * 100, + default=1, null=False, blank=False, ) diff --git a/api/models/order.py b/api/models/order.py index 4d568381f..70fbdf859 100644 --- a/api/models/order.py +++ b/api/models/order.py @@ -1,6 +1,7 @@ import uuid from decouple import config +from django.conf import settings from django.contrib.auth.models import User from django.core.validators import MaxValueValidator, MinValueValidator from django.db import models @@ -8,10 +9,6 @@ from django.dispatch import receiver from django.utils import timezone -MIN_TRADE = config("MIN_TRADE", cast=int, default=20_000) -MAX_TRADE = config("MAX_TRADE", cast=int, default=1_000_000) -FIAT_EXCHANGE_DURATION = config("FIAT_EXCHANGE_DURATION", cast=int, default=24) - class Order(models.Model): class Types(models.IntegerChoices): @@ -85,20 +82,22 @@ class ExpiryReasons(models.IntegerChoices): # explicit satoshis = models.PositiveBigIntegerField( null=True, - validators=[MinValueValidator(MIN_TRADE), MaxValueValidator(MAX_TRADE)], + validators=[ + MinValueValidator(settings.MIN_TRADE), + MaxValueValidator(settings.MAX_TRADE), + ], blank=True, ) # optionally makers can choose the public order duration length (seconds) public_duration = models.PositiveBigIntegerField( - default=60 * 60 * config("DEFAULT_PUBLIC_ORDER_DURATION", cast=int, default=24) - - 1, + default=60 * 60 * settings.DEFAULT_PUBLIC_ORDER_DURATION - 1, null=False, validators=[ MinValueValidator( - 60 * 60 * config("MIN_PUBLIC_ORDER_DURATION", cast=float, default=0.166) + 60 * 60 * settings.MIN_PUBLIC_ORDER_DURATION ), # Min is 10 minutes MaxValueValidator( - 60 * 60 * config("MAX_PUBLIC_ORDER_DURATION", cast=float, default=24) + 60 * 60 * settings.MAX_PUBLIC_ORDER_DURATION ), # Max is 24 Hours ], blank=False, @@ -106,7 +105,7 @@ class ExpiryReasons(models.IntegerChoices): # optionally makers can choose the escrow lock / invoice submission step length (seconds) escrow_duration = models.PositiveBigIntegerField( - default=60 * int(config("INVOICE_AND_ESCROW_DURATION")) - 1, + default=60 * settings.INVOICE_AND_ESCROW_DURATION - 1, null=False, validators=[ MinValueValidator(60 * 30), # Min is 30 minutes @@ -119,11 +118,33 @@ class ExpiryReasons(models.IntegerChoices): bond_size = models.DecimalField( max_digits=4, decimal_places=2, - default=config("DEFAULT_BOND_SIZE", cast=float, default=3), + default=settings.DEFAULT_BOND_SIZE, null=False, validators=[ - MinValueValidator(config("MIN_BOND_SIZE", cast=float, default=1)), # 1 % - MaxValueValidator(config("MAX_BOND_SIZE", cast=float, default=1)), # 15 % + MinValueValidator(settings.MIN_BOND_SIZE), # 2 % + MaxValueValidator(settings.MAX_BOND_SIZE), # 15 % + ], + blank=False, + ) + + # optionally makers can choose a coordinate for F2F + latitude = models.DecimalField( + max_digits=8, + decimal_places=6, + null=True, + validators=[ + MinValueValidator(-90), + MaxValueValidator(90), + ], + blank=False, + ) + longitude = models.DecimalField( + max_digits=9, + decimal_places=6, + null=True, + validators=[ + MinValueValidator(-180), + MaxValueValidator(180), ], blank=False, ) @@ -153,12 +174,15 @@ class ExpiryReasons(models.IntegerChoices): # how many sats at creation and at last check (relevant for marked to market) t0_satoshis = models.PositiveBigIntegerField( null=True, - validators=[MinValueValidator(MIN_TRADE), MaxValueValidator(MAX_TRADE)], + validators=[ + MinValueValidator(settings.MIN_TRADE), + MaxValueValidator(settings.MAX_TRADE), + ], blank=True, ) # sats at creation last_satoshis = models.PositiveBigIntegerField( null=True, - validators=[MinValueValidator(0), MaxValueValidator(MAX_TRADE * 2)], + validators=[MinValueValidator(0), MaxValueValidator(settings.MAX_TRADE * 2)], blank=True, ) # sats last time checked. Weird if 2* trade max... # timestamp of last_satoshis @@ -289,8 +313,10 @@ def t_to_expire(self, status): ), # 'Waiting for trade collateral and buyer invoice' 7: int(self.escrow_duration), # 'Waiting only for seller trade collateral' 8: int(self.escrow_duration), # 'Waiting only for buyer invoice' - 9: 60 * 60 * FIAT_EXCHANGE_DURATION, # 'Sending fiat - In chatroom' - 10: 60 * 60 * FIAT_EXCHANGE_DURATION, # 'Fiat sent - In chatroom' + 9: 60 + * 60 + * settings.FIAT_EXCHANGE_DURATION, # 'Sending fiat - In chatroom' + 10: 60 * 60 * settings.FIAT_EXCHANGE_DURATION, # 'Fiat sent - In chatroom' 11: 1 * 24 * 60 * 60, # 'In dispute' 12: 0, # 'Collaboratively cancelled' 13: 100 * 24 * 60 * 60, # 'Sending satoshis to buyer' diff --git a/api/oas_schemas.py b/api/oas_schemas.py index bb2abfa4a..ed59bcd50 100644 --- a/api/oas_schemas.py +++ b/api/oas_schemas.py @@ -1,6 +1,7 @@ import textwrap from decouple import config +from django.conf import settings from drf_spectacular.utils import OpenApiExample, OpenApiParameter from api.serializers import ( @@ -11,9 +12,6 @@ EXP_MAKER_BOND_INVOICE = int(config("EXP_MAKER_BOND_INVOICE")) RETRY_TIME = int(config("RETRY_TIME")) -PUBLIC_DURATION = 60 * 60 * int(config("DEFAULT_PUBLIC_ORDER_DURATION")) - 1 -ESCROW_DURATION = 60 * int(config("INVOICE_AND_ESCROW_DURATION")) -BOND_SIZE = int(config("DEFAULT_BOND_SIZE")) class MakerViewSchema: @@ -25,9 +23,9 @@ class MakerViewSchema: Default values for the following fields if not specified: - - `public_duration` - **{PUBLIC_DURATION}** - - `escrow_duration` - **{ESCROW_DURATION}** - - `bond_size` - **{BOND_SIZE}** + - `public_duration` - **{settings.DEFAULT_PUBLIC_ORDER_DURATION}** + - `escrow_duration` - **{settings.INVOICE_AND_ESCROW_DURATION}** + - `bond_size` - **{settings.DEFAULT_BOND_SIZE}** - `has_range` - **false** - `premium` - **0** """ diff --git a/api/serializers.py b/api/serializers.py index ad909499b..d2b0db2a5 100644 --- a/api/serializers.py +++ b/api/serializers.py @@ -4,8 +4,6 @@ from .models import MarketTick, Order RETRY_TIME = int(config("RETRY_TIME")) -MIN_PUBLIC_ORDER_DURATION_SECS = 60 * 60 * float(config("MIN_PUBLIC_ORDER_DURATION")) -MAX_PUBLIC_ORDER_DURATION_SECS = 60 * 60 * float(config("MAX_PUBLIC_ORDER_DURATION")) class InfoSerializer(serializers.Serializer): diff --git a/api/tasks.py b/api/tasks.py index 35463af81..fa3cdb9f0 100644 --- a/api/tasks.py +++ b/api/tasks.py @@ -105,7 +105,7 @@ def send_devfund_donation(order_id, proceeds, reason): ) else: target_pubkey = ( - "0282eb467bc073833a039940392592bf10cf338a830ba4e392c1667d7697654c7e" + "02187352cc4b1856b9604e0a79e1bc9b301be7e0c14acbbb8c29f7051d507127d7" ) order = Order.objects.get(id=order_id) diff --git a/api/views.py b/api/views.py index 8e458d5a8..d03485ef8 100644 --- a/api/views.py +++ b/api/views.py @@ -54,15 +54,10 @@ EXP_MAKER_BOND_INVOICE = int(config("EXP_MAKER_BOND_INVOICE")) RETRY_TIME = int(config("RETRY_TIME")) -PUBLIC_DURATION = 60 * 60 * int(config("DEFAULT_PUBLIC_ORDER_DURATION")) - 1 -ESCROW_DURATION = 60 * int(config("INVOICE_AND_ESCROW_DURATION")) -BOND_SIZE = int(config("DEFAULT_BOND_SIZE")) avatar_path = Path(settings.AVATAR_ROOT) avatar_path.mkdir(parents=True, exist_ok=True) -# Create your views here. - class MakerView(CreateAPIView): serializer_class = MakeOrderSerializer @@ -115,11 +110,11 @@ def post(self, request): # Optional params if public_duration is None: - public_duration = PUBLIC_DURATION + public_duration = 60 * 60 * settings.DEFAULT_PUBLIC_ORDER_DURATION if escrow_duration is None: - escrow_duration = ESCROW_DURATION + escrow_duration = 60 * settings.INVOICE_AND_ESCROW_DURATION if bond_size is None: - bond_size = BOND_SIZE + bond_size = settings.DEFAULT_BOND_SIZE if has_range is None: has_range = False @@ -793,7 +788,7 @@ def get(self, request): context["taker_fee"] = float(config("FEE")) * ( 1 - float(config("MAKER_FEE_SPLIT")) ) - context["bond_size"] = float(config("DEFAULT_BOND_SIZE")) + context["bond_size"] = settings.DEFAULT_BOND_SIZE context["notice_severity"] = config("NOTICE_SEVERITY", cast=str, default="none") context["notice_message"] = config("NOTICE_MESSAGE", cast=str, default="") @@ -907,8 +902,8 @@ class LimitView(ListAPIView): @extend_schema(**LimitViewSchema.get) def get(self, request): # Trade limits as BTC - min_trade = float(config("MIN_TRADE")) / 100_000_000 - max_trade = float(config("MAX_TRADE")) / 100_000_000 + min_trade = config("MIN_ORDER_SIZE", cast=int, default=20_000) / 100_000_000 + max_trade = config("MAX_ORDER_SIZE", cast=int, default=5_000_000) / 100_000_000 payload = {} queryset = Currency.objects.all().order_by("currency") diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 83abc4241..4e02efc8d 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -17,8 +17,8 @@ "@mui/lab": "^5.0.0-alpha.136", "@mui/material": "^5.14.0", "@mui/system": "^5.14.0", - "@mui/x-data-grid": "^6.14.0", - "@mui/x-date-pickers": "^6.14.0", + "@mui/x-data-grid": "^6.16.1", + "@mui/x-date-pickers": "^6.16.0", "@nivo/core": "^0.83.0", "@nivo/line": "^0.83.0", "base-ex": "^0.8.1", @@ -32,7 +32,7 @@ "js-sha256": "^0.10.1", "leaflet": "^1.9.4", "light-bolt11-decoder": "^3.0.0", - "npm": "^10.1.0", + "npm": "^10.2.0", "openpgp": "^5.10.2", "react": "^18.2.0", "react-countdown": "^2.3.5", @@ -44,7 +44,7 @@ "react-qr-code": "^2.0.11", "react-router-dom": "^6.16.0", "react-smooth-image": "^1.1.0", - "react-world-flags": "^1.5.1", + "react-world-flags": "^1.6.0", "reconnecting-websocket": "^4.4.0", "simple-plist": "^1.3.1", "webln": "^0.3.2", @@ -1877,9 +1877,9 @@ "dev": true }, "node_modules/@babel/runtime": { - "version": "7.22.15", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.22.15.tgz", - "integrity": "sha512-T0O+aa+4w0u06iNmapipJXMV4HoUir03hpx3/YqXXhu9xim3w+dVphjFWl1OH8NbZHw5Lbm9k45drDkgq2VNNA==", + "version": "7.23.1", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.1.tgz", + "integrity": "sha512-hC2v6p8ZSI/W0HUzh3V8C5g+NwSKzKPtJwSpTjwl0o297GP9+ZLQSkdvHz46CM3LqyoXxq+5G9komY+eSqSO0g==", "dependencies": { "regenerator-runtime": "^0.14.0" }, @@ -3314,11 +3314,12 @@ } }, "node_modules/@mui/utils": { - "version": "5.14.9", - "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.14.9.tgz", - "integrity": "sha512-9ysB5e+RwS7ofn0n3nwAg1/3c81vBTmSvauD3EuK9LmqMzhmF//BFDaC44U4yITvB/0m1kWyDqg924Ll3VHCcg==", + "version": "5.14.12", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.14.12.tgz", + "integrity": "sha512-RFNXnhKQlzIkIUig6mmv0r5VbtjPdWoaBPYicq25LETdZux59HAqoRdWw15T7lp3c7gXOoE8y67+hTB8C64m2g==", "dependencies": { - "@babel/runtime": "^7.22.15", + "@babel/runtime": "^7.23.1", + "@types/prop-types": "^15.7.7", "prop-types": "^15.8.1", "react-is": "^18.2.0" }, @@ -3331,8 +3332,7 @@ }, "peerDependencies": { "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0", - "react-dom": "^17.0.0 || ^18.0.0" + "react": "^17.0.0 || ^18.0.0" }, "peerDependenciesMeta": { "@types/react": { @@ -3341,12 +3341,12 @@ } }, "node_modules/@mui/x-data-grid": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-6.14.0.tgz", - "integrity": "sha512-EMkPT0YQsjqfH8f/UpPscpPFlywWuyrkS6aaB90t821Z6khoheFS1XeKbCa3L6byC/fwt1cAmIljlh8xJxIueg==", + "version": "6.16.1", + "resolved": "https://registry.npmjs.org/@mui/x-data-grid/-/x-data-grid-6.16.1.tgz", + "integrity": "sha512-jiV4kMegueNiaB3Qs0VpHG0Cp+eIZa5upMr9fcdPMPNLhOYnkNtexTyezfptJyfD8Adbjrjt4bbRktBcDCC5DA==", "dependencies": { - "@babel/runtime": "^7.22.15", - "@mui/utils": "^5.14.8", + "@babel/runtime": "^7.23.1", + "@mui/utils": "^5.14.11", "clsx": "^2.0.0", "prop-types": "^15.8.1", "reselect": "^4.1.8" @@ -3374,9 +3374,9 @@ } }, "node_modules/@mui/x-date-pickers": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-6.14.0.tgz", - "integrity": "sha512-vgVEMGrm6FISD0vVTnrShwWYB6IoaXSRZogwwgF5ruKjtxwKifXNk7d6836uVo/Mv2TSKYBMk1dVwl6gand6DQ==", + "version": "6.16.0", + "resolved": "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-6.16.0.tgz", + "integrity": "sha512-5xN/OuVtcy/bX/Yx4cJrGWLmHTMTZkufhQMtInFOM8u93TJJSPwA7X86vQdl6OztYNyYKnEpxNKxSrxcDHfKFQ==", "dependencies": { "@babel/runtime": "^7.22.15", "@mui/base": "^5.0.0-beta.14", @@ -4102,9 +4102,9 @@ "dev": true }, "node_modules/@types/prop-types": { - "version": "15.7.5", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" + "version": "15.7.8", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.8.tgz", + "integrity": "sha512-kMpQpfZKSCBqltAJwskgePRaYRFukDkm1oItcAbC3gNELR20XIBcN9VRgg4+m8DKsTfkWeA4m4Imp4DDuWy7FQ==" }, "node_modules/@types/react": { "version": "18.2.21", @@ -5740,14 +5740,14 @@ } }, "node_modules/css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", "dependencies": { "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", "nth-check": "^2.0.1" }, "funding": { @@ -5755,23 +5755,15 @@ } }, "node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" }, "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/css-tree/node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "engines": { - "node": ">=0.10.0" + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" } }, "node_modules/css-what": { @@ -5786,16 +5778,35 @@ } }, "node_modules/csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/csso/-/csso-5.0.5.tgz", + "integrity": "sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==", "dependencies": { - "css-tree": "^1.1.2" + "css-tree": "~2.2.0" }, "engines": { - "node": ">=8.0.0" + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" } }, + "node_modules/csso/node_modules/css-tree": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.2.1.tgz", + "integrity": "sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==", + "dependencies": { + "mdn-data": "2.0.28", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0", + "npm": ">=7.0.0" + } + }, + "node_modules/csso/node_modules/mdn-data": { + "version": "2.0.28", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.28.tgz", + "integrity": "sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==" + }, "node_modules/csstype": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz", @@ -6214,13 +6225,13 @@ } }, "node_modules/dom-serializer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.4.1.tgz", - "integrity": "sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" }, "funding": { "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" @@ -6238,11 +6249,11 @@ ] }, "node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dependencies": { - "domelementtype": "^2.2.0" + "domelementtype": "^2.3.0" }, "engines": { "node": ">= 4" @@ -6252,13 +6263,13 @@ } }, "node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" }, "funding": { "url": "https://github.com/fb55/domutils?sponsor=1" @@ -6309,9 +6320,12 @@ } }, "node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "engines": { + "node": ">=0.12" + }, "funding": { "url": "https://github.com/fb55/entities?sponsor=1" } @@ -10219,9 +10233,9 @@ } }, "node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==" }, "node_modules/merge-stream": { "version": "2.0.0", @@ -10385,9 +10399,9 @@ } }, "node_modules/npm": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/npm/-/npm-10.1.0.tgz", - "integrity": "sha512-pZ2xybXzNGbJFZEKNbPoEXsE38Xou9VTnxxBk+B3pz0ndsGCs7iWHoUCPSsISU2hjmkWfDkJo3bYKE8RDOg4eg==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/npm/-/npm-10.2.0.tgz", + "integrity": "sha512-Auyq6d4cfg/SY4URjZE2aePLOPzK4lUD+qyMxY/7HbxAvCnOCKtMlyLPcbLSOq9lhEGBZN800S1o+UmfjA5dTg==", "bundleDependencies": [ "@isaacs/string-locale-compare", "@npmcli/arborist", @@ -10433,6 +10447,7 @@ "ms", "node-gyp", "nopt", + "normalize-package-data", "npm-audit-report", "npm-install-checks", "npm-package-arg", @@ -10448,7 +10463,9 @@ "qrcode-terminal", "read", "semver", + "spdx-expression-parse", "ssri", + "strip-ansi", "supports-color", "tar", "text-table", @@ -10460,8 +10477,8 @@ ], "dependencies": { "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/arborist": "^7.1.0", - "@npmcli/config": "^7.2.0", + "@npmcli/arborist": "^7.2.0", + "@npmcli/config": "^8.0.0", "@npmcli/fs": "^3.1.0", "@npmcli/map-workspaces": "^3.0.4", "@npmcli/package-json": "^5.0.0", @@ -10478,34 +10495,35 @@ "columnify": "^1.6.0", "fastest-levenshtein": "^1.0.16", "fs-minipass": "^3.0.3", - "glob": "^10.3.3", + "glob": "^10.3.10", "graceful-fs": "^4.2.11", - "hosted-git-info": "^7.0.0", + "hosted-git-info": "^7.0.1", "ini": "^4.1.1", "init-package-json": "^6.0.0", "is-cidr": "^4.0.2", "json-parse-even-better-errors": "^3.0.0", - "libnpmaccess": "^8.0.0", - "libnpmdiff": "^6.0.1", - "libnpmexec": "^7.0.1", - "libnpmfund": "^4.1.1", + "libnpmaccess": "^8.0.1", + "libnpmdiff": "^6.0.2", + "libnpmexec": "^7.0.2", + "libnpmfund": "^5.0.0", "libnpmhook": "^10.0.0", - "libnpmorg": "^6.0.0", - "libnpmpack": "^6.0.1", - "libnpmpublish": "^9.0.0", + "libnpmorg": "^6.0.1", + "libnpmpack": "^6.0.2", + "libnpmpublish": "^9.0.1", "libnpmsearch": "^7.0.0", "libnpmteam": "^6.0.0", "libnpmversion": "^5.0.0", "make-fetch-happen": "^13.0.0", "minimatch": "^9.0.3", - "minipass": "^7.0.3", + "minipass": "^7.0.4", "minipass-pipeline": "^1.2.4", "ms": "^2.1.2", "node-gyp": "^9.4.0", "nopt": "^7.2.0", + "normalize-package-data": "^6.0.0", "npm-audit-report": "^5.0.0", "npm-install-checks": "^6.2.0", - "npm-package-arg": "^11.0.0", + "npm-package-arg": "^11.0.1", "npm-pick-manifest": "^9.0.0", "npm-profile": "^9.0.0", "npm-registry-fetch": "^16.0.0", @@ -10518,9 +10536,11 @@ "qrcode-terminal": "^0.12.0", "read": "^2.1.0", "semver": "^7.5.4", + "spdx-expression-parse": "^3.0.1", "ssri": "^10.0.5", + "strip-ansi": "^6.0.1", "supports-color": "^9.4.0", - "tar": "^6.1.15", + "tar": "^6.2.0", "text-table": "~0.2.0", "tiny-relative-date": "^1.3.0", "treeverse": "^3.0.0", @@ -10625,10 +10645,11 @@ "license": "ISC" }, "node_modules/npm/node_modules/@npmcli/agent": { - "version": "2.1.1", + "version": "2.2.0", "inBundle": true, "license": "ISC", "dependencies": { + "agent-base": "^7.1.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.1", "lru-cache": "^10.0.1", @@ -10687,7 +10708,7 @@ } }, "node_modules/npm/node_modules/@npmcli/arborist": { - "version": "7.1.0", + "version": "7.2.0", "inBundle": true, "license": "ISC", "dependencies": { @@ -10699,18 +10720,18 @@ "@npmcli/name-from-folder": "^2.0.0", "@npmcli/node-gyp": "^3.0.0", "@npmcli/package-json": "^5.0.0", - "@npmcli/query": "^3.0.0", + "@npmcli/query": "^3.0.1", "@npmcli/run-script": "^7.0.1", "bin-links": "^4.0.1", "cacache": "^18.0.0", "common-ancestor-path": "^1.0.1", - "hosted-git-info": "^7.0.0", + "hosted-git-info": "^7.0.1", "json-parse-even-better-errors": "^3.0.0", "json-stringify-nice": "^1.1.4", "minimatch": "^9.0.0", "nopt": "^7.0.0", "npm-install-checks": "^6.2.0", - "npm-package-arg": "^11.0.0", + "npm-package-arg": "^11.0.1", "npm-pick-manifest": "^9.0.0", "npm-registry-fetch": "^16.0.0", "npmlog": "^7.0.1", @@ -10733,7 +10754,7 @@ } }, "node_modules/npm/node_modules/@npmcli/config": { - "version": "7.2.0", + "version": "8.0.0", "inBundle": true, "license": "ISC", "dependencies": { @@ -10747,7 +10768,7 @@ "walk-up-path": "^3.0.1" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^16.14.0 || >=18.0.0" } }, "node_modules/npm/node_modules/@npmcli/disparity-colors": { @@ -10878,7 +10899,7 @@ } }, "node_modules/npm/node_modules/@npmcli/query": { - "version": "3.0.0", + "version": "3.0.1", "inBundle": true, "license": "ISC", "dependencies": { @@ -11532,18 +11553,18 @@ } }, "node_modules/npm/node_modules/glob": { - "version": "10.3.3", + "version": "10.3.10", "inBundle": true, "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", - "jackspeak": "^2.0.3", + "jackspeak": "^2.3.5", "minimatch": "^9.0.1", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", "path-scurry": "^1.10.1" }, "bin": { - "glob": "dist/cjs/src/bin.js" + "glob": "dist/esm/bin.mjs" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -11574,7 +11595,7 @@ "license": "ISC" }, "node_modules/npm/node_modules/hosted-git-info": { - "version": "7.0.0", + "version": "7.0.1", "inBundle": true, "license": "ISC", "dependencies": { @@ -11773,7 +11794,7 @@ "license": "ISC" }, "node_modules/npm/node_modules/jackspeak": { - "version": "2.2.1", + "version": "2.3.6", "inBundle": true, "license": "BlueOak-1.0.0", "dependencies": { @@ -11824,11 +11845,11 @@ "license": "MIT" }, "node_modules/npm/node_modules/libnpmaccess": { - "version": "8.0.0", + "version": "8.0.1", "inBundle": true, "license": "ISC", "dependencies": { - "npm-package-arg": "^11.0.0", + "npm-package-arg": "^11.0.1", "npm-registry-fetch": "^16.0.0" }, "engines": { @@ -11836,33 +11857,33 @@ } }, "node_modules/npm/node_modules/libnpmdiff": { - "version": "6.0.1", + "version": "6.0.2", "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^7.1.0", + "@npmcli/arborist": "^7.2.0", "@npmcli/disparity-colors": "^3.0.0", "@npmcli/installed-package-contents": "^2.0.2", "binary-extensions": "^2.2.0", "diff": "^5.1.0", "minimatch": "^9.0.0", - "npm-package-arg": "^11.0.0", + "npm-package-arg": "^11.0.1", "pacote": "^17.0.4", - "tar": "^6.1.13" + "tar": "^6.2.0" }, "engines": { "node": "^16.14.0 || >=18.0.0" } }, "node_modules/npm/node_modules/libnpmexec": { - "version": "7.0.1", + "version": "7.0.2", "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^7.1.0", + "@npmcli/arborist": "^7.2.0", "@npmcli/run-script": "^7.0.1", "ci-info": "^3.7.1", - "npm-package-arg": "^11.0.0", + "npm-package-arg": "^11.0.1", "npmlog": "^7.0.1", "pacote": "^17.0.4", "proc-log": "^3.0.0", @@ -11876,14 +11897,14 @@ } }, "node_modules/npm/node_modules/libnpmfund": { - "version": "4.1.1", + "version": "5.0.0", "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^7.1.0" + "@npmcli/arborist": "^7.2.0" }, "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + "node": "^16.14.0 || >=18.0.0" } }, "node_modules/npm/node_modules/libnpmhook": { @@ -11899,7 +11920,7 @@ } }, "node_modules/npm/node_modules/libnpmorg": { - "version": "6.0.0", + "version": "6.0.1", "inBundle": true, "license": "ISC", "dependencies": { @@ -11911,13 +11932,13 @@ } }, "node_modules/npm/node_modules/libnpmpack": { - "version": "6.0.1", + "version": "6.0.2", "inBundle": true, "license": "ISC", "dependencies": { - "@npmcli/arborist": "^7.1.0", + "@npmcli/arborist": "^7.2.0", "@npmcli/run-script": "^7.0.1", - "npm-package-arg": "^11.0.0", + "npm-package-arg": "^11.0.1", "pacote": "^17.0.4" }, "engines": { @@ -11925,13 +11946,13 @@ } }, "node_modules/npm/node_modules/libnpmpublish": { - "version": "9.0.0", + "version": "9.0.1", "inBundle": true, "license": "ISC", "dependencies": { "ci-info": "^3.6.1", "normalize-package-data": "^6.0.0", - "npm-package-arg": "^11.0.0", + "npm-package-arg": "^11.0.1", "npm-registry-fetch": "^16.0.0", "proc-log": "^3.0.0", "semver": "^7.3.7", @@ -12024,7 +12045,7 @@ } }, "node_modules/npm/node_modules/minipass": { - "version": "7.0.3", + "version": "7.0.4", "inBundle": true, "license": "ISC", "engines": { @@ -12549,7 +12570,7 @@ } }, "node_modules/npm/node_modules/npm-package-arg": { - "version": "11.0.0", + "version": "11.0.1", "inBundle": true, "license": "ISC", "dependencies": { @@ -13177,7 +13198,7 @@ } }, "node_modules/npm/node_modules/tar": { - "version": "6.1.15", + "version": "6.2.0", "inBundle": true, "license": "ISC", "dependencies": { @@ -14246,13 +14267,13 @@ } }, "node_modules/react-world-flags": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/react-world-flags/-/react-world-flags-1.5.1.tgz", - "integrity": "sha512-42TjDVT/rgLvQ/DxmnxSeH5XCOkbBtrnlG/NDeUfwHAdNPUQ2wZxjK+lhPLiomtoGbK1zC3yuj7HDAtW0djZdA==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/react-world-flags/-/react-world-flags-1.6.0.tgz", + "integrity": "sha512-eutSeAy5YKoVh14js/JUCSlA6EBk1n4k+bDaV+NkNB50VhnG+f4QDTpYycnTUTsZ5cqw/saPmk0Z4Fa0VVZ1Iw==", "dependencies": { "svg-country-flags": "^1.2.10", - "svgo": "^2.8.0", - "world-countries": "^4.0.0" + "svgo": "^3.0.2", + "world-countries": "^5.0.0" }, "peerDependencies": { "react": ">=0.14" @@ -14737,6 +14758,14 @@ "node": ">=0.10.0" } }, + "node_modules/source-map-js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", + "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-support": { "version": "0.5.13", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", @@ -14762,12 +14791,6 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, - "node_modules/stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility" - }, "node_modules/stack-utils": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", @@ -14963,23 +14986,26 @@ "integrity": "sha512-xrqwo0TYf/h2cfPvGpjdSuSguUbri4vNNizBnwzoZnX0xGo3O5nGJMlbYEp7NOYcnPGBm6LE2axqDWSB847bLw==" }, "node_modules/svgo": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", - "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-3.0.2.tgz", + "integrity": "sha512-Z706C1U2pb1+JGP48fbazf3KxHrWOsLme6Rv7imFBn5EnuanDW1GPaA/P1/dvObE670JDePC3mnj0k0B7P0jjQ==", "dependencies": { "@trysound/sax": "0.2.0", "commander": "^7.2.0", - "css-select": "^4.1.3", - "css-tree": "^1.1.3", - "csso": "^4.2.0", - "picocolors": "^1.0.0", - "stable": "^0.1.8" + "css-select": "^5.1.0", + "css-tree": "^2.2.1", + "csso": "^5.0.5", + "picocolors": "^1.0.0" }, "bin": { "svgo": "bin/svgo" }, "engines": { - "node": ">=10.13.0" + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/svgo" } }, "node_modules/synckit": { @@ -15843,9 +15869,9 @@ "dev": true }, "node_modules/world-countries": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/world-countries/-/world-countries-4.0.0.tgz", - "integrity": "sha512-LsFFYmggquj0U+i7VUaJOZYz5F4QNu+oceGw8odnyVHMT2LxYSdVncqdouOEnq1esr7yCakp9+3BZTztuSw1Pg==" + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/world-countries/-/world-countries-5.0.0.tgz", + "integrity": "sha512-wAfOT9Y5i/xnxNOdKJKXdOCw9Q3yQLahBUeuRol+s+o20F6h2a4tLEbJ1lBCYwEQ30Sf9Meqeipk1gib3YwF5w==" }, "node_modules/wrap-ansi": { "version": "7.0.0", diff --git a/frontend/package.json b/frontend/package.json index c0ac71269..e65b9a944 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -56,8 +56,8 @@ "@mui/lab": "^5.0.0-alpha.136", "@mui/material": "^5.14.0", "@mui/system": "^5.14.0", - "@mui/x-data-grid": "^6.14.0", - "@mui/x-date-pickers": "^6.14.0", + "@mui/x-data-grid": "^6.16.1", + "@mui/x-date-pickers": "^6.16.0", "@nivo/core": "^0.83.0", "@nivo/line": "^0.83.0", "base-ex": "^0.8.1", @@ -71,7 +71,7 @@ "js-sha256": "^0.10.1", "leaflet": "^1.9.4", "light-bolt11-decoder": "^3.0.0", - "npm": "^10.1.0", + "npm": "^10.2.0", "openpgp": "^5.10.2", "react": "^18.2.0", "react-countdown": "^2.3.5", @@ -83,7 +83,7 @@ "react-qr-code": "^2.0.11", "react-router-dom": "^6.16.0", "react-smooth-image": "^1.1.0", - "react-world-flags": "^1.5.1", + "react-world-flags": "^1.6.0", "reconnecting-websocket": "^4.4.0", "simple-plist": "^1.3.1", "webln": "^0.3.2", diff --git a/requirements.txt b/requirements.txt index 309a1c3de..bf8a33032 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,9 +1,9 @@ -django==4.2.5 +django==4.2.6 django-admin-relation-links==0.2.5 django-celery-beat==2.5.0 django-celery-results==2.5.1 django-model-utils==4.3.1 -django-redis==5.3.0 +django-redis==5.4.0 djangorestframework==3.14.0 channels==4.0.0 channels-redis==4.1.0 @@ -18,7 +18,7 @@ requests==2.31.0 ring==0.10.1 git+https://github.com/RoboSats/Robohash.git gunicorn==21.2.0 -psycopg2==2.9.8 +psycopg2==2.9.9 SQLAlchemy==2.0.16 django-import-export==3.3.1 requests[socks] diff --git a/robosats/settings.py b/robosats/settings.py index 7ca1bf6c0..492ac9cb0 100644 --- a/robosats/settings.py +++ b/robosats/settings.py @@ -254,3 +254,32 @@ # https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" + + +##################################################################### +# RoboSats API settings. These should remain the same across +# all coordinators. Altering will require a DB migration. +# Do not change unless you know what you are doing. +# If there is a value here you would like to tweak or play with, +# there is possibly a better way to do it! E.g. the .env file + +# Trade limits in satoshis to be applied as DB validator/constrain +MIN_TRADE = 20_000 +MAX_TRADE = 5_000_000 + +# Time a order is public in the book HOURS +DEFAULT_PUBLIC_ORDER_DURATION = 24 +# Max value API will accept for public duration (cannot be higher than 24h, hardcoded as DB validator) +MAX_PUBLIC_ORDER_DURATION = 24 +# Max value API will accept for public duration (cannot be higher than 24h, hardcoded as DB validator) +MIN_PUBLIC_ORDER_DURATION = 0.166 + +# Bond size as percentage (%) +DEFAULT_BOND_SIZE = 3 +MIN_BOND_SIZE = 2 +MAX_BOND_SIZE = 15 + +# Default time to provide a valid invoice and the trade escrow MINUTES +INVOICE_AND_ESCROW_DURATION = 180 +# Time to confirm chat and confirm fiat (time to Fiat Sent confirmation) HOURS +FIAT_EXCHANGE_DURATION = 24