@forgedevv/core 0.1.0 → 0.3.0
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/CHANGELOG.md +227 -4
- package/README.md +4 -3
- package/dist/addresses.d.ts +73 -7
- package/dist/addresses.js +96 -5
- package/dist/claims.d.ts +43 -6
- package/dist/claims.js +75 -16
- package/dist/config.d.ts +48 -37
- package/dist/config.js +282 -52
- package/dist/constants.d.ts +16 -0
- package/dist/constants.js +20 -0
- package/dist/index.d.ts +9 -5
- package/dist/index.js +15 -4
- package/dist/jupiter-referral.d.ts +334 -0
- package/dist/jupiter-referral.js +666 -0
- package/dist/launch-metadata.d.ts +5 -1
- package/dist/launch-metadata.js +2 -0
- package/dist/meteora-referral.d.ts +119 -0
- package/dist/meteora-referral.js +188 -0
- package/dist/payments.d.ts +17 -0
- package/dist/payments.js +20 -2
- package/dist/pool.d.ts +108 -17
- package/dist/pool.js +237 -60
- package/dist/position-claims.d.ts +215 -0
- package/dist/position-claims.js +457 -0
- package/dist/priority-fee.d.ts +202 -0
- package/dist/priority-fee.js +322 -0
- package/dist/reads.d.ts +20 -0
- package/dist/reads.js +39 -2
- package/dist/settings.d.ts +73 -0
- package/dist/settings.js +119 -0
- package/dist/swap.d.ts +95 -23
- package/dist/swap.js +144 -30
- package/dist/tx.d.ts +2 -0
- package/dist/tx.js +4 -2
- package/dist/validate.d.ts +14 -1
- package/dist/validate.js +86 -6
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -3,13 +3,236 @@
|
|
|
3
3
|
All notable changes to `@forge/core`. Versions follow semantic versioning. Consumers (the
|
|
4
4
|
launchpad template, the signer, the web app) pin an exact version, never a range.
|
|
5
5
|
|
|
6
|
-
## 0.
|
|
6
|
+
## 0.3.0 — 2026-10-17
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
`node scripts/publish-core.mjs --publish`. Not published yet.
|
|
8
|
+
Changes after 0.2.0. Publish `@forgedevv/shared` 0.3.0 with it (new kill switch `revenue_paused` in `FlagKey`).
|
|
10
9
|
|
|
11
|
-
|
|
10
|
+
### Changed (Jupiter fixes)
|
|
11
|
+
|
|
12
|
+
- **Jupiter referral fee.** `FEES.jupiterIntegratorFeeBps` (re-exported from `@forge/shared`) is
|
|
13
|
+
50 bps, was 30: the Jupiter Plugin passes `referralFee` to Ultra `/order`, which refuses any
|
|
14
|
+
value outside 50..255 bps, so every swap of a graduated coin failed. Jupiter keeps 20% of it.
|
|
15
|
+
`FEES.platformFeeBps` (30 bps, `PLATFORM_FEE_BPS` on swaps built by core) is unchanged.
|
|
16
|
+
- **Jupiter referral claims.** `buildJupiterReferralClaimTx` refuses a referral account of another
|
|
17
|
+
project than Jupiter's Ultra project (`project_mismatch`; the new `expectedProject` parameter
|
|
18
|
+
overrides the default `JUPITER_ULTRA_REFERRAL_PROJECT`). A funded v2 collection account is only
|
|
19
|
+
claimed for a named referral account at the PDA `["referral", project, name]`, the only kind
|
|
20
|
+
`claim_v2` accepts: `referral_account_unnamed` or `referral_account_not_pda` otherwise (new
|
|
21
|
+
`JupiterReferralErrorCode` values; the whole build is refused). With an empty v2 account, an
|
|
22
|
+
unnamed account still claims its v1 collection account. Devnet is unchanged: any cluster but
|
|
23
|
+
mainnet-beta is still refused (`wrong_cluster`) before these reads.
|
|
24
|
+
|
|
25
|
+
### Added (Jupiter fixes)
|
|
26
|
+
|
|
27
|
+
- `JUPITER_REFERRAL_FEE_BPS_RANGE` (`{ min: 50, max: 255 }`) and
|
|
28
|
+
`assertJupiterReferralFeeBps(bps)` (constants.ts): returns a whole number of bps within the range
|
|
29
|
+
Jupiter Ultra accepts, throws a `RangeError` otherwise. The launchpad template runs the plugin
|
|
30
|
+
fee through it and fails closed outside it.
|
|
31
|
+
- `JUPITER_ULTRA_REFERRAL_PROJECT` (`DkiqsTrw1u1bYFumumC7sCG2S8K25qc2vemJFHyW2wJc`) and
|
|
32
|
+
`deriveJupiterReferralAccount(project, name, programId?)` (jupiter-referral.ts).
|
|
33
|
+
|
|
34
|
+
### Added (revenue wallet referral accounts setup)
|
|
35
|
+
|
|
36
|
+
Pure builders of the two accounts the revenue wallet must hold (docs/MAINNET.md section 5), for
|
|
37
|
+
the signer's one-off `--setup-revenue-referrals` command. Only the payer signs: neither the
|
|
38
|
+
revenue wallet nor the new accounts do.
|
|
39
|
+
|
|
40
|
+
- **`meteora-referral.ts`** (re-exported by the index): `deriveMeteoraReferralAccount(payer,
|
|
41
|
+
seed?)` (`createWithSeed(payer, seed, SPL Token)`, default seed
|
|
42
|
+
`METEORA_REFERRAL_ACCOUNT_SEED` = `forge-meteora-referral`), `buildCreateMeteoraReferralAccountIxs`
|
|
43
|
+
/ `buildCreateMeteoraReferralAccountTx({ payer, owner, seed?, rentLamports, blockhash,
|
|
44
|
+
lastValidBlockHeight, priorityFee? })`: System `createAccountWithSeed` (from = base = payer,
|
|
45
|
+
the rent of 165 bytes, SPL Token owned) then SPL Token `InitializeAccount3` (wrapped SOL,
|
|
46
|
+
owner = the revenue wallet, no owner signature), the compute budget pair first when the quote
|
|
47
|
+
has a price (`METEORA_REFERRAL_SETUP_COMPUTE_UNITS` = 30,000); `inspectMeteoraReferralAccount`
|
|
48
|
+
(pure: `absent`, `ready`, or `mismatch` with a reason: not a token account, wrong mint or owner,
|
|
49
|
+
the owner's associated account, frozen, delegated, closable by someone else) and
|
|
50
|
+
`readMeteoraReferralAccount` (any cluster); `MeteoraReferralError` (`invalid_params`).
|
|
51
|
+
- **Jupiter referral setup** (jupiter-referral.ts), verified against the program source
|
|
52
|
+
(`initialize_referral_account_with_name.rs`, `lib.rs`, `claim_v2.rs`) and the SDK 0.3.0 IDL:
|
|
53
|
+
`JUPITER_INITIALIZE_REFERRAL_ACCOUNT_WITH_NAME_DISCRIMINATOR`, `JUPITER_REFERRAL_ACCOUNT_SIZE`
|
|
54
|
+
(274), `JUPITER_REFERRAL_NAME_MAX_CHARS` (19: the program requires fewer than 20 characters)
|
|
55
|
+
and `JUPITER_REFERRAL_NAME_MAX_BYTES` (32: a PDA seed), `assertJupiterReferralName` (also
|
|
56
|
+
refuses whitespace and control characters), `encodeJupiterReferralName` (Borsh),
|
|
57
|
+
`buildJupiterInitializeReferralAccountWithNameIx({ payer, partner, project, referralAccount },
|
|
58
|
+
name)` (the IDL's accounts: payer the only signer, partner read-only and not a signer, the
|
|
59
|
+
referral account the PDA `["referral", project, name]`),
|
|
60
|
+
`buildJupiterReferralTokenAccountV2Ix({ payer, referralAccount, mint, tokenProgram })` (the v2
|
|
61
|
+
collection account `claim_v2` empties is the referral account's associated token account: an
|
|
62
|
+
idempotent creation, what the SDK's `initializeReferralTokenAccountV2` sends),
|
|
63
|
+
`buildJupiterReferralSetupTx({ payer, partner, project?, name, createReferralAccount,
|
|
64
|
+
tokenAccounts, blockhash, lastValidBlockHeight, priorityFee? })` (Ultra project by default,
|
|
65
|
+
`JUPITER_REFERRAL_SETUP_COMPUTE_UNITS` = 150,000), `inspectJupiterReferralAccount` /
|
|
66
|
+
`inspectJupiterReferralTokenAccountV2` (pure statuses with mismatch reasons: partner, project,
|
|
67
|
+
name, owner, mint) and `readJupiterReferralSetup({ connection, partner, name, mints })`
|
|
68
|
+
(mainnet-beta only, `wrong_cluster` before any read; reads the project, the mints' token
|
|
69
|
+
programs, the referral account and its collection accounts).
|
|
70
|
+
|
|
71
|
+
### Changed (revenue wallet, docs/DECISIONS.md D34)
|
|
72
|
+
|
|
73
|
+
- **New address `FORGE_REVENUE_WALLET`** (`FORGE_ADDRESS_NAMES`, `getRevenueWallet`): the
|
|
74
|
+
signer-held wallet where the non-native trading revenue lands before the signer converts it to
|
|
75
|
+
SOL and forwards it to the multisig vault. It replaces the vault as the holder of the Meteora
|
|
76
|
+
referral account and as the partner of the Jupiter referral account; the platform fee goes to
|
|
77
|
+
it too (`FORGE_PLATFORM_FEE_WALLET` must be that wallet).
|
|
78
|
+
- **Swaps.** `swapFeeAddresses` returns `revenueWallet` (was `multisigVault`), read from
|
|
79
|
+
`FORGE_REVENUE_WALLET` (optional, as before): when set, the Meteora referral token account must
|
|
80
|
+
be held by it (`REFERRAL_ACCOUNT_INVALID`, `assertReferralAccountReady(..., expectedOwner?)`)
|
|
81
|
+
and `FORGE_PLATFORM_FEE_WALLET` must be it (`PLATFORM_FEE_WALLET_MISMATCH`, checked before any
|
|
82
|
+
network call by `buildBuyTx`, `buildSellTx` and `assertSwapFeeAccountsReady`). Client sites
|
|
83
|
+
receive `NEXT_PUBLIC_FORGE_REVENUE_WALLET` instead of `NEXT_PUBLIC_FORGE_MULTISIG_VAULT`.
|
|
84
|
+
- `buildJupiterReferralClaimTx` is unchanged: `expectedPartner` is now the revenue wallet.
|
|
85
|
+
|
|
86
|
+
### Added (priority fees)
|
|
87
|
+
|
|
88
|
+
- **`priority-fee.ts`** (browser-safe, re-exported by the index): `computePriorityFee` (pure: the
|
|
89
|
+
nearest-rank `percentile` of `getRecentPrioritizationFees`, at least `floorMicroLamports`, at
|
|
90
|
+
most `maxMicroLamports` per CU and `maxLamports` for the whole transaction; an empty list or a
|
|
91
|
+
failed read prices at the floor, reported in `source`), `estimatePriorityFee` (reads the fees
|
|
92
|
+
for the transaction's writable accounts, at most `MAX_PRIORITY_FEE_ACCOUNTS` = 32),
|
|
93
|
+
`readRecentPriorityFees`, `resolvePriorityFeePolicy`, `feePercentile`, `maxPriceForBudget`,
|
|
94
|
+
`maxPriorityFeeLamports` (the worst case of a setting, to show before building),
|
|
95
|
+
`fixedPriorityFee`, `priorityFeeInstructions` (unit limit then price; `priceOnly`),
|
|
96
|
+
`writableAccountsOf`, and `checkComputeBudgetInstructions` / `ComputeBudgetCheckError` for
|
|
97
|
+
transaction policies (no account, `SetComputeUnitLimit` / `SetComputeUnitPrice` only, at most
|
|
98
|
+
one of each, bounded values and fee; without a limit the fee is counted for 1.4M CU).
|
|
99
|
+
`DEFAULT_PRIORITY_FEE_POLICY`: 75th percentile, floor 10,000 micro-lamports per CU, at most
|
|
100
|
+
1,000,000 per CU and 500,000 lamports (0.0005 SOL) per transaction; hard ceilings
|
|
101
|
+
`MAX_PRIORITY_FEE_MICRO_LAMPORTS` (10 lamports per CU) and `MAX_PRIORITY_FEE_LAMPORTS`
|
|
102
|
+
(0.01 SOL). Types `PriorityFeeSetting`, `PriorityFeePolicy`, `PriorityFeeQuote`,
|
|
103
|
+
`PriorityFeeSource`, `RecentPrioritizationFee`.
|
|
104
|
+
- **Builders accept an optional `priority` setting** (exclusive with their fixed price, if any),
|
|
105
|
+
which puts `setComputeUnitLimit` then `setComputeUnitPrice` first (after the nonce advance):
|
|
106
|
+
`buildBuyTx` / `buildSellTx` (`SwapBuildOptions.priority`; the pure `buildSwapTransaction`
|
|
107
|
+
refuses it), `buildPaymentTx` (`PaymentTxOptions.priority`, limit `PAYMENT_COMPUTE_UNITS` =
|
|
108
|
+
50,000), `buildLaunchCoinTx` and `buildUserCoinLaunchTx`, `buildCreateConfigTx`, the creator,
|
|
109
|
+
partner and pool creation fee claims (`ClaimOptions.priority`, limits `CLAIM_COMPUTE_UNITS` =
|
|
110
|
+
200,000 and `POOL_CREATION_FEE_CLAIM_COMPUTE_UNITS` = 100,000), the DAMM v2 position claim
|
|
111
|
+
(`positionClaimComputeUnits`) and `buildJupiterReferralClaimTx`
|
|
112
|
+
(`JUPITER_REFERRAL_CLAIM_COMPUTE_UNITS` = 300,000). Their results report the quote
|
|
113
|
+
(`priorityFee`), and the claim costs count the fee. `CREATE_NONCE_ACCOUNT_COMPUTE_UNITS`
|
|
114
|
+
(10,000) names the limit of the nonce account builders.
|
|
115
|
+
- **Launch sizes.** The launchpad coin launch keeps the 148-byte metadata budget: with a priority
|
|
116
|
+
fee it carries the unit limit and the price up to 136 bytes of metadata, the price alone up to
|
|
117
|
+
144 (priced for `MAX_TRANSACTION_COMPUTE_UNITS`), and no price beyond
|
|
118
|
+
(`LaunchCoinSummary.priorityFeePlacement`: `limit_and_price`, `price_only`,
|
|
119
|
+
`omitted_for_size`). A priced swap or user coin launch is 12 bytes larger.
|
|
120
|
+
|
|
121
|
+
### Changed (priority fees)
|
|
122
|
+
|
|
123
|
+
- `BuiltSwapTransaction.priorityFee`, `PaymentTxResult.priorityFee`, `CreateConfigTx.priorityFee`,
|
|
124
|
+
`ClaimSummary.priorityFee`, `PoolCreationFeeClaimSummary.priorityFee`,
|
|
125
|
+
`PositionClaimSummary.priorityFee`, `JupiterReferralClaimTx.priorityFee` and
|
|
126
|
+
`LaunchCoinSummary` / `UserCoinLaunchSummary` `.priorityFee` and `.priorityFeePlacement` are new
|
|
127
|
+
required fields: code that builds these objects itself (test fakes) must set them. Without a
|
|
128
|
+
`priority` setting every transaction is byte for byte what 0.2.0 built.
|
|
129
|
+
- `ClaimCosts.networkFeeLamports` and `PositionClaimCosts.networkFeeLamports` include the
|
|
130
|
+
priority fee (0 without a setting).
|
|
131
|
+
- Consumers: the launchpad template prices its trades, coin creations and creator fee claims with
|
|
132
|
+
the defaults, so client sites need this version, and the FORGE RPC relay must serve
|
|
133
|
+
`getRecentPrioritizationFees` (apps/web, same release).
|
|
134
|
+
|
|
135
|
+
### Added (on-chain fallback of the coin data)
|
|
136
|
+
|
|
137
|
+
- `listPoolStatesOfConfig(connection, config, options?)` (reads.ts): the decoded pools of a config
|
|
138
|
+
with the config state (`DbcPoolState[]`, sorted by pool address), from the SDK's
|
|
139
|
+
`getPoolsByConfig`; a pool whose decoded config differs is dropped. `listCoinsOfConfig` now
|
|
140
|
+
summarizes its result (unchanged output). The launchpad template lists its coins with it when
|
|
141
|
+
the Jupiter data API is unavailable (and always on devnet).
|
|
142
|
+
- `poolSpotPrice(sqrtPrice, baseDecimals, quoteDecimals = 9)` (reads.ts): display price of one
|
|
143
|
+
whole coin in whole quote tokens from the pool's Q64.64 `sqrtPrice` (same value as the SDK's
|
|
144
|
+
`getPriceFromSqrtPrice`, as a float).
|
|
145
|
+
|
|
146
|
+
## 0.2.0 — 2026-10-17
|
|
147
|
+
|
|
148
|
+
Everything below was added after 0.1.0 and published on npm on 2026-10-17 with `@forgedevv/shared` 0.2.0.
|
|
149
|
+
|
|
150
|
+
### Changed (security review)
|
|
151
|
+
|
|
152
|
+
- **On-chain configs compared field by field.** New `onchainConfigMismatches(config, kind,
|
|
153
|
+
{ spec?, owner?, poolCreationFeeLamports? })` (config.ts) compares a decoded config with the
|
|
154
|
+
parameters core builds for it: accounts, token, base fee (cliff, periods, period, reduction,
|
|
155
|
+
mode), dynamic fee, creator share, pool creation fee, first swap at the minimum fee, activation,
|
|
156
|
+
liquidity split and vesting, migration option / fee option / threshold, migration fee
|
|
157
|
+
percentages, migrated pool fee, locked vesting, token supply, start price and curve. Without a
|
|
158
|
+
spec, the spec fields are read from the config and must be values a FORGE spec can hold.
|
|
159
|
+
- `assertLaunchCoinConfig(config, owner, spec?)`: runs it (optional `spec`, recommended).
|
|
160
|
+
`BuildLaunchCoinTxParams.spec?` passes it. A coin config with a pool creation fee is now
|
|
161
|
+
`CONFIG_MISMATCH` (the current builder sets none).
|
|
162
|
+
- `assertUserCoinConfig(config, expected?)`: runs it against the launchpad config;
|
|
163
|
+
`BuildUserCoinLaunchTxParams.expectedConfig?` passes the expectation.
|
|
164
|
+
- **validate.ts pins every value-moving field to FORGE's settings**: no migration fee
|
|
165
|
+
(`MIGRATION_FEE_NOT_ALLOWED`), no locked vesting (`LOCKED_VESTING_NOT_ALLOWED`), the fixed supply
|
|
166
|
+
of `FORGE_TOKEN_SETTINGS` (`TOKEN_SUPPLY_MISMATCH`), FORGE's curve and start price
|
|
167
|
+
(`CURVE_MISMATCH`, they decide the leftover), SPL token with 6 decimals, timestamp activation,
|
|
168
|
+
and the anti-sniper schedule exactly `ANTI_SNIPER_FEE_SCHEDULE` (a flat linear fee when
|
|
169
|
+
`spec.antiSniper` is off): an exponential schedule, another starting fee or one 300 s period at
|
|
170
|
+
99% are refused.
|
|
171
|
+
- The fixed settings moved to `settings.ts` (re-exported by config.ts, unchanged values), with
|
|
172
|
+
`FORGE_TOKEN_SUPPLY_RAW`, `forgeFeeSchedulerParam`, `forgeBaseFee`, `forgeReferenceCurve`.
|
|
173
|
+
`curveParamsFor`, `creatorTradingFeePercentageFor` and `poolCreationFeeSolFor` accept just the
|
|
174
|
+
spec fields they read (`ConfigSpecFields`); a full `LaunchpadSpec` still fits.
|
|
175
|
+
- **Platform fee on a user coin's first buy.** `buildUserCoinLaunchTx` adds ONE SystemProgram
|
|
176
|
+
transfer of `platformFeeLamports(firstBuyLamports)` (30 bps, rounded up) to
|
|
177
|
+
`FORGE_PLATFORM_FEE_WALLET` (read from `env`), as the last instruction; `chargePlatformFee:
|
|
178
|
+
false` turns it off. The wallet must be rent-exempt (`PLATFORM_FEE_WALLET_NOT_READY`). The
|
|
179
|
+
summary gains `platformFeeLamports` and `platformFeeWallet`; `LaunchCoinCosts.platformFeeLamports`
|
|
180
|
+
(optional) is set and counted in `ownerTotalLamports`.
|
|
181
|
+
- **Swaps.** `MAX_SWAP_SLIPPAGE_BPS` is 2,500 (25%, was 50%). `buildBuyTx`, `buildSellTx`,
|
|
182
|
+
`quoteSwap`, `fetchSwapContext` and `fetchSwapPoolState` take an optional `allowedConfigs`: a
|
|
183
|
+
pool whose on-chain config is not listed is refused (`POOL_NOT_ALLOWED`) before its config is
|
|
184
|
+
read. The builders now require the platform fee wallet to be exactly `FORGE_PLATFORM_FEE_WALLET`
|
|
185
|
+
and a system account (`PLATFORM_FEE_WALLET_MISMATCH`), and, when the environment has
|
|
186
|
+
`FORGE_MULTISIG_VAULT`, the Meteora referral token account to be held by it
|
|
187
|
+
(`REFERRAL_ACCOUNT_INVALID`). `buildSwapTransaction(ctx, request, expected?)`,
|
|
188
|
+
`assertPlatformFeeWalletReady(..., expectedWallet?)`, `assertReferralAccountReady(...,
|
|
189
|
+
expectedOwner?)`, new `assertPoolConfigAllowed`, `readOptionalAddress` (addresses.ts);
|
|
190
|
+
`swapFeeAddresses` also returns `multisigVault`.
|
|
12
191
|
- `checkPaymentTransaction` / `verifyPayment`: `transferLamports` on `amount_mismatch` when the transfer amount differs.
|
|
192
|
+
- Jupiter referral fee claim (`jupiter-referral.ts`, mainnet-beta only): `buildJupiterReferralClaimTx`
|
|
193
|
+
reads the referral account, its project and the two collection accounts of a mint (classic
|
|
194
|
+
`referral_ata` PDA and the referral account's associated token account) and builds the
|
|
195
|
+
permissionless `claim` / `claim_v2` instructions to the referral account's partner (the FORGE
|
|
196
|
+
multisig vault, asserted with `expectedPartner`). Raw instructions from the referral program IDL
|
|
197
|
+
(no Anchor dependency), with the pure pieces exported (`decodeJupiterReferralAccount`,
|
|
198
|
+
`decodeJupiterProject`, `deriveJupiterReferralTokenAccount[V2]`, `buildJupiterReferralClaimIx`,
|
|
199
|
+
`buildJupiterCreateAdminTokenAccountIx`). Any cluster but mainnet-beta is refused
|
|
200
|
+
(`JupiterReferralError` `wrong_cluster`). The summary also carries the project's `admin` and
|
|
201
|
+
`projectAuthority`, so a caller can pin every account of the built claim.
|
|
202
|
+
- Squads accounts of the buyback read in addresses.ts (PLANEXECUTE rule 7): `FORGE_SQUADS_MULTISIG`
|
|
203
|
+
and `FORGE_SQUADS_SPENDING_LIMIT` join `FORGE_ADDRESS_NAMES` as optional names;
|
|
204
|
+
`readSquadsAddresses(env)` returns them with `FORGE_SQUADS_VAULT_INDEX` (default 0) or `null`
|
|
205
|
+
when both are absent, and refuses half a configuration, an index without them, an index outside
|
|
206
|
+
0..255 or a spending limit equal to the multisig (`ForgeSquadsConfigError`). Deriving the vault
|
|
207
|
+
needs the Squads program id: the signer keeps that check.
|
|
208
|
+
|
|
209
|
+
### Added (DAMM v2 position fee claims)
|
|
210
|
+
|
|
211
|
+
- `position-claims.ts`: after a launchpad coin migrates, the FORGE creator wallet keeps a
|
|
212
|
+
permanently locked DAMM v2 position that earns the migrated pool's trading fees.
|
|
213
|
+
`buildCreatorPositionFeeClaimTx` builds the unsigned `claim_position_fee` of the creator's
|
|
214
|
+
position(s) to a receiver (`buildForgeCreatorPositionFeeClaimTx`: the multisig vault), creator
|
|
215
|
+
signing, optional fee payer: coin fees to the receiver's associated account, SOL fees to the
|
|
216
|
+
creator's temporary WSOL account closed to the receiver (fees plus rent as lamports). The
|
|
217
|
+
transaction never removes liquidity nor closes, locks or transfers the position or its NFT.
|
|
218
|
+
Summary, costs (`PositionClaimCosts`), skip reasons (`no_position`, `nothing_to_claim`,
|
|
219
|
+
`not_worthwhile`), `isPositionClaimWorthwhile`. Pure helpers: `migratedDammV2Pool` (the DAMM v2
|
|
220
|
+
pool of a migrated DBC pool, derived like the SDK migration), `positionPendingFees`,
|
|
221
|
+
`summarizePosition`, `sumPendingFees`; reads: `findCreatorDammV2Positions` (the creator's
|
|
222
|
+
positions, NFT ownership re-checked), `getDammV2PoolState`. Constants for policies:
|
|
223
|
+
`DAMM_V2_PROGRAM_ID`, `CLAIM_POSITION_FEE_DISCRIMINATOR`, `CLAIM_POSITION_FEE_ACCOUNTS`.
|
|
224
|
+
New `ClaimError` codes: `not_migrated`, `damm_pool_not_found`, `damm_pool_mismatch`,
|
|
225
|
+
`position_not_found`, `position_mismatch`, `position_not_owned`.
|
|
226
|
+
- Dependency: `@meteora-ag/cp-amm-sdk` 1.5.1 (exact pin, like the DBC SDK).
|
|
227
|
+
- Fixtures: `__fixtures__/cp-amm-devnet-accounts.json`, the devnet test 2 migration captured
|
|
228
|
+
read-only (`scripts/devnet-tests` `fixtures:cp-amm`).
|
|
229
|
+
|
|
230
|
+
## 0.1.0 — 2026-10-14
|
|
231
|
+
|
|
232
|
+
First version published on npm as `@forgedevv/core` (with `@forgedevv/shared`), through
|
|
233
|
+
`node scripts/publish-core.mjs --publish`.
|
|
234
|
+
|
|
235
|
+
- `listCoinsOfCreator` (creator pools through SDK `getPoolsByCreator`), `DBC_POOL_CREATOR_OFFSET`, `DBC_POOL_CONFIG_OFFSET`.
|
|
13
236
|
|
|
14
237
|
### Changed (wave 5 review)
|
|
15
238
|
|
package/README.md
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# @forgedevv/core
|
|
2
2
|
|
|
3
3
|
The FORGE transaction core: it builds the Meteora Dynamic Bonding Curve configs, the launchpad coin
|
|
4
|
-
launch, buys and sells with the FORGE platform fee and referral, creator fee claims
|
|
5
|
-
and the
|
|
6
|
-
returns it **unsigned**: the
|
|
4
|
+
launch, buys and sells with the FORGE platform fee and referral, creator fee claims (bonding curve
|
|
5
|
+
share, and the DAMM v2 position fees of a migrated pool), payment checks and the read helpers used
|
|
6
|
+
by FORGE launchpad sites. Every function that builds a transaction returns it **unsigned**: the
|
|
7
|
+
user signs in their wallet.
|
|
7
8
|
|
|
8
9
|
Inside the FORGE monorepo this package is `@forge/core`. It is published on the public npm registry
|
|
9
10
|
as `@forgedevv/core` (with its contracts package `@forgedevv/shared`), and client projects install
|
package/dist/addresses.d.ts
CHANGED
|
@@ -9,17 +9,26 @@
|
|
|
9
9
|
* Validation choice: a value is valid when the `PublicKey` constructor accepts it (base58 that
|
|
10
10
|
* decodes to exactly 32 bytes) and it re-encodes to the same string. Being on the ed25519 curve is
|
|
11
11
|
* NOT required, because some of these addresses are token accounts or PDAs (e.g. the Meteora
|
|
12
|
-
* referral account, which is a WSOL token account held by the
|
|
12
|
+
* referral account, which is a WSOL token account held by the revenue wallet, or a Squads vault
|
|
13
|
+
* PDA).
|
|
14
|
+
*
|
|
15
|
+
* The revenue wallet (`FORGE_REVENUE_WALLET`, docs/DECISIONS.md D34) is the signer-held wallet
|
|
16
|
+
* where the non-native trading revenue lands: the platform fee (`FORGE_PLATFORM_FEE_WALLET` must
|
|
17
|
+
* be that wallet), the Meteora referral WSOL account it holds, and the Jupiter referral claims
|
|
18
|
+
* (it is the referral account's partner). The signer converts and forwards it to the vault.
|
|
13
19
|
* The all-zero key (`11111111111111111111111111111111`, the System Program) is rejected: fees
|
|
14
20
|
* sent there would be lost.
|
|
15
21
|
*
|
|
16
22
|
* Error messages list variable names only, never values.
|
|
17
23
|
*/
|
|
18
24
|
import { PublicKey } from '@solana/web3.js';
|
|
19
|
-
export declare const FORGE_ADDRESS_NAMES: readonly ["FORGE_MULTISIG_VAULT", "FORGE_METEORA_REFERRAL_ACCOUNT", "FORGE_PLATFORM_FEE_WALLET", "FORGE_JUPITER_REFERRAL_ACCOUNT", "FORGE_CASHBOX_WALLET", "FORGE_MINT"];
|
|
25
|
+
export declare const FORGE_ADDRESS_NAMES: readonly ["FORGE_MULTISIG_VAULT", "FORGE_METEORA_REFERRAL_ACCOUNT", "FORGE_PLATFORM_FEE_WALLET", "FORGE_REVENUE_WALLET", "FORGE_JUPITER_REFERRAL_ACCOUNT", "FORGE_CASHBOX_WALLET", "FORGE_MINT", "FORGE_SQUADS_MULTISIG", "FORGE_SQUADS_SPENDING_LIMIT"];
|
|
20
26
|
export type ForgeAddressName = (typeof FORGE_ADDRESS_NAMES)[number];
|
|
21
|
-
/**
|
|
22
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Addresses that may be absent. `FORGE_MINT` is absent before the $FORGE launch; the Squads
|
|
29
|
+
* accounts are absent while the buyback stays in simulation (see `readSquadsAddresses`).
|
|
30
|
+
*/
|
|
31
|
+
export declare const OPTIONAL_FORGE_ADDRESS_NAMES: readonly ["FORGE_MINT", "FORGE_SQUADS_MULTISIG", "FORGE_SQUADS_SPENDING_LIMIT"];
|
|
23
32
|
export type OptionalForgeAddressName = (typeof OPTIONAL_FORGE_ADDRESS_NAMES)[number];
|
|
24
33
|
/** Environment object to read from (defaults to `process.env`; injectable for tests). */
|
|
25
34
|
export type AddressEnv = Readonly<Record<string, string | undefined>>;
|
|
@@ -41,15 +50,72 @@ export declare class ForgeAddressError extends Error {
|
|
|
41
50
|
* @throws ForgeAddressError listing the missing and invalid names (never the values).
|
|
42
51
|
*/
|
|
43
52
|
export declare function requireAddresses<N extends ForgeAddressName>(names: readonly N[], env?: AddressEnv): ForgeAddresses<N>;
|
|
44
|
-
/**
|
|
53
|
+
/**
|
|
54
|
+
* One FORGE address when it is set, `null` when it is absent or empty. A value that is set but is
|
|
55
|
+
* not a valid public key is refused, exactly as `requireAddresses` does. For checks that run
|
|
56
|
+
* wherever the address is known and are skipped elsewhere (e.g. the owner of the Meteora referral
|
|
57
|
+
* account, `FORGE_REVENUE_WALLET`, in a browser that was not given it).
|
|
58
|
+
*
|
|
59
|
+
* @throws ForgeAddressError (invalid value; names only).
|
|
60
|
+
*/
|
|
61
|
+
export declare function readOptionalAddress(name: ForgeAddressName, env?: AddressEnv): PublicKey | null;
|
|
62
|
+
/**
|
|
63
|
+
* Squads multisig vault: receives the creator fees, the cashbox sweeps and the revenue wallet's
|
|
64
|
+
* forwards (the converted trading revenue).
|
|
65
|
+
*/
|
|
45
66
|
export declare function getMultisigVault(env?: AddressEnv): PublicKey;
|
|
46
|
-
/** Meteora referral token account (WSOL, held by the
|
|
67
|
+
/** Meteora referral token account (WSOL, held by the revenue wallet), passed as `referralTokenAccount`. */
|
|
47
68
|
export declare function getMeteoraReferralAccount(env?: AddressEnv): PublicKey;
|
|
48
|
-
/**
|
|
69
|
+
/**
|
|
70
|
+
* Wallet receiving the 0.3% platform fee on swaps built by @forge/core: the revenue wallet
|
|
71
|
+
* (`FORGE_REVENUE_WALLET`, D34). Kept as its own variable so the fee destination stays explicit;
|
|
72
|
+
* `swapFeeAddresses` refuses an environment where the two differ.
|
|
73
|
+
*/
|
|
49
74
|
export declare function getPlatformFeeWallet(env?: AddressEnv): PublicKey;
|
|
75
|
+
/**
|
|
76
|
+
* Revenue wallet (D34): held by the signer (keystore role `revenue`), it receives the platform
|
|
77
|
+
* fee, holds the Meteora referral WSOL account and is the partner of the Jupiter referral
|
|
78
|
+
* account. The signer regularly converts what it holds to SOL and forwards it to the vault.
|
|
79
|
+
*/
|
|
80
|
+
export declare function getRevenueWallet(env?: AddressEnv): PublicKey;
|
|
50
81
|
/** Jupiter referral account (integrator fee after graduation). */
|
|
51
82
|
export declare function getJupiterReferralAccount(env?: AddressEnv): PublicKey;
|
|
52
83
|
/** Cashbox wallet (held by the signer) receiving client payments. */
|
|
53
84
|
export declare function getCashboxWallet(env?: AddressEnv): PublicKey;
|
|
54
85
|
/** $FORGE mint, or `null` before the $FORGE launch (token-gating off, buyback simulated). */
|
|
55
86
|
export declare function getForgeMint(env?: AddressEnv): PublicKey | null;
|
|
87
|
+
/** Squads v4 accounts the buyback withdraws through, read from the environment. */
|
|
88
|
+
export interface SquadsAddresses {
|
|
89
|
+
/** FORGE_SQUADS_MULTISIG: the multisig account. */
|
|
90
|
+
multisig: PublicKey;
|
|
91
|
+
/** FORGE_SQUADS_SPENDING_LIMIT: the spending limit account of the buyback wallet. */
|
|
92
|
+
spendingLimit: PublicKey;
|
|
93
|
+
/** FORGE_SQUADS_VAULT_INDEX (default 0): the vault index of the treasury vault. */
|
|
94
|
+
vaultIndex: number;
|
|
95
|
+
}
|
|
96
|
+
export type SquadsAddressProblem =
|
|
97
|
+
/** One of the two addresses without the other. */
|
|
98
|
+
'incomplete'
|
|
99
|
+
/** FORGE_SQUADS_VAULT_INDEX other than the default 0 without the addresses. */
|
|
100
|
+
| 'index_without_multisig'
|
|
101
|
+
/** FORGE_SQUADS_VAULT_INDEX is not an integer between 0 and 255. */
|
|
102
|
+
| 'invalid_index'
|
|
103
|
+
/** The spending limit account is the multisig account. */
|
|
104
|
+
| 'not_distinct';
|
|
105
|
+
/** Thrown by `readSquadsAddresses` on a rule the names alone cannot express. Names only. */
|
|
106
|
+
export declare class ForgeSquadsConfigError extends Error {
|
|
107
|
+
readonly problem: SquadsAddressProblem;
|
|
108
|
+
constructor(problem: SquadsAddressProblem, message: string);
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* FORGE_SQUADS_MULTISIG, FORGE_SQUADS_SPENDING_LIMIT and FORGE_SQUADS_VAULT_INDEX. Returns `null`
|
|
112
|
+
* when both addresses are absent (no withdrawer: the buyback stays in simulation). Rules: the
|
|
113
|
+
* two addresses are set together or not at all; an index other than the default `0` needs them
|
|
114
|
+
* (a lone `0` is the default spelled out, not a configuration); the index is an integer between
|
|
115
|
+
* 0 and 255 (default 0); the spending limit is a distinct account. Deriving the vault from the
|
|
116
|
+
* multisig and the index, and comparing it with FORGE_MULTISIG_VAULT, needs the Squads program
|
|
117
|
+
* id (pinned SDK): the caller (the signer) does it.
|
|
118
|
+
*
|
|
119
|
+
* @throws ForgeAddressError (invalid address, names only), ForgeSquadsConfigError (other rules).
|
|
120
|
+
*/
|
|
121
|
+
export declare function readSquadsAddresses(env?: AddressEnv): SquadsAddresses | null;
|
package/dist/addresses.js
CHANGED
|
@@ -9,7 +9,13 @@
|
|
|
9
9
|
* Validation choice: a value is valid when the `PublicKey` constructor accepts it (base58 that
|
|
10
10
|
* decodes to exactly 32 bytes) and it re-encodes to the same string. Being on the ed25519 curve is
|
|
11
11
|
* NOT required, because some of these addresses are token accounts or PDAs (e.g. the Meteora
|
|
12
|
-
* referral account, which is a WSOL token account held by the
|
|
12
|
+
* referral account, which is a WSOL token account held by the revenue wallet, or a Squads vault
|
|
13
|
+
* PDA).
|
|
14
|
+
*
|
|
15
|
+
* The revenue wallet (`FORGE_REVENUE_WALLET`, docs/DECISIONS.md D34) is the signer-held wallet
|
|
16
|
+
* where the non-native trading revenue lands: the platform fee (`FORGE_PLATFORM_FEE_WALLET` must
|
|
17
|
+
* be that wallet), the Meteora referral WSOL account it holds, and the Jupiter referral claims
|
|
18
|
+
* (it is the referral account's partner). The signer converts and forwards it to the vault.
|
|
13
19
|
* The all-zero key (`11111111111111111111111111111111`, the System Program) is rejected: fees
|
|
14
20
|
* sent there would be lost.
|
|
15
21
|
*
|
|
@@ -20,13 +26,21 @@ export const FORGE_ADDRESS_NAMES = [
|
|
|
20
26
|
'FORGE_MULTISIG_VAULT',
|
|
21
27
|
'FORGE_METEORA_REFERRAL_ACCOUNT',
|
|
22
28
|
'FORGE_PLATFORM_FEE_WALLET',
|
|
29
|
+
'FORGE_REVENUE_WALLET',
|
|
23
30
|
'FORGE_JUPITER_REFERRAL_ACCOUNT',
|
|
24
31
|
'FORGE_CASHBOX_WALLET',
|
|
25
32
|
'FORGE_MINT',
|
|
33
|
+
'FORGE_SQUADS_MULTISIG',
|
|
34
|
+
'FORGE_SQUADS_SPENDING_LIMIT',
|
|
26
35
|
];
|
|
27
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* Addresses that may be absent. `FORGE_MINT` is absent before the $FORGE launch; the Squads
|
|
38
|
+
* accounts are absent while the buyback stays in simulation (see `readSquadsAddresses`).
|
|
39
|
+
*/
|
|
28
40
|
export const OPTIONAL_FORGE_ADDRESS_NAMES = [
|
|
29
41
|
'FORGE_MINT',
|
|
42
|
+
'FORGE_SQUADS_MULTISIG',
|
|
43
|
+
'FORGE_SQUADS_SPENDING_LIMIT',
|
|
30
44
|
];
|
|
31
45
|
/** Thrown when required addresses are missing or invalid. Holds names only, never values. */
|
|
32
46
|
export class ForgeAddressError extends Error {
|
|
@@ -101,18 +115,47 @@ export function requireAddresses(names, env = defaultEnv()) {
|
|
|
101
115
|
throw new ForgeAddressError(missing, invalid);
|
|
102
116
|
return result;
|
|
103
117
|
}
|
|
104
|
-
/**
|
|
118
|
+
/**
|
|
119
|
+
* One FORGE address when it is set, `null` when it is absent or empty. A value that is set but is
|
|
120
|
+
* not a valid public key is refused, exactly as `requireAddresses` does. For checks that run
|
|
121
|
+
* wherever the address is known and are skipped elsewhere (e.g. the owner of the Meteora referral
|
|
122
|
+
* account, `FORGE_REVENUE_WALLET`, in a browser that was not given it).
|
|
123
|
+
*
|
|
124
|
+
* @throws ForgeAddressError (invalid value; names only).
|
|
125
|
+
*/
|
|
126
|
+
export function readOptionalAddress(name, env = defaultEnv()) {
|
|
127
|
+
const value = env[name];
|
|
128
|
+
if (value === undefined || value === '')
|
|
129
|
+
return null;
|
|
130
|
+
return requireAddresses([name], env)[name];
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Squads multisig vault: receives the creator fees, the cashbox sweeps and the revenue wallet's
|
|
134
|
+
* forwards (the converted trading revenue).
|
|
135
|
+
*/
|
|
105
136
|
export function getMultisigVault(env) {
|
|
106
137
|
return requireAddresses(['FORGE_MULTISIG_VAULT'], env).FORGE_MULTISIG_VAULT;
|
|
107
138
|
}
|
|
108
|
-
/** Meteora referral token account (WSOL, held by the
|
|
139
|
+
/** Meteora referral token account (WSOL, held by the revenue wallet), passed as `referralTokenAccount`. */
|
|
109
140
|
export function getMeteoraReferralAccount(env) {
|
|
110
141
|
return requireAddresses(['FORGE_METEORA_REFERRAL_ACCOUNT'], env).FORGE_METEORA_REFERRAL_ACCOUNT;
|
|
111
142
|
}
|
|
112
|
-
/**
|
|
143
|
+
/**
|
|
144
|
+
* Wallet receiving the 0.3% platform fee on swaps built by @forge/core: the revenue wallet
|
|
145
|
+
* (`FORGE_REVENUE_WALLET`, D34). Kept as its own variable so the fee destination stays explicit;
|
|
146
|
+
* `swapFeeAddresses` refuses an environment where the two differ.
|
|
147
|
+
*/
|
|
113
148
|
export function getPlatformFeeWallet(env) {
|
|
114
149
|
return requireAddresses(['FORGE_PLATFORM_FEE_WALLET'], env).FORGE_PLATFORM_FEE_WALLET;
|
|
115
150
|
}
|
|
151
|
+
/**
|
|
152
|
+
* Revenue wallet (D34): held by the signer (keystore role `revenue`), it receives the platform
|
|
153
|
+
* fee, holds the Meteora referral WSOL account and is the partner of the Jupiter referral
|
|
154
|
+
* account. The signer regularly converts what it holds to SOL and forwards it to the vault.
|
|
155
|
+
*/
|
|
156
|
+
export function getRevenueWallet(env) {
|
|
157
|
+
return requireAddresses(['FORGE_REVENUE_WALLET'], env).FORGE_REVENUE_WALLET;
|
|
158
|
+
}
|
|
116
159
|
/** Jupiter referral account (integrator fee after graduation). */
|
|
117
160
|
export function getJupiterReferralAccount(env) {
|
|
118
161
|
return requireAddresses(['FORGE_JUPITER_REFERRAL_ACCOUNT'], env).FORGE_JUPITER_REFERRAL_ACCOUNT;
|
|
@@ -125,3 +168,51 @@ export function getCashboxWallet(env) {
|
|
|
125
168
|
export function getForgeMint(env) {
|
|
126
169
|
return requireAddresses(['FORGE_MINT'], env).FORGE_MINT;
|
|
127
170
|
}
|
|
171
|
+
/** Thrown by `readSquadsAddresses` on a rule the names alone cannot express. Names only. */
|
|
172
|
+
export class ForgeSquadsConfigError extends Error {
|
|
173
|
+
problem;
|
|
174
|
+
constructor(problem, message) {
|
|
175
|
+
super(message);
|
|
176
|
+
this.name = 'ForgeSquadsConfigError';
|
|
177
|
+
this.problem = problem;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
const VAULT_INDEX_RE = /^(0|[1-9][0-9]?|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/;
|
|
181
|
+
/**
|
|
182
|
+
* FORGE_SQUADS_MULTISIG, FORGE_SQUADS_SPENDING_LIMIT and FORGE_SQUADS_VAULT_INDEX. Returns `null`
|
|
183
|
+
* when both addresses are absent (no withdrawer: the buyback stays in simulation). Rules: the
|
|
184
|
+
* two addresses are set together or not at all; an index other than the default `0` needs them
|
|
185
|
+
* (a lone `0` is the default spelled out, not a configuration); the index is an integer between
|
|
186
|
+
* 0 and 255 (default 0); the spending limit is a distinct account. Deriving the vault from the
|
|
187
|
+
* multisig and the index, and comparing it with FORGE_MULTISIG_VAULT, needs the Squads program
|
|
188
|
+
* id (pinned SDK): the caller (the signer) does it.
|
|
189
|
+
*
|
|
190
|
+
* @throws ForgeAddressError (invalid address, names only), ForgeSquadsConfigError (other rules).
|
|
191
|
+
*/
|
|
192
|
+
export function readSquadsAddresses(env = defaultEnv()) {
|
|
193
|
+
const multisigRaw = env.FORGE_SQUADS_MULTISIG ?? '';
|
|
194
|
+
const limitRaw = env.FORGE_SQUADS_SPENDING_LIMIT ?? '';
|
|
195
|
+
const indexRaw = env.FORGE_SQUADS_VAULT_INDEX ?? '';
|
|
196
|
+
if (multisigRaw === '' && limitRaw === '') {
|
|
197
|
+
if (indexRaw !== '' && indexRaw !== '0') {
|
|
198
|
+
throw new ForgeSquadsConfigError('index_without_multisig', 'FORGE_SQUADS_VAULT_INDEX needs FORGE_SQUADS_MULTISIG');
|
|
199
|
+
}
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
if (multisigRaw === '' || limitRaw === '') {
|
|
203
|
+
throw new ForgeSquadsConfigError('incomplete', 'FORGE_SQUADS_MULTISIG and FORGE_SQUADS_SPENDING_LIMIT must be set together');
|
|
204
|
+
}
|
|
205
|
+
const multisig = readOptionalAddress('FORGE_SQUADS_MULTISIG', env);
|
|
206
|
+
const spendingLimit = readOptionalAddress('FORGE_SQUADS_SPENDING_LIMIT', env);
|
|
207
|
+
let vaultIndex = 0;
|
|
208
|
+
if (indexRaw !== '') {
|
|
209
|
+
if (!VAULT_INDEX_RE.test(indexRaw)) {
|
|
210
|
+
throw new ForgeSquadsConfigError('invalid_index', 'FORGE_SQUADS_VAULT_INDEX must be an integer between 0 and 255');
|
|
211
|
+
}
|
|
212
|
+
vaultIndex = Number(indexRaw);
|
|
213
|
+
}
|
|
214
|
+
if (spendingLimit.equals(multisig)) {
|
|
215
|
+
throw new ForgeSquadsConfigError('not_distinct', 'FORGE_SQUADS_SPENDING_LIMIT must be a distinct account');
|
|
216
|
+
}
|
|
217
|
+
return { multisig, spendingLimit, vaultIndex };
|
|
218
|
+
}
|
package/dist/claims.d.ts
CHANGED
|
@@ -1,10 +1,19 @@
|
|
|
1
|
-
import { PublicKey, Transaction, type Commitment, type Connection } from '@solana/web3.js';
|
|
1
|
+
import { PublicKey, Transaction, type Commitment, type Connection, type TransactionInstruction } from '@solana/web3.js';
|
|
2
2
|
import { type AddressEnv } from './addresses.js';
|
|
3
|
-
import { type
|
|
4
|
-
|
|
3
|
+
import { type PriorityFeeQuote, type PriorityFeeSetting } from './priority-fee.js';
|
|
4
|
+
import { type DbcPoolState, type RetryOptions, type TokenAmounts } from './reads.js';
|
|
5
|
+
/** Base fee per signature (lamports); a priority fee comes on top with `ClaimOptions.priority`. */
|
|
5
6
|
export declare const CLAIM_LAMPORTS_PER_SIGNATURE = 5000n;
|
|
7
|
+
/**
|
|
8
|
+
* Compute unit limit of a trading fee claim with a priority fee: two idempotent token account
|
|
9
|
+
* creations (about 25,000 CU each when they create), the DBC claim (two token transfers and its
|
|
10
|
+
* event), a token self-transfer, a close and a SOL transfer, about 100,000 CU at most: 2x margin.
|
|
11
|
+
*/
|
|
12
|
+
export declare const CLAIM_COMPUTE_UNITS = 200000;
|
|
13
|
+
/** Compute unit limit of a pool creation fee claim (one DBC instruction moving lamports). */
|
|
14
|
+
export declare const POOL_CREATION_FEE_CLAIM_COMPUTE_UNITS = 100000;
|
|
6
15
|
export { PARTNER_POOL_CREATION_FEE_CLAIMED_BIT, partnerPoolCreationFeeShare } from './reads.js';
|
|
7
|
-
export type ClaimErrorCode = 'not_pool_creator' | 'not_fee_claimer' | 'unsupported_quote_mint' | 'invalid_receiver' | 'receiver_mismatch' | 'receiver_not_rent_exempt' | 'claimer_wsol_not_empty' | 'unexpected_sdk_instructions';
|
|
16
|
+
export type ClaimErrorCode = 'not_pool_creator' | 'not_fee_claimer' | 'unsupported_quote_mint' | 'invalid_receiver' | 'receiver_mismatch' | 'receiver_not_rent_exempt' | 'claimer_wsol_not_empty' | 'unexpected_sdk_instructions' | 'not_migrated' | 'damm_pool_not_found' | 'damm_pool_mismatch' | 'position_not_found' | 'position_mismatch' | 'position_not_owned';
|
|
8
17
|
export declare class ClaimError extends Error {
|
|
9
18
|
readonly code: ClaimErrorCode;
|
|
10
19
|
constructor(code: ClaimErrorCode, message: string);
|
|
@@ -12,7 +21,7 @@ export declare class ClaimError extends Error {
|
|
|
12
21
|
export type ClaimKind = 'creator' | 'partner';
|
|
13
22
|
/** Lamport costs of a trading fee claim, as bigint. */
|
|
14
23
|
export interface ClaimCosts {
|
|
15
|
-
/** Signature fees (signers x 5000 lamports
|
|
24
|
+
/** Signature fees (signers x 5000 lamports) plus the priority fee, if any; paid by the payer. */
|
|
16
25
|
networkFeeLamports: bigint;
|
|
17
26
|
/**
|
|
18
27
|
* Rent of the receiver's coin account, created on the first claim of a pool (paid by the payer,
|
|
@@ -43,6 +52,12 @@ export interface ClaimSummary {
|
|
|
43
52
|
*/
|
|
44
53
|
receiverQuoteLamports: bigint;
|
|
45
54
|
quoteIsExact: boolean;
|
|
55
|
+
/**
|
|
56
|
+
* WSOL the claimer's temporary account already held when the transaction was built and that
|
|
57
|
+
* the close hands to the receiver (counted in `receiverQuoteLamports`). Zero when the account
|
|
58
|
+
* is empty or new, and when the close returns it to a claimer paying its own claim.
|
|
59
|
+
*/
|
|
60
|
+
existingWsolLamports: bigint;
|
|
46
61
|
/** Zero costs when there is no transaction. */
|
|
47
62
|
costs: ClaimCosts;
|
|
48
63
|
/**
|
|
@@ -50,6 +65,8 @@ export interface ClaimSummary {
|
|
|
50
65
|
* costs are paid (negative when it costs more than it collects). Base tokens are not valued.
|
|
51
66
|
*/
|
|
52
67
|
netLamports: bigint;
|
|
68
|
+
/** The priority fee of the transaction (price, fee, cap), or null without one. */
|
|
69
|
+
priorityFee: PriorityFeeQuote | null;
|
|
53
70
|
}
|
|
54
71
|
export type ClaimSkipReason = 'nothing_to_claim' | 'not_worthwhile';
|
|
55
72
|
export interface ClaimTxResult {
|
|
@@ -69,7 +86,21 @@ export interface ClaimOptions {
|
|
|
69
86
|
* than this many lamports (see `isClaimWorthwhile`). Default: never skip a non-empty claim.
|
|
70
87
|
*/
|
|
71
88
|
minNetLamports?: bigint;
|
|
89
|
+
/**
|
|
90
|
+
* Priority fee read from the cluster for the claim's writable accounts, bounded by this setting
|
|
91
|
+
* (`{}` = `DEFAULT_PRIORITY_FEE_POLICY`, at most 0.0005 SOL). Default: none.
|
|
92
|
+
*/
|
|
93
|
+
priority?: PriorityFeeSetting;
|
|
72
94
|
}
|
|
95
|
+
/** Checks `options.priority` before any network call. @throws RangeError. */
|
|
96
|
+
export declare function assertClaimPriority(options: {
|
|
97
|
+
priority?: PriorityFeeSetting;
|
|
98
|
+
}): void;
|
|
99
|
+
/** The priced compute budget of a claim, or nothing without `priority`. */
|
|
100
|
+
export declare function claimPriorityFee(connection: Connection, instructions: readonly TransactionInstruction[], computeUnitLimit: number, priority: PriorityFeeSetting | undefined): Promise<{
|
|
101
|
+
quote: PriorityFeeQuote | null;
|
|
102
|
+
instructions: TransactionInstruction[];
|
|
103
|
+
}>;
|
|
73
104
|
export interface CreatorClaimParams {
|
|
74
105
|
pool: PublicKey;
|
|
75
106
|
/** Pool creator (must match the pool state); signs the claim. */
|
|
@@ -100,6 +131,10 @@ export declare function minimumWorthwhileClaimLamports(costs: ClaimCosts, minNet
|
|
|
100
131
|
* callers skip claims below it. Base tokens are not valued (FORGE configs collect SOL fees only).
|
|
101
132
|
*/
|
|
102
133
|
export declare function isClaimWorthwhile(summary: ClaimSummary, minNetLamports?: bigint): boolean;
|
|
134
|
+
/** @throws ClaimError `unsupported_quote_mint` unless the pool is quoted in SOL. */
|
|
135
|
+
export declare function assertSolQuotedPool(state: DbcPoolState): void;
|
|
136
|
+
/** @throws ClaimError `invalid_receiver` for anything but a usable wallet address. */
|
|
137
|
+
export declare function assertClaimReceiver(receiver: PublicKey): void;
|
|
103
138
|
/**
|
|
104
139
|
* Builds the creator claim of `pool` to `receiver` (see the module comment for the transaction).
|
|
105
140
|
* @throws ClaimError when `creator` is not the pool creator, the pool is not SOL-quoted, the
|
|
@@ -153,10 +188,12 @@ export interface PoolCreationFeeClaimSummary {
|
|
|
153
188
|
alreadyClaimed: boolean;
|
|
154
189
|
/** SOL the receiver gets from the transaction (0 when there is none), lamports. */
|
|
155
190
|
claimableLamports: bigint;
|
|
156
|
-
/** Signature fees of the transaction (0 when there is none)
|
|
191
|
+
/** Signature fees plus the priority fee of the transaction (0 when there is none). */
|
|
157
192
|
networkFeeLamports: bigint;
|
|
158
193
|
/** `claimableLamports - networkFeeLamports` (0 when there is no transaction). */
|
|
159
194
|
netLamports: bigint;
|
|
195
|
+
/** The priority fee of the transaction (price, fee, cap), or null without one. */
|
|
196
|
+
priorityFee: PriorityFeeQuote | null;
|
|
160
197
|
}
|
|
161
198
|
export type PoolCreationFeeSkipReason = 'no_pool_creation_fee' | 'already_claimed';
|
|
162
199
|
export interface PoolCreationFeeClaimTxResult {
|