Add support for multiple accounts on the same connection
This commit is contained in:
parent
2259b20eab
commit
4132f48a45
|
@ -0,0 +1,70 @@
|
|||
package sdk
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
)
|
||||
|
||||
// Account represents a logged in user on statusd node
|
||||
type Account struct {
|
||||
conn *SDK
|
||||
Address string
|
||||
PubKey string
|
||||
Mnemonic string
|
||||
Username string
|
||||
channels []*Channel
|
||||
}
|
||||
|
||||
// JoinPublicChannel joins a status public channel
|
||||
func (a *Account) JoinPublicChannel(channelName string) (*Channel, error) {
|
||||
symkeyResponse, err := shhGenerateSymKeyFromPasswordRequest(a.conn, []string{channelName})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
symKey := symkeyResponse.Key
|
||||
|
||||
topicID, err := a.calculatePublicChannelTopicID(channelName, symkeyResponse.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return a.Join(channelName, topicID, symKey)
|
||||
}
|
||||
|
||||
// Join joins a status channel
|
||||
func (a *Account) Join(channelName, topicID, symKey string) (*Channel, error) {
|
||||
newMessageFilterResponse, err := newShhMessageFilterFormatRequest(a.conn, []string{topicID}, symKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
filterID := newMessageFilterResponse.FilterID
|
||||
|
||||
ch := &Channel{
|
||||
account: a,
|
||||
name: channelName,
|
||||
filterID: filterID,
|
||||
topicID: topicID,
|
||||
channelKey: symKey,
|
||||
}
|
||||
a.channels = append(a.channels, ch)
|
||||
|
||||
return ch, nil
|
||||
}
|
||||
|
||||
func (a *Account) calculatePublicChannelTopicID(name string, symkey int) (topicID string, err error) {
|
||||
p := "0x" + hex.EncodeToString([]byte(name))
|
||||
web3ShaResponse, err := web3Sha3Request(a.conn, symkey, []string{p})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
topicID = web3ShaResponse.Result[0:10]
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Close all channels you're subscribed to
|
||||
func (a *Account) Close() {
|
||||
for _, ch := range a.channels {
|
||||
ch.Close()
|
||||
}
|
||||
}
|
18
chan.go
18
chan.go
|
@ -9,7 +9,7 @@ import (
|
|||
|
||||
// Channel : ...
|
||||
type Channel struct {
|
||||
conn *SDK
|
||||
account *Account
|
||||
name string
|
||||
filterID string
|
||||
channelKey string
|
||||
|
@ -52,7 +52,7 @@ func (c *Channel) NewContactKeyRequest(username string) error {
|
|||
contactRequest := fmt.Sprintf(format, ContactRequestType, username, "", "", "")
|
||||
|
||||
format = `["%s",["%s","%s",%s]`
|
||||
msg := fmt.Sprintf(format, NewContactKeyType, c.conn.address, c.topicID, contactRequest)
|
||||
msg := fmt.Sprintf(format, NewContactKeyType, c.account.Address, c.topicID, contactRequest)
|
||||
|
||||
return c.SendPostRawMsg(msg)
|
||||
}
|
||||
|
@ -60,7 +60,7 @@ func (c *Channel) NewContactKeyRequest(username string) error {
|
|||
// ContactRequest wrapped in a NewContactKey message when initiating a contact request.
|
||||
func (c *Channel) ContactRequest(username, image string) error {
|
||||
format := `["%s",["%s","%s","%s","%s"]]]`
|
||||
msg := fmt.Sprintf(format, ContactRequestType, username, image, c.conn.address, "")
|
||||
msg := fmt.Sprintf(format, ContactRequestType, username, image, c.account.Address, "")
|
||||
|
||||
return c.SendPostRawMsg(msg)
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ func (c *Channel) ContactRequest(username, image string) error {
|
|||
// Both users will therefore have the same filter.
|
||||
func (c *Channel) ConfirmedContactRequest(username, image string) error {
|
||||
format := `["%s",["%s","%s","%s","%s"]]`
|
||||
msg := fmt.Sprintf(format, ConfirmedContactRequestType, username, image, c.conn.address, "")
|
||||
msg := fmt.Sprintf(format, ConfirmedContactRequestType, username, image, c.account.Address, "")
|
||||
|
||||
return c.SendPostRawMsg(msg)
|
||||
}
|
||||
|
@ -117,16 +117,16 @@ func (c *Channel) ContactUpdateRequest(username, image string) error {
|
|||
// SendPostRawMsg sends a shh_post message with the given body.
|
||||
func (c *Channel) SendPostRawMsg(body string) error {
|
||||
param := shhPostParam{
|
||||
Signature: c.conn.address,
|
||||
Signature: c.account.Address,
|
||||
SymKeyID: c.channelKey,
|
||||
Payload: rawrChatMessage(body),
|
||||
Topic: c.topicID,
|
||||
TTL: 10,
|
||||
PowTarget: c.conn.minimumPoW,
|
||||
PowTarget: c.account.conn.minimumPoW,
|
||||
PowTime: 1,
|
||||
}
|
||||
|
||||
_, err := shhPostRequest(c.conn, []*shhPostParam{¶m})
|
||||
_, err := shhPostRequest(c.account.conn, []*shhPostParam{¶m})
|
||||
if err != nil {
|
||||
log.Println(err.Error())
|
||||
}
|
||||
|
@ -139,7 +139,7 @@ func (c *Channel) SendPostRawMsg(body string) error {
|
|||
// push notification server Public Key.
|
||||
func (c *Channel) PNBroadcastAvailabilityRequest() error {
|
||||
format := `["%s",["%s"]]`
|
||||
msg := fmt.Sprintf(format, PNBroadcastAvailabilityType, c.conn.pubkey)
|
||||
msg := fmt.Sprintf(format, PNBroadcastAvailabilityType, c.account.PubKey)
|
||||
|
||||
return c.SendPostRawMsg(msg)
|
||||
}
|
||||
|
@ -178,7 +178,7 @@ func (c *Channel) removeSubscription(sub *Subscription) {
|
|||
}
|
||||
|
||||
func (c *Channel) pollMessages() (msg *Msg) {
|
||||
res, err := shhGetFilterMessagesRequest(c.conn, []string{c.filterID})
|
||||
res, err := shhGetFilterMessagesRequest(c.account.conn, []string{c.filterID})
|
||||
if err != nil {
|
||||
log.Fatalf("Error when sending request to server: %s", err)
|
||||
return
|
||||
|
|
92
sdk.go
92
sdk.go
|
@ -1,7 +1,6 @@
|
|||
package sdk
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"log"
|
||||
)
|
||||
|
@ -14,11 +13,7 @@ type RPCClient interface {
|
|||
// SDK is a set of tools to interact with status node
|
||||
type SDK struct {
|
||||
RPCClient RPCClient
|
||||
address string
|
||||
pubkey string
|
||||
mnemonic string
|
||||
userName string
|
||||
channels []*Channel
|
||||
accounts []*Account
|
||||
minimumPoW float64
|
||||
}
|
||||
|
||||
|
@ -30,44 +25,39 @@ func New(c RPCClient) *SDK {
|
|||
}
|
||||
}
|
||||
|
||||
// Close all channels you're subscribed to
|
||||
func (c *SDK) Close() {
|
||||
for _, channel := range c.channels {
|
||||
channel.Close()
|
||||
}
|
||||
}
|
||||
|
||||
// Login to status with the given credentials
|
||||
func (c *SDK) Login(addr, pwd string) error {
|
||||
func (c *SDK) Login(addr, pwd string) (a *Account, err error) {
|
||||
res, err := statusLoginRequest(c, addr, pwd)
|
||||
if err != nil {
|
||||
return err
|
||||
return a, err
|
||||
}
|
||||
c.address = res.Result.AddressKeyID
|
||||
|
||||
return nil
|
||||
return &Account{
|
||||
Address: res.Result.AddressKeyID,
|
||||
}, err
|
||||
}
|
||||
|
||||
// Signup creates a new account with the given credentials
|
||||
func (c *SDK) Signup(pwd string) (addr string, pubkey string, mnemonic string, err error) {
|
||||
func (c *SDK) Signup(pwd string) (a *Account, err error) {
|
||||
res, err := statusSignupRequest(c, pwd)
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
return a, err
|
||||
}
|
||||
c.address = res.Result.Address
|
||||
c.pubkey = res.Result.Pubkey
|
||||
c.mnemonic = res.Result.Mnemonic
|
||||
return &Account{
|
||||
Address: res.Result.Address,
|
||||
PubKey: res.Result.Pubkey,
|
||||
Mnemonic: res.Result.Mnemonic,
|
||||
}, err
|
||||
|
||||
return res.Result.Address, res.Result.Pubkey, res.Result.Mnemonic, err
|
||||
}
|
||||
|
||||
// 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)
|
||||
func (c *SDK) SignupAndLogin(password string) (a *Account, err error) {
|
||||
a, err = c.Signup(password)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
err = c.Login(addr, password)
|
||||
la, err := c.Login(a.Address, password)
|
||||
a.Address = la.Address
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -76,54 +66,6 @@ type NewMessageFilterResponse struct {
|
|||
Result string `json:"result"`
|
||||
}
|
||||
|
||||
// JoinPublicChannel joins a status public channel
|
||||
func (c *SDK) JoinPublicChannel(channelName string) (*Channel, error) {
|
||||
symkeyResponse, err := shhGenerateSymKeyFromPasswordRequest(c, []string{channelName})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
symKey := symkeyResponse.Key
|
||||
|
||||
topicID, err := c.calculatePublicChannelTopicID(channelName, symkeyResponse.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
filterID := newMessageFilterResponse.FilterID
|
||||
|
||||
ch := &Channel{
|
||||
conn: c,
|
||||
name: channelName,
|
||||
filterID: filterID,
|
||||
topicID: topicID,
|
||||
channelKey: symKey,
|
||||
}
|
||||
c.channels = append(c.channels, ch)
|
||||
|
||||
return ch, nil
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func (c *SDK) call(cmd string, res interface{}) error {
|
||||
log.Println("[ REQUEST ] : " + cmd)
|
||||
body, err := c.RPCClient.Call(cmd)
|
||||
|
|
Loading…
Reference in New Issue