Understanding Cosmic Links

In this article I’ll explain the motivation behind the creation of cosmic links and how it can improve the Stellar ecosystem as a whole. I’ll then cover the minimal requirements to support them. I’ll describe how we could implement a login interface to complete this scheme. Finally I’ll talk briefly about possible additional steps to secure better the whole thing.

Why Cosmic Links ?

The Stellar ecosystem is constantly growing and is now made of dozens of services, soon to become hundredth. As creativity and innovation unfold, we can note a few things:

  • A lot of services implement their own wallet, mostly because they somehow require the user to sign a significant amount of transactions. While this could make senses for some of them, like sophisticated wallets with DEX access, we may question whether this is generally a desirable thing. If we think about it, having 50 different “light wallets” — and having to create a new accounts / new wallets each time we want to try a new service — leads to a sub-optimal user experience. And to a fragmented ecosystem. Ideally, I would create one wallet and I would access to the whole thing.
  • Some are “solving” this by asking for our private keys. This is bad: we all know it. One should never share its private keys. Spreading this habit leads to dramas each time scammers enter the place. Won’t do well with public adoption. I’d like to underline here that the Stellar very official account viewer actually asks for private keys; So unfortunately they gave the wrong example here.
  • A few other services are using XDRs. Now this is good, but we know that this is not really user friendly. Hopefully we can make the experience a bit more pleasant.

My point is not to judge or criticize anybody for its design choice. In the current context, those are basically the tree options you have to deal with. I’m simply trying to consider the situation at an higher scale, and look at what can be done to make it better.

So. Three things are limiting our ecosystem potential here : first, we end up coding the same thing again and again (wallets) — second, it may not be safe and easy enough for public adoption to follow — third, users are getting jailed. Now, securing your userbase is certainly a good thing to do. But you want them to stay because you got an innovative high-quality service, not because the ecosystem is fragmented by entry/exit frictions, right?

If you don’t get me here’s the thing: When people are sharing their new wonderfull SBC projects, I get curious and click on the link. Then it asks me to create an account. Then I close the tab. I guess you know what I’m talking about. And the same thing likely happens at your door until the day you offer a fully-functionnal service built ontop publickey logins. That is, you allow anybody to use your service whichever wallet she have.

Let’s open the door

The Cosmic Link protocol have been specifically designed to bypass those limits. How? By allowing you to pass on transaction to other services, and to receive them aswell. It is utterly simple: you take a transaction object and you rewrite it as an URI query. Everybody can handle it. The implentation had to be that straightforward, because we’re talking about establishing a common language here. So you get something like:

https://cosmic.link/?payment&amount=100&destination=tips*cosmic.link

Or maybe like:

https://cosmic.link/?transaction&operation=manageData&name=migrated&value=true&operation=setOptions&homeDomain=anywallet.org

And sometimes it is like this:

https://cosmic.link/?xdr=AAAA...AA==&network=public

It’s simply following the way we already write transactions in other libraries. What is important is that everything is in the query part of those URL. The domain could be anything else. Note that in some cases the source account is not specified, which means the link can be signed by anybody. It also means that we need some way to find out the public key and the right wallet after the link is clicked.

Around those simple links, we can build three different kind of applications:

  • Wallets: allow users to sign those transactions.
  • Non-wallet services: are issuing transactions to be signed in wallets.
  • Relay: may act as an articulation between those two.

So we can secure each one private key in one and only one wallet, while the whole ecosystem of applications remains available to everybody. We may login using public keys and any transaction to be signed would be relayed back to our wallet. Simple, elegant and ahead of the industry standards.

Relays are website like https://cosmic.link that exclusively focus on accepting a transaction-as-query and setup redirection toward each one wallet. This solve the cases were the link issuer have no idea which wallet they should point to. At first, I envisioned the system to work like this:

(Warning: this may hurt your eyes)

Non-wallet service 1 — — \        / — — -> Wallet 1
Non-wallet service 2 — — — -> Relay — — — — -> Wallet 2
Non-wallet service 3 — — / \ — — -> Wallet 3
Static documents — — — -/
Social medias — — — — — /
Emails — — — — — — — — /

Of course you immediately get the problem here: we got a single point of failure. Fortunately in most cases we won’t need a relay at all. The simple solution is to offer to select your wallet at login time. Eventually, this may be done automatically, for example by asking the relay to contact the wallet the very first time in order to enable a direct connection afterward.

Non-wallet service 1 — — -+ — — -> Wallet 1
Non-wallet service 2 — — -+ — — -> Wallet 2
Non-wallet service 3 — — -+ — — -> Wallet 3
/
Relays -/
First login ever — -/
Static documents — /
Social medias — — /
Emails — — — — — /

As https://cosmic.link and all the related code is open-source, we can assume that multiple relays will popup over time. Maybe not hundred of them, because it would be self-defeating, but likely a dozen or so. Actually, it’s part of the roadmap to make it easy to do. It’s not unrealistic to imagine big player setting up their own home-secured relay, for instance.

Implementation

XDR Links

Cosmic links offer two level of implementation, which makes them more likely to spread around. The first level is using the XDR encoded links. Those are the most easy to handle for a wallet, but the more difficult to emit because it needs a stellar library and some technical knowledge to do so:

…?xdr={XDR}&network={public|test}

You’re likely already working with them as it is a standard way to encode Stellar transaction in all official libraries. Now I added three options, that a wallet could eventually accept:

  • &stripSignatures: Remove the signatures when parsing the transaction.
  • &stripSequence: Remove sequence number when parsing the transaction. Meaning it can be signed anytime in the future, possibly several times. Imply &stripSignatures.
  • &stripSource: Remove the source account when parsing the transaction. Meaning it can be signed by anybody, possibly several times. Imply &stripSequence and &stripSignatures.

This is easy to implement and it opens up a bit the field of possibilities: for example if I am an exchange I could emit ‘&stripSource’ links for an user who didn’t logged in at all and let the relay do the work. This simple syntax allows to write virtually any possible cosmic link using XDR only. This way, non-wallet services which already deal with Transaction objects can implement cosmic links cheaply, and wallet can accept them cheaply as well.

Readable Links

The second format is now implemented in JavaScript with js-cosmic-lib. This is not such a trivial task, as it’s around 4000 lines of code including comments. The lib is under 80KB, though. While it depends on js-stellar-sdk, this dependency will become optional at some point in the near future.

There’s a huge benefit having a simple syntax, accepting federated address and covering all the possible transaction one would like to write: it’s easy to use, and it’s way shorter. You need it for smaller QRcodes. You need it in your JavaScript widgets. You need it anywhere the URI is actually going to show its face. Mail, Twitter, Facebook and so on. It also allows to show the transaction description directly in the social medias. In fact, it is bound to become viral:

Now for a wallet it’s an optional thing. If you don’t implement it, a relay will translate into XDR links for you. We don’t loose so much decentralization here, as most transaction-heavy services are likely to use XDR links, and social medias and static documents links are not going to point to any particular wallet anyway.

I expect the second syntax to be implemented in wallets more gradually, while the first format them to enter the game as soon as now.

Toward a standard login interface

Note: while the Cosmic Link protocol is fully implemented, the login interface is still a proposal at that time.

The minimal requirement upon which a we can build a standard login system into non-wallet services is:

https://nonwallet.io/?publicKey=...&walletUri=...&protocol=...

The transaction query will simply have to be passed to ‘walletUri’. Again, this is only a few lines of code away. Some one-liner made available from the lib would certainly help, though.

The protocol field allow to define if a wallet supports only XDR format or both formats. It’s also here for the future implementation of SEP-0007 links, which’s an alternative that quickly followed cosmic links. While it is a bit tricky to implement, it’s the Stellar official thing and it’s going to get fully supported by js-cosmic-lib in the following months for compatibility purpose.

Now let’s see the login interface for the wallet:

https://wallet.io/?sharekeys&url=nonwallet.io

Would lead to a page where the user would have to confirm that he wants his public key to be shared. After that the value is passed to non-wallet which would hopefully record it for future usage, effectively short-cutting the relays.

It is also possible that various wallets start to offer direct links to partner/most interesting third-party services, making the process even simpler.

As a side-note: the term login here refer to the well-known user interface. Technically, this is not a login, as the user is not formally identified as the owner of a given Stellar account. This is only a way to pass a public key. A true login would consist of signing an unique piece of data with the private key and pass it back. Maybe a different name could help underline this important distinction.

Security

What we’re trying to achieve here is of course a more friendly and more secure environment. There’s not point in the protocol I’m describing if it doesn’t achieve that. Clearly, I don’t feel like accepting the never-ending stream of wallet breaks and private keys thefts as something that have to happen in our space.

The present protocol already allow to secure one’s private keys, and to remove any risk from using non-wallet services. And the whole implementation is open-source. This is greatly reducing the surface attack. Now we’ll have to address a few more situations:

  • Server crack / DNS attacks : Get the private keys by cracking into wallets server, redirecting to wrong transactions and so on.
  • Phishing attacks: A link looking familiar brings you to a copy of a website and tries to trick you into signing the wrong transaction.
  • Spam, scam, good old tricks: Luring people into signing wrong transactions by promising various things and so on.
  • Self-hacked wallets: ==(G_G)==

To begin, one will notice that the luring part have a lot to do with education. It is easier to lure a naive uneducated user into signing something inappropriate. When talking about massive adoption, one should remember we should not ask too much either, but having clear and informative interface, some educative information here and there and promoting good habit is certainly important and have to be mentioned here.

A lot of thefts that went with the internet rise were actually related to abusing naive new users. Obviously we can expect the same thing to happen here.

Now whatever way we put it relays are going to one of the a prime target. The cosmic.link website have to offer the highest level of robustness, not only to resist attacks but also to set a high level of expectation among the ecosystem. The service is open-source, and the code is directly served from the GitHub repository through CloudFlare. It complies with coding good practices and web standard of security (SSL, HSTS, 2-FA).

My strategy is to implement various layers of protection as adoption grows. Along the way I intend to bring a few new tools into our toolboxes.

My first experiment was the little robot you see on the website. This is uniquely generated for your browser, and a phisher have no chance replicating it successfully. The feature actually need to be improved with the option of setting up some piece of text, but you get the idea. Hopefully we can build some good habit out of that kind of stuff.

The layer being currently implement is trivial: it involves the service being available offline and being installable and served locally.

The next layer is more ambitious. This will implement integrity checks and auditing contracts. The functionality will be made available stand-alone to the whole ecosystem. I’m not going to much into that as another article will follow along the release of a proof-of-concept this autumn. Basically, this will block links toward relays/wallets when they are not serving the files they are supposed to. This is a kind of a new thing and I can’t wait to having time to work on it :).

I’d like to name two security features on my short-term TODO list for js-cosmic-lib: DKIF and StellarGuard. Those are great tools and I’ll be happy to contribute to their propagation. The first one allows to have federated addresses served by third-party without security risk, thanks to address signing. The second one basically implement two-factor authentication into the ecosystem. So hopefully js-cosmic-lib will become a diffusion vector for that kind of clever innovations.

Conclusion

In this article, I tried to convey my vision of a more secure, more open and more accessible ecosystem. I know a lot of us are working toward this direction by various means, as this is obviously what will makes us successful as a group. I’d to see some reactions and hopefully some services jumping in. I’ve been working dedicate half of this year for this to happen. I expect the whole protocol to become widely supported by the end of the year. At least, it’s the delay I put on myself to have the implementation being fully polished.

While the protocol is complete, there’s a few more things to achive. The wallet-part of the library is already complete, that is converting/displaying/signing/sending. The non-wallet part, that is login and links generation routines, require further work. I’d like to make it as simple as possible to implement on that side.

Nothing is fixed, and I’m always willing to listen to feedback. Please feel free to step in and comment, criticize, challenge, ask for more information. If the whole thing is still blur for you, I’d like to know it so I can explain myself better in the future. I’m also available to help whoever needs support for implementing cosmic links in its service.

So. Let’s raise the level :)