TS: add estimatePrioritizationFee
This commit is contained in:
parent
f462c62816
commit
aace8a06e5
|
@ -62,7 +62,7 @@
|
|||
"@project-serum/serum": "0.13.65",
|
||||
"@pythnetwork/client": "~2.14.0",
|
||||
"@solana/spl-token": "0.3.7",
|
||||
"@solana/web3.js": "^1.73.2",
|
||||
"@solana/web3.js": "^1.78.2",
|
||||
"@switchboard-xyz/sbv2-lite": "^0.1.6",
|
||||
"big.js": "^6.1.1",
|
||||
"binance-api-node": "^0.12.0",
|
||||
|
|
|
@ -26,6 +26,7 @@ import {
|
|||
SystemProgram,
|
||||
TransactionInstruction,
|
||||
TransactionSignature,
|
||||
RecentPrioritizationFees,
|
||||
} from '@solana/web3.js';
|
||||
import bs58 from 'bs58';
|
||||
import chunk from 'lodash/chunk';
|
||||
|
@ -68,7 +69,12 @@ import {
|
|||
buildIxGate,
|
||||
TokenRegisterParams,
|
||||
} from './clientIxParamBuilder';
|
||||
import { MANGO_V4_ID, OPENBOOK_PROGRAM_ID, RUST_U64_MAX } from './constants';
|
||||
import {
|
||||
MANGO_V4_ID,
|
||||
MAX_RECENT_PRIORITY_FEE_ACCOUNTS,
|
||||
OPENBOOK_PROGRAM_ID,
|
||||
RUST_U64_MAX,
|
||||
} from './constants';
|
||||
import { Id } from './ids';
|
||||
import { IDL, MangoV4 } from './mango_v4';
|
||||
import { I80F48 } from './numbers/I80F48';
|
||||
|
@ -97,6 +103,7 @@ export type MangoClientOptions = {
|
|||
idsSource?: IdsSource;
|
||||
postSendTxCallback?: ({ txid }: { txid: string }) => void;
|
||||
prioritizationFee?: number;
|
||||
estimateFee?: boolean;
|
||||
txConfirmationCommitment?: Commitment;
|
||||
openbookFeesToDao?: boolean;
|
||||
};
|
||||
|
@ -105,6 +112,7 @@ export class MangoClient {
|
|||
private idsSource: IdsSource;
|
||||
private postSendTxCallback?: ({ txid }) => void;
|
||||
private prioritizationFee: number;
|
||||
private estimateFee: boolean;
|
||||
private txConfirmationCommitment: Commitment;
|
||||
private openbookFeesToDao: boolean;
|
||||
|
||||
|
@ -116,6 +124,7 @@ export class MangoClient {
|
|||
) {
|
||||
this.idsSource = opts?.idsSource || 'get-program-accounts';
|
||||
this.prioritizationFee = opts?.prioritizationFee || 0;
|
||||
this.estimateFee = opts?.estimateFee || false;
|
||||
this.postSendTxCallback = opts?.postSendTxCallback;
|
||||
this.openbookFeesToDao = opts?.openbookFeesToDao ?? true;
|
||||
this.txConfirmationCommitment =
|
||||
|
@ -140,13 +149,21 @@ export class MangoClient {
|
|||
ixs: TransactionInstruction[],
|
||||
opts: any = {},
|
||||
): Promise<string> {
|
||||
let prioritizationFee: number;
|
||||
if (opts.prioritizationFee) {
|
||||
prioritizationFee = opts.prioritizationFee;
|
||||
} else if (this.estimateFee) {
|
||||
prioritizationFee = await this.estimatePrioritizationFee(ixs);
|
||||
} else {
|
||||
prioritizationFee = this.prioritizationFee;
|
||||
}
|
||||
return await sendTransaction(
|
||||
this.program.provider as AnchorProvider,
|
||||
ixs,
|
||||
opts.alts ?? [],
|
||||
{
|
||||
postSendTxCallback: this.postSendTxCallback,
|
||||
prioritizationFee: this.prioritizationFee,
|
||||
prioritizationFee,
|
||||
txConfirmationCommitment: this.txConfirmationCommitment,
|
||||
...opts,
|
||||
},
|
||||
|
@ -4193,4 +4210,55 @@ export class MangoClient {
|
|||
transactionInstructions,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an estimate of a prioritization fee for a set of instructions.
|
||||
*
|
||||
* The estimate is based on the exponential moving average of the prioritization fees of accounts that will be involved in the transaction.
|
||||
*
|
||||
* @param ixs - the instructions that make up the transaction
|
||||
* @returns prioritizationFeeEstimate -- in microLamports
|
||||
*/
|
||||
public async estimatePrioritizationFee(
|
||||
ixs: TransactionInstruction[],
|
||||
): Promise<number> {
|
||||
const accounts = [
|
||||
...new Set(ixs.map((x) => x.keys.map((k) => k.pubkey)).flat()),
|
||||
].slice(0, MAX_RECENT_PRIORITY_FEE_ACCOUNTS);
|
||||
const priorityFees = await this.connection.getRecentPrioritizationFees({
|
||||
lockedWritableAccounts: accounts,
|
||||
});
|
||||
|
||||
// get max priority fee per slot (and sort by slot from old to new)
|
||||
const flatFees = priorityFees.flat();
|
||||
const maxFeeBySlot = flatFees.reduce(
|
||||
(
|
||||
acc: Record<number, RecentPrioritizationFees>,
|
||||
fee: RecentPrioritizationFees,
|
||||
) => {
|
||||
if (
|
||||
!acc[fee.slot] ||
|
||||
fee.prioritizationFee > acc[fee.slot].prioritizationFee
|
||||
) {
|
||||
acc[fee.slot] = fee;
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
);
|
||||
const maximumFees = Object.values(maxFeeBySlot).sort(
|
||||
(a, b) => a.slot - b.slot,
|
||||
);
|
||||
|
||||
// take the EMA
|
||||
const smoothingFactor = 2 / (maximumFees.length + 1);
|
||||
let ema = maximumFees[0].prioritizationFee;
|
||||
for (let i = 1; i < maximumFees.length; i++) {
|
||||
ema =
|
||||
maximumFees[i].prioritizationFee * smoothingFactor +
|
||||
ema * (1 - smoothingFactor);
|
||||
}
|
||||
|
||||
return Math.ceil(1.2 * ema);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,3 +25,4 @@ export const MANGO_V4_ID = {
|
|||
export const USDC_MINT = new PublicKey(
|
||||
'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
|
||||
);
|
||||
export const MAX_RECENT_PRIORITY_FEE_ACCOUNTS = 128;
|
||||
|
|
76
yarn.lock
76
yarn.lock
|
@ -37,6 +37,13 @@
|
|||
dependencies:
|
||||
regenerator-runtime "^0.13.11"
|
||||
|
||||
"@babel/runtime@^7.22.6":
|
||||
version "7.22.10"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.10.tgz#ae3e9631fd947cb7e3610d3e9d8fef5f76696682"
|
||||
integrity sha512-21t/fkKLMZI4pqP2wlmsQAWnYW1PDyKyyUV4vCi+B25ydmdaYTKXPwCj0BzSUnZf4seIiYvSA3jcZ3gdsMFkLQ==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.14.0"
|
||||
|
||||
"@colors/colors@1.5.0":
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9"
|
||||
|
@ -171,11 +178,23 @@
|
|||
"@jridgewell/resolve-uri" "^3.0.3"
|
||||
"@jridgewell/sourcemap-codec" "^1.4.10"
|
||||
|
||||
"@noble/curves@^1.0.0":
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.1.0.tgz#f13fc667c89184bc04cccb9b11e8e7bae27d8c3d"
|
||||
integrity sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA==
|
||||
dependencies:
|
||||
"@noble/hashes" "1.3.1"
|
||||
|
||||
"@noble/ed25519@^1.7.0":
|
||||
version "1.7.3"
|
||||
resolved "https://registry.yarnpkg.com/@noble/ed25519/-/ed25519-1.7.3.tgz#57e1677bf6885354b466c38e2b620c62f45a7123"
|
||||
integrity sha512-iR8GBkDt0Q3GyaVcIu7mSsVIqnFbkbRzGLWlvhwunacoLwt4J3swfKhfaM6rN6WY+TBGoYT1GtT1mIh2/jGbRQ==
|
||||
|
||||
"@noble/hashes@1.3.1", "@noble/hashes@^1.3.0":
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9"
|
||||
integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA==
|
||||
|
||||
"@noble/hashes@^1.1.2":
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.2.0.tgz#a3150eeb09cc7ab207ebf6d7b9ad311a9bdbed12"
|
||||
|
@ -413,7 +432,7 @@
|
|||
rpc-websockets "^7.5.0"
|
||||
superstruct "^0.14.2"
|
||||
|
||||
"@solana/web3.js@^1.68.0", "@solana/web3.js@^1.73.2":
|
||||
"@solana/web3.js@^1.68.0":
|
||||
version "1.73.2"
|
||||
resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.73.2.tgz#4b30cd402b35733dae3a7d0b638be26a7742b395"
|
||||
integrity sha512-9WACF8W4Nstj7xiDw3Oom22QmrhBh0VyZyZ7JvvG3gOxLWLlX3hvm5nPVJOGcCE/9fFavBbCUb5A6CIuvMGdoA==
|
||||
|
@ -435,6 +454,27 @@
|
|||
rpc-websockets "^7.5.0"
|
||||
superstruct "^0.14.2"
|
||||
|
||||
"@solana/web3.js@^1.78.2":
|
||||
version "1.78.3"
|
||||
resolved "https://registry.yarnpkg.com/@solana/web3.js/-/web3.js-1.78.3.tgz#1214f17f51612e403c4dc7844c7a9694938bfbab"
|
||||
integrity sha512-qhpnyIlrj/4Czw1dBFZK6KgZBk5FwuJhvMl0C7m94jhl90yDC8b6w4svKwPjhB+OOrdQAzHyRp0+ocEs/Liw7w==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.22.6"
|
||||
"@noble/curves" "^1.0.0"
|
||||
"@noble/hashes" "^1.3.0"
|
||||
"@solana/buffer-layout" "^4.0.0"
|
||||
agentkeepalive "^4.3.0"
|
||||
bigint-buffer "^1.1.5"
|
||||
bn.js "^5.2.1"
|
||||
borsh "^0.7.0"
|
||||
bs58 "^4.0.1"
|
||||
buffer "6.0.3"
|
||||
fast-stable-stringify "^1.0.0"
|
||||
jayson "^4.1.0"
|
||||
node-fetch "^2.6.12"
|
||||
rpc-websockets "^7.5.1"
|
||||
superstruct "^0.14.2"
|
||||
|
||||
"@switchboard-xyz/sbv2-lite@^0.1.6":
|
||||
version "0.1.6"
|
||||
resolved "https://registry.yarnpkg.com/@switchboard-xyz/sbv2-lite/-/sbv2-lite-0.1.6.tgz#dc3fbb5b3b028dbd3c688b991bcc48a670131ddb"
|
||||
|
@ -672,6 +712,13 @@ agentkeepalive@^4.2.1:
|
|||
depd "^1.1.2"
|
||||
humanize-ms "^1.2.1"
|
||||
|
||||
agentkeepalive@^4.3.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.5.0.tgz#2673ad1389b3c418c5a20c5d7364f93ca04be923"
|
||||
integrity sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==
|
||||
dependencies:
|
||||
humanize-ms "^1.2.1"
|
||||
|
||||
ajv@^6.10.0, ajv@^6.12.4:
|
||||
version "6.12.6"
|
||||
resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz"
|
||||
|
@ -858,7 +905,7 @@ bn.js@^4.11.9:
|
|||
resolved "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz"
|
||||
integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==
|
||||
|
||||
bn.js@^5.0.0, bn.js@^5.1.0, bn.js@^5.1.2, bn.js@^5.1.3, bn.js@^5.2.0:
|
||||
bn.js@^5.0.0, bn.js@^5.1.0, bn.js@^5.1.2, bn.js@^5.1.3, bn.js@^5.2.0, bn.js@^5.2.1:
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70"
|
||||
integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==
|
||||
|
@ -1754,6 +1801,24 @@ jayson@^3.4.4:
|
|||
uuid "^8.3.2"
|
||||
ws "^7.4.5"
|
||||
|
||||
jayson@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/jayson/-/jayson-4.1.0.tgz#60dc946a85197317f2b1439d672a8b0a99cea2f9"
|
||||
integrity sha512-R6JlbyLN53Mjku329XoRT2zJAE6ZgOQ8f91ucYdMCD4nkGCF9kZSrcGXpHIU4jeKj58zUZke2p+cdQchU7Ly7A==
|
||||
dependencies:
|
||||
"@types/connect" "^3.4.33"
|
||||
"@types/node" "^12.12.54"
|
||||
"@types/ws" "^7.4.4"
|
||||
JSONStream "^1.3.5"
|
||||
commander "^2.20.3"
|
||||
delay "^5.0.0"
|
||||
es6-promisify "^5.0.0"
|
||||
eyes "^0.1.8"
|
||||
isomorphic-ws "^4.0.1"
|
||||
json-stringify-safe "^5.0.1"
|
||||
uuid "^8.3.2"
|
||||
ws "^7.4.5"
|
||||
|
||||
js-sha256@^0.9.0:
|
||||
version "0.9.0"
|
||||
resolved "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz"
|
||||
|
@ -2071,7 +2136,7 @@ node-addon-api@^2.0.0:
|
|||
resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz"
|
||||
integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==
|
||||
|
||||
node-fetch@2, node-fetch@2.6.7, node-fetch@^2.6.1, node-fetch@^2.6.7, "node-fetch@npm:@blockworks-foundation/node-fetch@2.6.11":
|
||||
node-fetch@2, node-fetch@2.6.7, node-fetch@^2.6.1, node-fetch@^2.6.12, node-fetch@^2.6.7, "node-fetch@npm:@blockworks-foundation/node-fetch@2.6.11":
|
||||
version "2.6.11"
|
||||
resolved "https://registry.yarnpkg.com/@blockworks-foundation/node-fetch/-/node-fetch-2.6.11.tgz#fb536ef0e6a960e7b7993f3c1d3b3bba9bdfbc56"
|
||||
integrity sha512-HeDTxpIypSR4qCoqgUXGr8YL4OG1z7BbV4VhQ9iQs+pt2wV3MtqO+sQk2vXK3WDKu5C6BsbGmWE22BmIrcuOOw==
|
||||
|
@ -2241,6 +2306,11 @@ regenerator-runtime@^0.13.11, regenerator-runtime@^0.13.4:
|
|||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9"
|
||||
integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==
|
||||
|
||||
regenerator-runtime@^0.14.0:
|
||||
version "0.14.0"
|
||||
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45"
|
||||
integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==
|
||||
|
||||
regexpp@^3.1.0, regexpp@^3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz"
|
||||
|
|
Loading…
Reference in New Issue