1199 lines
30 KiB
Go
1199 lines
30 KiB
Go
// Copyright (c) 2013 Conformal Systems LLC.
|
|
// Use of this source code is governed by an ISC
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package btcws
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"github.com/conformal/btcjson"
|
|
)
|
|
|
|
var (
|
|
// ErrNotANtfn describes an error where a JSON-RPC Request
|
|
// object cannot be successfully parsed as a notification
|
|
// due to having an ID.
|
|
ErrNotANtfn = errors.New("notifications may not have IDs")
|
|
)
|
|
|
|
const (
|
|
// AccountBalanceNtfnMethod is the method of the btcwallet
|
|
// accountbalance notification.
|
|
AccountBalanceNtfnMethod = "accountbalance"
|
|
|
|
// AllTxNtfnMethod is the method of the btcd alltx
|
|
// notification
|
|
AllTxNtfnMethod = "alltx"
|
|
|
|
// AllVerboseTxNtfnMethod is the method of the btcd
|
|
// allverbosetx notifications.
|
|
AllVerboseTxNtfnMethod = "allverbosetx"
|
|
|
|
// BlockConnectedNtfnMethod is the method of the btcd
|
|
// blockconnected notification.
|
|
BlockConnectedNtfnMethod = "blockconnected"
|
|
|
|
// BlockDisconnectedNtfnMethod is the method of the btcd
|
|
// blockdisconnected notification.
|
|
BlockDisconnectedNtfnMethod = "blockdisconnected"
|
|
|
|
// BtcdConnectedNtfnMethod is the method of the btcwallet
|
|
// btcdconnected notification.
|
|
BtcdConnectedNtfnMethod = "btcdconnected"
|
|
|
|
// RecvTxNtfnMethod is the method of the btcd recvtx notification.
|
|
RecvTxNtfnMethod = "recvtx"
|
|
|
|
// TxNtfnMethod is the method of the btcwallet newtx
|
|
// notification.
|
|
TxNtfnMethod = "newtx"
|
|
|
|
// RedeemingTxNtfnMethod is the method of the btcd redeemingtx
|
|
// notification.
|
|
RedeemingTxNtfnMethod = "redeemingtx"
|
|
|
|
// RescanProgressNtfnMethod is the method of the btcd rescanprogress
|
|
// notification.
|
|
RescanProgressNtfnMethod = "rescanprogress"
|
|
|
|
// WalletLockStateNtfnMethod is the method of the btcwallet
|
|
// walletlockstate notification.
|
|
WalletLockStateNtfnMethod = "walletlockstate"
|
|
)
|
|
|
|
// Register notifications with btcjson.
|
|
func init() {
|
|
btcjson.RegisterCustomCmd(AccountBalanceNtfnMethod,
|
|
parseAccountBalanceNtfn, `TODO(jrick) fillmein`)
|
|
btcjson.RegisterCustomCmd(BlockConnectedNtfnMethod,
|
|
parseBlockConnectedNtfn, `TODO(jrick) fillmein`)
|
|
btcjson.RegisterCustomCmd(BlockDisconnectedNtfnMethod,
|
|
parseBlockDisconnectedNtfn, `TODO(jrick) fillmein`)
|
|
btcjson.RegisterCustomCmd(BtcdConnectedNtfnMethod,
|
|
parseBtcdConnectedNtfn, `TODO(jrick) fillmein`)
|
|
btcjson.RegisterCustomCmd(RecvTxNtfnMethod,
|
|
parseRecvTxNtfn, `TODO(jrick) fillmein`)
|
|
btcjson.RegisterCustomCmd(RescanProgressNtfnMethod,
|
|
parseRescanProgressNtfn, `TODO(jrick) fillmein`)
|
|
|
|
btcjson.RegisterCustomCmd(RedeemingTxNtfnMethod, parseRedeemingTxNtfn,
|
|
`TODO(jrick) fillmein`)
|
|
btcjson.RegisterCustomCmd(TxNtfnMethod, parseTxNtfn,
|
|
`TODO(jrick) fillmein`)
|
|
btcjson.RegisterCustomCmd(WalletLockStateNtfnMethod,
|
|
parseWalletLockStateNtfn, `TODO(jrick) fillmein`)
|
|
btcjson.RegisterCustomCmd(AllTxNtfnMethod,
|
|
parseAllTxNtfn, `TODO(flam) fillmein`)
|
|
btcjson.RegisterCustomCmdGenerator(AllVerboseTxNtfnMethod,
|
|
generateAllVerboseTxNtfn)
|
|
}
|
|
|
|
// BlockDetails describes details of a tx in a block.
|
|
type BlockDetails struct {
|
|
Height int32
|
|
Hash string
|
|
Index int
|
|
Time int64
|
|
}
|
|
|
|
// AccountBalanceNtfn is a type handling custom marshaling and
|
|
// unmarshaling of accountbalance JSON websocket notifications.
|
|
type AccountBalanceNtfn struct {
|
|
Account string
|
|
Balance float64
|
|
Confirmed bool // Whether Balance is confirmed or unconfirmed.
|
|
}
|
|
|
|
// Enforce that AccountBalanceNtfn satisifes the btcjson.Cmd interface.
|
|
var _ btcjson.Cmd = &AccountBalanceNtfn{}
|
|
|
|
// NewAccountBalanceNtfn creates a new AccountBalanceNtfn.
|
|
func NewAccountBalanceNtfn(account string, balance float64,
|
|
confirmed bool) *AccountBalanceNtfn {
|
|
|
|
return &AccountBalanceNtfn{
|
|
Account: account,
|
|
Balance: balance,
|
|
Confirmed: confirmed,
|
|
}
|
|
}
|
|
|
|
// parseAccountBalanceNtfn parses a RawCmd into a concrete type satisifying
|
|
// the btcjson.Cmd interface. This is used when registering the notification
|
|
// with the btcjson parser.
|
|
func parseAccountBalanceNtfn(r *btcjson.RawCmd) (btcjson.Cmd, error) {
|
|
if r.Id != nil {
|
|
return nil, ErrNotANtfn
|
|
}
|
|
|
|
if len(r.Params) != 3 {
|
|
return nil, btcjson.ErrWrongNumberOfParams
|
|
}
|
|
|
|
account, ok := r.Params[0].(string)
|
|
if !ok {
|
|
return nil, errors.New("first parameter account must be a string")
|
|
}
|
|
balance, ok := r.Params[1].(float64)
|
|
if !ok {
|
|
return nil, errors.New("second parameter balance must be a number")
|
|
}
|
|
confirmed, ok := r.Params[2].(bool)
|
|
if !ok {
|
|
return nil, errors.New("third parameter confirmed must be a boolean")
|
|
}
|
|
|
|
return NewAccountBalanceNtfn(account, balance, confirmed), nil
|
|
}
|
|
|
|
// Id satisifies the btcjson.Cmd interface by returning nil for a
|
|
// notification ID.
|
|
func (n *AccountBalanceNtfn) Id() interface{} {
|
|
return nil
|
|
}
|
|
|
|
// SetId is implemented to satisify the btcjson.Cmd interface. The
|
|
// notification id is not modified.
|
|
func (n *AccountBalanceNtfn) SetId(id interface{}) {}
|
|
|
|
// Method satisifies the btcjson.Cmd interface by returning the method
|
|
// of the notification.
|
|
func (n *AccountBalanceNtfn) Method() string {
|
|
return AccountBalanceNtfnMethod
|
|
}
|
|
|
|
// MarshalJSON returns the JSON encoding of n. Part of the btcjson.Cmd
|
|
// interface.
|
|
func (n *AccountBalanceNtfn) MarshalJSON() ([]byte, error) {
|
|
ntfn := btcjson.Message{
|
|
Jsonrpc: "1.0",
|
|
Method: n.Method(),
|
|
Params: []interface{}{
|
|
n.Account,
|
|
n.Balance,
|
|
n.Confirmed,
|
|
},
|
|
}
|
|
return json.Marshal(ntfn)
|
|
}
|
|
|
|
// UnmarshalJSON unmarshals the JSON encoding of n into n. Part of
|
|
// the btcjson.Cmd interface.
|
|
func (n *AccountBalanceNtfn) UnmarshalJSON(b []byte) error {
|
|
// Unmarshal into a RawCmd.
|
|
var r btcjson.RawCmd
|
|
if err := json.Unmarshal(b, &r); err != nil {
|
|
return err
|
|
}
|
|
|
|
newNtfn, err := parseAccountBalanceNtfn(&r)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
concreteNtfn, ok := newNtfn.(*AccountBalanceNtfn)
|
|
if !ok {
|
|
return btcjson.ErrInternal
|
|
}
|
|
*n = *concreteNtfn
|
|
return nil
|
|
}
|
|
|
|
// BlockConnectedNtfn is a type handling custom marshaling and
|
|
// unmarshaling of blockconnected JSON websocket notifications.
|
|
type BlockConnectedNtfn struct {
|
|
Hash string
|
|
Height int32
|
|
}
|
|
|
|
// Enforce that BlockConnectedNtfn satisfies the btcjson.Cmd interface.
|
|
var _ btcjson.Cmd = &BlockConnectedNtfn{}
|
|
|
|
// NewBlockConnectedNtfn creates a new BlockConnectedNtfn.
|
|
func NewBlockConnectedNtfn(hash string, height int32) *BlockConnectedNtfn {
|
|
return &BlockConnectedNtfn{
|
|
Hash: hash,
|
|
Height: height,
|
|
}
|
|
}
|
|
|
|
// parseBlockConnectedNtfn parses a RawCmd into a concrete type satisifying
|
|
// the btcjson.Cmd interface. This is used when registering the notification
|
|
// with the btcjson parser.
|
|
func parseBlockConnectedNtfn(r *btcjson.RawCmd) (btcjson.Cmd, error) {
|
|
if r.Id != nil {
|
|
return nil, ErrNotANtfn
|
|
}
|
|
|
|
if len(r.Params) != 2 {
|
|
return nil, btcjson.ErrWrongNumberOfParams
|
|
}
|
|
|
|
hash, ok := r.Params[0].(string)
|
|
if !ok {
|
|
return nil, errors.New("first parameter hash must be a string")
|
|
}
|
|
fheight, ok := r.Params[1].(float64)
|
|
if !ok {
|
|
return nil, errors.New("second parameter height must be a number")
|
|
}
|
|
|
|
return NewBlockConnectedNtfn(hash, int32(fheight)), nil
|
|
}
|
|
|
|
// Id satisifies the btcjson.Cmd interface by returning nil for a
|
|
// notification ID.
|
|
func (n *BlockConnectedNtfn) Id() interface{} {
|
|
return nil
|
|
}
|
|
|
|
// SetId is implemented to satisify the btcjson.Cmd interface. The
|
|
// notification id is not modified.
|
|
func (n *BlockConnectedNtfn) SetId(id interface{}) {}
|
|
|
|
// Method satisifies the btcjson.Cmd interface by returning the method
|
|
// of the notification.
|
|
func (n *BlockConnectedNtfn) Method() string {
|
|
return BlockConnectedNtfnMethod
|
|
}
|
|
|
|
// MarshalJSON returns the JSON encoding of n. Part of the btcjson.Cmd
|
|
// interface.
|
|
func (n *BlockConnectedNtfn) MarshalJSON() ([]byte, error) {
|
|
ntfn := btcjson.Message{
|
|
Jsonrpc: "1.0",
|
|
Method: n.Method(),
|
|
Params: []interface{}{
|
|
n.Hash,
|
|
n.Height,
|
|
},
|
|
}
|
|
return json.Marshal(ntfn)
|
|
}
|
|
|
|
// UnmarshalJSON unmarshals the JSON encoding of n into n. Part of
|
|
// the btcjson.Cmd interface.
|
|
func (n *BlockConnectedNtfn) UnmarshalJSON(b []byte) error {
|
|
// Unmarshal into a RawCmd.
|
|
var r btcjson.RawCmd
|
|
if err := json.Unmarshal(b, &r); err != nil {
|
|
return err
|
|
}
|
|
|
|
newNtfn, err := parseBlockConnectedNtfn(&r)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
concreteNtfn, ok := newNtfn.(*BlockConnectedNtfn)
|
|
if !ok {
|
|
return btcjson.ErrInternal
|
|
}
|
|
*n = *concreteNtfn
|
|
return nil
|
|
}
|
|
|
|
// BlockDisconnectedNtfn is a type handling custom marshaling and
|
|
// unmarshaling of blockdisconnected JSON websocket notifications.
|
|
type BlockDisconnectedNtfn struct {
|
|
Hash string
|
|
Height int32
|
|
}
|
|
|
|
// Enforce that BlockDisconnectedNtfn satisfies the btcjson.Cmd interface.
|
|
var _ btcjson.Cmd = &BlockDisconnectedNtfn{}
|
|
|
|
// NewBlockDisconnectedNtfn creates a new BlockDisconnectedNtfn.
|
|
func NewBlockDisconnectedNtfn(hash string, height int32) *BlockDisconnectedNtfn {
|
|
return &BlockDisconnectedNtfn{
|
|
Hash: hash,
|
|
Height: height,
|
|
}
|
|
}
|
|
|
|
// parseBlockDisconnectedNtfn parses a RawCmd into a concrete type satisifying
|
|
// the btcjson.Cmd interface. This is used when registering the notification
|
|
// with the btcjson parser.
|
|
func parseBlockDisconnectedNtfn(r *btcjson.RawCmd) (btcjson.Cmd, error) {
|
|
if r.Id != nil {
|
|
return nil, ErrNotANtfn
|
|
}
|
|
|
|
if len(r.Params) != 2 {
|
|
return nil, btcjson.ErrWrongNumberOfParams
|
|
}
|
|
|
|
hash, ok := r.Params[0].(string)
|
|
if !ok {
|
|
return nil, errors.New("first parameter hash must be a string")
|
|
}
|
|
fheight, ok := r.Params[1].(float64)
|
|
if !ok {
|
|
return nil, errors.New("second parameter height must be a number")
|
|
}
|
|
|
|
return NewBlockDisconnectedNtfn(hash, int32(fheight)), nil
|
|
}
|
|
|
|
// Id satisifies the btcjson.Cmd interface by returning nil for a
|
|
// notification ID.
|
|
func (n *BlockDisconnectedNtfn) Id() interface{} {
|
|
return nil
|
|
}
|
|
|
|
// SetId is implemented to satisify the btcjson.Cmd interface. The
|
|
// notification id is not modified.
|
|
func (n *BlockDisconnectedNtfn) SetId(id interface{}) {}
|
|
|
|
// Method satisifies the btcjson.Cmd interface by returning the method
|
|
// of the notification.
|
|
func (n *BlockDisconnectedNtfn) Method() string {
|
|
return BlockDisconnectedNtfnMethod
|
|
}
|
|
|
|
// MarshalJSON returns the JSON encoding of n. Part of the btcjson.Cmd
|
|
// interface.
|
|
func (n *BlockDisconnectedNtfn) MarshalJSON() ([]byte, error) {
|
|
ntfn := btcjson.Message{
|
|
Jsonrpc: "1.0",
|
|
Method: n.Method(),
|
|
Params: []interface{}{
|
|
n.Hash,
|
|
n.Height,
|
|
},
|
|
}
|
|
return json.Marshal(ntfn)
|
|
}
|
|
|
|
// UnmarshalJSON unmarshals the JSON encoding of n into n. Part of
|
|
// the btcjson.Cmd interface.
|
|
func (n *BlockDisconnectedNtfn) UnmarshalJSON(b []byte) error {
|
|
// Unmarshal into a RawCmd.
|
|
var r btcjson.RawCmd
|
|
if err := json.Unmarshal(b, &r); err != nil {
|
|
return err
|
|
}
|
|
|
|
newNtfn, err := parseBlockDisconnectedNtfn(&r)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
concreteNtfn, ok := newNtfn.(*BlockDisconnectedNtfn)
|
|
if !ok {
|
|
return btcjson.ErrInternal
|
|
}
|
|
*n = *concreteNtfn
|
|
return nil
|
|
}
|
|
|
|
// BtcdConnectedNtfn is a type handling custom marshaling and
|
|
// unmarshaling of btcdconnected JSON websocket notifications.
|
|
type BtcdConnectedNtfn struct {
|
|
Connected bool
|
|
}
|
|
|
|
// Enforce that BtcdConnectedNtfn satisifies the btcjson.Cmd
|
|
// interface.
|
|
var _ btcjson.Cmd = &BtcdConnectedNtfn{}
|
|
|
|
// NewBtcdConnectedNtfn creates a new BtcdConnectedNtfn.
|
|
func NewBtcdConnectedNtfn(connected bool) *BtcdConnectedNtfn {
|
|
return &BtcdConnectedNtfn{connected}
|
|
}
|
|
|
|
// parseBtcdConnectedNtfn parses a RawCmd into a concrete type satisifying
|
|
// the btcjson.Cmd interface. This is used when registering the notification
|
|
// with the btcjson parser.
|
|
func parseBtcdConnectedNtfn(r *btcjson.RawCmd) (btcjson.Cmd, error) {
|
|
if r.Id != nil {
|
|
return nil, ErrNotANtfn
|
|
}
|
|
|
|
if len(r.Params) != 1 {
|
|
return nil, btcjson.ErrWrongNumberOfParams
|
|
}
|
|
|
|
connected, ok := r.Params[0].(bool)
|
|
if !ok {
|
|
return nil, errors.New("first parameter connected is not a boolean")
|
|
}
|
|
|
|
return NewBtcdConnectedNtfn(connected), nil
|
|
}
|
|
|
|
// Id satisifies the btcjson.Cmd interface by returning nil for a
|
|
// notification ID.
|
|
func (n *BtcdConnectedNtfn) Id() interface{} {
|
|
return nil
|
|
}
|
|
|
|
// SetId is implemented to satisify the btcjson.Cmd interface. The
|
|
// notification id is not modified.
|
|
func (n *BtcdConnectedNtfn) SetId(id interface{}) {}
|
|
|
|
// Method satisifies the btcjson.Cmd interface by returning the method
|
|
// of the notification.
|
|
func (n *BtcdConnectedNtfn) Method() string {
|
|
return BtcdConnectedNtfnMethod
|
|
}
|
|
|
|
// MarshalJSON returns the JSON encoding of n. Part of the btcjson.Cmd
|
|
// interface.
|
|
func (n *BtcdConnectedNtfn) MarshalJSON() ([]byte, error) {
|
|
ntfn := btcjson.Message{
|
|
Jsonrpc: "1.0",
|
|
Method: n.Method(),
|
|
Params: []interface{}{
|
|
n.Connected,
|
|
},
|
|
}
|
|
return json.Marshal(ntfn)
|
|
}
|
|
|
|
// UnmarshalJSON unmarshals the JSON encoding of n into n. Part of
|
|
// the btcjson.Cmd interface.
|
|
func (n *BtcdConnectedNtfn) UnmarshalJSON(b []byte) error {
|
|
// Unmarshal into a RawCmd.
|
|
var r btcjson.RawCmd
|
|
if err := json.Unmarshal(b, &r); err != nil {
|
|
return err
|
|
}
|
|
|
|
newNtfn, err := parseBtcdConnectedNtfn(&r)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
concreteNtfn, ok := newNtfn.(*BtcdConnectedNtfn)
|
|
if !ok {
|
|
return btcjson.ErrInternal
|
|
}
|
|
*n = *concreteNtfn
|
|
return nil
|
|
}
|
|
|
|
// RecvTxNtfn is a type handling custom marshaling and unmarshaling
|
|
// of recvtx JSON websocket notifications.
|
|
type RecvTxNtfn struct {
|
|
HexTx string
|
|
Block *BlockDetails
|
|
}
|
|
|
|
// Enforce that RecvTxNtfn satisifies the btcjson.Cmd interface.
|
|
var _ btcjson.Cmd = &RecvTxNtfn{}
|
|
|
|
// NewRecvTxNtfn creates a new RecvTxNtfn.
|
|
func NewRecvTxNtfn(hextx string, block *BlockDetails) *RecvTxNtfn {
|
|
return &RecvTxNtfn{
|
|
HexTx: hextx,
|
|
Block: block,
|
|
}
|
|
}
|
|
|
|
// parsRecvTxNtfn parses a RawCmd into a concrete type satisifying the
|
|
// btcjson.Cmd interface. This is used when registering the notification with
|
|
// the btcjson parser.
|
|
func parseRecvTxNtfn(r *btcjson.RawCmd) (btcjson.Cmd, error) {
|
|
if r.Id != nil {
|
|
return nil, ErrNotANtfn
|
|
}
|
|
|
|
// Must have one or two parameters.
|
|
if len(r.Params) == 0 || len(r.Params) > 2 {
|
|
return nil, btcjson.ErrWrongNumberOfParams
|
|
}
|
|
|
|
hextx, ok := r.Params[0].(string)
|
|
if !ok {
|
|
return nil, errors.New("first parameter hextx must be a string")
|
|
}
|
|
|
|
ntfn := &RecvTxNtfn{HexTx: hextx}
|
|
|
|
if len(r.Params) > 1 {
|
|
details, ok := r.Params[1].(map[string]interface{})
|
|
if !ok {
|
|
return nil, errors.New("second parameter must be a JSON object")
|
|
}
|
|
|
|
height, ok := details["height"].(float64)
|
|
if !ok {
|
|
return nil, errors.New("unspecified block height")
|
|
}
|
|
|
|
hash, ok := details["hash"].(string)
|
|
if !ok {
|
|
return nil, errors.New("unspecified block hash")
|
|
}
|
|
|
|
index, ok := details["index"].(float64)
|
|
if !ok {
|
|
return nil, errors.New("unspecified block index")
|
|
}
|
|
|
|
time, ok := details["time"].(float64)
|
|
if !ok {
|
|
return nil, errors.New("unspecified block time")
|
|
}
|
|
|
|
ntfn.Block = &BlockDetails{
|
|
Height: int32(height),
|
|
Hash: hash,
|
|
Index: int(index),
|
|
Time: int64(time),
|
|
}
|
|
}
|
|
|
|
return ntfn, nil
|
|
}
|
|
|
|
// Id satisifies the btcjson.Cmd interface by returning nil for a
|
|
// notification ID.
|
|
func (n *RecvTxNtfn) Id() interface{} {
|
|
return nil
|
|
}
|
|
|
|
// SetId is implemented to satisify the btcjson.Cmd interface. The
|
|
// notification id is not modified.
|
|
func (n *RecvTxNtfn) SetId(id interface{}) {}
|
|
|
|
// Method satisifies the btcjson.Cmd interface by returning the method
|
|
// of the notification.
|
|
func (n *RecvTxNtfn) Method() string {
|
|
return RecvTxNtfnMethod
|
|
}
|
|
|
|
// MarshalJSON returns the JSON encoding of n. Part of the btcjson.Cmd
|
|
// interface.
|
|
func (n *RecvTxNtfn) MarshalJSON() ([]byte, error) {
|
|
params := []interface{}{n.HexTx}
|
|
|
|
if n.Block != nil {
|
|
details := map[string]interface{}{
|
|
"height": float64(n.Block.Height),
|
|
"hash": n.Block.Hash,
|
|
"index": float64(n.Block.Index),
|
|
"time": float64(n.Block.Time),
|
|
}
|
|
params = append(params, details)
|
|
}
|
|
|
|
ntfn := btcjson.Message{
|
|
Jsonrpc: "1.0",
|
|
Method: n.Method(),
|
|
Params: params,
|
|
}
|
|
|
|
return json.Marshal(ntfn)
|
|
}
|
|
|
|
// UnmarshalJSON unmarshals the JSON encoding of n into n. Part of
|
|
// the btcjson.Cmd interface.
|
|
func (n *RecvTxNtfn) UnmarshalJSON(b []byte) error {
|
|
// Unmarshal into a RawCmd.
|
|
var r btcjson.RawCmd
|
|
if err := json.Unmarshal(b, &r); err != nil {
|
|
return err
|
|
}
|
|
|
|
newNtfn, err := parseRecvTxNtfn(&r)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
concreteNtfn, ok := newNtfn.(*RecvTxNtfn)
|
|
if !ok {
|
|
return btcjson.ErrInternal
|
|
}
|
|
*n = *concreteNtfn
|
|
return nil
|
|
}
|
|
|
|
// RedeemingTxNtfn is a type handling custom marshaling and unmarshaling
|
|
// of redeemingtx JSON websocket notifications.
|
|
type RedeemingTxNtfn struct {
|
|
HexTx string
|
|
Block *BlockDetails
|
|
}
|
|
|
|
// Enforce that RedeemingTxNtfn satisifies the btcjson.Cmd interface.
|
|
var _ btcjson.Cmd = &RedeemingTxNtfn{}
|
|
|
|
// NewRedeemingTxNtfn creates a new RedeemingTxNtfn.
|
|
func NewRedeemingTxNtfn(hextx string, block *BlockDetails) *RedeemingTxNtfn {
|
|
return &RedeemingTxNtfn{
|
|
HexTx: hextx,
|
|
Block: block,
|
|
}
|
|
}
|
|
|
|
// parseRedeemingTxNtfn parses a RawCmd into a concrete type satisifying the
|
|
// btcjson.Cmd interface. This is used when registering the notification with
|
|
// the btcjson parser.
|
|
func parseRedeemingTxNtfn(r *btcjson.RawCmd) (btcjson.Cmd, error) {
|
|
if r.Id != nil {
|
|
return nil, ErrNotANtfn
|
|
}
|
|
|
|
// Must have one or two parameters.
|
|
if len(r.Params) == 0 || len(r.Params) > 2 {
|
|
return nil, btcjson.ErrWrongNumberOfParams
|
|
}
|
|
|
|
hextx, ok := r.Params[0].(string)
|
|
if !ok {
|
|
return nil, errors.New("first parameter hextx must be a string")
|
|
}
|
|
|
|
ntfn := &RedeemingTxNtfn{HexTx: hextx}
|
|
|
|
if len(r.Params) > 1 {
|
|
details, ok := r.Params[1].(map[string]interface{})
|
|
if !ok {
|
|
return nil, errors.New("second parameter must be a JSON object")
|
|
}
|
|
|
|
height, ok := details["height"].(float64)
|
|
if !ok {
|
|
return nil, errors.New("unspecified block height")
|
|
}
|
|
|
|
hash, ok := details["hash"].(string)
|
|
if !ok {
|
|
return nil, errors.New("unspecified block hash")
|
|
}
|
|
|
|
index, ok := details["index"].(float64)
|
|
if !ok {
|
|
return nil, errors.New("unspecified block index")
|
|
}
|
|
|
|
time, ok := details["time"].(float64)
|
|
if !ok {
|
|
return nil, errors.New("unspecified block time")
|
|
}
|
|
|
|
ntfn.Block = &BlockDetails{
|
|
Height: int32(height),
|
|
Hash: hash,
|
|
Index: int(index),
|
|
Time: int64(time),
|
|
}
|
|
}
|
|
|
|
return ntfn, nil
|
|
}
|
|
|
|
// Id satisifies the btcjson.Cmd interface by returning nil for a
|
|
// notification ID.
|
|
func (n *RedeemingTxNtfn) Id() interface{} {
|
|
return nil
|
|
}
|
|
|
|
// SetId is implemented to satisify the btcjson.Cmd interface. The
|
|
// notification id is not modified.
|
|
func (n *RedeemingTxNtfn) SetId(id interface{}) {}
|
|
|
|
// Method satisifies the btcjson.Cmd interface by returning the method
|
|
// of the notification.
|
|
func (n *RedeemingTxNtfn) Method() string {
|
|
return RedeemingTxNtfnMethod
|
|
}
|
|
|
|
// MarshalJSON returns the JSON encoding of n. Part of the btcjson.Cmd
|
|
// interface.
|
|
func (n *RedeemingTxNtfn) MarshalJSON() ([]byte, error) {
|
|
params := []interface{}{n.HexTx}
|
|
|
|
if n.Block != nil {
|
|
details := map[string]interface{}{
|
|
"height": float64(n.Block.Height),
|
|
"hash": n.Block.Hash,
|
|
"index": float64(n.Block.Index),
|
|
"time": float64(n.Block.Time),
|
|
}
|
|
params = append(params, details)
|
|
}
|
|
|
|
ntfn := btcjson.Message{
|
|
Jsonrpc: "1.0",
|
|
Method: n.Method(),
|
|
Params: params,
|
|
}
|
|
|
|
return json.Marshal(ntfn)
|
|
}
|
|
|
|
// UnmarshalJSON unmarshals the JSON encoding of n into n. Part of
|
|
// the btcjson.Cmd interface.
|
|
func (n *RedeemingTxNtfn) UnmarshalJSON(b []byte) error {
|
|
// Unmarshal into a RawCmd.
|
|
var r btcjson.RawCmd
|
|
if err := json.Unmarshal(b, &r); err != nil {
|
|
return err
|
|
}
|
|
|
|
newNtfn, err := parseRedeemingTxNtfn(&r)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
concreteNtfn, ok := newNtfn.(*RedeemingTxNtfn)
|
|
if !ok {
|
|
return btcjson.ErrInternal
|
|
}
|
|
*n = *concreteNtfn
|
|
return nil
|
|
}
|
|
|
|
// RescanProgressNtfn is type handling custom marshaling and
|
|
// unmarshaling of rescanprogress JSON websocket notifications.
|
|
type RescanProgressNtfn struct {
|
|
LastProcessed int32
|
|
}
|
|
|
|
// Enforce that RescanProgressNtfn satisifies the btcjson.Cmd interface.
|
|
var _ btcjson.Cmd = &RescanProgressNtfn{}
|
|
|
|
// NewRescanProgressNtfn creates a new RescanProgressNtfn.
|
|
func NewRescanProgressNtfn(last int32) *RescanProgressNtfn {
|
|
return &RescanProgressNtfn{last}
|
|
}
|
|
|
|
// parseRescanProgressNtfn parses a RawCmd into a concrete type satisifying
|
|
// the btcjson.Cmd interface. This is used when registering the notification
|
|
// with the btcjson parser.
|
|
func parseRescanProgressNtfn(r *btcjson.RawCmd) (btcjson.Cmd, error) {
|
|
if r.Id != nil {
|
|
return nil, ErrNotANtfn
|
|
}
|
|
|
|
if len(r.Params) != 1 {
|
|
return nil, btcjson.ErrWrongNumberOfParams
|
|
}
|
|
|
|
last, ok := r.Params[0].(float64)
|
|
if !ok {
|
|
return nil, errors.New("first parameter must be a number")
|
|
}
|
|
|
|
return NewRescanProgressNtfn(int32(last)), nil
|
|
}
|
|
|
|
// Id satisifies the btcjson.Cmd interface by returning nil for a
|
|
// notification ID.
|
|
func (n *RescanProgressNtfn) Id() interface{} {
|
|
return nil
|
|
}
|
|
|
|
// SetId is implemented to satisify the btcjson.Cmd interface. The
|
|
// notification ID is not modified.
|
|
func (n *RescanProgressNtfn) SetId(id interface{}) {}
|
|
|
|
// Method satisifies the btcjson.Cmd interface by returning the method
|
|
// of the notification.
|
|
func (n *RescanProgressNtfn) Method() string {
|
|
return RescanProgressNtfnMethod
|
|
}
|
|
|
|
// MarshalJSON returns the JSON encoding of n. Part of the btcjson.Cmd
|
|
// interface.
|
|
func (n *RescanProgressNtfn) MarshalJSON() ([]byte, error) {
|
|
ntfn := btcjson.Message{
|
|
Jsonrpc: "1.0",
|
|
Method: n.Method(),
|
|
Params: []interface{}{n.LastProcessed},
|
|
}
|
|
return json.Marshal(ntfn)
|
|
}
|
|
|
|
// UnmarshalJSON unmarshals the JSON encoding of n into n. Part of
|
|
// the btcjson.Cmd interface.
|
|
func (n *RescanProgressNtfn) UnmarshalJSON(b []byte) error {
|
|
// Unmarshal into a RawCmd.
|
|
var r btcjson.RawCmd
|
|
if err := json.Unmarshal(b, &r); err != nil {
|
|
return err
|
|
}
|
|
|
|
newNtfn, err := parseRescanProgressNtfn(&r)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
concreteNtfn, ok := newNtfn.(*RescanProgressNtfn)
|
|
if !ok {
|
|
return btcjson.ErrInternal
|
|
}
|
|
*n = *concreteNtfn
|
|
return nil
|
|
}
|
|
|
|
// TxNtfn is a type handling custom marshaling and
|
|
// unmarshaling of newtx JSON websocket notifications.
|
|
type TxNtfn struct {
|
|
Account string
|
|
Details map[string]interface{}
|
|
}
|
|
|
|
// Enforce that TxNtfn satisifies the btcjson.Cmd interface.
|
|
var _ btcjson.Cmd = &TxNtfn{}
|
|
|
|
// NewTxNtfn creates a new TxNtfn.
|
|
func NewTxNtfn(account string, details map[string]interface{}) *TxNtfn {
|
|
return &TxNtfn{
|
|
Account: account,
|
|
Details: details,
|
|
}
|
|
}
|
|
|
|
// parseTxNtfn parses a RawCmd into a concrete type satisifying
|
|
// the btcjson.Cmd interface. This is used when registering the notification
|
|
// with the btcjson parser.
|
|
func parseTxNtfn(r *btcjson.RawCmd) (btcjson.Cmd, error) {
|
|
if r.Id != nil {
|
|
return nil, ErrNotANtfn
|
|
}
|
|
|
|
if len(r.Params) != 2 {
|
|
return nil, btcjson.ErrWrongNumberOfParams
|
|
}
|
|
|
|
account, ok := r.Params[0].(string)
|
|
if !ok {
|
|
return nil, errors.New("first parameter account must be a string")
|
|
}
|
|
details, ok := r.Params[1].(map[string]interface{})
|
|
if !ok {
|
|
return nil, errors.New("second parameter details must be a JSON object")
|
|
}
|
|
|
|
return NewTxNtfn(account, details), nil
|
|
}
|
|
|
|
// Id satisifies the btcjson.Cmd interface by returning nil for a
|
|
// notification ID.
|
|
func (n *TxNtfn) Id() interface{} {
|
|
return nil
|
|
}
|
|
|
|
// SetId is implemented to satisify the btcjson.Cmd interface. The
|
|
// notification id is not modified.
|
|
func (n *TxNtfn) SetId(id interface{}) {}
|
|
|
|
// Method satisifies the btcjson.Cmd interface by returning the method
|
|
// of the notification.
|
|
func (n *TxNtfn) Method() string {
|
|
return TxNtfnMethod
|
|
}
|
|
|
|
// MarshalJSON returns the JSON encoding of n. Part of the btcjson.Cmd
|
|
// interface.
|
|
func (n *TxNtfn) MarshalJSON() ([]byte, error) {
|
|
ntfn := btcjson.Message{
|
|
Jsonrpc: "1.0",
|
|
Method: n.Method(),
|
|
Params: []interface{}{
|
|
n.Account,
|
|
n.Details,
|
|
},
|
|
}
|
|
return json.Marshal(ntfn)
|
|
}
|
|
|
|
// UnmarshalJSON unmarshals the JSON encoding of n into n. Part of
|
|
// the btcjson.Cmd interface.
|
|
func (n *TxNtfn) UnmarshalJSON(b []byte) error {
|
|
// Unmarshal into a RawCmd.
|
|
var r btcjson.RawCmd
|
|
if err := json.Unmarshal(b, &r); err != nil {
|
|
return err
|
|
}
|
|
|
|
newNtfn, err := parseTxNtfn(&r)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
concreteNtfn, ok := newNtfn.(*TxNtfn)
|
|
if !ok {
|
|
return btcjson.ErrInternal
|
|
}
|
|
*n = *concreteNtfn
|
|
return nil
|
|
}
|
|
|
|
// WalletLockStateNtfn is a type handling custom marshaling and
|
|
// unmarshaling of walletlockstate JSON websocket notifications.
|
|
type WalletLockStateNtfn struct {
|
|
Account string
|
|
Locked bool
|
|
}
|
|
|
|
// Enforce that WalletLockStateNtfnMethod satisifies the btcjson.Cmd
|
|
// interface.
|
|
var _ btcjson.Cmd = &WalletLockStateNtfn{}
|
|
|
|
// NewWalletLockStateNtfn creates a new WalletLockStateNtfn.
|
|
func NewWalletLockStateNtfn(account string,
|
|
locked bool) *WalletLockStateNtfn {
|
|
|
|
return &WalletLockStateNtfn{
|
|
Account: account,
|
|
Locked: locked,
|
|
}
|
|
}
|
|
|
|
// parseWalletLockStateNtfn parses a RawCmd into a concrete type
|
|
// satisifying the btcjson.Cmd interface. This is used when registering
|
|
// the notification with the btcjson parser.
|
|
func parseWalletLockStateNtfn(r *btcjson.RawCmd) (btcjson.Cmd, error) {
|
|
if r.Id != nil {
|
|
return nil, ErrNotANtfn
|
|
}
|
|
|
|
if len(r.Params) != 2 {
|
|
return nil, btcjson.ErrWrongNumberOfParams
|
|
}
|
|
|
|
account, ok := r.Params[0].(string)
|
|
if !ok {
|
|
return nil, errors.New("first parameter account must be a string")
|
|
}
|
|
locked, ok := r.Params[1].(bool)
|
|
if !ok {
|
|
return nil, errors.New("second parameter locked must be a boolean")
|
|
}
|
|
|
|
return NewWalletLockStateNtfn(account, locked), nil
|
|
}
|
|
|
|
// Id satisifies the btcjson.Cmd interface by returning nil for a
|
|
// notification ID.
|
|
func (n *WalletLockStateNtfn) Id() interface{} {
|
|
return nil
|
|
}
|
|
|
|
// SetId is implemented to satisify the btcjson.Cmd interface. The
|
|
// notification id is not modified.
|
|
func (n *WalletLockStateNtfn) SetId(id interface{}) {}
|
|
|
|
// Method satisifies the btcjson.Cmd interface by returning the method
|
|
// of the notification.
|
|
func (n *WalletLockStateNtfn) Method() string {
|
|
return WalletLockStateNtfnMethod
|
|
}
|
|
|
|
// MarshalJSON returns the JSON encoding of n. Part of the btcjson.Cmd
|
|
// interface.
|
|
func (n *WalletLockStateNtfn) MarshalJSON() ([]byte, error) {
|
|
ntfn := btcjson.Message{
|
|
Jsonrpc: "1.0",
|
|
Method: n.Method(),
|
|
Params: []interface{}{
|
|
n.Account,
|
|
n.Locked,
|
|
},
|
|
}
|
|
return json.Marshal(ntfn)
|
|
}
|
|
|
|
// UnmarshalJSON unmarshals the JSON encoding of n into n. Part of
|
|
// the btcjson.Cmd interface.
|
|
func (n *WalletLockStateNtfn) UnmarshalJSON(b []byte) error {
|
|
// Unmarshal into a RawCmd.
|
|
var r btcjson.RawCmd
|
|
if err := json.Unmarshal(b, &r); err != nil {
|
|
return err
|
|
}
|
|
|
|
newNtfn, err := parseWalletLockStateNtfn(&r)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
concreteNtfn, ok := newNtfn.(*WalletLockStateNtfn)
|
|
if !ok {
|
|
return btcjson.ErrInternal
|
|
}
|
|
*n = *concreteNtfn
|
|
return nil
|
|
}
|
|
|
|
// AllTxNtfn is a type handling custom marshaling and
|
|
// unmarshaling of txmined JSON websocket notifications.
|
|
type AllTxNtfn struct {
|
|
TxID string `json:"txid"`
|
|
Amount int64 `json:"amount"`
|
|
}
|
|
|
|
// Enforce that AllTxNtfn satisifies the btcjson.Cmd interface.
|
|
var _ btcjson.Cmd = &AllTxNtfn{}
|
|
|
|
// NewAllTxNtfn creates a new AllTxNtfn.
|
|
func NewAllTxNtfn(txid string, amount int64) *AllTxNtfn {
|
|
return &AllTxNtfn{
|
|
TxID: txid,
|
|
Amount: amount,
|
|
}
|
|
}
|
|
|
|
// parseAllTxNtfn parses a RawCmd into a concrete type satisifying
|
|
// the btcjson.Cmd interface. This is used when registering the notification
|
|
// with the btcjson parser.
|
|
func parseAllTxNtfn(r *btcjson.RawCmd) (btcjson.Cmd, error) {
|
|
if r.Id != nil {
|
|
return nil, ErrNotANtfn
|
|
}
|
|
|
|
if len(r.Params) != 2 {
|
|
return nil, btcjson.ErrWrongNumberOfParams
|
|
}
|
|
|
|
txid, ok := r.Params[0].(string)
|
|
if !ok {
|
|
return nil, errors.New("first parameter txid must be a string")
|
|
}
|
|
famount, ok := r.Params[1].(float64)
|
|
if !ok {
|
|
return nil, errors.New("second parameter amount must be a number")
|
|
}
|
|
|
|
return NewAllTxNtfn(txid, int64(famount)), nil
|
|
}
|
|
|
|
// Id satisifies the btcjson.Cmd interface by returning nil for a
|
|
// notification ID.
|
|
func (n *AllTxNtfn) Id() interface{} {
|
|
return nil
|
|
}
|
|
|
|
// SetId is implemented to satisify the btcjson.Cmd interface. The
|
|
// notification id is not modified.
|
|
func (n *AllTxNtfn) SetId(id interface{}) {}
|
|
|
|
// Method satisifies the btcjson.Cmd interface by returning the method
|
|
// of the notification.
|
|
func (n *AllTxNtfn) Method() string {
|
|
return AllTxNtfnMethod
|
|
}
|
|
|
|
// MarshalJSON returns the JSON encoding of n. Part of the btcjson.Cmd
|
|
// interface.
|
|
func (n *AllTxNtfn) MarshalJSON() ([]byte, error) {
|
|
ntfn := btcjson.Message{
|
|
Jsonrpc: "1.0",
|
|
Method: n.Method(),
|
|
Params: []interface{}{
|
|
n.TxID,
|
|
n.Amount,
|
|
},
|
|
}
|
|
return json.Marshal(ntfn)
|
|
}
|
|
|
|
// UnmarshalJSON unmarshals the JSON encoding of n into n. Part of
|
|
// the btcjson.Cmd interface.
|
|
func (n *AllTxNtfn) UnmarshalJSON(b []byte) error {
|
|
// Unmarshal into a RawCmd.
|
|
var r btcjson.RawCmd
|
|
if err := json.Unmarshal(b, &r); err != nil {
|
|
return err
|
|
}
|
|
|
|
newNtfn, err := parseAllTxNtfn(&r)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
concreteNtfn, ok := newNtfn.(*AllTxNtfn)
|
|
if !ok {
|
|
return btcjson.ErrInternal
|
|
}
|
|
*n = *concreteNtfn
|
|
return nil
|
|
}
|
|
|
|
// AllVerboseTxNtfn is a type handling custom marshaling and
|
|
// unmarshaling of txmined JSON websocket notifications.
|
|
type AllVerboseTxNtfn struct {
|
|
RawTx *btcjson.TxRawResult `json:"rawtx"`
|
|
}
|
|
|
|
// Enforce that AllTxNtfn satisifies the btcjson.Cmd interface.
|
|
var _ btcjson.Cmd = &AllVerboseTxNtfn{}
|
|
|
|
// NewAllVerboseTxNtfn creates a new AllVerboseTxNtfn.
|
|
func NewAllVerboseTxNtfn(rawTx *btcjson.TxRawResult) *AllVerboseTxNtfn {
|
|
return &AllVerboseTxNtfn{
|
|
RawTx: rawTx,
|
|
}
|
|
}
|
|
|
|
// Id satisifies the btcjson.Cmd interface by returning nil for a
|
|
// notification ID.
|
|
func (n *AllVerboseTxNtfn) Id() interface{} {
|
|
return nil
|
|
}
|
|
|
|
// SetId is implemented to satisify the btcjson.Cmd interface. The
|
|
// notification id is not modified.
|
|
func (n *AllVerboseTxNtfn) SetId(id interface{}) {}
|
|
|
|
// Method satisifies the btcjson.Cmd interface by returning the method
|
|
// of the notification.
|
|
func (n *AllVerboseTxNtfn) Method() string {
|
|
return AllVerboseTxNtfnMethod
|
|
}
|
|
|
|
// MarshalJSON returns the JSON encoding of n. Part of the btcjson.Cmd
|
|
// interface.
|
|
func (n *AllVerboseTxNtfn) MarshalJSON() ([]byte, error) {
|
|
ntfn := btcjson.Message{
|
|
Jsonrpc: "1.0",
|
|
Method: n.Method(),
|
|
Params: []interface{}{
|
|
n.RawTx,
|
|
},
|
|
}
|
|
return json.Marshal(ntfn)
|
|
}
|
|
|
|
func generateAllVerboseTxNtfn() btcjson.Cmd {
|
|
return new(AllVerboseTxNtfn)
|
|
}
|
|
|
|
type rawParamsCmd struct {
|
|
Jsonrpc string `json:"jsonrpc"`
|
|
Id interface{} `json:"id"`
|
|
Method string `json:"method"`
|
|
Params []*json.RawMessage `json:"params"`
|
|
}
|
|
|
|
// UnmarshalJSON unmarshals the JSON encoding of n into n. Part of
|
|
// the btcjson.Cmd interface.
|
|
func (n *AllVerboseTxNtfn) UnmarshalJSON(b []byte) error {
|
|
// Unmarshal into a custom rawParamsCmd
|
|
var r rawParamsCmd
|
|
if err := json.Unmarshal(b, &r); err != nil {
|
|
return err
|
|
}
|
|
|
|
if r.Id != nil {
|
|
return ErrNotANtfn
|
|
}
|
|
|
|
if len(r.Params) != 1 {
|
|
return btcjson.ErrWrongNumberOfParams
|
|
}
|
|
|
|
var rawTx *btcjson.TxRawResult
|
|
if err := json.Unmarshal(*r.Params[0], &rawTx); err != nil {
|
|
return err
|
|
}
|
|
|
|
*n = *NewAllVerboseTxNtfn(rawTx)
|
|
return nil
|
|
}
|