P1Sat Permission Scheme for Basket 1sat
David Case (david.case@shruggr.cloud) Brandon Cryderman / HandCash (brandongcryderman@gmail.com)
Abstract
This BRC defines the P1Sat basket permission scheme for BRC-100 wallets: scheme id 1sat under BRC-99 / BRC-116.
Storage of collectables remains the plain basket 1sat (BRC-147). Applications request view access with a BRC-99 basket p 1sat <scope> (scope names the permission axis; filter values ride ordinary tags). Applications request spend authorization by labeling createAction with p 1sat input id <key>, where <key> is the bare BRC-164 list key for the held row. Conforming wallets route those requests to a scheme module, normalize storage to 1sat where needed, apply view grants and per-action spend approval as specified below, and MUST NOT treat payment / auto-pay grants as item access.
This document does not redefine 1Sat chain theory, inscriptions, collections, or provenance proofs. It does not replace BRC-147 or retarget BRC-150.
Motivation
Plain BRC-46 baskets only support coarse grant/deny. Collectables need finer app access — one collection, one app, one creator, or the full inventory — without inventing a storage basket per filter and without forcing inventory to live under a p … name.
BRC-99 reserves p <scheme> … for richer permission modules. This BRC defines scheme id 1sat and separates storage from permission routing:
Basket Namespace
Scheme ID:
1sat(no spaces; BRC-99)Wallet capability: Must implement storage basket
1satper BRC-147; must routep 1sat …basket operations andp 1sat input id …labels to this scheme’s module; must enforce view grants on list and per-action spend approval on labeled spends
Module presence detection uses the BRC-98 protocol p 1sat probe (security level 0); see Module detection. Wallets route by scheme id 1sat (BRC-116). That probe is not the default key-derivation protocol for new inventory tips. New tip key derivation SHOULD follow BRC-147 / wallet policy (e.g. plain protocol names such as onesat).
BRC-123 registry listing for this scheme is deferred (current §3.1 letter-first scheme ids do not admit 1sat).
Specification
Scheme identifier
Scheme id:
1sat(no spaces; BRC-99)BRC-98 probe protocol:
[0, "p 1sat probe"](level 0; see Module detection)BRC-99 basket form (view):
p 1sat <scope>(scope required; see Scopes)BRC-111 label form (spend):
p 1sat input id <key>(<key>= bare BRC-164 list key)
Wallets that do not implement this scheme MUST reject operations under these identifiers per BRC-99 / BRC-98.
Module detection
Applications MAY detect whether scheme 1sat is available by probing a BRC-98 protocol under this scheme. Per BRC-98, protocol names are p <scheme-id> <rest>; the rest token for this probe is probe.
Probe (application behavior): call BRC-100 getPublicKey with:
Notes:
Conforming module: when the wallet routes this
getPublicKeyto the1satmodule, the module SHOULD pass the request through (return a public key) so the probe succeeds without a user prompt.keyID:1sat-module-probeis RECOMMENDED for interoperability among probers; it is not a special wallet-reserved id beyond ordinary BRC-43 key-id rules.seekPermission: false: RECOMMENDED so capability detection does not open a permission UI.Interpretation: applications treat probe success (on a wallet that uses P-module routing) as evidence that scheme
1satis registered, and a BRC-98/99 unsupported-scheme rejection as evidence it is not. Bare wallets without a permissions manager may not give a reliable signal; applications SHOULD only enable module-mediated labels/baskets when they expect P-module routing.
This probe does not grant view or spend rights. It does not change BRC-111 label rules; spend labels under this scheme still follow BRC-111’s p <scheme> <payload> form as specified in Spend.
Storage vs permissions
Conforming wallets MUST file collectables in storage basket
1sat(BRC-147).Permission basket ids are
p 1sat <scope>only (scope required). They are routing names only; held tips remain in1sat.When a request uses a basket beginning with
p 1sat(after BRC-46 trim/lowercase), the wallet MUST:treat the request as scheme
1sat;parse scope from the basket name (reject if missing or unknown; values are not in the basket name);
require axis tag value(s) on the request when the scope is not
all;normalize the storage target to basket
1sat;apply view permission for that scope and value(s) (prompt or prior grant) before returning outputs;
enforce axis tags as a mandatory filter; other caller tags only narrow further.
View (listOutputs)
Scopes
After the scheme prefix p 1sat, a scope is required. The scope names a permission axis only. Filter values are not part of the basket name; they use ordinary output tags. The full basket name MUST stay within BRC-100 [a-z0-9 ].
p 1sat all
all
Entire storage 1sat
p 1sat collection
collection
Collection-scoped view; values from collection:… tags
p 1sat app
app
App-scoped view; values from app:… tags
p 1sat creator
creator
Creator-scoped view; values from creator:… tags
Rules:
Bare
p 1sat(no scope token) MUST be rejected. Full inventory usesp 1sat allonly.Scope is exactly one token after
p 1sat(all,collection,app,creator, orid). Extra tokens in the basket name MUST be rejected.Unknown scope tokens MUST be rejected with a clear error (fail closed). Future axes are added by revising this table.
For scopes collection, app, creator, and id, the request MUST include at least one tag with the matching prefix (
collection:,app:,creator:,id:). The tag value (after the prefix) is the filter id. For collection, the value is a collection id per BRC-147.For scope all, no axis tag is required. Caller tags are optional further filters only.
Scope id is a targeted lookup, not full-inventory access. It MUST NOT require grant all. Conforming wallets MUST allow
p 1sat id+id:<key>through the module without a prior collection/app/creator/all grant (auto-allow this narrow query, or an equivalent one-shot / id-scoped grant). Results MUST still be limited to the requestedid:…value(s). Spend targeting remains Spend (p 1sat input id <key>), not this scope alone.
Request shape
basket:p 1sat <scope>as in Scopes (axis only; scope required).tags: for non-allscopes, MUST include the axis tag(s) carrying the filter value(s). Additional tags (e.g.type:) only narrow further.tagQueryMode: applies to the caller’s tag set as constrained by Scope ceiling.
Normalization
On listOutputs with basket p 1sat <scope>, conforming wallets MUST:
Parse the scope (Scopes); reject bare
p 1sat, unknown scopes, and basket names that embed values after the scope token.For non-
allscopes, require at least one matching axis tag on the request; reject if missing.Require a view grant covering that scope and the requested axis value(s) (or prompt to create one) — see View grants.
Rewrite the storage query basket to
1sat.Enforce the granted axis tag value(s) as a mandatory filter on results (
tagQueryMode: "any"MUST NOT drop them).Apply any additional non-axis caller tags only inside that ceiling.
Return only outputs that satisfy the grant and the effective tag query.
How the wallet enforces (4)–(6) (query rewrite, post-filter, or equivalent) is an implementation choice.
Denial SHOULD use a distinct error so apps can distinguish “user denied item view” from generic basket denial.
View grants
Item view is not covered by ordinary payment / auto-pay grants.
Each list request has one scope. The scope maps to a tag prefix (or to no prefix for all):
all
none
collection
one or more collection:…
app
one or more app:…
creator
one or more creator:…
id
one or more id:…
The wallet queries storage basket 1sat with those tags (plus any optional extra tags the caller adds). Grant check is on this request’s scope and tag values, not a multi-axis matrix.
p 1sat all— requires a standing grant for full inventory (or a prompt that creates one).p 1sat collection/app/creator— requires a standing grant that covers the requested tag value(s) for that scope (or a prompt). Grant all also covers these.p 1sat id— no standing inventory grant; knowingid:<key>is enough to look up that row (see Scopes).
When the user approves a collection/app/creator/all request, the wallet SHOULD persist a grant for that scope and those tag values (or upgrade to all). Storage layout is local.
A later request MAY skip a new prompt when its scope and tag values are already covered by a stored grant (including grant all covering narrower scopes). Otherwise prompt or deny.
Scope ceiling and tag query
The scope’s required tags are mandatory on the result set. Optional extra tags (e.g. type:image/png) only narrow further. tagQueryMode: "any" MUST NOT drop the scope’s required tags.
Spend (createAction)
Spend targeting under this scheme is built on BRC-164 output identity tags. The held row MUST carry an id:<key> tag stamped by the holding wallet. The spend label names that key explicitly; the module resolves it back to the row with tag id:<key> under storage basket 1sat.
Label form
Held row (normative):
Rules:
BRC-111-style P-label: scheme id
1sat, payloadinput id <key>.<key>is the BRC-164 list key — the substring afterid:on the held output’s tags. Non-empty, no spaces, noid:prefix in the label.Storage basket is implied by the scheme:
1sat.
Example (row tagged id:a1b2c3d4e5f60708):
Multiple such labels MAY appear when the action spends multiple tracked rows. Rows without a BRC-164 id: tag cannot use this form.
Other input payloads. A label p 1sat input <outpoint> whose single payload outpoint is not the keyword id is outside this scheme’s permission model (e.g. naming a beefed external input). It is not a BRC-164 list key and is not further specified here. The normative spend path for wallet-held tips remains p 1sat input id <key>.
Module behavior
When createAction carries one or more p 1sat input id <key> labels, conforming wallets MUST:
Route the call to the
1satpermission module (BRC-116).Resolve each
<key>to a held output in storage basket1satvia BRC-164 (id:<key>).Obtain user approval for this action’s spend before spending those outputs. Payment / auto-pay MUST NOT satisfy this. Send approval is per action (inline prompt); this BRC does not define a standing/persisted “can send items” grant.
On approval, authorize only the spend set the user approved. A later
createSignature(or equivalent) MUST NOT expand that set without a new approval.
Once an action is classified as a held-tip spend under this scheme (via input id <key> and successful resolution), payment auto-approve MUST NOT apply.
Outpoint spend without labels
Apps MAY still spend by outpoint without a p 1sat input label. That path does not enter this scheme via labels. Wallets SHOULD still refuse to spend storage 1sat outputs under ordinary payment grants (BRC-147 payment separation). Interoperable module-mediated spend targeting uses the input label form above.
Capabilities (summary)
View
listOutputs basket p 1sat <scope>
Listing storage 1sat under the module
Send
createAction labels p 1sat input id …
Per-action approval to spend labeled held rows (not a standing grant)
Receive / internalizeAction insertion into 1sat remains ordinary basket insertion under BRC-147 and wallet basket-access policy. Fine-grained receive grants are out of scope for this BRC.
Relationship to plain basket 1sat
Operation
Plain 1sat
p 1sat … / input labels
Storage of tips
Yes (normative)
Never
listOutputs
Ordinary basket access
Module view + scope grants
Out of scope
Origin / sat-ordering / transfer consensus rules
Inscription envelope bytes
Collection membership proofs
BSV-21 fungible storage and permissions
Marketplace lock templates
Labels other than
p 1sat input …under scheme1satFine-grained receive /
internalizeActiongrants
Security considerations
Tag / grant spoofing — View matching on tags is only as trustworthy as the holding wallet’s own stamps. Tags are claims; tip→origin proof is BRC-150.
Scheme bypass — Filing collectables only in a non-
1satbasket loses this profile’s storage contract.Payment separation — Pay / auto-pay MUST NOT cover view under
p 1sat …or spends authorized viap 1sat input id ….Scope ceiling — Extra caller tags MUST NOT widen past the granted axis values.
Approval binding — After a spend is approved, signatures MUST NOT authorize a different spend set without a new approval.
Implementations
1sat-sdk — scheme module, input labels, scoped view
HandCash Desktop / Mobile — prior art for item view/send separation (storage
1sat)
References
BRC-123: Basket Permission Scheme Registry (registry listing deferred; see Basket Namespace)
Last updated
Was this helpful?

