New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add default-token-account program #626
Conversation
Chiming in here with an idea @bartosz-lipinski and I were discussing. It would be really useful to have a system instruction which allows users to create accounts for a program address directly, performing |
I see how a One problem I see is that until we have an account realloc instruction, |
Yeah that's definitely a big drawback, may be best to leave this off until later then |
Certainly something to think about in general, I did find it annoying how I had find a "workaround" for account funding here. The solution of prepending a system Transfer instruction doesn't feel natural at all |
It can also create a slicker experience for frontend dapps. We discussed this before regarding swap applications, but let's say I only want one swap contract for ETH / SOL, to get that swap contract, I need to do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Certainly something to think about in general, I did find it annoying how I had find a "workaround" for account funding here. The solution of prepending a system Transfer instruction doesn't feel natural at all
Can you not pass in the funding account as a writable signer in the instruction and invoke()
the transfer? This suggests that would work, although I haven't traced the code to confirm: https://docs.solana.com/implemented-proposals/cross-program-invocation#instructions-that-require-privileges
)?; | ||
|
||
// Initialize the default token account | ||
invoke_signed( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can just use invoke()
here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep. I didn't at the time because then I'd need to stub out invoke()
like invoke_signed()
. But I'm knee deep into overhauling the non-BPF syscalls in sdk/src
and with my latest local code, moving back to invoke()
just works!
No. The funding account is a system account that I control, and the program can't act as a signer for it. |
Which is why that system account would need to be passed in as a writable signer. Quoting from the above link: "if the instruction the caller is processing contains a signer or writable account, then the caller can invoke an instruction that also contains that signer and/or writable account." |
I was dead curious about this, so I threw together a little test program to try it: CriesofCarrots@2509f9b |
Whoa! Awesome, that's a big win for usability. I'll give that go! |
445b9fb
to
ee514a6
Compare
new program-test framework is coming along nicely. Check out
The tests themselves are BanksClient-based. But while setting up the test environment, you can inject program and account fixtures either in the test directly, or by putting them in For example, |
// Dial down the BPF compute budget to detect if the program gets bloated in the future | ||
pc.set_bpf_compute_max_units(25_000); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Demo of how solana-labs/solana#13245 is employed in a solana-program-test
-based test harness to reduce the BPF compute budget
Tests are all passing using |
/// 2. `[]` The mint this account should be associated with. | ||
/// 3. `[]` SPL Token program | ||
/// | ||
Exists, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From your guide, I was confused by:
Doing so will cause the
DefaultTokenAccountInstruction::Exists
instruction to fail
and thought that
Doing so will cause the
DefaultTokenAccountInstruction::Assert
instruction to fail
would be easier to understand
Exists, | |
Assert, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, sure
What if this was "Derived Token" program instead with an input seed? No input seed would be the same as your current implementation. Not sure if it needs to be generalized, but it could be nice to have an early convention for this. |
hmm, maybe! How about the
For SPL Token, you'd then give it
and you need to add a Assert generalizes to:
|
Interesting.. by dropping the initialization piece, this
Looks good, you want owner as well Also, maybe |
hmm, so if The main purpose of
But without |
0b6f8e0
to
985e61c
Compare
Yeah, it just reinvents
I now feel like it's not strict enough. It feels bad that you could totally brick your default account. Kinda defeats the purpose of having an ecosystem-wide convention. I think the authority has to be controlled by the default token program. What if this becomes a |
@jstarry - wdyt about this morphing into the The "Assert" instruction is gone and there's only "Create":
The "default-token-account" then has the SPL Token Account for #2, and the mint this account will |
but the cost of creating / transferring to a new token account is minimal. I can't imagine an actual need for that
it is worse because every wallet app is going to be setup to send tokens to that associated account. e.g. All of a sudden when everyone in the family tries to send USDC to grandma they get a strange error because she accidentally gave up ownership of hers and the assert is failing |
See #779 |
The SPL Default Token Account program defines and implements conventions around locating and creating the default token account for a user wallet as discussed in #612
TODO:
invoke_signed()
spl-token-cli
. This'll really clean up the command-line UX!