01 / Overview
Overview
NFA is a safety layer for onchain activity: personal rules, verifiable receipts and accountable agents.
Most wallets answer one question: can this transaction be signed? NFA is built around a second one: should it run right now? You write rules while you are calm; the system holds you to them when you are not, and leaves an auditable record of what happened.
It is made of three systems that work together:
| System | What it does | Where |
|---|---|---|
| A — Receipts & Discipline Score | Every verified trade produces an archival receipt. A score measures one thing only: whether you kept your own rules. | Receipts |
| B — Sleep on It & Panic | Personal limits, a queue that delays large actions, delayed loosening of rules, and an emergency freeze. | Guardrails |
| C — Agent Black Box | Scoped permissions for autonomous agent keys, and a hashed journal of every decision they publish. | Agents |
02 / Quickstart
Quickstart
From a blank account to your first receipt in about two minutes.
- 01
Connect a wallet
Open the app and connect a browser wallet. This is read-only: the app only asks for your address. Nothing is signed or sent.
- 02
Start from zero
Your address gets its own simulated account, saved in this browser. It begins empty, with default guardrails.
- 03
Add simulated test funds
On the Overview, press Add simulated test funds. These are not real tokens; they exist only in the simulation. More options are under Simulation controls in the top bar.
- 04
Look at your rules
Open Guardrails. Try lowering the daily cap (applies at once) and raising it (becomes a pending change for 24 hours).
- 05
Propose an action
On Sleep queue, propose a swap. Below your max trade value it executes; above it, it waits ten minutes. The right-hand panel shows the verdict before you submit.
- 06
Move time forward
Waiting ten minutes or a day is not necessary. Open Simulation controls and advance the clock to unlock a queued action or let a delayed rule change take effect.
- 07
Read the receipt
Each executed swap appears in Receipts. Open one, then download it as an SVG file.
03 / Key concepts
Key concepts
The vocabulary used across the product.
| Term | Meaning |
|---|---|
| Smart account | An account whose behaviour is defined by code, not just a key. Guardrails would only exist on compatible smart accounts (planned: ERC-4337 accounts with ERC-7579 modules). Ordinary EOAs are not covered. |
| Guardrail | A personal rule: a limit, a list, a delay or a guardian. |
| Tightening / loosening | Making a rule stricter (instant) or weaker (delayed). If a change cannot be classified safely it counts as loosening. |
| Sleep on It | A queue that holds large or agent-proposed actions for a waiting period before they can run. |
| Guardian / co-signer | An optional second approver for large actions and for loosening some rules. |
| Agent | An autonomous key you authorize with narrow permissions: targets, functions, caps and an expiry. |
| Decision record | What an agent publishes with each action: model, a hash of its reasoning text, a URI, and a summary. |
| Receipt | An archival record produced after a verified trade. In this prototype it is an SVG preview, not a minted NFT. |
| Price quality | Whether a price can be trusted: fresh, stale, manipulable, invalid, unavailable (or self-reported). |
| Discipline Score | A bounded 0–100 number describing adherence to your own rules over time. Not skill, not profit. |
| Panic | An emergency control that revokes agents, cancels the queue and freezes governed execution. |
| Simulated clock | The prototype's own time. It only moves when you move it, so waiting is never required. |
04 / Guardrails
Guardrails
Ten rules describe how your account is allowed to behave.
Every guardrail change is classified before it is applied. Tightening applies immediately. Loosening creates a pending change that takes effect after the loosening delay (24 hours by default). While a change is pending, that rule cannot be edited again until the change is applied or canceled.
| Rule | Stricter means | Default | Guardian needed to loosen |
|---|---|---|---|
| Maximum trade value Hard ceiling per action. Larger actions go to Sleep on It. | Lower is stricter | 5,000 | No |
| Rolling 24-hour volume cap Aggregate volume across any 24-hour window. | Lower is stricter | 20,000 | No |
| Cooldown between trades Minimum seconds between governed trades. | Higher is stricter | 600 | No |
| Allowed targets Contracts governed calls may reach. | Fewer entries is stricter; empty = not enforced | 2 entries | No |
| Denied targets Contracts that are always blocked. | More entries is stricter | empty | No |
| Allowed tokens Assets that may be traded. | Fewer entries is stricter; empty = not enforced | 4 entries | No |
| Denied tokens Assets that are always blocked. | More entries is stricter | empty | No |
| Guardian / co-signer Optional second approver. | Setting one tightens; changing or removing loosens | none | Yes, if a guardian is set |
| Co-signer value threshold Trades above this need the guardian signature. | Lower is stricter; 0 = off | 0 | Yes, if a guardian is set |
| Rule-loosening delay How long loosening waits before taking effect. | Higher is stricter | 86,400 | Yes, if a guardian is set |
How changes are classified
- Numbers. A stricter value is a tightening: a lower max trade, a lower cap, a longer cooldown, a longer delay. A co-signer threshold of 0 means “off” and is the loosest setting.
- Allow lists. An empty allow list is not enforced. Adding the first entry, or removing entries, tightens. Adding entries, or clearing the list, loosens.
- Deny lists. Adding entries tightens; removing entries loosens.
- Guardian. Setting one where there was none tightens. Changing or removing it loosens, because it weakens oversight.
- Mixed edits. Adding and removing in one list edit cannot be compared safely, so it loosens.
05 / Sleep on It
Sleep on It
Large actions wait. Everything waiting can be inspected and canceled.
An action goes to the queue instead of executing if its value is above your max trade value, or if it was proposed by an agent in ask-first mode. A queued action records the account, chain ID, a nonce, the target, value, calldata and the calldata’s SHA-256 hash, plus its unlock and expiry times.
| Status | When | What you can do |
|---|---|---|
| pending | From queuing until 10 minutes later | Inspect or cancel. Execution is rejected as too early. |
| ready | For 1 hour after unlock | Execute or cancel. Rules are re-checked at execution. |
| executed | After a successful execution | Read-only. A second execution is rejected as a duplicate. |
| canceled | After you (or panic) canceled it | Read-only. |
| expired | 1 hour after unlock with no execution | Read-only. Cancel and queue a new action instead. |
Queued actions cannot be edited. To change one, cancel it and queue a new action. At execution the rules run again, so a revoked agent, a newly denied target, a cooldown, a missing co-signer approval or a freeze can still block it.
06 / Agents
Agents
Give an agent a narrow permission, then keep a hashed record of what it decides.
An agent is an autonomous signer (an EOA, or a contract account verified through EIP-1271 in a real deployment). Each permission defines:
- allowed target contracts and allowed function selectors;
- a per-action cap and a rolling 24-hour cap (in a normalized USD reference);
- an expiry (1–90 days) — every permission must expire;
- optional ask-first mode, which routes every action to your queue.
You can edit an active agent, or revoke it instantly. Revoking also invalidates that agent’s queued proposals.
The decision record
An agent action is rejected unless it carries a decision record with a reasonHash (or reasoning text to hash), a reasonURI and a model identifier. Limits apply: URI up to 200 characters starting with ipfs://, https:// or ar://; model up to 64; reasoning text up to 4,000.
When you give text, the hash is a real SHA-256 computed locally in your browser. A hash that does not match its text is rejected. Nothing is uploaded anywhere.
07 / Receipts
Receipts
Archival records of what happened — never a promise about what will.
A receipt is produced only after a successful simulated swap. It captures the smart account, owner, optional agent, input and output assets and amounts, the entry price and its quality, a timestamp, a simulated block, an indicative return and a holding-time label. Balance snapshots before and after must match the amounts exactly, or no receipt is created.
| State | Meaning | Shown on the receipt |
|---|---|---|
| VERIFIED | The action went through the supported trade path (the allow-listed router or pool and the swap function). | A solid VERIFIED chip. |
| SELF-REPORTED | The owner entered it, or it used a path that is not supported. It never changes balances or limits. | A dashed SELF-REPORTED chip. |
| fresh | Both price legs passed checks when the trade executed. | An entry price and, while still fresh, an indicative return. |
| stale · manipulable · invalid · unavailable | The price cannot be trusted. | PRICE UNAVAILABLE instead of a figure. |
Indicative return compares the entry price with the current price, and is shown only when the entry quote and both current price legs are fresh. If a source degrades later, the return disappears from existing receipts. Return bands: below −5%, −1% to −5%, within ±1%, +1% to +5%, above +5%. Holding labels: FRESH (under an hour), SHORT (under a day), MEDIUM (under a week), LONG (a week or more).
Every receipt can be downloaded as a standalone SVG file with its background photograph embedded. Receipts are not minted tokens and the transactions are not confirmed onchain.
08 / Discipline Score
Discipline Score
A bounded number describing adherence to your own rules. Not skill. Not profit.
The score is replayed day by day from the moment your rules were first set. Each completed day extends your streak only if your rules were meaningfully strict and no loosening took effect that day.
target = 100 × (0.25·age + 0.4·streak + 0.35·strictness) age, streak = 0 below 7 days; then (days − 7) / 53, capped at 1 strictness = clamp((ratio − 1) / (2× − 1)); 0 until rules are 7 days old ratio = geometric mean of: baseline max trade ÷ yours, baseline daily cap ÷ yours, yours ÷ baseline cooldown baseline = 8,000 max trade · 32,000 daily cap · 5 minute cooldown each completed day: score = min(target, previous + 2) a loosening taking effect resets the streak and drops the score to the new, lower target at once
| Input | Effect |
|---|---|
| Rule age | Rules younger than 7 days earn no credit at all. |
| Streak | Counts days of qualifying rules (strictness ≥ 1.05× baseline) with no loosening. |
| Strictness | Rewards stricter-than-baseline limits; saturates at 2× so extreme settings do not run away. |
| Executed loosening | Resets the streak. A pending loosening changes nothing until it takes effect. |
| Panic | Neutral: it neither rewards nor penalizes. |
| Inactivity | Qualifies. Not trading is a valid way to keep your rules. |
| Rejected actions | Never counted. Hypothetical or blocked attempts are not violations. |
| Profit, balance, volume, frequency | Never inputs. |
09 / Panic & recovery
Panic & recovery
Freeze first. Recover slowly.
Engaging panic does four things at once: it revokes every active agent, cancels every pending or ready queued action, freezes governed execution and starts a recovery countdown (24 hours by default). Panic never consults prices, so it works even when every price source is down. It is neutral for the Discipline Score. Rules can still be tightened while frozen.
| Method | How |
|---|---|
| Time-delayed | Available once 24 hours have passed since the freeze. |
| Guardian-approved (simulated) | Request early recovery, record a simulated guardian approval, then recover immediately. Requires a guardian to be configured. |
Recovery unfreezes the account but does not silently restore agents. Revoked agents must be granted again.
10 / How an action is judged
How an action is judged
One deterministic function. The first failing rule wins.
- 01
Panic
A frozen account rejects everything.
- 02
Input
Amount above zero, valid target address, a 4-byte selector, known tokens.
- 03
Agent checks
The agent exists, is not revoked or expired; the target and selector are allowed; a valid decision record; the value is priced; per-action cap; rolling daily cap.
- 04
Account lists
Denied targets and tokens, then allow lists (an empty allow list is not enforced).
- 05
Valuation
A needed price that is not fresh rejects the action with PRICE_UNAVAILABLE. A missing price is never treated as zero.
- 06
Routing
An ask-first agent, or a value above the max trade value, sends the action to the queue.
- 07
Execution-time rules
Cooldown, rolling 24-hour volume cap, the output price, balance, and — above the threshold — a matching, unexpired, unused guardian approval.
The verdict is one of allowed, queued, rejected or needs-guardian, with a stable reason code and a human-readable explanation. The composer on the Sleep queue page shows the same verdict live, using the same function the engine uses.
Simulated guardian approvals
An approval is an explicit record, not a cryptographic signature. It stores the account, a commitment (a SHA-256 hash of the exact action), the signer, a nonce, a 30-minute deadline and a consumed flag. It is valid only for that exact action, once, before its deadline, while the signer is still the configured guardian. Real EIP-712 / EIP-1271 verification belongs to the future contract integration.
11 / Reason codes
Reason codes
Every verdict carries one of these stable codes.
| Code | Outcome | Meaning |
|---|---|---|
| OK_EXECUTE | allowed | Every rule passed; the action executes immediately. |
| OK_QUEUE_SLEEP | queued | Value is above the max trade value, so the action waits in Sleep on It. |
| OK_QUEUE_ASK_FIRST | queued | The agent is in ask-first mode, so its proposal waits for the owner. |
| PANIC_FROZEN | rejected | The account is frozen by panic. Governed execution is disabled until recovery. |
| INVALID_INPUT | rejected | Amount, address, selector or token is malformed or unknown. |
| INSUFFICIENT_BALANCE | rejected | The simulated balance of the input token is below the requested amount. |
| AGENT_UNKNOWN | rejected | No agent with that ID exists. |
| AGENT_REVOKED | rejected | The agent's permissions were revoked (by you or by panic). |
| AGENT_EXPIRED | rejected | The agent's permission passed its expiry time. |
| AGENT_TARGET_NOT_ALLOWED | rejected | The target contract is not on this agent's allowed list. |
| AGENT_SELECTOR_NOT_ALLOWED | rejected | The function selector is not on this agent's allowed list. |
| AGENT_PER_ACTION_CAP | rejected | The value exceeds the agent's per-action cap. |
| AGENT_DAILY_CAP | rejected | The agent's rolling 24-hour cap would be exceeded. |
| DECISION_MISSING | rejected | An agent action needs a decision record: reasonHash (or text to hash), reasonURI and model. |
| DECISION_INVALID | rejected | The decision record is malformed, too long, or its hash does not match its text. |
| TARGET_DENIED | rejected | The target is on the account's denied list. |
| TARGET_NOT_ALLOWED | rejected | The account has an allowed-target list and this target is not on it. |
| TOKEN_DENIED | rejected | One of the tokens is on the denied-token list. |
| TOKEN_NOT_ALLOWED | rejected | The account has an allowed-token list and one of the tokens is not on it. |
| PRICE_UNAVAILABLE | rejected | A needed price is stale, manipulable, invalid or unavailable. The prototype never assumes a zero value. |
| COOLDOWN | rejected | The cooldown since the last execution has not elapsed. The message shows the time remaining. |
| DAILY_CAP | rejected | The rolling 24-hour volume cap would be exceeded. |
| NEEDS_GUARDIAN | needs-guardian | Value is above the co-signer threshold. A (simulated) guardian approval bound to this exact action is required. |
| APPROVAL_NOT_FOUND | rejected | No simulated approval with that ID exists. |
| APPROVAL_MISMATCH | rejected | The approval was issued for a different action or account. |
| APPROVAL_EXPIRED | rejected | The approval passed its 30-minute deadline. |
| APPROVAL_CONSUMED | rejected | The approval was already used once. Replays are rejected. |
| APPROVAL_SIGNER | rejected | The approval's signer is not the currently configured guardian. |
12 / Defaults & limits
Defaults & limits
The numbers behind the prototype.
| Setting | Value |
|---|---|
| Sleep on It delay | 10 minutes |
| Execution window after unlock | 1 hour |
| Loosening delay | 24 hours |
| Panic recovery delay | 24 hours |
| Guardian approval deadline | 30 minutes |
| Minimum rule age for score credit | 7 days |
| Daily score growth cap | 2 points per day |
| Simulated swap fee | 10 basis points |
| Faucet limit per call | 25,000 USDC · 25,000 DAI · 10 WETH · 10 cbETH |
| List length limits | 200 entries for the activity and decision lists |
13 / Simulation & time
Simulation & time
A state machine you can control, so nothing needs waiting for.
All logic lives in pure functions: reduce(state, action) returns a new state and a typed result, never mutating its input and never reading the wall clock or randomness. A single store holds the state and every screen reads it, so a revoked agent, a canceled queue item or a new receipt shows up everywhere at once.
Time is simulated. Open Simulation controls in the top bar to advance one minute, ten minutes, an hour, a day or a week, run the clock at 1×, degrade a mock price source to see how unreliable prices are handled, add simulated test funds, load an example dataset, or reset the account to empty.
Block numbers advance with simulated time. Prices come from a swappable price-source interface with fixed mock values; fresh sources re-poll on every tick, degraded ones stay degraded until you change them.
14 / Wallet & your data
Wallet & your data
Connecting reveals an address. It does nothing else.
The app asks your browser wallet for the account address (EIP-1193 eth_requestAccounts) and nothing more: no signature requests, no transactions, no chain switching, no token approvals and no balance reads. Your address is used as a local key for your own simulated account.
- Each address gets its own account, stored in this browser’s
localStorage, starting from zero. - Disconnecting returns you to the gate; reconnecting the same address restores that account.
- There is no server, no analytics and no network call by the application.
- Clearing site data deletes everything.
15 / Architecture
Architecture
The planned design. Not implemented.
The planned system uses ERC-4337 smart accounts with ERC-7579 modules that enforce the guardrails onchain. A user or agent submits an operation; validation and policy modules evaluate it; it is then queued or executed against a supported target; verified trades mint a receipt; and discipline state follows from rule events.
- 01
USER / AGENT
Owner key or limited agent key
- 02
SMART ACCOUNT
ERC-4337 account
- 03
VALIDATION & POLICIES
ERC-7579 modules
- 04
QUEUE OR EXECUTION
Sleep on It, or direct
- 05
SUPPORTED TARGET
Venue-agnostic EVM call
- 06
RECEIPT
ERC-721 artifact
- 07
DISCIPLINE STATE
Rule age, streaks
The prototype mirrors this flow in software so the product can be designed and tested before any contract exists. See BACKEND_INTEGRATION.md in the repository for how each simulated part maps to a real component.
16 / Limits & security
Limits & security
What this prototype is not.
| It is not… | Because… |
|---|---|
| Enforcement | No rule is enforced onchain. The simulation lives in your browser and can be edited with developer tools. |
| Protection for EOAs | Future guardrails would only apply to compatible smart accounts, not ordinary EOAs or assets held elsewhere. |
| Cryptographic approval | Guardian approvals are simulated records, not signatures. |
| Minted tokens | Receipts are SVG previews. No ERC-721 exists, and the score badge is not a soulbound token. |
| Onchain transactions | Nothing is signed, broadcast or confirmed. Hashes are SHA-256 digests of example strings, and block numbers are simulated. |
| An oracle | Prices are fixed mock values; return figures are illustrative. |
| Proof of reasoning | A reasonHash proves text integrity only. |
| Audited | No external audit has been performed. |
Risks a real implementation must solve
- Module uninstall or downgrade: removing protections must itself be delayed and guardian-gated.
- Execution bypass: direct EOA signing, alternative modules, delegatecall and third-party approvals defeat guardrails unless the account architecture prevents them.
- Oracle manipulation and staleness for value-based limits, and slippage.
- Guardian compromise or collusion, and griefing by withholding approvals.
- Replay of approvals across accounts or chains: production needs full domain separation.
- Frontend trust: a malicious frontend can mislead users; contracts must stand on their own.
NFA does not predict prices, promise returns, or offer staking, prediction markets or token sales. Nothing here is financial, investment, legal or security advice.
17 / FAQ
FAQ
| Question | Answer |
|---|---|
| Is any of this real? | The interface and the rules engine are real software, but they operate on a simulated account. No funds, contracts or transactions are involved. |
| Why must I connect a wallet? | To give you your own individual account. Connecting only reveals your address and is read-only. |
| Where is my data? | In this browser, per address. Nothing is sent anywhere. |
| Why did my action get rejected? | Open the Sleep queue composer: it shows the reason code and a plain-language explanation. See the reason-code table above. |
| Why does a receipt say PRICE UNAVAILABLE? | Its price data is stale, invalid, manipulable or unavailable. The prototype refuses to invent a number. |
| Why did my score drop? | A loosening of one of your rules took effect, which resets the streak. Panic and rejected actions never lower it. |
| Why can't I edit a rule? | It has a pending change. Cancel that change on the Guardrails page, then edit. |
| How do I skip the waiting? | Use Simulation controls to advance the clock. |
| Will this protect my real wallet? | No. A future version could protect compatible smart accounts only, and would need an audit first. |
18 / Status
Status
Honest, and short.
| Item | State |
|---|---|
| Functional frontend prototype | Complete · simulated |
| Contract integration | Planned |
| External audit | Not completed |
| Testnet deployment | Pending |
No partners, audits, metrics, funding or deployed addresses are claimed anywhere on this site, because none exist yet.
19 / Official links
Official links
How to tell the real project from a copy.
| What | Where |
|---|---|
| Website | notfinancialadvice.cash |
| X (Twitter) | x.com/nfacash · @nfacash ↗ |
Nothing in this project is financial, investment, legal or security advice.