Giter VIP home page Giter VIP logo

wcips's Introduction

WCIPs

WalletConnect Improvement Proposals (WCIPs), modelled after https://github.com/ethereum/EIPs.

WCIP Status Terms

  • Draft - a WCIP that is undergoing rapid iteration and changes.
  • Review - a WCIP that is done with its initial iteration and ready for review by a wide audience.
  • Accepted - a WCIP that has received a sign-off from the core WalletConnect team.
  • Delivered - a WCIP that has been implemented and released in the product.
  • Deferred - a WCIP that is not being considered for immediate adoption. May be reconsidered in the future.

wcips's People

Contributors

pedrouid avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

wcips's Issues

WCIP-10: WalletConnect Notifications

The ability to post future intents of display information based on blockchain events by Dapps that shared at least one session with the address.

The Wallet node would be able to listen to cached notifications left outside of session but have been encrypted and signed by previous Dapps that you have connected (hence prior knowledge). Therefore you can both whitelist them or blacklist them in your WalletConnect client.

These caching servers for notifications are mostly push servers run by Wallet providers which are mostly incentivized to maintain these subscriptions for their users that will receive rather than send them.

WCIP-11: Update Session Params

Right now the current interface for Session Params includes the following parameters (L129)

interface ISessionParams {
    approved: boolean
    chainId: number | null
    accounts: string[] | null
    peerId?: string | null
    peerMeta?: IClientMeta | null
  }

However it would be beneficial to add some extra parameters like networkId (required) and rpcUrl (optional). These would be analogous to the proposed changes on EIP-2015. Therefore the new Session Params interface would look as follows:

interface ISessionParams {
    approved: boolean
    chainId: number | null
    networkId: number | null
    accounts: string[] | null
    rpcUrl?: string | null
    peerId?: string | null
    peerMeta?: IClientMeta | null
  }

WCIP-7: DID session requests and accounts

Inspired by uPort Connect's selective disclosure, where the two peers share their DID's with authenticated claims about their metadata. This would make it easy to build both a backwards compatible DID resolver for WalletConnect v1.0 protocol and also allow v2.0 protocol to support multiple resolvers.

This would dramatically expand the scope of WalletConnect to not only support other blockchains like for example Bitcoin which already has it's own DID resolver as part of the current W3C spec but also allow WalletConnect to serve as a protocol for DID Authentication for non-blockchain protocols.

The idea is to introduce this as part of the v2.0 protocol at the handshake process which will then allow the two peers to parse and agree on how to handle the communication during the session.

This would also allow to more flexibly describe accounts and their specific-protocols. Instead of tightly coupling the WalletConnect protocol to how Ethereum handles accounts with an array of addresses, it could instead allow accounts to be DIDs and expand different types of accounts and their own signing schemes

WCIP-8: Account-based signing modules

Similar to subproviders normally used with web3-provider-engine and other libraries that handle web3 / ethereum providers. These signing modules can be stacked inside the WalletConnect SDK to handle incoming call requests.

The main different would be that instead of modularizing these modules by which JSON RPC methods they handle, they would be modularized by accounts. This way a wallet could expose its accounts and hook different signing modules to handle signing methods for each account.

This feature would be more easily introduced with the WalletConnect v2.0 protocol with the introduction of the DID-based session requests (#7). Where you could semantically describe which protocol is being used to sign the requests, therefore supporting multiple chains and even non-blockchain authentication methods. Yet it would also allow for different signing protocols within Ethereum, for example, this would allow for delegate key signing removing the requirement to transport requests to the Wallet’s device for a specific account, or even better allow the Wallet to generate a new key for message signing in-browser for state channels and hooking it up to a state channel signing module.

WCIP-12: Multi-blockchain support

There should be a support to use Walletconnect with Bitcoin and other cryptographies and blockchains. This would increase the scope of WalletConnect and make it possible to use with other systems.


First other cryptography to support should probably be Bitcoin.

It should have support for sending and signing a transaction and some equivalents to eth_sign, eth_signTypedData and personal_sign. There should be support for "Electrum Bitcoin" signing format (like G4/obhsNpqRdHtCdvwIwWmLA+nPHkPeWEN3KGlsfjZ+gD7QYq906mUsS8MQb7G10hM8cc606/rjcOaGgMIS6gNg=).


There is already issue #7 which has some similarities:

This would dramatically expand the scope of WalletConnect to not only support other blockchains like for example Bitcoin which already has it's own DID resolver as part of the current W3C spec but also allow WalletConnect to serve as a protocol for DID Authentication for non-blockchain protocols.

WCIP-9: Asymmetric Initial Key Exchange

As a result of the discussion of the proposal #2 for refactoring the key exchange flow for WalletConnect v1.0 protocol, it was clear that the complexity for adding a key exchange during a session on the current protocol architecture was not sufficiently secure and introduced the chance for race conditions for payloads sent during the key exchange.

Therefore the solution would be to introduce an initial key exchange before the session is established. Because this would be a significant breaking change to the current v1.0 protocol, it will only be introduced on the v2.0 protocol.

The idea is to generate an asymmetric key pair from the initiating peer, A,(usually a Dapp) and provide its public key using the URI schema for WalletConnect through an "offline" method such as a QR Code or Deep Link.

The counter peer, B, will be able to generate a symmetric key for communication and include its own peerId (or a one time handshake topic) to receive the session request. The peer A will receive the payload including (peerId + symKey) encrypted with its own pubKey and will be able to decrypt it with the privKey.

At this point the peer A can now create a session request and encrypt it securely with the symKey only known by the peer B. Then the peer B will be able to respond with the session approval or rejection and the rest of the communication should follow as previously with v1.0 protocol.

WCIP-1: WalletConnect v1.0 protocol spec

I think v1.0 should get a WCIP where we specify the protocol including all the ideas that recently where discussed in the walletconnect forum.
The main idea was to move information from the QR-Code and bridge to one initial session object. I would want to add 2 more things: rendezvous points (think the future libp2p feature) and a version field (perhaps then we don't even need the version from EIP1328)

so the initial session data would include:

  • protocol version
  • dapp name
  • [MultiHash to logo?]
  • listOf(rendezvous points)
  • listOf(initialCalls)

I would suggest the URL for the QR code to look like this

wc:<MultiHash(initial_session_data)>/session_key[?bridge=bridge_url]

in the future we might even be able to get rid of bridge_url

WCIP-6: Silent Payloads

Currently we have a Push server infrastructure that subscribes to topics received by a Bridge server as a third-party that provides a Webhook that will trigger notifications on the user's Wallet.

There is however certain payloads, more concretely Ethereum read JSON-RPC requests and WalletConnect session related JSON-RPC requests which shouldn't require to notify the user of the incoming requests.

We should only trigger these notifications whenever the user is required to sign/authenticate these requests from the Wallet side. Hence I would like to propose an additional parameter to the SocketMessage payloads that are to be received by the Bridge server.

This additional parameter would be named silent and it would be a boolean value with default to false in order to maintain backwards compatibility with previous iterations. For future versions, all payloads would have a value of true except for signing requests which in the case of Ethereum would be eth_sendTransaction, eth_signTransaction, eth_sign, eth_signTypedData and personal_sign.

WCIP-14: Peer Liveness Monitoring

This WCIP specifies how two clients can monitor in a connected session wether their respective peers is still online.

To test the liveness of the other peer, the client will send a JSON-RPC request during the session with a new proposed method wc_isAlive, this request should be responded with a JSON-RPC response with result null.

The client should send this request every 10 seconds and should expect a response within one cycle. If the client doesn't receive a response for two cycles (20 seconds) then it should assume the peer is offline.

WCIP-13: Use MQTT standard for peer communication

Problem

Walletconnect v1.0 uses non-standard socket implementation which needs to be handled effectively on following scenarios:

  • Low-end devices, like most Android devices in India
  • Devices with low-batteries
  • On sleep mode devices

Having multiple connections for each DApp is an inefficient way of handling sockets where optimization is essential.

Solution

Use the MQTT standard with QoS=2 instead of custom socket implementations: https://mqtt.org/

The bridge will work as MQTT broker and maintain only one connection per device.

Benefits for using MQTT over custom socket implementation:

  • Optimized for low-end devices and sleep mode
  • Single socket connection per client
  • Library/SDKs are available in different languages out of the box (no need to create the same custom socket implementation in each language). Less code, fewer bugs (in theory)
  • Message caching when devices are offline when QoS=2. No need to write custom queueing for each device at bridge side
  • Production ready

WCIP-4: Session Permissions on Session Request

When a Dapp initiates a session request, it would be useful to include a set of permissions associated with a session to be approved by the Wallet.

This would include a more restricted read-only mode that would only disclose accounts and chainId plus other read methods like (eth_getBalance and eth_call) and the regular read-write mode which would allow the dapp to also request signing messages and transactions with the private key.

Finally it would be possible to include a more advanced set of special permissions like auto-signing with a specific scope of methods to support Layer 2 solutions like State Channels and Plasma Chains without prompting the user every time it needs to counter-sign messages that for example include receiving or withdrawing amounts.

WCIP-3: WalletConnect Instant

WalletConnect Instant ⚡

What's an Instant Request?

WalletConnect Instant feature introduces the ability to make an ephemeral session that bypasses the process of session approval by the wallet, displaying to the user a call request to be signed from the Dapp right after scanning the QR Code. This is useful for one-time use-cases like payments, topping-up or withdrawals. This is still highly experimental and hasn't been published to the official library. A PoC to aggregate feedback on this feature!

Source code available at WalletConnect/walletconnect-monorepo on walletconnect-instant branch.

Install

yarn add @walletconnect/browser @walletconnect/qrcode-modal

# OR

npm install --save @walletconnect/browser @walletconnect/qrcode-modal

Create Instant Request

import WalletConnect from "@walletconnect/browser";
import WalletConnectQRCodeModal from "@walletconnect/qrcode-modal";

/**
 *  Create a walletConnector
 */
const walletConnector = new WalletConnect({
  bridge: "https://bridge.walletconnect.org" // Required
});

/**
 *  Draft Instant Request
 */
const instantRequest = {
  id: 1,
  jsonrpc: "2.0",
  method: "eth_sendTransaction",
  params: [
    {
      from: "0xbc28ea04101f03ea7a94c1379bc3ab32e65e62d3",
      to: "0x0000000000000000000000000000000000000000",
      nonce: 1,
      gas: 100000,
      value: 0,
      data: "0x0"
    }
  ]
};

/**
 *  Subscribe to Instant Request URI
 */
walletConnector.on("display_uri", (error, payload) => {
  if (error) {
    throw error;
  }

  const uri = payload.params[0].uri;

  /**
   *  Display QR Code Modal
   */
  WalletConnectQRCodeModal.open(uri, () => {
    console.log("QR Code Modal closed");
  });
});

/**
 *  Create Instant Request
 */
walletConnector
  .createInstantRequest(instantRequest)
  .then(result => {
    /**
     *  Get Instant Request Result
     */
    console.log(result);

    /**
     *  Close QR Code Modal
     */

    WalletConnectQRCodeModal.close();
  })
  .catch(error => {
    /**
     *  Handle Error or Rejection
     */

    console.error(error);
  });

WCIP-2: Refactor exchangeKey flow

Current implementation of exchangeKey is insecure. I first designed it as a pragmatic approach to recycle persisted sessions on browser's localstorage. However you can't securely exchange symmetric keys using previously compromised keys. This is something that I've been wanting to revisit and change for months but haven't prioritized in the whole scope of things that needed to be tackled.

A couple of weeks ago, me and @ligi brainstormed a better selection to ensure that the key exchange was secure and guaranteed to only be known by two parties. WalletConnect protocol is intended to only be used 1-on-1 therefore anyone else with access to the symmetry key exposed through URI (displayed by either a QR Code or deep link) shouldn't be able to decrypt these communications between these parties.

The first proposed change is that exchangeKey should only be triggered after the connection is established, therefore no unnecessary computation is used unless the session is approved by the counter-party (which currently is exchange prior approval).

The second proposed change is that the exchangeKey flow should be initiated by a signing challenge through a JSON-RPC request with the method wc_signingChallenge. For example, after connection approval the Dapp will request a signing challenge (which should be specific for WalletConnect to be auto-signed). This is very analogous to a similar proposal that I made on ETH Magicians here. The Wallet would receive this challenge and trigger an event for the signing challenge which can be handled with a callback as follows.

walletConnector.on("signing_challenge", (error, payload) => {
  if (error) {
    throw error;
  }

  wallet.sign(payload.params[1])
    .then((signature) => {
      walletConnector.approveSigningChallenge(signature)
    })
    .catch((error) => {
      walletConnector.rejectSigningChallenge(error.message)
    });
});

The reason we included this signing challenge is to be used by the Dapp to recover the public key to be used to encrypted the contents of the following exchangKey request. Hence after the Wallet has successfully signed the challenged, the Dapp will follow with a new request that will contain an encrypted payload with the next symmetric key to be used in the communications. We won't reuse the wc_exchangeKey JSON RPC method in order to keep backwards compatibility with previous v1.0.0-beta versions. The JSON-RPC request should have a method of wc_updateKey and should include a single parameter that includes a hexadecimal encoded string of the next key encrypted with the public key recovered from the signing challenge. This key can be decrypted by subscribing to an event for the key update which can be handled with a callback as follows.

walletConnector.on("key_update", (error, payload) => {
  if (error) {
    throw error;
  }

  wallet.decrypt(payload.params[1])
    .then((nextKey) => {
      walletConnector.approveKeyUpdate(nextKey)
    })
    .catch((error) => {
      walletConnector.rejectKeyUpdate(error.message)
    });
});

Additionally, we could provide an easier integration within the SDK configuration options that include a field for a private key to be used for the new exchangeKey flow. This will make it easier for Wallet integrations instead of subscribing to both events individually, yet both options should be available.

Finally, the private/public key pair doesn't need to be the same as the wallet keys which hold funds, meaning that can be generated separately and potentially could be generated within the SDK instead of passing this responsibility to the Wallet developer

WCIP-5: Session expiration

Currently a session is persisted in localStorage in browser environments which allows a Dapp to maintain the connection to make call requests. Disregarding the security concerns of the exposure of the symmetric key which are described in the WCIP-2, there are also other security concerns regarding the user maintaining a session indefinitely open on a device that it may or may not own.

Considering the scenario where you establish a WalletConnect session with a Dapp and is persisted. An attacker could access the device which persists the session by simply opening the same Dapp where this session is persisted. Although this attacker could not sign anything without the possession of the user's Wallet, it could still access all read information displayed by the Dapp.

This could be seen as failure of the Dapp to re-authenticate by requiring a time sensitive signature by the user's Wallet. We could ever mitigate by implementing ourselves on the WalletConnect side.

Hence we would add an expiry date to all persisted sessions. I propose a 24 hour timeframe for this expiry. Whenever this expiry date is reached, the user will be required to sign a personal_sign or eth_signTypedData message that re-authenticates the session for another 24 hours. Otherwise the session will be disconnected after 5 minutes have passed since its expiry date.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.