Bootstrap copied BFF and local accounts with public Sendico contracts (#34)

This commit is contained in:
Stephan D committed 2026-09-12 13:37:48 +02:00
1 parent 67dc5b5b1e
commit 7062672a87
556 files changed
+42291 -777

No files matched your search

+50
View File
@@ -0,0 +1,50 @@
package moneybase
import (
"math/big"
"strings"
decimalbase "git.sendico.io/tech/sxchnge/bff/pkg/decimal"
"git.sendico.io/tech/sxchnge/bff/pkg/merrors"
)
// SourceRoundedConversionMatches reports whether sourceAmount is the minimum
// source-scale amount that covers targetAmount at rate.
func SourceRoundedConversionMatches(sourceAmount, targetAmount, rate string, sourceScale uint32) (bool, error) {
if err := ValidateScale("source scale", sourceScale); err != nil {
return false, err
}
source, err := positiveRat(sourceAmount, "source amount")
if err != nil {
return false, err
}
target, err := positiveRat(targetAmount, "target amount")
if err != nil {
return false, err
}
rateRat, err := positiveRat(rate, "conversion rate")
if err != nil {
return false, err
}
exactSource := new(big.Rat).Quo(target, rateRat)
roundedSource := ceilDecimalToScale(exactSource, sourceScale)
return roundedSource.Cmp(source) == 0 && source.Cmp(exactSource) >= 0, nil
}
func positiveRat(value string, field string) (*big.Rat, error) {
parsed, err := decimalbase.RatFromString(strings.TrimSpace(value))
if err != nil || parsed.Sign() <= 0 {
return nil, merrors.InvalidArgument(field + " must be a positive decimal")
}
return parsed, nil
}
func ceilDecimalToScale(value *big.Rat, scale uint32) *big.Rat {
factor := new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(scale)), nil)
scaled := new(big.Rat).Mul(value, new(big.Rat).SetInt(factor))
q, r := new(big.Int).QuoRem(scaled.Num(), scaled.Denom(), new(big.Int))
if r.Sign() > 0 {
q.Add(q, big.NewInt(1))
}
return new(big.Rat).SetFrac(q, factor)
}
+29
View File
@@ -0,0 +1,29 @@
package moneybase
import (
"testing"
)
func TestSourceRoundedConversionMatches(t *testing.T) {
ok, err := SourceRoundedConversionMatches("0.06", "3.72", "73.1275", 2)
if err != nil {
t.Fatalf("SourceRoundedConversionMatches returned error: %v", err)
}
if !ok {
t.Fatal("expected rounded source conversion to match")
}
ok, err = SourceRoundedConversionMatches("0.07", "3.72", "73.1275", 2)
if err != nil {
t.Fatalf("SourceRoundedConversionMatches returned error: %v", err)
}
if ok {
t.Fatal("expected oversized source amount to fail")
}
ok, err = SourceRoundedConversionMatches("0.05", "3.72", "73.1275", 2)
if err != nil {
t.Fatalf("SourceRoundedConversionMatches returned error: %v", err)
}
if ok {
t.Fatal("expected undersized source amount to fail")
}
}
+12
View File
@@ -0,0 +1,12 @@
package moneybase
import "git.sendico.io/tech/sxchnge/bff/pkg/merrors"
const MaxScale uint32 = 36
func ValidateScale(field string, scale uint32) error {
if scale > MaxScale {
return merrors.InvalidArgumentf("%s exceeds supported money scale %d", field, MaxScale)
}
return nil
}