Repository navigation
Conversation
lukachi
marked this pull request as ready for review
August 28, 2026 11:40
The dapp no longer assembles a transaction. For each of the seven actions a person can take on a lending offer it hands the wallet the deployed manifest, the .simf sources of every covenant involved, the instance the factory published, the state the indexer reports, and the parameters the person chose. The wallet compiles the sources, resolves what the manifest computes for itself, builds the transaction, shows what it will do and broadcasts it. Landed here: - One wallet facade between the application and any provider, connected to the humid extension through the injected AppKit adapter. - Creating a borrower account and creating an offer, from the protocol's own deployed document rather than from code written against it. - Accepting, cancelling, claiming the principal, liquidating, repaying and collecting the lender settlement, all through one shared request builder and one shared hook, so each modal and each demo page differ only in the action they name. - What a contract action can be funded from is read from the chain, because the wallet does not serve it. - The deployed lending document is carried beside the contracts it describes, with the two references that named a namespace unable to hold them corrected. - The indexer's compose build generates the contract artifacts it depends on. - Tests over the request builder, the shared action hook and the seam itself.
…action The dapp acted through one wallet. It acts through four now - the HUMID extension, a Jade device, a recovery phrase held in the page for demos, and SideSwap over its relay - and every screen sees the same value whichever is connected. Adding a wallet is writing one adapter; it is never another path from a screen to a connector. Selection. connect takes the wallet the person pressed and whatever that wallet needs to start - a phrase, an address kind, a resume flag - availability is reported per wallet rather than as one flag, and signerType is the connected wallet's own answer. Nothing selected refuses by name rather than answering from whichever adapter happened to be built first, and a wallet already connected or coming back from a held approval is selected without anyone pressing anything. The account. Descriptor derivation stopped assuming a bare descriptor: the chain library is asked rather than the string guessed at, so a connector's already confidential descriptor is read as it stands and only a bare one is wrapped. scriptPubkey is a real script on all four wallets. What an adapter publishes has the account's own blinding key taken out first - anything holding it could unblind every output the account owns - and a descriptor whose key cannot be taken out is refused rather than passed on. The chain. The cached wollet, its IndexedDB namespace, the cross-tab lock, the 60s reread with its throttle and focus handlers, the reconciliation of a just-broadcast transaction and the asset-contract stage that lets a device show asset names rather than hashes all moved out of the old provider and behind the facade. It gives back the Rust memory it takes. syncWallet rereads the chain before the balances are asked for, which is what the six builders that call it before choosing inputs have always meant by it. A reread nobody asked for reaches the screens rather than sitting in the session. Performing. Each wallet that signs in the page performs an action by following the document's own input rule - an input is either one the wallet finds itself, named by asset and amount, or one located in the deployment's state by its type - and hands the result to the builder that already implements that action. All eight actions, creating the borrower account included, which every other one presupposes. The seven builders moved beside the protocol they build for, because a wallet and a screen both call them now. What the screens are told. The confirmed balance is what has confirmed, because only that can fund an action; the receive address is the wallet's own; a device waiting for its PIN reads as locked and gets its unlock screen back; a wallet being approved elsewhere says which request and offers the link and a cancel. The picker offers four cards, each disabled only for a reason true of this browser or this build. The seam test still guards the seam. Modules that became adapters left its superseded list, each departure stated, and it now notices a screen reaching for a wallet however the import is spelled. Two adversarial reviews over five rounds broke seventeen things with executable tests, every one of them fixed here. Forty-five stubs of this code fail the suite that used to stay green under them. Typecheck, lint, format, build and 143 tests pass at zero warnings. Creating a borrower account is proven against Liquid testnet by transaction 61d9833f at block 2590033. The other seven actions on a signing wallet await a recorded manual run.
lukachi
force-pushed
the
humid/wallet-protocol-actions
branch
from
August 28, 2026 11:45
34f5ecf to
7c5ca63
Compare
Author
|
Reopened against upstream: BlockstreamResearch#162. This fork was the wrong base — closing here so review happens in one place. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The dapp used to build its own transactions against one wallet. It now hands the protocol's own deployed document to whichever of four wallets is connected, and every screen sees the same value whichever that is.
How it worked before
providers/wallet/andproviders/humid/were parallel paths from a screen to a wallet, and the connect modal reached each one by hand. Adding a wallet meant another path.How it works now
providers/walletFacade/is the only thing a screen talks to. Behind it: the HUMID extension, a Jade device, a recovery phrase held in the page for demos, and SideSwap over its relay. Adding a wallet is writing one adapter — never another path from a screen to a connector.connecttakes the wallet the person pressed and whatever that wallet needs to start; availability is reported per wallet rather than as one flag;signerTypeis the connected wallet's own answer..simfsources of every covenant involved, the instance the factory published, the state the indexer reports, and the parameters the person chose. The HUMID extension compiles those sources, resolves what the manifest computes for itself, builds the transaction, shows what it will do, signs and broadcasts it. A wallet that signs in the page follows the document's own input rule — an input is either one the wallet finds itself, named by asset and amount, or one located in the deployment's state by its type — and hands the result to the builder that implements that action.syncWalletrereads the chain before balances are asked for, which is what the six builders that call it before choosing inputs always meant by it; a reread nobody asked for reaches the screens rather than sitting in the session.scriptPubkeyis a real script on all four wallets. What an adapter publishes has the account's own blinding key removed first — anything holding it could unblind every output the account owns — and a descriptor whose key cannot be removed is refused rather than passed on.The shape is the one Ethereum dapps have with an ABI, with one difference: with the extension, the transaction is assembled in the wallet rather than here.
The seam is checked, not asserted
web/src/test/theSeam.test.tswalks the import graph from the entry point and fails if the running application can reach a superseded module, or if anything above the facade names a wallet directly — however the import is spelled. Modules that became adapters left its superseded list, each departure stated in the test itself, so the list shrinking is a decision that was made rather than a test that was quieted.Nothing was deleted. What remains superseded is the pre-facade wiring —
providers/wallet/,providers/humid/, the old connect modal and account chip, the demo pages written around outpoints they chose, and the borrower-account hook that built the transaction here.Verified on chain
Liquid testnet, against the deployed protocol.
e0154712…2e089324…cddc64df…114c0bee…1afe98ad…b2bbcddd…793d73d7…Creating a borrower account on a wallet that signs in the page is proven by transaction
61d9833fat block 2590033. The other seven actions on a signing wallet await a recorded manual run; the extension path is the one confirmed in the table above.Gates
tsc -b,eslint,prettier --check,vite buildand 143 tests pass at zero warnings. The protocol check confirms both program ids still match the contract sources in this repository. Two adversarial reviews over five rounds broke seventeen things with executable tests; every one is fixed here, and forty-five stubs of this code fail a suite that used to stay green under them.Two known limitations
Neither is introduced by this change; both are properties of the wallet it talks to, and both are recorded rather than worked around.