diff --git a/keybase.go b/keybase.go index 975bf51..95c7b53 100644 --- a/keybase.go +++ b/keybase.go @@ -87,6 +87,14 @@ func (k *Keybase) NewTeam(name string) Team { } } +// NewKV returns a new KV instance +func (k *Keybase) NewKV(team string) KV { + return KV{ + keybase: k, + Team: team, + } +} + // NewWallet returns a new Wallet instance func (k *Keybase) NewWallet() Wallet { return Wallet{ diff --git a/kvstore.go b/kvstore.go new file mode 100644 index 0000000..a1caf81 --- /dev/null +++ b/kvstore.go @@ -0,0 +1,45 @@ +package keybase + +import ( + "encoding/json" + "errors" +) + +// kvAPIOut sends a JSON request to the kvstore API and returns its response. +func kvAPIOut(k *Keybase, kv KVAPI) (KVAPI, error) { + jsonBytes, _ := json.Marshal(kv) + + cmdOut, err := k.Exec("kvstore", "api", "-m", string(jsonBytes)) + if err != nil { + return KVAPI{}, err + } + + var r KVAPI + if err := json.Unmarshal(cmdOut, &r); err != nil { + return KVAPI{}, err + } + + if r.Error != nil { + return KVAPI{}, errors.New(r.Error.Message) + } + + return r, nil +} + +// Namespaces returns all namespaces for a team +func (kv KV) Namespaces() (KVAPI, error) { + m := KVAPI{ + Params: &kvParams{}, + } + m.Params.Options = kvOptions{ + Team: kv.Team, + } + + m.Method = "list" + + r, err := kvAPIOut(kv.keybase, m) + if err != nil { + return r, err + } + return r, nil +} diff --git a/types.go b/types.go index 1424ab7..b70d014 100644 --- a/types.go +++ b/types.go @@ -646,6 +646,32 @@ type teamInfo struct { Implicit implicit `json:"implicit,omitempty"` } +// KVAPI holds information sent and received to/from the kvstore api +type KVAPI struct { + Method string `json:"method,omitempty"` + Params *kvParams `json:"params,omitempty"` + Result *kvResult `json:"result,omitempty"` + Error *Error `json:"error"` + keybase Keybase +} + +type kvOptions struct { + Team string `json:"team,omitempty"` + Namespace string `json:"namespace,omitempty"` + EntryKey string `json:"entryKey,omitempty"` + Revision int `json:"revision,omitempty"` + EntryValue string `json:"entryValue,omitempty"` +} + +type kvParams struct { + Options kvOptions `json:"options,omitempty"` +} + +type kvResult struct { + TeamName string `json:"teamName"` + Namespaces []string `json:"namespaces"` +} + // UserAPI holds information received from the user/lookup api type UserAPI struct { Status uStatus `json:"status"` @@ -848,6 +874,16 @@ type wallet interface { TxDetail(txid string) (WalletAPI, error) } +// KV holds basic information about a KVStore +type KV struct { + keybase *Keybase + Team string +} + +type kvInterface interface { + Namespaces() (KVAPI, error) +} + type keybase interface { AdvertiseCommand(advertisement BotAdvertisement) (ChatAPI, error) AdvertiseCommands(advertisements []BotAdvertisement) (ChatAPI, error) @@ -856,6 +892,7 @@ type keybase interface { CreateTeam(name string) (TeamAPI, error) NewChat(channel Channel) Chat NewTeam(name string) Team + NewKV(team string) KV NewWallet() Wallet Run(handler func(ChatAPI), options ...RunOptions) status() status