Skip to content

Commit

Permalink
STREAM-1060: check all token accounts ATA (#118)
Browse files Browse the repository at this point in the history
* STREAM-1060: check all token accounts ATA
  • Loading branch information
Yolley authored Dec 27, 2023
1 parent 977658b commit 58212d2
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 23 deletions.
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
"packages": [
"packages/*"
],
"version": "5.9.0",
"version": "5.9.1",
"$schema": "node_modules/lerna/schemas/lerna-schema.json"
}
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/stream/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@streamflow/stream",
"version": "5.9.0",
"version": "5.9.1",
"description": "JavaScript SDK to interact with Streamflow protocol.",
"main": "dist/index.js",
"homepage": "https://github.com/streamflow-finance/js-sdk/",
Expand Down
59 changes: 40 additions & 19 deletions packages/stream/solana/StreamClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import {
ICreateStreamSolanaExt,
IInteractStreamSolanaExt,
ITopUpStreamSolanaExt,
CheckAssociatedTokenAccountData,
CheckAssociatedTokenAccountsData,
} from "./types";
import {
ata,
Expand Down Expand Up @@ -479,7 +479,7 @@ export default class SolanaStreamClient extends BaseStreamClient {

const streamflowTreasuryTokens = await ata(data.mint, STREAMFLOW_TREASURY_PUBLIC_KEY);
const partnerTokens = await ata(data.mint, data.partner);
await this.checkAssociatedTokenAccount(data, { invoker }, ixs);
await this.checkAssociatedTokenAccounts(data, { invoker }, ixs);

ixs.push(
withdrawStreamInstruction(amount, this.programId, {
Expand Down Expand Up @@ -534,7 +534,7 @@ export default class SolanaStreamClient extends BaseStreamClient {
const partnerTokens = await ata(data.mint, data.partner);

const ixs: TransactionInstruction[] = [];
await this.checkAssociatedTokenAccount(data, { invoker }, ixs);
await this.checkAssociatedTokenAccounts(data, { invoker }, ixs);

ixs.push(
cancelStreamInstruction(this.programId, {
Expand Down Expand Up @@ -947,25 +947,46 @@ export default class SolanaStreamClient extends BaseStreamClient {
}

/**
* Utility function that checks whether associated token account for the recipient exists and adds an instruction to add if not
* Utility function that checks whether associated token accounts still exist and adds instructions to add them if not
*/
private async checkAssociatedTokenAccount(
data: CheckAssociatedTokenAccountData,
{ invoker }: IInteractStreamSolanaExt,
private async checkAssociatedTokenAccounts(
data: CheckAssociatedTokenAccountsData,
{ invoker, checkTokenAccounts }: IInteractStreamSolanaExt,
ixs: TransactionInstruction[]
) {
const accountExists = await this.connection.getAccountInfo(data.recipientTokens);
if (!accountExists?.data) {
ixs.push(
createAssociatedTokenAccountInstruction(
invoker.publicKey!,
data.recipientTokens,
data.recipient,
data.mint,
TOKEN_PROGRAM_ID,
ASSOCIATED_TOKEN_PROGRAM_ID
)
);
if (!checkTokenAccounts) {
return;
}
const checkedKeys: Set<PublicKey> = new Set();
// TODO: optimize fetching and maps/arrays
const accountArrays = [
[data.sender, data.senderTokens],
[data.recipient, data.recipientTokens],
[data.partner, data.partnerTokens],
[data.streamflowTreasury, data.streamflowTreasuryTokens],
].filter((value) => {
if (checkedKeys.has(value[1])) {
return false;
}
checkedKeys.add(value[1]);
return true;
});
const response = await this.connection.getMultipleAccountsInfo(
accountArrays.map((item) => item[1])
);
for (let i = 0; i < response.length; i++) {
if (!response[i]) {
ixs.push(
createAssociatedTokenAccountInstruction(
invoker.publicKey!,
accountArrays[i][0],
accountArrays[i][1],
data.mint,
TOKEN_PROGRAM_ID,
ASSOCIATED_TOKEN_PROGRAM_ID
)
);
}
}
}

Expand Down
9 changes: 8 additions & 1 deletion packages/stream/solana/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export interface ICreateStreamSolanaExt {

export interface IInteractStreamSolanaExt {
invoker: SignerWalletAdapter | Keypair;
checkTokenAccounts?: boolean;
}

export interface ITopUpStreamSolanaExt {
Expand Down Expand Up @@ -426,9 +427,15 @@ export interface CreateMultipleStreamsValues {
recipients: Recipient[];
}

export interface CheckAssociatedTokenAccountData {
export interface CheckAssociatedTokenAccountsData {
sender: PublicKey;
senderTokens: PublicKey;
recipient: PublicKey;
recipientTokens: PublicKey;
partner: PublicKey;
partnerTokens: PublicKey;
streamflowTreasury: PublicKey;
streamflowTreasuryTokens: PublicKey;
mint: PublicKey;
}

Expand Down

0 comments on commit 58212d2

Please sign in to comment.