import { Immutable } from '../format/format' ; /**
 * The list of 32 symbols used in Bech32 encoding.
 */ export const bech32CharacterSet = 'qpzry9x8gf2tvdw0s3jn54khce6mua7l' ; /**
 * An object mapping each of the 32 symbols used in Bech32 encoding to their respective index in the character set.
 */ export const bech32CharacterSetIndex = { q : 0 , p : 1 , z : 2 , r : 3 , y : 4 , '9' : 5 , x : 6 , '8' : 7 , g : 8 , f : 9 , '2' : 10 , t : 11 , v : 12 , d : 13 , w : 14 , '0' : 15 , s : 16 , '3' : 17 , j : 18 , n : 19 , '5' : 20 , '4' : 21 , k : 22 , h : 23 , c : 24 , e : 25 , '6' : 26 , m : 27 , u : 28 , a : 29 , '7' : 30 , l : 31 } as const ; export enum BitRegroupingError { integerOutOfRange = 'An integer provided in the source array is out of the range of the specified source word length.' , hasDisallowedPadding = 'Encountered padding when padding was disallowed.' , requiresDisallowedPadding = 'Encoding requires padding while padding is disallowed.' } param bin param sourceWordLength param resultWordLength param allowPadding privateRemarks export const regroupBits = ( { bin , sourceWordLength , resultWordLength , allowPadding = true , } ) => { let accumulator = 0 ; let bits = 0 ; const result = [ ] ; const maxResultInt = ( 1 << resultWordLength ) - 1 ; for ( let p = 0 ; p < bin . length ; ++ p ) { const value = bin [ p ] ; if ( value < 0 || value >> sourceWordLength !== 0 ) { return BitRegroupingError . integerOutOfRange ; } accumulator = ( accumulator << sourceWordLength ) | value ; bits += sourceWordLength ; while ( bits >= resultWordLength ) { bits -= resultWordLength ; result . push ( ( accumulator >> bits ) & maxResultInt ) ; } } if ( allowPadding ) { if ( bits > 0 ) { result . push ( ( accumulator << ( resultWordLength - bits ) ) & maxResultInt ) ; } } else if ( bits >= sourceWordLength ) { return BitRegroupingError . hasDisallowedPadding ; } else if ( ( ( accumulator << ( resultWordLength - bits ) ) & maxResultInt ) > 0 ) { return BitRegroupingError . requiresDisallowedPadding ; } return result ; } ; param base32IntegerArray export const encodeBech32 = ( base32IntegerArray ) => { let result = '' ; for ( let i = 0 ; i < base32IntegerArray . length ; i ++ ) { result += bech32CharacterSet [ base32IntegerArray [ i ] ] ; } return result ; } ; param validBech32 export const decodeBech32 = ( validBech32 ) => { const result = [ ] ; for ( let i = 0 ; i < validBech32 . length ; i ++ ) { result . push ( bech32CharacterSetIndex [ validBech32 [ i ] as keyof typeof bech32CharacterSetIndex ] ) ; } return result ; } ; const nonBech32Characters = new RegExp ( `[^${ bech32CharacterSet }]` , 'u' ) ; const base32WordLength = 5 ; const base256WordLength = 8 ; param maybeBech32 export const isBech32CharacterSet = ( maybeBech32 ) => ! nonBech32Characters . test ( maybeBech32 ) ; export enum Bech32DecodingError { notBech32CharacterSet = 'Bech32 decoding error: input contains characters outside of the Bech32 character set.' } param bech32Padded export const bech32PaddedToBin = ( bech32Padded ) => { const result = isBech32CharacterSet ( bech32Padded ) ? regroupBits ( { allowPadding : false , bin : decodeBech32 ( bech32Padded ) , resultWordLength : base256WordLength , sourceWordLength : base32WordLength , } ) : Bech32DecodingError . notBech32CharacterSet ; return typeof result === 'string' ? result : Uint8Array . from ( result ) ; } ; param bytes export const binToBech32Padded = ( bytes ) => encodeBech32 ( regroupBits ( { bin : bytes , resultWordLength : base32WordLength , sourceWordLength : base256WordLength , } ) as number [ ] ) ;