@@ -6,6 +6,7 @@ import { None, Option, Some } from './src/monads';
66import { Rune } from './src/rune' ;
77import { RuneId } from './src/runeid' ;
88import { Runestone } from './src/runestone' ;
9+ import { SpacedRune } from './src/spacedrune' ;
910import { Terms } from './src/terms' ;
1011
1112export {
@@ -28,9 +29,9 @@ export { Edict } from './src/edict';
2829export { Etching } from './src/etching' ;
2930export { Network } from './src/network' ;
3031export { Rune } from './src/rune' ;
32+ export { SpacedRune } from './src/spacedrune' ;
3133export { RuneId } from './src/runeid' ;
3234export { Runestone } from './src/runestone' ;
33- export { SpacedRune } from './src/spacedrune' ;
3435export { Terms } from './src/terms' ;
3536
3637export {
@@ -90,6 +91,8 @@ const u128Strict = (n: bigint) => {
9091 return u128 ( bigN ) ;
9192} ;
9293
94+ const SPACERS = [ '•' , '.' ] ;
95+
9396// TODO: Add unit tests
9497/**
9598 * Low level function to allow for encoding runestones without any indexer and transaction checks.
@@ -98,7 +101,10 @@ const u128Strict = (n: bigint) => {
98101 * @returns encoded runestone bytes
99102 * @throws Error if encoding is detected to be considered a cenotaph
100103 */
101- export function encodeRunestoneUnsafe ( runestone : RunestoneSpec ) : Buffer {
104+ export function encodeRunestoneUnsafe ( runestone : RunestoneSpec ) : {
105+ encodedRune : Buffer ;
106+ etchingCommitment : Buffer | undefined ;
107+ } {
102108 const mint = runestone . mint
103109 ? Some ( new RuneId ( u64Strict ( runestone . mint . block ) , u32Strict ( runestone . mint . tx ) ) )
104110 : None ;
@@ -112,20 +118,28 @@ export function encodeRunestoneUnsafe(runestone: RunestoneSpec): Buffer {
112118 } ) ) ;
113119
114120 let etching : Option < Etching > = None ;
121+ let etchingCommitment : string | undefined = undefined ;
115122 if ( runestone . etching ) {
116123 const etchingSpec = runestone . etching ;
117-
118- if ( ! etchingSpec . rune && etchingSpec . spacers ?. length ) {
119- throw Error ( 'Spacers specified with no rune' ) ;
124+ let hasSpacers = false ;
125+ for ( const spacer of SPACERS ) {
126+ if ( runestone . etching ?. rune ?. includes ( spacer ) ) {
127+ hasSpacers = true ;
128+ break ;
129+ }
120130 }
121131
122- if (
123- etchingSpec . rune &&
124- etchingSpec . spacers ?. length &&
125- Math . max ( ...etchingSpec . spacers ) ! >= etchingSpec . rune . length - 1
126- ) {
127- throw Error ( 'Spacers specified out of bounds of rune' ) ;
132+ let runeSpacers : number | undefined = undefined ;
133+ let parsedRawRune : Rune | undefined = undefined ;
134+ if ( hasSpacers ) {
135+ const spacedRune = etchingSpec . rune ? SpacedRune . fromString ( etchingSpec . rune ) : undefined ;
136+ runeSpacers = spacedRune ?. spacers ;
137+ parsedRawRune = spacedRune ?. rune ;
138+ } else {
139+ parsedRawRune = etchingSpec . rune ? Rune . fromString ( etchingSpec . rune ) : undefined ;
128140 }
141+ const rune : Option < Rune > =
142+ parsedRawRune !== undefined ? Some ( parsedRawRune ) . map ( ( ) => parsedRawRune ! ) : None ;
129143
130144 if ( etchingSpec . symbol && etchingSpec . symbol . codePointAt ( 1 ) !== undefined ) {
131145 throw Error ( 'Symbol must be one code point' ) ;
@@ -135,17 +149,7 @@ export function encodeRunestoneUnsafe(runestone: RunestoneSpec): Buffer {
135149 etchingSpec . divisibility !== undefined ? Some ( etchingSpec . divisibility ) . map ( u8Strict ) : None ;
136150 const premine =
137151 etchingSpec . premine !== undefined ? Some ( etchingSpec . premine ) . map ( u128Strict ) : None ;
138- const rune =
139- etchingSpec . rune !== undefined
140- ? Some ( etchingSpec . rune ) . map ( ( rune ) => Rune . fromString ( rune ) )
141- : None ;
142- const spacers = etchingSpec . spacers
143- ? Some (
144- u32Strict (
145- etchingSpec . spacers . reduce ( ( spacers , flagIndex ) => spacers | ( 1 << flagIndex ) , 0 )
146- )
147- )
148- : None ;
152+ const spacers : Option < u32 > = hasSpacers && runeSpacers ? Some ( u32Strict ( runeSpacers ) ) : None ;
149153 const symbol = etchingSpec . symbol ? Some ( etchingSpec . symbol ) : None ;
150154
151155 if ( divisibility . isSome ( ) && divisibility . unwrap ( ) > MAX_DIVISIBILITY ) {
@@ -185,7 +189,11 @@ export function encodeRunestoneUnsafe(runestone: RunestoneSpec): Buffer {
185189 const turbo = etchingSpec . turbo ?? false ;
186190
187191 etching = Some ( new Etching ( divisibility , rune , spacers , symbol , terms , premine , turbo ) ) ;
192+ etchingCommitment = ( parsedRawRune as Rune ) ?. commitment ;
188193 }
189194
190- return new Runestone ( mint , pointer , edicts , etching ) . encipher ( ) ;
195+ return {
196+ encodedRune : new Runestone ( mint , pointer , edicts , etching ) . encipher ( ) ,
197+ etchingCommitment,
198+ } ;
191199}
0 commit comments