[Withdrewed] Request for Funding @davidtavarez: One-time use Slatepack addresses for Wallet (RFC and Grin++ Implementation)


On April 1st my previous funding request expired. In order to advance the Post 5.0.0 wish list I would like to tackle the One-time use Slatepack addresses for Wallet and implement this in Grin++. This implementation requires a RFC.

What do I want to achieve?

The SlatepackAddress is a shareable bech32 encoded ed25519 public key that can be used both to route synchronous transactions and to encrypt asynchronous transactions. We can use Grin HD wallets to generate deterministic ed25519 public keys and therefore Grin addresses. Addresses are being generated using keychain paths.

I will bring the possibility for the users to be able to use one-time Slatepack addresses.

Why I want to do that?

One-time addresses is a tool to protect users privacy and are very common in a large variety of cryptocurrencies. Grin should definitely give this option to the users. One-time addresses are not the same as addresses from different accounts, this One-time addresses are tied to an specific account. Users can use one-time address for each account.

Time Estimations/Plan

In this situation it would be hard to estimate time. I will considered this as finished when the RFC gets approved. This process could take x amount of time that I am not aware of. The plan is to have a working implementation on Grin++ of the RFC. This will help us to see this working and polish the UX. The implementation of this RFC on grin-wallet will depend on the Rust team priorities.

Anyways, if one wants to be pessimistic I would say that in 2 months this should be merged into the Grin++ master branch. But since Grin have this 2-weeks cycle for the Developers meetings, I might be shooting myself in a foot by giving an estimation because I can’t say when the RFC will be approved and I can’t predict the potential suggestions :sweat_smile:.

Funds requested

I am requesting 10.000 EUR equivalent in BTC. I will place a PR for the RFC and also, I will have this feature released on Grin++ Desktop.


EDIT: This funding request was not approved.
EDIT 2: Added Withdrawed at the title to avoid misunderstanding.


if it’s a one-time address which always uses a new tor address then if i have 100 active transactions you will need to have 100 tor listeners? What if instead you would have eg. X addresses per tor address but you would filter them out based on the nonce that you put in that address (eg. nonces would be from 1 to X)? It might also be possible to only have one tor address, but maybe that’s not preferable. What i’m thinking about is the async non-autoreceive tor support

1 Like

I fully support researching this direction :+1: The reason I say researching is because I believe this is much more of a research problem than an implementation one. My understanding is that the ed25519 public key is the identity which is used for payment proofs. If this key gets changed per transaction, then the existing payment proofs no longer work because you have ephemeral (one-time) keys which are no longer identities and would need to be signed by an actual identity outside of this context. It is definitely worth researching imo (I might also be wrong about the above). I remember @joltz mentioned one time addresses when we were discussing possible improvements so perhaps he has also something to add here.

P.S. I really believe we should first get the RFC to accepted and only then implement things. Similarly like fix-fees RFC right now where we have a blocked merge and are waiting for the acceptance.

Edit: oops, I just remembered I had a conversation about this with @david and he suggested having a suffix in grin address which changes. I believe this form has no issues with the problem I mentioned.


In support of this funding.
Just to improve my understanding, is this is different from adding another level of derivation to the keys you use for each address, e.g. going from m/44’/0’/0’/c to m/44’/0’/0’/c/i?

What is the current situation for Grin++ and grin-wallet. Does Grin uses a new key as blinding factor for each transaction, or just one key for all transactions?
One reason why I want to understand this better is because I think this also is related to on one of the community projects ideas, creating an Airdrop workflow.

So e.g. generating one time use keys to which you send some Grin for an airdrop. Users can self spend, send the transaction to their own wallet upon scanning. After e.g. 1 year, you reclaim any unclaimed airdrops from your airdrop account.
Alternatively special airdrop seed phrases could be used, e.g. 12 word seed phrases. Only in this case it might be harder to manage and reclaim unclaimed airdrops, unless we use something like BIP84

This is a bit off-topic since no new slatepack addresses are needed to self spend an airdrop, but it does relate much to the derivation sheme used by the wallet. Best to consider all future uses.

1 Like

Maybe relevant.
Attacking Deterministic Signature Schemes using Fault Attacks

1 Like

I’ve been experimenting a bit. There are 3 potential flows for this.

#1. Automatically generate a new address after receiving a transaction. Many BTC wallets allow this, and people are familiar with this, but after shortly testing this flow, it is a bit confusing to be honest.

#2. Generate a new address on-demand. This case is less confusing than #1 and very straight forward. The user would just need to demand a new address. But there is a downside, especially for Miners, they will need to set their address every time they want to withdraw.

#3. Generate a permanent address and temporary ones. This seems to be more flexible. We could set the address generated from m/0/a/0 as permanent and we could allow users to generate new ones on demand. Having a list of addressed that can be used and reused at any moment could complement this flow.

What do you think?


Definitely in favor of #3.
Basically one main address for most uses, and temporary addresses to use for fun purposes and for people you do not actually like to leak your main address to since even though it is tor, it still is a pseudonym of sorts that you might not want to share with everyone.
I would just add the temporary ones one derivation level lower of the main address.

1 Like

Are we talking about auto-receive? If there is no auto-receive then i think you need new address for each tx to prevent spam

I absolutely love all of them, I think if we can get any of these implemented then it will go a long way in bridging the usability gap. Thank you for all the diligence

My ranked preference would be 3, 2, 1.

I guess just to satisfy the interactivity camp, this would be optional and wallet side?


I am using my vote to 3.

#2 Could easily work in a non auto receive scenario too I think.

Yes, totally optional. I like the one-permanent address enabled, specially for miners, but I’m not sure whether this will be confusing for regular users or not.

1 Like

Here’s the example where i don’t see how you can prevent a spam with #2. You give me your address, i create 1k different transactions sending you minimal amount. If there is no auto-receive then i need to manually cancel (or accept if i want to) 1k transactions

The answer is simple: both options could be available for users; potentially, I could enable a setting to autogenerate a new address after receiving a transaction (#1). And also, I could have the option of generating a new address on demand (#2), in this case (1k transactions) I have 2 hours and 45 minutes (if we say that each tx through tor is about 10 seconds) to either turn off the listener or just generate a new address.

Still, wallets could also make things easier by having bulk actions, so people could cancel x amount of transactions “at the same time”.

1 Like

If you turn off the listener you will not be getting other valid transactions which is imo not desirable. From my understanding when you don’t have autoreceive there’s only 1 communication required through tor to spam, why would that take 10 sec per request? When you generate a new address does your old one become invalid? I’m assuming yes, but then what happens with transactions which are in progress (or not yet started but you’ve shared your old address already)?

From what I do understand is, if we change the receiving address you can only listen on the newly generated address , correct?

So its only possible to listen on one address at the time, if I am not misstaken?

I would then suggest, to have the address changes in a manual way, if you can not listen to more then one address at the time. This makes it clear which address I am using at the moment and can receive GRINs to.

There is no practical reason for #1. Bitcoin wallets do that because their addresses are stored on-chain, so therefore reusing is discouraged. For Grin, much like Monero’s stealth addresses, the only time you really need a new one is if you have 2 separate online identities that you don’t want to link together (e.g. say I have 2 forum.grin.mw accounts and want to share addresses on both - I obviously wouldn’t want to use the same address).

I think #3 is ideal of course. The best approach is to have some kind of address management page that allows you to create new addresses, mark them as one-time, permanent, or limited duration (maybe 1 day). You can manually expire addresses, or manually restore old addresses as needed. This would solve all use-cases, but would require the most amount of work from you, obviously.


You could include a random number in grin address. Eg. grinaddress1 = { x1, tor_pubkey1 }, grinaddress2 = { x2, tor_pubkey1 }. Wallet keeps { x1, x2 } (maybe you need tor pubkey relation as well, not sure). Whenever i generate new grinaddress i store its x, whenever tx is finished i remove it. When a partial tx arrives to you, you drop it if its x is not in your xs set

That’s only true with auto-receive because there is no spam attack, right?

1 Like

I don’t see how this potential feature is related to a non auto-receive flow and why/how is meant to solve then Spam issue on a non auto-receive context, but, again, the simple answer is: turn off the listener. Also, we could block transactions by address if you like and then change you address, but that is out of scope, one-time addresses won’t introduce any possibility of Spam attacks because the current behavior is: auto-receive.

In a context of non auto receive? Both address, sender and receiver, are known, there is enough information for the receiver to communicate back to the sender. But, what happen if the transaction is legit and the sender changes their address for whatever reason in a context of non auto receive? since transactions are interactive, the receiver would do the same as if the sender address is not reachable, which is either do nothing or to contact the sender.

Right now yes, it is only possible to listen on one address, but we could create as many hidden services as we want, that’s why we could have a permanent address always listening (option #3).

I like this. We could have the initial address as permanent by default, and, optionally, let the user setup the extra addresses.

auto-receive is the current behavior.


I would like to summarize this including the feedback received.

I’m proposing a feature. Grin could offer the possibility of having extra addresses for each account.

Reusable, Disposable (one-time) or Permanent.

Addresses can be: reusables, disposables or permanent. Reusable means that this address can be used more than once at any moment. Disposable or One-time Use Address, can’t be used again after receiving a transaction. A Permanent address is the default address. Currently by default we are using the address generated from m/0/a/0 where a is the account, this could be the initial address. A permanent or default address is the address that is used to create the default listener by the wallet. This wallet does not change automatically, only can be alternate by the user manually.


Only one permanent address and one extra address can be enabled (listening) at the same time, to avoid confusion.

Addresses Manager

Addresses should be managed by the wallet using the local database with the current state, the type and an alias. More about how this should work will be written in the RFC.


This feature must be optional and could be enabled and/or disabled by using a configuration flag. The default value is: disabled.


Miners could use a different address for each pool and enable the address using the alias, since transactions are interactive, this won’t represent any problem.

What about in a context of User Level interactivity or UITX?

I don’t see any incompatibility with the flow described here.

1 Like

Exactly It doesn’t disrupt anything for people who do not elect to use it. I am both befuddled and frustrated with the attempt to scuttle any improvement on the non-interactive front, when so many times it was said that the protocol would remain agnostic and usability would be solved on the GUI level.

I speak for myself, but anecdotally many, when I say thank you so much for your hard work and determination on this.

1 Like