diff --git a/README.mediawiki b/README.mediawiki index 6240aca..7b88225 100644 --- a/README.mediawiki +++ b/README.mediawiki @@ -109,6 +109,13 @@ Having an ELIP here does not make it a formally accepted standard until its stat | Tom Trevethan | Standards Track | Draft +|- style="background-color: #ffcfcf" +| [[elip-0206.mediawiki|206]] +| Wallet +| Clear Signing for Liquid Wallets +| Kyrylo Riabov, Artem Chystiakov +| Standards Track +| Draft |} diff --git a/elip-0206.mediawiki b/elip-0206.mediawiki new file mode 100644 index 0000000..b18c88b --- /dev/null +++ b/elip-0206.mediawiki @@ -0,0 +1,243 @@ +
+ ELIP: 206 + Layer: Wallet + Title: Clear Signing for Liquid Wallets + Author: Kyrylo Riabov+ +==Introduction== + +===Abstract=== + +This proposal gathers available resources on existing methods to attach and read metadata related to transaction. +As well as, presents a way to interpret a general-purpose action of signing a transaction on the Liquid network to the user. + +It helps users understand the consequences of signing a particular transaction and lowers the risk of blind signing +as much as possible within provided trust assumptions. + +===Copyright=== + +This document is licensed under the 3-clause BSD license. + +===Motivation=== + +To expand the Liquid ecosystem, infrastructure and user-facing applications should be able to explain +to a non-technical user what is happening and which outcomes to expect. Similar to banking systems, +users should be given as much security as possible by default. + +Therefore, ecosystem participants should make as much effort as possible in explaining actions to the user. + +==Specification== + +The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [https://www.rfc-editor.org/rfc/rfc2119 RFC 2119] and [https://www.rfc-editor.org/rfc/rfc8174 RFC 8174] when, and only when, they appear in all capitals. + +===High-level verification procedure=== + +The wallet should show which assets and amounts the user is spending or receiving, so the user can recognize the intended asset and check for unrecognized spendings. +It should also explain how the transaction affects the user's ability to spend those assets later, including any conditions attached to the new outputs. + +On Liquid, spending conditions can be written directly in [Bitcoin Script with Elements extensions](https://github.com/ElementsProject/elements/blob/c7e856fab1b0c4d37005e25c0940184d812a26a0/src/script/interpreter.cpp), expressed using [Miniscript](https://github.com/ElementsProject/elements-miniscript/blob/e6eca8bd52bdc397e7d386b481deb7be980683de/README.md), or written in [Simplicity](https://github.com/BlockstreamResearch/simplicity/blob/91d89bac54e9411281ee3b6e766a0ea20eb0a3d3/README.md). +Those can require a signature, multiple signatures, a waiting period, or restrictions on the outputs a transaction creates. +Simplicity programs and the [https://github.com/ElementsProject/elements-miniscript/blob/e6eca8bd52bdc397e7d386b481deb7be980683de/src/extensions/introspect_ops.rs Elements extensions to Miniscript] can also constrain the assets, amounts, scripts, and structure of transaction inputs and outputs. +For example, the [https://github.com/BlockstreamResearch/damp/blob/96db9a2226951fd1be57a9b1cfb4105ce4dcb2a3/paper/main.tex DAMP paper] describes Simplicity covenants that enforce issuer-defined blacklists, whitelists, and per-transaction payment limits for regulated assets. + +Liquid outputs can keep their assets and amounts confidential. +Wallets should show which outputs use this protection and explain any privacy consequences by modifying those. + +The wallet's explanation should distinguish its own checks from information it accepts from an application or registry, and identify any part it cannot explain. +See [[#Security_considerations|Security considerations]] for the risks involved. + +===Asset verification=== + +Names and tickers such as L-BTC and USDT help users recognize assets. +The asset identifier itself is 32 bytes. +[https://github.com/ElementsProject/ELIPs/blob/d886692e44cc7c47340d8659f60f9478707c7ad8/elip-0100.mediawiki ELIP 100] describes how a contract and issuance prevout bind an issued asset's identifier to metadata such as its name, ticker, precision, and issuer domain, etc. +Wallets and signers MUST follow its applicable verification rules before relying on that metadata. + +====Implementation examples==== + +These products show how wallets and services handle asset metadata. + +{| class="wikitable" +! Project +! Asset metadata handling +|- +| Jade +| The Liquid signing RPC reads+ Artem Chystiakov + Comments-Summary: No comments yet. + Comments-URI: https://github.com/ElementsProject/ELIPs/pull/40 + Status: Draft + Type: Standards Track + Created: 2026-06-09 + License: BSD-3-Clause +
asset_info in [https://github.com/Blockstream/Jade/blob/9c097297f58339c15fb9b8df4c7fe105efefb902/main/process/sign_tx.c#L466-L478 sign_tx.c]. [https://github.com/Blockstream/Jade/blob/9c097297f58339c15fb9b8df4c7fe105efefb902/main/assets.c#L105-L180 assets_get_allocate] recomputes the asset identifier from the contract and issuance prevout before accepting the supplied metadata. [https://github.com/Blockstream/Jade/commit/f6433446ee76a5c9c481452166b7c384bd6bbbf7 Commit f6433446] introduced this RPC support. The limitation is in the separate [https://github.com/Blockstream/Jade/blob/9c097297f58339c15fb9b8df4c7fe105efefb902/main/process/sign_psbt.c#L989-L1007 PSET signing path], which passes no external asset metadata to the display at the linked revision.
+|-
+| Simplicity Lending
+| [https://github.com/BlockstreamResearch/simplicity-lending/pull/124 PR #124], from feat/clear-signing-asset-metadata, added asset metadata integration. The [https://github.com/BlockstreamResearch/simplicity-lending/blob/f1f6c29c592d635775fed2d120bb292e4f418a2e/web/src/lwk/assetContract.ts client] constructs contracts for protocol-issued assets. The [https://github.com/BlockstreamResearch/simplicity-lending/blob/f1f6c29c592d635775fed2d120bb292e4f418a2e/crates/indexer/src/indexer/asset_registration.rs#L87-L140 indexer] checks their issuance binding before registration. The [https://github.com/BlockstreamResearch/simplicity-lending/blob/f1f6c29c592d635775fed2d120bb292e4f418a2e/crates/indexer/src/api/assets/handlers.rs#L32-L62 domain-proof endpoint] serves evidence for known protocol assets, and the [https://github.com/BlockstreamResearch/simplicity-lending/blob/f1f6c29c592d635775fed2d120bb292e4f418a2e/web/src/providers/wallet/WalletProvider.tsx#L327-L346 wallet integration] adds available registry contracts to PSETs. The signer remains responsible for ELIP 100 verification.
+|-
+| Liquid Asset Registry
+| In the published asset_registry implementation, [https://github.com/Blockstream/asset_registry/blob/5ecf533caffeec23ea3887f89ccf0962bf601ebe/src/registry.rs#L47-L59 registration] calls [https://github.com/Blockstream/asset_registry/blob/5ecf533caffeec23ea3887f89ccf0962bf601ebe/src/asset.rs#L135-L147 Asset::verify] to check the contract binding, asset fields, on-chain issuance, and domain association. [https://github.com/Blockstream/asset_registry/blob/5ecf533caffeec23ea3887f89ccf0962bf601ebe/src/entity.rs entity.rs] implements HTTP and DNS domain proofs. The separate [https://github.com/Blockstream/asset_registry_v2/blob/bea05e99b86b0b619dd1c3199e2f30bbcc523b2c/README.md registry v2 trust model] also describes domain verification as an acceptance check at registration time.
+|}
+
+====Asset metadata example====
+
+This excerpt shows an issued asset's metadata in the [https://github.com/Blockstream/asset_registry/blob/5ecf533caffeec23ea3887f89ccf0962bf601ebe/src/asset.rs Liquid Asset Registry] format.
+
+
+{
+ "asset_id": "ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2",
+ "contract": {
+ "entity": {"domain": "tether.to"},
+ "issuer_pubkey": "0337cceec0beea0232ebe14cba0197a9fbd45fcf2ec946749de920e71434c2b904",
+ "name": "Tether USD",
+ "precision": 8,
+ "ticker": "USDt",
+ "version": 0
+ },
+ "issuance_prevout": {
+ "txid": "9596d259270ef5bac0020435e6d859aea633409483ba64e232b8ba04ce288668",
+ "vout": 0
+ }
+}
+
+
+A wallet still needs to verify metadata supplied by the registry.
+
+The registry expects an HTTP domain proof at /.well-known/liquid-asset-proof- in this form, with the placeholders replaced:
+
+Authorize linking the domain name to the Liquid asset
+
+====Issuer and registry trust====
+
+An ELIP 100 check establishes the binding between a contract and an asset identifier.
+It does not establish the issuer's real-world identity, the asset's value, or whether an issuer will honor a redemption promise.
+Those judgments depend on the issuer and the evidence the user relies on about that issuer.
+
+Anyone can issue a different asset with copied metadata, including the same domain string.
+That copied string alone does not satisfy the registry's domain-proof check for the new asset identifier.
+The cited legacy registry implementation also rejects a second registration with the same entity and ticker.
+These acceptance rules depend on the registry enforcing them correctly and on the security of the domain's control.
+A recorded acceptance decision does not prove that the domain remains under the same control or still serves the proof.
+
+The issuer_pubkey field is part of the contract's metadata.
+It does not by itself grant authority to spend or reissue the asset.
+The cited legacy registry implementation uses that key to authorize [https://github.com/Blockstream/asset_registry/blob/5ecf533caffeec23ea3887f89ccf0962bf601ebe/src/asset.rs#L154-L161 deletion of a registration].
+Losing the corresponding private key can prevent that authorization.
+Compromise can allow another party to authorize it.
+Neither event changes the contract already bound to the on-chain asset identifier.
+
+===Verification of spending conditions===
+
+To explain a spend, a wallet needs to identify the method used to lock the funds.
+
+Existing methods shown in the table below demonstrate the portion of functionality that wallets should handle to enable proper explanation of the UTXO spending to the user.
+
+{| class="wikitable"
+! Mechanism
+! What the user needs to understand
+! Reference
+|-
+| Multisignature scripts
+| Which keys authorize the spend and how many signatures are required.
+| [https://github.com/bitcoin/bips/blob/09e21036a4001fe6c9ba65c1d3a39b737768132f/bip-0011.mediawiki BIP 11]
+|-
+| Absolute and relative timelocks
+| Which block height, time, or output age the spending path requires.
+| [https://github.com/bitcoin/bips/blob/09e21036a4001fe6c9ba65c1d3a39b737768132f/bip-0065.mediawiki BIP 65], [https://github.com/bitcoin/bips/blob/09e21036a4001fe6c9ba65c1d3a39b737768132f/bip-0112.mediawiki BIP 112]
+|-
+| Pay-to-script-hash and SegWit script commitments
+| Which redeem script or witness script defines the spending conditions.
+| [https://github.com/bitcoin/bips/blob/09e21036a4001fe6c9ba65c1d3a39b737768132f/bip-0016.mediawiki BIP 16], [https://github.com/bitcoin/bips/blob/09e21036a4001fe6c9ba65c1d3a39b737768132f/bip-0141.mediawiki BIP 141]
+|-
+| Taproot
+| Whether the transaction uses the key path or a script path, and what authorizes that path.
+| [https://github.com/bitcoin/bips/blob/09e21036a4001fe6c9ba65c1d3a39b737768132f/bip-0341.mediawiki BIP 341], [https://github.com/bitcoin/bips/blob/09e21036a4001fe6c9ba65c1d3a39b737768132f/bip-0342.mediawiki BIP 342]
+|-
+| Miniscript
+| Which signatures, hash preimages or timelocks are required, and which inputs and outputs its Elements extensions constrain.
+| [https://github.com/ElementsProject/elements-miniscript/blob/e6eca8bd52bdc397e7d386b481deb7be980683de/README.md Elements Miniscript], [https://github.com/ElementsProject/elements-miniscript/blob/e6eca8bd52bdc397e7d386b481deb7be980683de/src/extensions/introspect_ops.rs Elements extensions]
+|-
+| Simplicity
+| Which signatures or other witness values the program requires, and how it restricts transaction inputs and outputs.
+| [https://github.com/BlockstreamResearch/simplicity/blob/8adafc9b55d694111c99fa11f90c7e48376ed1e5/Simplicity-TR.pdf Simplicity technical report]
+|}
+
+A Simplicity program can require several UTXOs to be spent together and restrict the outputs created by the transaction.
+
+Some of those would require a separate ELIP/BIP to standardize the parsing and explanation for the user.
+In the case of Simplicity, we rely on [https://github.com/stringhandler/ELIPs/blob/41462cfbd02e6eae8795f7753ceb5ef0c779b84c/elip-0205.mediawiki ELIP 205], which is explained in the next section.
+
+====Transaction manifests for Simplicity contracts====
+
+[https://github.com/stringhandler/ELIPs/blob/41462cfbd02e6eae8795f7753ceb5ef0c779b84c/elip-0205.mediawiki ELIP 205] describes how to construct a protocol transaction, including the inputs it consumes, outputs it creates and witnesses needed to satisfy its inputs.
+Its manifests carry signer-facing text to explain the operation.
+The draft currently defines only the Simplicity script type and allows other types to be added.
+A wallet using a transaction manifest to explain a Simplicity operation MUST follow ELIP 205's applicable construction and validation rules.
+ELIP 205 supplies the manifest rules.
+Elements' Simplicity execution rules determine whether the program and witness satisfy the spending conditions.
+The [https://github.com/ElementsProject/ELIPs/pull/41 draft proposal] names [https://github.com/stringhandler/txmanifest-wallet/tree/5624dfc77f742d66798d469de1bb79c8f09fcf0b txmanifest-wallet] as its reference implementation and records known conformance gaps.
+
+==Rationale==
+
+===Readable explanations with supporting evidence===
+
+Clear signing separates a description from the evidence that supports it.
+A familiar ticker or contract name helps the user recognize an operation, but recognition alone cannot establish that the description applies to the transaction being authorized.
+Keeping full identifiers accessible lets the user inspect what a displayed label refers to, including when two assets use the same label.
+
+===Using existing specifications===
+
+ELIP 100 carries issued-asset evidence to offline signers, while ELIP 205 describes how a wallet constructs and explains a protocol transaction.
+Referencing these specifications gives implementers a defined place to find the rules for each part of the review.
+
+===Ongoing work===
+
+ELIP 206 remains a draft under discussion in [https://github.com/ElementsProject/ELIPs/pull/40 PR #40].
+It can be updated as new proposals improve clear signing, existing standards evolve, and implementations provide better ways to explain transactions.
+
+==Backwards compatibility==
+
+This ELIP changes neither Elements consensus nor transaction serialization.
+Wallets can adopt ELIP 100 asset metadata support independently of support for Simplicity transaction manifests.
+
+==Security considerations==
+
+===Misleading metadata===
+
+An attacker can substitute a familiar name or ticker for a different asset.
+Even correctly bound metadata can use a visually confusing label.
+Wallets should make the verification result clear and keep the full asset identifier accessible, following ELIP 100's display guidance.
+Interfaces should defend against Unicode confusables and ambiguous truncation.
+
+===External sources and unavailable evidence===
+
+An authenticated connection identifies the endpoint serving data.
+The wallet must still check that the description matches the transaction.
+A wallet should identify the source of labels and explain what it could not verify.
+Failures and timeouts must not turn an unchecked description into a verified one.
+These recommendations on source attribution and fallback draw on the [https://github.com/ethereum/clear-signing-erc7730-registry/blob/0318f9a51ec4fc7ba4aed6de5e315c8884d1fe38/specs/erc-7730.md#security-considerations security considerations in ERC-7730].
+
+===Confidential transactions===
+
+A signer can produce a valid [https://github.com/ElementsProject/elements/blob/c7e856fab1b0c4d37005e25c0940184d812a26a0/src/script/interpreter.cpp#L2688-L2756 Taproot signature] over confidential commitments without knowing the underlying asset or amount.
+A signer can verify explicit assets and amounts supplied with the [https://github.com/ElementsProject/elements/blob/c7e856fab1b0c4d37005e25c0940184d812a26a0/doc/pset.mediawiki PSET commitment proofs] without holding the blinding keys.
+Without unblinding data or these proofs, it cannot verify a confidential output's claimed asset and amount.
+Sharing an output's unblinding data reveals its asset and amount to the recipient of that data.
+
+===Manifest descriptions===
+
+Signer-facing text in a manifest is author-supplied.
+The user still relies on the manifest author to describe the declared operation honestly.
+A valid signature over a manifest does not make a transaction conform to that manifest.
+
+===Constrained signers===
+
+A hardware or otherwise constrained signer MUST independently verify every transaction-specific claim it marks as verified.
+Host-supplied claims that cannot be checked on the signer MUST be marked unverified or omitted.
+An implementation may split verification across components only when the user can tell which component established each claim and the authorization policy does not silently promote a host assertion.
+
+===Resource exhaustion===
+
+Metadata and manifest parsers handle attacker-controlled input.
+Implementations SHOULD limit document size, nesting, field lengths, compilation work, network requests and cached entries.
+If a resource limit prevents a required verification, the implementation MUST fail closed.