observer-cmd-utils/utils/signed_action.go

120 lines
2.7 KiB
Go

package utils
import (
"bytes"
"git.gammaspectra.live/P2Pool/consensus/v3/monero/address"
"git.gammaspectra.live/P2Pool/consensus/v3/utils"
"github.com/goccy/go-json"
"slices"
)
type SignedActionEntry struct {
Key string `json:"key"`
Value string `json:"value"`
}
type SignedAction struct {
Action string `json:"action"`
Data []SignedActionEntry `json:"data"`
Realm string `json:"realm"`
}
func (a *SignedAction) Get(key string) (string, bool) {
if i := slices.IndexFunc(a.Data, func(entry SignedActionEntry) bool {
return entry.Key == key
}); i != -1 {
return a.Data[i].Value, true
}
return "", false
}
// String Creates a consistent string for signing
func (a *SignedAction) String() string {
if a.Data == nil {
a.Data = make([]SignedActionEntry, 0)
}
d, err := utils.MarshalJSON(a)
if err != nil {
panic(err)
}
buf := bytes.NewBuffer(make([]byte, 0, len(d)))
if err = json.Compact(buf, d); err != nil {
panic(err)
}
return buf.String()
}
func (a *SignedAction) Verify(realm string, addr address.Interface, signature string) address.SignatureVerifyResult {
if a.Realm != realm {
// Realm does not match
return address.ResultFail
}
message := a.String()
return address.VerifyMessage(addr, []byte(message), signature)
}
func (a *SignedAction) VerifyFallbackToZero(realm string, addr address.Interface, signature string) address.SignatureVerifyResult {
if a.Realm != realm {
// Realm does not match
return address.ResultFail
}
message := a.String()
return address.VerifyMessageFallbackToZero(addr, []byte(message), signature)
}
func SignedActionSetMinerAlias(realm, alias string) *SignedAction {
return &SignedAction{
Action: "set_miner_alias",
Data: []SignedActionEntry{
{
Key: "alias",
Value: alias,
},
},
Realm: realm,
}
}
func SignedActionUnsetMinerAlias(realm string) *SignedAction {
return &SignedAction{
Action: "unset_miner_alias",
Data: make([]SignedActionEntry, 0),
Realm: realm,
}
}
func SignedActionAddWebHook(realm, webhookType, webhookUrl string, other ...SignedActionEntry) *SignedAction {
return &SignedAction{
Action: "add_webhook",
Data: append([]SignedActionEntry{
{
Key: "type",
Value: webhookType,
},
{
Key: "url",
Value: webhookUrl,
},
}, other...),
Realm: realm,
}
}
func SignedActionRemoveWebHook(realm, webhookType, webhookUrlHash string, other ...SignedActionEntry) *SignedAction {
return &SignedAction{
Action: "remove_webhook",
Data: append([]SignedActionEntry{
{
Key: "type",
Value: webhookType,
},
{
Key: "url_hash",
Value: webhookUrlHash,
},
}, other...),
Realm: realm,
}
}