New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@jet-lab/margin

Package Overview
Dependencies
Maintainers
5
Versions
89
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@jet-lab/margin - npm Package Compare versions

Comparing version 0.1.34 to 0.1.35

4

dist/cjs/margin/accountPosition.d.ts

@@ -44,4 +44,4 @@ import { PublicKey } from "@solana/web3.js";

calculateValue(): void;
collateralValue(): BN;
requiredCollateralValue(): BN;
collateralValue(): any;
requiredCollateralValue(): any;
setBalance(balance: BN): void;

@@ -48,0 +48,0 @@ setPrice(price: PriceInfo): void;

@@ -1,2 +0,1 @@

/// <reference types="bn.js" />
import { Address, AnchorProvider, BN } from "@project-serum/anchor";

@@ -3,0 +2,0 @@ import { GetProgramAccountsFilter, PublicKey, TransactionInstruction, TransactionSignature } from "@solana/web3.js";

@@ -1,2 +0,1 @@

/// <reference types="bn.js" />
import { Address, BN } from "@project-serum/anchor";

@@ -6,3 +5,3 @@ import { PriceData } from "@pythnetwork/client";

import { PublicKey, TransactionInstruction } from "@solana/web3.js";
import { AssociatedToken } from "../../token";
import { AssociatedToken, TokenAddress } from "../../token";
import { TokenAmount } from "../../token/tokenAmount";

@@ -90,4 +89,4 @@ import { MarginAccount } from "../marginAccount";

calculatePrices(pythPrice: PriceData | undefined): PriceResult;
depositNoteExchangeRate(): BN;
loanNoteExchangeRate(): BN;
depositNoteExchangeRate(): any;
loanNoteExchangeRate(): any;
/**

@@ -145,15 +144,16 @@ * Linear interpolation between (x0, y0) and (x1, y1)

amount: BN;
source?: Address;
source?: TokenAddress;
}): Promise<string>;
withDeposit({ instructions, depositor, source, destination, amount }: {
withDeposit({ instructions, marginAccount, source, destination, amount }: {
instructions: TransactionInstruction[];
depositor: Address;
source: Address;
marginAccount: MarginAccount;
source?: TokenAddress;
destination: Address;
amount: BN;
}): Promise<void>;
marginBorrow({ marginAccount, pools, amount }: {
marginBorrow({ marginAccount, pools, amount, destination }: {
marginAccount: MarginAccount;
pools: Pool[];
amount: BN;
destination?: TokenAddress;
}): Promise<void>;

@@ -168,13 +168,14 @@ withGetOrCreateLoanPosition(instructions: TransactionInstruction[], marginAccount: MarginAccount): Promise<Address>;

}): Promise<void>;
marginRepay({ marginAccount, pools, amount }: {
marginRepay({ marginAccount, pools, source, amount }: {
marginAccount: MarginAccount;
pools: Pool[];
amount: PoolAmount;
source?: TokenAddress;
amount: BN;
}): Promise<void>;
makeMarginRepayInstruction({ instructions, marginAccount, deposit_account, loan_account, amount }: {
withMarginRepay({ instructions, marginAccount, depositPosition, loanPosition, amount }: {
instructions: TransactionInstruction[];
marginAccount: MarginAccount;
deposit_account: Address;
loan_account: Address;
amount: PoolAmount;
depositPosition: Address;
loanPosition: Address;
amount: BN;
}): Promise<void>;

@@ -185,3 +186,3 @@ withdraw({ marginAccount, pools, amount, destination }: {

amount: PoolAmount;
destination?: Address;
destination?: TokenAddress;
}): Promise<void>;

@@ -191,4 +192,4 @@ withWithdraw({ instructions, marginAccount, source, destination, amount }: {

marginAccount: MarginAccount;
source: Address;
destination: Address;
source: PublicKey;
destination?: TokenAddress;
amount: PoolAmount;

@@ -195,0 +196,0 @@ }): Promise<void>;

@@ -320,3 +320,3 @@ "use strict";

*/
async deposit({ marginAccount, amount, source }) {
async deposit({ marginAccount, amount, source = token_1.TokenFormat.unwrappedSol }) {
(0, chai_1.assert)(marginAccount);

@@ -330,6 +330,5 @@ (0, chai_1.assert)(amount);

const instructions = [];
source !== null && source !== void 0 ? source : (source = await token_1.AssociatedToken.withCreateOrWrapIfNativeMint(instructions, marginAccount.provider, this.tokenMint, amount));
await this.withDeposit({
instructions: instructions,
depositor: marginAccount.owner,
marginAccount,
source,

@@ -342,3 +341,12 @@ destination: position.address,

}
async withDeposit({ instructions, depositor, source, destination, amount }) {
async withDeposit({ instructions, marginAccount, source = token_1.TokenFormat.unwrappedSol, destination, amount }) {
const provider = marginAccount.provider;
const mint = this.tokenMint;
source = await token_1.AssociatedToken.withBeginTransferFromSource({
instructions,
provider,
mint,
amount,
source
});
const ix = await this.programs.marginPool.methods

@@ -350,3 +358,3 @@ .deposit(amount)

depositNoteMint: this.addresses.depositNoteMint,
depositor,
depositor: marginAccount.owner,
source,

@@ -358,14 +366,20 @@ destination,

instructions.push(ix);
token_1.AssociatedToken.withEndTransfer({
instructions,
provider,
mint,
destination
});
}
async marginBorrow({ marginAccount, pools, amount }) {
async marginBorrow({ marginAccount, pools, amount, destination }) {
const lamports = poolAmount_1.PoolAmount.tokens(amount);
await marginAccount.refresh();
const preInstructons = [];
const refreshInstructions = [];
const postInstructions = [];
const instructionsInstructions = [];
const depositPosition = await marginAccount.getOrCreatePosition(this.addresses.depositNoteMint);
(0, chai_1.assert)(depositPosition);
const loanNoteAccount = await this.withGetOrCreateLoanPosition(preInstructons, marginAccount);
await this.withMarginRefreshAllPositionPrices({ instructions: refreshInstructions, pools, marginAccount });
const loanNoteAccount = await this.withGetOrCreateLoanPosition(instructionsInstructions, marginAccount);
await this.withMarginBorrow({
instructions: postInstructions,
instructions: instructionsInstructions,
marginAccount,

@@ -376,4 +390,13 @@ depositPosition,

});
if (destination !== undefined) {
await this.withWithdraw({
instructions: instructionsInstructions,
marginAccount,
source: depositPosition.address,
destination,
amount: lamports
});
}
try {
return await (0, utils_1.sendAll)(marginAccount.provider, [preInstructons, (0, utils_1.chunks)(11, refreshInstructions), postInstructions]);
return await (0, utils_1.sendAll)(marginAccount.provider, [(0, utils_1.chunks)(11, refreshInstructions), instructionsInstructions]);
}

@@ -432,6 +455,6 @@ catch (err) {

/// `amount` - The amount to be repaid
async marginRepay({ marginAccount, pools, amount }) {
async marginRepay({ marginAccount, pools, source, amount }) {
await marginAccount.refresh();
const deposit_position = await marginAccount.getOrCreatePosition(this.addresses.depositNoteMint);
(0, chai_1.assert)(deposit_position);
const depositPosition = await marginAccount.getOrCreatePosition(this.addresses.depositNoteMint);
(0, chai_1.assert)(depositPosition);
const refreshInstructions = [];

@@ -441,7 +464,16 @@ const instructions = [];

const loanNoteAccount = await this.withGetOrCreateLoanPosition(instructions, marginAccount);
await this.makeMarginRepayInstruction({
if (source !== undefined) {
await this.withDeposit({
instructions,
marginAccount,
source,
destination: depositPosition.address,
amount
});
}
await this.withMarginRepay({
instructions,
marginAccount: marginAccount,
deposit_account: deposit_position.address,
loan_account: loanNoteAccount,
depositPosition: depositPosition.address,
loanPosition: loanNoteAccount,
amount

@@ -463,3 +495,3 @@ });

}
async makeMarginRepayInstruction({ instructions, marginAccount, deposit_account, loan_account, amount }) {
async withMarginRepay({ instructions, marginAccount, depositPosition, loanPosition, amount }) {
await marginAccount.withAdapterInvoke({

@@ -470,3 +502,3 @@ instructions,

adapterInstruction: await this.programs.marginPool.methods
.marginRepay(amount.toRpcArg())
.marginRepay(poolAmount_1.PoolAmount.tokens(amount).toRpcArg())
.accounts({

@@ -477,4 +509,4 @@ marginAccount: marginAccount.address,

depositNoteMint: this.addresses.depositNoteMint,
loanAccount: loan_account,
depositAccount: deposit_account,
loanAccount: loanPosition,
depositAccount: depositPosition,
tokenProgram: spl_token_1.TOKEN_PROGRAM_ID

@@ -492,4 +524,4 @@ })

/// `destination` - (Optional) The token account to send the withdrawn deposit
async withdraw({ marginAccount, pools, amount, destination }) {
// FIXME: can be getPosition
async withdraw({ marginAccount, pools, amount, destination = token_1.TokenFormat.unwrappedSol }) {
// FIXME: can source be calculated in withdraw?
const { address: source } = await marginAccount.getOrCreatePosition(this.addresses.depositNoteMint);

@@ -499,4 +531,2 @@ const preInstructions = [];

const instructions = [];
const postInstructions = [];
let marginWithdrawDestination = destination !== null && destination !== void 0 ? destination : (await token_1.AssociatedToken.withCreateOrUnwrapIfNativeMint(preInstructions, postInstructions, marginAccount.provider, this.tokenMint));
await this.withMarginRefreshAllPositionPrices({ instructions: refreshInstructions, pools, marginAccount });

@@ -508,29 +538,41 @@ await marginAccount.withUpdateAllPositionBalances({ instructions: refreshInstructions });

source,
destination: marginWithdrawDestination,
destination,
amount
});
return await (0, utils_1.sendAll)(marginAccount.provider, [
preInstructions,
(0, utils_1.chunks)(11, refreshInstructions),
[...instructions, ...postInstructions]
]);
return await (0, utils_1.sendAll)(marginAccount.provider, [preInstructions, (0, utils_1.chunks)(11, refreshInstructions), instructions]);
}
async withWithdraw({ instructions, marginAccount, source, destination, amount }) {
await marginAccount.withAdapterInvoke({
async withWithdraw({ instructions, marginAccount, source, destination = token_1.TokenFormat.unwrappedSol, amount }) {
const provider = marginAccount.provider;
const mint = this.tokenMint;
destination = await token_1.AssociatedToken.withBeginTransferToDestination({
instructions,
adapterProgram: this.programs.config.marginPoolProgramId,
adapterMetadata: this.addresses.marginPoolAdapterMetadata,
adapterInstruction: await this.programs.marginPool.methods
.withdraw(amount.toRpcArg())
.accounts({
depositor: marginAccount.address,
marginPool: this.address,
vault: this.addresses.vault,
depositNoteMint: this.addresses.depositNoteMint,
source,
destination,
tokenProgram: spl_token_1.TOKEN_PROGRAM_ID
})
.instruction()
provider,
mint,
destination
});
if (destination) {
await marginAccount.withAdapterInvoke({
instructions,
adapterProgram: this.programs.config.marginPoolProgramId,
adapterMetadata: this.addresses.marginPoolAdapterMetadata,
adapterInstruction: await this.programs.marginPool.methods
.withdraw(amount.toRpcArg())
.accounts({
depositor: marginAccount.address,
marginPool: this.address,
vault: this.addresses.vault,
depositNoteMint: this.addresses.depositNoteMint,
source,
destination,
tokenProgram: spl_token_1.TOKEN_PROGRAM_ID
})
.instruction()
});
}
token_1.AssociatedToken.withEndTransfer({
instructions,
provider,
mint,
destination
});
}

@@ -537,0 +579,0 @@ async withRegisterLoan(instructions, marginAccount) {

@@ -1,2 +0,1 @@

/// <reference types="bn.js" />
import { BN } from "@project-serum/anchor";

@@ -3,0 +2,0 @@ declare type PoolAmountKindTokens = {

@@ -24,5 +24,5 @@ /// <reference types="node" />

getExposure(value: BN): BN;
getCollateralValue(value: BN): BN;
getRequiredCollateralValue(value: BN): BN;
getCollateralValue(value: BN): any;
getRequiredCollateralValue(value: BN): any;
}
//# sourceMappingURL=positionTokenMetadata.d.ts.map
/// <reference types="node" />
/// <reference types="bn.js" />
import { BN } from "@project-serum/anchor";

@@ -4,0 +3,0 @@ import { Market as SerumMarket, OpenOrders } from "@project-serum/serum";

@@ -1,2 +0,1 @@

/// <reference types="bn.js" />
import { BN, Idl } from "@project-serum/anchor";

@@ -3,0 +2,0 @@ import { IdlTypeDef } from "@project-serum/anchor/dist/cjs/idl";

@@ -1,2 +0,1 @@

/// <reference types="bn.js" />
import { BN } from "@project-serum/anchor";

@@ -3,0 +2,0 @@ import { Account, Connection, PublicKey, Signer, TransactionInstruction } from "@solana/web3.js";

/// <reference types="node" />
/// <reference types="bn.js" />
import { BN, Address, AnchorProvider } from "@project-serum/anchor";

@@ -7,2 +6,9 @@ import { Mint, Account } from "@solana/spl-token";

import { TokenAmount } from "./tokenAmount";
export declare type TokenAddress = Address | TokenFormat;
export declare enum TokenFormat {
/** The users associated token account will be used, and sol will be unwrapped. */
unwrappedSol = 0,
/** The users associated token account will be used, and sol will be wrapped. */
wrappedSol = 1
}
export declare class AssociatedToken {

@@ -40,2 +46,3 @@ address: PublicKey;

static exists(connection: Connection, mint: Address, owner: Address): Promise<boolean>;
static existsAux(connection: Connection, mint: Address, owner: Address, address: Address): Promise<boolean>;
static loadAux(connection: Connection, address: Address, decimals: number): Promise<AssociatedToken>;

@@ -128,3 +135,3 @@ static zero(mint: Address, owner: Address, decimals: number): AssociatedToken;

/**
* If the native wrapped token account does not exist, add instruction to create the token account. If ATA exists, do nothing.
* If the token account does not exist, add instructions to create and initialize the token account. If the account exists do nothing.
* @static

@@ -134,6 +141,7 @@ * @param {TransactionInstruction[]} instructions

* @param {Address} owner
* @param {Address} mint
* @returns {Promise<PublicKey>} returns the public key of the token account
* @memberof AssociatedToken
*/
static withCreateNative(instructions: TransactionInstruction[], provider: AnchorProvider, owner: Address): Promise<PublicKey>;
static withCreateAux(instructions: TransactionInstruction[], provider: AnchorProvider, owner: Address, mint: Address, address: Address): Promise<void>;
/**

@@ -170,3 +178,3 @@ * Add close associated token account IX

*/
static withWrapIfNativeMint(instructions: TransactionInstruction[], provider: AnchorProvider, mint: Address, tokenAccountOrNative: Address, amount: BN): Promise<PublicKey>;
static withWrapIfNativeMint(instructions: TransactionInstruction[], provider: AnchorProvider, mint: Address, amount: BN): Promise<PublicKey>;
/**

@@ -180,5 +188,5 @@ * Unwraps all SOL if the mint is native and the tokenAccount is the owner

*/
static withUnwrapIfNative(instructions: TransactionInstruction[], owner: Address, mint: Address, tokenAccountOrNative: Address): void;
static withUnwrapIfNative(instructions: TransactionInstruction[], owner: Address, mint: Address): void;
/**
* Create the associated token account. Funds it if natve.
* Create the associated token account. Funds it if native.
*

@@ -189,6 +197,6 @@ * @static

* @param {Address} mint
* @param {BN} initialAmount
* @param {BN} wrapAmount
* @memberof AssociatedToken
*/
static withCreateOrWrapIfNativeMint(instructions: TransactionInstruction[], provider: AnchorProvider, mint: Address, initialAmount: BN): Promise<PublicKey>;
static withCreateOrWrapIfNativeMint(instructions: TransactionInstruction[], provider: AnchorProvider, mint: Address, wrapAmount: BN): Promise<PublicKey>;
/**

@@ -206,2 +214,22 @@ * Create the associated token account as a pre-instruction.

static withCreateOrUnwrapIfNativeMint(preInstructions: TransactionInstruction[], postInstructions: TransactionInstruction[], provider: AnchorProvider, mint: Address): Promise<PublicKey>;
static withBeginTransferFromSource({ instructions, provider, mint, amount, source }: {
instructions: TransactionInstruction[];
provider: AnchorProvider;
mint: Address;
amount: BN;
source: Address | TokenFormat;
}): Promise<PublicKey>;
static withBeginTransferToDestination({ instructions, provider, mint, destination }: {
instructions: TransactionInstruction[];
provider: AnchorProvider;
mint: Address;
destination: Address | TokenFormat;
}): Promise<PublicKey>;
/** Ends the transfer by unwraps the token if it is the native mint. */
static withEndTransfer({ instructions, provider, mint, destination }: {
instructions: TransactionInstruction[];
provider: AnchorProvider;
mint: Address;
destination: Address | TokenFormat;
}): void;
}

@@ -208,0 +236,0 @@ /**

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.numberToBigInt = exports.bigIntToNumber = exports.bigIntToBn = exports.bnToNumber = exports.numberToBn = exports.AssociatedToken = void 0;
exports.numberToBigInt = exports.bigIntToNumber = exports.bigIntToBn = exports.bnToNumber = exports.numberToBn = exports.AssociatedToken = exports.TokenFormat = void 0;
const anchor_1 = require("@project-serum/anchor");

@@ -11,2 +11,9 @@ const token_instructions_1 = require("@project-serum/serum/lib/token-instructions");

const tokenAmount_1 = require("./tokenAmount");
var TokenFormat;
(function (TokenFormat) {
/** The users associated token account will be used, and sol will be unwrapped. */
TokenFormat[TokenFormat["unwrappedSol"] = 0] = "unwrappedSol";
/** The users associated token account will be used, and sol will be wrapped. */
TokenFormat[TokenFormat["wrappedSol"] = 1] = "wrappedSol";
})(TokenFormat = exports.TokenFormat || (exports.TokenFormat = {}));
class AssociatedToken {

@@ -56,3 +63,3 @@ /**

if (token.info && !token.info.owner.equals(ownerAddress)) {
throw new Error("Unexpected owner of the associated token");
throw new spl_token_1.TokenInvalidOwnerError("The owner of a token account doesn't match the expected owner");
}

@@ -65,5 +72,25 @@ return token;

const address = this.derive(mintAddress, ownerAddress);
const account = await connection.getAccountInfo(address);
return !!account;
return await AssociatedToken.existsAux(connection, mint, owner, address);
}
static async existsAux(connection, mint, owner, address) {
const mintAddress = (0, anchor_1.translateAddress)(mint);
const ownerAddress = (0, anchor_1.translateAddress)(owner);
const tokenAddress = (0, anchor_1.translateAddress)(address);
const info = await connection.getAccountInfo(tokenAddress);
if (info) {
const fakeDecimals = 0;
const account = this.decodeAccount(info, address, fakeDecimals);
if (!account.info) {
throw new spl_token_1.TokenInvalidAccountSizeError();
}
if (!account.info.owner.equals(ownerAddress)) {
throw new spl_token_1.TokenInvalidOwnerError("The owner of a token account doesn't match the expected owner");
}
if (!account.info.mint.equals(mintAddress)) {
throw new spl_token_1.TokenInvalidMintError("The mint of a token account doesn't match the expected mint");
}
return true;
}
return false;
}
static async loadAux(connection, address, decimals) {

@@ -337,3 +364,3 @@ const pubkey = (0, anchor_1.translateAddress)(address);

/**
* If the native wrapped token account does not exist, add instruction to create the token account. If ATA exists, do nothing.
* If the token account does not exist, add instructions to create and initialize the token account. If the account exists do nothing.
* @static

@@ -343,13 +370,22 @@ * @param {TransactionInstruction[]} instructions

* @param {Address} owner
* @param {Address} mint
* @returns {Promise<PublicKey>} returns the public key of the token account
* @memberof AssociatedToken
*/
static async withCreateNative(instructions, provider, owner) {
static async withCreateAux(instructions, provider, owner, mint, address) {
const ownerAddress = (0, anchor_1.translateAddress)(owner);
const tokenAddress = this.derive(spl_token_1.NATIVE_MINT, ownerAddress);
if (!(await AssociatedToken.exists(provider.connection, spl_token_1.NATIVE_MINT, ownerAddress))) {
const ix = (0, spl_token_1.createAssociatedTokenAccountInstruction)(provider.wallet.publicKey, tokenAddress, ownerAddress, spl_token_1.NATIVE_MINT);
instructions.push(ix);
const mintAddress = (0, anchor_1.translateAddress)(mint);
const tokenAddress = (0, anchor_1.translateAddress)(address);
if (!(await AssociatedToken.existsAux(provider.connection, mintAddress, ownerAddress, address))) {
let rent = await (0, spl_token_1.getMinimumBalanceForRentExemptAccount)(provider.connection);
let createIx = web3_js_1.SystemProgram.createAccount({
fromPubkey: provider.wallet.publicKey,
newAccountPubkey: tokenAddress,
lamports: rent,
space: spl_token_1.ACCOUNT_SIZE,
programId: token_instructions_1.TOKEN_PROGRAM_ID
});
let initIx = (0, spl_token_1.createInitializeAccountInstruction)(tokenAddress, mintAddress, ownerAddress);
instructions.push(createIx, initIx);
}
return tokenAddress;
}

@@ -410,11 +446,9 @@ /**

*/
static async withWrapIfNativeMint(instructions, provider, mint, tokenAccountOrNative, amount) {
const owner = provider.wallet.publicKey;
static async withWrapIfNativeMint(instructions, provider, mint, amount) {
const mintPubkey = (0, anchor_1.translateAddress)(mint);
const tokenAccountOrNativePubkey = (0, anchor_1.translateAddress)(tokenAccountOrNative);
//only run if mint is wrapped sol mint, and the token account is actually the native wallet
if (this.isNative(owner, mintPubkey, tokenAccountOrNativePubkey)) {
//only run if mint is wrapped sol mint
if (mintPubkey.equals(spl_token_1.NATIVE_MINT)) {
return this.withWrapNative(instructions, provider, amount);
}
return tokenAccountOrNativePubkey;
return AssociatedToken.derive(mint, provider.wallet.publicKey);
}

@@ -429,7 +463,6 @@ /**

*/
static withUnwrapIfNative(instructions, owner, mint, tokenAccountOrNative) {
static withUnwrapIfNative(instructions, owner, mint) {
const ownerPubkey = (0, anchor_1.translateAddress)(owner);
const mintPubkey = (0, anchor_1.translateAddress)(mint);
const tokenAccountOrNativePubkey = (0, anchor_1.translateAddress)(tokenAccountOrNative);
if (this.isNative(ownerPubkey, mintPubkey, tokenAccountOrNativePubkey)) {
if (mintPubkey.equals(spl_token_1.NATIVE_MINT)) {
//add close account IX

@@ -440,3 +473,3 @@ this.withUnwrapNative(instructions, owner);

/**
* Create the associated token account. Funds it if natve.
* Create the associated token account. Funds it if native.
*

@@ -447,6 +480,6 @@ * @static

* @param {Address} mint
* @param {BN} initialAmount
* @param {BN} wrapAmount
* @memberof AssociatedToken
*/
static async withCreateOrWrapIfNativeMint(instructions, provider, mint, initialAmount) {
static async withCreateOrWrapIfNativeMint(instructions, provider, mint, wrapAmount) {
const owner = provider.wallet.publicKey;

@@ -456,3 +489,3 @@ const mintPubkey = (0, anchor_1.translateAddress)(mint);

// Only run if mint is wrapped sol mint. Create the wrapped sol account and return its pubkey
return await this.withWrapNative(instructions, provider, initialAmount);
return await this.withWrapNative(instructions, provider, wrapAmount);
}

@@ -485,2 +518,55 @@ else {

}
static async withBeginTransferFromSource({ instructions, provider, mint, amount, source = TokenFormat.unwrappedSol }) {
let sourceAddress;
if (source instanceof web3_js_1.PublicKey || typeof source === "string") {
sourceAddress = (0, anchor_1.translateAddress)(source);
}
let owner = provider.wallet.publicKey;
let isSourceOwner = sourceAddress && sourceAddress.equals(owner);
let isSourceAssociatedAddress = sourceAddress && AssociatedToken.derive(mint, owner).equals(sourceAddress);
if (source === TokenFormat.unwrappedSol || isSourceOwner || isSourceAssociatedAddress) {
return await AssociatedToken.withCreateOrWrapIfNativeMint(instructions, provider, mint, amount);
}
else if (source === TokenFormat.wrappedSol) {
return await AssociatedToken.withCreate(instructions, provider, owner, mint);
}
else if (sourceAddress) {
await AssociatedToken.withCreateAux(instructions, provider, owner, mint, sourceAddress);
return sourceAddress;
}
throw new Error("Unexpected argument 'source' or there are multiple versions of @solana/web3.js PublicKey installed");
}
static async withBeginTransferToDestination({ instructions, provider, mint, destination = TokenFormat.unwrappedSol }) {
let destinationAddress;
if (destination instanceof web3_js_1.PublicKey || typeof destination === "string") {
destinationAddress = (0, anchor_1.translateAddress)(destination);
}
let owner = provider.wallet.publicKey;
let isDestinationOwner = destinationAddress && destinationAddress.equals(owner);
let isDestinationAssociatedAddress = destinationAddress && AssociatedToken.derive(mint, owner).equals(destinationAddress);
if (destination === TokenFormat.wrappedSol ||
destination === TokenFormat.unwrappedSol ||
isDestinationOwner ||
isDestinationAssociatedAddress) {
return await AssociatedToken.withCreate(instructions, provider, owner, mint);
}
else if (destinationAddress) {
await AssociatedToken.withCreateAux(instructions, provider, owner, mint, destinationAddress);
return destinationAddress;
}
throw new Error("Unexpected argument 'destination' or there are multiple versions of @solana/web3.js PublicKey installed");
}
/** Ends the transfer by unwraps the token if it is the native mint. */
static withEndTransfer({ instructions, provider, mint, destination = TokenFormat.unwrappedSol }) {
let destinationAddress;
if (destination instanceof web3_js_1.PublicKey || typeof destination === "string") {
destinationAddress = (0, anchor_1.translateAddress)(destination);
}
let owner = provider.wallet.publicKey;
let isDestinationOwner = destinationAddress && destinationAddress.equals(owner);
if ((0, anchor_1.translateAddress)(mint).equals(spl_token_1.NATIVE_MINT) &&
(destination === TokenFormat.unwrappedSol || isDestinationOwner)) {
AssociatedToken.withUnwrapNative(instructions, owner);
}
}
}

@@ -487,0 +573,0 @@ exports.AssociatedToken = AssociatedToken;

@@ -1,2 +0,1 @@

/// <reference types="bn.js" />
import { BN } from "@project-serum/anchor";

@@ -3,0 +2,0 @@ import { Account, Mint } from "@solana/spl-token";

@@ -1,2 +0,1 @@

/// <reference types="bn.js" />
import { PublicKey } from "@solana/web3.js";

@@ -3,0 +2,0 @@ import { Address, BN, AnchorProvider } from "@project-serum/anchor";

@@ -1,11 +0,10 @@

/// <reference types="bn.js" />
import { BN } from "@project-serum/anchor";
export declare class Number128 {
static readonly PRECISION = 10;
static readonly ONE: BN;
static readonly ZERO: BN;
static readonly MAX: BN;
static readonly U64_MAX: BN;
static readonly ONE: any;
static readonly ZERO: any;
static readonly MAX: any;
static readonly U64_MAX: any;
static readonly BPS_EXPONENT = -4;
static readonly POWERS_OF_TEN: BN[];
static readonly POWERS_OF_TEN: any[];
private constructor();

@@ -16,7 +15,7 @@ /** Removes the fractional component from the number.*/

static asU64(value: BN, exponent: number): BN;
static from(value: BN): BN;
static fromDecimal(value: BN, exponent: number): BN;
static from(value: BN): any;
static fromDecimal(value: BN, exponent: number): any;
/** Convert from basis points */
static fromBps(basisPoints: BN): BN;
static fromBps(basisPoints: BN): any;
}
//# sourceMappingURL=number128.d.ts.map

@@ -1,9 +0,8 @@

/// <reference types="bn.js" />
import { BN } from "@project-serum/anchor";
export declare class Number192 {
static readonly PRECISION = 15;
static readonly ONE: BN;
static readonly ZERO: BN;
static readonly U64_MAX: BN;
static readonly POWERS_OF_TEN: BN[];
static readonly ONE: any;
static readonly ZERO: any;
static readonly U64_MAX: any;
static readonly POWERS_OF_TEN: any[];
private constructor();

@@ -15,5 +14,5 @@ /** Removes the fractional component from the number. */

static asU64Rounded(value: BN, exponent: number): BN;
static from(value: BN): BN;
static fromDecimal(value: BN, exponent: number): BN;
static from(value: BN): any;
static fromDecimal(value: BN, exponent: number): any;
}
//# sourceMappingURL=number192.d.ts.map

@@ -1,4 +0,2 @@

/// <reference types="bn.js" />
import { BN } from "@project-serum/anchor";
export declare function getTimestamp(): BN;
export declare function getTimestamp(): any;
//# sourceMappingURL=timestamp.d.ts.map

@@ -44,4 +44,4 @@ import { PublicKey } from "@solana/web3.js";

calculateValue(): void;
collateralValue(): BN;
requiredCollateralValue(): BN;
collateralValue(): any;
requiredCollateralValue(): any;
setBalance(balance: BN): void;

@@ -48,0 +48,0 @@ setPrice(price: PriceInfo): void;

@@ -1,2 +0,1 @@

/// <reference types="bn.js" />
import { Address, AnchorProvider, BN } from "@project-serum/anchor";

@@ -3,0 +2,0 @@ import { GetProgramAccountsFilter, PublicKey, TransactionInstruction, TransactionSignature } from "@solana/web3.js";

@@ -1,2 +0,1 @@

/// <reference types="bn.js" />
import { Address, BN } from "@project-serum/anchor";

@@ -6,3 +5,3 @@ import { PriceData } from "@pythnetwork/client";

import { PublicKey, TransactionInstruction } from "@solana/web3.js";
import { AssociatedToken } from "../../token";
import { AssociatedToken, TokenAddress } from "../../token";
import { TokenAmount } from "../../token/tokenAmount";

@@ -90,4 +89,4 @@ import { MarginAccount } from "../marginAccount";

calculatePrices(pythPrice: PriceData | undefined): PriceResult;
depositNoteExchangeRate(): BN;
loanNoteExchangeRate(): BN;
depositNoteExchangeRate(): any;
loanNoteExchangeRate(): any;
/**

@@ -145,15 +144,16 @@ * Linear interpolation between (x0, y0) and (x1, y1)

amount: BN;
source?: Address;
source?: TokenAddress;
}): Promise<string>;
withDeposit({ instructions, depositor, source, destination, amount }: {
withDeposit({ instructions, marginAccount, source, destination, amount }: {
instructions: TransactionInstruction[];
depositor: Address;
source: Address;
marginAccount: MarginAccount;
source?: TokenAddress;
destination: Address;
amount: BN;
}): Promise<void>;
marginBorrow({ marginAccount, pools, amount }: {
marginBorrow({ marginAccount, pools, amount, destination }: {
marginAccount: MarginAccount;
pools: Pool[];
amount: BN;
destination?: TokenAddress;
}): Promise<void>;

@@ -168,13 +168,14 @@ withGetOrCreateLoanPosition(instructions: TransactionInstruction[], marginAccount: MarginAccount): Promise<Address>;

}): Promise<void>;
marginRepay({ marginAccount, pools, amount }: {
marginRepay({ marginAccount, pools, source, amount }: {
marginAccount: MarginAccount;
pools: Pool[];
amount: PoolAmount;
source?: TokenAddress;
amount: BN;
}): Promise<void>;
makeMarginRepayInstruction({ instructions, marginAccount, deposit_account, loan_account, amount }: {
withMarginRepay({ instructions, marginAccount, depositPosition, loanPosition, amount }: {
instructions: TransactionInstruction[];
marginAccount: MarginAccount;
deposit_account: Address;
loan_account: Address;
amount: PoolAmount;
depositPosition: Address;
loanPosition: Address;
amount: BN;
}): Promise<void>;

@@ -185,3 +186,3 @@ withdraw({ marginAccount, pools, amount, destination }: {

amount: PoolAmount;
destination?: Address;
destination?: TokenAddress;
}): Promise<void>;

@@ -191,4 +192,4 @@ withWithdraw({ instructions, marginAccount, source, destination, amount }: {

marginAccount: MarginAccount;
source: Address;
destination: Address;
source: PublicKey;
destination?: TokenAddress;
amount: PoolAmount;

@@ -195,0 +196,0 @@ }): Promise<void>;

@@ -6,3 +6,3 @@ import { BN, translateAddress } from "@project-serum/anchor";

import { assert } from "chai";
import { AssociatedToken, bigIntToBn } from "../../token";
import { AssociatedToken, bigIntToBn, TokenFormat } from "../../token";
import { TokenAmount } from "../../token/tokenAmount";

@@ -318,3 +318,3 @@ import { PoolAmount } from "./poolAmount";

*/
async deposit({ marginAccount, amount, source }) {
async deposit({ marginAccount, amount, source = TokenFormat.unwrappedSol }) {
assert(marginAccount);

@@ -328,6 +328,5 @@ assert(amount);

const instructions = [];
source !== null && source !== void 0 ? source : (source = await AssociatedToken.withCreateOrWrapIfNativeMint(instructions, marginAccount.provider, this.tokenMint, amount));
await this.withDeposit({
instructions: instructions,
depositor: marginAccount.owner,
marginAccount,
source,

@@ -340,3 +339,12 @@ destination: position.address,

}
async withDeposit({ instructions, depositor, source, destination, amount }) {
async withDeposit({ instructions, marginAccount, source = TokenFormat.unwrappedSol, destination, amount }) {
const provider = marginAccount.provider;
const mint = this.tokenMint;
source = await AssociatedToken.withBeginTransferFromSource({
instructions,
provider,
mint,
amount,
source
});
const ix = await this.programs.marginPool.methods

@@ -348,3 +356,3 @@ .deposit(amount)

depositNoteMint: this.addresses.depositNoteMint,
depositor,
depositor: marginAccount.owner,
source,

@@ -356,14 +364,20 @@ destination,

instructions.push(ix);
AssociatedToken.withEndTransfer({
instructions,
provider,
mint,
destination
});
}
async marginBorrow({ marginAccount, pools, amount }) {
async marginBorrow({ marginAccount, pools, amount, destination }) {
const lamports = PoolAmount.tokens(amount);
await marginAccount.refresh();
const preInstructons = [];
const refreshInstructions = [];
const postInstructions = [];
const instructionsInstructions = [];
const depositPosition = await marginAccount.getOrCreatePosition(this.addresses.depositNoteMint);
assert(depositPosition);
const loanNoteAccount = await this.withGetOrCreateLoanPosition(preInstructons, marginAccount);
await this.withMarginRefreshAllPositionPrices({ instructions: refreshInstructions, pools, marginAccount });
const loanNoteAccount = await this.withGetOrCreateLoanPosition(instructionsInstructions, marginAccount);
await this.withMarginBorrow({
instructions: postInstructions,
instructions: instructionsInstructions,
marginAccount,

@@ -374,4 +388,13 @@ depositPosition,

});
if (destination !== undefined) {
await this.withWithdraw({
instructions: instructionsInstructions,
marginAccount,
source: depositPosition.address,
destination,
amount: lamports
});
}
try {
return await sendAll(marginAccount.provider, [preInstructons, chunks(11, refreshInstructions), postInstructions]);
return await sendAll(marginAccount.provider, [chunks(11, refreshInstructions), instructionsInstructions]);
}

@@ -430,6 +453,6 @@ catch (err) {

/// `amount` - The amount to be repaid
async marginRepay({ marginAccount, pools, amount }) {
async marginRepay({ marginAccount, pools, source, amount }) {
await marginAccount.refresh();
const deposit_position = await marginAccount.getOrCreatePosition(this.addresses.depositNoteMint);
assert(deposit_position);
const depositPosition = await marginAccount.getOrCreatePosition(this.addresses.depositNoteMint);
assert(depositPosition);
const refreshInstructions = [];

@@ -439,7 +462,16 @@ const instructions = [];

const loanNoteAccount = await this.withGetOrCreateLoanPosition(instructions, marginAccount);
await this.makeMarginRepayInstruction({
if (source !== undefined) {
await this.withDeposit({
instructions,
marginAccount,
source,
destination: depositPosition.address,
amount
});
}
await this.withMarginRepay({
instructions,
marginAccount: marginAccount,
deposit_account: deposit_position.address,
loan_account: loanNoteAccount,
depositPosition: depositPosition.address,
loanPosition: loanNoteAccount,
amount

@@ -461,3 +493,3 @@ });

}
async makeMarginRepayInstruction({ instructions, marginAccount, deposit_account, loan_account, amount }) {
async withMarginRepay({ instructions, marginAccount, depositPosition, loanPosition, amount }) {
await marginAccount.withAdapterInvoke({

@@ -468,3 +500,3 @@ instructions,

adapterInstruction: await this.programs.marginPool.methods
.marginRepay(amount.toRpcArg())
.marginRepay(PoolAmount.tokens(amount).toRpcArg())
.accounts({

@@ -475,4 +507,4 @@ marginAccount: marginAccount.address,

depositNoteMint: this.addresses.depositNoteMint,
loanAccount: loan_account,
depositAccount: deposit_account,
loanAccount: loanPosition,
depositAccount: depositPosition,
tokenProgram: TOKEN_PROGRAM_ID

@@ -490,4 +522,4 @@ })

/// `destination` - (Optional) The token account to send the withdrawn deposit
async withdraw({ marginAccount, pools, amount, destination }) {
// FIXME: can be getPosition
async withdraw({ marginAccount, pools, amount, destination = TokenFormat.unwrappedSol }) {
// FIXME: can source be calculated in withdraw?
const { address: source } = await marginAccount.getOrCreatePosition(this.addresses.depositNoteMint);

@@ -497,4 +529,2 @@ const preInstructions = [];

const instructions = [];
const postInstructions = [];
let marginWithdrawDestination = destination !== null && destination !== void 0 ? destination : (await AssociatedToken.withCreateOrUnwrapIfNativeMint(preInstructions, postInstructions, marginAccount.provider, this.tokenMint));
await this.withMarginRefreshAllPositionPrices({ instructions: refreshInstructions, pools, marginAccount });

@@ -506,29 +536,41 @@ await marginAccount.withUpdateAllPositionBalances({ instructions: refreshInstructions });

source,
destination: marginWithdrawDestination,
destination,
amount
});
return await sendAll(marginAccount.provider, [
preInstructions,
chunks(11, refreshInstructions),
[...instructions, ...postInstructions]
]);
return await sendAll(marginAccount.provider, [preInstructions, chunks(11, refreshInstructions), instructions]);
}
async withWithdraw({ instructions, marginAccount, source, destination, amount }) {
await marginAccount.withAdapterInvoke({
async withWithdraw({ instructions, marginAccount, source, destination = TokenFormat.unwrappedSol, amount }) {
const provider = marginAccount.provider;
const mint = this.tokenMint;
destination = await AssociatedToken.withBeginTransferToDestination({
instructions,
adapterProgram: this.programs.config.marginPoolProgramId,
adapterMetadata: this.addresses.marginPoolAdapterMetadata,
adapterInstruction: await this.programs.marginPool.methods
.withdraw(amount.toRpcArg())
.accounts({
depositor: marginAccount.address,
marginPool: this.address,
vault: this.addresses.vault,
depositNoteMint: this.addresses.depositNoteMint,
source,
destination,
tokenProgram: TOKEN_PROGRAM_ID
})
.instruction()
provider,
mint,
destination
});
if (destination) {
await marginAccount.withAdapterInvoke({
instructions,
adapterProgram: this.programs.config.marginPoolProgramId,
adapterMetadata: this.addresses.marginPoolAdapterMetadata,
adapterInstruction: await this.programs.marginPool.methods
.withdraw(amount.toRpcArg())
.accounts({
depositor: marginAccount.address,
marginPool: this.address,
vault: this.addresses.vault,
depositNoteMint: this.addresses.depositNoteMint,
source,
destination,
tokenProgram: TOKEN_PROGRAM_ID
})
.instruction()
});
}
AssociatedToken.withEndTransfer({
instructions,
provider,
mint,
destination
});
}

@@ -535,0 +577,0 @@ async withRegisterLoan(instructions, marginAccount) {

@@ -1,2 +0,1 @@

/// <reference types="bn.js" />
import { BN } from "@project-serum/anchor";

@@ -3,0 +2,0 @@ declare type PoolAmountKindTokens = {

@@ -24,5 +24,5 @@ /// <reference types="node" />

getExposure(value: BN): BN;
getCollateralValue(value: BN): BN;
getRequiredCollateralValue(value: BN): BN;
getCollateralValue(value: BN): any;
getRequiredCollateralValue(value: BN): any;
}
//# sourceMappingURL=positionTokenMetadata.d.ts.map
/// <reference types="node" />
/// <reference types="bn.js" />
import { BN } from "@project-serum/anchor";

@@ -4,0 +3,0 @@ import { Market as SerumMarket, OpenOrders } from "@project-serum/serum";

@@ -1,2 +0,1 @@

/// <reference types="bn.js" />
import { BN, Idl } from "@project-serum/anchor";

@@ -3,0 +2,0 @@ import { IdlTypeDef } from "@project-serum/anchor/dist/cjs/idl";

@@ -1,2 +0,1 @@

/// <reference types="bn.js" />
import { BN } from "@project-serum/anchor";

@@ -3,0 +2,0 @@ import { Account, Connection, PublicKey, Signer, TransactionInstruction } from "@solana/web3.js";

/// <reference types="node" />
/// <reference types="bn.js" />
import { BN, Address, AnchorProvider } from "@project-serum/anchor";

@@ -7,2 +6,9 @@ import { Mint, Account } from "@solana/spl-token";

import { TokenAmount } from "./tokenAmount";
export declare type TokenAddress = Address | TokenFormat;
export declare enum TokenFormat {
/** The users associated token account will be used, and sol will be unwrapped. */
unwrappedSol = 0,
/** The users associated token account will be used, and sol will be wrapped. */
wrappedSol = 1
}
export declare class AssociatedToken {

@@ -40,2 +46,3 @@ address: PublicKey;

static exists(connection: Connection, mint: Address, owner: Address): Promise<boolean>;
static existsAux(connection: Connection, mint: Address, owner: Address, address: Address): Promise<boolean>;
static loadAux(connection: Connection, address: Address, decimals: number): Promise<AssociatedToken>;

@@ -128,3 +135,3 @@ static zero(mint: Address, owner: Address, decimals: number): AssociatedToken;

/**
* If the native wrapped token account does not exist, add instruction to create the token account. If ATA exists, do nothing.
* If the token account does not exist, add instructions to create and initialize the token account. If the account exists do nothing.
* @static

@@ -134,6 +141,7 @@ * @param {TransactionInstruction[]} instructions

* @param {Address} owner
* @param {Address} mint
* @returns {Promise<PublicKey>} returns the public key of the token account
* @memberof AssociatedToken
*/
static withCreateNative(instructions: TransactionInstruction[], provider: AnchorProvider, owner: Address): Promise<PublicKey>;
static withCreateAux(instructions: TransactionInstruction[], provider: AnchorProvider, owner: Address, mint: Address, address: Address): Promise<void>;
/**

@@ -170,3 +178,3 @@ * Add close associated token account IX

*/
static withWrapIfNativeMint(instructions: TransactionInstruction[], provider: AnchorProvider, mint: Address, tokenAccountOrNative: Address, amount: BN): Promise<PublicKey>;
static withWrapIfNativeMint(instructions: TransactionInstruction[], provider: AnchorProvider, mint: Address, amount: BN): Promise<PublicKey>;
/**

@@ -180,5 +188,5 @@ * Unwraps all SOL if the mint is native and the tokenAccount is the owner

*/
static withUnwrapIfNative(instructions: TransactionInstruction[], owner: Address, mint: Address, tokenAccountOrNative: Address): void;
static withUnwrapIfNative(instructions: TransactionInstruction[], owner: Address, mint: Address): void;
/**
* Create the associated token account. Funds it if natve.
* Create the associated token account. Funds it if native.
*

@@ -189,6 +197,6 @@ * @static

* @param {Address} mint
* @param {BN} initialAmount
* @param {BN} wrapAmount
* @memberof AssociatedToken
*/
static withCreateOrWrapIfNativeMint(instructions: TransactionInstruction[], provider: AnchorProvider, mint: Address, initialAmount: BN): Promise<PublicKey>;
static withCreateOrWrapIfNativeMint(instructions: TransactionInstruction[], provider: AnchorProvider, mint: Address, wrapAmount: BN): Promise<PublicKey>;
/**

@@ -206,2 +214,22 @@ * Create the associated token account as a pre-instruction.

static withCreateOrUnwrapIfNativeMint(preInstructions: TransactionInstruction[], postInstructions: TransactionInstruction[], provider: AnchorProvider, mint: Address): Promise<PublicKey>;
static withBeginTransferFromSource({ instructions, provider, mint, amount, source }: {
instructions: TransactionInstruction[];
provider: AnchorProvider;
mint: Address;
amount: BN;
source: Address | TokenFormat;
}): Promise<PublicKey>;
static withBeginTransferToDestination({ instructions, provider, mint, destination }: {
instructions: TransactionInstruction[];
provider: AnchorProvider;
mint: Address;
destination: Address | TokenFormat;
}): Promise<PublicKey>;
/** Ends the transfer by unwraps the token if it is the native mint. */
static withEndTransfer({ instructions, provider, mint, destination }: {
instructions: TransactionInstruction[];
provider: AnchorProvider;
mint: Address;
destination: Address | TokenFormat;
}): void;
}

@@ -208,0 +236,0 @@ /**

import { BN, translateAddress } from "@project-serum/anchor";
import { TOKEN_PROGRAM_ID } from "@project-serum/serum/lib/token-instructions";
import { ASSOCIATED_TOKEN_PROGRAM_ID, NATIVE_MINT, createAssociatedTokenAccountInstruction, createCloseAccountInstruction, createSyncNativeInstruction, TokenAccountNotFoundError, TokenInvalidAccountOwnerError, TokenInvalidAccountSizeError, ACCOUNT_SIZE, AccountLayout, AccountState, MINT_SIZE, MintLayout } from "@solana/spl-token";
import { ASSOCIATED_TOKEN_PROGRAM_ID, NATIVE_MINT, createAssociatedTokenAccountInstruction, createCloseAccountInstruction, createSyncNativeInstruction, TokenAccountNotFoundError, TokenInvalidAccountOwnerError, TokenInvalidAccountSizeError, ACCOUNT_SIZE, AccountLayout, AccountState, MINT_SIZE, MintLayout, TokenInvalidOwnerError, createInitializeAccountInstruction, getMinimumBalanceForRentExemptAccount, TokenInvalidMintError } from "@solana/spl-token";
import { PublicKey, SystemProgram } from "@solana/web3.js";

@@ -8,2 +8,9 @@ import { Number192 } from "../utils/number192";

import { TokenAmount } from "./tokenAmount";
export var TokenFormat;
(function (TokenFormat) {
/** The users associated token account will be used, and sol will be unwrapped. */
TokenFormat[TokenFormat["unwrappedSol"] = 0] = "unwrappedSol";
/** The users associated token account will be used, and sol will be wrapped. */
TokenFormat[TokenFormat["wrappedSol"] = 1] = "wrappedSol";
})(TokenFormat || (TokenFormat = {}));
export class AssociatedToken {

@@ -53,3 +60,3 @@ /**

if (token.info && !token.info.owner.equals(ownerAddress)) {
throw new Error("Unexpected owner of the associated token");
throw new TokenInvalidOwnerError("The owner of a token account doesn't match the expected owner");
}

@@ -62,5 +69,25 @@ return token;

const address = this.derive(mintAddress, ownerAddress);
const account = await connection.getAccountInfo(address);
return !!account;
return await AssociatedToken.existsAux(connection, mint, owner, address);
}
static async existsAux(connection, mint, owner, address) {
const mintAddress = translateAddress(mint);
const ownerAddress = translateAddress(owner);
const tokenAddress = translateAddress(address);
const info = await connection.getAccountInfo(tokenAddress);
if (info) {
const fakeDecimals = 0;
const account = this.decodeAccount(info, address, fakeDecimals);
if (!account.info) {
throw new TokenInvalidAccountSizeError();
}
if (!account.info.owner.equals(ownerAddress)) {
throw new TokenInvalidOwnerError("The owner of a token account doesn't match the expected owner");
}
if (!account.info.mint.equals(mintAddress)) {
throw new TokenInvalidMintError("The mint of a token account doesn't match the expected mint");
}
return true;
}
return false;
}
static async loadAux(connection, address, decimals) {

@@ -334,3 +361,3 @@ const pubkey = translateAddress(address);

/**
* If the native wrapped token account does not exist, add instruction to create the token account. If ATA exists, do nothing.
* If the token account does not exist, add instructions to create and initialize the token account. If the account exists do nothing.
* @static

@@ -340,13 +367,22 @@ * @param {TransactionInstruction[]} instructions

* @param {Address} owner
* @param {Address} mint
* @returns {Promise<PublicKey>} returns the public key of the token account
* @memberof AssociatedToken
*/
static async withCreateNative(instructions, provider, owner) {
static async withCreateAux(instructions, provider, owner, mint, address) {
const ownerAddress = translateAddress(owner);
const tokenAddress = this.derive(NATIVE_MINT, ownerAddress);
if (!(await AssociatedToken.exists(provider.connection, NATIVE_MINT, ownerAddress))) {
const ix = createAssociatedTokenAccountInstruction(provider.wallet.publicKey, tokenAddress, ownerAddress, NATIVE_MINT);
instructions.push(ix);
const mintAddress = translateAddress(mint);
const tokenAddress = translateAddress(address);
if (!(await AssociatedToken.existsAux(provider.connection, mintAddress, ownerAddress, address))) {
let rent = await getMinimumBalanceForRentExemptAccount(provider.connection);
let createIx = SystemProgram.createAccount({
fromPubkey: provider.wallet.publicKey,
newAccountPubkey: tokenAddress,
lamports: rent,
space: ACCOUNT_SIZE,
programId: TOKEN_PROGRAM_ID
});
let initIx = createInitializeAccountInstruction(tokenAddress, mintAddress, ownerAddress);
instructions.push(createIx, initIx);
}
return tokenAddress;
}

@@ -407,11 +443,9 @@ /**

*/
static async withWrapIfNativeMint(instructions, provider, mint, tokenAccountOrNative, amount) {
const owner = provider.wallet.publicKey;
static async withWrapIfNativeMint(instructions, provider, mint, amount) {
const mintPubkey = translateAddress(mint);
const tokenAccountOrNativePubkey = translateAddress(tokenAccountOrNative);
//only run if mint is wrapped sol mint, and the token account is actually the native wallet
if (this.isNative(owner, mintPubkey, tokenAccountOrNativePubkey)) {
//only run if mint is wrapped sol mint
if (mintPubkey.equals(NATIVE_MINT)) {
return this.withWrapNative(instructions, provider, amount);
}
return tokenAccountOrNativePubkey;
return AssociatedToken.derive(mint, provider.wallet.publicKey);
}

@@ -426,7 +460,6 @@ /**

*/
static withUnwrapIfNative(instructions, owner, mint, tokenAccountOrNative) {
static withUnwrapIfNative(instructions, owner, mint) {
const ownerPubkey = translateAddress(owner);
const mintPubkey = translateAddress(mint);
const tokenAccountOrNativePubkey = translateAddress(tokenAccountOrNative);
if (this.isNative(ownerPubkey, mintPubkey, tokenAccountOrNativePubkey)) {
if (mintPubkey.equals(NATIVE_MINT)) {
//add close account IX

@@ -437,3 +470,3 @@ this.withUnwrapNative(instructions, owner);

/**
* Create the associated token account. Funds it if natve.
* Create the associated token account. Funds it if native.
*

@@ -444,6 +477,6 @@ * @static

* @param {Address} mint
* @param {BN} initialAmount
* @param {BN} wrapAmount
* @memberof AssociatedToken
*/
static async withCreateOrWrapIfNativeMint(instructions, provider, mint, initialAmount) {
static async withCreateOrWrapIfNativeMint(instructions, provider, mint, wrapAmount) {
const owner = provider.wallet.publicKey;

@@ -453,3 +486,3 @@ const mintPubkey = translateAddress(mint);

// Only run if mint is wrapped sol mint. Create the wrapped sol account and return its pubkey
return await this.withWrapNative(instructions, provider, initialAmount);
return await this.withWrapNative(instructions, provider, wrapAmount);
}

@@ -482,2 +515,55 @@ else {

}
static async withBeginTransferFromSource({ instructions, provider, mint, amount, source = TokenFormat.unwrappedSol }) {
let sourceAddress;
if (source instanceof PublicKey || typeof source === "string") {
sourceAddress = translateAddress(source);
}
let owner = provider.wallet.publicKey;
let isSourceOwner = sourceAddress && sourceAddress.equals(owner);
let isSourceAssociatedAddress = sourceAddress && AssociatedToken.derive(mint, owner).equals(sourceAddress);
if (source === TokenFormat.unwrappedSol || isSourceOwner || isSourceAssociatedAddress) {
return await AssociatedToken.withCreateOrWrapIfNativeMint(instructions, provider, mint, amount);
}
else if (source === TokenFormat.wrappedSol) {
return await AssociatedToken.withCreate(instructions, provider, owner, mint);
}
else if (sourceAddress) {
await AssociatedToken.withCreateAux(instructions, provider, owner, mint, sourceAddress);
return sourceAddress;
}
throw new Error("Unexpected argument 'source' or there are multiple versions of @solana/web3.js PublicKey installed");
}
static async withBeginTransferToDestination({ instructions, provider, mint, destination = TokenFormat.unwrappedSol }) {
let destinationAddress;
if (destination instanceof PublicKey || typeof destination === "string") {
destinationAddress = translateAddress(destination);
}
let owner = provider.wallet.publicKey;
let isDestinationOwner = destinationAddress && destinationAddress.equals(owner);
let isDestinationAssociatedAddress = destinationAddress && AssociatedToken.derive(mint, owner).equals(destinationAddress);
if (destination === TokenFormat.wrappedSol ||
destination === TokenFormat.unwrappedSol ||
isDestinationOwner ||
isDestinationAssociatedAddress) {
return await AssociatedToken.withCreate(instructions, provider, owner, mint);
}
else if (destinationAddress) {
await AssociatedToken.withCreateAux(instructions, provider, owner, mint, destinationAddress);
return destinationAddress;
}
throw new Error("Unexpected argument 'destination' or there are multiple versions of @solana/web3.js PublicKey installed");
}
/** Ends the transfer by unwraps the token if it is the native mint. */
static withEndTransfer({ instructions, provider, mint, destination = TokenFormat.unwrappedSol }) {
let destinationAddress;
if (destination instanceof PublicKey || typeof destination === "string") {
destinationAddress = translateAddress(destination);
}
let owner = provider.wallet.publicKey;
let isDestinationOwner = destinationAddress && destinationAddress.equals(owner);
if (translateAddress(mint).equals(NATIVE_MINT) &&
(destination === TokenFormat.unwrappedSol || isDestinationOwner)) {
AssociatedToken.withUnwrapNative(instructions, owner);
}
}
}

@@ -484,0 +570,0 @@ AssociatedToken.NATIVE_DECIMALS = 9;

@@ -1,2 +0,1 @@

/// <reference types="bn.js" />
import { BN } from "@project-serum/anchor";

@@ -3,0 +2,0 @@ import { Account, Mint } from "@solana/spl-token";

@@ -1,2 +0,1 @@

/// <reference types="bn.js" />
import { PublicKey } from "@solana/web3.js";

@@ -3,0 +2,0 @@ import { Address, BN, AnchorProvider } from "@project-serum/anchor";

@@ -1,11 +0,10 @@

/// <reference types="bn.js" />
import { BN } from "@project-serum/anchor";
export declare class Number128 {
static readonly PRECISION = 10;
static readonly ONE: BN;
static readonly ZERO: BN;
static readonly MAX: BN;
static readonly U64_MAX: BN;
static readonly ONE: any;
static readonly ZERO: any;
static readonly MAX: any;
static readonly U64_MAX: any;
static readonly BPS_EXPONENT = -4;
static readonly POWERS_OF_TEN: BN[];
static readonly POWERS_OF_TEN: any[];
private constructor();

@@ -16,7 +15,7 @@ /** Removes the fractional component from the number.*/

static asU64(value: BN, exponent: number): BN;
static from(value: BN): BN;
static fromDecimal(value: BN, exponent: number): BN;
static from(value: BN): any;
static fromDecimal(value: BN, exponent: number): any;
/** Convert from basis points */
static fromBps(basisPoints: BN): BN;
static fromBps(basisPoints: BN): any;
}
//# sourceMappingURL=number128.d.ts.map

@@ -1,9 +0,8 @@

/// <reference types="bn.js" />
import { BN } from "@project-serum/anchor";
export declare class Number192 {
static readonly PRECISION = 15;
static readonly ONE: BN;
static readonly ZERO: BN;
static readonly U64_MAX: BN;
static readonly POWERS_OF_TEN: BN[];
static readonly ONE: any;
static readonly ZERO: any;
static readonly U64_MAX: any;
static readonly POWERS_OF_TEN: any[];
private constructor();

@@ -15,5 +14,5 @@ /** Removes the fractional component from the number. */

static asU64Rounded(value: BN, exponent: number): BN;
static from(value: BN): BN;
static fromDecimal(value: BN, exponent: number): BN;
static from(value: BN): any;
static fromDecimal(value: BN, exponent: number): any;
}
//# sourceMappingURL=number192.d.ts.map

@@ -1,4 +0,2 @@

/// <reference types="bn.js" />
import { BN } from "@project-serum/anchor";
export declare function getTimestamp(): BN;
export declare function getTimestamp(): any;
//# sourceMappingURL=timestamp.d.ts.map
{
"name": "@jet-lab/margin",
"version": "0.1.34",
"version": "0.1.35",
"description": "Library for interacting with the Jet margin on-chain programs",

@@ -48,3 +48,4 @@ "keywords": [

"typescript": "^4.5.4"
}
},
"type": "module"
}

@@ -6,3 +6,3 @@ import { Address, BN, translateAddress } from "@project-serum/anchor"

import { assert } from "chai"
import { AssociatedToken, bigIntToBn } from "../../token"
import { AssociatedToken, bigIntToBn, TokenAddress, TokenFormat } from "../../token"
import { TokenAmount } from "../../token/tokenAmount"

@@ -444,3 +444,11 @@ import { MarginAccount } from "../marginAccount"

*/
async deposit({ marginAccount, amount, source }: { marginAccount: MarginAccount; amount: BN; source?: Address }) {
async deposit({
marginAccount,
amount,
source = TokenFormat.unwrappedSol
}: {
marginAccount: MarginAccount
amount: BN
source?: TokenAddress
}) {
assert(marginAccount)

@@ -456,12 +464,6 @@ assert(amount)

const instructions: TransactionInstruction[] = []
source ??= await AssociatedToken.withCreateOrWrapIfNativeMint(
instructions,
marginAccount.provider,
this.tokenMint,
amount
)
await this.withDeposit({
instructions: instructions,
depositor: marginAccount.owner,
marginAccount,
source,

@@ -477,4 +479,4 @@ destination: position.address,

instructions,
depositor,
source,
marginAccount,
source = TokenFormat.unwrappedSol,
destination,

@@ -484,7 +486,18 @@ amount

instructions: TransactionInstruction[]
depositor: Address
source: Address
marginAccount: MarginAccount
source?: TokenAddress
destination: Address
amount: BN
}): Promise<void> {
const provider = marginAccount.provider
const mint = this.tokenMint
source = await AssociatedToken.withBeginTransferFromSource({
instructions,
provider,
mint,
amount,
source
})
const ix = await this.programs.marginPool.methods

@@ -496,3 +509,3 @@ .deposit(amount)

depositNoteMint: this.addresses.depositNoteMint,
depositor,
depositor: marginAccount.owner,
source,

@@ -504,9 +517,26 @@ destination,

instructions.push(ix)
AssociatedToken.withEndTransfer({
instructions,
provider,
mint,
destination
})
}
async marginBorrow({ marginAccount, pools, amount }: { marginAccount: MarginAccount; pools: Pool[]; amount: BN }) {
async marginBorrow({
marginAccount,
pools,
amount,
destination
}: {
marginAccount: MarginAccount
pools: Pool[]
amount: BN
destination?: TokenAddress
}) {
const lamports = PoolAmount.tokens(amount)
await marginAccount.refresh()
const preInstructons: TransactionInstruction[] = []
const refreshInstructions: TransactionInstruction[] = []
const postInstructions: TransactionInstruction[] = []
const instructionsInstructions: TransactionInstruction[] = []

@@ -516,8 +546,8 @@ const depositPosition = await marginAccount.getOrCreatePosition(this.addresses.depositNoteMint)

const loanNoteAccount = await this.withGetOrCreateLoanPosition(preInstructons, marginAccount)
await this.withMarginRefreshAllPositionPrices({ instructions: refreshInstructions, pools, marginAccount })
const loanNoteAccount = await this.withGetOrCreateLoanPosition(instructionsInstructions, marginAccount)
await this.withMarginBorrow({
instructions: postInstructions,
instructions: instructionsInstructions,
marginAccount,

@@ -528,4 +558,15 @@ depositPosition,

})
if (destination !== undefined) {
await this.withWithdraw({
instructions: instructionsInstructions,
marginAccount,
source: depositPosition.address,
destination,
amount: lamports
})
}
try {
return await sendAll(marginAccount.provider, [preInstructons, chunks(11, refreshInstructions), postInstructions])
return await sendAll(marginAccount.provider, [chunks(11, refreshInstructions), instructionsInstructions])
} catch (err) {

@@ -604,2 +645,3 @@ console.log(err)

pools,
source,
amount

@@ -609,7 +651,8 @@ }: {

pools: Pool[]
amount: PoolAmount
source?: TokenAddress
amount: BN
}) {
await marginAccount.refresh()
const deposit_position = await marginAccount.getOrCreatePosition(this.addresses.depositNoteMint)
assert(deposit_position)
const depositPosition = await marginAccount.getOrCreatePosition(this.addresses.depositNoteMint)
assert(depositPosition)

@@ -622,7 +665,18 @@ const refreshInstructions: TransactionInstruction[] = []

const loanNoteAccount = await this.withGetOrCreateLoanPosition(instructions, marginAccount)
await this.makeMarginRepayInstruction({
if (source !== undefined) {
await this.withDeposit({
instructions,
marginAccount,
source,
destination: depositPosition.address,
amount
})
}
await this.withMarginRepay({
instructions,
marginAccount: marginAccount,
deposit_account: deposit_position.address,
loan_account: loanNoteAccount,
depositPosition: depositPosition.address,
loanPosition: loanNoteAccount,
amount

@@ -646,7 +700,7 @@ })

async makeMarginRepayInstruction({
async withMarginRepay({
instructions,
marginAccount,
deposit_account,
loan_account,
depositPosition,
loanPosition,
amount

@@ -656,5 +710,5 @@ }: {

marginAccount: MarginAccount
deposit_account: Address
loan_account: Address
amount: PoolAmount
depositPosition: Address
loanPosition: Address
amount: BN
}): Promise<void> {

@@ -666,3 +720,3 @@ await marginAccount.withAdapterInvoke({

adapterInstruction: await this.programs.marginPool.methods
.marginRepay(amount.toRpcArg())
.marginRepay(PoolAmount.tokens(amount).toRpcArg())
.accounts({

@@ -673,4 +727,4 @@ marginAccount: marginAccount.address,

depositNoteMint: this.addresses.depositNoteMint,
loanAccount: loan_account,
depositAccount: deposit_account,
loanAccount: loanPosition,
depositAccount: depositPosition,
tokenProgram: TOKEN_PROGRAM_ID

@@ -693,3 +747,3 @@ })

amount,
destination
destination = TokenFormat.unwrappedSol
}: {

@@ -699,5 +753,5 @@ marginAccount: MarginAccount

amount: PoolAmount
destination?: Address
destination?: TokenAddress
}) {
// FIXME: can be getPosition
// FIXME: can source be calculated in withdraw?
const { address: source } = await marginAccount.getOrCreatePosition(this.addresses.depositNoteMint)

@@ -708,13 +762,3 @@

const instructions: TransactionInstruction[] = []
const postInstructions: TransactionInstruction[] = []
let marginWithdrawDestination =
destination ??
(await AssociatedToken.withCreateOrUnwrapIfNativeMint(
preInstructions,
postInstructions,
marginAccount.provider,
this.tokenMint
))
await this.withMarginRefreshAllPositionPrices({ instructions: refreshInstructions, pools, marginAccount })

@@ -726,11 +770,7 @@ await marginAccount.withUpdateAllPositionBalances({ instructions: refreshInstructions })

source,
destination: marginWithdrawDestination,
destination,
amount
})
return await sendAll(marginAccount.provider, [
preInstructions,
chunks(11, refreshInstructions),
[...instructions, ...postInstructions]
])
return await sendAll(marginAccount.provider, [preInstructions, chunks(11, refreshInstructions), instructions])
}

@@ -742,3 +782,3 @@

source,
destination,
destination = TokenFormat.unwrappedSol,
amount

@@ -748,23 +788,42 @@ }: {

marginAccount: MarginAccount
source: Address
destination: Address
source: PublicKey
destination?: TokenAddress
amount: PoolAmount
}): Promise<void> {
await marginAccount.withAdapterInvoke({
const provider = marginAccount.provider
const mint = this.tokenMint
destination = await AssociatedToken.withBeginTransferToDestination({
instructions,
adapterProgram: this.programs.config.marginPoolProgramId,
adapterMetadata: this.addresses.marginPoolAdapterMetadata,
adapterInstruction: await this.programs.marginPool.methods
.withdraw(amount.toRpcArg())
.accounts({
depositor: marginAccount.address,
marginPool: this.address,
vault: this.addresses.vault,
depositNoteMint: this.addresses.depositNoteMint,
source,
destination,
tokenProgram: TOKEN_PROGRAM_ID
})
.instruction()
provider,
mint,
destination
})
if (destination) {
await marginAccount.withAdapterInvoke({
instructions,
adapterProgram: this.programs.config.marginPoolProgramId,
adapterMetadata: this.addresses.marginPoolAdapterMetadata,
adapterInstruction: await this.programs.marginPool.methods
.withdraw(amount.toRpcArg())
.accounts({
depositor: marginAccount.address,
marginPool: this.address,
vault: this.addresses.vault,
depositNoteMint: this.addresses.depositNoteMint,
source,
destination,
tokenProgram: TOKEN_PROGRAM_ID
})
.instruction()
})
}
AssociatedToken.withEndTransfer({
instructions,
provider,
mint,
destination
})
}

@@ -771,0 +830,0 @@

@@ -18,3 +18,7 @@ import { BN, Address, translateAddress, AnchorProvider, Provider } from "@project-serum/anchor"

MINT_SIZE,
MintLayout
MintLayout,
TokenInvalidOwnerError,
createInitializeAccountInstruction,
getMinimumBalanceForRentExemptAccount,
TokenInvalidMintError
} from "@solana/spl-token"

@@ -26,2 +30,11 @@ import { Connection, PublicKey, TransactionInstruction, SystemProgram, AccountInfo } from "@solana/web3.js"

export type TokenAddress = Address | TokenFormat
export enum TokenFormat {
/** The users associated token account will be used, and sol will be unwrapped. */
unwrappedSol,
/** The users associated token account will be used, and sol will be wrapped. */
wrappedSol
}
export class AssociatedToken {

@@ -70,3 +83,3 @@ static readonly NATIVE_DECIMALS = 9

if (token.info && !token.info.owner.equals(ownerAddress)) {
throw new Error("Unexpected owner of the associated token")
throw new TokenInvalidOwnerError("The owner of a token account doesn't match the expected owner")
}

@@ -80,6 +93,28 @@ return token

const address = this.derive(mintAddress, ownerAddress)
const account = await connection.getAccountInfo(address)
return !!account
return await AssociatedToken.existsAux(connection, mint, owner, address)
}
static async existsAux(connection: Connection, mint: Address, owner: Address, address: Address) {
const mintAddress = translateAddress(mint)
const ownerAddress = translateAddress(owner)
const tokenAddress = translateAddress(address)
const info = await connection.getAccountInfo(tokenAddress)
if (info) {
const fakeDecimals = 0
const account = this.decodeAccount(info, address, fakeDecimals)
if (!account.info) {
throw new TokenInvalidAccountSizeError()
}
if (!account.info.owner.equals(ownerAddress)) {
throw new TokenInvalidOwnerError("The owner of a token account doesn't match the expected owner")
}
if (!account.info.mint.equals(mintAddress)) {
throw new TokenInvalidMintError("The mint of a token account doesn't match the expected mint")
}
return true
}
return false
}
static async loadAux(connection: Connection, address: Address, decimals: number) {

@@ -421,3 +456,3 @@ const pubkey = translateAddress(address)

/**
* If the native wrapped token account does not exist, add instruction to create the token account. If ATA exists, do nothing.
* If the token account does not exist, add instructions to create and initialize the token account. If the account exists do nothing.
* @static

@@ -427,23 +462,29 @@ * @param {TransactionInstruction[]} instructions

* @param {Address} owner
* @param {Address} mint
* @returns {Promise<PublicKey>} returns the public key of the token account
* @memberof AssociatedToken
*/
static async withCreateNative(
static async withCreateAux(
instructions: TransactionInstruction[],
provider: AnchorProvider,
owner: Address
): Promise<PublicKey> {
owner: Address,
mint: Address,
address: Address
): Promise<void> {
const ownerAddress = translateAddress(owner)
const tokenAddress = this.derive(NATIVE_MINT, ownerAddress)
const mintAddress = translateAddress(mint)
const tokenAddress = translateAddress(address)
if (!(await AssociatedToken.exists(provider.connection, NATIVE_MINT, ownerAddress))) {
const ix = createAssociatedTokenAccountInstruction(
provider.wallet.publicKey,
tokenAddress,
ownerAddress,
NATIVE_MINT
)
instructions.push(ix)
if (!(await AssociatedToken.existsAux(provider.connection, mintAddress, ownerAddress, address))) {
let rent = await getMinimumBalanceForRentExemptAccount(provider.connection)
let createIx = SystemProgram.createAccount({
fromPubkey: provider.wallet.publicKey,
newAccountPubkey: tokenAddress,
lamports: rent,
space: ACCOUNT_SIZE,
programId: TOKEN_PROGRAM_ID
})
let initIx = createInitializeAccountInstruction(tokenAddress, mintAddress, ownerAddress)
instructions.push(createIx, initIx)
}
return tokenAddress
}

@@ -518,14 +559,11 @@

mint: Address,
tokenAccountOrNative: Address,
amount: BN
): Promise<PublicKey> {
const owner = provider.wallet.publicKey
const mintPubkey = translateAddress(mint)
const tokenAccountOrNativePubkey = translateAddress(tokenAccountOrNative)
//only run if mint is wrapped sol mint, and the token account is actually the native wallet
if (this.isNative(owner, mintPubkey, tokenAccountOrNativePubkey)) {
//only run if mint is wrapped sol mint
if (mintPubkey.equals(NATIVE_MINT)) {
return this.withWrapNative(instructions, provider, amount)
}
return tokenAccountOrNativePubkey
return AssociatedToken.derive(mint, provider.wallet.publicKey)
}

@@ -541,13 +579,7 @@

*/
static withUnwrapIfNative(
instructions: TransactionInstruction[],
owner: Address,
mint: Address,
tokenAccountOrNative: Address
): void {
static withUnwrapIfNative(instructions: TransactionInstruction[], owner: Address, mint: Address): void {
const ownerPubkey = translateAddress(owner)
const mintPubkey = translateAddress(mint)
const tokenAccountOrNativePubkey = translateAddress(tokenAccountOrNative)
if (this.isNative(ownerPubkey, mintPubkey, tokenAccountOrNativePubkey)) {
if (mintPubkey.equals(NATIVE_MINT)) {
//add close account IX

@@ -559,3 +591,3 @@ this.withUnwrapNative(instructions, owner)

/**
* Create the associated token account. Funds it if natve.
* Create the associated token account. Funds it if native.
*

@@ -566,3 +598,3 @@ * @static

* @param {Address} mint
* @param {BN} initialAmount
* @param {BN} wrapAmount
* @memberof AssociatedToken

@@ -574,3 +606,3 @@ */

mint: Address,
initialAmount: BN
wrapAmount: BN
): Promise<PublicKey> {

@@ -582,3 +614,3 @@ const owner = provider.wallet.publicKey

// Only run if mint is wrapped sol mint. Create the wrapped sol account and return its pubkey
return await this.withWrapNative(instructions, provider, initialAmount)
return await this.withWrapNative(instructions, provider, wrapAmount)
} else {

@@ -619,2 +651,99 @@ // Return the associated token

}
static async withBeginTransferFromSource({
instructions,
provider,
mint,
amount,
source = TokenFormat.unwrappedSol
}: {
instructions: TransactionInstruction[]
provider: AnchorProvider
mint: Address
amount: BN
source: Address | TokenFormat
}): Promise<PublicKey> {
let sourceAddress: PublicKey | undefined
if (source instanceof PublicKey || typeof source === "string") {
sourceAddress = translateAddress(source)
}
let owner = provider.wallet.publicKey
let isSourceOwner = sourceAddress && sourceAddress.equals(owner)
let isSourceAssociatedAddress = sourceAddress && AssociatedToken.derive(mint, owner).equals(sourceAddress)
if (source === TokenFormat.unwrappedSol || isSourceOwner || isSourceAssociatedAddress) {
return await AssociatedToken.withCreateOrWrapIfNativeMint(instructions, provider, mint, amount)
} else if (source === TokenFormat.wrappedSol) {
return await AssociatedToken.withCreate(instructions, provider, owner, mint)
} else if (sourceAddress) {
await AssociatedToken.withCreateAux(instructions, provider, owner, mint, sourceAddress)
return sourceAddress
}
throw new Error(
"Unexpected argument 'source' or there are multiple versions of @solana/web3.js PublicKey installed"
)
}
static async withBeginTransferToDestination({
instructions,
provider,
mint,
destination = TokenFormat.unwrappedSol
}: {
instructions: TransactionInstruction[]
provider: AnchorProvider
mint: Address
destination: Address | TokenFormat
}): Promise<PublicKey> {
let destinationAddress: PublicKey | undefined
if (destination instanceof PublicKey || typeof destination === "string") {
destinationAddress = translateAddress(destination)
}
let owner = provider.wallet.publicKey
let isDestinationOwner = destinationAddress && destinationAddress.equals(owner)
let isDestinationAssociatedAddress =
destinationAddress && AssociatedToken.derive(mint, owner).equals(destinationAddress)
if (
destination === TokenFormat.wrappedSol ||
destination === TokenFormat.unwrappedSol ||
isDestinationOwner ||
isDestinationAssociatedAddress
) {
return await AssociatedToken.withCreate(instructions, provider, owner, mint)
} else if (destinationAddress) {
await AssociatedToken.withCreateAux(instructions, provider, owner, mint, destinationAddress)
return destinationAddress
}
throw new Error(
"Unexpected argument 'destination' or there are multiple versions of @solana/web3.js PublicKey installed"
)
}
/** Ends the transfer by unwraps the token if it is the native mint. */
static withEndTransfer({
instructions,
provider,
mint,
destination = TokenFormat.unwrappedSol
}: {
instructions: TransactionInstruction[]
provider: AnchorProvider
mint: Address
destination: Address | TokenFormat
}) {
let destinationAddress: PublicKey | undefined
if (destination instanceof PublicKey || typeof destination === "string") {
destinationAddress = translateAddress(destination)
}
let owner = provider.wallet.publicKey
let isDestinationOwner = destinationAddress && destinationAddress.equals(owner)
if (
translateAddress(mint).equals(NATIVE_MINT) &&
(destination === TokenFormat.unwrappedSol || isDestinationOwner)
) {
AssociatedToken.withUnwrapNative(instructions, owner)
}
}
}

@@ -621,0 +750,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc