2
0
mirror of https://github.com/namecoin/ncdns synced 2024-11-16 00:13:01 +00:00
ncdns/namecoin/extratypes/extratypes.go
2014-12-01 00:44:06 +00:00

277 lines
5.0 KiB
Go

// This package contains extensions to btcjson used by the namecoin package.
// It is not intended for public use.
package extratypes
import "github.com/hlandauf/btcjson"
import "encoding/json"
import "fmt"
// name_show
type NameShowCmd struct {
id interface{}
Name string `json:"name"`
}
func NewNameShowCmd(id interface{}, name string) (*NameShowCmd, error) {
return &NameShowCmd{
id: id,
Name: name,
}, nil
}
func (c *NameShowCmd) Id() interface{} {
return c.id
}
func (c *NameShowCmd) Method() string {
return "name_show"
}
func (c *NameShowCmd) MarshalJSON() ([]byte, error) {
params := []interface{}{
c.Name,
}
raw, err := btcjson.NewRawCmd(c.id, c.Method(), params)
if err != nil {
return nil, err
}
return json.Marshal(raw)
}
func (c *NameShowCmd) UnmarshalJSON(b []byte) error {
// We don't need to implement this as we are only ever the client.
panic("not implemented")
return nil
}
type NameShowReply struct {
Name string `json:"name"`
Value string `json:"value"`
ExpiresIn int `json:"expires_in"`
}
func showReplyParser(m json.RawMessage) (interface{}, error) {
nsr := &NameShowReply{}
err := json.Unmarshal(m, nsr)
if err != nil {
return nil, err
}
return nsr, nil
}
// name_sync
type NameSyncCmd struct {
id interface{}
BlockHash string `json:"hash"`
Count int
Wait bool
}
func NewNameSyncCmd(id interface{}, blockHash string, count int, wait bool) (*NameSyncCmd, error) {
return &NameSyncCmd{
id: id,
BlockHash: blockHash,
Count: count,
Wait: wait,
}, nil
}
func (c *NameSyncCmd) Id() interface{} {
return c.id
}
func (c *NameSyncCmd) Method() string {
return "name_sync"
}
func (c *NameSyncCmd) MarshalJSON() ([]byte, error) {
params := []interface{}{
c.BlockHash,
c.Count,
c.Wait,
}
raw, err := btcjson.NewRawCmd(c.id, c.Method(), params)
if err != nil {
return nil, err
}
return json.Marshal(raw)
}
func (c *NameSyncCmd) UnmarshalJSON(b []byte) error {
// We don't need to implement this as we are only ever the client.
panic("not implemented")
return nil
}
type NameSyncReply []NameSyncEvent
type NameSyncEvent struct {
Type string // "firstupdate" or "update" or "atblock"
// Used for firstupdate and update.
Name string // "d/example"
Value string // "..."
// Used for atblock.
BlockHash string // in hex
BlockHeight int
}
var errMalformed = fmt.Errorf("malformed name_sync event")
func (e *NameSyncEvent) UnmarshalJSON(data []byte) error {
a := []interface{}{}
err := json.Unmarshal(data, &a)
if err != nil {
return err
}
if len(a) < 1 {
return errMalformed
}
eventType, ok := a[0].(string)
if !ok {
return errMalformed
}
e.Type = eventType
switch eventType {
case "firstupdate", "update":
if len(a) < 3 {
return errMalformed
}
k, ok := a[1].(string)
if !ok {
return errMalformed
}
v, ok := a[2].(string)
if !ok {
return errMalformed
}
e.Name = k
e.Value = v
case "atblock":
if len(a) < 3 {
return errMalformed
}
hash, ok := a[1].(string)
if !ok {
return errMalformed
}
heightf, ok := a[2].(float64)
if !ok {
return errMalformed
}
height := int(heightf)
e.BlockHash = hash
e.BlockHeight = height
}
return nil
}
func syncReplyParser(m json.RawMessage) (interface{}, error) {
nsr := NameSyncReply{}
err := json.Unmarshal(m, &nsr)
if err != nil {
return nil, err
}
return nsr, nil
}
// name_filter
type NameFilterCmd struct {
id interface{}
Regexp string
MaxAge int
From int
Count int
}
func NewNameFilterCmd(id interface{}, regexp string, maxage, from, count int) (*NameFilterCmd, error) {
return &NameFilterCmd{
id: id,
Regexp: regexp,
MaxAge: maxage,
From: from,
Count: count,
}, nil
}
func (c *NameFilterCmd) Id() interface{} {
return c.id
}
func (c *NameFilterCmd) Method() string {
return "name_filter"
}
func (c *NameFilterCmd) MarshalJSON() ([]byte, error) {
params := []interface{}{
c.Regexp,
c.MaxAge,
c.From,
c.Count,
}
raw, err := btcjson.NewRawCmd(c.id, c.Method(), params)
if err != nil {
return nil, err
}
return json.Marshal(raw)
}
func (c *NameFilterCmd) UnmarshalJSON(b []byte) error {
// We don't need to implement this as we are only ever the client.
panic("not implemented")
return nil
}
type NameFilterReply []NameFilterItem
type NameFilterItem struct {
Name string // "d/example"
Value string // "..."
TxID string
Address string
Height int
ExpiresIn int `json:"expires_in"`
Expired bool
}
func filterReplyParser(m json.RawMessage) (interface{}, error) {
nsr := NameFilterReply{}
err := json.Unmarshal(m, &nsr)
if err != nil {
return nil, err
}
return nsr, nil
}
func init() {
btcjson.RegisterCustomCmd("name_show", nil, showReplyParser, "name_show <name>")
btcjson.RegisterCustomCmd("name_sync", nil, syncReplyParser, "name_sync <block-hash> <count> <wait?>")
btcjson.RegisterCustomCmd("name_filter", nil, filterReplyParser, "name_filter <regexp> <maxage> <from> <count>")
}
// © 2014 Hugo Landau <hlandau@devever.net> GPLv3 or later