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: nervos crosschain | bounties/hackathons #8550

Merged
merged 26 commits into from
Jun 7, 2021
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
7507614
backend work
chibie Mar 11, 2021
486a140
backend sync with explorer api
chibie Mar 16, 2021
36d5153
use manual payout type
chibie Apr 13, 2021
2bb56ed
Merge branch 'master' into feat/nervos-bounties
chibie Apr 14, 2021
bb756f4
create bounty flow
chibie Apr 14, 2021
d24f3a0
Merge branch 'feat/nervos-bounties' of github.com:gitcoinco/web into …
chibie Apr 14, 2021
100a12a
allow change of funder address
chibie Apr 14, 2021
83a4837
post to bounty change api
chibie Apr 14, 2021
4cae5bc
remove check for bounty eligibility
chibie Apr 14, 2021
e398506
defer funder address api call
chibie Apr 16, 2021
a9a6b99
remove bounty_owner_address from change_bounty
chibie Apr 16, 2021
bb43697
- use nervos_ext
chibie Apr 22, 2021
1d91ad1
restore block for manual payout for bounty
chibie Apr 26, 2021
c222402
write nervos extension + update fe flow
chibie Apr 26, 2021
bc509eb
tx sync
chibie May 9, 2021
9942639
reenact removal of manual web3_type
chibie May 9, 2021
04cef26
remove output status condition from sync
chibie May 12, 2021
ea41be6
prod ready + sync bug fix
chibie May 12, 2021
d1da29a
Merge branch 'master' into feat/nervos-bounties
chibie May 12, 2021
8174c4d
refactor + remove unused nervos_extension
chibie May 14, 2021
a880e78
refactor funder address validation
chibie May 14, 2021
55bc1fa
little fix
chibie May 14, 2021
320c506
bump address validation
chibie May 14, 2021
9af8126
remove unused function
chibie May 14, 2021
be98320
probable bug fix
chibie Jun 1, 2021
892e656
Merge branch 'master' into feat/nervos-bounties
chibie Jun 7, 2021
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/nervos.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
43 changes: 42 additions & 1 deletion app/assets/v2/js/pages/bounty_details2.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ Vue.mixin({
url = `https://explorer.rsk.co/tx/${txn}`;
break;

case 'CKB':
url = `https://explorer.nervos.org/transaction/${txn}`;
break;

case 'XDC':
url = `https://explorer.xinfin.network/tx/${txn}`;
break;
Expand Down Expand Up @@ -210,6 +214,10 @@ Vue.mixin({
url = `https://explorer.rsk.co/address/${address}`;
break;

case 'CKB':
url = `https://explorer.nervos.org/address/${address}`;
break;

case 'XDC':
url = `https://explorer.xinfin.network/addr/${address}`;
break;
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 @@ -443,6 +452,11 @@ Vue.mixin({
tenant = 'RSK';
break;

case 'CKB':
tenant = 'NERVOS';
vm.canChangeFunderAddress = true;
break;

case 'XDC':
tenant = 'XINFIN';
break;
Expand Down Expand Up @@ -754,7 +768,9 @@ Vue.mixin({
switch (fulfillment.payout_type) {
case 'qr':
case 'manual':
case 'nervos_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,29 @@ Vue.mixin({
vm.fulfillment_context.active_step = 'payout_amount';
break;
}
},
validateFunderAddress: function(token_name) {
let vm = this;
let hasError = false;

vm.errors = {};

switch (token_name) {
case 'CKB': {
const ADDRESS_REGEX = new RegExp('^(ckb){1}[0-9a-zA-Z]{43,92}$');
const isNervosValid = ADDRESS_REGEX.test(vm.bounty.bounty_owner_address);

if (!isNervosValid && !address.toLowerCase().startsWith('0x')) {
hasError = true;
}
}

// include validation for other tokens here
}

if (hasError) {
vm.$set(vm.errors, 'funderAddress', `Please enter a valid ${token_name} address`);
}
thelostone-mc marked this conversation as resolved.
Show resolved Hide resolved
}
},
computed: {
Expand Down Expand Up @@ -844,6 +883,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 +899,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
13 changes: 11 additions & 2 deletions app/assets/v2/js/pages/fulfill_bounty/token.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,20 +96,29 @@ const is_valid_address = (address) => {
}
return true;


case 'polkadot_ext':
if (address.toLowerCase().startsWith('0x')) {
return false;
}
return true;


case 'xinfin_ext':
if (!address.toLowerCase().startsWith('xdc')) {
return false;
}
return true;

case 'nervos_ext': {
const ADDRESS_REGEX = new RegExp('^(ckb){1}[0-9a-zA-Z]{43,92}$');
const isNervosValid = ADDRESS_REGEX.test(address);

if (isNervosValid || address.toLowerCase().startsWith('0x')) {
return true;
}

return false;
}

case 'qr':

if (token_name == 'BTC') {
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 @@ -170,6 +170,10 @@ Vue.mixin({
// harmony
type = 'harmony_ext';
break;
case '1995':
// nervos
type = 'nervos_ext';
break;
case '1001':
// algorand
type = 'algorand_ext';
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 @@ -210,6 +210,10 @@ Vue.mixin({
// harmony
type = 'harmony_ext';
break;
case '1995':
// nervos
type = 'nervos_ext';
break;
case '1001':
// algorand
type = 'algorand_ext';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ 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', 'nervos_ext', 'algorand_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():
Expand Down
3 changes: 3 additions & 0 deletions app/dashboard/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ class Bounty(SuperModel):
('harmony_ext', 'Harmony Ext'),
('rsk_ext', 'RSK Ext'),
('xinfin_ext', 'Xinfin Ext'),
('nervos_ext', 'Nervos Ext'),
('algorand_ext', 'Algorand Ext'),
('fiat', 'Fiat'),
('manual', 'Manual')
Expand Down Expand Up @@ -1415,6 +1416,7 @@ class BountyFulfillment(SuperModel):
('harmony_ext', 'harmony_ext'),
('rsk_ext', 'rsk_ext'),
('xinfin_ext', 'xinfin_ext'),
('nervos_ext', 'nervos_ext'),
('algorand_ext', 'algorand_ext'),
('manual', 'manual')
]
Expand All @@ -1432,6 +1434,7 @@ class BountyFulfillment(SuperModel):
('FILECOIN', 'FILECOIN'),
('RSK', 'RSK'),
('XINFIN', 'XINFIN'),
('NERVOS', 'NERVOS'),
('ALGORAND', 'ALGORAND'),
('OTHERS', 'OTHERS')
]
Expand Down
47 changes: 47 additions & 0 deletions app/dashboard/sync/nervos.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from django.utils import timezone

import requests
from dashboard.sync.helpers import record_payout_activity

HEADERS = {
'Content-Type': 'application/vnd.api+json',
'Accept': 'application/vnd.api+json'
}


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

if network == 'mainnet':
base_url = 'https://api.explorer.nervos.org/api/v1'
else:
base_url = 'https://api.explorer.nervos.org/testnet/api/v1'

explorer_url = f'{base_url}/transactions/{txnid}'
tip_block_number_url = f'{base_url}/statistics/tip_block_number'

tx_response = requests.get(explorer_url, headers=HEADERS)

if tx_response.status_code == 200:
tx_data = tx_response.json()['data']['attributes']
tip_block_number = requests.get(
tip_block_number_url, headers=HEADERS
).json()['data']['attributes']['tip_block_number']
confirmations = tip_block_number - int(tx_data['block_number'])

if confirmations > 0 and tx_data['tx_status'] == 'committed':
return True
else:
return False


def sync_nervos_payout(fulfillment):
if fulfillment.payout_tx_id and fulfillment.payout_tx_id != "0x0":
txn_status = get_nervos_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 === '1995'}">
<input type="radio" name="bounty_chain" id="1995_chain" value="1995" v-model="chainId"><img class="mr-2" src="{% static 'v2/images/chains/nervos.svg' %}" alt="" width="16"> Nervos
</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
5 changes: 5 additions & 0 deletions app/dashboard/templates/dashboard/hackathon/new_bounty.html
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,10 @@ <h1 class="text-center">Fund Prize</h1>
<input type="radio" name="bounty_chain" id="50_chain" value="50" v-model="chainId"><img class="mr-2" src="{% static 'v2/images/chains/xinfin.svg' %}" alt="" width="16"> Xinfin
</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 === '1995'}">
<input type="radio" name="bounty_chain" id="1995_chain" value="1995" v-model="chainId"><img class="mr-2" src="{% static 'v2/images/chains/nervos.svg' %}" alt="" width="16"> Nervos
</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 === '1001'}">
<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>
Expand All @@ -195,6 +199,7 @@ <h1 class="text-center">Fund Prize</h1>
<input type="radio" name="bounty_chain" id="717171_chain" value="717171" v-model="chainId"> Other
</label>


</div>
<div class="text-danger" v-if="errors.chainId && !form.chainId">
[[errors.chainId]]
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 @@ -47,6 +47,7 @@
from dashboard.sync.eth import sync_eth_payout
from dashboard.sync.filecoin import sync_filecoin_payout
from dashboard.sync.harmony import sync_harmony_payout
from dashboard.sync.nervos import sync_nervos_payout
from dashboard.sync.polkadot import sync_polkadot_payout
from dashboard.sync.rsk import sync_rsk_payout
from dashboard.sync.xinfin import sync_xinfin_payout
Expand Down Expand Up @@ -610,6 +611,9 @@ def sync_payout(fulfillment):
elif fulfillment.payout_type == 'xinfin_ext':
sync_xinfin_payout(fulfillment)

elif fulfillment.payout_type == 'nervos_ext':
sync_nervos_payout(fulfillment)

elif fulfillment.payout_type == 'algorand_ext':
sync_algorand_payout(fulfillment)

Expand Down
Loading