@drift-labs/sdk-browser
Version:
SDK for Drift Protocol
189 lines (188 loc) • 8.47 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TokenFaucet = void 0;
const anchor = __importStar(require("@coral-xyz/anchor"));
const anchor_1 = require("@coral-xyz/anchor");
const spl_token_1 = require("@solana/spl-token");
const web3_js_1 = require("@solana/web3.js");
const token_faucet_json_1 = __importDefault(require("./idl/token_faucet.json"));
const config_1 = require("./config");
class TokenFaucet {
constructor(connection, wallet, programId, mint, opts, context) {
this.connection = connection;
this.context = context;
this.wallet = wallet;
this.opts = opts || config_1.DEFAULT_CONFIRMATION_OPTS;
// @ts-ignore
const provider = new anchor_1.AnchorProvider(context ? context.connection.toConnection() : this.connection,
// @ts-ignore
wallet, this.opts);
this.provider = provider;
this.program = new anchor_1.Program(token_faucet_json_1.default, programId, provider);
this.mint = mint;
}
async getFaucetConfigPublicKeyAndNonce() {
return anchor.web3.PublicKey.findProgramAddress([
Buffer.from(anchor.utils.bytes.utf8.encode('faucet_config')),
this.mint.toBuffer(),
], this.program.programId);
}
async getMintAuthority() {
return (await anchor.web3.PublicKey.findProgramAddress([
Buffer.from(anchor.utils.bytes.utf8.encode('mint_authority')),
this.mint.toBuffer(),
], this.program.programId))[0];
}
async getFaucetConfigPublicKey() {
return (await this.getFaucetConfigPublicKeyAndNonce())[0];
}
async initialize() {
const [faucetConfigPublicKey] = await this.getFaucetConfigPublicKeyAndNonce();
const ix = this.program.instruction.initialize({
accounts: {
faucetConfig: faucetConfigPublicKey,
admin: this.wallet.publicKey,
mintAccount: this.mint,
rent: web3_js_1.SYSVAR_RENT_PUBKEY,
systemProgram: anchor.web3.SystemProgram.programId,
tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
},
});
const tx = new web3_js_1.Transaction().add(ix);
const txSig = await this.context.sendTransaction(tx);
return txSig;
}
async fetchState() {
return await this.program.account.faucetConfig.fetch(await this.getFaucetConfigPublicKey());
}
async mintToUserIx(userTokenAccount, amount) {
return this.program.instruction.mintToUser(amount, {
accounts: {
faucetConfig: await this.getFaucetConfigPublicKey(),
mintAccount: this.mint,
userTokenAccount,
mintAuthority: await this.getMintAuthority(),
tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
},
});
}
async mintToUser(userTokenAccount, amount) {
const mintIx = await this.mintToUserIx(userTokenAccount, amount);
const tx = new web3_js_1.Transaction().add(mintIx);
if (this.context) {
return await this.context.sendTransaction(tx);
}
else {
return await this.program.provider.sendAndConfirm(tx, [], this.opts);
}
}
async transferMintAuthority() {
if (this.context) {
const ix = this.program.instruction.transferMintAuthority({
accounts: {
faucetConfig: await this.getFaucetConfigPublicKey(),
mintAccount: this.mint,
mintAuthority: await this.getMintAuthority(),
tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
admin: this.wallet.publicKey,
},
});
const tx = new web3_js_1.Transaction().add(ix);
const txSig = await this.context.sendTransaction(tx);
return txSig;
}
return await this.program.rpc.transferMintAuthority({
accounts: {
faucetConfig: await this.getFaucetConfigPublicKey(),
mintAccount: this.mint,
mintAuthority: await this.getMintAuthority(),
tokenProgram: spl_token_1.TOKEN_PROGRAM_ID,
admin: this.wallet.publicKey,
},
});
}
async createAssociatedTokenAccountAndMintTo(userPublicKey, amount) {
const tx = new web3_js_1.Transaction();
const [associatedTokenPublicKey, createAssociatedAccountIx, mintToTx] = await this.createAssociatedTokenAccountAndMintToInstructions(userPublicKey, amount);
let associatedTokenAccountExists = false;
try {
const assosciatedTokenAccount = await this.context.connection.getAccountInfo(associatedTokenPublicKey);
associatedTokenAccountExists = !!assosciatedTokenAccount;
}
catch (e) {
// token account doesn't exist
associatedTokenAccountExists = false;
}
const skipAccountCreation = associatedTokenAccountExists;
if (!skipAccountCreation)
tx.add(createAssociatedAccountIx);
tx.add(mintToTx);
let txSig;
if (this.context) {
txSig = await this.context.sendTransaction(tx);
}
else {
txSig = await this.program.provider.sendAndConfirm(tx, [], this.opts);
}
return [associatedTokenPublicKey, txSig];
}
async createAssociatedTokenAccountAndMintToInstructions(userPublicKey, amount) {
const state = await this.fetchState();
const associateTokenPublicKey = await this.getAssosciatedMockUSDMintAddress({ userPubKey: userPublicKey });
const createAssociatedAccountIx = (0, spl_token_1.createAssociatedTokenAccountInstruction)(this.wallet.publicKey, associateTokenPublicKey, userPublicKey, state.mint);
const mintToIx = await this.mintToUserIx(associateTokenPublicKey, amount);
return [associateTokenPublicKey, createAssociatedAccountIx, mintToIx];
}
async getAssosciatedMockUSDMintAddress(props) {
const state = await this.fetchState();
return (0, spl_token_1.getAssociatedTokenAddress)(state.mint, props.userPubKey);
}
async getTokenAccountInfo(props) {
const associatedKey = await this.getAssosciatedMockUSDMintAddress(props);
if (this.context) {
return await this.context.connection.getTokenAccount(associatedKey);
}
return await (0, spl_token_1.getAccount)(this.connection, associatedKey);
}
async subscribeToTokenAccount(props) {
try {
const tokenAccountKey = await this.getAssosciatedMockUSDMintAddress(props);
props.callback(await this.getTokenAccountInfo(props));
// Couldn't find a way to do it using anchor framework subscription, someone on serum discord recommended this way
this.context.connection.onAccountChange(tokenAccountKey, async (_accountInfo /* accountInfo is a buffer which we don't know how to deserialize */) => {
props.callback(await this.getTokenAccountInfo(props));
});
return true;
}
catch (e) {
return false;
}
}
}
exports.TokenFaucet = TokenFaucet;