From dc062682e0ef9657bc6a63f30d827b801e4388ce Mon Sep 17 00:00:00 2001 From: Paul Nicolas Date: Tue, 23 Jun 2026 08:10:57 +0200 Subject: [PATCH] feat(builder): add SrcAllowingUnboundedOverdraft combinator --- builder/source.go | 13 +++++++++++++ builder/source_test.go | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 builder/source_test.go diff --git a/builder/source.go b/builder/source.go index 7da25da8..5a5aad59 100644 --- a/builder/source.go +++ b/builder/source.go @@ -17,6 +17,19 @@ func SrcColored( } } +// SrcAllowingUnboundedOverdraft wraps a source (typically SrcAccount or +// SrcColored) and appends the `allowing unbounded overdraft` clause, per the +// Numscript grammar rule `srcAccountUnboundedOverdraft` +// (address colorConstraint? ALLOWING UNBOUNDED OVERDRAFT). It lets a non-world +// source go negative — required, for instance, when minting a colour the +// account does not yet hold. +func SrcAllowingUnboundedOverdraft(source Source) Source { + return func(env *env, w int) { + source(env, w) + env.builder.WriteString(" allowing unbounded overdraft") + } +} + func SrcInorder(sources ...Source) Source { return func(env *env, w int) { env.builder.WriteString("{\n") diff --git a/builder/source_test.go b/builder/source_test.go new file mode 100644 index 00000000..f2cb2f71 --- /dev/null +++ b/builder/source_test.go @@ -0,0 +1,40 @@ +package builder_test + +import ( + "math/big" + "testing" + + "github.com/formancehq/numscript/builder" + "github.com/gkampitakis/go-snaps/snaps" +) + +func TestSrcAllowingUnboundedOverdraft(t *testing.T) { + stmt := builder.StmtSend( + builder.ExprMonetary( + builder.ExprAsset("USD/2"), + builder.ExprNumberBigInt(big.NewInt(100)), + ), + builder.SrcAllowingUnboundedOverdraft( + builder.SrcColored( + builder.ExprAccount("tmp:acc"), + builder.ExprString("ABCDEF"), + ), + ), + builder.DestAccount( + builder.ExprAccount("dest"), + ), + ) + + _, _, script := builder.BuildProgram(stmt) + snaps.MatchInlineSnapshot(t, script, snaps.Inline(`vars { + account $account_0 + account $account_1 + string $string_0 + asset $asset_0 +} + +send [$asset_0 100] ( + source = $account_0 \ $string_0 allowing unbounded overdraft + destination = $account_1 +)`)) +}