forked from celestiaorg/docs
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexample_test.go
More file actions
218 lines (179 loc) · 6.67 KB
/
example_test.go
File metadata and controls
218 lines (179 loc) · 6.67 KB
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
// Package main provides compilation tests for the Golang client tutorial examples
// This file validates that the Go code snippets in golang-client-tutorial.md compile correctly
package main
import (
"bytes"
"context"
"fmt"
"time"
client "github.com/celestiaorg/celestia-node/api/rpc/client"
"github.com/celestiaorg/celestia-node/blob"
"github.com/celestiaorg/celestia-node/state"
share "github.com/celestiaorg/go-square/v2/share"
"github.com/celestiaorg/rsmt2d"
)
// Test compilation guard: If this file does not compile, the CI/CD build will fail
// This ensures that all Go code examples in the tutorial are syntactically correct
// SubmitBlob submits a blob containing "Hello, World!" to the 0xDEADBEEF namespace. It uses the default signer on the running node.
func SubmitBlob(ctx context.Context, url string, token string) error {
client, err := client.NewClient(ctx, url, token)
if err != nil {
return err
}
defer client.Close() // It is important to close the connection after use
// let's post to 0xDEADBEEF namespace
namespace, err := share.NewV0Namespace([]byte{0xDE, 0xAD, 0xBE, 0xEF})
if err != nil {
return err
}
// create a blob
helloWorldBlob, err := blob.NewBlobV0(namespace, []byte("Hello, World!"))
if err != nil {
return err
}
// submit the blob to the network
height, err := client.Blob.Submit(ctx, []*blob.Blob{helloWorldBlob}, nil)
if err != nil {
return err
}
fmt.Printf("Blob was included at height %d\n", height)
// fetch the blob back from the network
retrievedBlobs, err := client.Blob.GetAll(ctx, height, []share.Namespace{namespace})
if err != nil {
return err
}
fmt.Printf("Blobs are equal? %v\n", bytes.Equal(helloWorldBlob.Commitment, retrievedBlobs[0].Commitment))
return nil
}
// SubscribeBlobs subscribes to new blobs in a namespace
func SubscribeBlobs(ctx context.Context, url string, token string) error {
client, err := client.NewClient(ctx, url, token)
if err != nil {
return err
}
defer client.Close() // We close the WebSocket connection after use
// create a namespace to filter blobs with
namespace, err := share.NewV0Namespace([]byte{0xDE, 0xAD, 0xBE, 0xEF})
if err != nil {
return err
}
// subscribe to new blobs using a <-chan *blob.BlobResponse channel
blobChan, err := client.Blob.Subscribe(ctx, namespace)
if err != nil {
return err
}
for {
select {
case resp := <-blobChan:
fmt.Printf("Found %d blobs at height %d in 0xDEADBEEF namespace\n", len(resp.Blobs()), resp.Height)
case <-ctx.Done():
return nil
}
}
}
// SubscribeHeaders subscribes to new headers and fetches all blobs at the height of the new header in the 0xDEADBEEF namespace.
func SubscribeHeaders(ctx context.Context, url string, token string) error {
client, err := client.NewClient(ctx, url, token)
if err != nil {
return err
}
defer client.Close() // We close the WebSocket connection after usage
// create a namespace to filter blobs with
namespace, err := share.NewV0Namespace([]byte{0xDE, 0xAD, 0xBE, 0xEF})
if err != nil {
return err
}
// subscribe to new headers using a <-chan *header.ExtendedHeader channel
headerChan, err := client.Header.Subscribe(ctx)
if err != nil {
return err
}
for {
select {
case header := <-headerChan:
// fetch all blobs at the height of the new header
blobs, err := client.Blob.GetAll(context.TODO(), header.Height(), []share.Namespace{namespace})
if err != nil {
fmt.Printf("Error fetching blobs: %v\n", err)
}
fmt.Printf("Found %d blobs at height %d in 0xDEADBEEF namespace\n", len(blobs), header.Height())
case <-ctx.Done():
return nil
}
}
}
// GetEDS fetches the EDS at the given height.
func GetEDS(ctx context.Context, url string, token string, height uint64) (*rsmt2d.ExtendedDataSquare, error) {
client, err := client.NewClient(ctx, url, token)
if err != nil {
return nil, err
}
defer client.Close() // We close the connection after use
// Fetch the EDS
return client.Share.GetEDS(ctx, height)
}
// SubmitBlobComplete submits a blob containing "Hello, World!" to the 0xDEADBEEF namespace
// and retrieves it from the network to verify the process works.
func SubmitBlobComplete(ctx context.Context, url string, token string) error {
// Create a new client
c, err := client.NewClient(ctx, url, token)
if err != nil {
return fmt.Errorf("failed to create client: %w", err)
}
defer c.Close() // Important to close the connection after use
fmt.Println("Connected to Celestia node")
// Create the 0xDEADBEEF namespace
namespace, err := share.NewV0Namespace([]byte{0xDE, 0xAD, 0xBE, 0xEF})
if err != nil {
return fmt.Errorf("failed to create namespace: %w", err)
}
// Create a blob with "Hello, World!" content
message := []byte("Hello, World!")
helloWorldBlob, err := blob.NewBlobV0(namespace, message)
if err != nil {
return fmt.Errorf("failed to create blob: %w", err)
}
fmt.Println("Submitting blob to the network...")
// Create basic TxConfig instead of passing nil
options := state.NewTxConfig()
// Submit the blob to the network with the options
height, err := c.Blob.Submit(ctx, []*blob.Blob{helloWorldBlob}, options)
if err != nil {
return fmt.Errorf("failed to submit blob: %w", err)
}
fmt.Printf("Success! Blob was included at height %d\n", height)
// Wait a moment to ensure the blob is available for retrieval
time.Sleep(2 * time.Second)
fmt.Println("Retrieving blob from the network...")
// Fetch the blob back from the network
retrievedBlobs, err := c.Blob.GetAll(ctx, height, []share.Namespace{namespace})
if err != nil {
return fmt.Errorf("failed to retrieve blob: %w", err)
}
if len(retrievedBlobs) == 0 {
return fmt.Errorf("no blobs retrieved from height %d", height)
}
// Verify the retrieved blob matches the submitted blob
equal := bytes.Equal(helloWorldBlob.Commitment, retrievedBlobs[0].Commitment)
fmt.Printf("Retrieved blob successfully! Blobs are equal? %v\n", equal)
// Verify the content is what we expect
fmt.Printf("Original message: %s\n", message)
fmt.Printf("Retrieved message: %s\n", retrievedBlobs[0].Data)
return nil
}
// GetNetworkHead retrieves the current network height
func GetNetworkHead(ctx context.Context, c *client.Client) (uint64, error) {
// Get the network head
header, err := c.Header.NetworkHead(ctx)
if err != nil {
return 0, fmt.Errorf("failed to get network head: %w", err)
}
return header.Height(), nil
}
// main function for compilation test - not intended to be run
func main() {
// This main function is only for compilation testing
// It demonstrates that all the tutorial functions compile correctly
fmt.Println("✅ Compilation test passed - all tutorial functions are syntactically correct")
fmt.Println("✅ The fixed API calls (share.NewV0Namespace) compile successfully")
}