decred.org/dcrwallet/v3@v3.1.0/rpc/client/dcrwallet/marshaling.go (about)

     1  package dcrwallet
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/hex"
     6  	"encoding/json"
     7  	"strings"
     8  
     9  	"github.com/decred/dcrd/chaincfg/chainhash"
    10  	"github.com/decred/dcrd/chaincfg/v3"
    11  	"github.com/decred/dcrd/dcrutil/v4"
    12  	"github.com/decred/dcrd/hdkeychain/v3"
    13  	dcrdtypes "github.com/decred/dcrd/rpc/jsonrpc/types/v4"
    14  	"github.com/decred/dcrd/txscript/v4/stdaddr"
    15  	"github.com/decred/dcrd/wire"
    16  )
    17  
    18  type marshalJSONFunc func() ([]byte, error)
    19  type unmarshalJSONFunc func([]byte) error
    20  
    21  func (f marshalJSONFunc) MarshalJSON() ([]byte, error)    { return f() }
    22  func (f *unmarshalJSONFunc) UnmarshalJSON(j []byte) error { return (*f)(j) }
    23  
    24  func addressArrayMarshaler(n int, s func(i int) string) json.Marshaler {
    25  	return marshalJSONFunc(func() ([]byte, error) {
    26  		// Make buffer of estimated needed size.  Base58 Hash160
    27  		// addresses are typically 35 characters long, plus 3 additional
    28  		// characters per item for string quotes and comma.  Minimum two
    29  		// characters are needed for the outer [].
    30  		buf := new(bytes.Buffer)
    31  		buf.Grow(2 + n*(3+35))
    32  
    33  		buf.WriteByte('[')
    34  		for i := 0; i < n; i++ {
    35  			if i != 0 {
    36  				buf.WriteByte(',')
    37  			}
    38  			buf.WriteByte('"')
    39  			buf.WriteString(s(i))
    40  			buf.WriteByte('"')
    41  		}
    42  		buf.WriteByte(']')
    43  
    44  		return buf.Bytes(), nil
    45  	})
    46  }
    47  
    48  func marshalAddresses(addrs []stdaddr.Address) json.Marshaler {
    49  	return addressArrayMarshaler(len(addrs), func(i int) string {
    50  		return addrs[i].String()
    51  	})
    52  }
    53  
    54  func marshalTx(tx *wire.MsgTx) json.Marshaler {
    55  	return marshalJSONFunc(func() ([]byte, error) {
    56  		s := new(strings.Builder)
    57  		err := tx.Serialize(hex.NewEncoder(s))
    58  		if err != nil {
    59  			return nil, err
    60  		}
    61  		return json.Marshal(s.String())
    62  	})
    63  }
    64  
    65  func unmarshalOutpoints(ops *[]*wire.OutPoint) json.Unmarshaler {
    66  	f := unmarshalJSONFunc(func(j []byte) error {
    67  		var array []dcrdtypes.TransactionInput
    68  		err := json.Unmarshal(j, &array)
    69  		if err != nil {
    70  			return err
    71  		}
    72  		*ops = make([]*wire.OutPoint, 0, len(array))
    73  		for i := range array {
    74  			hash, err := chainhash.NewHashFromStr(array[i].Txid)
    75  			if err != nil {
    76  				return err
    77  			}
    78  			*ops = append(*ops, wire.NewOutPoint(hash, array[i].Vout, array[i].Tree))
    79  		}
    80  		return nil
    81  	})
    82  	return &f
    83  }
    84  
    85  func unmarshalHash(hash **chainhash.Hash) json.Unmarshaler {
    86  	f := unmarshalJSONFunc(func(j []byte) error {
    87  		var s string
    88  		err := json.Unmarshal(j, &s)
    89  		if err != nil {
    90  			return err
    91  		}
    92  		*hash, err = chainhash.NewHashFromStr(s)
    93  		return err
    94  	})
    95  	return &f
    96  }
    97  
    98  func unmarshalHashes(hashes *[]*chainhash.Hash) json.Unmarshaler {
    99  	f := unmarshalJSONFunc(func(j []byte) error {
   100  		var array []string
   101  		err := json.Unmarshal(j, &array)
   102  		if err != nil {
   103  			return err
   104  		}
   105  		*hashes = make([]*chainhash.Hash, 0, len(array))
   106  		for i := range array {
   107  			hash, err := chainhash.NewHashFromStr(array[i])
   108  			if err != nil {
   109  				return err
   110  			}
   111  			*hashes = append(*hashes, hash)
   112  		}
   113  		return nil
   114  	})
   115  	return &f
   116  }
   117  
   118  func unmarshalAddress(addr *stdaddr.Address, net *chaincfg.Params) json.Unmarshaler {
   119  	f := unmarshalJSONFunc(func(j []byte) error {
   120  		var s string
   121  		err := json.Unmarshal(j, &s)
   122  		if err != nil {
   123  			return err
   124  		}
   125  		a, err := stdaddr.DecodeAddress(s, net)
   126  		if err != nil {
   127  			return err
   128  		}
   129  		*addr = a
   130  		return nil
   131  	})
   132  	return &f
   133  }
   134  
   135  func unmarshalAddresses(addrs *[]stdaddr.Address, net *chaincfg.Params) json.Unmarshaler {
   136  	f := unmarshalJSONFunc(func(j []byte) error {
   137  		var array []string
   138  		err := json.Unmarshal(j, &array)
   139  		if err != nil {
   140  			return err
   141  		}
   142  		*addrs = make([]stdaddr.Address, 0, len(array))
   143  		for i := range array {
   144  			a, err := stdaddr.DecodeAddress(array[i], net)
   145  			if err != nil {
   146  				return err
   147  			}
   148  			*addrs = append(*addrs, a)
   149  		}
   150  		return nil
   151  	})
   152  	return &f
   153  }
   154  
   155  func unmarshalListAccounts(accounts map[string]dcrutil.Amount) json.Unmarshaler {
   156  	f := unmarshalJSONFunc(func(j []byte) error {
   157  		object := make(map[string]float64)
   158  		err := json.Unmarshal(j, &object)
   159  		if err != nil {
   160  			return err
   161  		}
   162  		for account, amount := range object {
   163  			atoms, err := dcrutil.NewAmount(amount)
   164  			if err != nil {
   165  				return err
   166  			}
   167  			accounts[account] = atoms
   168  		}
   169  		return nil
   170  	})
   171  	return &f
   172  }
   173  
   174  func unmarshalHDKey(key **hdkeychain.ExtendedKey, net *chaincfg.Params) json.Unmarshaler {
   175  	f := unmarshalJSONFunc(func(j []byte) error {
   176  		var s string
   177  		err := json.Unmarshal(j, &s)
   178  		if err != nil {
   179  			return err
   180  		}
   181  		*key, err = hdkeychain.NewKeyFromString(s, net)
   182  		return err
   183  	})
   184  	return &f
   185  }
   186  
   187  func unmarshalAmount(amount *dcrutil.Amount) json.Unmarshaler {
   188  	f := unmarshalJSONFunc(func(j []byte) error {
   189  		var number float64
   190  		err := json.Unmarshal(j, &number)
   191  		if err != nil {
   192  			return err
   193  		}
   194  		*amount, err = dcrutil.NewAmount(number)
   195  		return err
   196  	})
   197  	return &f
   198  }
   199  
   200  func unmarshalWIF(wif **dcrutil.WIF, net *chaincfg.Params) json.Unmarshaler {
   201  	f := unmarshalJSONFunc(func(j []byte) error {
   202  		var s string
   203  		err := json.Unmarshal(j, &s)
   204  		if err != nil {
   205  			return err
   206  		}
   207  		*wif, err = dcrutil.DecodeWIF(s, net.PrivateKeyID)
   208  		return err
   209  	})
   210  	return &f
   211  }
   212  
   213  func unmarshalTx(tx **wire.MsgTx) json.Unmarshaler {
   214  	f := unmarshalJSONFunc(func(j []byte) error {
   215  		var s string
   216  		err := json.Unmarshal(j, &s)
   217  		if err != nil {
   218  			return err
   219  		}
   220  		*tx = new(wire.MsgTx)
   221  		return (*tx).Deserialize(hex.NewDecoder(strings.NewReader(s)))
   222  	})
   223  	return &f
   224  }