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

casper crosschain | bounties/hackathons #9291

Merged
merged 24 commits into from
Jul 26, 2021
Merged
Show file tree
Hide file tree
Changes from 23 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/app/bundle_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from cacheops import cached_as
from perftools.models import JSONStore


@cached_as(JSONStore.objects.filter(view='bundleTags', key='bundleTags'), timeout=60)
def templateTags():

Expand Down
1 change: 1 addition & 0 deletions app/app/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
url('^api/v1/bounty/fulfill', dashboard.views.fulfill_bounty_v1, name='fulfill_bounty_v1'),
path('api/v1/bounty/<int:bounty_id>/close', dashboard.views.close_bounty_v1, name='close_bounty_v1'),
path('api/v1/bounty/payout/<int:fulfillment_id>', dashboard.views.payout_bounty_v1, name='payout_bounty_v1'),
path('api/v1/reverse-proxy/<str:tenant>', dashboard.views.reverse_proxy_rpc_v1, name='payout_tx_forwarder_v1'),
re_path(r'.*api/v0.1/video/presence$', townsquare.views.video_presence, name='video_presence'),

# inbox
Expand Down
1 change: 1 addition & 0 deletions app/assets/v2/images/chains/casper.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions app/assets/v2/js/lib/casper/casper_js_sdk.js

Large diffs are not rendered by default.

93 changes: 93 additions & 0 deletions app/assets/v2/js/pages/bounty_detail/casper_extension.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
const payWithCasperExtension = async(fulfillment_id, to_address, vm, modal) => {

const amount = vm.fulfillment_context.amount;
const token_name = vm.bounty.token_name;
const tenant = vm.getTenant(token_name, vm.bounty.web3_type);

const { CasperClient, DeployUtil, PublicKey, Signer } = casper;
const casperClient = new CasperClient(`/api/v1/reverse-proxy/${tenant}`);

const isConnected = await Signer.isConnected();

if (!isConnected) {
try {
Signer.sendConnectionRequest();
} catch (e) {
_alert({ message: gettext('Please download or enable CasperLabs Signer extension.') }, 'danger');
chibie marked this conversation as resolved.
Show resolved Hide resolved
return;
}
}

const selectedAddress = await Signer.getActivePublicKey();

const paymentAmount = 10000; // for native-transfers the payment price is fixed
const id = fulfillment_id;
const gasPrice = 1; // gasPrice for native transfers can be set to 1

// time that the deploy will remain valid for, in milliseconds
// the default value is 1800000 ms (30 minutes)
const ttl = 1800000;
chibie marked this conversation as resolved.
Show resolved Hide resolved

const fromPublicKey = PublicKey.fromHex(selectedAddress);
const toPublicKey = PublicKey.fromHex(to_address);

let deployParams = new DeployUtil.DeployParams(fromPublicKey, 'casper', gasPrice, ttl);

const session = DeployUtil.ExecutableDeployItem.newTransfer(
amount * 10 ** vm.decimals,
toPublicKey,
null,
id
);

const payment = DeployUtil.standardPayment(paymentAmount);
const deploy = DeployUtil.makeDeploy(deployParams, session, payment);
const deployJson = DeployUtil.deployToJson(deploy);

const signedDeployJson = await Signer.sign(deployJson, selectedAddress, to_address);
const signedDeploy = DeployUtil.deployFromJson(signedDeployJson);

try {
const deployHash = await casperClient.putDeploy(signedDeploy);

callback(null, selectedAddress, deployHash);
} catch (e) {
modal.closeModal();
callback(e);
}

function callback(error, from_address, txn) {
if (error) {
_alert({ message: gettext('Unable to payout bounty due to: ' + error) }, 'danger');
console.log(error);
} else {

const payload = {
payout_type: 'casper_ext',
tenant: 'CASPER',
amount: amount,
token_name: token_name,
funder_address: from_address,
payout_tx_id: txn
};

modal.closeModal();
const apiUrlBounty = `/api/v1/bounty/payout/${fulfillment_id}`;

fetchData(apiUrlBounty, 'POST', payload).then(response => {
if (200 <= response.status && response.status <= 204) {
vm.fetchBounty();
_alert('Payment Successful', 'success');

} else {
_alert('Unable to make payout bounty. Please try again later', 'danger');
console.error(`error: bounty payment failed with status: ${response.status} and message: ${response.message}`);
}
}).catch(function(error) {
_alert('Unable to make payout bounty. Please try again later', 'danger');
console.log(error);
});
}
}
};

17 changes: 17 additions & 0 deletions app/assets/v2/js/pages/bounty_details2.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ Vue.mixin({
url = `https://tzkt.io/${txn}`;
break;

case 'CSPR':
url = `https://casperstats.io/tx/${txn}`;
break;

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

Expand Down Expand Up @@ -244,6 +248,10 @@ Vue.mixin({
url = `https://tzkt.io/${address}/operations/`;
break;

case 'CSPR':
url = `https://casperstats.io/address/${address}`;
break;

default:
url = `https://etherscan.io/address/${address}`;
}
Expand Down Expand Up @@ -492,6 +500,10 @@ Vue.mixin({
tenant = 'TEZOS';
break;

case 'CSPR':
tenant = 'CASPER';
break;

default:
tenant = 'ETH';
}
Expand Down Expand Up @@ -589,6 +601,10 @@ Vue.mixin({
case 'tezos_ext':
payWithTezosExtension(fulfillment_id, fulfiller_address, vm, modal);
break;

case 'casper_ext':
payWithCasperExtension(fulfillment_id, fulfiller_address, vm, modal);
break;
}
},
closeBounty: function() {
Expand Down Expand Up @@ -809,6 +825,7 @@ Vue.mixin({
case 'xinfin_ext':
case 'algorand_ext':
case 'tezos_ext':
case 'casper_ext':
vm.fulfillment_context.active_step = 'payout_amount';
break;
}
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 @@ -186,6 +186,10 @@ Vue.mixin({
// tezos
type = 'tezos_ext';
break;
case '270895':
// casper
type = 'casper_ext';
break;
case '666':
// paypal
type = 'fiat';
Expand Down
14 changes: 14 additions & 0 deletions app/assets/v2/js/pages/new_bounty.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,16 @@ Vue.mixin({
break;
}

case '270895': {
// casper
let addr = vm.form.funderAddress;

if (!addr.toLowerCase().startsWith('01') && !addr.toLowerCase().startsWith('02')) {
isValid = false;
}
break;
}

// include validation for other chains here
}

Expand Down Expand Up @@ -255,6 +265,10 @@ Vue.mixin({
// tezos
type = 'tezos_ext';
break;
case '270895':
// casper
type = 'casper_ext';
break;
case '666':
// paypal
type = 'fiat';
Expand Down
2 changes: 1 addition & 1 deletion app/dashboard/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from django.utils.safestring import mark_safe

from adminsortable2.admin import SortableInlineAdminMixin
from perftools.management.commands import create_page_cache

from .models import (
Activity, Answer, BlockedIP, BlockedURLFilter, BlockedUser, Bounty, BountyEvent, BountyFulfillment, BountyInvites,
Expand All @@ -35,7 +36,6 @@
TransactionHistory, TribeMember, TribesSubscription, UserAction, UserVerificationModel,
)

from perftools.management.commands import create_page_cache

class BountyEventAdmin(admin.ModelAdmin):
list_display = ['created_on', '__str__', 'event_type']
Expand Down
3 changes: 1 addition & 2 deletions app/dashboard/management/commands/bundle.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@
from django.template import Context, Template
from django.template.loaders.app_directories import get_app_template_dirs

from dashboard.templatetags.bundle import render

from app.bundle_context import context, templateTags
from dashboard.templatetags.bundle import render


def rmdir(loc, depth=1):
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', 'nervos_ext', 'algorand_ext', 'sia_ext', 'tezos_ext']
ext_payout_types= ['web3_modal', 'polkadot_ext', 'harmony_ext', 'binance_ext', 'rsk_ext', 'xinfin_ext', 'nervos_ext', 'algorand_ext', 'sia_ext', 'tezos_ext', 'casper_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):
('algorand_ext', 'Algorand Ext'),
('sia_ext', 'Sia Ext'),
('tezos_ext', 'Tezos Ext'),
('casper_ext', 'Casper Ext'),
('fiat', 'Fiat'),
('manual', 'Manual')
)
Expand Down Expand Up @@ -1410,6 +1411,7 @@ class BountyFulfillment(SuperModel):
('algorand_ext', 'algorand_ext'),
('sia_ext', 'sia_ext'),
('tezos_ext', 'tezos_ext'),
('casper_ext', 'casper_ext'),
('manual', 'manual')
]

Expand All @@ -1430,6 +1432,7 @@ class BountyFulfillment(SuperModel):
('ALGORAND', 'ALGORAND'),
('SIA', 'SIA'),
('TEZOS', 'TEZOS'),
('CASPER', 'CASPER'),
('OTHERS', 'OTHERS')
]

Expand Down
4 changes: 0 additions & 4 deletions app/dashboard/sync/binance.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,6 @@ def get_binance_txn_status(fulfillment):
'params': [ txnid ]
}

headers = {
'Host': 'gitcoin.co'
zlsgh marked this conversation as resolved.
Show resolved Hide resolved
}

binance_response = requests.post(binance_url, json=data).json()

result = binance_response['result']
Expand Down
64 changes: 64 additions & 0 deletions app/dashboard/sync/casper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import logging

from django.utils import timezone

import requests
from dashboard.sync.helpers import record_payout_activity

logger = logging.getLogger(__name__)


def get_casper_txn_status(fulfillment):
txnid = fulfillment.payout_tx_id
token_name = fulfillment.token_name
funderAddress = fulfillment.funder_address
amount = fulfillment.payout_amount
payeeAddress = fulfillment.fulfiller_address

if token_name != 'CSPR' or not txnid:
return None

try:
data = {
'id': 0,
'jsonrpc': '2.0',
'method': 'info_get_deploy',
'params': [ txnid ]
}

casper_response = requests.post('http://3.142.224.108:7777/rpc', json=data).json()
chibie marked this conversation as resolved.
Show resolved Hide resolved

result = casper_response['result']

if result:
transfer_args = result["deploy"]["session"]["Transfer"]["args"]
if (
result["deploy"]["hash"] == txnid
and result["deploy"]["header"]["account"] == funderAddress
thelostone-mc marked this conversation as resolved.
Show resolved Hide resolved
and float([
arg for arg in transfer_args if arg[0] == 'amount'
][0][1]['parsed']) == float(amount) * 10 ** 9
):
if result["execution_results"][0]["result"].get("Success", False) != False:
return 'success'
return 'expired'

except Exception as e:
logger.error(f'error: get_casper_txn_status - {e}')

return None


def sync_casper_payout(fulfillment):
if fulfillment.payout_tx_id:
txn_status = get_casper_txn_status(fulfillment)

if txn_status == 'success':
fulfillment.payout_status = 'done'
fulfillment.accepted_on = timezone.now()
fulfillment.accepted = True
record_payout_activity(fulfillment)
elif txn_status == 'expired':
fulfillment.payout_status = 'expired'

fulfillment.save()
4 changes: 1 addition & 3 deletions app/dashboard/sync/tezos.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,8 @@ def get_tezos_txn_status(fulfillment):
and tx_response['sender']['address'] == funderAddress
and tx_response['target']['address'] == payeeAddress
and tx_response['amount'] == float(amount) * 10 ** 6
and tx_response['status'] == 'applied'
and confirmations > 0
):
if tx_response['status'] == 'applied':
if tx_response['status'] == 'applied' and confirmations > 0:
return 'success'
return 'expired'

Expand Down
7 changes: 6 additions & 1 deletion app/dashboard/templates/bounty/details2.html
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ <h5 class="font-body font-weight-semibold">{% trans "SUBMISSIONS" %}</h5>
</div>

<!-- WEB3 MODAL FLOW -->
<div v-else-if="fulfillment.payout_type == 'algorand_ext' || fulfillment.payout_type == 'xinfin_ext' || fulfillment.payout_type == 'rsk_ext' || fulfillment.payout_type == 'web3_modal' || fulfillment.payout_type == 'polkadot_ext' || fulfillment.payout_type == 'harmony_ext' || fulfillment.payout_type == 'binance_ext' || fulfillment.payout_type == 'tezos_ext'" class="px-sm-4">
<div v-else-if="fulfillment.payout_type == 'algorand_ext' || fulfillment.payout_type == 'xinfin_ext' || fulfillment.payout_type == 'rsk_ext' || fulfillment.payout_type == 'web3_modal' || fulfillment.payout_type == 'polkadot_ext' || fulfillment.payout_type == 'harmony_ext' || fulfillment.payout_type == 'binance_ext' || fulfillment.payout_type == 'tezos_ext' || fulfillment.payout_type == 'casper_ext'" class="px-sm-4">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we are getting in a moment to rethink the crosschain code 🤣

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

swears man! we really need to! 😄


<div class="text-center pb-3">
<p class="mb-3 font-subheader font-weight-bold">Payout</p>
Expand Down Expand Up @@ -1163,6 +1163,11 @@ <h3>{{ noscript.keywords }}</h3>
<script src="{% static "v2/js/lib/tezos/taquito-beacon-wallet.min.js" %}"></script>
<script src="{% static "v2/js/pages/bounty_detail/tezos_extension.js" %}"></script>

{% elif web3_type == 'casper_ext' %}

<script src="{% static "v2/js/lib/casper/casper_js_sdk.js" %}"></script>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gdixon this is right with the new yarn config?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup yup ! i asked the same thing in the PR :P all custom lib cross chain file continue to live in the path

<script src="{% static "v2/js/pages/bounty_detail/casper_extension.js" %}"></script>

{% elif web3_type == 'fiat' %}

{% if PYPL_CLIENT_ID %}
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 @@ -139,6 +139,10 @@ <h1 class="text-center">Fund Issue</h1>
<input type="radio" name="bounty_chain" id="50797_chain" value="50797" v-model="chainId"><img class="mr-2" src="{% static 'v2/images/chains/tezos.svg' %}" alt="" width="16"> Tezos
</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 === '270895'}">
<input type="radio" name="bounty_chain" id="270895_chain" value="270895" v-model="chainId"><img class="mr-2" src="{% static 'v2/images/chains/casper.svg' %}" alt="" width="16"> Casper
</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 @@ -203,6 +203,10 @@ <h1 class="text-center">Fund Prize</h1>
<input type="radio" name="bounty_chain" id="50797_chain" value="50797" v-model="chainId"><img class="mr-2" src="{% static 'v2/images/chains/tezos.svg' %}" alt="" width="16"> Tezos
</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 === '270895'}">
<input type="radio" name="bounty_chain" id="270895_chain" value="270895" v-model="chainId"><img class="mr-2" src="{% static 'v2/images/chains/casper.svg' %}" alt="" width="16"> Casper
</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
Loading