Nagare

Reference

The contract, what it publishes, how a sale works, and what the error messages mean.

Contract

Nagare is deployed once on Starknet mainnet, with no owner, no pause and no upgrade path. Nobody can change its behaviour, including its authors. It has not been audited.

0x00ae22ea6b8c2e10bb19450d4caac7d31c89168379e4aef02d83e3eb8f03e323

Read it on Voyager

Operations

All eight run through the STRK20 pool, which is the only caller the contract accepts. Each is authorized by an ECDSA signature over the operation, bound to the chain, the contract, the schedule, the note being paid into and a nonce, so a signature cannot be replayed on another schedule, another chain or a second time.

Create
Funds a schedule. The pool pays Nagare and the terms are written on chain.
Withdraw
Pays the recipient what has vested, into a private note. Recipient key.
Cancel
Returns whatever has not vested to the sender, privately. Sender key.
Transfer
Moves the schedule to a different recipient key. Recipient key.
List
Marks the schedule open to offers, or takes it off. Recipient key.
Offer
Escrows a price against a listed schedule under a buyer key.
Accept
Moves the schedule to the buyer and pays the holder, in one call. Recipient key.
Reclaim
Returns an escrowed offer to the buyer. Buyer key.

Verifying an uncancelable schedule

An uncancelable schedule stores a published constant where the sender key would be. It is the Poseidon hash of the short string NAGARE_NO_CANCEL, which is not a point on the Stark curve, so no private key for it exists and no signature can satisfy a cancel.

0x3beacfb8418e802316632224f14b0902b6f61b5c7f06b18843cd1e0d39fac52

Read get_stream for the schedule and compare its sender key against that value. It is identical on every uncancelable schedule, which also means an uncancelable schedule is publicly identifiable as one.

Selling a schedule

A recipient can open their schedule to offers from the gear on its page, which lists it on the Marketplace. A buyer escrows a price against it under a key derived from their own wallet, for up to 24 hours. Accepting moves the schedule to the buyer’s key and pays the holder in the same call. A buyer can reclaim their escrow at any point before it is accepted.

Two rules protect the buyer. An offer can only be accepted while the amount already withdrawn matches what it was when the offer was made, so a holder cannot withdraw and then sell the emptied schedule. And a live offer blocks a transfer, so the schedule cannot be moved elsewhere while a price is standing against it.

Each offer is numbered, and its escrow belongs to that number. Opening a new offer does not clear an earlier one, so an offer that expired without being accepted keeps its STRK in the contract until its buyer reclaims it. The contract can only read back the newest round, so Nagare offers a reclaim for every round your browser holds a key for and lets the contract say which of them still holds anything.

Neither of them covers the sender. A sale moves the recipient key and leaves the sender key alone, so on a cancelable schedule the sender can still cancel after you have paid and take the unvested part back. Price that in, or buy an uncancelable one, where the sender key is a constant with no private key behind it.

The whole path has run on mainnet: listed, offered against twice, accepted, withdrawn from by the buyer, and the escrow behind the expired offer reclaimed under the key that made it.

What the chain records

Never published

  • The wallet address that funded a schedule
  • The wallet address that receives it
  • The wallet address that cancelled, transferred, listed, offered or accepted
  • Which wallet owns the note a payout lands in

Public on chain

  • The total, token, start, cliff and end of every schedule, and its id
  • The sender key and recipient key, and every re-key
  • Nagare's STRK balance, and what it owes across every schedule
  • The amount and time of every withdrawal, refund and sale
  • Every offer price, expiry and buyer key
  • Every signature and every calldata item, including note ids

What Nagare does not claim

  • Moving STRK into the pool is a public transaction that puts your address and the amount on chain.
  • Amounts and timing can be correlated: a distinctive amount withdrawn shortly after a distinctive deposit is a link.
  • A key used for two schedules links them, which is why every schedule gets a fresh sender key.
  • The pool charges 6 STRK for each private transaction, taken from your shielded balance.

The claim is that no wallet address of either party appears in any Nagare transaction. Amounts, dates and keys are public by design, and correlation between a deposit and a withdrawal is a real risk that Nagare does not remove.

When something fails

Private balances are off in your wallet
Turn on STRK20 private balances in Ready, then reload. Nagare cannot move anything until the pool knows your wallet.
The pool charges more than you have shielded
Shield more STRK in your wallet. Every Nagare operation costs the pool fee.
Your wallet did not approve this
The prompt was rejected, or the wallet lacked the fee. Both are safe to retry, and nothing was sent.
Your wallet returned a transaction Nagare could not read
A payout is signed against the note your wallet picked, so Nagare has to find that note in what the wallet prepared. Try again, and update the wallet if it persists.
The wallet rejected the shape of this transaction
Usually a wallet version that does not support the operation. Update it, and report it if it persists.
An operation went to your wallet and has not come back
Approve or reject it in the wallet, then retry. Nagare holds one operation per schedule at a time so a second one cannot be sent by accident.
You hold no key for this schedule
Connect the wallet that opened it, or open the claim link that carries the recipient key. Everything on the page is public and readable without either.