morphit/node_modules/@beblurt/dblurt/lib/helpers/broadcast.js
Morphit Team 24240cef4c
Some checks failed
morphit-release / Build + publish release tarball (push) Has been cancelled
Reputation flags clearable across all four signals; names and avatars stop vanishing
2026-07-23 14:28:04 -07:00

606 lines
28 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use strict";
/**
* @file Blurt Broadcast API helpers.
* @author BeBlurt <https://beblurt.com/@beblurt>
* @description adaptation from Johan Nordberg <code@johan-nordberg.com> Broadcast API helpers.
* @license
* Copyright (c) 2017 Johan Nordberg. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistribution of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistribution in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* You acknowledge that this software is not designed, licensed or intended for use
* in the design, construction, operation or maintenance of any military facility.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.BroadcastAPI = void 0;
const social_1 = require("../social");
const crypto_1 = require("../crypto");
class BroadcastAPI {
constructor(client) {
this.client = client;
/**
* How many milliseconds in the future to set the expiry time to when
* broadcasting a transaction, defaults to 1 minute.
*/
this.expireTime = 120 * 1000;
}
/** Convenience for calling `condenser_api`. */
call(method, params) {
return this.client.call('condenser_api', method, params);
}
/**
* Create account.
* Broadcasted to the blockchain to create a new account.
* @param data The account_create payload. See {@link AccountCreateOperation}
* @param key The Active or Owner private key of the account creator.
*/
async accountCreate(data, key) {
const op = ['account_create', data];
return this.sendOperations([op], key);
}
/**
* Update account.
* Updates account information.
* @param data The account_update payload. See {@link AccountUpdateOperation}
* @param key The Active or Owner private key of the account.
*/
async accountUpdate(data, key) {
const op = ['account_update', data];
return this.sendOperations([op], key);
}
/**
* Set witness voting proxy.
* @param data The account_witness_proxy payload. See {@link AccountWitnessProxyOperation}
* @param key The private key of the account, should be the Active key at least.
* @deprecated Current Blurt Layer 1 rejects witness proxies after hardfork 0.8
* (`account_witness_proxy_evaluator` asserts that proxies were disabled). Use direct
* witness votes instead.
*/
async accountWitnessProxy(data, key) {
const op = ['account_witness_proxy', data];
return this.sendOperations([op], key);
}
/**
* Witness vote.
* Vote from an account to a witness.
* @param data The account_witness_vote payload. See {@link AccountWitnessVoteOperation}
* @param key The private key of the account, should be the Active key at least.
* @remarks Since HF 0.8 the formula VS/N where VP is the Vesting Share of the account and N the number of witnesses upvoted by the account is applied.
*/
async accountWitnessVote(data, key) {
const op = ['account_witness_vote', data];
return this.sendOperations([op], key);
}
/**
* Cancel transfer from saving.
* Funds withdrawals from the savings can be canceled at any time before it is executed.
* @param data The cancel_transfer_from_savings payload. See {@link CancelTransferFromSavingsOperation}
* @param key The private key of the account, should be the Active key at least.
*/
async cancelTransferFromSavings(data, key) {
const op = ['cancel_transfer_from_savings', data];
return this.sendOperations([op], key);
}
/**
* Change recovery account.
* Funds withdrawals from the savings can be canceled at any time before it is executed.
* @param data The change_recovery_account payload. See {@link ChangeRecoveryAccountOperation}
* @param key The Owner private key of the account.
*/
async changeRecoveryAccount(data, key) {
const op = ['change_recovery_account', data];
return this.sendOperations([op], key);
}
/**
* Claim account.
* Requests from users or dApps to get an account creation ticket in order to create new accounts.
* These operations are issued before the actual creation of the account on the blockchain.
* @param data The claim_account payload. See {@link ClaimAccountOperation}
* @param key The Active or Owner private key of the account.
* @deprecated Current Blurt Layer 1 rejects `claim_account` after hardfork 0.2
* (`claim_account_evaluator` asserts that this operation is disabled). Use regular
* account creation flows supported by current chain rules instead.
*/
async claimAccount(data, key) {
const op = ['claim_account', data];
return this.sendOperations([op], key);
}
/**
* Claim reward balance.
* Author and curator rewards are not automatically transferred to the accounts balances.
* One has to issue a `claim_reward_balance` operation to trigger the transfer from the reward pool to its balance.
* @param data The claim_reward_balance payload. See {@link ClaimRewardBalanceOperation}
* @param key The Posting, Active or Owner private key of the account.
*/
async claimRewardBalance(data, key) {
const op = ['claim_reward_balance', data];
return this.sendOperations([op], key);
}
/**
* Comment.
* Creates a post/comment.
* @param data The comment payload. See {@link CommentOperation}
* @param key The Posting, Active or Owner private key of the account.
* @param options The comment_options payload [optional]. See {@link CommentOptionsOperation}
* @remarks
* Rules:
* - The “title” must not be longer than 256 bytes
* - The “title” must be UTF-8
* - The “body” must be larger than 0 bytes
* - The “body” much also be UTF-8
*
* json_metadata: There is no blockchain enforced validation on `json_metadata`, but the community has adopted a particular structure:
* - tags - An array of up to 5 strings. Although the blockchain will accept more than 5, the tags plugin only looks at the first five
* - app - A user agent style application identifier. Typically app_name/version, e.g. beblurt/0.1
* - format - The format of the body, e.g. markdown
*
* In addition to the above keys, application developers are free to add any other keys they want to help manage the content they broadcast.
*
* When a comment is first broadcast, the permlink must be unique for the author. Otherwise, it is interpreted as an update operation.
* Updating will either replace the entire body with the latest operation or patch the body if using diff-match-patch.
*/
async comment(data, key, options) {
const ops = [];
ops.push(['comment', data]);
if (options) {
ops.push(['comment_options', options]);
}
return this.sendOperations(ops, key);
}
/**
* Comment options.
* Authors of posts may not want all of the benefits that come from creating a post. This operation allows authors to update properties associated with their post.
* Typically, these options will accompany a comment operation in the same transaction.
* @param data The comment_options payload. See {@link CommentOptionsOperation}
* @param key The Active or Owner private key of the account creator.
*/
async commentOptions(data, key) {
const op = ['comment_options', data];
return this.sendOperations([op], key);
}
/**
* Delete a post or comment by author/permlink.
* @param data The delete_comment payload. See {@link DeleteCommentOperation}.
* @param key Private posting key of the author.
*/
async deleteComment(data, key) {
const op = ['delete_comment', data];
return this.sendOperations([op], key);
}
/**
* Transfer liquid BLURT into vesting shares.
* @param data The transfer_to_vesting payload. See {@link TransferToVestingOperation}.
* @param key Private active key of the source account.
*/
async transferToVesting(data, key) {
const op = ['transfer_to_vesting', data];
return this.sendOperations([op], key);
}
/**
* Start or update a vesting withdrawal schedule.
* @param data The withdraw_vesting payload. See {@link WithdrawVestingOperation}.
* @param key Private active key of the withdrawing account.
*/
async withdrawVesting(data, key) {
const op = ['withdraw_vesting', data];
return this.sendOperations([op], key);
}
/**
* Route vesting withdrawals to another account.
* @param data The set_withdraw_vesting_route payload. See {@link SetWithdrawVestingRouteOperation}.
* @param key Private active key of the source account.
*/
async setWithdrawVestingRoute(data, key) {
const op = ['set_withdraw_vesting_route', data];
return this.sendOperations([op], key);
}
/**
* Transfer liquid BLURT into savings.
* @param data The transfer_to_savings payload. See {@link TransferToSavingsOperation}.
* @param key Private active key of the source account.
*/
async transferToSavings(data, key) {
const op = ['transfer_to_savings', data];
return this.sendOperations([op], key);
}
/**
* Request a transfer from savings.
* @param data The transfer_from_savings payload. See {@link TransferFromSavingsOperation}.
* @param key Private active key of the source account.
*/
async transferFromSavings(data, key) {
const op = ['transfer_from_savings', data];
return this.sendOperations([op], key);
}
/**
* Create claimed account.
* When used with `claim_account`, works identically to `account_create` See {@link accountCreate}.
* @param data The create_claimed_account payload. See {@link CreateClaimedAccountOperation}
* @param key The Active or Owner private key of the account creator.
* @deprecated Current Blurt Layer 1 rejects `create_claimed_account` after hardfork 0.2
* (`create_claimed_account_evaluator` asserts that this operation is disabled). Use regular
* account creation flows supported by current chain rules instead.
*/
async createClaimedAccount(data, key) {
const op = ['create_claimed_account', data];
return this.sendOperations([op], key);
}
/**
* Create an account recovery request.
* @param data The request_account_recovery payload. See {@link RequestAccountRecoveryOperation}.
* @param key Private owner key of the recovery account.
*/
async requestAccountRecovery(data, key) {
const op = ['request_account_recovery', data];
return this.sendOperations([op], key);
}
/**
* Recover an account using current and recent owner authorities.
* @param data The recover_account payload. See {@link RecoverAccountOperation}.
* @param key Private owner key or keys required by the recovery authorities.
*/
async recoverAccount(data, key) {
const op = ['recover_account', data];
return this.sendOperations([op], key);
}
/**
* Create an escrow transfer.
* @param data The escrow_transfer payload. See {@link EscrowTransferOperation}.
* @param key Private active key of the sender.
*/
async escrowTransfer(data, key) {
const op = ['escrow_transfer', data];
return this.sendOperations([op], key);
}
/**
* Approve or reject an escrow transfer.
* @param data The escrow_approve payload. See {@link EscrowApproveOperation}.
* @param key Private active key of `data.who`.
*/
async escrowApprove(data, key) {
const op = ['escrow_approve', data];
return this.sendOperations([op], key);
}
/**
* Dispute an escrow transfer.
* @param data The escrow_dispute payload. See {@link EscrowDisputeOperation}.
* @param key Private active key of `data.who`.
*/
async escrowDispute(data, key) {
const op = ['escrow_dispute', data];
return this.sendOperations([op], key);
}
/**
* Release funds from an escrow transfer.
* @param data The escrow_release payload. See {@link EscrowReleaseOperation}.
* @param key Private active key of `data.who`.
*/
async escrowRelease(data, key) {
const op = ['escrow_release', data];
return this.sendOperations([op], key);
}
/** Register or update witness metadata. */
async witnessUpdate(data, key) {
const op = ['witness_update', data];
return this.sendOperations([op], key);
}
/** Set low-level witness properties. */
async witnessSetProperties(data, key) {
const op = ['witness_set_properties', data];
return this.sendOperations([op], key);
}
/** Create a governance proposal. */
async createProposal(data, key) {
const op = ['create_proposal', data];
return this.sendOperations([op], key);
}
/** Vote for or against governance proposals. */
async updateProposalVotes(data, key) {
const op = ['update_proposal_votes', data];
return this.sendOperations([op], key);
}
/** Remove governance proposals owned by an account. */
async removeProposal(data, key) {
const op = ['remove_proposal', data];
return this.sendOperations([op], key);
}
/**
* Broadcast custom JSON.
* Serves the same purpose as custom but also supports required posting authorities. Unlike custom, this operation is designed to be human readable/developer friendly.
* @param data The custom_json operation payload. See {@link CustomJsonOperation}
* @param key The Posting, Active or Owner private key of the account.
*/
async customJson(data, key) {
const op = ['custom_json', data];
return this.sendOperations([op], key);
}
/**
* Delegate vesting shares from one account to the other. The vesting shares are still owned
* by the original account, but content voting rights and bandwidth allocation are transferred
* to the receiving account. This sets the delegation to `vesting_shares`, increasing it or
* decreasing it as needed. (i.e. a delegation of 0 removes the delegation)
*
* When a delegation is removed the shares are placed in limbo for a week to prevent a satoshi
* of VESTS from voting on the same content twice.
*
* @param options Delegation options. See {@link DelegateVestingSharesOperation}
* @param key Private active key of the delegator.
*/
async delegateVestingShares(options, key) {
const op = ['delegate_vesting_shares', options];
return this.sendOperations([op], key);
}
/**
* Prepare transaction with operations for Sign and broadcast to the network.
* @param operations List of operations to send.
*/
async prepareTransaction(operations) {
const props = await this.client.condenser.getDynamicGlobalProperties();
const ref_block_num = props.head_block_number & 0xffff;
const ref_block_prefix = Buffer.from(props.head_block_id, 'hex').readUInt32LE(4);
const expiration = new Date(new Date(props.time + 'Z').getTime() + this.expireTime).toISOString().slice(0, -5);
const extensions = [];
const tx = {
expiration,
extensions,
operations,
ref_block_num,
ref_block_prefix
};
return tx;
}
/**
* Reblurt/Undo Reblurt a post
* @param account The account submitting the custom_json operation.
* @param author The author of the post.
* @param permlink The permlink of the post.
* @param undo if true Undo Reblurt else Reblurt
* @param key The Posting, Active or Owner private key of the account.
**/
async reblurt(account, author, permlink, undo = false, key) {
const op = undo
? (0, social_1.buildUndoReblogOperation)({ account, author, permlink })
: (0, social_1.buildReblogOperation)({ account, author, permlink });
return this.sendOperations([op], key);
}
/** Broadcast a reblog custom_json operation. */
async reblog(account, author, permlink, key) {
return this.sendOperations([(0, social_1.buildReblogOperation)({ account, author, permlink })], key);
}
/** Broadcast an undo-reblog custom_json operation. */
async undoReblog(account, author, permlink, key) {
return this.sendOperations([(0, social_1.buildUndoReblogOperation)({ account, author, permlink })], key);
}
/** Broadcast a follow custom_json operation. */
async follow(follower, following, key) {
return this.sendOperations([(0, social_1.buildFollowOperation)({ follower, following })], key);
}
/** Broadcast an unfollow custom_json operation. */
async unfollow(follower, following, key) {
return this.sendOperations([(0, social_1.buildUnfollowOperation)({ follower, following })], key);
}
/** Broadcast a mute custom_json operation using the follow/ignore convention. */
async mute(follower, following, key) {
return this.sendOperations([(0, social_1.buildMuteOperation)({ follower, following })], key);
}
/** Broadcast an unmute custom_json operation using the empty follow-list convention. */
async unmute(follower, following, key) {
return this.sendOperations([(0, social_1.buildUnmuteOperation)({ follower, following })], key);
}
/** Broadcast a read notification to the network. */
async readNotification(account, date, key) {
return this.sendOperations([(0, social_1.buildReadNotificationOperation)({ account, date })], key);
}
/** Broadcast a signed transaction to the network. */
async send(transaction) {
const trxId = crypto_1.cryptoUtils.generateTrxId(transaction);
const result = await this.call('broadcast_transaction', [transaction]);
return Object.assign({ id: trxId }, result);
}
/**
* Sign and broadcast transaction with operations to the network. Throws if the transaction expires.
* @param operations List of operations to send.
* @param key Private key(s) used to sign transaction.
*/
// eslint-disable-next-line max-len
async sendOperations(operations, key) {
const tx = await this.prepareTransaction(operations);
const result = await this.send(this.sign(tx, key));
// assert(result.expired === false, 'transaction expired')
return result;
}
/** Sign a transaction with key(s) */
sign(transaction, key) {
return crypto_1.cryptoUtils.signTransaction(transaction, key, this.client.chainId);
}
/**
* Broadcast a transfer.
* @param data The transfer operation payload.
* @param key Private active key of sender.
*/
async transfer(data, key) {
const op = ['transfer', data];
return this.sendOperations([op], key);
}
/**
* Broadcast a vote.
* @param vote The vote to send.
* @param key Private posting key of the voter.
*/
async vote(vote, key) {
const op = ['vote', vote];
return this.sendOperations([op], key);
}
// ____________________ NEXUS
/**
* Mute a post (Mods or higher). Can be a topic or a comment.
* @param community The community account concerned.
* @param authority The account submitting the custom_json operation.
* @param account The author of the post.
* @param permlink The permlink of the post.
* @param notes short notes
* @param key The Posting, Active or Owner private key of the account.
*/
async nexusMutePost(community, authority, account, permlink, notes, key) {
const op = [
'custom_json', { required_auths: [], required_posting_auths: [authority], id: 'community', json: JSON.stringify(['mutePost', { community, account, permlink, notes }]) }
];
return this.sendOperations([op], key);
}
/**
* Stickies a post to the top of the community homepage (Mods or higher). If multiple posts are stickied, the newest ones are shown first.
* @param community The community account concerned.
* @param authority The account submitting the custom_json operation.
* @param account The author of the post.
* @param permlink The permlink of the post.
* @param key The Posting, Active or Owner private key of the account.
*/
async nexusPinPost(community, authority, account, permlink, key) {
const op = [
'custom_json', { required_auths: [], required_posting_auths: [authority], id: 'community', json: JSON.stringify(['pinPost', { community, account, permlink }]) }
];
return this.sendOperations([op], key);
}
/**
* Stickies a post to the top of the community homepage (Mods or higher). If multiple posts are stickied, the newest ones are shown first.
* @param community The community account concerned.
* @param authority The account submitting the custom_json operation.
* @param account The account submitting the custom_json operation.
* @param role The author of the post.
* @param key The Posting, Active or Owner private key of the account.
*/
async nexusSetRole(community, authority, account, role, key) {
const op = [
'custom_json', { required_auths: [], required_posting_auths: [authority], id: 'community', json: JSON.stringify(['setRole', { community, account, role }]) }
];
return this.sendOperations([op], key);
}
/**
* Stickies a post to the top of the community homepage (Mods or higher). If multiple posts are stickied, the newest ones are shown first.
* @param community The community account concerned.
* @param authority The account submitting the custom_json operation.
* @param account The account submitting the custom_json operation.
* @param title title for the account
* @param key The Posting, Active or Owner private key of the account.
*/
async nexusSetUserTitle(community, authority, account, title, key) {
const op = [
'custom_json', { required_auths: [], required_posting_auths: [authority], id: 'community', json: JSON.stringify(['setUserTitle', { community, account, title }]) }
];
return this.sendOperations([op], key);
}
/**
* Unmute a post (Mods or higher).
* @param community The community account concerned.
* @param authority The account submitting the custom_json operation.
* @param account The author of the post.
* @param permlink The permlink of the post.
* @param notes short notes
* @param key The Posting, Active or Owner private key of the account.
*/
async nexusUnmutePost(community, authority, account, permlink, notes, key) {
const op = [
'custom_json', { required_auths: [], required_posting_auths: [authority], id: 'community', json: JSON.stringify(['unmutePost', { community, account, permlink, notes }]) }
];
return this.sendOperations([op], key);
}
/**
* Removes a post to the top of the community homepage (Mods or higher).
* @param community The community account concerned.
* @param authority The account submitting the custom_json operation.
* @param account The author of the post.
* @param permlink The permlink of the post.
* @param key The Posting, Active or Owner private key of the account.
*/
async nexusUnpinPost(community, authority, account, permlink, key) {
const op = [
'custom_json', { required_auths: [], required_posting_auths: [authority], id: 'community', json: JSON.stringify(['unpinPost', { community, account, permlink }]) }
];
return this.sendOperations([op], key);
}
/**
* Broadcast Nexus update properties (Admin Operations).
* Update display settings of a Community.
* @param data The custom_json operation payload. See {@link NexusUpdateProps}
* @param authority The account submitting the custom_json operation.
* @param key The Posting, Active or Owner private key of the account.
*/
async nexusUpdateProps(data, authority, key) {
const op = ['custom_json', { required_auths: [], required_posting_auths: [authority], id: 'community', json: JSON.stringify(['updateProps', data]) }];
return this.sendOperations([op], key);
}
// ____________________ NEXUS Guest Operations
/**
* Used by guests to suggest a post for the review queue. Its up to the community to define what constitutes flagging.
* @param community The community account concerned.
* @param authority The account submitting the custom_json operation.
* @param account The author of the post.
* @param permlink The permlink of the post.
* @param notes short notes
* @param key The Posting, Active or Owner private key of the account.
*/
async nexusFlagPost(community, authority, account, permlink, notes, key) {
const op = [
'custom_json', { required_auths: [], required_posting_auths: [authority], id: 'community', json: JSON.stringify(['flagPost', { community, account, permlink, notes }]) }
];
return this.sendOperations([op], key);
}
/**
* Un/subscribe to a community (Guest Operations)
* @param community The community account concerned.
* @param action Un/subscribe to a community.
* @param account The account submitting the custom_json operation.
* @param key The Posting, Active or Owner private key of the account.
**/
async nexusSubscription(community, action, account, key) {
const op = action === 'subscribe'
? (0, social_1.buildCommunitySubscribeOperation)({ account, community })
: (0, social_1.buildCommunityUnsubscribeOperation)({ account, community });
return this.sendOperations([op], key);
}
/** Broadcast a community subscribe custom_json operation. */
async communitySubscribe(account, community, key) {
return this.sendOperations([(0, social_1.buildCommunitySubscribeOperation)({ account, community })], key);
}
/** Broadcast a community unsubscribe custom_json operation. */
async communityUnsubscribe(account, community, key) {
return this.sendOperations([(0, social_1.buildCommunityUnsubscribeOperation)({ account, community })], key);
}
/**
* Stickies a post to the top of the community homepage (Mods or higher). If multiple posts are stickied, the newest ones are shown first.
* @param authority The account submitting the custom_json operation.
* @param referrer The referrer of the account.
* @param campaign The campaign id of the referrer.
* @param key The Posting, Active or Owner private key of the account.
*/
async nexusAddReferrer(authority, referrer, campaign, key) {
const op = [
'custom_json', { required_auths: [], required_posting_auths: [authority], id: 'referral', json: JSON.stringify({ referrer, campaign }) }
];
return this.sendOperations([op], key);
}
}
exports.BroadcastAPI = BroadcastAPI;