hive-stream 3.0.4 → 3.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/DOCUMENTATION.md +693 -1
- package/README.md +13 -0
- package/dist/adapters/mongodb.adapter.js +21 -30
- package/dist/adapters/mongodb.adapter.js.map +1 -1
- package/dist/adapters/postgresql.adapter.js +16 -16
- package/dist/adapters/postgresql.adapter.js.map +1 -1
- package/dist/adapters/sqlite.adapter.js +17 -17
- package/dist/adapters/sqlite.adapter.js.map +1 -1
- package/dist/api.js +2 -0
- package/dist/api.js.map +1 -1
- package/dist/builders.d.ts +269 -1
- package/dist/builders.js +883 -1
- package/dist/builders.js.map +1 -1
- package/dist/config.js +2 -2
- package/dist/config.js.map +1 -1
- package/dist/streamer.d.ts +105 -10
- package/dist/streamer.js +539 -61
- package/dist/streamer.js.map +1 -1
- package/dist/types/hive-stream.d.ts +306 -0
- package/dist/utils.d.ts +442 -0
- package/dist/utils.js +1423 -0
- package/dist/utils.js.map +1 -1
- package/package.json +4 -5
package/DOCUMENTATION.md
CHANGED
|
@@ -435,8 +435,700 @@ When the built-in API server is running, the following endpoints are available:
|
|
|
435
435
|
|
|
436
436
|
---
|
|
437
437
|
|
|
438
|
+
## Social Operations
|
|
439
|
+
|
|
440
|
+
Follow, unfollow, mute, and reblog users directly from the streamer:
|
|
441
|
+
|
|
442
|
+
```typescript
|
|
443
|
+
// Direct methods
|
|
444
|
+
await streamer.follow('myaccount', 'targetuser');
|
|
445
|
+
await streamer.unfollow('myaccount', 'targetuser');
|
|
446
|
+
await streamer.mute('myaccount', 'spammer');
|
|
447
|
+
await streamer.reblog('myaccount', 'author', 'great-post');
|
|
448
|
+
|
|
449
|
+
// Or use builders
|
|
450
|
+
await streamer.ops.follow().follower('myaccount').following('targetuser').send();
|
|
451
|
+
await streamer.ops.unfollow().follower('myaccount').following('targetuser').send();
|
|
452
|
+
await streamer.ops.mute().follower('myaccount').following('spammer').send();
|
|
453
|
+
await streamer.ops.reblog().account('myaccount').author('author').permlink('great-post').send();
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
---
|
|
457
|
+
|
|
458
|
+
## Staking Operations
|
|
459
|
+
|
|
460
|
+
Power up, power down, delegate, and undelegate Hive Power:
|
|
461
|
+
|
|
462
|
+
```typescript
|
|
463
|
+
// Power up HIVE to HP
|
|
464
|
+
await streamer.powerUp('myaccount', 'myaccount', '100.000');
|
|
465
|
+
await streamer.ops.powerUp().from('myaccount').to('myaccount').amount(100).send();
|
|
466
|
+
|
|
467
|
+
// Power down (withdraw vesting)
|
|
468
|
+
await streamer.powerDown('myaccount', '50000.000000 VESTS');
|
|
469
|
+
await streamer.ops.powerDown().account('myaccount').vestingShares('50000.000000 VESTS').send();
|
|
470
|
+
|
|
471
|
+
// Cancel active power down
|
|
472
|
+
await streamer.cancelPowerDown('myaccount');
|
|
473
|
+
await streamer.ops.cancelPowerDown().account('myaccount').send();
|
|
474
|
+
|
|
475
|
+
// Delegate HP to another account
|
|
476
|
+
await streamer.delegateVestingShares('myaccount', 'recipient', '10000.000000 VESTS');
|
|
477
|
+
await streamer.ops.delegate().delegator('myaccount').delegatee('recipient').vestingShares('10000.000000 VESTS').send();
|
|
478
|
+
|
|
479
|
+
// Remove delegation
|
|
480
|
+
await streamer.undelegateVestingShares('myaccount', 'recipient');
|
|
481
|
+
await streamer.ops.undelegate().delegator('myaccount').delegatee('recipient').send();
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
---
|
|
485
|
+
|
|
486
|
+
## Account Operations
|
|
487
|
+
|
|
488
|
+
### Claim Rewards
|
|
489
|
+
```typescript
|
|
490
|
+
await streamer.claimRewards('myaccount', '1.000 HIVE', '0.500 HBD', '100.000000 VESTS');
|
|
491
|
+
await streamer.ops.claimRewards()
|
|
492
|
+
.account('myaccount')
|
|
493
|
+
.rewardHive('1.000 HIVE')
|
|
494
|
+
.rewardHbd('0.500 HBD')
|
|
495
|
+
.rewardVests('100.000000 VESTS')
|
|
496
|
+
.send();
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
### Witness Voting
|
|
500
|
+
```typescript
|
|
501
|
+
await streamer.witnessVote('myaccount', 'goodwitness', true);
|
|
502
|
+
await streamer.ops.witnessVote().account('myaccount').witness('goodwitness').approve().send();
|
|
503
|
+
|
|
504
|
+
// Remove witness vote
|
|
505
|
+
await streamer.witnessVote('myaccount', 'badwitness', false);
|
|
506
|
+
await streamer.ops.witnessVote().account('myaccount').witness('badwitness').unapprove().send();
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
### Governance Proxy
|
|
510
|
+
```typescript
|
|
511
|
+
await streamer.setProxy('myaccount', 'trustedvoter');
|
|
512
|
+
await streamer.ops.setProxy().account('myaccount').proxy('trustedvoter').send();
|
|
513
|
+
|
|
514
|
+
// Remove proxy
|
|
515
|
+
await streamer.clearProxy('myaccount');
|
|
516
|
+
await streamer.ops.clearProxy().account('myaccount').send();
|
|
517
|
+
```
|
|
518
|
+
|
|
519
|
+
### Update Profile
|
|
520
|
+
```typescript
|
|
521
|
+
await streamer.updateProfile('myaccount', {
|
|
522
|
+
name: 'My Display Name',
|
|
523
|
+
about: 'Hive developer',
|
|
524
|
+
location: 'Decentralized',
|
|
525
|
+
website: 'https://example.com',
|
|
526
|
+
profile_image: 'https://example.com/avatar.png',
|
|
527
|
+
cover_image: 'https://example.com/cover.png'
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
// Or use the builder
|
|
531
|
+
await streamer.ops.updateProfile()
|
|
532
|
+
.account('myaccount')
|
|
533
|
+
.name('My Display Name')
|
|
534
|
+
.about('Hive developer')
|
|
535
|
+
.website('https://example.com')
|
|
536
|
+
.profileImage('https://example.com/avatar.png')
|
|
537
|
+
.set('custom_field', 'custom_value')
|
|
538
|
+
.send();
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
### Account Lookup
|
|
542
|
+
```typescript
|
|
543
|
+
const account = await streamer.getAccount('alice');
|
|
544
|
+
const accounts = await streamer.getAccounts(['alice', 'bob', 'charlie']);
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
---
|
|
548
|
+
|
|
549
|
+
## Event Subscriptions
|
|
550
|
+
|
|
551
|
+
In addition to the existing `onTransfer`, `onCustomJson`, `onComment`, `onPost`, and escrow subscriptions, you can now subscribe to:
|
|
552
|
+
|
|
553
|
+
```typescript
|
|
554
|
+
// Watch all votes on the blockchain
|
|
555
|
+
streamer.onVote((data, blockNumber, blockId, prevBlockId, trxId, blockTime) => {
|
|
556
|
+
console.log(`${data.voter} voted on @${data.author}/${data.permlink} with weight ${data.weight}`);
|
|
557
|
+
});
|
|
558
|
+
|
|
559
|
+
// Watch delegations
|
|
560
|
+
streamer.onDelegate((data, blockNumber, blockId, prevBlockId, trxId, blockTime) => {
|
|
561
|
+
console.log(`${data.delegator} delegated ${data.vesting_shares} to ${data.delegatee}`);
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
// Watch power ups
|
|
565
|
+
streamer.onPowerUp((data, blockNumber, blockId, prevBlockId, trxId, blockTime) => {
|
|
566
|
+
console.log(`${data.from} powered up ${data.amount} to ${data.to}`);
|
|
567
|
+
});
|
|
568
|
+
|
|
569
|
+
// Watch power downs
|
|
570
|
+
streamer.onPowerDown((data, blockNumber, blockId, prevBlockId, trxId, blockTime) => {
|
|
571
|
+
console.log(`${data.account} started power down of ${data.vesting_shares}`);
|
|
572
|
+
});
|
|
573
|
+
|
|
574
|
+
// Watch reward claims
|
|
575
|
+
streamer.onClaimRewards((data, blockNumber, blockId, prevBlockId, trxId, blockTime) => {
|
|
576
|
+
console.log(`${data.account} claimed rewards`);
|
|
577
|
+
});
|
|
578
|
+
|
|
579
|
+
// Watch witness votes
|
|
580
|
+
streamer.onAccountWitnessVote((data, blockNumber, blockId, prevBlockId, trxId, blockTime) => {
|
|
581
|
+
console.log(`${data.account} ${data.approve ? 'voted for' : 'unvoted'} witness ${data.witness}`);
|
|
582
|
+
});
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
---
|
|
586
|
+
|
|
587
|
+
## Blockchain Helpers
|
|
588
|
+
|
|
589
|
+
### Reputation Score
|
|
590
|
+
```typescript
|
|
591
|
+
import { Utils } from 'hive-stream';
|
|
592
|
+
|
|
593
|
+
// Convert raw blockchain reputation to human-readable score (25-75 range)
|
|
594
|
+
const score = Utils.calculateReputation('253948692668213'); // e.g. 73.64
|
|
595
|
+
```
|
|
596
|
+
|
|
597
|
+
### VESTS / HP Conversion
|
|
598
|
+
```typescript
|
|
599
|
+
// Convert VESTS to Hive Power
|
|
600
|
+
const hp = Utils.vestToHP('1000000', totalVestingFundHive, totalVestingShares); // '500.000'
|
|
601
|
+
|
|
602
|
+
// Convert HP to VESTS
|
|
603
|
+
const vests = Utils.hpToVest('500', totalVestingFundHive, totalVestingShares); // '1000000.000000'
|
|
604
|
+
|
|
605
|
+
// Get formatted VESTS string for delegation/power down
|
|
606
|
+
const vestsStr = Utils.hpToVestString('500', totalVestingFundHive, totalVestingShares); // '1000000.000000 VESTS'
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
### Parse Profile Metadata
|
|
610
|
+
```typescript
|
|
611
|
+
const profile = Utils.parseProfileMetadata(account.posting_json_metadata);
|
|
612
|
+
// { name: 'Alice', about: '...', location: '...', website: '...', profile_image: '...', cover_image: '...' }
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
---
|
|
616
|
+
|
|
617
|
+
## Query Namespace
|
|
618
|
+
|
|
619
|
+
The `streamer.query` namespace provides read-only access to the entire Hive blockchain. No keys required.
|
|
620
|
+
|
|
621
|
+
### Chain State
|
|
622
|
+
```typescript
|
|
623
|
+
const props = await streamer.query.getDynamicGlobalProperties();
|
|
624
|
+
const chainProps = await streamer.query.getChainProperties();
|
|
625
|
+
const config = await streamer.query.getConfig();
|
|
626
|
+
const price = await streamer.query.getCurrentMedianHistoryPrice();
|
|
627
|
+
const rewardFund = await streamer.query.getRewardFund('post');
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
### Content & Discussions
|
|
631
|
+
```typescript
|
|
632
|
+
const post = await streamer.query.getContent('author', 'permlink');
|
|
633
|
+
const replies = await streamer.query.getContentReplies('author', 'permlink');
|
|
634
|
+
const votes = await streamer.query.getActiveVotes('author', 'permlink');
|
|
635
|
+
|
|
636
|
+
const trending = await streamer.query.getTrending({ tag: 'hive', limit: 10 });
|
|
637
|
+
const hot = await streamer.query.getHot({ limit: 20 });
|
|
638
|
+
const newPosts = await streamer.query.getCreated({ tag: 'dev', limit: 10 });
|
|
639
|
+
const blog = await streamer.query.getBlog('alice');
|
|
640
|
+
const feed = await streamer.query.getFeed('alice');
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
### Social Graph
|
|
644
|
+
```typescript
|
|
645
|
+
const followers = await streamer.query.getFollowers('alice', '', 'blog', 100);
|
|
646
|
+
const following = await streamer.query.getFollowing('alice', '', 'blog', 100);
|
|
647
|
+
const counts = await streamer.query.getFollowCount('alice');
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
### Delegations & Vesting
|
|
651
|
+
```typescript
|
|
652
|
+
const delegations = await streamer.query.getVestingDelegations('alice');
|
|
653
|
+
```
|
|
654
|
+
|
|
655
|
+
### Account History
|
|
656
|
+
```typescript
|
|
657
|
+
const history = await streamer.query.getAccountHistory('alice', -1, 100);
|
|
658
|
+
```
|
|
659
|
+
|
|
660
|
+
### Market & Orders
|
|
661
|
+
```typescript
|
|
662
|
+
const orderBook = await streamer.query.getOrderBook(50);
|
|
663
|
+
const openOrders = await streamer.query.getOpenOrders('alice');
|
|
664
|
+
```
|
|
665
|
+
|
|
666
|
+
### Resource Credits & Voting Power
|
|
667
|
+
```typescript
|
|
668
|
+
const rc = await streamer.query.getRCMana('alice');
|
|
669
|
+
const vp = await streamer.query.getVPMana('alice');
|
|
670
|
+
const rcAccounts = await streamer.query.findRCAccounts(['alice', 'bob']);
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
### Communities & Notifications
|
|
674
|
+
```typescript
|
|
675
|
+
const community = await streamer.query.getCommunity('hive-12345');
|
|
676
|
+
const communities = await streamer.query.listCommunities({ limit: 50 });
|
|
677
|
+
const notifications = await streamer.query.getAccountNotifications('alice');
|
|
678
|
+
const subs = await streamer.query.listAllSubscriptions('alice');
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
### Witnesses
|
|
682
|
+
```typescript
|
|
683
|
+
const witness = await streamer.query.getWitnessByAccount('someguy');
|
|
684
|
+
const topWitnesses = await streamer.query.getWitnessesByVote('', 100);
|
|
685
|
+
```
|
|
686
|
+
|
|
687
|
+
### Blocks & Transactions
|
|
688
|
+
```typescript
|
|
689
|
+
const block = await streamer.query.getBlock(12345678);
|
|
690
|
+
const header = await streamer.query.getBlockHeader(12345678);
|
|
691
|
+
const ops = await streamer.query.getOperations(12345678);
|
|
692
|
+
const txStatus = await streamer.query.findTransaction('trx-id-here');
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
### Conversions & Savings
|
|
696
|
+
```typescript
|
|
697
|
+
const conversions = await streamer.query.getConversionRequests('alice');
|
|
698
|
+
const collateralized = await streamer.query.getCollateralizedConversionRequests('alice');
|
|
699
|
+
const savingsWithdrawals = await streamer.query.getSavingsWithdrawFrom('alice');
|
|
700
|
+
```
|
|
701
|
+
|
|
702
|
+
### Proposals & Account Lookup
|
|
703
|
+
```typescript
|
|
704
|
+
const proposals = await streamer.query.getProposals({ status: 'votable', limit: 50 });
|
|
705
|
+
const accounts = await streamer.query.lookupAccounts('ali', 10);
|
|
706
|
+
```
|
|
707
|
+
|
|
708
|
+
---
|
|
709
|
+
|
|
710
|
+
## Savings Operations
|
|
711
|
+
|
|
712
|
+
```typescript
|
|
713
|
+
// Transfer to savings
|
|
714
|
+
await streamer.transferToSavings('myaccount', 'myaccount', '100', 'HIVE');
|
|
715
|
+
await streamer.ops.transferToSavings().from('myaccount').hive(100).send();
|
|
716
|
+
|
|
717
|
+
// Transfer from savings (3-day delay)
|
|
718
|
+
await streamer.transferFromSavings('myaccount', 'myaccount', '50', 'HBD', 1);
|
|
719
|
+
await streamer.ops.transferFromSavings().from('myaccount').hbd(50).requestId(1).send();
|
|
720
|
+
|
|
721
|
+
// Cancel pending savings withdrawal
|
|
722
|
+
await streamer.cancelTransferFromSavings('myaccount', 1);
|
|
723
|
+
```
|
|
724
|
+
|
|
725
|
+
---
|
|
726
|
+
|
|
727
|
+
## Convert Operations
|
|
728
|
+
|
|
729
|
+
```typescript
|
|
730
|
+
// Convert HBD to HIVE (3.5-day delay)
|
|
731
|
+
await streamer.convert('myaccount', '10.000 HBD');
|
|
732
|
+
await streamer.ops.convert().from('myaccount').hbd(10).send();
|
|
733
|
+
|
|
734
|
+
// Collateralized convert HIVE to HBD (instant, with collateral)
|
|
735
|
+
await streamer.collateralizedConvert('myaccount', '10.000 HIVE');
|
|
736
|
+
await streamer.ops.collateralizedConvert().from('myaccount').hive(10).send();
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
---
|
|
740
|
+
|
|
741
|
+
## Market Operations
|
|
742
|
+
|
|
743
|
+
```typescript
|
|
744
|
+
// Create a limit order (sell HIVE for HBD)
|
|
745
|
+
await streamer.ops.limitOrder()
|
|
746
|
+
.owner('myaccount')
|
|
747
|
+
.amountToSell('10.000 HIVE')
|
|
748
|
+
.minToReceive('4.000 HBD')
|
|
749
|
+
.expiration(new Date(Date.now() + 7 * 24 * 60 * 60 * 1000))
|
|
750
|
+
.send();
|
|
751
|
+
|
|
752
|
+
// Cancel an order
|
|
753
|
+
await streamer.ops.cancelOrder().owner('myaccount').orderId(12345).send();
|
|
754
|
+
```
|
|
755
|
+
|
|
756
|
+
---
|
|
757
|
+
|
|
758
|
+
## Content Operations
|
|
759
|
+
|
|
760
|
+
```typescript
|
|
761
|
+
// Delete a post or comment
|
|
762
|
+
await streamer.deleteComment('myaccount', 'my-permlink');
|
|
763
|
+
await streamer.ops.deleteComment().author('myaccount').permlink('my-permlink').send();
|
|
764
|
+
|
|
765
|
+
// Set post options with beneficiaries
|
|
766
|
+
await streamer.ops.commentOptions()
|
|
767
|
+
.author('myaccount')
|
|
768
|
+
.permlink('my-post')
|
|
769
|
+
.maxAcceptedPayout('1000.000 HBD')
|
|
770
|
+
.percentHbd(5000)
|
|
771
|
+
.beneficiary('devfund', 500)
|
|
772
|
+
.beneficiary('curator', 1000)
|
|
773
|
+
.send();
|
|
774
|
+
```
|
|
775
|
+
|
|
776
|
+
---
|
|
777
|
+
|
|
778
|
+
## Vesting Withdrawal Routes
|
|
779
|
+
|
|
780
|
+
```typescript
|
|
781
|
+
// Route 50% of power-down to another account
|
|
782
|
+
await streamer.ops.withdrawRoute()
|
|
783
|
+
.from('myaccount')
|
|
784
|
+
.to('savings-account')
|
|
785
|
+
.percent(5000)
|
|
786
|
+
.autoVest(true) // Auto power-up at destination
|
|
787
|
+
.send();
|
|
788
|
+
```
|
|
789
|
+
|
|
790
|
+
---
|
|
791
|
+
|
|
792
|
+
## Witness Operations
|
|
793
|
+
|
|
794
|
+
```typescript
|
|
795
|
+
// Publish price feed (witnesses only)
|
|
796
|
+
await streamer.feedPublish('mywitness', '0.400 HBD', '1.000 HIVE');
|
|
797
|
+
```
|
|
798
|
+
|
|
799
|
+
---
|
|
800
|
+
|
|
801
|
+
## Additional Event Subscriptions
|
|
802
|
+
|
|
803
|
+
```typescript
|
|
804
|
+
// Watch follows/unfollows/mutes
|
|
805
|
+
streamer.onFollow((data, blockNumber, blockId, prevBlockId, trxId, blockTime) => {
|
|
806
|
+
console.log(`${data.follower} ${data.what.length ? 'followed' : 'unfollowed'} ${data.following}`);
|
|
807
|
+
});
|
|
808
|
+
|
|
809
|
+
// Watch reblogs
|
|
810
|
+
streamer.onReblog((data, blockNumber, blockId, prevBlockId, trxId, blockTime) => {
|
|
811
|
+
console.log(`${data.account} reblogged @${data.author}/${data.permlink}`);
|
|
812
|
+
});
|
|
813
|
+
|
|
814
|
+
// Watch account updates
|
|
815
|
+
streamer.onAccountUpdate((data, blockNumber, blockId, prevBlockId, trxId, blockTime) => {
|
|
816
|
+
console.log(`${data.account} updated their account`);
|
|
817
|
+
});
|
|
818
|
+
|
|
819
|
+
// Watch comment deletions
|
|
820
|
+
streamer.onDeleteComment((data, blockNumber, blockId, prevBlockId, trxId, blockTime) => {
|
|
821
|
+
console.log(`${data.author} deleted ${data.permlink}`);
|
|
822
|
+
});
|
|
823
|
+
|
|
824
|
+
// Watch market activity
|
|
825
|
+
streamer.onLimitOrder((data, blockNumber, blockId, prevBlockId, trxId, blockTime) => {
|
|
826
|
+
console.log('Market order activity:', data);
|
|
827
|
+
});
|
|
828
|
+
|
|
829
|
+
// Watch savings transfers
|
|
830
|
+
streamer.onSavingsTransfer((data, blockNumber, blockId, prevBlockId, trxId, blockTime) => {
|
|
831
|
+
console.log('Savings transfer:', data);
|
|
832
|
+
});
|
|
833
|
+
|
|
834
|
+
// Watch HBD/HIVE conversions
|
|
835
|
+
streamer.onConvert((data, blockNumber, blockId, prevBlockId, trxId, blockTime) => {
|
|
836
|
+
console.log('Conversion:', data);
|
|
837
|
+
});
|
|
838
|
+
```
|
|
839
|
+
|
|
840
|
+
---
|
|
841
|
+
|
|
842
|
+
## Content Helpers
|
|
843
|
+
|
|
844
|
+
```typescript
|
|
845
|
+
import { Utils } from 'hive-stream';
|
|
846
|
+
|
|
847
|
+
// Generate a permlink from a title
|
|
848
|
+
const permlink = Utils.generatePermlink('My Awesome Post!'); // 'my-awesome-post'
|
|
849
|
+
|
|
850
|
+
// Generate a reply permlink
|
|
851
|
+
const replyPermlink = Utils.generateReplyPermlink('parent-post'); // 're-parent-post-20260318...'
|
|
852
|
+
|
|
853
|
+
// Create post metadata JSON
|
|
854
|
+
const metadata = Utils.createPostMetadata({
|
|
855
|
+
tags: ['hive', 'development'],
|
|
856
|
+
image: ['https://example.com/hero.png'],
|
|
857
|
+
description: 'A great post about Hive development',
|
|
858
|
+
app: 'my-app/1.0'
|
|
859
|
+
});
|
|
860
|
+
```
|
|
861
|
+
|
|
862
|
+
---
|
|
863
|
+
|
|
864
|
+
## Account Validation
|
|
865
|
+
|
|
866
|
+
```typescript
|
|
867
|
+
// Validate account name format
|
|
868
|
+
const error = Utils.validateAccountName('alice'); // null (valid)
|
|
869
|
+
const error2 = Utils.validateAccountName('AB'); // 'Account name must be at least 3 characters'
|
|
870
|
+
|
|
871
|
+
// Quick boolean check
|
|
872
|
+
const valid = Utils.isValidAccountName('alice'); // true
|
|
873
|
+
|
|
874
|
+
// Check if account exists on chain
|
|
875
|
+
const exists = await Utils.accountExists(client, 'alice'); // true/false
|
|
876
|
+
```
|
|
877
|
+
|
|
878
|
+
---
|
|
879
|
+
|
|
880
|
+
## URL & Link Parsing
|
|
881
|
+
|
|
882
|
+
```typescript
|
|
883
|
+
// Parse Hive URLs
|
|
884
|
+
Utils.parseHiveUrl('@alice/my-post');
|
|
885
|
+
// { author: 'alice', permlink: 'my-post' }
|
|
886
|
+
|
|
887
|
+
Utils.parseHiveUrl('https://hive.blog/hive-12345/@alice/my-post');
|
|
888
|
+
// { author: 'alice', permlink: 'my-post', category: 'hive-12345' }
|
|
889
|
+
```
|
|
890
|
+
|
|
891
|
+
---
|
|
892
|
+
|
|
893
|
+
## Voting Power & Vote Value
|
|
894
|
+
|
|
895
|
+
```typescript
|
|
896
|
+
// Calculate current voting mana %
|
|
897
|
+
const mana = Utils.calculateVotingMana(account); // 98.5
|
|
898
|
+
|
|
899
|
+
// Get effective vesting shares (own + received - delegated)
|
|
900
|
+
const effectiveVests = Utils.getEffectiveVestingShares(account);
|
|
901
|
+
|
|
902
|
+
// Estimate vote value in USD
|
|
903
|
+
const voteValue = Utils.estimateVoteValue(
|
|
904
|
+
mana, // current voting mana %
|
|
905
|
+
100, // vote weight %
|
|
906
|
+
effectiveVests, // effective vesting shares
|
|
907
|
+
rewardFund, // from query.getRewardFund()
|
|
908
|
+
medianPrice // from query.getCurrentMedianHistoryPrice()
|
|
909
|
+
);
|
|
910
|
+
```
|
|
911
|
+
|
|
912
|
+
---
|
|
913
|
+
|
|
914
|
+
## Memo Encryption
|
|
915
|
+
|
|
916
|
+
```typescript
|
|
917
|
+
// Encode a private memo
|
|
918
|
+
const encoded = Utils.encodeMemo(privateMemoKey, receiverPublicMemoKey, 'secret message');
|
|
919
|
+
|
|
920
|
+
// Decode a private memo
|
|
921
|
+
const decoded = Utils.decodeMemo(privateMemoKey, encodedMemo);
|
|
922
|
+
```
|
|
923
|
+
|
|
924
|
+
---
|
|
925
|
+
|
|
926
|
+
## Post Builder
|
|
927
|
+
|
|
928
|
+
The post builder is the easiest way to create posts and replies on Hive. It atomically combines `comment` + `comment_options` in a single transaction, handling beneficiaries, metadata, communities, and more.
|
|
929
|
+
|
|
930
|
+
```typescript
|
|
931
|
+
// Create a post with beneficiaries
|
|
932
|
+
await streamer.ops.post()
|
|
933
|
+
.author('alice')
|
|
934
|
+
.title('My First dApp Post')
|
|
935
|
+
.body('Hello from hive-stream!')
|
|
936
|
+
.tags('hive', 'dev', 'tutorial')
|
|
937
|
+
.community('hive-169321')
|
|
938
|
+
.beneficiary('devfund', 500) // 5%
|
|
939
|
+
.beneficiary('alice-savings', 1000) // 10%
|
|
940
|
+
.maxAcceptedPayout(100, 'HBD')
|
|
941
|
+
.percentHbd(5000) // 50% HBD
|
|
942
|
+
.app('my-app/1.0')
|
|
943
|
+
.image('https://example.com/hero.png')
|
|
944
|
+
.description('A tutorial on building dApps')
|
|
945
|
+
.metadata('canonical_url', 'https://myapp.com/posts/1')
|
|
946
|
+
.send();
|
|
947
|
+
|
|
948
|
+
// Reply to a post
|
|
949
|
+
await streamer.ops.post()
|
|
950
|
+
.author('bob')
|
|
951
|
+
.parentAuthor('alice')
|
|
952
|
+
.parentPermlink('my-first-dapp-post')
|
|
953
|
+
.body('Great post! Very helpful.')
|
|
954
|
+
.send();
|
|
955
|
+
|
|
956
|
+
// Post with zero payout (decline rewards)
|
|
957
|
+
await streamer.ops.post()
|
|
958
|
+
.author('alice')
|
|
959
|
+
.title('PSA: Important Announcement')
|
|
960
|
+
.body('This is a community announcement.')
|
|
961
|
+
.tags('psa')
|
|
962
|
+
.maxAcceptedPayout(0, 'HBD')
|
|
963
|
+
.send();
|
|
964
|
+
```
|
|
965
|
+
|
|
966
|
+
---
|
|
967
|
+
|
|
968
|
+
## Batch Operations
|
|
969
|
+
|
|
970
|
+
Batch multiple operations into a single atomic transaction:
|
|
971
|
+
|
|
972
|
+
```typescript
|
|
973
|
+
// Vote + comment in one transaction
|
|
974
|
+
await streamer.batch()
|
|
975
|
+
.vote('alice', 'bob', 'great-post', 10000)
|
|
976
|
+
.comment('alice', 're-great-post-reply', 'bob', 'great-post', '', 'Love this!', '{}')
|
|
977
|
+
.send();
|
|
978
|
+
|
|
979
|
+
// Multiple transfers in one transaction
|
|
980
|
+
await streamer.batch()
|
|
981
|
+
.transfer('alice', 'bob', '1.000 HIVE', 'payment 1')
|
|
982
|
+
.transfer('alice', 'carol', '2.000 HIVE', 'payment 2')
|
|
983
|
+
.transfer('alice', 'dave', '3.000 HIVE', 'payment 3')
|
|
984
|
+
.send();
|
|
985
|
+
|
|
986
|
+
// Mix different operation types
|
|
987
|
+
await streamer.batch()
|
|
988
|
+
.add(['transfer', { from: 'alice', to: 'bob', amount: '1.000 HIVE', memo: '' }])
|
|
989
|
+
.customJson('myapp', { action: 'register' }, 'alice')
|
|
990
|
+
.send();
|
|
991
|
+
```
|
|
992
|
+
|
|
993
|
+
---
|
|
994
|
+
|
|
995
|
+
## Authority Management
|
|
996
|
+
|
|
997
|
+
Manage posting authority for Hive apps:
|
|
998
|
+
|
|
999
|
+
```typescript
|
|
1000
|
+
// Check if an app has posting authority
|
|
1001
|
+
const hasAuth = await streamer.hasPostingAuth('alice', 'myapp');
|
|
1002
|
+
|
|
1003
|
+
// Grant posting authority to an app
|
|
1004
|
+
await streamer.grantPostingAuth('alice', 'myapp');
|
|
1005
|
+
|
|
1006
|
+
// Revoke posting authority
|
|
1007
|
+
await streamer.revokePostingAuth('alice', 'myapp');
|
|
1008
|
+
```
|
|
1009
|
+
|
|
1010
|
+
---
|
|
1011
|
+
|
|
1012
|
+
## Power Down Schedule
|
|
1013
|
+
|
|
1014
|
+
Calculate when power down payments arrive:
|
|
1015
|
+
|
|
1016
|
+
```typescript
|
|
1017
|
+
const schedule = Utils.calculatePowerDownSchedule(account);
|
|
1018
|
+
// [
|
|
1019
|
+
// { week: 1, date: 2026-03-25T..., amount: '1000.000000', vestingShares: '1000.000000 VESTS' },
|
|
1020
|
+
// { week: 2, date: 2026-04-01T..., amount: '1000.000000', vestingShares: '1000.000000 VESTS' },
|
|
1021
|
+
// ...up to 13 weeks
|
|
1022
|
+
// ]
|
|
1023
|
+
```
|
|
1024
|
+
|
|
1025
|
+
---
|
|
1026
|
+
|
|
1027
|
+
## HBD Savings Interest
|
|
1028
|
+
|
|
1029
|
+
```typescript
|
|
1030
|
+
const interest = Utils.calculateHbdInterest(
|
|
1031
|
+
account.savings_hbd_balance, // '1000.000 HBD'
|
|
1032
|
+
account.savings_hbd_last_interest_payment,
|
|
1033
|
+
15 // current APR %
|
|
1034
|
+
);
|
|
1035
|
+
// '12.328' (pending interest in HBD)
|
|
1036
|
+
```
|
|
1037
|
+
|
|
1038
|
+
---
|
|
1039
|
+
|
|
1040
|
+
## Payout Helpers
|
|
1041
|
+
|
|
1042
|
+
```typescript
|
|
1043
|
+
// Is the post still earning?
|
|
1044
|
+
Utils.isInPayoutWindow(post); // true/false
|
|
1045
|
+
|
|
1046
|
+
// How long until payout?
|
|
1047
|
+
Utils.timeUntilPayout(post); // milliseconds (0 if already paid)
|
|
1048
|
+
|
|
1049
|
+
// What's the payout value?
|
|
1050
|
+
Utils.getPendingPayout(post); // '10.500' (HBD)
|
|
1051
|
+
```
|
|
1052
|
+
|
|
1053
|
+
---
|
|
1054
|
+
|
|
1055
|
+
## Account Value Calculator
|
|
1056
|
+
|
|
1057
|
+
```typescript
|
|
1058
|
+
const value = Utils.calculateAccountValue(
|
|
1059
|
+
account,
|
|
1060
|
+
hivePrice, // e.g. 0.40 USD
|
|
1061
|
+
hbdPrice, // e.g. 1.00 USD
|
|
1062
|
+
totalVestingFundHive,
|
|
1063
|
+
totalVestingShares
|
|
1064
|
+
);
|
|
1065
|
+
// {
|
|
1066
|
+
// hive: 100, // liquid HIVE
|
|
1067
|
+
// hbd: 50, // liquid HBD
|
|
1068
|
+
// savings_hive: 200, // savings HIVE
|
|
1069
|
+
// savings_hbd: 100, // savings HBD
|
|
1070
|
+
// hp: 500, // Hive Power (HP)
|
|
1071
|
+
// total_hive: 800, // total in HIVE terms
|
|
1072
|
+
// total_usd: 470.0 // total in USD
|
|
1073
|
+
// }
|
|
1074
|
+
```
|
|
1075
|
+
|
|
1076
|
+
---
|
|
1077
|
+
|
|
1078
|
+
## Content Extraction
|
|
1079
|
+
|
|
1080
|
+
```typescript
|
|
1081
|
+
// Extract all images from a post body (for thumbnails, galleries)
|
|
1082
|
+
const images = Utils.extractImagesFromBody(post.body);
|
|
1083
|
+
// ['https://example.com/img1.png', 'https://example.com/img2.jpg']
|
|
1084
|
+
|
|
1085
|
+
// Extract all hyperlinks (excluding images)
|
|
1086
|
+
const links = Utils.extractLinksFromBody(post.body);
|
|
1087
|
+
|
|
1088
|
+
// Generate a plain-text summary (for previews, SEO)
|
|
1089
|
+
const summary = Utils.generatePostSummary(post.body, 200);
|
|
1090
|
+
// 'Hello world. This is a great post about...'
|
|
1091
|
+
```
|
|
1092
|
+
|
|
1093
|
+
---
|
|
1094
|
+
|
|
1095
|
+
## Hivesigner URLs
|
|
1096
|
+
|
|
1097
|
+
```typescript
|
|
1098
|
+
// Generate signing URLs for any operation
|
|
1099
|
+
const transferUrl = Utils.getTransferUrl('bob', 'thanks', '1.000 HIVE', 'https://myapp.com');
|
|
1100
|
+
const voteUrl = Utils.getVoteUrl('alice', 'bob', 'great-post', 10000);
|
|
1101
|
+
const delegateUrl = Utils.getDelegateUrl('alice', 'bob', '1000.000000 VESTS');
|
|
1102
|
+
const followUrl = Utils.getFollowUrl('alice', 'bob');
|
|
1103
|
+
|
|
1104
|
+
// Generic signing URL for any operation type
|
|
1105
|
+
const url = Utils.getHivesignerSignUrl('transfer', {
|
|
1106
|
+
from: 'alice', to: 'bob', amount: '1.000 HIVE'
|
|
1107
|
+
}, 'https://myapp.com/callback');
|
|
1108
|
+
```
|
|
1109
|
+
|
|
1110
|
+
---
|
|
1111
|
+
|
|
1112
|
+
## Transfer Memo Helpers
|
|
1113
|
+
|
|
1114
|
+
```typescript
|
|
1115
|
+
// Check if a memo is encrypted
|
|
1116
|
+
Utils.isEncryptedMemo('#encrypted-content'); // true
|
|
1117
|
+
Utils.isEncryptedMemo('regular memo'); // false
|
|
1118
|
+
|
|
1119
|
+
// Create structured JSON memos (for exchanges, apps)
|
|
1120
|
+
const memo = Utils.createJsonMemo({ action: 'deposit', orderId: 12345 });
|
|
1121
|
+
|
|
1122
|
+
// Parse JSON memos from transfers
|
|
1123
|
+
const data = Utils.parseJsonMemo('{"action":"deposit","orderId":12345}');
|
|
1124
|
+
// { action: 'deposit', orderId: 12345 }
|
|
1125
|
+
Utils.parseJsonMemo('regular memo'); // null
|
|
1126
|
+
```
|
|
1127
|
+
|
|
1128
|
+
---
|
|
1129
|
+
|
|
438
1130
|
## Utilities
|
|
439
|
-
The library includes helpers for JSON parsing, randomness, and transfer verification. See `src/utils.ts` for
|
|
1131
|
+
The library includes additional helpers for JSON parsing, randomness, seeded RNG, and transfer verification. See `src/utils.ts` for the complete API.
|
|
440
1132
|
|
|
441
1133
|
---
|
|
442
1134
|
|