From 9d64d84eaa338d0279b0efca76d5ec91c39242b8 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Thu, 27 Apr 2023 21:03:51 +0100 Subject: [PATCH 01/35] Governance wallet connector first draft --- CIP-XXXX/CIP-XXXX.md | 897 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 897 insertions(+) create mode 100644 CIP-XXXX/CIP-XXXX.md diff --git a/CIP-XXXX/CIP-XXXX.md b/CIP-XXXX/CIP-XXXX.md new file mode 100644 index 0000000000..da630b8a9f --- /dev/null +++ b/CIP-XXXX/CIP-XXXX.md @@ -0,0 +1,897 @@ +--- +CIP: ? +Title: Cardano dApp-Wallet Web Bridge Governance Extension +Category: Wallets +Status: Proposed +Authors: + - Ryan Williams +Implementors: [] +Discussions: + - https://github.com/cardano-foundation/cips/pulls/? +Created: 2022-02-24 +License: CC-BY-4.0 +--- + +## Abstract + +This document describes an interface between webpage/web-based stacks and +Cardano wallets. This specification defines the API of the javascript object +that needs to be injected into web applications. + +These definitions extend +[CIP-30 | Cardano dApp-Wallet Web Bridge](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030) +to provide support for +[CIP-1694 | A First Step Towards On-Chain Decentralized Governance](https://github.com/cardano-foundation/CIPs/pull/380) +focussed web-based stacks. Here we aim to support the requirements of both Ada +holders' and DReps' interactions with such web-based stacks. + +> **Note** This proposal assumes knowledge of the ledger governance model as outlined within +> [CIP-1694](https://github.com/cardano-foundation/CIPs/pull/380). + +## Motivation: why is this CIP necessary? + +CIP-1694 introduces many new concepts, entities and actors to Cardano; +describing their implementation at the ledger level. Yet, for most eco-system +participants low level details are abstracted away by tools, such as wallets. +This creates a need for tooling to be able support the utilization of ledger +features. This specification allows for creation of web-based tools for the +utilization of CIP-1694's governance features. + +This proposal enables Ada holders and DReps to engage web-based tooling through +wallets. Thus the primary stakeholders for this proposal are tool developers and +wallet providers. Here we aim to outline all endpoints needed to be exposed to +web based tools to support all the needs Ada holders and DReps to engage with +CIP-1694's governance design. + +## Specification + +We define the following specification as an extension to the specification +described within CIP-30. + +> **Note** This specification will evolve as the proposed ledger governance +> model matures. It is likely the precise data structures outlined here will be +> need to be adjusted. + +### DRep Key + +CIP-1694 does not define a derivation path for registered DRep credentials, here +we propose the introduction of DRep Keys to act as DRep credentials for +registered DReps. + +The methods described here should not be considered the only definitive method +of generating DRep credentials. Rather these methods should be employed to +derive keys for non-script registered DReps. + +#### Derivation + +Here we describe DRep Key derivation as it attains to Cardano wallets who follow +the +[CIP-1852 | HD (Hierarchy for Deterministic) Wallets for Cardano](https://github.com/cardano-foundation/CIPs/blob/master/CIP-1852/README.md) +standard. + +To differentiate DRep credentials from other Cardano keys the derivation path +must follow: + +`m / 1718' / 1815' / account' / chain / address_index` + +We strongly suggest that a maximum of one set of DRep credentials should be +associated with one wallet account, this can be achieved by setting `chain=0` +and `address_index=0`. Thus avoiding the need for DRep Key discovery. + +We believe the overhead that would be introduced by "multi-DRep" accounts is an +unjustified expense. Future iterations of this specification may expand on this, +but at present this is seen as unnecessary. + +> **Note** `1718` was the year that François-Marie adopted the pseudonym Voltaire. + +#### Tooling + +Supporting tooling should clearly label these key pairs as "CIP-???? DRep Keys". + +Bech32 prefixes of `drep_sk` and `drep_vk` should be used. + +Examples of acceptable `keyType`s for supporting tools: + +| `keyType` | Description | +| ------------------------------------ | --------------------- | +| `CIP????DRepSigningKey_ed25519` | DRep Signing Key | +| `CIP????DRepVerificationKey_ed25519` | DRep Verification Key | + +For hardware implementations: + +| `keyType` | Description | +| ------------------------------------ | ------------------------------ | +| `CIP????DRepVerificationKey_ed25519` | Hardware DRep Verification Key | | +| `CIP????DRepHWSigningFile_ed25519` | Hardware DRep Signing File | + +### Data Types + +#### DRepID + +```ts +type DRepID = string; +``` + +A hex string representing a registered DRep's ID which is a 32-byte Blake2b-224 +hash digest of a 32 byte Ed25519 public key, as described in +[CIP-1694 Registered DReps](https://github.com/JaredCorduan/CIPs/blob/voltaire-v1/CIP-1694/README.md#registered-dreps). + +#### PubDRepKey + +```ts +type PubDRepKey = string; +``` + +A hex string representing 32 byte Ed25519 DRep public key, as described in +[DRep Key](#DRep-key). + +#### PubStakeKey + +```ts +type PubStakeKey = string; +``` + +A hex string representing 32 byte Ed25519 public key used as a staking +credential. + +#### MetadataAnchor + +```ts +interface MetadataAnchor { + metadataURL: string; + metadataHash: string; +} +``` + +This interface represents a metadata anchor which can be related to particular +on-chain entities. + +- `metadataURL`: A string containing the URL-to-plaintext version of the + metadata. +- `metadataHash`: A string containing a Blake2b-256 hash of the metadata + plaintext, which is stored at the metadataURL. This hash allows clients to + verify the correctness of data presented at metadataURL. + +> **Note** This specification is not concerned with how metadata hosted. + +#### SignedDelegationCertificate + +```ts +interface SignedDelegationCertificate { + target: DRepID | "Abstain" | "No Confidence"; + stakeKey: PubStakeKey; + txHash: string; + witness: string; +} +``` + +This interface represents a vote delegation certificate that has been submitted +to chain and included within a block. + +- `target`: The target of the delegation, DRep ID provided if the delegation was + to a + [registered DRep](https://github.com/JaredCorduan/CIPs/blob/voltaire-v1/CIP-1694/README.md#registered-dreps). + If delegating to a + [pre-defined DRep](https://github.com/JaredCorduan/CIPs/blob/voltaire-v1/CIP-1694/README.md#pre-defined-dreps) + then the name. +- `stakeKey`: The public stake key acting as the stake credential of the Ada + holder who has submitted the delegation. +- `txHash`: A string containing the hash of the transaction which contained this + certificate that was submitted to chain and included in a block. This is to be + used by clients to track the status of the delegation transaction on-chain. +- `witness`: A string containing the stake credential witness attached to the + certificate. + +#### DRepRegistrationCertificate + +```ts +interface DRepRegistrationCertificate { + dRepKey: PubDRepKey; + metadataAnchor?: MetadataAnchor; + depositAmount?: number; + // reward address for deposit return TBC +} +``` + +This interface represents a DRep registration certificate as described in +[CIP-1698 Delegated Representatives](https://github.com/JaredCorduan/CIPs/blob/voltaire-v1/CIP-1694/README.md#delegated-representatives-DReps). +//todo: link CDDL + +- `dRepKey`: The public side of the DRep Key pair used for witnessing the + certificate and to be hashed to provide DRep ID. +- `metadataAnchor`: Optionally allows the linking of off-chain metadata. +- `depositAmount`: Optionally supplied by the client, if the user is registering + for the first time a deposit amount is supplied. + +#### SignedDRepRegistrationCertificate + +```ts +interface SignedDRepRegistrationCertificate { + certificate: DRepRegistrationCertificate; + txHash: string; + witness: string; +} +``` + +This is returned from the wallet back to the client once a DRep registration +certificate is submitted to chain and included in a block. + +- `certificate`: Contains the `DRepRegistrationCertificate` object. +- `txHash`: A string containing the hash of the transaction which contained this + certificate that was submitted to chain and included in a block. This is to be + used by dApps to track the status of the transaction on-chain. +- `witness`: A string containing the DRep credential witness attached to the + certificate. + +#### DRepRetirementCertificate + +```ts +interface DRepRetirementCertificate { + dRepKey: PubDRepKey; + expirationEpoch: number; +} +``` + +This data structure is used to represent a DRep Retirement Certificate as +described in +[CIP-1698 Delegated Representatives](https://github.com/JaredCorduan/CIPs/blob/voltaire-v1/CIP-1694/README.md#delegated-representatives-DReps). +//todo: link CDDL + +- `dRepKey`: The public side of the DRep Key pair used for witnessing the + certificate and to be hashed to obtain the required DRep ID. +- `expirationEpoch`: An integer representing the Cardano epoch number after + which the DRep will retire. + +#### SignedDRepRetirementCertificate + +```ts +interface SignedDRepRetirementCertificate { + certificate: DRepRetirementCertificate; + txHash: String; + witness: string; +} +``` + +This is returned from the wallet back to the client once a DRep Retirement +Certificate is submitted to chain and included in a block. + +- `certificate`: Contains the `DRepRetirementCertificate` object. +- `txHash`: A string containing the hash of the transaction which contained this + certificate that was submitted to chain and included in a block. This is to be + used by clients to track the status of the transaction on-chain. +- `witness`: A string containing the dRep credential witness attached to the + certificate. + +#### Governance Action Types + +Here we outline interfaces for each governance action which need to support +additional data to the ledger + +##### NewCommittee + +```ts +interface NewCommittee { + keyHashes: string[]; + quorum: number; +} +``` + +Interface representing a governance action to introduce a new committee/quorum, +as described in +[Conway ledger specification `new_commitee`](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L126). + +- `keyHashes`: A string list representing the 28-byte Blake2b-224 hash digests + of the new committee's keys. +- `committeeSize`: A number representing the needed quorum for the new + committee. + +##### UpdateConstitution + +```ts +interface UpdateConstitution { + constitutionHash: string; +} +``` + +Interface representing a governance action to update the Cardano Constitution +document, as described in +[Conway ledger specification `new_constitution`](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L128). + +- `constitutionHash`: A string containing the 32-byte Blake2b-256 hash digest of + the new constitution document. + +##### HardForkInit + +```ts +interface HardForkInit { + protocolVer: number; +} +``` + +Interface representing a governance action to initiate a Hard-Fork, as described +in +[Conway ledger specification `hard_fork_initiation_action`](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L120). + +- `protocolVer`: A number representing the new major protocol version which is + too hard-fork to. + +##### UpdateParameters + +```ts +interface UpdateParameters { + params: { + key: string; + newValue: number; + }[]; +} +``` + +// todo: make a better representation for this Interface representing a +governance action to update values of protocol parameters, as described in +[Conway ledger specification `parameter_change_action`](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L118). + +- `params`: An array of objects representing the parameters to be adjusted and + their new values. +- `key`: The protocol parameter to be adjusted. +- `newValue`: A string array of each parameters new value. + +##### TreasuryWithdrawal + +```ts +interface TreasuryWithdrawal { + mappings: { + recipient: string; + amount: number; + }[]; +} +``` + +Interface representing a governance action to withdraw funds from the Cardano +treasury, as described in +[Conway ledger specification `treasury_withdrawals_action`](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L122). + +- `mappings`: An array of objects representing reward addresses and amounts in + Ada. +- `recipient`: A string representing a reward account address. +- `amount`: A number representing the amount of Lovelace to send to the + corresponding recipient. + +#### GovernanceActionID + +```ts +interface GovernanceActionID { + transactionID: string; + govActionIndex: number; +} +``` + +Interface representing a governance action ID, as described in +[Conway ledger specification `governance_action_id`](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L145). + +- `transactionID`: A 32-byte Blake2b-256 hash digest of the transaction + containing the governance action. +- `govActionIndex`: The index within the transaction body pointing to the + governance action. + +#### GovernanceAction + +```ts +interface GovernanceAction { + actionType: + | "MotionOfNoConfidence" // no payload + | NewCommittee + | UpdateConstitution + | HardForkInit + | UpdateParameters + | TreasuryWithdrawal + | "Info"; // no payload + lastAction: GovernanceActionID; + depositAmount: number; + rewardAddress: string; + metadataAnchor: MetadataAnchor; +} +``` + +Interface representing a governance action proposal to be submitted in a +transaction, to chain, as described in +[Conway ledger specification `proposal_procedure`](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#97). + +- `actionType`: The governance action type, with needed additional payload data. +- `lastAction`: A `GovernanceActionID` object identifying the preceding + governance action of this type. +- `depositAmount`: A number representing the number of Lovelace deposited for + this action. +- `rewardAddress`: A string containing the address where the deposit will be + returned to. +- `metadataAnchor`: Used to allow the linking of off-chain metadata. + +#### SignedGovernanceAction + +```ts +interface SignedGovernanceAction { + action: GovernanceAction; + governanceActionID: GovernanceActionID; +} +``` + +Interface representing a governance action which has been successfully submitted +to chain and included in a block. + +- `action`: Contains the submitted `GovernanceAction` object. +- `governanceActionID`: A `GovernanceActionID` object representing the ID of the + submitted governance action. + +> **Note** Unlike other 'signed' data structures we omit a witness field, this +> is because verification from client applications is not necessary. + +#### Vote + +```ts +interface Vote { + DRepKey: PubDRepKey; + governanceActionID: GovernanceActionID; + choice: "Yes" | "No" | "Abstain"; + metadataAnchor?: MetadataAnchor; +} +``` + +An interface used to represent an unsigned vote transaction, as described in +[Conway ledger specification `voting_procedure`](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#89). + +- `DRepKey`: The public side of the DRep Key pair used for witnessing the vote. +- `governanceActionID`: A `GovernanceActionID` object representing the target + governance action for this vote. +- `choice`: A string representing the user's choice for the governance action + vote, must be either 'Yes', 'No' or 'Abstain'. +- `metadataAnchor`: Optionally used to allow the linking of off-chain metadata + in a way to ensure correctness. + +> **Note** This interface does not map directly to the +> [Conway ledger specification `voting_procedure`](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L79), +> this is because this specification only caters for DRep role. + +#### SignedVote + +```ts +interface SignedVote { + vote: Vote; + txHash: string; + witness: string; +} +``` + +Interface representing a vote transaction which has been successfully submitted +to chain and included in a block. + +- `vote`: Contains the `Vote` object representing the submitted vote. +- `txHash`: A string containing the hash of the transaction which contained this + submitted vote. +- `witness`: The governance credential witness for this vote. + +### Error Types + +This specification inherits all Error Types defined in CIP-30. + +// todo: add more + avoid collisions with CIP-62? + +#### Extended APIError + +Here we define extensions to +[CIP-30's Error Types](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030#error-types). + +```ts +type enum APIErrorCode { + // CIP-30 error codes + InvalidArgumentError = -5 + UnknownChoiceError = -6 + UnknownKey = -7 + InvalidKey = -8 +} + +interface APIError { + code: APIErrorCode, + info: string +} +``` + +- `InvalidArgumentError` - Generic error for errors in the formatting of the + arguments. +- `UnknownChoiceError` - client supplies an unknown choice in a `Vote`. +- `UnknownKey` - client supplies an unknown public key (DRep or Stake) with the + expectation of signature. +- `InvalidKey` - client supplies a public key that does not match another + supplied credential. This could be for DRep Keys not matching DRepID in + Retirement Certificate or, could be when the incorrect role is supplied in a + vote with a DRep key. + +##### APIError elements + +- `code`: The `APIErrorCode` which is being reported. +- `info` - A human readable description of the error. + +#### Extended TxSignError + +Here we add additional error codes to CIP-30's +[TxSignError](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030#txsignerror). + +```ts +type enum TxSignErrorCode { + ProofGeneration = 1, + UserDeclined = 2, +} + +interface TxSignError = { + code: TxSignErrorCode, + info: string, +} +``` + +- `ProofGeneration` - Raised when there is an error during witness/proof + generation. +- `UserDeclined` - Raised when the user declined to sign one or many items. + +### Full Governance API + +Methods contained in this section on invocation should request the user to +review and to consent to signature and submission. The exceptions to this are +`.getActiveStakeKeys()` and `.getDRepKey()`, user consent should not be needed +to share public key information. + +#### `api.getDRepKey(): Promise` + +Errors: `APIError` + +The connected wallet account provides the account's public DRep Key, derivation +as described in [DRep Key](#DRep-key). + +##### Returns + +The wallet account's DRep Key. + +#### `api.getActiveStakeKeys(): Promise` + +Errors: `APIError` + +The connected wallet account's active public stake keys (with keys which are +being used for staking), if the wallet tracks the keys that are used for +governance then only those keys shall be returned. + +These are used by the client to identify the user's on-chain CIP-1694 +interactions. Here we allow for multiple stake credentials to provided at once +for the case of +[multi-stake key wallets](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0018). + +##### Returns + +An array of the connected user's active stake keys. + +#### `api.submitDelegation(DRep: DRepID, stakeKey: PubStakeKey): Promise` + +Errors: [APIError](#extended-apierror), [`TxSignError`](#extended-txsignerror) + +This endpoint requests the wallet to build, sign and submit a vote delegation +certificate for a supplied DRepID and Public Stake Key. This certificate is +described **todo: add CDDL when available**. This must be signed by the secret +key of the provided public stake key. + +By allowing clients to supply the stake key we are placing the burden of +multi-governance-delegation management onto the client, reducing the complexity +for wallet implementations. + +The user's permission to sign this transaction must be requested by the wallet, +additionally wallets may wish to display the contents of the certificate to the +user to check. This allows for the user to catch malicious clients attempting to +alter the certificate's contents. + +##### Returns + +This returns a `SignedDelegationCertificate` object which contains all the +details of the submitted delegation certificate, for the client to confirm. The +returned `txHash` can be used by the client to track the status of the +transaction containing the certificate on Cardano. + +#### `api.submitDRepRegistration(certificate: DRepRegistrationCertificate): Promise` + +Errors: [APIError](#extended-apierror), [`TxSignError`](#extended-txsignerror) + +This endpoint requests the wallet to build, sign and submit a DRep registration +certificate as described **todo: add CDDL when available**. The wallet must sign +the certificate using the secret side of the supplied DRep public key presented +in the `DRepKey` field. + +The user's permission to sign this transaction must be requested for by the +wallet, additionally wallets may wish to display the contents of the certificate +to the user to check. + +Wallets should be responsible for handling the payment of deposit required with +the submission of this certificate shown by the `depositAmount` field. + +##### Returns + +This returns a `signedDRepRegistrationCertificate` object which contains all the +details of the submitted registration certificate, for the client to confirm. +The returned `txHash` can be used by the client to track the status of the +transaction containing the certificate on Cardano. + +#### `api.submitDRepRetirement(certificate: DRepRetirementCertificate): Promise` + +Errors: [APIError](#extended-apierror), [`TxSignError`](#extended-txsignerror) + +This endpoint requests the wallet to build, sign and submit a DRep retirement +certificate as described in CIP-1694 **todo: add CDDL when available**. The +wallet must sign the certificate using the secret side of the supplied dRep +public key presented in the `DRepKey` field. + +The user's permission to sign this transaction must be requested for by the +wallet, additionally wallets may wish to display the contents of the certificate +to the user to check. + +##### Returns + +This returns a `SignedDRepRetirementCertificate` object which contains all the +details of the submitted retirement certificate, for the client to confirm. The +returned `txHash` can be used by the client to track the status of the +transaction containing the certificate on Cardano. + +#### `api.submitVote(votes: Vote[]): Promise[]` + +Errors: [APIError](#extended-apierror), [`TxSignError`](#extended-txsignerror) + +This endpoint requests the wallet to build, sign and submit transaction(s) +containing supplied data in the vote field as described in the +[ledger conway specification](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L79). +The wallet must create and attach a governance credential witness using the +secret side of the supplied public DRep key. Wallets using this API should +always fill in the the role field with DRep. + +The user's permission to sign this transaction must be requested for by the +wallet, additionally wallets should display the contents of the transaction +field to the user to confirm the data supplied by the client. + +##### Returns + +This returns an array of `SignedVote` objects, matching each `Vote` passed at +invocation. The returned `txHash` fields can be used by the client to track the +status of the submitted vote transactions. + +#### `api.submitGovernanceAction(action: GovernanceAction): Promise` + +Errors: [APIError](#extended-apierror), [`TxSignError`](#extended-txsignerror) + +This endpoint requests the wallet to build, sign and submit a transaction +containing supplied data in the governance action field as described in the +[ledger conway specification](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L94). + +Wallets should be responsible for handling the payment of deposit required with +the submission of this certificate. This is in accordance with the +`depositAmount` field. + +##### Returns + +This returns a `SignedGovernanceAction` object which contains all the details of +the submitted governance action submission, for the client to confirm. The +returned `txHash` can be used by the client to track the status of the +transaction on Cardano. + +### Examples of Flows + +#### Login + +1. **Connection:** User indicates to the client their intent to connect, causing + client offer a list of supported wallets, user selects their wallet causing + the client to invoke `.{wallet-name}.enable({ "cip": ?})` from the shared + cardano `namespace`. +2. **Wallet Confirmation:** The wallet indicates through its UI the clients + intent to connect, the user grants permission. +3. **Share Credentials:** The client invokes both `.getActiveStakeKeys()` and + `.getDRepKey()`, causing the connected wallet to share relevant credentials. +4. **Chain Lookup:** The client uses a chain indexer to work out the governance + state of the provided credentials. + +#### Vote Delegation + +Assume a "DRep Aggregator/Explorer" specialized client, who aggregates DRep +metadata from on-chain registration certificates to show to prospective +delegators. Assume that connection has already been made via +`.{wallet-name}.enable({ "cip": ?})`. + +1. **Choose DRep:** User browses DReps and selects one which align's with their + values and chooses which stake credential they wish to use for delegation. +2. **Construct Delegation:** The client passes the chosen DRep's ID and the + connected wallet's chosen stake key to the wallet in a + `api.submitDelegation()` call. +3. **Submit Delegation:** The wallet uses the provided details from the client + to construct a delegation certificate, the wallet confirms the contents of + the certificate with the user when asking for signature permission, wallet + submits transaction through it's infrastructure. +4. **Feedback to user:** The wallet returns a `SignedDelegationCertificate` and + the client uses the `txHash` to track the status of the transaction on-chain, + providing feedback to the user. + +#### DRep Registration + +Assume that connection has already been established via +`.{wallet-name}.enable({ "cip": ?})`. + +1. **User Indicates Intent:** User indicates to the client that they wish to + register as a DRep. The client asks the user to provide metadata anchor, this + is bundled with DRepID the client derives from the wallets DRepKey provided + via `.getDRepKey()`. This information is passed to the wallet via + `.submitDRepRegistration()`. +2. **Sign and Submit:** The wallet uses the data provided to generate a DRep + registration certificate, signing it with the matching key to the key hash + provided in the certificate. This is then submitted to chain and included in + a block. +3. **Feedback to user:** The wallet returns a + `SignedDRepRegistrationCertificate` and the client uses the `txHash` to track + the status of the transaction on-chain, providing feedback to the user. + +## Rationale: how does this CIP achieve its goals? + +The guiding principle for this design is to reduce the complexity for wallet +providers to implement. This is motivated by the necessity for users to be able +to interact with the age of Voltaire as soon as possible, keeping the wallet's +ask small should reduce implementation time. + +This design aims to make the tracking of a user's governance state an optional +endeavour for wallet providers. This is achieved by placing the responsibility +on clients to track a user's governance (CIP-1694) state, i.e. if a wallet user +is a DRep, what DRep a wallet holder has delegated to. + +Despite only defining the minimal set of endpoints required, we do not wish to +discourage the creation of subsequent CIPs which may support a wider range of +governance endpoints. Nor does this specification aim to discourage wallet +providers from fully integrating CIP-1694 governance, side-stepping the +necessity for clients (and this API). + +### Why Web-based Stacks + +Web-based stacks, with wallet connectivity, are a familiar place for users to be +able to interact with Cardano. These tools lower the technical bar to be able to +engage with the eco-system. Thus we believe encouraging further adoption of this +approach is beneficial. + +The primary alternative approach to this is wallet providers integrating this +functionality fully inside of wallet software, matching how staking is often +implemented. We deem this approach as preferable from a security standpoint for +combined functionality and would encourage wallet providers to pursue this. But +we understand that this may add overhead to wallet designs so offer this API as +an alternative. + +### Why these DReps and Ada Holders + +This proposal only caters to two types of actor described in CIP-1694; Ada +holders and DReps, this decision was three fold. Primarily this is to allow +these groups to utilize a client to participate in Cardano's governance. These +groups are likely less comfortable utilizing command-line interfaces than other +groups, thus making alternatives from them is a priority. Secondly, the other +types of actor (Constitution Committee member and SPOs) are identified by +different credentials than Ada holders and DReps. Thirdly, these groups +represent the majority of participants. These alternative credentials are +unlikely to be stored within standard wallet software which may interface with +this API. + +### Transaction Burden + +Endpoints defined here require wallets to generate, sign and submit transactions +to chain. The possible minimum ask for wallets is to just sign transactions this +is because signing keys should always remain within the wallet's control. This +alternative approach moves the complexity of transaction building and submission +onto client applications. + +The design outlined here aims to improve the security by placing the burden of +submission onto wallets. This prevents malicious clients from being able to +censor which transactions are submitted to chain. This is of particular concern +due to the potential political impact of transactions being handled by this API. +We thus deem it necessary for wallets to bare this burden. + +Furthermore by passing typescript interfaces to wallets rather than serialized +transactions we make inspection of transaction elements as easy as possible for +wallet's. This improves security as it avoids the need for wallets to +deserialize transactions to inspect their contents. + +#### The role of the wallet + +Relying on wallet's for transaction construction and submission has precedent +from the approach of +[CIP-62?](https://github.com/cardano-foundation/CIPs/pull/296). This abstracts +clients from the need to manage core wallet functionality such as UTxO handling. +This approach allows client developers to focus on their domain rather than +having to be involved in wallet function management. + +### Extension Design + +Whilst CIP-30 facilitated the launch of client development on Cardano, it's +functionality is limited in scope. Although it does offer generic functions, +these cannot satisfy the problem that this proposal tackles. Thus extending it's +functionality is a necessity. + +With this specification we chose to extend CIP-30's functionalities. There would +be two competing designs to this approach. One; move to have this specification +included within CIP-30. Two; deploy this specification as its own standalone +web-bridge. + +It would be undesirable to include this functionality within the base CIP-30 API +because it would force all clients and wallets supporting CIP-30 to support this +API. This is because not all client apps or wallet will have the need or desire +to support this specification thus forcing cooperation would not desirable. + +The reason we chose to not deploy this specification on its own is because it is +unlikely that clients implementing this API will not want to also use the +functionality offered by CIP-30. Additionally, CIP-30 offers a extensibility +mechanism meaning that the initial handshake connection is defined and thus wont +be needed to be defined within this specification. + +### DRep Key + +We chose to introduce the concept of a DRep Key, building on top of CIP-1694, +this we see as a necessary step for wallet implementors. By setting a +(hierarchical) deterministic derivation path it enables restorability from a +seed phrase. + +With this definition we aim to standard for tooling to be able to derive DRep +credentials from mnemonics, not only those wallets who support this web-bridge. +This standard brings all the benefits of the application of generic eco-system +standards. + +### Multi-stake Key Support + +Although +[multi-stake key wallets](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0018) +are not widely adopted across Cardano, we make an effort to support them here. +This is because a single stake key can delegate to a single DRep. By allowing +users to spread stake across multiple stake keys it allows different weighted +delegation to different DReps, this could be a very desirable feature. + +### Types of wallets + +This specification does not cater for wallets who manage non-key-based stake +credentials and those who wish to handle non-key-based DRep credentials. This +does limit the usefulness of this specification, but we believe the added +complexity of supporting these types of wallet. This means that we are likely +excluding tooling for DAOs from being supported through this standard. The +argument could be made that such entities generally prefer to use more advanced +wallet tooling which is not dependent on web-based stacks. + +### Backwards Compatibility + +This proposal should not effect the backwards compatibility of either clients or +wallet implementors. + +#### CIP-62? + +[CIP-62?](https://github.com/cardano-foundation/CIPs/pull/296) is another +extension to the CIP-30 API, this proposal is independent of this. This proposal +does not rely on any of the implementation defined in CIP-62?. We have attempted +to avoid any collisions of naming between these proposals, this was done to make +wallet implementations more straight forward for wallets implementing both APIs. + +### Open Questions + +- Is it necessary to provide a method to prove ownership of DRep key? and can + CIP-30's `api.signData()` be used to prove ownership of multi-stake keys? +- Is it sensible to place multi-stake key burden onto clients? +- Does supporting governance action submission a necessary burden for the scope + of this proposal? +- Should this proposal cater for non-key-based stake credential? +- Should there be a more elegant way for the optional sharing of governance + state? + +## Path to Active + +### Acceptance Criteria + +- [ ] Resolve all [open questions](#open-questions). +- [ ] The interface is implemented and supported by various wallet providers. +- [ ] The interface is used by clients to interact with wallet providers. + +### Implementation Plan + +- [ ] Provide a public Discord channel for open discussion of this + specification. +- [ ] Author to setup regular discussion forums to support wallet implementors. + +## Copyright + +This CIP is licensed under +[CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/legalcode). From 863d56778aa62e6d25f1fe6cf4849fbd8452eb8c Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Thu, 27 Apr 2023 21:55:17 +0100 Subject: [PATCH 02/35] Small formatting --- CIP-XXXX/CIP-XXXX.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CIP-XXXX/CIP-XXXX.md b/CIP-XXXX/CIP-XXXX.md index da630b8a9f..4d2bf1ca10 100644 --- a/CIP-XXXX/CIP-XXXX.md +++ b/CIP-XXXX/CIP-XXXX.md @@ -4,10 +4,10 @@ Title: Cardano dApp-Wallet Web Bridge Governance Extension Category: Wallets Status: Proposed Authors: - - Ryan Williams + - Ryan Williams Implementors: [] Discussions: - - https://github.com/cardano-foundation/cips/pulls/? + - https://github.com/cardano-foundation/cips/pulls/509 Created: 2022-02-24 License: CC-BY-4.0 --- @@ -21,7 +21,7 @@ that needs to be injected into web applications. These definitions extend [CIP-30 | Cardano dApp-Wallet Web Bridge](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030) to provide support for -[CIP-1694 | A First Step Towards On-Chain Decentralized Governance](https://github.com/cardano-foundation/CIPs/pull/380) +[CIP-1694? | A First Step Towards On-Chain Decentralized Governance](https://github.com/cardano-foundation/CIPs/pull/380) focussed web-based stacks. Here we aim to support the requirements of both Ada holders' and DReps' interactions with such web-based stacks. From 366fa90f507390f8fd74b4f22437621c3bdbe978 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Fri, 28 Apr 2023 21:13:10 +0100 Subject: [PATCH 03/35] Small formatting adds --- CIP-XXXX/CIP-XXXX.md | 59 +++++++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 20 deletions(-) diff --git a/CIP-XXXX/CIP-XXXX.md b/CIP-XXXX/CIP-XXXX.md index 4d2bf1ca10..c5da735696 100644 --- a/CIP-XXXX/CIP-XXXX.md +++ b/CIP-XXXX/CIP-XXXX.md @@ -8,6 +8,7 @@ Authors: Implementors: [] Discussions: - https://github.com/cardano-foundation/cips/pulls/509 + - https://discord.com/channels/826816523368005654/1101547251903504474/1101548279277309983 Created: 2022-02-24 License: CC-BY-4.0 --- @@ -26,7 +27,7 @@ focussed web-based stacks. Here we aim to support the requirements of both Ada holders' and DReps' interactions with such web-based stacks. > **Note** This proposal assumes knowledge of the ledger governance model as outlined within -> [CIP-1694](https://github.com/cardano-foundation/CIPs/pull/380). +> [CIP-1694?](https://github.com/cardano-foundation/CIPs/pull/380). ## Motivation: why is this CIP necessary? @@ -154,14 +155,12 @@ on-chain entities. > **Note** This specification is not concerned with how metadata hosted. -#### SignedDelegationCertificate +#### DelegationCertificate ```ts -interface SignedDelegationCertificate { +interface DelegationCertificate { target: DRepID | "Abstain" | "No Confidence"; stakeKey: PubStakeKey; - txHash: string; - witness: string; } ``` @@ -176,6 +175,21 @@ to chain and included within a block. then the name. - `stakeKey`: The public stake key acting as the stake credential of the Ada holder who has submitted the delegation. + +#### SignedDelegationCertificate + +```ts +interface SignedDelegationCertificate { + certificate: DelegationCertificate + txHash: string; + witness: string; +} +``` + +This interface represents a vote delegation certificate that has been submitted +to chain and included within a block. + +- `certificate`: Contains the `DRepRegistrationCertificate` object. - `txHash`: A string containing the hash of the transaction which contained this certificate that was submitted to chain and included in a block. This is to be used by clients to track the status of the delegation transaction on-chain. @@ -312,8 +326,7 @@ Interface representing a governance action to initiate a Hard-Fork, as described in [Conway ledger specification `hard_fork_initiation_action`](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L120). -- `protocolVer`: A number representing the new major protocol version which is - too hard-fork to. +- `protocolVer`: A number representing the new major protocol version too hard-fork to. ##### UpdateParameters @@ -565,12 +578,12 @@ for the case of An array of the connected user's active stake keys. -#### `api.submitDelegation(DRep: DRepID, stakeKey: PubStakeKey): Promise` +#### `api.submitDelegation(DelegationCertificate[]): Promise` Errors: [APIError](#extended-apierror), [`TxSignError`](#extended-txsignerror) -This endpoint requests the wallet to build, sign and submit a vote delegation -certificate for a supplied DRepID and Public Stake Key. This certificate is +This endpoint requests the wallet to build, sign and submit vote delegation +certificates for a supplied DRepID and public stake key. These certificates are described **todo: add CDDL when available**. This must be signed by the secret key of the provided public stake key. @@ -578,17 +591,19 @@ By allowing clients to supply the stake key we are placing the burden of multi-governance-delegation management onto the client, reducing the complexity for wallet implementations. -The user's permission to sign this transaction must be requested by the wallet, +The user's permission to sign must be requested by the wallet, additionally wallets may wish to display the contents of the certificate to the user to check. This allows for the user to catch malicious clients attempting to -alter the certificate's contents. +alter the certificate's contents. It is up to the wallet to decide if user permission's is required for each signature or one permission granted to sign all. + +One `TxSignError` should be returned if there is a signature error with any of the certificates. ##### Returns -This returns a `SignedDelegationCertificate` object which contains all the +This returns an array of `SignedDelegationCertificate` objects which contains all the details of the submitted delegation certificate, for the client to confirm. The -returned `txHash` can be used by the client to track the status of the -transaction containing the certificate on Cardano. +returned `txHash`s can be used by the client to track the status of the +transactions containing the certificates on Cardano. #### `api.submitDRepRegistration(certificate: DRepRegistrationCertificate): Promise` @@ -644,9 +659,12 @@ The wallet must create and attach a governance credential witness using the secret side of the supplied public DRep key. Wallets using this API should always fill in the the role field with DRep. -The user's permission to sign this transaction must be requested for by the -wallet, additionally wallets should display the contents of the transaction -field to the user to confirm the data supplied by the client. +The user's permission to sign must be requested by the wallet, +additionally wallets should display the contents of the vote transaction to the +user to check. This allows for the user to catch malicious clients attempting to +alter the vote's contents. It is up to the wallet to decide if user permission's is required for each signature or one permission granted to sign all. + +One `TxSignError` should be returned if there is a signature error with any of the transactions. ##### Returns @@ -792,7 +810,7 @@ deserialize transactions to inspect their contents. #### The role of the wallet -Relying on wallet's for transaction construction and submission has precedent +Relying on wallets for transaction construction and submission has precedent from the approach of [CIP-62?](https://github.com/cardano-foundation/CIPs/pull/296). This abstracts clients from the need to manage core wallet functionality such as UTxO handling. @@ -887,8 +905,9 @@ wallet implementations more straight forward for wallets implementing both APIs. ### Implementation Plan -- [ ] Provide a public Discord channel for open discussion of this +- [x] Provide a public Discord channel for open discussion of this specification. + - See [`gov-wallet-cip`](https://discord.com/channels/826816523368005654/1101547251903504474/1101548279277309983) channel in the [IOG Technical Discord](https://discord.gg/inputoutput) under the `🥑BUILD` section (to view you have to opt-in to the Builders group). - [ ] Author to setup regular discussion forums to support wallet implementors. ## Copyright From 288eae962db4b76911d036e9fbf539a1bcea091c Mon Sep 17 00:00:00 2001 From: Ryan Williams <44342099+Ryun1@users.noreply.github.com> Date: Mon, 1 May 2023 20:45:13 +0100 Subject: [PATCH 04/35] Update CIP-XXXX/CIP-XXXX.md Co-authored-by: Robert Phair --- CIP-XXXX/CIP-XXXX.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIP-XXXX/CIP-XXXX.md b/CIP-XXXX/CIP-XXXX.md index c5da735696..e060a051d3 100644 --- a/CIP-XXXX/CIP-XXXX.md +++ b/CIP-XXXX/CIP-XXXX.md @@ -849,7 +849,7 @@ seed phrase. With this definition we aim to standard for tooling to be able to derive DRep credentials from mnemonics, not only those wallets who support this web-bridge. -This standard brings all the benefits of the application of generic eco-system +This standard brings all the benefits of the application of generic ecosystem standards. ### Multi-stake Key Support From 2354f7ad8839c4cae0eb398a8c088af9b66bf900 Mon Sep 17 00:00:00 2001 From: Ryan Williams <44342099+Ryun1@users.noreply.github.com> Date: Mon, 1 May 2023 20:45:20 +0100 Subject: [PATCH 05/35] Update CIP-XXXX/CIP-XXXX.md Co-authored-by: Robert Phair --- CIP-XXXX/CIP-XXXX.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIP-XXXX/CIP-XXXX.md b/CIP-XXXX/CIP-XXXX.md index e060a051d3..e1b205cd94 100644 --- a/CIP-XXXX/CIP-XXXX.md +++ b/CIP-XXXX/CIP-XXXX.md @@ -32,7 +32,7 @@ holders' and DReps' interactions with such web-based stacks. ## Motivation: why is this CIP necessary? CIP-1694 introduces many new concepts, entities and actors to Cardano; -describing their implementation at the ledger level. Yet, for most eco-system +describing their implementation at the ledger level. Yet, for most ecosystem participants low level details are abstracted away by tools, such as wallets. This creates a need for tooling to be able support the utilization of ledger features. This specification allows for creation of web-based tools for the From 3ac58162569d216347df6c649ebc5b5e6cebb022 Mon Sep 17 00:00:00 2001 From: Ryan Williams <44342099+Ryun1@users.noreply.github.com> Date: Mon, 1 May 2023 20:45:29 +0100 Subject: [PATCH 06/35] Update CIP-XXXX/CIP-XXXX.md Co-authored-by: Robert Phair --- CIP-XXXX/CIP-XXXX.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIP-XXXX/CIP-XXXX.md b/CIP-XXXX/CIP-XXXX.md index e1b205cd94..ca4120e15d 100644 --- a/CIP-XXXX/CIP-XXXX.md +++ b/CIP-XXXX/CIP-XXXX.md @@ -766,7 +766,7 @@ necessity for clients (and this API). Web-based stacks, with wallet connectivity, are a familiar place for users to be able to interact with Cardano. These tools lower the technical bar to be able to -engage with the eco-system. Thus we believe encouraging further adoption of this +engage with the ecosystem. Thus we believe encouraging further adoption of this approach is beneficial. The primary alternative approach to this is wallet providers integrating this From 65e34ef65214752adfaf9ac31d67b77297191184 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Mon, 1 May 2023 21:14:55 +0100 Subject: [PATCH 07/35] added Bech32 prefixes to CIP-0005 --- CIP-0005/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CIP-0005/README.md b/CIP-0005/README.md index b900a97a91..47c21a266a 100644 --- a/CIP-0005/README.md +++ b/CIP-0005/README.md @@ -51,6 +51,8 @@ We define the following set of common prefixes with their corresponding semantic | `addr_shared_vk` | CIP-1854's address verification key | Ed25519 public key | | `addr_shared_xsk` | CIP-1854's address extended signing key | Ed25519-bip32 extended private key | | `addr_shared_xvk` | CIP-1854's address extended verification key | Ed25519 public key with chain code | +| `drep_sk` | CIP-????'s DRep vote signing key | Ed25519 private key | +| `drep_vk` | CIP-????'s DRep vote verification key | Ed25519 public key | | `gov_sk` | Governance vote signing key | Ed25519 private key | | `gov_vk` | Governance vote verification key | Ed25519 public key | | `cvote_sk` | CIP-36's vote signing key | Ed25519 private key | From 3c86c31206c7663e92bfffa62043fa726dd400b0 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Thu, 4 May 2023 10:10:44 +0100 Subject: [PATCH 08/35] Add open Qs from CIP editors + small formatting --- CIP-XXXX/CIP-XXXX.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/CIP-XXXX/CIP-XXXX.md b/CIP-XXXX/CIP-XXXX.md index ca4120e15d..ddac0fec4a 100644 --- a/CIP-XXXX/CIP-XXXX.md +++ b/CIP-XXXX/CIP-XXXX.md @@ -246,7 +246,7 @@ interface DRepRetirementCertificate { } ``` -This data structure is used to represent a DRep Retirement Certificate as +This data structure is used to represent a DRep retirement certificate as described in [CIP-1698 Delegated Representatives](https://github.com/JaredCorduan/CIPs/blob/voltaire-v1/CIP-1694/README.md#delegated-representatives-DReps). //todo: link CDDL @@ -266,8 +266,8 @@ interface SignedDRepRetirementCertificate { } ``` -This is returned from the wallet back to the client once a DRep Retirement -Certificate is submitted to chain and included in a block. +This is returned from the wallet back to the client once a DRep retirement +certificate is submitted to chain and included in a block. - `certificate`: Contains the `DRepRetirementCertificate` object. - `txHash`: A string containing the hash of the transaction which contained this @@ -886,6 +886,8 @@ wallet implementations more straight forward for wallets implementing both APIs. ### Open Questions +- The burden of transaction building to be placed on dApps or wallets? +- Move DRep key to CIP-1852? - Is it necessary to provide a method to prove ownership of DRep key? and can CIP-30's `api.signData()` be used to prove ownership of multi-stake keys? - Is it sensible to place multi-stake key burden onto clients? From 568272ff53b4e3188bbe3db1b6c7a36a1c8bf582 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Mon, 15 May 2023 16:24:43 +0100 Subject: [PATCH 09/35] aligned with CIP-95 namining --- CIP-XXXX/CIP-XXXX.md => CIP-0095/README.md | 108 ++++++++++++--------- 1 file changed, 60 insertions(+), 48 deletions(-) rename CIP-XXXX/CIP-XXXX.md => CIP-0095/README.md (90%) diff --git a/CIP-XXXX/CIP-XXXX.md b/CIP-0095/README.md similarity index 90% rename from CIP-XXXX/CIP-XXXX.md rename to CIP-0095/README.md index ddac0fec4a..b4e852202e 100644 --- a/CIP-XXXX/CIP-XXXX.md +++ b/CIP-0095/README.md @@ -1,5 +1,5 @@ --- -CIP: ? +CIP: 95 Title: Cardano dApp-Wallet Web Bridge Governance Extension Category: Wallets Status: Proposed @@ -26,7 +26,8 @@ to provide support for focussed web-based stacks. Here we aim to support the requirements of both Ada holders' and DReps' interactions with such web-based stacks. -> **Note** This proposal assumes knowledge of the ledger governance model as outlined within +> **Note** This proposal assumes knowledge of the ledger governance model as +> outlined within > [CIP-1694?](https://github.com/cardano-foundation/CIPs/pull/380). ## Motivation: why is this CIP necessary? @@ -83,27 +84,28 @@ We believe the overhead that would be introduced by "multi-DRep" accounts is an unjustified expense. Future iterations of this specification may expand on this, but at present this is seen as unnecessary. -> **Note** `1718` was the year that François-Marie adopted the pseudonym Voltaire. +> **Note** `1718` was the year that François-Marie adopted the pseudonym +> Voltaire. #### Tooling -Supporting tooling should clearly label these key pairs as "CIP-???? DRep Keys". +Supporting tooling should clearly label these key pairs as "CIP-95 DRep Keys". Bech32 prefixes of `drep_sk` and `drep_vk` should be used. Examples of acceptable `keyType`s for supporting tools: -| `keyType` | Description | -| ------------------------------------ | --------------------- | -| `CIP????DRepSigningKey_ed25519` | DRep Signing Key | -| `CIP????DRepVerificationKey_ed25519` | DRep Verification Key | +| `keyType` | Description | +| ---------------------------------- | --------------------- | +| `CIP95DRepSigningKey_ed25519` | DRep Signing Key | +| `CIP95DRepVerificationKey_ed25519` | DRep Verification Key | -For hardware implementations: +For hardware implementations: -| `keyType` | Description | -| ------------------------------------ | ------------------------------ | -| `CIP????DRepVerificationKey_ed25519` | Hardware DRep Verification Key | | -| `CIP????DRepHWSigningFile_ed25519` | Hardware DRep Signing File | +| `keyType` | Description | +| ---------------------------------- | ------------------------------ | +| `CIP95DRepVerificationKey_ed25519` | Hardware DRep Verification Key | +| `CIP95DRepHWSigningFile_ed25519` | Hardware DRep Signing File | ### Data Types @@ -180,7 +182,7 @@ to chain and included within a block. ```ts interface SignedDelegationCertificate { - certificate: DelegationCertificate + certificate: DelegationCertificate; txHash: string; witness: string; } @@ -326,7 +328,8 @@ Interface representing a governance action to initiate a Hard-Fork, as described in [Conway ledger specification `hard_fork_initiation_action`](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L120). -- `protocolVer`: A number representing the new major protocol version too hard-fork to. +- `protocolVer`: A number representing the new major protocol version too + hard-fork to. ##### UpdateParameters @@ -583,7 +586,7 @@ An array of the connected user's active stake keys. Errors: [APIError](#extended-apierror), [`TxSignError`](#extended-txsignerror) This endpoint requests the wallet to build, sign and submit vote delegation -certificates for a supplied DRepID and public stake key. These certificates are +certificates for a supplied DRepID and public stake key. These certificates are described **todo: add CDDL when available**. This must be signed by the secret key of the provided public stake key. @@ -591,19 +594,22 @@ By allowing clients to supply the stake key we are placing the burden of multi-governance-delegation management onto the client, reducing the complexity for wallet implementations. -The user's permission to sign must be requested by the wallet, -additionally wallets may wish to display the contents of the certificate to the -user to check. This allows for the user to catch malicious clients attempting to -alter the certificate's contents. It is up to the wallet to decide if user permission's is required for each signature or one permission granted to sign all. +The user's permission to sign must be requested by the wallet, additionally +wallets may wish to display the contents of the certificate to the user to +check. This allows for the user to catch malicious clients attempting to alter +the certificate's contents. It is up to the wallet to decide if user +permission's is required for each signature or one permission granted to sign +all. -One `TxSignError` should be returned if there is a signature error with any of the certificates. +One `TxSignError` should be returned if there is a signature error with any of +the certificates. ##### Returns -This returns an array of `SignedDelegationCertificate` objects which contains all the -details of the submitted delegation certificate, for the client to confirm. The -returned `txHash`s can be used by the client to track the status of the -transactions containing the certificates on Cardano. +This returns an array of `SignedDelegationCertificate` objects which contains +all the details of the submitted delegation certificate, for the client to +confirm. The returned `txHash`s can be used by the client to track the status of +the transactions containing the certificates on Cardano. #### `api.submitDRepRegistration(certificate: DRepRegistrationCertificate): Promise` @@ -659,12 +665,14 @@ The wallet must create and attach a governance credential witness using the secret side of the supplied public DRep key. Wallets using this API should always fill in the the role field with DRep. -The user's permission to sign must be requested by the wallet, -additionally wallets should display the contents of the vote transaction to the -user to check. This allows for the user to catch malicious clients attempting to -alter the vote's contents. It is up to the wallet to decide if user permission's is required for each signature or one permission granted to sign all. +The user's permission to sign must be requested by the wallet, additionally +wallets should display the contents of the vote transaction to the user to +check. This allows for the user to catch malicious clients attempting to alter +the vote's contents. It is up to the wallet to decide if user permission's is +required for each signature or one permission granted to sign all. -One `TxSignError` should be returned if there is a signature error with any of the transactions. +One `TxSignError` should be returned if there is a signature error with any of +the transactions. ##### Returns @@ -746,27 +754,27 @@ Assume that connection has already been established via ## Rationale: how does this CIP achieve its goals? -The guiding principle for this design is to reduce the complexity for wallet -providers to implement. This is motivated by the necessity for users to be able -to interact with the age of Voltaire as soon as possible, keeping the wallet's -ask small should reduce implementation time. +The principle aim for this design is to reduce the complexity for wallet +implementors. This is motivated by the necessity for users to be able to +interact with the age of Voltaire promptly, by keeping the wallet's providers +ask small we aim to reduce implementation time. This design aims to make the tracking of a user's governance state an optional endeavour for wallet providers. This is achieved by placing the responsibility -on clients to track a user's governance (CIP-1694) state, i.e. if a wallet user -is a DRep, what DRep a wallet holder has delegated to. +on clients to track a user's governance state, i.e. if a wallet user is a DRep, +what DRep a wallet holder has delegated to, etc. Despite only defining the minimal set of endpoints required, we do not wish to -discourage the creation of subsequent CIPs which may support a wider range of -governance endpoints. Nor does this specification aim to discourage wallet -providers from fully integrating CIP-1694 governance, side-stepping the -necessity for clients (and this API). +discourage the creation of subsequent CIPs with a wider range of governance +functionality. Nor does this specification aim to discourage wallet providers +from fully integrating CIP-1694 governance, side-stepping the necessity for this +API and client applications. ### Why Web-based Stacks Web-based stacks, with wallet connectivity, are a familiar place for users to be -able to interact with Cardano. These tools lower the technical bar to be able to -engage with the ecosystem. Thus we believe encouraging further adoption of this +able to interact with Cardano. These tools lower the technical bar to engage +with the ecosystem. Thus we believe encouraging further adoption of this approach is beneficial. The primary alternative approach to this is wallet providers integrating this @@ -878,11 +886,12 @@ wallet implementors. #### CIP-62? -[CIP-62?](https://github.com/cardano-foundation/CIPs/pull/296) is another -extension to the CIP-30 API, this proposal is independent of this. This proposal -does not rely on any of the implementation defined in CIP-62?. We have attempted -to avoid any collisions of naming between these proposals, this was done to make -wallet implementations more straight forward for wallets implementing both APIs. +[CIP-62? | Cardano dApp-Wallet Web Bridge Catalyst Extension](https://github.com/cardano-foundation/CIPs/pull/296) +is another extension to the CIP-30 API, this proposal is independent of this. +This specification does not rely on any of the implementation defined in +CIP-62?. We have attempted to avoid any collisions of naming between these +proposals, this was done to make wallet implementations more straight forward +for wallets implementing both APIs. ### Open Questions @@ -909,7 +918,10 @@ wallet implementations more straight forward for wallets implementing both APIs. - [x] Provide a public Discord channel for open discussion of this specification. - - See [`gov-wallet-cip`](https://discord.com/channels/826816523368005654/1101547251903504474/1101548279277309983) channel in the [IOG Technical Discord](https://discord.gg/inputoutput) under the `🥑BUILD` section (to view you have to opt-in to the Builders group). + - See + [`gov-wallet-cip`](https://discord.com/channels/826816523368005654/1101547251903504474/1101548279277309983) + channel in the [IOG Technical Discord](https://discord.gg/inputoutput) under + the `🥑BUILD` section (to view you have to opt-in to the Builders group). - [ ] Author to setup regular discussion forums to support wallet implementors. ## Copyright From 80424e5aff58559d89f343603450776fc25ff978 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Fri, 26 May 2023 17:47:30 +0100 Subject: [PATCH 10/35] Added open q and fixed prefixes --- CIP-0005/README.md | 4 ++-- CIP-0095/README.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CIP-0005/README.md b/CIP-0005/README.md index 47c21a266a..f2df752949 100644 --- a/CIP-0005/README.md +++ b/CIP-0005/README.md @@ -51,8 +51,8 @@ We define the following set of common prefixes with their corresponding semantic | `addr_shared_vk` | CIP-1854's address verification key | Ed25519 public key | | `addr_shared_xsk` | CIP-1854's address extended signing key | Ed25519-bip32 extended private key | | `addr_shared_xvk` | CIP-1854's address extended verification key | Ed25519 public key with chain code | -| `drep_sk` | CIP-????'s DRep vote signing key | Ed25519 private key | -| `drep_vk` | CIP-????'s DRep vote verification key | Ed25519 public key | +| `drep_sk` | CIP-0095's DRep vote signing key | Ed25519 private key | +| `drep_vk` | CIP-0095's DRep vote verification key | Ed25519 public key | | `gov_sk` | Governance vote signing key | Ed25519 private key | | `gov_vk` | Governance vote verification key | Ed25519 public key | | `cvote_sk` | CIP-36's vote signing key | Ed25519 private key | diff --git a/CIP-0095/README.md b/CIP-0095/README.md index b4e852202e..129a76abce 100644 --- a/CIP-0095/README.md +++ b/CIP-0095/README.md @@ -896,7 +896,7 @@ for wallets implementing both APIs. ### Open Questions - The burden of transaction building to be placed on dApps or wallets? -- Move DRep key to CIP-1852? +- Move DRep key definitions into a CIP which is dedicated to describing CIP-1694 related credentials? - Is it necessary to provide a method to prove ownership of DRep key? and can CIP-30's `api.signData()` be used to prove ownership of multi-stake keys? - Is it sensible to place multi-stake key burden onto clients? From c481a50913ef289f2e9ad201babf581698d3d555 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Thu, 8 Jun 2023 16:01:24 +0100 Subject: [PATCH 11/35] moved transaction building to the application --- CIP-0095/README.md | 582 ++++++++++++--------------------------------- 1 file changed, 149 insertions(+), 433 deletions(-) diff --git a/CIP-0095/README.md b/CIP-0095/README.md index 129a76abce..9dfdb8047a 100644 --- a/CIP-0095/README.md +++ b/CIP-0095/README.md @@ -4,11 +4,11 @@ Title: Cardano dApp-Wallet Web Bridge Governance Extension Category: Wallets Status: Proposed Authors: - - Ryan Williams + - Ryan Williams Implementors: [] Discussions: - - https://github.com/cardano-foundation/cips/pulls/509 - - https://discord.com/channels/826816523368005654/1101547251903504474/1101548279277309983 + - https://github.com/cardano-foundation/cips/pulls/509 + - https://discord.com/channels/826816523368005654/1101547251903504474/1101548279277309983 Created: 2022-02-24 License: CC-BY-4.0 --- @@ -50,6 +50,9 @@ CIP-1694's governance design. We define the following specification as an extension to the specification described within CIP-30. +- todo: explain + [extension](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030#extension) + > **Note** This specification will evolve as the proposed ledger governance > model matures. It is likely the precise data structures outlined here will be > need to be adjusted. @@ -76,6 +79,9 @@ must follow: `m / 1718' / 1815' / account' / chain / address_index` +> **Note** `1718` was the year that François-Marie adopted the pseudonym +> Voltaire. + We strongly suggest that a maximum of one set of DRep credentials should be associated with one wallet account, this can be achieved by setting `chain=0` and `address_index=0`. Thus avoiding the need for DRep Key discovery. @@ -84,14 +90,12 @@ We believe the overhead that would be introduced by "multi-DRep" accounts is an unjustified expense. Future iterations of this specification may expand on this, but at present this is seen as unnecessary. -> **Note** `1718` was the year that François-Marie adopted the pseudonym -> Voltaire. - #### Tooling Supporting tooling should clearly label these key pairs as "CIP-95 DRep Keys". -Bech32 prefixes of `drep_sk` and `drep_vk` should be used. +Bech32 prefixes of `drep_sk` and `drep_vk` should be used, as described in +[CIP-0005](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0005/README.md). Examples of acceptable `keyType`s for supporting tools: @@ -104,7 +108,7 @@ For hardware implementations: | `keyType` | Description | | ---------------------------------- | ------------------------------ | -| `CIP95DRepVerificationKey_ed25519` | Hardware DRep Verification Key | +| `CIP95DRepVerificationKey_ed25519` | Hardware DRep Verification Key | | `CIP95DRepHWSigningFile_ed25519` | Hardware DRep Signing File | ### Data Types @@ -137,353 +141,29 @@ type PubStakeKey = string; A hex string representing 32 byte Ed25519 public key used as a staking credential. -#### MetadataAnchor - -```ts -interface MetadataAnchor { - metadataURL: string; - metadataHash: string; -} -``` - -This interface represents a metadata anchor which can be related to particular -on-chain entities. - -- `metadataURL`: A string containing the URL-to-plaintext version of the - metadata. -- `metadataHash`: A string containing a Blake2b-256 hash of the metadata - plaintext, which is stored at the metadataURL. This hash allows clients to - verify the correctness of data presented at metadataURL. - -> **Note** This specification is not concerned with how metadata hosted. - -#### DelegationCertificate - -```ts -interface DelegationCertificate { - target: DRepID | "Abstain" | "No Confidence"; - stakeKey: PubStakeKey; -} -``` - -This interface represents a vote delegation certificate that has been submitted -to chain and included within a block. +#### Tx TODO -- `target`: The target of the delegation, DRep ID provided if the delegation was - to a - [registered DRep](https://github.com/JaredCorduan/CIPs/blob/voltaire-v1/CIP-1694/README.md#registered-dreps). - If delegating to a - [pre-defined DRep](https://github.com/JaredCorduan/CIPs/blob/voltaire-v1/CIP-1694/README.md#pre-defined-dreps) - then the name. -- `stakeKey`: The public stake key acting as the stake credential of the Ada - holder who has submitted the delegation. +unsigned, unwitnessed Tx containing a -#### SignedDelegationCertificate +#### SubmittedTransaction ```ts -interface SignedDelegationCertificate { - certificate: DelegationCertificate; +interface SubmittedTransaction { + tx: ; txHash: string; witness: string; } ``` -This interface represents a vote delegation certificate that has been submitted -to chain and included within a block. +This interface represents a -- `certificate`: Contains the `DRepRegistrationCertificate` object. +- `tx`: - `txHash`: A string containing the hash of the transaction which contained this certificate that was submitted to chain and included in a block. This is to be used by clients to track the status of the delegation transaction on-chain. - `witness`: A string containing the stake credential witness attached to the certificate. -#### DRepRegistrationCertificate - -```ts -interface DRepRegistrationCertificate { - dRepKey: PubDRepKey; - metadataAnchor?: MetadataAnchor; - depositAmount?: number; - // reward address for deposit return TBC -} -``` - -This interface represents a DRep registration certificate as described in -[CIP-1698 Delegated Representatives](https://github.com/JaredCorduan/CIPs/blob/voltaire-v1/CIP-1694/README.md#delegated-representatives-DReps). -//todo: link CDDL - -- `dRepKey`: The public side of the DRep Key pair used for witnessing the - certificate and to be hashed to provide DRep ID. -- `metadataAnchor`: Optionally allows the linking of off-chain metadata. -- `depositAmount`: Optionally supplied by the client, if the user is registering - for the first time a deposit amount is supplied. - -#### SignedDRepRegistrationCertificate - -```ts -interface SignedDRepRegistrationCertificate { - certificate: DRepRegistrationCertificate; - txHash: string; - witness: string; -} -``` - -This is returned from the wallet back to the client once a DRep registration -certificate is submitted to chain and included in a block. - -- `certificate`: Contains the `DRepRegistrationCertificate` object. -- `txHash`: A string containing the hash of the transaction which contained this - certificate that was submitted to chain and included in a block. This is to be - used by dApps to track the status of the transaction on-chain. -- `witness`: A string containing the DRep credential witness attached to the - certificate. - -#### DRepRetirementCertificate - -```ts -interface DRepRetirementCertificate { - dRepKey: PubDRepKey; - expirationEpoch: number; -} -``` - -This data structure is used to represent a DRep retirement certificate as -described in -[CIP-1698 Delegated Representatives](https://github.com/JaredCorduan/CIPs/blob/voltaire-v1/CIP-1694/README.md#delegated-representatives-DReps). -//todo: link CDDL - -- `dRepKey`: The public side of the DRep Key pair used for witnessing the - certificate and to be hashed to obtain the required DRep ID. -- `expirationEpoch`: An integer representing the Cardano epoch number after - which the DRep will retire. - -#### SignedDRepRetirementCertificate - -```ts -interface SignedDRepRetirementCertificate { - certificate: DRepRetirementCertificate; - txHash: String; - witness: string; -} -``` - -This is returned from the wallet back to the client once a DRep retirement -certificate is submitted to chain and included in a block. - -- `certificate`: Contains the `DRepRetirementCertificate` object. -- `txHash`: A string containing the hash of the transaction which contained this - certificate that was submitted to chain and included in a block. This is to be - used by clients to track the status of the transaction on-chain. -- `witness`: A string containing the dRep credential witness attached to the - certificate. - -#### Governance Action Types - -Here we outline interfaces for each governance action which need to support -additional data to the ledger - -##### NewCommittee - -```ts -interface NewCommittee { - keyHashes: string[]; - quorum: number; -} -``` - -Interface representing a governance action to introduce a new committee/quorum, -as described in -[Conway ledger specification `new_commitee`](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L126). - -- `keyHashes`: A string list representing the 28-byte Blake2b-224 hash digests - of the new committee's keys. -- `committeeSize`: A number representing the needed quorum for the new - committee. - -##### UpdateConstitution - -```ts -interface UpdateConstitution { - constitutionHash: string; -} -``` - -Interface representing a governance action to update the Cardano Constitution -document, as described in -[Conway ledger specification `new_constitution`](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L128). - -- `constitutionHash`: A string containing the 32-byte Blake2b-256 hash digest of - the new constitution document. - -##### HardForkInit - -```ts -interface HardForkInit { - protocolVer: number; -} -``` - -Interface representing a governance action to initiate a Hard-Fork, as described -in -[Conway ledger specification `hard_fork_initiation_action`](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L120). - -- `protocolVer`: A number representing the new major protocol version too - hard-fork to. - -##### UpdateParameters - -```ts -interface UpdateParameters { - params: { - key: string; - newValue: number; - }[]; -} -``` - -// todo: make a better representation for this Interface representing a -governance action to update values of protocol parameters, as described in -[Conway ledger specification `parameter_change_action`](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L118). - -- `params`: An array of objects representing the parameters to be adjusted and - their new values. -- `key`: The protocol parameter to be adjusted. -- `newValue`: A string array of each parameters new value. - -##### TreasuryWithdrawal - -```ts -interface TreasuryWithdrawal { - mappings: { - recipient: string; - amount: number; - }[]; -} -``` - -Interface representing a governance action to withdraw funds from the Cardano -treasury, as described in -[Conway ledger specification `treasury_withdrawals_action`](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L122). - -- `mappings`: An array of objects representing reward addresses and amounts in - Ada. -- `recipient`: A string representing a reward account address. -- `amount`: A number representing the amount of Lovelace to send to the - corresponding recipient. - -#### GovernanceActionID - -```ts -interface GovernanceActionID { - transactionID: string; - govActionIndex: number; -} -``` - -Interface representing a governance action ID, as described in -[Conway ledger specification `governance_action_id`](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L145). - -- `transactionID`: A 32-byte Blake2b-256 hash digest of the transaction - containing the governance action. -- `govActionIndex`: The index within the transaction body pointing to the - governance action. - -#### GovernanceAction - -```ts -interface GovernanceAction { - actionType: - | "MotionOfNoConfidence" // no payload - | NewCommittee - | UpdateConstitution - | HardForkInit - | UpdateParameters - | TreasuryWithdrawal - | "Info"; // no payload - lastAction: GovernanceActionID; - depositAmount: number; - rewardAddress: string; - metadataAnchor: MetadataAnchor; -} -``` - -Interface representing a governance action proposal to be submitted in a -transaction, to chain, as described in -[Conway ledger specification `proposal_procedure`](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#97). - -- `actionType`: The governance action type, with needed additional payload data. -- `lastAction`: A `GovernanceActionID` object identifying the preceding - governance action of this type. -- `depositAmount`: A number representing the number of Lovelace deposited for - this action. -- `rewardAddress`: A string containing the address where the deposit will be - returned to. -- `metadataAnchor`: Used to allow the linking of off-chain metadata. - -#### SignedGovernanceAction - -```ts -interface SignedGovernanceAction { - action: GovernanceAction; - governanceActionID: GovernanceActionID; -} -``` - -Interface representing a governance action which has been successfully submitted -to chain and included in a block. - -- `action`: Contains the submitted `GovernanceAction` object. -- `governanceActionID`: A `GovernanceActionID` object representing the ID of the - submitted governance action. - -> **Note** Unlike other 'signed' data structures we omit a witness field, this -> is because verification from client applications is not necessary. - -#### Vote - -```ts -interface Vote { - DRepKey: PubDRepKey; - governanceActionID: GovernanceActionID; - choice: "Yes" | "No" | "Abstain"; - metadataAnchor?: MetadataAnchor; -} -``` - -An interface used to represent an unsigned vote transaction, as described in -[Conway ledger specification `voting_procedure`](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#89). - -- `DRepKey`: The public side of the DRep Key pair used for witnessing the vote. -- `governanceActionID`: A `GovernanceActionID` object representing the target - governance action for this vote. -- `choice`: A string representing the user's choice for the governance action - vote, must be either 'Yes', 'No' or 'Abstain'. -- `metadataAnchor`: Optionally used to allow the linking of off-chain metadata - in a way to ensure correctness. - -> **Note** This interface does not map directly to the -> [Conway ledger specification `voting_procedure`](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L79), -> this is because this specification only caters for DRep role. - -#### SignedVote - -```ts -interface SignedVote { - vote: Vote; - txHash: string; - witness: string; -} -``` - -Interface representing a vote transaction which has been successfully submitted -to chain and included in a block. - -- `vote`: Contains the `Vote` object representing the submitted vote. -- `txHash`: A string containing the hash of the transaction which contained this - submitted vote. -- `witness`: The governance credential witness for this vote. - ### Error Types This specification inherits all Error Types defined in CIP-30. @@ -581,123 +261,163 @@ for the case of An array of the connected user's active stake keys. -#### `api.submitDelegation(DelegationCertificate[]): Promise` +#### `api.submitVoteDelegation(delegations: [tx, pubStakeKey]): Promise` Errors: [APIError](#extended-apierror), [`TxSignError`](#extended-txsignerror) -This endpoint requests the wallet to build, sign and submit vote delegation -certificates for a supplied DRepID and public stake key. These certificates are -described **todo: add CDDL when available**. This must be signed by the secret -key of the provided public stake key. +This endpoint requests the wallet to inspect, sign and submit transaction(s) +containing vote delegation certificates. The wallet should articulate this +request from client application in a explicit and highly informative way. Users +must be shown the target of the delegation (DRepID or a predefined DRep +identifier) and must be informed which of their stake keys are being used. For +the case of multiple delegations at once, the user may only be asked for +permission to authorize all at once, but this can depend on wallet's +implementation. + +If user grants permission, each transaction must be signed by the secret key of +the provided public stake key, with the signature and key to be added to the +transaction witness set before submission. By allowing clients to supply the stake key we are placing the burden of -multi-governance-delegation management onto the client, reducing the complexity -for wallet implementations. +"multi-governance-delegation" management onto the client, reducing the +complexity for wallet implementations. By forcing wallets to inspect these +certificates it allows the user to catch malicious client applications +attempting to insert their own delegation targets. -The user's permission to sign must be requested by the wallet, additionally -wallets may wish to display the contents of the certificate to the user to -check. This allows for the user to catch malicious clients attempting to alter -the certificate's contents. It is up to the wallet to decide if user -permission's is required for each signature or one permission granted to sign -all. +##### Errors One `TxSignError` should be returned if there is a signature error with any of the certificates. ##### Returns -This returns an array of `SignedDelegationCertificate` objects which contains -all the details of the submitted delegation certificate, for the client to -confirm. The returned `txHash`s can be used by the client to track the status of -the transactions containing the certificates on Cardano. +This returns an array of `SubmittedTransaction` objects which contain the +details of the submitted delegation certificates, for the client to confirm. The +returned `txHash`s can be used by the client to track the status of the +transactions containing the certificates on Cardano. -#### `api.submitDRepRegistration(certificate: DRepRegistrationCertificate): Promise` +#### `api.submitDRepRegistration(tx, pubDRepKey): Promise` Errors: [APIError](#extended-apierror), [`TxSignError`](#extended-txsignerror) -This endpoint requests the wallet to build, sign and submit a DRep registration -certificate as described **todo: add CDDL when available**. The wallet must sign -the certificate using the secret side of the supplied DRep public key presented -in the `DRepKey` field. +This endpoint requests the wallet to inspect, sign and submit a transaction +containing a DRep registration certificate. The wallet should articulate this +request from client application in a explicit and highly informative way. Users +should be made aware of the type of certificate, associated DRepID, metadata +anchor and or deposit amount. + +If user grants permission, the transaction must be signed by the secret key of +the provided public DRep Key, with the signature and key to be added to the +transaction witness set before submission. -The user's permission to sign this transaction must be requested for by the -wallet, additionally wallets may wish to display the contents of the certificate -to the user to check. +By allowing clients to supply the DRep Key and choose UTxOs we are placing the +burden of managing a user's DRep registration deposit on the application. By +forcing wallets to inspect these certificates it allows the user to catch +malicious client applications attempting to insert their own data into the +certificate. -Wallets should be responsible for handling the payment of deposit required with -the submission of this certificate shown by the `depositAmount` field. +##### Errors + +One `TxSignError` should be returned if there is a signature error with any of +the certificates. ##### Returns -This returns a `signedDRepRegistrationCertificate` object which contains all the -details of the submitted registration certificate, for the client to confirm. -The returned `txHash` can be used by the client to track the status of the -transaction containing the certificate on Cardano. +This returns a `SubmittedTransaction` object which contains all the details of +the submitted registration certificate, for the client to confirm. The returned +`txHash` can be used by the client to track the status of the transaction +containing the certificate on Cardano. -#### `api.submitDRepRetirement(certificate: DRepRetirementCertificate): Promise` +#### `api.submitDRepRetirement(tx, pubDRepKey): Promise` Errors: [APIError](#extended-apierror), [`TxSignError`](#extended-txsignerror) -This endpoint requests the wallet to build, sign and submit a DRep retirement -certificate as described in CIP-1694 **todo: add CDDL when available**. The -wallet must sign the certificate using the secret side of the supplied dRep -public key presented in the `DRepKey` field. +This endpoint requests the wallet to inspect, sign and submit a transaction +containing a DRep retirement certificate. The wallet should articulate this +request from client application in a explicit and highly informative way. Users +should be made aware of the type of certificate, associated DRepID and metadata +anchor. + +If user grants permission, the transaction must be signed by the secret key of +the provided public DRep Key, with the signature and key to be added to the +transaction witness set before submission. + +By forcing wallets to inspect these certificates it allows the user to catch +malicious client applications attempting to insert their own data into the +certificate. -The user's permission to sign this transaction must be requested for by the -wallet, additionally wallets may wish to display the contents of the certificate -to the user to check. +##### Errors + +One `TxSignError` should be returned if there is a signature error with any of +the certificates. ##### Returns -This returns a `SignedDRepRetirementCertificate` object which contains all the -details of the submitted retirement certificate, for the client to confirm. The -returned `txHash` can be used by the client to track the status of the -transaction containing the certificate on Cardano. +This returns a `SubmittedTransaction` object which contains all the details of +the submitted retirement certificate, for the client to confirm. The returned +`txHash` can be used by the client to track the status of the transaction +containing the certificate on Cardano. -#### `api.submitVote(votes: Vote[]): Promise[]` +#### `api.submitVote([tx, pubDRepKey]): Promise[]` Errors: [APIError](#extended-apierror), [`TxSignError`](#extended-txsignerror) -This endpoint requests the wallet to build, sign and submit transaction(s) -containing supplied data in the vote field as described in the -[ledger conway specification](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L79). -The wallet must create and attach a governance credential witness using the -secret side of the supplied public DRep key. Wallets using this API should -always fill in the the role field with DRep. +This endpoint requests the wallet to inspect, sign and submit transaction(s) +containing votes. The wallet should articulate this request from client +application in a explicit and highly informative way. For each vote, users must +be shown the governance action ID, vote choice (yes, no, abstain) and metadata +anchor. For the case of multiple votes at once, the user may only be asked for +permission to authorize all at once, but this can depend on wallet's +implementation. + +If user grants permission, each transaction must be signed by the secret key of +the provided public stake key, with the signature and key to be added to the +transaction witness set before submission. + +By forcing wallets to inspect these votes it allows the user to catch malicious +client applications attempting to alter the vote's contents. -The user's permission to sign must be requested by the wallet, additionally -wallets should display the contents of the vote transaction to the user to -check. This allows for the user to catch malicious clients attempting to alter -the vote's contents. It is up to the wallet to decide if user permission's is -required for each signature or one permission granted to sign all. +##### Errors One `TxSignError` should be returned if there is a signature error with any of the transactions. ##### Returns -This returns an array of `SignedVote` objects, matching each `Vote` passed at -invocation. The returned `txHash` fields can be used by the client to track the -status of the submitted vote transactions. +This returns an array of `SubmittedTransaction` objects which contain the +details of the submitted votes, for the client to confirm. The returned +`txHash`s can be used by the client to track the status of the transactions +containing the certificates on Cardano. -#### `api.submitGovernanceAction(action: GovernanceAction): Promise` +#### `api.submitGovernanceAction(tx): Promise` Errors: [APIError](#extended-apierror), [`TxSignError`](#extended-txsignerror) -This endpoint requests the wallet to build, sign and submit a transaction -containing supplied data in the governance action field as described in the -[ledger conway specification](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L94). +This endpoint requests the wallet to inspect, sign and submit a transaction +containing a governance action. The wallet should articulate this request from +client application in a explicit and highly informative way. For the governance +action the user must be shown the amount of ADA to be locked as deposit, +governance action type and the metadata anchor. + +If user grants permission, the transaction must be signed using the wallets +payment key and submitted. + +By allowing clients to choose UTxOs, we are placing the burden of managing the +deposit on the application. By forcing wallets to inspect these transactions it +allows the user to catch malicious client applications attempting to insert +their own data into the governance action. -Wallets should be responsible for handling the payment of deposit required with -the submission of this certificate. This is in accordance with the -`depositAmount` field. +##### Errors + +One `TxSignError` should be returned if there is a signature error with any of +the transactions. ##### Returns -This returns a `SignedGovernanceAction` object which contains all the details of -the submitted governance action submission, for the client to confirm. The -returned `txHash` can be used by the client to track the status of the -transaction on Cardano. +This returns a `SubmittedTransaction` object which contains all the details of +the submitted governance action, for the client to confirm. The returned +`txHash` can be used by the client to track the status of the transaction +containing the certificate on Cardano. ### Examples of Flows @@ -714,7 +434,9 @@ transaction on Cardano. 4. **Chain Lookup:** The client uses a chain indexer to work out the governance state of the provided credentials. -#### Vote Delegation +TODO: add updated flows for delegation and DRep registration + + ## Rationale: how does this CIP achieve its goals? @@ -784,7 +506,7 @@ combined functionality and would encourage wallet providers to pursue this. But we understand that this may add overhead to wallet designs so offer this API as an alternative. -### Why these DReps and Ada Holders +### Why these DReps and Ada Holders? This proposal only caters to two types of actor described in CIP-1694; Ada holders and DReps, this decision was three fold. Primarily this is to allow @@ -797,13 +519,17 @@ represent the majority of participants. These alternative credentials are unlikely to be stored within standard wallet software which may interface with this API. -### Transaction Burden +### The Role of the Wallet + +The endpoints specified here aim to maintain the wallets role of: sharing public +keys, inspecting, signing and submission. -Endpoints defined here require wallets to generate, sign and submit transactions -to chain. The possible minimum ask for wallets is to just sign transactions this -is because signing keys should always remain within the wallet's control. This -alternative approach moves the complexity of transaction building and submission -onto client applications. +By not placing the burden of transaction construction onto the wallet, we move +this application specific complexity from wallet implementations and onto +applications. This has a number of benefits, primarily this should lower the bar +for wallet adoption. But this also helps in the creation of iterative updates, +all wallet implementers do not need to update if the format of these +transactions is adjusted The design outlined here aims to improve the security by placing the burden of submission onto wallets. This prevents malicious clients from being able to @@ -811,20 +537,6 @@ censor which transactions are submitted to chain. This is of particular concern due to the potential political impact of transactions being handled by this API. We thus deem it necessary for wallets to bare this burden. -Furthermore by passing typescript interfaces to wallets rather than serialized -transactions we make inspection of transaction elements as easy as possible for -wallet's. This improves security as it avoids the need for wallets to -deserialize transactions to inspect their contents. - -#### The role of the wallet - -Relying on wallets for transaction construction and submission has precedent -from the approach of -[CIP-62?](https://github.com/cardano-foundation/CIPs/pull/296). This abstracts -clients from the need to manage core wallet functionality such as UTxO handling. -This approach allows client developers to focus on their domain rather than -having to be involved in wallet function management. - ### Extension Design Whilst CIP-30 facilitated the launch of client development on Cardano, it's @@ -860,6 +572,8 @@ credentials from mnemonics, not only those wallets who support this web-bridge. This standard brings all the benefits of the application of generic ecosystem standards. +- TODO: why not reuse Catalyst's CIP-36 key? + ### Multi-stake Key Support Although @@ -895,8 +609,10 @@ for wallets implementing both APIs. ### Open Questions -- The burden of transaction building to be placed on dApps or wallets? -- Move DRep key definitions into a CIP which is dedicated to describing CIP-1694 related credentials? +- The burden of transaction building to be placed on dApps or wallets? + - This has been moved from the wallet to the application. +- Move DRep key definitions into a CIP which is dedicated to describing CIP-1694 + related credentials? or CIP-1852? - Is it necessary to provide a method to prove ownership of DRep key? and can CIP-30's `api.signData()` be used to prove ownership of multi-stake keys? - Is it sensible to place multi-stake key burden onto clients? From a47237bada065c2c332bdc47d0bb6c3630fd471e Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Wed, 21 Jun 2023 10:18:12 +0100 Subject: [PATCH 12/35] Small tidy throughout --- CIP-0095/README.md | 84 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 58 insertions(+), 26 deletions(-) diff --git a/CIP-0095/README.md b/CIP-0095/README.md index 9dfdb8047a..7d29f05312 100644 --- a/CIP-0095/README.md +++ b/CIP-0095/README.md @@ -47,11 +47,19 @@ CIP-1694's governance design. ## Specification -We define the following specification as an extension to the specification -described within CIP-30. +We define the following section as an extension to the specification described +within CIP-30. -- todo: explain - [extension](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030#extension) +To access these functionalities a client application must present this CIP +extension object: + +```ts +{ "cip": 95 } +``` + +This extension object is provided during the initial handshake procedure as +described within +[CIP-30's Initial API](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030#cardanowalletnameenable-extensions-extension----promiseapi). > **Note** This specification will evolve as the proposed ledger governance > model matures. It is likely the precise data structures outlined here will be @@ -113,6 +121,12 @@ For hardware implementations: ### Data Types +From +[CIP-30's Data Types](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030#data-types) +we only inherit: + +- [cbor\](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030#cbort) + #### DRepID ```ts @@ -129,8 +143,8 @@ hash digest of a 32 byte Ed25519 public key, as described in type PubDRepKey = string; ``` -A hex string representing 32 byte Ed25519 DRep public key, as described in -[DRep Key](#DRep-key). +A hex-encoded string representing 32 byte Ed25519 DRep public key, as described +in [DRep Key](#DRep-key). #### PubStakeKey @@ -138,31 +152,40 @@ A hex string representing 32 byte Ed25519 DRep public key, as described in type PubStakeKey = string; ``` -A hex string representing 32 byte Ed25519 public key used as a staking +A hex-encoded string representing 32 byte Ed25519 public key used as a staking credential. -#### Tx TODO +#### UnsignedTransaction -unsigned, unwitnessed Tx containing a +```ts +type UnsignedTransaction = string; +``` + +A hex-encoded string representing a CBOR transaction that is completely unsigned +(has an empty transaction witness set). + +This data model is used to represent transactions which contain, for example: +DRep registration certificates and the client wishes the wallet inspect, add +signatures (with payment and DRep key) and submit. #### SubmittedTransaction ```ts interface SubmittedTransaction { - tx: ; + tx: cbor; txHash: string; witness: string; } ``` -This interface represents a +This interface represents a transaction that has been submitted to chain. -- `tx`: +- `tx`: A hex-encoded string representing CBOR transaction, which was submitted + to chain. - `txHash`: A string containing the hash of the transaction which contained this certificate that was submitted to chain and included in a block. This is to be used by clients to track the status of the delegation transaction on-chain. -- `witness`: A string containing the stake credential witness attached to the - certificate. +- `witness`: A string containing the witnesses attached to the transaction. ### Error Types @@ -261,7 +284,7 @@ for the case of An array of the connected user's active stake keys. -#### `api.submitVoteDelegation(delegations: [tx, pubStakeKey]): Promise` +#### `api.submitVoteDelegation([tx: UnsignedTransaction, stakeKey: PubStakeKey]): Promise` Errors: [APIError](#extended-apierror), [`TxSignError`](#extended-txsignerror) @@ -296,7 +319,7 @@ details of the submitted delegation certificates, for the client to confirm. The returned `txHash`s can be used by the client to track the status of the transactions containing the certificates on Cardano. -#### `api.submitDRepRegistration(tx, pubDRepKey): Promise` +#### `api.submitDRepRegistration(tx: UnsignedTransaction, dRepKey: PubDRepKey): Promise` Errors: [APIError](#extended-apierror), [`TxSignError`](#extended-txsignerror) @@ -328,7 +351,7 @@ the submitted registration certificate, for the client to confirm. The returned `txHash` can be used by the client to track the status of the transaction containing the certificate on Cardano. -#### `api.submitDRepRetirement(tx, pubDRepKey): Promise` +#### `api.submitDRepRetirement: UnsignedTransaction, dRepKey: PubDRepKey): Promise` Errors: [APIError](#extended-apierror), [`TxSignError`](#extended-txsignerror) @@ -358,7 +381,7 @@ the submitted retirement certificate, for the client to confirm. The returned `txHash` can be used by the client to track the status of the transaction containing the certificate on Cardano. -#### `api.submitVote([tx, pubDRepKey]): Promise[]` +#### `api.submitVote([tx: UnsignedTransaction, dRepKey: PubDRepKey]): Promise[]` Errors: [APIError](#extended-apierror), [`TxSignError`](#extended-txsignerror) @@ -389,7 +412,7 @@ details of the submitted votes, for the client to confirm. The returned `txHash`s can be used by the client to track the status of the transactions containing the certificates on Cardano. -#### `api.submitGovernanceAction(tx): Promise` +#### `api.submitGovernanceAction(tx: UnsignedTransaction): Promise` Errors: [APIError](#extended-apierror), [`TxSignError`](#extended-txsignerror) @@ -421,12 +444,15 @@ containing the certificate on Cardano. ### Examples of Flows -#### Login +#### Connection and Login + +This describes a potential flow of connection between CIP-95 compatible client +application and wallet then a subsequent login. 1. **Connection:** User indicates to the client their intent to connect, causing - client offer a list of supported wallets, user selects their wallet causing - the client to invoke `.{wallet-name}.enable({ "cip": ?})` from the shared - cardano `namespace`. + client offer a list of supported wallets, user selects their desired wallet. + The client will then invoke `.{wallet-name}.enable({ "cip": 95 })` from the + shared `cardano` namespace. 2. **Wallet Confirmation:** The wallet indicates through its UI the clients intent to connect, the user grants permission. 3. **Share Credentials:** The client invokes both `.getActiveStakeKeys()` and @@ -529,7 +555,9 @@ this application specific complexity from wallet implementations and onto applications. This has a number of benefits, primarily this should lower the bar for wallet adoption. But this also helps in the creation of iterative updates, all wallet implementers do not need to update if the format of these -transactions is adjusted +transactions is adjusted. + +-todo: also easier error checking for wallet The design outlined here aims to improve the security by placing the burden of submission onto wallets. This prevents malicious clients from being able to @@ -616,9 +644,13 @@ for wallets implementing both APIs. - Is it necessary to provide a method to prove ownership of DRep key? and can CIP-30's `api.signData()` be used to prove ownership of multi-stake keys? - Is it sensible to place multi-stake key burden onto clients? -- Does supporting governance action submission a necessary burden for the scope - of this proposal? +- Does supporting governance action submission a necessary burden for the + scope of this proposal? + - Since moving burden of transaction construction from wallet to app, this + becomes much less of an issue as the complex error checking should now be + done by the application. - Should this proposal cater for non-key-based stake credential? + - We could just change all references of keys to credentials to allow this? - Should there be a more elegant way for the optional sharing of governance state? From 560de553d8b4e35fd4c99a084e5e6492e9f881a1 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Thu, 29 Jun 2023 15:55:04 +0100 Subject: [PATCH 13/35] Added flow examples and tidied --- CIP-0095/README.md | 137 +++++++++++++++++++++++++-------------------- 1 file changed, 76 insertions(+), 61 deletions(-) diff --git a/CIP-0095/README.md b/CIP-0095/README.md index 7d29f05312..5127c04fe5 100644 --- a/CIP-0095/README.md +++ b/CIP-0095/README.md @@ -256,7 +256,7 @@ review and to consent to signature and submission. The exceptions to this are `.getActiveStakeKeys()` and `.getDRepKey()`, user consent should not be needed to share public key information. -#### `api.getDRepKey(): Promise` +#### `api.getPubDRepKey(): Promise` Errors: `APIError` @@ -267,7 +267,7 @@ as described in [DRep Key](#DRep-key). The wallet account's DRep Key. -#### `api.getActiveStakeKeys(): Promise` +#### `api.getActivePubStakeKeys(): Promise` Errors: `APIError` @@ -327,7 +327,7 @@ This endpoint requests the wallet to inspect, sign and submit a transaction containing a DRep registration certificate. The wallet should articulate this request from client application in a explicit and highly informative way. Users should be made aware of the type of certificate, associated DRepID, metadata -anchor and or deposit amount. +anchor and deposit amount. If user grants permission, the transaction must be signed by the secret key of the provided public DRep Key, with the signature and key to be added to the @@ -455,50 +455,57 @@ application and wallet then a subsequent login. shared `cardano` namespace. 2. **Wallet Confirmation:** The wallet indicates through its UI the clients intent to connect, the user grants permission. -3. **Share Credentials:** The client invokes both `.getActiveStakeKeys()` and +3. **Share Credentials:** The client invokes both `.getActivePubStakeKeys()` and `.getDRepKey()`, causing the connected wallet to share relevant credentials. 4. **Chain Lookup:** The client uses a chain indexer to work out the governance state of the provided credentials. -TODO: add updated flows for delegation and DRep registration - - +3. **Inspect, sign and submit:** The wallet inspects the content of the + transaction, showing the user associated certificate's DRepID, metadata + anchor and deposit amount. If the user confirm that they accepts this then + the wallet should sign and submit the transaction. +4. **Feedback to user:** The wallet returns a `SubmittedTransaction` and the + client uses the `txHash` field to track the status of the transaction + on-chain, providing feedback to the user. ## Rationale: how does this CIP achieve its goals? @@ -510,13 +517,13 @@ ask small we aim to reduce implementation time. This design aims to make the tracking of a user's governance state an optional endeavour for wallet providers. This is achieved by placing the responsibility on clients to track a user's governance state, i.e. if a wallet user is a DRep, -what DRep a wallet holder has delegated to, etc. +what DRep a wallet user has delegated to, etc. Despite only defining the minimal set of endpoints required, we do not wish to discourage the creation of subsequent CIPs with a wider range of governance functionality. Nor does this specification aim to discourage wallet providers -from fully integrating CIP-1694 governance, side-stepping the necessity for this -API and client applications. +from fully integrating governance features, side-stepping the necessity for this +API and client applications (matching how staking is achieved). ### Why Web-based Stacks @@ -529,58 +536,63 @@ The primary alternative approach to this is wallet providers integrating this functionality fully inside of wallet software, matching how staking is often implemented. We deem this approach as preferable from a security standpoint for combined functionality and would encourage wallet providers to pursue this. But -we understand that this may add overhead to wallet designs so offer this API as -an alternative. - -### Why these DReps and Ada Holders? - -This proposal only caters to two types of actor described in CIP-1694; Ada -holders and DReps, this decision was three fold. Primarily this is to allow -these groups to utilize a client to participate in Cardano's governance. These -groups are likely less comfortable utilizing command-line interfaces than other -groups, thus making alternatives from them is a priority. Secondly, the other -types of actor (Constitution Committee member and SPOs) are identified by -different credentials than Ada holders and DReps. Thirdly, these groups -represent the majority of participants. These alternative credentials are -unlikely to be stored within standard wallet software which may interface with -this API. +we understand that this adds significant overhead to wallet designs, so we offer +this API as an alternative. + +### Why DReps and Ada Holders? + +This proposal only caters to two types of governance actor described in +CIP-1694; Ada holders and DReps, this decision was three fold. Primarily, this +is to allow these groups to utilize a web-based client to participate in +Cardano's governance. These groups are likely less comfortable utilizing +command-line interfaces than other groups, thus making alternatives from them is +a priority. Secondly, the other types of actor (Constitution Committee member +and SPOs) are identified by different credentials than Ada holders and DReps, +making their integration in this specification complex. These alternative +credentials are unlikely to be stored within standard wallet software which may +interface with this API. Thirdly, Ada holders and DReps likely represent the +majority of participants thus we aim to cast a wide net with this specification. ### The Role of the Wallet -The endpoints specified here aim to maintain the wallets role of: sharing public -keys, inspecting, signing and submission. +The endpoints specified here aim to maintain the role of the wallet as: sharing +public keys, transaction inspecting, transaction signing and transaction +submission. By not placing the burden of transaction construction onto the wallet, we move -this application specific complexity from wallet implementations and onto +the application specific complexity from wallet implementations and onto applications. This has a number of benefits, primarily this should lower the bar for wallet adoption. But this also helps in the creation of iterative updates, all wallet implementers do not need to update if the format of these -transactions is adjusted. +transactions is adjusted during development. --todo: also easier error checking for wallet +By placing the burden of submission onto wallets we prevent malicious clients +from being able to censor which transactions are submitted to chain. This is of +particular concern due to the potential political impact of transactions being +handled by this API. We thus deem it necessary for wallets to bare this burden. -The design outlined here aims to improve the security by placing the burden of -submission onto wallets. This prevents malicious clients from being able to -censor which transactions are submitted to chain. This is of particular concern -due to the potential political impact of transactions being handled by this API. -We thus deem it necessary for wallets to bare this burden. +One argument against this design is that, if wallets are required to be able to +inspect and thus understand these application specific transactions then they +may as well build the transaction. For this reason I have placed this back into +the ### Extension Design -Whilst CIP-30 facilitated the launch of client development on Cardano, it's +Whilst CIP-30 facilitated the launch of dApp client development on Cardano, it's functionality is limited in scope. Although it does offer generic functions, these cannot satisfy the problem that this proposal tackles. Thus extending it's functionality is a necessity. With this specification we chose to extend CIP-30's functionalities. There would be two competing designs to this approach. One; move to have this specification -included within CIP-30. Two; deploy this specification as its own standalone +included within CIP-30. Two; deploy this specification as it's own standalone web-bridge. It would be undesirable to include this functionality within the base CIP-30 API -because it would force all clients and wallets supporting CIP-30 to support this -API. This is because not all client apps or wallet will have the need or desire -to support this specification thus forcing cooperation would not desirable. +because it would force all wallets supporting CIP-30 to support this API. This +is undesirable because not all client apps or wallet will have the need or +desire to support this specification thus forcing cooperation would not +desirable. The reason we chose to not deploy this specification on its own is because it is unlikely that clients implementing this API will not want to also use the @@ -639,6 +651,8 @@ for wallets implementing both APIs. - The burden of transaction building to be placed on dApps or wallets? - This has been moved from the wallet to the application. + - Since wallets still have to be able to be able to inspect these + transactions, its not far away from just generating the transaction itself. - Move DRep key definitions into a CIP which is dedicated to describing CIP-1694 related credentials? or CIP-1852? - Is it necessary to provide a method to prove ownership of DRep key? and can @@ -653,6 +667,7 @@ for wallets implementing both APIs. - We could just change all references of keys to credentials to allow this? - Should there be a more elegant way for the optional sharing of governance state? +- should provide support for combination certificates? ## Path to Active From 9af3bf045daf57bcb46116b69f446db685fb9a79 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Thu, 29 Jun 2023 21:56:51 +0100 Subject: [PATCH 14/35] Incorporate changes from comments --- CIP-0095/README.md | 39 +++++++++++++++++++++------------------ 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/CIP-0095/README.md b/CIP-0095/README.md index 5127c04fe5..dcf28af42e 100644 --- a/CIP-0095/README.md +++ b/CIP-0095/README.md @@ -319,7 +319,7 @@ details of the submitted delegation certificates, for the client to confirm. The returned `txHash`s can be used by the client to track the status of the transactions containing the certificates on Cardano. -#### `api.submitDRepRegistration(tx: UnsignedTransaction, dRepKey: PubDRepKey): Promise` +#### `api.submitDRepRegistration(tx: UnsignedTransaction): Promise` Errors: [APIError](#extended-apierror), [`TxSignError`](#extended-txsignerror) @@ -329,15 +329,14 @@ request from client application in a explicit and highly informative way. Users should be made aware of the type of certificate, associated DRepID, metadata anchor and deposit amount. -If user grants permission, the transaction must be signed by the secret key of -the provided public DRep Key, with the signature and key to be added to the -transaction witness set before submission. +If user grants permission, the transaction must be signed by the secret DRep key +as described in [DRep Key](#drep-key), with the signature and key to be added to +the transaction witness set before submission. -By allowing clients to supply the DRep Key and choose UTxOs we are placing the -burden of managing a user's DRep registration deposit on the application. By -forcing wallets to inspect these certificates it allows the user to catch -malicious client applications attempting to insert their own data into the -certificate. +By allowing clients to choose UTxOs we are placing the burden of managing a +user's DRep registration deposit on the application. By forcing wallets to +inspect these certificates it allows the user to catch malicious client +applications attempting to insert their own data into the certificate. ##### Errors @@ -351,7 +350,7 @@ the submitted registration certificate, for the client to confirm. The returned `txHash` can be used by the client to track the status of the transaction containing the certificate on Cardano. -#### `api.submitDRepRetirement: UnsignedTransaction, dRepKey: PubDRepKey): Promise` +#### `api.submitDRepRetirement(tx: UnsignedTransaction): Promise` Errors: [APIError](#extended-apierror), [`TxSignError`](#extended-txsignerror) @@ -361,9 +360,9 @@ request from client application in a explicit and highly informative way. Users should be made aware of the type of certificate, associated DRepID and metadata anchor. -If user grants permission, the transaction must be signed by the secret key of -the provided public DRep Key, with the signature and key to be added to the -transaction witness set before submission. +If user grants permission, the transaction must be signed by the secret DRep key +as described in [DRep Key](#drep-key), with the signature and key to be added to +the transaction witness set before submission. By forcing wallets to inspect these certificates it allows the user to catch malicious client applications attempting to insert their own data into the @@ -381,7 +380,7 @@ the submitted retirement certificate, for the client to confirm. The returned `txHash` can be used by the client to track the status of the transaction containing the certificate on Cardano. -#### `api.submitVote([tx: UnsignedTransaction, dRepKey: PubDRepKey]): Promise[]` +#### `api.submitVote([tx: UnsignedTransaction]): Promise[]` Errors: [APIError](#extended-apierror), [`TxSignError`](#extended-txsignerror) @@ -393,9 +392,9 @@ anchor. For the case of multiple votes at once, the user may only be asked for permission to authorize all at once, but this can depend on wallet's implementation. -If user grants permission, each transaction must be signed by the secret key of -the provided public stake key, with the signature and key to be added to the -transaction witness set before submission. +If user grants permission, each transaction must be signed by the secret DRep +key as described in [DRep Key](#drep-key), with the signature and key to be +added to the transaction witness set before submission. By forcing wallets to inspect these votes it allows the user to catch malicious client applications attempting to alter the vote's contents. @@ -420,7 +419,7 @@ This endpoint requests the wallet to inspect, sign and submit a transaction containing a governance action. The wallet should articulate this request from client application in a explicit and highly informative way. For the governance action the user must be shown the amount of ADA to be locked as deposit, -governance action type and the metadata anchor. +governance action type, all action specific details and the metadata anchor. If user grants permission, the transaction must be signed using the wallets payment key and submitted. @@ -633,6 +632,10 @@ excluding tooling for DAOs from being supported through this standard. The argument could be made that such entities generally prefer to use more advanced wallet tooling which is not dependent on web-based stacks. +- TODO: discuss change design to allow script based credentials? +- TODO: discuss why end points for each type of cert, rather than group by + key/signature + ### Backwards Compatibility This proposal should not effect the backwards compatibility of either clients or From a426eaa37a9e1499afcb13ee130c311c0ac71778 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sat, 1 Jul 2023 21:36:15 +0100 Subject: [PATCH 15/35] Added discussion on reusing cip36 keys --- CIP-0095/README.md | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/CIP-0095/README.md b/CIP-0095/README.md index dcf28af42e..e7c0138404 100644 --- a/CIP-0095/README.md +++ b/CIP-0095/README.md @@ -606,12 +606,32 @@ this we see as a necessary step for wallet implementors. By setting a (hierarchical) deterministic derivation path it enables restorability from a seed phrase. -With this definition we aim to standard for tooling to be able to derive DRep -credentials from mnemonics, not only those wallets who support this web-bridge. -This standard brings all the benefits of the application of generic ecosystem +With this definition we aim to standard for all ecosystem tooling to be able to +derive DRep credentials from mnemonics. This brings the benefits ecosystem standards. -- TODO: why not reuse Catalyst's CIP-36 key? +#### Why not reuse [CIP-36 Vote Keys](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0036/README.md#voting-key)? + +CIP-36 defines derivation path for a key pair to be used within CIP-36 style +governance. The most notable user of this standard is +[Project Catalyst](projectcatalyst.io), where CIP-36 vote keys are used to sign +vote transactions on the Jormungandr side-chain. + +One suggestion is to reuse this key pair instead of defining a new key pair in +DRep key. The benefits to this would be that it is easier for users and tools to +manage a single key pair to be used for any projects following the CIP-36 +standard and for use in this API. This would mean a single key could be used to +sign Catalyst votes and CIP-1694 DRep votes. + +Reusing keys comes with the downside of possible confusion for users and +tooling. This is why we have attempted to assign the DRep keys clear and +explicit naming and usage to avoid confusion with CIP-36 vote keys. Furthermore, +the keys described here are used for more than just vote signing just the +"CIP-36 vote key" naming may be a cause of confusion. + +> **Note** The derivation path used for CIP-36 vote keys includes `1694` as the +> `purpose`, this is a perhaps misleading reality and hints to the original +> intension of using CIP-36 vote keys for Cardano's Voltaire. ### Multi-stake Key Support From 4efbedb6b3986b8afd0ca4ee661314555447c39e Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Wed, 5 Jul 2023 10:44:53 +0100 Subject: [PATCH 16/35] Added DRep ID bech 32 prefix to CIP-05 --- CIP-0005/README.md | 1 + CIP-0095/README.md | 10 ---------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/CIP-0005/README.md b/CIP-0005/README.md index f2df752949..e232603371 100644 --- a/CIP-0005/README.md +++ b/CIP-0005/README.md @@ -95,6 +95,7 @@ We define the following set of common prefixes with their corresponding semantic | `stake_vkh` | Stake address verification key hash | blake2b\_224 digest of a delegation verification key | | `stake_shared_vkh` | Shared stake address verification key hash | blake2b\_224 digest of a delegation verification key | | `req_signer_vkh` | Required signer verification key hash | blake2b\_224 digest of a required signer verification key | +| `drep_id` | CIP-1694 DRep ID | blake2b\_224 digest of a DRep's voting credential | | `vrf_vkh` | VRF verification key hash | blake2b\_256 digest of a VRF verification key | | `datum` | Output datum hash | blake2b\_256 digest of output datum | | `script_data` | Script data hash | blake2b\_256 digest of script data | diff --git a/CIP-0095/README.md b/CIP-0095/README.md index e7c0138404..edc0c6485c 100644 --- a/CIP-0095/README.md +++ b/CIP-0095/README.md @@ -127,16 +127,6 @@ we only inherit: - [cbor\](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030#cbort) -#### DRepID - -```ts -type DRepID = string; -``` - -A hex string representing a registered DRep's ID which is a 32-byte Blake2b-224 -hash digest of a 32 byte Ed25519 public key, as described in -[CIP-1694 Registered DReps](https://github.com/JaredCorduan/CIPs/blob/voltaire-v1/CIP-1694/README.md#registered-dreps). - #### PubDRepKey ```ts From 197a814aed897ae8682c083602c131cc16654ab8 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Wed, 5 Jul 2023 15:19:34 +0100 Subject: [PATCH 17/35] added more rationale around CIP30 compatibility --- CIP-0095/README.md | 93 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 79 insertions(+), 14 deletions(-) diff --git a/CIP-0095/README.md b/CIP-0095/README.md index edc0c6485c..00caddc6b2 100644 --- a/CIP-0095/README.md +++ b/CIP-0095/README.md @@ -563,14 +563,78 @@ handled by this API. We thus deem it necessary for wallets to bare this burden. One argument against this design is that, if wallets are required to be able to inspect and thus understand these application specific transactions then they may as well build the transaction. For this reason I have placed this back into -the +the [Open Questions](#open-questions). -### Extension Design +### CIP-30 Reuse Whilst CIP-30 facilitated the launch of dApp client development on Cardano, it's functionality is limited in scope. Although it does offer generic functions, -these cannot satisfy the problem that this proposal tackles. Thus extending it's -functionality is a necessity. +these cannot satisfy the problem that this proposal tackles in a backwards +compatible manner. Thus extending it's functionality is a necessity. + +#### Backwards Compatibility + +The primary issue with just using CIP-30 to inspect, sign and submit Conway +transactions/certificates is that wallet implementations are likely +incompatible. This is because such certificates/transactions were not part of +the ledger design at time of original CIP-30 implementation. Furthermore, CIP-30 +was written and implemented before voting credentials were defined and thus it +would be impossible to provide signatures with this credential to votes, DRep +registrations and DRep retirements. + +Although it is likely that some of the capabilities of this API can be achieved +by existing CIP-30 implementations it is not certain how much. We would like to +avoid the potential mismatching of capabilities between CIP-30 implementations, +as this creates unpredictable wallet behavior for client applications. Such +behavior was a primary motivator to introduce such an extendability mechanism to +CIP-30. + +#### Functionality Differences + +In this proposal we specify the precise information that must be shown to the +user at time of signature and submission for transactions. This is not possible +with current CIP-30 implementations, rather CIP-30's +[`.signTx()`](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030#apisigntxtx-cbortransaction-partialsign-bool--false-promisecbortransaction_witness_set) +only requires that "must request the user's consent in an informative way". + +In the case of political transactions we think it should be explicit and +unambiguous what information the user must be shown. This is to prevent +politically motivated malicious client applications from attempting to sign and +submit malicious transactions. + +### Sign and Submit + +By making our endpoints combination, sign and submit we bring forth two +benefits. Firstly, we avoid any potential issues with backwards compatibility of +the new transactions and clients attempting to use CIP-30's +[`.submitTx()`](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030#apisubmittxtx-cbortransaction-promisehash32) +to submit transactions. Secondly, we improve security by allowing the submit to +chain, this prevents malicious clients from censoring which transactions are +submitted to chain. + +### Explicit Singular Endpoints + +This API explicitly separates all our transaction inspect, sign and submit +endpoints. A reasonable alternative to this could be to group endpoints together +by which keys (stake or DRep) are needed to witness the +certificate/transactions. Here we chose to avoid any potential complexity on the +behalf of a wallet, to figure out what type of transaction/certificate they have +to inspect. This in particularly important for cases of transactions containing +multiple governance artifacts, for example: a vote, a governance action and DRep +registration certificate in one transaction. By separating the signing and +submission of each transaction/certificate we avoid the need for wallets to have +to deal with such edge cases. + +One downside of this approach is that it limits how much can be done in a single +transaction. These methods do not allow multiple certificates to be supplied at +once. Thus users are limited to a single governance artifact per transaction. +This is limiting as it means users have to submit multiple transactions to +achieve what is possible in one. We do recognize this as a legitimate drawback +of our design. Later CIPs which replace this one may choose a more compact +design to allow such transactions, but for this we aim to keep wallet +implementations more straight forward. + +### Extension Design With this specification we chose to extend CIP-30's functionalities. There would be two competing designs to this approach. One; move to have this specification @@ -632,19 +696,20 @@ This is because a single stake key can delegate to a single DRep. By allowing users to spread stake across multiple stake keys it allows different weighted delegation to different DReps, this could be a very desirable feature. -### Types of wallets +### Types of credential This specification does not cater for wallets who manage non-key-based stake credentials and those who wish to handle non-key-based DRep credentials. This -does limit the usefulness of this specification, but we believe the added -complexity of supporting these types of wallet. This means that we are likely -excluding tooling for DAOs from being supported through this standard. The -argument could be made that such entities generally prefer to use more advanced -wallet tooling which is not dependent on web-based stacks. - -- TODO: discuss change design to allow script based credentials? -- TODO: discuss why end points for each type of cert, rather than group by - key/signature +does limit the usefulness of this specification. But the complexities that would +be introduced by generalization this specification to these credentials is +unlikely to yield much benefit since these types of wallet are not prevalent in +Cardano. + +Although this means that we are likely excluding tooling for DAOs from being +supported through this standard. The argument could be made that such entities +generally prefer to use more advanced wallet tooling rather than relying on +interaction with web-based stacks, thus it is not even certain DAOs would want +to use such a standard. ### Backwards Compatibility From 6c83052722d3ee3bd3c0a1fc63c5fee6e25de209 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Fri, 14 Jul 2023 16:51:53 +0100 Subject: [PATCH 18/35] add notes from hackathon --- CIP-0095/README.md | 248 +++++++++++---------------------------------- 1 file changed, 61 insertions(+), 187 deletions(-) diff --git a/CIP-0095/README.md b/CIP-0095/README.md index 00caddc6b2..4f6d7884c7 100644 --- a/CIP-0095/README.md +++ b/CIP-0095/README.md @@ -30,6 +30,24 @@ holders' and DReps' interactions with such web-based stacks. > outlined within > [CIP-1694?](https://github.com/cardano-foundation/CIPs/pull/380). +
+ Wallets and Tooling Hackathon + + On 2023.07.14 a online and in person community hackathon took place, aims of this event included maturation of the design of this specification. + + We would like to thank the following attendees for providing their valuable insights: + - Piotr Czeglik - Lace + - Mircea Hasegan - Lace + - Alex Apeldoorn - Lace + - Michal Szorad - Yoroi + - Javier Bueno - Yoroi + - Vladimir Volek - Five Binaries + - Marek Mahut - Five Binaries + - Markus Gufler - Cardano Foundation + - Michal Ciborowski - BinarApps + +
+ ## Motivation: why is this CIP necessary? CIP-1694 introduces many new concepts, entities and actors to Cardano; @@ -62,11 +80,12 @@ described within [CIP-30's Initial API](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030#cardanowalletnameenable-extensions-extension----promiseapi). > **Note** This specification will evolve as the proposed ledger governance -> model matures. It is likely the precise data structures outlined here will be -> need to be adjusted. +> model matures. ### DRep Key +// TODO: Move into a separate CIP. + CIP-1694 does not define a derivation path for registered DRep credentials, here we propose the introduction of DRep Keys to act as DRep credentials for registered DReps. @@ -274,162 +293,16 @@ for the case of An array of the connected user's active stake keys. -#### `api.submitVoteDelegation([tx: UnsignedTransaction, stakeKey: PubStakeKey]): Promise` - -Errors: [APIError](#extended-apierror), [`TxSignError`](#extended-txsignerror) - -This endpoint requests the wallet to inspect, sign and submit transaction(s) -containing vote delegation certificates. The wallet should articulate this -request from client application in a explicit and highly informative way. Users -must be shown the target of the delegation (DRepID or a predefined DRep -identifier) and must be informed which of their stake keys are being used. For -the case of multiple delegations at once, the user may only be asked for -permission to authorize all at once, but this can depend on wallet's -implementation. - -If user grants permission, each transaction must be signed by the secret key of -the provided public stake key, with the signature and key to be added to the -transaction witness set before submission. - -By allowing clients to supply the stake key we are placing the burden of -"multi-governance-delegation" management onto the client, reducing the -complexity for wallet implementations. By forcing wallets to inspect these -certificates it allows the user to catch malicious client applications -attempting to insert their own delegation targets. - -##### Errors - -One `TxSignError` should be returned if there is a signature error with any of -the certificates. - -##### Returns - -This returns an array of `SubmittedTransaction` objects which contain the -details of the submitted delegation certificates, for the client to confirm. The -returned `txHash`s can be used by the client to track the status of the -transactions containing the certificates on Cardano. - -#### `api.submitDRepRegistration(tx: UnsignedTransaction): Promise` - -Errors: [APIError](#extended-apierror), [`TxSignError`](#extended-txsignerror) - -This endpoint requests the wallet to inspect, sign and submit a transaction -containing a DRep registration certificate. The wallet should articulate this -request from client application in a explicit and highly informative way. Users -should be made aware of the type of certificate, associated DRepID, metadata -anchor and deposit amount. - -If user grants permission, the transaction must be signed by the secret DRep key -as described in [DRep Key](#drep-key), with the signature and key to be added to -the transaction witness set before submission. - -By allowing clients to choose UTxOs we are placing the burden of managing a -user's DRep registration deposit on the application. By forcing wallets to -inspect these certificates it allows the user to catch malicious client -applications attempting to insert their own data into the certificate. - -##### Errors - -One `TxSignError` should be returned if there is a signature error with any of -the certificates. - -##### Returns - -This returns a `SubmittedTransaction` object which contains all the details of -the submitted registration certificate, for the client to confirm. The returned -`txHash` can be used by the client to track the status of the transaction -containing the certificate on Cardano. - -#### `api.submitDRepRetirement(tx: UnsignedTransaction): Promise` - -Errors: [APIError](#extended-apierror), [`TxSignError`](#extended-txsignerror) - -This endpoint requests the wallet to inspect, sign and submit a transaction -containing a DRep retirement certificate. The wallet should articulate this -request from client application in a explicit and highly informative way. Users -should be made aware of the type of certificate, associated DRepID and metadata -anchor. - -If user grants permission, the transaction must be signed by the secret DRep key -as described in [DRep Key](#drep-key), with the signature and key to be added to -the transaction witness set before submission. - -By forcing wallets to inspect these certificates it allows the user to catch -malicious client applications attempting to insert their own data into the -certificate. +#### `api.signTx()` -##### Errors +// TODO: add more detail here +- Here we supersede CIP-30's `.signTx()` and replace it. +- This endpoint extends CIP30 implementation to be able to support all Conway ledger era transactions. -One `TxSignError` should be returned if there is a signature error with any of -the certificates. - -##### Returns - -This returns a `SubmittedTransaction` object which contains all the details of -the submitted retirement certificate, for the client to confirm. The returned -`txHash` can be used by the client to track the status of the transaction -containing the certificate on Cardano. - -#### `api.submitVote([tx: UnsignedTransaction]): Promise[]` - -Errors: [APIError](#extended-apierror), [`TxSignError`](#extended-txsignerror) - -This endpoint requests the wallet to inspect, sign and submit transaction(s) -containing votes. The wallet should articulate this request from client -application in a explicit and highly informative way. For each vote, users must -be shown the governance action ID, vote choice (yes, no, abstain) and metadata -anchor. For the case of multiple votes at once, the user may only be asked for -permission to authorize all at once, but this can depend on wallet's -implementation. - -If user grants permission, each transaction must be signed by the secret DRep -key as described in [DRep Key](#drep-key), with the signature and key to be -added to the transaction witness set before submission. - -By forcing wallets to inspect these votes it allows the user to catch malicious -client applications attempting to alter the vote's contents. - -##### Errors - -One `TxSignError` should be returned if there is a signature error with any of -the transactions. - -##### Returns - -This returns an array of `SubmittedTransaction` objects which contain the -details of the submitted votes, for the client to confirm. The returned -`txHash`s can be used by the client to track the status of the transactions -containing the certificates on Cardano. - -#### `api.submitGovernanceAction(tx: UnsignedTransaction): Promise` - -Errors: [APIError](#extended-apierror), [`TxSignError`](#extended-txsignerror) - -This endpoint requests the wallet to inspect, sign and submit a transaction -containing a governance action. The wallet should articulate this request from -client application in a explicit and highly informative way. For the governance -action the user must be shown the amount of ADA to be locked as deposit, -governance action type, all action specific details and the metadata anchor. - -If user grants permission, the transaction must be signed using the wallets -payment key and submitted. - -By allowing clients to choose UTxOs, we are placing the burden of managing the -deposit on the application. By forcing wallets to inspect these transactions it -allows the user to catch malicious client applications attempting to insert -their own data into the governance action. - -##### Errors - -One `TxSignError` should be returned if there is a signature error with any of -the transactions. - -##### Returns - -This returns a `SubmittedTransaction` object which contains all the details of -the submitted governance action, for the client to confirm. The returned -`txHash` can be used by the client to track the status of the transaction -containing the certificate on Cardano. +#### `api.signData()` +// TODO: add more detail here +- Here we supersede CIP-30's `.signData()` and replace it. +- This endpoint extends CIP30 implementation to be able to support signatures using Conway ledger era's voting credential. ### Examples of Flows @@ -445,11 +318,11 @@ application and wallet then a subsequent login. 2. **Wallet Confirmation:** The wallet indicates through its UI the clients intent to connect, the user grants permission. 3. **Share Credentials:** The client invokes both `.getActivePubStakeKeys()` and - `.getDRepKey()`, causing the connected wallet to share relevant credentials. + `.getPubDRepKey()`, causing the connected wallet to share relevant credentials. 4. **Chain Lookup:** The client uses a chain indexer to work out the governance state of the provided credentials. -#### Vote Delegation + ## Rationale: how does this CIP achieve its goals? The principle aim for this design is to reduce the complexity for wallet -implementors. This is motivated by the necessity for users to be able to +implementors whilst maintaining backwards compatibility with CIP-30 implementations. This is motivated by the necessity for users to be able to interact with the age of Voltaire promptly, by keeping the wallet's providers ask small we aim to reduce implementation time. @@ -514,7 +387,7 @@ functionality. Nor does this specification aim to discourage wallet providers from fully integrating governance features, side-stepping the necessity for this API and client applications (matching how staking is achieved). -### Why Web-based Stacks +### Why Web-based Stacks? Web-based stacks, with wallet connectivity, are a familiar place for users to be able to interact with Cardano. These tools lower the technical bar to engage @@ -602,18 +475,10 @@ unambiguous what information the user must be shown. This is to prevent politically motivated malicious client applications from attempting to sign and submit malicious transactions. -### Sign and Submit - -By making our endpoints combination, sign and submit we bring forth two -benefits. Firstly, we avoid any potential issues with backwards compatibility of -the new transactions and clients attempting to use CIP-30's -[`.submitTx()`](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030#apisubmittxtx-cbortransaction-promisehash32) -to submit transactions. Secondly, we improve security by allowing the submit to -chain, this prevents malicious clients from censoring which transactions are -submitted to chain. - ### Explicit Singular Endpoints +// TODO: change to explain pivot + This API explicitly separates all our transaction inspect, sign and submit endpoints. A reasonable alternative to this could be to group endpoints together by which keys (stake or DRep) are needed to witness the @@ -636,6 +501,8 @@ implementations more straight forward. ### Extension Design +// TODO: add in explanation for replacing CIP30 endpoints + With this specification we chose to extend CIP-30's functionalities. There would be two competing designs to this approach. One; move to have this specification included within CIP-30. Two; deploy this specification as it's own standalone @@ -653,7 +520,7 @@ functionality offered by CIP-30. Additionally, CIP-30 offers a extensibility mechanism meaning that the initial handshake connection is defined and thus wont be needed to be defined within this specification. -### DRep Key + #### Why not reuse [CIP-36 Vote Keys](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0036/README.md#voting-key)? @@ -728,24 +595,27 @@ for wallets implementing both APIs. ### Open Questions - The burden of transaction building to be placed on dApps or wallets? - - This has been moved from the wallet to the application. - - Since wallets still have to be able to be able to inspect these - transactions, its not far away from just generating the transaction itself. -- Move DRep key definitions into a CIP which is dedicated to describing CIP-1694 - related credentials? or CIP-1852? -- Is it necessary to provide a method to prove ownership of DRep key? and can - CIP-30's `api.signData()` be used to prove ownership of multi-stake keys? -- Is it sensible to place multi-stake key burden onto clients? + - As we are replacing CIP-30's signTx it makes sense to follow the same flow and place the burden on the client applications. +- Move DRep key definitions into a CIP which is dedicated to describing CIP-1694 + related credentials? or CIP-1852? + - Yes, this is a cleaner approach, as we keep the purity of this proposal to being a wallet web bridge. - Does supporting governance action submission a necessary burden for the scope of this proposal? - Since moving burden of transaction construction from wallet to app, this becomes much less of an issue as the complex error checking should now be done by the application. -- Should this proposal cater for non-key-based stake credential? - - We could just change all references of keys to credentials to allow this? -- Should there be a more elegant way for the optional sharing of governance - state? -- should provide support for combination certificates? +- should provide support for combination certificates? + - Yes we will support ALL conway ledger era Tx/Certs, this will allow for CIP95 to be "the Conway compatible" wallet web bridge. +- Is it necessary to provide a method to prove ownership of DRep key? + - Yes, this will be a useful add. +- Is it sensible to place multi-stake key burden onto clients? + - Yes, seems like a reasonable approach. If wallets want to manage it, they can only provide the keys they wish. +- Do we need to share stake keys or can we just reuse reward addresses? + - Reusing CIP30's `.getRewardAddresses()` may act as an alternative, but it is unclear how implementors have supported this function and thus its reuse maybe a mistake. + - It is a more reasonable approach to share public key material instead of addresses as it gives the client application more freedom. +- Should this proposal cater for non-key-based stake credential? + - We can leave this for a future iteration. +- Should there be a way for the optional sharing of governance state, from wallet to client? ## Path to Active @@ -763,7 +633,11 @@ for wallets implementing both APIs. [`gov-wallet-cip`](https://discord.com/channels/826816523368005654/1101547251903504474/1101548279277309983) channel in the [IOG Technical Discord](https://discord.gg/inputoutput) under the `🥑BUILD` section (to view you have to opt-in to the Builders group). -- [ ] Author to setup regular discussion forums to support wallet implementors. +- [x] Author to engage with wallet providers for feedback. +- [x] Author to run a hackathon workshop with wallet providers. + - In person and online hackathon run 2023.07.13, outcomes presented here. TODO: add outcomes summary. +- [x] Author to provide a reference client application for wallet implementors to be able to test against. + - See: [Ryun1/cip95-cardano-wallet-connector](https://github.com/Ryun1/cardano-wallet-connector). ## Copyright From 49c8da7a96f5f9efbf82b60a1234392845499fa0 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 23 Jul 2023 13:26:38 +0100 Subject: [PATCH 19/35] Addressing comments + hackathon adjustments --- CIP-0095/README.md | 175 ++++++++++++++++++++++++--------------------- 1 file changed, 92 insertions(+), 83 deletions(-) diff --git a/CIP-0095/README.md b/CIP-0095/README.md index 4f6d7884c7..4bfc84dec6 100644 --- a/CIP-0095/README.md +++ b/CIP-0095/README.md @@ -22,29 +22,33 @@ that needs to be injected into web applications. These definitions extend [CIP-30 | Cardano dApp-Wallet Web Bridge](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030) to provide support for -[CIP-1694? | A First Step Towards On-Chain Decentralized Governance](https://github.com/cardano-foundation/CIPs/pull/380) -focussed web-based stacks. Here we aim to support the requirements of both Ada -holders' and DReps' interactions with such web-based stacks. +[CIP-1694 | A First Step Towards On-Chain Decentralized Governance](https://github.com/cardano-foundation/CIPs/blob/master/CIP-1694/README.md) +focussed web-based stacks. Here we aim to support the requirements of the Conway +Ledger era, this specification is based on the +[Draft Conway Ledger Era Specification](https://github.com/input-output-hk/cardano-ledger/tree/master/eras/conway/test-suite/cddl-files). > **Note** This proposal assumes knowledge of the ledger governance model as > outlined within -> [CIP-1694?](https://github.com/cardano-foundation/CIPs/pull/380). +> [CIP-1694](https://github.com/cardano-foundation/CIPs/blob/master/CIP-1694/README.md).
Wallets and Tooling Hackathon - On 2023.07.14 a online and in person community hackathon took place, aims of this event included maturation of the design of this specification. +On 2023.07.13 a online and in person community hackathon took place, aims of +this event included maturation of the design of this specification. - We would like to thank the following attendees for providing their valuable insights: - - Piotr Czeglik - Lace - - Mircea Hasegan - Lace - - Alex Apeldoorn - Lace - - Michal Szorad - Yoroi - - Javier Bueno - Yoroi - - Vladimir Volek - Five Binaries - - Marek Mahut - Five Binaries - - Markus Gufler - Cardano Foundation - - Michal Ciborowski - BinarApps +We would like to thank the following attendees for providing their valuable +insights: + +- Piotr Czeglik - Lace +- Mircea Hasegan - Lace +- Alex Apeldoorn - Lace +- Michal Szorad - Yoroi +- Javier Bueno - Yoroi +- Vladimir Volek - Five Binaries +- Marek Mahut - Five Binaries +- Markus Gufler - Cardano Foundation +- Michal Ciborowski - BinarApps
@@ -52,12 +56,19 @@ holders' and DReps' interactions with such web-based stacks. CIP-1694 introduces many new concepts, entities and actors to Cardano; describing their implementation at the ledger level. Yet, for most ecosystem -participants low level details are abstracted away by tools, such as wallets. -This creates a need for tooling to be able support the utilization of ledger -features. This specification allows for creation of web-based tools for the -utilization of CIP-1694's governance features. +participants low level details are abstracted away by tooling. This creates a +need for such tooling to be able support the utilization of ledger features. +This specification allows for creation of web-based tools for the utilization of +CIP-1694's governance features. + +Whilst CIP-30 facilitated the launch of dApp client development on Cardano, it's +functionality is limited in scope. It was written well before the emergence of +the Conway Ledger Era and thus lacks the required methods to support full user +interaction. We believe that expecting existing CIP-30 implementors to upgrade +implementations is unfeasible, thus we must extend it's functionality with this +API. -This proposal enables Ada holders and DReps to engage web-based tooling through +This proposal enables Ada holders, and DReps to engage web-based tooling through wallets. Thus the primary stakeholders for this proposal are tool developers and wallet providers. Here we aim to outline all endpoints needed to be exposed to web based tools to support all the needs Ada holders and DReps to engage with @@ -84,7 +95,7 @@ described within ### DRep Key -// TODO: Move into a separate CIP. +// TODO: Move this into a separate CIP. CIP-1694 does not define a derivation path for registered DRep credentials, here we propose the introduction of DRep Keys to act as DRep credentials for @@ -104,14 +115,14 @@ standard. To differentiate DRep credentials from other Cardano keys the derivation path must follow: -`m / 1718' / 1815' / account' / chain / address_index` +`m / 1694' / 1815' / account' / 1718 / address_index` > **Note** `1718` was the year that François-Marie adopted the pseudonym > Voltaire. We strongly suggest that a maximum of one set of DRep credentials should be -associated with one wallet account, this can be achieved by setting `chain=0` -and `address_index=0`. Thus avoiding the need for DRep Key discovery. +associated with one wallet account, this can be achieved by only ever setting +`address_index=0`. This avoids the need for DRep Key discovery. We believe the overhead that would be introduced by "multi-DRep" accounts is an unjustified expense. Future iterations of this specification may expand on this, @@ -142,7 +153,7 @@ For hardware implementations: From [CIP-30's Data Types](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030#data-types) -we only inherit: +we inherit: - [cbor\](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030#cbort) @@ -164,38 +175,6 @@ type PubStakeKey = string; A hex-encoded string representing 32 byte Ed25519 public key used as a staking credential. -#### UnsignedTransaction - -```ts -type UnsignedTransaction = string; -``` - -A hex-encoded string representing a CBOR transaction that is completely unsigned -(has an empty transaction witness set). - -This data model is used to represent transactions which contain, for example: -DRep registration certificates and the client wishes the wallet inspect, add -signatures (with payment and DRep key) and submit. - -#### SubmittedTransaction - -```ts -interface SubmittedTransaction { - tx: cbor; - txHash: string; - witness: string; -} -``` - -This interface represents a transaction that has been submitted to chain. - -- `tx`: A hex-encoded string representing CBOR transaction, which was submitted - to chain. -- `txHash`: A string containing the hash of the transaction which contained this - certificate that was submitted to chain and included in a block. This is to be - used by clients to track the status of the delegation transaction on-chain. -- `witness`: A string containing the witnesses attached to the transaction. - ### Error Types This specification inherits all Error Types defined in CIP-30. @@ -260,11 +239,6 @@ interface TxSignError = { ### Full Governance API -Methods contained in this section on invocation should request the user to -review and to consent to signature and submission. The exceptions to this are -`.getActiveStakeKeys()` and `.getDRepKey()`, user consent should not be needed -to share public key information. - #### `api.getPubDRepKey(): Promise` Errors: `APIError` @@ -293,16 +267,34 @@ for the case of An array of the connected user's active stake keys. -#### `api.signTx()` +#### `api.signTx(tx: cbor, partialSign: bool = false): Promise>` + +Errors: `APIError`, `TxSignError` // TODO: add more detail here -- Here we supersede CIP-30's `.signTx()` and replace it. -- This endpoint extends CIP30 implementation to be able to support all Conway ledger era transactions. -#### `api.signData()` +Here we supersede CIP-30's `.signTx()` and replace it, to allow signatures with +the Conway era `voting_credential`. + +This endpoint extends CIP30 implementation to be able to support all Conway +ledger era transactions and certificates. + +##### Returns + +The portions of the witness set that were signed as a result of this call are +returned to encourage dApps to verify the contents returned by this endpoint +while building the final transaction. + +#### `api.signData(addr: Address, payload: Bytes): Promise` + +Errors: `APIError`, `DataSignError` + // TODO: add more detail here -- Here we supersede CIP-30's `.signData()` and replace it. -- This endpoint extends CIP30 implementation to be able to support signatures using Conway ledger era's voting credential. + +Here we supersede CIP-30's `.signData()` and replace it, to allow signatures +with the Conway era `voting_credential`. + +##### Returns ### Examples of Flows @@ -318,7 +310,8 @@ application and wallet then a subsequent login. 2. **Wallet Confirmation:** The wallet indicates through its UI the clients intent to connect, the user grants permission. 3. **Share Credentials:** The client invokes both `.getActivePubStakeKeys()` and - `.getPubDRepKey()`, causing the connected wallet to share relevant credentials. + `.getPubDRepKey()`, causing the connected wallet to share relevant + credentials. 4. **Chain Lookup:** The client uses a chain indexer to work out the governance state of the provided credentials. @@ -372,7 +365,8 @@ client. ## Rationale: how does this CIP achieve its goals? The principle aim for this design is to reduce the complexity for wallet -implementors whilst maintaining backwards compatibility with CIP-30 implementations. This is motivated by the necessity for users to be able to +implementors whilst maintaining backwards compatibility with CIP-30 +implementations. This is motivated by the necessity for users to be able to interact with the age of Voltaire promptly, by keeping the wallet's providers ask small we aim to reduce implementation time. @@ -520,6 +514,10 @@ functionality offered by CIP-30. Additionally, CIP-30 offers a extensibility mechanism meaning that the initial handshake connection is defined and thus wont be needed to be defined within this specification. +- TODO: moves multi-stake key issues to wallet by reusing signTx +- TODO: CIP95 extension tag clearly allows for dApps to know if these functions + are allowed + ### The Role of the Wallet @@ -422,10 +558,10 @@ for wallet adoption. But this also helps in the creation of iterative updates, all wallet implementers do not need to update if the format of these transactions is adjusted during development. -By placing the burden of submission onto wallets we prevent malicious clients + One argument against this design is that, if wallets are required to be able to inspect and thus understand these application specific transactions then they @@ -456,7 +592,7 @@ as this creates unpredictable wallet behavior for client applications. Such behavior was a primary motivator to introduce such an extendability mechanism to CIP-30. -#### Functionality Differences + -### Explicit Singular Endpoints + ### Extension Design @@ -576,6 +712,8 @@ generally prefer to use more advanced wallet tooling rather than relying on interaction with web-based stacks, thus it is not even certain DAOs would want to use such a standard. +- TODO: why not support CC certs / pool certs + ### Backwards Compatibility This proposal should not effect the backwards compatibility of either clients or From c067362e6427e8a0ebee4a27cd75b10fee5931b4 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Tue, 25 Jul 2023 13:57:12 +0100 Subject: [PATCH 21/35] refactor prose + tidy --- CIP-0095/README.md | 457 ++++++++++++++++++++++++--------------------- 1 file changed, 241 insertions(+), 216 deletions(-) diff --git a/CIP-0095/README.md b/CIP-0095/README.md index 8e2b356573..c17e1d1b1f 100644 --- a/CIP-0095/README.md +++ b/CIP-0095/README.md @@ -5,7 +5,8 @@ Category: Wallets Status: Proposed Authors: - Ryan Williams -Implementors: [] +Implementors: + - Lace Discussions: - https://github.com/cardano-foundation/cips/pulls/509 - https://discord.com/channels/826816523368005654/1101547251903504474/1101548279277309983 @@ -23,14 +24,16 @@ These definitions extend [CIP-30 | Cardano dApp-Wallet Web Bridge](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030) to provide support for [CIP-1694 | A First Step Towards On-Chain Decentralized Governance](https://github.com/cardano-foundation/CIPs/blob/master/CIP-1694/README.md) -focussed web-based stacks. Here we aim to support the requirements of the Conway -Ledger era, this specification is based on the +focussed web-based stacks. Here we aim to support the requirements of Ada +Holders and DReps in the Conway Ledger era, this specification is based on the [Draft Conway Ledger Era Specification](https://github.com/input-output-hk/cardano-ledger/tree/master/eras/conway/test-suite/cddl-files). > **Note** This proposal assumes knowledge of the ledger governance model as > outlined within > [CIP-1694](https://github.com/cardano-foundation/CIPs/blob/master/CIP-1694/README.md). +### Acknowledgments +
Wallets and Tooling Hackathon @@ -45,6 +48,7 @@ insights: - Alex Apeldoorn - Lace - Michal Szorad - Yoroi - Javier Bueno - Yoroi +- Ed Eykholt - Yoroi - Vladimir Volek - Five Binaries - Marek Mahut - Five Binaries - Markus Gufler - Cardano Foundation @@ -56,12 +60,12 @@ insights: CIP-1694 introduces many new concepts, entities and actors to Cardano; describing their implementation at the ledger level. Yet, for most ecosystem -participants low level details are abstracted away by tooling. This creates a -need for such tooling to be able support the utilization of ledger features. -This specification allows for creation of web-based tools for the utilization of +participants low level details are abstracted away by tooling. Creating a need +for such tooling, to allow the utilization of new ledger features. This +specification allows for creation of web-based tools for the utilization of CIP-1694's governance features. -Whilst CIP-30 facilitated the launch of dApp client development on Cardano, it's +Whilst CIP-30 facilitated the launch of dApp development on Cardano, it's functionality is limited in scope. It was written well before the emergence of the Conway Ledger Era and thus lacks the required methods to support full user interaction. We believe that expecting existing CIP-30 implementors to upgrade @@ -79,31 +83,25 @@ CIP-1694's governance design. We define the following section as an extension to the specification described within CIP-30. -To access these functionalities a client application must present this CIP -extension object: - -```ts -{ "cip": 95 } -``` - -This extension object is provided during the initial handshake procedure as -described within -[CIP-30's Initial API](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030#cardanowalletnameenable-extensions-extension----promiseapi). - > **Note** This specification will evolve as the proposed ledger governance > model matures. ### DRep Key -// TODO: Move this into a separate CIP. +// TODO: Move this into a more appropriate **separate** CIP. + +The Conway ledger era introduces a new _first class_ credential in +[`voting_credential`](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L321). +This is used to identify registered DReps on-chain, via their certificates and +votes. -CIP-1694 does not define a derivation path for registered DRep credentials, here -we propose the introduction of DRep Keys to act as DRep credentials for -registered DReps. +CIP-1694 does not define a derivation path for these registered DRep +credentials, here we propose the introduction of DRep Keys to be used as DRep +`voting_credential`s for (non-script) registered DReps. -The methods described here should not be considered the only definitive method -of generating DRep credentials. Rather these methods should be employed to -derive keys for non-script registered DReps. +The methods described here should not be considered the definitive method of +generating DRep credentials. Rather these methods should be employed by wallets +to derive keys for non-script registered DReps. #### Derivation @@ -151,17 +149,56 @@ For hardware implementations: ### Data Types +#### CIP-30 Inherited Data Types + From [CIP-30's Data Types](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030#data-types) we inherit: -- [Address](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0030/README.md#address). -- [Bytes](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0030/README.md#bytes). -- [cbor\](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030#cbort). -- [DataSignature](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0030/README.md#bytes). -- [Extension](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0030/README.md#extension). +##### [Address](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0030/README.md#address) + +A string representing an address in either bech32 format, or hex-encoded bytes. +All return types containing `Address` must return the hex-encoded bytes format, +but must accept either format for inputs. + +##### [Bytes](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0030/README.md#bytes) + +A hex-encoded string of the corresponding bytes. + +##### [cbor\](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030#cbort) + +A hex-encoded string representing [CBOR](https://tools.ietf.org/html/rfc7049) +corresponding to `T` defined via [CDDL](https://tools.ietf.org/html/rfc8610) +either inside of the +[Shelley Multi-asset binary spec](https://github.com/input-output-hk/cardano-ledger-specs/blob/0738804155245062f05e2f355fadd1d16f04cd56/shelley-ma/shelley-ma-test/cddl-files/shelley-ma.cddl) +or, if not present there, from the +[CIP-0008 signing spec](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0008/CIP-0008.md). +This representation was chosen when possible as it is consistent across the +Cardano ecosystem and widely used by other tools, such as +[cardano-serialization-lib](https://github.com/Emurgo/cardano-serialization-lib), +which has support to encode every type in the binary spec as CBOR bytes. + +##### [DataSignature](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0030/README.md#datasignature) + +```ts +type DataSignature = {| + signature: cbor, + key: cbor, +|}; +``` + +##### [Extension](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0030/README.md#extension) + +An extension is an object with a single field `"cip"` that describe a CIP number +extending the API (as a plain integer, without padding). For example: + +```ts +{ "cip": 30 } +``` -#### PubDRepKey +#### CIP-95 Data Types + +##### PubDRepKey ```ts type PubDRepKey = string; @@ -170,7 +207,7 @@ type PubDRepKey = string; A hex-encoded string representing 32 byte Ed25519 DRep public key, as described in [DRep Key](#DRep-key). -#### PubStakeKey +##### PubStakeKey ```ts type PubStakeKey = string; @@ -183,65 +220,23 @@ credential. This specification inherits all Error Types defined in CIP-30. -// todo: add more + avoid collisions with CIP-62? - -#### Extended APIError +// TODO: add more, once specification matured and avoid collisions with +CIP-62?'s extended errors. -Here we define extensions to -[CIP-30's Error Types](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030#error-types). - -```ts -type enum APIErrorCode { - // CIP-30 error codes - InvalidArgumentError = -5 - UnknownChoiceError = -6 - UnknownKey = -7 - InvalidKey = -8 -} - -interface APIError { - code: APIErrorCode, - info: string -} -``` +### Governance Extension API -- `InvalidArgumentError` - Generic error for errors in the formatting of the - arguments. -- `UnknownChoiceError` - client supplies an unknown choice in a `Vote`. -- `UnknownKey` - client supplies an unknown public key (DRep or Stake) with the - expectation of signature. -- `InvalidKey` - client supplies a public key that does not match another - supplied credential. This could be for DRep Keys not matching DRepID in - Retirement Certificate or, could be when the incorrect role is supplied in a - vote with a DRep key. +These are the CIP-95 methods that should be returned as part of the API object. -##### APIError elements - -- `code`: The `APIErrorCode` which is being reported. -- `info` - A human readable description of the error. - -#### Extended TxSignError - -Here we add additional error codes to CIP-30's -[TxSignError](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030#txsignerror). +To access these functionalities a client application must present this CIP-95 +extension object: ```ts -type enum TxSignErrorCode { - ProofGeneration = 1, - UserDeclined = 2, -} - -interface TxSignError = { - code: TxSignErrorCode, - info: string, -} +{ "cip": 95 } ``` -- `ProofGeneration` - Raised when there is an error during witness/proof - generation. -- `UserDeclined` - Raised when the user declined to sign one or many items. - -### Full Governance API +This extension object is provided during the initial handshake procedure as +described within +[CIP-30's Initial API](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030#cardanowalletnameenable-extensions-extension----promiseapi). #### `api.getPubDRepKey(): Promise` @@ -250,9 +245,12 @@ Errors: `APIError` The connected wallet account provides the account's public DRep Key, derivation as described in [DRep Key](#DRep-key). +These are used by the client to identify the user's on-chain CIP-1694 +interactions, i.e. if a user has registered to be a DRep. + ##### Returns -The wallet account's DRep Key. +The wallet account's public DRep Key. #### `api.getActivePubStakeKeys(): Promise` @@ -263,13 +261,13 @@ being used for staking), if the wallet tracks the keys that are used for governance then only those keys shall be returned. These are used by the client to identify the user's on-chain CIP-1694 -interactions. Here we allow for multiple stake credentials to provided at once -for the case of +interactions, i.e if a user has delegated to a DRep. Here we allow for multiple +stake credentials to provided at once for the case of [multi-stake key wallets](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0018). ##### Returns -An array of the connected user's active stake keys. +An array of the connected user's active public stake keys. #### `api.signTx(tx: cbor, partialSign: bool = false): Promise>` @@ -279,22 +277,24 @@ This endpoint requests the wallet to inspect and provide appropriate witnesses for a supplied transaction. The wallet should articulate this request from client application in a explicit and highly informative way. -Here we supersede -[CIP-30's `.signTx()`](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0030/README.md#apisigntxtx-cbortransaction-partialsign-bool--false-promisecbortransaction_witness_set) -and replace it. To allow signatures with `voting_credential` and recognition of -Conway ledger era transaction fields and certificates. +Here we add to the capabilities of +[CIP-30's `.signTx()`](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0030/README.md#apisigntxtx-cbortransaction-partialsign-bool--false-promisecbortransaction_witness_set). +To allow signatures with `voting_credential` and recognition of Conway ledger +era transaction fields and certificates. -**CIP-30 is not descriptive** in what supporting implementors should be able to -recognize and sign, we believe this adds unneeded ambiguity. For this extension -we wish to remedy this by defining explicitly what wallets have to support. +CIP-30 is **not** descriptive in what supporting wallets should be able to +recognize and sign, we believe this adds considerable unneeded ambiguity. Thus +for this extension we wish explicitly define what wallets have to be able to +recognize and sign. ##### Expected Support As read from [cardano-ledger Conway _draft_ specification](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl). -Supporting wallets should be able to correctly witness all certificates and data -contained in transaction body, in any combination. +Supporting wallets should be able to recognize, inspect and correctly witness +all the following certificates and data contained in transaction body, in any +combination. | Supported Pre-Conway Certificates | | --------------------------------- | @@ -314,10 +314,14 @@ contained in transaction body, in any combination. | `reg_drep_cert` | | `unreg_drep_cert` | -| Conway Transaction Field Data | -| ----------------------------- | -| `voting_procedure` | -| `proposal_procedure` | +| Supported Conway Transaction Field Data | +| --------------------------------------- | +| `voting_procedure` | +| `proposal_procedure` | + +All other potential transaction field inclusions +[0-18](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L54-#L69), +should be able to be recognized and supported wallets. ##### Not Supported @@ -341,8 +345,8 @@ certificates, when the CIP-95 flag is enabled they should not. ##### Returns The portions of the witness set that were signed as a result of this call are -returned to encourage dApps to verify the contents returned by this endpoint -while building the final transaction. +returned. This encourages client apps to verify the contents returned by this +endpoint before building the final transaction. ##### Errors @@ -359,9 +363,9 @@ This endpoint requests the wallet to inspect and provide a signature for a supplied data. The wallet should articulate this request from client application in a explicit and highly informative way. -Here we supersede -[CIP-30's `.signData()`](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0030/README.md#apisigndataaddr-address-payload-bytes-promisedatasignaturet) -and replace it. To allow for signatures using `voting_credential`. +Here we add to the capabilities of +[CIP-30's `.signData()`](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0030/README.md#apisigndataaddr-address-payload-bytes-promisedatasignaturet). +To allow for signatures using `voting_credential`. This endpoint utilizes the [CIP-0008 signing spec](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0008/CIP-0008.md) @@ -378,17 +382,19 @@ To construct an address for DRep Key, the client application should construct a [type 6 address](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0019/CIP-0019-cardano-addresses.abnf#L7C8-L7C93). Using an appropriate [Network Tag](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0019/CIP-0019-cardano-addresses.abnf#L13) -and a hash of the DRep Key. +and a hash of a public DRep Key. // TODO: Change how to identify DRep Key? -| Key | Identifying `addr` | -| ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | + +| Key | Identifying `addr` | +| ----------- | ------------------ | | Payment Key | Address types: [0](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0019/CIP-0019-cardano-addresses.abnf#L1), [2](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0019/CIP-0019-cardano-addresses.abnf#L3), [4](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0019/CIP-0019-cardano-addresses.abnf#L5), [6](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0019/CIP-0019-cardano-addresses.abnf#L7C27-L7C72). | -| Stake Key | Address type: [14](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0019/CIP-0019-cardano-addresses.abnf#L10). | -| DRep Key | Denoted by constructed of type [6](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0019/CIP-0019-cardano-addresses.abnf#L7C27-L7C72). | +| Stake Key | Address type: [14](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0019/CIP-0019-cardano-addresses.abnf#L10). | +| DRep Key | Denoted by constructed of type [6](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0019/CIP-0019-cardano-addresses.abnf#L7C27-L7C72). | + -These key will be used to sign the `COSE_Sign1`'s `Sig_structure` with the +These keys will be used to sign the `COSE_Sign1`'s `Sig_structure` with the following headers set: - `alg` (1) - must be set to `EdDSA` (-8) @@ -444,10 +450,10 @@ application and wallet, then a subsequent _login_. #### Vote Delegation -Assume a "DRep Aggregator/Explorer" specialized client app, who aggregates DRep -metadata from DRep registration certificates and renders this metadata to show -prospective delegators. Assume that connection to a users wallet has already -been made via `cardano.{wallet-name}.enable({ "cip": 95})`. +Assume a _DRep Aggregator and Delegation_ specialized client app, that +aggregates DRep metadata from DRep registration certificates and renders this +metadata to show prospective delegators. Assume that connection to a users +wallet has already been made via `cardano.{wallet-name}.enable({ "cip": 95 })`. 1. **Choose DRep:** User browses DReps and selects one which align's with their values to delegate too. It is up to the client application to choose and @@ -463,42 +469,48 @@ been made via `cardano.{wallet-name}.enable({ "cip": 95})`. 3. **Inspect and Sign:** The app passes the transaction to the wallet via `.signTx()`. The wallet inspects the content of the transaction, informing the user of the client app's intension. If the user confirms that they are - happy to sign, the wallet returns the appropriate witnesses. + happy to sign, the wallet returns the appropriate witnesses, of payment key + and stake key. 4. **Submit:** The app will add the provided witnesses into the transaction body and then pass the witnessed transaction back to the wallet for submission via `.submitTx()`. -5. **Feedback to user:** The wallet returns a `SubmittedTransaction` and the - client uses the `txHash` field to track the status of the transaction - on-chain, providing feedback to the user. +5. **Feedback to user:** The wallet returns the submitted transaction's hash, + the app can use this to track the status of the transaction on-chain and + provide feedback to the user. -// TODO: give example flow of DRep reg and Voting. +#### DRep Registration - + is bundled with DRepID the client generates from the wallet's public DRep Key + provided via `.getPubDRepKey()`. +2. **Construct Registration**: The client application uses CIP-30 endpoints to + query the wallet's UTxO set and payment address. A DRep registration + certificate + ([`reg_drep_cert`](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L275C6-L275C19)) + is constructed by the app using the wallet's DRep ID and the provided + metadata anchor. A transaction is constructed to send 1 ADA to the wallet's + payment address with the certificate included in the transaction body. +3. **Inspect and sign:** The app passes the transaction to the wallet via + `.signTx()`. The wallet inspects the content of the transaction, informing + the user of the client app's intension. If the user confirms that they are + happy to sign, the wallet returns the appropriate witnesses, of payment key + and DRep key (`voting_credential`). +4. **Submit:** The app will add the provided witnesses into the transaction body + and then pass the witnessed transaction back to the wallet for submission via + `.submitTx()`. +5. **Feedback to user:** The wallet returns the submitted transaction's hash, + the app can use this to track the status of the transaction on-chain and + provide feedback to the user. -## Rationale: how does this CIP achieve its goals? +// TODO: give example flow for DRep Voting -// TODO: redo and add in rationale from hackathon changes +## Rationale: how does this CIP achieve its goals? The principle aim for this design is to reduce the complexity for wallet implementors whilst maintaining backwards compatibility with CIP-30 @@ -531,7 +543,7 @@ combined functionality and would encourage wallet providers to pursue this. But we understand that this adds significant overhead to wallet designs, so we offer this API as an alternative. - +majority of participants thus we aim to cast a wide net with this specification. + +// TODO: why not support CC certs / pool certs ### The Role of the Wallet @@ -551,6 +565,13 @@ The endpoints specified here aim to maintain the role of the wallet as: sharing public keys, transaction inspecting, transaction signing and transaction submission. +#### Transaction Inspection + +// TODO: add in discussion from hacakthon + scope of this CIP is not wallet best +practices + +#### Transaction Construction + By not placing the burden of transaction construction onto the wallet, we move the application specific complexity from wallet implementations and onto applications. This has a number of benefits, primarily this should lower the bar @@ -558,15 +579,14 @@ for wallet adoption. But this also helps in the creation of iterative updates, all wallet implementers do not need to update if the format of these transactions is adjusted during development. - +Here we also benefit from imitating the existing flows which have been utilized +by CIP-30 compliant systems. Reusing existing flows is beneficial for developer +adoption as it enables straight forward code reuse. One argument against this design is that, if wallets are required to be able to inspect and thus understand these application specific transactions then they -may as well build the transaction. For this reason I have placed this back into -the [Open Questions](#open-questions). +may as well build the transaction. Ultimately, we have taken the design decision +to leave transaction construction to the applications. ### CIP-30 Reuse @@ -575,6 +595,27 @@ functionality is limited in scope. Although it does offer generic functions, these cannot satisfy the problem that this proposal tackles in a backwards compatible manner. Thus extending it's functionality is a necessity. +#### Extension Design + +With this specification we chose to extend CIP-30's functionalities. There would +be two competing designs to this approach. One; move to have this specification +included within CIP-30. Two; deploy this specification as it's own standalone +web-bridge. + +It would be undesirable to include this functionality within the base CIP-30 API +because it would force all wallets supporting CIP-30 to support this API. This +is undesirable because not all client apps or wallets will have the need or +desire to support this specification. + +The reason we chose to not deploy this specification on its own is because it is +unlikely that clients implementing this API will not want to also use the +functionality offered by CIP-30. Additionally, CIP-30 offers a extensibility +mechanism meaning that the initial handshake connection is defined and thus wont +be needed to be defined within this specification. + +// TODO: another benefit is that users can choose if a client has access to + governance items or not. + #### Backwards Compatibility The primary issue with just using CIP-30 to inspect, sign and submit Conway @@ -592,69 +633,46 @@ as this creates unpredictable wallet behavior for client applications. Such behavior was a primary motivator to introduce such an extendability mechanism to CIP-30. - +#### Inheriting Endpoints + +In this design we chose to extend the capabilities of CIP-30's `.signTx()` and +`.signData()` rather than introducing new endpoints for signing and submission. +This was a result of community discussion at the wallets and tooling hackathon. +Originally we had individual endpoints for sign and submitting of DRep +registration, DRep retirement, votes, governance actions and vote delegations. + +Whilst individual endpoints seem like a simpler solution they would likely +introduce more complexities for wallet implementors. As constraining what +transactions an endpoint would require additional validation complexities and +error handling from wallets. For example; what should a wallet do if it is +passed a DRep registration certificate via `.signTx()`? should it witness or +reject and only witness with a dedicated DRep registration endpoint? + +Furthermore individual restrictive endpoints limit how much can be done in a +single transaction. These methods would not allow multiple certificates to be +supplied at once. Thus client apps would be limited to a single governance +artifact per transaction. This is limiting as it means users have to submit +multiple transactions to achieve what is possible in one. + +// TODO: full conway feature set makes more sense. + +#### CIP-95 as a Conway Flag + +By providing _updated_ CIP-30 endpoints we essentially use the CIP-95 extension +object as a flag to signal to apps at connection time a wallet's compatibility +with Conway leger era. This goes against how past ledger feature upgrades have +rolled out. Rather in the past, existing CIP-30 implementors have just updated +their implementations, we believe this to be an error prone approach. This +undoubted introduces deltas between what a client application expects a wallet +to be able to do and what it can do. There is no way for a client application to +know what a wallet is capable of. + +Despite this we do not discourage CIP-30 implementors from updating their +implementations to support Conway artifacts to `.signData()` and `.signTx()`. +But if so they must support the CIP-95 object flag at connection time, so that +clients are aware of this functionality. - - -### Extension Design - -// TODO: add in explanation for replacing CIP30 endpoints - -With this specification we chose to extend CIP-30's functionalities. There would -be two competing designs to this approach. One; move to have this specification -included within CIP-30. Two; deploy this specification as it's own standalone -web-bridge. - -It would be undesirable to include this functionality within the base CIP-30 API -because it would force all wallets supporting CIP-30 to support this API. This -is undesirable because not all client apps or wallet will have the need or -desire to support this specification thus forcing cooperation would not -desirable. - -The reason we chose to not deploy this specification on its own is because it is -unlikely that clients implementing this API will not want to also use the -functionality offered by CIP-30. Additionally, CIP-30 offers a extensibility -mechanism meaning that the initial handshake connection is defined and thus wont -be needed to be defined within this specification. - -- TODO: moves multi-stake key issues to wallet by reusing signTx -- TODO: CIP95 extension tag clearly allows for dApps to know if these functions - are allowed - - +standards. #### Why not reuse [CIP-36 Vote Keys](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0036/README.md#voting-key)? @@ -688,6 +706,8 @@ the keys described here are used for more than just vote signing just the > `purpose`, this is a perhaps misleading reality and hints to the original > intension of using CIP-36 vote keys for Cardano's Voltaire. +// TODO: add note derivation path change + ### Multi-stake Key Support Although @@ -712,7 +732,9 @@ generally prefer to use more advanced wallet tooling rather than relying on interaction with web-based stacks, thus it is not even certain DAOs would want to use such a standard. -- TODO: why not support CC certs / pool certs +#### Raw Keys + +// TODO: why raw keys, not encoded and not addresses ### Backwards Compatibility @@ -767,7 +789,8 @@ for wallets implementing both APIs. - [ ] Resolve all [open questions](#open-questions). - [ ] The interface is implemented and supported by various wallet providers. -- [ ] The interface is used by clients to interact with wallet providers. +- [ ] The interface is used by client applications to interact with wallets to + allow users to engage with the Conway ledger design. ### Implementation Plan @@ -780,7 +803,9 @@ for wallets implementing both APIs. - [x] Author to engage with wallet providers for feedback. - [x] Author to run a hackathon workshop with wallet providers. - In person and online hackathon run 2023.07.13, outcomes presented here. - TODO: add outcomes summary. + - See + [CIP-95 pull request comment](https://github.com/cardano-foundation/CIPs/pull/509#issuecomment-1636103821) + with summary. - [x] Author to provide a reference client application for wallet implementors to be able to test against. - See: From 65fffa14643a2252e0dffbf9c5b7c8ca1e6bfb42 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Thu, 27 Jul 2023 22:53:42 +0100 Subject: [PATCH 22/35] added open question --- CIP-0095/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CIP-0095/README.md b/CIP-0095/README.md index c17e1d1b1f..94a6d08dcd 100644 --- a/CIP-0095/README.md +++ b/CIP-0095/README.md @@ -782,6 +782,7 @@ for wallets implementing both APIs. - We can leave this for a future iteration. - Should there be a way for the optional sharing of governance state, from wallet to client? +- How to represent DRep keys in signData endpoint? ## Path to Active From 43fd06871dc88cb344e48eb2d6e0f760fc450836 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Mon, 31 Jul 2023 13:52:10 +0100 Subject: [PATCH 23/35] Addressed todos in rationale --- CIP-0095/README.md | 157 ++++++++++++++++++++++++++++++--------------- 1 file changed, 107 insertions(+), 50 deletions(-) diff --git a/CIP-0095/README.md b/CIP-0095/README.md index 94a6d08dcd..34c34d3521 100644 --- a/CIP-0095/README.md +++ b/CIP-0095/README.md @@ -91,7 +91,7 @@ within CIP-30. // TODO: Move this into a more appropriate **separate** CIP. The Conway ledger era introduces a new _first class_ credential in -[`voting_credential`](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L321). +[`voting_credential`](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L329). This is used to identify registered DReps on-chain, via their certificates and votes. @@ -462,7 +462,7 @@ wallet has already been made via `cardano.{wallet-name}.enable({ "cip": 95 })`. 2. **Construct Delegation:** The client application uses CIP-30 endpoints to query the wallet's UTxO set and payment address. A DRep delegation certificate - ([`vote_deleg_cert`](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L293C1-L293C16)) + ([`vote_deleg_cert`](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L3016)) is constructed by the app using the chosen DRep's ID and wallet's stake credential. A transaction is constructed to send 1 ADA to the wallet's payment address with the certificate included in the transaction body. @@ -492,7 +492,7 @@ a registered DRep. 2. **Construct Registration**: The client application uses CIP-30 endpoints to query the wallet's UTxO set and payment address. A DRep registration certificate - ([`reg_drep_cert`](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L275C6-L275C19)) + ([`reg_drep_cert`](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L310)) is constructed by the app using the wallet's DRep ID and the provided metadata anchor. A transaction is constructed to send 1 ADA to the wallet's payment address with the certificate included in the transaction body. @@ -508,8 +508,6 @@ a registered DRep. the app can use this to track the status of the transaction on-chain and provide feedback to the user. -// TODO: give example flow for DRep Voting - ## Rationale: how does this CIP achieve its goals? The principle aim for this design is to reduce the complexity for wallet @@ -527,7 +525,7 @@ Despite only defining the minimal set of endpoints required, we do not wish to discourage the creation of subsequent CIPs with a wider range of governance functionality. Nor does this specification aim to discourage wallet providers from fully integrating governance features, side-stepping the necessity for this -API and client applications (matching how staking is achieved). +API (matching how staking is achieved). ### Why Web-based Stacks? @@ -536,12 +534,12 @@ able to interact with Cardano. These tools lower the technical bar to engage with the ecosystem. Thus we believe encouraging further adoption of this approach is beneficial. -The primary alternative approach to this is wallet providers integrating this +The primary alternative approach is for wallet providers to integrate this functionality fully inside of wallet software, matching how staking is often -implemented. We deem this approach as preferable from a security standpoint for -combined functionality and would encourage wallet providers to pursue this. But -we understand that this adds significant overhead to wallet designs, so we offer -this API as an alternative. +implemented. We deem this approach as preferable from a security standpoint, we +would encourage wallet providers to pursue this. But we understand that this +adds significant overhead to wallet designs, so we offer this API as an +alternative. ### Why DReps and Ada Holders? @@ -550,14 +548,40 @@ CIP-1694; Ada holders and DReps, this decision was three fold. Primarily, this is to allow these groups to utilize a web-based client to participate in Cardano's governance. These groups are likely less comfortable utilizing command-line interfaces than other groups, thus making alternatives from them is -a priority. Secondly, the other types of actor (Constitution Committee member +a priority. Secondly, the other types of actor (constitution committee member and SPOs) are identified by different credentials than Ada holders and DReps, -making their integration in this specification complex. These alternative +making their integration in this specification more complex. These alternative credentials are unlikely to be stored within standard wallet software which may interface with this API. Thirdly, Ada holders and DReps likely represent the majority of participants thus we aim to cast a wide net with this specification. -// TODO: why not support CC certs / pool certs +#### Unsupported Items + +In this specification we have placed explicit boundaries on what should not be +supported with `.signTx()`. Those being +[stake pool certificates](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L292-#L293), +genesis key delegation, MIR certificates and +[constitutional committee certificates](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L308-#L309). + +From speaking to CIP-30 implementors it seems reasonable that there does not +existing implementations or motivation to support stake pool certificates via +wallet web bridges. This is because stake pool operators much prefer the utility +and security advantages not operating via light wallets. Due to the +[Lack of Specificity](#lack-of-specificity) of CIP-30 we felt it necessary to +explicitly state the lack of support in this extension. + +Genesis key delegation and move instantaneous reward certificates (see in +[Shelley spec](https://github.com/input-output-hk/cardano-ledger/blob/0738804155245062f05e2f355fadd1d16f04cd56/shelley-ma/shelley-ma-test/cddl-files/shelley-ma.cddl#L117#L118)) +are not supported here because they have been depreciated in the Conway Ledger +Era. Furthermore, due to the lack of accessibility (require access to genesis +keys) for these certificates it is extremely unlikely any CIP-30 implementations +supported these. + +[Constitutional committee certificates](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L308-#L309) +are not supported by this specification's `.signTx()` for two reasons. First, +this specification is only focussed on the need's of Ada holders and DReps. +Secondly, the credentials used by the constitutional committee, are a hot and +cold key setup. Hot and cold keys are not suited for standard light wallets. ### The Role of the Wallet @@ -567,8 +591,14 @@ submission. #### Transaction Inspection -// TODO: add in discussion from hacakthon + scope of this CIP is not wallet best -practices +In a previous design we had stipulated the precise information that must be +shown to user by wallets at signature time. This was discussed during the +wallets and tooling hackathon and consensus was reached that is not the place of +these APIs to prescribe such details to wallets. Rather this specification +should be describing the interface between web-based stacks and wallets and not +telling wallets what UI elements should be used. It is in a wallet's best +interest to always adequately inform the user, with varying levels of detail +based on the wallet's discretion. #### Transaction Construction @@ -595,6 +625,19 @@ functionality is limited in scope. Although it does offer generic functions, these cannot satisfy the problem that this proposal tackles in a backwards compatible manner. Thus extending it's functionality is a necessity. +#### Lack of Specificity + +The CIP-30 specification has required amendments to add clarification to it's +ambiguity. There is further ambiguity around what is and is not supported via +`.signTx()`. The specification does not explicitly list the transaction +artifacts wallets has to be able to inspect and witness. Whilst for most use +cases this is likely fine and has served the community well. We forsee issues +around large ledger upgrades which introduce new types of transaction fields and +certificate. Without explicit mention of what is and is not supported deltas +between expected and actual functionality become common and hazardous. This is +why we choose to explicitly list those items that wallet have to support when +complying with this API. + #### Extension Design With this specification we chose to extend CIP-30's functionalities. There would @@ -613,8 +656,12 @@ functionality offered by CIP-30. Additionally, CIP-30 offers a extensibility mechanism meaning that the initial handshake connection is defined and thus wont be needed to be defined within this specification. -// TODO: another benefit is that users can choose if a client has access to - governance items or not. +Furthermore, another benefit of utilizing the CIP-30 extensibility mechanism is +the potential for siloing of wallet capabilities between client apps. By having +to request access to each extension wallets and users are able to silo which +extensions they allow to each client application. An example of this could be +only allowing the CIP-95 API with governance related applications and not +decentralized extensions. #### Backwards Compatibility @@ -637,9 +684,10 @@ CIP-30. In this design we chose to extend the capabilities of CIP-30's `.signTx()` and `.signData()` rather than introducing new endpoints for signing and submission. -This was a result of community discussion at the wallets and tooling hackathon. -Originally we had individual endpoints for sign and submitting of DRep -registration, DRep retirement, votes, governance actions and vote delegations. +This was a result of community discussion at the wallets and tooling hackathon, +leading to a more straight forward design. Originally we had individual +endpoints for sign and submitting of DRep registration, DRep retirement, votes, +governance actions and vote delegations. Whilst individual endpoints seem like a simpler solution they would likely introduce more complexities for wallet implementors. As constraining what @@ -654,8 +702,6 @@ supplied at once. Thus client apps would be limited to a single governance artifact per transaction. This is limiting as it means users have to submit multiple transactions to achieve what is possible in one. -// TODO: full conway feature set makes more sense. - #### CIP-95 as a Conway Flag By providing _updated_ CIP-30 endpoints we essentially use the CIP-95 extension @@ -683,12 +729,22 @@ With this definition we aim to standard for all ecosystem tooling to be able to derive DRep credentials from mnemonics. This brings the benefits ecosystem standards. +#### Derivation Path + +When choosing the derivation path there were a few possible options. Initially +we chose to follow how a new key definition was done in +[CIP-36](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0036/README.md#derivation-path) +by defining a new purpose of `1718'`. This was an oversight, as defining a new +derivation purposes will likely have hardware wallet audit implications. + +// TODO: add note derivation path change + #### Why not reuse [CIP-36 Vote Keys](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0036/README.md#voting-key)? CIP-36 defines derivation path for a key pair to be used within CIP-36 style governance. The most notable user of this standard is [Project Catalyst](projectcatalyst.io), where CIP-36 vote keys are used to sign -vote transactions on the Jormungandr side-chain. +vote transactions for the Jormungandr side-chain. One suggestion is to reuse this key pair instead of defining a new key pair in DRep key. The benefits to this would be that it is easier for users and tools to @@ -706,8 +762,6 @@ the keys described here are used for more than just vote signing just the > `purpose`, this is a perhaps misleading reality and hints to the original > intension of using CIP-36 vote keys for Cardano's Voltaire. -// TODO: add note derivation path change - ### Multi-stake Key Support Although @@ -732,9 +786,18 @@ generally prefer to use more advanced wallet tooling rather than relying on interaction with web-based stacks, thus it is not even certain DAOs would want to use such a standard. -#### Raw Keys +#### Encoding -// TODO: why raw keys, not encoded and not addresses +Unlike the CIP-30 specification we have made an decision, where possible to +represent keys as raw hex rather than encoded representations. We believe that +it is not the role of the wallet to encode such credentials, encoding needs +should be at the application's discretion. Introducing different encodings into +this API would add unneeded complexity. + +Furthermore, in this API we chose to return public keys over key-hashes or +addresses. Again we believe wallets should just serve public key information and +it is up to the application to encode and derive addresses as needed. This +simplifies the overall design and makes implementations easier for wallets. ### Backwards Compatibility @@ -744,21 +807,17 @@ wallet implementors. #### CIP-62? [CIP-62? | Cardano dApp-Wallet Web Bridge Catalyst Extension](https://github.com/cardano-foundation/CIPs/pull/296) -is another extension to the CIP-30 API, this proposal is independent of this. -This specification does not rely on any of the implementation defined in +is another extension to the CIP-30 API, this proposal is independent of CIP-95. +The CIP-95 specification does not rely on any of the implementation defined in CIP-62?. We have attempted to avoid any collisions of naming between these -proposals, this was done to make wallet implementations more straight forward -for wallets implementing both APIs. +proposals, this was motivated by a desire to make wallet implementations more +straight forward for wallets implementing both APIs. ### Open Questions - The burden of transaction building to be placed on dApps or wallets? - As we are replacing CIP-30's signTx it makes sense to follow the same flow and place the burden on the client applications. -- Move DRep key definitions into a CIP which is dedicated to describing - CIP-1694 related credentials? or CIP-1852? - - Yes, this is a cleaner approach, as we keep the purity of this proposal to - being a wallet web bridge. - Does supporting governance action submission a necessary burden for the scope of this proposal? - Since moving burden of transaction construction from wallet to app, this @@ -780,18 +839,21 @@ for wallets implementing both APIs. addresses as it gives the client application more freedom. - Should this proposal cater for non-key-based stake credential? - We can leave this for a future iteration. -- Should there be a way for the optional sharing of governance state, from - wallet to client? +- Move DRep key definitions be moved into another CIP? + - Yes, this is a cleaner approach, as we keep the purity of this proposal to + being a wallet web bridge. +- Should there be a way for the optional sharing of governance state, from + wallet to client? - How to represent DRep keys in signData endpoint? +- Should DRep key be moved into CIP-1852? ## Path to Active ### Acceptance Criteria -- [ ] Resolve all [open questions](#open-questions). -- [ ] The interface is implemented and supported by various wallet providers. -- [ ] The interface is used by client applications to interact with wallets to - allow users to engage with the Conway ledger design. +- [ ] The interface is supported by three wallet providers. +- [ ] The interface is used by one web application to allow users to engage with + the Conway ledger design. ### Implementation Plan @@ -803,14 +865,9 @@ for wallets implementing both APIs. the `🥑BUILD` section (to view you have to opt-in to the Builders group). - [x] Author to engage with wallet providers for feedback. - [x] Author to run a hackathon workshop with wallet providers. - - In person and online hackathon run 2023.07.13, outcomes presented here. - - See - [CIP-95 pull request comment](https://github.com/cardano-foundation/CIPs/pull/509#issuecomment-1636103821) - with summary. -- [x] Author to provide a reference client application for wallet implementors - to be able to test against. - - See: - [Ryun1/cip95-cardano-wallet-connector](https://github.com/Ryun1/cardano-wallet-connector). + - In person and online hackathon run 2023.07.13, outcomes presented here: + [CIP-95 pull request comment](https://github.com/cardano-foundation/CIPs/pull/509#issuecomment-1636103821). +- [ ] Resolve all [Open Questions](#open-questions). ## Copyright From c5f65c455224756bdb231e53d8288bdfaba7458f Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Mon, 31 Jul 2023 21:38:27 +0100 Subject: [PATCH 24/35] added error codes and other small adjustments --- CIP-0095/README.md | 286 ++++++++++++++++++++++++++++++++------------- 1 file changed, 204 insertions(+), 82 deletions(-) diff --git a/CIP-0095/README.md b/CIP-0095/README.md index 34c34d3521..447a8adee0 100644 --- a/CIP-0095/README.md +++ b/CIP-0095/README.md @@ -198,6 +198,16 @@ extending the API (as a plain integer, without padding). For example: #### CIP-95 Data Types +#### DRepID + +```ts +type DRepID = string; +``` + +A hex-encoded string representing a registered DRep's ID which is a Blake2b-224 +hash digest of a 32 byte Ed25519 public key, as described in +[CIP-1694 Registered DReps](https://github.com/cardano-foundation/CIPs/blob/master/CIP-1694/README.md?plain=1#L386). + ##### PubDRepKey ```ts @@ -218,10 +228,92 @@ credential. ### Error Types -This specification inherits all Error Types defined in CIP-30. +For the methods described in +[Governance Extension API](#governance-extension-api), we inherent APIError, +DataSignError and TxSignError from +[CIP-30's Error Types](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030#error-types). + +> **Note** We choose to reword some descriptions from CIP-30, to improve +> clarity. + +#### [APIError](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030#apierror) + +We repurpose this error type from CIP-30, extending it's functionality. We +extend the `Refused` error code to also include the case of the extension no +longer being enabled. + +```ts +APIErrorCode { + InvalidRequest: -1, + InternalError: -2, + Refused: -3, + AccountChange: -4, +} +type APIError { + code: APIErrorCode, + info: string +} +``` + +- `InvalidRequest` - Inputs do not conform to this specification or are + otherwise invalid. +- `InternalError` - An internal wallet error occurred during execution of this + API call. +- `Refused` - The request was refused due to lack of access - e.g. wallet + disconnects or extension is no longer enabled. +- `AccountChange` - The account has changed. The client application should call + `wallet.enable()` to reestablish connection to the new account. The wallet + should not ask for confirmation as the user was the one who initiated the + account change in the first place. + +#### [TxSignError](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030#txsignerror) + +We repurpose this error type from CIP-30, extending it's functionality. We +extend the `ProofGeneration` error code to also include cases where DRep secret +key is not available. We also add one new error code `DepreciatedCertificate`. + +```ts +TxSignErrorCode = { + ProofGeneration: 1, + UserDeclined: 2, + DepreciatedCertificate: 3, +}; +type TxSignError = { + code: TxSignErrorCode; + info: String; +}; +``` + +- `ProofGeneration` - User has accepted the transaction sign, but the wallet was + unable to sign the transaction. This is because the wallet does have some of + the private keys required. +- `UserDeclined` - User declined to sign the transaction. +- `DepreciatedCertificate` - Returned regardless of user consent if the + transaction contains a depreciated certificate. + +#### [DataSignError](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030#datasignerror) + +We repurpose this error type from CIP-30, extending it's functionality. We +extend the `ProofGeneration` error code to also include cases where DRep secret +key is not available. + +```ts +DataSignErrorCode { + ProofGeneration: 1, + AddressNotPK: 2, + UserDeclined: 3, +} +type DataSignError = { + code: DataSignErrorCode, + info: String +} +``` -// TODO: add more, once specification matured and avoid collisions with -CIP-62?'s extended errors. +- `ProofGeneration` - Wallet could not sign the data; because the wallet does + not have the secret key to the associated with the address or DRep ID. +- `AddressNotPK` - Address was not a P2PK address and thus had no SK associated + with it. +- `UserDeclined` - User declined to sign the data. ### Governance Extension API @@ -240,8 +332,6 @@ described within #### `api.getPubDRepKey(): Promise` -Errors: `APIError` - The connected wallet account provides the account's public DRep Key, derivation as described in [DRep Key](#DRep-key). @@ -252,9 +342,18 @@ interactions, i.e. if a user has registered to be a DRep. The wallet account's public DRep Key. -#### `api.getActivePubStakeKeys(): Promise` +##### Errors -Errors: `APIError` + +| Error Type | Error Code | Return Condition | +| ------------ | ---------------- | ----------------------------------------------------------------------------------------- | +| `APIError` | `InvalidRequest` | Returned if a input parameter is passed. | +| `APIError` | `InternalError` | Returned if there is a generic internal error occurred during execution of this API call. | +| `APIError` | `Refused` | Returned if there is a refusal, could be wallet disconnection or extension is revoked. | +| `APIError` | `AccountChange` | Returned if wallet has changed account, meaning connection should be reestablished. | + + +#### `api.getActivePubStakeKeys(): Promise` The connected wallet account's active public stake keys (with keys which are being used for staking), if the wallet tracks the keys that are used for @@ -269,31 +368,35 @@ stake credentials to provided at once for the case of An array of the connected user's active public stake keys. -#### `api.signTx(tx: cbor, partialSign: bool = false): Promise>` +##### Errors + + +| Error Type | Error Code | Return Condition | +| ------------ | ---------------- | ----------------------------------------------------------------------------------------- | +| `APIError` | `InvalidRequest` | Returned if a input parameter is passed. | +| `APIError` | `InternalError` | Returned if there is a generic internal error occurred during execution of this API call. | +| `APIError` | `Refused` | Returned if there is a refusal, could be wallet disconnection or extension is revoked. | +| `APIError` | `AccountChange` | Returned if wallet has changed account, meaning connection should be reestablished. | + -Errors: `APIError`, `TxSignError` +#### `api.signTx(tx: cbor, partialSign: bool = false): Promise>` This endpoint requests the wallet to inspect and provide appropriate witnesses for a supplied transaction. The wallet should articulate this request from client application in a explicit and highly informative way. -Here we add to the capabilities of +Here we extend the capabilities of [CIP-30's `.signTx()`](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0030/README.md#apisigntxtx-cbortransaction-partialsign-bool--false-promisecbortransaction_witness_set). To allow signatures with `voting_credential` and recognition of Conway ledger era transaction fields and certificates. -CIP-30 is **not** descriptive in what supporting wallets should be able to -recognize and sign, we believe this adds considerable unneeded ambiguity. Thus -for this extension we wish explicitly define what wallets have to be able to -recognize and sign. - -##### Expected Support +##### Expected Inspection Support As read from [cardano-ledger Conway _draft_ specification](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl). -Supporting wallets should be able to recognize, inspect and correctly witness -all the following certificates and data contained in transaction body, in any +Supporting wallets should be able to recognize and inspect +all the following certificates and data contained in transaction bodies, in any combination. | Supported Pre-Conway Certificates | @@ -301,18 +404,22 @@ combination. | `stake_registration` | | `stake_deregistration` | | `stake_delegation` | +| `pool_registration` | +| `pool_retirement` | -| Supported Conway Certificates | -| ----------------------------- | -| `reg_cert` | -| `unreg_cert` | -| `vote_deleg_cert` | -| `stake_vote_deleg_cert` | -| `stake_reg_deleg_cert` | -| `vote_reg_deleg_cert` | -| `stake_vote_reg_deleg_cert` | -| `reg_drep_cert` | -| `unreg_drep_cert` | +| Supported Conway Certificates | +| ------------------------------- | +| `reg_cert` | +| `unreg_cert` | +| `vote_deleg_cert` | +| `stake_vote_deleg_cert` | +| `stake_reg_deleg_cert` | +| `vote_reg_deleg_cert` | +| `stake_vote_reg_deleg_cert` | +| `reg_committee_hot_key_cert` | +| `unreg_committee_hot_key_cert` | +| `reg_drep_cert` | +| `unreg_drep_cert` | | Supported Conway Transaction Field Data | | --------------------------------------- | @@ -321,26 +428,20 @@ combination. All other potential transaction field inclusions [0-18](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L54-#L69), -should be able to be recognized and supported wallets. +should be able to be recognized by supporting wallets. -##### Not Supported +##### Unsupported Inspection -Without inspecting all CIP-30 implementations it is not possible to know what -certifies they support, from surveying a couple implementors, the following is -reasonable. Even if current CIP-30 implementations support the following -certificates, when the CIP-95 flag is enabled they should not. +In the Conway ledger era two certificate types are depreciated `genesis_key_delegation` and `move_instantaneous_rewards_cert`. If the wallet receives a transaction containing a depreciated certificate it should return a `TxSignError` with an error code of `DepreciatedCertificate`. -| Unsupported Pre-Conway Certificates | -| -------------------------------------------------------- | -| `pool_registration` | -| `pool_retirement` | -| `genesis_key_delegation` (deprecated in Conway) | -| `move_instantaneous_rewards_cert` (deprecated in Conway) | +| Unsupported Pre-Conway Certificates | +| ----------------------------------- | +| `genesis_key_delegation` | +| `move_instantaneous_rewards_cert` | -| Unsupported Conway Certificates | -| ------------------------------- | -| `reg_committee_hot_key_cert` | -| `unreg_committee_hot_key_cert` | +##### Expected Witness Support + +Although constitutional committee certificates and stake pool certificates should be able to be recognized they should not be able to be correctly witnessed by wallets. Wallet's should only support witnesses using Payment, Stake and DRep keys. ##### Returns @@ -350,26 +451,36 @@ endpoint before building the final transaction. ##### Errors -If `partialSign` is true, the wallet only tries to sign what it can. If -`partialSign` is false and the wallet could not sign the entire transaction, -`TxSignError` shall be returned with the `ProofGeneration` code. Likewise if the -user declined in either case it shall return the `UserDeclined` code. - -#### `api.signData(addr: Address, payload: Bytes): Promise` + +| Error Type | Error Code | `partialSign` | Return Condition | +| ------------- | ------------------------ | ----------------- | --------------------------------------------------------------------------------------------------------------------------------- | +| `APIError` | `InvalidRequest` | `true` or `false` | Returned if an erroneous parameter is passed, wrong type or too many etc. | +| `APIError` | `InternalError` | `true` or `false` | Returned if there is a generic internal error occurred during execution of this API call. | +| `APIError` | `Refused` | `true` or `false` | Returned if there is a refusal, could be wallet disconnection or the extension is revoked. | +| `APIError` | `AccountChange` | `true` or `false` | Returned if wallet has changed account, meaning connection should be reestablished. | +| `TxSignError` | `ProofGeneration` | `false` | Returned if user has accepted transaction to sign, but the wallet is unable to sign because it does not have the required key(s). | +| `TxSignError` | `UserDeclined` | `true` or `false` | Returned if user has declined to sign the transaction. | +| `TxSignError` | `DepreciatedCertificate` | `true` or `false` | Returned regardless of user consent if the transaction contains a depreciated certificate. | + + +If `partialSign` is `true`, the wallet only tries to sign what it can. If +`partialSign` is `false` and the wallet could not sign the entire transaction, +`TxSignError` shall be returned with the `ProofGeneration` code. + +#### `api.signData(addr: Address | DRepID, payload: Bytes): Promise` Errors: `APIError`, `DataSignError` -This endpoint requests the wallet to inspect and provide a signature for a -supplied data. The wallet should articulate this request from client application +This endpoint requests the wallet to inspect and provide a DataSignature for the supplied data. The wallet should articulate this request from client application in a explicit and highly informative way. -Here we add to the capabilities of +Here we extend the capabilities of [CIP-30's `.signData()`](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0030/README.md#apisigndataaddr-address-payload-bytes-promisedatasignaturet). -To allow for signatures using `voting_credential`. +To allow for signatures using DRep keys. This endpoint utilizes the -[CIP-0008 signing spec](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0008/CIP-0008.md) -for standardization/safety reasons. It allows the dApp to request the user to +[CIP-0008 | Message Signing](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0008/README.md) +for standardization/safety reasons. It allows the client app to request the user to sign a payload conforming to said spec. ##### Supported Credentials @@ -378,20 +489,20 @@ Here we define how each key is identified by an `Address` in relation to [CIP-0019 | Cardano Addresses](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0019/README.md), these are all Shelley key-hash-based addresses. +We allow for `DRepID` to be passed in the `addr` field to signal signature using the associated DRep key. + To construct an address for DRep Key, the client application should construct a [type 6 address](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0019/CIP-0019-cardano-addresses.abnf#L7C8-L7C93). Using an appropriate [Network Tag](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0019/CIP-0019-cardano-addresses.abnf#L13) and a hash of a public DRep Key. -// TODO: Change how to identify DRep Key? - | Key | Identifying `addr` | | ----------- | ------------------ | | Payment Key | Address types: [0](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0019/CIP-0019-cardano-addresses.abnf#L1), [2](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0019/CIP-0019-cardano-addresses.abnf#L3), [4](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0019/CIP-0019-cardano-addresses.abnf#L5), [6](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0019/CIP-0019-cardano-addresses.abnf#L7C27-L7C72). | | Stake Key | Address type: [14](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0019/CIP-0019-cardano-addresses.abnf#L10). | -| DRep Key | Denoted by constructed of type [6](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0019/CIP-0019-cardano-addresses.abnf#L7C27-L7C72). | +| DRep Key | [`DRepID`](#drepid) | These keys will be used to sign the `COSE_Sign1`'s `Sig_structure` with the @@ -422,11 +533,19 @@ hex-encoded CBOR bytes of a `COSE_Key` structure with the following headers set: ##### Errors -If the payment key for `addr` is not a P2Pk address then `DataSignError` will be -returned with code `AddressNotPK`. `ProofGeneration` shall be returned if the -wallet cannot generate a signature (i.e. the wallet does not own the requested -payment private key), and `UserDeclined` will be returned if the user refuses -the request. + + +| Error Type | Error Code | Return Condition | +| --------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------ | +| `APIError` | `InvalidRequest` | Returned if a input parameter is passed. | +| `APIError` | `InternalError` | Returned if there is a generic internal error occurred during execution of this API call. | +| `APIError` | `Refused` | Returned if there is a refusal, could be wallet disconnection or extension is revoked. | +| `APIError` | `AccountChange` | Returned if wallet has changed account, meaning connection should be reestablished. | +| `DataSignError` | `ProofGeneration` | Returned if user has accepted to sign, but wallet could not sign the data; because the wallet does not have the required keys. | +| `DataSignError` | `AddressNotPK` | Returned if Address was not a P2PK address and thus had no SK associated with it. | +| `DataSignError` | `UserDeclined` | Returned if the user declined to sign the data. | + + ### Examples of Flows @@ -558,24 +677,18 @@ majority of participants thus we aim to cast a wide net with this specification. #### Unsupported Items In this specification we have placed explicit boundaries on what should not be -supported with `.signTx()`. Those being -[stake pool certificates](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L292-#L293), -genesis key delegation, MIR certificates and -[constitutional committee certificates](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L308-#L309). +supported with `.signTx()`. Those being not witnessing +[stake pool](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L292-#L293) +or +[constitutional committee](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L308-#L309), +certificates and not inspecting genesis key delegation or MIR certificates. From speaking to CIP-30 implementors it seems reasonable that there does not -existing implementations or motivation to support stake pool certificates via -wallet web bridges. This is because stake pool operators much prefer the utility -and security advantages not operating via light wallets. Due to the -[Lack of Specificity](#lack-of-specificity) of CIP-30 we felt it necessary to -explicitly state the lack of support in this extension. - -Genesis key delegation and move instantaneous reward certificates (see in -[Shelley spec](https://github.com/input-output-hk/cardano-ledger/blob/0738804155245062f05e2f355fadd1d16f04cd56/shelley-ma/shelley-ma-test/cddl-files/shelley-ma.cddl#L117#L118)) -are not supported here because they have been depreciated in the Conway Ledger -Era. Furthermore, due to the lack of accessibility (require access to genesis -keys) for these certificates it is extremely unlikely any CIP-30 implementations -supported these. +exist implementations or motivation to support witnessing stake pool +certificates via wallet web bridges. This is because stake pool operators much +prefer the utility and security advantages not operating via light wallets. Due +to the [Lack of Specificity](#lack-of-specificity) of CIP-30 we felt it +necessary to explicitly state the lack of support in this extension. [Constitutional committee certificates](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L308-#L309) are not supported by this specification's `.signTx()` for two reasons. First, @@ -583,6 +696,13 @@ this specification is only focussed on the need's of Ada holders and DReps. Secondly, the credentials used by the constitutional committee, are a hot and cold key setup. Hot and cold keys are not suited for standard light wallets. +Genesis key delegation and move instantaneous reward certificates (see in +[Shelley spec](https://github.com/input-output-hk/cardano-ledger/blob/0738804155245062f05e2f355fadd1d16f04cd56/shelley-ma/shelley-ma-test/cddl-files/shelley-ma.cddl#L117#L118)) +are not supported here because they have been depreciated in the Conway ledger +era. Furthermore, due to the lack of accessibility (require access to genesis +keys) for these certificates it is extremely unlikely any CIP-30 implementations +supported these. + ### The Role of the Wallet The endpoints specified here aim to maintain the role of the wallet as: sharing @@ -737,7 +857,8 @@ we chose to follow how a new key definition was done in by defining a new purpose of `1718'`. This was an oversight, as defining a new derivation purposes will likely have hardware wallet audit implications. -// TODO: add note derivation path change +// TODO: add note derivation path change when/if this is moved to a separate +CIP. #### Why not reuse [CIP-36 Vote Keys](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0036/README.md#voting-key)? @@ -868,6 +989,7 @@ straight forward for wallets implementing both APIs. - In person and online hackathon run 2023.07.13, outcomes presented here: [CIP-95 pull request comment](https://github.com/cardano-foundation/CIPs/pull/509#issuecomment-1636103821). - [ ] Resolve all [Open Questions](#open-questions). +- [ ] Author to produce a set of test vectors for wallets to test against. ## Copyright From 7e660cecb8341f3d7dd33a761ff71ec5595a05d7 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Tue, 1 Aug 2023 09:08:19 +0100 Subject: [PATCH 25/35] fix naming --- CIP-0095/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIP-0095/README.md b/CIP-0095/README.md index 447a8adee0..3bb8e13c4d 100644 --- a/CIP-0095/README.md +++ b/CIP-0095/README.md @@ -48,7 +48,7 @@ insights: - Alex Apeldoorn - Lace - Michal Szorad - Yoroi - Javier Bueno - Yoroi -- Ed Eykholt - Yoroi +- Ed Eykholt - Blocktrust - Vladimir Volek - Five Binaries - Marek Mahut - Five Binaries - Markus Gufler - Cardano Foundation From 04b7ad1ea5e7bf72aa27c85605cea3c425748f47 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Wed, 2 Aug 2023 23:03:14 +0100 Subject: [PATCH 26/35] added name spacing of endpoints --- CIP-0095/README.md | 17 ++++++++++++----- CIP-1852/README.md | 2 +- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/CIP-0095/README.md b/CIP-0095/README.md index 3bb8e13c4d..7c8a2dcb8b 100644 --- a/CIP-0095/README.md +++ b/CIP-0095/README.md @@ -317,7 +317,10 @@ type DataSignError = { ### Governance Extension API -These are the CIP-95 methods that should be returned as part of the API object. +These are the CIP-95 methods that should be returned as part of the API object, namespaced by `cip95` without any leading zeros. + +For example: +`api.cip95.getPubDRepKey()` To access these functionalities a client application must present this CIP-95 extension object: @@ -330,7 +333,7 @@ This extension object is provided during the initial handshake procedure as described within [CIP-30's Initial API](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030#cardanowalletnameenable-extensions-extension----promiseapi). -#### `api.getPubDRepKey(): Promise` +#### `api.cip95.getPubDRepKey(): Promise` The connected wallet account provides the account's public DRep Key, derivation as described in [DRep Key](#DRep-key). @@ -353,7 +356,7 @@ The wallet account's public DRep Key. | `APIError` | `AccountChange` | Returned if wallet has changed account, meaning connection should be reestablished. | -#### `api.getActivePubStakeKeys(): Promise` +#### `api.cip95.getActivePubStakeKeys(): Promise` The connected wallet account's active public stake keys (with keys which are being used for staking), if the wallet tracks the keys that are used for @@ -379,7 +382,7 @@ An array of the connected user's active public stake keys. | `APIError` | `AccountChange` | Returned if wallet has changed account, meaning connection should be reestablished. | -#### `api.signTx(tx: cbor, partialSign: bool = false): Promise>` +#### `api.cip95.signTx(tx: cbor, partialSign: bool = false): Promise>` This endpoint requests the wallet to inspect and provide appropriate witnesses for a supplied transaction. The wallet should articulate this request from @@ -467,7 +470,7 @@ If `partialSign` is `true`, the wallet only tries to sign what it can. If `partialSign` is `false` and the wallet could not sign the entire transaction, `TxSignError` shall be returned with the `ProofGeneration` code. -#### `api.signData(addr: Address | DRepID, payload: Bytes): Promise` +#### `api.cip95.signData(addr: Address | DRepID, payload: Bytes): Promise` Errors: `APIError`, `DataSignError` @@ -547,6 +550,10 @@ hex-encoded CBOR bytes of a `COSE_Key` structure with the following headers set: +### Versioning of this proposal + +TODO: explain versioning approach + ### Examples of Flows #### Connection and Login diff --git a/CIP-1852/README.md b/CIP-1852/README.md index 634f25ac69..369056f081 100644 --- a/CIP-1852/README.md +++ b/CIP-1852/README.md @@ -66,4 +66,4 @@ The `role` can however be extending with new roles so long as they have no overl ## Copyright -This CIP is licensed under [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/legalcode) +This CIP is licensed under [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/legalcode) \ No newline at end of file From 6deda41afc567aad19db576029bd0eba62a96104 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Thu, 3 Aug 2023 13:33:56 +0100 Subject: [PATCH 27/35] Fixed change to CIP-1852 --- CIP-1852/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIP-1852/README.md b/CIP-1852/README.md index 369056f081..634f25ac69 100644 --- a/CIP-1852/README.md +++ b/CIP-1852/README.md @@ -66,4 +66,4 @@ The `role` can however be extending with new roles so long as they have no overl ## Copyright -This CIP is licensed under [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/legalcode) \ No newline at end of file +This CIP is licensed under [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/legalcode) From 2bf97016b1513b497d404e8a3611238eea636944 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Fri, 4 Aug 2023 17:47:02 +0100 Subject: [PATCH 28/35] added versioning discussion --- CIP-0005/README.md | 3 --- CIP-0095/README.md | 9 +++++---- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/CIP-0005/README.md b/CIP-0005/README.md index e232603371..b900a97a91 100644 --- a/CIP-0005/README.md +++ b/CIP-0005/README.md @@ -51,8 +51,6 @@ We define the following set of common prefixes with their corresponding semantic | `addr_shared_vk` | CIP-1854's address verification key | Ed25519 public key | | `addr_shared_xsk` | CIP-1854's address extended signing key | Ed25519-bip32 extended private key | | `addr_shared_xvk` | CIP-1854's address extended verification key | Ed25519 public key with chain code | -| `drep_sk` | CIP-0095's DRep vote signing key | Ed25519 private key | -| `drep_vk` | CIP-0095's DRep vote verification key | Ed25519 public key | | `gov_sk` | Governance vote signing key | Ed25519 private key | | `gov_vk` | Governance vote verification key | Ed25519 public key | | `cvote_sk` | CIP-36's vote signing key | Ed25519 private key | @@ -95,7 +93,6 @@ We define the following set of common prefixes with their corresponding semantic | `stake_vkh` | Stake address verification key hash | blake2b\_224 digest of a delegation verification key | | `stake_shared_vkh` | Shared stake address verification key hash | blake2b\_224 digest of a delegation verification key | | `req_signer_vkh` | Required signer verification key hash | blake2b\_224 digest of a required signer verification key | -| `drep_id` | CIP-1694 DRep ID | blake2b\_224 digest of a DRep's voting credential | | `vrf_vkh` | VRF verification key hash | blake2b\_256 digest of a VRF verification key | | `datum` | Output datum hash | blake2b\_256 digest of output datum | | `script_data` | Script data hash | blake2b\_256 digest of script data | diff --git a/CIP-0095/README.md b/CIP-0095/README.md index 7c8a2dcb8b..ea542fd192 100644 --- a/CIP-0095/README.md +++ b/CIP-0095/README.md @@ -552,7 +552,9 @@ hex-encoded CBOR bytes of a `COSE_Key` structure with the following headers set: ### Versioning of this proposal -TODO: explain versioning approach +Whilst this CIP is in it's unmerged proposed state, it remains very fluid and substantial changes can happen, so I would advise against any implementation. Once more feedback is received, maturing this design I think implementations can safely emerge, alongside this proposal's merger into the CIPs repository. Once merged only small necessary changes should be made, ideally in backwards compatible fashion. + +This, in tandem with, maturing implementations should move this proposal to an active state where only small backwards compatible changes can be made. If any large changes are needed once active then a new proposal should be made to replace this one. This I believe aligns with the (new) extendibility design of CIP-0030. ### Examples of Flows @@ -847,6 +849,8 @@ clients are aware of this functionality. ### DRep Key +// todo: once DRep CIP added + We chose to introduce the concept of a DRep Key, building on top of CIP-1694, this we see as a necessary step for wallet implementors. By setting a (hierarchical) deterministic derivation path it enables restorability from a @@ -864,9 +868,6 @@ we chose to follow how a new key definition was done in by defining a new purpose of `1718'`. This was an oversight, as defining a new derivation purposes will likely have hardware wallet audit implications. -// TODO: add note derivation path change when/if this is moved to a separate -CIP. - #### Why not reuse [CIP-36 Vote Keys](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0036/README.md#voting-key)? CIP-36 defines derivation path for a key pair to be used within CIP-36 style From fbc5fcbb127313ccfd2a30376145f63627f3afd9 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Mon, 7 Aug 2023 22:11:40 +0100 Subject: [PATCH 29/35] misc tidy --- CIP-0095/README.md | 79 ++++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 38 deletions(-) diff --git a/CIP-0095/README.md b/CIP-0095/README.md index ea542fd192..4377f5fc91 100644 --- a/CIP-0095/README.md +++ b/CIP-0095/README.md @@ -91,17 +91,12 @@ within CIP-30. // TODO: Move this into a more appropriate **separate** CIP. The Conway ledger era introduces a new _first class_ credential in -[`voting_credential`](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L329). +[`voting_credential`](https://github.com/input-output-hk/cardano-ledger/blob/d42dbc00b27ff2731211b45f22cec172a070e3e6/eras/conway/test-suite/cddl-files/conway.cddl#L331). This is used to identify registered DReps on-chain, via their certificates and votes. -CIP-1694 does not define a derivation path for these registered DRep -credentials, here we propose the introduction of DRep Keys to be used as DRep -`voting_credential`s for (non-script) registered DReps. - -The methods described here should not be considered the definitive method of -generating DRep credentials. Rather these methods should be employed by wallets -to derive keys for non-script registered DReps. +Here we introduction of DRep Keys to be used to create `voting_credential`s for +(non-script) registered DReps. #### Derivation @@ -110,16 +105,13 @@ the [CIP-1852 | HD (Hierarchy for Deterministic) Wallets for Cardano](https://github.com/cardano-foundation/CIPs/blob/master/CIP-1852/README.md) standard. -To differentiate DRep credentials from other Cardano keys the derivation path -must follow: - -`m / 1694' / 1815' / account' / 1718 / address_index` +To differentiate DRep keys from other Cardano keys the derivation path must +follow: -> **Note** `1718` was the year that François-Marie adopted the pseudonym -> Voltaire. +`m / 1852' / 1815' / account' / 3 / address_index` -We strongly suggest that a maximum of one set of DRep credentials should be -associated with one wallet account, this can be achieved by only ever setting +We strongly suggest that a maximum of one set of DRep keys should be associated +with one wallet account, this can be achieved by only ever setting `address_index=0`. This avoids the need for DRep Key discovery. We believe the overhead that would be introduced by "multi-DRep" accounts is an @@ -135,17 +127,19 @@ Bech32 prefixes of `drep_sk` and `drep_vk` should be used, as described in Examples of acceptable `keyType`s for supporting tools: -| `keyType` | Description | -| ---------------------------------- | --------------------- | -| `CIP95DRepSigningKey_ed25519` | DRep Signing Key | -| `CIP95DRepVerificationKey_ed25519` | DRep Verification Key | +| `keyType` | Description | +| ------------------------------------------- | --------------------- | +| `DRepSigningKey_ed25519` | DRep Signing Key | +| `DRepExtendedSigningKey_ed25519_bip32` | DRep Signing Key | +| `DRepVerificationKey_ed25519` | DRep Verification Key | +| `DRepExtendedVerificationKey_ed25519_bip32` | DRep Verification Key | For hardware implementations: -| `keyType` | Description | -| ---------------------------------- | ------------------------------ | -| `CIP95DRepVerificationKey_ed25519` | Hardware DRep Verification Key | -| `CIP95DRepHWSigningFile_ed25519` | Hardware DRep Signing File | +| `keyType` | Description | +| ----------------------------- | ------------------------------ | +| `DRepVerificationKey_ed25519` | Hardware DRep Verification Key | +| `DRepHWSigningFile_ed25519` | Hardware DRep Signing File | ### Data Types @@ -206,7 +200,7 @@ type DRepID = string; A hex-encoded string representing a registered DRep's ID which is a Blake2b-224 hash digest of a 32 byte Ed25519 public key, as described in -[CIP-1694 Registered DReps](https://github.com/cardano-foundation/CIPs/blob/master/CIP-1694/README.md?plain=1#L386). +[CIP-1694 Registered DReps](https://github.com/cardano-foundation/CIPs/blob/430f64d3e86dd67903a6bf1e611c06e5343072f3/CIP-1694/README.md#registered-dreps). ##### PubDRepKey @@ -317,10 +311,10 @@ type DataSignError = { ### Governance Extension API -These are the CIP-95 methods that should be returned as part of the API object, namespaced by `cip95` without any leading zeros. + To access these functionalities a client application must present this CIP-95 extension object: @@ -333,7 +327,7 @@ This extension object is provided during the initial handshake procedure as described within [CIP-30's Initial API](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030#cardanowalletnameenable-extensions-extension----promiseapi). -#### `api.cip95.getPubDRepKey(): Promise` +#### `api.getPubDRepKey(): Promise` The connected wallet account provides the account's public DRep Key, derivation as described in [DRep Key](#DRep-key). @@ -356,7 +350,7 @@ The wallet account's public DRep Key. | `APIError` | `AccountChange` | Returned if wallet has changed account, meaning connection should be reestablished. | -#### `api.cip95.getActivePubStakeKeys(): Promise` +#### `api.getActivePubStakeKeys(): Promise` The connected wallet account's active public stake keys (with keys which are being used for staking), if the wallet tracks the keys that are used for @@ -382,7 +376,7 @@ An array of the connected user's active public stake keys. | `APIError` | `AccountChange` | Returned if wallet has changed account, meaning connection should be reestablished. | -#### `api.cip95.signTx(tx: cbor, partialSign: bool = false): Promise>` +#### `api.signTx(tx: cbor, partialSign: bool = false): Promise>` This endpoint requests the wallet to inspect and provide appropriate witnesses for a supplied transaction. The wallet should articulate this request from @@ -470,7 +464,7 @@ If `partialSign` is `true`, the wallet only tries to sign what it can. If `partialSign` is `false` and the wallet could not sign the entire transaction, `TxSignError` shall be returned with the `ProofGeneration` code. -#### `api.cip95.signData(addr: Address | DRepID, payload: Bytes): Promise` +#### `api.signData(addr: Address | DRepID, payload: Bytes): Promise` Errors: `APIError`, `DataSignError` @@ -552,9 +546,18 @@ hex-encoded CBOR bytes of a `COSE_Key` structure with the following headers set: ### Versioning of this proposal -Whilst this CIP is in it's unmerged proposed state, it remains very fluid and substantial changes can happen, so I would advise against any implementation. Once more feedback is received, maturing this design I think implementations can safely emerge, alongside this proposal's merger into the CIPs repository. Once merged only small necessary changes should be made, ideally in backwards compatible fashion. +Whilst this CIP is in it's unmerged proposed state, it remains very fluid and +substantial changes can happen, so I would advise against any implementation. +Once more feedback is received, maturing this design I think implementations can +safely emerge, alongside this proposal's merger into the CIPs repository. Once +merged only small necessary changes should be made, ideally in backwards +compatible fashion. -This, in tandem with, maturing implementations should move this proposal to an active state where only small backwards compatible changes can be made. If any large changes are needed once active then a new proposal should be made to replace this one. This I believe aligns with the (new) extendibility design of CIP-0030. +This, in tandem with, maturing implementations should move this proposal to an +active state where only small backwards compatible changes can be made. If any +large changes are needed once active then a new proposal should be made to +replace this one. This I believe aligns with the (new) extendibility design of +CIP-0030. ### Examples of Flows @@ -590,7 +593,7 @@ wallet has already been made via `cardano.{wallet-name}.enable({ "cip": 95 })`. 2. **Construct Delegation:** The client application uses CIP-30 endpoints to query the wallet's UTxO set and payment address. A DRep delegation certificate - ([`vote_deleg_cert`](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L3016)) + ([`vote_deleg_cert`](https://github.com/input-output-hk/cardano-ledger/blob/d42dbc00b27ff2731211b45f22cec172a070e3e6/eras/conway/test-suite/cddl-files/conway.cddl#L302)) is constructed by the app using the chosen DRep's ID and wallet's stake credential. A transaction is constructed to send 1 ADA to the wallet's payment address with the certificate included in the transaction body. @@ -620,7 +623,7 @@ a registered DRep. 2. **Construct Registration**: The client application uses CIP-30 endpoints to query the wallet's UTxO set and payment address. A DRep registration certificate - ([`reg_drep_cert`](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L310)) + ([`reg_drep_cert`](https://github.com/input-output-hk/cardano-ledger/blob/d42dbc00b27ff2731211b45f22cec172a070e3e6/eras/conway/test-suite/cddl-files/conway.cddl#L311)) is constructed by the app using the wallet's DRep ID and the provided metadata anchor. A transaction is constructed to send 1 ADA to the wallet's payment address with the certificate included in the transaction body. @@ -687,9 +690,9 @@ majority of participants thus we aim to cast a wide net with this specification. In this specification we have placed explicit boundaries on what should not be supported with `.signTx()`. Those being not witnessing -[stake pool](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L292-#L293) +[stake pool](https://github.com/input-output-hk/cardano-ledger/blob/d42dbc00b27ff2731211b45f22cec172a070e3e6/eras/conway/test-suite/cddl-files/conway.cddl#L292C1-L294C43) or -[constitutional committee](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L308-#L309), +[constitutional committee](https://github.com/input-output-hk/cardano-ledger/blob/d42dbc00b27ff2731211b45f22cec172a070e3e6/eras/conway/test-suite/cddl-files/conway.cddl#L309C1-L310C60), certificates and not inspecting genesis key delegation or MIR certificates. From speaking to CIP-30 implementors it seems reasonable that there does not @@ -699,7 +702,7 @@ prefer the utility and security advantages not operating via light wallets. Due to the [Lack of Specificity](#lack-of-specificity) of CIP-30 we felt it necessary to explicitly state the lack of support in this extension. -[Constitutional committee certificates](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L308-#L309) +[Constitutional committee certificates](https://github.com/input-output-hk/cardano-ledger/blob/d42dbc00b27ff2731211b45f22cec172a070e3e6/eras/conway/test-suite/cddl-files/conway.cddl#L309C1-L310C60) are not supported by this specification's `.signTx()` for two reasons. First, this specification is only focussed on the need's of Ada holders and DReps. Secondly, the credentials used by the constitutional committee, are a hot and From 1f75f990c4e8fdf308c3ed209bac723a84822931 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Mon, 4 Sep 2023 11:30:41 +0100 Subject: [PATCH 30/35] Update ledger design + add implementors --- CIP-0095/README.md | 116 ++++++++++++++++++++++++++------------------- 1 file changed, 66 insertions(+), 50 deletions(-) diff --git a/CIP-0095/README.md b/CIP-0095/README.md index 4377f5fc91..8fcc38c597 100644 --- a/CIP-0095/README.md +++ b/CIP-0095/README.md @@ -6,10 +6,16 @@ Status: Proposed Authors: - Ryan Williams Implementors: + - Eternl - Lace + - NuFi + - Ryan Williams + - Typhon + - Yoroi Discussions: - https://github.com/cardano-foundation/cips/pulls/509 - https://discord.com/channels/826816523368005654/1101547251903504474/1101548279277309983 + - https://discord.com/channels/826816523368005654/1143258005354328156/1143272934966837309 Created: 2022-02-24 License: CC-BY-4.0 --- @@ -91,11 +97,11 @@ within CIP-30. // TODO: Move this into a more appropriate **separate** CIP. The Conway ledger era introduces a new _first class_ credential in -[`voting_credential`](https://github.com/input-output-hk/cardano-ledger/blob/d42dbc00b27ff2731211b45f22cec172a070e3e6/eras/conway/test-suite/cddl-files/conway.cddl#L331). +[`drep_credential`](https://github.com/input-output-hk/cardano-ledger/blob/1beddd3d9f10d8fcb163b5e83985c4bac6b74be7/eras/conway/test-suite/cddl-files/conway.cddl#L332). This is used to identify registered DReps on-chain, via their certificates and votes. -Here we introduction of DRep Keys to be used to create `voting_credential`s for +Here we introduction of DRep Keys to be used to create `drep_credential`s for (non-script) registered DReps. #### Derivation @@ -384,7 +390,7 @@ client application in a explicit and highly informative way. Here we extend the capabilities of [CIP-30's `.signTx()`](https://github.com/cardano-foundation/CIPs/blob/master/CIP-0030/README.md#apisigntxtx-cbortransaction-partialsign-bool--false-promisecbortransaction_witness_set). -To allow signatures with `voting_credential` and recognition of Conway ledger +To allow signatures with `drep_credential` and recognition of Conway ledger era transaction fields and certificates. ##### Expected Inspection Support @@ -396,32 +402,35 @@ Supporting wallets should be able to recognize and inspect all the following certificates and data contained in transaction bodies, in any combination. -| Supported Pre-Conway Certificates | -| --------------------------------- | -| `stake_registration` | -| `stake_deregistration` | -| `stake_delegation` | -| `pool_registration` | -| `pool_retirement` | - -| Supported Conway Certificates | -| ------------------------------- | -| `reg_cert` | -| `unreg_cert` | -| `vote_deleg_cert` | -| `stake_vote_deleg_cert` | -| `stake_reg_deleg_cert` | -| `vote_reg_deleg_cert` | -| `stake_vote_reg_deleg_cert` | -| `reg_committee_hot_key_cert` | -| `unreg_committee_hot_key_cert` | -| `reg_drep_cert` | -| `unreg_drep_cert` | - -| Supported Conway Transaction Field Data | -| --------------------------------------- | -| `voting_procedure` | -| `proposal_procedure` | +| Index | Supported Pre-Conway Certificates | +| ----- | --------------------------------- | +| 0 | `stake_registration` | +| 1 | `stake_deregistration` | +| 2 | `stake_delegation` | +| 3 | `pool_registration` | +| 4 | `pool_retirement` | + +| Index | Supported Conway Certificates | +| ----- | ------------------------------- | +| 5 | `reg_cert` | +| 6 | `unreg_cert` | +| 7 | `vote_deleg_cert` | +| 8 | `stake_vote_deleg_cert` | +| 9 | `stake_reg_deleg_cert` | +| 10 | `vote_reg_deleg_cert` | +| 11 | `stake_vote_reg_deleg_cert` | +| 12 | `auth_committee_hot_cert` | +| 13 | `resign_committee_cold_cert` | +| 14 | `reg_drep_cert` | +| 15 | `unreg_drep_cert` | +| 16 | `update_drep_cert` | + +| Transaction Index | Supported Conway Transaction Field Data | +| ----------------- | --------------------------------------- | +| 19 | `voting_procedure` | +| 20 | `proposal_procedure` | +| 21 | `coin` (current treasury value) | +| 22 | `positive_coin` (new donation) | All other potential transaction field inclusions [0-18](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/conway/test-suite/cddl-files/conway.cddl#L54-#L69), @@ -431,14 +440,14 @@ should be able to be recognized by supporting wallets. In the Conway ledger era two certificate types are depreciated `genesis_key_delegation` and `move_instantaneous_rewards_cert`. If the wallet receives a transaction containing a depreciated certificate it should return a `TxSignError` with an error code of `DepreciatedCertificate`. -| Unsupported Pre-Conway Certificates | -| ----------------------------------- | -| `genesis_key_delegation` | -| `move_instantaneous_rewards_cert` | +| Index | Unsupported Pre-Conway Certificates | +| ----- | ----------------------------------- | +| 5 | `genesis_key_delegation` | +| 6 | `move_instantaneous_rewards_cert` | ##### Expected Witness Support -Although constitutional committee certificates and stake pool certificates should be able to be recognized they should not be able to be correctly witnessed by wallets. Wallet's should only support witnesses using Payment, Stake and DRep keys. +Although constitutional committee certificates and stake pool certificates should be able to be recognized they should not be able to be correctly witnessed by wallets following this API. Wallet's should only support witnesses using payment, stake and DRep keys. ##### Returns @@ -547,16 +556,16 @@ hex-encoded CBOR bytes of a `COSE_Key` structure with the following headers set: ### Versioning of this proposal Whilst this CIP is in it's unmerged proposed state, it remains very fluid and -substantial changes can happen, so I would advise against any implementation. -Once more feedback is received, maturing this design I think implementations can -safely emerge, alongside this proposal's merger into the CIPs repository. Once -merged only small necessary changes should be made, ideally in backwards -compatible fashion. +substantial changes can happen, so we would advise against any implementation. +Once more feedback is received, maturing this design, implementations can safely +emerge, alongside this proposal's merger into the CIPs repository. Once merged +only small necessary changes should be made, ideally in backwards compatible +fashion. This, in tandem with, maturing implementations should move this proposal to an active state where only small backwards compatible changes can be made. If any large changes are needed once active then a new proposal should be made to -replace this one. This I believe aligns with the (new) extendibility design of +replace this one. This we believe aligns with the (new) extendibility design of CIP-0030. ### Examples of Flows @@ -593,7 +602,7 @@ wallet has already been made via `cardano.{wallet-name}.enable({ "cip": 95 })`. 2. **Construct Delegation:** The client application uses CIP-30 endpoints to query the wallet's UTxO set and payment address. A DRep delegation certificate - ([`vote_deleg_cert`](https://github.com/input-output-hk/cardano-ledger/blob/d42dbc00b27ff2731211b45f22cec172a070e3e6/eras/conway/test-suite/cddl-files/conway.cddl#L302)) + ([`vote_deleg_cert`](https://github.com/input-output-hk/cardano-ledger/blob/1beddd3d9f10d8fcb163b5e83985c4bac6b74be7/eras/conway/test-suite/cddl-files/conway.cddl#L303)) is constructed by the app using the chosen DRep's ID and wallet's stake credential. A transaction is constructed to send 1 ADA to the wallet's payment address with the certificate included in the transaction body. @@ -623,7 +632,7 @@ a registered DRep. 2. **Construct Registration**: The client application uses CIP-30 endpoints to query the wallet's UTxO set and payment address. A DRep registration certificate - ([`reg_drep_cert`](https://github.com/input-output-hk/cardano-ledger/blob/d42dbc00b27ff2731211b45f22cec172a070e3e6/eras/conway/test-suite/cddl-files/conway.cddl#L311)) + ([`reg_drep_cert`](https://github.com/input-output-hk/cardano-ledger/blob/1beddd3d9f10d8fcb163b5e83985c4bac6b74be7/eras/conway/test-suite/cddl-files/conway.cddl#L312)) is constructed by the app using the wallet's DRep ID and the provided metadata anchor. A transaction is constructed to send 1 ADA to the wallet's payment address with the certificate included in the transaction body. @@ -631,7 +640,7 @@ a registered DRep. `.signTx()`. The wallet inspects the content of the transaction, informing the user of the client app's intension. If the user confirms that they are happy to sign, the wallet returns the appropriate witnesses, of payment key - and DRep key (`voting_credential`). + and DRep key (`drep_credential`). 4. **Submit:** The app will add the provided witnesses into the transaction body and then pass the witnessed transaction back to the wallet for submission via `.submitTx()`. @@ -690,9 +699,9 @@ majority of participants thus we aim to cast a wide net with this specification. In this specification we have placed explicit boundaries on what should not be supported with `.signTx()`. Those being not witnessing -[stake pool](https://github.com/input-output-hk/cardano-ledger/blob/d42dbc00b27ff2731211b45f22cec172a070e3e6/eras/conway/test-suite/cddl-files/conway.cddl#L292C1-L294C43) +[stake pool](https://github.com/input-output-hk/cardano-ledger/blob/1beddd3d9f10d8fcb163b5e83985c4bac6b74be7/eras/conway/test-suite/cddl-files/conway.cddl#L294C1-L295C43) or -[constitutional committee](https://github.com/input-output-hk/cardano-ledger/blob/d42dbc00b27ff2731211b45f22cec172a070e3e6/eras/conway/test-suite/cddl-files/conway.cddl#L309C1-L310C60), +[constitutional committee](https://github.com/input-output-hk/cardano-ledger/blob/1beddd3d9f10d8fcb163b5e83985c4bac6b74be7/eras/conway/test-suite/cddl-files/conway.cddl#L310C1-L311C61), certificates and not inspecting genesis key delegation or MIR certificates. From speaking to CIP-30 implementors it seems reasonable that there does not @@ -702,7 +711,7 @@ prefer the utility and security advantages not operating via light wallets. Due to the [Lack of Specificity](#lack-of-specificity) of CIP-30 we felt it necessary to explicitly state the lack of support in this extension. -[Constitutional committee certificates](https://github.com/input-output-hk/cardano-ledger/blob/d42dbc00b27ff2731211b45f22cec172a070e3e6/eras/conway/test-suite/cddl-files/conway.cddl#L309C1-L310C60) +[Constitutional committee certificates](https://github.com/input-output-hk/cardano-ledger/blob/1beddd3d9f10d8fcb163b5e83985c4bac6b74be7/eras/conway/test-suite/cddl-files/conway.cddl#L310C1-L311C61) are not supported by this specification's `.signTx()` for two reasons. First, this specification is only focussed on the need's of Ada holders and DReps. Secondly, the credentials used by the constitutional committee, are a hot and @@ -976,8 +985,9 @@ straight forward for wallets implementing both APIs. being a wallet web bridge. - Should there be a way for the optional sharing of governance state, from wallet to client? -- How to represent DRep keys in signData endpoint? - Should DRep key be moved into CIP-1852? + - Yes it will be moved to it's own CIP with reference added to + CIP-1852. ## Path to Active @@ -992,14 +1002,20 @@ straight forward for wallets implementing both APIs. - [x] Provide a public Discord channel for open discussion of this specification. - See - [`gov-wallet-cip`](https://discord.com/channels/826816523368005654/1101547251903504474/1101548279277309983) + [`wallets-sanchonet`](https://discord.com/channels/826816523368005654/1143258005354328156/1143272934966837309) channel in the [IOG Technical Discord](https://discord.gg/inputoutput) under - the `🥑BUILD` section (to view you have to opt-in to the Builders group). + (to view you have to opt-in to the Sanchonet group in the start-here + channel). - [x] Author to engage with wallet providers for feedback. - [x] Author to run a hackathon workshop with wallet providers. - In person and online hackathon run 2023.07.13, outcomes presented here: [CIP-95 pull request comment](https://github.com/cardano-foundation/CIPs/pull/509#issuecomment-1636103821). -- [ ] Resolve all [Open Questions](#open-questions). +- [x] Resolve all [Open Questions](#open-questions). +- [x] Author to provide test dApp to test against. + - See + [cip95-cardano-wallet-connector](https://github.com/Ryun1/cip95-cardano-wallet-connector/tree/master). +- [x] Author to provide a reference implementation. + - See [cip95-demos-wallet](https://github.com/Ryun1/cip95-demos-wallet/). - [ ] Author to produce a set of test vectors for wallets to test against. ## Copyright From d02b02faf9733e3099f71fa2922f8de02fa1e0a3 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Fri, 8 Sep 2023 15:35:25 +0100 Subject: [PATCH 31/35] responded to feedback from open hour call --- CIP-0095/README.md | 62 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/CIP-0095/README.md b/CIP-0095/README.md index 8fcc38c597..4bff5e552e 100644 --- a/CIP-0095/README.md +++ b/CIP-0095/README.md @@ -323,7 +323,7 @@ For example: `api.cip95.getPubDRepKey()` --> To access these functionalities a client application must present this CIP-95 -extension object: +extension object, as part of the extensions object passed at enable time: ```ts { "cip": 95 } @@ -356,20 +356,42 @@ The wallet account's public DRep Key. | `APIError` | `AccountChange` | Returned if wallet has changed account, meaning connection should be reestablished. | -#### `api.getActivePubStakeKeys(): Promise` +#### `api.getRegisteredPubStakeKeys(): Promise` -The connected wallet account's active public stake keys (with keys which are -being used for staking), if the wallet tracks the keys that are used for -governance then only those keys shall be returned. +The connected wallet account's registered public stake keys. These keys may or may not control any Ada, but they must all have been registered via a stake key registration certificate. -These are used by the client to identify the user's on-chain CIP-1694 -interactions, i.e if a user has delegated to a DRep. Here we allow for multiple -stake credentials to provided at once for the case of -[multi-stake key wallets](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0018). +If none of the wallets stake keys are registered then an empty array is returned. + +These keys can then be used by the client to identify the user's on-chain CIP-1694 +interactions, and also create vote delegation certificates which can be signed via `.signTx()`. + +##### Returns + +An array of the connected user's registered public stake keys. + +##### Errors + + +| Error Type | Error Code | Return Condition | +| ------------ | ---------------- | ----------------------------------------------------------------------------------------- | +| `APIError` | `InvalidRequest` | Returned if a input parameter is passed. | +| `APIError` | `InternalError` | Returned if there is a generic internal error occurred during execution of this API call. | +| `APIError` | `Refused` | Returned if there is a refusal, could be wallet disconnection or extension is revoked. | +| `APIError` | `AccountChange` | Returned if wallet has changed account, meaning connection should be reestablished. | + + +#### `api.getUnregisteredPubStakeKeys(): Promise` + +The connected wallet account's unregistered public stake keys. These keys may or may not control any Ada. + +If the wallet does not know the registration status of it's stake keys then it should return them as part of this call. If all of the wallets stake keys are registered then an empty array is returned. + +These keys can then be used by the client to identify the user's on-chain CIP-1694 +interactions, i.e if a user has delegated to a DRep. ##### Returns -An array of the connected user's active public stake keys. +An array of the connected user's unregistered stake keys. ##### Errors @@ -553,7 +575,7 @@ hex-encoded CBOR bytes of a `COSE_Key` structure with the following headers set: -### Versioning of this proposal +### Versioning Whilst this CIP is in it's unmerged proposed state, it remains very fluid and substantial changes can happen, so we would advise against any implementation. @@ -577,12 +599,13 @@ application and wallet, then a subsequent _login_. 1. **Connection:** User indicates to the client their intent to connect, causing client offer a list of supported wallets, user selects their desired wallet. - The client will then invoke `.{wallet-name}.enable({ "cip": 95 })` from the - shared `cardano` namespace, ensuring to pass in the CIP-95 extension object. + The client will then invoke + `.{wallet-name}.enable({extensions: [{ "cip": 95 }]})` from the shared + `cardano` namespace, ensuring to pass in the CIP-95 extension object. 2. **Wallet Confirmation:** The wallet indicates through its UI the clients intent to connect, the user should then grant permission. -3. **Share Credentials:** The client invokes both `.getActivePubStakeKeys()` and - `.getPubDRepKey()`, causing the connected wallet to share relevant +3. **Share Credentials:** The client invokes both `.getRegisteredPubStakeKeys()` + and `.getPubDRepKey()`, causing the connected wallet to share relevant credentials. 4. **Chain Lookup:** The client uses a chain indexer to work out the governance state of the provided credentials. The results of the lookup are then shown @@ -593,7 +616,8 @@ application and wallet, then a subsequent _login_. Assume a _DRep Aggregator and Delegation_ specialized client app, that aggregates DRep metadata from DRep registration certificates and renders this metadata to show prospective delegators. Assume that connection to a users -wallet has already been made via `cardano.{wallet-name}.enable({ "cip": 95 })`. +wallet has already been made via +`cardano.{wallet-name}.enable({extensions: [{ cip: 95 }]})`. 1. **Choose DRep:** User browses DReps and selects one which align's with their values to delegate too. It is up to the client application to choose and @@ -622,8 +646,8 @@ wallet has already been made via `cardano.{wallet-name}.enable({ "cip": 95 })`. Assume a _DRep Registration_ specialized client app, that allows people to register as a DRep. Assume that connection to a users wallet has already been -made via `cardano.{wallet-name}.enable({ "cip": 95 })` and that the user is not -a registered DRep. +made via `cardano.{wallet-name}.enable({extensions: [{ cip: 95 }]})` and that +the user is not a registered DRep. 1. **User Indicates Intent:** User indicates to the client that they wish to register as a DRep. The client asks the user to provide metadata anchor, this @@ -861,7 +885,7 @@ clients are aware of this functionality. ### DRep Key -// todo: once DRep CIP added +// todo: move to DRep Key CIP We chose to introduce the concept of a DRep Key, building on top of CIP-1694, this we see as a necessary step for wallet implementors. By setting a From a80f560e14ac009bca46f734d29775724705e576 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Sun, 10 Sep 2023 20:35:31 +0100 Subject: [PATCH 32/35] namespace and more rationale --- CIP-0095/README.md | 48 ++++++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/CIP-0095/README.md b/CIP-0095/README.md index 4bff5e552e..0fd02187e0 100644 --- a/CIP-0095/README.md +++ b/CIP-0095/README.md @@ -34,10 +34,6 @@ focussed web-based stacks. Here we aim to support the requirements of Ada Holders and DReps in the Conway Ledger era, this specification is based on the [Draft Conway Ledger Era Specification](https://github.com/input-output-hk/cardano-ledger/tree/master/eras/conway/test-suite/cddl-files). -> **Note** This proposal assumes knowledge of the ledger governance model as -> outlined within -> [CIP-1694](https://github.com/cardano-foundation/CIPs/blob/master/CIP-1694/README.md). - ### Acknowledgments
@@ -87,7 +83,8 @@ CIP-1694's governance design. ## Specification We define the following section as an extension to the specification described -within CIP-30. +within CIP-30. Although currently CIP-30 acts as the defacto Cardano dApp-wallet +connector, this specification could be applied to similar standards. > **Note** This specification will evolve as the proposed ledger governance > model matures. @@ -317,23 +314,19 @@ type DataSignError = { ### Governance Extension API - +For example: `api.cip95.getPubDRepKey()` To access these functionalities a client application must present this CIP-95 extension object, as part of the extensions object passed at enable time: ```ts -{ "cip": 95 } +.enable({ extensions: [{ cip : 95 }]}) ``` -This extension object is provided during the initial handshake procedure as -described within -[CIP-30's Initial API](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030#cardanowalletnameenable-extensions-extension----promiseapi). - -#### `api.getPubDRepKey(): Promise` +#### `api.cip95.getPubDRepKey(): Promise` The connected wallet account provides the account's public DRep Key, derivation as described in [DRep Key](#DRep-key). @@ -380,7 +373,7 @@ An array of the connected user's registered public stake keys. | `APIError` | `AccountChange` | Returned if wallet has changed account, meaning connection should be reestablished. | -#### `api.getUnregisteredPubStakeKeys(): Promise` +#### `api.cip95.getUnregisteredPubStakeKeys(): Promise` The connected wallet account's unregistered public stake keys. These keys may or may not control any Ada. @@ -495,7 +488,7 @@ If `partialSign` is `true`, the wallet only tries to sign what it can. If `partialSign` is `false` and the wallet could not sign the entire transaction, `TxSignError` shall be returned with the `ProofGeneration` code. -#### `api.signData(addr: Address | DRepID, payload: Bytes): Promise` +#### `api.cip95.signData(addr: Address | DRepID, payload: Bytes): Promise` Errors: `APIError`, `DataSignError` @@ -845,6 +838,15 @@ as this creates unpredictable wallet behavior for client applications. Such behavior was a primary motivator to introduce such an extendability mechanism to CIP-30. +#### Namespacing + +In this specification we have chosen to explicitly namespace all endpoint except +`.signTx()` where we omit the namespacing. By not namespacing `.signTx()` we +intend to offer client apps an override of the CIP-30 `.signTx()`. We chose to +do this because this `.signTx()` extends the CIP-30 functionality in a backwards +compatible way. All other endpoints are namespaced to avoid possible collisions +with other future extensions. + #### Inheriting Endpoints In this design we chose to extend the capabilities of CIP-30's `.signTx()` and @@ -964,6 +966,20 @@ addresses. Again we believe wallets should just serve public key information and it is up to the application to encode and derive addresses as needed. This simplifies the overall design and makes implementations easier for wallets. +### Splitting of Stake Key endpoint + +For stake keys we have chosen to implement two endpoints where wallets can share +registered and unregistered stake keys. Originally we had a single endpoint +which only allowed sharing of registered stake keys. This was problematic for +wallets which had no registered stake keys, and thus the second endpoint was +introduced. + +We chose to keep a single endpoint for DRep keys, although it would have been +possible to introduce a second to allow for wallets to activity of their DRep +keys. This was just for the simplicity of the API. Furthermore, due to the +design of this proposal it is unlikely that wallets will implement methods to +track a user's DRep state. + ### Backwards Compatibility This proposal should not effect the backwards compatibility of either clients or From 7a69940a8ab8bc4f53fa2fb139da2d59773442fc Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Tue, 19 Sep 2023 12:23:18 +0100 Subject: [PATCH 33/35] final adjustments --- CIP-0095/README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/CIP-0095/README.md b/CIP-0095/README.md index 0fd02187e0..82074c10ef 100644 --- a/CIP-0095/README.md +++ b/CIP-0095/README.md @@ -1,6 +1,6 @@ --- CIP: 95 -Title: Cardano dApp-Wallet Web Bridge Governance Extension +Title: Web-Wallet Bridge: Governance Category: Wallets Status: Proposed Authors: @@ -351,7 +351,7 @@ The wallet account's public DRep Key. #### `api.getRegisteredPubStakeKeys(): Promise` -The connected wallet account's registered public stake keys. These keys may or may not control any Ada, but they must all have been registered via a stake key registration certificate. +The connected wallet account's registered public stake keys. These keys may or may not control any Ada, but they must all have been registered via a stake key registration certificate. This includes keys which the wallet knows are in the process of being registered (already included in a pending stake key registration certificate). If none of the wallets stake keys are registered then an empty array is returned. @@ -375,7 +375,7 @@ An array of the connected user's registered public stake keys. #### `api.cip95.getUnregisteredPubStakeKeys(): Promise` -The connected wallet account's unregistered public stake keys. These keys may or may not control any Ada. +The connected wallet account's unregistered public stake keys. These keys may or may not control any Ada. This includes keys which the wallet knows are in the process of becoming unregistered (already included in a pending stake key unregistration certificate). If the wallet does not know the registration status of it's stake keys then it should return them as part of this call. If all of the wallets stake keys are registered then an empty array is returned. @@ -1054,10 +1054,11 @@ straight forward for wallets implementing both APIs. - [x] Author to provide test dApp to test against. - See [cip95-cardano-wallet-connector](https://github.com/Ryun1/cip95-cardano-wallet-connector/tree/master). -- [x] Author to provide a reference implementation. +- [x] Author to provide a reference wallet implementation. - See [cip95-demos-wallet](https://github.com/Ryun1/cip95-demos-wallet/). - [ ] Author to produce a set of test vectors for wallets to test against. - +- [ ] Author to move DRep key definitions to a separate CIP. + ## Copyright This CIP is licensed under From 55d11353f44f907e18837ee29ac19ae2709f87cc Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Tue, 19 Sep 2023 17:28:43 +0100 Subject: [PATCH 34/35] changed naming to pipe --- CIP-0095/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CIP-0095/README.md b/CIP-0095/README.md index 82074c10ef..4314a44806 100644 --- a/CIP-0095/README.md +++ b/CIP-0095/README.md @@ -1,6 +1,6 @@ --- CIP: 95 -Title: Web-Wallet Bridge: Governance +Title: Web-Wallet Bridge | Governance Category: Wallets Status: Proposed Authors: From 2eeef5c36711d4d09961fabf88c7359a83087db5 Mon Sep 17 00:00:00 2001 From: Ryan Williams Date: Tue, 19 Sep 2023 17:39:10 +0100 Subject: [PATCH 35/35] added warning about DRep keys --- CIP-0095/README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CIP-0095/README.md b/CIP-0095/README.md index 4314a44806..da6de9ad8f 100644 --- a/CIP-0095/README.md +++ b/CIP-0095/README.md @@ -91,7 +91,8 @@ connector, this specification could be applied to similar standards. ### DRep Key -// TODO: Move this into a more appropriate **separate** CIP. +⚠ These definitions are an initial version of these keys, such definitions are +to be moved to a new CIP. Once new CIP is published please view that CIP. The Conway ledger era introduces a new _first class_ credential in [`drep_credential`](https://github.com/input-output-hk/cardano-ledger/blob/1beddd3d9f10d8fcb163b5e83985c4bac6b74be7/eras/conway/test-suite/cddl-files/conway.cddl#L332).