From 85b1f9b00d7ba73e2324d00b42245e82ef6c0b5a Mon Sep 17 00:00:00 2001 From: Snazzah Date: Thu, 24 Jun 2021 18:51:21 -0500 Subject: [PATCH] Add trusted commands --- src/commands/trusted/tabandon.ts | 40 +++++++++++++++++++++++++ src/commands/trusted/tbalance.ts | 25 ++++++++++++++++ src/commands/trusted/tsupport.ts | 50 +++++++++++++++++++++++++++++++ src/commands/trusted/tsupports.ts | 50 +++++++++++++++++++++++++++++++ src/modules/lbryx.ts | 2 ++ src/util/abstracts.ts | 42 +++++++++++++++++++++++++- 6 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 src/commands/trusted/tabandon.ts create mode 100644 src/commands/trusted/tbalance.ts create mode 100644 src/commands/trusted/tsupport.ts create mode 100644 src/commands/trusted/tsupports.ts diff --git a/src/commands/trusted/tabandon.ts b/src/commands/trusted/tabandon.ts new file mode 100644 index 0000000..ebb2fcb --- /dev/null +++ b/src/commands/trusted/tabandon.ts @@ -0,0 +1,40 @@ +import { stripIndents } from 'common-tags'; +import { CommandContext, DexareClient } from 'dexare'; +import { confirm } from '../../util'; +import { GeneralCommand } from '../../util/abstracts'; + +export default class TAbandonCommand extends GeneralCommand { + constructor(client: DexareClient) { + super(client, { + name: 'tabandon', + description: 'Abandon a support on a claim from the trusted account.', + category: 'Trusted', + aliases: ['taban', 'tdrop'], + userPermissions: ['lbry.trustedOrAdmin'], + metadata: { + examples: ['tabandon @channel#a/video#b'], + usage: '' + } + }); + + this.filePath = __filename; + } + + async run(ctx: CommandContext) { + const claim = await this.lbryx.resolveClaim(ctx.args[0]); + if (!claim) return "That claim isn't valid."; + const accountID = await this.lbryx.getDefaultAccount(); + + if (!(await confirm(ctx, 'Are you sure you want to abandon a claim from a **trusted** account?'))) return; + + // Drop support + const transaction = await this.lbry.supportAbandon({ + account_id: accountID, + claim_id: claim + }); + return stripIndents` + Abandon successful! + 🔗 https://explorer.lbry.com/tx/${transaction.txid} + `; + } +} diff --git a/src/commands/trusted/tbalance.ts b/src/commands/trusted/tbalance.ts new file mode 100644 index 0000000..a4fe724 --- /dev/null +++ b/src/commands/trusted/tbalance.ts @@ -0,0 +1,25 @@ +import { DexareClient } from 'dexare'; +import { GeneralCommand } from '../../util/abstracts'; + +export default class TBalanceCommand extends GeneralCommand { + constructor(client: DexareClient) { + super(client, { + name: 'tbalance', + description: 'Shows the trusted account balance.', + category: 'Trusted', + aliases: ['tbal'], + userPermissions: ['lbry.trustedOrAdmin'], + metadata: { + examples: ['tbalance'] + } + }); + + this.filePath = __filename; + } + + async run() { + const accountID = await this.lbryx.getDefaultAccount(); + const wallet = await this.lbry.accountBalance({ account_id: accountID }); + return this.displayWallet(wallet, 'Trusted Account Balance'); + } +} diff --git a/src/commands/trusted/tsupport.ts b/src/commands/trusted/tsupport.ts new file mode 100644 index 0000000..6bce8cc --- /dev/null +++ b/src/commands/trusted/tsupport.ts @@ -0,0 +1,50 @@ +import { stripIndents } from 'common-tags'; +import { CommandContext, DexareClient } from 'dexare'; +import { ensureDecimal, confirm } from '../../util'; +import { GeneralCommand } from '../../util/abstracts'; + +export default class TSupportCommand extends GeneralCommand { + constructor(client: DexareClient) { + super(client, { + name: 'tsupport', + description: 'Support a claim from the trusted account.', + category: 'Trusted', + aliases: ['tsup'], + userPermissions: ['lbry.trustedOrAdmin'], + metadata: { + examples: ['tsupport @channel#a/video#b 2.0'], + usage: ' ' + } + }); + + this.filePath = __filename; + } + + async run(ctx: CommandContext) { + const claim = await this.lbryx.resolveClaim(ctx.args[0]); + if (!claim) return "That claim isn't valid."; + const amount = ensureDecimal(ctx.args[1]); + if (!amount) return 'You must give a numeric amount of LBC to send!'; + const accountID = await this.lbryx.getDefaultAccount(); + + // Check if the balance is more than requested + const balance = await this.lbry.accountBalance({ account_id: accountID }); + const availableBalance = parseFloat(balance.available); + if (parseFloat(amount) > availableBalance) + return 'There is not enough available LBC in the account to fund that amount!'; + + if (!(await confirm(ctx, 'Are you sure you want to support a claim from a **trusted** account?'))) return; + + // Create support + const transaction = await this.lbry.supportCreate({ + account_id: accountID, + funding_account_ids: [accountID], + claim_id: claim, + amount + }); + return stripIndents` + Support created! + 🔗 https://explorer.lbry.com/tx/${transaction.txid} + `; + } +} diff --git a/src/commands/trusted/tsupports.ts b/src/commands/trusted/tsupports.ts new file mode 100644 index 0000000..e03b4b5 --- /dev/null +++ b/src/commands/trusted/tsupports.ts @@ -0,0 +1,50 @@ +import { CommandContext, DexareClient } from 'dexare'; +import { GeneralCommand } from '../../util/abstracts'; +import { paginate } from '../../util/pager'; + +export default class TSupportsCommand extends GeneralCommand { + constructor(client: DexareClient) { + super(client, { + name: 'tsupports', + description: 'List supports from the trusted account.', + category: 'Trusted', + aliases: ['tsups'], + userPermissions: ['lbry.trustedOrAdmin'], + metadata: { + examples: ['tsupports @channel#a/video#b'], + usage: '[claim]' + } + }); + + this.filePath = __filename; + } + + async run(ctx: CommandContext) { + let claim: string | null = null; + if (ctx.args[0]) { + claim = await this.lbryx.resolveClaim(ctx.args[0]); + if (!claim) return "That claim isn't valid."; + } + + const accountID = await this.lbryx.getDefaultAccount(); + const supportsCount = await this.lbryx.getSupportsCount(accountID); + if (supportsCount <= 0) return 'No supports found.'; + + const supports = await this.lbry.supportList({ + account_id: accountID, + page_size: supportsCount, + claim_id: claim || undefined + }); + + await paginate( + ctx, + { + items: supports.items.map((item) => `> ${item.name} \`${item.claim_id}\`\n> ${item.amount} LBC`), + itemSeparator: '\n\n' + }, + { + author: { name: `All supports for the trusted account${claim ? ` on claim \`${claim}\`` : ''}` } + } + ); + } +} diff --git a/src/modules/lbryx.ts b/src/modules/lbryx.ts index 2ad0a92..dabbdab 100644 --- a/src/modules/lbryx.ts +++ b/src/modules/lbryx.ts @@ -252,6 +252,8 @@ export default class LBRYXModule> extends D * @param query The query to resolve */ async resolveClaim(query: string) { + if (!query) return null; + // Regular claim ID if (/^[a-f0-9]{40}$/.test(query)) return query; diff --git a/src/util/abstracts.ts b/src/util/abstracts.ts index 3fefa4a..39f59ef 100644 --- a/src/util/abstracts.ts +++ b/src/util/abstracts.ts @@ -1,6 +1,8 @@ -import { oneLine } from 'common-tags'; +import { oneLine, stripIndents } from 'common-tags'; import { ClientEvent, CommandContext, DexareCommand, PermissionNames } from 'dexare'; +import Eris from 'eris'; import LBRYModule from '../modules/lbry'; +import * as LBRY from '../modules/lbry/types'; import LBRYXModule from '../modules/lbryx'; import WalletModule from '../modules/wallet'; @@ -21,6 +23,44 @@ export abstract class GeneralCommand extends DexareCommand { return this.client.config.embedColor; } + log(level: 'info' | 'debug', ...args: any[]) { + return this.client.events.emit('logger', level, 'lbrybot', args); + } + + displayWallet( + wallet: LBRY.Balance, + title = 'Balance', + { newAccount = false, thumbnail = '' } = {} + ): Eris.MessageContent { + return { + embed: { + color: this.embedColor, + title, + ...(thumbnail + ? { + thumbnail: { url: thumbnail } + } + : {}), + description: stripIndents` + **Available:** ${wallet.available} LBC + + Reserved in Supports: ${wallet.reserved_subtotals.supports} LBC + Total: ${wallet.total} LBC + + + ${ + newAccount + ? stripIndents` + :warning: This account was just created. + 'Please wait a few seconds, and run the command again to get an accurate balance. + ` + : '' + } + ` + } + }; + } + hasPermission(ctx: CommandContext, event?: ClientEvent): boolean | string { if (this.userPermissions) { let permissionMap = event && event.has('dexare/permissionMap') ? event.get('dexare/permissionMap') : {};