@@ -202,34 +202,68 @@ type Address struct {
202202 networkId uint8
203203 paymentAddress []byte
204204 stakingAddress []byte
205- hrp string
206205}
207206
208- func ( a * Address ) UnmarshalCBOR ( data [] byte ) error {
209- // Decode bytes from CBOR
210- tmpData := [] byte {}
211- if _ , err := cbor . Decode ( data , & tmpData ); err != nil {
212- return err
207+ // NewAddress returns an Address based on the provided bech32 address string
208+ func NewAddress ( addr string ) ( Address , error ) {
209+ _ , data , err := bech32 . DecodeNoLimit ( addr )
210+ if err != nil {
211+ return Address {}, err
213212 }
213+ decoded , err := bech32 .ConvertBits (data , 5 , 8 , false )
214+ if err != nil {
215+ return Address {}, err
216+ }
217+ a := Address {}
218+ a .populateFromBytes (decoded )
219+ return a , nil
220+ }
221+
222+ func (a * Address ) populateFromBytes (data []byte ) {
214223 // Extract header info
215- header := tmpData [0 ]
224+ header := data [0 ]
216225 a .addressType = (header & addressHeaderTypeMask ) >> 4
217226 a .networkId = header & addressHeaderNetworkMask
218227 // Extract payload
219228 // NOTE: this is probably incorrect for Byron
220- payload := tmpData [1 :]
229+ payload := data [1 :]
221230 a .paymentAddress = payload [:addressHashSize ]
222231 a .stakingAddress = payload [addressHashSize :]
223- // Generate human readable part of address for output
224- a .hrp = a .generateHRP ()
232+ // Adjust stake addresses
233+ if a .addressType == addressTypeNoneKey || a .addressType == addressTypeNoneScript {
234+ a .stakingAddress = a .paymentAddress [:]
235+ a .paymentAddress = make ([]byte , 0 )
236+ }
237+ }
238+
239+ func (a * Address ) UnmarshalCBOR (data []byte ) error {
240+ // Decode bytes from CBOR
241+ tmpData := []byte {}
242+ if _ , err := cbor .Decode (data , & tmpData ); err != nil {
243+ return err
244+ }
245+ a .populateFromBytes (tmpData )
225246 return nil
226247}
227248
228249func (a * Address ) MarshalCBOR () ([]byte , error ) {
229250 return cbor .Encode (a .Bytes ())
230251}
231252
232- func (a * Address ) generateHRP () string {
253+ // StakeAddress returns a new Address with only the stake key portion. This will return nil if the address is not a payment/staking key pair
254+ func (a * Address ) StakeAddress () * Address {
255+ if a .addressType != addressTypeKeyKey {
256+ return nil
257+ }
258+ newAddr := & Address {
259+ addressType : addressTypeNoneKey ,
260+ networkId : a .networkId ,
261+ stakingAddress : a .stakingAddress [:],
262+ }
263+ return newAddr
264+ }
265+
266+ func (a Address ) generateHRP () string {
233267 var ret string
234268 if a .addressType == addressTypeNoneKey || a .addressType == addressTypeNoneScript {
235269 ret = "stake"
@@ -243,14 +277,16 @@ func (a *Address) generateHRP() string {
243277 return ret
244278}
245279
246- func (a * Address ) Bytes () []byte {
280+ // Bytes returns the underlying bytes for the address
281+ func (a Address ) Bytes () []byte {
247282 ret := []byte {}
248283 ret = append (ret , (byte (a .addressType )<< 4 )| (byte (a .networkId )& addressHeaderNetworkMask ))
249284 ret = append (ret , a .paymentAddress ... )
250285 ret = append (ret , a .stakingAddress ... )
251286 return ret
252287}
253288
289+ // String returns the bech32-encoded version of the address
254290func (a Address ) String () string {
255291 data := a .Bytes ()
256292 if a .addressType == addressTypeByron {
@@ -263,7 +299,9 @@ func (a Address) String() string {
263299 if err != nil {
264300 panic (fmt .Sprintf ("unexpected error converting data to base32: %s" , err ))
265301 }
266- encoded , err := bech32 .Encode (a .hrp , convData )
302+ // Generate human readable part of address for output
303+ hrp := a .generateHRP ()
304+ encoded , err := bech32 .Encode (hrp , convData )
267305 if err != nil {
268306 panic (fmt .Sprintf ("unexpected error encoding data as bech32: %s" , err ))
269307 }
0 commit comments