package keybase
import (
"encoding/json"
"fmt"
"os/exec"
"strings"
"samhofi.us/x/keybase/v2/types/chat1"
)
// Used for testing
var execCommand = exec . Command
// Possible MemberTypes
const (
TEAM string = "team"
USER string = "impteamnative"
)
// Possible TopicTypes
const (
DEV string = "dev"
CHAT string = "chat"
)
// New returns a new Keybase
func New ( opts ... KeybaseOpt ) * Keybase {
k := & Keybase { ExePath : "keybase" }
for _ , opt := range opts {
opt . apply ( k )
}
s := k . status ( )
k . Version = k . version ( )
k . LoggedIn = s . LoggedIn
if k . LoggedIn {
k . Username = s . Username
k . Device = s . Device . Name
}
return k
}
// NewKeybase returns a new Keybase. Optionally, you can pass a string containing the path to the Keybase executable as the first argument.
// This is deprecated and will be removed in a future update. Use New() instead.
func NewKeybase ( path ... string ) * Keybase {
k := & Keybase { }
if len ( path ) < 1 {
k . ExePath = "keybase"
} else {
k . ExePath = path [ 0 ]
}
s := k . status ( )
k . Version = k . version ( )
k . LoggedIn = s . LoggedIn
if k . LoggedIn {
k . Username = s . Username
k . Device = s . Device . Name
}
return k
}
// Exec executes the given Keybase command
func ( k * Keybase ) Exec ( command ... string ) ( [ ] byte , error ) {
cmd := make ( [ ] string , 0 )
if k . HomePath != "" {
cmd = append ( cmd , "--home" , k . HomePath )
}
cmd = append ( cmd , command ... )
out , err := execCommand ( k . ExePath , cmd ... ) . Output ( )
if err != nil {
return [ ] byte { } , err
}
return out , nil
}
// NewChat returns a new Chat instance
func ( k * Keybase ) NewChat ( channel chat1 . ChatChannel ) Chat {
return Chat {
keybase : k ,
Channel : channel ,
}
}
// NewTeam returns a new Team instance
func ( k * Keybase ) NewTeam ( name string ) Team {
return Team {
keybase : k ,
Name : name ,
}
}
// NewWallet returns a new Wallet instance
func ( k * Keybase ) NewWallet ( ) Wallet {
return Wallet {
keybase : k ,
}
}
// status returns the results of the `keybase status` command, which includes
// information about the client, and the currently logged-in Keybase user.
func ( k * Keybase ) status ( ) status {
cmdOut , err := k . Exec ( "status" , "-j" )
if err != nil {
return status { }
}
var s status
json . Unmarshal ( cmdOut , & s )
return s
}
// version returns the version string of the client.
func ( k * Keybase ) version ( ) string {
cmdOut , err := k . Exec ( "version" , "-S" , "-f" , "s" )
if err != nil {
return ""
}
return string ( cmdOut )
}
// UserLookup pulls information about users.
// The following fields are currently returned: basics, profile, proofs_summary, devices -- See https://keybase.io/docs/api/1.0/call/user/lookup for more info.
func ( k * Keybase ) UserLookup ( users ... string ) ( UserAPI , error ) {
var fields = [ ] string { "basics" , "profile" , "proofs_summary" , "devices" }
cmdOut , err := k . Exec ( "apicall" , "--arg" , fmt . Sprintf ( "usernames=%s" , strings . Join ( users , "," ) ) , "--arg" , fmt . Sprintf ( "fields=%s" , strings . Join ( fields , "," ) ) , "user/lookup" )
if err != nil {
return UserAPI { } , err
}
var r UserAPI
if err := json . Unmarshal ( cmdOut , & r ) ; err != nil {
return UserAPI { } , err
}
return r , nil
}
// UserCard pulls the information that is typically displayed when you open a user's profile.
func ( k * Keybase ) UserCard ( user string ) ( UserCardAPI , error ) {
cmdOut , err := k . Exec ( "apicall" , "--arg" , "username=" + user , "user/card" )
if err != nil {
return UserCardAPI { } , err
}
var r UserCardAPI
if err := json . Unmarshal ( cmdOut , & r ) ; err != nil {
return UserCardAPI { } , err
}
return r , nil
}