Skip to content

Commit 7777c1d

Browse files
committed
add binaries for creating farm and account
1 parent feba4ab commit 7777c1d

File tree

3 files changed

+277
-331
lines changed

3 files changed

+277
-331
lines changed

node-registrar/cmds/account/main.go

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"crypto/ed25519"
6+
"crypto/rand"
7+
"encoding/base64"
8+
"encoding/hex"
9+
"encoding/json"
10+
"flag"
11+
"fmt"
12+
"net/http"
13+
"net/url"
14+
"time"
15+
16+
"github.com/rs/zerolog/log"
17+
)
18+
19+
var urls = map[string]string{
20+
"dev": "https://registrar.dev4.grid.tf/v1",
21+
"qa": "https://registrar.qa4.grid.tf/v1",
22+
"test": "https://registrar.test4.grid.tf/v1",
23+
"main": "https://registrar.prod4.grid.tf/v1",
24+
}
25+
26+
func main() {
27+
var seed string
28+
var network string
29+
30+
flag.StringVar(&seed, "seed", "", "seed")
31+
flag.StringVar(&network, "network", "", "network (dev, qa, test, main)")
32+
flag.Parse()
33+
34+
u, ok := urls[network]
35+
if !ok {
36+
log.Fatal().Msgf("invalid network %s", network)
37+
}
38+
39+
var publicKey ed25519.PublicKey
40+
var privateKey ed25519.PrivateKey
41+
var err error
42+
43+
if len(seed) == 0 {
44+
s := make([]byte, 32)
45+
_, err := rand.Read(s)
46+
if err != nil {
47+
log.Fatal().Err(err).Send()
48+
}
49+
seed = hex.EncodeToString(s)
50+
fmt.Println("New Seed (Hex):", seed)
51+
}
52+
53+
publicKey, privateKey, err = getKeyPair(seed)
54+
if err != nil {
55+
log.Fatal().Err(err).Send()
56+
}
57+
58+
twinID, err := createAccount(privateKey, publicKey, u)
59+
if err != nil {
60+
log.Fatal().Err(err).Send()
61+
}
62+
63+
fmt.Println(twinID)
64+
}
65+
66+
func createAccount(privateKey ed25519.PrivateKey, publicKey ed25519.PublicKey, u string) (twinID uint64, err error) {
67+
url, err := url.JoinPath(u, "accounts")
68+
if err != nil {
69+
return
70+
}
71+
72+
timestamp := time.Now().Unix()
73+
publicKeyBase64 := base64.StdEncoding.EncodeToString(publicKey)
74+
75+
challenge := []byte(fmt.Sprintf("%d:%v", timestamp, publicKeyBase64))
76+
signature := ed25519.Sign(privateKey, challenge)
77+
78+
data := map[string]any{
79+
"public_key": publicKey,
80+
"signature": signature,
81+
"timestamp": timestamp,
82+
}
83+
84+
var body bytes.Buffer
85+
err = json.NewEncoder(&body).Encode(data)
86+
if err != nil {
87+
return
88+
}
89+
90+
resp, err := http.DefaultClient.Post(url, "application/json", &body)
91+
if err != nil {
92+
return
93+
}
94+
95+
if resp.StatusCode != http.StatusCreated {
96+
return twinID, fmt.Errorf("account not created successfully")
97+
}
98+
99+
defer resp.Body.Close()
100+
101+
result := struct {
102+
TwinID uint64 `json:"twin_id"`
103+
}{}
104+
105+
err = json.NewDecoder(resp.Body).Decode(&result)
106+
return result.TwinID, err
107+
}
108+
109+
func getKeyPair(seed string) (ed25519.PublicKey, ed25519.PrivateKey, error) {
110+
privateKeyBytes, err := hex.DecodeString(seed)
111+
if err != nil {
112+
return nil, nil, err
113+
}
114+
115+
privateKey := ed25519.NewKeyFromSeed(privateKeyBytes)
116+
publicKey := privateKey.Public().(ed25519.PublicKey)
117+
return publicKey, privateKey, nil
118+
}

node-registrar/cmds/farm/main.go

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,159 @@
1+
package main
2+
3+
import (
4+
"bytes"
5+
"crypto/ed25519"
6+
"encoding/base64"
7+
"encoding/hex"
8+
"encoding/json"
9+
"flag"
10+
"fmt"
11+
"net/http"
12+
"net/url"
13+
"time"
14+
15+
"github.com/rs/zerolog/log"
16+
)
17+
18+
var urls = map[string]string{
19+
"dev": "https://registrar.dev4.grid.tf/v1",
20+
"qa": "https://registrar.qa4.grid.tf/v1",
21+
"test": "https://registrar.test4.grid.tf/v1",
22+
"main": "https://registrar.prod4.grid.tf/v1",
23+
}
24+
25+
func main() {
26+
var seed string
27+
var network string
28+
var name string
29+
30+
flag.StringVar(&seed, "seed", "", "seed")
31+
flag.StringVar(&network, "network", "", "network (dev, qa, test, main)")
32+
flag.StringVar(&name, "farm_name", "", "farm name")
33+
flag.Parse()
34+
35+
u, ok := urls[network]
36+
if !ok {
37+
log.Fatal().Msgf("invalid network %s", network)
38+
}
39+
40+
publicKey, privateKey, err := getKeyPair(seed)
41+
if err != nil {
42+
log.Fatal().Err(err).Send()
43+
}
44+
45+
twinID, err := getAccount(publicKey, u)
46+
if err != nil {
47+
log.Fatal().Err(err).Send()
48+
}
49+
50+
result, err := createFarm(name, twinID, privateKey, u)
51+
if err != nil {
52+
log.Fatal().Err(err).Send()
53+
}
54+
55+
fmt.Println(result)
56+
}
57+
58+
func createFarm(name string, twinID uint64, privateKey ed25519.PrivateKey, u string) (farmID uint64, err error) {
59+
url, err := url.JoinPath(u, "farms")
60+
if err != nil {
61+
return
62+
}
63+
data := map[string]any{
64+
"farm_name": name,
65+
"twin_id": twinID,
66+
"dedicated": false,
67+
}
68+
69+
var body bytes.Buffer
70+
err = json.NewEncoder(&body).Encode(data)
71+
if err != nil {
72+
return
73+
}
74+
75+
req, err := http.NewRequest("POST", url, &body)
76+
if err != nil {
77+
return
78+
}
79+
80+
timestamp := time.Now().Unix()
81+
challenge := []byte(fmt.Sprintf("%d:%v", timestamp, twinID))
82+
signature := ed25519.Sign(privateKey, challenge)
83+
84+
authHeader := fmt.Sprintf(
85+
"%s:%s",
86+
base64.StdEncoding.EncodeToString(challenge),
87+
base64.StdEncoding.EncodeToString(signature),
88+
)
89+
req.Header.Set("X-Auth", authHeader)
90+
req.Header.Set("Content-Type", "application/json")
91+
92+
resp, err := http.DefaultClient.Do(req)
93+
if err != nil {
94+
return
95+
}
96+
97+
defer resp.Body.Close()
98+
99+
if resp.StatusCode != http.StatusCreated {
100+
return farmID, fmt.Errorf("could not create a farm")
101+
}
102+
103+
result := struct {
104+
FarmID uint64 `json:"farm_id"`
105+
}{}
106+
107+
if err = json.NewDecoder(resp.Body).Decode(&result); err != nil {
108+
return
109+
}
110+
fmt.Println(result)
111+
return result.FarmID, nil
112+
}
113+
114+
func getAccount(publicKey []byte, u string) (twinID uint64, err error) {
115+
url, err := url.JoinPath(u, "accounts")
116+
if err != nil {
117+
return
118+
}
119+
120+
publicKeyBase64 := base64.StdEncoding.EncodeToString(publicKey)
121+
122+
req, err := http.NewRequest("GET", url, nil)
123+
if err != nil {
124+
return
125+
}
126+
127+
q := req.URL.Query()
128+
q.Add("public_key", publicKeyBase64)
129+
req.URL.RawQuery = q.Encode()
130+
131+
resp, err := http.DefaultClient.Do(req)
132+
if err != nil {
133+
return
134+
}
135+
defer resp.Body.Close()
136+
137+
if resp.StatusCode != http.StatusOK {
138+
return twinID, fmt.Errorf("status code not ok")
139+
}
140+
141+
result := struct {
142+
TwinID uint64 `json:"twin_id"`
143+
}{}
144+
145+
err = json.NewDecoder(resp.Body).Decode(&result)
146+
return result.TwinID, err
147+
}
148+
149+
func getKeyPair(seed string) (ed25519.PublicKey, ed25519.PrivateKey, error) {
150+
privateKeyBytes, err := hex.DecodeString(seed)
151+
if err != nil {
152+
return nil, nil, err
153+
}
154+
155+
privateKey := ed25519.NewKeyFromSeed(privateKeyBytes)
156+
157+
publicKey := privateKey.Public().(ed25519.PublicKey)
158+
return publicKey, privateKey, nil
159+
}

0 commit comments

Comments
 (0)