Add ELIP: Liquid Wallet RPC Profile - #36
Open
KyrylR wants to merge 8 commits into
Open
Conversation
tvolk131
added a commit
to Resolvr-io/apogee
that referenced
this pull request
Jul 28, 2026
## Summary - define transport-neutral TypeScript request, result, and event types for the ten methods proposed in [ElementsProject/ELIPs#36](ElementsProject/ELIPs#36), pinned to draft revision `d5b713cbbad5a13f15baa35073e8dda53886f0b0` - add the proposed injected `LiquidProvider` contract: provider-owned JSON-RPC IDs, typed `request({ method, params })`, and `on({ event, listener })` returning an unsubscribe function - add structured RPC errors and dependency-free runtime validation that rebuilds trusted request objects from untrusted page input - model ELIP-0144 identifiers, descriptor result variants, message-signing variants, PSET constraints, and the provisional wallet ABI boundary ## Why This establishes a reviewable type and validation boundary before wiring the draft API into `window.liquid`. It intentionally leaves the existing provider and runtime behavior unchanged. ## Impact No new wallet methods are exposed yet and there are no user-visible behavior changes. Follow-up PRs can build the injection transport, router, and handlers against this contract. ## Validation - TypeScript: `tsconfig.json` - TypeScript: `tsconfig.node.json` - Vitest: 10 files, 159 tests (including the existing live SideSwap integration tests) - `git diff --check` <!-- codesmith:footer --> --- <a href="https://app.blacksmith.sh/Resolvr-io/codesmith/apogee/pr/63"><picture><source media="(prefers-color-scheme: dark)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"><source media="(prefers-color-scheme: light)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-light-v2.svg"><img alt="View with [code]smith" src="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"></picture></a> <a href="https://backend.blacksmith.sh/track/enable-autofix?expires=1787863915&installation_model_id=20418&pr_number=63&repository=Resolvr-io%2Fapogee&return_to=https%3A%2F%2Fgithub.com%2FResolvr-io%2Fapogee%2Fpull%2F63&signature=c7aa81156c2fedfaee37764bc988c4ca44b41b7d1fce665feba47f1012c40376"><picture><source media="(prefers-color-scheme: dark)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-light.svg"><img alt="Autofix with [code]smith" src="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"></picture></a> <sup>Need help on this PR? Tag <code>@codesmith-bot</code> with what you need. Autofix is disabled.</sup> <!-- codesmith:autofix:disabled --> <!-- /codesmith:footer -->
Member
|
Assigned ELIP 207 |
tvolk131
added a commit
to Resolvr-io/apogee
that referenced
this pull request
Aug 6, 2026
## Summary
- advertise and negotiate the ELIP-207 `sendTransfer` permission through
the event-discovered browser provider
- validate the pinned account and chain, preserve decimal base-unit
amounts exactly through LWK's `bigint` boundary, and support both
policy-asset and issued-asset transfers
- reuse Apogee's wallet-controlled review, local/Jade signing, and
broadcast paths while returning the profile's `{ txid }` result
- extend the provider playground and Chromium conformance suite with
transfer permission and error flows
## Security and behavior
A connection grant only authorizes a site to request `sendTransfer`;
every call builds the actual PSET and requires a fresh Apogee-controlled
approval showing the selected account, recipient, asset, exact amount,
and computed fee. Approval revalidates the origin's pinned connection,
permission, wallet, revision, and global connection generation before
signing, closing revoke/reconnect races.
Apogee continues to require confidential recipient addresses. Amounts
are validated as positive unsigned 64-bit decimal strings and are never
rounded through JavaScript `number` values on the RPC/review path.
The ELIP makes memo support optional. LWK 0.18 cannot add the required
arbitrary zero-value OP_RETURN output, so Apogee rejects requests
containing `memo` with structured `4200 unsupported_capability` rather
than silently dropping it.
## Validation
- `pnpm typecheck`
- `pnpm test` — 20 files, 283 tests
- `pnpm test:provider` — production Chrome build plus 2 real-extension
browser tests
- `pnpm build:firefox`
Profile source: ElementsProject/ELIPs#36.
<!-- codesmith:footer -->
---
<a
href="https://app.blacksmith.sh/Resolvr-io/codesmith/apogee/pr/77"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-light-v2.svg"><img
alt="View with [code]smith"
src="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"></picture></a>
<a
href="https://backend.blacksmith.sh/track/enable-autofix?expires=1788583661&installation_model_id=20418&pr_number=77&repository=Resolvr-io%2Fapogee&return_to=https%3A%2F%2Fgithub.com%2FResolvr-io%2Fapogee%2Fpull%2F77&signature=8db93b64d1f8028b638ca503503584197f65aaa98fd4d5472d7d958d1d8f3af4"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-light.svg"><img
alt="Autofix with [code]smith"
src="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"></picture></a>
<sup>Need help on this PR? Tag <code>@codesmith-bot</code> with what you
need. Autofix is disabled.</sup>
<!-- codesmith:autofix:disabled -->
<!-- /codesmith:footer -->
tvolk131
added a commit
to Resolvr-io/apogee
that referenced
this pull request
Aug 6, 2026
## Summary - implement ELIP #36 `getWalletDescriptor` for `publicWalletDescriptor` in `bip380-bip389-multipath` format - add explicit per-origin descriptor permission and authorization-gated `bip122_walletDescriptorChanged` delivery - extend the approval UI, provider playground, documentation, unit coverage, and real-browser conformance suite ## Security boundary - LWK validates and canonicalizes the stored CT descriptor before projection - projection accepts only `ct(slip77(...), ...)`, removes the independent private SLIP-77 master blinding key, rejects private spend keys and unsupported blinding policies, and recomputes the BIP-380 checksum - `publicConfidentialDescriptor` and unsupported descriptor formats fail with `4200` - raw parser errors are never forwarded to the dapp - descriptor reads recheck lock state, connection revision, wallet identity, and method permission before returning - descriptor events require both `getWalletDescriptor` and `bip122_walletDescriptorChanged` grants ## Test plan - `nix develop --command pnpm typecheck` - `nix develop --command pnpm test` (294 tests) - `nix develop --command pnpm test:provider` (2 real-browser tests) - `nix develop --command pnpm build:firefox` - `git diff --check` Upstream profile: ElementsProject/ELIPs#36 at `d5b713cbbad5a13f15baa35073e8dda53886f0b0`. <!-- codesmith:footer --> --- <a href="https://app.blacksmith.sh/Resolvr-io/codesmith/apogee/pr/80"><picture><source media="(prefers-color-scheme: dark)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"><source media="(prefers-color-scheme: light)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-light-v2.svg"><img alt="View with [code]smith" src="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"></picture></a> <a href="https://backend.blacksmith.sh/track/enable-autofix?expires=1788618894&installation_model_id=20418&pr_number=80&repository=Resolvr-io%2Fapogee&return_to=https%3A%2F%2Fgithub.com%2FResolvr-io%2Fapogee%2Fpull%2F80&signature=103e751db5e050f8328670c563d1cc210b25c9b6f5eb6dc3924525a083da7c24"><picture><source media="(prefers-color-scheme: dark)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-light.svg"><img alt="Autofix with [code]smith" src="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"></picture></a> <sup>Need help on this PR? Tag <code>@codesmith-bot</code> with what you need. Autofix is disabled.</sup> <!-- codesmith:autofix:disabled --> <!-- /codesmith:footer -->
tvolk131
added a commit
to Resolvr-io/apogee
that referenced
this pull request
Aug 6, 2026
## Summary - advertise and permission the Liquid Wallet RPC Profile `signPset` method - require a fresh Apogee-controlled approval for every signature request - bind approval to the exact analyzed PSET effects, then re-sync and re-analyze before signing - support both local-key and Jade wallets while returning the signed PSET without broadcasting - add playground controls, conformance coverage, provider E2E coverage, and implementation docs ## Security model - rejects `broadcast: true` with structured `4200`; signing and broadcasting remain separate boundaries - rejects watch-only wallets, collaborative/non-wallet inputs, issuance, unsupported scripts, incomplete outputs, and sighashes that do not commit to every output - derives approval details from current wallet state rather than trusting page-supplied amounts or recipients - shows full input outpoints/addresses/assets/amounts, external recipients, wallet effects, fees, confidentiality, and sighash modes - local signing re-analyzes and signs the same parsed PSET atomically - Jade signing carries the approved review and origin authorization through the device round-trip, then refreshes and validates the returned PSET before releasing it - rechecks the origin connection before and after signing so a revoked site cannot receive a late signature ## Supported scope - native P2WPKH wallet inputs - `SIGHASH_ALL` and `SIGHASH_ALL|ANYONECANPAY` - signed-PSET return only; no finalize or broadcast ## Verification - `pnpm typecheck` - `pnpm test` — 314 tests - `pnpm test:provider` — Chromium production build + 2 real-extension Playwright tests - `pnpm build:firefox` - `git diff --check` The browser E2E suite intentionally does not perform a successful funded signature because that would couple CI to a funded wallet and live Liquid service. Unit tests cover the atomic analyze-before-sign gate, exact review binding, mutation rejection, and signer-failure containment; the real-extension suite covers the permission prompt, unauthorized calls, and explicit no-broadcast boundary. A funded local or Jade signing flow is available through the playground for manual testing. Tracks the current draft of ElementsProject/ELIPs#36 (revision `d5b713cbbad5a13f15baa35073e8dda53886f0b0`). <!-- codesmith:footer --> --- <a href="https://app.blacksmith.sh/Resolvr-io/codesmith/apogee/pr/83"><picture><source media="(prefers-color-scheme: dark)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"><source media="(prefers-color-scheme: light)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-light-v2.svg"><img alt="View with [code]smith" src="https://pr-comments-assets.blacksmith.sh/codesmith/view-with-codesmith-dark-v2.svg"></picture></a> <a href="https://backend.blacksmith.sh/track/enable-autofix?expires=1788626418&installation_model_id=20418&pr_number=83&repository=Resolvr-io%2Fapogee&return_to=https%3A%2F%2Fgithub.com%2FResolvr-io%2Fapogee%2Fpull%2F83&signature=4380cc8c6887331d885c097325c0579a3b8ee3d8ad5c787a0d3a1f72881c8976"><picture><source media="(prefers-color-scheme: dark)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-light.svg"><img alt="Autofix with [code]smith" src="https://pr-comments-assets.blacksmith.sh/codesmith/autofix-with-codesmith-dark.svg"></picture></a> <sup>Need help on this PR? Tag <code>@codesmith-bot</code> with what you need. Autofix is disabled.</sup> <!-- codesmith:autofix:disabled --> <!-- /codesmith:footer -->
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.
This ELIP defines a Liquid wallet JSON-RPC profile for the wallet SDKs and other dapp-to-wallet transports.
It specifies how a dapp identifies a connected Liquid account, requests public wallet descriptors, reads wallet-computed
balances and UTXOs, requests transfers, requests PSET signatures, signs messages, uses deterministic identity keys,
delegates complex confidential transaction construction to the Wallet ABI transaction protocol, and receives descriptor-change events.
Bitcoin integrations can use public addresses and PSBTs as their main wallet-facing primitives.
Liquid wallets require a more explicit profile because Liquid has confidential transactions, multiple issued assets,
network-specific policy assets, CT descriptors, blinding keys, PSETs, and Simplicity.
Dapps need enough public wallet information to identify the connected account, construct descriptor-aware receive
and change logic, read user-approved balances and UTXOs, and build valid PSET signing requests. At the same time,
wallets must not leak view material merely to support these flows. This ELIP separates public descriptor disclosure
from wallet-computed balance and UTXO disclosure, and it defines a descriptor-format negotiation mechanism
based on descriptor representations.