Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: sia crosschain | bounties/hackathons #8899

Merged
merged 8 commits into from
Jun 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/assets/v2/images/chains/sia.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 31 additions & 1 deletion app/assets/v2/js/pages/bounty_details2.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,10 @@ Vue.mixin({
url = `https://algoexplorer.io/tx/${txn}`;
break;

case 'SC':
url = `https://siastats.info/navigator?search=${txn}`;
break;

default:
url = `https://etherscan.io/tx/${txn}`;

Expand Down Expand Up @@ -220,6 +224,10 @@ Vue.mixin({
url = `https://algoexplorer.io/tx/${address}`;
break;

case 'SC':
url = `https://siastats.info/navigator?search=${address}`;
break;

default:
url = `https://etherscan.io/address/${address}`;
}
Expand Down Expand Up @@ -392,6 +400,7 @@ Vue.mixin({
},
getTenant: function(token_name, web3_type) {
let tenant;
let vm = this;

if (web3_type == 'manual') {
tenant = 'OTHERS';
Expand Down Expand Up @@ -453,6 +462,11 @@ Vue.mixin({
tenant = 'ALGORAND';
break;

case 'SC':
tenant = 'SIA';
vm.canChangeFunderAddress = true;
break;

default:
tenant = 'ETH';
}
Expand Down Expand Up @@ -754,7 +768,9 @@ Vue.mixin({
switch (fulfillment.payout_type) {
case 'qr':
case 'manual':
case 'sia_ext':
vm.fulfillment_context.active_step = 'check_wallet_owner';
vm.getTenant(vm.bounty.token_name, fulfillment.payout_type);
break;

case 'fiat':
Expand Down Expand Up @@ -803,6 +819,18 @@ Vue.mixin({
vm.fulfillment_context.active_step = 'payout_amount';
break;
}
},
validateFunderAddress: function(token_name) {
let vm = this;
let hasError = false;

vm.errors = {};

// include validation for tokens here - switch statement

if (hasError) {
vm.$set(vm.errors, 'funderAddress', `Please enter a valid ${token_name} address`);
}
}
},
computed: {
Expand Down Expand Up @@ -844,6 +872,7 @@ if (document.getElementById('gc-bounty-detail')) {
el: '#gc-bounty-detail',
data() {
return {
errors: {},
loadingState: loadingState['loading'],
bounty: bounty,
url: url,
Expand All @@ -859,7 +888,8 @@ if (document.getElementById('gc-bounty-detail')) {
inputBountyOwnerAddress: bounty.bounty_owner_address,
contxt: document.contxt,
quickLinks: [],
pollInterval: null
pollInterval: null,
canChangeFunderAddress: false
};
},
mounted() {
Expand Down
4 changes: 4 additions & 0 deletions app/assets/v2/js/pages/hackathon_new_bounty.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,10 @@ Vue.mixin({
// algorand
type = 'algorand_ext';
break;
case '1935':
// sia
type = 'sia_ext';
break;
case '666':
// paypal
type = 'fiat';
Expand Down
4 changes: 4 additions & 0 deletions app/assets/v2/js/pages/new_bounty.js
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,10 @@ Vue.mixin({
// algorand
type = 'algorand_ext';
break;
case '1935':
// sia
type = 'sia_ext';
break;
case '666':
// paypal
type = 'fiat';
Expand Down
1 change: 0 additions & 1 deletion app/dashboard/management/commands/cleanup_earnings.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from django.contrib.contenttypes.models import ContentType

from django.core.management.base import BaseCommand

from dashboard.models import Earning
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,12 @@ def handle(self, *args, **options):
)

# Extensions
ext_payout_types= ['web3_modal', 'polkadot_ext', 'harmony_ext', 'binance_ext', 'rsk_ext', 'xinfin_ext', 'algorand_ext']
ext_payout_types= ['web3_modal', 'polkadot_ext', 'harmony_ext', 'binance_ext', 'rsk_ext', 'xinfin_ext', 'algorand_ext', 'sia_ext']
for ext_payout_type in ext_payout_types:
ext_pending_fulfillments = pending_fulfillments.filter(payout_type=ext_payout_type)
for fulfillment in ext_pending_fulfillments.all():
sync_payout(fulfillment)


# QR
qr_pending_fulfillments = pending_fulfillments.filter(payout_type='qr')
if qr_pending_fulfillments:
Expand Down
3 changes: 3 additions & 0 deletions app/dashboard/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ class Bounty(SuperModel):
('rsk_ext', 'RSK Ext'),
('xinfin_ext', 'Xinfin Ext'),
('algorand_ext', 'Algorand Ext'),
('sia_ext', 'Sia Ext'),
('fiat', 'Fiat'),
('manual', 'Manual')
)
Expand Down Expand Up @@ -1416,6 +1417,7 @@ class BountyFulfillment(SuperModel):
('rsk_ext', 'rsk_ext'),
('xinfin_ext', 'xinfin_ext'),
('algorand_ext', 'algorand_ext'),
('sia_ext', 'sia_ext'),
('manual', 'manual')
]

Expand All @@ -1433,6 +1435,7 @@ class BountyFulfillment(SuperModel):
('RSK', 'RSK'),
('XINFIN', 'XINFIN'),
('ALGORAND', 'ALGORAND'),
('SIA', 'SIA'),
('OTHERS', 'OTHERS')
]

Expand Down
74 changes: 74 additions & 0 deletions app/dashboard/sync/sia.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
from django.utils import timezone

import requests
from dashboard.sync.helpers import record_payout_activity, txn_already_used

BASE_URL = 'https://siastats.info:3500/navigator-api'


def find_txn_on_sia_explorer(fulfillment):
token_name = fulfillment.token_name

funderAddress = fulfillment.funder_address
amount = fulfillment.payout_amount

if token_name != 'SC':
return None

url = f'{BASE_URL}/hash/{funderAddress}'

response = requests.get(url).json()

if response:
last100_txns = response[1]['last100Transactions']
if response[0]['Type'] == 'address' and last100_txns:
for txn in last100_txns:
if (
txn['TxType'] == 'ScTx'
and txn['ScChange'] < 0
and abs(txn['ScChange']) / 10 ** 24 == amount / 10 ** 24
and not txn_already_used(txn['MasterHash'], token_name)
):
return txn
return None


def get_sia_txn_status(txnid, network='mainnet'):
if not txnid:
return None

tx_url = f'{BASE_URL}/hash/{txnid}'
stats_url = f'{BASE_URL}/status'

tx_response = requests.get(tx_url).json()

if tx_response:
last_block = requests.get(stats_url).json()[0]['lastblock'] # or consensusblock ?

confirmations = last_block - tx_response[1]['Height']

if (
tx_response[0]['Type'] == 'ScTx'
and tx_response[0]['MasterHash'].strip() == txnid
and confirmations > 0
):
return True
else:
return False


def sync_sia_payout(fulfillment):
if not fulfillment.payout_tx_id or fulfillment.payout_tx_id == "0x0":
txn = find_txn_on_sia_explorer(fulfillment)
if txn:
fulfillment.payout_tx_id = txn['MasterHash']
fulfillment.save()

if fulfillment.payout_tx_id and fulfillment.payout_tx_id != "0x0":
txn_status = get_sia_txn_status(fulfillment.payout_tx_id)
if txn_status:
fulfillment.payout_status = 'done'
fulfillment.accepted_on = timezone.now()
fulfillment.accepted = True
record_payout_activity(fulfillment)
fulfillment.save()
50 changes: 33 additions & 17 deletions app/dashboard/templates/bounty/details2.html
Original file line number Diff line number Diff line change
Expand Up @@ -530,14 +530,14 @@ <h5 class="font-body font-weight-semibold">{% trans "SUBMISSIONS" %}</h5>
<p>
This bounty can only be paid out from the same wallet address that funded it.
</p>
<br>
<p class="mb-4 font-weight-bold">
Make sure you’re paying out from this address

<span v-if="fulfillment.payout_type == 'manual'">[[ bounty.bounty_owner_address | truncateHash ]]</span>
<a v-else class="font-weight-bold" :href="getAddressURL(fulfillment.token_name, bounty.bounty_owner_address)" target="_blank">
[[ bounty.bounty_owner_address ]]
</a>

</p>
<button class="btn btn-primary btn-block py-3 btn-lg mt-4"
v-on:click="goToStep('payout_amount', 'check_wallet_owner')"
Expand Down Expand Up @@ -613,7 +613,7 @@ <h5 class="font-body font-weight-semibold">{% trans "SUBMISSIONS" %}</h5>
<button class="btn btn-primary btn-block py-3 btn-lg mt-3"
@click="fulfillmentComplete(fulfillment.payout_type, fulfillment.pk, $event)"
>
I have Paid
I have paid
</button>

<p class="font-subheader mt-4 mb-0 text-center">
Expand Down Expand Up @@ -645,29 +645,45 @@ <h5 class="font-body font-weight-semibold">{% trans "SUBMISSIONS" %}</h5>

<!-- STEP : WALLET OWNER CHECK -->
<div id="check_wallet_owner" v-if="fulfillment_context.active_step == 'check_wallet_owner'">

<p>
<div class="funder-address-container mt-4" v-if="canChangeFunderAddress">
<label class="font-caption letter-spacing text-black-60 text-uppercase" for="funderAddress">Funder Address</label>
<input v-model="bounty.bounty_owner_address" @input="validateFunderAddress(bounty.token_name)" name="funderAddress" id="funderAddress" class="form__input" type="text" placeholder="Address with which the bounty will be paid out">
<div class="text-danger" v-if="errors.funderAddress">
[[ errors.funderAddress ]]
</div>
</div>
<p v-else>
This bounty can only be paid out from the same wallet address that funded it.
</p>
<p class="mb-4">
<br>
<p class="mb-4 font-weight-bold">
Make sure you’re paying out from this address

<span v-if="fulfillment.payout_type == 'manual'">[[ bounty.bounty_owner_address | truncateHash ]]</span>
<span v-if="fulfillment.payout_type == 'manual' && !canChangeFunderAddress">[[ bounty.bounty_owner_address | truncateHash ]]</span>
<a v-else class="font-weight-bold" :href="getAddressURL(fulfillment.token_name, bounty.bounty_owner_address)" target="_blank">
[[ bounty.bounty_owner_address ]]
</a>

</p>
<button class="btn btn-primary btn-block py-3 btn-lg mt-4"
v-on:click="goToStep('payout_amount', 'check_wallet_owner', 'access_to_wallet')"
>
Yes, I understand
</button>
<p class="font-subheader mt-4 mb-0 text-center">
<a href="#" v-on:click="goToStep('payout_amount', 'check_wallet_owner', 'no_access_to_wallet')">
I don’t have access to this address
</a>
</p>
<div v-if="canChangeFunderAddress">
<button :disabled="errors.funderAddress" class="btn btn-primary btn-block py-3 btn-lg mt-4"
v-on:click="goToStep('payout_amount', 'check_wallet_owner')"
>
Yes, I understand
</button>
</div>
<div v-else>
<button class="btn btn-primary btn-block py-3 btn-lg mt-4"
v-on:click="goToStep('payout_amount', 'check_wallet_owner', 'access_to_wallet')"
>
Yes, I understand
</button>
<p class="font-subheader mt-4 mb-0 text-center">
<a href="#" v-on:click="goToStep('payout_amount', 'check_wallet_owner', 'no_access_to_wallet')">
I don’t have access to this address
</a>
</p>
</div>

</div>

Expand Down Expand Up @@ -801,7 +817,7 @@ <h5 class="font-body font-weight-semibold">{% trans "SUBMISSIONS" %}</h5>
<button class="btn btn-primary btn-block py-3 btn-lg mt-3"
@click="fulfillmentComplete(fulfillment.payout_type, fulfillment.pk, $event)"
>
I have Paid
I have paid
</button>

<p class="font-subheader mt-4 mb-0 text-center">
Expand Down
4 changes: 4 additions & 0 deletions app/dashboard/templates/bounty/new_bounty.html
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ <h1 class="text-center">Fund Issue</h1>
</label>

{% if is_staff %}
<label class="btn btn-radio chain-btn d-flex align-items-center mr-2 mb-2 font-weight-bold py-2 px-4" :class="{'active': chainId === '1935'}">
<input type="radio" name="bounty_chain" id="1935_chain" value="1935" v-model="chainId"><img class="mr-2" src="{% static 'v2/images/chains/sia.svg' %}" alt="" width="16"> Sia
</label>

<label class="btn btn-radio chain-btn d-flex align-items-center mr-2 mb-2 font-weight-bold py-2 px-4" :class="{'active': chainId === '717171'}">
<input type="radio" name="bounty_chain" id="717171_chain" value="717171" v-model="chainId"> Other
</label>
Expand Down
4 changes: 4 additions & 0 deletions app/dashboard/templates/dashboard/hackathon/new_bounty.html
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,10 @@ <h1 class="text-center">Fund Prize</h1>
<input type="radio" name="bounty_chain" id="1001_chain" value="1001" v-model="chainId"><img class="mr-2" src="{% static 'v2/images/chains/algorand.svg' %}" alt="" width="16"> Algorand
</label>

<label class="btn btn-radio chain-btn d-flex align-items-center mr-2 mb-2 font-weight-bold py-2 px-4" :class="{'active': chainId === '1935'}">
<input type="radio" name="bounty_chain" id="1935_chain" value="1935" v-model="chainId"><img class="mr-2" src="{% static 'v2/images/chains/sia.svg' %}" alt="" width="16"> Sia
</label>

<label class="btn btn-radio chain-btn d-flex align-items-center mr-2 mb-2 font-weight-bold py-2 px-4" :class="{'active': chainId === '717171'}">
<input type="radio" name="bounty_chain" id="717171_chain" value="717171" v-model="chainId"> Other
</label>
Expand Down
1 change: 0 additions & 1 deletion app/dashboard/templatetags/bundle.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

from bs4 import BeautifulSoup


register = template.Library()


Expand Down
4 changes: 4 additions & 0 deletions app/dashboard/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
from dashboard.sync.harmony import sync_harmony_payout
from dashboard.sync.polkadot import sync_polkadot_payout
from dashboard.sync.rsk import sync_rsk_payout
from dashboard.sync.sia import sync_sia_payout
from dashboard.sync.xinfin import sync_xinfin_payout
from dashboard.sync.zil import sync_zil_payout
from ens.auto import ns
Expand Down Expand Up @@ -613,6 +614,9 @@ def sync_payout(fulfillment):
elif fulfillment.payout_type == 'algorand_ext':
sync_algorand_payout(fulfillment)

elif fulfillment.payout_type == 'sia_ext':
sync_sia_payout(fulfillment)


def get_bounty_id(issue_url, network):
issue_url = normalize_url(issue_url)
Expand Down
Loading