import type { AccountInfo, Connection, PublicKey, TransactionInstruction } from '@solana/web3.js'; /** * The vault state and share-mint supply as of a **single slot**. * * Both figures price the quote, so they have to come from one snapshot. Read * independently — even concurrently, as two RPC requests — a deposit or * redemption landing in between combines a supply and an asset total that * never coexisted, and the quote is wrong in whichever direction the * interleaving fell. Seeing a 10% deposit's new assets against the old supply * quotes ~10% high, and the floor then rejects a redemption whose share price * never moved; the opposite ordering quotes low and silently weakens the * protection. `getMultipleAccountsInfo` is served from one slot, so the pair * is always coherent — and it costs one round trip instead of two. * * @param program - Anchor program, used only for its account coder; the * provider it was built with is irrelevant, so no read-only program is needed. * @param vaultStatePda - Vault state account to decode. * @param shareMintAddr - Share mint whose supply and decimals are read. * @param extraAccounts - Further accounts to read in the same call and slot, * returned raw and in order (`null` for an absent one). Lets a caller that * also needs, say, token accounts avoid a second round trip. * @returns The decoded `VaultState`, the share mint's raw `supply`, its * `decimals`, and `extraAccountInfos` — all from the same slot. * @throws {@link AugustSDKError} when either account is absent, or is not the * account type it should be. */ export declare function readPricingSnapshot({ connection, program, vaultStatePda, shareMintAddr, extraAccounts, }: { connection: Connection; program: any; vaultStatePda: PublicKey; shareMintAddr: PublicKey; extraAccounts?: PublicKey[]; }): Promise<{ vaultStateData: any; supply: bigint; shareDecimals: number; extraAccountInfos: (AccountInfo | null)[]; }>; /** * The token account a vault instruction should use for `mint`, its balance, * and the instruction (if any) needed to bring it into existence. * * `createIx` is present iff the owner holds no *account* for `mint`. It says * nothing about balance — an existing account may hold zero, which is a * distinct state. Callers that need funds must check {@link balance}. */ export interface IResolvedTokenAccount { /** Account to pass to the program as `sender_token_account` / `sender_share_account`. */ address: PublicKey; /** Raw on-chain balance of {@link address}; `0n` when the account is absent. */ balance: bigint; /** * True when every account the wallet holds for this mint is frozen. Tokens * can move neither out of nor into a frozen account, so this is fatal for * funding, burning *and* payout — reject before requesting a signature. */ frozen: boolean; /** * Idempotent ATA-creation instruction, or `undefined` when an account * already exists. Prepend to the vault instruction — never send on its own. */ createIx?: TransactionInstruction; } /** * Pick which token account to hand the vault program for a given mint, and * describe how to create it when the user has none. * * The vault program constrains these accounts by `token::mint` + * `token::authority` (not `associated_token::…`), so any account the signer * owns qualifies. We therefore keep an existing account when there is one — * that is where the user's balance already lives — and fall back to the * associated token account otherwise. * * Two deliberate choices: * * - **The create is returned, not sent.** Prepended to the deposit/redeem via * `.preInstructions()` it is atomic with the transfer, so there is no window * in which the vault instruction can reference an account that has not * landed. Sent as its own transaction — as this module used to — it raced * its own confirmation. Observed in production (2026-08-11): * a deposit failed with `Simulation failed … Logs: []` while the share-ATA * create was still in flight, then succeeded 17s later on retry. The empty * log array means the transaction never reached program execution, so there * was nothing on-chain to debug from. * - **Idempotent.** `createAssociatedTokenAccountIdempotentInstruction` is a * no-op when the account already exists, so a concurrent create — another * tab, a wallet's auto-provisioning — cannot turn into an * `SystemError::AccountAlreadyInUse` ("already in use") failure between our * read and our submit. * * Which account wins when several exist is decided by * {@link selectRichestTokenAccount} — the same rule every balance *read* in * this adapter uses, so the account a UI reports and the account a transfer * names are never different accounts. * * Classic SPL Token only: the ATA is derived under `TOKEN_PROGRAM_ID`, matching * the `tokenProgram` both handlers pass, even though the program's * `TokenInterface` would also accept Token-2022. * * @param owner - Wallet that owns the account and pays rent for any creation. * @throws AugustSDKError when a candidate account's balance cannot be read * (propagated from the shared selector). */ export declare function resolveUserTokenAccount({ connection, owner, mint, }: { connection: Connection; owner: PublicKey; mint: PublicKey; }): Promise;