@solana/spl-token#ASSOCIATED_TOKEN_PROGRAM_ID TypeScript Examples
The following examples show how to use
@solana/spl-token#ASSOCIATED_TOKEN_PROGRAM_ID.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: index.ts From zo-client with Apache License 2.0 | 6 votes |
export async function findAssociatedTokenAddress(
walletAddress: PublicKey,
tokenMintAddress: PublicKey,
): Promise<PublicKey> {
return (
await PublicKey.findProgramAddress(
[
walletAddress.toBuffer(),
TOKEN_PROGRAM_ID.toBuffer(),
tokenMintAddress.toBuffer(),
],
ASSOCIATED_TOKEN_PROGRAM_ID,
)
)[0];
}
Example #2
Source File: model.spec.ts From kin-node with MIT License | 6 votes |
test("parseTransaction create without close auth", async() => {
const [subsidizer, wallet, mint] = generateKeys(3);
const [createInstructions, addr] = await generateCreateInstructions(subsidizer, wallet, mint);
const assoc = await Token.getAssociatedTokenAddress(ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID, mint, wallet);
const createAssocInstruction = Token.createAssociatedTokenAccountInstruction(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
mint,
assoc,
wallet,
subsidizer,
);
const txs = [
new solanaweb3.Transaction({
feePayer: subsidizer,
}).add(
...createInstructions.slice(0, 2)
),
new solanaweb3.Transaction({
feePayer: subsidizer,
}).add(
createAssocInstruction,
),
];
for (let i = 0; i < txs.length; i++) {
try {
parseTransaction(txs[i]);
fail();
} catch (error) {
expect(error.toString()).toContain('missing SplToken::SetAuthority(Close) instruction');
}
}
});
Example #3
Source File: model.spec.ts From kin-node with MIT License | 6 votes |
async function generateCreateInstructions(subsidizer: solanaweb3.PublicKey, wallet: solanaweb3.PublicKey, mint: solanaweb3.PublicKey): Promise<[solanaweb3.TransactionInstruction[], solanaweb3.PublicKey]> {
const addr = await Token.getAssociatedTokenAddress(ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID, mint, wallet);
const pub = PrivateKey.random().publicKey().solanaKey();
const instructions = [
solanaweb3.SystemProgram.createAccount({
fromPubkey: subsidizer,
newAccountPubkey: addr,
lamports: 10,
space: AccountSize,
programId: TOKEN_PROGRAM_ID,
}),
Token.createInitAccountInstruction(
TOKEN_PROGRAM_ID,
mint,
addr,
pub,
),
Token.createSetAuthorityInstruction(
TOKEN_PROGRAM_ID,
addr,
subsidizer,
'CloseAccount',
pub,
[],
),
Token.createSetAuthorityInstruction(
TOKEN_PROGRAM_ID,
addr,
wallet,
'AccountOwner',
pub,
[],
)
];
return [instructions, addr];
}
Example #4
Source File: initializeMarket.ts From psyoptions with Apache License 2.0 | 6 votes |
getOrAddAssociatedTokenAccountTx = async (
associatedAddress: PublicKey,
token: Token,
payer: PublicKey,
owner: PublicKey = FEE_OWNER_KEY,
) => {
// This is the optimum logic, considering TX fee, client-side computation,
// RPC roundtrips and guaranteed idempotent.
// Sadly we can't do this atomically;
try {
await token.getAccountInfo(associatedAddress);
return null;
} catch (err) {
// INVALID_ACCOUNT_OWNER can be possible if the associatedAddress has
// already been received some lamports (= became system accounts).
// Assuming program derived addressing is safe, this is the only case
// for the INVALID_ACCOUNT_OWNER in this code-path
if (
err.message === 'Failed to find account' ||
err.message === 'Invalid account owner'
) {
// as this isn't atomic, it's possible others can create associated
// accounts meanwhile
return Token.createAssociatedTokenAccountInstruction(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
token.publicKey,
associatedAddress,
owner,
payer,
);
} else {
throw err;
}
}
}
Example #5
Source File: helpers.ts From psyoptions with Apache License 2.0 | 6 votes |
initOptionMarket = async (
program: anchor.Program<PsyAmerican>,
payer: Keypair,
optionMarket: OptionMarketV2,
remainingAccounts: AccountMeta[],
instructions: TransactionInstruction[]
) => {
await program.rpc.initializeMarket(
optionMarket.underlyingAmountPerContract,
optionMarket.quoteAmountPerContract,
optionMarket.expirationUnixTimestamp,
optionMarket.bumpSeed,
{
accounts: {
authority: payer.publicKey,
underlyingAssetMint: optionMarket.underlyingAssetMint,
quoteAssetMint: optionMarket.quoteAssetMint,
optionMint: optionMarket.optionMint,
writerTokenMint: optionMarket.writerTokenMint,
quoteAssetPool: optionMarket.quoteAssetPool,
underlyingAssetPool: optionMarket.underlyingAssetPool,
optionMarket: optionMarket.key,
feeOwner: FEE_OWNER_KEY,
tokenProgram: TOKEN_PROGRAM_ID,
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
rent: SYSVAR_RENT_PUBKEY,
systemProgram: SystemProgram.programId,
clock: SYSVAR_CLOCK_PUBKEY,
},
remainingAccounts,
signers: [payer],
instructions,
}
);
}
Example #6
Source File: token-program.ts From kin-node with MIT License | 6 votes |
static decodeCreateAssociatedAccount(instruction: TransactionInstruction): CreateAssociatedAccountParams {
this.checkProgramId(instruction.programId, ASSOCIATED_TOKEN_PROGRAM_ID);
this.checkKeyLength(instruction.keys, 7);
if (instruction.data.length !== 0) {
throw new Error(`invalid instruction data size: ${instruction.data.length}`);
}
if (!instruction.keys[4].pubkey.equals(SystemProgram.programId)) {
throw new Error('system program key mismatch');
}
if (!instruction.keys[5].pubkey.equals(TOKEN_PROGRAM_ID)) {
throw new Error('token progrma key mismatch');
}
if (!instruction.keys[6].pubkey.equals(SYSVAR_RENT_PUBKEY)) {
throw new Error('rent sys var mismatch');
}
return {
subsidizer: instruction.keys[0].pubkey,
address: instruction.keys[1].pubkey,
owner: instruction.keys[2].pubkey,
mint: instruction.keys[3].pubkey,
};
}
Example #7
Source File: Swap.tsx From swap-ui with Apache License 2.0 | 6 votes |
export function useReferral(fromMarket?: Market): PublicKey | undefined {
const { referral } = useSwapContext();
const asyncReferral = useAsync(async () => {
if (!referral) {
return undefined;
}
if (!fromMarket) {
return undefined;
}
if (
!fromMarket.quoteMintAddress.equals(USDC_MINT) &&
!fromMarket.quoteMintAddress.equals(USDT_MINT)
) {
return undefined;
}
return Token.getAssociatedTokenAddress(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
fromMarket.quoteMintAddress,
referral
);
}, [fromMarket]);
if (!asyncReferral.result) {
return undefined;
}
return asyncReferral.result;
}
Example #8
Source File: associated-token-account.ts From easy-spl with Apache License 2.0 | 6 votes |
createAssociatedTokenAccountRawInstructions = (
mint: web3.PublicKey,
address: web3.PublicKey,
owner: web3.PublicKey,
sender: web3.PublicKey,
): web3.TransactionInstruction[] => {
return [Token.createAssociatedTokenAccountInstruction(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
mint,
address,
owner,
sender
)]
}
Example #9
Source File: associatedToken.ts From jet-engine with GNU Affero General Public License v3.0 | 6 votes |
/**
* Get the address for the associated token account
* @static
* @param {Address} mint Token mint account
* @param {Address} owner Owner of the new account
* @returns {Promise<PublicKey>} Public key of the associated token account
* @memberof AssociatedToken
*/
static derive(mint: Address, owner: Address): PublicKey {
const mintAddress = translateAddress(mint)
const ownerAddress = translateAddress(owner)
return findDerivedAccount(ASSOCIATED_TOKEN_PROGRAM_ID, ownerAddress, TOKEN_PROGRAM_ID, mintAddress)
}
Example #10
Source File: mockUSDCFaucet.ts From protocol-v1 with Apache License 2.0 | 6 votes |
public async getAssosciatedMockUSDMintAddress(props: {
userPubKey: PublicKey;
}): Promise<anchor.web3.PublicKey> {
const state: any = await this.fetchState();
return Token.getAssociatedTokenAddress(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
state.mint,
props.userPubKey
);
}
Example #11
Source File: mockUSDCFaucet.ts From protocol-v1 with Apache License 2.0 | 6 votes |
public async createAssociatedTokenAccountAndMintToInstructions(
userPublicKey: PublicKey,
amount: BN
): Promise<[PublicKey, TransactionInstruction, TransactionInstruction]> {
const state: any = await this.fetchState();
const associateTokenPublicKey = await this.getAssosciatedMockUSDMintAddress(
{ userPubKey: userPublicKey }
);
const createAssociatedAccountIx =
Token.createAssociatedTokenAccountInstruction(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
state.mint,
associateTokenPublicKey,
userPublicKey,
this.wallet.publicKey
);
const mintToIx = await this.program.instruction.mintToUser(amount, {
accounts: {
mockUsdcFaucetState: await this.getMockUSDCFaucetStatePublicKey(),
mintAccount: state.mint,
userTokenAccount: associateTokenPublicKey,
mintAuthority: state.mintAuthority,
tokenProgram: TOKEN_PROGRAM_ID,
},
});
return [associateTokenPublicKey, createAssociatedAccountIx, mintToIx];
}
Example #12
Source File: cli.ts From protocol-v1 with Apache License 2.0 | 6 votes |
commandWithDefaultOption('deposit')
.argument('<amount>', 'The amount to deposit')
.action(async (amount, options: OptionValues) => {
await wrapActionInUserSubscribeUnsubscribe(
options,
async (user: ClearingHouseUser) => {
log.info(`amount: ${amount}`);
amount = new BN(amount);
const associatedTokenPublicKey = await Token.getAssociatedTokenAddress(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
user.clearingHouse.getStateAccount().collateralMint,
user.authority
);
await user.clearingHouse.depositCollateral(
amount,
associatedTokenPublicKey
);
}
);
});
Example #13
Source File: tokens.ts From swap-ui with Apache License 2.0 | 5 votes |
export async function getOwnedAssociatedTokenAccounts(
connection: Connection,
publicKey: PublicKey
) {
let filters = getOwnedAccountsFilters(publicKey);
// @ts-ignore
let resp = await connection.getProgramAccounts(TOKEN_PROGRAM_ID, {
commitment: connection.commitment,
filters,
});
const accs = resp
.map(({ pubkey, account: { data, executable, owner, lamports } }: any) => ({
publicKey: new PublicKey(pubkey),
accountInfo: {
data,
executable,
owner: new PublicKey(owner),
lamports,
},
}))
.map(({ publicKey, accountInfo }: any) => {
return { publicKey, account: parseTokenAccountData(accountInfo.data) };
});
return (
(
await Promise.all(
accs
// @ts-ignore
.map(async (ta) => {
const ata = await Token.getAssociatedTokenAddress(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
ta.account.mint,
publicKey
);
return [ta, ata];
})
)
)
// @ts-ignore
.filter(([ta, ata]) => ta.publicKey.equals(ata))
// @ts-ignore
.map(([ta]) => ta)
);
}
Example #14
Source File: mintOption.ts From psyoptions with Apache License 2.0 | 5 votes |
mintOptionsTx = async (
program: Program<PsyAmerican>,
minter: Keypair,
minterOptionAcct: Keypair,
minterWriterAcct: Keypair,
minterUnderlyingAccount: Keypair,
size: anchor.BN,
optionMarket: OptionMarketV2,
) => {
let mintFeeKey: PublicKey,
remainingAccounts: AccountMeta[] = [];
const mintFee = feeAmountPerContract(
optionMarket.underlyingAmountPerContract,
);
if (mintFee.gtn(0)) {
mintFeeKey = await Token.getAssociatedTokenAddress(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
optionMarket.underlyingAssetMint,
FEE_OWNER_KEY,
);
remainingAccounts.push({
pubkey: mintFeeKey,
isWritable: true,
isSigner: false,
});
}
await program.rpc.mintOption(size, {
accounts: {
userAuthority: minter.publicKey,
underlyingAssetMint: optionMarket.underlyingAssetMint,
underlyingAssetPool: optionMarket.underlyingAssetPool,
underlyingAssetSrc: minterUnderlyingAccount.publicKey,
optionMint: optionMarket.optionMint,
mintedOptionDest: minterOptionAcct.publicKey,
writerTokenMint: optionMarket.writerTokenMint,
mintedWriterTokenDest: minterWriterAcct.publicKey,
optionMarket: optionMarket.key,
feeOwner: FEE_OWNER_KEY,
tokenProgram: TOKEN_PROGRAM_ID,
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
clock: SYSVAR_CLOCK_PUBKEY,
rent: SYSVAR_RENT_PUBKEY,
systemProgram: SystemProgram.programId,
},
remainingAccounts,
signers: [minter],
});
}
Example #15
Source File: associated-token-account.ts From easy-spl with Apache License 2.0 | 5 votes |
getAssociatedTokenAddress = async (
mint: web3.PublicKey,
user: web3.PublicKey
): Promise<web3.PublicKey> => {
return Token.getAssociatedTokenAddress(ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID, mint, user)
}
Example #16
Source File: webhook.spec.ts From kin-node with MIT License | 5 votes |
test("createAccountHandler rejection", async () => {
const app = express();
interface createResponse {
signature: string
}
app.use("/create_account", express.json());
app.use("/create_account", CreateAccountHandler(Environment.Test, (req: CreateAccountRequest, resp: CreateAccountResponse) => {
resp.reject();
}, WEBHOOK_SECRET));
const recentBlockhash = PrivateKey.random().publicKey().solanaKey();
const owner = PrivateKey.random().publicKey().solanaKey();
const mint = PrivateKey.random().publicKey().solanaKey();
const assoc = await Token.getAssociatedTokenAddress(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
mint,
owner,
);
const createTx = new Transaction({
feePayer: subsidizer.publicKey().solanaKey(),
recentBlockhash: recentBlockhash.toBase58(),
}).add(
Token.createAssociatedTokenAccountInstruction(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
mint,
assoc,
owner,
subsidizer.publicKey().solanaKey(),
),
Token.createSetAuthorityInstruction(
TOKEN_PROGRAM_ID,
assoc,
subsidizer.publicKey().solanaKey(),
'CloseAccount',
owner,
[],
),
);
const req = {
solana_transaction: createTx.serialize({
verifySignatures: false,
requireAllSignatures: false,
}).toString('base64'),
};
const resp = await request(app)
.post("/create_account")
.set('Accept', 'application/json')
.set(AGORA_HMAC_HEADER, getHmacHeader(req))
.send(req)
.expect(403);
expect((<createResponse>resp.body).signature).toBeUndefined();
});
Example #17
Source File: index.ts From zo-client with Apache License 2.0 | 5 votes |
export function getAssociatedTokenTransactionWithPayer(
tokenMintAddress: PublicKey,
associatedTokenAddress: PublicKey,
owner: PublicKey,
) {
const keys = [
{
pubkey: owner,
isSigner: true,
isWritable: true,
},
{
pubkey: associatedTokenAddress,
isSigner: false,
isWritable: true,
},
{
pubkey: owner,
isSigner: false,
isWritable: false,
},
{
pubkey: tokenMintAddress,
isSigner: false,
isWritable: false,
},
{
pubkey: SystemProgram.programId,
isSigner: false,
isWritable: false,
},
{
pubkey: TOKEN_PROGRAM_ID,
isSigner: false,
isWritable: false,
},
{
pubkey: RENT_PROGRAM_ID,
isSigner: false,
isWritable: false,
},
];
return new TransactionInstruction({
keys,
programId: ASSOCIATED_TOKEN_PROGRAM_ID,
data: Buffer.from([]),
});
}
Example #18
Source File: webhook.spec.ts From kin-node with MIT License | 5 votes |
test("createAccountHandler", async () => {
const app = express();
interface createResponse {
signature: string
}
let actualUserId: string | undefined;
let actualUserPasskey: string | undefined;
app.use("/create_account", express.json());
app.use("/create_account", CreateAccountHandler(Environment.Test, (req: CreateAccountRequest, resp: CreateAccountResponse) => {
actualUserId = req.userId;
actualUserPasskey = req.userPassKey;
resp.sign(subsidizer);
}, WEBHOOK_SECRET));
const recentBlockhash = PrivateKey.random().publicKey().solanaKey();
const owner = PrivateKey.random().publicKey().solanaKey();
const mint = PrivateKey.random().publicKey().solanaKey();
const assoc = await Token.getAssociatedTokenAddress(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
mint,
owner,
);
const createTx = new Transaction({
feePayer: subsidizer.publicKey().solanaKey(),
recentBlockhash: recentBlockhash.toBase58(),
}).add(
Token.createAssociatedTokenAccountInstruction(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
mint,
assoc,
owner,
subsidizer.publicKey().solanaKey(),
),
Token.createSetAuthorityInstruction(
TOKEN_PROGRAM_ID,
assoc,
subsidizer.publicKey().solanaKey(),
'CloseAccount',
owner,
[],
),
);
const req = {
solana_transaction: createTx.serialize({
verifySignatures: false,
requireAllSignatures: false,
}).toString('base64'),
};
const resp = await request(app)
.post("/create_account")
.set('Accept', 'application/json')
.set(AGORA_HMAC_HEADER, getHmacHeader(req))
.set(AGORA_USER_ID_HEADER, "user_id")
.set(AGORA_USER_PASSKEY_HEADER, "user_pass_key")
.send(req)
.expect(200);
expect((<createResponse>resp.body).signature).toBeDefined();
expect(actualUserId).toBe("user_id");
expect(actualUserPasskey).toBe("user_pass_key");
});
Example #19
Source File: model.spec.ts From kin-node with MIT License | 5 votes |
test("parseTransaction create without account holder auth", async() => {
const [subsidizer, wallet, mint] = generateKeys(3);
const [createInstructions, addr] = await generateCreateInstructions(subsidizer, wallet, mint);
const assoc = await Token.getAssociatedTokenAddress(ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID, mint, wallet);
const createAssocInstruction = Token.createAssociatedTokenAccountInstruction(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
mint,
assoc,
wallet,
subsidizer,
);
const txs = [
new solanaweb3.Transaction({
feePayer: subsidizer,
}).add(
...createInstructions.slice(0, 3)
),
new solanaweb3.Transaction({
feePayer: subsidizer,
}).add(
createAssocInstruction,
Token.createSetAuthorityInstruction(
TOKEN_PROGRAM_ID,
assoc,
subsidizer,
'CloseAccount',
assoc,
[],
),
),
];
for (let i = 0; i < txs.length; i++) {
const [creations, payments] = parseTransaction(txs[i]);
expect(creations.length).toEqual(1);
expect(payments.length).toEqual(0);
if (i === 0) {
expect(creations[0].owner).toBeDefined(); // randomly generated
expect(creations[0].address.solanaKey().equals(addr)).toBeTruthy();
} else {
expect(creations[0].owner.solanaKey().equals(wallet)).toBeTruthy();
expect(creations[0].address.solanaKey().equals(assoc)).toBeTruthy();
}
}
});
Example #20
Source File: clearingHouse.ts From protocol-v1 with Apache License 2.0 | 5 votes |
async getInitializeUserInstructions(): Promise<
[Keypair, PublicKey, TransactionInstruction, TransactionInstruction]
> {
const [userAccountPublicKey, userAccountNonce] =
await getUserAccountPublicKeyAndNonce(
this.program.programId,
this.wallet.publicKey
);
const remainingAccounts = [];
const optionalAccounts = {
whitelistToken: false,
};
const state = this.getStateAccount();
if (state.whitelistMint) {
optionalAccounts.whitelistToken = true;
const associatedTokenPublicKey = await Token.getAssociatedTokenAddress(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
state.whitelistMint,
this.wallet.publicKey
);
remainingAccounts.push({
pubkey: associatedTokenPublicKey,
isWritable: false,
isSigner: false,
});
}
const userPositions = new Keypair();
const initializeUserAccountIx =
await this.program.instruction.initializeUser(
userAccountNonce,
optionalAccounts,
{
accounts: {
user: userAccountPublicKey,
authority: this.wallet.publicKey,
rent: anchor.web3.SYSVAR_RENT_PUBKEY,
systemProgram: anchor.web3.SystemProgram.programId,
userPositions: userPositions.publicKey,
state: await this.getStatePublicKey(),
},
remainingAccounts: remainingAccounts,
}
);
const initializeUserOrdersAccountIx =
await this.getInitializeUserOrdersInstruction(userAccountPublicKey);
return [
userPositions,
userAccountPublicKey,
initializeUserAccountIx,
initializeUserOrdersAccountIx,
];
}
Example #21
Source File: index.ts From kin-node with MIT License | 5 votes |
function isSPLAssoc(tx: SolanaTransaction, index: number): boolean {
return tx.instructions[index].programId.equals(ASSOCIATED_TOKEN_PROGRAM_ID);
}
Example #22
Source File: client.spec.ts From kin-node with MIT License | 5 votes |
async function assertMergeTx(tx: Transaction, priv: PrivateKey, infos: accountpbv4.AccountInfo[], createAssoc: boolean, shouldClose: boolean, closeAuth?: Buffer, appSubsidizer?: PrivateKey) {
let dest: SolanaPublicKey;
let remainingAccounts: accountpbv4.AccountInfo[] = [];
let i = 0;
if (createAssoc) {
const assoc = await Token.getAssociatedTokenAddress(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
new SolanaPublicKey(token),
priv.publicKey().solanaKey(),
);
// create, set auth, and [transfer, optional[close]] for each account
if (shouldClose) {
expect(tx.instructions.length).toEqual(2 * (infos.length + 1));
} else {
expect(tx.instructions.length).toEqual(2 + infos.length);
}
const createAssoc = TokenInstruction.decodeCreateAssociatedAccount(tx.instructions[i]);
expect(createAssoc.subsidizer.toBuffer()).toEqual(appSubsidizer ? appSubsidizer.publicKey().buffer : subsidizer);
expect(createAssoc.address.toBuffer()).toEqual(assoc.toBuffer());
expect(createAssoc.owner.toBuffer()).toEqual(priv.publicKey().buffer);
expect(createAssoc.mint.toBuffer()).toEqual(token);
i++;
const setAuth = TokenInstruction.decodeSetAuthority(tx.instructions[i]);
expect(setAuth.account.toBuffer()).toEqual(assoc.toBuffer());
expect(setAuth.currentAuthority.toBuffer()).toEqual(priv.publicKey().buffer);
expect(setAuth.authorityType).toEqual('CloseAccount');
expect(setAuth.newAuthority!.toBuffer()).toEqual(appSubsidizer ? appSubsidizer.publicKey().buffer : subsidizer);
i++;
dest = assoc;
remainingAccounts = infos;
} else {
// [transfer, optional[close]] for all but one account
if (shouldClose) {
expect(tx.instructions.length).toEqual(2 * (infos.length - 1));
} else {
expect(tx.instructions.length).toEqual(infos.length - 1);
}
dest = new SolanaPublicKey(infos[0].getAccountId()!.getValue_asU8());
remainingAccounts = infos.slice(1);
}
remainingAccounts.forEach(info => {
const transfer = TokenInstruction.decodeTransfer(tx.instructions[i]);
expect(transfer.source.toBuffer()).toEqual(Buffer.from(info.getAccountId()!.getValue_asU8()));
expect(transfer.dest).toEqual(dest);
expect(transfer.owner.toBuffer()).toEqual(priv.publicKey().buffer);
expect(transfer.amount).toEqual(BigInt(new BigNumber(info.getBalance())));
i++;
if (shouldClose) {
const close = TokenInstruction.decodeCloseAccount(tx.instructions[i]);
expect(close.account.toBuffer()).toEqual(Buffer.from(info.getAccountId()!.getValue_asU8()));
expect(close.destination.toBuffer()).toEqual(appSubsidizer ? appSubsidizer.publicKey().buffer : subsidizer);
expect(close.owner.toBuffer()).toEqual(appSubsidizer ? appSubsidizer.publicKey().buffer : subsidizer);
i++;
}
});
}
Example #23
Source File: internal.spec.ts From kin-node with MIT License | 5 votes |
test('createAccount', async () => {
const account = PrivateKey.random();
const tokenAccount = await Token.getAssociatedTokenAddress(ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID, new PublicKey(token).solanaKey(), account.publicKey().solanaKey());
const env = newTestEnv();
const [client, accountClientV4, txClientV4] = [env.client, env.accountClientV4, env.txClientV4];
setGetServiceConfigResp(txClientV4);
setGetRecentBlockhashResp(txClientV4);
let created = false;
when(accountClientV4.createAccount(anything(), anything(), anything()))
.thenCall((req: accountpbv4.CreateAccountRequest, md: grpc.Metadata, callback) => {
const err = validateHeaders(md);
if (err != undefined) {
callback(err, undefined);
return;
}
const resp = new accountpbv4.CreateAccountResponse();
if (created) {
resp.setResult(accountpbv4.CreateAccountResponse.Result.EXISTS);
} else {
const tx = SolanaTransaction.from(req.getTransaction()!.getValue_asU8());
expect(tx.signatures).toHaveLength(2);
expect(tx.signatures[0].publicKey.toBuffer()).toEqual(subsidizer);
expect(tx.signatures[0].signature).toBeNull();
expect(tx.signatures[1].publicKey.toBuffer()).toEqual(account.publicKey().buffer);
expect(account.kp.verify(tx.serializeMessage(), tx.signatures[1].signature!)).toBeTruthy();
expect(tx.instructions).toHaveLength(2);
const createAssocInstruction = TokenInstruction.decodeCreateAssociatedAccount(tx.instructions[0]);
expect(createAssocInstruction.subsidizer.toBuffer()).toEqual(subsidizer);
expect(createAssocInstruction.address).toEqual(tokenAccount);
expect(createAssocInstruction.owner.toBuffer()).toEqual(account.publicKey().buffer);
expect(createAssocInstruction.mint.toBuffer()).toEqual(token);
const setAuthInstruction = TokenInstruction.decodeSetAuthority(tx.instructions[1]);
expect(setAuthInstruction.account).toEqual(tokenAccount);
expect(setAuthInstruction.currentAuthority.toBuffer()).toEqual(account.publicKey().buffer);
expect(setAuthInstruction.newAuthority!.toBuffer()).toEqual(subsidizer);
expect(setAuthInstruction.authorityType).toEqual('CloseAccount');
resp.setResult(accountpbv4.CreateAccountResponse.Result.OK);
created = true;
}
callback(undefined, resp);
});
await client.createAccount(account);
expect(created).toBeTruthy();
try {
await client.createAccount(account);
fail();
} catch (err) {
expect(err).toBeInstanceOf(AccountExists);
}
});
Example #24
Source File: internal.spec.ts From kin-node with MIT License | 5 votes |
test('createAccount no service subsidizer', async () => {
const account = PrivateKey.random();
const tokenAccount = await Token.getAssociatedTokenAddress(ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID, new PublicKey(token).solanaKey(), account.publicKey().solanaKey());
const appSubsidizer = PrivateKey.random();
const env = newTestEnv();
const [client, accountClientV4, txClientV4] = [env.client, env.accountClientV4, env.txClientV4];
setGetServiceConfigRespNoSubsidizer(txClientV4);
setGetRecentBlockhashResp(txClientV4);
when(accountClientV4.createAccount(anything(), anything(), anything()))
.thenCall((req: accountpbv4.CreateAccountRequest, md: grpc.Metadata, callback) => {
const err = validateHeaders(md);
if (err != undefined) {
callback(err, undefined);
return;
}
const resp = new accountpbv4.CreateAccountResponse();
// This should only be reached if an app subsidizer was passed in
const tx = SolanaTransaction.from(req.getTransaction()!.getValue_asU8());
expect(tx.signatures).toHaveLength(2);
expect(tx.signatures[0].publicKey.toBuffer()).toEqual(appSubsidizer.publicKey().buffer);
expect(appSubsidizer.kp.verify(tx.serializeMessage(), tx.signatures[0].signature!)).toBeTruthy();
expect(tx.signatures[1].publicKey.toBuffer()).toEqual(account.publicKey().buffer);
expect(account.kp.verify(tx.serializeMessage(), tx.signatures[1].signature!)).toBeTruthy();
expect(tx.instructions).toHaveLength(2);
const createAssocInstruction = TokenInstruction.decodeCreateAssociatedAccount(tx.instructions[0]);
expect(createAssocInstruction.subsidizer.toBuffer()).toEqual(appSubsidizer.publicKey().buffer);
expect(createAssocInstruction.address).toEqual(tokenAccount);
expect(createAssocInstruction.owner.toBuffer()).toEqual(account.publicKey().buffer);
expect(createAssocInstruction.mint.toBuffer()).toEqual(token);
const setAuthInstruction = TokenInstruction.decodeSetAuthority(tx.instructions[1]);
expect(setAuthInstruction.account).toEqual(tokenAccount);
expect(setAuthInstruction.currentAuthority.toBuffer()).toEqual(account.publicKey().buffer);
expect(setAuthInstruction.newAuthority!.toBuffer()).toEqual(appSubsidizer.publicKey().buffer);
expect(setAuthInstruction.authorityType).toEqual('CloseAccount');
resp.setResult(accountpbv4.CreateAccountResponse.Result.OK);
callback(undefined, resp);
});
// Don't pass in subsidizer
try {
await client.createAccount(account);
fail();
} catch (err) {
expect(err).toBeInstanceOf(NoSubsidizerError);
}
// Pass in subsidizer
await client.createAccount(account, undefined, appSubsidizer);
});
Example #25
Source File: mint_tests.ts From psyoptions with Apache License 2.0 | 4 votes |
describe("mintOption", () => {
const payer = anchor.web3.Keypair.generate();
const mintAuthority = anchor.web3.Keypair.generate();
const program = anchor.workspace.PsyAmerican as Program<PsyAmerican>;
const provider = program.provider;
const minter = anchor.web3.Keypair.generate();
let quoteToken: Token;
let underlyingToken: Token;
let optionToken: Token;
let optionMarket: OptionMarketV2;
let underlyingAmountPerContract: anchor.BN;
let quoteAmountPerContract: anchor.BN;
let expiration: anchor.BN;
let optionMarketKey: PublicKey;
let bumpSeed: number;
let mintFeeKey: PublicKey | null;
let exerciseFeeKey: PublicKey;
let optionMintAccount: Keypair;
let writerTokenMintAccount: Keypair;
let underlyingAssetPoolAccount: Keypair;
let quoteAssetPoolAccount: Keypair;
let remainingAccounts: AccountMeta[] = [];
let instructions: TransactionInstruction[] = [];
let optionAccount: Keypair;
let underlyingAccount: Keypair;
let writerTokenAccount: Keypair;
let size = new u64(2);
beforeEach(async () => {
await provider.connection.confirmTransaction(
await provider.connection.requestAirdrop(payer.publicKey, 10_000_000_000),
"confirmed"
);
await provider.connection.confirmTransaction(
await provider.connection.requestAirdrop(
minter.publicKey,
10_000_000_000
),
"confirmed"
);
size = new u64(2);
});
const mintOptionsTx = async (
opts: {
underlyingAssetPoolKey?: PublicKey;
remainingAccounts?: AccountMeta[];
feeOwner?: PublicKey;
} = {}
) => {
await program.rpc.mintOption(size, {
accounts: {
userAuthority: minter.publicKey,
underlyingAssetMint: optionMarket?.underlyingAssetMint,
underlyingAssetPool:
opts.underlyingAssetPoolKey || optionMarket?.underlyingAssetPool,
underlyingAssetSrc: underlyingAccount.publicKey,
optionMint: optionMarket?.optionMint,
mintedOptionDest: optionAccount.publicKey,
writerTokenMint: optionMarket?.writerTokenMint,
mintedWriterTokenDest: writerTokenAccount.publicKey,
optionMarket: optionMarket?.key,
feeOwner: opts.feeOwner || FEE_OWNER_KEY,
tokenProgram: TOKEN_PROGRAM_ID,
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
clock: SYSVAR_CLOCK_PUBKEY,
rent: SYSVAR_RENT_PUBKEY,
systemProgram: SystemProgram.programId,
},
remainingAccounts: opts.remainingAccounts
? opts.remainingAccounts
: remainingAccounts,
signers: [minter],
});
};
describe("proper mint", () => {
beforeEach(async () => {
({
quoteToken,
underlyingToken,
optionToken,
underlyingAmountPerContract,
quoteAmountPerContract,
expiration,
optionMarketKey,
bumpSeed,
mintFeeKey,
exerciseFeeKey,
optionMarket,
remainingAccounts,
instructions,
} = await initSetup(provider, payer, mintAuthority, program));
await initOptionMarket(
program,
payer,
optionMarket,
remainingAccounts,
instructions
);
({ optionAccount, underlyingAccount, writerTokenAccount } =
await createMinter(
provider.connection,
minter,
mintAuthority,
underlyingToken,
size.mul(optionMarket.underlyingAmountPerContract).muln(2).toNumber(),
optionMarket.optionMint,
optionMarket.writerTokenMint,
quoteToken
));
});
it("should mint size OptionTokens", async () => {
try {
await mintOptionsTx();
} catch (err) {
console.error((err as AnchorError).error.errorMessage);
throw err;
}
const mintInfo = await optionToken.getMintInfo();
assert.equal(mintInfo.supply.toString(), size.toString());
});
it("should mint size WriterTokens", async () => {
try {
await mintOptionsTx();
} catch (err) {
console.error((err as AnchorError).error.errorMessage);
throw err;
}
const writerToken = new Token(
provider.connection,
optionMarket.writerTokenMint,
TOKEN_PROGRAM_ID,
payer
);
const mintInfo = await writerToken.getMintInfo();
assert.equal(mintInfo.supply.toString(), size.toString());
});
it("should transfer the underlying from the minter to the pool and take a fee", async () => {
if (!mintFeeKey) {
throw new Error("mintFeeKey wasn't set when it should be");
}
const mintFeeAcctBefore = await underlyingToken.getAccountInfo(
mintFeeKey
);
const underlyingPoolBefore = await underlyingToken.getAccountInfo(
optionMarket.underlyingAssetPool
);
const minterUnderlyingBefore = await underlyingToken.getAccountInfo(
underlyingAccount.publicKey
);
try {
await mintOptionsTx();
} catch (err) {
console.error((err as AnchorError).error.errorMessage);
throw err;
}
const expectedUnderlyingTransfered = size.mul(
underlyingAmountPerContract
);
const mintFeeAmountPerContract = feeAmountPerContract(
underlyingAmountPerContract
);
const mintFeeAmount = mintFeeAmountPerContract.mul(size);
const underlyingPoolAfter = await underlyingToken.getAccountInfo(
optionMarket.underlyingAssetPool
);
const poolDiff = underlyingPoolAfter.amount.sub(
underlyingPoolBefore.amount
);
const mintFeeAcctAfter = await underlyingToken.getAccountInfo(mintFeeKey);
assert.equal(
poolDiff.toString(),
expectedUnderlyingTransfered.toString()
);
const minterUnderlyingAfter = await underlyingToken.getAccountInfo(
underlyingAccount.publicKey
);
const minterUnderlyingDiff = minterUnderlyingAfter.amount.sub(
minterUnderlyingBefore.amount
);
assert.equal(
expectedUnderlyingTransfered.add(mintFeeAmount).neg().toString(),
minterUnderlyingDiff.toString()
);
const mintFeeAcctDiff = mintFeeAcctAfter.amount.sub(
mintFeeAcctBefore.amount
);
assert.equal(mintFeeAcctDiff.toString(), mintFeeAmount.toString());
});
});
describe("OptionMarket expired", () => {
beforeEach(async () => {
({
quoteToken,
underlyingToken,
underlyingAmountPerContract,
quoteAmountPerContract,
expiration,
optionMarketKey,
bumpSeed,
mintFeeKey,
exerciseFeeKey,
optionMarket,
remainingAccounts,
instructions,
} = await initSetup(provider, payer, mintAuthority, program, {
// set expiration to 2 seconds from now
expiration: new anchor.BN(new Date().getTime() / 1000 + 2),
}));
await initOptionMarket(
program,
payer,
optionMarket,
remainingAccounts,
instructions
);
({ optionAccount, underlyingAccount, writerTokenAccount } =
await createMinter(
provider.connection,
minter,
mintAuthority,
underlyingToken,
optionMarket.underlyingAmountPerContract.muln(2).toNumber(),
optionMarket.optionMint,
optionMarket.writerTokenMint,
quoteToken
));
});
it("should error", async () => {
try {
await wait(2000);
await mintOptionsTx();
assert.ok(false);
} catch (err) {
const errMsg = "OptionMarket is expired, can't mint";
assert.equal((err as AnchorError).error.errorMessage, errMsg);
}
});
});
describe("Underlying pool key differs from option market", () => {
beforeEach(async () => {
({
quoteToken,
underlyingToken,
underlyingAmountPerContract,
quoteAmountPerContract,
expiration,
optionMarketKey,
bumpSeed,
mintFeeKey,
exerciseFeeKey,
optionMarket,
remainingAccounts,
instructions,
} = await initSetup(provider, payer, mintAuthority, program));
await initOptionMarket(
program,
payer,
optionMarket,
remainingAccounts,
instructions
);
({ optionAccount, underlyingAccount, writerTokenAccount } =
await createMinter(
provider.connection,
minter,
mintAuthority,
underlyingToken,
size.mul(optionMarket.underlyingAmountPerContract.muln(2)).toNumber(),
optionMarket.optionMint,
optionMarket.writerTokenMint,
quoteToken
));
// Create a new token account and set it as the underlyingAssetPoolAccount
const { tokenAccount } = await initNewTokenAccount(
provider.connection,
payer.publicKey,
underlyingToken.publicKey,
payer
);
optionMarket.underlyingAssetPool = tokenAccount.publicKey;
});
it("should error", async () => {
try {
await mintOptionsTx();
assert.ok(false);
} catch (err) {
const errMsg =
"Underlying pool account does not match the value on the OptionMarket";
assert.equal((err as AnchorError).error.errorMessage, errMsg);
}
});
});
describe("OptionToken Mint key differs from option market", () => {
beforeEach(async () => {
({
quoteToken,
underlyingToken,
underlyingAmountPerContract,
quoteAmountPerContract,
expiration,
optionMarketKey,
bumpSeed,
mintFeeKey,
exerciseFeeKey,
optionMarket,
remainingAccounts,
instructions,
} = await initSetup(provider, payer, mintAuthority, program));
await initOptionMarket(
program,
payer,
optionMarket,
remainingAccounts,
instructions
);
// Create a new token mint and set it as the optionMintAccount
const { mintAccount } = await initNewTokenMint(
provider.connection,
payer.publicKey,
payer
);
optionMarket.optionMint = mintAccount.publicKey;
({ optionAccount, underlyingAccount, writerTokenAccount } =
await createMinter(
provider.connection,
minter,
mintAuthority,
underlyingToken,
size.mul(optionMarket.underlyingAmountPerContract.muln(2)).toNumber(),
optionMarket.optionMint,
optionMarket.writerTokenMint,
quoteToken
));
});
it("should error", async () => {
try {
await mintOptionsTx();
assert.ok(false);
} catch (err) {
const errMsg =
"OptionToken mint does not match the value on the OptionMarket";
assert.equal((err as AnchorError).error.errorMessage, errMsg);
}
});
});
describe("WriterToken Mint key differs from option market", () => {
beforeEach(async () => {
({
quoteToken,
underlyingToken,
underlyingAmountPerContract,
quoteAmountPerContract,
expiration,
optionMarketKey,
bumpSeed,
mintFeeKey,
exerciseFeeKey,
optionMarket,
remainingAccounts,
instructions,
} = await initSetup(provider, payer, mintAuthority, program));
await initOptionMarket(
program,
payer,
optionMarket,
remainingAccounts,
instructions
);
// Create a new token mint and set it as the optionMintAccount
const { mintAccount } = await initNewTokenMint(
provider.connection,
payer.publicKey,
payer
);
optionMarket.writerTokenMint = mintAccount.publicKey;
({ optionAccount, underlyingAccount, writerTokenAccount } =
await createMinter(
provider.connection,
minter,
mintAuthority,
underlyingToken,
size.mul(optionMarket.underlyingAmountPerContract.muln(2)).toNumber(),
optionMarket.optionMint,
optionMarket.writerTokenMint,
quoteToken
));
});
it("should error", async () => {
try {
await mintOptionsTx();
assert.ok(false);
} catch (err) {
const errMsg =
"WriterToken mint does not match the value on the OptionMarket";
assert.equal((err as AnchorError).error.errorMessage, errMsg);
}
});
});
describe("MintFee account differs from option market", () => {
let badMintFeeKey: PublicKey;
beforeEach(async () => {
({
quoteToken,
underlyingToken,
underlyingAmountPerContract,
quoteAmountPerContract,
expiration,
optionMarketKey,
bumpSeed,
mintFeeKey,
exerciseFeeKey,
optionMarket,
remainingAccounts,
instructions,
} = await initSetup(provider, payer, mintAuthority, program));
await initOptionMarket(
program,
payer,
optionMarket,
remainingAccounts,
instructions
);
// Create a new token account and set it as the mintFeeKey
const { tokenAccount } = await initNewTokenAccount(
provider.connection,
FEE_OWNER_KEY,
underlyingToken.publicKey,
payer
);
badMintFeeKey = tokenAccount.publicKey;
({ optionAccount, underlyingAccount, writerTokenAccount } =
await createMinter(
provider.connection,
minter,
mintAuthority,
underlyingToken,
optionMarket.underlyingAmountPerContract.muln(2).toNumber(),
optionMarket.optionMint,
optionMarket.writerTokenMint,
quoteToken
));
});
it("should error", async () => {
try {
await mintOptionsTx({
remainingAccounts: [
{
pubkey: badMintFeeKey,
isWritable: true,
isSigner: false,
},
],
});
assert.ok(false);
} catch (err) {
const errMsg =
"MintFee key does not match the value on the OptionMarket";
assert.equal((err as AnchorError).error.errorMessage, errMsg);
}
});
});
describe("Size <= 0", () => {
beforeEach(async () => {
({
quoteToken,
underlyingToken,
underlyingAmountPerContract,
quoteAmountPerContract,
expiration,
optionMarketKey,
bumpSeed,
mintFeeKey,
exerciseFeeKey,
optionMarket,
remainingAccounts,
instructions,
} = await initSetup(provider, payer, mintAuthority, program));
await initOptionMarket(
program,
payer,
optionMarket,
remainingAccounts,
instructions
);
({ optionAccount, underlyingAccount, writerTokenAccount } =
await createMinter(
provider.connection,
minter,
mintAuthority,
underlyingToken,
optionMarket.underlyingAmountPerContract.muln(2).toNumber(),
optionMarket.optionMint,
optionMarket.writerTokenMint,
quoteToken
));
// Set the size to 0 to trigger an error
size = new anchor.BN(0);
});
it("should error", async () => {
try {
await mintOptionsTx();
assert.ok(false);
} catch (err) {
const errMsg = "The size argument must be > 0";
assert.equal((err as AnchorError).error.errorMessage, errMsg);
}
});
});
describe("Fee owner is incorrect", () => {
beforeEach(async () => {
({
quoteToken,
underlyingToken,
underlyingAmountPerContract,
quoteAmountPerContract,
expiration,
optionMarketKey,
bumpSeed,
mintFeeKey,
exerciseFeeKey,
optionMarket,
remainingAccounts,
instructions,
} = await initSetup(provider, payer, mintAuthority, program));
await initOptionMarket(
program,
payer,
optionMarket,
remainingAccounts,
instructions
);
({ optionAccount, underlyingAccount, writerTokenAccount } =
await createMinter(
provider.connection,
minter,
mintAuthority,
underlyingToken,
optionMarket.underlyingAmountPerContract.muln(2).toNumber(),
optionMarket.optionMint,
optionMarket.writerTokenMint,
quoteToken
));
});
it("should error", async () => {
try {
await mintOptionsTx({
feeOwner: new Keypair().publicKey,
});
assert.ok(false);
} catch (err) {
const errMsg = "Fee owner does not match the program's fee owner";
assert.equal((err as AnchorError).error.errorMessage, errMsg);
}
});
});
describe("OptionMarket is for NFT", () => {
beforeEach(async () => {
({
quoteToken,
underlyingToken,
underlyingAmountPerContract,
quoteAmountPerContract,
expiration,
optionMarketKey,
bumpSeed,
mintFeeKey,
exerciseFeeKey,
optionMarket,
remainingAccounts,
instructions,
} = await initSetup(provider, payer, mintAuthority, program, {
underlyingAmountPerContract: new anchor.BN("1"),
}));
await initOptionMarket(
program,
payer,
optionMarket,
remainingAccounts,
instructions
);
({ optionAccount, underlyingAccount, writerTokenAccount } =
await createMinter(
provider.connection,
minter,
mintAuthority,
underlyingToken,
optionMarket.underlyingAmountPerContract.muln(2).toNumber(),
optionMarket.optionMint,
optionMarket.writerTokenMint,
quoteToken
));
});
it("should transfer enough lamports as required by the fee", async () => {
const minterBefore = await provider.connection.getAccountInfo(
minter.publicKey
);
const feeOwnerBefore =
(await provider.connection.getAccountInfo(FEE_OWNER_KEY))?.lamports ||
0;
try {
await mintOptionsTx();
} catch (err) {
console.error((err as AnchorError).error.errorMessage);
throw err;
}
const minterAfter = await provider.connection.getAccountInfo(
minter.publicKey
);
const feeOwnerAfter =
(await provider.connection.getAccountInfo(FEE_OWNER_KEY))?.lamports ||
0;
if (!minterAfter?.lamports || !minterBefore?.lamports) {
throw new Error("minter has no lamports");
}
const minterDiff = minterAfter?.lamports - minterBefore?.lamports;
const feeOwnerDiff = feeOwnerAfter - feeOwnerBefore;
assert.equal(-minterDiff, size.mul(new BN(NFT_MINT_LAMPORTS)));
assert.equal(feeOwnerDiff, size.mul(new BN(NFT_MINT_LAMPORTS)));
});
});
});
Example #26
Source File: webhook.spec.ts From kin-node with MIT License | 4 votes |
test("hmac header validation", async () => {
await request(app)
.post("/events")
.set('Accept', 'application/json')
.send([])
.expect(401);
const events: Event[] = [
{
transaction_event: {
tx_id: Buffer.from(base58.decode('2nBhEBYYvfaAe16UMNqRHre4YNSskvuYgx3M6E4JP1oDYvZEJHvoPzyUidNgNX5r9sTyN1J9UxtbCXy2rqYcuyuv')).toString('base64'),
solana_event: {
transaction: 'AVj7dxHlQ9IrvdYVIjuiRFs1jLaDMHixgrv+qtHBwz51L4/ImLZhszwiyEJDIp7xeBSpm/TX5B7mYzxa+fPOMw0BAAMFJMJVqLw+hJYheizSoYlLm53KzgT82cDVmazarqQKG2GQsLgiqktA+a+FDR4/7xnDX7rsusMwryYVUdixfz1B1Qan1RcZLwqvxvJl4/t3zHragsUp0L47E24tAFUgAAAABqfVFxjHdMkoVmOYaR1etoteuKObS21cc1VbIQAAAAAHYUgdNXR0u3xNdiTr072z2DVec9EQQ/wNo1OAAAAAAAtxOUhPBp2WSjUNJEgfvy70BbxI00fZyEPvFHNfxrtEAQQEAQIDADUCAAAAAQAAAAAAAACtAQAAAAAAAAdUE18R96XTJCe+YfRfUp6WP+YKCy/72ucOL8AoBFSpAA==',
}
}
}
];
await request(app)
.post("/events")
.set('Accept', 'application/json')
.set(AGORA_HMAC_HEADER, "blah")
.send(events)
.expect(401);
await request(app)
.post("/sign_transaction")
.set('Accept', 'application/json')
.set(AGORA_HMAC_HEADER, "blah")
.send(events)
.expect(401);
await request(app)
.post("/events")
.set('Accept', 'application/json')
.set(AGORA_HMAC_HEADER, getHmacHeader(events))
.send(events)
.expect(200);
const sender = PrivateKey.random().publicKey();
const destination = PrivateKey.random().publicKey();
const recentBlockhash = PrivateKey.random().publicKey();
const tx = new Transaction({
feePayer: subsidizer.publicKey().solanaKey(),
recentBlockhash: recentBlockhash.toBase58(),
}).add(
Token.createTransferInstruction(
TOKEN_PROGRAM_ID,
sender.solanaKey(),
destination.solanaKey(),
sender.solanaKey(),
[],
100,
)
);
const signRequest = {
solana_transaction: tx.serialize({
verifySignatures: false,
requireAllSignatures: false,
}).toString('base64'),
};
await request(app)
.post("/sign_transaction")
.set('Accept', 'application/json')
.set(AGORA_HMAC_HEADER, getHmacHeader(signRequest))
.send(signRequest)
.expect(200);
const mint = PrivateKey.random().publicKey().solanaKey();
const assoc = await Token.getAssociatedTokenAddress(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
mint,
sender.solanaKey(),
);
const createTx = new Transaction({
feePayer: subsidizer.publicKey().solanaKey(),
recentBlockhash: recentBlockhash.toBase58(),
}).add(
Token.createAssociatedTokenAccountInstruction(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
mint,
assoc,
sender.solanaKey(),
subsidizer.publicKey().solanaKey(),
),
Token.createSetAuthorityInstruction(
TOKEN_PROGRAM_ID,
assoc,
subsidizer.publicKey().solanaKey(),
'CloseAccount',
sender.solanaKey(),
[],
),
);
const createRequest = {
solana_transaction: createTx.serialize({
verifySignatures: false,
requireAllSignatures: false,
}).toString('base64'),
};
await request(app)
.post("/create_account")
.set('Accept', 'application/json')
.set(AGORA_HMAC_HEADER, getHmacHeader(createRequest))
.send(createRequest)
.expect(200);
});
Example #27
Source File: client.ts From kin-node with MIT License | 4 votes |
async mergeTokenAccounts(key: PrivateKey, createAssociatedAccount: boolean, commitment: Commitment = this.defaultCommitment, subsidizer?: PrivateKey): Promise<Buffer|undefined> {
const existingAccounts = await this.internal.resolveTokenAccounts(key.publicKey(), true);
const owner = key.publicKey().solanaKey();
if (existingAccounts.length === 0 || (!createAssociatedAccount && existingAccounts.length === 1)) {
return Promise.resolve(undefined);
}
let dest = new SolanaPublicKey(Buffer.from(existingAccounts[0].getAccountId()!.getValue_asU8()));
const signers = [key];
let subsidizerId: SolanaPublicKey;
const config = await this.internal.getServiceConfig();
if (!config.getSubsidizerAccount() && !subsidizer) {
return Promise.reject(new NoSubsidizerError());
}
const mint = new SolanaPublicKey(Buffer.from(config.getToken()!.getValue_asU8()));
if (subsidizer) {
subsidizerId = subsidizer.publicKey().solanaKey();
signers.push(subsidizer);
} else {
subsidizerId = new SolanaPublicKey(Buffer.from(config.getSubsidizerAccount()!.getValue_asU8()));
}
const instructions = [];
if (createAssociatedAccount) {
const assoc = await Token.getAssociatedTokenAddress(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
mint,
owner,
);
if (!Buffer.from(existingAccounts[0].getAccountId()!.getValue_asU8()).equals(assoc.toBuffer())) {
instructions.push(Token.createAssociatedTokenAccountInstruction(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
mint,
assoc,
owner,
subsidizerId
));
instructions.push(Token.createSetAuthorityInstruction(
TOKEN_PROGRAM_ID,
assoc,
subsidizerId,
'CloseAccount',
owner,
[],
));
dest = assoc;
} else if (existingAccounts.length === 1) {
return Promise.resolve(undefined);
}
}
for(let i = 0; i < existingAccounts.length; i++) {
const existingAccount = existingAccounts[i];
if (Buffer.from(existingAccount.getAccountId()!.getValue_asU8()).equals(dest.toBuffer())) {
continue;
}
instructions.push(Token.createTransferInstruction(
TOKEN_PROGRAM_ID,
new SolanaPublicKey(existingAccount.getAccountId()!.getValue_asU8()),
dest,
owner,
[],
bigNumberToU64(new BigNumber(existingAccount.getBalance()))),
);
// If no close authority is set, it likely means we do not know it and can't make any assumptions
const closeAuth = existingAccount.getCloseAuthority();
if (!closeAuth) {
continue;
}
const closeableAuths = [key.publicKey().buffer, subsidizerId.toBuffer()];
let shouldClose = false;
for(let i = 0; i < closeableAuths.length; i++) {
if (closeableAuths[i].equals(Buffer.from(closeAuth.getValue_asU8()))) {
shouldClose = true;
break;
}
}
if (shouldClose) {
instructions.push(Token.createCloseAccountInstruction(
TOKEN_PROGRAM_ID,
new SolanaPublicKey(existingAccount.getAccountId()!.getValue_asU8()),
new SolanaPublicKey(closeAuth.getValue_asU8()),
new SolanaPublicKey(closeAuth.getValue_asU8()),
[],
));
}
}
const tx = new Transaction({
feePayer: subsidizerId,
}).add(...instructions);
const result = await this.signAndSubmitTx(signers, tx, commitment);
if (result.Errors && result.Errors?.TxError) {
return Promise.reject(result.Errors.TxError);
}
return result.TxId;
}
Example #28
Source File: market.ts From raydium-ui with GNU General Public License v3.0 | 4 votes |
async function initAmm(
conn: any,
wallet: any,
market: any,
ammProgramId: PublicKey,
dexProgramId: PublicKey,
// ammKeypair: PublicKey,
ammKeys: any,
userInputBaseValue: number,
userInputQuoteValue: number,
poolCoinTokenAccount: PublicKey,
poolPcTokenAccount: PublicKey,
lpMintAddress: PublicKey,
startTime: number
) {
const baseMintDecimals = new BigNumber(await getMintDecimals(conn, market.baseMintAddress as PublicKey))
const quoteMintDecimals = new BigNumber(await getMintDecimals(conn, market.quoteMintAddress as PublicKey))
const coinVol = new BigNumber(10).exponentiatedBy(baseMintDecimals).multipliedBy(userInputBaseValue)
const pcVol = new BigNumber(10).exponentiatedBy(quoteMintDecimals).multipliedBy(userInputQuoteValue)
const transaction = new Transaction()
const signers: any = []
const owner = wallet.publicKey
const baseTokenAccount = await getFilteredTokenAccountsByOwner(conn, owner, market.baseMintAddress)
const quoteTokenAccount = await getFilteredTokenAccountsByOwner(conn, owner, market.quoteMintAddress)
const baseTokenList: any = baseTokenAccount.value.map((item: any) => {
if (item.account.data.parsed.info.tokenAmount.amount >= getBigNumber(coinVol)) {
return item.pubkey
}
return null
})
const quoteTokenList: any = quoteTokenAccount.value.map((item: any) => {
if (item.account.data.parsed.info.tokenAmount.amount >= getBigNumber(pcVol)) {
return item.pubkey
}
return null
})
let baseToken: string | null = null
for (const item of baseTokenList) {
if (item !== null) {
baseToken = item
}
}
let quoteToken: string | null = null
for (const item of quoteTokenList) {
if (item !== null) {
quoteToken = item
}
}
if (
(baseToken === null && market.baseMintAddress.toString() !== TOKENS.WSOL.mintAddress) ||
(quoteToken === null && market.quoteMintAddress.toString() !== TOKENS.WSOL.mintAddress)
) {
throw new Error('no money')
}
const destLpToken = await findAssociatedTokenAddress(owner, lpMintAddress)
const destLpTokenInfo = await conn.getAccountInfo(destLpToken)
if (!destLpTokenInfo) {
transaction.add(
Token.createAssociatedTokenAccountInstruction(
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
lpMintAddress,
destLpToken,
owner,
owner
)
)
}
if (market.baseMintAddress.toString() === TOKENS.WSOL.mintAddress) {
const newAccount = new Account()
transaction.add(
SystemProgram.createAccount({
fromPubkey: owner,
newAccountPubkey: newAccount.publicKey,
lamports: parseInt(coinVol.toFixed()) + 1e7,
space: ACCOUNT_LAYOUT.span,
programId: TOKEN_PROGRAM_ID
})
)
transaction.add(
initializeAccount({
account: newAccount.publicKey,
mint: new PublicKey(TOKENS.WSOL.mintAddress),
owner
})
)
transaction.add(transfer(newAccount.publicKey, poolCoinTokenAccount, owner, parseInt(coinVol.toFixed())))
transaction.add(
closeAccount({
source: newAccount.publicKey,
destination: owner,
owner
})
)
signers.push(newAccount)
} else {
transaction.add(
// @ts-ignore
transfer(new PublicKey(baseToken), poolCoinTokenAccount, owner, parseInt(coinVol.toFixed()))
)
}
if (market.quoteMintAddress.toString() === TOKENS.WSOL.mintAddress) {
const newAccount = new Account()
transaction.add(
SystemProgram.createAccount({
fromPubkey: owner,
newAccountPubkey: newAccount.publicKey,
lamports: parseInt(pcVol.toFixed()) + 1e7,
space: ACCOUNT_LAYOUT.span,
programId: TOKEN_PROGRAM_ID
})
)
transaction.add(
initializeAccount({
account: newAccount.publicKey,
mint: new PublicKey(TOKENS.WSOL.mintAddress),
owner
})
)
transaction.add(transfer(newAccount.publicKey, poolPcTokenAccount, owner, parseInt(pcVol.toFixed())))
transaction.add(
closeAccount({
source: newAccount.publicKey,
destination: owner,
owner
})
)
signers.push(newAccount)
} else {
// @ts-ignore
transaction.add(transfer(new PublicKey(quoteToken), poolPcTokenAccount, owner, parseInt(pcVol.toFixed())))
}
transaction.add(
initialize(
ammProgramId,
ammKeys.ammId,
ammKeys.ammAuthority,
ammKeys.ammOpenOrders,
ammKeys.lpMintAddress,
market.baseMintAddress,
market.quoteMintAddress,
ammKeys.poolCoinTokenAccount,
ammKeys.poolPcTokenAccount,
ammKeys.poolWithdrawQueue,
ammKeys.ammTargetOrders,
destLpToken,
ammKeys.poolTempLpTokenAccount,
dexProgramId,
market.address,
owner,
ammKeys.nonce,
startTime
)
)
const txid = await sendTransaction(conn, wallet, transaction, signers)
console.log('txid3', txid)
let txidSuccessFlag = 0
await conn.onSignature(txid, function (_signatureResult: any, _context: any) {
if (_signatureResult.err) {
txidSuccessFlag = -1
} else {
txidSuccessFlag = 1
}
})
const timeAwait = new Date().getTime()
let outOfWhile = false
while (!outOfWhile) {
console.log('txid3', outOfWhile, txidSuccessFlag, (new Date().getTime() - timeAwait) / 1000)
if (txidSuccessFlag !== 0) {
outOfWhile = true
}
await new Promise((resolve) => setTimeout(resolve, 1000))
}
if (txidSuccessFlag !== 1) {
throw new Error('Transaction failed')
}
clearLocal()
}
Example #29
Source File: execute-sell.ts From sdk with MIT License | 4 votes |
export async function getAuctionHouseExecuteSellInstructions(
request: IActionHouseExecuteSellRequest
): Promise<ITransactionPreparedInstructions> {
const anchorProgram = await loadAuctionHouseProgram(request.connection, request.signer)
const auctionHouseObj = await anchorProgram.account.auctionHouse.fetch(request.auctionHouse)
const isNative = auctionHouseObj.treasuryMint.equals(WRAPPED_SOL_MINT)
const buyPriceAdjusted = new BN(
await getPriceWithMantissa(
request.price,
auctionHouseObj.treasuryMint,
request.signer,
anchorProgram,
),
)
const tokenSizeAdjusted = new BN(
await getPriceWithMantissa(
request.tokensAmount,
request.mint,
request.signer,
anchorProgram,
),
)
const tokenAccountKey = (await getAssociatedTokenAccountForMint(request.mint, request.sellerWallet))[0]
const buyerTradeState = (
await getAuctionHouseTradeState(
request.auctionHouse,
request.buyerWallet,
tokenAccountKey,
//@ts-ignore
auctionHouseObj.treasuryMint,
request.mint,
tokenSizeAdjusted,
buyPriceAdjusted,
)
)[0]
const sellerTradeState = (
await getAuctionHouseTradeState(
request.auctionHouse,
request.sellerWallet,
tokenAccountKey,
//@ts-ignore
auctionHouseObj.treasuryMint,
request.mint,
tokenSizeAdjusted,
buyPriceAdjusted,
)
)[0]
const [freeTradeState, freeTradeStateBump] = await getAuctionHouseTradeState(
request.auctionHouse,
request.sellerWallet,
tokenAccountKey,
//@ts-ignore
auctionHouseObj.treasuryMint,
request.mint,
tokenSizeAdjusted,
new BN(0),
)
const [escrowPaymentAccount, escrowBump] = await getAuctionHouseBuyerEscrow(
request.auctionHouse,
request.buyerWallet,
)
const [programAsSigner, programAsSignerBump] = await getAuctionHouseProgramAsSigner()
const metadata = await getMetadata(request.mint)
const metadataObj = await anchorProgram.provider.connection.getAccountInfo(
metadata,
)
if (!metadataObj) {
throw new Error("Account info doesn't fetched")
}
const metadataDecoded: Metadata = decodeMetadata(
Buffer.from(metadataObj.data),
)
const remainingAccounts = []
if (metadataDecoded.data.creators) {
for (let i = 0; i < metadataDecoded.data.creators.length; i++) {
remainingAccounts.push({
pubkey: new web3.PublicKey(metadataDecoded.data.creators[i].address),
isWritable: true,
isSigner: false,
})
if (!isNative) {
remainingAccounts.push({
pubkey: (
await getAssociatedTokenAccountForMint(
//@ts-ignore
auctionHouseObj.treasuryMint,
remainingAccounts[remainingAccounts.length - 1].pubkey,
)
)[0],
isWritable: true,
isSigner: false,
})
}
}
}
const signers: any[] = []
const tMint = auctionHouseObj.treasuryMint
/*const instruction = AuctionHouseProgram.instructions.createExecuteSaleInstruction(
{
buyer: request.buyerWallet,
seller: request.sellerWallet,
tokenAccount: tokenAccountKey,
tokenMint: request.mint,
metadata: metadata,
treasuryMint: tMint,
escrowPaymentAccount: escrowPaymentAccount,
sellerPaymentReceiptAccount: isNative ? request.sellerWallet :
(await getAssociatedTokenAccountForMint(tMint, request.sellerWallet))[0],
buyerReceiptTokenAccount: (await getAssociatedTokenAccountForMint(request.mint, request.buyerWallet))[0],
authority: auctionHouseObj.authority,
auctionHouse: request.auctionHouse,
auctionHouseFeeAccount: auctionHouseObj.auctionHouseFeeAccount,
auctionHouseTreasury: auctionHouseObj.auctionHouseTreasury,
buyerTradeState: buyerTradeState,
sellerTradeState: sellerTradeState,
freeTradeState: freeTradeState,
programAsSigner: programAsSigner,
},
{
escrowPaymentBump: escrowBump,
freeTradeStateBump: freeTradeStateBump,
programAsSignerBump: programAsSignerBump,
buyerPrice: buyPriceAdjusted,
tokenSize: tokenSizeAdjusted,
}
)*/
const instruction = await anchorProgram.instruction.executeSale(
escrowBump,
freeTradeStateBump,
programAsSignerBump,
buyPriceAdjusted,
tokenSizeAdjusted,
{
accounts: {
buyer: request.buyerWallet,
seller: request.sellerWallet,
metadata,
tokenAccount: tokenAccountKey,
tokenMint: request.mint,
escrowPaymentAccount,
treasuryMint: tMint,
sellerPaymentReceiptAccount: isNative
? request.sellerWallet
: (await getAssociatedTokenAccountForMint(tMint, request.sellerWallet))[0],
buyerReceiptTokenAccount: (await getAssociatedTokenAccountForMint(request.mint, request.buyerWallet))[0],
authority: auctionHouseObj.authority,
auctionHouse: request.auctionHouse,
auctionHouseFeeAccount: auctionHouseObj.auctionHouseFeeAccount,
auctionHouseTreasury: auctionHouseObj.auctionHouseTreasury,
sellerTradeState,
buyerTradeState,
tokenProgram: TOKEN_PROGRAM_ID,
systemProgram: web3.SystemProgram.programId,
ataProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
programAsSigner,
rent: web3.SYSVAR_RENT_PUBKEY,
freeTradeState,
},
remainingAccounts,
signers,
}
)
instruction.keys
.filter(k => k.pubkey.equals(request.signer.publicKey))
.map(k => (k.isSigner = true))
return { instructions: [instruction], signers }
}