@@ -5,7 +5,7 @@ import { ApiServer, startApiServer } from '../api/init';
5
5
import * as supertest from 'supertest' ;
6
6
import { startEventServer } from '../event-stream/event-server' ;
7
7
import { Server } from 'net' ;
8
- import { DbBlock , DbTx , DbMempoolTx , DbTxStatus } from '../datastore/common' ;
8
+ import { DbBlock , DbTx , DbMempoolTx , DbTxStatus , DbTxTypeId } from '../datastore/common' ;
9
9
import * as assert from 'assert' ;
10
10
import {
11
11
createStacksPrivateKey ,
@@ -27,6 +27,10 @@ import { bufferToHexPrefixString, digestSha512_256 } from '../helpers';
27
27
import {
28
28
RosettaConstructionCombineRequest ,
29
29
RosettaConstructionCombineResponse ,
30
+ RosettaAccount ,
31
+ RosettaAccountBalanceRequest ,
32
+ RosettaAccountBalanceResponse ,
33
+ RosettaAmount ,
30
34
RosettaConstructionDeriveRequest ,
31
35
RosettaConstructionDeriveResponse ,
32
36
RosettaConstructionHashRequest ,
@@ -37,6 +41,12 @@ import {
37
41
RosettaConstructionPayloadsRequest ,
38
42
RosettaConstructionPreprocessRequest ,
39
43
RosettaConstructionPreprocessResponse ,
44
+ RosettaMempoolRequest ,
45
+ RosettaMempoolResponse ,
46
+ RosettaMempoolTransactionRequest ,
47
+ RosettaMempoolTransactionResponse ,
48
+ RosettaOperation ,
49
+ RosettaTransaction ,
40
50
} from '@blockstack/stacks-blockchain-api-types' ;
41
51
import { RosettaConstants , RosettaErrors } from '../api/rosetta-constants' ;
42
52
import { GetStacksTestnetNetwork , testnetKeys } from '../api/routes/debug' ;
@@ -434,6 +444,236 @@ describe('Rosetta API', () => {
434
444
} ) ;
435
445
} ) ;
436
446
447
+ test ( 'rosetta/mempool list' , async ( ) => {
448
+ for ( let i = 0 ; i < 10 ; i ++ ) {
449
+ const mempoolTx : DbMempoolTx = {
450
+ tx_id : `0x891200000000000000000000000000000000000000000000000000000000000${ i } ` ,
451
+ raw_tx : Buffer . from ( 'test-raw-tx' ) ,
452
+ type_id : DbTxTypeId . Coinbase ,
453
+ receipt_time : ( new Date ( `2020-07-09T15:14:0${ i } Z` ) . getTime ( ) / 1000 ) | 0 ,
454
+ coinbase_payload : Buffer . from ( 'coinbase hi' ) ,
455
+ status : 1 ,
456
+ post_conditions : Buffer . from ( [ 0x01 , 0xf5 ] ) ,
457
+ fee_rate : BigInt ( 1234 ) ,
458
+ sponsored : false ,
459
+ sender_address : 'sender-addr' ,
460
+ origin_hash_mode : 1 ,
461
+ } ;
462
+ await db . updateMempoolTx ( { mempoolTx } ) ;
463
+ }
464
+
465
+ const request1 : RosettaMempoolRequest = {
466
+ network_identifier : {
467
+ blockchain : 'stacks' ,
468
+ network : 'testnet' ,
469
+ } ,
470
+ } ;
471
+ const searchResult1 = await supertest ( api . server ) . post ( '/rosetta/v1/mempool/' ) . send ( request1 ) ;
472
+
473
+ expect ( searchResult1 . status ) . toBe ( 200 ) ;
474
+ expect ( searchResult1 . type ) . toBe ( 'application/json' ) ;
475
+ const expectedResp1 : RosettaMempoolResponse = {
476
+ transaction_identifiers : [
477
+ {
478
+ hash : '0x8912000000000000000000000000000000000000000000000000000000000007' ,
479
+ } ,
480
+ {
481
+ hash : '0x8912000000000000000000000000000000000000000000000000000000000006' ,
482
+ } ,
483
+ {
484
+ hash : '0x8912000000000000000000000000000000000000000000000000000000000005' ,
485
+ } ,
486
+ ] ,
487
+ } ;
488
+
489
+ const result : RosettaMempoolResponse = JSON . parse ( searchResult1 . text ) ;
490
+
491
+ expect ( result ) . toHaveProperty ( 'transaction_identifiers' ) ;
492
+
493
+ expect ( result . transaction_identifiers ) . toEqual (
494
+ expect . arrayContaining ( expectedResp1 . transaction_identifiers )
495
+ ) ;
496
+ } ) ;
497
+
498
+ test ( 'rosetta/mempool/transaction' , async ( ) => {
499
+ const mempoolTx : DbMempoolTx = {
500
+ tx_id : '0x8912000000000000000000000000000000000000000000000000000000000000' ,
501
+ raw_tx : Buffer . from ( 'test-raw-tx' ) ,
502
+ type_id : DbTxTypeId . Coinbase ,
503
+ status : DbTxStatus . Success ,
504
+ receipt_time : 1594307695 ,
505
+ coinbase_payload : Buffer . from ( 'coinbase hi' ) ,
506
+ post_conditions : Buffer . from ( [ 0x01 , 0xf5 ] ) ,
507
+ fee_rate : BigInt ( 1234 ) ,
508
+ sponsored : false ,
509
+ sender_address : 'sender-addr' ,
510
+ origin_hash_mode : 1 ,
511
+ } ;
512
+ await db . updateMempoolTx ( { mempoolTx } ) ;
513
+
514
+ const request1 : RosettaMempoolTransactionRequest = {
515
+ network_identifier : {
516
+ blockchain : 'stacks' ,
517
+ network : 'testnet' ,
518
+ } ,
519
+ transaction_identifier : { hash : mempoolTx . tx_id } ,
520
+ } ;
521
+
522
+ const searchResult1 = await supertest ( api . server )
523
+ . post ( `/rosetta/v1/mempool/transaction/` )
524
+ . send ( request1 ) ;
525
+ expect ( searchResult1 . status ) . toBe ( 200 ) ;
526
+ expect ( searchResult1 . type ) . toBe ( 'application/json' ) ;
527
+
528
+ const rosettaAccount : RosettaAccount = {
529
+ address : 'sender-addr' ,
530
+ } ;
531
+
532
+ const rosettaOperation : RosettaOperation = {
533
+ operation_identifier : {
534
+ index : 0 ,
535
+ } ,
536
+ status : 'success' ,
537
+ type : 'coinbase' ,
538
+ account : rosettaAccount ,
539
+ } ;
540
+ const rosettaOperations : RosettaOperation [ ] = [ ] ;
541
+ rosettaOperations . push ( rosettaOperation ) ;
542
+ const transaction : RosettaTransaction = {
543
+ operations : rosettaOperations ,
544
+ transaction_identifier : {
545
+ hash : mempoolTx . tx_id ,
546
+ } ,
547
+ } ;
548
+
549
+ const expectedResp1 : RosettaMempoolTransactionResponse = {
550
+ transaction : transaction ,
551
+ } ;
552
+
553
+ expect ( JSON . parse ( searchResult1 . text ) ) . toEqual ( expectedResp1 ) ;
554
+ } ) ;
555
+
556
+ test ( 'account/balance success' , async ( ) => {
557
+ const request1 : RosettaAccountBalanceRequest = {
558
+ network_identifier : {
559
+ blockchain : 'stacks' ,
560
+ network : 'testnet' ,
561
+ } ,
562
+ account_identifier : {
563
+ address : 'STRYYQQ9M8KAF4NS7WNZQYY59X93XEKR31JP64CP' ,
564
+ } ,
565
+ } ;
566
+
567
+ const result1 = await supertest ( api . server ) . post ( `/rosetta/v1/account/balance/` ) . send ( request1 ) ;
568
+ console . log ( 'account balance' , result1 . text ) ;
569
+ expect ( result1 . status ) . toBe ( 200 ) ;
570
+ expect ( result1 . type ) . toBe ( 'application/json' ) ;
571
+
572
+ const curren_block = await api . datastore . getCurrentBlock ( ) ;
573
+ assert ( curren_block . found ) ;
574
+
575
+ const amount : RosettaAmount = {
576
+ value : '3852' ,
577
+ currency : {
578
+ symbol : 'STX' ,
579
+ decimals : 6 ,
580
+ } ,
581
+ } ;
582
+
583
+ const expectedResponse : RosettaAccountBalanceResponse = {
584
+ block_identifier : {
585
+ hash : curren_block . result . block_hash ,
586
+ index : curren_block . result . block_height ,
587
+ } ,
588
+ balances : [ amount ] ,
589
+
590
+ coins : [ ] ,
591
+ metadata : {
592
+ sequence_number : 0 ,
593
+ } ,
594
+ } ;
595
+
596
+ expect ( JSON . parse ( result1 . text ) ) . toEqual ( expectedResponse ) ;
597
+ } ) ;
598
+
599
+ test ( 'account/balance - invalid account identifier' , async ( ) => {
600
+ const request : RosettaAccountBalanceRequest = {
601
+ network_identifier : {
602
+ blockchain : 'stacks' ,
603
+ network : 'testnet' ,
604
+ } ,
605
+ account_identifier : {
606
+ address : 'KK' ,
607
+ metadata : { } ,
608
+ } ,
609
+ } ;
610
+
611
+ const result = await supertest ( api . server ) . post ( `/rosetta/v1/account/balance/` ) . send ( request ) ;
612
+ expect ( result . status ) . toBe ( 400 ) ;
613
+ expect ( result . type ) . toBe ( 'application/json' ) ;
614
+
615
+ const expectResponse = {
616
+ code : 601 ,
617
+ message : 'Invalid Account.' ,
618
+ retriable : true ,
619
+ } ;
620
+
621
+ expect ( JSON . parse ( result . text ) ) . toEqual ( expectResponse ) ;
622
+ } ) ;
623
+
624
+ test ( 'account/balance - empty block identifier' , async ( ) => {
625
+ const request : RosettaAccountBalanceRequest = {
626
+ network_identifier : {
627
+ blockchain : 'stacks' ,
628
+ network : 'testnet' ,
629
+ } ,
630
+ account_identifier : {
631
+ address : 'SP2QXJDSWYFGT9022M6NCA9SS4XNQM79D8E7EDSPQ' ,
632
+ metadata : { } ,
633
+ } ,
634
+ block_identifier : { } ,
635
+ } ;
636
+
637
+ const result = await supertest ( api . server ) . post ( `/rosetta/v1/account/balance/` ) . send ( request ) ;
638
+ expect ( result . status ) . toBe ( 400 ) ;
639
+ expect ( result . type ) . toBe ( 'application/json' ) ;
640
+
641
+ const expectResponse = {
642
+ code : 615 ,
643
+ message : 'Block identifier is null.' ,
644
+ retriable : true ,
645
+ } ;
646
+
647
+ expect ( JSON . parse ( result . text ) ) . toEqual ( expectResponse ) ;
648
+ } ) ;
649
+
650
+ test ( 'account/balance - invalid block hash' , async ( ) => {
651
+ const request : RosettaAccountBalanceRequest = {
652
+ network_identifier : {
653
+ blockchain : 'stacks' ,
654
+ network : 'testnet' ,
655
+ } ,
656
+ account_identifier : {
657
+ address : 'SP2QXJDSWYFGT9022M6NCA9SS4XNQM79D8E7EDSPQ' ,
658
+ metadata : { } ,
659
+ } ,
660
+ block_identifier : {
661
+ hash : 'afd' ,
662
+ } ,
663
+ } ;
664
+ const result = await supertest ( api . server ) . post ( `/rosetta/v1/account/balance/` ) . send ( request ) ;
665
+ expect ( result . status ) . toBe ( 400 ) ;
666
+ expect ( result . type ) . toBe ( 'application/json' ) ;
667
+
668
+ const expectResponse = {
669
+ code : 606 ,
670
+ message : 'Invalid block hash.' ,
671
+ retriable : true ,
672
+ } ;
673
+
674
+ expect ( JSON . parse ( result . text ) ) . toEqual ( expectResponse ) ;
675
+ } ) ;
676
+
437
677
/* rosetta construction api tests below */
438
678
439
679
test ( 'construction/derive' , async ( ) => {
0 commit comments