@@ -58,6 +58,9 @@ import { getChannelState, type ChannelState } from './State.js'
5858 * })
5959 * ```
6060 */
61+ const LOG_PREFIX = '[stellar:channel]'
62+ const STORE_PREFIX = 'stellar:channel'
63+
6164export function channel ( parameters : channel . Parameters ) {
6265 const {
6366 channel : channelAddress ,
@@ -95,7 +98,7 @@ export function channel(parameters: channel.Parameters) {
9598 const feeBumpKeypair = feeBumpSignerParam ? resolveKeypair ( feeBumpSignerParam ) : undefined
9699
97100 // Track cumulative amounts per channel in the store
98- const cumulativeKey = `stellar:channel :cumulative:${ channelAddress } `
101+ const cumulativeKey = `${ STORE_PREFIX } :cumulative:${ channelAddress } `
99102
100103 // Serialize verify operations to prevent concurrent double-acceptance.
101104 // Without a transactional store, two concurrent verify calls could both
@@ -149,13 +152,13 @@ export function channel(parameters: channel.Parameters) {
149152 // NM-001: Reject credentials once the channel has been closed on-chain.
150153 // Applied to all actions including 'open'.
151154 if ( store ) {
152- const closed = await store . get ( `stellar:channel :closed:${ channelAddress } ` )
155+ const closed = await store . get ( `${ STORE_PREFIX } :closed:${ channelAddress } ` )
153156 if ( closed ) {
154- logger . warn ( '[stellar:channel] Rejecting credential — channel already closed' , {
157+ logger . warn ( ` ${ LOG_PREFIX } Rejecting credential — channel already closed` , {
155158 channel : channelAddress ,
156159 } )
157160 throw new ChannelVerificationError (
158- '[stellar:channel] Channel has been closed. No further credentials accepted.' ,
161+ ` ${ LOG_PREFIX } Channel has been closed. No further credentials accepted.` ,
159162 { channel : channelAddress } ,
160163 )
161164 }
@@ -166,7 +169,7 @@ export function channel(parameters: channel.Parameters) {
166169 // be exploited in a single-process deployment. Multi-process
167170 // deployments MUST use a store with atomic put-if-absent semantics.
168171 if ( store ) {
169- const replayKey = `stellar:channel :challenge:${ challenge . id } `
172+ const replayKey = `${ STORE_PREFIX } :challenge:${ challenge . id } `
170173 const existing = await store . get ( replayKey )
171174 if ( existing ) {
172175 throw new ChannelVerificationError ( 'Challenge already used. Replay rejected.' , {
@@ -210,14 +213,14 @@ export function channel(parameters: channel.Parameters) {
210213 sourceAccount,
211214 } )
212215
213- logger . debug ( '[stellar:channel] On-chain state check' , {
216+ logger . debug ( ` ${ LOG_PREFIX } On-chain state check` , {
214217 balance : state . balance . toString ( ) ,
215218 closeAt : state . closeEffectiveAtLedger ,
216219 } )
217220
218221 // Cache the on-chain state for the caller
219222 if ( store ) {
220- await store . put ( `stellar:channel :state:${ channelAddress } ` , {
223+ await store . put ( `${ STORE_PREFIX } :state:${ channelAddress } ` , {
221224 balance : state . balance . toString ( ) ,
222225 closeEffectiveAtLedger : state . closeEffectiveAtLedger ,
223226 currentLedger : state . currentLedger ,
@@ -229,12 +232,12 @@ export function channel(parameters: channel.Parameters) {
229232 onDisputeDetected ?.( state )
230233
231234 if ( state . currentLedger >= state . closeEffectiveAtLedger ) {
232- logger . warn ( '[stellar:channel] Channel is closed — effective ledger reached' , {
235+ logger . warn ( ` ${ LOG_PREFIX } Channel is closed — effective ledger reached` , {
233236 closeEffectiveAtLedger : state . closeEffectiveAtLedger ,
234237 currentLedger : state . currentLedger ,
235238 } )
236239 throw new ChannelVerificationError (
237- '[stellar:channel] Channel is closed: close effective ledger has been reached.' ,
240+ ` ${ LOG_PREFIX } Channel is closed: close effective ledger has been reached.` ,
238241 {
239242 closeEffectiveAtLedger : String ( state . closeEffectiveAtLedger ) ,
240243 currentLedger : String ( state . currentLedger ) ,
@@ -245,12 +248,12 @@ export function channel(parameters: channel.Parameters) {
245248
246249 // NM-003: Reject commitments that exceed the channel's on-chain balance.
247250 if ( commitmentAmount > state . balance ) {
248- logger . warn ( '[stellar:channel] Commitment exceeds channel balance' , {
251+ logger . warn ( ` ${ LOG_PREFIX } Commitment exceeds channel balance` , {
249252 commitmentAmount : commitmentAmount . toString ( ) ,
250253 balance : state . balance . toString ( ) ,
251254 } )
252255 throw new ChannelVerificationError (
253- `[stellar:channel] Commitment ${ commitmentAmount } exceeds channel balance ${ state . balance } .` ,
256+ `${ LOG_PREFIX } Commitment ${ commitmentAmount } exceeds channel balance ${ state . balance } .` ,
254257 {
255258 commitmentAmount : commitmentAmount . toString ( ) ,
256259 balance : state . balance . toString ( ) ,
@@ -262,11 +265,11 @@ export function channel(parameters: channel.Parameters) {
262265 if ( error instanceof ChannelVerificationError ) throw error
263266 // NM-005: Fail closed — reject the voucher when the on-chain
264267 // check cannot be completed rather than silently skipping it.
265- logger . warn ( '[stellar:channel] On-chain state check failed' , {
268+ logger . warn ( ` ${ LOG_PREFIX } On-chain state check failed` , {
266269 error : error instanceof Error ? error . message : String ( error ) ,
267270 } )
268271 throw new ChannelVerificationError (
269- '[stellar:channel] On-chain state check failed. Cannot verify channel status.' ,
272+ ` ${ LOG_PREFIX } On-chain state check failed. Cannot verify channel status.` ,
270273 { error : error instanceof Error ? error . message : String ( error ) } ,
271274 )
272275 }
@@ -276,12 +279,12 @@ export function channel(parameters: channel.Parameters) {
276279 try {
277280 validateHexSignature ( signatureHex )
278281 } catch ( err ) {
279- logger . warn ( '[stellar:channel] Invalid signature format' , {
282+ logger . warn ( ` ${ LOG_PREFIX } Invalid signature format` , {
280283 signature : signatureHex ,
281284 length : signatureHex ?. length ,
282285 } )
283286 throw new ChannelVerificationError (
284- `[stellar:channel] ${ err instanceof Error ? err . message : 'Invalid signature' } ` ,
287+ `${ LOG_PREFIX } ${ err instanceof Error ? err . message : 'Invalid signature' } ` ,
285288 { signature : signatureHex , length : String ( signatureHex ?. length ?? 0 ) } ,
286289 )
287290 }
@@ -300,22 +303,22 @@ export function channel(parameters: channel.Parameters) {
300303 validateAmount ( challengeRequest . amount )
301304 const requestedAmount = BigInt ( challengeRequest . amount )
302305 if ( requestedAmount <= 0n ) {
303- logger . warn ( '[stellar:channel] Non-positive requested amount' , {
306+ logger . warn ( ` ${ LOG_PREFIX } Non-positive requested amount` , {
304307 requestedAmount : requestedAmount . toString ( ) ,
305308 } )
306- throw new ChannelVerificationError ( '[stellar:channel] Requested amount must be positive.' , {
309+ throw new ChannelVerificationError ( ` ${ LOG_PREFIX } Requested amount must be positive.` , {
307310 requestedAmount : requestedAmount . toString ( ) ,
308311 } )
309312 }
310313
311314 // The new cumulative must be strictly greater than previous cumulative
312315 if ( commitmentAmount <= previousCumulative ) {
313- logger . warn ( '[stellar:channel] Commitment not greater than previous cumulative' , {
316+ logger . warn ( ` ${ LOG_PREFIX } Commitment not greater than previous cumulative` , {
314317 commitmentAmount : commitmentAmount . toString ( ) ,
315318 previousCumulative : previousCumulative . toString ( ) ,
316319 } )
317320 throw new ChannelVerificationError (
318- `[stellar:channel] Commitment amount ${ commitmentAmount } must be greater than previous cumulative ${ previousCumulative } .` ,
321+ `${ LOG_PREFIX } Commitment amount ${ commitmentAmount } must be greater than previous cumulative ${ previousCumulative } .` ,
319322 {
320323 commitmentAmount : commitmentAmount . toString ( ) ,
321324 previousCumulative : previousCumulative . toString ( ) ,
@@ -325,13 +328,13 @@ export function channel(parameters: channel.Parameters) {
325328
326329 // The commitment must cover the requested amount
327330 if ( commitmentAmount < previousCumulative + requestedAmount ) {
328- logger . warn ( '[stellar:channel] Commitment does not cover requested amount' , {
331+ logger . warn ( ` ${ LOG_PREFIX } Commitment does not cover requested amount` , {
329332 commitmentAmount : commitmentAmount . toString ( ) ,
330333 requestedAmount : requestedAmount . toString ( ) ,
331334 previousCumulative : previousCumulative . toString ( ) ,
332335 } )
333336 throw new ChannelVerificationError (
334- `[stellar:channel] Commitment amount ${ commitmentAmount } does not cover the requested amount ${ requestedAmount } (previous cumulative: ${ previousCumulative } ).` ,
337+ `${ LOG_PREFIX } Commitment amount ${ commitmentAmount } does not cover the requested amount ${ requestedAmount } (previous cumulative: ${ previousCumulative } ).` ,
335338 {
336339 commitmentAmount : commitmentAmount . toString ( ) ,
337340 requestedAmount : requestedAmount . toString ( ) ,
@@ -343,7 +346,7 @@ export function channel(parameters: channel.Parameters) {
343346 // Verify: call prepare_commitment on the channel contract to
344347 // reconstruct the expected commitment bytes, then verify the
345348 // ed25519 signature.
346- logger . debug ( '[stellar:channel] Verifying commitment signature...' )
349+ logger . debug ( ` ${ LOG_PREFIX } Verifying commitment signature...` )
347350 const contract = new Contract ( channelAddress )
348351 const call = contract . call (
349352 'prepare_commitment' ,
@@ -364,7 +367,7 @@ export function channel(parameters: channel.Parameters) {
364367 const returnValue = simResult . result ?. retval
365368 if ( ! returnValue ) {
366369 throw new ChannelVerificationError (
367- '[stellar:channel] prepare_commitment returned no value.' ,
370+ ` ${ LOG_PREFIX } prepare_commitment returned no value.` ,
368371 { } ,
369372 )
370373 }
@@ -375,12 +378,12 @@ export function channel(parameters: channel.Parameters) {
375378 const valid = commitmentKeypair . verify ( Buffer . from ( commitmentBytes ) , signatureBytes )
376379
377380 if ( ! valid ) {
378- logger . warn ( '[stellar:channel] Commitment signature verification failed' , {
381+ logger . warn ( ` ${ LOG_PREFIX } Commitment signature verification failed` , {
379382 amount : commitmentAmount . toString ( ) ,
380383 channel : channelAddress ,
381384 } )
382385 throw new ChannelVerificationError (
383- '[stellar:channel] Commitment signature verification failed.' ,
386+ ` ${ LOG_PREFIX } Commitment signature verification failed.` ,
384387 {
385388 amount : commitmentAmount . toString ( ) ,
386389 channel : channelAddress ,
@@ -399,7 +402,7 @@ export function channel(parameters: channel.Parameters) {
399402 if ( action === 'close' ) {
400403 if ( ! signerKeypair ) {
401404 throw new ChannelVerificationError (
402- '[stellar:channel] Close action requires a signer to be configured.' ,
405+ ` ${ LOG_PREFIX } Close action requires a signer to be configured.` ,
403406 { } ,
404407 )
405408 }
@@ -431,7 +434,7 @@ export function channel(parameters: channel.Parameters) {
431434 } )
432435 }
433436
434- logger . debug ( '[stellar:channel] Broadcasting close tx...' )
437+ logger . debug ( ` ${ LOG_PREFIX } Broadcasting close tx...` )
435438 const sendResult = await server . sendTransaction ( txToSubmit )
436439
437440 const txResult = await pollTransaction ( server , sendResult . hash , {
@@ -442,7 +445,7 @@ export function channel(parameters: channel.Parameters) {
442445
443446 if ( txResult . status !== 'SUCCESS' ) {
444447 throw new ChannelVerificationError (
445- `[stellar:channel] Close transaction failed: ${ txResult . status } ` ,
448+ `${ LOG_PREFIX } Close transaction failed: ${ txResult . status } ` ,
446449 {
447450 hash : sendResult . hash ,
448451 status : txResult . status ,
@@ -451,9 +454,9 @@ export function channel(parameters: channel.Parameters) {
451454 }
452455
453456 // Mark channel as closed in store
454- logger . debug ( '[stellar:channel] Channel closed, marking in store' )
457+ logger . debug ( ` ${ LOG_PREFIX } Channel closed, marking in store` )
455458 if ( store ) {
456- await store . put ( `stellar:channel :closed:${ channelAddress } ` , {
459+ await store . put ( `${ STORE_PREFIX } :closed:${ channelAddress } ` , {
457460 closedAt : new Date ( ) . toISOString ( ) ,
458461 txHash : sendResult . hash ,
459462 amount : commitmentAmount . toString ( ) ,
@@ -489,7 +492,7 @@ export function channel(parameters: channel.Parameters) {
489492
490493 if ( ! txXdr || typeof txXdr !== 'string' ) {
491494 throw new ChannelVerificationError (
492- '[stellar:channel] Open action requires a signed transaction XDR.' ,
495+ ` ${ LOG_PREFIX } Open action requires a signed transaction XDR.` ,
493496 { } ,
494497 )
495498 }
@@ -498,11 +501,11 @@ export function channel(parameters: channel.Parameters) {
498501 try {
499502 validateHexSignature ( signatureHex )
500503 } catch {
501- logger . warn ( '[stellar:channel] Invalid commitment signature for open action' , {
504+ logger . warn ( ` ${ LOG_PREFIX } Invalid commitment signature for open action` , {
502505 length : signatureHex ?. length ,
503506 } )
504507 throw new ChannelVerificationError (
505- '[stellar:channel] Invalid commitment signature for open action.' ,
508+ ` ${ LOG_PREFIX } Invalid commitment signature for open action.` ,
506509 {
507510 length : String ( signatureHex ?. length ?? 0 ) ,
508511 } ,
@@ -519,23 +522,23 @@ export function channel(parameters: channel.Parameters) {
519522 const requestedAmount = BigInt ( challenge . request . amount )
520523 if ( requestedAmount <= 0n ) {
521524 throw new ChannelVerificationError (
522- '[stellar:channel] Open action requires a positive requested amount.' ,
525+ ` ${ LOG_PREFIX } Open action requires a positive requested amount.` ,
523526 {
524527 requestedAmount : requestedAmount . toString ( ) ,
525528 } ,
526529 )
527530 }
528531 if ( commitmentAmount <= 0n ) {
529532 throw new ChannelVerificationError (
530- '[stellar:channel] Open action requires a positive commitment amount.' ,
533+ ` ${ LOG_PREFIX } Open action requires a positive commitment amount.` ,
531534 {
532535 commitmentAmount : commitmentAmount . toString ( ) ,
533536 } ,
534537 )
535538 }
536539 if ( commitmentAmount < requestedAmount ) {
537540 throw new ChannelVerificationError (
538- '[stellar:channel] Commitment amount does not cover requested amount for open action.' ,
541+ ` ${ LOG_PREFIX } Commitment amount does not cover requested amount for open action.` ,
539542 {
540543 commitmentAmount : commitmentAmount . toString ( ) ,
541544 requestedAmount : requestedAmount . toString ( ) ,
@@ -548,14 +551,14 @@ export function channel(parameters: channel.Parameters) {
548551 const existing = await store . get ( cumulativeKey )
549552 if ( existing ) {
550553 throw new ChannelVerificationError (
551- '[stellar:channel] Channel is already open. Cannot replay an open credential.' ,
554+ ` ${ LOG_PREFIX } Channel is already open. Cannot replay an open credential.` ,
552555 { channel : channelAddress } ,
553556 )
554557 }
555558 }
556559
557560 // Verify the initial commitment signature via prepare_commitment simulation
558- logger . debug ( '[stellar:channel] Verifying commitment signature...' )
561+ logger . debug ( ` ${ LOG_PREFIX } Verifying commitment signature...` )
559562 const contract = new Contract ( channelAddress )
560563 const call = contract . call (
561564 'prepare_commitment' ,
@@ -576,7 +579,7 @@ export function channel(parameters: channel.Parameters) {
576579 const returnValue = simResult . result ?. retval
577580 if ( ! returnValue ) {
578581 throw new ChannelVerificationError (
579- '[stellar:channel] prepare_commitment returned no value during open.' ,
582+ ` ${ LOG_PREFIX } prepare_commitment returned no value during open.` ,
580583 { } ,
581584 )
582585 }
@@ -586,12 +589,12 @@ export function channel(parameters: channel.Parameters) {
586589 const valid = commitmentKeypair . verify ( Buffer . from ( commitmentBytes ) , signatureBytes )
587590
588591 if ( ! valid ) {
589- logger . warn ( '[stellar:channel] Initial commitment signature verification failed' , {
592+ logger . warn ( ` ${ LOG_PREFIX } Initial commitment signature verification failed` , {
590593 amount : commitmentAmount . toString ( ) ,
591594 channel : channelAddress ,
592595 } )
593596 throw new ChannelVerificationError (
594- '[stellar:channel] Initial commitment signature verification failed.' ,
597+ ` ${ LOG_PREFIX } Initial commitment signature verification failed.` ,
595598 {
596599 amount : commitmentAmount . toString ( ) ,
597600 channel : channelAddress ,
@@ -604,7 +607,7 @@ export function channel(parameters: channel.Parameters) {
604607 try {
605608 openTx = TransactionBuilder . fromXDR ( txXdr , networkPassphrase )
606609 } catch ( err ) {
607- throw new ChannelVerificationError ( '[stellar:channel] Invalid open transaction XDR.' , {
610+ throw new ChannelVerificationError ( ` ${ LOG_PREFIX } Invalid open transaction XDR.` , {
608611 error : err instanceof Error ? err . message : String ( err ) ,
609612 } )
610613 }
@@ -628,7 +631,7 @@ export function channel(parameters: channel.Parameters) {
628631
629632 if ( txResult . status !== 'SUCCESS' ) {
630633 throw new ChannelVerificationError (
631- `[stellar:channel] Open transaction failed: ${ txResult . status } ` ,
634+ `${ LOG_PREFIX } Open transaction failed: ${ txResult . status } ` ,
632635 {
633636 hash : sendResult . hash ,
634637 status : txResult . status ,
@@ -730,7 +733,7 @@ export async function close(parameters: {
730733 } )
731734 }
732735
733- log . debug ( '[stellar:channel] Broadcasting close tx...' )
736+ log . debug ( ` ${ LOG_PREFIX } Broadcasting close tx...` )
734737 const result = await server . sendTransaction ( txToSubmit )
735738
736739 const txResult = await pollTransaction ( server , result . hash , {
@@ -741,7 +744,7 @@ export async function close(parameters: {
741744
742745 if ( txResult . status !== 'SUCCESS' ) {
743746 throw new ChannelVerificationError (
744- `[stellar:channel] Close transaction failed: ${ txResult . status } ` ,
747+ `${ LOG_PREFIX } Close transaction failed: ${ txResult . status } ` ,
745748 {
746749 hash : result . hash ,
747750 status : txResult . status ,
0 commit comments