@@ -1517,6 +1517,148 @@ func receiveBlockHeadersFromClient[Client interface {
15171517 }
15181518}
15191519
1520+ func (c * BaseClient ) SubscribeAccountStatusesFromStartHeight (
1521+ ctx context.Context ,
1522+ startHeight uint64 ,
1523+ filter flow.AccountStatusFilter ,
1524+ opts ... grpc.CallOption ,
1525+ ) (<- chan flow.AccountStatus , <- chan error , error ) {
1526+ request := & executiondata.SubscribeAccountStatusesFromStartHeightRequest {
1527+ StartBlockHeight : startHeight ,
1528+ EventEncodingVersion : c .eventEncoding ,
1529+ }
1530+ request .Filter = & executiondata.StatusFilter {
1531+ EventType : filter .EventTypes ,
1532+ Address : filter .Addresses ,
1533+ }
1534+
1535+ subscribeClient , err := c .executionDataClient .SubscribeAccountStatusesFromStartHeight (ctx , request , opts ... )
1536+ if err != nil {
1537+ return nil , nil , newRPCError (err )
1538+ }
1539+
1540+ accountStatutesChan := make (chan flow.AccountStatus )
1541+ errChan := make (chan error )
1542+
1543+ go func () {
1544+ defer close (accountStatutesChan )
1545+ defer close (errChan )
1546+ receiveAccountStatusesFromStream (ctx , subscribeClient , accountStatutesChan , errChan )
1547+ }()
1548+
1549+ return accountStatutesChan , errChan , nil
1550+ }
1551+
1552+ func (c * BaseClient ) SubscribeAccountStatusesFromStartBlockID (
1553+ ctx context.Context ,
1554+ startBlockID flow.Identifier ,
1555+ filter flow.AccountStatusFilter ,
1556+ opts ... grpc.CallOption ,
1557+ ) (<- chan flow.AccountStatus , <- chan error , error ) {
1558+ request := & executiondata.SubscribeAccountStatusesFromStartBlockIDRequest {
1559+ StartBlockId : startBlockID .Bytes (),
1560+ EventEncodingVersion : c .eventEncoding ,
1561+ }
1562+ request .Filter = & executiondata.StatusFilter {
1563+ EventType : filter .EventTypes ,
1564+ Address : filter .Addresses ,
1565+ }
1566+
1567+ subscribeClient , err := c .executionDataClient .SubscribeAccountStatusesFromStartBlockID (ctx , request , opts ... )
1568+ if err != nil {
1569+ return nil , nil , newRPCError (err )
1570+ }
1571+
1572+ accountStatutesChan := make (chan flow.AccountStatus )
1573+ errChan := make (chan error )
1574+
1575+ go func () {
1576+ defer close (accountStatutesChan )
1577+ defer close (errChan )
1578+ receiveAccountStatusesFromStream (ctx , subscribeClient , accountStatutesChan , errChan )
1579+ }()
1580+
1581+ return accountStatutesChan , errChan , nil
1582+ }
1583+
1584+ func (c * BaseClient ) SubscribeAccountStatusesFromLatestBlock (
1585+ ctx context.Context ,
1586+ filter flow.AccountStatusFilter ,
1587+ opts ... grpc.CallOption ,
1588+ ) (<- chan flow.AccountStatus , <- chan error , error ) {
1589+ request := & executiondata.SubscribeAccountStatusesFromLatestBlockRequest {
1590+ EventEncodingVersion : c .eventEncoding ,
1591+ }
1592+ request .Filter = & executiondata.StatusFilter {
1593+ EventType : filter .EventTypes ,
1594+ Address : filter .Addresses ,
1595+ }
1596+
1597+ subscribeClient , err := c .executionDataClient .SubscribeAccountStatusesFromLatestBlock (ctx , request , opts ... )
1598+ if err != nil {
1599+ return nil , nil , newRPCError (err )
1600+ }
1601+
1602+ accountStatutesChan := make (chan flow.AccountStatus )
1603+ errChan := make (chan error )
1604+
1605+ go func () {
1606+ defer close (accountStatutesChan )
1607+ defer close (errChan )
1608+ receiveAccountStatusesFromStream (ctx , subscribeClient , accountStatutesChan , errChan )
1609+ }()
1610+
1611+ return accountStatutesChan , errChan , nil
1612+ }
1613+
1614+ func receiveAccountStatusesFromStream [Stream interface {
1615+ Recv () (* executiondata.SubscribeAccountStatusesResponse , error )
1616+ }](
1617+ ctx context.Context ,
1618+ stream Stream ,
1619+ accountStatutesChan chan <- flow.AccountStatus ,
1620+ errChan chan <- error ,
1621+ ) {
1622+ sendErr := func (err error ) {
1623+ select {
1624+ case <- ctx .Done ():
1625+ case errChan <- err :
1626+ }
1627+ }
1628+
1629+ var nextExpectedMsgIndex uint64
1630+ for {
1631+ accountStatusResponse , err := stream .Recv ()
1632+ if err != nil {
1633+ if err == io .EOF {
1634+ // End of stream, return gracefully
1635+ return
1636+ }
1637+
1638+ sendErr (fmt .Errorf ("error receiving account status: %w" , err ))
1639+ return
1640+ }
1641+
1642+ accountStatus , err := convert .MessageToAccountStatus (accountStatusResponse )
1643+ if err != nil {
1644+ sendErr (fmt .Errorf ("error converting message to account status: %w" , err ))
1645+ return
1646+ }
1647+
1648+ if accountStatus .MessageIndex != nextExpectedMsgIndex {
1649+ sendErr (fmt .Errorf ("message received out of order" ))
1650+ return
1651+ }
1652+ nextExpectedMsgIndex = accountStatus .MessageIndex + 1
1653+
1654+ select {
1655+ case <- ctx .Done ():
1656+ return
1657+ case accountStatutesChan <- accountStatus :
1658+ }
1659+ }
1660+ }
1661+
15201662func (c * BaseClient ) SubscribeBlockDigestsFromStartBlockID (
15211663 ctx context.Context ,
15221664 startBlockID flow.Identifier ,
0 commit comments