Feedback requested for Onboarding & Complex transaction flow

Hi there,

This post is made out of 2 parts (Onboarding of new clients & complex transaction model) for which we need help with.

Topic 1: Onboarding of new clients (10,000+ accounts)

We would like to set up accounts for our users where we opt-in USDC asset and then trustlessly assign them out via Rekeying, so they can import the set up account to Pera Wallet via 25-word mnemonics.

Questions:
1. Creating accounts:
Can we create 10K+ accounts at once or is there any manual action required for each account that would make this process cumbersome?

2. Opting-in assets:
To what degree can we opt-in USDC asset via atomic transfers? How many accounts could we group together per atomic transfer? Will we have to sign each transaction for the opt-in to USDC asset manually (from the receiver side)?

3. Distributing mnemonics:
To what degree can we trigger the rekeying of the set up accounts automatically for when a user requests to receive the mnemonics for a set up account? Or could we rekey the set up accounts right away and trustlessly assign them in a later point of time to the new owner?

4. Security of mnemonics:
Is there a way that we can send the mnemonics to our clients via our platform, without us having access to their mnemonics?

Topic 2: Complex transaction model

Background information:
With upcoming stablecoin regulations we want to prevent any sort of transaction flow that results in practicing escrow (holding assets on behalf of users) - which is globally regulated by most financial authorities and requires a respective fiduciary license.

We have a few ideas in mind on potential transaction flows for our use case but are not certain about feasibility and technical limitations and therefore ask for your support on this matter.

Use case:

  1. John drafts a monetary Request to Silvio Micali’s Twitter handle on our platform
    e.g. “500 USDC @silviomicali if you sing Happy Birthday to me on Twitter”
  2. John posts the Request, which will expire in 7 days. The 500 USDC + commission fees are locked away during this timeframe.
  3. Silvio creates an account on our platform, verifies his Twitter account and receives access to the said Request
  4. Silvio can accept/reject the Request, or miss the Request if he’s too late on taking action.
  5. For any further steps post-accepting the Request, the platform will function as an arbiter.

Transaction Flow
John sends USDC to an account of which no one owns the keys to (including us). The outflow of USDC will be triggered by the status of the Request on our platform. When status is missed or rejected, then USDC flows back to John’s account. When status is accepted, then USDC flows to a ⅔ multisig account (John, Micali, Platform), which will be created once Silvio has provided his wallet address.

Questions to Transaction Flow:

1. Escrow Dilemma: Can an account be set up so that no one has access to its keys anymore? or could we define a set of irrevocable rules which take away the power from us, so that we technically can’t run away with the USDC as a consequence? This would solve the escrow problem, since the funds wouldn’t be in our custody anymore. Please note that once John has committed to send his Request, he shouldn’t be able to withdraw from it by obstructing the business transaction. Therefore it would be desired that we don’t require John’s signatures for future transactions other than potentially making him vote in the process of a dispute (⅔ majority approval).

2. Types of Accounts:
What type of account to lock John’s USDC away would best suit our needs as mentioned above? e.g. Stateless Smart Contract, Logic Signature, Contract Account, Delegated Account? Any other type of account we are not aware of?

3. Feasibility:
Instead of creating many such accounts for every single Request, could we set it up so that every inflow gets coupled with a multisig account which will be defined via our platform in a later point of time?

4. Multisig Accounts
Can we set up â…” multisig accounts, with only 2 predetermined signatures and the 3rd signature being added on later?

Any suggestions on adapting the flow to circumvent the escrow problematic is highly welcome!

Helpful resources:

An account can just be a public/secret key pair.
The public key is the address of the account.
You can create as many of those as you want without even sending a single transaction.
However, an account only appears on the blockchain if you send 0.1 Algo (or more) to its address.

Sending 0.1 Algos to 10k+ accounts is quite easy.
You just want to not send the 10k+ transactions at the same time but stagger a bit (like 1000 transactions every block).
Also note that most examples send one transaction and then wait for confirmation.
Instead, you want to send 1000 transactions, and then wait for confirmation.

You need to handle proper re-issuing transaction in case any transaction fail.
So you need to write a little bit of custom logic but nothing too fancy.

First note that you will need to send 0.201 Algos to all these accounts and then send a transaction from each account to itself of 0 USDC to opt in to USDC, which would cost 0.001 Algo.

Most likely atomic transfers would not be of use there.
Atomic transfers are useful when you want all transactions in a group to all happen or all fail.
But most likely, in this case there is no need for that.
If a transaction opt-in fail, you can just try it again.

You need to send a transaction to rekey an account.
If you want the user to be in full custody of the account, you can ask them for an Algorand address and issue a rekey transaction to this address.

You cannot do that in advance as you cannot know what Algorand address the user will generate.
And if you generate the address yourself, you will necessarily know the secret key.

In theory, you may be able to use stateless smart contract (as a contract account).
But nowadays, I strongly recommend to systematically use application aka (stateful) smart contracts.
Applications have an associated application account that is essentially controlled by the application.
This can be used as your escrow account.

If you use an application, you can use a single escrow for multiple queries.
Right now, you may run into a global storage limit issue, but this will soon be solved using “boxes” that should provide unlimited global storage.
So you will be able to store in the application all the requests that have been made.
And you have a single escrow accounts that contain all the USDC for all the requests, that is the application account.

Yes, using rekeying by having first the 3rd signature be a random address (not associated to any public key).
However, in your case, I think you instead want to manage this logic at an application level.

1 Like

First of all - Thank you very much for your feedback @fabrice ! I really appreciate the support you bring to the forum with your knowledge and many replies.

I’d like to ask you a few follow-up questions to your provided answers

As you mentioned, creating accounts is rather easy and funding 10K accounts is also rather easy since it could be done in 10 transactions (Ă  1000 addresses each).

You mentioned for opting-in USDC that we have to send a transaction from each account to itself. I only know accounts from an end-user perspective which is entering the mnemonics to my wallet provider and then manually click on the USDC asset to opt-in. How does that look like from a developer side? I assume that my developers won’t have to click on every single account and manually opt-in to USDC right? Will that be done in batches where they select a bunch of accounts and trigger the USDC opt-in action, which will apply to all the selected accounts? And will they have to actually sign 10’000 transactions manually?

Custodial wallets are not really an option for us because we don’t want to burden our clients with KYC, so in that case, we might as well not set up opted-in USDC accounts on our end and just send the users Algos to their (freshly created) accounts and ask them to opt-in USDC themselves…

This sounds like the solution to the problem! Can I configure the application so that when it’s deployed, no preset rules can be changed nor new rules can be added on?

Do I understand this correctly? We will set up an application with a command so that it will open an account on its own behalf and only disclose its public but not private keys?

If I assume the possibilities of an application correctly, then multisig wallets are no longer required for my use case. Instead, I can just simulate the functions of a multisig account with an application where the platform users can interact with the application by triggering certain commands on our platform which will again trigger certain commands in the application. Does that sound somewhat right?

Thank you for your time and efforts!

All of this can be fully automated by the developer, as long as you know the secret key/mnemonic of all those accounts (which to my understanding you will until the account is rekeyed).

That’s also an option.

Yes, you can have arbitrary logic controlling whether rules can be changed or not.
You can have the smart contract be such that it can never be changed.

Yes

1 Like

Hi @fabrice some time has passed since you helped me out in this thread. You mentioned back then that a new feature called Boxes will make the global storage unlimited and help with my specific use case. As I’ve seen, this feature meanwhile released!

I wanted to clarify again for my escrow use case below if this is the way to go.
Use case:
We want one single escrow account for all incoming transactions from different users. The amount of time for each transaction being kept in escrow and outflow distribution (refund, deduction of fees, transfer to seller, etc.) is dependant on preset rules that wait for feedback from our web app to know what rule to execute next. The preset rules have to be immutable and be setup in a trustless manner that prevents the application creator from the power of withdrawing client funds to his own address.

  • Do you recommend for this operation exclusively stateful smart contracts aka applications?
  • Will the box storage provide us with the solution to make all those transactions via one single address that is associated to the stateful smart contract?
  • Is it correct that we can setup the stateful smart contract in a way so that nobody including creator can control the associated “application account”? And also not have access to the private keys of the associated “application account” (escrow account)?

I saw in some other posts regarding escrow questions that you have suggested a framework called “Beaker”. Does this have any benefit for our use case as well?

As a final question, I’d like to ask if I can setup the stateful smart contract so that the corresponding beneficiary of the transaction can trigger a rule via our platform that he/she has lost access to the specified receiver address and that he/she can provide after 30 days a new wallet address? (Users on our platform don’t login via wallet address but via e-mail/phone).

As always, thank you very much for your support!

Yes, I strongly recomment only using smart contracts / applications.
Smart signatures should be restricted to very complex niche use cases:

  1. (as a smart signature contract account) if you need to run very complex computation that would cost too much in a smart contract
  2. (as a delegated logicsig) if you need to delegate some control of an account to another user or smart contract (this is an extremely rare case for very advanced key management).

I don’t think you need any of these use cases.

It depends a lot of your logic in the smart contract. Boxes are just a storage solution. To select the right storage solution for your smart contract, you can read Overview - Algorand Developer Portal

There are by default no private key for the application account. Only the smart contract can control it.

I strongly recommend using Beaker for smart contracts as it significantly simplify smart contract development. The only exception is if you need to put your smart contract in production in the coming month, as Beaker is still in beta.

This is something you would need to implement in the smart contract.
Note however this means that your platform would actually be able to do that by itself (without approval of the user). Indeed the smart contract cannot check if the user actually requested this change or not if the user lost their keys. This may or may not be an issue depending on your use case.