import cbor from 'cbor' ; import { RadixAtom , RadixSpin , RadixTransferrableTokensParticle , RadixParticle } from 'radixdlt' ; interface ByteInterval { startsAtByte : number ; byteCount : number ; } export function cborByteOffsets ( atom ) { const upParticles = atom . getParticlesOfSpin ( RadixSpin . UP ) ; const bytes = [ ] ; for ( const particle of upParticles ) { const byteIntervalOfKey = getByteIntervalFunction ( particle , atom ) ; for ( const key of [ 'address' , 'amount' , 'serializer' , 'tokenDefinitionReference' ] ) { const interval = byteIntervalOfKey ( key ) ; bytes . push ( interval . startsAtByte ) ; bytes . push ( interval . byteCount ) ; } } return writeBytes ( bytes , Buffer . from ( '' ) ) ; } const getByteIntervalFunction = ( particle , atom ) : ( key : string ) => ByteInterval => { if ( particle . constructor . name === 'RadixTransferrableTokensParticle' ) { return byteIntervalInAtom ( particle , atom ) ; } else { return ( key ) => { if ( key !== 'serializer' ) { return { startsAtByte : 0 , byteCount : 0 } ; } return byteIntervalInAtom ( particle , atom ) ( key ) ; } ; } } ; const intervalByString = ( particleDSON , atomDSON ) : ByteInterval => { return { startsAtByte : atomDSON . toString ( 'hex' ) . indexOf ( particleDSON . toString ( 'hex' ) ) / 2 , byteCount : particleDSON . length , } ; } ; const byteIntervalInAtom = ( particle , atom ) => ( key ) : ByteInterval => { const particleEncoded = particle . toDSON ( ) ; const atomEncoded = atom . toDSON ( ) ; const particleIntervalInAtom = intervalByString ( particleEncoded , atomEncoded ) ; const fieldValueEncoded = cbor . encode ( particle [ key ] ) ; const intervalInParticle = intervalByString ( fieldValueEncoded , particleEncoded ) ; intervalInParticle . startsAtByte += particleIntervalInAtom . startsAtByte ; return intervalInParticle ; } ; const writeBytes = ( values , buf ) : Buffer => { for ( const value of values ) { const newValue = Buffer . alloc ( 2 ) ; newValue . writeInt16BE ( value , 0 ) ; buf = Buffer . concat ( [ buf , newValue , ] ) ; } return buf ; } ;