1- import { AddressFormat , BaseUtils } from '@bitgo/sdk-core' ;
1+ import { AddressFormat , BaseUtils , InvalidAddressError } from '@bitgo/sdk-core' ;
22import {
33 BaseAddress ,
44 PublicKey ,
@@ -11,6 +11,10 @@ import {
1111 Ed25519KeyHash ,
1212 ScriptHash ,
1313 DRepKind ,
14+ ByronAddress ,
15+ Address ,
16+ EnterpriseAddress ,
17+ PointerAddress ,
1418} from '@emurgo/cardano-serialization-lib-nodejs' ;
1519import { KeyPair } from './keyPair' ;
1620import { bech32 } from 'bech32' ;
@@ -149,26 +153,38 @@ export class Utils implements BaseUtils {
149153 const POINTER_ADDR_LEN = 52 ;
150154 const VALIDATOR_ADDR_LEN = 56 ;
151155
152- // test if this is a bech32 address first
153- if ( new RegExp ( bech32PrefixList . join ( '|' ) ) . test ( address ) ) {
156+ //Check for Shelley-era (Bech32) addresses
157+ if ( new RegExp ( `^( ${ bech32PrefixList . join ( '|' ) } )` ) . test ( address ) ) {
154158 try {
155159 const decodedBech = bech32 . decode ( address , 108 ) ;
156160 const wordLength = decodedBech . words . length ;
157- if ( ! bech32PrefixList . includes ( decodedBech . prefix ) ) {
158- return false ;
161+ if (
162+ bech32PrefixList . includes ( decodedBech . prefix ) &&
163+ ( wordLength === BASE_ADDR_LEN ||
164+ wordLength === REWARD_AND_ENTERPRISE_ADDR_LEN ||
165+ wordLength === POINTER_ADDR_LEN )
166+ ) {
167+ return true ;
159168 }
160- return (
161- wordLength === BASE_ADDR_LEN ||
162- wordLength === REWARD_AND_ENTERPRISE_ADDR_LEN ||
163- wordLength === POINTER_ADDR_LEN
164- ) ;
165- } catch ( err ) {
166- return false ;
169+ } catch ( e ) {
170+ console . log ( `Address: ${ address } failed Bech32 test with error: ${ e } ` ) ;
167171 }
168- } else {
169- // maybe this is a validator address
170- return new RegExp ( `^(?!pool)[a-z0-9]\{${ VALIDATOR_ADDR_LEN } \}$` ) . test ( address ) ;
171172 }
173+
174+ //Check for Validator addresses
175+ if ( new RegExp ( `^(?!pool)[a-z0-9]{${ VALIDATOR_ADDR_LEN } }$` ) . test ( address ) ) {
176+ return true ;
177+ }
178+
179+ //Check for Byron-era address
180+ try {
181+ return ByronAddress . is_valid ( address ) ;
182+ } catch ( e ) {
183+ console . log ( `Address: ${ address } failed Byron test with error: ${ e } ` ) ;
184+ console . log ( e . stack ) ;
185+ }
186+
187+ return false ;
172188 }
173189
174190 /** @inheritdoc */
@@ -228,6 +244,62 @@ export class Utils implements BaseUtils {
228244 : Buffer . from ( serializedTx , 'base64' ) ;
229245 return Buffer . from ( CardanoTransaction . from_bytes ( bufferRawTransaction ) . body ( ) . to_bytes ( ) ) . toString ( 'hex' ) ;
230246 }
247+
248+ /**
249+ * Decode wallet address from string.
250+ * Attempts to decode as Shelley (bech32) first, then Byron (base58).
251+ * @param {string } address - Valid Byron or Shelley-era address.
252+ * @returns {Address } - Valid address object.
253+ * @throws {InvalidAddressError } If the address is neither valid Shelley nor Byron.
254+ */
255+ getWalletAddress ( address : string ) : Address {
256+ if ( ! address || typeof address !== 'string' ) {
257+ throw new InvalidAddressError ( 'Provided address is not a valid string' ) ;
258+ }
259+
260+ // Try decoding as a Shelley (bech32) address first
261+ try {
262+ return Address . from_bech32 ( address ) ;
263+ } catch ( e ) {
264+ console . error ( `Could not decode shelly address from string '${ address } '` ) ;
265+ }
266+
267+ // Try decoding as a Byron (base58) address later
268+ try {
269+ return ByronAddress . from_base58 ( address ) . to_address ( ) ;
270+ } catch ( e ) {
271+ console . error ( `Could not decode byron address from string '${ address } '` ) ;
272+ }
273+ throw new InvalidAddressError ( 'Provided string is not a valid Shelley or Byron address' ) ;
274+ }
275+
276+ /**
277+ * Decode address string from Address object.
278+ * Attempts to decode as Shelley (bech32) first, then Byron (base58).
279+ * @param {Address } address - Valid Address object
280+ * @returns {string } - Valid Byron or Shelley-era address string.
281+ * @throws {InvalidAddressError } If the Address object is neither valid Shelley nor Byron.
282+ */
283+ getAddressString ( address : Address ) : string {
284+ // Check all Shelley address types
285+ if (
286+ BaseAddress . from_address ( address ) ||
287+ EnterpriseAddress . from_address ( address ) ||
288+ RewardAddress . from_address ( address ) ||
289+ PointerAddress . from_address ( address )
290+ ) {
291+ return address . to_bech32 ( ) ;
292+ }
293+
294+ // If not Shelley, try Byron
295+ const byronAddress = ByronAddress . from_address ( address ) ;
296+ if ( byronAddress ) {
297+ return byronAddress . to_base58 ( ) ;
298+ }
299+
300+ // If neither, it's invalid
301+ throw new InvalidAddressError ( 'Provided Address is not a valid Shelley or Byron address' ) ;
302+ }
231303}
232304
233305const utils = new Utils ( ) ;
0 commit comments