getting some chain syncing going, still very rough

main
lza_menace 2 years ago
parent c6289bd816
commit 19738fccc5

3
.gitignore vendored

@ -132,9 +132,6 @@ dmypy.json
data/
go-ipfs/
avalanchego-v1.7.3
*jpg
*png
*svg
*mp4
*webp
*mkv

@ -1,6 +1,11 @@
import requests
from flask import Blueprint
from secrets import token_urlsafe
from suchwowx.factory import db
from suchwowx.helpers import get_eth_contract
from suchwowx.models import Meme, User
from suchwowx import config
bp = Blueprint('cli', 'cli', cli_group=None)
@ -9,3 +14,49 @@ bp = Blueprint('cli', 'cli', cli_group=None)
@bp.cli.command('init')
def init():
db.create_all()
@bp.cli.command('sync-avax')
def sync_avax():
"""
Synchronize your local database with the tokens minted on Avalanche blockchain.
"""
contract = get_eth_contract()
total_supply = contract.functions.totalSupply().call()
# walk backwards through all tokens at top of supply
# until you've accounted for the last known
for i in range(total_supply, 0, -1):
# first get metadata ipfs hash
deets = contract.functions.tokenMeme(i).call()
try:
meme_exists = Meme.query.filter(Meme.meta_ipfs_hash == deets[5]).first() # noqa
user_exists = User.query.filter(User.public_address == deets[4].lower()).first() # noqa
if meme_exists:
if not meme_exists.minted:
meme_exists.minted = True
db.session.commit()
print(f'[+] Marked existing meme {meme_exists.id} as minted')
else:
print(deets)
if not user_exists:
user_exists = User(
public_address=deets[4].lower()
)
db.session.add(user_exists)
db.session.commit()
user_exists.handle = f'anon{user_exists.id}-{token_urlsafe(6)}'
db.session.commit()
print(f'[+] Created user {user_exists.handle}')
res = requests.get(f'{config.IPFS_SERVER}/ipfs/{deets[5]}', timeout=30).json()
meme = Meme(
title=res['name'],
description=res['description'],
user_id=user_exists.id,
meta_ipfs_hash=deets[5],
meme_ipfs_hash=res['image'].split('ipfs://')[1],
minted=True
)
db.session.add(meme)
db.session.commit()
print(f'[+] Added new meme {meme.id}')
except Exception as e:
print(e)

@ -8,6 +8,7 @@ SECRET_KEY = getenv('SECRET_KEY', 'yyyyyyyyyyyyy')
DATA_FOLDER = getenv('DATA_FOLDER', '/path/to/uploads')
SERVER_NAME = getenv('SERVER_NAME', '127.0.0.1:5000')
IPFS_SERVER = getenv('IPFS_SERVER', 'http://127.0.0.1:8080')
AVAX_RPC = getenv('AVAX_RPC', 'https://api.avax-test.network/ext/bc/C/rpc')
# Cache
CACHE_HOST = getenv('CACHE_HOST', 'localhost')

@ -10,7 +10,7 @@ from suchwowx import config
db = SQLAlchemy()
w3 = Web3(Web3.HTTPProvider('http://127.0.0.1:9650')) # noqa
w3 = Web3(Web3.HTTPProvider(config.AVAX_RPC))
def setup_db(app: Flask, db: SQLAlchemy = db):

@ -6,6 +6,19 @@ from suchwowx.factory import w3
from suchwowx import config
def get_eth_contract():
"""
Return a web3 contract object with the currently
deployed SuchWowX smart contract.
"""
contract_abi = config.CONTRACT_ABI
contract_address = w3.toChecksumAddress(config.CONTRACT_ADDRESS)
return w3.eth.contract(
address=contract_address,
abi=contract_abi
)
def verify_signature(message, signature, public_address):
msg = encode_defunct(text=message)
recovered = w3.eth.account.recover_message(msg, signature=signature)

@ -21,15 +21,7 @@ def index():
memes = Meme.query.filter(
Meme.approved == True
).order_by(Meme.create_date.desc())
w3 = Web3(Web3.HTTPProvider('http://127.0.0.1:9650'))
contract_address = w3.toChecksumAddress(config.CONTRACT_ADDRESS)
contract_abi = config.CONTRACT_ABI
contract = w3.eth.contract(
address=contract_address,
abi=contract_abi
)
# total_supply = contract.functions.totalSupply().call()
return render_template('index.html', memes=memes, contract=contract)
return render_template('index.html', memes=memes)
@bp.route('/mod')

@ -27,3 +27,8 @@
.wrap {
word-wrap: break-word;
}
.mintedAVAX {
background-color: rgba(242,37,52,.2);
border: 2px solid rgba(243,37,52,1);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

@ -1,8 +1,9 @@
{# expects meme var #}
<div class="card">
<div class="card {% if meme.minted %}mintedAVAX{% endif %}">
<div class="card-image">
<figure class="image">
<a href="{{ url_for('meme.show', meme_id=meme.id) }}">
{% if meme.file_name %}
{% if meme.file_name.endswith('mp4') %}
<video class="img-fluid" {% if not request.MOBILE %}autoplay{% else %}controls{% endif %} muted loop>
<source src="{{ url_for('meta.uploaded_file', filename=meme.file_name) }}" type="video/mp4">
@ -11,6 +12,9 @@
{% else %}
<img alt="{{ meme.title }}" src="{{ url_for('meta.uploaded_file', filename=meme.file_name) }}" width="200px" class="img-fluid" style="" />
{% endif %}
{% else %}
<img alt="{{ meme.title }}" src="{{ config.IPFS_SERVER }}/ipfs/{{ meme.meme_ipfs_hash }}" width="200px" class="img-fluid" style="" />
{% endif %}
</a>
</figure>
</div>

@ -19,6 +19,7 @@
<div id="screen">
<div class="screen">
{% if meme.file_name %}
{% if meme.file_name.endswith('mp4') %}
<video style="max-height: 60vh!important;max-width:100%;" {% if not request.MOBILE %}autoplay{% else %}controls{% endif %} muted loop>
<source src="{{ meme_url }}" type="video/mp4">
@ -27,10 +28,14 @@
{% else %}
<img src="{{ meme_url }}" id="memeImage" />
{% endif %}
{% endif %}
<br/>
<p>Title: <strong>{{ meme.title }}</strong></p>
<p>Description: <strong>{{ meme.description }}</strong></p>
<p>Poster Address: <a href="{{ url_for('user.show', handle=meme.user.handle) }}">{{ meme.user.handle }}</a></p>
{% if meme.user.wownero_address %}
<p>Wownero Address: <strong><span style="word-wrap: break-word">{{ meme.user.wownero_address }}</strong></p>
{% endif %}
{% if meme.meta_ipfs_hash %}
<p>Meta IPFS: <a href="{{ meta_url }}" target=_self up-preload up-follow=".container">{{ meme.meta_ipfs_hash }}</a></p>
{% endif %}
@ -42,12 +47,14 @@
<div class="modal-background"></div>
<div class="modal-card">
<header class="modal-card-head">
<p class="modal-card-title">Modal title</p>
<button class="delete" aria-label="close"></button>
<p class="modal-card-title">Tip meme in WOW</p>
<button class="delete" aria-label="close" onclick="closeModal('profileModal')" id="closeModal"></button>
</header>
<section class="modal-card-body">
<p style="word-wrap: break-word;">Wownero Address: {{ meme.user.wownero_address }}</p>
<p style="word-wrap: break-word;">Wownero Address: <span id="wowneroAddress">{{ meme.user.wownero_address | default('?') }}</span></p>
</section>
<footer class="modal-card-foot">
</footer>
</div>
</div>
{% if not meme.approved %}
@ -63,19 +70,19 @@
{% else %}
<br/>
<div id="tipButtons" class="columns" style="display:none;">
<div class="column">
<!-- <div class="column">
<a class="button is-info is-12 column" onclick="tipAVAX()">Tip AVAX</a>
</div>
<div class="column">
<a class="button is-info is-12 column" onclick="tipWOWX()">Tip WOWX</a>
</div>
</div> -->
<div class="column">
<a class="button is-info is-12 column" onclick="tipWOW()">Tip WOW</a>
<a class="button is-info is-12 column" onclick="tipWOW()">Tip</a>
</div>
</div>
<div id="mintButton" class="columns" style="display:none;">
<div class="column">
<a class="button is-danger is-12 column" onclick="mint()">Mint</a>
<a class="button is-danger is-12 column" onclick="mint()" id="mintButtonLoading">Mint</a>
</div>
</div>
{% endif %}
@ -96,8 +103,23 @@
} else {
document.getElementById('mintButton').style.display = "flex";
}
try {
_walletAddress = w3.utils.toChecksumAddress('{{ meme.user.public_address }}');
const userProfile = await contract.methods.userProfile(_walletAddress).call();
console.log(userProfile)
if (userProfile.wowneroAddress){document.getElementById('wowneroAddress').innerHTML = userProfile.wowneroAddress};
} catch(e) {
console.log(e);
}
});
async function tipWOW() {
document.getElementById('profileModal').classList.add('is-active');
document.getElementById('closeModal').onclick = () => {
document.getElementById('profileModal').classList.remove('is-active');
}
}
async function tipAVAX() {
const tokenId = await getTokenID('{{ meme.meta_ipfs_hash }}');
const walletAddress = await getMetamaskAccount();
@ -110,7 +132,7 @@
notif(`Tipping meme "{{ meme.id | shorten_address }}" by "{{ meme.user.handle }} ({{ meme.user.public_address | shorten_address }})" to the Avalanche blockchain.`, 'info');
let res = await contract.methods.tipAVAX(tokenId).send({
from: walletAddress,
value: 1000000000000000,
value: 1,
gasPrice: gasPrice,
gas: gasLimit
});
@ -126,6 +148,7 @@
notif('Already minted!', 'warning');
return
}
document.getElementById('mintButtonLoading').classList.add('is-active');
const walletAddress = await getMetamaskAccount();
const gasPrice = await w3.eth.getGasPrice();
const gasLimit = await contract.methods.mint("{{ meme.meta_ipfs_hash }}", "{{ meme.user.public_address }}").estimateGas({from: walletAddress}, function(err, gas){
@ -140,6 +163,7 @@
gas: gasLimit
});
console.log(res);
document.getElementById('mintButtonLoading').classList.remove('is-active');
window.location.href = "";
} catch(e) {
notif(e.message, 'warning');

Loading…
Cancel
Save