@orca-so/common-sdk
Advanced tools
Comparing version 0.2.2 to 0.3.0-beta-0
@@ -1,3 +0,3 @@ | ||
import { u64 } from "@solana/spl-token"; | ||
import { PublicKey } from "@solana/web3.js"; | ||
import BN from "bn.js"; | ||
import { Instruction } from "../web3/transactions/types"; | ||
@@ -7,2 +7,2 @@ export type ResolvedTokenAddressInstruction = { | ||
} & Instruction; | ||
export declare function createWSOLAccountInstructions(walletAddress: PublicKey, amountIn: u64, rentExemptLamports: number): ResolvedTokenAddressInstruction; | ||
export declare function createWrappedNativeAccountInstruction(owner: PublicKey, amountIn: BN, rentExemptLamports: number, payer?: PublicKey, unwrapDestination?: PublicKey): ResolvedTokenAddressInstruction; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.createWSOLAccountInstructions = void 0; | ||
exports.createWrappedNativeAccountInstruction = void 0; | ||
const spl_token_1 = require("@solana/spl-token"); | ||
const web3_js_1 = require("@solana/web3.js"); | ||
// TODO use native-mint instead | ||
function createWSOLAccountInstructions(walletAddress, amountIn, rentExemptLamports) { | ||
function createWrappedNativeAccountInstruction(owner, amountIn, rentExemptLamports, payer, unwrapDestination) { | ||
const payerKey = payer ?? owner; | ||
const tempAccount = new web3_js_1.Keypair(); | ||
const unwrapDestinationKey = unwrapDestination ?? payer ?? owner; | ||
const createAccountInstruction = web3_js_1.SystemProgram.createAccount({ | ||
fromPubkey: walletAddress, | ||
fromPubkey: payerKey, | ||
newAccountPubkey: tempAccount.publicKey, | ||
@@ -16,4 +17,4 @@ lamports: amountIn.toNumber() + rentExemptLamports, | ||
}); | ||
const initAccountInstruction = spl_token_1.Token.createInitAccountInstruction(spl_token_1.TOKEN_PROGRAM_ID, spl_token_1.NATIVE_MINT, tempAccount.publicKey, walletAddress); | ||
const closeWSOLAccountInstruction = spl_token_1.Token.createCloseAccountInstruction(spl_token_1.TOKEN_PROGRAM_ID, tempAccount.publicKey, walletAddress, walletAddress, []); | ||
const initAccountInstruction = (0, spl_token_1.createInitializeAccountInstruction)(tempAccount.publicKey, spl_token_1.NATIVE_MINT, owner); | ||
const closeWSOLAccountInstruction = (0, spl_token_1.createCloseAccountInstruction)(tempAccount.publicKey, unwrapDestinationKey, owner); | ||
return { | ||
@@ -26,2 +27,2 @@ address: tempAccount.publicKey, | ||
} | ||
exports.createWSOLAccountInstructions = createWSOLAccountInstructions; | ||
exports.createWrappedNativeAccountInstruction = createWrappedNativeAccountInstruction; |
@@ -1,8 +0,8 @@ | ||
import { u64 } from "@solana/spl-token"; | ||
import BN from "bn.js"; | ||
import Decimal from "decimal.js"; | ||
export declare class DecimalUtil { | ||
static adjustDecimals(input: Decimal, shift?: number): Decimal; | ||
static fromU64(input: u64, shift?: number): Decimal; | ||
static fromBN(input: BN, shift?: number): Decimal; | ||
static fromNumber(input: number, shift?: number): Decimal; | ||
static toU64(input: Decimal, shift?: number): u64; | ||
static toBN(input: Decimal, shift?: number): BN; | ||
} |
@@ -7,3 +7,3 @@ "use strict"; | ||
exports.DecimalUtil = void 0; | ||
const spl_token_1 = require("@solana/spl-token"); | ||
const bn_js_1 = __importDefault(require("bn.js")); | ||
const decimal_js_1 = __importDefault(require("decimal.js")); | ||
@@ -14,3 +14,3 @@ class DecimalUtil { | ||
} | ||
static fromU64(input, shift = 0) { | ||
static fromBN(input, shift = 0) { | ||
return new decimal_js_1.default(input.toString()).div(new decimal_js_1.default(10).pow(shift)); | ||
@@ -21,11 +21,11 @@ } | ||
} | ||
static toU64(input, shift = 0) { | ||
static toBN(input, shift = 0) { | ||
if (input.isNeg()) { | ||
throw new Error("Negative decimal value ${input} cannot be converted to u64."); | ||
throw new Error("Negative decimal value ${input} cannot be converted to BN."); | ||
} | ||
const shiftedValue = input.mul(new decimal_js_1.default(10).pow(shift)); | ||
const zeroDecimalValue = shiftedValue.trunc(); | ||
return new spl_token_1.u64(zeroDecimalValue.toString()); | ||
return new bn_js_1.default(zeroDecimalValue.toString()); | ||
} | ||
} | ||
exports.DecimalUtil = DecimalUtil; |
@@ -1,2 +0,2 @@ | ||
import { u64 } from "@solana/spl-token"; | ||
import BN from "bn.js"; | ||
import Decimal from "decimal.js"; | ||
@@ -7,7 +7,7 @@ /** | ||
export declare class Percentage { | ||
readonly numerator: u64; | ||
readonly denominator: u64; | ||
constructor(numerator: u64, denominator: u64); | ||
readonly numerator: BN; | ||
readonly denominator: BN; | ||
constructor(numerator: BN, denominator: BN); | ||
static fromDecimal(number: Decimal): Percentage; | ||
static fromFraction(numerator: u64 | number, denominator: u64 | number): Percentage; | ||
static fromFraction(numerator: BN | number, denominator: BN | number): Percentage; | ||
toString: () => string; | ||
@@ -14,0 +14,0 @@ toDecimal(): Decimal; |
@@ -7,3 +7,3 @@ "use strict"; | ||
exports.Percentage = void 0; | ||
const spl_token_1 = require("@solana/spl-token"); | ||
const bn_js_1 = __importDefault(require("bn.js")); | ||
const decimal_js_1 = __importDefault(require("decimal.js")); | ||
@@ -25,8 +25,8 @@ /** | ||
static fromFraction(numerator, denominator) { | ||
const num = typeof numerator === "number" ? new spl_token_1.u64(numerator.toString()) : numerator; | ||
const denom = typeof denominator === "number" ? new spl_token_1.u64(denominator.toString()) : denominator; | ||
const num = typeof numerator === "number" ? new bn_js_1.default(numerator.toString()) : numerator; | ||
const denom = typeof denominator === "number" ? new bn_js_1.default(denominator.toString()) : denominator; | ||
return new Percentage(num, denom); | ||
} | ||
toDecimal() { | ||
if (this.denominator.eq(new spl_token_1.u64(0))) { | ||
if (this.denominator.eq(new bn_js_1.default(0))) { | ||
return new decimal_js_1.default(0); | ||
@@ -44,5 +44,5 @@ } | ||
const newNumerator = p1NumeratorAdjusted.add(p2NumeratorAdjusted); | ||
return new Percentage(new spl_token_1.u64(newNumerator.toString()), new spl_token_1.u64(denomLcm.toString())); | ||
return new Percentage(new bn_js_1.default(newNumerator.toString()), new bn_js_1.default(denomLcm.toString())); | ||
} | ||
} | ||
exports.Percentage = Percentage; |
@@ -1,4 +0,4 @@ | ||
import { u64 } from "@solana/spl-token"; | ||
import { Connection, PublicKey } from "@solana/web3.js"; | ||
import { ResolvedTokenAddressInstruction } from "../helpers/token-instructions"; | ||
import BN from "bn.js"; | ||
import { ResolvedTokenAddressInstruction } from "./token-util"; | ||
/** | ||
@@ -17,6 +17,6 @@ * IMPORTANT: wrappedSolAmountIn should only be used for input/source token that | ||
*/ | ||
export declare function resolveOrCreateATA(connection: Connection, ownerAddress: PublicKey, tokenMint: PublicKey, getAccountRentExempt: () => Promise<number>, wrappedSolAmountIn?: u64, payer?: PublicKey, modeIdempotent?: boolean): Promise<ResolvedTokenAddressInstruction>; | ||
export declare function resolveOrCreateATA(connection: Connection, ownerAddress: PublicKey, tokenMint: PublicKey, getAccountRentExempt: () => Promise<number>, wrappedSolAmountIn?: BN, payer?: PublicKey, modeIdempotent?: boolean): Promise<ResolvedTokenAddressInstruction>; | ||
type ResolvedTokenAddressRequest = { | ||
tokenMint: PublicKey; | ||
wrappedSolAmountIn?: u64; | ||
wrappedSolAmountIn?: BN; | ||
}; | ||
@@ -37,3 +37,2 @@ /** | ||
export declare function resolveOrCreateATAs(connection: Connection, ownerAddress: PublicKey, requests: ResolvedTokenAddressRequest[], getAccountRentExempt: () => Promise<number>, payer?: PublicKey, modeIdempotent?: boolean): Promise<ResolvedTokenAddressInstruction[]>; | ||
export declare function deriveATA(ownerAddress: PublicKey, tokenMint: PublicKey): Promise<PublicKey>; | ||
export {}; |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.deriveATA = exports.resolveOrCreateATAs = exports.resolveOrCreateATA = void 0; | ||
exports.resolveOrCreateATAs = exports.resolveOrCreateATA = void 0; | ||
const spl_token_1 = require("@solana/spl-token"); | ||
const web3_js_1 = require("@solana/web3.js"); | ||
const token_instructions_1 = require("../helpers/token-instructions"); | ||
const math_1 = require("../math"); | ||
const network_1 = require("./network"); | ||
const token_util_1 = require("./token-util"); | ||
const types_1 = require("./transactions/types"); | ||
const network_1 = require("./network"); | ||
/** | ||
@@ -31,7 +22,5 @@ * IMPORTANT: wrappedSolAmountIn should only be used for input/source token that | ||
*/ | ||
function resolveOrCreateATA(connection, ownerAddress, tokenMint, getAccountRentExempt, wrappedSolAmountIn = new spl_token_1.u64(0), payer = ownerAddress, modeIdempotent = false) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const instructions = yield resolveOrCreateATAs(connection, ownerAddress, [{ tokenMint, wrappedSolAmountIn }], getAccountRentExempt, payer, modeIdempotent); | ||
return instructions[0]; | ||
}); | ||
async function resolveOrCreateATA(connection, ownerAddress, tokenMint, getAccountRentExempt, wrappedSolAmountIn = math_1.ZERO, payer = ownerAddress, modeIdempotent = false) { | ||
const instructions = await resolveOrCreateATAs(connection, ownerAddress, [{ tokenMint, wrappedSolAmountIn }], getAccountRentExempt, payer, modeIdempotent); | ||
return instructions[0]; | ||
} | ||
@@ -52,74 +41,45 @@ exports.resolveOrCreateATA = resolveOrCreateATA; | ||
*/ | ||
function resolveOrCreateATAs(connection, ownerAddress, requests, getAccountRentExempt, payer = ownerAddress, modeIdempotent = false) { | ||
var _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const nonNativeMints = requests.filter(({ tokenMint }) => !tokenMint.equals(spl_token_1.NATIVE_MINT)); | ||
const nativeMints = requests.filter(({ tokenMint }) => tokenMint.equals(spl_token_1.NATIVE_MINT)); | ||
if (nativeMints.length > 1) { | ||
throw new Error("Cannot resolve multiple WSolAccounts"); | ||
} | ||
let instructionMap = {}; | ||
if (nonNativeMints.length > 0) { | ||
const nonNativeAddresses = yield Promise.all(nonNativeMints.map(({ tokenMint }) => deriveATA(ownerAddress, tokenMint))); | ||
const tokenAccounts = yield (0, network_1.getMultipleParsedAccounts)(connection, nonNativeAddresses, network_1.ParsableTokenAccountInfo); | ||
tokenAccounts.forEach((tokenAccount, index) => { | ||
const ataAddress = nonNativeAddresses[index]; | ||
let resolvedInstruction; | ||
if (tokenAccount) { | ||
// ATA whose owner has been changed is abnormal entity. | ||
// To prevent to send swap/withdraw/collect output to the ATA, an error should be thrown. | ||
if (!tokenAccount.owner.equals(ownerAddress)) { | ||
throw new Error(`ATA with change of ownership detected: ${ataAddress.toBase58()}`); | ||
} | ||
resolvedInstruction = Object.assign({ address: ataAddress }, types_1.EMPTY_INSTRUCTION); | ||
async function resolveOrCreateATAs(connection, ownerAddress, requests, getAccountRentExempt, payer = ownerAddress, modeIdempotent = false) { | ||
const nonNativeMints = requests.filter(({ tokenMint }) => !tokenMint.equals(spl_token_1.NATIVE_MINT)); | ||
const nativeMints = requests.filter(({ tokenMint }) => tokenMint.equals(spl_token_1.NATIVE_MINT)); | ||
if (nativeMints.length > 1) { | ||
throw new Error("Cannot resolve multiple WSolAccounts"); | ||
} | ||
let instructionMap = {}; | ||
if (nonNativeMints.length > 0) { | ||
const nonNativeAddresses = nonNativeMints.map(({ tokenMint }) => (0, spl_token_1.getAssociatedTokenAddressSync)(tokenMint, ownerAddress)); | ||
const tokenAccounts = await (0, network_1.getMultipleParsedAccounts)(connection, nonNativeAddresses, network_1.ParsableTokenAccountInfo); | ||
tokenAccounts.forEach((tokenAccount, index) => { | ||
const ataAddress = nonNativeAddresses[index]; | ||
let resolvedInstruction; | ||
if (tokenAccount) { | ||
// ATA whose owner has been changed is abnormal entity. | ||
// To prevent to send swap/withdraw/collect output to the ATA, an error should be thrown. | ||
if (!tokenAccount.owner.equals(ownerAddress)) { | ||
throw new Error(`ATA with change of ownership detected: ${ataAddress.toBase58()}`); | ||
} | ||
else { | ||
const createAtaInstruction = createAssociatedTokenAccountInstruction(spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID, spl_token_1.TOKEN_PROGRAM_ID, nonNativeMints[index].tokenMint, ataAddress, ownerAddress, payer, modeIdempotent); | ||
resolvedInstruction = { | ||
address: ataAddress, | ||
instructions: [createAtaInstruction], | ||
cleanupInstructions: [], | ||
signers: [], | ||
}; | ||
} | ||
instructionMap[nonNativeMints[index].tokenMint.toBase58()] = resolvedInstruction; | ||
}); | ||
} | ||
if (nativeMints.length > 0) { | ||
const accountRentExempt = yield getAccountRentExempt(); | ||
const wrappedSolAmountIn = ((_a = nativeMints[0]) === null || _a === void 0 ? void 0 : _a.wrappedSolAmountIn) || new spl_token_1.u64(0); | ||
instructionMap[spl_token_1.NATIVE_MINT.toBase58()] = (0, token_instructions_1.createWSOLAccountInstructions)(ownerAddress, wrappedSolAmountIn, accountRentExempt); | ||
} | ||
// Preserve order of resolution | ||
return requests.map(({ tokenMint }) => instructionMap[tokenMint.toBase58()]); | ||
}); | ||
resolvedInstruction = { address: ataAddress, ...types_1.EMPTY_INSTRUCTION }; | ||
} | ||
else { | ||
const createAtaInstruction = modeIdempotent | ||
? (0, spl_token_1.createAssociatedTokenAccountIdempotentInstruction)(payer, ataAddress, ownerAddress, nonNativeMints[index].tokenMint) | ||
: (0, spl_token_1.createAssociatedTokenAccountInstruction)(payer, ataAddress, ownerAddress, nonNativeMints[index].tokenMint); | ||
resolvedInstruction = { | ||
address: ataAddress, | ||
instructions: [createAtaInstruction], | ||
cleanupInstructions: [], | ||
signers: [], | ||
}; | ||
} | ||
instructionMap[nonNativeMints[index].tokenMint.toBase58()] = resolvedInstruction; | ||
}); | ||
} | ||
if (nativeMints.length > 0) { | ||
const accountRentExempt = await getAccountRentExempt(); | ||
const wrappedSolAmountIn = nativeMints[0]?.wrappedSolAmountIn || math_1.ZERO; | ||
instructionMap[spl_token_1.NATIVE_MINT.toBase58()] = token_util_1.TokenUtil.createWrappedNativeAccountInstruction(ownerAddress, wrappedSolAmountIn, accountRentExempt); | ||
} | ||
// Preserve order of resolution | ||
return requests.map(({ tokenMint }) => instructionMap[tokenMint.toBase58()]); | ||
} | ||
exports.resolveOrCreateATAs = resolveOrCreateATAs; | ||
function deriveATA(ownerAddress, tokenMint) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
return yield spl_token_1.Token.getAssociatedTokenAddress(spl_token_1.ASSOCIATED_TOKEN_PROGRAM_ID, spl_token_1.TOKEN_PROGRAM_ID, tokenMint, ownerAddress); | ||
}); | ||
} | ||
exports.deriveATA = deriveATA; | ||
function createAssociatedTokenAccountInstruction(associatedTokenProgramId, tokenProgramId, mint, associatedAccount, owner, payer, modeIdempotent) { | ||
if (!modeIdempotent) { | ||
return spl_token_1.Token.createAssociatedTokenAccountInstruction(associatedTokenProgramId, tokenProgramId, mint, associatedAccount, owner, payer); | ||
} | ||
// create CreateIdempotent instruction | ||
// spl-token v0.1.8 doesn't have a method for CreateIdempotent. | ||
// https://github.com/solana-labs/solana-program-library/blob/master/associated-token-account/program/src/instruction.rs#L26 | ||
const keys = [ | ||
{ pubkey: payer, isSigner: true, isWritable: true }, | ||
{ pubkey: associatedAccount, isSigner: false, isWritable: true }, | ||
{ pubkey: owner, isSigner: false, isWritable: false }, | ||
{ pubkey: mint, isSigner: false, isWritable: false }, | ||
{ pubkey: web3_js_1.SystemProgram.programId, isSigner: false, isWritable: false }, | ||
{ pubkey: tokenProgramId, isSigner: false, isWritable: false }, | ||
]; | ||
const instructionData = Buffer.from([1]); | ||
return new web3_js_1.TransactionInstruction({ | ||
keys, | ||
programId: associatedTokenProgramId, | ||
data: instructionData, | ||
}); | ||
} |
/// <reference types="node" /> | ||
import { Address } from "@project-serum/anchor"; | ||
import { Connection, AccountInfo } from "@solana/web3.js"; | ||
import { AccountInfo, Connection, PublicKey } from "@solana/web3.js"; | ||
import { ParsableEntity } from "./parsing"; | ||
export declare function getParsedAccount<T>(connection: Connection, address: Address, parser: ParsableEntity<T>): Promise<T | null>; | ||
export declare function getMultipleParsedAccounts<T>(connection: Connection, addresses: Address[], parser: ParsableEntity<T>): Promise<(T | null)[]>; | ||
type GetMultipleAccountsInfoResponse = (AccountInfo<Buffer> | null)[]; | ||
export declare function getMultipleAccounts(connection: Connection, addresses: Address[]): Promise<GetMultipleAccountsInfoResponse>; | ||
export {}; | ||
export type FetchedAccountEntry = [PublicKey, AccountInfo<Buffer> | null]; | ||
export type FetchedAccountMap = Map<string, AccountInfo<Buffer> | null>; | ||
export declare function getMultipleAccountsInMap(connection: Connection, addresses: Address[], timeoutAfterSeconds?: number): Promise<Readonly<FetchedAccountMap>>; | ||
export declare function getMultipleAccounts(connection: Connection, addresses: Address[], timeoutAfterSeconds?: number): Promise<Readonly<FetchedAccountEntry[]>>; |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -15,43 +6,67 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getMultipleAccounts = exports.getMultipleParsedAccounts = exports.getParsedAccount = void 0; | ||
exports.getMultipleAccounts = exports.getMultipleAccountsInMap = exports.getMultipleParsedAccounts = exports.getParsedAccount = void 0; | ||
const tiny_invariant_1 = __importDefault(require("tiny-invariant")); | ||
const address_util_1 = require("../address-util"); | ||
function getParsedAccount(connection, address, parser) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const value = yield connection.getAccountInfo(address_util_1.AddressUtil.toPubKey(address)); | ||
return parser.parse(value === null || value === void 0 ? void 0 : value.data); | ||
}); | ||
async function getParsedAccount(connection, address, parser) { | ||
const value = await connection.getAccountInfo(address_util_1.AddressUtil.toPubKey(address)); | ||
const key = address_util_1.AddressUtil.toPubKey(address); | ||
return parser.parse(key, value); | ||
} | ||
exports.getParsedAccount = getParsedAccount; | ||
function getMultipleParsedAccounts(connection, addresses, parser) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (addresses.length === 0) { | ||
return []; | ||
async function getMultipleParsedAccounts(connection, addresses, parser) { | ||
if (addresses.length === 0) { | ||
return []; | ||
} | ||
const values = await getMultipleAccounts(connection, address_util_1.AddressUtil.toPubKeys(addresses)); | ||
const results = values.map((val) => { | ||
if (val[1] === null) { | ||
return null; | ||
} | ||
const values = yield getMultipleAccounts(connection, address_util_1.AddressUtil.toPubKeys(addresses)); | ||
const results = values | ||
.map((value) => parser.parse(value === null || value === void 0 ? void 0 : value.data)) | ||
.filter((value) => value !== undefined); | ||
(0, tiny_invariant_1.default)(results.length === addresses.length, "not enough results fetched"); | ||
return results; | ||
return parser.parse(val[0], val[1]); | ||
}); | ||
(0, tiny_invariant_1.default)(results.length === addresses.length, "not enough results fetched"); | ||
return results; | ||
} | ||
exports.getMultipleParsedAccounts = getMultipleParsedAccounts; | ||
function getMultipleAccounts(connection, addresses) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (addresses.length === 0) { | ||
return []; | ||
} | ||
const responses = []; | ||
const chunk = 100; // getMultipleAccounts has limitation of 100 accounts per request | ||
for (let i = 0; i < addresses.length; i += chunk) { | ||
const addressChunk = addresses.slice(i, i + chunk); | ||
const res = connection.getMultipleAccountsInfo(address_util_1.AddressUtil.toPubKeys(addressChunk), connection.commitment); | ||
responses.push(res); | ||
} | ||
const combinedResult = (yield Promise.all(responses)).flat(); | ||
(0, tiny_invariant_1.default)(combinedResult.length === addresses.length, "getMultipleAccounts not enough results"); | ||
return combinedResult; | ||
async function getMultipleAccountsInMap(connection, addresses, timeoutAfterSeconds = 10) { | ||
const results = await getMultipleAccounts(connection, addresses, timeoutAfterSeconds); | ||
return results.reduce((map, [key, value]) => { | ||
map.set(key.toBase58(), value); | ||
return map; | ||
}, new Map()); | ||
} | ||
exports.getMultipleAccountsInMap = getMultipleAccountsInMap; | ||
async function getMultipleAccounts(connection, addresses, timeoutAfterSeconds = 10) { | ||
if (addresses.length === 0) { | ||
return []; | ||
} | ||
const promises = []; | ||
const chunk = 100; // getMultipleAccounts has limitation of 100 accounts per request | ||
const result = []; | ||
for (let i = 0; i < addresses.length; i += chunk) { | ||
const addressChunk = address_util_1.AddressUtil.toPubKeys(addresses.slice(i, i + chunk)); | ||
const promise = new Promise(async (resolve) => { | ||
const res = await connection.getMultipleAccountsInfo(addressChunk); | ||
const map = res.map((result, index) => { | ||
return [addressChunk[index], result]; | ||
}); | ||
result.push(...map); | ||
resolve(); | ||
}); | ||
promises.push(promise); | ||
} | ||
await Promise.race([ | ||
Promise.all(promises), | ||
timeoutAfter(timeoutAfterSeconds, "connection.getMultipleAccountsInfo timeout"), | ||
]); | ||
(0, tiny_invariant_1.default)(result.length === addresses.length, "getMultipleAccounts not enough results"); | ||
return result; | ||
} | ||
exports.getMultipleAccounts = getMultipleAccounts; | ||
function timeoutAfter(seconds, message) { | ||
return new Promise((_, reject) => { | ||
setTimeout(() => { | ||
reject(new Error(message)); | ||
}, seconds * 1000); | ||
}); | ||
} | ||
exports.getMultipleAccounts = getMultipleAccounts; |
/// <reference types="node" /> | ||
import { AccountInfo, MintInfo } from "@solana/spl-token"; | ||
import { Account, Mint } from "@solana/spl-token"; | ||
import { AccountInfo, PublicKey } from "@solana/web3.js"; | ||
/** | ||
@@ -14,3 +15,3 @@ * Static abstract class definition to parse entities. | ||
*/ | ||
parse: (accountData: Buffer | undefined | null) => T | null; | ||
parse: (address: PublicKey, accountData: AccountInfo<Buffer> | undefined | null) => T | null; | ||
} | ||
@@ -22,3 +23,3 @@ /** | ||
private constructor(); | ||
static parse(data: Buffer | undefined | null): AccountInfo | null; | ||
static parse(address: PublicKey, data: AccountInfo<Buffer> | undefined | null): Account | null; | ||
} | ||
@@ -30,3 +31,3 @@ /** | ||
private constructor(); | ||
static parse(data: Buffer | undefined | null): MintInfo | null; | ||
static parse(address: PublicKey, data: AccountInfo<Buffer> | undefined | null): Mint | null; | ||
} | ||
@@ -33,0 +34,0 @@ /** |
@@ -10,5 +10,3 @@ "use strict"; | ||
exports.staticImplements = exports.ParsableMintInfo = exports.ParsableTokenAccountInfo = void 0; | ||
const web3_js_1 = require("@solana/web3.js"); | ||
const spl_token_1 = require("@solana/spl-token"); | ||
const token_util_1 = require("../token-util"); | ||
/** | ||
@@ -19,3 +17,3 @@ * @category Parsables | ||
constructor() { } | ||
static parse(data) { | ||
static parse(address, data) { | ||
if (!data) { | ||
@@ -25,6 +23,6 @@ return null; | ||
try { | ||
return token_util_1.TokenUtil.deserializeTokenAccount(data); | ||
return (0, spl_token_1.unpackAccount)(address, data); | ||
} | ||
catch (e) { | ||
console.error(`error while parsing TokenAccount: ${e}`); | ||
console.error(`error while parsing TokenAccount ${address.toBase58()}: ${e}`); | ||
return null; | ||
@@ -43,3 +41,3 @@ } | ||
constructor() { } | ||
static parse(data) { | ||
static parse(address, data) { | ||
if (!data) { | ||
@@ -49,17 +47,6 @@ return null; | ||
try { | ||
if (data.byteLength !== spl_token_1.MintLayout.span) { | ||
throw new Error("Invalid data length for MintInfo"); | ||
} | ||
const buffer = spl_token_1.MintLayout.decode(data); | ||
const mintInfo = { | ||
mintAuthority: buffer.mintAuthorityOption === 0 ? null : new web3_js_1.PublicKey(buffer.mintAuthority), | ||
supply: spl_token_1.u64.fromBuffer(buffer.supply), | ||
decimals: buffer.decimals, | ||
isInitialized: buffer.isInitialized !== 0, | ||
freezeAuthority: buffer.freezeAuthorityOption === 0 ? null : new web3_js_1.PublicKey(buffer.freezeAuthority), | ||
}; | ||
return mintInfo; | ||
return (0, spl_token_1.unpackMint)(address, data); | ||
} | ||
catch (e) { | ||
console.error(`error while parsing MintInfo: ${e}`); | ||
console.error(`error while parsing Mint ${address.toBase58()}: ${e}`); | ||
return null; | ||
@@ -66,0 +53,0 @@ } |
@@ -1,4 +0,3 @@ | ||
/// <reference types="node" /> | ||
import { AccountInfo, u64 } from "@solana/spl-token"; | ||
import { Connection, PublicKey } from "@solana/web3.js"; | ||
import BN from "bn.js"; | ||
import { Instruction } from "../web3"; | ||
@@ -8,6 +7,21 @@ /** | ||
*/ | ||
export type ResolvedTokenAddressInstruction = { | ||
address: PublicKey; | ||
} & Instruction; | ||
/** | ||
* @category Util | ||
*/ | ||
export declare class TokenUtil { | ||
static isNativeMint(mint: PublicKey): boolean; | ||
static deserializeTokenAccount: (data: Buffer | undefined) => AccountInfo | null; | ||
/** | ||
* Create an ix to send a native-mint and unwrap it to the user's wallet. | ||
* @param owner | ||
* @param amountIn | ||
* @param rentExemptLamports | ||
* @param payer | ||
* @param unwrapDestination | ||
* @returns | ||
*/ | ||
static createWrappedNativeAccountInstruction(owner: PublicKey, amountIn: BN, rentExemptLamports: number, payer?: PublicKey, unwrapDestination?: PublicKey): ResolvedTokenAddressInstruction; | ||
/** | ||
* Create an ix to send a spl-token / native-mint to another wallet. | ||
@@ -27,3 +41,3 @@ * This function will handle the associated token accounts internally for spl-token. | ||
*/ | ||
static createSendTokensToWalletInstruction(connection: Connection, sourceWallet: PublicKey, destinationWallet: PublicKey, tokenMint: PublicKey, tokenDecimals: number, amount: u64, getAccountRentExempt: () => Promise<number>, payer?: PublicKey): Promise<Instruction>; | ||
static createSendTokensToWalletInstruction(connection: Connection, sourceWallet: PublicKey, destinationWallet: PublicKey, tokenMint: PublicKey, tokenDecimals: number, amount: BN, getAccountRentExempt: () => Promise<number>, payer?: PublicKey): Promise<Instruction>; | ||
} |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __rest = (this && this.__rest) || function (s, e) { | ||
var t = {}; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) | ||
t[p] = s[p]; | ||
if (s != null && typeof Object.getOwnPropertySymbols === "function") | ||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { | ||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) | ||
t[p[i]] = s[p[i]]; | ||
} | ||
return t; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -40,2 +20,31 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
/** | ||
* Create an ix to send a native-mint and unwrap it to the user's wallet. | ||
* @param owner | ||
* @param amountIn | ||
* @param rentExemptLamports | ||
* @param payer | ||
* @param unwrapDestination | ||
* @returns | ||
*/ | ||
static createWrappedNativeAccountInstruction(owner, amountIn, rentExemptLamports, payer, unwrapDestination) { | ||
const payerKey = payer ?? owner; | ||
const tempAccount = new web3_js_1.Keypair(); | ||
const unwrapDestinationKey = unwrapDestination ?? payer ?? owner; | ||
const createAccountInstruction = web3_js_1.SystemProgram.createAccount({ | ||
fromPubkey: payerKey, | ||
newAccountPubkey: tempAccount.publicKey, | ||
lamports: amountIn.toNumber() + rentExemptLamports, | ||
space: spl_token_1.AccountLayout.span, | ||
programId: spl_token_1.TOKEN_PROGRAM_ID, | ||
}); | ||
const initAccountInstruction = (0, spl_token_1.createInitializeAccountInstruction)(tempAccount.publicKey, spl_token_1.NATIVE_MINT, owner); | ||
const closeWSOLAccountInstruction = (0, spl_token_1.createCloseAccountInstruction)(tempAccount.publicKey, unwrapDestinationKey, owner); | ||
return { | ||
address: tempAccount.publicKey, | ||
instructions: [createAccountInstruction, initAccountInstruction], | ||
cleanupInstructions: [closeWSOLAccountInstruction], | ||
signers: [tempAccount], | ||
}; | ||
} | ||
/** | ||
* Create an ix to send a spl-token / native-mint to another wallet. | ||
@@ -55,66 +64,27 @@ * This function will handle the associated token accounts internally for spl-token. | ||
*/ | ||
static createSendTokensToWalletInstruction(connection, sourceWallet, destinationWallet, tokenMint, tokenDecimals, amount, getAccountRentExempt, payer) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
(0, tiny_invariant_1.default)(!amount.eq(math_1.ZERO), "SendToken transaction must send more than 0 tokens."); | ||
// Specifically handle SOL, which is not a spl-token. | ||
if (tokenMint.equals(spl_token_1.NATIVE_MINT)) { | ||
const sendSolTxn = web3_js_1.SystemProgram.transfer({ | ||
fromPubkey: sourceWallet, | ||
toPubkey: destinationWallet, | ||
lamports: BigInt(amount.toString()), | ||
}); | ||
return { | ||
instructions: [sendSolTxn], | ||
cleanupInstructions: [], | ||
signers: [], | ||
}; | ||
} | ||
const sourceTokenAccount = yield (0, web3_1.deriveATA)(sourceWallet, tokenMint); | ||
const _a = yield (0, web3_1.resolveOrCreateATA)(connection, destinationWallet, tokenMint, getAccountRentExempt, amount, payer), { address: destinationTokenAccount } = _a, destinationAtaIx = __rest(_a, ["address"]); | ||
const transferIx = spl_token_1.Token.createTransferCheckedInstruction(spl_token_1.TOKEN_PROGRAM_ID, sourceTokenAccount, tokenMint, destinationTokenAccount, sourceWallet, [], new spl_token_1.u64(amount.toString()), tokenDecimals); | ||
static async createSendTokensToWalletInstruction(connection, sourceWallet, destinationWallet, tokenMint, tokenDecimals, amount, getAccountRentExempt, payer) { | ||
(0, tiny_invariant_1.default)(!amount.eq(math_1.ZERO), "SendToken transaction must send more than 0 tokens."); | ||
// Specifically handle SOL, which is not a spl-token. | ||
if (tokenMint.equals(spl_token_1.NATIVE_MINT)) { | ||
const sendSolTxn = web3_js_1.SystemProgram.transfer({ | ||
fromPubkey: sourceWallet, | ||
toPubkey: destinationWallet, | ||
lamports: BigInt(amount.toString()), | ||
}); | ||
return { | ||
instructions: destinationAtaIx.instructions.concat(transferIx), | ||
cleanupInstructions: destinationAtaIx.cleanupInstructions, | ||
signers: destinationAtaIx.signers, | ||
instructions: [sendSolTxn], | ||
cleanupInstructions: [], | ||
signers: [], | ||
}; | ||
}); | ||
} | ||
const sourceTokenAccount = (0, spl_token_1.getAssociatedTokenAddressSync)(tokenMint, sourceWallet); | ||
const { address: destinationTokenAccount, ...destinationAtaIx } = await (0, web3_1.resolveOrCreateATA)(connection, destinationWallet, tokenMint, getAccountRentExempt, amount, payer); | ||
const transferIx = (0, spl_token_1.createTransferCheckedInstruction)(sourceTokenAccount, tokenMint, destinationTokenAccount, sourceWallet, BigInt(amount.toString()), tokenDecimals); | ||
return { | ||
instructions: destinationAtaIx.instructions.concat(transferIx), | ||
cleanupInstructions: destinationAtaIx.cleanupInstructions, | ||
signers: destinationAtaIx.signers, | ||
}; | ||
} | ||
} | ||
exports.TokenUtil = TokenUtil; | ||
TokenUtil.deserializeTokenAccount = (data) => { | ||
if (!data) { | ||
return null; | ||
} | ||
if (data.byteLength !== spl_token_1.AccountLayout.span) { | ||
throw new Error("Invalid data length for TokenAccount"); | ||
} | ||
const accountInfo = spl_token_1.AccountLayout.decode(data); | ||
accountInfo.mint = new web3_js_1.PublicKey(accountInfo.mint); | ||
accountInfo.owner = new web3_js_1.PublicKey(accountInfo.owner); | ||
accountInfo.amount = spl_token_1.u64.fromBuffer(accountInfo.amount); | ||
if (accountInfo.delegateOption === 0) { | ||
accountInfo.delegate = null; | ||
accountInfo.delegatedAmount = new spl_token_1.u64(0); | ||
} | ||
else { | ||
accountInfo.delegate = new web3_js_1.PublicKey(accountInfo.delegate); | ||
accountInfo.delegatedAmount = spl_token_1.u64.fromBuffer(accountInfo.delegatedAmount); | ||
} | ||
accountInfo.isInitialized = accountInfo.state !== 0; | ||
accountInfo.isFrozen = accountInfo.state === 2; | ||
if (accountInfo.isNativeOption === 1) { | ||
accountInfo.rentExemptReserve = spl_token_1.u64.fromBuffer(accountInfo.isNative); | ||
accountInfo.isNative = true; | ||
} | ||
else { | ||
accountInfo.rentExemptReserve = null; | ||
accountInfo.isNative = false; | ||
} | ||
if (accountInfo.closeAuthorityOption === 0) { | ||
accountInfo.closeAuthority = null; | ||
} | ||
else { | ||
accountInfo.closeAuthority = new web3_js_1.PublicKey(accountInfo.closeAuthority); | ||
} | ||
return accountInfo; | ||
}; |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -38,3 +29,3 @@ exports.isVersionedTransaction = exports.TransactionBuilder = exports.defaultTransactionBuilderOptions = void 0; | ||
this.signers = []; | ||
this.opts = defaultOpts !== null && defaultOpts !== void 0 ? defaultOpts : exports.defaultTransactionBuilderOptions; | ||
this.opts = defaultOpts ?? exports.defaultTransactionBuilderOptions; | ||
} | ||
@@ -122,3 +113,7 @@ /** | ||
txnSize(userOptions) { | ||
const finalOptions = Object.assign(Object.assign(Object.assign({}, this.opts.defaultBuildOption), userOptions), { latestBlockhash: constants_1.MEASUREMENT_BLOCKHASH }); | ||
const finalOptions = { | ||
...this.opts.defaultBuildOption, | ||
...userOptions, | ||
latestBlockhash: constants_1.MEASUREMENT_BLOCKHASH, | ||
}; | ||
if (this.isEmpty()) { | ||
@@ -142,3 +137,6 @@ return 0; | ||
if (maxSupportedTransactionVersion === "legacy") { | ||
const transaction = new web3_js_1.Transaction(Object.assign(Object.assign({}, recentBlockhash), { feePayer: this.wallet.publicKey })); | ||
const transaction = new web3_js_1.Transaction({ | ||
...recentBlockhash, | ||
feePayer: this.wallet.publicKey, | ||
}); | ||
transaction.add(...ix.instructions); | ||
@@ -171,12 +169,10 @@ transaction.feePayer = this.wallet.publicKey; | ||
*/ | ||
build(userOptions) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const finalOptions = Object.assign(Object.assign({}, this.opts.defaultBuildOption), userOptions); | ||
const { latestBlockhash, blockhashCommitment } = finalOptions; | ||
let recentBlockhash = latestBlockhash; | ||
if (!recentBlockhash) { | ||
recentBlockhash = yield this.connection.getLatestBlockhash(blockhashCommitment); | ||
} | ||
return this.buildSync(Object.assign(Object.assign({}, finalOptions), { latestBlockhash: recentBlockhash })); | ||
}); | ||
async build(userOptions) { | ||
const finalOptions = { ...this.opts.defaultBuildOption, ...userOptions }; | ||
const { latestBlockhash, blockhashCommitment } = finalOptions; | ||
let recentBlockhash = latestBlockhash; | ||
if (!recentBlockhash) { | ||
recentBlockhash = await this.connection.getLatestBlockhash(blockhashCommitment); | ||
} | ||
return this.buildSync({ ...finalOptions, latestBlockhash: recentBlockhash }); | ||
} | ||
@@ -190,28 +186,29 @@ /** | ||
*/ | ||
buildAndExecute(options, sendOptions, confirmCommitment) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const sendOpts = Object.assign(Object.assign({}, this.opts.defaultSendOption), sendOptions); | ||
const btx = yield this.build(options); | ||
const txn = btx.transaction; | ||
const resolvedConfirmCommitment = confirmCommitment !== null && confirmCommitment !== void 0 ? confirmCommitment : this.opts.defaultConfirmationCommitment; | ||
let txId; | ||
if ((0, exports.isVersionedTransaction)(txn)) { | ||
const signedTxn = yield this.wallet.signTransaction(txn); | ||
signedTxn.sign(btx.signers); | ||
txId = yield this.connection.sendTransaction(signedTxn, sendOpts); | ||
} | ||
else { | ||
const signedTxn = yield this.wallet.signTransaction(txn); | ||
btx.signers | ||
.filter((s) => s !== undefined) | ||
.forEach((keypair) => signedTxn.partialSign(keypair)); | ||
txId = yield this.connection.sendRawTransaction(signedTxn.serialize(), sendOpts); | ||
} | ||
const result = yield this.connection.confirmTransaction(Object.assign({ signature: txId }, btx.recentBlockhash), resolvedConfirmCommitment); | ||
const confirmTxErr = result.value.err; | ||
if (confirmTxErr) { | ||
throw new Error(confirmTxErr.toString()); | ||
} | ||
return txId; | ||
}); | ||
async buildAndExecute(options, sendOptions, confirmCommitment) { | ||
const sendOpts = { ...this.opts.defaultSendOption, ...sendOptions }; | ||
const btx = await this.build(options); | ||
const txn = btx.transaction; | ||
const resolvedConfirmCommitment = confirmCommitment ?? this.opts.defaultConfirmationCommitment; | ||
let txId; | ||
if ((0, exports.isVersionedTransaction)(txn)) { | ||
const signedTxn = await this.wallet.signTransaction(txn); | ||
signedTxn.sign(btx.signers); | ||
txId = await this.connection.sendTransaction(signedTxn, sendOpts); | ||
} | ||
else { | ||
const signedTxn = await this.wallet.signTransaction(txn); | ||
btx.signers | ||
.filter((s) => s !== undefined) | ||
.forEach((keypair) => signedTxn.partialSign(keypair)); | ||
txId = await this.connection.sendRawTransaction(signedTxn.serialize(), sendOpts); | ||
} | ||
const result = await this.connection.confirmTransaction({ | ||
signature: txId, | ||
...btx.recentBlockhash, | ||
}, resolvedConfirmCommitment); | ||
const confirmTxErr = result.value.err; | ||
if (confirmTxErr) { | ||
throw new Error(confirmTxErr.toString()); | ||
} | ||
return txId; | ||
} | ||
@@ -218,0 +215,0 @@ } |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -22,40 +13,34 @@ exports.TransactionProcessor = void 0; | ||
} | ||
signTransaction(txRequest) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const { transactions, lastValidBlockHeight, blockhash } = yield this.signTransactions([ | ||
txRequest, | ||
]); | ||
return { transaction: transactions[0], lastValidBlockHeight, blockhash }; | ||
}); | ||
async signTransaction(txRequest) { | ||
const { transactions, lastValidBlockHeight, blockhash } = await this.signTransactions([ | ||
txRequest, | ||
]); | ||
return { transaction: transactions[0], lastValidBlockHeight, blockhash }; | ||
} | ||
signTransactions(txRequests) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const { blockhash, lastValidBlockHeight } = yield this.connection.getLatestBlockhash(this.commitment); | ||
const feePayer = this.wallet.publicKey; | ||
const pSignedTxs = txRequests.map((txRequest) => { | ||
return rewriteTransaction(txRequest, feePayer, blockhash); | ||
}); | ||
const transactions = yield this.wallet.signAllTransactions(pSignedTxs); | ||
return { | ||
transactions, | ||
lastValidBlockHeight, | ||
blockhash, | ||
}; | ||
async signTransactions(txRequests) { | ||
const { blockhash, lastValidBlockHeight } = await this.connection.getLatestBlockhash(this.commitment); | ||
const feePayer = this.wallet.publicKey; | ||
const pSignedTxs = txRequests.map((txRequest) => { | ||
return rewriteTransaction(txRequest, feePayer, blockhash); | ||
}); | ||
const transactions = await this.wallet.signAllTransactions(pSignedTxs); | ||
return { | ||
transactions, | ||
lastValidBlockHeight, | ||
blockhash, | ||
}; | ||
} | ||
sendTransaction(transaction, lastValidBlockHeight, blockhash) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const execute = this.constructSendTransactions([transaction], lastValidBlockHeight, blockhash); | ||
const txs = yield execute(); | ||
const ex = txs[0]; | ||
if (ex.status === "fulfilled") { | ||
return ex.value; | ||
} | ||
else { | ||
throw ex.reason; | ||
} | ||
}); | ||
async sendTransaction(transaction, lastValidBlockHeight, blockhash) { | ||
const execute = this.constructSendTransactions([transaction], lastValidBlockHeight, blockhash); | ||
const txs = await execute(); | ||
const ex = txs[0]; | ||
if (ex.status === "fulfilled") { | ||
return ex.value; | ||
} | ||
else { | ||
throw ex.reason; | ||
} | ||
} | ||
constructSendTransactions(transactions, lastValidBlockHeight, blockhash, parallel = true) { | ||
const executeTx = (tx) => __awaiter(this, void 0, void 0, function* () { | ||
const executeTx = async (tx) => { | ||
const rawTxs = tx.serialize(); | ||
@@ -65,5 +50,5 @@ return this.connection.sendRawTransaction(rawTxs, { | ||
}); | ||
}); | ||
const confirmTx = (txId) => __awaiter(this, void 0, void 0, function* () { | ||
const result = yield this.connection.confirmTransaction({ | ||
}; | ||
const confirmTx = async (txId) => { | ||
const result = await this.connection.confirmTransaction({ | ||
signature: txId, | ||
@@ -76,10 +61,10 @@ lastValidBlockHeight: lastValidBlockHeight, | ||
} | ||
}); | ||
return () => __awaiter(this, void 0, void 0, function* () { | ||
}; | ||
return async () => { | ||
if (parallel) { | ||
const results = transactions.map((tx) => __awaiter(this, void 0, void 0, function* () { | ||
const txId = yield executeTx(tx); | ||
yield confirmTx(txId); | ||
const results = transactions.map(async (tx) => { | ||
const txId = await executeTx(tx); | ||
await confirmTx(txId); | ||
return txId; | ||
})); | ||
}); | ||
return Promise.allSettled(results); | ||
@@ -90,4 +75,4 @@ } | ||
for (const tx of transactions) { | ||
const txId = yield executeTx(tx); | ||
yield confirmTx(txId); | ||
const txId = await executeTx(tx); | ||
await confirmTx(txId); | ||
results.push(txId); | ||
@@ -97,19 +82,15 @@ } | ||
} | ||
}); | ||
}; | ||
} | ||
signAndConstructTransaction(txRequest) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const { transaction, lastValidBlockHeight, blockhash } = yield this.signTransaction(txRequest); | ||
return { | ||
signedTx: transaction, | ||
execute: () => __awaiter(this, void 0, void 0, function* () { return this.sendTransaction(transaction, lastValidBlockHeight, blockhash); }), | ||
}; | ||
}); | ||
async signAndConstructTransaction(txRequest) { | ||
const { transaction, lastValidBlockHeight, blockhash } = await this.signTransaction(txRequest); | ||
return { | ||
signedTx: transaction, | ||
execute: async () => this.sendTransaction(transaction, lastValidBlockHeight, blockhash), | ||
}; | ||
} | ||
signAndConstructTransactions(txRequests, parallel = true) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const { transactions, lastValidBlockHeight, blockhash } = yield this.signTransactions(txRequests); | ||
const execute = this.constructSendTransactions(transactions, lastValidBlockHeight, blockhash, parallel); | ||
return { signedTxs: transactions, execute }; | ||
}); | ||
async signAndConstructTransactions(txRequests, parallel = true) { | ||
const { transactions, lastValidBlockHeight, blockhash } = await this.signTransactions(txRequests); | ||
const execute = this.constructSendTransactions(transactions, lastValidBlockHeight, blockhash, parallel); | ||
return { signedTxs: transactions, execute }; | ||
} | ||
@@ -119,4 +100,3 @@ } | ||
function rewriteTransaction(txRequest, feePayer, blockhash) { | ||
var _a; | ||
const signers = (_a = txRequest.signers) !== null && _a !== void 0 ? _a : []; | ||
const signers = txRequest.signers ?? []; | ||
const tx = txRequest.transaction; | ||
@@ -123,0 +103,0 @@ tx.feePayer = feePayer; |
{ | ||
"name": "@orca-so/common-sdk", | ||
"version": "0.2.2", | ||
"version": "0.3.0-beta-0", | ||
"description": "Common Typescript components across Orca", | ||
@@ -11,4 +11,4 @@ "repository": "https://github.com/orca-so/orca-sdks", | ||
"dependencies": { | ||
"@solana/spl-token": "0.1.8", | ||
"@solana/web3.js": "^1.74.0", | ||
"@solana/spl-token": "^0.3.8", | ||
"@solana/web3.js": "^1.75.0", | ||
"decimal.js": "^10.3.1", | ||
@@ -20,10 +20,10 @@ "tiny-invariant": "^1.2.0" | ||
"@types/decimal.js": "^7.4.0", | ||
"@types/jest": "^26.0.24", | ||
"@types/jest": "^29.5.2", | ||
"@typescript-eslint/eslint-plugin": "^4.26.0", | ||
"@typescript-eslint/parser": "^4.26.0", | ||
"eslint-config-prettier": "^8.3.0", | ||
"jest": "^27.0.6", | ||
"jest": "^29.5.0", | ||
"prettier": "^2.3.2", | ||
"process": "^0.11.10", | ||
"ts-jest": "^27.0.3", | ||
"ts-jest": "^29.1.0", | ||
"typescript": "^4.5.5" | ||
@@ -36,3 +36,3 @@ }, | ||
"prettier-format": "prettier --config .prettierrc 'src/**/*.ts' --write", | ||
"test": "jest", | ||
"test": "jest --detectOpenHandles", | ||
"docs": "npx typedoc --excludePrivate --categorizeByGroup false --tsconfig src/tsconfig.json" | ||
@@ -46,2 +46,2 @@ }, | ||
] | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
132679
48
1541
+ Added@solana/buffer-layout-utils@0.2.0(transitive)
+ Added@solana/codecs@2.0.0-rc.1(transitive)
+ Added@solana/codecs-core@2.0.0-rc.1(transitive)
+ Added@solana/codecs-data-structures@2.0.0-rc.1(transitive)
+ Added@solana/codecs-numbers@2.0.0-rc.1(transitive)
+ Added@solana/codecs-strings@2.0.0-rc.1(transitive)
+ Added@solana/errors@2.0.0-rc.1(transitive)
+ Added@solana/options@2.0.0-rc.1(transitive)
+ Added@solana/spl-token@0.3.11(transitive)
+ Added@solana/spl-token-metadata@0.1.6(transitive)
+ Addedbignumber.js@9.1.2(transitive)
+ Addedchalk@5.4.1(transitive)
+ Addedcommander@12.1.0(transitive)
+ Addedfastestsmallesttextencoderdecoder@1.0.22(transitive)
+ Addedtypescript@5.7.2(transitive)
- Removed@solana/spl-token@0.1.8(transitive)
- Removedbuffer-layout@1.2.2(transitive)
- Removeddotenv@10.0.0(transitive)
Updated@solana/spl-token@^0.3.8
Updated@solana/web3.js@^1.75.0