@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 @@
1
+ {"version":3,"sources":["../../src/constants/index.ts","../../src/pdas/index.ts","../../src/accounts/index.ts"],"names":["BN","PublicKey"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Raise Constants\n *\n * Mirrors the on-chain program constants for client-side validation\n * and display purposes.\n */\n\n// =============================================================================\n// PDA Seeds\n// =============================================================================\n\nexport const SEEDS = {\n PROJECT: 'project',\n MILESTONE: 'milestone',\n INVESTMENT: 'investment',\n VOTE: 'vote',\n ESCROW: 'escrow',\n PIVOT: 'pivot',\n PIVOT_PROPOSAL: 'pivot_proposal',\n TGE_ESCROW: 'tge_escrow',\n TGE_ESCROW_VAULT: 'tge_escrow_vault',\n SCAM_REPORT: 'scam_report',\n ADMIN_CONFIG: 'admin-config',\n NFT_MINT: 'nft_mint',\n AUTHORITY: 'authority',\n} as const;\n\n// =============================================================================\n// Validation Constants\n// =============================================================================\n\nexport const VALIDATION = {\n /** Minimum number of milestones per project */\n MIN_MILESTONES: 2,\n /** Maximum number of milestones per project */\n MAX_MILESTONES: 10,\n /** Milestone percentages must sum to this value */\n MILESTONE_PERCENTAGE_SUM: 100,\n /** Maximum funding buffer (110% of goal) */\n MAX_FUNDING_BUFFER_PERCENT: 110,\n /** Maximum metadata URI length */\n MAX_METADATA_URI_LENGTH: 200,\n /** Maximum pivot description length */\n MAX_PIVOT_DESCRIPTION_LEN: 256,\n /** Maximum pivot vision length */\n MAX_PIVOT_VISION_LEN: 512,\n /** Maximum pivot justification length */\n MAX_PIVOT_JUSTIFICATION_LEN: 512,\n} as const;\n\n// =============================================================================\n// Timing Constants (in seconds)\n// =============================================================================\n\nexport const TIMING = {\n /** Production voting period (14 days) */\n VOTING_PERIOD_SECONDS: 1_209_600,\n /** Production hold period (7 days) */\n HOLD_PERIOD_SECONDS: 604_800,\n /** Inactivity timeout (90 days) */\n INACTIVITY_TIMEOUT_SECONDS: 7_776_000,\n /** Abandonment timeout (90 days) */\n ABANDONMENT_TIMEOUT_SECONDS: 7_776_000,\n /** Refund window (14 days) */\n REFUND_WINDOW_SECONDS: 1_209_600,\n /** Pivot withdrawal window (7 days) */\n PIVOT_WITHDRAWAL_WINDOW_SECONDS: 604_800,\n /** Minimum TGE date (15 days from now) */\n TGE_MIN_DAYS: 1_296_000,\n /** Maximum TGE date (90 days from now) */\n TGE_MAX_DAYS: 7_776_000,\n /** Post-TGE holdback period (30 days) */\n POST_TGE_HOLDBACK_DAYS: 2_592_000,\n} as const;\n\n// =============================================================================\n// Tier Configuration Constraints\n// =============================================================================\n\nexport const TIER_CONSTRAINTS = {\n /** Minimum number of tiers */\n MIN_TIERS: 1,\n /** Maximum number of tiers */\n MAX_TIERS: 10,\n /** Minimum tier amount (10 USDC in lamports) */\n MIN_TIER_AMOUNT: 10_000_000n,\n /** Minimum max_lots per tier */\n MIN_TIER_MAX_LOTS: 1,\n /** Minimum token ratio */\n MIN_TIER_TOKEN_RATIO: 1n,\n /** Minimum vote multiplier (100 = 1.0x) */\n MIN_TIER_VOTE_MULTIPLIER: 100,\n} as const;\n\n// =============================================================================\n// Investment Tiers (Legacy - kept for backwards compatibility)\n// =============================================================================\n\nexport enum InvestmentTier {\n Bronze = 'Bronze',\n Silver = 'Silver',\n Gold = 'Gold',\n Platinum = 'Platinum',\n Diamond = 'Diamond',\n}\n\n/** Investment tier minimum amounts in USDC lamports (6 decimals) - LEGACY */\nexport const TIER_MINIMUMS = {\n [InvestmentTier.Bronze]: 100_000_000n, // 100 USDC\n [InvestmentTier.Silver]: 500_000_000n, // 500 USDC\n [InvestmentTier.Gold]: 1_000_000_000n, // 1,000 USDC\n [InvestmentTier.Platinum]: 5_000_000_000n, // 5,000 USDC\n [InvestmentTier.Diamond]: 10_000_000_000n, // 10,000 USDC\n} as const;\n\n/** Vote weight multipliers (scaled by 100) - LEGACY */\nexport const TIER_VOTE_MULTIPLIERS = {\n [InvestmentTier.Bronze]: 100, // 1.0x\n [InvestmentTier.Silver]: 120, // 1.2x\n [InvestmentTier.Gold]: 150, // 1.5x\n [InvestmentTier.Platinum]: 200, // 2.0x\n [InvestmentTier.Diamond]: 300, // 3.0x\n} as const;\n\n/** Token allocation multipliers (same as vote multipliers) - LEGACY */\nexport const TIER_TOKEN_MULTIPLIERS = {\n [InvestmentTier.Bronze]: 100,\n [InvestmentTier.Silver]: 120,\n [InvestmentTier.Gold]: 150,\n [InvestmentTier.Platinum]: 200,\n [InvestmentTier.Diamond]: 300,\n} as const;\n\n/** Get tier from investment amount (in lamports) - LEGACY, use project.tiers instead */\nexport function getTierFromAmount(amount: bigint): InvestmentTier {\n if (amount >= TIER_MINIMUMS[InvestmentTier.Diamond]) return InvestmentTier.Diamond;\n if (amount >= TIER_MINIMUMS[InvestmentTier.Platinum]) return InvestmentTier.Platinum;\n if (amount >= TIER_MINIMUMS[InvestmentTier.Gold]) return InvestmentTier.Gold;\n if (amount >= TIER_MINIMUMS[InvestmentTier.Silver]) return InvestmentTier.Silver;\n return InvestmentTier.Bronze;\n}\n\n/** Get vote multiplier for an investment amount - LEGACY */\nexport function getVoteMultiplier(amount: bigint): number {\n const tier = getTierFromAmount(amount);\n return TIER_VOTE_MULTIPLIERS[tier] / 100;\n}\n\n/** Get token multiplier for an investment amount - LEGACY */\nexport function getTokenMultiplier(amount: bigint): number {\n const tier = getTierFromAmount(amount);\n return TIER_TOKEN_MULTIPLIERS[tier] / 100;\n}\n\n/**\n * Find matching tier index for an investment amount (threshold-based)\n * Returns the highest tier where amount >= tier.amount\n */\nexport function findTierIndex(tiers: Array<{ amount: bigint }>, amount: bigint): number | null {\n for (let i = tiers.length - 1; i >= 0; i--) {\n if (amount >= tiers[i].amount) {\n return i;\n }\n }\n return null;\n}\n\n// =============================================================================\n// Voting and Governance\n// =============================================================================\n\nexport const GOVERNANCE = {\n /** Scam report threshold (30%) */\n SCAM_THRESHOLD_PERCENT: 30,\n /** Consecutive milestone failures before exit window eligible */\n CONSECUTIVE_FAILURES_THRESHOLD: 3,\n /** Milestone approval threshold (>50% weighted approval per whitepaper voting.md:100-101) */\n MILESTONE_APPROVAL_THRESHOLD_PERCENT: 50,\n} as const;\n\n// =============================================================================\n// NFT Constants\n// =============================================================================\n\nexport const NFT = {\n /** NFT symbol */\n SYMBOL: 'SNI',\n /** NFT name prefix */\n NAME_PREFIX: 'Raise Investment #',\n /** Royalty basis points (2%) */\n ROYALTY_BASIS_POINTS: 200,\n} as const;\n\n// =============================================================================\n// USDC Constants\n// =============================================================================\n\nexport const USDC = {\n /** USDC decimals */\n DECIMALS: 6,\n /** Convert USDC to lamports */\n toAmount: (usdc: number): bigint => BigInt(Math.floor(usdc * 10 ** 6)),\n /** Convert lamports to USDC */\n fromAmount: (lamports: bigint): number => Number(lamports) / 10 ** 6,\n} as const;\n","/**\n * Raise PDA Derivation Helpers\n *\n * All PDA derivation functions for the Raise program.\n * PDAs are deterministic addresses derived from seeds and program ID.\n */\n\nimport { PublicKey } from '@solana/web3.js';\nimport { BN } from '@coral-xyz/anchor';\nimport { SEEDS } from '../constants/index.js';\n\n/**\n * Ensure value is a proper BN instance\n * This handles cases where BN objects lose their prototype chain\n * (e.g., when passing through React state or JSON serialization)\n *\n * Uses duck typing instead of instanceof to handle different BN module instances\n */\nfunction ensureBN(value: BN | number | string | { toString(): string }): BN {\n // Duck typing: if it has toArrayLike, it's BN-like and we can use it\n if (value && typeof (value as BN).toArrayLike === 'function') {\n return value as BN;\n }\n // Always create a fresh BN from the SDK's imported BN class\n return new BN(String(value));\n}\n\n/**\n * Derive Project PDA from project ID\n *\n * @param projectId - Unique project identifier\n * @param programId - Raise program ID\n * @returns Project account PDA\n */\nexport function getProjectPDA(projectId: BN | number | string, programId: PublicKey): PublicKey {\n const projectIdBN = ensureBN(projectId);\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from(SEEDS.PROJECT), projectIdBN.toArrayLike(Buffer, 'le', 8)],\n programId\n );\n return pda;\n}\n\n/**\n * Derive Escrow PDA from project ID\n *\n * @param projectId - Project identifier\n * @param programId - Raise program ID\n * @returns Escrow account PDA\n */\nexport function getEscrowPDA(projectId: BN | number | string, programId: PublicKey): PublicKey {\n const projectIdBN = ensureBN(projectId);\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from(SEEDS.ESCROW), projectIdBN.toArrayLike(Buffer, 'le', 8)],\n programId\n );\n return pda;\n}\n\n/**\n * Derive Milestone PDA from project PDA and milestone index\n *\n * @param projectPda - Project account PDA\n * @param milestoneIndex - Milestone index (0-based)\n * @param programId - Raise program ID\n * @returns Milestone account PDA\n */\nexport function getMilestonePDA(\n projectPda: PublicKey,\n milestoneIndex: number,\n programId: PublicKey\n): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [\n Buffer.from(SEEDS.MILESTONE),\n projectPda.toBuffer(),\n Buffer.from([milestoneIndex]),\n ],\n programId\n );\n return pda;\n}\n\n/**\n * Derive Investment PDA from project PDA and NFT mint\n *\n * @param projectPda - Project account PDA\n * @param nftMint - Investment NFT mint address\n * @param programId - Raise program ID\n * @returns Investment account PDA\n */\nexport function getInvestmentPDA(\n projectPda: PublicKey,\n nftMint: PublicKey,\n programId: PublicKey\n): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [\n Buffer.from(SEEDS.INVESTMENT),\n projectPda.toBuffer(),\n nftMint.toBuffer(),\n ],\n programId\n );\n return pda;\n}\n\n/**\n * Derive Vote PDA from milestone PDA, voter key, and voting round\n *\n * @param milestonePda - Milestone account PDA\n * @param voterKey - Voter's public key\n * @param votingRound - Current voting round (0 initially, incremented on resubmit)\n * @param programId - Raise program ID\n * @returns Vote account PDA\n */\nexport function getVotePDA(\n milestonePda: PublicKey,\n voterKey: PublicKey,\n votingRound: number,\n programId: PublicKey\n): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from(SEEDS.VOTE), milestonePda.toBuffer(), voterKey.toBuffer(), Buffer.from([votingRound])],\n programId\n );\n return pda;\n}\n\n/**\n * Derive PivotProposal PDA from project PDA and pivot count\n *\n * @param projectPda - Project account PDA\n * @param pivotCount - Current pivot count from project account\n * @param programId - Raise program ID\n * @returns PivotProposal account PDA\n */\nexport function getPivotProposalPDA(\n projectPda: PublicKey,\n pivotCount: number,\n programId: PublicKey\n): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [\n Buffer.from(SEEDS.PIVOT), // Use PIVOT seed, not PIVOT_PROPOSAL\n projectPda.toBuffer(),\n Buffer.from([pivotCount]), // pivot_count is u8 (1 byte) on-chain\n ],\n programId\n );\n return pda;\n}\n\n/**\n * Derive TgeEscrow PDA from project PDA\n *\n * @param projectPda - Project account PDA\n * @param programId - Raise program ID\n * @returns TgeEscrow account PDA\n */\nexport function getTgeEscrowPDA(\n projectPda: PublicKey,\n programId: PublicKey\n): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from(SEEDS.TGE_ESCROW), projectPda.toBuffer()],\n programId\n );\n return pda;\n}\n\n/**\n * Derive TgeEscrowVault PDA from project PDA\n * Used for holding 10% USDC holdback from final milestone\n *\n * @param projectPda - Project account PDA\n * @param programId - Raise program ID\n * @returns TgeEscrowVault PDA\n */\nexport function getTgeEscrowVaultPDA(\n projectPda: PublicKey,\n programId: PublicKey\n): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from(SEEDS.TGE_ESCROW_VAULT), projectPda.toBuffer()],\n programId\n );\n return pda;\n}\n\n/**\n * Derive TokenVault PDA from project PDA\n * Used for holding project tokens for investor distribution\n *\n * @param projectPda - Project account PDA\n * @param programId - Raise program ID\n * @returns TokenVault PDA\n */\nexport function getTokenVaultPDA(\n projectPda: PublicKey,\n programId: PublicKey\n): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from('token_vault'), projectPda.toBuffer()],\n programId\n );\n return pda;\n}\n\n/**\n * Derive ScamReport PDA from project PDA and NFT mint\n *\n * @param projectPda - Project account PDA\n * @param nftMint - Reporter's NFT mint address\n * @param programId - Raise program ID\n * @returns ScamReport account PDA\n */\nexport function getScamReportPDA(\n projectPda: PublicKey,\n nftMint: PublicKey,\n programId: PublicKey\n): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [\n Buffer.from(SEEDS.SCAM_REPORT),\n projectPda.toBuffer(),\n nftMint.toBuffer(),\n ],\n programId\n );\n return pda;\n}\n\n/**\n * Derive AdminConfig PDA (global admin authority)\n *\n * @param programId - Raise program ID\n * @returns AdminConfig account PDA\n */\nexport function getAdminConfigPDA(programId: PublicKey): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from(SEEDS.ADMIN_CONFIG)],\n programId\n );\n return pda;\n}\n\n/**\n * Derive NFT Mint PDA\n *\n * @param projectId - Project identifier\n * @param investor - Investor's public key\n * @param investmentCount - Investment count (u64 in Rust, 8 bytes LE)\n * @param programId - Raise program ID\n * @returns NFT Mint PDA and bump\n */\nexport function getNftMintPDA(\n projectId: BN | number | string,\n investor: PublicKey,\n investmentCount: BN | number,\n programId: PublicKey\n): [PublicKey, number] {\n // Ensure both values are proper BN instances (handles prototype chain issues)\n const projectIdBN = ensureBN(projectId);\n const countBN = ensureBN(investmentCount);\n return PublicKey.findProgramAddressSync(\n [\n Buffer.from(SEEDS.NFT_MINT),\n projectIdBN.toArrayLike(Buffer, 'le', 8),\n investor.toBuffer(),\n countBN.toArrayLike(Buffer, 'le', 8), // u64 is 8 bytes LE\n ],\n programId\n );\n}\n\n/**\n * Derive Program Authority PDA\n *\n * @param programId - Raise program ID\n * @returns Program authority PDA and bump\n */\nexport function getProgramAuthorityPDA(programId: PublicKey): [PublicKey, number] {\n return PublicKey.findProgramAddressSync(\n [Buffer.from(SEEDS.AUTHORITY)],\n programId\n );\n}\n\n/**\n * Helper to derive all PDAs for a project\n *\n * @param projectId - Project identifier\n * @param programId - Raise program ID\n * @returns Object with project and escrow PDAs\n */\nexport function getProjectPDAs(projectId: BN, programId: PublicKey) {\n const project = getProjectPDA(projectId, programId);\n const escrow = getEscrowPDA(projectId, programId);\n return { project, escrow };\n}\n\n// =============================================================================\n// ZTM v2.0 PDAs\n// =============================================================================\n\n/**\n * Derive Tokenomics PDA from project PDA\n */\nexport function getTokenomicsPDA(projectPda: PublicKey, programId: PublicKey): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from('tokenomics'), projectPda.toBuffer()],\n programId\n );\n return pda;\n}\n\n/**\n * Derive Token Mint PDA from project PDA\n */\nexport function getTokenMintPDA(projectPda: PublicKey, programId: PublicKey): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from('token_mint'), projectPda.toBuffer()],\n programId\n );\n return pda;\n}\n\n/**\n * Derive Vault Authority PDA from project PDA\n */\nexport function getVaultAuthorityPDA(projectPda: PublicKey, programId: PublicKey): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from('vault_authority'), projectPda.toBuffer()],\n programId\n );\n return pda;\n}\n\n/**\n * Derive Investor Vault PDA from project PDA\n */\nexport function getInvestorVaultPDA(projectPda: PublicKey, programId: PublicKey): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from('investor_vault'), projectPda.toBuffer()],\n programId\n );\n return pda;\n}\n\n/**\n * Derive Founder Vault PDA from project PDA\n */\nexport function getFounderVaultPDA(projectPda: PublicKey, programId: PublicKey): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from('founder_vault'), projectPda.toBuffer()],\n programId\n );\n return pda;\n}\n\n/**\n * Derive LP Token Vault PDA from project PDA\n */\nexport function getLpTokenVaultPDA(projectPda: PublicKey, programId: PublicKey): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from('lp_token_vault'), projectPda.toBuffer()],\n programId\n );\n return pda;\n}\n\n/**\n * Derive Treasury Vault PDA from project PDA\n */\nexport function getTreasuryVaultPDA(projectPda: PublicKey, programId: PublicKey): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from('treasury_vault'), projectPda.toBuffer()],\n programId\n );\n return pda;\n}\n\n/**\n * Derive LP USDC Vault PDA from project PDA\n */\nexport function getLpUsdcVaultPDA(projectPda: PublicKey, programId: PublicKey): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from('lp_usdc_vault'), projectPda.toBuffer()],\n programId\n );\n return pda;\n}\n\n/**\n * Derive Founder Vesting PDA from project PDA\n */\nexport function getFounderVestingPDA(projectPda: PublicKey, programId: PublicKey): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from('founder_vesting'), projectPda.toBuffer()],\n programId\n );\n return pda;\n}\n","/**\n * Raise Account Fetchers\n *\n * Functions to fetch and decode program accounts.\n */\n\nimport { Program, BN } from '@coral-xyz/anchor';\nimport { PublicKey } from '@solana/web3.js';\nimport {\n getProjectPDA,\n getMilestonePDA,\n getInvestmentPDA,\n getVotePDA,\n getPivotProposalPDA,\n getTgeEscrowPDA,\n getAdminConfigPDA,\n} from '../pdas/index.js';\nimport type { InvestmentWithKey, MilestoneWithKey, VoteWithKey } from '../types/index.js';\n\n// Generic type for any Anchor program\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyProgram = Program<any>;\n\n// Helper to access account namespace dynamically\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction getAccountNamespace(program: AnyProgram): any {\n return program.account;\n}\n\n/**\n * Fetch project account data\n *\n * @param program - Anchor program instance\n * @param projectId - Project identifier\n * @returns Project account data or null if not found\n */\nexport async function fetchProject(\n program: AnyProgram,\n projectId: BN\n) {\n try {\n const projectPda = getProjectPDA(projectId, program.programId);\n return await getAccountNamespace(program).project.fetch(projectPda);\n } catch (error) {\n if (error instanceof Error && error.message?.includes('Account does not exist')) {\n return null;\n }\n throw error;\n }\n}\n\n/**\n * Fetch project account by PDA\n *\n * @param program - Anchor program instance\n * @param projectPda - Project account PDA\n * @returns Project account data or null if not found\n */\nexport async function fetchProjectByPda(\n program: AnyProgram,\n projectPda: PublicKey\n) {\n try {\n return await getAccountNamespace(program).project.fetch(projectPda);\n } catch (error) {\n if (error instanceof Error && error.message?.includes('Account does not exist')) {\n return null;\n }\n throw error;\n }\n}\n\n/**\n * Fetch milestone account data\n *\n * @param program - Anchor program instance\n * @param projectId - Project identifier\n * @param milestoneIndex - Milestone index\n * @returns Milestone account data or null if not found\n */\nexport async function fetchMilestone(\n program: AnyProgram,\n projectId: BN,\n milestoneIndex: number\n) {\n try {\n const projectPda = getProjectPDA(projectId, program.programId);\n const milestonePda = getMilestonePDA(projectPda, milestoneIndex, program.programId);\n return await getAccountNamespace(program).milestone.fetch(milestonePda);\n } catch (error) {\n if (error instanceof Error && error.message?.includes('Account does not exist')) {\n return null;\n }\n throw error;\n }\n}\n\n/**\n * Fetch all milestones for a project\n *\n * @param program - Anchor program instance\n * @param projectId - Project identifier\n * @returns Array of milestone accounts with their public keys\n */\nexport async function fetchAllMilestones(\n program: AnyProgram,\n projectId: BN\n): Promise<MilestoneWithKey[]> {\n const projectPda = getProjectPDA(projectId, program.programId);\n\n const milestones = await getAccountNamespace(program).milestone.all([\n {\n memcmp: {\n offset: 8, // Skip discriminator\n bytes: projectPda.toBase58(),\n },\n },\n ]);\n\n return milestones.map((m: { publicKey: PublicKey; account: unknown }) => ({\n publicKey: m.publicKey,\n account: m.account,\n })) as MilestoneWithKey[];\n}\n\n/**\n * Fetch investment account data\n *\n * @param program - Anchor program instance\n * @param projectId - Project identifier\n * @param nftMint - Investment NFT mint address\n * @returns Investment account data or null if not found\n */\nexport async function fetchInvestment(\n program: AnyProgram,\n projectId: BN,\n nftMint: PublicKey\n) {\n try {\n const projectPda = getProjectPDA(projectId, program.programId);\n const investmentPda = getInvestmentPDA(projectPda, nftMint, program.programId);\n return await getAccountNamespace(program).investment.fetch(investmentPda);\n } catch (error) {\n if (error instanceof Error && error.message?.includes('Account does not exist')) {\n return null;\n }\n throw error;\n }\n}\n\n/**\n * Fetch all investments for a project\n *\n * @param program - Anchor program instance\n * @param projectId - Project identifier\n * @returns Array of investment accounts with their public keys\n */\nexport async function fetchAllInvestments(\n program: AnyProgram,\n projectId: BN\n): Promise<InvestmentWithKey[]> {\n const projectPda = getProjectPDA(projectId, program.programId);\n\n const investments = await getAccountNamespace(program).investment.all([\n {\n memcmp: {\n offset: 8, // Skip discriminator\n bytes: projectPda.toBase58(),\n },\n },\n ]);\n\n return investments.map((inv: { publicKey: PublicKey; account: unknown }) => ({\n publicKey: inv.publicKey,\n account: inv.account,\n })) as InvestmentWithKey[];\n}\n\n/**\n * Fetch vote account data\n *\n * @param program - Anchor program instance\n * @param projectId - Project identifier\n * @param milestoneIndex - Milestone index\n * @param voterKey - Voter's public key\n * @param votingRound - Current voting round (0 initially, incremented on resubmit)\n * @returns Vote account data or null if not found\n */\nexport async function fetchVote(\n program: AnyProgram,\n projectId: BN,\n milestoneIndex: number,\n voterKey: PublicKey,\n votingRound: number\n) {\n try {\n const projectPda = getProjectPDA(projectId, program.programId);\n const milestonePda = getMilestonePDA(projectPda, milestoneIndex, program.programId);\n const votePda = getVotePDA(milestonePda, voterKey, votingRound, program.programId);\n return await getAccountNamespace(program).vote.fetch(votePda);\n } catch (error) {\n if (error instanceof Error && error.message?.includes('Account does not exist')) {\n return null;\n }\n throw error;\n }\n}\n\n/**\n * Fetch all votes for a milestone\n *\n * @param program - Anchor program instance\n * @param projectId - Project identifier\n * @param milestoneIndex - Milestone index\n * @returns Array of vote accounts with their public keys\n */\nexport async function fetchAllVotes(\n program: AnyProgram,\n projectId: BN,\n milestoneIndex: number\n): Promise<VoteWithKey[]> {\n const projectPda = getProjectPDA(projectId, program.programId);\n const milestonePda = getMilestonePDA(projectPda, milestoneIndex, program.programId);\n\n const votes = await getAccountNamespace(program).vote.all([\n {\n memcmp: {\n offset: 8, // Skip discriminator\n bytes: milestonePda.toBase58(),\n },\n },\n ]);\n\n return votes.map((v: { publicKey: PublicKey; account: unknown }) => ({\n publicKey: v.publicKey,\n account: v.account,\n })) as VoteWithKey[];\n}\n\n/**\n * Fetch pivot proposal account data\n *\n * @param program - Anchor program instance\n * @param projectId - Project identifier\n * @returns PivotProposal account data or null if not found\n */\nexport async function fetchPivotProposal(\n program: AnyProgram,\n projectId: BN\n) {\n try {\n const projectPda = getProjectPDA(projectId, program.programId);\n\n // First fetch the project to get the active pivot or pivot_count\n const projectAccount = await getAccountNamespace(program).project.fetch(projectPda);\n\n // Use active_pivot if available, otherwise derive from pivot_count\n let pivotPda;\n if (projectAccount.activePivot) {\n pivotPda = projectAccount.activePivot;\n } else {\n const pivotCount = projectAccount.pivotCount || 0;\n pivotPda = getPivotProposalPDA(projectPda, pivotCount, program.programId);\n }\n\n return await getAccountNamespace(program).pivotProposal.fetch(pivotPda);\n } catch (error) {\n if (error instanceof Error && error.message?.includes('Account does not exist')) {\n return null;\n }\n throw error;\n }\n}\n\n/**\n * Fetch TGE escrow account data\n *\n * @param program - Anchor program instance\n * @param projectId - Project identifier\n * @returns TgeEscrow account data or null if not found\n */\nexport async function fetchTgeEscrow(\n program: AnyProgram,\n projectId: BN\n) {\n try {\n const projectPda = getProjectPDA(projectId, program.programId);\n const tgeEscrowPda = getTgeEscrowPDA(projectPda, program.programId);\n return await getAccountNamespace(program).tgeEscrow.fetch(tgeEscrowPda);\n } catch (error) {\n if (error instanceof Error && error.message?.includes('Account does not exist')) {\n return null;\n }\n throw error;\n }\n}\n\n/**\n * Fetch admin config account data\n *\n * @param program - Anchor program instance\n * @returns AdminConfig account data\n */\nexport async function fetchAdminConfig(program: AnyProgram) {\n const adminConfigPda = getAdminConfigPDA(program.programId);\n return await getAccountNamespace(program).adminConfig.fetch(adminConfigPda);\n}\n\n/**\n * Check if an account exists\n *\n * @param program - Anchor program instance\n * @param accountType - Account type name\n * @param pda - Account PDA\n * @returns True if account exists\n */\nexport async function accountExists(\n program: AnyProgram,\n accountType: string,\n pda: PublicKey\n): Promise<boolean> {\n try {\n // @ts-expect-error - dynamic account access\n await program.account[accountType].fetch(pda);\n return true;\n } catch {\n return false;\n }\n}\n"]}
@@ -0,0 +1,115 @@
1
+ import { Program, BN } from '@coral-xyz/anchor';
2
+ import { PublicKey } from '@solana/web3.js';
3
+ import { MilestoneWithKey, InvestmentWithKey, VoteWithKey } from '../types/index.cjs';
4
+
5
+ /**
6
+ * Raise Account Fetchers
7
+ *
8
+ * Functions to fetch and decode program accounts.
9
+ */
10
+
11
+ type AnyProgram = Program<any>;
12
+ /**
13
+ * Fetch project account data
14
+ *
15
+ * @param program - Anchor program instance
16
+ * @param projectId - Project identifier
17
+ * @returns Project account data or null if not found
18
+ */
19
+ declare function fetchProject(program: AnyProgram, projectId: BN): Promise<any>;
20
+ /**
21
+ * Fetch project account by PDA
22
+ *
23
+ * @param program - Anchor program instance
24
+ * @param projectPda - Project account PDA
25
+ * @returns Project account data or null if not found
26
+ */
27
+ declare function fetchProjectByPda(program: AnyProgram, projectPda: PublicKey): Promise<any>;
28
+ /**
29
+ * Fetch milestone account data
30
+ *
31
+ * @param program - Anchor program instance
32
+ * @param projectId - Project identifier
33
+ * @param milestoneIndex - Milestone index
34
+ * @returns Milestone account data or null if not found
35
+ */
36
+ declare function fetchMilestone(program: AnyProgram, projectId: BN, milestoneIndex: number): Promise<any>;
37
+ /**
38
+ * Fetch all milestones for a project
39
+ *
40
+ * @param program - Anchor program instance
41
+ * @param projectId - Project identifier
42
+ * @returns Array of milestone accounts with their public keys
43
+ */
44
+ declare function fetchAllMilestones(program: AnyProgram, projectId: BN): Promise<MilestoneWithKey[]>;
45
+ /**
46
+ * Fetch investment account data
47
+ *
48
+ * @param program - Anchor program instance
49
+ * @param projectId - Project identifier
50
+ * @param nftMint - Investment NFT mint address
51
+ * @returns Investment account data or null if not found
52
+ */
53
+ declare function fetchInvestment(program: AnyProgram, projectId: BN, nftMint: PublicKey): Promise<any>;
54
+ /**
55
+ * Fetch all investments for a project
56
+ *
57
+ * @param program - Anchor program instance
58
+ * @param projectId - Project identifier
59
+ * @returns Array of investment accounts with their public keys
60
+ */
61
+ declare function fetchAllInvestments(program: AnyProgram, projectId: BN): Promise<InvestmentWithKey[]>;
62
+ /**
63
+ * Fetch vote account data
64
+ *
65
+ * @param program - Anchor program instance
66
+ * @param projectId - Project identifier
67
+ * @param milestoneIndex - Milestone index
68
+ * @param voterKey - Voter's public key
69
+ * @param votingRound - Current voting round (0 initially, incremented on resubmit)
70
+ * @returns Vote account data or null if not found
71
+ */
72
+ declare function fetchVote(program: AnyProgram, projectId: BN, milestoneIndex: number, voterKey: PublicKey, votingRound: number): Promise<any>;
73
+ /**
74
+ * Fetch all votes for a milestone
75
+ *
76
+ * @param program - Anchor program instance
77
+ * @param projectId - Project identifier
78
+ * @param milestoneIndex - Milestone index
79
+ * @returns Array of vote accounts with their public keys
80
+ */
81
+ declare function fetchAllVotes(program: AnyProgram, projectId: BN, milestoneIndex: number): Promise<VoteWithKey[]>;
82
+ /**
83
+ * Fetch pivot proposal account data
84
+ *
85
+ * @param program - Anchor program instance
86
+ * @param projectId - Project identifier
87
+ * @returns PivotProposal account data or null if not found
88
+ */
89
+ declare function fetchPivotProposal(program: AnyProgram, projectId: BN): Promise<any>;
90
+ /**
91
+ * Fetch TGE escrow account data
92
+ *
93
+ * @param program - Anchor program instance
94
+ * @param projectId - Project identifier
95
+ * @returns TgeEscrow account data or null if not found
96
+ */
97
+ declare function fetchTgeEscrow(program: AnyProgram, projectId: BN): Promise<any>;
98
+ /**
99
+ * Fetch admin config account data
100
+ *
101
+ * @param program - Anchor program instance
102
+ * @returns AdminConfig account data
103
+ */
104
+ declare function fetchAdminConfig(program: AnyProgram): Promise<any>;
105
+ /**
106
+ * Check if an account exists
107
+ *
108
+ * @param program - Anchor program instance
109
+ * @param accountType - Account type name
110
+ * @param pda - Account PDA
111
+ * @returns True if account exists
112
+ */
113
+ declare function accountExists(program: AnyProgram, accountType: string, pda: PublicKey): Promise<boolean>;
114
+
115
+ export { accountExists, fetchAdminConfig, fetchAllInvestments, fetchAllMilestones, fetchAllVotes, fetchInvestment, fetchMilestone, fetchPivotProposal, fetchProject, fetchProjectByPda, fetchTgeEscrow, fetchVote };
@@ -0,0 +1,115 @@
1
+ import { Program, BN } from '@coral-xyz/anchor';
2
+ import { PublicKey } from '@solana/web3.js';
3
+ import { MilestoneWithKey, InvestmentWithKey, VoteWithKey } from '../types/index.js';
4
+
5
+ /**
6
+ * Raise Account Fetchers
7
+ *
8
+ * Functions to fetch and decode program accounts.
9
+ */
10
+
11
+ type AnyProgram = Program<any>;
12
+ /**
13
+ * Fetch project account data
14
+ *
15
+ * @param program - Anchor program instance
16
+ * @param projectId - Project identifier
17
+ * @returns Project account data or null if not found
18
+ */
19
+ declare function fetchProject(program: AnyProgram, projectId: BN): Promise<any>;
20
+ /**
21
+ * Fetch project account by PDA
22
+ *
23
+ * @param program - Anchor program instance
24
+ * @param projectPda - Project account PDA
25
+ * @returns Project account data or null if not found
26
+ */
27
+ declare function fetchProjectByPda(program: AnyProgram, projectPda: PublicKey): Promise<any>;
28
+ /**
29
+ * Fetch milestone account data
30
+ *
31
+ * @param program - Anchor program instance
32
+ * @param projectId - Project identifier
33
+ * @param milestoneIndex - Milestone index
34
+ * @returns Milestone account data or null if not found
35
+ */
36
+ declare function fetchMilestone(program: AnyProgram, projectId: BN, milestoneIndex: number): Promise<any>;
37
+ /**
38
+ * Fetch all milestones for a project
39
+ *
40
+ * @param program - Anchor program instance
41
+ * @param projectId - Project identifier
42
+ * @returns Array of milestone accounts with their public keys
43
+ */
44
+ declare function fetchAllMilestones(program: AnyProgram, projectId: BN): Promise<MilestoneWithKey[]>;
45
+ /**
46
+ * Fetch investment account data
47
+ *
48
+ * @param program - Anchor program instance
49
+ * @param projectId - Project identifier
50
+ * @param nftMint - Investment NFT mint address
51
+ * @returns Investment account data or null if not found
52
+ */
53
+ declare function fetchInvestment(program: AnyProgram, projectId: BN, nftMint: PublicKey): Promise<any>;
54
+ /**
55
+ * Fetch all investments for a project
56
+ *
57
+ * @param program - Anchor program instance
58
+ * @param projectId - Project identifier
59
+ * @returns Array of investment accounts with their public keys
60
+ */
61
+ declare function fetchAllInvestments(program: AnyProgram, projectId: BN): Promise<InvestmentWithKey[]>;
62
+ /**
63
+ * Fetch vote account data
64
+ *
65
+ * @param program - Anchor program instance
66
+ * @param projectId - Project identifier
67
+ * @param milestoneIndex - Milestone index
68
+ * @param voterKey - Voter's public key
69
+ * @param votingRound - Current voting round (0 initially, incremented on resubmit)
70
+ * @returns Vote account data or null if not found
71
+ */
72
+ declare function fetchVote(program: AnyProgram, projectId: BN, milestoneIndex: number, voterKey: PublicKey, votingRound: number): Promise<any>;
73
+ /**
74
+ * Fetch all votes for a milestone
75
+ *
76
+ * @param program - Anchor program instance
77
+ * @param projectId - Project identifier
78
+ * @param milestoneIndex - Milestone index
79
+ * @returns Array of vote accounts with their public keys
80
+ */
81
+ declare function fetchAllVotes(program: AnyProgram, projectId: BN, milestoneIndex: number): Promise<VoteWithKey[]>;
82
+ /**
83
+ * Fetch pivot proposal account data
84
+ *
85
+ * @param program - Anchor program instance
86
+ * @param projectId - Project identifier
87
+ * @returns PivotProposal account data or null if not found
88
+ */
89
+ declare function fetchPivotProposal(program: AnyProgram, projectId: BN): Promise<any>;
90
+ /**
91
+ * Fetch TGE escrow account data
92
+ *
93
+ * @param program - Anchor program instance
94
+ * @param projectId - Project identifier
95
+ * @returns TgeEscrow account data or null if not found
96
+ */
97
+ declare function fetchTgeEscrow(program: AnyProgram, projectId: BN): Promise<any>;
98
+ /**
99
+ * Fetch admin config account data
100
+ *
101
+ * @param program - Anchor program instance
102
+ * @returns AdminConfig account data
103
+ */
104
+ declare function fetchAdminConfig(program: AnyProgram): Promise<any>;
105
+ /**
106
+ * Check if an account exists
107
+ *
108
+ * @param program - Anchor program instance
109
+ * @param accountType - Account type name
110
+ * @param pda - Account PDA
111
+ * @returns True if account exists
112
+ */
113
+ declare function accountExists(program: AnyProgram, accountType: string, pda: PublicKey): Promise<boolean>;
114
+
115
+ export { accountExists, fetchAdminConfig, fetchAllInvestments, fetchAllMilestones, fetchAllVotes, fetchInvestment, fetchMilestone, fetchPivotProposal, fetchProject, fetchProjectByPda, fetchTgeEscrow, fetchVote };
@@ -0,0 +1,245 @@
1
+ import { PublicKey } from '@solana/web3.js';
2
+ import { BN } from '@coral-xyz/anchor';
3
+
4
+ // src/pdas/index.ts
5
+
6
+ // src/constants/index.ts
7
+ var SEEDS = {
8
+ PROJECT: "project",
9
+ MILESTONE: "milestone",
10
+ INVESTMENT: "investment",
11
+ VOTE: "vote",
12
+ PIVOT: "pivot",
13
+ TGE_ESCROW: "tge_escrow",
14
+ ADMIN_CONFIG: "admin-config"};
15
+
16
+ // src/pdas/index.ts
17
+ function ensureBN(value) {
18
+ if (value && typeof value.toArrayLike === "function") {
19
+ return value;
20
+ }
21
+ return new BN(String(value));
22
+ }
23
+ function getProjectPDA(projectId, programId) {
24
+ const projectIdBN = ensureBN(projectId);
25
+ const [pda] = PublicKey.findProgramAddressSync(
26
+ [Buffer.from(SEEDS.PROJECT), projectIdBN.toArrayLike(Buffer, "le", 8)],
27
+ programId
28
+ );
29
+ return pda;
30
+ }
31
+ function getMilestonePDA(projectPda, milestoneIndex, programId) {
32
+ const [pda] = PublicKey.findProgramAddressSync(
33
+ [
34
+ Buffer.from(SEEDS.MILESTONE),
35
+ projectPda.toBuffer(),
36
+ Buffer.from([milestoneIndex])
37
+ ],
38
+ programId
39
+ );
40
+ return pda;
41
+ }
42
+ function getInvestmentPDA(projectPda, nftMint, programId) {
43
+ const [pda] = PublicKey.findProgramAddressSync(
44
+ [
45
+ Buffer.from(SEEDS.INVESTMENT),
46
+ projectPda.toBuffer(),
47
+ nftMint.toBuffer()
48
+ ],
49
+ programId
50
+ );
51
+ return pda;
52
+ }
53
+ function getVotePDA(milestonePda, voterKey, votingRound, programId) {
54
+ const [pda] = PublicKey.findProgramAddressSync(
55
+ [Buffer.from(SEEDS.VOTE), milestonePda.toBuffer(), voterKey.toBuffer(), Buffer.from([votingRound])],
56
+ programId
57
+ );
58
+ return pda;
59
+ }
60
+ function getPivotProposalPDA(projectPda, pivotCount, programId) {
61
+ const [pda] = PublicKey.findProgramAddressSync(
62
+ [
63
+ Buffer.from(SEEDS.PIVOT),
64
+ // Use PIVOT seed, not PIVOT_PROPOSAL
65
+ projectPda.toBuffer(),
66
+ Buffer.from([pivotCount])
67
+ // pivot_count is u8 (1 byte) on-chain
68
+ ],
69
+ programId
70
+ );
71
+ return pda;
72
+ }
73
+ function getTgeEscrowPDA(projectPda, programId) {
74
+ const [pda] = PublicKey.findProgramAddressSync(
75
+ [Buffer.from(SEEDS.TGE_ESCROW), projectPda.toBuffer()],
76
+ programId
77
+ );
78
+ return pda;
79
+ }
80
+ function getAdminConfigPDA(programId) {
81
+ const [pda] = PublicKey.findProgramAddressSync(
82
+ [Buffer.from(SEEDS.ADMIN_CONFIG)],
83
+ programId
84
+ );
85
+ return pda;
86
+ }
87
+
88
+ // src/accounts/index.ts
89
+ function getAccountNamespace(program) {
90
+ return program.account;
91
+ }
92
+ async function fetchProject(program, projectId) {
93
+ try {
94
+ const projectPda = getProjectPDA(projectId, program.programId);
95
+ return await getAccountNamespace(program).project.fetch(projectPda);
96
+ } catch (error) {
97
+ if (error instanceof Error && error.message?.includes("Account does not exist")) {
98
+ return null;
99
+ }
100
+ throw error;
101
+ }
102
+ }
103
+ async function fetchProjectByPda(program, projectPda) {
104
+ try {
105
+ return await getAccountNamespace(program).project.fetch(projectPda);
106
+ } catch (error) {
107
+ if (error instanceof Error && error.message?.includes("Account does not exist")) {
108
+ return null;
109
+ }
110
+ throw error;
111
+ }
112
+ }
113
+ async function fetchMilestone(program, projectId, milestoneIndex) {
114
+ try {
115
+ const projectPda = getProjectPDA(projectId, program.programId);
116
+ const milestonePda = getMilestonePDA(projectPda, milestoneIndex, program.programId);
117
+ return await getAccountNamespace(program).milestone.fetch(milestonePda);
118
+ } catch (error) {
119
+ if (error instanceof Error && error.message?.includes("Account does not exist")) {
120
+ return null;
121
+ }
122
+ throw error;
123
+ }
124
+ }
125
+ async function fetchAllMilestones(program, projectId) {
126
+ const projectPda = getProjectPDA(projectId, program.programId);
127
+ const milestones = await getAccountNamespace(program).milestone.all([
128
+ {
129
+ memcmp: {
130
+ offset: 8,
131
+ // Skip discriminator
132
+ bytes: projectPda.toBase58()
133
+ }
134
+ }
135
+ ]);
136
+ return milestones.map((m) => ({
137
+ publicKey: m.publicKey,
138
+ account: m.account
139
+ }));
140
+ }
141
+ async function fetchInvestment(program, projectId, nftMint) {
142
+ try {
143
+ const projectPda = getProjectPDA(projectId, program.programId);
144
+ const investmentPda = getInvestmentPDA(projectPda, nftMint, program.programId);
145
+ return await getAccountNamespace(program).investment.fetch(investmentPda);
146
+ } catch (error) {
147
+ if (error instanceof Error && error.message?.includes("Account does not exist")) {
148
+ return null;
149
+ }
150
+ throw error;
151
+ }
152
+ }
153
+ async function fetchAllInvestments(program, projectId) {
154
+ const projectPda = getProjectPDA(projectId, program.programId);
155
+ const investments = await getAccountNamespace(program).investment.all([
156
+ {
157
+ memcmp: {
158
+ offset: 8,
159
+ // Skip discriminator
160
+ bytes: projectPda.toBase58()
161
+ }
162
+ }
163
+ ]);
164
+ return investments.map((inv) => ({
165
+ publicKey: inv.publicKey,
166
+ account: inv.account
167
+ }));
168
+ }
169
+ async function fetchVote(program, projectId, milestoneIndex, voterKey, votingRound) {
170
+ try {
171
+ const projectPda = getProjectPDA(projectId, program.programId);
172
+ const milestonePda = getMilestonePDA(projectPda, milestoneIndex, program.programId);
173
+ const votePda = getVotePDA(milestonePda, voterKey, votingRound, program.programId);
174
+ return await getAccountNamespace(program).vote.fetch(votePda);
175
+ } catch (error) {
176
+ if (error instanceof Error && error.message?.includes("Account does not exist")) {
177
+ return null;
178
+ }
179
+ throw error;
180
+ }
181
+ }
182
+ async function fetchAllVotes(program, projectId, milestoneIndex) {
183
+ const projectPda = getProjectPDA(projectId, program.programId);
184
+ const milestonePda = getMilestonePDA(projectPda, milestoneIndex, program.programId);
185
+ const votes = await getAccountNamespace(program).vote.all([
186
+ {
187
+ memcmp: {
188
+ offset: 8,
189
+ // Skip discriminator
190
+ bytes: milestonePda.toBase58()
191
+ }
192
+ }
193
+ ]);
194
+ return votes.map((v) => ({
195
+ publicKey: v.publicKey,
196
+ account: v.account
197
+ }));
198
+ }
199
+ async function fetchPivotProposal(program, projectId) {
200
+ try {
201
+ const projectPda = getProjectPDA(projectId, program.programId);
202
+ const projectAccount = await getAccountNamespace(program).project.fetch(projectPda);
203
+ let pivotPda;
204
+ if (projectAccount.activePivot) {
205
+ pivotPda = projectAccount.activePivot;
206
+ } else {
207
+ const pivotCount = projectAccount.pivotCount || 0;
208
+ pivotPda = getPivotProposalPDA(projectPda, pivotCount, program.programId);
209
+ }
210
+ return await getAccountNamespace(program).pivotProposal.fetch(pivotPda);
211
+ } catch (error) {
212
+ if (error instanceof Error && error.message?.includes("Account does not exist")) {
213
+ return null;
214
+ }
215
+ throw error;
216
+ }
217
+ }
218
+ async function fetchTgeEscrow(program, projectId) {
219
+ try {
220
+ const projectPda = getProjectPDA(projectId, program.programId);
221
+ const tgeEscrowPda = getTgeEscrowPDA(projectPda, program.programId);
222
+ return await getAccountNamespace(program).tgeEscrow.fetch(tgeEscrowPda);
223
+ } catch (error) {
224
+ if (error instanceof Error && error.message?.includes("Account does not exist")) {
225
+ return null;
226
+ }
227
+ throw error;
228
+ }
229
+ }
230
+ async function fetchAdminConfig(program) {
231
+ const adminConfigPda = getAdminConfigPDA(program.programId);
232
+ return await getAccountNamespace(program).adminConfig.fetch(adminConfigPda);
233
+ }
234
+ async function accountExists(program, accountType, pda) {
235
+ try {
236
+ await program.account[accountType].fetch(pda);
237
+ return true;
238
+ } catch {
239
+ return false;
240
+ }
241
+ }
242
+
243
+ export { accountExists, fetchAdminConfig, fetchAllInvestments, fetchAllMilestones, fetchAllVotes, fetchInvestment, fetchMilestone, fetchPivotProposal, fetchProject, fetchProjectByPda, fetchTgeEscrow, fetchVote };
244
+ //# sourceMappingURL=index.js.map
245
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/constants/index.ts","../../src/pdas/index.ts","../../src/accounts/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Raise Constants\n *\n * Mirrors the on-chain program constants for client-side validation\n * and display purposes.\n */\n\n// =============================================================================\n// PDA Seeds\n// =============================================================================\n\nexport const SEEDS = {\n PROJECT: 'project',\n MILESTONE: 'milestone',\n INVESTMENT: 'investment',\n VOTE: 'vote',\n ESCROW: 'escrow',\n PIVOT: 'pivot',\n PIVOT_PROPOSAL: 'pivot_proposal',\n TGE_ESCROW: 'tge_escrow',\n TGE_ESCROW_VAULT: 'tge_escrow_vault',\n SCAM_REPORT: 'scam_report',\n ADMIN_CONFIG: 'admin-config',\n NFT_MINT: 'nft_mint',\n AUTHORITY: 'authority',\n} as const;\n\n// =============================================================================\n// Validation Constants\n// =============================================================================\n\nexport const VALIDATION = {\n /** Minimum number of milestones per project */\n MIN_MILESTONES: 2,\n /** Maximum number of milestones per project */\n MAX_MILESTONES: 10,\n /** Milestone percentages must sum to this value */\n MILESTONE_PERCENTAGE_SUM: 100,\n /** Maximum funding buffer (110% of goal) */\n MAX_FUNDING_BUFFER_PERCENT: 110,\n /** Maximum metadata URI length */\n MAX_METADATA_URI_LENGTH: 200,\n /** Maximum pivot description length */\n MAX_PIVOT_DESCRIPTION_LEN: 256,\n /** Maximum pivot vision length */\n MAX_PIVOT_VISION_LEN: 512,\n /** Maximum pivot justification length */\n MAX_PIVOT_JUSTIFICATION_LEN: 512,\n} as const;\n\n// =============================================================================\n// Timing Constants (in seconds)\n// =============================================================================\n\nexport const TIMING = {\n /** Production voting period (14 days) */\n VOTING_PERIOD_SECONDS: 1_209_600,\n /** Production hold period (7 days) */\n HOLD_PERIOD_SECONDS: 604_800,\n /** Inactivity timeout (90 days) */\n INACTIVITY_TIMEOUT_SECONDS: 7_776_000,\n /** Abandonment timeout (90 days) */\n ABANDONMENT_TIMEOUT_SECONDS: 7_776_000,\n /** Refund window (14 days) */\n REFUND_WINDOW_SECONDS: 1_209_600,\n /** Pivot withdrawal window (7 days) */\n PIVOT_WITHDRAWAL_WINDOW_SECONDS: 604_800,\n /** Minimum TGE date (15 days from now) */\n TGE_MIN_DAYS: 1_296_000,\n /** Maximum TGE date (90 days from now) */\n TGE_MAX_DAYS: 7_776_000,\n /** Post-TGE holdback period (30 days) */\n POST_TGE_HOLDBACK_DAYS: 2_592_000,\n} as const;\n\n// =============================================================================\n// Tier Configuration Constraints\n// =============================================================================\n\nexport const TIER_CONSTRAINTS = {\n /** Minimum number of tiers */\n MIN_TIERS: 1,\n /** Maximum number of tiers */\n MAX_TIERS: 10,\n /** Minimum tier amount (10 USDC in lamports) */\n MIN_TIER_AMOUNT: 10_000_000n,\n /** Minimum max_lots per tier */\n MIN_TIER_MAX_LOTS: 1,\n /** Minimum token ratio */\n MIN_TIER_TOKEN_RATIO: 1n,\n /** Minimum vote multiplier (100 = 1.0x) */\n MIN_TIER_VOTE_MULTIPLIER: 100,\n} as const;\n\n// =============================================================================\n// Investment Tiers (Legacy - kept for backwards compatibility)\n// =============================================================================\n\nexport enum InvestmentTier {\n Bronze = 'Bronze',\n Silver = 'Silver',\n Gold = 'Gold',\n Platinum = 'Platinum',\n Diamond = 'Diamond',\n}\n\n/** Investment tier minimum amounts in USDC lamports (6 decimals) - LEGACY */\nexport const TIER_MINIMUMS = {\n [InvestmentTier.Bronze]: 100_000_000n, // 100 USDC\n [InvestmentTier.Silver]: 500_000_000n, // 500 USDC\n [InvestmentTier.Gold]: 1_000_000_000n, // 1,000 USDC\n [InvestmentTier.Platinum]: 5_000_000_000n, // 5,000 USDC\n [InvestmentTier.Diamond]: 10_000_000_000n, // 10,000 USDC\n} as const;\n\n/** Vote weight multipliers (scaled by 100) - LEGACY */\nexport const TIER_VOTE_MULTIPLIERS = {\n [InvestmentTier.Bronze]: 100, // 1.0x\n [InvestmentTier.Silver]: 120, // 1.2x\n [InvestmentTier.Gold]: 150, // 1.5x\n [InvestmentTier.Platinum]: 200, // 2.0x\n [InvestmentTier.Diamond]: 300, // 3.0x\n} as const;\n\n/** Token allocation multipliers (same as vote multipliers) - LEGACY */\nexport const TIER_TOKEN_MULTIPLIERS = {\n [InvestmentTier.Bronze]: 100,\n [InvestmentTier.Silver]: 120,\n [InvestmentTier.Gold]: 150,\n [InvestmentTier.Platinum]: 200,\n [InvestmentTier.Diamond]: 300,\n} as const;\n\n/** Get tier from investment amount (in lamports) - LEGACY, use project.tiers instead */\nexport function getTierFromAmount(amount: bigint): InvestmentTier {\n if (amount >= TIER_MINIMUMS[InvestmentTier.Diamond]) return InvestmentTier.Diamond;\n if (amount >= TIER_MINIMUMS[InvestmentTier.Platinum]) return InvestmentTier.Platinum;\n if (amount >= TIER_MINIMUMS[InvestmentTier.Gold]) return InvestmentTier.Gold;\n if (amount >= TIER_MINIMUMS[InvestmentTier.Silver]) return InvestmentTier.Silver;\n return InvestmentTier.Bronze;\n}\n\n/** Get vote multiplier for an investment amount - LEGACY */\nexport function getVoteMultiplier(amount: bigint): number {\n const tier = getTierFromAmount(amount);\n return TIER_VOTE_MULTIPLIERS[tier] / 100;\n}\n\n/** Get token multiplier for an investment amount - LEGACY */\nexport function getTokenMultiplier(amount: bigint): number {\n const tier = getTierFromAmount(amount);\n return TIER_TOKEN_MULTIPLIERS[tier] / 100;\n}\n\n/**\n * Find matching tier index for an investment amount (threshold-based)\n * Returns the highest tier where amount >= tier.amount\n */\nexport function findTierIndex(tiers: Array<{ amount: bigint }>, amount: bigint): number | null {\n for (let i = tiers.length - 1; i >= 0; i--) {\n if (amount >= tiers[i].amount) {\n return i;\n }\n }\n return null;\n}\n\n// =============================================================================\n// Voting and Governance\n// =============================================================================\n\nexport const GOVERNANCE = {\n /** Scam report threshold (30%) */\n SCAM_THRESHOLD_PERCENT: 30,\n /** Consecutive milestone failures before exit window eligible */\n CONSECUTIVE_FAILURES_THRESHOLD: 3,\n /** Milestone approval threshold (>50% weighted approval per whitepaper voting.md:100-101) */\n MILESTONE_APPROVAL_THRESHOLD_PERCENT: 50,\n} as const;\n\n// =============================================================================\n// NFT Constants\n// =============================================================================\n\nexport const NFT = {\n /** NFT symbol */\n SYMBOL: 'SNI',\n /** NFT name prefix */\n NAME_PREFIX: 'Raise Investment #',\n /** Royalty basis points (2%) */\n ROYALTY_BASIS_POINTS: 200,\n} as const;\n\n// =============================================================================\n// USDC Constants\n// =============================================================================\n\nexport const USDC = {\n /** USDC decimals */\n DECIMALS: 6,\n /** Convert USDC to lamports */\n toAmount: (usdc: number): bigint => BigInt(Math.floor(usdc * 10 ** 6)),\n /** Convert lamports to USDC */\n fromAmount: (lamports: bigint): number => Number(lamports) / 10 ** 6,\n} as const;\n","/**\n * Raise PDA Derivation Helpers\n *\n * All PDA derivation functions for the Raise program.\n * PDAs are deterministic addresses derived from seeds and program ID.\n */\n\nimport { PublicKey } from '@solana/web3.js';\nimport { BN } from '@coral-xyz/anchor';\nimport { SEEDS } from '../constants/index.js';\n\n/**\n * Ensure value is a proper BN instance\n * This handles cases where BN objects lose their prototype chain\n * (e.g., when passing through React state or JSON serialization)\n *\n * Uses duck typing instead of instanceof to handle different BN module instances\n */\nfunction ensureBN(value: BN | number | string | { toString(): string }): BN {\n // Duck typing: if it has toArrayLike, it's BN-like and we can use it\n if (value && typeof (value as BN).toArrayLike === 'function') {\n return value as BN;\n }\n // Always create a fresh BN from the SDK's imported BN class\n return new BN(String(value));\n}\n\n/**\n * Derive Project PDA from project ID\n *\n * @param projectId - Unique project identifier\n * @param programId - Raise program ID\n * @returns Project account PDA\n */\nexport function getProjectPDA(projectId: BN | number | string, programId: PublicKey): PublicKey {\n const projectIdBN = ensureBN(projectId);\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from(SEEDS.PROJECT), projectIdBN.toArrayLike(Buffer, 'le', 8)],\n programId\n );\n return pda;\n}\n\n/**\n * Derive Escrow PDA from project ID\n *\n * @param projectId - Project identifier\n * @param programId - Raise program ID\n * @returns Escrow account PDA\n */\nexport function getEscrowPDA(projectId: BN | number | string, programId: PublicKey): PublicKey {\n const projectIdBN = ensureBN(projectId);\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from(SEEDS.ESCROW), projectIdBN.toArrayLike(Buffer, 'le', 8)],\n programId\n );\n return pda;\n}\n\n/**\n * Derive Milestone PDA from project PDA and milestone index\n *\n * @param projectPda - Project account PDA\n * @param milestoneIndex - Milestone index (0-based)\n * @param programId - Raise program ID\n * @returns Milestone account PDA\n */\nexport function getMilestonePDA(\n projectPda: PublicKey,\n milestoneIndex: number,\n programId: PublicKey\n): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [\n Buffer.from(SEEDS.MILESTONE),\n projectPda.toBuffer(),\n Buffer.from([milestoneIndex]),\n ],\n programId\n );\n return pda;\n}\n\n/**\n * Derive Investment PDA from project PDA and NFT mint\n *\n * @param projectPda - Project account PDA\n * @param nftMint - Investment NFT mint address\n * @param programId - Raise program ID\n * @returns Investment account PDA\n */\nexport function getInvestmentPDA(\n projectPda: PublicKey,\n nftMint: PublicKey,\n programId: PublicKey\n): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [\n Buffer.from(SEEDS.INVESTMENT),\n projectPda.toBuffer(),\n nftMint.toBuffer(),\n ],\n programId\n );\n return pda;\n}\n\n/**\n * Derive Vote PDA from milestone PDA, voter key, and voting round\n *\n * @param milestonePda - Milestone account PDA\n * @param voterKey - Voter's public key\n * @param votingRound - Current voting round (0 initially, incremented on resubmit)\n * @param programId - Raise program ID\n * @returns Vote account PDA\n */\nexport function getVotePDA(\n milestonePda: PublicKey,\n voterKey: PublicKey,\n votingRound: number,\n programId: PublicKey\n): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from(SEEDS.VOTE), milestonePda.toBuffer(), voterKey.toBuffer(), Buffer.from([votingRound])],\n programId\n );\n return pda;\n}\n\n/**\n * Derive PivotProposal PDA from project PDA and pivot count\n *\n * @param projectPda - Project account PDA\n * @param pivotCount - Current pivot count from project account\n * @param programId - Raise program ID\n * @returns PivotProposal account PDA\n */\nexport function getPivotProposalPDA(\n projectPda: PublicKey,\n pivotCount: number,\n programId: PublicKey\n): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [\n Buffer.from(SEEDS.PIVOT), // Use PIVOT seed, not PIVOT_PROPOSAL\n projectPda.toBuffer(),\n Buffer.from([pivotCount]), // pivot_count is u8 (1 byte) on-chain\n ],\n programId\n );\n return pda;\n}\n\n/**\n * Derive TgeEscrow PDA from project PDA\n *\n * @param projectPda - Project account PDA\n * @param programId - Raise program ID\n * @returns TgeEscrow account PDA\n */\nexport function getTgeEscrowPDA(\n projectPda: PublicKey,\n programId: PublicKey\n): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from(SEEDS.TGE_ESCROW), projectPda.toBuffer()],\n programId\n );\n return pda;\n}\n\n/**\n * Derive TgeEscrowVault PDA from project PDA\n * Used for holding 10% USDC holdback from final milestone\n *\n * @param projectPda - Project account PDA\n * @param programId - Raise program ID\n * @returns TgeEscrowVault PDA\n */\nexport function getTgeEscrowVaultPDA(\n projectPda: PublicKey,\n programId: PublicKey\n): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from(SEEDS.TGE_ESCROW_VAULT), projectPda.toBuffer()],\n programId\n );\n return pda;\n}\n\n/**\n * Derive TokenVault PDA from project PDA\n * Used for holding project tokens for investor distribution\n *\n * @param projectPda - Project account PDA\n * @param programId - Raise program ID\n * @returns TokenVault PDA\n */\nexport function getTokenVaultPDA(\n projectPda: PublicKey,\n programId: PublicKey\n): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from('token_vault'), projectPda.toBuffer()],\n programId\n );\n return pda;\n}\n\n/**\n * Derive ScamReport PDA from project PDA and NFT mint\n *\n * @param projectPda - Project account PDA\n * @param nftMint - Reporter's NFT mint address\n * @param programId - Raise program ID\n * @returns ScamReport account PDA\n */\nexport function getScamReportPDA(\n projectPda: PublicKey,\n nftMint: PublicKey,\n programId: PublicKey\n): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [\n Buffer.from(SEEDS.SCAM_REPORT),\n projectPda.toBuffer(),\n nftMint.toBuffer(),\n ],\n programId\n );\n return pda;\n}\n\n/**\n * Derive AdminConfig PDA (global admin authority)\n *\n * @param programId - Raise program ID\n * @returns AdminConfig account PDA\n */\nexport function getAdminConfigPDA(programId: PublicKey): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from(SEEDS.ADMIN_CONFIG)],\n programId\n );\n return pda;\n}\n\n/**\n * Derive NFT Mint PDA\n *\n * @param projectId - Project identifier\n * @param investor - Investor's public key\n * @param investmentCount - Investment count (u64 in Rust, 8 bytes LE)\n * @param programId - Raise program ID\n * @returns NFT Mint PDA and bump\n */\nexport function getNftMintPDA(\n projectId: BN | number | string,\n investor: PublicKey,\n investmentCount: BN | number,\n programId: PublicKey\n): [PublicKey, number] {\n // Ensure both values are proper BN instances (handles prototype chain issues)\n const projectIdBN = ensureBN(projectId);\n const countBN = ensureBN(investmentCount);\n return PublicKey.findProgramAddressSync(\n [\n Buffer.from(SEEDS.NFT_MINT),\n projectIdBN.toArrayLike(Buffer, 'le', 8),\n investor.toBuffer(),\n countBN.toArrayLike(Buffer, 'le', 8), // u64 is 8 bytes LE\n ],\n programId\n );\n}\n\n/**\n * Derive Program Authority PDA\n *\n * @param programId - Raise program ID\n * @returns Program authority PDA and bump\n */\nexport function getProgramAuthorityPDA(programId: PublicKey): [PublicKey, number] {\n return PublicKey.findProgramAddressSync(\n [Buffer.from(SEEDS.AUTHORITY)],\n programId\n );\n}\n\n/**\n * Helper to derive all PDAs for a project\n *\n * @param projectId - Project identifier\n * @param programId - Raise program ID\n * @returns Object with project and escrow PDAs\n */\nexport function getProjectPDAs(projectId: BN, programId: PublicKey) {\n const project = getProjectPDA(projectId, programId);\n const escrow = getEscrowPDA(projectId, programId);\n return { project, escrow };\n}\n\n// =============================================================================\n// ZTM v2.0 PDAs\n// =============================================================================\n\n/**\n * Derive Tokenomics PDA from project PDA\n */\nexport function getTokenomicsPDA(projectPda: PublicKey, programId: PublicKey): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from('tokenomics'), projectPda.toBuffer()],\n programId\n );\n return pda;\n}\n\n/**\n * Derive Token Mint PDA from project PDA\n */\nexport function getTokenMintPDA(projectPda: PublicKey, programId: PublicKey): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from('token_mint'), projectPda.toBuffer()],\n programId\n );\n return pda;\n}\n\n/**\n * Derive Vault Authority PDA from project PDA\n */\nexport function getVaultAuthorityPDA(projectPda: PublicKey, programId: PublicKey): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from('vault_authority'), projectPda.toBuffer()],\n programId\n );\n return pda;\n}\n\n/**\n * Derive Investor Vault PDA from project PDA\n */\nexport function getInvestorVaultPDA(projectPda: PublicKey, programId: PublicKey): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from('investor_vault'), projectPda.toBuffer()],\n programId\n );\n return pda;\n}\n\n/**\n * Derive Founder Vault PDA from project PDA\n */\nexport function getFounderVaultPDA(projectPda: PublicKey, programId: PublicKey): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from('founder_vault'), projectPda.toBuffer()],\n programId\n );\n return pda;\n}\n\n/**\n * Derive LP Token Vault PDA from project PDA\n */\nexport function getLpTokenVaultPDA(projectPda: PublicKey, programId: PublicKey): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from('lp_token_vault'), projectPda.toBuffer()],\n programId\n );\n return pda;\n}\n\n/**\n * Derive Treasury Vault PDA from project PDA\n */\nexport function getTreasuryVaultPDA(projectPda: PublicKey, programId: PublicKey): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from('treasury_vault'), projectPda.toBuffer()],\n programId\n );\n return pda;\n}\n\n/**\n * Derive LP USDC Vault PDA from project PDA\n */\nexport function getLpUsdcVaultPDA(projectPda: PublicKey, programId: PublicKey): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from('lp_usdc_vault'), projectPda.toBuffer()],\n programId\n );\n return pda;\n}\n\n/**\n * Derive Founder Vesting PDA from project PDA\n */\nexport function getFounderVestingPDA(projectPda: PublicKey, programId: PublicKey): PublicKey {\n const [pda] = PublicKey.findProgramAddressSync(\n [Buffer.from('founder_vesting'), projectPda.toBuffer()],\n programId\n );\n return pda;\n}\n","/**\n * Raise Account Fetchers\n *\n * Functions to fetch and decode program accounts.\n */\n\nimport { Program, BN } from '@coral-xyz/anchor';\nimport { PublicKey } from '@solana/web3.js';\nimport {\n getProjectPDA,\n getMilestonePDA,\n getInvestmentPDA,\n getVotePDA,\n getPivotProposalPDA,\n getTgeEscrowPDA,\n getAdminConfigPDA,\n} from '../pdas/index.js';\nimport type { InvestmentWithKey, MilestoneWithKey, VoteWithKey } from '../types/index.js';\n\n// Generic type for any Anchor program\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyProgram = Program<any>;\n\n// Helper to access account namespace dynamically\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction getAccountNamespace(program: AnyProgram): any {\n return program.account;\n}\n\n/**\n * Fetch project account data\n *\n * @param program - Anchor program instance\n * @param projectId - Project identifier\n * @returns Project account data or null if not found\n */\nexport async function fetchProject(\n program: AnyProgram,\n projectId: BN\n) {\n try {\n const projectPda = getProjectPDA(projectId, program.programId);\n return await getAccountNamespace(program).project.fetch(projectPda);\n } catch (error) {\n if (error instanceof Error && error.message?.includes('Account does not exist')) {\n return null;\n }\n throw error;\n }\n}\n\n/**\n * Fetch project account by PDA\n *\n * @param program - Anchor program instance\n * @param projectPda - Project account PDA\n * @returns Project account data or null if not found\n */\nexport async function fetchProjectByPda(\n program: AnyProgram,\n projectPda: PublicKey\n) {\n try {\n return await getAccountNamespace(program).project.fetch(projectPda);\n } catch (error) {\n if (error instanceof Error && error.message?.includes('Account does not exist')) {\n return null;\n }\n throw error;\n }\n}\n\n/**\n * Fetch milestone account data\n *\n * @param program - Anchor program instance\n * @param projectId - Project identifier\n * @param milestoneIndex - Milestone index\n * @returns Milestone account data or null if not found\n */\nexport async function fetchMilestone(\n program: AnyProgram,\n projectId: BN,\n milestoneIndex: number\n) {\n try {\n const projectPda = getProjectPDA(projectId, program.programId);\n const milestonePda = getMilestonePDA(projectPda, milestoneIndex, program.programId);\n return await getAccountNamespace(program).milestone.fetch(milestonePda);\n } catch (error) {\n if (error instanceof Error && error.message?.includes('Account does not exist')) {\n return null;\n }\n throw error;\n }\n}\n\n/**\n * Fetch all milestones for a project\n *\n * @param program - Anchor program instance\n * @param projectId - Project identifier\n * @returns Array of milestone accounts with their public keys\n */\nexport async function fetchAllMilestones(\n program: AnyProgram,\n projectId: BN\n): Promise<MilestoneWithKey[]> {\n const projectPda = getProjectPDA(projectId, program.programId);\n\n const milestones = await getAccountNamespace(program).milestone.all([\n {\n memcmp: {\n offset: 8, // Skip discriminator\n bytes: projectPda.toBase58(),\n },\n },\n ]);\n\n return milestones.map((m: { publicKey: PublicKey; account: unknown }) => ({\n publicKey: m.publicKey,\n account: m.account,\n })) as MilestoneWithKey[];\n}\n\n/**\n * Fetch investment account data\n *\n * @param program - Anchor program instance\n * @param projectId - Project identifier\n * @param nftMint - Investment NFT mint address\n * @returns Investment account data or null if not found\n */\nexport async function fetchInvestment(\n program: AnyProgram,\n projectId: BN,\n nftMint: PublicKey\n) {\n try {\n const projectPda = getProjectPDA(projectId, program.programId);\n const investmentPda = getInvestmentPDA(projectPda, nftMint, program.programId);\n return await getAccountNamespace(program).investment.fetch(investmentPda);\n } catch (error) {\n if (error instanceof Error && error.message?.includes('Account does not exist')) {\n return null;\n }\n throw error;\n }\n}\n\n/**\n * Fetch all investments for a project\n *\n * @param program - Anchor program instance\n * @param projectId - Project identifier\n * @returns Array of investment accounts with their public keys\n */\nexport async function fetchAllInvestments(\n program: AnyProgram,\n projectId: BN\n): Promise<InvestmentWithKey[]> {\n const projectPda = getProjectPDA(projectId, program.programId);\n\n const investments = await getAccountNamespace(program).investment.all([\n {\n memcmp: {\n offset: 8, // Skip discriminator\n bytes: projectPda.toBase58(),\n },\n },\n ]);\n\n return investments.map((inv: { publicKey: PublicKey; account: unknown }) => ({\n publicKey: inv.publicKey,\n account: inv.account,\n })) as InvestmentWithKey[];\n}\n\n/**\n * Fetch vote account data\n *\n * @param program - Anchor program instance\n * @param projectId - Project identifier\n * @param milestoneIndex - Milestone index\n * @param voterKey - Voter's public key\n * @param votingRound - Current voting round (0 initially, incremented on resubmit)\n * @returns Vote account data or null if not found\n */\nexport async function fetchVote(\n program: AnyProgram,\n projectId: BN,\n milestoneIndex: number,\n voterKey: PublicKey,\n votingRound: number\n) {\n try {\n const projectPda = getProjectPDA(projectId, program.programId);\n const milestonePda = getMilestonePDA(projectPda, milestoneIndex, program.programId);\n const votePda = getVotePDA(milestonePda, voterKey, votingRound, program.programId);\n return await getAccountNamespace(program).vote.fetch(votePda);\n } catch (error) {\n if (error instanceof Error && error.message?.includes('Account does not exist')) {\n return null;\n }\n throw error;\n }\n}\n\n/**\n * Fetch all votes for a milestone\n *\n * @param program - Anchor program instance\n * @param projectId - Project identifier\n * @param milestoneIndex - Milestone index\n * @returns Array of vote accounts with their public keys\n */\nexport async function fetchAllVotes(\n program: AnyProgram,\n projectId: BN,\n milestoneIndex: number\n): Promise<VoteWithKey[]> {\n const projectPda = getProjectPDA(projectId, program.programId);\n const milestonePda = getMilestonePDA(projectPda, milestoneIndex, program.programId);\n\n const votes = await getAccountNamespace(program).vote.all([\n {\n memcmp: {\n offset: 8, // Skip discriminator\n bytes: milestonePda.toBase58(),\n },\n },\n ]);\n\n return votes.map((v: { publicKey: PublicKey; account: unknown }) => ({\n publicKey: v.publicKey,\n account: v.account,\n })) as VoteWithKey[];\n}\n\n/**\n * Fetch pivot proposal account data\n *\n * @param program - Anchor program instance\n * @param projectId - Project identifier\n * @returns PivotProposal account data or null if not found\n */\nexport async function fetchPivotProposal(\n program: AnyProgram,\n projectId: BN\n) {\n try {\n const projectPda = getProjectPDA(projectId, program.programId);\n\n // First fetch the project to get the active pivot or pivot_count\n const projectAccount = await getAccountNamespace(program).project.fetch(projectPda);\n\n // Use active_pivot if available, otherwise derive from pivot_count\n let pivotPda;\n if (projectAccount.activePivot) {\n pivotPda = projectAccount.activePivot;\n } else {\n const pivotCount = projectAccount.pivotCount || 0;\n pivotPda = getPivotProposalPDA(projectPda, pivotCount, program.programId);\n }\n\n return await getAccountNamespace(program).pivotProposal.fetch(pivotPda);\n } catch (error) {\n if (error instanceof Error && error.message?.includes('Account does not exist')) {\n return null;\n }\n throw error;\n }\n}\n\n/**\n * Fetch TGE escrow account data\n *\n * @param program - Anchor program instance\n * @param projectId - Project identifier\n * @returns TgeEscrow account data or null if not found\n */\nexport async function fetchTgeEscrow(\n program: AnyProgram,\n projectId: BN\n) {\n try {\n const projectPda = getProjectPDA(projectId, program.programId);\n const tgeEscrowPda = getTgeEscrowPDA(projectPda, program.programId);\n return await getAccountNamespace(program).tgeEscrow.fetch(tgeEscrowPda);\n } catch (error) {\n if (error instanceof Error && error.message?.includes('Account does not exist')) {\n return null;\n }\n throw error;\n }\n}\n\n/**\n * Fetch admin config account data\n *\n * @param program - Anchor program instance\n * @returns AdminConfig account data\n */\nexport async function fetchAdminConfig(program: AnyProgram) {\n const adminConfigPda = getAdminConfigPDA(program.programId);\n return await getAccountNamespace(program).adminConfig.fetch(adminConfigPda);\n}\n\n/**\n * Check if an account exists\n *\n * @param program - Anchor program instance\n * @param accountType - Account type name\n * @param pda - Account PDA\n * @returns True if account exists\n */\nexport async function accountExists(\n program: AnyProgram,\n accountType: string,\n pda: PublicKey\n): Promise<boolean> {\n try {\n // @ts-expect-error - dynamic account access\n await program.account[accountType].fetch(pda);\n return true;\n } catch {\n return false;\n }\n}\n"]}