Problem
The contract keeps exactly one index, and it points the wrong way for half the users:
enum DataKey {
Count,
Split(u64),
Balance(u64, Address),
Created(Address), // creator -> [split ids]
}
splits_of(creator) answers "which splits did I create". There is no way to answer "which splits pay me".
Why this matters
Tributary has two user types: the person who sets up a split, and the people who get paid by it. The product currently only serves the first. A recipient who is added to a split has no way to discover it: not through the contract, not through the SDK, and not through the dashboard (App.tsx only calls fetchMineIds(wallet), which is splits_of, so a connected wallet sees only splits it created).
A maintainer added to a donation split, a collaborator on a royalty split, or a referrer in a marketplace split all currently have to be told the split id out of band. That is a significant gap for a payment-splitting product: the payee cannot see their own income streams.
Suggested fix
Add a Paid(Address) -> Vec<u64> (recipient to split ids) index maintained in create_split and update_split, plus a splits_paying(recipient) view.
The hard part is update_split: removing a recipient must remove the reverse index entry, so the update path has to diff old against new. Worth considering whether the index should be pruned on removal or kept append-only with a liveness check at read time.
Alternative worth costing in the PR: derive this off-chain in the indexer from creation/update events instead, which keeps contract storage and write costs flat. If #250-#252-style TTL and storage costs are a concern, the off-chain route may win.
Acceptance criteria
- A recipient can enumerate the splits that route to them, on-chain or via the indexer, with a written justification for the chosen approach.
- Removing a recipient via
update_split is reflected correctly.
- Nested
Recipient::Split entries are handled sensibly (a child split is a payee too).
- Tests cover add, remove, and re-add of a recipient.
- The dashboard can render an "incoming" view from it (follow-up issue).
Problem
The contract keeps exactly one index, and it points the wrong way for half the users:
splits_of(creator)answers "which splits did I create". There is no way to answer "which splits pay me".Why this matters
Tributary has two user types: the person who sets up a split, and the people who get paid by it. The product currently only serves the first. A recipient who is added to a split has no way to discover it: not through the contract, not through the SDK, and not through the dashboard (
App.tsxonly callsfetchMineIds(wallet), which issplits_of, so a connected wallet sees only splits it created).A maintainer added to a donation split, a collaborator on a royalty split, or a referrer in a marketplace split all currently have to be told the split id out of band. That is a significant gap for a payment-splitting product: the payee cannot see their own income streams.
Suggested fix
Add a
Paid(Address) -> Vec<u64>(recipient to split ids) index maintained increate_splitandupdate_split, plus asplits_paying(recipient)view.The hard part is
update_split: removing a recipient must remove the reverse index entry, so the update path has to diff old against new. Worth considering whether the index should be pruned on removal or kept append-only with a liveness check at read time.Alternative worth costing in the PR: derive this off-chain in the indexer from creation/update events instead, which keeps contract storage and write costs flat. If #250-#252-style TTL and storage costs are a concern, the off-chain route may win.
Acceptance criteria
update_splitis reflected correctly.Recipient::Splitentries are handled sensibly (a child split is a payee too).