lbcd/notifications.go

1008 lines
26 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"
// 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"
// ProcessedTxNtfnMethod is the method of the btcd
// processedtx notification.
ProcessedTxNtfnMethod = "processedx"
// TxMinedNtfnMethod is the method of the btcd txmined
// notification.
TxMinedNtfnMethod = "txmined"
// TxNtfnMethod is the method of the btcwallet newtx
// notification.
TxNtfnMethod = "newtx"
// TxSpentNtfnMethod is the method of the btcd txspent
// notification.
TxSpentNtfnMethod = "txspent"
// WalletLockStateNtfnMethod is the method of the btcwallet
// walletlockstate notification.
WalletLockStateNtfnMethod = "walletlockstate"
)
// Register notifications with btcjson.
func init() {
btcjson.RegisterCustomCmd(AccountBalanceNtfnMethod, parseAccountBalanceNtfn)
btcjson.RegisterCustomCmd(BlockConnectedNtfnMethod, parseBlockConnectedNtfn)
btcjson.RegisterCustomCmd(BlockDisconnectedNtfnMethod, parseBlockDisconnectedNtfn)
btcjson.RegisterCustomCmd(BtcdConnectedNtfnMethod, parseBtcdConnectedNtfn)
btcjson.RegisterCustomCmd(ProcessedTxNtfnMethod, parseProcessedTxNtfn)
btcjson.RegisterCustomCmd(TxMinedNtfnMethod, parseTxMinedNtfn)
btcjson.RegisterCustomCmd(TxSpentNtfnMethod, parseTxSpentNtfn)
btcjson.RegisterCustomCmd(TxNtfnMethod, parseTxNtfn)
btcjson.RegisterCustomCmd(WalletLockStateNtfnMethod, parseWalletLockStateNtfn)
}
// 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 := parseTxMinedNtfn(&r)
if err != nil {
return err
}
concreteNtfn, ok := newNtfn.(*BtcdConnectedNtfn)
if !ok {
return btcjson.ErrInternal
}
*n = *concreteNtfn
return nil
}
// ProcessedTxNtfn is a type handling custom marshaling and unmarshaling
// of processedtx JSON websocket notifications.
type ProcessedTxNtfn struct {
Receiver string
Amount int64
TxID string
TxOutIndex uint32
PkScript string
BlockHash string
BlockHeight int32
BlockIndex int
BlockTime int64
Spent bool
}
// Enforce that ProcessedTxNtfn satisifies the btcjson.Cmd interface.
var _ btcjson.Cmd = &ProcessedTxNtfn{}
// parseProcessedTxNtfn parses a RawCmd into a concrete type satisifying
// the btcjson.Cmd interface. This is used when registering the notification
// with the btcjson parser.
func parseProcessedTxNtfn(r *btcjson.RawCmd) (btcjson.Cmd, error) {
if r.Id != nil {
return nil, ErrNotANtfn
}
if len(r.Params) != 10 {
return nil, btcjson.ErrWrongNumberOfParams
}
receiver, ok := r.Params[0].(string)
if !ok {
return nil, errors.New("first parameter receiver must be a string")
}
famount, ok := r.Params[1].(float64)
if !ok {
return nil, errors.New("second parameter amount must be a number")
}
amount := int64(famount)
txid, ok := r.Params[2].(string)
if !ok {
return nil, errors.New("third parameter txid must be a string")
}
fTxOutIdx, ok := r.Params[3].(float64)
if !ok {
return nil, errors.New("fourth parameter txoutidx must be a number")
}
txOutIdx := uint32(fTxOutIdx)
pkScript, ok := r.Params[4].(string)
if !ok {
return nil, errors.New("fifth parameter pkScript must be a string")
}
blockHash := r.Params[5].(string)
if !ok {
return nil, errors.New("sixth parameter blockHash must be a string")
}
fBlockHeight, ok := r.Params[6].(float64)
if !ok {
return nil, errors.New("seventh parameter blockHeight must be a number")
}
blockHeight := int32(fBlockHeight)
fBlockIndex, ok := r.Params[7].(float64)
if !ok {
return nil, errors.New("eighth parameter blockIndex must be a number")
}
blockIndex := int(fBlockIndex)
fBlockTime, ok := r.Params[8].(float64)
if !ok {
return nil, errors.New("ninth parameter blockTime must be a number")
}
blockTime := int64(fBlockTime)
spent, ok := r.Params[9].(bool)
if !ok {
return nil, errors.New("tenth parameter spent must be a bool")
}
cmd := &ProcessedTxNtfn{
Receiver: receiver,
Amount: amount,
TxID: txid,
TxOutIndex: txOutIdx,
PkScript: pkScript,
BlockHash: blockHash,
BlockHeight: blockHeight,
BlockIndex: blockIndex,
BlockTime: blockTime,
Spent: spent,
}
return cmd, nil
}
// Id satisifies the btcjson.Cmd interface by returning nil for a
// notification ID.
func (n *ProcessedTxNtfn) Id() interface{} {
return nil
}
// SetId is implemented to satisify the btcjson.Cmd interface. The
// notification id is not modified.
func (n *ProcessedTxNtfn) SetId(id interface{}) {}
// Method satisifies the btcjson.Cmd interface by returning the method
// of the notification.
func (n *ProcessedTxNtfn) Method() string {
return ProcessedTxNtfnMethod
}
// MarshalJSON returns the JSON encoding of n. Part of the btcjson.Cmd
// interface.
func (n *ProcessedTxNtfn) MarshalJSON() ([]byte, error) {
ntfn := btcjson.Message{
Jsonrpc: "1.0",
Method: n.Method(),
Params: []interface{}{
n.Receiver,
n.Amount,
n.TxID,
n.TxOutIndex,
n.PkScript,
n.BlockHash,
n.BlockHeight,
n.BlockIndex,
n.BlockTime,
n.Spent,
},
}
return json.Marshal(ntfn)
}
// UnmarshalJSON unmarshals the JSON encoding of n into n. Part of
// the btcjson.Cmd interface.
func (n *ProcessedTxNtfn) UnmarshalJSON(b []byte) error {
// Unmarshal into a RawCmd.
var r btcjson.RawCmd
if err := json.Unmarshal(b, &r); err != nil {
return err
}
newNtfn, err := parseProcessedTxNtfn(&r)
if err != nil {
return err
}
concreteNtfn, ok := newNtfn.(*ProcessedTxNtfn)
if !ok {
return btcjson.ErrInternal
}
*n = *concreteNtfn
return nil
}
// TxMinedNtfn is a type handling custom marshaling and
// unmarshaling of txmined JSON websocket notifications.
type TxMinedNtfn struct {
TxID string
BlockHash string
BlockHeight int32
BlockTime int64
Index int
}
// Enforce that TxMinedNtfn satisifies the btcjson.Cmd interface.
var _ btcjson.Cmd = &TxMinedNtfn{}
// NewTxMinedNtfn creates a new TxMinedNtfn.
func NewTxMinedNtfn(txid, blockhash string, blockheight int32,
blocktime int64, index int) *TxMinedNtfn {
return &TxMinedNtfn{
TxID: txid,
BlockHash: blockhash,
BlockHeight: blockheight,
BlockTime: blocktime,
Index: index,
}
}
// parseTxMinedNtfn parses a RawCmd into a concrete type satisifying
// the btcjson.Cmd interface. This is used when registering the notification
// with the btcjson parser.
func parseTxMinedNtfn(r *btcjson.RawCmd) (btcjson.Cmd, error) {
if r.Id != nil {
return nil, ErrNotANtfn
}
if len(r.Params) != 5 {
return nil, btcjson.ErrWrongNumberOfParams
}
txid, ok := r.Params[0].(string)
if !ok {
return nil, errors.New("first parameter txid must be a string")
}
blockhash, ok := r.Params[1].(string)
if !ok {
return nil, errors.New("second parameter blockhash must be a string")
}
fblockheight, ok := r.Params[2].(float64)
if !ok {
return nil, errors.New("third parameter blockheight must be a number")
}
fblocktime, ok := r.Params[3].(float64)
if !ok {
return nil, errors.New("fourth parameter blocktime must be a number")
}
findex, ok := r.Params[4].(float64)
if !ok {
return nil, errors.New("fifth parameter index must be a number")
}
return NewTxMinedNtfn(txid, blockhash, int32(fblockheight),
int64(fblocktime), int(findex)), nil
}
// Id satisifies the btcjson.Cmd interface by returning nil for a
// notification ID.
func (n *TxMinedNtfn) Id() interface{} {
return nil
}
// SetId is implemented to satisify the btcjson.Cmd interface. The
// notification id is not modified.
func (n *TxMinedNtfn) SetId(id interface{}) {}
// Method satisifies the btcjson.Cmd interface by returning the method
// of the notification.
func (n *TxMinedNtfn) Method() string {
return TxMinedNtfnMethod
}
// MarshalJSON returns the JSON encoding of n. Part of the btcjson.Cmd
// interface.
func (n *TxMinedNtfn) MarshalJSON() ([]byte, error) {
ntfn := btcjson.Message{
Jsonrpc: "1.0",
Method: n.Method(),
Params: []interface{}{
n.TxID,
n.BlockHash,
n.BlockHeight,
n.BlockTime,
n.Index,
},
}
return json.Marshal(ntfn)
}
// UnmarshalJSON unmarshals the JSON encoding of n into n. Part of
// the btcjson.Cmd interface.
func (n *TxMinedNtfn) UnmarshalJSON(b []byte) error {
// Unmarshal into a RawCmd.
var r btcjson.RawCmd
if err := json.Unmarshal(b, &r); err != nil {
return err
}
newNtfn, err := parseTxMinedNtfn(&r)
if err != nil {
return err
}
concreteNtfn, ok := newNtfn.(*TxMinedNtfn)
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{}
}
// TxSpentNtfn is a type handling custom marshaling and
// unmarshaling of txspent JSON websocket notifications.
type TxSpentNtfn struct {
SpentTxId string
SpentTxOutIndex int
SpendingTx string
}
// Enforce that TxSpentNtfn satisifies the btcjson.Cmd interface.
var _ btcjson.Cmd = &TxSpentNtfn{}
// NewTxSpentNtfn creates a new TxSpentNtfn.
func NewTxSpentNtfn(txid string, txOutIndex int, spendingTx string) *TxSpentNtfn {
return &TxSpentNtfn{
SpentTxId: txid,
SpentTxOutIndex: txOutIndex,
SpendingTx: spendingTx,
}
}
// parseTxSpentNtfn parses a RawCmd into a concrete type satisifying
// the btcjson.Cmd interface. This is used when registering the notification
// with the btcjson parser.
func parseTxSpentNtfn(r *btcjson.RawCmd) (btcjson.Cmd, error) {
if r.Id != nil {
return nil, ErrNotANtfn
}
if len(r.Params) != 3 {
return nil, btcjson.ErrWrongNumberOfParams
}
txid, ok := r.Params[0].(string)
if !ok {
return nil, errors.New("first parameter txid must be a string")
}
findex, ok := r.Params[1].(float64)
if !ok {
return nil, errors.New("second parameter index must be a number")
}
index := int(findex)
spendingTx, ok := r.Params[2].(string)
if !ok {
return nil, errors.New("third parameter spendingTx must be a string")
}
return NewTxSpentNtfn(txid, index, spendingTx), nil
}
// Id satisifies the btcjson.Cmd interface by returning nil for a
// notification ID.
func (n *TxSpentNtfn) Id() interface{} {
return nil
}
// SetId is implemented to satisify the btcjson.Cmd interface. The
// notification id is not modified.
func (n *TxSpentNtfn) SetId(id interface{}) {}
// Method satisifies the btcjson.Cmd interface by returning the method
// of the notification.
func (n *TxSpentNtfn) Method() string {
return TxSpentNtfnMethod
}
// MarshalJSON returns the JSON encoding of n. Part of the btcjson.Cmd
// interface.
func (n *TxSpentNtfn) MarshalJSON() ([]byte, error) {
ntfn := btcjson.Message{
Jsonrpc: "1.0",
Method: n.Method(),
Params: []interface{}{
n.SpentTxId,
n.SpentTxOutIndex,
n.SpendingTx,
},
}
return json.Marshal(ntfn)
}
// UnmarshalJSON unmarshals the JSON encoding of n into n. Part of
// the btcjson.Cmd interface.
func (n *TxSpentNtfn) UnmarshalJSON(b []byte) error {
// Unmarshal into a RawCmd.
var r btcjson.RawCmd
if err := json.Unmarshal(b, &r); err != nil {
return err
}
newNtfn, err := parseTxSpentNtfn(&r)
if err != nil {
return err
}
concreteNtfn, ok := newNtfn.(*TxSpentNtfn)
if !ok {
return btcjson.ErrInternal
}
*n = *concreteNtfn
return nil
}
// 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
}