diff --git a/config/_default.js b/config/_default.js index a9884c7..d1d5ba3 100644 --- a/config/_default.js +++ b/config/_default.js @@ -13,6 +13,8 @@ module.exports = { embedColor: 0x15521c, // [string|Array] The role ID(s) for curator roles curatorRoleID: "", + // [string|Array] The role ID(s) for trusted roles + trustedRoleID: "", // [string|Array] The role ID(s) for admin roles adminRoleID: "", // [string] guild_id diff --git a/src/commands/curator/abandon.js b/src/commands/curator/abandon.js index 3468130..6503f82 100644 --- a/src/commands/curator/abandon.js +++ b/src/commands/curator/abandon.js @@ -1,7 +1,7 @@ const Command = require('../../structures/Command'); const Util = require('../../util'); -module.exports = class Abaondon extends Command { +module.exports = class Abandon extends Command { get name() { return 'abandon'; } get _options() { return { diff --git a/src/commands/trusted/tabandon.js b/src/commands/trusted/tabandon.js new file mode 100644 index 0000000..be6e999 --- /dev/null +++ b/src/commands/trusted/tabandon.js @@ -0,0 +1,40 @@ +const Command = require('../../structures/Command'); +const Util = require('../../util'); + +module.exports = class TAbandon extends Command { + get name() { return 'tabandon'; } + + get _options() { return { + aliases: ['taban', 'tdrop'], + permissions: ['trustedOrAdmin'], + minimumArgs: 1 + }; } + + async exec(message, { args }) { + const givenClaim = Util.resolveToClaimID(args[0]); + if (!givenClaim) + // @TODO use claim_search for invalid claim ids + return message.channel.createMessage('That Claim ID isn\'t valid.'); + + if (!await this.client.messageAwaiter.confirm(message, { + header: + 'Are you sure you want to abandon a claim from a **trusted** account?' + })) return; + + const account = await Util.LBRY.findSDKAccount(this.client, account => account.is_default); + + // Drop support + const response = await this.client.lbry.abandonSupport({ + accountID: account.id, claimID: givenClaim }); + const transaction = await response.json(); + if (await this.handleResponse(message, response, transaction)) return; + const txid = transaction.result.txid; + return message.channel.createMessage(`Abandon successful! https://explorer.lbry.com/tx/${txid}`); + } + + get metadata() { return { + category: 'Trusted', + description: 'Abandons a support on a given claim from the trusted account.', + usage: '' + }; } +}; diff --git a/src/commands/trusted/tbalance.js b/src/commands/trusted/tbalance.js new file mode 100644 index 0000000..b5c1262 --- /dev/null +++ b/src/commands/trusted/tbalance.js @@ -0,0 +1,30 @@ +const Command = require('../../structures/Command'); +const Util = require('../../util'); +const config = require('config'); + +module.exports = class TBalance extends Command { + get name() { return 'tbalance'; } + + get _options() { return { + aliases: ['tbal', 'trustedbal', 'trustedbalance'], + permissions: ['trustedOrAdmin'] + }; } + + async exec(message) { + const account = await Util.LBRY.findSDKAccount(this.client, account => account.is_default); + const response = await this.client.lbry.accountBalance(account.id); + const wallet = await response.json(); + if (await this.handleResponse(message, response, wallet)) return; + return message.channel.createMessage({ embed: { + color: config.embedColor, + description: `**${wallet.result.available}** LBC is available in the trusted account.\n\n` + + `Reserved in Supports: ${wallet.result.reserved_subtotals.supports} LBC\n` + + `Total: ${wallet.result.total} LBC` + } }); + } + + get metadata() { return { + category: 'Trusted', + description: 'Shows the trusted wallet balance.' + }; } +}; diff --git a/src/commands/trusted/tsupport.js b/src/commands/trusted/tsupport.js new file mode 100644 index 0000000..d196197 --- /dev/null +++ b/src/commands/trusted/tsupport.js @@ -0,0 +1,51 @@ +const Command = require('../../structures/Command'); +const Util = require('../../util'); + +module.exports = class TSupport extends Command { + get name() { return 'tsupport'; } + + get _options() { return { + aliases: ['tsup'], + permissions: ['trustedOrAdmin'], + minimumArgs: 2 + }; } + + async exec(message, { args }) { + const givenAmount = Util.LBRY.ensureDecimal(args[1]); + if (!givenAmount) + return message.channel.createMessage('The second argument must be a numeric amount of LBC to send!'); + + const givenClaim = Util.resolveToClaimID(args[0]); + if (!givenClaim) + // @TODO use claim_search for invalid claim ids + return message.channel.createMessage('That Claim ID isn\'t valid.'); + + // Get and check balance + const account = await Util.LBRY.findSDKAccount(this.client, account => account.is_default); + const walletResponse = await this.client.lbry.accountBalance(account.id); + const wallet = await walletResponse.json(); + if (await this.handleResponse(message, walletResponse, wallet)) return; + const balance = wallet.result.available; + if (parseFloat(givenAmount) > parseFloat(balance)) + return message.channel.createMessage('You don\'t have enough LBC to do this!'); + + if (!await this.client.messageAwaiter.confirm(message, { + header: + 'Are you sure you want to support a claim from a **trusted** account?' + })) return; + + // Create support + const response = await this.client.lbry.createSupport({ + accountID: account.id, claimID: givenClaim, amount: givenAmount }); + const transaction = await response.json(); + if (await this.handleResponse(message, response, transaction)) return; + const txid = transaction.result.txid; + return message.channel.createMessage(`Support successful! https://explorer.lbry.com/tx/${txid}`); + } + + get metadata() { return { + category: 'Trusted', + description: 'Support a given claim from the trusted account.', + usage: ' ' + }; } +}; diff --git a/src/commands/trusted/tsupports.js b/src/commands/trusted/tsupports.js new file mode 100644 index 0000000..3038751 --- /dev/null +++ b/src/commands/trusted/tsupports.js @@ -0,0 +1,42 @@ +const Command = require('../../structures/Command'); +const GenericPager = require('../../structures/GenericPager'); +const Util = require('../../util'); + +module.exports = class TSupports extends Command { + get name() { return 'tsupports'; } + get _options() { return { + aliases: ['tsups'], + permissions: ['trustedOrAdmin'], + minimumArgs: 0 + }; } + async exec(message, { args }) { + let givenClaim; + if (args[0]) { + givenClaim = Util.resolveToClaimID(args[0]); + if (!givenClaim) + // @TODO use claim_search for invalid claim ids + return message.channel.createMessage('That Claim ID isn\'t valid.'); + } + + const account = await Util.LBRY.findSDKAccount(this.client, account => account.is_default); + const supportsCount = await Util.LBRY.getSupportsCount(this.client, account.id); + if (supportsCount <= 0) + return message.channel.createMessage('No supports found.'); + + const supportsResponse = await this.client.lbry.listSupports({ + accountID: account.id, page_size: supportsCount, claimID: givenClaim }); + const supports = (await supportsResponse.json()).result.items; + const paginator = new GenericPager(this.client, message, { + items: supports, + header: `All supports for the trusted account${ + givenClaim ? ` on claim \`${givenClaim}\`` : ''}`, itemTitle: 'Supports', + display: item => `*lbry://**${item.name}***#\`${item.claim_id}\` (${item.amount} LBC)` + }); + return paginator.start(message.channel.id, message.author.id); + } + get metadata() { return { + category: 'Trusted', + description: 'Shows the list of supports from the trusted account.', + usage: '[claimID]' + }; } +}; diff --git a/src/structures/GenericPager.js b/src/structures/GenericPager.js index 71cfe5e..1e3c586 100644 --- a/src/structures/GenericPager.js +++ b/src/structures/GenericPager.js @@ -21,7 +21,7 @@ class GenericPager extends Paginator { constructor(client, message, { items = [], itemsPerPage = 15, display = item => item.toString(), - embedExtra = {}, itemTitle = 'words.item.many', + embedExtra = {}, itemTitle = 'Items', header = null, footer = null } = {}) { super(client, message, { items, itemsPerPage }); diff --git a/src/util.js b/src/util.js index 854e037..baf12b0 100644 --- a/src/util.js +++ b/src/util.js @@ -94,6 +94,17 @@ Util.CommandPermissions = { if (Util.CommandPermissions.elevated(client, message)) return true; return roles.map(r => member.roles.includes(r)).includes(true); }, + trustedOrAdmin: (client, message) => { + const member = message.guildID ? message.member : + client.guilds.get(config.guildID).members.get(message.author.id); + const roles = [ + ...(Array.isArray(config.adminRoleID) ? config.adminRoleID : [config.adminRoleID]), + ...(Array.isArray(config.trustedRoleID) ? config.trustedRoleID : [config.trustedRoleID]), + ]; + if (!member) return false; + if (Util.CommandPermissions.elevated(client, message)) return true; + return roles.map(r => member.roles.includes(r)).includes(true); + }, }; /**