-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathsolana.go
executable file
·144 lines (125 loc) · 3.75 KB
/
solana.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
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
package main
import (
"context"
"fmt"
"log"
"github.com/dfuse-io/solana-go"
"github.com/dfuse-io/solana-go/rpc"
"github.com/mr-tron/base58"
)
type SolanaApp struct {
Account *solana.Account
PublicKey solana.PublicKey
RPC *rpc.Client
Balance *solBalance
Network *solNetwork
}
type solNetwork struct {
URL string
Prefix string
}
type solBalance struct {
Lamports uint64
Context uint64
}
func (a *App) initializeSolana(network string, privkey []byte) {
if network == "mainnet" {
a.Solana.Network = &solNetwork{
URL: "api.mainnet-beta.solana.com",
Prefix: network,
}
} else if network == "testnet" {
a.Solana.Network = &solNetwork{
URL: "testnet.solana.com",
Prefix: network,
}
} else {
a.Solana.Network = &solNetwork{
URL: "devnet.solana.com",
Prefix: network,
}
}
var err error
// setup rpc and web sockets
a.Solana.RPC = rpc.NewClient("https://" + a.Solana.Network.URL)
// get solana account from private key
var privkeyStr string = base58.Encode(privkey)
a.Solana.Account, err = solana.AccountFromPrivateKeyBase58(privkeyStr)
if err != nil {
fmt.Println("error generating key: ", err)
}
a.Solana.PublicKey = a.Solana.Account.PublicKey()
log.Printf("SOL: pubkey: https://explorer.solana.com/address/%s?cluster=%s\n", a.Solana.PublicKey, a.Solana.Network.Prefix)
}
// func (sol *SolanaApp) subscribeAccount(done <-chan struct{}) error {
// s, err := sol.WS.AccountSubscribe(sol.PublicKey, "")
// if err != nil {
// panic(err)
// }
// log.Println("SOL: subscribed to account")
// for {
// select {
// case <-done:
// log.Println("SOL: unsubscribing account")
// s.Unsubscribe()
// return nil
// default:
// _, err := s.Recv()
// if err != nil {
// fmt.Println("SOL: error receiving subscription message: ", err)
// }
// // acctResult, ok := message.(*ws.AccountResult)
// // if !ok {
// // log.Printf("error decoding msg: %+v\n", message)
// // }
// // log.Printf("msg received: %+v\n", *acctResult)
// // unmarshalling message not working so using channel as a trigger
// go sol.getAccountBalance()
// }
// }
// }
func (sol *SolanaApp) getAccountBalance() (*solBalance, error) {
acct, err := sol.RPC.GetBalance(context.Background(), fmt.Sprint(sol.PublicKey), "")
if err != nil {
log.Println("error getting acct balance: ", err)
}
sol.Balance = &solBalance{
Lamports: (uint64)(acct.Value),
Context: (uint64)(acct.Context.Slot),
}
log.Println(sol.Balance.String())
return sol.Balance, nil
}
func (sol *SolanaApp) requestAccountAirdrop(lamports uint64) (url string, err error) {
airdrop, err := sol.RPC.RequestAirdrop(context.Background(), &sol.PublicKey, lamports, rpc.CommitmentMax)
if err != nil {
return "", fmt.Errorf("error getting airdrop: %e", err)
}
url = fmt.Sprintf("https://explorer.solana.com/tx/%s?cluster=devnet", airdrop)
log.Println("SOL: requested airdrop: ", url)
return url, nil
}
// func (sol *SolanaApp) pollRPCAccount(pollRate uint, done <-chan struct{}) {
// if pollRate == 0 {
// pollRate = 30
// }
// log.Printf("polling account every %d seconds\n", pollRate)
// go func(t *time.Ticker) {
// for {
// select {
// case <-done:
// log.Println("polling stopped")
// t.Stop()
// return
// case <-t.C:
// go sol.getAccountBalance()
// }
// }
// }(time.NewTicker(time.Duration(pollRate) * time.Second))
// }
func (b solBalance) String() string {
return fmt.Sprintf("block %d: %f", b.Context, float32(b.Lamports)/float32(1000000000))
}
func (b solBalance) FancyString() string {
return fmt.Sprintf("###################### ACCOUNT BALANCE ######################\nblock %d: %f\n#############################################################", b.Context, float32(b.Lamports)/float32(1000000000))
}