-
Notifications
You must be signed in to change notification settings - Fork 124
/
Copy pathmain.go
100 lines (83 loc) · 3.7 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package main
import (
"context"
"fmt"
"time"
"github.com/NethermindEth/starknet.go/rpc"
setup "github.com/NethermindEth/starknet.go/examples/internal"
)
func main() {
fmt.Println("Starting websocket example")
// Load variables from '.env' file
wsProviderUrl := setup.GetWsProviderUrl()
// Initialize connection to WS provider
wsClient, err := rpc.NewWebsocketProvider(wsProviderUrl)
if err != nil {
panic(fmt.Sprintf("Error dialing the WS provider: %s", err))
}
defer wsClient.Close() // Close the WS client when the program finishes
fmt.Println("Established connection with the client")
// Let's now call the SubscribeNewHeads method. To do this, we need to create a channel to receive the new heads.
//
// Note: We'll need to do this for each of the methods we want to subscribe to, always creating a channel to receive the values from
// the node. Check each method's description for the type required for the channel.
newHeadsChan := make(chan *rpc.BlockHeader)
// We then call the desired websocket method, passing in the channel and the parameters if needed.
// For example, to subscribe to new block headers, we call the SubscribeNewHeads method, passing in the channel and the blockID.
// As the description says it's optional, we pass an empty BlockID as value. That way, the latest block will be used by default.
sub, err := wsClient.SubscribeNewHeads(context.Background(), newHeadsChan, rpc.BlockID{})
if err != nil {
panic(err)
}
fmt.Println()
fmt.Println("Successfully subscribed to the node. Subscription ID:", sub.ID())
var latestBlockNumber uint64
// Now we'll create the loop to continuously read the new heads from the channel.
// This will make the program wait indefinitely for new heads or errors if not interrupted.
loop1:
for {
select {
case newHead := <-newHeadsChan:
// This case will be triggered when a new block header is received.
fmt.Println("New block header received:", newHead.BlockNumber)
latestBlockNumber = newHead.BlockNumber
break loop1 // Let's exit the loop after receiving the first block header
case err := <-sub.Err():
// This case will be triggered when an error occurs.
panic(err)
}
}
// We can also use the subscription returned by the WS methods to unsubscribe from the stream when we're done
sub.Unsubscribe()
fmt.Printf("Unsubscribed from the subscription %s successfully\n", sub.ID())
// We'll now subscribe to the node again, but this time we'll pass in an older block number as the blockID.
// This way, the node will send us block headers from that block number onwards.
sub, err = wsClient.SubscribeNewHeads(context.Background(), newHeadsChan, rpc.WithBlockNumber(latestBlockNumber-10))
if err != nil {
panic(err)
}
fmt.Println()
fmt.Println("Successfully subscribed to the node. Subscription ID:", sub.ID())
go func() {
time.Sleep(20 * time.Second)
// Unsubscribe from the subscription after 20 seconds
sub.Unsubscribe()
}()
loop2:
for {
select {
case newHead := <-newHeadsChan:
fmt.Println("New block header received:", newHead.BlockNumber)
case err := <-sub.Err():
if err == nil { // when sub.Unsubscribe() is called a nil error is returned, so let's just break the loop if that's the case
fmt.Printf("Unsubscribed from the subscription %s successfully\n", sub.ID())
break loop2
}
panic(err)
}
}
// This example can be used to understand how to use all the methods that return a subscription.
// It's just a matter of creating a channel to receive the values from the node and calling the
// desired method, passing in the channel and the parameters if needed. Remember to check the method's
// description for the type required for the channel and whether there are any other parameters needed.
}