diff --git a/alembic/versions/40734564d415_init_suchwowx.py b/alembic/versions/40734564d415_init_suchwowx.py
new file mode 100644
index 0000000..8298ae9
--- /dev/null
+++ b/alembic/versions/40734564d415_init_suchwowx.py
@@ -0,0 +1,62 @@
+"""init suchwowx
+
+Revision ID: 40734564d415
+Revises:
+Create Date: 2021-12-28 22:05:09.994215
+
+"""
+from uuid import uuid4
+
+from alembic import op
+import sqlalchemy as sa
+
+# revision identifiers, used by Alembic.
+revision = '40734564d415'
+down_revision = None
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+ mods_table = op.create_table('moderators',
+ sa.Column('id', sa.Integer, autoincrement=True, nullable=False, primary_key=True),
+ sa.Column('user_id', sa.Integer, nullable=False),
+ sa.ForeignKeyConstraint(['user_id'], ['users.id'], name='moderators_user_id_fkey'),
+ )
+ users_table = op.create_table('users',
+ sa.Column('id', sa.Integer, autoincrement=True, nullable=False),
+ sa.Column('register_date', sa.DateTime(), autoincrement=False, nullable=True),
+ sa.Column('last_login_date', sa.DateTime(), autoincrement=False, nullable=True),
+ sa.Column('verified', sa.Boolean, autoincrement=False, nullable=True),
+ sa.Column('public_address', sa.String(180), autoincrement=False, nullable=True),
+ sa.Column('nonce', sa.String(180), autoincrement=False, nullable=True),
+ sa.Column('nonce_date', sa.DateTime(), autoincrement=False, nullable=True),
+ sa.Column('handle', sa.String(40), autoincrement=False, nullable=True, ),
+ sa.Column('bio', sa.String(600), autoincrement=False, nullable=True),
+ sa.Column('profile_image', sa.String(300), autoincrement=False, nullable=True),
+ sa.Column('website_url', sa.String(120), autoincrement=False, nullable=True),
+ sa.Column('moderator_id', sa.Integer, nullable=True),
+ sa.PrimaryKeyConstraint('id', name='users_pkey'),
+ sa.UniqueConstraint('handle', name='users_handle_key'),
+ sa.ForeignKeyConstraint(['moderator_id'], ['moderators.id'], name='users_user_id_fkey'),
+ )
+ memes_table = op.create_table('memes',
+ sa.Column('id', sa.String(80), server_default=uuid4().hex, autoincrement=False, nullable=False),
+ sa.Column('user_id', sa.Integer, autoincrement=False, nullable=True),
+ sa.Column('create_date', sa.DateTime(), autoincrement=False, nullable=True),
+ sa.Column('title', sa.String(80), autoincrement=False, nullable=True),
+ sa.Column('description', sa.String(300), autoincrement=False, nullable=True),
+ sa.Column('file_name', sa.String(300), autoincrement=False, nullable=True),
+ sa.Column('minted', sa.Boolean, autoincrement=False, nullable=True),
+ sa.Column('meta_ipfs_hash', sa.String(100), autoincrement=False, nullable=True),
+ sa.Column('meme_ipfs_hash', sa.String(100), autoincrement=False, nullable=True),
+ sa.ForeignKeyConstraint(['user_id'], ['users.id'], name='artwork_user_id_fkey'),
+ sa.PrimaryKeyConstraint('id', name='artwork_pkey'),
+ sa.UniqueConstraint('meta_ipfs_hash', name='memes_meta_ipfs_hash_key'),
+ sa.UniqueConstraint('meme_ipfs_hash', name='memes_meme_ipfs_hash_key')
+ )
+
+def downgrade():
+ op.drop_table('moderators')
+ op.drop_table('users')
+ op.drop_table('memes')
diff --git a/suchwowx/models.py b/suchwowx/models.py
index e1e99fc..c685db7 100644
--- a/suchwowx/models.py
+++ b/suchwowx/models.py
@@ -95,7 +95,7 @@ class Meme(db.Model):
meme_ipfs_hash = db.Column(db.String(100), unique=True, nullable=True)
title = db.Column(db.String(50))
description = db.Column(db.String(400), nullable=True)
- creator_handle = db.Column(db.String(50), nullable=True)
+ minted = db.Column(db.Boolean, default=False)
def __repr__(self):
return str(f'meme-{self.id}')
diff --git a/suchwowx/static/js/main.js b/suchwowx/static/js/main.js
new file mode 100644
index 0000000..b479bd1
--- /dev/null
+++ b/suchwowx/static/js/main.js
@@ -0,0 +1,8 @@
+async function getSignedData(publicAddress, jsonData) {
+ const signedData = await window.ethereum.request({
+ method: 'eth_signTypedData_v3',
+ params: [publicAddress, JSON.stringify(jsonData)]
+ });
+ console.log(signedData);
+ return signedData
+}
diff --git a/suchwowx/static/js/metamask.js b/suchwowx/static/js/metamask.js
new file mode 100644
index 0000000..190edd3
--- /dev/null
+++ b/suchwowx/static/js/metamask.js
@@ -0,0 +1,78 @@
+window.addEventListener('DOMContentLoaded', () => {
+ onboardMetaMask()
+})
+
+async function onboardMetaMask(){
+ const onboarding = new MetaMaskOnboarding();
+ const onboardButton = document.getElementById('metamaskConnect');
+ let accounts;
+ let nonce = 0;
+
+ const connectButton = async () => {
+ if (!MetaMaskOnboarding.isMetaMaskInstalled()) {
+ onboardButton.innerText = 'Click here to install MetaMask!';
+ onboardButton.onclick = () => {
+ onboardButton.classList.add('is-loading');
+ onboardButton.disabled = true;
+ onboarding.startOnboarding();
+ };
+ } else if (accounts && accounts.length > 0) {
+ onboardButton.classList.remove('is-loading');
+ onboardButton.disabled = false;
+ onboarding.stopOnboarding();
+ } else {
+ onboardButton.onclick = async () => {
+ onboardButton.classList.add('is-loading');
+ onboardButton.disabled = true;
+ let userExists;
+ const allAccounts = await window.ethereum.request({
+ method: 'eth_requestAccounts',
+ });
+ await fetch('/api/v1/user_exists?public_address=' + allAccounts[0])
+ .then((resp) => resp.json())
+ .then(function(data) {
+ if (!data['success']) {
+ console.log('error checking user_exists!')
+ return
+ }
+ console.log(data);
+ nonce = data['nonce'];
+ })
+
+ const msg = 'Authentication request from SuchWowX app! Verifying message with nonce ' + nonce
+ const signedData = await window.ethereum.request({
+ method: 'personal_sign',
+ params: [msg, allAccounts[0]]
+ });
+ console.log(`Signing data with msg "${msg}", address "${allAccounts[0]}", signed data: ${signedData}`)
+
+ await fetch('/api/v1/authenticate/metamask', {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json;charset=utf-8'
+ },
+ body: JSON.stringify({
+ 'signed_data': signedData,
+ 'public_address': allAccounts[0],
+ 'nonce': nonce,
+ 'message': msg,
+ })
+ })
+ .then((resp) => resp.json())
+ .then(function(data) {
+ console.log(data);
+ if (data['success']) {
+ window.location.href = '/';
+ }
+ })
+ }
+ }
+ };
+
+ connectButton();
+ if (MetaMaskOnboarding.isMetaMaskInstalled()) {
+ window.ethereum.on('accountsChanged', (newAccounts) => {
+ window.location.href = '/disconnect';
+ });
+ }
+};
diff --git a/suchwowx/templates/includes/navbar.html b/suchwowx/templates/includes/navbar.html
index 12b2146..765690c 100644
--- a/suchwowx/templates/includes/navbar.html
+++ b/suchwowx/templates/includes/navbar.html
@@ -15,9 +15,9 @@
{% endif %}
New Meme
{% else %}
- Connect
+ Connect
{% endif %}
{% else %}
- Go Home
+ Go Home
{% endif %}
diff --git a/suchwowx/templates/includes/scripts.html b/suchwowx/templates/includes/scripts.html
index 5741a57..48fdd60 100644
--- a/suchwowx/templates/includes/scripts.html
+++ b/suchwowx/templates/includes/scripts.html
@@ -1,6 +1,10 @@
+{% if not current_user.is_authenticated %}
+
+
+
+{% endif %}
-
-
+
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
@@ -18,92 +22,3 @@
{% endif %}
{% endwith %}
-
-{% if not current_user.is_authenticated %}
-
-
-
-{% endif %}