@star-factory/sdk-launchpad 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.
Files changed (86) hide show
  1. package/README.md +343 -0
  2. package/dist/claims/accounts.d.ts +49 -0
  3. package/dist/claims/accounts.d.ts.map +1 -0
  4. package/dist/claims/accounts.js +118 -0
  5. package/dist/claims/accounts.js.map +1 -0
  6. package/dist/claims/eligibility.d.ts +67 -0
  7. package/dist/claims/eligibility.d.ts.map +1 -0
  8. package/dist/claims/eligibility.js +275 -0
  9. package/dist/claims/eligibility.js.map +1 -0
  10. package/dist/claims/index.d.ts +5 -0
  11. package/dist/claims/index.d.ts.map +1 -0
  12. package/dist/claims/index.js +41 -0
  13. package/dist/claims/index.js.map +1 -0
  14. package/dist/claims/pdas.d.ts +24 -0
  15. package/dist/claims/pdas.d.ts.map +1 -0
  16. package/dist/claims/pdas.js +43 -0
  17. package/dist/claims/pdas.js.map +1 -0
  18. package/dist/claims/tx.d.ts +47 -0
  19. package/dist/claims/tx.d.ts.map +1 -0
  20. package/dist/claims/tx.js +126 -0
  21. package/dist/claims/tx.js.map +1 -0
  22. package/dist/index.d.ts +27 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +40 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/instructions/cancel-launch.d.ts +16 -0
  27. package/dist/instructions/cancel-launch.d.ts.map +1 -0
  28. package/dist/instructions/cancel-launch.js +72 -0
  29. package/dist/instructions/cancel-launch.js.map +1 -0
  30. package/dist/instructions/configure-launch.d.ts +16 -0
  31. package/dist/instructions/configure-launch.d.ts.map +1 -0
  32. package/dist/instructions/configure-launch.js +50 -0
  33. package/dist/instructions/configure-launch.js.map +1 -0
  34. package/dist/instructions/constants.d.ts +8 -0
  35. package/dist/instructions/constants.d.ts.map +1 -0
  36. package/dist/instructions/constants.js +14 -0
  37. package/dist/instructions/constants.js.map +1 -0
  38. package/dist/instructions/create-launch-token.d.ts +18 -0
  39. package/dist/instructions/create-launch-token.d.ts.map +1 -0
  40. package/dist/instructions/create-launch-token.js +65 -0
  41. package/dist/instructions/create-launch-token.js.map +1 -0
  42. package/dist/instructions/execute-launch.d.ts +68 -0
  43. package/dist/instructions/execute-launch.d.ts.map +1 -0
  44. package/dist/instructions/execute-launch.js +190 -0
  45. package/dist/instructions/execute-launch.js.map +1 -0
  46. package/dist/instructions/index.d.ts +8 -0
  47. package/dist/instructions/index.d.ts.map +1 -0
  48. package/dist/instructions/index.js +57 -0
  49. package/dist/instructions/index.js.map +1 -0
  50. package/dist/instructions/initialize-launch.d.ts +15 -0
  51. package/dist/instructions/initialize-launch.d.ts.map +1 -0
  52. package/dist/instructions/initialize-launch.js +71 -0
  53. package/dist/instructions/initialize-launch.js.map +1 -0
  54. package/dist/instructions/pdas.d.ts +95 -0
  55. package/dist/instructions/pdas.d.ts.map +1 -0
  56. package/dist/instructions/pdas.js +168 -0
  57. package/dist/instructions/pdas.js.map +1 -0
  58. package/dist/pdas.d.ts +19 -0
  59. package/dist/pdas.d.ts.map +1 -0
  60. package/dist/pdas.js +40 -0
  61. package/dist/pdas.js.map +1 -0
  62. package/dist/sdk.d.ts +274 -0
  63. package/dist/sdk.d.ts.map +1 -0
  64. package/dist/sdk.js +505 -0
  65. package/dist/sdk.js.map +1 -0
  66. package/dist/types.d.ts +578 -0
  67. package/dist/types.d.ts.map +1 -0
  68. package/dist/types.js +8 -0
  69. package/dist/types.js.map +1 -0
  70. package/dist/zc/client.d.ts +69 -0
  71. package/dist/zc/client.d.ts.map +1 -0
  72. package/dist/zc/client.js +121 -0
  73. package/dist/zc/client.js.map +1 -0
  74. package/dist/zc/constants.d.ts +49 -0
  75. package/dist/zc/constants.d.ts.map +1 -0
  76. package/dist/zc/constants.js +64 -0
  77. package/dist/zc/constants.js.map +1 -0
  78. package/dist/zc/index.d.ts +4 -0
  79. package/dist/zc/index.d.ts.map +1 -0
  80. package/dist/zc/index.js +7 -0
  81. package/dist/zc/index.js.map +1 -0
  82. package/dist/zc/types.d.ts +65 -0
  83. package/dist/zc/types.d.ts.map +1 -0
  84. package/dist/zc/types.js +3 -0
  85. package/dist/zc/types.js.map +1 -0
  86. package/package.json +63 -0
package/README.md ADDED
@@ -0,0 +1,343 @@
1
+ # @star-factory/sdk-launchpad
2
+
3
+ TypeScript SDK for the Star Launchpad program. Covers the full lifecycle:
4
+
5
+ 1. **Launch Flow** — initialize, configure, create token, execute launch (pool + DAO + authority transfer)
6
+ 2. **Token Claims** — eligibility checks, vesting math, claim transaction building
7
+
8
+ ## Install
9
+
10
+ ```bash
11
+ yarn add @star-factory/sdk-launchpad
12
+ ```
13
+
14
+ Runtime dependencies (including `@solana/web3.js`, `@coral-xyz/anchor`, `bn.js`) are bundled via this package's `dependencies`.
15
+ Peer dependency: `typescript@^5`.
16
+
17
+ ## Quick Start
18
+
19
+ ```typescript
20
+ import { LaunchpadSDK } from '@star-factory/sdk-launchpad';
21
+
22
+ const sdk = new LaunchpadSDK({
23
+ connection,
24
+ cluster: 'devnet',
25
+ zcApiKey: process.env.ZC_API_KEY!,
26
+ });
27
+ ```
28
+
29
+ ---
30
+
31
+ ## Launch Flow
32
+
33
+ ### 1. Initialize Launch
34
+
35
+ Creates a `LaunchConfig` PDA + underlying fundraise vault via CPI to `vault::make`.
36
+
37
+ ```typescript
38
+ const tx = await sdk.buildInitializeLaunchTx(launchpadProgram, {
39
+ creator: wallet.publicKey,
40
+ seed: new BN(Date.now()),
41
+ vaultSeed: new BN(Date.now() + 1),
42
+ totalSupply: new BN('1000000000000000'), // 1M tokens @ 9 decimals
43
+ tokensToParticipants: new BN('500000000000000'), // 500K to participants
44
+ quoteMint: NATIVE_MINT,
45
+ minRaise: new BN('100000000'),
46
+ targetRaise: new BN('100000000'),
47
+ startTime: new BN(now - 5),
48
+ endTime: new BN(now + 300),
49
+ vaultProgramId: VAULT_PROGRAM_ID,
50
+ });
51
+ await sendTx(tx, [creator]);
52
+ ```
53
+
54
+ ### 2. Configure Launch
55
+
56
+ Sets vanity mint configuration and token metadata. Transitions `FundraiseActive → ReadyToLaunch`.
57
+
58
+ ```typescript
59
+ const tx = await sdk.buildConfigureLaunchTx(launchpadProgram, {
60
+ admin: admin.publicKey,
61
+ launchConfig: launchConfigPda,
62
+ fundraiseState: vaultPda,
63
+ basePubkey: baseKeypair.publicKey,
64
+ vanitySeed: 'my-token-seed',
65
+ expectedMint: derivedMintAddress,
66
+ name: 'My Token',
67
+ symbol: 'MTK',
68
+ uri: 'https://arweave.net/metadata.json',
69
+ });
70
+ await sendTx(tx, [admin]);
71
+ ```
72
+
73
+ ### 3. Create Launch Token
74
+
75
+ Creates the vanity mint, Metaplex metadata, and mints total supply. Transitions `ReadyToLaunch → TokenCreated`.
76
+
77
+ ```typescript
78
+ const tx = await sdk.buildCreateLaunchTokenTx(launchpadProgram, {
79
+ admin: admin.publicKey,
80
+ baseKeypairPubkey: baseKeypair.publicKey,
81
+ launchConfig: launchConfigPda,
82
+ expectedMint: derivedMintAddress,
83
+ });
84
+ await sendTx(tx, [admin, baseKeypair]); // both must sign
85
+ ```
86
+
87
+ ### 4. Reserve Admin (off-chain)
88
+
89
+ Calls the zCombinator API to allocate a managed admin wallet for the DAO.
90
+
91
+ ```typescript
92
+ const poolAddress = sdk.derivePoolAddress(baseMint, quoteMint);
93
+
94
+ const reservation = await sdk.reserveAdmin({
95
+ name: 'ProjectDAO',
96
+ tokenMint: baseMint,
97
+ poolAddress,
98
+ poolType: 'damm',
99
+ quoteMint,
100
+ treasuryCosigner: teamMultisig,
101
+ ownerWallet: projectOwner,
102
+ });
103
+ ```
104
+
105
+ Or use the one-call helper:
106
+
107
+ ```typescript
108
+ const result = await sdk.prepareLaunchExecution({
109
+ daoName: 'ProjectDAO',
110
+ tokenMint: baseMint,
111
+ quoteMint,
112
+ treasuryCosigner: teamMultisig,
113
+ ownerWallet: projectOwner,
114
+ });
115
+ ```
116
+
117
+ ### 5. Execute Launch
118
+
119
+ Atomically finalizes the vault, creates DAMM pool, creates DAO, transfers authorities, and routes funds. Transitions `TokenCreated → Launched`.
120
+
121
+ Returns both the TX and all resolved accounts (for ALT creation).
122
+
123
+ ```typescript
124
+ const { tx, accounts } = await sdk.buildExecuteLaunchTx(launchpadProgram, {
125
+ admin: admin.publicKey,
126
+ launchConfig: launchConfigPda,
127
+ launchConfigData,
128
+ poolActivationTime: new BN(now + 120),
129
+ daoName: 'ProjectDAO',
130
+ treasuryCosigner: teamMultisig,
131
+ newDaoAdmin: reservation.adminWallet,
132
+ dammPool: poolAddress,
133
+ vaultProgramId: VAULT_PROGRAM_ID,
134
+ computeUnits: 1_400_000,
135
+ });
136
+
137
+ // Create ALT from `accounts`, compile to VersionedTransaction, send
138
+ ```
139
+
140
+ ### 6. Cancel Launch
141
+
142
+ Cancels from any pre-Launched state. Burns tokens if minted, enables refunds.
143
+
144
+ ```typescript
145
+ const tx = await sdk.buildCancelLaunchTx(launchpadProgram, {
146
+ admin: admin.publicKey,
147
+ launchConfig: launchConfigPda,
148
+ launchConfigData,
149
+ vaultProgramId: VAULT_PROGRAM_ID,
150
+ });
151
+ await sendTx(tx, [admin]);
152
+ ```
153
+
154
+ ---
155
+
156
+ ## Token Claims
157
+
158
+ After a launch executes, depositors claim vested tokens through the `claim_tokens` instruction.
159
+
160
+ ### Check Eligibility
161
+
162
+ ```typescript
163
+ const eligibility = await sdk.getClaimEligibility(
164
+ launchpadProgram,
165
+ vaultProgram,
166
+ launchConfigPda,
167
+ wallet.publicKey,
168
+ );
169
+
170
+ if (eligibility.canClaim) {
171
+ console.log(`Claimable: ${eligibility.claimableNow.toString()}`);
172
+ } else {
173
+ console.log(`Reason: ${eligibility.reason}`);
174
+ }
175
+ ```
176
+
177
+ The `ClaimEligibility` result contains everything a UI needs:
178
+
179
+ | Field | Type | Description |
180
+ |-------------------|-------------------|------------------------------------------------|
181
+ | `canClaim` | `boolean` | Whether the user can claim right now |
182
+ | `reason` | `string \| null` | Why they can't (null when `canClaim` is true) |
183
+ | `claimableNow` | `BN` | Tokens claimable at this moment |
184
+ | `totalTokens` | `BN` | User's total token entitlement |
185
+ | `totalClaimed` | `BN` | Already claimed |
186
+ | `totalVested` | `BN` | Total vested as of now |
187
+ | `tier` | `number \| null` | Vesting tier (0–6) |
188
+ | `vestingSchedule` | `VestingSchedule` | Start/end timestamps, percent vested, etc. |
189
+
190
+ ### Build Claim Transaction
191
+
192
+ **Client-side (wallet adapter):**
193
+
194
+ ```typescript
195
+ const tx = await sdk.buildClaimTx(launchpadProgram, {
196
+ user: wallet.publicKey,
197
+ launchConfig: launchConfigPda,
198
+ launchConfigData,
199
+ vaultProgramId: VAULT_PROGRAM_ID,
200
+ });
201
+ const sig = await wallet.sendTransaction(tx, connection);
202
+ ```
203
+
204
+ **Server-side (sponsored/relay):**
205
+
206
+ ```typescript
207
+ const tx = await sdk.buildClaimTx(launchpadProgram, {
208
+ user: userPubkey,
209
+ launchConfig: launchConfigPda,
210
+ launchConfigData,
211
+ vaultProgramId: VAULT_PROGRAM_ID,
212
+ feePayer: relayPubkey,
213
+ priorityFee: 10_000,
214
+ computeUnits: 200_000,
215
+ });
216
+ ```
217
+
218
+ ---
219
+
220
+ ## Vesting Model
221
+
222
+ Tokens vest linearly from pool activation time based on the depositor's tier:
223
+
224
+ | Tier | Vesting Duration | Unlock |
225
+ |------|------------------|------------------------------|
226
+ | 0 | Immediate | 100% at pool activation |
227
+ | 1 | 2 weeks | Linear over 1,209,600s |
228
+ | 2 | 4 weeks | Linear over 2,419,200s |
229
+ | 3 | 6 weeks | Linear over 3,628,800s |
230
+ | 4 | 8 weeks | Linear over 4,838,400s |
231
+ | 5 | 10 weeks | Linear over 6,048,000s |
232
+ | 6 | 12 weeks | Linear over 7,257,600s |
233
+
234
+ Users can claim multiple times — each claim transfers `vested - already_claimed`.
235
+
236
+ ---
237
+
238
+ ## Low-Level Exports
239
+
240
+ Every building block is exported individually:
241
+
242
+ ```typescript
243
+ import {
244
+ // Instruction TX builders
245
+ buildInitializeLaunchTx,
246
+ buildConfigureLaunchTx,
247
+ buildCreateLaunchTokenTx,
248
+ buildExecuteLaunchTx,
249
+ buildCancelLaunchTx,
250
+
251
+ // Claim TX builders
252
+ buildClaimTransaction,
253
+ buildBatchClaimTransactions,
254
+
255
+ // Launchpad PDAs
256
+ deriveLaunchConfigPda,
257
+ deriveLaunchpadSignerPda,
258
+ deriveClaimRecordPda,
259
+ derivePositionNftMintPda,
260
+
261
+ // External program PDAs
262
+ deriveVaultPda,
263
+ deriveTgeConfigPda,
264
+ deriveDammPoolAuthority,
265
+ deriveDammTokenVault,
266
+ deriveDammPosition,
267
+ deriveDammPositionNftAccount,
268
+ deriveDammEventAuthority,
269
+ deriveSquadsMultisig,
270
+ deriveSquadsVault,
271
+ deriveSquadsProgramConfig,
272
+ deriveDaoPda,
273
+ deriveModeratorPda,
274
+ deriveMintCreateKeyPda,
275
+ deriveMetadataPda,
276
+
277
+ // Pool derivation
278
+ derivePoolAddress,
279
+ sortMints,
280
+
281
+ // Account fetching + resolution
282
+ fetchLaunchConfig,
283
+ fetchClaimRecord,
284
+ fetchDepositorRecord,
285
+ resolveClaimAccounts,
286
+ deriveDepositorRecordPda,
287
+
288
+ // Eligibility (pure computation)
289
+ computeAllocatedAmount,
290
+ computeClaimEligibility,
291
+ computeUserTokens,
292
+ computeVestedAmount,
293
+
294
+ // Constants
295
+ NUM_TIERS,
296
+ TIER_VESTING_SECONDS,
297
+ TIER_VESTING_WEEKS,
298
+ DAMM_PROGRAM_ID,
299
+ DAMM_CONFIG_PDA,
300
+ SQUADS_PROGRAM_ID,
301
+ METAPLEX_PROGRAM_ID,
302
+
303
+ // ZC client
304
+ ZCClient,
305
+ } from '@star-factory/sdk-launchpad';
306
+ ```
307
+
308
+ ---
309
+
310
+ ## Architecture
311
+
312
+ ```
313
+ sdk-launchpad/src/
314
+ ├── index.ts Barrel exports
315
+ ├── sdk.ts LaunchpadSDK class (high-level API)
316
+ ├── types.ts All TypeScript interfaces and types
317
+ ├── pdas.ts DAMM pool PDA derivation
318
+ ├── instructions/
319
+ │ ├── pdas.ts External program PDAs (DAMM, Squads, Futarchy, Metaplex, Vault)
320
+ │ ├── constants.ts External program IDs
321
+ │ ├── initialize-launch.ts
322
+ │ ├── configure-launch.ts
323
+ │ ├── create-launch-token.ts
324
+ │ ├── execute-launch.ts Account resolution (~35 accounts) + TX builder
325
+ │ └── cancel-launch.ts
326
+ ├── claims/
327
+ │ ├── pdas.ts Launchpad PDA derivation (launch config, signer, claim record)
328
+ │ ├── accounts.ts Account fetching + resolution
329
+ │ ├── eligibility.ts Pure vesting math + eligibility computation
330
+ │ └── tx.ts claim_tokens TX builder
331
+ └── zc/
332
+ ├── client.ts zCombinator REST API client
333
+ ├── constants.ts Program IDs, API endpoints, rate limits
334
+ └── types.ts ZC-specific types
335
+ ```
336
+
337
+ **Design principles:**
338
+
339
+ - **Pure math is separated from RPC** — `eligibility.ts` has zero network calls; it takes pre-fetched data and returns a deterministic result.
340
+ - **All PDAs are deterministic** — every account for every instruction is derived from known inputs. No guessing, no fetching account lists.
341
+ - **Transactions are unsigned** — the SDK never touches private keys. It returns `Transaction` objects for the caller to sign however they want.
342
+ - **On-chain math parity** — `computeAllocatedAmount`, `computeUserTokens`, and `computeVestedAmount` mirror the Rust implementations exactly.
343
+ - **Full lifecycle coverage** — every launchpad program instruction has a corresponding TX builder.
@@ -0,0 +1,49 @@
1
+ import type { Idl, Program } from '@coral-xyz/anchor';
2
+ import { PublicKey } from '@solana/web3.js';
3
+ import type { ClaimAccountsResolved, ClaimRecordAccount, DepositorRecordRaw, LaunchConfigAccount } from '../types';
4
+ /**
5
+ * Fetch and decode a LaunchConfig account.
6
+ *
7
+ * @param connection - Solana RPC connection
8
+ * @param program - Anchor program instance (launchpad)
9
+ * @param launchConfig - The launch config PDA address
10
+ * @returns Typed LaunchConfig or `null` if account doesn't exist
11
+ */
12
+ export declare function fetchLaunchConfig(program: Program<Idl>, launchConfig: PublicKey): Promise<LaunchConfigAccount | null>;
13
+ /**
14
+ * Fetch and decode a ClaimRecord account.
15
+ *
16
+ * Returns `null` if the account doesn't exist yet (user hasn't claimed).
17
+ * This is the expected state for first-time claimants.
18
+ */
19
+ export declare function fetchClaimRecord(program: Program<Idl>, claimRecord: PublicKey): Promise<ClaimRecordAccount | null>;
20
+ /**
21
+ * Fetch a DepositorRecord from the vault program.
22
+ *
23
+ * The depositor record lives in the vault program, not the launchpad program.
24
+ * We use a generic `fetch` approach so the SDK doesn't need the vault IDL.
25
+ */
26
+ export declare function fetchDepositorRecord(vaultProgram: Program<Idl>, depositorRecord: PublicKey): Promise<DepositorRecordRaw | null>;
27
+ /**
28
+ * Derive the depositor record PDA from the vault program.
29
+ *
30
+ * Seeds: `["depositor", vault, user]`
31
+ */
32
+ export declare function deriveDepositorRecordPda(vault: PublicKey, user: PublicKey, vaultProgramId: PublicKey): [PublicKey, number];
33
+ /**
34
+ * Resolve all accounts needed for a `claim_tokens` instruction.
35
+ *
36
+ * Given a LaunchConfig account (already fetched) and user pubkey,
37
+ * deterministically derives every account the instruction needs.
38
+ *
39
+ * This is the core account resolution function — used by both the
40
+ * transaction builder (client-side) and eligibility checker (server-side).
41
+ *
42
+ * @param launchConfig - The LaunchConfig PDA address
43
+ * @param launchConfigData - The decoded LaunchConfig account data
44
+ * @param user - The claiming user's wallet pubkey
45
+ * @param vaultProgramId - The vault program ID (for depositor record PDA)
46
+ * @param launchpadProgramId - The launchpad program ID
47
+ */
48
+ export declare function resolveClaimAccounts(launchConfig: PublicKey, launchConfigData: LaunchConfigAccount, user: PublicKey, vaultProgramId: PublicKey, launchpadProgramId: PublicKey): ClaimAccountsResolved;
49
+ //# sourceMappingURL=accounts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accounts.d.ts","sourceRoot":"","sources":["../../src/claims/accounts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAEtD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,KAAK,EACR,qBAAqB,EACrB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACtB,MAAM,UAAU,CAAC;AAoBlB;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,EACrB,YAAY,EAAE,SAAS,GACtB,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAOrC;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,EACrB,WAAW,EAAE,SAAS,GACrB,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAOpC;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CACxC,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,EAC1B,eAAe,EAAE,SAAS,GACzB,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAOpC;AAMD;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,SAAS,EAChB,IAAI,EAAE,SAAS,EACf,cAAc,EAAE,SAAS,GACxB,CAAC,SAAS,EAAE,MAAM,CAAC,CAKrB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE,SAAS,EACvB,gBAAgB,EAAE,mBAAmB,EACrC,IAAI,EAAE,SAAS,EACf,cAAc,EAAE,SAAS,EACzB,kBAAkB,EAAE,SAAS,GAC5B,qBAAqB,CA0BvB"}
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.fetchLaunchConfig = fetchLaunchConfig;
4
+ exports.fetchClaimRecord = fetchClaimRecord;
5
+ exports.fetchDepositorRecord = fetchDepositorRecord;
6
+ exports.deriveDepositorRecordPda = deriveDepositorRecordPda;
7
+ exports.resolveClaimAccounts = resolveClaimAccounts;
8
+ const spl_token_1 = require("@solana/spl-token");
9
+ const web3_js_1 = require("@solana/web3.js");
10
+ const pdas_1 = require("./pdas");
11
+ function getAccountFetcher(program, accountName) {
12
+ const accounts = program.account;
13
+ const fetcher = accounts[accountName];
14
+ if (!fetcher) {
15
+ throw new Error(`Account namespace missing '${accountName}'`);
16
+ }
17
+ return fetcher;
18
+ }
19
+ // ============================================================================
20
+ // Account Fetching
21
+ // ============================================================================
22
+ /**
23
+ * Fetch and decode a LaunchConfig account.
24
+ *
25
+ * @param connection - Solana RPC connection
26
+ * @param program - Anchor program instance (launchpad)
27
+ * @param launchConfig - The launch config PDA address
28
+ * @returns Typed LaunchConfig or `null` if account doesn't exist
29
+ */
30
+ async function fetchLaunchConfig(program, launchConfig) {
31
+ try {
32
+ const raw = await getAccountFetcher(program, 'launchConfig').fetch(launchConfig);
33
+ return raw;
34
+ }
35
+ catch {
36
+ return null;
37
+ }
38
+ }
39
+ /**
40
+ * Fetch and decode a ClaimRecord account.
41
+ *
42
+ * Returns `null` if the account doesn't exist yet (user hasn't claimed).
43
+ * This is the expected state for first-time claimants.
44
+ */
45
+ async function fetchClaimRecord(program, claimRecord) {
46
+ try {
47
+ const raw = await getAccountFetcher(program, 'claimRecord').fetch(claimRecord);
48
+ return raw;
49
+ }
50
+ catch {
51
+ return null;
52
+ }
53
+ }
54
+ /**
55
+ * Fetch a DepositorRecord from the vault program.
56
+ *
57
+ * The depositor record lives in the vault program, not the launchpad program.
58
+ * We use a generic `fetch` approach so the SDK doesn't need the vault IDL.
59
+ */
60
+ async function fetchDepositorRecord(vaultProgram, depositorRecord) {
61
+ try {
62
+ const raw = await getAccountFetcher(vaultProgram, 'depositorRecord').fetch(depositorRecord);
63
+ return raw;
64
+ }
65
+ catch {
66
+ return null;
67
+ }
68
+ }
69
+ // ============================================================================
70
+ // Account Resolution
71
+ // ============================================================================
72
+ /**
73
+ * Derive the depositor record PDA from the vault program.
74
+ *
75
+ * Seeds: `["depositor", vault, user]`
76
+ */
77
+ function deriveDepositorRecordPda(vault, user, vaultProgramId) {
78
+ return web3_js_1.PublicKey.findProgramAddressSync([Buffer.from('depositor'), vault.toBuffer(), user.toBuffer()], vaultProgramId);
79
+ }
80
+ /**
81
+ * Resolve all accounts needed for a `claim_tokens` instruction.
82
+ *
83
+ * Given a LaunchConfig account (already fetched) and user pubkey,
84
+ * deterministically derives every account the instruction needs.
85
+ *
86
+ * This is the core account resolution function — used by both the
87
+ * transaction builder (client-side) and eligibility checker (server-side).
88
+ *
89
+ * @param launchConfig - The LaunchConfig PDA address
90
+ * @param launchConfigData - The decoded LaunchConfig account data
91
+ * @param user - The claiming user's wallet pubkey
92
+ * @param vaultProgramId - The vault program ID (for depositor record PDA)
93
+ * @param launchpadProgramId - The launchpad program ID
94
+ */
95
+ function resolveClaimAccounts(launchConfig, launchConfigData, user, vaultProgramId, launchpadProgramId) {
96
+ const fundraiseState = launchConfigData.fundraiseState;
97
+ const baseMint = launchConfigData.baseMint;
98
+ if (!baseMint) {
99
+ throw new Error('LaunchConfig.baseMint is not set — launch token not yet created');
100
+ }
101
+ const [launchpadSigner] = (0, pdas_1.deriveLaunchpadSignerPda)(launchConfig, launchpadProgramId);
102
+ const [claimRecord] = (0, pdas_1.deriveClaimRecordPda)(launchConfig, user, launchpadProgramId);
103
+ const [userRecord] = deriveDepositorRecordPda(fundraiseState, user, vaultProgramId);
104
+ const tokenVault = (0, spl_token_1.getAssociatedTokenAddressSync)(baseMint, launchpadSigner, true);
105
+ const userTokenAta = (0, spl_token_1.getAssociatedTokenAddressSync)(baseMint, user, false);
106
+ return {
107
+ user,
108
+ launchConfig,
109
+ fundraiseState,
110
+ userRecord,
111
+ claimRecord,
112
+ baseMint,
113
+ tokenVault,
114
+ userTokenAta,
115
+ launchpadSigner,
116
+ };
117
+ }
118
+ //# sourceMappingURL=accounts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accounts.js","sourceRoot":"","sources":["../../src/claims/accounts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ import BN from 'bn.js';
2
+ import type { ClaimEligibility, ClaimRecordAccount, DepositorRecordRaw, LaunchConfigAccount, VaultAllocationData } from '../types';
3
+ /** Number of vesting tiers (0–6 inclusive). */
4
+ export declare const NUM_TIERS = 7;
5
+ /** Maximum valid tier index. */
6
+ export declare const MAX_TIER = 6;
7
+ /**
8
+ * Tier vesting durations in seconds.
9
+ *
10
+ * - Tier 0: immediate at activation
11
+ * - Tier 1: 2 weeks = 1,209,600s
12
+ * - Tier 2: 4 weeks = 2,419,200s
13
+ * - Tier 3: 6 weeks = 3,628,800s
14
+ * - Tier 4: 8 weeks = 4,838,400s
15
+ * - Tier 5: 10 weeks = 6,048,000s
16
+ * - Tier 6: 12 weeks = 7,257,600s
17
+ */
18
+ export declare const TIER_VESTING_SECONDS: readonly number[];
19
+ /** Tier vesting durations in weeks (for display). */
20
+ export declare const TIER_VESTING_WEEKS: readonly number[];
21
+ /**
22
+ * Compute the user's total token entitlement from their vault allocation.
23
+ *
24
+ * Formula: `tokens_to_participants × user_allocated / total_allocated`
25
+ *
26
+ * Uses BN for precision. Returns `null` if `total_allocated == 0`.
27
+ */
28
+ export declare function computeUserTokens(tokensToParticipants: BN, userAllocated: BN, totalAllocated: BN): BN | null;
29
+ /**
30
+ * Compute the total vested amount at a given time.
31
+ *
32
+ * - Tier 0: 100% immediately at pool activation time
33
+ * - Tier 1–6: Linear vesting from pool_activation_time over tier duration
34
+ *
35
+ * Returns the total vested (caller subtracts `already_claimed`).
36
+ */
37
+ export declare function computeVestedAmount(totalTokens: BN, tier: number, poolActivationTime: number, currentTime: number): BN;
38
+ /**
39
+ * Compute the user's allocated amount from their depositor record and vault data.
40
+ *
41
+ * Mirrors `DepositorRecord::allocated_amount(&self, vault)` on-chain:
42
+ * - If allocations not yet calculated → return raw `amount`
43
+ * - If tier_totals_at_allocation[tier] == 0 → return 0
44
+ * - Otherwise → `amount × tier_allocated[tier] / tier_totals_at_allocation[tier]`
45
+ *
46
+ * IMPORTANT: This uses vault tier-level allocation data for accuracy.
47
+ * The `finalAmount` field on `DepositorRecord` only reflects the correct
48
+ * allocation AFTER the user claims their excess refund. Before that,
49
+ * `finalAmount == amount` (the full deposit), which over-estimates
50
+ * allocation in oversubscribed tiers.
51
+ */
52
+ export declare function computeAllocatedAmount(depositor: DepositorRecordRaw, vaultData: VaultAllocationData): BN;
53
+ /**
54
+ * Compute full claim eligibility for a user.
55
+ *
56
+ * This is a **pure function** — no RPC calls. It takes pre-fetched account
57
+ * data and returns a comprehensive eligibility result. Works identically
58
+ * on client and server.
59
+ *
60
+ * @param launchConfigData - Decoded LaunchConfig account
61
+ * @param depositorRecord - Decoded DepositorRecord (from vault program), or `null` if not found
62
+ * @param claimRecord - Decoded ClaimRecord, or `null` if user hasn't claimed yet
63
+ * @param currentTime - Current unix timestamp in seconds (from `Date.now() / 1000` or RPC clock)
64
+ * @param vaultData - Vault allocation data (tier arrays + total_allocated + flag)
65
+ */
66
+ export declare function computeClaimEligibility(launchConfigData: LaunchConfigAccount, depositorRecord: DepositorRecordRaw | null, claimRecord: ClaimRecordAccount | null, currentTime: number, vaultData: VaultAllocationData): ClaimEligibility;
67
+ //# sourceMappingURL=eligibility.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"eligibility.d.ts","sourceRoot":"","sources":["../../src/claims/eligibility.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,OAAO,CAAC;AAEvB,OAAO,KAAK,EACR,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EAEtB,MAAM,UAAU,CAAC;AAMlB,+CAA+C;AAC/C,eAAO,MAAM,SAAS,IAAI,CAAC;AAE3B,gCAAgC;AAChC,eAAO,MAAM,QAAQ,IAAI,CAAC;AAE1B;;;;;;;;;;GAUG;AACH,eAAO,MAAM,oBAAoB,EAAE,SAAS,MAAM,EAQjD,CAAC;AAEF,qDAAqD;AACrD,eAAO,MAAM,kBAAkB,EAAE,SAAS,MAAM,EAA4B,CAAC;AAM7E;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,oBAAoB,EAAE,EAAE,EACxB,aAAa,EAAE,EAAE,EACjB,cAAc,EAAE,EAAE,GACjB,EAAE,GAAG,IAAI,CAKX;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,EAAE,EACf,IAAI,EAAE,MAAM,EACZ,kBAAkB,EAAE,MAAM,EAC1B,WAAW,EAAE,MAAM,GAClB,EAAE,CAwBJ;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,kBAAkB,EAC7B,SAAS,EAAE,mBAAmB,GAC7B,EAAE,CAmBJ;AAOD;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CACrC,gBAAgB,EAAE,mBAAmB,EACrC,eAAe,EAAE,kBAAkB,GAAG,IAAI,EAC1C,WAAW,EAAE,kBAAkB,GAAG,IAAI,EACtC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,mBAAmB,GAC7B,gBAAgB,CAgKlB"}