PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/p/nt/treasury/v0

Package
Open in gnoweb ↗

Overview

Kind
Pure package
Name
v0
Namespace
nt / treasury
Files
14 (README)(gnomod.toml)
Exported functions
n/a — not supported for pure packages by the node (vm/qfuncs)
Module
gno.land/p/nt/treasury/v0
gno
0.9

Files (14)

  • README.mdmarkdown
  • gnomod.tomltoml
  • banker_coins.gnogno
  • banker_grc20.gnogno
  • doc.gnogno
  • render.gnogno
  • treasury.gnogno
  • types.gnogno
  • banker_canonical_filetest.gnogno
  • banker_coins_filetest.gnogno
  • banker_coins_payment_canonical_filetest.gnogno
  • banker_coins_payment_copy_filetest.gnogno
  • banker_grc20_filetest.gnogno
  • treasury_filetest.gnogno
  • treasury.gnogno
    1package treasury23import (4	"errors"56	"gno.land/p/nt/bptree/pager/v0"7	"gno.land/p/nt/bptree/v0"8

    Functions

    not supported for pure packages by the node (vm/qfuncs)

    Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.

    "gno.land/p/nt/ufmt/v0"
    9)
    10
    11var (
    12 ErrNoBankerProvided = errors.New("no banker provided")
    13 ErrDuplicateBanker = errors.New("duplicate banker")
    14 ErrBankerNotFound = errors.New("banker not found")
    15 ErrSendPaymentFailed = errors.New("failed to send payment")
    16 ErrNonCanonicalBankerImpl = errors.New("non-canonical Banker impl: only *CoinsBanker / *GRC20Banker accepted")
    17)
    18
    19// New creates a new Treasury instance with the given bankers.
    20//
    21// pkgPath should be the package path of the owning realm. It is
    22// captured on the Treasury and used to build the "See full history"
    23// link in RenderBanker. Pass `cur.PkgPath()` from the owning realm's
    24// init (or another live-cur context). Passing "" disables the link.
    25//
    26// The path is stored as plain data — no IsCurrent guard inside this
    27// /p/ constructor. The caller is the trust boundary; it must derive
    28// the value from a real `cur realm` rather than accept it from
    29// untrusted input. The captured path is consumed only for render
    30// output (Class-2 designation-forgery shape, accepted as
    31// display-only — see docs/resources/gno-security.md).
    32//
    33// Each banker must be one of treasury's canonical concrete impls
    34// (*CoinsBanker, *GRC20Banker) per IsCanonicalBanker. Foreign-realm impls
    35// (including embedded wrappers around canonical types) are rejected: a
    36// malicious Send impl would receive a capability token via its rlm
    37// parameter when treasury.Send dispatches into it.
    38//
    39// The allowlist validates type only, not captured state. Treasury operators
    40// must construct their own bankers; never accept a pre-built *Banker value
    41// from an external realm.
    42func New(bankers []Banker, pkgPath string) (*Treasury, error) {
    43 if len(bankers) == 0 {
    44 return nil, ErrNoBankerProvided
    45 }
    46
    47 // Canonical-impl allowlist: reject foreign types (embedding-based
    48 // bypasses fail here because type assertions are nominal).
    49 for _, b := range bankers {
    50 if !IsCanonicalBanker(b) {
    51 return nil, ErrNonCanonicalBankerImpl
    52 }
    53 }
    54
    55 // Create a new Treasury instance.
    56 treasury := &Treasury{bankers: bptree.NewBPTree32(), realmPath: pkgPath}
    57
    58 // Register the bankers.
    59 for _, banker := range bankers {
    60 if treasury.bankers.Has(banker.ID()) {
    61 return nil, ufmt.Errorf("%v: %s", ErrDuplicateBanker, banker.ID())
    62 }
    63
    64 treasury.bankers.Set(
    65 banker.ID(),
    66 &bankerRecord{banker: banker},
    67 )
    68 }
    69
    70 // Register the Render routes.
    71 treasury.initRenderRouter()
    72
    73 return treasury, nil
    74}
    75
    76// Send sends a payment using the corresponding banker. rlm is threaded
    77// to the banker's Send for IsCurrent + owner validation.
    78func (t *Treasury) Send(_ int, rlm realm, p Payment) error {
    79 // Get the banker record corresponding to this Payment.
    80 br := t.bankers.Get(p.BankerID())
    81 if br == nil {
    82 return ufmt.Errorf("%v: %s", ErrBankerNotFound, p.BankerID())
    83 }
    84 record := br.(*bankerRecord)
    85
    86 // Send the payment using the corresponding banker.
    87 if err := record.banker.Send(0, rlm, p); err != nil {
    88 return ufmt.Errorf("%v: %s", ErrSendPaymentFailed, err)
    89 }
    90
    91 // Add the payment to the history of the banker.
    92 record.history.Append(p)
    93
    94 return nil
    95}
    96
    97// History returns the payment history sent by the banker with the given ID.
    98// Payments are paginated, with the most recent payments first.
    99func (t *Treasury) History(
    100 bankerID string,
    101 pageNumber int,
    102 pageSize int,
    103) ([]Payment, error) {
    104 // Get the banker record corresponding to this ID.
    105 br := t.bankers.Get(bankerID)
    106 if br == nil {
    107 return nil, ufmt.Errorf("%v: %s", ErrBankerNotFound, bankerID)
    108 }
    109 history := br.(*bankerRecord).history
    110
    111 // Get the page of payments from the history.
    112 p := pager.NewPager(history.Tree(), pageSize, true)
    113 page := p.GetPage(pageNumber)
    114
    115 // Convert the items in the page to a slice of Payments.
    116 payments := make([]Payment, len(page.Items))
    117 for i := range page.Items {
    118 payments[i] = page.Items[i].Value.(Payment)
    119 }
    120
    121 return payments, nil
    122}
    123
    124// Balances returns the balances of the banker with the given ID.
    125func (t *Treasury) Balances(bankerID string) ([]Balance, error) {
    126 // Get the banker record corresponding to this ID.
    127 br := t.bankers.Get(bankerID)
    128 if br == nil {
    129 return nil, ufmt.Errorf("%v: %s", ErrBankerNotFound, bankerID)
    130 }
    131
    132 // Get the balances from the banker.
    133 return br.(*bankerRecord).banker.Balances(), nil
    134}
    135
    136// Address returns the address of the banker with the given ID.
    137func (t *Treasury) Address(bankerID string) (string, error) {
    138 // Get the banker record corresponding to this ID.
    139 br := t.bankers.Get(bankerID)
    140 if br == nil {
    141 return "", ufmt.Errorf("%v: %s", ErrBankerNotFound, bankerID)
    142 }
    143
    144 // Get the address from the banker.
    145 return br.(*bankerRecord).banker.Address(), nil
    146}
    147
    148// HasBanker checks if a banker with the given ID is registered.
    149func (t *Treasury) HasBanker(bankerID string) bool {
    150 return t.bankers.Has(bankerID)
    151}
    152
    153// ListBankerIDs returns a list of all registered banker IDs.
    154func (t *Treasury) ListBankerIDs() []string {
    155 var bankerIDs []string
    156
    157 t.bankers.Iterate("", "", func(bankerID string, _ any) bool {
    158 bankerIDs = append(bankerIDs, bankerID)
    159 return false
    160 })
    161
    162 return bankerIDs
    163}
    164