Storage, config & types
Summary. Goblin keeps a small per-wallet archive of Nostr metadata (transaction context, contacts, requests, processed-event markers) in an embedded key-value store, and a per-wallet config file for relay list, accept policy, and timeouts. These join to the GRIM wallet’s own transaction log to produce the Activity feed.
Motivation
Grin’s wallet log knows about transactions; it knows nothing about who you paid by username, the note you attached, or which request is still pending. Goblin needs a side-archive for that nostr-shaped context, plus a record of which events it has already processed (so it doesn’t replay them), all scoped to the wallet so nothing leaks between wallets.
How it works
The metadata store
A per-wallet rkv (SafeMode/LMDB) archive at wallet_data/nostr.rkv, holding:
tx_meta: nostr context for a slate (counterpartynpub, direction, note, status, the gift-wrap/rumor event ids, timestamps), keyed by slate id and joined to the GRIM tx log.contacts: people you’ve paid or saved (petname,nip05+ when last verified, DM relays, avatar hue, ablockedflag, and anunknownflag for keys auto-added from an incoming payment).requests: incoming/outgoing payment requests by rumor id.processed: event/rumor ids already handled, with slate state, pruned after 30 days (replay + dedup guard).
Per-wallet config
A nostr.toml (NostrConfig) holding: enabled, relays override, accept_from (Everyone default / Contacts / Ask), nip05_server (your name authority, which also yields home_domain() for federation), expiry_secs (auto-cancel an unanswered payment, default 24 h), cancel_grace_secs (how long before the cancel button appears, default 10 min), and allow_incoming_requests (opt-out of Invoice-1, advertised in your kind 0).
The types
types.rs defines the vocabulary the rest of the layer speaks:
NostrTxDirection:Sent,Received,RequestedByUs,RequestedOfUs.NostrSendStatus: the slate state machine:Created,AwaitingS2,RepliedS2,AwaitingI2,PaidAwaitingFinalize,Finalized,SendFailed,Cancelled, …TxNostrMeta,Contact,PaymentRequest,RequestStatus,CancelOutcome.
Reference
- Store:
goblin/src/nostr/store.rs: rkv SafeMode, the named databases above, 30-day TTL onprocessed. (Note: the env is opened with extra capacity so reopening a full set of DBs doesn’t panic, a fix recorded in the wallet history.) - Config:
goblin/src/nostr/config.rs:AcceptPolicy,NostrConfig,load()/save(),home_domain(). - Types:
goblin/src/nostr/types.rs: directions, statuses,TxNostrMeta,Contact,PaymentRequest.
References
- How statuses drive acceptance: Ingest policy.
- How
tx_meta+ the GRIM log become the feed: Send & request andgoblin/src/gui/views/goblin/data.rs.