@zemyth/raise-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.
Files changed (54) hide show
  1. package/README.md +416 -0
  2. package/dist/accounts/index.cjs +258 -0
  3. package/dist/accounts/index.cjs.map +1 -0
  4. package/dist/accounts/index.d.cts +115 -0
  5. package/dist/accounts/index.d.ts +115 -0
  6. package/dist/accounts/index.js +245 -0
  7. package/dist/accounts/index.js.map +1 -0
  8. package/dist/constants/index.cjs +174 -0
  9. package/dist/constants/index.cjs.map +1 -0
  10. package/dist/constants/index.d.cts +143 -0
  11. package/dist/constants/index.d.ts +143 -0
  12. package/dist/constants/index.js +158 -0
  13. package/dist/constants/index.js.map +1 -0
  14. package/dist/errors/index.cjs +177 -0
  15. package/dist/errors/index.cjs.map +1 -0
  16. package/dist/errors/index.d.cts +83 -0
  17. package/dist/errors/index.d.ts +83 -0
  18. package/dist/errors/index.js +170 -0
  19. package/dist/errors/index.js.map +1 -0
  20. package/dist/index.cjs +2063 -0
  21. package/dist/index.cjs.map +1 -0
  22. package/dist/index.d.cts +680 -0
  23. package/dist/index.d.ts +680 -0
  24. package/dist/index.js +1926 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/instructions/index.cjs +852 -0
  27. package/dist/instructions/index.cjs.map +1 -0
  28. package/dist/instructions/index.d.cts +452 -0
  29. package/dist/instructions/index.d.ts +452 -0
  30. package/dist/instructions/index.js +809 -0
  31. package/dist/instructions/index.js.map +1 -0
  32. package/dist/pdas/index.cjs +241 -0
  33. package/dist/pdas/index.cjs.map +1 -0
  34. package/dist/pdas/index.d.cts +171 -0
  35. package/dist/pdas/index.d.ts +171 -0
  36. package/dist/pdas/index.js +217 -0
  37. package/dist/pdas/index.js.map +1 -0
  38. package/dist/types/index.cjs +44 -0
  39. package/dist/types/index.cjs.map +1 -0
  40. package/dist/types/index.d.cts +229 -0
  41. package/dist/types/index.d.ts +229 -0
  42. package/dist/types/index.js +39 -0
  43. package/dist/types/index.js.map +1 -0
  44. package/package.json +130 -0
  45. package/src/accounts/index.ts +329 -0
  46. package/src/client.ts +715 -0
  47. package/src/constants/index.ts +205 -0
  48. package/src/errors/index.ts +222 -0
  49. package/src/events/index.ts +256 -0
  50. package/src/index.ts +253 -0
  51. package/src/instructions/index.ts +1504 -0
  52. package/src/pdas/index.ts +404 -0
  53. package/src/types/index.ts +267 -0
  54. package/src/utils/index.ts +277 -0
@@ -0,0 +1,404 @@
1
+ /**
2
+ * Raise PDA Derivation Helpers
3
+ *
4
+ * All PDA derivation functions for the Raise program.
5
+ * PDAs are deterministic addresses derived from seeds and program ID.
6
+ */
7
+
8
+ import { PublicKey } from '@solana/web3.js';
9
+ import { BN } from '@coral-xyz/anchor';
10
+ import { SEEDS } from '../constants/index.js';
11
+
12
+ /**
13
+ * Ensure value is a proper BN instance
14
+ * This handles cases where BN objects lose their prototype chain
15
+ * (e.g., when passing through React state or JSON serialization)
16
+ *
17
+ * Uses duck typing instead of instanceof to handle different BN module instances
18
+ */
19
+ function ensureBN(value: BN | number | string | { toString(): string }): BN {
20
+ // Duck typing: if it has toArrayLike, it's BN-like and we can use it
21
+ if (value && typeof (value as BN).toArrayLike === 'function') {
22
+ return value as BN;
23
+ }
24
+ // Always create a fresh BN from the SDK's imported BN class
25
+ return new BN(String(value));
26
+ }
27
+
28
+ /**
29
+ * Derive Project PDA from project ID
30
+ *
31
+ * @param projectId - Unique project identifier
32
+ * @param programId - Raise program ID
33
+ * @returns Project account PDA
34
+ */
35
+ export function getProjectPDA(projectId: BN | number | string, programId: PublicKey): PublicKey {
36
+ const projectIdBN = ensureBN(projectId);
37
+ const [pda] = PublicKey.findProgramAddressSync(
38
+ [Buffer.from(SEEDS.PROJECT), projectIdBN.toArrayLike(Buffer, 'le', 8)],
39
+ programId
40
+ );
41
+ return pda;
42
+ }
43
+
44
+ /**
45
+ * Derive Escrow PDA from project ID
46
+ *
47
+ * @param projectId - Project identifier
48
+ * @param programId - Raise program ID
49
+ * @returns Escrow account PDA
50
+ */
51
+ export function getEscrowPDA(projectId: BN | number | string, programId: PublicKey): PublicKey {
52
+ const projectIdBN = ensureBN(projectId);
53
+ const [pda] = PublicKey.findProgramAddressSync(
54
+ [Buffer.from(SEEDS.ESCROW), projectIdBN.toArrayLike(Buffer, 'le', 8)],
55
+ programId
56
+ );
57
+ return pda;
58
+ }
59
+
60
+ /**
61
+ * Derive Milestone PDA from project PDA and milestone index
62
+ *
63
+ * @param projectPda - Project account PDA
64
+ * @param milestoneIndex - Milestone index (0-based)
65
+ * @param programId - Raise program ID
66
+ * @returns Milestone account PDA
67
+ */
68
+ export function getMilestonePDA(
69
+ projectPda: PublicKey,
70
+ milestoneIndex: number,
71
+ programId: PublicKey
72
+ ): PublicKey {
73
+ const [pda] = PublicKey.findProgramAddressSync(
74
+ [
75
+ Buffer.from(SEEDS.MILESTONE),
76
+ projectPda.toBuffer(),
77
+ Buffer.from([milestoneIndex]),
78
+ ],
79
+ programId
80
+ );
81
+ return pda;
82
+ }
83
+
84
+ /**
85
+ * Derive Investment PDA from project PDA and NFT mint
86
+ *
87
+ * @param projectPda - Project account PDA
88
+ * @param nftMint - Investment NFT mint address
89
+ * @param programId - Raise program ID
90
+ * @returns Investment account PDA
91
+ */
92
+ export function getInvestmentPDA(
93
+ projectPda: PublicKey,
94
+ nftMint: PublicKey,
95
+ programId: PublicKey
96
+ ): PublicKey {
97
+ const [pda] = PublicKey.findProgramAddressSync(
98
+ [
99
+ Buffer.from(SEEDS.INVESTMENT),
100
+ projectPda.toBuffer(),
101
+ nftMint.toBuffer(),
102
+ ],
103
+ programId
104
+ );
105
+ return pda;
106
+ }
107
+
108
+ /**
109
+ * Derive Vote PDA from milestone PDA, voter key, and voting round
110
+ *
111
+ * @param milestonePda - Milestone account PDA
112
+ * @param voterKey - Voter's public key
113
+ * @param votingRound - Current voting round (0 initially, incremented on resubmit)
114
+ * @param programId - Raise program ID
115
+ * @returns Vote account PDA
116
+ */
117
+ export function getVotePDA(
118
+ milestonePda: PublicKey,
119
+ voterKey: PublicKey,
120
+ votingRound: number,
121
+ programId: PublicKey
122
+ ): PublicKey {
123
+ const [pda] = PublicKey.findProgramAddressSync(
124
+ [Buffer.from(SEEDS.VOTE), milestonePda.toBuffer(), voterKey.toBuffer(), Buffer.from([votingRound])],
125
+ programId
126
+ );
127
+ return pda;
128
+ }
129
+
130
+ /**
131
+ * Derive PivotProposal PDA from project PDA and pivot count
132
+ *
133
+ * @param projectPda - Project account PDA
134
+ * @param pivotCount - Current pivot count from project account
135
+ * @param programId - Raise program ID
136
+ * @returns PivotProposal account PDA
137
+ */
138
+ export function getPivotProposalPDA(
139
+ projectPda: PublicKey,
140
+ pivotCount: number,
141
+ programId: PublicKey
142
+ ): PublicKey {
143
+ const [pda] = PublicKey.findProgramAddressSync(
144
+ [
145
+ Buffer.from(SEEDS.PIVOT), // Use PIVOT seed, not PIVOT_PROPOSAL
146
+ projectPda.toBuffer(),
147
+ Buffer.from([pivotCount]), // pivot_count is u8 (1 byte) on-chain
148
+ ],
149
+ programId
150
+ );
151
+ return pda;
152
+ }
153
+
154
+ /**
155
+ * Derive TgeEscrow PDA from project PDA
156
+ *
157
+ * @param projectPda - Project account PDA
158
+ * @param programId - Raise program ID
159
+ * @returns TgeEscrow account PDA
160
+ */
161
+ export function getTgeEscrowPDA(
162
+ projectPda: PublicKey,
163
+ programId: PublicKey
164
+ ): PublicKey {
165
+ const [pda] = PublicKey.findProgramAddressSync(
166
+ [Buffer.from(SEEDS.TGE_ESCROW), projectPda.toBuffer()],
167
+ programId
168
+ );
169
+ return pda;
170
+ }
171
+
172
+ /**
173
+ * Derive TgeEscrowVault PDA from project PDA
174
+ * Used for holding 10% USDC holdback from final milestone
175
+ *
176
+ * @param projectPda - Project account PDA
177
+ * @param programId - Raise program ID
178
+ * @returns TgeEscrowVault PDA
179
+ */
180
+ export function getTgeEscrowVaultPDA(
181
+ projectPda: PublicKey,
182
+ programId: PublicKey
183
+ ): PublicKey {
184
+ const [pda] = PublicKey.findProgramAddressSync(
185
+ [Buffer.from(SEEDS.TGE_ESCROW_VAULT), projectPda.toBuffer()],
186
+ programId
187
+ );
188
+ return pda;
189
+ }
190
+
191
+ /**
192
+ * Derive TokenVault PDA from project PDA
193
+ * Used for holding project tokens for investor distribution
194
+ *
195
+ * @param projectPda - Project account PDA
196
+ * @param programId - Raise program ID
197
+ * @returns TokenVault PDA
198
+ */
199
+ export function getTokenVaultPDA(
200
+ projectPda: PublicKey,
201
+ programId: PublicKey
202
+ ): PublicKey {
203
+ const [pda] = PublicKey.findProgramAddressSync(
204
+ [Buffer.from('token_vault'), projectPda.toBuffer()],
205
+ programId
206
+ );
207
+ return pda;
208
+ }
209
+
210
+ /**
211
+ * Derive ScamReport PDA from project PDA and NFT mint
212
+ *
213
+ * @param projectPda - Project account PDA
214
+ * @param nftMint - Reporter's NFT mint address
215
+ * @param programId - Raise program ID
216
+ * @returns ScamReport account PDA
217
+ */
218
+ export function getScamReportPDA(
219
+ projectPda: PublicKey,
220
+ nftMint: PublicKey,
221
+ programId: PublicKey
222
+ ): PublicKey {
223
+ const [pda] = PublicKey.findProgramAddressSync(
224
+ [
225
+ Buffer.from(SEEDS.SCAM_REPORT),
226
+ projectPda.toBuffer(),
227
+ nftMint.toBuffer(),
228
+ ],
229
+ programId
230
+ );
231
+ return pda;
232
+ }
233
+
234
+ /**
235
+ * Derive AdminConfig PDA (global admin authority)
236
+ *
237
+ * @param programId - Raise program ID
238
+ * @returns AdminConfig account PDA
239
+ */
240
+ export function getAdminConfigPDA(programId: PublicKey): PublicKey {
241
+ const [pda] = PublicKey.findProgramAddressSync(
242
+ [Buffer.from(SEEDS.ADMIN_CONFIG)],
243
+ programId
244
+ );
245
+ return pda;
246
+ }
247
+
248
+ /**
249
+ * Derive NFT Mint PDA
250
+ *
251
+ * @param projectId - Project identifier
252
+ * @param investor - Investor's public key
253
+ * @param investmentCount - Investment count (u64 in Rust, 8 bytes LE)
254
+ * @param programId - Raise program ID
255
+ * @returns NFT Mint PDA and bump
256
+ */
257
+ export function getNftMintPDA(
258
+ projectId: BN | number | string,
259
+ investor: PublicKey,
260
+ investmentCount: BN | number,
261
+ programId: PublicKey
262
+ ): [PublicKey, number] {
263
+ // Ensure both values are proper BN instances (handles prototype chain issues)
264
+ const projectIdBN = ensureBN(projectId);
265
+ const countBN = ensureBN(investmentCount);
266
+ return PublicKey.findProgramAddressSync(
267
+ [
268
+ Buffer.from(SEEDS.NFT_MINT),
269
+ projectIdBN.toArrayLike(Buffer, 'le', 8),
270
+ investor.toBuffer(),
271
+ countBN.toArrayLike(Buffer, 'le', 8), // u64 is 8 bytes LE
272
+ ],
273
+ programId
274
+ );
275
+ }
276
+
277
+ /**
278
+ * Derive Program Authority PDA
279
+ *
280
+ * @param programId - Raise program ID
281
+ * @returns Program authority PDA and bump
282
+ */
283
+ export function getProgramAuthorityPDA(programId: PublicKey): [PublicKey, number] {
284
+ return PublicKey.findProgramAddressSync(
285
+ [Buffer.from(SEEDS.AUTHORITY)],
286
+ programId
287
+ );
288
+ }
289
+
290
+ /**
291
+ * Helper to derive all PDAs for a project
292
+ *
293
+ * @param projectId - Project identifier
294
+ * @param programId - Raise program ID
295
+ * @returns Object with project and escrow PDAs
296
+ */
297
+ export function getProjectPDAs(projectId: BN, programId: PublicKey) {
298
+ const project = getProjectPDA(projectId, programId);
299
+ const escrow = getEscrowPDA(projectId, programId);
300
+ return { project, escrow };
301
+ }
302
+
303
+ // =============================================================================
304
+ // ZTM v2.0 PDAs
305
+ // =============================================================================
306
+
307
+ /**
308
+ * Derive Tokenomics PDA from project PDA
309
+ */
310
+ export function getTokenomicsPDA(projectPda: PublicKey, programId: PublicKey): PublicKey {
311
+ const [pda] = PublicKey.findProgramAddressSync(
312
+ [Buffer.from('tokenomics'), projectPda.toBuffer()],
313
+ programId
314
+ );
315
+ return pda;
316
+ }
317
+
318
+ /**
319
+ * Derive Token Mint PDA from project PDA
320
+ */
321
+ export function getTokenMintPDA(projectPda: PublicKey, programId: PublicKey): PublicKey {
322
+ const [pda] = PublicKey.findProgramAddressSync(
323
+ [Buffer.from('token_mint'), projectPda.toBuffer()],
324
+ programId
325
+ );
326
+ return pda;
327
+ }
328
+
329
+ /**
330
+ * Derive Vault Authority PDA from project PDA
331
+ */
332
+ export function getVaultAuthorityPDA(projectPda: PublicKey, programId: PublicKey): PublicKey {
333
+ const [pda] = PublicKey.findProgramAddressSync(
334
+ [Buffer.from('vault_authority'), projectPda.toBuffer()],
335
+ programId
336
+ );
337
+ return pda;
338
+ }
339
+
340
+ /**
341
+ * Derive Investor Vault PDA from project PDA
342
+ */
343
+ export function getInvestorVaultPDA(projectPda: PublicKey, programId: PublicKey): PublicKey {
344
+ const [pda] = PublicKey.findProgramAddressSync(
345
+ [Buffer.from('investor_vault'), projectPda.toBuffer()],
346
+ programId
347
+ );
348
+ return pda;
349
+ }
350
+
351
+ /**
352
+ * Derive Founder Vault PDA from project PDA
353
+ */
354
+ export function getFounderVaultPDA(projectPda: PublicKey, programId: PublicKey): PublicKey {
355
+ const [pda] = PublicKey.findProgramAddressSync(
356
+ [Buffer.from('founder_vault'), projectPda.toBuffer()],
357
+ programId
358
+ );
359
+ return pda;
360
+ }
361
+
362
+ /**
363
+ * Derive LP Token Vault PDA from project PDA
364
+ */
365
+ export function getLpTokenVaultPDA(projectPda: PublicKey, programId: PublicKey): PublicKey {
366
+ const [pda] = PublicKey.findProgramAddressSync(
367
+ [Buffer.from('lp_token_vault'), projectPda.toBuffer()],
368
+ programId
369
+ );
370
+ return pda;
371
+ }
372
+
373
+ /**
374
+ * Derive Treasury Vault PDA from project PDA
375
+ */
376
+ export function getTreasuryVaultPDA(projectPda: PublicKey, programId: PublicKey): PublicKey {
377
+ const [pda] = PublicKey.findProgramAddressSync(
378
+ [Buffer.from('treasury_vault'), projectPda.toBuffer()],
379
+ programId
380
+ );
381
+ return pda;
382
+ }
383
+
384
+ /**
385
+ * Derive LP USDC Vault PDA from project PDA
386
+ */
387
+ export function getLpUsdcVaultPDA(projectPda: PublicKey, programId: PublicKey): PublicKey {
388
+ const [pda] = PublicKey.findProgramAddressSync(
389
+ [Buffer.from('lp_usdc_vault'), projectPda.toBuffer()],
390
+ programId
391
+ );
392
+ return pda;
393
+ }
394
+
395
+ /**
396
+ * Derive Founder Vesting PDA from project PDA
397
+ */
398
+ export function getFounderVestingPDA(projectPda: PublicKey, programId: PublicKey): PublicKey {
399
+ const [pda] = PublicKey.findProgramAddressSync(
400
+ [Buffer.from('founder_vesting'), projectPda.toBuffer()],
401
+ programId
402
+ );
403
+ return pda;
404
+ }
@@ -0,0 +1,267 @@
1
+ /**
2
+ * Raise Type Definitions
3
+ *
4
+ * Re-exports types from the IDL and provides additional utility types.
5
+ */
6
+
7
+ import { PublicKey } from '@solana/web3.js';
8
+ import { BN } from '@coral-xyz/anchor';
9
+
10
+ // =============================================================================
11
+ // Project State Enums
12
+ // =============================================================================
13
+
14
+ export enum ProjectState {
15
+ Draft = 'draft',
16
+ PendingApproval = 'pendingApproval',
17
+ Open = 'open',
18
+ Funded = 'funded',
19
+ InProgress = 'inProgress',
20
+ Completed = 'completed',
21
+ Abandoned = 'abandoned',
22
+ Failed = 'failed',
23
+ TGEFailed = 'tgeFailed',
24
+ Cancelled = 'cancelled',
25
+ }
26
+
27
+ export enum MilestoneState {
28
+ Proposed = 'proposed',
29
+ Approved = 'approved',
30
+ InProgress = 'inProgress',
31
+ UnderReview = 'underReview',
32
+ Passed = 'passed',
33
+ Failed = 'failed',
34
+ Unlocked = 'unlocked',
35
+ }
36
+
37
+ export enum VoteChoice {
38
+ Good = 'good',
39
+ Bad = 'bad',
40
+ }
41
+
42
+ export enum PivotState {
43
+ PendingModeratorApproval = 'pendingModeratorApproval',
44
+ ApprovedAwaitingInvestorWindow = 'approvedAwaitingInvestorWindow',
45
+ Finalized = 'finalized',
46
+ }
47
+
48
+ // =============================================================================
49
+ // Account Types
50
+ // =============================================================================
51
+
52
+ /**
53
+ * Tier configuration stored on-chain (includes filled_lots)
54
+ */
55
+ export interface Tier {
56
+ /** USDC amount per lot */
57
+ amount: BN;
58
+ /** Maximum lots available */
59
+ maxLots: number;
60
+ /** Currently filled lots */
61
+ filledLots: number;
62
+ /** Token allocation per $1 invested */
63
+ tokenRatio: BN;
64
+ /** Vote weight multiplier (basis points, 100 = 1.0x) */
65
+ voteMultiplier: number;
66
+ }
67
+
68
+ /**
69
+ * Tier configuration input for project initialization
70
+ * Founders pass these when creating a project
71
+ */
72
+ export interface TierConfig {
73
+ /** USDC amount per lot (must be >= 10 USDC = 10_000_000 lamports) */
74
+ amount: BN;
75
+ /** Maximum lots available (must be >= 1) */
76
+ maxLots: number;
77
+ /** Token allocation per $1 invested (must be >= 1) */
78
+ tokenRatio: BN;
79
+ /** Vote weight multiplier (basis points, must be >= 100 = 1.0x) */
80
+ voteMultiplier: number;
81
+ }
82
+
83
+ export interface ProjectAccount {
84
+ founder: PublicKey;
85
+ projectId: BN;
86
+ fundingGoal: BN;
87
+ amountRaised: BN;
88
+ state: ProjectState;
89
+ metadataUri: string;
90
+ escrow: PublicKey;
91
+ currentMilestone: number;
92
+ totalMilestones: number;
93
+ /** Number of active tiers (1-10) */
94
+ tierCount: number;
95
+ /** All tier slots (only first tierCount are active) */
96
+ tiers: Tier[];
97
+ tokenMint: PublicKey | null;
98
+ tgeDate: BN | null;
99
+ tokensDeposited: BN;
100
+ tokenAllocationBps: number;
101
+ totalTokenAllocation: BN;
102
+ consecutiveFailures: number;
103
+ investorCount: number;
104
+ bump: number;
105
+ }
106
+
107
+ export interface MilestoneAccount {
108
+ project: PublicKey;
109
+ milestoneIndex: number;
110
+ percentage: number;
111
+ description: string;
112
+ state: MilestoneState;
113
+ yesVotes: BN;
114
+ noVotes: BN;
115
+ totalWeight: BN;
116
+ voterCount: number;
117
+ votingEndsAt: BN | null;
118
+ bump: number;
119
+ }
120
+
121
+ export interface InvestmentAccount {
122
+ project: PublicKey;
123
+ investor: PublicKey;
124
+ nftMint: PublicKey;
125
+ amount: BN;
126
+ voteWeight: BN;
127
+ tokenAllocation: BN;
128
+ tier: number;
129
+ investedAt: BN;
130
+ tokensClaimed: boolean;
131
+ withdrawnFromPivot: boolean;
132
+ refundClaimed: boolean;
133
+ bump: number;
134
+ }
135
+
136
+ export interface VoteAccount {
137
+ milestone: PublicKey;
138
+ voter: PublicKey;
139
+ choice: VoteChoice;
140
+ weight: BN;
141
+ votedAt: BN;
142
+ bump: number;
143
+ }
144
+
145
+ export interface AdminConfigAccount {
146
+ admin: PublicKey;
147
+ pendingAdmin: PublicKey | null;
148
+ bump: number;
149
+ }
150
+
151
+ export interface PivotProposalAccount {
152
+ project: PublicKey;
153
+ newMetadataUri: string;
154
+ newMilestones: Array<{ percentage: number; description: string }>;
155
+ state: PivotState;
156
+ proposedAt: BN;
157
+ approvedAt: BN | null;
158
+ withdrawalWindowEndsAt: BN | null;
159
+ withdrawnAmount: BN;
160
+ withdrawnCount: number;
161
+ bump: number;
162
+ }
163
+
164
+ export interface TgeEscrowAccount {
165
+ project: PublicKey;
166
+ holdbackAmount: BN;
167
+ scamReports: BN;
168
+ scamWeight: BN;
169
+ scamConfirmed: boolean;
170
+ holdbackReleased: boolean;
171
+ bump: number;
172
+ }
173
+
174
+ // =============================================================================
175
+ // Instruction Arguments
176
+ // =============================================================================
177
+
178
+ export interface InitializeProjectArgs {
179
+ projectId: BN;
180
+ fundingGoal: BN;
181
+ metadataUri: string;
182
+ /** Founder-configured tiers (1-10 tiers) */
183
+ tiers: TierConfig[];
184
+ }
185
+
186
+ export interface CreateMilestoneArgs {
187
+ milestoneIndex: number;
188
+ percentage: number;
189
+ description: string;
190
+ }
191
+
192
+ export interface InvestArgs {
193
+ amount: BN;
194
+ }
195
+
196
+ export interface VoteOnMilestoneArgs {
197
+ choice: VoteChoice;
198
+ }
199
+
200
+ export interface SetTgeDateArgs {
201
+ tgeDate: BN;
202
+ tokenMint: PublicKey;
203
+ }
204
+
205
+ export interface DepositTokensArgs {
206
+ amount: BN;
207
+ }
208
+
209
+ export interface ProposePivotArgs {
210
+ newMetadataUri: string;
211
+ newMilestones: Array<{ percentage: number; description: string }>;
212
+ }
213
+
214
+ // =============================================================================
215
+ // Event Types
216
+ // =============================================================================
217
+
218
+ export interface ProjectCreatedEvent {
219
+ projectId: BN;
220
+ founder: PublicKey;
221
+ fundingGoal: BN;
222
+ metadataUri: string;
223
+ }
224
+
225
+ export interface InvestmentMadeEvent {
226
+ projectId: BN;
227
+ investor: PublicKey;
228
+ amount: BN;
229
+ nftMint: PublicKey;
230
+ tier: number;
231
+ voteWeight: BN;
232
+ }
233
+
234
+ export interface MilestoneVoteCastEvent {
235
+ projectId: BN;
236
+ milestoneIndex: number;
237
+ voter: PublicKey;
238
+ choice: VoteChoice;
239
+ weight: BN;
240
+ }
241
+
242
+ export interface MilestoneVoteFinalizedEvent {
243
+ projectId: BN;
244
+ milestoneIndex: number;
245
+ passed: boolean;
246
+ yesVotes: BN;
247
+ noVotes: BN;
248
+ }
249
+
250
+ // =============================================================================
251
+ // Utility Types
252
+ // =============================================================================
253
+
254
+ export interface InvestmentWithKey {
255
+ publicKey: PublicKey;
256
+ account: InvestmentAccount;
257
+ }
258
+
259
+ export interface MilestoneWithKey {
260
+ publicKey: PublicKey;
261
+ account: MilestoneAccount;
262
+ }
263
+
264
+ export interface VoteWithKey {
265
+ publicKey: PublicKey;
266
+ account: VoteAccount;
267
+ }