Using a Programmatic Public Address (PDA) Account in Another Program
In the Solana ecosystem, a Programmatic Depository Address (PDA) account allows you to manage token transfers safely and efficiently. However, if you decide to use such an account in another program or application, there are certain requirements that must be met.
Background
A PDA is a public address that can be used by any program to receive funds. However, not all programs allow withdrawals from PDA accounts. To solve this problem, we need to look at how the withdrawal process works and what is needed to authorize the account for use in another program.
Withdrawal Process
When creating a PDA account in Solana, the following steps are performed:
- The program creates a PDA account using its own wallet.
- When a user withdraws funds from their PDA account, the withdrawal transaction is sent to the program’s PDA account.
- The program’s PDA account signs the withdrawal transaction with its private key, which allows for verification of the sender and the amount being withdrawn.
Problem
Now let’s see how an account created in the program can use the whitelist-based withdrawal process, which allows withdrawals only to users from specific whitelisted addresses. This requires additional configuration and settings:
- The PDA account must be configured to accept withdrawals from the original program.
- The original program must implement a function that notifies the whitelist service of the withdrawal attempt, using the public address of the PDA account.
- When a user tries to withdraw funds using their PDA account, the following steps are performed:
ma. The user initiates a withdrawal transaction and sends it to the network.
B. If the original program correctly configured the PDA account, it will sign the withdrawal transaction with its private key.
Solution
To solve this problem, we can implement a custom solution that will allow the account created in the program to use the whitelist-based withdrawal process when it is connected to the same Solana network. Here is one possible approach:
- Introduce a new wallet in the original program that provides a PDA address.
- Configure the new wallet to accept withdrawals from a public address using the private key of the original program.
- When the account created in the original program tries to withdraw funds, it can use the PDA address of the new wallet to sign the withdrawal transaction.
Example code
Here is a simple example of how this can be implemented using the Solana SDK:
“`typescript
import { Account, Program } from “@solana/web3.js”;
import { splTokenProgram } from “./spl-token-program”;
const originalProgram = new Program(splTokenProgram, “original_program”);
const newWallet = new Account(“new_wallet”, “new_wallet_address”);
async function withdrawalFunds(account: Account) {
// Get the private key of the account’s PDA address
const privateKey = await account.getPrivate();
// Create a new wallet with a new PDA address
const newWalletProgram = new Program(splTokenProgram, “new_program-wallet”);
const newWalletAddress = await newWalletProgram.createAccount(privateKey);
// Sign the withdrawal transaction using the new PDA address
const removalTransaction = {
account,
amount: splTokenProgram.amount,
};
const signedTransaction = await originalProgram.signTransaction(withdrawalTransaction, privateKey);
// Send the signed transaction to the network
await originalProgram.sendSignedTransaction(signedTransaction);
}
// Use :
const newWallet = wait originalProgram.newWallet();
newWalletProgram = wait newWallet.createAccount(newWalletAddress);
withdrawFunds(originalProgram.