lbry-desktop/ui/js/rewards.js

225 lines
5.5 KiB
JavaScript

const hashes = require('jshashes');
import lbry from 'lbry';
import lbryio from 'lbryio';
import { doShowSnackBar } from 'actions/app';
function rewardMessage(type, amount) {
return {
new_developer: __(
'You earned %s for registering as a new developer.',
amount
),
new_user: __('You earned %s LBC new user reward.', amount),
confirm_email: __(
'You earned %s LBC for verifying your email address.',
amount
),
new_channel: __(
'You earned %s LBC for creating a publisher identity.',
amount
),
first_stream: __(
'You earned %s LBC for streaming your first video.',
amount
),
many_downloads: __(
'You earned %s LBC for downloading some of the things.',
amount
),
first_publish: __(
'You earned %s LBC for making your first publication.',
amount
)
}[type];
}
function toHex(s) {
let h = '';
for (var i = 0; i < s.length; i++) {
let c = s.charCodeAt(i).toString(16);
if (c.length < 2) {
c = '0'.concat(c);
}
h += c;
}
return h;
}
function fromHex(h) {
let s = '';
for (let i = 0; i < h.length; i += 2) {
s += String.fromCharCode(parseInt(h.substr(i, 2), 16));
}
return s;
}
function reverseString(s) {
let o = '';
for (let i = s.length - 1; i >= 0; i--) {
o += s[i];
}
return o;
}
function pack(num) {
return (
'' +
String.fromCharCode(num & 0xff) +
String.fromCharCode((num >> 8) & 0xff) +
String.fromCharCode((num >> 16) & 0xff) +
String.fromCharCode((num >> 24) & 0xff)
);
}
// Returns true if claim is an initial claim, false if it's an update to an existing claim
function isInitialClaim(claim) {
const reversed = reverseString(fromHex(claim.txid));
const concat = reversed.concat(pack(claim.nout));
const sha256 = new hashes.SHA256({ utf8: false }).raw(concat);
const ripemd160 = new hashes.RMD160({ utf8: false }).raw(sha256);
const hash = toHex(reverseString(ripemd160));
return hash == claim.claim_id;
}
const rewards = {};
(rewards.TYPE_NEW_DEVELOPER = 'new_developer'), (rewards.TYPE_NEW_USER =
'new_user'), (rewards.TYPE_CONFIRM_EMAIL =
'confirm_email'), (rewards.TYPE_FIRST_CHANNEL =
'new_channel'), (rewards.TYPE_FIRST_STREAM =
'first_stream'), (rewards.TYPE_MANY_DOWNLOADS =
'many_downloads'), (rewards.TYPE_FIRST_PUBLISH = 'first_publish');
rewards.TYPE_FEATURED_DOWNLOAD = 'featured_download';
rewards.claimReward = function(type) {
function requestReward(resolve, reject, params) {
if (!lbryio.enabled || !lbryio.getAccessToken()) {
reject(new Error(__('Rewards are not enabled.')));
return;
}
lbryio.call('reward', 'new', params, 'post').then(({ reward_amount }) => {
const message = rewardMessage(type, reward_amount),
result = {
type: type,
amount: reward_amount,
message: message
};
// Display global notice
const action = doShowSnackBar({
message,
linkText: __('Show All'),
linkTarget: '/rewards',
isError: false
});
window.app.store.dispatch(action);
// Add more events here to display other places
resolve(result);
}, reject);
}
return new Promise((resolve, reject) => {
lbry.wallet_unused_address().then(address => {
const params = {
reward_type: type,
wallet_address: address
};
switch (type) {
case rewards.TYPE_FIRST_CHANNEL:
lbry
.claim_list_mine()
.then(function(claims) {
let claim = claims.find(function(claim) {
return (
claim.name.length &&
claim.name[0] == '@' &&
claim.txid.length &&
isInitialClaim(claim)
);
});
if (claim) {
params.transaction_id = claim.txid;
requestReward(resolve, reject, params);
} else {
reject(
new Error(__('Please create a channel identity first.'))
);
}
})
.catch(reject);
break;
case rewards.TYPE_FIRST_PUBLISH:
lbry
.claim_list_mine()
.then(claims => {
let claim = claims.find(function(claim) {
return (
claim.name.length &&
claim.name[0] != '@' &&
claim.txid.length &&
isInitialClaim(claim)
);
});
if (claim) {
params.transaction_id = claim.txid;
requestReward(resolve, reject, params);
} else {
reject(
claims.length
? new Error(
__(
'Please publish something and wait for confirmation by the network to claim this reward.'
)
)
: new Error(
__('Please publish something to claim this reward.')
)
);
}
})
.catch(reject);
break;
case rewards.TYPE_FIRST_STREAM:
case rewards.TYPE_NEW_USER:
default:
requestReward(resolve, reject, params);
}
});
});
};
rewards.claimEligiblePurchaseRewards = () => {
if (!lbryio.enabled || !lbryio.getAccessToken()) {
return;
}
let types = {};
types[rewards.TYPE_FIRST_STREAM] = false;
types[rewards.TYPE_FEATURED_DOWNLOAD] = false;
types[rewards.TYPE_MANY_DOWNLOADS] = false;
lbryio.call('reward', 'list', {}).then(
userRewards => {
userRewards.forEach(reward => {
if (types[reward.reward_type] === false && reward.transaction_id) {
types[reward.reward_type] = true;
}
});
let unclaimedType = Object.keys(types).find(type => {
return types[type] === false && type !== rewards.TYPE_FEATURED_DOWNLOAD; //handled below
});
if (unclaimedType) {
rewards.claimReward(unclaimedType);
}
if (types[rewards.TYPE_FEATURED_DOWNLOAD] === false) {
rewards.claimReward(rewards.TYPE_FEATURED_DOWNLOAD);
}
},
() => {}
);
};
export default rewards;