pangu-sdk 0.1.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/dist/dbc.d.mts ADDED
@@ -0,0 +1,505 @@
1
+ import { PublicKey, Transaction, Keypair, Connection, AccountMeta } from '@solana/web3.js';
2
+ import * as _meteora_ag_dynamic_bonding_curve_sdk from '@meteora-ag/dynamic-bonding-curve-sdk';
3
+ import { TokenType, TokenAuthorityOption, CollectFeeMode, MigrationOption, BuildCurveParams, VirtualPool, PoolConfig } from '@meteora-ag/dynamic-bonding-curve-sdk';
4
+ import { P as PriceBandInput, a as PanguErrorName, b as PriceReading } from './feed-CY-pcUU2.mjs';
5
+ import * as _coral_xyz_anchor from '@coral-xyz/anchor';
6
+ import { BN } from '@anchor-lang/core';
7
+ import { S as Sale } from './accounts-BuD-oCcr.mjs';
8
+
9
+ /**
10
+ * The settings a Pangu sale cannot work without.
11
+ *
12
+ * Token-2022 base: a transfer hook only exists on Token-2022.
13
+ * The hook program: Pangu itself, or no rule is ever applied.
14
+ * DAMM v2 migration: where a finished sale graduates to.
15
+ * Fees in the paying token only: C11 in the threat model. With fees collected
16
+ * in the sale token, a fee claim would move the sale token while the hook is
17
+ * live, past every cap and approval.
18
+ * The token authority option: C14. It decides whether DBC leaves the mint
19
+ * authority alive at pool creation, and a token that can still be minted is one
20
+ * the hook can never hold to a cap.
21
+ */
22
+ declare const FORCED: {
23
+ readonly tokenType: TokenType.Token2022;
24
+ readonly tokenUpdateAuthority: TokenAuthorityOption.CreatorUpdateAuthority;
25
+ readonly collectFeeMode: CollectFeeMode.QuoteToken;
26
+ readonly migrationOption: MigrationOption.MET_DAMM_V2;
27
+ readonly transferHookProgram: PublicKey;
28
+ };
29
+ /**
30
+ * The caller's curve with Pangu's own settings put in.
31
+ *
32
+ * Anything else about the curve, the supply, the graduation threshold, the fee
33
+ * schedule, the liquidity split, is the issuer's to choose. Exported so the app
34
+ * can show what it will send before anybody signs.
35
+ *
36
+ * Throws PanguInputError when the caller set one of Pangu's settings to
37
+ * something else, or asked for a token that can still be minted.
38
+ */
39
+ declare function panguCurve(curve: BuildCurveParams): BuildCurveParams;
40
+ interface LaunchTemplateInput {
41
+ connection: Connection;
42
+ /** The partner opening the template. Pays unless a payer is given. */
43
+ partner: PublicKey;
44
+ payer?: PublicKey;
45
+ /** The token buyers pay in. */
46
+ quoteMint: PublicKey;
47
+ curve: BuildCurveParams;
48
+ /** Who may claim the partner's share of the trading fees. Defaults to partner. */
49
+ feeClaimer?: PublicKey;
50
+ /** Who receives tokens left on the curve at graduation. Defaults to partner. */
51
+ leftoverReceiver?: PublicKey;
52
+ /** DBC's badge for a paying token that needs one, such as a stock token. */
53
+ tokenBadge?: PublicKey;
54
+ /** The hook program. Only Pangu's own id is allowed. */
55
+ transferHookProgram?: PublicKey;
56
+ }
57
+ interface LaunchTemplate {
58
+ transaction: Transaction;
59
+ /** The new template's account. It signs this transaction once. */
60
+ config: Keypair;
61
+ bytes: number;
62
+ }
63
+ /**
64
+ * Builds the launch template every Pangu sale is opened from.
65
+ *
66
+ * Wraps Meteora's `createConfigWithTransferHook` and fixes the settings a Pangu
67
+ * sale depends on, refusing any attempt to set them otherwise. Signs and
68
+ * sends nothing: the partner signs the returned transaction together with the
69
+ * returned config keypair.
70
+ *
71
+ * Throws PanguInputError for a forced setting the caller tried to override, or
72
+ * for a transaction that would not fit.
73
+ */
74
+ declare function launchTemplateTransaction(input: LaunchTemplateInput): Promise<LaunchTemplate>;
75
+
76
+ /** The sale's rules, as the issuer chooses them. */
77
+ interface SaleTerms {
78
+ /** Most raw token units one wallet may end up holding. */
79
+ cap?: bigint;
80
+ /** The same cap written as a share of what the curve sells. Use one or the other. */
81
+ capShareBps?: number;
82
+ accessMode: number;
83
+ /** Access mode 2 only. */
84
+ credential?: PublicKey;
85
+ schema?: PublicKey;
86
+ band?: PriceBandInput;
87
+ /** Unix seconds at which the offering ends and every rule lifts. Leave out for no end. */
88
+ endsAt?: number;
89
+ }
90
+ interface OpenSaleInput {
91
+ connection: Connection;
92
+ /** The pool's creator, who becomes the sale's issuer. Pays unless a payer is given. */
93
+ creator: PublicKey;
94
+ payer?: PublicKey;
95
+ config: PublicKey;
96
+ name: string;
97
+ symbol: string;
98
+ uri: string;
99
+ sale: SaleTerms;
100
+ /** The new token's mint. Generated when not given. It signs this transaction. */
101
+ baseMint?: Keypair;
102
+ /**
103
+ * DBC's badge for a paying token that needs one, such as a tokenized stock.
104
+ * Without it DBC refuses the pool with InvalidTokenBadge. The same badge the
105
+ * launch template was opened with.
106
+ */
107
+ tokenBadge?: PublicKey;
108
+ }
109
+ interface OpenSale {
110
+ transaction: Transaction;
111
+ baseMint: Keypair;
112
+ pool: PublicKey;
113
+ bytes: number;
114
+ }
115
+ /**
116
+ * A cap written as a share of the tokens the curve will sell before graduation.
117
+ *
118
+ * Taken from the template rather than from a number typed in, so the cap means
119
+ * the same thing whatever supply the issuer chose. A share of 100 percent or
120
+ * more is refused: create_sale answers CapCoversWholeSale for a cap at or above
121
+ * the curve's supply, because one wallet could then buy the whole sale.
122
+ */
123
+ declare function capFromShare(swapBaseAmount: bigint, capShareBps: number): bigint;
124
+ /**
125
+ * Opens the pool and the sale's rules in one transaction.
126
+ *
127
+ * C7: the rules and the hook's account list are derived from the mint, which is
128
+ * public the moment the pool transaction is seen. Creating them in the same
129
+ * transaction as the pool is what stops anyone else setting the rules for this
130
+ * sale. Nothing is signed or sent here, and the transaction is measured, so a
131
+ * sale that would not fit is refused before the creator signs.
132
+ *
133
+ * Throws PanguInputError when the template is not one Pangu opened, when the
134
+ * cap is given twice or not at all, or when the transaction would not fit.
135
+ */
136
+ declare function openSaleTransaction(input: OpenSaleInput): Promise<OpenSale>;
137
+
138
+ /** A trade, built but not signed. */
139
+ interface TradeTransaction {
140
+ transaction: Transaction;
141
+ /** What Meteora's own quote says this trade returns, in raw units. */
142
+ expectedAmountOut: bigint;
143
+ /** The least the trade may return before it is refused, after slippage. */
144
+ minimumAmountOut: bigint;
145
+ bytes: number;
146
+ computeUnitLimit: number;
147
+ }
148
+ interface BuyInput {
149
+ connection: Connection;
150
+ buyer: PublicKey;
151
+ mint: PublicKey;
152
+ /** Raw units of the paying token to spend. */
153
+ amountIn: bigint;
154
+ slippageBps?: number;
155
+ /**
156
+ * How to handle a curve with less left than this buy asks for.
157
+ *
158
+ * "exactIn", the default, spends the whole amount or the trade is refused.
159
+ * "partial" lets DBC take what the curve can still absorb and leave the rest
160
+ * in the buyer's account. The last buy of a sale needs "partial": the tokens
161
+ * run out before the paying side does, and an exact-in swap is refused.
162
+ */
163
+ fill?: "exactIn" | "partial";
164
+ /**
165
+ * The fewest sale tokens, in raw units, the buy may return before the chain
166
+ * refuses it. Set it from the quote the buyer was shown, less their slippage,
167
+ * so the floor is what they agreed to and not a fresh quote taken at build
168
+ * time. When given it replaces `slippageBps`, and the build throws if its own
169
+ * fresh quote already returns less.
170
+ */
171
+ minimumAmountOut?: bigint;
172
+ }
173
+ interface SellInput {
174
+ connection: Connection;
175
+ seller: PublicKey;
176
+ mint: PublicKey;
177
+ /** Raw units of the sale token to sell back to the pool. */
178
+ amountIn: bigint;
179
+ slippageBps?: number;
180
+ /**
181
+ * The fewest paying tokens, in raw units, the sell may return before the
182
+ * chain refuses it. The same rule as `minimumAmountOut` on a buy.
183
+ */
184
+ minimumQuoteOut?: bigint;
185
+ }
186
+ /**
187
+ * Buys into a sale: the buyer's paying token in, the sale token out.
188
+ *
189
+ * Everything the hook needs travels with it. The paying token account is opened
190
+ * if missing, wrapped SOL is funded, the buyer's record is opened when this is
191
+ * their first buy, and the hook's accounts come from the sale's own published
192
+ * list, so a credential sale and a banded sale carry their extra accounts
193
+ * without the caller knowing they exist. Nothing is signed or sent.
194
+ *
195
+ * Throws PanguInputError for a mint with no Pangu sale, an amount of zero, a
196
+ * transaction that would not fit, or a `minimumAmountOut` the market has
197
+ * already moved past.
198
+ */
199
+ declare function buyTransaction(input: BuyInput): Promise<TradeTransaction>;
200
+ /**
201
+ * Sells back to the pool: the sale token in, the paying token out.
202
+ *
203
+ * The exit reads nothing that can be missing, which is C5 in the threat model,
204
+ * so a seller who is no longer approved, or whose sale's price feed has gone
205
+ * stale, still gets out. That includes a sale whose rules this package cannot
206
+ * read, because an older build wrote them: the program lets that sell through,
207
+ * so the pool is found from the mint instead and the sell is built all the
208
+ * same. Nothing is signed or sent.
209
+ *
210
+ * Throws PanguInputError when no transfer hook pool sells the mint, for an
211
+ * amount of zero, for a transaction that would not fit, or for a
212
+ * `minimumQuoteOut` the market has already moved past.
213
+ */
214
+ declare function sellTransaction(input: SellInput): Promise<TradeTransaction>;
215
+
216
+ /** What the chain says about a buy that has not been signed yet. */
217
+ interface BuyPreflight {
218
+ ok: boolean;
219
+ /** The program's own refusal this buy would hit, or null when it would pass. */
220
+ error: PanguErrorName | null;
221
+ /** One sentence a buyer can read. Null when the buy would pass. */
222
+ reason: string | null;
223
+ /** Raw token units this wallet may still buy before the cap stops it. */
224
+ capRoom: bigint;
225
+ /** Where this buy would leave the curve, in dollars scaled by 1e18. */
226
+ curvePrice: bigint | null;
227
+ /** The highest curve price the band allows right now, same scale. */
228
+ ceiling: bigint | null;
229
+ /** The sale's live stock price, when it has a band. */
230
+ price: PriceReading | null;
231
+ /**
232
+ * True when the wallet has no record yet and the caller said the buy opens
233
+ * one in the same transaction, so every answer above assumes a fresh record:
234
+ * unapproved, nothing bought. `buyTransaction` always does that.
235
+ */
236
+ recordOpensInThisBuy: boolean;
237
+ }
238
+ interface PreflightBuyInput {
239
+ connection: Connection;
240
+ buyer: PublicKey;
241
+ mint: PublicKey;
242
+ /** Raw units of the sale token the buyer wants to end up with. */
243
+ amountOut: bigint;
244
+ /**
245
+ * Set when the buy will open the wallet's record in the same transaction, as
246
+ * `buyTransaction` does on a first buy. A missing record is then judged as
247
+ * the fresh one that transaction creates instead of being refused, so a first
248
+ * buyer gets the band and the cap answers. Off by default, which refuses a
249
+ * missing record with BuyerRecordMissing as the hook would on its own.
250
+ */
251
+ openingRecord?: boolean;
252
+ }
253
+ /**
254
+ * Says whether a buy would be refused, and why, before anything is signed.
255
+ *
256
+ * Runs the hook's own checks in the hook's own order against live chain state:
257
+ * the record, the approval or the credential, the price band, then the cap.
258
+ * The order is the hook's and not a tidier one, because a buy that breaks two
259
+ * rules at once has to be given the same refusal here that the chain would
260
+ * give it, and handle_execute judges the band before the cap.
261
+ *
262
+ * In mode 2 the attestation and the credential's list of authorized signers are
263
+ * decoded here the way the hook decodes them, so a wallet is told whether its
264
+ * approval is missing, out of date, or signed by a key the verifier has since
265
+ * dropped. The answer is one of the program's error names with its plain
266
+ * sentence, so the app can say the same thing before and after a refusal.
267
+ *
268
+ * With `openingRecord` a wallet with no record is judged as the record the buy
269
+ * opens would leave it: not approved, nothing bought, so an issuer-list sale
270
+ * still answers NotApproved and every other sale goes on to the band and the
271
+ * cap with the whole cap as room.
272
+ *
273
+ * What it cannot see: the Wormhole guardian signatures behind the price, which
274
+ * only Pyth's receiver program can check, and anything that changes between
275
+ * this read and the buy landing. A "pass" here is the state now, not a promise.
276
+ *
277
+ * Throws PanguInputError for a mint with no Pangu sale.
278
+ */
279
+ declare function preflightBuy(input: PreflightBuyInput): Promise<BuyPreflight>;
280
+
281
+ /** Everything a claim leaves the caller with. */
282
+ interface ClaimFees {
283
+ transaction: Transaction;
284
+ /** Who the fees go to, read from the pool and its template, not passed in. */
285
+ claimer: PublicKey;
286
+ bytes: number;
287
+ computeUnitLimit: number;
288
+ }
289
+ interface ClaimFeesInput {
290
+ connection: Connection;
291
+ who: "partner" | "creator";
292
+ mint: PublicKey;
293
+ }
294
+ /**
295
+ * Claims the trading fees of a sale that is still running.
296
+ *
297
+ * Meteora's own `claimPartnerTradingFee` calls the older instruction, which
298
+ * refuses a transfer hook pool with `PoolTypeMismatch`. This builds the hook
299
+ * aware pair, `claim_trading_fee2` and `claim_creator_trading_fee2`, with the
300
+ * hook's accounts attached. See finding 2 in docs/measurements/fork-test.md.
301
+ *
302
+ * The claimer is read off the chain: the partner is the template's fee claimer
303
+ * and the creator is the pool's creator, so no address a caller typed in can
304
+ * receive this money. The sale's fees are collected in the paying token only
305
+ * (C11), so no sale token moves here.
306
+ *
307
+ * Throws PanguInputError for a mint with no Pangu sale.
308
+ */
309
+ declare function claimFeesTransaction(input: ClaimFeesInput): Promise<ClaimFees>;
310
+
311
+ /** How far a sale has got, in the numbers a judge or a buyer reads. */
312
+ interface SaleProgress {
313
+ /** Raw units of the paying token the curve has taken in. */
314
+ quoteRaised: bigint;
315
+ /** What it has to reach before the sale graduates. */
316
+ threshold: bigint;
317
+ /** Between 0 and 1. */
318
+ percent: number;
319
+ /** True once the curve is full, whether or not anybody has migrated it yet. */
320
+ graduated: boolean;
321
+ /** The DAMM v2 pool, once migration has created it. */
322
+ dammPool: PublicKey | null;
323
+ }
324
+ interface GraduateInput {
325
+ connection: Connection;
326
+ /** Anyone may pay for this. It is permissionless. */
327
+ payer: PublicKey;
328
+ mint: PublicKey;
329
+ }
330
+ interface Graduate {
331
+ transaction: Transaction;
332
+ /** The two position accounts migration creates. Both sign this transaction. */
333
+ signers: Keypair[];
334
+ /** Where the liquidity lands. */
335
+ dammPool: PublicKey;
336
+ bytes: number;
337
+ }
338
+ /**
339
+ * Migrates a full curve into DAMM v2.
340
+ *
341
+ * Permissionless: anyone can send it, and the sale's own creator gets the
342
+ * locked liquidity whoever pays. No compute budget instruction is added, on
343
+ * purpose: migration measured 153,633 units against the 200,000 a single
344
+ * instruction gets by default, and the transaction is already 1,139 bytes.
345
+ *
346
+ * Throws PanguInputError when the curve is not full yet or has already been
347
+ * migrated.
348
+ */
349
+ declare function graduateTransaction(input: GraduateInput): Promise<Graduate>;
350
+ /**
351
+ * How far this sale has got, read from the pool and its template.
352
+ *
353
+ * `graduated` is the curve being full, which is the moment DBC takes the hook
354
+ * off the mint. `dammPool` stays null until somebody sends the migration, so
355
+ * the two questions the app asks, "is the sale over" and "where does it trade
356
+ * now", are answered separately.
357
+ *
358
+ * Throws PanguInputError for a mint with no Pangu sale.
359
+ */
360
+ declare function saleProgress(connection: Connection, mint: PublicKey): Promise<SaleProgress>;
361
+
362
+ /**
363
+ * A token account this transaction creates before the swap runs.
364
+ *
365
+ * Pangu derives a buyer's record from the owner field inside the receiving
366
+ * token account, so resolving the hook's accounts means reading that account.
367
+ * On a first buy it does not exist yet, and the chain cannot answer for it. The
368
+ * owner is not a guess though: the same transaction creates the account, so the
369
+ * bytes are filled in here from what is about to be written.
370
+ */
371
+ interface PendingTokenAccount {
372
+ address: PublicKey;
373
+ mint: PublicKey;
374
+ owner: PublicKey;
375
+ }
376
+ interface HookAccountsInput {
377
+ connection: Connection;
378
+ mint: PublicKey;
379
+ /** The token account the sale token leaves. */
380
+ source: PublicKey;
381
+ /** The token account the sale token lands in. */
382
+ destination: PublicKey;
383
+ /** Whoever signs for the source account. */
384
+ authority: PublicKey;
385
+ amount: bigint;
386
+ pending?: PendingTokenAccount[];
387
+ }
388
+ /**
389
+ * The accounts Pangu's hook has to be called with, read from the list the
390
+ * program itself published on chain.
391
+ *
392
+ * Nothing here is a copy of what the program writes. The list is fetched, each
393
+ * entry is resolved against the real token accounts of this transfer, and the
394
+ * caller gets whatever that sale needs: a plain sale's four, a credential
395
+ * sale's seven, a banded sale's eleven. The Meteora SDK's own helper cannot do
396
+ * this because it resolves against placeholder accounts, and a record derived
397
+ * from the receiver's owner has nothing to read there. See finding 1 in
398
+ * docs/measurements/fork-test.md.
399
+ *
400
+ * Order matters and is the one Token-2022 rebuilds on chain: the published list
401
+ * itself, then its entries, then the hook program.
402
+ *
403
+ * Throws PanguInputError when the mint has no published list, which means it is
404
+ * not a Pangu sale.
405
+ */
406
+ declare function hookAccounts(input: HookAccountsInput): Promise<AccountMeta[]>;
407
+ /** DBC has to be told how many of the remaining accounts belong to the hook. */
408
+ declare function hookAccountsInfo(accounts: AccountMeta[]): {
409
+ slices: {
410
+ accountsType: {
411
+ readonly transferHookBase: {};
412
+ };
413
+ length: number;
414
+ }[];
415
+ };
416
+
417
+ /** DBC's pool authority. Every pool vault is owned by it. */
418
+ declare const DBC_POOL_AUTHORITY: PublicKey;
419
+ /** The pool and its launch template: what a trade needs, whatever the rules say. */
420
+ interface PoolMarket {
421
+ pool: PublicKey;
422
+ /** The account as DBC's own quote functions want it, with `.poolState` inside. */
423
+ poolAccount: VirtualPool;
424
+ config: PublicKey;
425
+ configState: PoolConfig;
426
+ baseMint: PublicKey;
427
+ quoteMint: PublicKey;
428
+ baseVault: PublicKey;
429
+ quoteVault: PublicKey;
430
+ /** The token program the paying token belongs to, SPL or Token-2022. */
431
+ quoteProgram: PublicKey;
432
+ /** The unit DBC counts the fee schedule in, a slot or a Unix second. */
433
+ currentPoint: BN;
434
+ }
435
+ /** Everything a Pangu action needs to know about one live DBC pool. */
436
+ interface PoolView extends PoolMarket {
437
+ sale: Sale;
438
+ }
439
+ /**
440
+ * What a sell needs. The rules are there when this package can read them and
441
+ * null when it cannot, because a sell never depends on them.
442
+ */
443
+ interface SellView extends PoolMarket {
444
+ sale: Sale | null;
445
+ }
446
+ declare function dbcProgram(connection: Connection): _coral_xyz_anchor.Program<_meteora_ag_dynamic_bonding_curve_sdk.DynamicBondingCurveTypes>;
447
+ /** The sale's rules, refusing a mint that never had a Pangu sale. */
448
+ declare function requireSale(connection: Connection, mint: PublicKey): Promise<Sale>;
449
+ /**
450
+ * Reads the pool and its launch template in one go, for a buy or anything else
451
+ * that acts on the sale's rules.
452
+ *
453
+ * Everything downstream comes from these two accounts rather than from the
454
+ * caller, so a wrong vault or a wrong paying token cannot be passed in.
455
+ *
456
+ * Refuses a mint whose rules this package cannot read, because a buy is judged
457
+ * against them. Refuses a pool whose fee schedule needs the instructions sysvar
458
+ * as its first remaining account: a rate limiter, or the first-swap minimum fee.
459
+ * Pangu's hook accounts are the remaining accounts of every swap, and there is
460
+ * no room for a second thing in that list.
461
+ */
462
+ declare function loadPool(connection: Connection, mint: PublicKey): Promise<PoolView>;
463
+ /**
464
+ * Reads the pool and its launch template for a sell, which never needs the
465
+ * sale's rules.
466
+ *
467
+ * On chain a sell goes through whatever the rules account holds, including rules
468
+ * written by an older build or rules that are missing (C5). This is the same
469
+ * promise on the client side: the rules are read when they can be, and when
470
+ * they cannot, the pool is found by the mint it sells, straight from DBC, and
471
+ * the sell is built anyway. The hook's own accounts are still resolved from the
472
+ * list the program published, so nothing about the hook is guessed.
473
+ *
474
+ * Throws PanguInputError when no transfer hook pool sells this mint, when more
475
+ * than one does, or for the same template refusal as `loadPool`.
476
+ */
477
+ declare function loadSellPool(connection: Connection, mint: PublicKey): Promise<SellView>;
478
+
479
+ /** One Solana transaction, signatures included. */
480
+ declare const TRANSACTION_SIZE_LIMIT = 1232;
481
+ /**
482
+ * The compute limits this package asks for, each set from what the same action
483
+ * really used on a fork of mainnet. The measurements are in
484
+ * docs/measurements/fork-test.md. Roughly double the measured cost, because a
485
+ * banded or credential sale reads more accounts than the plain one that was
486
+ * measured, and running out of compute would look to a buyer like a refusal.
487
+ */
488
+ declare const COMPUTE_LIMIT: {
489
+ /** Measured: 113,000 to 130,000 units for a buy, 83,000 for a sell. */
490
+ readonly swap: 300000;
491
+ /** Measured: 55,192 for the partner claim, 51,742 for the creator claim. */
492
+ readonly claim: 150000;
493
+ };
494
+ /**
495
+ * How many bytes this transaction will take on the wire.
496
+ *
497
+ * `serialize()` throws once a transaction passes the limit, and the point of
498
+ * measuring is to find out whether it does, so the size is worked out from the
499
+ * compiled message instead. The fee payer and a blockhash must already be set.
500
+ */
501
+ declare function transactionBytes(transaction: Transaction): number;
502
+ /** Refuses a transaction that could never be sent, with the action named. */
503
+ declare function requireOneTransaction(transaction: Transaction, action: string): number;
504
+
505
+ export { type BuyInput, type BuyPreflight, COMPUTE_LIMIT, type ClaimFees, type ClaimFeesInput, DBC_POOL_AUTHORITY, FORCED, type Graduate, type GraduateInput, type HookAccountsInput, type LaunchTemplate, type LaunchTemplateInput, type OpenSale, type OpenSaleInput, type PendingTokenAccount, type PoolMarket, type PoolView, type PreflightBuyInput, type SaleProgress, type SaleTerms, type SellInput, type SellView, TRANSACTION_SIZE_LIMIT, type TradeTransaction, buyTransaction, capFromShare, claimFeesTransaction, dbcProgram, graduateTransaction, hookAccounts, hookAccountsInfo, launchTemplateTransaction, loadPool, loadSellPool, openSaleTransaction, panguCurve, preflightBuy, requireOneTransaction, requireSale, saleProgress, sellTransaction, transactionBytes };