@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
package/README.md ADDED
@@ -0,0 +1,416 @@
1
+ # @raise/sdk
2
+
3
+ TypeScript SDK for the Raise Solana program - a decentralized venture funding platform with milestone-based fund releases.
4
+
5
+ ## Features
6
+
7
+ - **Full Program Coverage** - All 34 instructions wrapped with TypeScript types
8
+ - **PDA Helpers** - Derive all program addresses deterministically
9
+ - **Account Fetchers** - Fetch and decode all account types
10
+ - **Error Handling** - Mapped error codes with helpful messages
11
+ - **Constants** - Investment tiers, timing values, governance parameters
12
+ - **Tree-shakable** - Modular exports for optimal bundle size
13
+ - **Dual Format** - ESM and CJS builds included
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install @raise/sdk
19
+ # or
20
+ yarn add @raise/sdk
21
+ # or
22
+ pnpm add @raise/sdk
23
+ ```
24
+
25
+ ### Peer Dependencies
26
+
27
+ ```bash
28
+ npm install @coral-xyz/anchor @solana/web3.js
29
+ ```
30
+
31
+ ## Quick Start
32
+
33
+ ### Initialize Client
34
+
35
+ ```typescript
36
+ import { Program, AnchorProvider } from '@coral-xyz/anchor';
37
+ import { Connection } from '@solana/web3.js';
38
+ import { RaiseClient, BN } from '@raise/sdk';
39
+ import idl from './idl/raise.json';
40
+
41
+ // Setup connection and provider
42
+ const connection = new Connection('https://api.devnet.solana.com');
43
+ const provider = new AnchorProvider(connection, wallet, {});
44
+
45
+ // Create program instance
46
+ const program = new Program(idl, provider);
47
+
48
+ // Create SDK client
49
+ const client = RaiseClient.fromProgram(program);
50
+ ```
51
+
52
+ ### Create a Project
53
+
54
+ ```typescript
55
+ const projectId = new BN(1);
56
+
57
+ // Initialize project
58
+ const tx = await client.initializeProject({
59
+ projectId,
60
+ fundingGoal: new BN(100_000_000_000), // 100,000 USDC
61
+ metadataUri: 'https://example.com/project.json',
62
+ });
63
+
64
+ console.log('Project created:', tx);
65
+
66
+ // Add milestones
67
+ await client.createMilestone({
68
+ projectId,
69
+ milestoneIndex: 0,
70
+ percentage: 30,
71
+ description: 'MVP Development',
72
+ });
73
+
74
+ await client.createMilestone({
75
+ projectId,
76
+ milestoneIndex: 1,
77
+ percentage: 40,
78
+ description: 'Beta Launch',
79
+ });
80
+
81
+ await client.createMilestone({
82
+ projectId,
83
+ milestoneIndex: 2,
84
+ percentage: 30,
85
+ description: 'Production Release',
86
+ });
87
+
88
+ // Submit for approval
89
+ await client.submitForApproval(projectId);
90
+ ```
91
+
92
+ ### Invest in a Project
93
+
94
+ ```typescript
95
+ import { USDC, getTierFromAmount, InvestmentTier } from '@raise/sdk';
96
+
97
+ const amount = USDC.toAmount(1000); // 1,000 USDC
98
+ const tier = getTierFromAmount(amount);
99
+
100
+ console.log(`Investing ${USDC.fromAmount(amount)} USDC (${tier} tier)`);
101
+
102
+ const tx = await client.invest({
103
+ projectId,
104
+ amount: new BN(amount.toString()),
105
+ investorTokenAccount: myUsdcAccount,
106
+ escrowTokenAccount: projectEscrow,
107
+ });
108
+ ```
109
+
110
+ ### Vote on Milestones
111
+
112
+ ```typescript
113
+ // Vote "Good" on milestone
114
+ await client.voteOnMilestone({
115
+ projectId,
116
+ milestoneIndex: 0,
117
+ nftMint: myInvestmentNft,
118
+ choice: { good: {} },
119
+ });
120
+
121
+ // Finalize voting after period ends
122
+ await client.finalizeVoting(projectId, 0);
123
+ ```
124
+
125
+ ### Fetch Account Data
126
+
127
+ ```typescript
128
+ // Fetch project
129
+ const project = await client.fetchProject(projectId);
130
+ console.log('Project state:', project?.state);
131
+ console.log('Amount raised:', project?.amountRaised.toString());
132
+
133
+ // Fetch all investments
134
+ const investments = await client.fetchAllInvestments(projectId);
135
+ console.log(`Total investors: ${investments.length}`);
136
+
137
+ // Fetch top investors (for veto eligibility)
138
+ const topInvestors = await client.fetchTopInvestors(projectId, 3);
139
+ ```
140
+
141
+ ## Modular Imports
142
+
143
+ Import only what you need for smaller bundles:
144
+
145
+ ```typescript
146
+ // PDAs only
147
+ import { getProjectPDA, getInvestmentPDA } from '@raise/sdk/pdas';
148
+
149
+ // Constants only
150
+ import { TIMING, TIER_MINIMUMS, InvestmentTier } from '@raise/sdk/constants';
151
+
152
+ // Account fetchers only
153
+ import { fetchProject, fetchAllInvestments } from '@raise/sdk/accounts';
154
+
155
+ // Instructions only
156
+ import { invest, voteOnMilestone } from '@raise/sdk/instructions';
157
+
158
+ // Error handling only
159
+ import { parseError, ERROR_CODES } from '@raise/sdk/errors';
160
+
161
+ // Types only
162
+ import type { ProjectAccount, MilestoneAccount } from '@raise/sdk/types';
163
+ ```
164
+
165
+ ## Constants Reference
166
+
167
+ ### Investment Tiers
168
+
169
+ ```typescript
170
+ import {
171
+ InvestmentTier,
172
+ TIER_MINIMUMS,
173
+ TIER_VOTE_MULTIPLIERS,
174
+ USDC
175
+ } from '@raise/sdk';
176
+
177
+ // Tier minimums (in lamports)
178
+ console.log(TIER_MINIMUMS[InvestmentTier.Bronze]); // 100_000_000n (100 USDC)
179
+ console.log(TIER_MINIMUMS[InvestmentTier.Silver]); // 500_000_000n (500 USDC)
180
+ console.log(TIER_MINIMUMS[InvestmentTier.Gold]); // 1_000_000_000n (1,000 USDC)
181
+ console.log(TIER_MINIMUMS[InvestmentTier.Platinum]); // 5_000_000_000n (5,000 USDC)
182
+ console.log(TIER_MINIMUMS[InvestmentTier.Diamond]); // 10_000_000_000n (10,000 USDC)
183
+
184
+ // Vote multipliers
185
+ console.log(TIER_VOTE_MULTIPLIERS[InvestmentTier.Bronze]); // 100 (1.0x)
186
+ console.log(TIER_VOTE_MULTIPLIERS[InvestmentTier.Diamond]); // 300 (3.0x)
187
+ ```
188
+
189
+ ### Timing Constants
190
+
191
+ ```typescript
192
+ import { TIMING } from '@raise/sdk';
193
+
194
+ console.log(TIMING.VOTING_PERIOD_SECONDS); // 1,209,600 (14 days)
195
+ console.log(TIMING.HOLD_PERIOD_SECONDS); // 604,800 (7 days)
196
+ console.log(TIMING.CHALLENGE_PERIOD_SECONDS); // 172,800 (48 hours)
197
+ console.log(TIMING.ABANDONMENT_TIMEOUT_SECONDS); // 7,776,000 (90 days)
198
+ ```
199
+
200
+ ### Governance Parameters
201
+
202
+ ```typescript
203
+ import { GOVERNANCE } from '@raise/sdk';
204
+
205
+ console.log(GOVERNANCE.MILESTONE_APPROVAL_THRESHOLD_PERCENT); // 50 (>50%)
206
+ console.log(GOVERNANCE.SHUTDOWN_THRESHOLD_BPS); // 6600 (66%)
207
+ console.log(GOVERNANCE.SCAM_THRESHOLD_PERCENT); // 30 (30%)
208
+ console.log(GOVERNANCE.CONSECUTIVE_FAILURES_THRESHOLD); // 4
209
+ ```
210
+
211
+ ## Error Handling
212
+
213
+ ```typescript
214
+ import {
215
+ parseError,
216
+ isRaiseError,
217
+ getErrorMessage,
218
+ ERROR_CODES
219
+ } from '@raise/sdk';
220
+
221
+ try {
222
+ await client.invest({ ... });
223
+ } catch (error) {
224
+ const parsed = parseError(error);
225
+
226
+ if (isRaiseError(parsed, ERROR_CODES.InvestmentBelowMinimum)) {
227
+ console.error('Investment too small for minimum tier');
228
+ } else if (isRaiseError(parsed, ERROR_CODES.FundingGoalExceeded)) {
229
+ console.error('Project is fully funded');
230
+ } else {
231
+ console.error(getErrorMessage(parsed));
232
+ }
233
+ }
234
+ ```
235
+
236
+ ## Utility Functions
237
+
238
+ ### Time Helpers
239
+
240
+ ```typescript
241
+ import {
242
+ timeRemaining,
243
+ formatDuration,
244
+ hasTimestampPassed,
245
+ timestampToDate
246
+ } from '@raise/sdk';
247
+
248
+ // Check voting deadline
249
+ const milestone = await client.fetchMilestone(projectId, 0);
250
+ if (milestone?.votingEndsAt) {
251
+ const remaining = timeRemaining(milestone.votingEndsAt);
252
+ console.log(`Time remaining: ${formatDuration(remaining)}`);
253
+ // Output: "Time remaining: 2d 5h 30m"
254
+
255
+ if (hasTimestampPassed(milestone.votingEndsAt)) {
256
+ console.log('Voting period ended');
257
+ }
258
+ }
259
+ ```
260
+
261
+ ### USDC Conversions
262
+
263
+ ```typescript
264
+ import { USDC } from '@raise/sdk';
265
+
266
+ // Convert USDC to lamports
267
+ const lamports = USDC.toAmount(100); // 100_000_000n
268
+
269
+ // Convert lamports to USDC
270
+ const usdc = USDC.fromAmount(100_000_000n); // 100
271
+ ```
272
+
273
+ ### Validation
274
+
275
+ ```typescript
276
+ import {
277
+ validateMilestonePercentages,
278
+ validateMetadataUri
279
+ } from '@raise/sdk';
280
+
281
+ // Validate milestone percentages sum to 100
282
+ const isValid = validateMilestonePercentages([30, 40, 30]); // true
283
+
284
+ // Validate metadata URI
285
+ const isValidUri = validateMetadataUri('https://example.com/project.json');
286
+ ```
287
+
288
+ ## React Integration
289
+
290
+ ```typescript
291
+ import { useMemo } from 'react';
292
+ import { useConnection, useWallet } from '@solana/wallet-adapter-react';
293
+ import { Program, AnchorProvider } from '@coral-xyz/anchor';
294
+ import { RaiseClient } from '@raise/sdk';
295
+ import idl from './idl/raise.json';
296
+
297
+ export function useRaise(): RaiseClient | null {
298
+ const { connection } = useConnection();
299
+ const wallet = useWallet();
300
+
301
+ return useMemo(() => {
302
+ if (!wallet.publicKey || !wallet.signTransaction) {
303
+ return null;
304
+ }
305
+
306
+ const provider = new AnchorProvider(
307
+ connection,
308
+ wallet as any,
309
+ AnchorProvider.defaultOptions()
310
+ );
311
+
312
+ const program = new Program(idl as any, provider);
313
+ return RaiseClient.fromProgram(program);
314
+ }, [connection, wallet]);
315
+ }
316
+
317
+ // Usage in component
318
+ function InvestButton({ projectId }) {
319
+ const client = useRaise();
320
+
321
+ const handleInvest = async () => {
322
+ if (!client) return;
323
+
324
+ const tx = await client.invest({
325
+ projectId: new BN(projectId),
326
+ amount: new BN(100_000_000),
327
+ investorTokenAccount: myUsdcAta,
328
+ escrowTokenAccount: projectEscrow,
329
+ });
330
+
331
+ console.log('Investment tx:', tx);
332
+ };
333
+
334
+ return (
335
+ <button onClick={handleInvest} disabled={!client}>
336
+ Invest
337
+ </button>
338
+ );
339
+ }
340
+ ```
341
+
342
+ ## API Reference
343
+
344
+ ### RaiseClient Methods
345
+
346
+ #### Admin Operations
347
+ - `initializeAdmin(admin)` - Initialize admin config
348
+ - `transferAdmin(newAdmin)` - Propose admin transfer
349
+ - `acceptAdmin()` - Accept admin transfer
350
+
351
+ #### Project Operations
352
+ - `initializeProject(args)` - Create new project
353
+ - `submitForApproval(projectId)` - Submit for admin approval
354
+ - `approveProject(projectId, adminKeypair)` - Approve project
355
+
356
+ #### Milestone Operations
357
+ - `createMilestone(args)` - Add milestone to project
358
+ - `submitMilestone(projectId, index)` - Submit for voting
359
+ - `voteOnMilestone(args)` - Cast vote
360
+ - `finalizeVoting(projectId, index)` - End voting period
361
+ - `claimMilestoneFunds(args)` - Claim funds after passing
362
+
363
+ #### Investment Operations
364
+ - `invest(args)` - Invest USDC, receive NFT
365
+ - `cancelInvestment(args)` - Cancel within 24h cooling-off
366
+
367
+ #### TGE Operations
368
+ - `setTgeDate(args)` - Set token generation date
369
+ - `depositTokens(args)` - Deposit tokens for distribution
370
+ - `claimTokens(args)` - Claim allocated tokens
371
+ - `releaseHoldback(args)` - Release 10% founder holdback
372
+
373
+ #### Governance Operations
374
+ - `initiateShutdownVote(args)` - Start shutdown vote
375
+ - `voteOnShutdown(args)` - Vote on shutdown
376
+ - `finalizeShutdownVote(args)` - Finalize shutdown vote
377
+ - `claimShutdownRefund(args)` - Claim refund after shutdown
378
+
379
+ #### Pivot Operations
380
+ - `proposePivot(args)` - Propose project pivot
381
+ - `approvePivot(projectId, adminKeypair)` - Approve pivot
382
+ - `withdrawFromPivot(args)` - Withdraw during window
383
+ - `finalizePivot(args)` - Finalize after window
384
+
385
+ #### Account Fetchers
386
+ - `fetchProject(projectId)`
387
+ - `fetchMilestone(projectId, index)`
388
+ - `fetchAllMilestones(projectId)`
389
+ - `fetchInvestment(projectId, nftMint)`
390
+ - `fetchAllInvestments(projectId)`
391
+ - `fetchTopInvestors(projectId, count)`
392
+ - `fetchVote(projectId, milestoneIndex, voter)`
393
+ - `fetchWithdrawal(projectId, milestoneIndex)`
394
+ - `fetchPivotProposal(projectId)`
395
+ - `fetchShutdownVote(projectId)`
396
+ - `fetchAdminConfig()`
397
+
398
+ ## Development
399
+
400
+ ```bash
401
+ # Install dependencies
402
+ npm install
403
+
404
+ # Build
405
+ npm run build
406
+
407
+ # Type check
408
+ npm run typecheck
409
+
410
+ # Watch mode
411
+ npm run dev
412
+ ```
413
+
414
+ ## License
415
+
416
+ MIT
@@ -0,0 +1,258 @@
1
+ 'use strict';
2
+
3
+ var web3_js = require('@solana/web3.js');
4
+ var anchor = require('@coral-xyz/anchor');
5
+
6
+ // src/pdas/index.ts
7
+
8
+ // src/constants/index.ts
9
+ var SEEDS = {
10
+ PROJECT: "project",
11
+ MILESTONE: "milestone",
12
+ INVESTMENT: "investment",
13
+ VOTE: "vote",
14
+ PIVOT: "pivot",
15
+ TGE_ESCROW: "tge_escrow",
16
+ ADMIN_CONFIG: "admin-config"};
17
+
18
+ // src/pdas/index.ts
19
+ function ensureBN(value) {
20
+ if (value && typeof value.toArrayLike === "function") {
21
+ return value;
22
+ }
23
+ return new anchor.BN(String(value));
24
+ }
25
+ function getProjectPDA(projectId, programId) {
26
+ const projectIdBN = ensureBN(projectId);
27
+ const [pda] = web3_js.PublicKey.findProgramAddressSync(
28
+ [Buffer.from(SEEDS.PROJECT), projectIdBN.toArrayLike(Buffer, "le", 8)],
29
+ programId
30
+ );
31
+ return pda;
32
+ }
33
+ function getMilestonePDA(projectPda, milestoneIndex, programId) {
34
+ const [pda] = web3_js.PublicKey.findProgramAddressSync(
35
+ [
36
+ Buffer.from(SEEDS.MILESTONE),
37
+ projectPda.toBuffer(),
38
+ Buffer.from([milestoneIndex])
39
+ ],
40
+ programId
41
+ );
42
+ return pda;
43
+ }
44
+ function getInvestmentPDA(projectPda, nftMint, programId) {
45
+ const [pda] = web3_js.PublicKey.findProgramAddressSync(
46
+ [
47
+ Buffer.from(SEEDS.INVESTMENT),
48
+ projectPda.toBuffer(),
49
+ nftMint.toBuffer()
50
+ ],
51
+ programId
52
+ );
53
+ return pda;
54
+ }
55
+ function getVotePDA(milestonePda, voterKey, votingRound, programId) {
56
+ const [pda] = web3_js.PublicKey.findProgramAddressSync(
57
+ [Buffer.from(SEEDS.VOTE), milestonePda.toBuffer(), voterKey.toBuffer(), Buffer.from([votingRound])],
58
+ programId
59
+ );
60
+ return pda;
61
+ }
62
+ function getPivotProposalPDA(projectPda, pivotCount, programId) {
63
+ const [pda] = web3_js.PublicKey.findProgramAddressSync(
64
+ [
65
+ Buffer.from(SEEDS.PIVOT),
66
+ // Use PIVOT seed, not PIVOT_PROPOSAL
67
+ projectPda.toBuffer(),
68
+ Buffer.from([pivotCount])
69
+ // pivot_count is u8 (1 byte) on-chain
70
+ ],
71
+ programId
72
+ );
73
+ return pda;
74
+ }
75
+ function getTgeEscrowPDA(projectPda, programId) {
76
+ const [pda] = web3_js.PublicKey.findProgramAddressSync(
77
+ [Buffer.from(SEEDS.TGE_ESCROW), projectPda.toBuffer()],
78
+ programId
79
+ );
80
+ return pda;
81
+ }
82
+ function getAdminConfigPDA(programId) {
83
+ const [pda] = web3_js.PublicKey.findProgramAddressSync(
84
+ [Buffer.from(SEEDS.ADMIN_CONFIG)],
85
+ programId
86
+ );
87
+ return pda;
88
+ }
89
+
90
+ // src/accounts/index.ts
91
+ function getAccountNamespace(program) {
92
+ return program.account;
93
+ }
94
+ async function fetchProject(program, projectId) {
95
+ try {
96
+ const projectPda = getProjectPDA(projectId, program.programId);
97
+ return await getAccountNamespace(program).project.fetch(projectPda);
98
+ } catch (error) {
99
+ if (error instanceof Error && error.message?.includes("Account does not exist")) {
100
+ return null;
101
+ }
102
+ throw error;
103
+ }
104
+ }
105
+ async function fetchProjectByPda(program, projectPda) {
106
+ try {
107
+ return await getAccountNamespace(program).project.fetch(projectPda);
108
+ } catch (error) {
109
+ if (error instanceof Error && error.message?.includes("Account does not exist")) {
110
+ return null;
111
+ }
112
+ throw error;
113
+ }
114
+ }
115
+ async function fetchMilestone(program, projectId, milestoneIndex) {
116
+ try {
117
+ const projectPda = getProjectPDA(projectId, program.programId);
118
+ const milestonePda = getMilestonePDA(projectPda, milestoneIndex, program.programId);
119
+ return await getAccountNamespace(program).milestone.fetch(milestonePda);
120
+ } catch (error) {
121
+ if (error instanceof Error && error.message?.includes("Account does not exist")) {
122
+ return null;
123
+ }
124
+ throw error;
125
+ }
126
+ }
127
+ async function fetchAllMilestones(program, projectId) {
128
+ const projectPda = getProjectPDA(projectId, program.programId);
129
+ const milestones = await getAccountNamespace(program).milestone.all([
130
+ {
131
+ memcmp: {
132
+ offset: 8,
133
+ // Skip discriminator
134
+ bytes: projectPda.toBase58()
135
+ }
136
+ }
137
+ ]);
138
+ return milestones.map((m) => ({
139
+ publicKey: m.publicKey,
140
+ account: m.account
141
+ }));
142
+ }
143
+ async function fetchInvestment(program, projectId, nftMint) {
144
+ try {
145
+ const projectPda = getProjectPDA(projectId, program.programId);
146
+ const investmentPda = getInvestmentPDA(projectPda, nftMint, program.programId);
147
+ return await getAccountNamespace(program).investment.fetch(investmentPda);
148
+ } catch (error) {
149
+ if (error instanceof Error && error.message?.includes("Account does not exist")) {
150
+ return null;
151
+ }
152
+ throw error;
153
+ }
154
+ }
155
+ async function fetchAllInvestments(program, projectId) {
156
+ const projectPda = getProjectPDA(projectId, program.programId);
157
+ const investments = await getAccountNamespace(program).investment.all([
158
+ {
159
+ memcmp: {
160
+ offset: 8,
161
+ // Skip discriminator
162
+ bytes: projectPda.toBase58()
163
+ }
164
+ }
165
+ ]);
166
+ return investments.map((inv) => ({
167
+ publicKey: inv.publicKey,
168
+ account: inv.account
169
+ }));
170
+ }
171
+ async function fetchVote(program, projectId, milestoneIndex, voterKey, votingRound) {
172
+ try {
173
+ const projectPda = getProjectPDA(projectId, program.programId);
174
+ const milestonePda = getMilestonePDA(projectPda, milestoneIndex, program.programId);
175
+ const votePda = getVotePDA(milestonePda, voterKey, votingRound, program.programId);
176
+ return await getAccountNamespace(program).vote.fetch(votePda);
177
+ } catch (error) {
178
+ if (error instanceof Error && error.message?.includes("Account does not exist")) {
179
+ return null;
180
+ }
181
+ throw error;
182
+ }
183
+ }
184
+ async function fetchAllVotes(program, projectId, milestoneIndex) {
185
+ const projectPda = getProjectPDA(projectId, program.programId);
186
+ const milestonePda = getMilestonePDA(projectPda, milestoneIndex, program.programId);
187
+ const votes = await getAccountNamespace(program).vote.all([
188
+ {
189
+ memcmp: {
190
+ offset: 8,
191
+ // Skip discriminator
192
+ bytes: milestonePda.toBase58()
193
+ }
194
+ }
195
+ ]);
196
+ return votes.map((v) => ({
197
+ publicKey: v.publicKey,
198
+ account: v.account
199
+ }));
200
+ }
201
+ async function fetchPivotProposal(program, projectId) {
202
+ try {
203
+ const projectPda = getProjectPDA(projectId, program.programId);
204
+ const projectAccount = await getAccountNamespace(program).project.fetch(projectPda);
205
+ let pivotPda;
206
+ if (projectAccount.activePivot) {
207
+ pivotPda = projectAccount.activePivot;
208
+ } else {
209
+ const pivotCount = projectAccount.pivotCount || 0;
210
+ pivotPda = getPivotProposalPDA(projectPda, pivotCount, program.programId);
211
+ }
212
+ return await getAccountNamespace(program).pivotProposal.fetch(pivotPda);
213
+ } catch (error) {
214
+ if (error instanceof Error && error.message?.includes("Account does not exist")) {
215
+ return null;
216
+ }
217
+ throw error;
218
+ }
219
+ }
220
+ async function fetchTgeEscrow(program, projectId) {
221
+ try {
222
+ const projectPda = getProjectPDA(projectId, program.programId);
223
+ const tgeEscrowPda = getTgeEscrowPDA(projectPda, program.programId);
224
+ return await getAccountNamespace(program).tgeEscrow.fetch(tgeEscrowPda);
225
+ } catch (error) {
226
+ if (error instanceof Error && error.message?.includes("Account does not exist")) {
227
+ return null;
228
+ }
229
+ throw error;
230
+ }
231
+ }
232
+ async function fetchAdminConfig(program) {
233
+ const adminConfigPda = getAdminConfigPDA(program.programId);
234
+ return await getAccountNamespace(program).adminConfig.fetch(adminConfigPda);
235
+ }
236
+ async function accountExists(program, accountType, pda) {
237
+ try {
238
+ await program.account[accountType].fetch(pda);
239
+ return true;
240
+ } catch {
241
+ return false;
242
+ }
243
+ }
244
+
245
+ exports.accountExists = accountExists;
246
+ exports.fetchAdminConfig = fetchAdminConfig;
247
+ exports.fetchAllInvestments = fetchAllInvestments;
248
+ exports.fetchAllMilestones = fetchAllMilestones;
249
+ exports.fetchAllVotes = fetchAllVotes;
250
+ exports.fetchInvestment = fetchInvestment;
251
+ exports.fetchMilestone = fetchMilestone;
252
+ exports.fetchPivotProposal = fetchPivotProposal;
253
+ exports.fetchProject = fetchProject;
254
+ exports.fetchProjectByPda = fetchProjectByPda;
255
+ exports.fetchTgeEscrow = fetchTgeEscrow;
256
+ exports.fetchVote = fetchVote;
257
+ //# sourceMappingURL=index.cjs.map
258
+ //# sourceMappingURL=index.cjs.map