@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.
- package/README.md +343 -0
- package/dist/claims/accounts.d.ts +49 -0
- package/dist/claims/accounts.d.ts.map +1 -0
- package/dist/claims/accounts.js +118 -0
- package/dist/claims/accounts.js.map +1 -0
- package/dist/claims/eligibility.d.ts +67 -0
- package/dist/claims/eligibility.d.ts.map +1 -0
- package/dist/claims/eligibility.js +275 -0
- package/dist/claims/eligibility.js.map +1 -0
- package/dist/claims/index.d.ts +5 -0
- package/dist/claims/index.d.ts.map +1 -0
- package/dist/claims/index.js +41 -0
- package/dist/claims/index.js.map +1 -0
- package/dist/claims/pdas.d.ts +24 -0
- package/dist/claims/pdas.d.ts.map +1 -0
- package/dist/claims/pdas.js +43 -0
- package/dist/claims/pdas.js.map +1 -0
- package/dist/claims/tx.d.ts +47 -0
- package/dist/claims/tx.d.ts.map +1 -0
- package/dist/claims/tx.js +126 -0
- package/dist/claims/tx.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +40 -0
- package/dist/index.js.map +1 -0
- package/dist/instructions/cancel-launch.d.ts +16 -0
- package/dist/instructions/cancel-launch.d.ts.map +1 -0
- package/dist/instructions/cancel-launch.js +72 -0
- package/dist/instructions/cancel-launch.js.map +1 -0
- package/dist/instructions/configure-launch.d.ts +16 -0
- package/dist/instructions/configure-launch.d.ts.map +1 -0
- package/dist/instructions/configure-launch.js +50 -0
- package/dist/instructions/configure-launch.js.map +1 -0
- package/dist/instructions/constants.d.ts +8 -0
- package/dist/instructions/constants.d.ts.map +1 -0
- package/dist/instructions/constants.js +14 -0
- package/dist/instructions/constants.js.map +1 -0
- package/dist/instructions/create-launch-token.d.ts +18 -0
- package/dist/instructions/create-launch-token.d.ts.map +1 -0
- package/dist/instructions/create-launch-token.js +65 -0
- package/dist/instructions/create-launch-token.js.map +1 -0
- package/dist/instructions/execute-launch.d.ts +68 -0
- package/dist/instructions/execute-launch.d.ts.map +1 -0
- package/dist/instructions/execute-launch.js +190 -0
- package/dist/instructions/execute-launch.js.map +1 -0
- package/dist/instructions/index.d.ts +8 -0
- package/dist/instructions/index.d.ts.map +1 -0
- package/dist/instructions/index.js +57 -0
- package/dist/instructions/index.js.map +1 -0
- package/dist/instructions/initialize-launch.d.ts +15 -0
- package/dist/instructions/initialize-launch.d.ts.map +1 -0
- package/dist/instructions/initialize-launch.js +71 -0
- package/dist/instructions/initialize-launch.js.map +1 -0
- package/dist/instructions/pdas.d.ts +95 -0
- package/dist/instructions/pdas.d.ts.map +1 -0
- package/dist/instructions/pdas.js +168 -0
- package/dist/instructions/pdas.js.map +1 -0
- package/dist/pdas.d.ts +19 -0
- package/dist/pdas.d.ts.map +1 -0
- package/dist/pdas.js +40 -0
- package/dist/pdas.js.map +1 -0
- package/dist/sdk.d.ts +274 -0
- package/dist/sdk.d.ts.map +1 -0
- package/dist/sdk.js +505 -0
- package/dist/sdk.js.map +1 -0
- package/dist/types.d.ts +578 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/zc/client.d.ts +69 -0
- package/dist/zc/client.d.ts.map +1 -0
- package/dist/zc/client.js +121 -0
- package/dist/zc/client.js.map +1 -0
- package/dist/zc/constants.d.ts +49 -0
- package/dist/zc/constants.d.ts.map +1 -0
- package/dist/zc/constants.js +64 -0
- package/dist/zc/constants.js.map +1 -0
- package/dist/zc/index.d.ts +4 -0
- package/dist/zc/index.d.ts.map +1 -0
- package/dist/zc/index.js +7 -0
- package/dist/zc/index.js.map +1 -0
- package/dist/zc/types.d.ts +65 -0
- package/dist/zc/types.d.ts.map +1 -0
- package/dist/zc/types.js +3 -0
- package/dist/zc/types.js.map +1 -0
- 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"}
|