2017-05-23 19:07:02 +02:00
|
|
|
const hashes = require('jshashes');
|
2017-05-23 09:21:21 +02:00
|
|
|
import lbry from 'lbry';
|
|
|
|
import lbryio from 'lbryio';
|
|
|
|
import {
|
|
|
|
doShowSnackBar,
|
|
|
|
} from 'actions/app'
|
2017-04-02 12:05:34 +02:00
|
|
|
|
2017-04-10 14:32:40 +02:00
|
|
|
function rewardMessage(type, amount) {
|
|
|
|
return {
|
2017-05-31 12:29:22 +02:00
|
|
|
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),
|
2017-04-10 14:32:40 +02:00
|
|
|
}[type];
|
|
|
|
}
|
2017-04-02 12:05:34 +02:00
|
|
|
|
2017-05-23 19:07:02 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2017-04-02 12:05:34 +02:00
|
|
|
const rewards = {};
|
|
|
|
|
2017-04-12 22:23:20 +02:00
|
|
|
rewards.TYPE_NEW_DEVELOPER = "new_developer",
|
2017-05-11 19:46:41 +02:00
|
|
|
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";
|
2017-05-26 17:56:32 +02:00
|
|
|
rewards.TYPE_FEATURED_DOWNLOAD = "featured_download";
|
2017-04-12 22:23:20 +02:00
|
|
|
|
|
|
|
rewards.claimReward = function (type) {
|
2017-04-13 20:52:26 +02:00
|
|
|
|
|
|
|
function requestReward(resolve, reject, params) {
|
2017-04-15 00:23:42 +02:00
|
|
|
if (!lbryio.enabled) {
|
2017-05-26 22:26:06 +02:00
|
|
|
reject(new Error(__("Rewards are not enabled.")))
|
2017-04-15 00:23:42 +02:00
|
|
|
return;
|
|
|
|
}
|
2017-05-11 19:46:41 +02:00
|
|
|
lbryio.call('reward', 'new', params, 'post').then(({reward_amount}) => {
|
2017-04-13 20:52:26 +02:00
|
|
|
const
|
2017-05-11 19:46:41 +02:00
|
|
|
message = rewardMessage(type, reward_amount),
|
2017-04-13 20:52:26 +02:00
|
|
|
result = {
|
|
|
|
type: type,
|
2017-05-11 19:46:41 +02:00
|
|
|
amount: reward_amount,
|
2017-04-13 20:52:26 +02:00
|
|
|
message: message
|
|
|
|
};
|
|
|
|
|
|
|
|
// Display global notice
|
2017-05-23 09:21:21 +02:00
|
|
|
const action = doShowSnackBar({
|
|
|
|
message,
|
2017-05-26 22:26:06 +02:00
|
|
|
linkText: __("Show All"),
|
2017-05-23 09:21:21 +02:00
|
|
|
linkTarget: "/rewards",
|
|
|
|
isError: false,
|
|
|
|
})
|
|
|
|
window.app.store.dispatch(action)
|
2017-04-13 20:52:26 +02:00
|
|
|
|
|
|
|
// Add more events here to display other places
|
|
|
|
|
|
|
|
resolve(result);
|
|
|
|
}, reject);
|
|
|
|
}
|
|
|
|
|
2017-04-02 12:05:34 +02:00
|
|
|
return new Promise((resolve, reject) => {
|
2017-05-04 05:44:08 +02:00
|
|
|
lbry.wallet_unused_address().then((address) => {
|
2017-04-02 12:05:34 +02:00
|
|
|
const params = {
|
|
|
|
reward_type: type,
|
|
|
|
wallet_address: address,
|
|
|
|
};
|
2017-04-13 20:52:26 +02:00
|
|
|
|
2017-04-12 22:23:20 +02:00
|
|
|
switch (type) {
|
2017-04-13 20:52:26 +02:00
|
|
|
case rewards.TYPE_FIRST_CHANNEL:
|
2017-04-17 14:27:39 +02:00
|
|
|
lbry.claim_list_mine().then(function(claims) {
|
|
|
|
let claim = claims.find(function(claim) {
|
2017-05-23 19:07:02 +02:00
|
|
|
return claim.name.length && claim.name[0] == '@' && claim.txid.length && isInitialClaim(claim)
|
2017-04-17 14:27:39 +02:00
|
|
|
})
|
|
|
|
if (claim) {
|
|
|
|
params.transaction_id = claim.txid;
|
2017-04-13 20:52:26 +02:00
|
|
|
requestReward(resolve, reject, params)
|
|
|
|
} else {
|
2017-05-26 22:26:06 +02:00
|
|
|
reject(new Error(__("Please create a channel identity first.")))
|
2017-04-13 20:52:26 +02:00
|
|
|
}
|
|
|
|
}).catch(reject)
|
2017-04-12 22:23:20 +02:00
|
|
|
break;
|
|
|
|
|
2017-04-17 14:27:39 +02:00
|
|
|
case rewards.TYPE_FIRST_PUBLISH:
|
|
|
|
lbry.claim_list_mine().then((claims) => {
|
|
|
|
let claim = claims.find(function(claim) {
|
2017-05-23 19:07:02 +02:00
|
|
|
return claim.name.length && claim.name[0] != '@' && claim.txid.length && isInitialClaim(claim)
|
2017-04-17 14:27:39 +02:00
|
|
|
})
|
|
|
|
if (claim) {
|
|
|
|
params.transaction_id = claim.txid
|
|
|
|
requestReward(resolve, reject, params)
|
|
|
|
} else {
|
|
|
|
reject(claims.length ?
|
2017-05-26 22:26:06 +02:00
|
|
|
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.")))
|
2017-04-17 14:27:39 +02:00
|
|
|
}
|
|
|
|
}).catch(reject)
|
2017-04-12 22:23:20 +02:00
|
|
|
break;
|
2017-04-02 12:05:34 +02:00
|
|
|
|
2017-04-17 14:27:39 +02:00
|
|
|
case rewards.TYPE_FIRST_STREAM:
|
|
|
|
case rewards.TYPE_NEW_USER:
|
2017-04-13 20:52:26 +02:00
|
|
|
default:
|
|
|
|
requestReward(resolve, reject, params);
|
|
|
|
}
|
2017-04-02 12:05:34 +02:00
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-05-26 17:56:32 +02:00
|
|
|
rewards.claimEligiblePurchaseRewards = function() {
|
2017-04-17 14:27:39 +02:00
|
|
|
let types = {}
|
|
|
|
types[rewards.TYPE_FIRST_STREAM] = false
|
2017-05-26 17:56:32 +02:00
|
|
|
types[rewards.TYPE_FEATURED_DOWNLOAD] = false
|
2017-04-17 14:27:39 +02:00
|
|
|
types[rewards.TYPE_MANY_DOWNLOADS] = false
|
|
|
|
lbryio.call('reward', 'list', {}).then((userRewards) => {
|
|
|
|
userRewards.forEach((reward) => {
|
2017-05-11 19:46:41 +02:00
|
|
|
if (types[reward.reward_type] === false && reward.transaction_id) {
|
|
|
|
types[reward.reward_type] = true
|
2017-04-17 14:27:39 +02:00
|
|
|
}
|
|
|
|
})
|
|
|
|
let unclaimedType = Object.keys(types).find((type) => {
|
2017-05-26 17:56:32 +02:00
|
|
|
return types[type] === false && type !== rewards.TYPE_FEATURED_DOWNLOAD; //handled below
|
2017-04-17 14:27:39 +02:00
|
|
|
})
|
|
|
|
if (unclaimedType) {
|
|
|
|
rewards.claimReward(unclaimedType);
|
|
|
|
}
|
2017-05-26 17:56:32 +02:00
|
|
|
if (types[rewards.TYPE_FEATURED_DOWNLOAD] === false) {
|
|
|
|
rewards.claimReward(rewards.TYPE_FEATURED_DOWNLOAD)
|
|
|
|
}
|
2017-04-17 14:27:39 +02:00
|
|
|
}, () => { });
|
|
|
|
}
|
|
|
|
|
2017-04-02 12:05:34 +02:00
|
|
|
export default rewards;
|