Merge branch 'develop' into kostia/fix/beeadcrumbs_mobile_view

This commit is contained in:
Kostiantyn Stoliarskyi 2023-05-05 10:44:13 +03:00
commit 1c6c806023
31 changed files with 122289 additions and 154 deletions

View File

@ -16,6 +16,7 @@
"jsonify", "jsonify",
"pydantic", "pydantic",
"pytest", "pytest",
"siwe",
"sqlalchemy", "sqlalchemy",
"tailwindcss", "tailwindcss",
"viewonly", "viewonly",

View File

@ -1,6 +1,6 @@
# flake8: noqa F401 # flake8: noqa F401
from .auth import LoginForm from .auth import LoginForm
from .user import UserForm, NewUserForm from .user import UserForm, NewUserForm, EditUserForm
from .book import CreateBookForm, EditBookForm from .book import CreateBookForm, EditBookForm
from .contributor import ( from .contributor import (
AddContributorForm, AddContributorForm,
@ -9,3 +9,4 @@ from .contributor import (
) )
from .collection import CreateCollectionForm, EditCollectionForm from .collection import CreateCollectionForm, EditCollectionForm
from .section import CreateSectionForm, EditSectionForm from .section import CreateSectionForm, EditSectionForm
from .interpretation import CreateInterpretationForm, EditInterpretationForm

View File

@ -0,0 +1,62 @@
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField, ValidationError
from wtforms.validators import DataRequired, Length
from app import models as m, db
from app.logger import log
class BaseInterpretationForm(FlaskForm):
label = StringField("Label", [DataRequired(), Length(3, 256)])
about = StringField("About")
class CreateInterpretationForm(BaseInterpretationForm):
section_id = StringField("Interpretation ID", [DataRequired()])
text = StringField("Text")
submit = SubmitField("Create")
def validate_label(self, field):
label = field.data
section_id = self.section_id.data
interpretation: m.Interpretation = m.Interpretation.query.filter_by(
is_deleted=False, label=label, section_id=section_id
).first()
if interpretation:
log(
log.WARNING,
"Interpretation with label [%s] already exists: [%s]",
label,
interpretation,
)
raise ValidationError("Interpretation label must be unique!")
class EditInterpretationForm(BaseInterpretationForm):
interpretation_id = StringField("Interpretation ID", [DataRequired()])
text = StringField("Text")
submit = SubmitField("Edit")
def validate_label(self, field):
label = field.data
interpretation_id = self.interpretation_id.data
section_id = db.session.get(m.Interpretation, interpretation_id).section_id
interpretation: m.Interpretation = (
m.Interpretation.query.filter_by(
is_deleted=False, label=label, section_id=section_id
)
.filter(m.Interpretation.id != interpretation_id)
.first()
)
if interpretation:
log(
log.WARNING,
"Interpretation with label [%s] already exists: [%s]",
label,
interpretation,
)
raise ValidationError("Interpretation label must be unique!")

View File

@ -1,12 +1,14 @@
from flask_wtf import FlaskForm from flask_wtf import FlaskForm
from wtforms import ( from wtforms import (
StringField, StringField,
FileField,
PasswordField, PasswordField,
SubmitField, SubmitField,
ValidationError, ValidationError,
BooleanField, BooleanField,
) )
from wtforms.validators import DataRequired, Length, EqualTo from wtforms.validators import DataRequired, Length, EqualTo
from flask_login import current_user
from app import models as m from app import models as m
@ -52,3 +54,17 @@ class NewUserForm(FlaskForm):
def validate_username(self, field): def validate_username(self, field):
if m.User.query.filter_by(username=field.data).first() is not None: if m.User.query.filter_by(username=field.data).first() is not None:
raise ValidationError("This username is taken.") raise ValidationError("This username is taken.")
class EditUserForm(FlaskForm):
name = StringField("Name", [DataRequired()])
avatar_img = FileField("Avatar file (max 200x200px)")
submit = SubmitField("Save")
def validate_username(self, field):
if (
m.User.query.filter_by(username=field.data)
.filter(m.User.id != current_user.id)
.first()
):
raise ValidationError("This username is taken.")

View File

@ -1,5 +1,5 @@
# flake8: noqa F401 # flake8: noqa F401
from .user import User, AnonymousUser, gen_password_reset_id from .user import User, AnonymousUser, gen_uniq_id
from .book import Book from .book import Book
from .books_stars import BookStar from .books_stars import BookStar
from .book_contributor import BookContributor from .book_contributor import BookContributor

View File

@ -11,16 +11,19 @@ from app.logger import log
from app import schema as s from app import schema as s
def gen_password_reset_id() -> str: def gen_uniq_id() -> str:
return str(uuid4()) return str(uuid4())
class User(BaseModel, UserMixin): class User(BaseModel, UserMixin):
__tablename__ = "users" __tablename__ = "users"
username = db.Column(db.String(60), unique=True, nullable=False) username = db.Column(db.String(64), unique=True, default=gen_uniq_id)
password_hash = db.Column(db.String(255), default="") password_hash = db.Column(db.String(256), default="")
is_activated = db.Column(db.Boolean, default=False)
# TODO: fix string length for wallet_id
wallet_id = db.Column(db.String(256), nullable=True)
avatar_img = db.Column(db.Text, nullable=True)
# Relationships # Relationships
stars = db.relationship("Book", secondary="books_stars", back_populates="stars") stars = db.relationship("Book", secondary="books_stars", back_populates="stars")
books = db.relationship("Book") books = db.relationship("Book")

File diff suppressed because one or more lines are too long

1
app/static/js/wallet.d.ts vendored Normal file
View File

@ -0,0 +1 @@
export declare function initWallet(): void;

View File

@ -54,6 +54,10 @@
</svg> </svg>
</button> </button>
<!-- prettier-ignore -->
{% if not current_user.is_authenticated %}
<button id="connectWalletBtn" type="button" class="text-white bg-gradient-to-r from-cyan-500 to-blue-500 hover:bg-gradient-to-bl focus:ring-4 focus:outline-none focus:ring-cyan-300 dark:focus:ring-cyan-800 font-medium rounded-lg text-sm px-5 py-2.5 text-center">Connect wallet</button>
{% endif %}
{% if current_user.is_authenticated %} {% if current_user.is_authenticated %}
<div class="flex"> <div class="flex">
<div class="items-center md:ml-3 hidden md:flex"> <div class="items-center md:ml-3 hidden md:flex">
@ -79,6 +83,9 @@
<div class="px-4 py-3" role="none"> <div class="px-4 py-3" role="none">
<p class="text-center text-sm text-gray-900 dark:text-white" role="none"> {{current_user.username}} </p> <p class="text-center text-sm text-gray-900 dark:text-white" role="none"> {{current_user.username}} </p>
</div> </div>
<div class="px-4 py-3" role="none">
<a class="text-center text-sm text-gray-900 dark:text-white" role="none" href="{{ url_for('user.profile') }}"> Edit profile </a>
</div>
<ul class="py-1" role="none"> <ul class="py-1" role="none">
<li> <li>
<a href="{{ url_for('auth.logout') }}" class="block px-4 py-2 text-sm dark:hover:bg-gray-600 dark:text-white" role="menuitem" >Sign out</a > <a href="{{ url_for('auth.logout') }}" class="block px-4 py-2 text-sm dark:hover:bg-gray-600 dark:text-white" role="menuitem" >Sign out</a >
@ -96,7 +103,7 @@
<!-- Dropdown menu --> <!-- Dropdown menu -->
<!--Those notification for now with dummy data--> <!--Those notification for now with dummy data-->
<!-- prettier-ignore --> <!-- prettier-ignore -->
<div id="dropdownNotification" class="shadow-md z-20 hidden w-screen bg-white divide-y divide-gray-100 rounded-lg dark:bg-gray-800 dark:divide-gray-700 border border-gray-600 dark:shadow-gray-600" aria-labelledby="dropdownNotificationButton"> <div id="dropdownNotification" class="shadow-md z-20 hidden w-screen bg-white divide-y divide-gray-100 rounded-lg dark:bg-gray-800 dark:divide-gray-700 border border-gray-600 dark:shadow-gray-600 md:w-1/2" aria-labelledby="dropdownNotificationButton">
<div class="block px-4 py-2 font-medium text-center text-gray-700 rounded-t-lg bg-gray-50 dark:bg-gray-800 dark:text-white"> Notifications </div> <div class="block px-4 py-2 font-medium text-center text-gray-700 rounded-t-lg bg-gray-50 dark:bg-gray-800 dark:text-white"> Notifications </div>
<div class="divide-y divide-gray-100 dark:divide-gray-700"> <div class="divide-y divide-gray-100 dark:divide-gray-700">
<a <a

View File

@ -5,25 +5,34 @@
<div class="h-full px-3 pb-4 overflow-y-auto bg-white dark:bg-gray-800"> <div class="h-full px-3 pb-4 overflow-y-auto bg-white dark:bg-gray-800">
<!-- prettier-ignore --> <!-- prettier-ignore -->
<ul class="space-y-2 font-medium"> <ul class="space-y-2 font-medium">
<li class="md:hidden"> {% if current_user.is_authenticated %}
<!-- prettier-ignore --> <li class="md:hidden">
<span class="flex items-center p-2 text-gray-900 rounded-lg dark:text-white bg-gray-200 dark:bg-gray-700" > <!-- prettier-ignore -->
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"> <path stroke-linecap="round" stroke-linejoin="round" d="M17.982 18.725A7.488 7.488 0 0012 15.75a7.488 7.488 0 00-5.982 2.975m11.963 0a9 9 0 10-11.963 0m11.963 0A8.966 8.966 0 0112 21a8.966 8.966 0 01-5.982-2.275M15 9.75a3 3 0 11-6 0 3 3 0 016 0z" /> </svg> <span class="flex items-center p-2 text-gray-900 rounded-lg dark:text-white bg-gray-200 dark:bg-gray-700" >
<p class="ml-2">{{ current_user.username }}</p> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"> <path stroke-linecap="round" stroke-linejoin="round" d="M17.982 18.725A7.488 7.488 0 0012 15.75a7.488 7.488 0 00-5.982 2.975m11.963 0a9 9 0 10-11.963 0m11.963 0A8.966 8.966 0 0112 21a8.966 8.966 0 01-5.982-2.275M15 9.75a3 3 0 11-6 0 3 3 0 016 0z" /> </svg>
</span> <p class="ml-2">{{ current_user.username }}</p>
</li> </li>
<li> <li>
<li class="md:hidden" id="dropdownNotificationButton" data-dropdown-toggle="dropdownNotification" > <a
<!-- prettier-ignore --> href="{{ url_for('user.profile') }}"
<span class="flex items-center p-2 text-gray-900 rounded-lg dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700" > class="flex items-center p-2 text-gray-900 rounded-lg dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700">
<svg class="w-6 h-6" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"> <path d="M10 2a6 6 0 00-6 6v3.586l-.707.707A1 1 0 004 14h12a1 1 0 00.707-1.707L16 11.586V8a6 6 0 00-6-6zM10 18a3 3 0 01-3-3h6a3 3 0 01-3 3z"></path> </svg> <!-- prettier-ignore -->
<div class="relative flex"> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"> <path stroke-linecap="round" stroke-linejoin="round" d="M16.862 4.487l1.687-1.688a1.875 1.875 0 112.652 2.652L10.582 16.07a4.5 4.5 0 01-1.897 1.13L6 18l.8-2.685a4.5 4.5 0 011.13-1.897l8.932-8.931zm0 0L19.5 7.125M18 14v4.75A2.25 2.25 0 0115.75 21H5.25A2.25 2.25 0 013 18.75V8.25A2.25 2.25 0 015.25 6H10" /> </svg>
<div <span class="ml-3">Edit profile</span>
class="relative inline-flex w-3 h-3 bg-red-500 border-2 border-white rounded-full -top-2 right-3 dark:border-gray-900"></div> </a>
</div> </li>
<p class="ml-2">Notifications</p> <li class="md:hidden" id="dropdownNotificationButton" data-dropdown-toggle="dropdownNotification" >
</span> <!-- prettier-ignore -->
</li> <span class="flex items-center p-2 text-gray-900 rounded-lg dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700" >
<svg class="w-6 h-6" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"> <path d="M10 2a6 6 0 00-6 6v3.586l-.707.707A1 1 0 004 14h12a1 1 0 00.707-1.707L16 11.586V8a6 6 0 00-6-6zM10 18a3 3 0 01-3-3h6a3 3 0 01-3 3z"></path> </svg>
<div class="relative flex">
<div
class="relative inline-flex w-3 h-3 bg-red-500 border-2 border-white rounded-full -top-2 right-3 dark:border-gray-900"></div>
</div>
<p class="ml-2">Notifications</p>
</span>
</li>
{% endif %}
<li> <li>
<a <a
href="{{ url_for('home.get_all') }}" href="{{ url_for('home.get_all') }}"
@ -35,13 +44,23 @@
</li> </li>
<li> <li>
<a <a
href="{{ url_for('book.my_books') }}" href="{{ url_for('book.get_all') }}"
class="flex items-center p-2 text-gray-900 rounded-lg dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700"> class="flex items-center p-2 text-gray-900 rounded-lg dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700">
<!-- prettier-ignore --> <!-- prettier-ignore -->
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"> <path stroke-linecap="round" stroke-linejoin="round" d="M16.5 3.75V16.5L12 14.25 7.5 16.5V3.75m9 0H18A2.25 2.25 0 0120.25 6v12A2.25 2.25 0 0118 20.25H6A2.25 2.25 0 013.75 18V6A2.25 2.25 0 016 3.75h1.5m9 0h-9" /> </svg> <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"> <path stroke-linecap="round" stroke-linejoin="round" d="M16.5 3.75V16.5L12 14.25 7.5 16.5V3.75m9 0H18A2.25 2.25 0 0120.25 6v12A2.25 2.25 0 0118 20.25H6A2.25 2.25 0 013.75 18V6A2.25 2.25 0 016 3.75h1.5m9 0h-9" /> </svg>
<span class="ml-3">My Books</span> <span class="ml-3">Books</span>
</a> </a>
</li> </li>
{% if current_user.is_authenticated %}
<li>
<a
href="{{ url_for('book.my_books') }}"
class="flex items-center p-2 text-gray-900 rounded-lg dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700">
<!-- prettier-ignore -->
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6"> <path stroke-linecap="round" stroke-linejoin="round" d="M16.5 3.75V16.5L12 14.25 7.5 16.5V3.75m9 0H18A2.25 2.25 0 0120.25 6v12A2.25 2.25 0 0118 20.25H6A2.25 2.25 0 013.75 18V6A2.25 2.25 0 016 3.75h1.5m9 0h-9" /> </svg>
<span class="ml-3">My Books</span>
</a>
</li>
<li> <li>
<a <a
href="#" href="#"
@ -60,6 +79,7 @@
<span class="flex-1 ml-3 whitespace-nowrap">Users</span> <span class="flex-1 ml-3 whitespace-nowrap">Users</span>
</a> </a>
</li> </li>
{% endif %}
<li> <li>
<a <a
href="https://github.com/Simple2B/open_law" href="https://github.com/Simple2B/open_law"

View File

@ -0,0 +1,35 @@
<!-- prettier-ignore -->
{% extends 'base.html' %}
{% block content %}
<!-- component -->
<section>
<div class="w-full lg:w-4/12 px-4 mx-auto pt-6">
<div>
<!-- prettier-ignore -->
<div class="w-full lg:max-w-xl p-6 space-y-8 sm:p-8 bg-white rounded-lg shadow-xl dark:bg-gray-800">
<!-- prettier-ignore -->
<h2 class="text-2xl font-bold text-gray-900 dark:text-white">Edit your profile</h2>
<!-- prettier-ignore -->
<form class="mt-8 space-y-6 from" role="form" action="{{ url_for('user.profile') }}" method="post" enctype="multipart/form-data">
{{ form.hidden_tag() }}
<div>
<!-- prettier-ignore -->
{{form.name.label(class='block mb-2 text-sm font-medium text-gray-900 dark:text-white')}}
{{form.name(autocomplete="off", class='bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500')}}
</div>
<!-- prettier-ignore -->
<div class="mb-3">
{{form.avatar_img.label(class='block mb-2 text-sm font-medium text-gray-900 dark:text-white')}}
{{form.avatar_img(type='file', class='bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500', id="avatar_img",
value=current_user.avatar_img if current_user.avatar_img else "")}}
</div>
<button type="submit" class="w-full px-5 py-3 text-base font-medium text-center text-white bg-blue-700 rounded-lg hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 sm:w-auto dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">Save changes</button>
</form>
</div>
</div>
</div>
</section>
{% block right_sidebar %}{% endblock %}
<!-- prettier-ignore -->
{% endblock %}

View File

@ -1,10 +1,33 @@
from flask import Blueprint, render_template, url_for, redirect, flash, request, session # flake8: noqa F501
import re
from http import HTTPStatus as status
from flask import (
Blueprint,
render_template,
url_for,
redirect,
flash,
request,
session,
jsonify,
current_app,
)
from flask_login import login_user, logout_user, login_required from flask_login import login_user, logout_user, login_required
from app import models as m from app import models as m
from app import forms as f from app import forms as f
from app.logger import log from app.logger import log
from siwe.siwe import (
SiweMessage,
generate_nonce,
ValidationError,
ExpiredMessage,
MalformedSession,
InvalidSignature,
)
from web3 import HTTPProvider
auth_blueprint = Blueprint("auth", __name__) auth_blueprint = Blueprint("auth", __name__)
@ -33,4 +56,77 @@ def logout():
logout_user() logout_user()
log(log.INFO, "You were logged out.") log(log.INFO, "You were logged out.")
session.clear() session.clear()
return redirect(url_for("auth.login")) return redirect(url_for("main.index"))
@auth_blueprint.route("/nonce")
def nonce():
session["nonce"] = generate_nonce()
return session["nonce"]
PATTERN_FORMAT_JS = re.compile(r"(?<!^)(?=[A-Z])")
@auth_blueprint.route("/verify", methods=["POST"])
def verify():
body = request.get_json()
if body["message"] is None:
return (
jsonify("Expected prepareMessage object as body."),
400,
)
siwe_message = SiweMessage(
message={
PATTERN_FORMAT_JS.sub("_", k).lower(): v for k, v in body["message"].items()
}
)
try:
siwe_message.verify(
body["signature"],
provider=HTTPProvider(current_app.config["HTTP_PROVIDER_URL"]),
)
if siwe_message.nonce != session["nonce"]:
return jsonify("invalid nonce"), 400
session["siwe"] = siwe_message.dict()
user = m.User.query.filter_by(wallet_id=siwe_message.address).first()
if not user:
# Create user
user: m.User = m.User(
wallet_id=siwe_message.address,
).save()
login_user(user=user)
log(log.INFO, "Register new user")
flash("User created and logged in successful.", "success")
return redirect(url_for("user.profile"))
login_user(user=user)
log(log.INFO, "Verify success.")
flash("Verify success.", "success")
return redirect(url_for("home.get_all"))
except ValidationError:
session.pop("siwe", default=None)
session.pop("nonce", default=None)
print("Authentication attempt rejected due to invalid message.")
return None
except ExpiredMessage:
session.pop("siwe", default=None)
session.pop("nonce", default=None)
print("Authentication attempt rejected due to expired message.")
return None
except MalformedSession as e:
session.pop("siwe", default=None)
session.pop("nonce", default=None)
print(
f"Authentication attempt rejected due to missing fields: {', '.join(e.missing_fields)}"
)
return None
except InvalidSignature:
session.pop("siwe", default=None)
session.pop("nonce", default=None)
print("Authentication attempt rejected due to invalid signature.")
return None

View File

@ -864,3 +864,254 @@ def section_delete(
book_id=book_id, book_id=book_id,
) )
) )
#####################
# Interpretation CRUD
#####################
@bp.route(
"/<int:book_id>/<int:collection_id>/<int:section_id>/create_interpretation",
methods=["POST"],
)
@bp.route(
"/<int:book_id>/<int:collection_id>/<int:sub_collection_id>/<int:section_id>/create_interpretation",
methods=["POST"],
)
@login_required
def interpretation_create(
book_id: int,
collection_id: int,
section_id: int,
sub_collection_id: int | None = None,
):
book: m.Book = db.session.get(m.Book, book_id)
if not book or book.is_deleted:
log(log.WARNING, "Book with id [%s] not found", book_id)
flash("Book not found", "danger")
return redirect(url_for("book.my_books"))
collection: m.Collection = db.session.get(m.Collection, collection_id)
if not collection or collection.is_deleted:
log(log.WARNING, "Collection with id [%s] not found", collection_id)
flash("Collection not found", "danger")
return redirect(url_for("book.collection_view", book_id=book_id))
sub_collection = None
if sub_collection_id:
sub_collection: m.Collection = db.session.get(m.Collection, sub_collection_id)
if not sub_collection or sub_collection.is_deleted:
log(log.WARNING, "Sub_collection with id [%s] not found", sub_collection_id)
flash("Subcollection not found", "danger")
return redirect(
url_for(
"book.sub_collection_view",
book_id=book_id,
collection_id=collection_id,
)
)
redirect_url = url_for(
"book.section_view",
book_id=book_id,
collection_id=collection_id,
sub_collection_id=sub_collection_id,
)
section: m.Section = db.session.get(m.Section, section_id)
if not section or collection.is_deleted:
log(log.WARNING, "Section with id [%s] not found", section)
flash("Section not found", "danger")
return redirect(redirect_url)
form = f.CreateInterpretationForm()
if form.validate_on_submit():
interpretation: m.Interpretation = m.Interpretation(
label=form.label.data,
text=form.text.data,
section_id=section_id,
)
log(
log.INFO,
"Create interpretation [%s]. Section: [%s]",
interpretation,
section,
)
interpretation.save()
flash("Success!", "success")
return redirect(redirect_url)
else:
log(log.ERROR, "Interpretation create errors: [%s]", form.errors)
for field, errors in form.errors.items():
field_label = form._fields[field].label.text
for error in errors:
flash(error.replace("Field", field_label), "danger")
return redirect(redirect_url)
@bp.route(
"/<int:book_id>/<int:collection_id>/<int:section_id>/<int:interpretation_id>/edit_interpretation",
methods=["POST"],
)
@bp.route(
(
"/<int:book_id>/<int:collection_id>/<int:sub_collection_id>/"
"<int:section_id>/<int:interpretation_id>/edit_interpretation"
),
methods=["POST"],
)
@login_required
def interpretation_edit(
book_id: int,
collection_id: int,
section_id: int,
interpretation_id: int,
sub_collection_id: int | None = None,
):
book: m.Book = db.session.get(m.Book, book_id)
if not book or book.owner != current_user or book.is_deleted:
log(log.INFO, "User: [%s] is not owner of book: [%s]", current_user, book)
flash("You are not owner of this book!", "danger")
return redirect(url_for("book.my_books"))
collection: m.Collection = db.session.get(m.Collection, collection_id)
if not collection or collection.is_deleted:
log(log.WARNING, "Collection with id [%s] not found", collection_id)
flash("Collection not found", "danger")
return redirect(url_for("book.collection_view", book_id=book_id))
if sub_collection_id:
sub_collection: m.Collection = db.session.get(m.Collection, sub_collection_id)
if not sub_collection or sub_collection.is_deleted:
log(log.WARNING, "Sub_collection with id [%s] not found", sub_collection_id)
flash("SubCollection not found", "danger")
return redirect(
url_for(
"book.sub_collection_view",
book_id=book_id,
collection_id=collection_id,
)
)
redirect_url = url_for(
"book.interpretation_view",
book_id=book_id,
collection_id=collection_id,
sub_collection_id=sub_collection_id,
section_id=section_id,
)
section: m.Section = db.session.get(m.Section, section_id)
if not section or section.is_deleted:
log(log.WARNING, "Section with id [%s] not found", section_id)
flash("Section not found", "danger")
return redirect(redirect_url)
interpretation: m.Interpretation = db.session.get(
m.Interpretation, interpretation_id
)
if not interpretation or interpretation.is_deleted:
log(log.WARNING, "Interpretation with id [%s] not found", interpretation_id)
flash("Interpretation not found", "danger")
return redirect(redirect_url)
form = f.EditInterpretationForm()
if form.validate_on_submit():
label = form.label.data
if label:
interpretation.label = label
interpretation.text = form.text.data
log(log.INFO, "Edit interpretation [%s]", interpretation.id)
interpretation.save()
flash("Success!", "success")
return redirect(redirect_url)
else:
log(log.ERROR, "Interpretation edit errors: [%s]", form.errors)
for field, errors in form.errors.items():
field_label = form._fields[field].label.text
for error in errors:
flash(error.replace("Field", field_label), "danger")
return redirect(redirect_url)
@bp.route(
"/<int:book_id>/<int:collection_id>/<int:section_id>/<int:interpretation_id>/delete_interpretation",
methods=["POST"],
)
@bp.route(
(
"/<int:book_id>/<int:collection_id>/<int:sub_collection_id>/"
"<int:section_id>/<int:interpretation_id>/delete_interpretation"
),
methods=["POST"],
)
@login_required
def interpretation_delete(
book_id: int,
collection_id: int,
section_id: int,
interpretation_id: int,
sub_collection_id: int | None = None,
):
book: m.Book = db.session.get(m.Book, book_id)
if not book or book.owner != current_user or book.is_deleted:
log(log.INFO, "User: [%s] is not owner of book: [%s]", current_user, book)
flash("You are not owner of this book!", "danger")
return redirect(url_for("book.my_books"))
collection: m.Collection = db.session.get(m.Collection, collection_id)
if not collection or collection.is_deleted:
log(log.WARNING, "Collection with id [%s] not found", collection_id)
flash("Collection not found", "danger")
return redirect(url_for("book.collection_view", book_id=book_id))
if sub_collection_id:
sub_collection: m.Collection = db.session.get(m.Collection, sub_collection_id)
if not sub_collection or sub_collection.is_deleted:
log(log.WARNING, "Sub_collection with id [%s] not found", sub_collection_id)
flash("SubCollection not found", "danger")
return redirect(
url_for(
"book.sub_collection_view",
book_id=book_id,
collection_id=collection_id,
)
)
redirect_url = url_for(
"book.interpretation_view",
book_id=book_id,
collection_id=collection_id,
sub_collection_id=sub_collection_id,
section_id=section_id,
)
section: m.Section = db.session.get(m.Section, section_id)
if not section or section.is_deleted:
log(log.WARNING, "Section with id [%s] not found", section_id)
flash("Section not found", "danger")
return redirect(redirect_url)
interpretation: m.Interpretation = db.session.get(
m.Interpretation, interpretation_id
)
if not interpretation or interpretation.is_deleted:
log(log.WARNING, "Interpretation with id [%s] not found", interpretation_id)
flash("Interpretation not found", "danger")
return redirect(redirect_url)
interpretation.is_deleted = True
log(log.INFO, "Delete interpretation [%s]", interpretation)
interpretation.save()
flash("Success!", "success")
return redirect(
url_for(
"book.collection_view",
book_id=book_id,
)
)

View File

@ -2,7 +2,7 @@ from flask import (
Blueprint, Blueprint,
render_template, render_template,
) )
from flask_login import current_user, login_required from flask_login import current_user
from app import models as m from app import models as m
@ -10,7 +10,6 @@ bp = Blueprint("home", __name__, url_prefix="/home")
@bp.route("/", methods=["GET"]) @bp.route("/", methods=["GET"])
@login_required
def get_all(): def get_all():
books: m.Book = m.Book.query.order_by(m.Book.id).limit(5) books: m.Book = m.Book.query.order_by(m.Book.id).limit(5)
sections: m.Section = m.Section.query.order_by(m.Section.id).limit(5) sections: m.Section = m.Section.query.order_by(m.Section.id).limit(5)

View File

@ -1,3 +1,5 @@
import base64
from flask import Blueprint, render_template, request, flash, redirect, url_for, jsonify from flask import Blueprint, render_template, request, flash, redirect, url_for, jsonify
from flask_login import login_required, current_user from flask_login import login_required, current_user
from app.controllers import create_pagination from app.controllers import create_pagination
@ -30,6 +32,32 @@ def get_all():
) )
@bp.route("/profile", methods=["GET", "POST"])
@login_required
def profile():
form = f.EditUserForm()
if form.validate_on_submit():
user: m.User = current_user
user.username = form.name.data
if form.avatar_img.data:
img_data = form.avatar_img.data.read()
img_data = base64.b64encode(img_data)
current_user.avatar_img = img_data.decode("utf-8")
user.is_activated = True
user.save()
return redirect(url_for("main.index"))
elif form.is_submitted:
log(log.ERROR, "Update user errors: [%s]", form.errors)
for field, errors in form.errors.items():
field_label = form._fields[field].label.text
for error in errors:
flash(error.replace("Field", field_label), "danger")
if current_user.is_activated:
form.name.data = current_user.username
return render_template("user/profile.html", form=form)
@bp.route("/save", methods=["POST"]) @bp.route("/save", methods=["POST"])
@login_required @login_required
def save(): def save():

View File

@ -25,6 +25,9 @@ class BaseConfig(BaseSettings):
PAGE_LINKS_NUMBER: int PAGE_LINKS_NUMBER: int
MAX_SEARCH_RESULTS: int MAX_SEARCH_RESULTS: int
# HTTPProvider for SIWE
HTTP_PROVIDER_URL: str
@staticmethod @staticmethod
def configure(app: Flask): def configure(app: Flask):
# Implement this method to do further configuration on your app. # Implement this method to do further configuration on your app.

View File

@ -0,0 +1,34 @@
"""user wallet_id
Revision ID: 067a10a531d7
Revises: bbc4b55246ba
Create Date: 2023-05-03 11:53:14.455999
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = "067a10a531d7"
down_revision = "bbc4b55246ba"
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table("users", schema=None) as batch_op:
batch_op.add_column(
sa.Column("wallet_id", sa.String(length=255), nullable=True)
)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table("users", schema=None) as batch_op:
batch_op.drop_column("wallet_id")
# ### end Alembic commands ###

View File

@ -0,0 +1,38 @@
"""user_is_activated
Revision ID: 377fc0b7e4bb
Revises: a1345b416f81
Create Date: 2023-05-04 11:14:58.810826
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = '377fc0b7e4bb'
down_revision = 'a1345b416f81'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('users', schema=None) as batch_op:
batch_op.add_column(sa.Column('is_activated', sa.Boolean(), nullable=True))
batch_op.alter_column('username',
existing_type=sa.VARCHAR(length=60),
nullable=True)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('users', schema=None) as batch_op:
batch_op.alter_column('username',
existing_type=sa.VARCHAR(length=60),
nullable=False)
batch_op.drop_column('is_activated')
# ### end Alembic commands ###

View File

@ -0,0 +1,32 @@
"""user avatar_img
Revision ID: a1345b416f81
Revises: 067a10a531d7
Create Date: 2023-05-04 09:11:09.406698
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'a1345b416f81'
down_revision = '067a10a531d7'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('users', schema=None) as batch_op:
batch_op.add_column(sa.Column('avatar_img', sa.Text(), nullable=True))
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('users', schema=None) as batch_op:
batch_op.drop_column('avatar_img')
# ### end Alembic commands ###

View File

@ -12,7 +12,9 @@
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"flowbite": "^1.6.4", "flowbite": "^1.6.4",
"tailwindcss": "^3.2.7" "tailwindcss": "^3.2.7",
"ethers": "5.5.3",
"siwe": "1.0.0"
}, },
"devDependencies": { "devDependencies": {
"css-loader": "^6.7.3", "css-loader": "^6.7.3",

1454
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -25,7 +25,7 @@ ADMIN_PASSWORD=admin
# Pagination # Pagination
DEFAULT_PAGE_SIZE=8 DEFAULT_PAGE_SIZE=8
PAGE_LINKS_NUMBER=8 PAGE_LINKS_NUMBER=5
MAX_SEARCH_RESULTS=5 MAX_SEARCH_RESULTS=5
#this provider for ethereum #this provider for ethereum

View File

@ -16,6 +16,7 @@ click = "^8.1.3"
email-validator = "^1.3.1" email-validator = "^1.3.1"
psycopg2-binary = "^2.9.5" psycopg2-binary = "^2.9.5"
pydantic = "^1.10.7" pydantic = "^1.10.7"
siwe = "^2.2.0"
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]
pytest = "^7.1.1" pytest = "^7.1.1"

View File

@ -50,7 +50,7 @@ export function initContributors() {
const userSearchbar: HTMLInputElement = document.querySelector('#username'); const userSearchbar: HTMLInputElement = document.querySelector('#username');
const userIdInput: HTMLInputElement = document.querySelector('#user_id'); const userIdInput: HTMLInputElement = document.querySelector('#user_id');
if (!searchBtn && !userSearchbar && !userIdInput) { if (!searchBtn || !userSearchbar || !userIdInput) {
return; return;
} }

View File

@ -1,6 +1,7 @@
import './styles.css'; import './styles.css';
import {initBooks} from './books'; import {initBooks} from './books';
import {initContributors} from './contributors'; import {initContributors} from './contributors';
import {initWallet} from './wallet';
import {initQuill} from './initQuill'; import {initQuill} from './initQuill';
import {initQuillValueToTextArea} from './quill_value_to_textarea'; import {initQuillValueToTextArea} from './quill_value_to_textarea';
@ -9,4 +10,5 @@ document.addEventListener('DOMContentLoaded', () => {
initContributors(); initContributors();
initQuill(); initQuill();
initQuillValueToTextArea(); initQuillValueToTextArea();
initWallet();
}); });

View File

@ -1,109 +0,0 @@
import {Modal} from 'flowbite';
import type {ModalOptions, ModalInterface} from 'flowbite';
// /*
// * $editUserModal: required
// * options: optional
// */
// // For your js code
interface IUser {
id: number;
username: string;
email: string;
activated: boolean;
}
const $modalElement: HTMLElement = document.querySelector('#editUserModal');
const $addUserModalElement: HTMLElement =
document.querySelector('#add-user-modal');
const modalOptions: ModalOptions = {
placement: 'bottom-right',
backdrop: 'dynamic',
backdropClasses:
'bg-gray-900 bg-opacity-50 dark:bg-opacity-80 fixed inset-0 z-40',
closable: true,
onHide: () => {
console.log('modal is hidden');
},
onShow: () => {
console.log('user id: ');
},
onToggle: () => {
console.log('modal has been toggled');
},
};
const modal: ModalInterface = new Modal($modalElement, modalOptions);
const addModal: ModalInterface = new Modal($addUserModalElement, modalOptions);
export function initUsers() {
const $buttonElements = document.querySelectorAll('.user-edit-button');
$buttonElements.forEach(e =>
e.addEventListener('click', () => {
editUser(JSON.parse(e.getAttribute('data-target')));
}),
);
// closing add edit modal
const $buttonClose = document.querySelector('#modalCloseButton');
if ($buttonClose) {
$buttonClose.addEventListener('click', () => {
modal.hide();
});
}
// closing add user modal
const addModalCloseBtn = document.querySelector('#modalAddCloseButton');
if (addModalCloseBtn) {
addModalCloseBtn.addEventListener('click', () => {
addModal.hide();
});
}
// search flow
const searchInput: HTMLInputElement = document.querySelector(
'#table-search-users',
);
const searchInputButton = document.querySelector('#table-search-user-button');
if (searchInputButton && searchInput) {
searchInputButton.addEventListener('click', () => {
const url = new URL(window.location.href);
url.searchParams.set('q', searchInput.value);
window.location.href = `${url.href}`;
});
}
const deleteButtons = document.querySelectorAll('.delete-user-btn');
deleteButtons.forEach(e => {
e.addEventListener('click', async () => {
if (confirm('Are sure?')) {
let id = e.getAttribute('data-user-id');
const response = await fetch(`/user/delete/${id}`, {
method: 'DELETE',
});
if (response.status == 200) {
location.reload();
}
}
});
});
}
function editUser(user: IUser) {
let input: HTMLInputElement = document.querySelector('#user-edit-username');
input.value = user.username;
input = document.querySelector('#user-edit-id');
input.value = user.id.toString();
input = document.querySelector('#user-edit-password');
input.value = '*******';
input = document.querySelector('#user-edit-password_confirmation');
input.value = '*******';
input = document.querySelector('#user-edit-activated');
input.checked = user.activated;
input = document.querySelector('#user-edit-next_url');
input.value = window.location.href;
modal.show();
}

68
src/wallet.ts Normal file
View File

@ -0,0 +1,68 @@
import {ethers} from 'ethers';
import {SiweMessage} from 'siwe';
interface IEthereumOwner extends Window {
ethereum:
| ethers.providers.ExternalProvider
| ethers.providers.JsonRpcFetchFunc;
}
export function initWallet() {
// current page url
const domain = window.location.host;
// protocol, hostname and port number of the URL
const origin = window.location.origin;
// connect to ethereum network and sign transactions with Metamask
if (!window.hasOwnProperty('ethereum')) {
let result = confirm(
"You don't have needed extension! Do you want to install it?",
);
if (result) {
window.open('https://metamask.io/', '_blank');
}
return;
}
const eOwner: IEthereumOwner = window as any;
const provider = new ethers.providers.Web3Provider(eOwner.ethereum);
const signer = provider.getSigner();
async function signInWithEthereum() {
// create siwe message and call backend to get a nonce
const res1 = await fetch('/nonce', {
credentials: 'include',
});
await provider.send('eth_requestAccounts', []); // <- this promps user to connect metamask
const message = new SiweMessage({
domain: domain,
address: await signer.getAddress(),
statement: 'Sign in with Ethereum to the app.',
uri: origin,
version: '1',
chainId: '1',
nonce: await res1.text(),
});
const signature = await signer.signMessage(message.signMessage());
message.signature = signature;
// post message and signature to backend where it will be verified
const res2 = await fetch(`/verify`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({message, signature}),
credentials: 'include',
redirect: 'follow',
});
console.log('res2', res2);
window.location.href = res2.url;
}
const connectWalletBtn = document.querySelector('#connectWalletBtn');
if (connectWalletBtn) {
connectWalletBtn.addEventListener('click', () => {
signInWithEthereum();
});
}
}

View File

@ -698,3 +698,221 @@ def test_crud_sections(client: FlaskClient, runner: FlaskCliRunner):
assert response.status_code == 200 assert response.status_code == 200
assert b"Section not found" in response.data assert b"Section not found" in response.data
def test_crud_interpretation(client: FlaskClient, runner: FlaskCliRunner):
_, user = login(client)
user: m.User
# add dummmy data
runner.invoke(args=["db-populate"])
book: m.Book = db.session.get(m.Book, 1)
book.user_id = user.id
book.save()
leaf_collection: m.Collection = m.Collection(
label="Test Leaf Collection #1 Label",
version_id=book.last_version.id,
is_leaf=True,
parent_id=book.last_version.root_collection.id,
).save()
section_in_collection: m.Section = m.Section(
label="Test Section in Collection #1 Label",
about="Test Section in Collection #1 About",
collection_id=leaf_collection.id,
version_id=book.last_version.id,
).save()
collection: m.Collection = m.Collection(
label="Test Collection #1 Label", version_id=book.last_version.id
).save()
sub_collection: m.Collection = m.Collection(
label="Test SubCollection #1 Label",
version_id=book.last_version.id,
parent_id=collection.id,
is_leaf=True,
).save()
section_in_subcollection: m.Section = m.Section(
label="Test Section in Subcollection #1 Label",
about="Test Section in Subcollection #1 About",
collection_id=sub_collection.id,
version_id=book.last_version.id,
).save()
label_1 = "Test Interpretation #1 Label"
text_1 = "Test Interpretation #1 Text"
response: Response = client.post(
f"/book/{book.id}/{collection.id}/{sub_collection.id}/{section_in_subcollection.id}/create_interpretation",
data=dict(section_id=section_in_subcollection.id, label=label_1, text=text_1),
follow_redirects=True,
)
assert response.status_code == 200
interpretation: m.Interpretation = m.Interpretation.query.filter_by(
label=label_1, section_id=section_in_subcollection.id
).first()
assert interpretation
assert interpretation.section_id == section_in_subcollection.id
assert not interpretation.comments
response: Response = client.post(
f"/book/{book.id}/{collection.id}/{sub_collection.id}/{section_in_subcollection.id}/create_interpretation",
data=dict(section_id=section_in_subcollection.id, label=label_1, text=text_1),
follow_redirects=True,
)
assert b"Interpretation label must be unique!" in response.data
response: Response = client.post(
f"/book/{book.id}/{leaf_collection.id}/{section_in_collection.id}/create_interpretation",
data=dict(section_id=section_in_collection.id, label=label_1, text=text_1),
follow_redirects=True,
)
assert response.status_code == 200
interpretation: m.Interpretation = m.Interpretation.query.filter_by(
label=label_1, section_id=section_in_collection.id
).first()
assert interpretation
assert interpretation.section_id == section_in_collection.id
assert not interpretation.comments
response: Response = client.post(
f"/book/{book.id}/{leaf_collection.id}/{section_in_collection.id}/create_interpretation",
data=dict(section_id=section_in_collection.id, label=label_1, text=text_1),
follow_redirects=True,
)
assert b"Interpretation label must be unique!" in response.data
response: Response = client.post(
f"/book/{book.id}/{collection.id}/999/create_section",
data=dict(collection_id=999, label=label_1, text=text_1),
follow_redirects=True,
)
assert response.status_code == 200
assert b"Subcollection not found" in response.data
response: Response = client.post(
f"/book/{book.id}/{leaf_collection.id}/999/create_interpretation",
data=dict(collection_id=999, label=label_1, text=text_1),
follow_redirects=True,
)
assert response.status_code == 200
assert b"Section not found" in response.data
response: Response = client.post(
f"/book/{book.id}/{collection.id}/{sub_collection.id}/888/create_interpretation",
data=dict(collection_id=999, label=label_1, text=text_1),
follow_redirects=True,
)
assert response.status_code == 200
assert b"Section not found" in response.data
# edit
m.Interpretation(
label="Test",
text="Test",
section_id=section_in_collection.id,
).save()
m.Interpretation(
label="Test",
text="Test",
section_id=section_in_subcollection.id,
).save()
interpretation: m.Interpretation = m.Interpretation.query.filter_by(
label=label_1, section_id=section_in_collection.id
).first()
response: Response = client.post(
f"/book/{book.id}/{leaf_collection.id}/{section_in_collection.id}/{interpretation.id}/edit_interpretation",
data=dict(
interpretation_id=interpretation.id,
label="Test",
text="Test",
),
follow_redirects=True,
)
assert response.status_code == 200
assert b"Interpretation label must be unique!" in response.data
new_label = "Test Interpretation #1 Label(edited)"
new_text = "Test Interpretation #1 Text(edited)"
response: Response = client.post(
f"/book/{book.id}/{leaf_collection.id}/{section_in_collection.id}/{interpretation.id}/edit_interpretation",
data=dict(
label=new_label,
interpretation_id=interpretation.id,
text=new_text,
),
follow_redirects=True,
)
assert response.status_code == 200
assert b"Success!" in response.data
edited_interpretation: m.Interpretation = m.Interpretation.query.filter_by(
label=new_label, text=new_text, id=interpretation.id
).first()
assert edited_interpretation
response: Response = client.post(
f"/book/{book.id}/{leaf_collection.id}/{section_in_collection.id}/999/edit_interpretation",
data=dict(
interpretation_id=interpretation.id,
label=new_label,
text=new_text,
),
follow_redirects=True,
)
assert response.status_code == 200
assert b"Interpretation not found" in response.data
response: Response = client.post(
f"/book/{book.id}/{leaf_collection.id}/{section_in_collection.id}/999/delete_interpretation",
follow_redirects=True,
)
assert response.status_code == 200
assert b"Interpretation not found" in response.data
response: Response = client.post(
(
f"/book/{book.id}/{collection.id}/{sub_collection.id}/"
f"{section_in_subcollection.id}/{section_in_subcollection.interpretations[0].id}/delete_interpretation"
),
follow_redirects=True,
)
assert response.status_code == 200
assert b"Success!" in response.data
deleted_interpretation: m.Interpretation = db.session.get(
m.Interpretation, section_in_subcollection.interpretations[0].id
)
assert deleted_interpretation.is_deleted
response: Response = client.post(
(
f"/book/{book.id}/{leaf_collection.id}/{section_in_collection.id}/"
f"{section_in_collection.interpretations[0].id}/delete_interpretation"
),
follow_redirects=True,
)
assert response.status_code == 200
assert b"Success!" in response.data
deleted_interpretation: m.Interpretation = db.session.get(
m.Interpretation, section_in_collection.interpretations[0].id
)
assert deleted_interpretation.is_deleted

View File

@ -1,6 +1,7 @@
from flask import current_app as app from flask import current_app as app
from flask.testing import FlaskClient, FlaskCliRunner from flask.testing import FlaskClient, FlaskCliRunner
from click.testing import Result from click.testing import Result
from werkzeug.datastructures import FileStorage
from app import models as m, db from app import models as m, db
from tests.utils import login from tests.utils import login
@ -113,3 +114,40 @@ def test_search_user(populate: FlaskClient, runner: FlaskCliRunner):
for user in users: for user in users:
user_id = user.get("id") user_id = user.get("id")
assert user_id not in contributors_ids assert user_id not in contributors_ids
def test_profile(client):
user: m.User = m.User(
wallet_id="nsagqklfhqwef84r23hr34r35jfn", password="password"
).save()
assert user
# assert default values
assert user.username
assert not user.is_activated
assert not user.avatar_img
avatar_img = FileStorage(
stream=open("tests/testing_data/1.jpg", "rb"),
filename="1.jpg",
content_type="img/jpg",
)
login(client, username=user.username, password="password")
res = client.post(
"/user/profile",
data={
"name": "Some other name",
"avatar_img": avatar_img,
},
follow_redirects=True,
)
assert res.status_code == 200
assert user.username == "Some other name"
assert user.is_activated
assert user.avatar_img
res2 = client.post(
"/user/profile",
follow_redirects=True,
)
assert b"This field is required." in res2.data

BIN
tests/testing_data/1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

872
yarn.lock
View File

@ -248,6 +248,688 @@
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==
"@ethersproject/abi@5.5.0":
version "5.5.0"
resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.5.0.tgz#fb52820e22e50b854ff15ce1647cc508d6660613"
integrity sha512-loW7I4AohP5KycATvc0MgujU6JyCHPqHdeoo9z3Nr9xEiNioxa65ccdm1+fsoJhkuhdRtfcL8cfyGamz2AxZ5w==
dependencies:
"@ethersproject/address" "^5.5.0"
"@ethersproject/bignumber" "^5.5.0"
"@ethersproject/bytes" "^5.5.0"
"@ethersproject/constants" "^5.5.0"
"@ethersproject/hash" "^5.5.0"
"@ethersproject/keccak256" "^5.5.0"
"@ethersproject/logger" "^5.5.0"
"@ethersproject/properties" "^5.5.0"
"@ethersproject/strings" "^5.5.0"
"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.5.0", "@ethersproject/abi@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.7.0.tgz#b3f3e045bbbeed1af3947335c247ad625a44e449"
integrity sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==
dependencies:
"@ethersproject/address" "^5.7.0"
"@ethersproject/bignumber" "^5.7.0"
"@ethersproject/bytes" "^5.7.0"
"@ethersproject/constants" "^5.7.0"
"@ethersproject/hash" "^5.7.0"
"@ethersproject/keccak256" "^5.7.0"
"@ethersproject/logger" "^5.7.0"
"@ethersproject/properties" "^5.7.0"
"@ethersproject/strings" "^5.7.0"
"@ethersproject/abstract-provider@5.5.1":
version "5.5.1"
resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.5.1.tgz#2f1f6e8a3ab7d378d8ad0b5718460f85649710c5"
integrity sha512-m+MA/ful6eKbxpr99xUYeRvLkfnlqzrF8SZ46d/xFB1A7ZVknYc/sXJG0RcufF52Qn2jeFj1hhcoQ7IXjNKUqg==
dependencies:
"@ethersproject/bignumber" "^5.5.0"
"@ethersproject/bytes" "^5.5.0"
"@ethersproject/logger" "^5.5.0"
"@ethersproject/networks" "^5.5.0"
"@ethersproject/properties" "^5.5.0"
"@ethersproject/transactions" "^5.5.0"
"@ethersproject/web" "^5.5.0"
"@ethersproject/abstract-provider@5.7.0", "@ethersproject/abstract-provider@^5.5.0", "@ethersproject/abstract-provider@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz#b0a8550f88b6bf9d51f90e4795d48294630cb9ef"
integrity sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==
dependencies:
"@ethersproject/bignumber" "^5.7.0"
"@ethersproject/bytes" "^5.7.0"
"@ethersproject/logger" "^5.7.0"
"@ethersproject/networks" "^5.7.0"
"@ethersproject/properties" "^5.7.0"
"@ethersproject/transactions" "^5.7.0"
"@ethersproject/web" "^5.7.0"
"@ethersproject/abstract-signer@5.5.0":
version "5.5.0"
resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.5.0.tgz#590ff6693370c60ae376bf1c7ada59eb2a8dd08d"
integrity sha512-lj//7r250MXVLKI7sVarXAbZXbv9P50lgmJQGr2/is82EwEb8r7HrxsmMqAjTsztMYy7ohrIhGMIml+Gx4D3mA==
dependencies:
"@ethersproject/abstract-provider" "^5.5.0"
"@ethersproject/bignumber" "^5.5.0"
"@ethersproject/bytes" "^5.5.0"
"@ethersproject/logger" "^5.5.0"
"@ethersproject/properties" "^5.5.0"
"@ethersproject/abstract-signer@5.7.0", "@ethersproject/abstract-signer@^5.5.0", "@ethersproject/abstract-signer@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz#13f4f32117868452191a4649723cb086d2b596b2"
integrity sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==
dependencies:
"@ethersproject/abstract-provider" "^5.7.0"
"@ethersproject/bignumber" "^5.7.0"
"@ethersproject/bytes" "^5.7.0"
"@ethersproject/logger" "^5.7.0"
"@ethersproject/properties" "^5.7.0"
"@ethersproject/address@5.5.0":
version "5.5.0"
resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.5.0.tgz#bcc6f576a553f21f3dd7ba17248f81b473c9c78f"
integrity sha512-l4Nj0eWlTUh6ro5IbPTgbpT4wRbdH5l8CQf7icF7sb/SI3Nhd9Y9HzhonTSTi6CefI0necIw7LJqQPopPLZyWw==
dependencies:
"@ethersproject/bignumber" "^5.5.0"
"@ethersproject/bytes" "^5.5.0"
"@ethersproject/keccak256" "^5.5.0"
"@ethersproject/logger" "^5.5.0"
"@ethersproject/rlp" "^5.5.0"
"@ethersproject/address@5.7.0", "@ethersproject/address@^5.5.0", "@ethersproject/address@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.7.0.tgz#19b56c4d74a3b0a46bfdbb6cfcc0a153fc697f37"
integrity sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==
dependencies:
"@ethersproject/bignumber" "^5.7.0"
"@ethersproject/bytes" "^5.7.0"
"@ethersproject/keccak256" "^5.7.0"
"@ethersproject/logger" "^5.7.0"
"@ethersproject/rlp" "^5.7.0"
"@ethersproject/base64@5.5.0":
version "5.5.0"
resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.5.0.tgz#881e8544e47ed976930836986e5eb8fab259c090"
integrity sha512-tdayUKhU1ljrlHzEWbStXazDpsx4eg1dBXUSI6+mHlYklOXoXF6lZvw8tnD6oVaWfnMxAgRSKROg3cVKtCcppA==
dependencies:
"@ethersproject/bytes" "^5.5.0"
"@ethersproject/base64@5.7.0", "@ethersproject/base64@^5.5.0", "@ethersproject/base64@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.7.0.tgz#ac4ee92aa36c1628173e221d0d01f53692059e1c"
integrity sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==
dependencies:
"@ethersproject/bytes" "^5.7.0"
"@ethersproject/basex@5.5.0":
version "5.5.0"
resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.5.0.tgz#e40a53ae6d6b09ab4d977bd037010d4bed21b4d3"
integrity sha512-ZIodwhHpVJ0Y3hUCfUucmxKsWQA5TMnavp5j/UOuDdzZWzJlRmuOjcTMIGgHCYuZmHt36BfiSyQPSRskPxbfaQ==
dependencies:
"@ethersproject/bytes" "^5.5.0"
"@ethersproject/properties" "^5.5.0"
"@ethersproject/basex@5.7.0", "@ethersproject/basex@^5.5.0", "@ethersproject/basex@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.7.0.tgz#97034dc7e8938a8ca943ab20f8a5e492ece4020b"
integrity sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==
dependencies:
"@ethersproject/bytes" "^5.7.0"
"@ethersproject/properties" "^5.7.0"
"@ethersproject/bignumber@5.5.0":
version "5.5.0"
resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.5.0.tgz#875b143f04a216f4f8b96245bde942d42d279527"
integrity sha512-6Xytlwvy6Rn3U3gKEc1vP7nR92frHkv6wtVr95LFR3jREXiCPzdWxKQ1cx4JGQBXxcguAwjA8murlYN2TSiEbg==
dependencies:
"@ethersproject/bytes" "^5.5.0"
"@ethersproject/logger" "^5.5.0"
bn.js "^4.11.9"
"@ethersproject/bignumber@5.7.0", "@ethersproject/bignumber@^5.5.0", "@ethersproject/bignumber@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.7.0.tgz#e2f03837f268ba655ffba03a57853e18a18dc9c2"
integrity sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==
dependencies:
"@ethersproject/bytes" "^5.7.0"
"@ethersproject/logger" "^5.7.0"
bn.js "^5.2.1"
"@ethersproject/bytes@5.5.0":
version "5.5.0"
resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.5.0.tgz#cb11c526de657e7b45d2e0f0246fb3b9d29a601c"
integrity sha512-ABvc7BHWhZU9PNM/tANm/Qx4ostPGadAuQzWTr3doklZOhDlmcBqclrQe/ZXUIj3K8wC28oYeuRa+A37tX9kog==
dependencies:
"@ethersproject/logger" "^5.5.0"
"@ethersproject/bytes@5.7.0", "@ethersproject/bytes@^5.5.0", "@ethersproject/bytes@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.7.0.tgz#a00f6ea8d7e7534d6d87f47188af1148d71f155d"
integrity sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==
dependencies:
"@ethersproject/logger" "^5.7.0"
"@ethersproject/constants@5.5.0":
version "5.5.0"
resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.5.0.tgz#d2a2cd7d94bd1d58377d1d66c4f53c9be4d0a45e"
integrity sha512-2MsRRVChkvMWR+GyMGY4N1sAX9Mt3J9KykCsgUFd/1mwS0UH1qw+Bv9k1UJb3X3YJYFco9H20pjSlOIfCG5HYQ==
dependencies:
"@ethersproject/bignumber" "^5.5.0"
"@ethersproject/constants@5.7.0", "@ethersproject/constants@^5.5.0", "@ethersproject/constants@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.7.0.tgz#df80a9705a7e08984161f09014ea012d1c75295e"
integrity sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==
dependencies:
"@ethersproject/bignumber" "^5.7.0"
"@ethersproject/contracts@5.5.0":
version "5.5.0"
resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.5.0.tgz#b735260d4bd61283a670a82d5275e2a38892c197"
integrity sha512-2viY7NzyvJkh+Ug17v7g3/IJC8HqZBDcOjYARZLdzRxrfGlRgmYgl6xPRKVbEzy1dWKw/iv7chDcS83pg6cLxg==
dependencies:
"@ethersproject/abi" "^5.5.0"
"@ethersproject/abstract-provider" "^5.5.0"
"@ethersproject/abstract-signer" "^5.5.0"
"@ethersproject/address" "^5.5.0"
"@ethersproject/bignumber" "^5.5.0"
"@ethersproject/bytes" "^5.5.0"
"@ethersproject/constants" "^5.5.0"
"@ethersproject/logger" "^5.5.0"
"@ethersproject/properties" "^5.5.0"
"@ethersproject/transactions" "^5.5.0"
"@ethersproject/contracts@5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.7.0.tgz#c305e775abd07e48aa590e1a877ed5c316f8bd1e"
integrity sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==
dependencies:
"@ethersproject/abi" "^5.7.0"
"@ethersproject/abstract-provider" "^5.7.0"
"@ethersproject/abstract-signer" "^5.7.0"
"@ethersproject/address" "^5.7.0"
"@ethersproject/bignumber" "^5.7.0"
"@ethersproject/bytes" "^5.7.0"
"@ethersproject/constants" "^5.7.0"
"@ethersproject/logger" "^5.7.0"
"@ethersproject/properties" "^5.7.0"
"@ethersproject/transactions" "^5.7.0"
"@ethersproject/hash@5.5.0":
version "5.5.0"
resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.5.0.tgz#7cee76d08f88d1873574c849e0207dcb32380cc9"
integrity sha512-dnGVpK1WtBjmnp3mUT0PlU2MpapnwWI0PibldQEq1408tQBAbZpPidkWoVVuNMOl/lISO3+4hXZWCL3YV7qzfg==
dependencies:
"@ethersproject/abstract-signer" "^5.5.0"
"@ethersproject/address" "^5.5.0"
"@ethersproject/bignumber" "^5.5.0"
"@ethersproject/bytes" "^5.5.0"
"@ethersproject/keccak256" "^5.5.0"
"@ethersproject/logger" "^5.5.0"
"@ethersproject/properties" "^5.5.0"
"@ethersproject/strings" "^5.5.0"
"@ethersproject/hash@5.7.0", "@ethersproject/hash@^5.5.0", "@ethersproject/hash@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.7.0.tgz#eb7aca84a588508369562e16e514b539ba5240a7"
integrity sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==
dependencies:
"@ethersproject/abstract-signer" "^5.7.0"
"@ethersproject/address" "^5.7.0"
"@ethersproject/base64" "^5.7.0"
"@ethersproject/bignumber" "^5.7.0"
"@ethersproject/bytes" "^5.7.0"
"@ethersproject/keccak256" "^5.7.0"
"@ethersproject/logger" "^5.7.0"
"@ethersproject/properties" "^5.7.0"
"@ethersproject/strings" "^5.7.0"
"@ethersproject/hdnode@5.5.0":
version "5.5.0"
resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.5.0.tgz#4a04e28f41c546f7c978528ea1575206a200ddf6"
integrity sha512-mcSOo9zeUg1L0CoJH7zmxwUG5ggQHU1UrRf8jyTYy6HxdZV+r0PBoL1bxr+JHIPXRzS6u/UW4mEn43y0tmyF8Q==
dependencies:
"@ethersproject/abstract-signer" "^5.5.0"
"@ethersproject/basex" "^5.5.0"
"@ethersproject/bignumber" "^5.5.0"
"@ethersproject/bytes" "^5.5.0"
"@ethersproject/logger" "^5.5.0"
"@ethersproject/pbkdf2" "^5.5.0"
"@ethersproject/properties" "^5.5.0"
"@ethersproject/sha2" "^5.5.0"
"@ethersproject/signing-key" "^5.5.0"
"@ethersproject/strings" "^5.5.0"
"@ethersproject/transactions" "^5.5.0"
"@ethersproject/wordlists" "^5.5.0"
"@ethersproject/hdnode@5.7.0", "@ethersproject/hdnode@^5.5.0", "@ethersproject/hdnode@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.7.0.tgz#e627ddc6b466bc77aebf1a6b9e47405ca5aef9cf"
integrity sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==
dependencies:
"@ethersproject/abstract-signer" "^5.7.0"
"@ethersproject/basex" "^5.7.0"
"@ethersproject/bignumber" "^5.7.0"
"@ethersproject/bytes" "^5.7.0"
"@ethersproject/logger" "^5.7.0"
"@ethersproject/pbkdf2" "^5.7.0"
"@ethersproject/properties" "^5.7.0"
"@ethersproject/sha2" "^5.7.0"
"@ethersproject/signing-key" "^5.7.0"
"@ethersproject/strings" "^5.7.0"
"@ethersproject/transactions" "^5.7.0"
"@ethersproject/wordlists" "^5.7.0"
"@ethersproject/json-wallets@5.5.0":
version "5.5.0"
resolved "https://registry.yarnpkg.com/@ethersproject/json-wallets/-/json-wallets-5.5.0.tgz#dd522d4297e15bccc8e1427d247ec8376b60e325"
integrity sha512-9lA21XQnCdcS72xlBn1jfQdj2A1VUxZzOzi9UkNdnokNKke/9Ya2xA9aIK1SC3PQyBDLt4C+dfps7ULpkvKikQ==
dependencies:
"@ethersproject/abstract-signer" "^5.5.0"
"@ethersproject/address" "^5.5.0"
"@ethersproject/bytes" "^5.5.0"
"@ethersproject/hdnode" "^5.5.0"
"@ethersproject/keccak256" "^5.5.0"
"@ethersproject/logger" "^5.5.0"
"@ethersproject/pbkdf2" "^5.5.0"
"@ethersproject/properties" "^5.5.0"
"@ethersproject/random" "^5.5.0"
"@ethersproject/strings" "^5.5.0"
"@ethersproject/transactions" "^5.5.0"
aes-js "3.0.0"
scrypt-js "3.0.1"
"@ethersproject/json-wallets@5.7.0", "@ethersproject/json-wallets@^5.5.0", "@ethersproject/json-wallets@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz#5e3355287b548c32b368d91014919ebebddd5360"
integrity sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==
dependencies:
"@ethersproject/abstract-signer" "^5.7.0"
"@ethersproject/address" "^5.7.0"
"@ethersproject/bytes" "^5.7.0"
"@ethersproject/hdnode" "^5.7.0"
"@ethersproject/keccak256" "^5.7.0"
"@ethersproject/logger" "^5.7.0"
"@ethersproject/pbkdf2" "^5.7.0"
"@ethersproject/properties" "^5.7.0"
"@ethersproject/random" "^5.7.0"
"@ethersproject/strings" "^5.7.0"
"@ethersproject/transactions" "^5.7.0"
aes-js "3.0.0"
scrypt-js "3.0.1"
"@ethersproject/keccak256@5.5.0":
version "5.5.0"
resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.5.0.tgz#e4b1f9d7701da87c564ffe336f86dcee82983492"
integrity sha512-5VoFCTjo2rYbBe1l2f4mccaRFN/4VQEYFwwn04aJV2h7qf4ZvI2wFxUE1XOX+snbwCLRzIeikOqtAoPwMza9kg==
dependencies:
"@ethersproject/bytes" "^5.5.0"
js-sha3 "0.8.0"
"@ethersproject/keccak256@5.7.0", "@ethersproject/keccak256@^5.5.0", "@ethersproject/keccak256@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.7.0.tgz#3186350c6e1cd6aba7940384ec7d6d9db01f335a"
integrity sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==
dependencies:
"@ethersproject/bytes" "^5.7.0"
js-sha3 "0.8.0"
"@ethersproject/logger@5.5.0":
version "5.5.0"
resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.5.0.tgz#0c2caebeff98e10aefa5aef27d7441c7fd18cf5d"
integrity sha512-rIY/6WPm7T8n3qS2vuHTUBPdXHl+rGxWxW5okDfo9J4Z0+gRRZT0msvUdIJkE4/HS29GUMziwGaaKO2bWONBrg==
"@ethersproject/logger@5.7.0", "@ethersproject/logger@^5.5.0", "@ethersproject/logger@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.7.0.tgz#6ce9ae168e74fecf287be17062b590852c311892"
integrity sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==
"@ethersproject/networks@5.5.2":
version "5.5.2"
resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.5.2.tgz#784c8b1283cd2a931114ab428dae1bd00c07630b"
integrity sha512-NEqPxbGBfy6O3x4ZTISb90SjEDkWYDUbEeIFhJly0F7sZjoQMnj5KYzMSkMkLKZ+1fGpx00EDpHQCy6PrDupkQ==
dependencies:
"@ethersproject/logger" "^5.5.0"
"@ethersproject/networks@5.7.1", "@ethersproject/networks@^5.5.0", "@ethersproject/networks@^5.7.0":
version "5.7.1"
resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.7.1.tgz#118e1a981d757d45ccea6bb58d9fd3d9db14ead6"
integrity sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==
dependencies:
"@ethersproject/logger" "^5.7.0"
"@ethersproject/pbkdf2@5.5.0":
version "5.5.0"
resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.5.0.tgz#e25032cdf02f31505d47afbf9c3e000d95c4a050"
integrity sha512-SaDvQFvXPnz1QGpzr6/HToLifftSXGoXrbpZ6BvoZhmx4bNLHrxDe8MZisuecyOziP1aVEwzC2Hasj+86TgWVg==
dependencies:
"@ethersproject/bytes" "^5.5.0"
"@ethersproject/sha2" "^5.5.0"
"@ethersproject/pbkdf2@5.7.0", "@ethersproject/pbkdf2@^5.5.0", "@ethersproject/pbkdf2@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz#d2267d0a1f6e123f3771007338c47cccd83d3102"
integrity sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==
dependencies:
"@ethersproject/bytes" "^5.7.0"
"@ethersproject/sha2" "^5.7.0"
"@ethersproject/properties@5.5.0":
version "5.5.0"
resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.5.0.tgz#61f00f2bb83376d2071baab02245f92070c59995"
integrity sha512-l3zRQg3JkD8EL3CPjNK5g7kMx4qSwiR60/uk5IVjd3oq1MZR5qUg40CNOoEJoX5wc3DyY5bt9EbMk86C7x0DNA==
dependencies:
"@ethersproject/logger" "^5.5.0"
"@ethersproject/properties@5.7.0", "@ethersproject/properties@^5.5.0", "@ethersproject/properties@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.7.0.tgz#a6e12cb0439b878aaf470f1902a176033067ed30"
integrity sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==
dependencies:
"@ethersproject/logger" "^5.7.0"
"@ethersproject/providers@5.5.2":
version "5.5.2"
resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.5.2.tgz#131ccf52dc17afd0ab69ed444b8c0e3a27297d99"
integrity sha512-hkbx7x/MKcRjyrO4StKXCzCpWer6s97xnm34xkfPiarhtEUVAN4TBBpamM+z66WcTt7H5B53YwbRj1n7i8pZoQ==
dependencies:
"@ethersproject/abstract-provider" "^5.5.0"
"@ethersproject/abstract-signer" "^5.5.0"
"@ethersproject/address" "^5.5.0"
"@ethersproject/basex" "^5.5.0"
"@ethersproject/bignumber" "^5.5.0"
"@ethersproject/bytes" "^5.5.0"
"@ethersproject/constants" "^5.5.0"
"@ethersproject/hash" "^5.5.0"
"@ethersproject/logger" "^5.5.0"
"@ethersproject/networks" "^5.5.0"
"@ethersproject/properties" "^5.5.0"
"@ethersproject/random" "^5.5.0"
"@ethersproject/rlp" "^5.5.0"
"@ethersproject/sha2" "^5.5.0"
"@ethersproject/strings" "^5.5.0"
"@ethersproject/transactions" "^5.5.0"
"@ethersproject/web" "^5.5.0"
bech32 "1.1.4"
ws "7.4.6"
"@ethersproject/providers@5.7.2":
version "5.7.2"
resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.7.2.tgz#f8b1a4f275d7ce58cf0a2eec222269a08beb18cb"
integrity sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==
dependencies:
"@ethersproject/abstract-provider" "^5.7.0"
"@ethersproject/abstract-signer" "^5.7.0"
"@ethersproject/address" "^5.7.0"
"@ethersproject/base64" "^5.7.0"
"@ethersproject/basex" "^5.7.0"
"@ethersproject/bignumber" "^5.7.0"
"@ethersproject/bytes" "^5.7.0"
"@ethersproject/constants" "^5.7.0"
"@ethersproject/hash" "^5.7.0"
"@ethersproject/logger" "^5.7.0"
"@ethersproject/networks" "^5.7.0"
"@ethersproject/properties" "^5.7.0"
"@ethersproject/random" "^5.7.0"
"@ethersproject/rlp" "^5.7.0"
"@ethersproject/sha2" "^5.7.0"
"@ethersproject/strings" "^5.7.0"
"@ethersproject/transactions" "^5.7.0"
"@ethersproject/web" "^5.7.0"
bech32 "1.1.4"
ws "7.4.6"
"@ethersproject/random@5.5.1":
version "5.5.1"
resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.5.1.tgz#7cdf38ea93dc0b1ed1d8e480ccdaf3535c555415"
integrity sha512-YaU2dQ7DuhL5Au7KbcQLHxcRHfgyNgvFV4sQOo0HrtW3Zkrc9ctWNz8wXQ4uCSfSDsqX2vcjhroxU5RQRV0nqA==
dependencies:
"@ethersproject/bytes" "^5.5.0"
"@ethersproject/logger" "^5.5.0"
"@ethersproject/random@5.7.0", "@ethersproject/random@^5.5.0", "@ethersproject/random@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.7.0.tgz#af19dcbc2484aae078bb03656ec05df66253280c"
integrity sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==
dependencies:
"@ethersproject/bytes" "^5.7.0"
"@ethersproject/logger" "^5.7.0"
"@ethersproject/rlp@5.5.0":
version "5.5.0"
resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.5.0.tgz#530f4f608f9ca9d4f89c24ab95db58ab56ab99a0"
integrity sha512-hLv8XaQ8PTI9g2RHoQGf/WSxBfTB/NudRacbzdxmst5VHAqd1sMibWG7SENzT5Dj3yZ3kJYx+WiRYEcQTAkcYA==
dependencies:
"@ethersproject/bytes" "^5.5.0"
"@ethersproject/logger" "^5.5.0"
"@ethersproject/rlp@5.7.0", "@ethersproject/rlp@^5.5.0", "@ethersproject/rlp@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.7.0.tgz#de39e4d5918b9d74d46de93af80b7685a9c21304"
integrity sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==
dependencies:
"@ethersproject/bytes" "^5.7.0"
"@ethersproject/logger" "^5.7.0"
"@ethersproject/sha2@5.5.0":
version "5.5.0"
resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.5.0.tgz#a40a054c61f98fd9eee99af2c3cc6ff57ec24db7"
integrity sha512-B5UBoglbCiHamRVPLA110J+2uqsifpZaTmid2/7W5rbtYVz6gus6/hSDieIU/6gaKIDcOj12WnOdiymEUHIAOA==
dependencies:
"@ethersproject/bytes" "^5.5.0"
"@ethersproject/logger" "^5.5.0"
hash.js "1.1.7"
"@ethersproject/sha2@5.7.0", "@ethersproject/sha2@^5.5.0", "@ethersproject/sha2@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.7.0.tgz#9a5f7a7824ef784f7f7680984e593a800480c9fb"
integrity sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==
dependencies:
"@ethersproject/bytes" "^5.7.0"
"@ethersproject/logger" "^5.7.0"
hash.js "1.1.7"
"@ethersproject/signing-key@5.5.0":
version "5.5.0"
resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.5.0.tgz#2aa37169ce7e01e3e80f2c14325f624c29cedbe0"
integrity sha512-5VmseH7qjtNmDdZBswavhotYbWB0bOwKIlOTSlX14rKn5c11QmJwGt4GHeo7NrL/Ycl7uo9AHvEqs5xZgFBTng==
dependencies:
"@ethersproject/bytes" "^5.5.0"
"@ethersproject/logger" "^5.5.0"
"@ethersproject/properties" "^5.5.0"
bn.js "^4.11.9"
elliptic "6.5.4"
hash.js "1.1.7"
"@ethersproject/signing-key@5.7.0", "@ethersproject/signing-key@^5.5.0", "@ethersproject/signing-key@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.7.0.tgz#06b2df39411b00bc57c7c09b01d1e41cf1b16ab3"
integrity sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==
dependencies:
"@ethersproject/bytes" "^5.7.0"
"@ethersproject/logger" "^5.7.0"
"@ethersproject/properties" "^5.7.0"
bn.js "^5.2.1"
elliptic "6.5.4"
hash.js "1.1.7"
"@ethersproject/solidity@5.5.0":
version "5.5.0"
resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.5.0.tgz#2662eb3e5da471b85a20531e420054278362f93f"
integrity sha512-9NgZs9LhGMj6aCtHXhtmFQ4AN4sth5HuFXVvAQtzmm0jpSCNOTGtrHZJAeYTh7MBjRR8brylWZxBZR9zDStXbw==
dependencies:
"@ethersproject/bignumber" "^5.5.0"
"@ethersproject/bytes" "^5.5.0"
"@ethersproject/keccak256" "^5.5.0"
"@ethersproject/logger" "^5.5.0"
"@ethersproject/sha2" "^5.5.0"
"@ethersproject/strings" "^5.5.0"
"@ethersproject/solidity@5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.7.0.tgz#5e9c911d8a2acce2a5ebb48a5e2e0af20b631cb8"
integrity sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==
dependencies:
"@ethersproject/bignumber" "^5.7.0"
"@ethersproject/bytes" "^5.7.0"
"@ethersproject/keccak256" "^5.7.0"
"@ethersproject/logger" "^5.7.0"
"@ethersproject/sha2" "^5.7.0"
"@ethersproject/strings" "^5.7.0"
"@ethersproject/strings@5.5.0":
version "5.5.0"
resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.5.0.tgz#e6784d00ec6c57710755699003bc747e98c5d549"
integrity sha512-9fy3TtF5LrX/wTrBaT8FGE6TDJyVjOvXynXJz5MT5azq+E6D92zuKNx7i29sWW2FjVOaWjAsiZ1ZWznuduTIIQ==
dependencies:
"@ethersproject/bytes" "^5.5.0"
"@ethersproject/constants" "^5.5.0"
"@ethersproject/logger" "^5.5.0"
"@ethersproject/strings@5.7.0", "@ethersproject/strings@^5.5.0", "@ethersproject/strings@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.7.0.tgz#54c9d2a7c57ae8f1205c88a9d3a56471e14d5ed2"
integrity sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==
dependencies:
"@ethersproject/bytes" "^5.7.0"
"@ethersproject/constants" "^5.7.0"
"@ethersproject/logger" "^5.7.0"
"@ethersproject/transactions@5.5.0":
version "5.5.0"
resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.5.0.tgz#7e9bf72e97bcdf69db34fe0d59e2f4203c7a2908"
integrity sha512-9RZYSKX26KfzEd/1eqvv8pLauCKzDTub0Ko4LfIgaERvRuwyaNV78mJs7cpIgZaDl6RJui4o49lHwwCM0526zA==
dependencies:
"@ethersproject/address" "^5.5.0"
"@ethersproject/bignumber" "^5.5.0"
"@ethersproject/bytes" "^5.5.0"
"@ethersproject/constants" "^5.5.0"
"@ethersproject/keccak256" "^5.5.0"
"@ethersproject/logger" "^5.5.0"
"@ethersproject/properties" "^5.5.0"
"@ethersproject/rlp" "^5.5.0"
"@ethersproject/signing-key" "^5.5.0"
"@ethersproject/transactions@5.7.0", "@ethersproject/transactions@^5.5.0", "@ethersproject/transactions@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.7.0.tgz#91318fc24063e057885a6af13fdb703e1f993d3b"
integrity sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==
dependencies:
"@ethersproject/address" "^5.7.0"
"@ethersproject/bignumber" "^5.7.0"
"@ethersproject/bytes" "^5.7.0"
"@ethersproject/constants" "^5.7.0"
"@ethersproject/keccak256" "^5.7.0"
"@ethersproject/logger" "^5.7.0"
"@ethersproject/properties" "^5.7.0"
"@ethersproject/rlp" "^5.7.0"
"@ethersproject/signing-key" "^5.7.0"
"@ethersproject/units@5.5.0":
version "5.5.0"
resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.5.0.tgz#104d02db5b5dc42cc672cc4587bafb87a95ee45e"
integrity sha512-7+DpjiZk4v6wrikj+TCyWWa9dXLNU73tSTa7n0TSJDxkYbV3Yf1eRh9ToMLlZtuctNYu9RDNNy2USq3AdqSbag==
dependencies:
"@ethersproject/bignumber" "^5.5.0"
"@ethersproject/constants" "^5.5.0"
"@ethersproject/logger" "^5.5.0"
"@ethersproject/units@5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.7.0.tgz#637b563d7e14f42deeee39245275d477aae1d8b1"
integrity sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==
dependencies:
"@ethersproject/bignumber" "^5.7.0"
"@ethersproject/constants" "^5.7.0"
"@ethersproject/logger" "^5.7.0"
"@ethersproject/wallet@5.5.0":
version "5.5.0"
resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.5.0.tgz#322a10527a440ece593980dca6182f17d54eae75"
integrity sha512-Mlu13hIctSYaZmUOo7r2PhNSd8eaMPVXe1wxrz4w4FCE4tDYBywDH+bAR1Xz2ADyXGwqYMwstzTrtUVIsKDO0Q==
dependencies:
"@ethersproject/abstract-provider" "^5.5.0"
"@ethersproject/abstract-signer" "^5.5.0"
"@ethersproject/address" "^5.5.0"
"@ethersproject/bignumber" "^5.5.0"
"@ethersproject/bytes" "^5.5.0"
"@ethersproject/hash" "^5.5.0"
"@ethersproject/hdnode" "^5.5.0"
"@ethersproject/json-wallets" "^5.5.0"
"@ethersproject/keccak256" "^5.5.0"
"@ethersproject/logger" "^5.5.0"
"@ethersproject/properties" "^5.5.0"
"@ethersproject/random" "^5.5.0"
"@ethersproject/signing-key" "^5.5.0"
"@ethersproject/transactions" "^5.5.0"
"@ethersproject/wordlists" "^5.5.0"
"@ethersproject/wallet@5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.7.0.tgz#4e5d0790d96fe21d61d38fb40324e6c7ef350b2d"
integrity sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==
dependencies:
"@ethersproject/abstract-provider" "^5.7.0"
"@ethersproject/abstract-signer" "^5.7.0"
"@ethersproject/address" "^5.7.0"
"@ethersproject/bignumber" "^5.7.0"
"@ethersproject/bytes" "^5.7.0"
"@ethersproject/hash" "^5.7.0"
"@ethersproject/hdnode" "^5.7.0"
"@ethersproject/json-wallets" "^5.7.0"
"@ethersproject/keccak256" "^5.7.0"
"@ethersproject/logger" "^5.7.0"
"@ethersproject/properties" "^5.7.0"
"@ethersproject/random" "^5.7.0"
"@ethersproject/signing-key" "^5.7.0"
"@ethersproject/transactions" "^5.7.0"
"@ethersproject/wordlists" "^5.7.0"
"@ethersproject/web@5.5.1":
version "5.5.1"
resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.5.1.tgz#cfcc4a074a6936c657878ac58917a61341681316"
integrity sha512-olvLvc1CB12sREc1ROPSHTdFCdvMh0J5GSJYiQg2D0hdD4QmJDy8QYDb1CvoqD/bF1c++aeKv2sR5uduuG9dQg==
dependencies:
"@ethersproject/base64" "^5.5.0"
"@ethersproject/bytes" "^5.5.0"
"@ethersproject/logger" "^5.5.0"
"@ethersproject/properties" "^5.5.0"
"@ethersproject/strings" "^5.5.0"
"@ethersproject/web@5.7.1", "@ethersproject/web@^5.5.0", "@ethersproject/web@^5.7.0":
version "5.7.1"
resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.7.1.tgz#de1f285b373149bee5928f4eb7bcb87ee5fbb4ae"
integrity sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==
dependencies:
"@ethersproject/base64" "^5.7.0"
"@ethersproject/bytes" "^5.7.0"
"@ethersproject/logger" "^5.7.0"
"@ethersproject/properties" "^5.7.0"
"@ethersproject/strings" "^5.7.0"
"@ethersproject/wordlists@5.5.0":
version "5.5.0"
resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.5.0.tgz#aac74963aa43e643638e5172353d931b347d584f"
integrity sha512-bL0UTReWDiaQJJYOC9sh/XcRu/9i2jMrzf8VLRmPKx58ckSlOJiohODkECCO50dtLZHcGU6MLXQ4OOrgBwP77Q==
dependencies:
"@ethersproject/bytes" "^5.5.0"
"@ethersproject/hash" "^5.5.0"
"@ethersproject/logger" "^5.5.0"
"@ethersproject/properties" "^5.5.0"
"@ethersproject/strings" "^5.5.0"
"@ethersproject/wordlists@5.7.0", "@ethersproject/wordlists@^5.5.0", "@ethersproject/wordlists@^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.7.0.tgz#8fb2c07185d68c3e09eb3bfd6e779ba2774627f5"
integrity sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==
dependencies:
"@ethersproject/bytes" "^5.7.0"
"@ethersproject/hash" "^5.7.0"
"@ethersproject/logger" "^5.7.0"
"@ethersproject/properties" "^5.7.0"
"@ethersproject/strings" "^5.7.0"
"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": "@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2":
version "0.3.3" version "0.3.3"
resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098"
@ -324,6 +1006,31 @@
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.7.tgz#ccab5c8f7dc557a52ca3288c10075c9ccd37fff7" resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.7.tgz#ccab5c8f7dc557a52ca3288c10075c9ccd37fff7"
integrity sha512-Cr4OjIkipTtcXKjAsm8agyleBuDHvxzeBoa1v543lbv1YaIwQjESsVcmjiWiPEbC1FIeHOG/Op9kdCmAmiS3Kw== integrity sha512-Cr4OjIkipTtcXKjAsm8agyleBuDHvxzeBoa1v543lbv1YaIwQjESsVcmjiWiPEbC1FIeHOG/Op9kdCmAmiS3Kw==
"@stablelib/binary@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@stablelib/binary/-/binary-1.0.1.tgz#c5900b94368baf00f811da5bdb1610963dfddf7f"
integrity sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q==
dependencies:
"@stablelib/int" "^1.0.1"
"@stablelib/int@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@stablelib/int/-/int-1.0.1.tgz#75928cc25d59d73d75ae361f02128588c15fd008"
integrity sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w==
"@stablelib/random@^1.0.1":
version "1.0.2"
resolved "https://registry.yarnpkg.com/@stablelib/random/-/random-1.0.2.tgz#2dece393636489bf7e19c51229dd7900eddf742c"
integrity sha512-rIsE83Xpb7clHPVRlBj8qNe5L8ISQOzjghYQm/dZ7VaM2KHYwMW5adjQjrzTZCchFnNCNhkwtnOBa9HTMJCI8w==
dependencies:
"@stablelib/binary" "^1.0.1"
"@stablelib/wipe" "^1.0.1"
"@stablelib/wipe@^1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@stablelib/wipe/-/wipe-1.0.1.tgz#d21401f1d59ade56a62e139462a97f104ed19a36"
integrity sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg==
"@types/body-parser@*": "@types/body-parser@*":
version "1.19.2" version "1.19.2"
resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0"
@ -624,6 +1331,11 @@ acorn@^8.5.0, acorn@^8.7.1:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a"
integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==
aes-js@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d"
integrity sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==
ajv-formats@^2.1.1: ajv-formats@^2.1.1:
version "2.1.1" version "2.1.1"
resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520"
@ -695,6 +1407,11 @@ anymatch@~3.1.2:
normalize-path "^3.0.0" normalize-path "^3.0.0"
picomatch "^2.0.4" picomatch "^2.0.4"
apg-js@^4.1.1:
version "4.1.3"
resolved "https://registry.yarnpkg.com/apg-js/-/apg-js-4.1.3.tgz#0cb9dc99f8830740d7a8f9fc0048fa618ae4d199"
integrity sha512-XYyDcoBho8OpnWPRnedMwyL+76ovCtsESerHZEfY39dO4IrEqN97mdEYkOyHa0XTX5+3+U5FmpqPLttK0f7n6g==
arg@^5.0.2: arg@^5.0.2:
version "5.0.2" version "5.0.2"
resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c" resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c"
@ -737,11 +1454,26 @@ batch@0.6.1:
resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16"
integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==
bech32@1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9"
integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==
binary-extensions@^2.0.0: binary-extensions@^2.0.0:
version "2.2.0" version "2.2.0"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
bn.js@^4.11.9:
version "4.12.0"
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88"
integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==
bn.js@^5.2.1:
version "5.2.1"
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70"
integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==
body-parser@1.20.1: body-parser@1.20.1:
version "1.20.1" version "1.20.1"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668"
@ -785,6 +1517,11 @@ braces@^3.0.2, braces@~3.0.2:
dependencies: dependencies:
fill-range "^7.0.1" fill-range "^7.0.1"
brorand@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==
browserslist@^4.14.5, browserslist@^4.21.5: browserslist@^4.14.5, browserslist@^4.21.5:
version "4.21.5" version "4.21.5"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7"
@ -1127,6 +1864,19 @@ electron-to-chromium@^1.4.284:
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.368.tgz#75901f97d3e23da2e66feb1e61fbb8e70ac96430" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.368.tgz#75901f97d3e23da2e66feb1e61fbb8e70ac96430"
integrity sha512-e2aeCAixCj9M7nJxdB/wDjO6mbYX+lJJxSJCXDzlr5YPGYVofuJwGN9nKg2o6wWInjX6XmxRinn3AeJMK81ltw== integrity sha512-e2aeCAixCj9M7nJxdB/wDjO6mbYX+lJJxSJCXDzlr5YPGYVofuJwGN9nKg2o6wWInjX6XmxRinn3AeJMK81ltw==
elliptic@6.5.4:
version "6.5.4"
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb"
integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==
dependencies:
bn.js "^4.11.9"
brorand "^1.1.0"
hash.js "^1.0.0"
hmac-drbg "^1.0.1"
inherits "^2.0.4"
minimalistic-assert "^1.0.1"
minimalistic-crypto-utils "^1.0.1"
encodeurl@~1.0.2: encodeurl@~1.0.2:
version "1.0.2" version "1.0.2"
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
@ -1202,6 +1952,78 @@ etag@~1.8.1:
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==
ethers@5.5.3:
version "5.5.3"
resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.5.3.tgz#1e361516711c0c3244b6210e7e3ecabf0c75fca0"
integrity sha512-fTT4WT8/hTe/BLwRUtl7I5zlpF3XC3P/Xwqxc5AIP2HGlH15qpmjs0Ou78az93b1rLITzXLFxoNX63B8ZbUd7g==
dependencies:
"@ethersproject/abi" "5.5.0"
"@ethersproject/abstract-provider" "5.5.1"
"@ethersproject/abstract-signer" "5.5.0"
"@ethersproject/address" "5.5.0"
"@ethersproject/base64" "5.5.0"
"@ethersproject/basex" "5.5.0"
"@ethersproject/bignumber" "5.5.0"
"@ethersproject/bytes" "5.5.0"
"@ethersproject/constants" "5.5.0"
"@ethersproject/contracts" "5.5.0"
"@ethersproject/hash" "5.5.0"
"@ethersproject/hdnode" "5.5.0"
"@ethersproject/json-wallets" "5.5.0"
"@ethersproject/keccak256" "5.5.0"
"@ethersproject/logger" "5.5.0"
"@ethersproject/networks" "5.5.2"
"@ethersproject/pbkdf2" "5.5.0"
"@ethersproject/properties" "5.5.0"
"@ethersproject/providers" "5.5.2"
"@ethersproject/random" "5.5.1"
"@ethersproject/rlp" "5.5.0"
"@ethersproject/sha2" "5.5.0"
"@ethersproject/signing-key" "5.5.0"
"@ethersproject/solidity" "5.5.0"
"@ethersproject/strings" "5.5.0"
"@ethersproject/transactions" "5.5.0"
"@ethersproject/units" "5.5.0"
"@ethersproject/wallet" "5.5.0"
"@ethersproject/web" "5.5.1"
"@ethersproject/wordlists" "5.5.0"
ethers@^5.5.1:
version "5.7.2"
resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e"
integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==
dependencies:
"@ethersproject/abi" "5.7.0"
"@ethersproject/abstract-provider" "5.7.0"
"@ethersproject/abstract-signer" "5.7.0"
"@ethersproject/address" "5.7.0"
"@ethersproject/base64" "5.7.0"
"@ethersproject/basex" "5.7.0"
"@ethersproject/bignumber" "5.7.0"
"@ethersproject/bytes" "5.7.0"
"@ethersproject/constants" "5.7.0"
"@ethersproject/contracts" "5.7.0"
"@ethersproject/hash" "5.7.0"
"@ethersproject/hdnode" "5.7.0"
"@ethersproject/json-wallets" "5.7.0"
"@ethersproject/keccak256" "5.7.0"
"@ethersproject/logger" "5.7.0"
"@ethersproject/networks" "5.7.1"
"@ethersproject/pbkdf2" "5.7.0"
"@ethersproject/properties" "5.7.0"
"@ethersproject/providers" "5.7.2"
"@ethersproject/random" "5.7.0"
"@ethersproject/rlp" "5.7.0"
"@ethersproject/sha2" "5.7.0"
"@ethersproject/signing-key" "5.7.0"
"@ethersproject/solidity" "5.7.0"
"@ethersproject/strings" "5.7.0"
"@ethersproject/transactions" "5.7.0"
"@ethersproject/units" "5.7.0"
"@ethersproject/wallet" "5.7.0"
"@ethersproject/web" "5.7.1"
"@ethersproject/wordlists" "5.7.0"
eventemitter3@^4.0.0: eventemitter3@^4.0.0:
version "4.0.7" version "4.0.7"
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
@ -1469,6 +2291,23 @@ has@^1.0.3:
dependencies: dependencies:
function-bind "^1.1.1" function-bind "^1.1.1"
hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3:
version "1.1.7"
resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42"
integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==
dependencies:
inherits "^2.0.3"
minimalistic-assert "^1.0.1"
hmac-drbg@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==
dependencies:
hash.js "^1.0.3"
minimalistic-assert "^1.0.0"
minimalistic-crypto-utils "^1.0.1"
hpack.js@^2.1.6: hpack.js@^2.1.6:
version "2.1.6" version "2.1.6"
resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2"
@ -1576,7 +2415,7 @@ inflight@^1.0.4:
once "^1.3.0" once "^1.3.0"
wrappy "1" wrappy "1"
inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3:
version "2.0.4" version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
@ -1695,6 +2534,11 @@ jiti@^1.17.2:
resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.18.2.tgz#80c3ef3d486ebf2450d9335122b32d121f2a83cd" resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.18.2.tgz#80c3ef3d486ebf2450d9335122b32d121f2a83cd"
integrity sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg== integrity sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==
js-sha3@0.8.0:
version "0.8.0"
resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840"
integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==
js-tokens@^4.0.0: js-tokens@^4.0.0:
version "4.0.0" version "4.0.0"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
@ -1836,11 +2680,16 @@ mini-svg-data-uri@^1.4.3:
resolved "https://registry.yarnpkg.com/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz#8ab0aabcdf8c29ad5693ca595af19dd2ead09939" resolved "https://registry.yarnpkg.com/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz#8ab0aabcdf8c29ad5693ca595af19dd2ead09939"
integrity sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg== integrity sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==
minimalistic-assert@^1.0.0: minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==
minimalistic-crypto-utils@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==
minimatch@^3.0.4, minimatch@^3.1.1: minimatch@^3.0.4, minimatch@^3.1.1:
version "3.1.2" version "3.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
@ -2613,6 +3462,11 @@ schema-utils@^4.0.0:
ajv-formats "^2.1.1" ajv-formats "^2.1.1"
ajv-keywords "^5.1.0" ajv-keywords "^5.1.0"
scrypt-js@3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312"
integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==
select-hose@^2.0.0: select-hose@^2.0.0:
version "2.0.0" version "2.0.0"
resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
@ -2729,6 +3583,15 @@ signal-exit@^3.0.3:
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
siwe@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/siwe/-/siwe-1.0.0.tgz#efda45b428e3ae63b048e7583b4c4395c971139d"
integrity sha512-rAPcXB/gFDunsGDnOI55jsAqEvS369GzKLB6pSVzvMUdrQzdjafllHRc2EnNovNG2zIwVW46kLA2okzJF/UIXw==
dependencies:
"@stablelib/random" "^1.0.1"
apg-js "^4.1.1"
ethers "^5.5.1"
sockjs@^0.3.24: sockjs@^0.3.24:
version "0.3.24" version "0.3.24"
resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce"
@ -3162,6 +4025,11 @@ wrappy@1:
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==
ws@7.4.6:
version "7.4.6"
resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c"
integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==
ws@^8.13.0: ws@^8.13.0:
version "8.13.0" version "8.13.0"
resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0"