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 }