Documentation
¶
Index ¶
- Constants
- Variables
- func Handshake() goplugin.HandshakeConfig
- func ParseAmount(value string) (*big.Rat, error)
- func Serve(implementation Plugin)
- func WriteError(w http.ResponseWriter, err error)
- func WriteJSON(w http.ResponseWriter, statusCode int, value any)
- type Caller
- type Captcha
- type Catalog
- type Config
- type ConfigWatcher
- type CreditRequest
- type DebitRequest
- type Email
- type Env
- type HTTPPlugin
- type HealthChecker
- type Host
- type HostError
- type KV
- func (s KV) Delete(ctx context.Context, collection, key string, ifVersion int64) (bool, error)
- func (s KV) Get(ctx context.Context, collection, key string) (*pluginpb.KVGetResponse, error)
- func (s KV) Incr(ctx context.Context, collection, key string, delta int64, ttl time.Duration) (*pluginpb.KVIncrResponse, error)
- func (s KV) List(ctx context.Context, request *pluginpb.KVListRequest) (*pluginpb.KVListResponse, error)
- func (s KV) Put(ctx context.Context, collection, key string, value any, options ...PutOption) (int64, error)
- type Orders
- type Plugin
- type PutOption
- type Redeem
- type Shutdowner
- type Site
- type Subscriptions
- func (s Subscriptions) Grant(ctx context.Context, request *pluginpb.GrantSubscriptionRequest) (*pluginpb.GrantSubscriptionResponse, error)
- func (s Subscriptions) ListForUser(ctx context.Context, userID int64, activeOnly bool) (*pluginpb.ListUserSubscriptionsResponse, error)
- func (s Subscriptions) Plans(ctx context.Context) (*pluginpb.ListSubscriptionPlansResponse, error)
- type TaskPlugin
- type Usage
- func (s Usage) Ranking(ctx context.Context, request *pluginpb.GetUsageRankingRequest) (*pluginpb.GetUsageRankingResponse, error)
- func (s Usage) Self(ctx context.Context, caller Caller) (*pluginpb.UsageSummary, error)
- func (s Usage) Stats(ctx context.Context, request *pluginpb.GetUsageStatsRequest) (*pluginpb.GetUsageStatsResponse, error)
- func (s Usage) Summary(ctx context.Context, userID int64) (*pluginpb.UsageSummary, error)
- type Users
- func (s Users) Get(ctx context.Context, userID int64) (*pluginpb.User, error)
- func (s Users) Identities(ctx context.Context, userID int64) (*pluginpb.ListUserIdentitiesResponse, error)
- func (s Users) LookupEmail(ctx context.Context, email string) (*pluginpb.LookupUsersResponse, error)
- func (s Users) LookupIDs(ctx context.Context, ids []int64) (*pluginpb.LookupUsersResponse, error)
- func (s Users) LookupUsername(ctx context.Context, username string) (*pluginpb.LookupUsersResponse, error)
- type Wallet
Constants ¶
const ( // Handshake values identify the TokenRouter protocol independently of publisher identity; the host verifies each installed executable separately. ProtocolVersion = 1 MagicCookieKey = "TOKENROUTER_PLUGIN" MagicCookieValue = "7d1f0c64-1f0a-4a55-9c2a-5b8f3c7e2a19" PluginKey = "tokenrouter" MaxMessageBytes = 16 << 20 )
Variables ¶
var ( // Host capability failures expose stable sentinels for plugin business decisions without requiring authors to inspect transport status messages. ErrPermissionDenied = errors.New("plugin permission not granted") ErrGrantInvalid = errors.New("caller grant is invalid or expired") ErrInsufficientBalance = errors.New("insufficient balance") ErrVersionConflict = errors.New("KV version conflict") ErrUserNotFound = errors.New("user not found") ErrLimitExceeded = errors.New("plugin limit exceeded") ErrInvalidArgument = errors.New("invalid argument") ErrPlanNotAllowed = errors.New("subscription plan not allowed") ErrEmailDeliveryUnknown = errors.New("email delivery outcome is unknown") )
Functions ¶
func Handshake ¶
func Handshake() goplugin.HandshakeConfig
Handshake returns the fixed protocol identity shared by plugins and hosts.
func ParseAmount ¶
ParseAmount parses a positive monetary amount into an exact rational value. Values use ordinary decimal notation with at most seven integer digits and eight fractional digits; zero, signs, and exponent notation are rejected.
func Serve ¶
func Serve(implementation Plugin)
Serve runs a plugin from its executable's main function until host shutdown. Init receives an authenticated callback connection; no host credentials are inherited or reconstructed here. Authors should pass a single implementation and let this entry point own transport listeners and process lifecycle.
Server options preserve go-plugin's automatic TLS configuration and add bounded messages plus panic recovery. A parent watchdog runs for the same lifetime as the server and exits orphaned processes even on platforms where the host cannot install a parent-death signal. Business work must still cooperate with context deadlines to finish within graceful shutdown budgets. @project-doc docs/interfaces/plugin_contracts.md#process_protocol
func WriteError ¶
func WriteError(w http.ResponseWriter, err error)
WriteError maps host failures to safe HTTP status and reason values. Unknown internal errors are not exposed to users. Plugin authors can log the original error separately when their diagnostics policy permits its contents.
func WriteJSON ¶
func WriteJSON(w http.ResponseWriter, statusCode int, value any)
WriteJSON writes one JSON value and the requested HTTP response status. Encoding occurs before headers are committed, so unsupported values produce a plain internal-error JSON response instead of partially encoded output.
Types ¶
type Caller ¶
type Caller struct {
UserID int64 // verified user identifier
Username string // verified account display name
Role string // verified account role
Locale string // negotiated request language
// contains filtered or unexported fields
}
Caller holds host-verified identity and private request authorization metadata.
type Captcha ¶
type Captcha hostClient
Captcha verifies a site captcha using the host-provided request address.
func (Captcha) Verify ¶
func (s Captcha) Verify(ctx context.Context, caller Caller, token string) (*pluginpb.VerifyCaptchaResponse, error)
Verify checks a captcha token using the address carried by its HTTP caller. A disabled site captcha returns enabled=false and success=true. Plugins must decide whether their own workflow permits that disabled-site result.
type Catalog ¶
type Catalog hostClient
Catalog reads the host's public models and effective user groups.
func (Catalog) GroupsForUser ¶
func (s Catalog) GroupsForUser(ctx context.Context, userID int64) (*pluginpb.ListUserGroupsResponse, error)
GroupsForUser returns available groups with the user's effective rate multipliers.
type Config ¶
type Config struct {
// contains filtered or unexported fields
}
Config provides concurrent scalar reads from a host-validated configuration.
func NewConfig ¶
NewConfig parses a configuration object into a separately owned live handle. JSON numbers retain their textual representation until a typed accessor reads them. Nonobject JSON and malformed values return an error.
func (Config) Bool ¶
Bool returns a boolean setting, or false when absent or differently typed. String values are not coerced to booleans. Required-field validation remains the host's responsibility before passing configuration to the plugin.
func (Config) Float ¶
Float returns a numeric setting as float64, or zero for an absent or invalid number. Monetary RPC requests still use decimal strings; callers should avoid using floating arithmetic to construct financial calculations.
func (Config) Int ¶
Int returns an integer setting, or zero when it cannot fit int64. Integral decimal notation is accepted through the numeric representation; values outside the signed range remain unavailable to this accessor.
type ConfigWatcher ¶
type ConfigWatcher interface {
// ConfigChanged receives a snapshot after Env.Config publishes the new values.
// It must honor cancellation; returning an error leaves the host's persisted
// configuration intact and allows diagnosis without reverting settings silently.
ConfigChanged(context.Context, Config) error
}
ConfigWatcher applies configuration changes without restarting the plugin process.
type CreditRequest ¶
type CreditRequest struct {
UserID int64 // target account identifier
Amount string // positive decimal balance amount
IdempotencyKey string // plugin-wide operation replay key
Reason string // user-visible balance adjustment explanation
}
CreditRequest describes a positive, idempotent balance credit for one user.
type DebitRequest ¶
type DebitRequest CreditRequest
DebitRequest describes a positive debit constrained by the supplied caller grant.
type Email ¶
type Email hostClient
Email sends bounded idempotent notifications through the host's subscription preferences.
func (Email) Send ¶
func (s Email) Send(ctx context.Context, request *pluginpb.SendEmailRequest) (*pluginpb.SendEmailResponse, error)
Send requests one idempotent plain-text notification through host templates. An uncertain delivery produces ErrEmailDeliveryUnknown and must not be retried with a new key, which could send the same message twice.
type Env ¶
type Env struct {
PluginID string // publisher-qualified plugin identity
Version string // running plugin release version
PreviousVersion string // previous running release version
HostVersion string // host release build version
InstanceID string // host process instance identity
StateDir string // disposable local cache directory
Permissions []string // administrator-granted capability names
// Config keeps a stable concurrent-read handle; the SDK publishes complete snapshots whenever the host applies new configuration.
Config Config
Host *Host // authenticated host capability client
Logger *slog.Logger // structured plugin stderr logger
}
Env holds process-generation identity, configuration, logging, and host capabilities.
type HTTPPlugin ¶
type HTTPPlugin interface {
// Handler returns a concurrency-safe handler for requests authorized by the host.
Handler() http.Handler
}
HTTPPlugin supplies ordinary Go handlers for declared plugin HTTP routes.
type HealthChecker ¶
type HealthChecker interface {
// Health returns nil while plugin-owned dependencies can serve business calls.
// Implementations must honor the short host deadline. Repeated failures cause
// the supervisor to stop and restart this process generation.
Health(context.Context) error
}
HealthChecker augments the SDK's initialization and stalled-call health checks.
type Host ¶
type Host struct {
Site Site // site context queries
Users Users // account identity queries
Wallet Wallet // balance reads and adjustments
Redeem Redeem // single-use redeem code issuance
Subscriptions Subscriptions // subscription queries and grants
Usage Usage // account usage aggregate queries
Orders Orders // sanitized payment order queries
Catalog Catalog // model and group queries
Email Email // idempotent notification email delivery
Captcha Captcha // site captcha verification
KV KV // plugin-isolated persistent JSON storage
}
Host groups the authenticated capabilities available through one broker connection.
func NewHost ¶
func NewHost(client pluginpb.HostClient) *Host
NewHost groups an authenticated RPC client without initiating any calls. The caller owns the transport connection and keeps it alive while plugin handlers or tasks use the returned capability groups.
type HostError ¶
type HostError struct {
Reason string // stable host reason code
Metadata map[string]string // host error detail metadata
// contains filtered or unexported fields
}
HostError preserves a host reason and the corresponding SDK sentinel.
func (*HostError) GRPCStatus ¶
GRPCStatus preserves status-code inspection when callers receive a HostError.
type KV ¶
type KV hostClient
KV accesses the connected plugin's isolated persistent JSON collections.
func (KV) Delete ¶
Delete removes a key using zero for unconditional or a matching positive version. The returned flag distinguishes deletion from an already absent key. A mismatched conditional version returns ErrVersionConflict without changing data.
func (KV) Incr ¶
func (s KV) Incr(ctx context.Context, collection, key string, delta int64, ttl time.Duration) (*pluginpb.KVIncrResponse, error)
Incr atomically adjusts an integer value, starting absent keys from zero. The host rejects noninteger stored values and overflowing arithmetic. A zero TTL leaves the resulting key without an expiration time.
func (KV) List ¶
func (s KV) List(ctx context.Context, request *pluginpb.KVListRequest) (*pluginpb.KVListResponse, error)
List reads a prefix-filtered page ordered by key with a continuation cursor.
func (KV) Put ¶
func (s KV) Put(ctx context.Context, collection, key string, value any, options ...PutOption) (int64, error)
Put encodes a JSON value and returns its newly stored version. Conditions and TTL default to unconditional and nonexpiring. Options apply in order, so a later condition or lifetime replaces the earlier selection.
type Orders ¶
type Orders hostClient
Orders reads sanitized user payment orders without payment channel credentials.
func (Orders) ListForUser ¶
func (s Orders) ListForUser(ctx context.Context, request *pluginpb.ListUserOrdersRequest) (*pluginpb.ListUserOrdersResponse, error)
ListForUser returns sanitized order fields for the requested account page.
type Plugin ¶
type Plugin interface {
// Init receives validated configuration and a connected host callback client.
// It must honor cancellation and return only when contributions are ready;
// a failure prevents this process generation from becoming healthy.
Init(context.Context, *Env) error
}
Plugin initializes one process generation before it can accept business calls.
type PutOption ¶
type PutOption func(*pluginpb.KVPutRequest)
PutOption changes one condition or lifetime for a KV write request.
func IfAbsent ¶
func IfAbsent() PutOption
IfAbsent requires that the key be absent or expired when written. A competing successful insertion causes ErrVersionConflict. The host applies the condition atomically with the write, so callers need no preliminary read.
type Redeem ¶
type Redeem hostClient
Redeem creates single-use codes through the host's existing entitlement rules.
func (Redeem) Issue ¶
func (s Redeem) Issue(ctx context.Context, request *pluginpb.IssueRedeemCodeRequest) (*pluginpb.IssueRedeemCodeResponse, error)
Issue requests a single-use redeem code under configured entitlement limits. Repeated calls with the same key and input return the original code. The eventual redemption follows the host's existing redemption and rebate rules.
type Shutdowner ¶
type Shutdowner interface {
// Shutdown stops plugin-owned background work and releases external resources.
// The host has stopped admitting requests before invoking it. Cancellation
// signals that the remaining graceful shutdown budget has expired.
Shutdown(context.Context) error
}
Shutdowner releases plugin-owned resources during the host's bounded drain period.
type Site ¶
type Site hostClient
Site reads public presentation context from the currently connected host.
type Subscriptions ¶
type Subscriptions hostClient
Subscriptions queries plans and requests grants from administrator-approved plans.
func (Subscriptions) Grant ¶
func (s Subscriptions) Grant(ctx context.Context, request *pluginpb.GrantSubscriptionRequest) (*pluginpb.GrantSubscriptionResponse, error)
Grant requests an idempotent subscription from the administrator's plan allowlist. A queued result starts after an existing grant. Replays preserve the original subscription identity and do not extend or issue a second grant.
func (Subscriptions) ListForUser ¶
func (s Subscriptions) ListForUser(ctx context.Context, userID int64, activeOnly bool) (*pluginpb.ListUserSubscriptionsResponse, error)
ListForUser returns subscriptions with the requested active-only host filter.
func (Subscriptions) Plans ¶
func (s Subscriptions) Plans(ctx context.Context) (*pluginpb.ListSubscriptionPlansResponse, error)
Plans lists currently offered subscription plans and their default durations.
type TaskPlugin ¶
type TaskPlugin interface {
// RunTask executes one scheduled occurrence with its host-selected timestamp.
// The host prevents overlapping runs of the same task. Implementations must
// observe context cancellation when the configured task deadline expires.
RunTask(context.Context, string, time.Time) error
}
TaskPlugin executes the named jobs declared by the plugin manifest.
type Usage ¶
type Usage hostClient
Usage reads caller-scoped or explicitly permitted account usage aggregates.
func (Usage) Ranking ¶
func (s Usage) Ranking(ctx context.Context, request *pluginpb.GetUsageRankingRequest) (*pluginpb.GetUsageRankingResponse, error)
Ranking returns host-formatted public account presentation with bounded usage rankings.
func (Usage) Stats ¶
func (s Usage) Stats(ctx context.Context, request *pluginpb.GetUsageStatsRequest) (*pluginpb.GetUsageStatsResponse, error)
Stats requests bounded aggregate usage for the supplied account identifiers.
type Users ¶
type Users hostClient
Users reads permitted account fields and exact identity lookup results.
func (Users) Identities ¶
func (s Users) Identities(ctx context.Context, userID int64) (*pluginpb.ListUserIdentitiesResponse, error)
Identities returns permitted third-party identity fields without their authentication tokens.
func (Users) LookupEmail ¶
func (s Users) LookupEmail(ctx context.Context, email string) (*pluginpb.LookupUsersResponse, error)
LookupEmail performs a case-insensitive exact email lookup with user.email permission.
func (Users) LookupIDs ¶
LookupIDs finds up to one hundred exact account identifiers through the host.
func (Users) LookupUsername ¶
func (s Users) LookupUsername(ctx context.Context, username string) (*pluginpb.LookupUsersResponse, error)
LookupUsername finds the account with the exact supplied username spelling.
type Wallet ¶
type Wallet hostClient
Wallet reads balances and requests bounded idempotent balance adjustments.
func (Wallet) Credit ¶
func (s Wallet) Credit(ctx context.Context, request CreditRequest) (*pluginpb.WalletResponse, error)
Credit requests a balance reward under the administrator's granted limits. Reuse the same idempotency key and input when retrying an uncertain call; changing either financial intent or recipient requires a new key.
func (Wallet) Debit ¶
func (s Wallet) Debit(ctx context.Context, caller Caller, request DebitRequest) (*pluginpb.WalletResponse, error)
Debit requests a debit authorized by the supplied HTTP caller's grant. The host checks that request.UserID matches the caller and rejects expired grants. Retrying the same financial intent requires the original idempotency key.