@@ -236,3 +236,101 @@ export const arbitrary = FastCheck.record({
236236 stakingCredential : props . stakingCredential ?? undefined
237237 } )
238238)
239+
240+ /**
241+ * Address details with both structured and serialized formats
242+ *
243+ * @since 1.0.0
244+ * @category Model
245+ */
246+ export interface AddressDetails {
247+ readonly type : "Base" | "Enterprise"
248+ readonly networkId : NetworkId . NetworkId
249+ readonly address : {
250+ readonly bech32 : string
251+ readonly hex : string
252+ }
253+ readonly paymentCredential : Credential . CredentialSchema
254+ readonly stakingCredential ?: Credential . CredentialSchema
255+ }
256+
257+ /**
258+ * Parse address from bech32 or hex string and extract all details
259+ * Returns undefined if the address cannot be parsed
260+ *
261+ * Supports:
262+ * - Base addresses (payment + staking credentials)
263+ * - Enterprise addresses (payment credential only)
264+ *
265+ * @since 1.0.0
266+ * @category Utils
267+ * @example
268+ * ```typescript
269+ * const details = getAddressDetails("addr_test1qp...")
270+ * if (details) {
271+ * console.log(details.type) // "Base" | "Enterprise"
272+ * console.log(details.networkId) // 0 | 1
273+ * console.log(details.paymentCredential)
274+ * console.log(details.stakingCredential) // present for Base addresses
275+ * }
276+ * ```
277+ */
278+ export const getAddressDetails = ( address : string ) : AddressDetails | undefined => {
279+ try {
280+ // Try bech32 first
281+ const parsed = fromBech32 ( address )
282+ return {
283+ type : parsed . stakingCredential ? "Base" : "Enterprise" ,
284+ networkId : parsed . networkId ,
285+ address : {
286+ bech32 : address ,
287+ hex : toHex ( parsed )
288+ } ,
289+ paymentCredential : parsed . paymentCredential ,
290+ stakingCredential : parsed . stakingCredential
291+ }
292+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
293+ } catch ( _bech32Error ) {
294+ try {
295+ // Try hex
296+ const parsed = fromHex ( address )
297+ return {
298+ type : parsed . stakingCredential ? "Base" : "Enterprise" ,
299+ networkId : parsed . networkId ,
300+ address : {
301+ bech32 : toBech32 ( parsed ) ,
302+ hex : address
303+ } ,
304+ paymentCredential : parsed . paymentCredential ,
305+ stakingCredential : parsed . stakingCredential
306+ }
307+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
308+ } catch ( _hexError ) {
309+ return undefined
310+ }
311+ }
312+ }
313+
314+ /**
315+ * Extract payment credential from address string
316+ * Returns undefined if the address cannot be parsed
317+ *
318+ * @since 1.0.0
319+ * @category Utils
320+ */
321+ export const getPaymentCredential = ( address : string ) : Credential . CredentialSchema | undefined => {
322+ const details = getAddressDetails ( address )
323+ return details ?. paymentCredential
324+ }
325+
326+ /**
327+ * Extract staking credential from address string
328+ * Returns undefined if the address has no staking credential or cannot be parsed
329+ *
330+ * @since 1.0.0
331+ * @category Utils
332+ */
333+ export const getStakingCredential = ( address : string ) : Credential . CredentialSchema | undefined => {
334+ const details = getAddressDetails ( address )
335+ return details ?. stakingCredential
336+ }
0 commit comments