@ar.io/sdk 4.0.0 → 4.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/esm/solana/clusters.js +1 -3
- package/lib/esm/solana/send.js +52 -11
- package/lib/esm/version.js +1 -1
- package/lib/types/solana/send.d.ts +23 -1
- package/lib/types/version.d.ts +1 -1
- package/package.json +1 -1
|
@@ -90,10 +90,8 @@ export const MAINNET_ATTESTOR_PUBKEY = address('7XtUnotZAeYZNzVSYV5nb7S9YH9qHXyV
|
|
|
90
90
|
* here for reference.
|
|
91
91
|
*/
|
|
92
92
|
export const MAINNET_AUTHORITY_PUBKEY = address('45ZuEb1Jk7pbjshD1BVasBekAXhimdWuJjyswQzMyTB1');
|
|
93
|
-
// TODO(mainnet): placeholder — this reuses the devnet mint and is WRONG for
|
|
94
|
-
// mainnet. Replace with the real mainnet ARIO mint once it is known.
|
|
95
93
|
/** ARIO SPL Token mint on Solana mainnet-beta. */
|
|
96
|
-
export const MAINNET_ARIO_MINT = address('
|
|
94
|
+
export const MAINNET_ARIO_MINT = address('DcNnMuFxwhgV4WY1HVSaSEgr92bv2b1vUvEKiNxWqHdF');
|
|
97
95
|
/**
|
|
98
96
|
* AR.IO program IDs deployed on Solana devnet (staging).
|
|
99
97
|
*
|
package/lib/esm/solana/send.js
CHANGED
|
@@ -26,26 +26,67 @@
|
|
|
26
26
|
import { ADDRESS_LOOKUP_TABLE_PROGRAM_ADDRESS, getCloseLookupTableInstruction, getCreateLookupTableInstructionAsync, getDeactivateLookupTableInstruction, getExtendLookupTableInstruction, } from '@solana-program/address-lookup-table';
|
|
27
27
|
import { getSetComputeUnitLimitInstruction, getSetComputeUnitPriceInstruction, } from '@solana-program/compute-budget';
|
|
28
28
|
import { appendTransactionMessageInstructions, compileTransaction, compressTransactionMessageUsingAddressLookupTables, createTransactionMessage, getAddressDecoder, getBase64EncodedWireTransaction, getSignatureFromTransaction, pipe, sendAndConfirmTransactionFactory, setTransactionMessageFeePayerSigner, setTransactionMessageLifetimeUsingBlockhash, signTransactionMessageWithSigners, } from '@solana/kit';
|
|
29
|
+
/**
|
|
30
|
+
* Floor for the auto-estimated priority fee (micro-lamports per CU). Ensures a
|
|
31
|
+
* non-zero fee so message-modifying wallets (Phantom) leave the tx alone. The
|
|
32
|
+
* absolute cost stays tiny: `fee ≈ price * CU_limit / 1e6` lamports
|
|
33
|
+
* (e.g. 10_000 µ£/CU × 400k CU ≈ 4_000 lamports ≈ 0.000004 SOL).
|
|
34
|
+
*/
|
|
35
|
+
const MIN_PRIORITY_FEE_MICRO_LAMPORTS = 10000n;
|
|
36
|
+
/** Cap so a spiky fee market can't blow up the fee unexpectedly. */
|
|
37
|
+
const MAX_PRIORITY_FEE_MICRO_LAMPORTS = 2000000n;
|
|
38
|
+
/**
|
|
39
|
+
* Estimate a compute-unit price from recent on-chain prioritization fees: the
|
|
40
|
+
* 75th percentile of recent non-zero per-slot fees, clamped to
|
|
41
|
+
* [{@link MIN_PRIORITY_FEE_MICRO_LAMPORTS}, {@link MAX_PRIORITY_FEE_MICRO_LAMPORTS}].
|
|
42
|
+
* Falls back to the floor when there's no data or the query fails. Matching the
|
|
43
|
+
* going rate both lands the tx and keeps Phantom from bumping (and thus
|
|
44
|
+
* rewriting) the fee.
|
|
45
|
+
*/
|
|
46
|
+
export async function estimatePriorityFeeMicroLamports(rpc) {
|
|
47
|
+
try {
|
|
48
|
+
const recent = await rpc.getRecentPrioritizationFees().send();
|
|
49
|
+
const fees = recent
|
|
50
|
+
.map((r) => BigInt(r.prioritizationFee))
|
|
51
|
+
.filter((f) => f > 0n)
|
|
52
|
+
.sort((a, b) => (a < b ? -1 : a > b ? 1 : 0));
|
|
53
|
+
if (fees.length === 0)
|
|
54
|
+
return MIN_PRIORITY_FEE_MICRO_LAMPORTS;
|
|
55
|
+
const p75 = fees[Math.min(fees.length - 1, Math.floor(fees.length * 0.75))];
|
|
56
|
+
if (p75 < MIN_PRIORITY_FEE_MICRO_LAMPORTS)
|
|
57
|
+
return MIN_PRIORITY_FEE_MICRO_LAMPORTS;
|
|
58
|
+
if (p75 > MAX_PRIORITY_FEE_MICRO_LAMPORTS)
|
|
59
|
+
return MAX_PRIORITY_FEE_MICRO_LAMPORTS;
|
|
60
|
+
return p75;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return MIN_PRIORITY_FEE_MICRO_LAMPORTS;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
29
66
|
/**
|
|
30
67
|
* Build, sign, send, and confirm a transaction in one call.
|
|
31
68
|
*
|
|
32
69
|
* The caller supplies the core instructions; a compute-unit-limit instruction
|
|
33
70
|
* is prepended automatically.
|
|
34
71
|
*/
|
|
35
|
-
export async function sendAndConfirm({ rpc, rpcSubscriptions, signer, instructions, commitment = 'confirmed', computeUnitLimit = 400_000, addressLookupTables, }) {
|
|
72
|
+
export async function sendAndConfirm({ rpc, rpcSubscriptions, signer, instructions, commitment = 'confirmed', computeUnitLimit = 400_000, priorityFeeMicroLamports = 'auto', addressLookupTables, }) {
|
|
73
|
+
const microLamports = priorityFeeMicroLamports === 'auto'
|
|
74
|
+
? await estimatePriorityFeeMicroLamports(rpc)
|
|
75
|
+
: priorityFeeMicroLamports === false
|
|
76
|
+
? 0n
|
|
77
|
+
: BigInt(priorityFeeMicroLamports);
|
|
36
78
|
const { value: latestBlockhash } = await rpc.getLatestBlockhash().send();
|
|
37
79
|
const baseMessage = pipe(createTransactionMessage({ version: 0 }), (tx) => setTransactionMessageFeePayerSigner(signer, tx), (tx) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, tx), (tx) => appendTransactionMessageInstructions([
|
|
38
80
|
getSetComputeUnitLimitInstruction({ units: computeUnitLimit }),
|
|
39
|
-
//
|
|
40
|
-
// don't
|
|
41
|
-
//
|
|
42
|
-
// mutation invalidates
|
|
43
|
-
//
|
|
44
|
-
//
|
|
45
|
-
//
|
|
46
|
-
//
|
|
47
|
-
|
|
48
|
-
getSetComputeUnitPriceInstruction({ microLamports: 0n }),
|
|
81
|
+
// Pin an explicit, NON-ZERO priority fee so wallets like Phantom
|
|
82
|
+
// don't rewrite the message to inject their own compute-budget
|
|
83
|
+
// instructions. Phantom treats a missing/zero fee as "unset" and
|
|
84
|
+
// overrides it on mainnet — that mutation invalidates the already-
|
|
85
|
+
// attached signatures (→ "Transaction did not pass signature
|
|
86
|
+
// verification" / preflight #-32002). A real, network-rate fee
|
|
87
|
+
// (see `microLamports` above) makes the wallet leave the message
|
|
88
|
+
// alone, so signatures over the original bytes still verify.
|
|
89
|
+
getSetComputeUnitPriceInstruction({ microLamports }),
|
|
49
90
|
...instructions,
|
|
50
91
|
], tx));
|
|
51
92
|
// Compress against any supplied lookup tables (v0). No-op when none given.
|
package/lib/esm/version.js
CHANGED
|
@@ -1,18 +1,40 @@
|
|
|
1
1
|
import { type Address, type Commitment, type Instruction, type TransactionSigner } from '@solana/kit';
|
|
2
2
|
import type { SolanaRpc, SolanaRpcSubscriptions } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Estimate a compute-unit price from recent on-chain prioritization fees: the
|
|
5
|
+
* 75th percentile of recent non-zero per-slot fees, clamped to
|
|
6
|
+
* [{@link MIN_PRIORITY_FEE_MICRO_LAMPORTS}, {@link MAX_PRIORITY_FEE_MICRO_LAMPORTS}].
|
|
7
|
+
* Falls back to the floor when there's no data or the query fails. Matching the
|
|
8
|
+
* going rate both lands the tx and keeps Phantom from bumping (and thus
|
|
9
|
+
* rewriting) the fee.
|
|
10
|
+
*/
|
|
11
|
+
export declare function estimatePriorityFeeMicroLamports(rpc: SolanaRpc): Promise<bigint>;
|
|
3
12
|
/**
|
|
4
13
|
* Build, sign, send, and confirm a transaction in one call.
|
|
5
14
|
*
|
|
6
15
|
* The caller supplies the core instructions; a compute-unit-limit instruction
|
|
7
16
|
* is prepended automatically.
|
|
8
17
|
*/
|
|
9
|
-
export declare function sendAndConfirm({ rpc, rpcSubscriptions, signer, instructions, commitment, computeUnitLimit, addressLookupTables, }: {
|
|
18
|
+
export declare function sendAndConfirm({ rpc, rpcSubscriptions, signer, instructions, commitment, computeUnitLimit, priorityFeeMicroLamports, addressLookupTables, }: {
|
|
10
19
|
rpc: SolanaRpc;
|
|
11
20
|
rpcSubscriptions: SolanaRpcSubscriptions;
|
|
12
21
|
signer: TransactionSigner;
|
|
13
22
|
instructions: Instruction[];
|
|
14
23
|
commitment?: Commitment;
|
|
15
24
|
computeUnitLimit?: number;
|
|
25
|
+
/**
|
|
26
|
+
* Compute-unit price (priority fee), in micro-lamports per CU.
|
|
27
|
+
* - `'auto'` (default): estimate from recent on-chain fees (see
|
|
28
|
+
* {@link estimatePriorityFeeMicroLamports}). A NON-ZERO fee is essential:
|
|
29
|
+
* wallets like Phantom treat a missing/zero fee as "unset" and rewrite the
|
|
30
|
+
* transaction to inject their own, which invalidates already-attached
|
|
31
|
+
* signatures (→ "Transaction did not pass signature verification"). A real,
|
|
32
|
+
* network-rate fee makes the wallet leave the message untouched.
|
|
33
|
+
* - a `number`/`bigint`: pin exactly this price.
|
|
34
|
+
* - `false`: no priority fee (price 0) — only for environments with no fee
|
|
35
|
+
* market (localnet) where wallet rewriting isn't a concern.
|
|
36
|
+
*/
|
|
37
|
+
priorityFeeMicroLamports?: bigint | number | 'auto' | false;
|
|
16
38
|
/**
|
|
17
39
|
* Address Lookup Tables to compress the (v0) message against, as
|
|
18
40
|
* `{ [tableAddress]: addresses }`. Accounts present in a table are referenced
|
package/lib/types/version.d.ts
CHANGED