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(grants): binance crosschain integration #8306

Merged
merged 17 commits into from
Feb 10, 2021
Merged
Show file tree
Hide file tree
Changes from 10 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
8 changes: 7 additions & 1 deletion app/assets/v2/js/cart-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,19 @@ class CartData {
grantData.grant_donation_currency = 'ZIL';
}
} else if (grantData.tenants.includes('HARMONY')) {

if (!grantData.grant_donation_amount) {
grantData.grant_donation_amount = 1;
}
if (!grantData.grant_donation_currency) {
grantData.grant_donation_currency = 'ONE';
}
} else if (grantData.tenants.includes('BINANCE')) {
if (!grantData.grant_donation_amount) {
grantData.grant_donation_amount = 1;
}
if (!grantData.grant_donation_currency) {
grantData.grant_donation_currency = 'BNB';
}
} else if (acceptsAllTokens || 'DAI' == accptedTokenName) {
if (!grantData.grant_donation_amount) {
grantData.grant_donation_amount = 5;
Expand Down
18 changes: 16 additions & 2 deletions app/assets/v2/js/cart.js
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,11 @@ Vue.component('grants-cart', {

isHarmonyExtInstalled() {
return window.onewallet && window.onewallet.isOneWallet;
},

isBinanceExtInstalled() {
return window.BinanceChain && false;
Copy link
Member

Choose a reason for hiding this comment

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

Is this right ?

Copy link
Contributor Author

@chibie chibie Feb 8, 2021

Choose a reason for hiding this comment

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

oops.... should be window.BinanceChain || false;

thanks man


}
},

Expand Down Expand Up @@ -376,6 +381,9 @@ Vue.component('grants-cart', {
case 'HARMONY':
vm.chainId = '1000';
break;
case 'BINANCE':
vm.chainId = '56';
break;
}
},
confirmQRPayment: function(e, grant) {
Expand Down Expand Up @@ -435,13 +443,16 @@ Vue.component('grants-cart', {
vm.$set(grant, 'loading', false);
});
},
contributeWithExtension: function(grant, tenant) {
contributeWithExtension: function(grant, tenant, data) {
chibie marked this conversation as resolved.
Show resolved Hide resolved
let vm = this;

switch (tenant) {
case 'HARMONY':
contributeWithHarmonyExtension(grant, vm);
break;
case 'BINANCE':
contributeWithBinanceExtension(grant, vm);
break;
}
},
loginWithGitHub() {
Expand Down Expand Up @@ -479,7 +490,7 @@ Vue.component('grants-cart', {
// $('input[type=textarea]').focus();
},

updatePaymentStatus(grant_id, step = 'waiting', txnid) {
updatePaymentStatus(grant_id, step = 'waiting', txnid, additionalAttributes) {
let vm = this;
let grantData = vm.grantData;

Expand All @@ -489,6 +500,9 @@ Vue.component('grants-cart', {
if (txnid) {
vm.grantData[index].txnid = txnid;
}
if (additionalAttributes) {
vm.grantData[index].additionalAttributes = additionalAttributes;
}
}
});
},
Expand Down
4 changes: 4 additions & 0 deletions app/assets/v2/js/grants/_new.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ Vue.mixin({
vm.$set(vm.errors, 'zil_payout_address', 'Please enter Zilliqa address');
} else if (vm.chainId == 'harmony' && !vm.form.harmony_payout_address) {
vm.$set(vm.errors, 'harmony_payout_address', 'Please enter Harmony address');
} else if (vm.chainId == 'binance' && !vm.form.binance_payout_address) {
vm.$set(vm.errors, 'binance_payout_address', 'Please enter Binance address');
}

if (!vm.form.grant_type) {
Expand Down Expand Up @@ -165,6 +167,7 @@ Vue.mixin({
'celo_payout_address': form.celo_payout_address,
'zil_payout_address': form.zil_payout_address,
'harmony_payout_address': form.harmony_payout_address,
'binance_payout_address': form.binance_payout_address,
'grant_type': form.grant_type,
'categories[]': form.grant_categories,
'network': form.network,
Expand Down Expand Up @@ -324,6 +327,7 @@ if (document.getElementById('gc-new-grant')) {
celo_payout_address: '',
zil_payout_address: '',
harmony_payout_address: '',
binance_payout_address: '',
grant_type: '',
grant_categories: [],
network: 'mainnet'
Expand Down
73 changes: 73 additions & 0 deletions app/assets/v2/js/grants/cart/binance_extension.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
const contributeWithBinanceExtension = async (grant, vm) => {
const amount = grant.grant_donation_amount;
const token_name = grant.grant_donation_currency;
const to_address = grant.binance_payout_address;

try {
const from_address = await binance_utils.getSelectedAccount();
} catch (error) {
_alert({ message: `Please ensure your Binance Chain Extension wallet is installed and enabled`}, 'error');
return;
}
const account_balance = await binance_utils.getAddressBalance(from_address);

if (Number(account_balance) < amount) {
_alert({ message: `Account needs to have more than ${amount} BNB for payout` }, 'error');
return;
}

binance_utils.transferViaExtension(
amount * 10 ** vm.decimals,
to_address,
from_address,
token_name
).then(txn => {
if (txn) {
callback(null, from_address, txn);
} else {
callback('error in signing transaction');
}
}).catch(err => {
callback(err);
});

function callback(error, from_address, txn) {
if (error) {
vm.updatePaymentStatus(grant.grant_id, 'failed');
_alert({ message: gettext('Unable to contribute to grant due to ' + error) }, 'error');
console.log(error);
} else {

const payload = {
'contributions': [{
'grant_id': grant.grant_id,
'contributor_address': from_address,
'tx_id': txn,
'token_symbol': grant.grant_donation_currency,
'tenant': 'BINANCE',
'comment': grant.grant_comments,
'amount_per_period': grant.grant_donation_amount
}]
};

const apiUrlGrant = `v1/api/contribute`;

fetchData(apiUrlGrant, 'POST', JSON.stringify(payload)).then(response => {
if (200 <= response.status && response.status <= 204) {
console.log('success', response);

vm.updatePaymentStatus(grant.grant_id, 'done', txn);

} else {
vm.updatePaymentStatus(grant.grant_id, 'failed');
_alert('Unable to make contribute to grant. Please try again later', 'error');
console.error(`error: grant contribution failed with status: ${response.status} and message: ${response.message}`);
}
}).catch(function (error) {
vm.updatePaymentStatus(grant.grant_id, 'failed');
_alert('Unable to make contribute to grant. Please try again later', 'error');
console.log(error);
});
}
}
};
3 changes: 3 additions & 0 deletions app/assets/v2/js/grants/funding.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,9 @@ function tokenOptionsForGrant(grant) {
} else if (grant.tenants && grant.tenants.includes('HARMONY')) {
tokenDataList = tokenDataList.filter(token => token.chainId === 1000);
tokenDefault = 'ONE';
} else if (grant.tenants && grant.tenants.includes('BINANCE')) {
tokenDataList = tokenDataList.filter(token => token.chainId === 56);
tokenDefault = 'BNB';
} else {
tokenDataList = tokenDataList.filter(token => token.chainId === 1);
}
Expand Down
2 changes: 1 addition & 1 deletion app/grants/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ class GrantAdmin(GeneralAdmin):
'link', 'clr_prediction_curve', 'hidden', 'next_clr_calc_date', 'last_clr_calc_date',
'metadata', 'twitter_handle_1', 'twitter_handle_2', 'view_count', 'is_clr_eligible', 'in_active_clrs',
'last_update', 'funding_info', 'twitter_verified', 'twitter_verified_by', 'twitter_verified_at', 'stats_history',
'zcash_payout_address', 'celo_payout_address','zil_payout_address', 'harmony_payout_address', 'emails'
'zcash_payout_address', 'celo_payout_address','zil_payout_address', 'harmony_payout_address', 'binance_payout_address', 'emails'
]
readonly_fields = [
'logo_svg_asset', 'logo_asset',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def handle(self, *args, **options):
# Auto expire pending transactions
timeout_period = timezone.now() - timedelta(minutes=60)

tenants = ['ZCASH', 'ZIL', 'CELO', 'POLKADOT', 'HARMONY']
tenants = ['ZCASH', 'ZIL', 'CELO', 'POLKADOT', 'HARMONY', 'BINANCE']

for tenant in tenants:
tenant_pending_contributions = pending_contribution.filter(subscription__tenant=tenant)
Expand Down
19 changes: 16 additions & 3 deletions app/grants/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,13 @@ class Meta:
blank=True,
help_text=_('The harmony wallet address where subscription funds will be sent.'),
)
binance_payout_address = models.CharField(
max_length=255,
default='0x0',
null=True,
blank=True,
help_text=_('The binance wallet address where subscription funds will be sent.'),
)
# TODO-GRANTS: remove
contract_owner_address = models.CharField(
max_length=255,
Expand Down Expand Up @@ -563,6 +570,8 @@ def tenants(self):
tenants.append('POLKADOT')
if self.harmony_payout_address and self.harmony_payout_address != '0x0':
tenants.append('HARMONY')
if self.binance_payout_address and self.binance_payout_address != '0x0':
tenants.append('BINANCE')

return tenants

Expand Down Expand Up @@ -795,7 +804,8 @@ def cart_payload(self, build_absolute_uri):
'celo_payout_address': self.celo_payout_address,
'zil_payout_address': self.zil_payout_address,
'polkadot_payout_address': self.polkadot_payout_address,
'harmony_payout_address': self.harmony_payout_address
'harmony_payout_address': self.harmony_payout_address,
'binance_payout_address': self.binance_payout_address
}

def repr(self, user, build_absolute_uri):
Expand Down Expand Up @@ -850,6 +860,7 @@ def repr(self, user, build_absolute_uri):
'zil_payout_address': self.zil_payout_address,
'polkadot_payout_address': self.polkadot_payout_address,
'harmony_payout_address': self.harmony_payout_address,
'binance_payout_address': self.binance_payout_address,
'token_address': self.token_address,
'image_css': self.image_css,
'verified': self.twitter_verified,
Expand Down Expand Up @@ -902,7 +913,8 @@ class Subscription(SuperModel):
('CELO', 'CELO'),
('ZIL', 'ZIL'),
('POLKADOT', 'POLKADOT'),
('HARMONY', 'HARMONY')
('HARMONY', 'HARMONY'),
('BINANCE', 'BINANCE')
]

active = models.BooleanField(default=True, db_index=True, help_text=_('Whether or not the Subscription is active.'))
Expand Down Expand Up @@ -1563,7 +1575,8 @@ class Contribution(SuperModel):
('celo_std', 'celo_std'),
('zil_std', 'zil_std'),
('polkadot_std', 'polkadot_std'),
('harmony_std', 'harmony_std')
('harmony_std', 'harmony_std'),
('binance_std', 'binance_std')
]

success = models.BooleanField(default=True, help_text=_('Whether or not success.'))
Expand Down
64 changes: 64 additions & 0 deletions app/grants/sync/binance.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import requests
from grants.sync.helpers import record_contribution_activity


def get_binance_txn_status(contribution):
txnid = contribution.tx_id

if not txnid or txnid == "0x0":
return None

response = { 'status': 'pending' }

try:
binance_url = f'https://bsc-dataseed.binance.org'

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

headers = {
'Host': 'gitcoin.co'
}

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

result = binance_response['result']

response = { 'status': 'pending' }

if result:
tx_status = int(result.get('status'), 16) # convert hex to decimal

if tx_status == 1:
response = { 'status': 'done' }
elif tx_status == 0:
response = { 'status': 'expired' }

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

finally:
return response


def sync_binance_payout(contribution):
if contribution.tx_id or contribution.tx_id == "0x0":
txn_status = get_binance_txn_status(contribution)

if txn_status:
status_description = txn_status.get('status')

if status_description == 'done':
contribution.success = True
contribution.tx_cleared = True
contribution.checkout_type = 'binance_std'
record_contribution_activity(contribution)
contribution.save()
elif status_description == 'expired':
contribution.success = True
contribution.tx_cleared = False
contribution.save()
21 changes: 21 additions & 0 deletions app/grants/templates/grants/_new.html
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,10 @@ <h5 class="mt-4">Funding Information</h5>
<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 === 'harmony'}">
<input type="radio" name="grant_chain" id="harmony_chain" value="harmony" v-model="chainId"><img class="mr-2" src="{% static 'v2/images/chains/harmony.svg' %}" alt="" width="20"> harmony
</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 === 'binance'}">
<input type="radio" name="grant_chain" id="binance_chain" value="binance" v-model="chainId"><img class="mr-2" src="{% static 'v2/images/chains/binance.svg' %}" alt="" width="20"> binance
</label>
{% endif %}
</div>

Expand Down Expand Up @@ -316,6 +320,23 @@ <h5 class="mt-4">Funding Information</h5>
</div>
</template>

<template v-if="chainId == 'binance'">
<label class="font-caption letter-spacing text-black-60 text-uppercase" for="binance_payout_address">
Binance Recipient Wallet Address
</label>
<span class="font-smaller-6 badge badge-greylight text-capitalize ml-2">Required</span>

<p class="text-black-60 font-caption mb-2">
This is where funds from contributors to this grant will be sent
</p>

<input id="binance_payout_address" v-model="form.binance_payout_address" name="binance_payout_address" class="form__input form__input-lg" maxlength="50" placeholder="0x0" required/>

<div class="text-danger" v-if="errors.binance_payout_address">
[[errors.binance_payout_address]]
</div>
</template>

</div>


Expand Down
Loading