@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.
@@ -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('6vTw5CysRXQ4ybbHkDUiisHWVsBeMtUzYvJqs2iqHyaN');
94
+ export const MAINNET_ARIO_MINT = address('DcNnMuFxwhgV4WY1HVSaSEgr92bv2b1vUvEKiNxWqHdF');
97
95
  /**
98
96
  * AR.IO program IDs deployed on Solana devnet (staging).
99
97
  *
@@ -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
- // Always pin the priority fee (even at 0) so wallets like Phantom
40
- // don't silently *append* their own compute-budget instructions
41
- // when the transaction is missing either limit or price. That
42
- // mutation invalidates signatures already attached by paired
43
- // keypair signers (e.g. the ANT mint signer in `spawnSolanaANT`),
44
- // producing `Transaction did not pass signature verification` on
45
- // the validator. Pre-supplying both keeps the wallet from
46
- // rewriting the message, so signatures over the original bytes
47
- // still verify.
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.
@@ -14,4 +14,4 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  // AUTOMATICALLY GENERATED FILE - DO NOT TOUCH
17
- export const version = '4.0.0';
17
+ export const version = '4.0.2';
@@ -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
@@ -13,4 +13,4 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- export declare const version = "4.0.0-alpha.4";
16
+ export declare const version = "4.0.1";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ar.io/sdk",
3
- "version": "4.0.0",
3
+ "version": "4.0.2",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/ar-io/ar-io-sdk.git"