Dweb support for wallets used for payment and ownership

I’ve outlined some wallet management features for dweb and welcome feedback, particularly from app developers because my plan is to begin implementing this along with REST and Rust APIs in dweb-lib and on the dweb-cli.

I envisage the secrets for any number of named wallets will be stored in a Vault on the network, and the APIs and CLI can be told the name of a wallet, and what and when to use it (e.g. for payments and ownership).

Here’s my outline spec. Let me know what you think, particularly if you plan building apps that will store data on the network, such as web apps using the dweb REST APIs.

Also very keen to hear from other devs working on libraries and APIs so we can try to end up with a common way of doing this and common implementations if possible.

Goal
	* named wallets with secrets stored in a vault on the network
	* CLI, REST and dweb-lib each support:
		* selection of a default wallet for payments with ability to override this for one-off operations
		* selection of a default wallet for ownership with ability to override this for one-off operations
		* creation, renaming, deletion, export, listing etc of named wallets
[ ] Stage 1 - separate payment and owner secrets
	[ ] payment key is from SECRET_KEY env or wallet as now
	[ ] if an owner key is provided from DWEB_OWNER_SECRET env, it is set in DwebClient, otherwise the payment key is copied and used for ownership as well
	[ ] dweb features all change to separate owner and payment option when calling Autonomi APIs
[ ] Stage 2 - store multiple named keys on the network
	[ ] dweb CLI provides way to use SECRET_KEY or DWEB_OWNER_SECRET to create a Vault, and SECRET_KEY is stored in the vault in a "wallets" map with name "payments". A new wallet is created at the same time and called "owner".
	[ ] DWEB_OWNER_SECRET provides access to the Vault, and dweb CLI and dweb serve use that to open the vault and load the keys into their wallets map
	[ ] dweb cli has options to specify the *name* of wallet to use for payments and ownership
	[ ] REST API has a /wallet PUT operation where Payment-Wallet Owner-Wallet custom headers can change the default wallet names from then on
	[ ] Each PUT/POST operation also supports the custom headers Payment-Wallet Owner-Wallet, which override the name to use for this operation only
[ ] Stage 3 - provide APIs for creating, naming and renaming wallets stored in the Vault
	[ ] dweb CLI wallet commands
		[ ] wallet --create WALLET-NAME (with option to specify the secret)
		[ ] wallet --rename WALLET-NAME NEW-NAME
		[ ] wallet --delete WALLET-NAME
		[ ] wallet --export WALLET-NAME
		[ ] wallet --address WALLET-NAME shows the public address
		[ ] wallet --balance WALLET-NAME - shows public address and balances (by ARB-ETH / ANT)
		[ ] wallet --list list wallets by name with various levels of detail (names, addresses, ETH balance, ANT balance)
		[ ] wallet --current-payments shows name of current payments wallet
		[ ] wallet --set-payments WALLET-NAME
		[ ] wallet --current-ownership shows name of current ownership wallet
		[ ] wallet --set-ownership WALLET-NAME
	[ ] dweb REST commands for each of the above

(cc @Traktion @riddim @loziniak @safemedia @Josh @Southside @Champii and any devs I’ve missed!)

7 Likes

What’s the usecase for separating payment from ownership? I always assumed it would be the same key, and was quite comfortable with this idea for most situations I thought about…

2 Likes

Passkey, Ubikey, Trezor support would be fun…

2 Likes

First of all the Ethereum keys happen to be able to be compatible with bis keys but they are calculated differently and therefore aren’t really BLS keys… Not sure that counts as argument because funnily it seems to work…

But then there’s that if you use the (publicly known) Ethereum address from which you sign payments you have the public key and therefore address of the vault - right? You cannot decrypt it but you know which one it is if you know the public address of your target.

And then there’s the fact that I have more than 1 Ethereum wallet, I want to have my autonomi account not bound to one of them because those 2 things have nothing to do with each other and I don’t want to be my autonomi account to be tied to a singled one of them.. I want to be able to maybe import or using metamask and trezor for external signing without a need for any extra hops for the ant bevause they’re not on the right address that happens to be my ‘account address’


2 Likes

I would appreciate if we could get away from storing private keys as clear text (in files/envs)

I added a feature to autoprox to import a payment key.

That key then is stored encrypted via aes with a passphrase. The hash of the passphrase is the name of the wallet. (it’s a strong passphrase generated by the backend and returned to the api user… Not one he could chose - but that was just a first shot - I like your naming idea and storing the keys on the network.)

So if you want to use that wallet you use that passphrase as a payment token - server side hashes, knows what to decrypt, decrypts the key and uses it for the payment. (and forgets it again until the next payment token flies in)

Similar could be done with the account package but with a user chosen phrase maybe? That gets used for derivation of a private key which then leads to the info needed to access the account vault..?


All in all I really like that concept and think it makes a lot of sense. I especially like the online storage of wallet stuff.
If we then store an encrypted version of the account secret too somewhere (maybe 3 out of 4 good friends BLS magic decrypt) I could recover my account by asking 3 of my good friends to decrypt their share of the secret for me and I could combine those then to recover my account if I somehow loose access at some point

2 Likes

I assumed that too but riddim pointed out that it is ok to have a separate owner from the payment wallet, and there’s nothing in my proposal that stops people still doing this.

I imagine there are a few use cases for separating them, but the one I most like is reducing the connection between what is currently a privacy vulnerability (the wallet used for payment), and something that can be used to prove someone uploaded certain data. That’s because wallets used for payments leave a trail can lead back to exchanges and KYC. So if you can link the payment wallet to some mutable data, you have a link to the person who uploaded that data (if it is accessed via something mutable, so Vault, Register/History, Pointer etc).

It isn’t a big deal for most cases, but wherever I can I will choose to reduce the chances of privacy being broken.

So I think it is good to allow people to separate them. And where it is no more difficult to do so, that I think should be the default. So for my wallet proposal they will be separate by default, but there’s nothing to stop someone (or an app) overriding that.

I have a DwebClient struct which wraps the autonomi::Client and use this for various API controls (such as retries, max payment etc) and can add a separate owner to that struct. But it can just be a copy of the payment wallet if folk want that.

3 Likes

I hadn’t realised this until embarrassingly recently too, but I’m very glad for it.

Being able to have a public append only data type, with both private and public keys shared, allows multiple people to write to it. As each write is immutable, the history cannot be rewritten, even with the private key.

For me, this unlocks comments threads, forums, etc, where multiple users may want to participate.

It could also help with data structures you own, but only want others to write to, e.g. email inboxes, message queues, etc. In those cases, you want folks to be able to append to your list.

Edit: same for payments/tokens too, actually.

Maybe this isn’t what you mean, but I only understood it after seeing the improved documentation and code.

6 Likes

Yes, I quickly reflected, that I forgot about basic difference, that we pay with ETH, and owner keys are BLS. I already live in a world of Native Token hahaha :smiley: Or because with Jams/Safeapi we tried to make this irrelevant by deriving owner key from payment key.

4 Likes

Even with native, it should still be possible for people to pay for others to upload. Hopefully without revealing any keys

I might have the token, but not the upload b/w, but my mate has the upload b/w but not the token. So it’d be good to be able to have them upload and I pay for it.

3 Likes

So at the moment it seems that the network explicitly verifies the source of the tokens, too. Is this needed for some technical / security reasons? Why can’t payment be valid just because funds arrived?

The only thing verified is that the payment address is within a range, which can be larger or smaller. It’s about accepting the payment even if the node it is addressed to has disappeared.

4 Likes

Thanks for clarifying, much appreciated :+1:

1 Like