2018-04-30 15:57:11 +00:00
|
|
|
package sdk
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/hex"
|
2018-05-01 07:46:34 +00:00
|
|
|
"encoding/json"
|
|
|
|
"log"
|
2018-04-30 15:57:11 +00:00
|
|
|
)
|
|
|
|
|
2018-05-04 14:12:36 +00:00
|
|
|
// RPCClient is a client to manage all rpc calls
|
|
|
|
type RPCClient interface {
|
|
|
|
Call(request interface{}) (response interface{}, err error)
|
|
|
|
}
|
|
|
|
|
2018-04-30 17:07:36 +00:00
|
|
|
// SDK is a set of tools to interact with status node
|
|
|
|
type SDK struct {
|
|
|
|
RPCClient RPCClient
|
2018-04-30 15:57:11 +00:00
|
|
|
address string
|
2018-05-04 08:01:42 +00:00
|
|
|
pubkey string
|
|
|
|
mnemonic string
|
2018-04-30 15:57:11 +00:00
|
|
|
userName string
|
|
|
|
channels []*Channel
|
2018-05-01 07:46:34 +00:00
|
|
|
minimumPoW float64
|
2018-04-30 15:57:11 +00:00
|
|
|
}
|
|
|
|
|
2018-04-30 17:07:36 +00:00
|
|
|
// New creates a default SDK object
|
2018-05-04 13:49:23 +00:00
|
|
|
func New(c RPCClient) *SDK {
|
2018-04-30 17:07:36 +00:00
|
|
|
return &SDK{
|
2018-05-04 13:49:23 +00:00
|
|
|
RPCClient: c,
|
2018-05-01 07:46:34 +00:00
|
|
|
minimumPoW: 0.001,
|
2018-04-30 15:57:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-30 17:07:36 +00:00
|
|
|
// Close all channels you're subscribed to
|
|
|
|
func (c *SDK) Close() {
|
2018-04-30 15:57:11 +00:00
|
|
|
for _, channel := range c.channels {
|
|
|
|
channel.Close()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-30 17:07:36 +00:00
|
|
|
// Login to status with the given credentials
|
|
|
|
func (c *SDK) Login(addr, pwd string) error {
|
2018-05-03 13:24:38 +00:00
|
|
|
res, err := statusLoginRequest(c, addr, pwd)
|
|
|
|
if err != nil {
|
2018-04-30 15:57:11 +00:00
|
|
|
return err
|
|
|
|
}
|
2018-05-01 07:46:34 +00:00
|
|
|
c.address = res.Result.AddressKeyID
|
2018-04-30 15:57:11 +00:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Signup creates a new account with the given credentials
|
2018-05-01 07:46:34 +00:00
|
|
|
func (c *SDK) Signup(pwd string) (addr string, pubkey string, mnemonic string, err error) {
|
2018-05-03 13:24:38 +00:00
|
|
|
res, err := statusSignupRequest(c, pwd)
|
|
|
|
if err != nil {
|
|
|
|
return "", "", "", err
|
2018-04-30 15:57:11 +00:00
|
|
|
}
|
2018-05-04 08:01:42 +00:00
|
|
|
c.address = res.Result.Address
|
|
|
|
c.pubkey = res.Result.Pubkey
|
|
|
|
c.mnemonic = res.Result.Mnemonic
|
2018-04-30 15:57:11 +00:00
|
|
|
|
2018-05-01 07:46:34 +00:00
|
|
|
return res.Result.Address, res.Result.Pubkey, res.Result.Mnemonic, err
|
2018-04-30 15:57:11 +00:00
|
|
|
}
|
|
|
|
|
2018-05-01 07:46:34 +00:00
|
|
|
// SignupAndLogin sign up and login on status network
|
|
|
|
func (c *SDK) SignupAndLogin(password string) (addr string, pubkey string, mnemonic string, err error) {
|
|
|
|
addr, pubkey, mnemonic, err = c.Signup(password)
|
|
|
|
if err != nil {
|
|
|
|
return
|
2018-04-30 15:57:11 +00:00
|
|
|
}
|
2018-05-01 07:46:34 +00:00
|
|
|
err = c.Login(addr, password)
|
|
|
|
return
|
2018-04-30 15:57:11 +00:00
|
|
|
}
|
|
|
|
|
2018-05-01 07:46:34 +00:00
|
|
|
// NewMessageFilterResponse NewMessageFilter json response
|
|
|
|
type NewMessageFilterResponse struct {
|
|
|
|
Result string `json:"result"`
|
|
|
|
}
|
2018-04-30 15:57:11 +00:00
|
|
|
|
2018-05-01 07:46:34 +00:00
|
|
|
// JoinPublicChannel joins a status public channel
|
|
|
|
func (c *SDK) JoinPublicChannel(channelName string) (*Channel, error) {
|
2018-05-03 13:24:38 +00:00
|
|
|
symkeyResponse, err := shhGenerateSymKeyFromPasswordRequest(c, []string{channelName})
|
|
|
|
if err != nil {
|
2018-05-01 07:46:34 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
2018-05-04 13:32:09 +00:00
|
|
|
symKey := symkeyResponse.Key
|
2018-05-01 07:46:34 +00:00
|
|
|
|
2018-05-03 13:24:38 +00:00
|
|
|
topicID, err := c.calculatePublicChannelTopicID(channelName, symkeyResponse.ID)
|
|
|
|
if err != nil {
|
2018-05-01 07:46:34 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
2018-04-30 15:57:11 +00:00
|
|
|
|
2018-05-04 13:32:09 +00:00
|
|
|
return c.Join(channelName, topicID, symKey)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Join joins a status channel
|
|
|
|
func (c *SDK) Join(channelName, topicID, symKey string) (*Channel, error) {
|
|
|
|
newMessageFilterResponse, err := newShhMessageFilterFormatRequest(c, []string{topicID}, symKey)
|
2018-05-03 13:24:38 +00:00
|
|
|
if err != nil {
|
2018-05-01 07:46:34 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
2018-05-03 13:24:38 +00:00
|
|
|
|
|
|
|
filterID := newMessageFilterResponse.FilterID
|
2018-04-30 15:57:11 +00:00
|
|
|
|
2018-05-01 07:46:34 +00:00
|
|
|
ch := &Channel{
|
2018-05-03 13:24:38 +00:00
|
|
|
conn: c,
|
|
|
|
name: channelName,
|
|
|
|
filterID: filterID,
|
|
|
|
topicID: topicID,
|
2018-05-04 13:32:09 +00:00
|
|
|
channelKey: symKey,
|
2018-05-01 07:46:34 +00:00
|
|
|
}
|
|
|
|
c.channels = append(c.channels, ch)
|
|
|
|
|
|
|
|
return ch, nil
|
2018-04-30 15:57:11 +00:00
|
|
|
}
|
2018-04-30 17:07:36 +00:00
|
|
|
|
2018-05-03 13:24:38 +00:00
|
|
|
func (c *SDK) calculatePublicChannelTopicID(name string, symkey int) (topicID string, err error) {
|
|
|
|
p := "0x" + hex.EncodeToString([]byte(name))
|
|
|
|
web3ShaResponse, err := web3Sha3Request(c, symkey, []string{p})
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
topicID = web3ShaResponse.Result[0:10]
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-05-01 07:46:34 +00:00
|
|
|
func (c *SDK) call(cmd string, res interface{}) error {
|
2018-05-03 13:24:38 +00:00
|
|
|
log.Println("[ REQUEST ] : " + cmd)
|
2018-05-01 07:46:34 +00:00
|
|
|
body, err := c.RPCClient.Call(cmd)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
log.Println("[ RESPONSE ] : " + body.(string))
|
|
|
|
|
|
|
|
return json.Unmarshal([]byte(body.(string)), &res)
|
2018-04-30 17:07:36 +00:00
|
|
|
}
|