Skip to content

Commit b169fa6

Browse files
fabianbormannrphairNetWalker108KtorZRyun1
authored
CIP-0045? | Decentralized WebRTC dApp-Wallet Communication (cardano-foundation#395)
* feat: add cip-0078 including a demo folder * fix: adjust the structure as described in CIP-0001 * fix: structure and incorrectly formatted to-do list * fix: reformat the structure to match the cip-0001 specs * fix: wrong formatted todo list item * fix: add the changes from Roberto manually due to the changed file structure * fix: relocate the demo implementation to a new repository * caught spelling mistake (not proofread whole doc) * Update README.md Typo fix * Apply suggestions from code review Co-authored-by: Matthias Benkort <[email protected]> * chore: add updates section, change wording to signaling server, update links * CIP-0045? | Removed top level title from old CIP template * feat: add identifier information with regards to cip-0013 * chore: cleanup README.md * feat: add more links and references to close open points * Update CIP-????/README.md * chore: renaming the folder to the actual CIP number --------- Co-authored-by: Robert Phair <[email protected]> Co-authored-by: NetWalker108 <[email protected]> Co-authored-by: Matthias Benkort <[email protected]> Co-authored-by: Ryan Williams <[email protected]>
1 parent b318dc6 commit b169fa6

File tree

1 file changed

+276
-0
lines changed

1 file changed

+276
-0
lines changed

CIP-0045/README.md

+276
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,276 @@
1+
---
2+
CIP: 45
3+
Title: Decentralized WebRTC dApp-Wallet Communication
4+
Status: Active
5+
Category: Wallets
6+
Authors:
7+
- Fabian Bormann <[email protected]>
8+
- Jaime Caso <[email protected]>
9+
Implementors:
10+
- Fabian Bormann <[email protected]>
11+
- Jaime Caso <[email protected]>
12+
Discussions:
13+
- https://github.com/cardano-foundation/CIPs/pull/395
14+
Created: 2022-11-29
15+
License: CC-BY-4.0
16+
---
17+
18+
## Abstract
19+
20+
We want to introduce a decentralized communication method between dApps and wallets based on WebTorrent trackers and WebRTC. This CIP also contains a proof of concept implementation injecting the wallet rpc methods into the dApps global window object similar to [CIP-0030](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0030).
21+
22+
## Motivation
23+
24+
In a decentralized ecosystem a communication between wallet-apps and dApps is still challanging. The inter-app communication on mobile devices does not directly allow remote procedure calls and is mostly restricted to Universal Links (iOS) or Deeplinks (Android). State-of-the-art solutions like WalletConnect tackle these problems using WebRTC communication which also works across devices, but requires a central signaling server to estalblish a WebRTC connection. In this CIP we want to introduce an architecture which uses WebTorrent trackers for the peer discovery to remove the need of this central component.
25+
26+
## Specification
27+
28+
### Establish a WebRTC Connection Using a Signaling Server (State-of-the-art approach)
29+
30+
```mermaid
31+
sequenceDiagram
32+
dApp-->>+Signaling Server: Who am I?
33+
Signaling Server-->>dApp: You are <ip:port>
34+
Wallet-->>+Signaling Server: Who am I?
35+
Signaling Server-->>Wallet: You are <ip:port>
36+
dApp->>Wallet: messages
37+
Wallet->>dApp: messages
38+
```
39+
40+
The data will be send peer to peer via a WebRTC data channel once the ip discovery has been finished. E.g. WalletConnect expects/provides a relay server URL to initialize the connection. While this method allows dApps to communitcate peer-to-peer with wallets it also leads to a [possible SPOF](https://twitter.com/walletconnect/status/1407279853943001088?lang=en).
41+
42+
### Establish a WebRTC Connection Using WebTorrent Tracker (Our approach)
43+
44+
```mermaid
45+
flowchart LR
46+
subgraph dApp
47+
subgraph .torrent server
48+
end
49+
end
50+
51+
subgraph Wallet[Wallet App]
52+
end
53+
54+
dApp-->|.torrent| TrackerA[Tracker 1]
55+
dApp-->|.torrent| TrackerB[Tracker 2]
56+
dApp-->|.torrent| TrackerC[...]
57+
dApp-->|.torrent| TrackerD[Tracker n]
58+
59+
dApp-->|.torrent| TrackerA[Tracker 1]
60+
dApp-->|.torrent| TrackerB[Tracker 2]
61+
dApp-->|.torrent| TrackerC[...]
62+
dApp-->|.torrent| TrackerD[Tracker n]
63+
64+
dApp-->|Share public key| Wallet
65+
```
66+
67+
Deep links, Universal Links, or even the clipboard could be utilized to share the identifier (public key) on the same device (in cases of a wallet based on web technology like Ionic). For sharing the identifier across different devices, QR codes would come into play. This method could be applied, for example, between a wallet mobile app and a dapp running on a PC, or vice versa. The wallet application would then initiate a query to a list of trackers using this distinct identifier in order to establish the WebRTC connection. After this process is completed, the data is transmitted peer-to-peer following the WebRTC standard, for instance, to invoke RPC calls.
68+
69+
```mermaid
70+
flowchart LR
71+
Wallet-->|queries| TrackerA[Tracker 1]
72+
Wallet-->|queries| TrackerB[Tracker 2]
73+
Wallet-->|queries| TrackerC[...]
74+
Wallet-->|queries| TrackerD[Tracker n]
75+
76+
Wallet-->|queries| TrackerA[Tracker 1]
77+
Wallet-->|queries| TrackerB[Tracker 2]
78+
Wallet-->|queries| TrackerC[...]
79+
Wallet-->|queries| TrackerD[Tracker n]
80+
81+
subgraph dApp
82+
subgraph .torrent server
83+
end
84+
end
85+
86+
Wallet<--Establish WebRTC data channel\n for peer to peer communication-->dApp
87+
```
88+
89+
#### CIP-0013 Compliant Identifiers
90+
91+
The keys (public key and corresponding 64-byte secret key) are generated using a function that implements Ed25519. This function requires a (random) seed, which can also be stored and re-used to ensure that whenever a client employs a dApp or a Wallet, the same key pair is generated consistently, even if the browser or mobile app is restarted. The public key will be used as an identifier for the torrent-based peer discovery. When this identifier is shared through methods like QR codes or links, it needs to be compliant to the following Cardano Uri Scheme [(CIP-0013)](https://github.com/cardano-foundation/CIPs/tree/master/CIP-0013):
92+
93+
| [scheme] | [authority] | [version] | [data] |
94+
|---------------|-------------|------------|--------------|
95+
| web+cardano: | //connect | /v1 | ?identifier= |
96+
97+
```
98+
web+cardano://connect/v1?identifier=<public_key>
99+
```
100+
### Proof of Concept
101+
102+
The idea of using WebTorrent trackers instead of signaling servers for peer discovery was already mentioned in [Aug 2018 by Chris McCormick](https://mccormick.cx/news/entries/on-self-hosting-and-decentralized-software):
103+
"I've also been tinkering with WebTorrent. [...]
104+
Working with this technology made me realise something the other day: it's now possible to host back-end services, or "servers" inside browser tabs. [...] So anyway, I've made this weird thing to enable developers to build "backend" services which run in browser tabs"
105+
106+
McCormick's idea has been developed and open sourced as a library called [bugout](https://github.com/chr15m/bugout/) (MIT).
107+
108+
For this proof of concept we wrote two small pieces of software:
109+
110+
- A html page aka the dApp
111+
- An ionic react app (to target mutliple devices) aka the wallet app
112+
113+
The whole code is provided within this [demo implementation](https://github.com/fabianbormann/WebRTC-WebTorrent-tracker-communication-demo) that also contains a step-by-step guide.
114+
115+
#### dApp
116+
117+
The dApp consists of a standard HTML5 template including the following lines of code:
118+
119+
```html
120+
<script src="https://chr15m.github.io/bugout/bugout.min.js"></script>
121+
<script>
122+
var bugout = new Bugout({
123+
seed: localStorage["poc-server-seed"],
124+
announce: [
125+
'udp://tracker.opentrackr.org:1337/announce',
126+
'udp://open.tracker.cl:1337/announce',
127+
'udp://opentracker.i2p.rocks:6969/announce',
128+
'https://opentracker.i2p.rocks:443/announce',
129+
'wss://tracker.files.fm:7073/announce',
130+
'wss://spacetradersapi-chatbox.herokuapp.com:443/announce',
131+
'ws://tracker.files.fm:7072/announce'
132+
]
133+
});
134+
localStorage["poc-server-seed"] = bugout.seed;
135+
136+
var connected = false;
137+
bugout.on("connections", function (clients) {
138+
if (clients == 0 && connected == false) {
139+
connected = true;
140+
console.log("[info]: server ready");
141+
console.log(`[info]: share this address with your wallet app -> ${bugout.address()}`);
142+
}
143+
console.log(`[info]: ${clients} clients connected`);
144+
});
145+
146+
bugout.register("api", function (address, args, callback) {
147+
const api = { version: args.api.version, address: address }
148+
149+
for (method of args.api.methods) {
150+
api[method] = () => new Promise((resolve, reject) => {
151+
bugout.rpc(address, method, {}, (result) => resolve(result));
152+
});
153+
}
154+
155+
window.cardano = window.cardano || {};
156+
window.cardano[args.api.name] = api;
157+
console.log(`[info]: injected api of ${args.api.name} into window.cardano`);
158+
});
159+
</script>
160+
```
161+
162+
#### Wallet App
163+
164+
The wallet app is a standard ionic react app built by the ionic cli:
165+
166+
```zsh
167+
ionic start WalletApp blank --type=react
168+
cd WalletApp
169+
npm i bugout
170+
```
171+
172+
The following lines of code were added to the index.tsx file:
173+
174+
```js
175+
const bugout = new Bugout(
176+
"<HASH provided by the dAPP>", {
177+
announce: [
178+
'udp://tracker.opentrackr.org:1337/announce',
179+
'udp://open.tracker.cl:1337/announce',
180+
'udp://opentracker.i2p.rocks:6969/announce',
181+
'https://opentracker.i2p.rocks:443/announce',
182+
'wss://tracker.files.fm:7073/announce',
183+
'wss://spacetradersapi-chatbox.herokuapp.com:443/announce',
184+
'ws://tracker.files.fm:7072/announce'
185+
]
186+
});
187+
188+
bugout.on("server", function() {
189+
console.log("[info]: connected to server")
190+
bugout.rpc("<HASH provided by the dAPP>", "api", {"api": {
191+
version: "1.0.3",
192+
name: 'boostwallet',
193+
methods: ["getRewardAddresses"]
194+
}});
195+
});
196+
197+
bugout.register("getRewardAddresses", (address:string, args:any, callback:Function) => {
198+
callback(["e1820506cb0ce54ae755b2512b6cf31856d7265e8792cb86afc94e0872"]);
199+
});
200+
```
201+
202+
This example has a few restrictions:
203+
204+
1. bugout is currently not compatible with Webpack 5, so polyfills are not automatically included and a react-scripts eject is needed to add them to the webpack.config.js file
205+
206+
2. bugout does not directly provide type declarations. There are some declarations within a [PR](https://github.com/chr15m/bugout/pull/45), but they need to be adjusted (a few parameters are not mandatory) and added to a bugout.d.ts file.
207+
208+
### User Flow
209+
210+
```mermaid
211+
sequenceDiagram
212+
dApp-->>Wallet: Share address using Deeplink /Universal Link / QR
213+
Wallet-->>Tracker List: Accept connection and start quering using the address
214+
Wallet-->>dApp: Once connected register RPC functions and share the API
215+
dApp-->>dApp: Inject the API to window.cardano[walletName]
216+
dApp-->>Wallet: Call RPC functions (e.g. getRewardAddresses)
217+
Wallet-->>Wallet: If needed bring app to foregrund (e.g. request signing)
218+
Wallet-->>dApp: Send response
219+
```
220+
221+
### Security Aspects
222+
223+
We decided to spawn the server within the dApp to force the user to manually scan a QR code (using a wallet app) or accept an "Open with `<WalletAppName>`" ui dialog (in case of Universal Links or Deeplinks). This prevents the user from connecting the wallet to an unwanted dApp. Additionally we need to add a few security checks to prevent a misusage of this method.
224+
225+
- The wallet app needs to verifiy the origin (address) of the RPC call
226+
- dApps should ask the user for permission to inject the wallet names into the window.cardano object to prevent XSS attack (Maybe using a graphical representation of the wallet app address e.g. blockies)
227+
228+
## Rationale
229+
230+
The purpose of this CIP mainly consists of two parts. It addresses the current lack of dApp mobile support, but at the same time provides an even more decentralized alternative to state-of-the-art communication methods. To achieve this goal we have introduced a WebTorrent and WebRTC based architecture. To demonstrate a viable implementation, we have implemented a proof of concept which also shows how a rpc method injection like CIP-0030 might look like.
231+
232+
## Path to Active
233+
234+
### Acceptance Criteria
235+
236+
- [x] A library should be build to make it easy from dAPP and wallet side to implement the proposed communication method
237+
- [x] The library target should be browser to avoid the need of manual polyfills
238+
- [x] Mobile testing on different devices and operating systems needs to be done with a special focus to the wallet app running in background mode
239+
- [x] Potential security issues and attack vectors need to be discussed in detail
240+
1. We discussed potential security issues in the [CIP discussion](https://github.com/cardano-foundation/CIPs/pull/395#issuecomment-1669460822) and we
241+
implement an identicon solutin, but it is obviously an never ending task
242+
- [x] A full reference implementation is needed to test if the entire user flow and at the same time provide this as a how-to for developers
243+
1. Has been implemented here https://github.com/fabianbormann/cip-0045-demo-implementation
244+
245+
### Implementation Plan
246+
247+
- [x] Fork/Extend bugout to add webpack 5 and typescript support
248+
- [x] Povide a general intermediate cardano-connect typescript library to provide
249+
1. A check for mobile/desktop environment
250+
2. Depending on the environment provide interfaces for CIP-0030 / and / or CIP-?
251+
3. Add a full implementation of the server/client side code above to define a communication standard similar to CIP-0030 (getRewardAddresses, signData, signTx, ...)
252+
- [x] Start discussions about security gaps within the proposed method with various developers and also look for research papers
253+
- [x] Check if the wallet app also reacts to rpc calls in background mode on Android
254+
- [x] Check if the wallet app also reacts to rpc calls in background mode on iOS
255+
- [x] Implement the library within an example dApp:
256+
1. Implemented in Cardano Ballot for the [summit voting 2023](https://voting.summit.cardano.org/)
257+
2. Implemented by (SundeaSwap)[https://www.youtube.com/watch?v=mRpXIh-DyYM]
258+
3. Implemented into the [cardano-connect-with-wallet core and react library](https://github.com/cardano-foundation/cardano-connect-with-wallet/tree/main)
259+
4. Implemented in [walkinwallet](https://walkinwallet.com/)
260+
261+
262+
### Updates
263+
264+
- The re-implementation of bugout that matches the expectations below is now available as [meerkat](https://github.com/fabianbormann/meerkat)
265+
266+
- A general [cardano-connect typescript library](https://github.com/fabianbormann/cardano-peer-connect) with 100% CIP-30 support has been provided
267+
268+
- The copy & paste [demo implementation](https://github.com/fabianbormann/cip-0045-demo-implementation) is ready to use
269+
270+
- Cardano Foundation's [connect-with-wallet](https://github.com/cardano-foundation/cardano-connect-with-wallet) component does include the dApp part of CIP-45 (via feature flag), so that dApp developers don't need to write a single line of code if they rely on this component
271+
272+
- The wording of the CIP-45 has been changed. Many thanks to [@jehrhardt](https://github.com/jehrhardt) for his valuable explanation and suggestions
273+
274+
## Copyright
275+
276+
This CIP is licensed under [CC-BY-4.0](https://creativecommons.org/licenses/by/4.0/legalcode)

0 commit comments

Comments
 (0)