@bannynet/core-v6
v1.1.0
Published
`@bannynet/core-v6` is the onchain avatar layer for Juicebox 721 collections. It defines how a body NFT wears outfit NFTs, uses a background NFT, and resolves to a base64 JSON token URI whose image is an onchain SVG.
Readme
Banny Retail
@bannynet/core-v6 is the onchain avatar layer for Juicebox 721 collections. It defines how a body NFT wears outfit NFTs, uses a background NFT, and resolves to a base64 JSON token URI whose image is an onchain SVG.
Documentation
- ARCHITECTURE.md — system structure and contract responsibilities
- USER_JOURNEYS.md — end-to-end flows for body owners and asset holders
- INVARIANTS.md — properties guaranteed by the resolver
- RISKS.md — known risks and edge cases
- ADMINISTRATION.md — owner-only actions and operational levers
- AUDIT_INSTRUCTIONS.md — guidance for security reviewers
- SKILLS.md — repo-specific gotchas and integration notes
- STYLE_GUIDE.md — coding and naming conventions
- CHANGELOG.md - V5 to V6 migration changelog
Overview
This is a resolver-centric app built on top of @bananapus/721-hook-v6. The resolver holds attached outfit and background NFTs while a body is decorated, then composes the active layers into a single token URI response.
The main user flows are:
- mint body, outfit, and background NFTs through a Juicebox 721 hook
- attach accessories to a body with
decorateBannyWith - optionally freeze the look for seven days with
lockOutfitChangesFor - upload SVG payloads after an owner registers the content hashes
Use this repo when you need collection-specific, fully onchain metadata composition on top of Juicebox NFTs. Do not use it as a generic 721 hook. It is an app-layer resolver, not a protocol NFT primitive.
Key contract
| Contract | Role |
| --- | --- |
| Banny721TokenUriResolver | Resolves metadata, stores equipped accessories, enforces outfit locks, and renders layered SVG output for Banny collections. |
Mental model
This repo owns three things:
- custody of outfit and background NFTs while they are equipped
- rules for what a body can wear and when that can change
- rendering of the final metadata payload
It does not own mint pricing, tier issuance, or treasury accounting.
Read these files first
src/Banny721TokenUriResolver.soltest/DecorateFlow.t.soltest/OutfitTransferLifecycle.t.solnana-721-hook-v6/src/JB721TiersHook.solfor upstream mint and tier behavior
High-signal tests
test/DecorateFlow.t.soltest/OutfitTransferLifecycle.t.soltest/regression/BurnedBodyStrandsAssets.t.soltest/regression/TryTransferFromStrandsAssets.t.soltest/TestQALastMile.t.sol
Integration traps
- the resolver holds equipped assets, so transfer edge cases matter as much as rendering output
- transferred bodies carry their equipped assets, so a new body holder can inherit control of them
- burned bodies and non-safe transfer patterns can strand expectations around resolver-held assets
- outfit locks survive body transfers until expiry
- metadata quality depends on lazily uploaded asset payloads, not only token state
Where state lives
- equipped outfit and background state live in
Banny721TokenUriResolver - layer rendering and token URI generation live in the same resolver
- mint pricing, tier inventory, and treasury behavior live upstream in
nana-721-hook-v6
Install
npm install @bannynet/core-v6Development
The contract stack relies on via_ir = true in foundry.toml.
npm install
forge build --deny notes
forge test --deny notesUseful scripts:
npm run deploy:mainnetsnpm run deploy:testnetsnpm run deploy:mainnets:drop:1npm run deploy:testnets:drop:1
Deployment notes
Deployments are handled through Sphinx using the environments configured in script/Deploy.s.sol. The resolver is meant to be plugged into a Juicebox 721 hook as that hook's token URI resolver.
Repository layout
src/
Banny721TokenUriResolver.sol
interfaces/
test/
unit, attack, fork, review, QA, and regression coverage
script/
Deploy.s.sol
Drop1.s.sol
Add.Denver.s.sol
helpers/Risks and notes
- attached outfits and backgrounds are held by the resolver while equipped
- outfit locks are fixed-duration and cannot be shortened once set
- onchain SVG content is immutable once uploaded for a committed hash
- plain
transferFromcan still create asset-tracking surprises around resolver custody - rendering quality depends on the integrity of uploaded SVG assets
For AI agents
- Treat this repo as an app-layer resolver, not as the NFT issuance primitive.
- Start with
Banny721TokenUriResolverand the lifecycle tests before summarizing attachment behavior. - If the question is about mint economics or tier availability, inspect
nana-721-hook-v6instead.
