@symmetry-hq/baskets-sdk
Version:
Software Development Kit for interacting with Symmetry Baskets Program
185 lines (162 loc) • 5.76 kB
text/typescript
import { PublicKey, SystemProgram, TransactionInstruction } from "@solana/web3.js";
import { struct, u32, u8 } from '@solana/buffer-layout';
import { publicKey, u64 } from '@solana/buffer-layout-utils';
/** Address of the SPL Token program */
export const TOKEN_PROGRAM_ID = new PublicKey('TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA');
/** Address of the SPL Token 2022 program */
export const TOKEN_2022_PROGRAM_ID = new PublicKey('TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb');
/** Address of the SPL Associated Token Account program */
export const ASSOCIATED_TOKEN_PROGRAM_ID = new PublicKey('ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL');
/** Address of the special mint for wrapped native SOL in spl-token */
export const NATIVE_MINT = new PublicKey('So11111111111111111111111111111111111111112');
/** Address of the special mint for wrapped native SOL in spl-token-2022 */
export const NATIVE_MINT_2022 = new PublicKey('9pan9bMn5HatX4EJdBwg9VgCa7Uz5HL8N1m5D3NdXejP');
export function createAssociatedTokenAccountInstruction(
payer: PublicKey,
associatedToken: PublicKey,
owner: PublicKey,
mint: PublicKey,
programId = TOKEN_PROGRAM_ID,
associatedTokenProgramId = ASSOCIATED_TOKEN_PROGRAM_ID
): TransactionInstruction {
return buildAssociatedTokenAccountInstruction(
payer,
associatedToken,
owner,
mint,
Buffer.alloc(0),
programId,
associatedTokenProgramId
);
}
export function getAssociatedTokenAddressSync(
mint: PublicKey,
owner: PublicKey,
allowOwnerOffCurve = false,
programId = TOKEN_PROGRAM_ID,
associatedTokenProgramId = ASSOCIATED_TOKEN_PROGRAM_ID
): PublicKey {
if (!allowOwnerOffCurve && !PublicKey.isOnCurve(owner.toBuffer())) throw new TokenOwnerOffCurveError();
const [address] = PublicKey.findProgramAddressSync(
[owner.toBuffer(), programId.toBuffer(), mint.toBuffer()],
associatedTokenProgramId
);
return address;
}
function buildAssociatedTokenAccountInstruction(
payer: PublicKey,
associatedToken: PublicKey,
owner: PublicKey,
mint: PublicKey,
instructionData: Buffer,
programId = TOKEN_PROGRAM_ID,
associatedTokenProgramId = ASSOCIATED_TOKEN_PROGRAM_ID
): TransactionInstruction {
const keys = [
{ pubkey: payer, isSigner: true, isWritable: true },
{ pubkey: associatedToken, isSigner: false, isWritable: true },
{ pubkey: owner, isSigner: false, isWritable: false },
{ pubkey: mint, isSigner: false, isWritable: false },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
{ pubkey: programId, isSigner: false, isWritable: false },
];
return new TransactionInstruction({
keys,
programId: associatedTokenProgramId,
data: instructionData,
});
}
export enum TokenInstruction {
InitializeMint = 0,
InitializeAccount = 1,
InitializeMultisig = 2,
Transfer = 3,
Approve = 4,
Revoke = 5,
SetAuthority = 6,
MintTo = 7,
Burn = 8,
CloseAccount = 9,
FreezeAccount = 10,
ThawAccount = 11,
TransferChecked = 12,
ApproveChecked = 13,
MintToChecked = 14,
BurnChecked = 15,
InitializeAccount2 = 16,
SyncNative = 17,
InitializeAccount3 = 18,
InitializeMultisig2 = 19,
InitializeMint2 = 20,
GetAccountDataSize = 21,
InitializeImmutableOwner = 22,
AmountToUiAmount = 23,
UiAmountToAmount = 24,
InitializeMintCloseAuthority = 25,
TransferFeeExtension = 26,
ConfidentialTransferExtension = 27,
DefaultAccountStateExtension = 28,
Reallocate = 29,
MemoTransferExtension = 30,
CreateNativeMint = 31,
InitializeNonTransferableMint = 32,
InterestBearingMintExtension = 33,
CpiGuardExtension = 34,
InitializePermanentDelegate = 35,
TransferHookExtension = 36,
// ConfidentialTransferFeeExtension = 37,
// WithdrawalExcessLamports = 38,
MetadataPointerExtension = 39,
}
export interface SyncNativeInstructionData {
instruction: TokenInstruction.SyncNative;
}
export const syncNativeInstructionData = struct<SyncNativeInstructionData>([u8('instruction')]);
export function createSyncNativeInstruction(account: PublicKey, programId = TOKEN_PROGRAM_ID): TransactionInstruction {
const keys = [{ pubkey: account, isSigner: false, isWritable: true }];
const data = Buffer.alloc(syncNativeInstructionData.span);
syncNativeInstructionData.encode({ instruction: TokenInstruction.SyncNative }, data);
return new TransactionInstruction({ keys, programId, data });
}
export abstract class TokenError extends Error {
constructor(message?: string) {
super(message);
}
}
/** Thrown if the owner of a token account is a PDA (Program Derived Address) */
export class TokenOwnerOffCurveError extends TokenError {
name = 'TokenOwnerOffCurveError';
}
/** Token account state as stored by the program */
export enum AccountState {
Uninitialized = 0,
Initialized = 1,
Frozen = 2,
}
/** Token account as stored by the program */
export interface RawAccount {
mint: PublicKey;
owner: PublicKey;
amount: bigint;
delegateOption: 1 | 0;
delegate: PublicKey;
state: AccountState;
isNativeOption: 1 | 0;
isNative: bigint;
delegatedAmount: bigint;
closeAuthorityOption: 1 | 0;
closeAuthority: PublicKey;
}
export const AccountLayout = struct<RawAccount>([
publicKey('mint'),
publicKey('owner'),
u64('amount'),
u32('delegateOption'),
publicKey('delegate'),
u8('state'),
u32('isNativeOption'),
u64('isNative'),
u64('delegatedAmount'),
u32('closeAuthorityOption'),
publicKey('closeAuthority'),
]);