Skip to content
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

[bug] SPL-Token transfers always overwrites the selected token to the native token (Solana) when trying to transfer within the appkit interface #3252

Open
Swertin opened this issue Nov 18, 2024 · 1 comment
Labels
bug Something isn't working needs review

Comments

@Swertin
Copy link

Swertin commented Nov 18, 2024

Link to minimal reproducible example

https://bonkbets.io/

Summary

Our platform is using a standard installation of appkit, with Solana as the only network available

The in-modal wallet token display properly reflects SPL-tokens that are held by an embedded wallet (generated with email, google SSO, etc)...
However, when trying to transfer any SPL-token out of the embedded wallet via the appkit interface, it overwrites any selected SPL-Token with a native SOL transfer of the same amount input for the target token.

For example, if I want to transfer 15000 BONK from my embedded appkit wallet to an external paper, it instead attempts to send 15000 SOL even when BONK is selected.

List of related npm package versions

"@reown/appkit": "^1.4.1",
"@reown/appkit-adapter-solana": "^1.4.1",

@Swertin Swertin added bug Something isn't working needs review labels Nov 18, 2024
@Swertin
Copy link
Author

Swertin commented Nov 18, 2024

Unless I'm mistaken, here is the entire handler to send a Solana transaction via the appkit client:
https://github.com/reown-com/appkit/blob/13c72ed9dfc27d9dc9a1aa55798d440b39177696/packages/adapters/solana/src/client.ts#L217C1-L251C4

This calls createSendTransaction here:
https://github.com/reown-com/appkit/blob/main/packages/adapters/solana/src/utils/createSendTransaction.ts#L27

Which is a significant fault from the expected behavior of "createSendTransaction", which should create a Solana transaction based on instructions as parameters, sign, and send it. It should probably be named "transferLamports", given that's what it does.

This looks more like test code than anything, frankly. Without providing functional SPL-token transfer logic, like the following, then the wallet should not allow users to select any tokens other than SOL, and developers should be made aware that they will need to write their own transfer logic in-site to send to the wallet provider for signing.

Sample SOL/SPL-token transfer code:

            const initializerPubkey = connectedPubkey;
            const recipientAddressPubkey = new PublicKey(recipientAddress);
            const tokenMintAddress = new PublicKey(user.selectedCurrency.mint);
            const initializerTokenAccount = getAssociatedTokenAddressSync(tokenMintAddress, initializerPubkey);
            const destinationTokenAccount = getAssociatedTokenAddressSync(tokenMintAddress, recipientAddressPubkey);
            const tokenAmount = balanceToWithdraw * 10 ** user.selectedCurrency.decimals;
            const instructions: TransactionInstruction[] = [];

            const createDebitTokenAccount = createAssociatedTokenAccountIdempotentInstruction(
                initializerPubkey,
                destinationTokenAccount,
                recipientAddressPubkey,
                tokenMintAddress
            );

            const transferBalanceIX = user.selectedCurrency?.tokenSymbol === 'SOL' ?
                SystemProgram.transfer({
                    fromPubkey: initializerPubkey,
                    toPubkey: connectedPubkey,
                    lamports: balanceToWithdraw * LAMPORTS_PER_SOL
                }) :
                createTransferCheckedInstruction(
                    initializerTokenAccount,
                    tokenMintAddress,
                    destinationTokenAccount,
                    initializerPubkey,
                    tokenAmount,
                    user.selectedCurrency.decimals
                );
            instructions.push(createDebitTokenAccount, transferBalanceIX);

            await sendAndConfirmTX({
                instructions: instructions,
                notificationID: 'handleWithdrawalNotification'
            }, successfulWithdrawCallback);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working needs review
Projects
None yet
Development

No branches or pull requests

1 participant