@zemyth/raise-sdk 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +462 -122
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,33 +1,44 @@
|
|
|
1
|
-
# @raise
|
|
1
|
+
# @zemyth/raise-sdk
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@zemyth/raise-sdk)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
5
|
+
[](https://www.typescriptlang.org/)
|
|
6
|
+
|
|
7
|
+
TypeScript SDK for the **Raise** Solana program — a decentralized venture funding platform with milestone-based fund releases and investor protections.
|
|
4
8
|
|
|
5
9
|
## Features
|
|
6
10
|
|
|
7
|
-
- **Full Program Coverage**
|
|
8
|
-
- **PDA Helpers**
|
|
9
|
-
- **Account Fetchers**
|
|
10
|
-
- **Error Handling**
|
|
11
|
-
- **
|
|
12
|
-
- **
|
|
13
|
-
- **
|
|
11
|
+
- **Full Program Coverage** — All instructions wrapped with TypeScript types
|
|
12
|
+
- **PDA Helpers** — Derive all program addresses deterministically
|
|
13
|
+
- **Account Fetchers** — Fetch and decode all account types
|
|
14
|
+
- **Error Handling** — Mapped error codes with helpful messages
|
|
15
|
+
- **Event Parsing** — Parse and filter program events
|
|
16
|
+
- **Constants** — Investment tiers, timing values, governance parameters
|
|
17
|
+
- **Tree-shakable** — Modular exports for optimal bundle size
|
|
18
|
+
- **Dual Format** — ESM and CJS builds included
|
|
19
|
+
- **ZTM v2.0** — Full tokenomics, vesting, and distribution support
|
|
14
20
|
|
|
15
21
|
## Installation
|
|
16
22
|
|
|
17
23
|
```bash
|
|
18
|
-
npm install @raise
|
|
24
|
+
npm install @zemyth/raise-sdk
|
|
19
25
|
# or
|
|
20
|
-
yarn add @raise
|
|
26
|
+
yarn add @zemyth/raise-sdk
|
|
21
27
|
# or
|
|
22
|
-
pnpm add @raise
|
|
28
|
+
pnpm add @zemyth/raise-sdk
|
|
23
29
|
```
|
|
24
30
|
|
|
25
31
|
### Peer Dependencies
|
|
26
32
|
|
|
27
33
|
```bash
|
|
28
|
-
npm install @coral-xyz/anchor @solana/web3.js
|
|
34
|
+
npm install @coral-xyz/anchor@^0.32.0 @solana/web3.js@^1.90.0
|
|
29
35
|
```
|
|
30
36
|
|
|
37
|
+
### Requirements
|
|
38
|
+
|
|
39
|
+
- Node.js >= 18
|
|
40
|
+
- TypeScript >= 5.0 (recommended)
|
|
41
|
+
|
|
31
42
|
## Quick Start
|
|
32
43
|
|
|
33
44
|
### Initialize Client
|
|
@@ -35,7 +46,7 @@ npm install @coral-xyz/anchor @solana/web3.js
|
|
|
35
46
|
```typescript
|
|
36
47
|
import { Program, AnchorProvider } from '@coral-xyz/anchor';
|
|
37
48
|
import { Connection } from '@solana/web3.js';
|
|
38
|
-
import { RaiseClient, BN } from '@raise
|
|
49
|
+
import { RaiseClient, BN } from '@zemyth/raise-sdk';
|
|
39
50
|
import idl from './idl/raise.json';
|
|
40
51
|
|
|
41
52
|
// Setup connection and provider
|
|
@@ -52,13 +63,31 @@ const client = RaiseClient.fromProgram(program);
|
|
|
52
63
|
### Create a Project
|
|
53
64
|
|
|
54
65
|
```typescript
|
|
66
|
+
import { BN, USDC } from '@zemyth/raise-sdk';
|
|
67
|
+
|
|
55
68
|
const projectId = new BN(1);
|
|
56
69
|
|
|
57
|
-
// Initialize project
|
|
70
|
+
// Initialize project with custom tiers and tokenomics
|
|
58
71
|
const tx = await client.initializeProject({
|
|
59
72
|
projectId,
|
|
60
|
-
fundingGoal: new BN(
|
|
73
|
+
fundingGoal: new BN(USDC.toAmount(100_000)), // 100,000 USDC
|
|
61
74
|
metadataUri: 'https://example.com/project.json',
|
|
75
|
+
tiers: [
|
|
76
|
+
{ amount: new BN(USDC.toAmount(100)), maxLots: 1000, tokenRatio: new BN(100), voteMultiplier: 100 },
|
|
77
|
+
{ amount: new BN(USDC.toAmount(500)), maxLots: 200, tokenRatio: new BN(120), voteMultiplier: 120 },
|
|
78
|
+
{ amount: new BN(USDC.toAmount(1000)), maxLots: 100, tokenRatio: new BN(150), voteMultiplier: 150 },
|
|
79
|
+
],
|
|
80
|
+
tokenomics: {
|
|
81
|
+
totalSupply: new BN('1000000000000000'), // 1B tokens (with decimals)
|
|
82
|
+
symbol: 'PROJ',
|
|
83
|
+
investorAllocationBps: 2000, // 20%
|
|
84
|
+
founderAllocationBps: 2000, // 20%
|
|
85
|
+
lpAllocationBps: 3000, // 30%
|
|
86
|
+
treasuryAllocationBps: 3000, // 30%
|
|
87
|
+
cliffSeconds: new BN(15552000), // 6 months
|
|
88
|
+
vestingSeconds: new BN(63072000), // 2 years
|
|
89
|
+
},
|
|
90
|
+
milestone1Deadline: new BN(Math.floor(Date.now() / 1000) + 90 * 24 * 60 * 60), // 90 days
|
|
62
91
|
});
|
|
63
92
|
|
|
64
93
|
console.log('Project created:', tx);
|
|
@@ -85,25 +114,33 @@ await client.createMilestone({
|
|
|
85
114
|
description: 'Production Release',
|
|
86
115
|
});
|
|
87
116
|
|
|
88
|
-
// Submit for approval
|
|
117
|
+
// Submit for admin approval
|
|
89
118
|
await client.submitForApproval(projectId);
|
|
90
119
|
```
|
|
91
120
|
|
|
92
121
|
### Invest in a Project
|
|
93
122
|
|
|
94
123
|
```typescript
|
|
95
|
-
import { USDC,
|
|
124
|
+
import { USDC, findTierIndex } from '@zemyth/raise-sdk';
|
|
96
125
|
|
|
126
|
+
// Fetch project to get tiers and investment count
|
|
127
|
+
const project = await client.fetchProject(projectId);
|
|
97
128
|
const amount = USDC.toAmount(1000); // 1,000 USDC
|
|
98
|
-
const tier = getTierFromAmount(amount);
|
|
99
129
|
|
|
100
|
-
|
|
130
|
+
// Find matching tier (threshold-based)
|
|
131
|
+
const tierIndex = findTierIndex(
|
|
132
|
+
project.tiers.slice(0, project.tierCount).map(t => ({ amount: BigInt(t.amount.toString()) })),
|
|
133
|
+
amount
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
console.log(`Investing ${USDC.fromAmount(amount)} USDC (Tier ${tierIndex})`);
|
|
101
137
|
|
|
102
138
|
const tx = await client.invest({
|
|
103
139
|
projectId,
|
|
104
140
|
amount: new BN(amount.toString()),
|
|
105
141
|
investorTokenAccount: myUsdcAccount,
|
|
106
142
|
escrowTokenAccount: projectEscrow,
|
|
143
|
+
investmentCount: project.investorCount, // Required for NFT mint derivation
|
|
107
144
|
});
|
|
108
145
|
```
|
|
109
146
|
|
|
@@ -122,20 +159,35 @@ await client.voteOnMilestone({
|
|
|
122
159
|
await client.finalizeVoting(projectId, 0);
|
|
123
160
|
```
|
|
124
161
|
|
|
162
|
+
### Claim Tokens (ZTM v2.0)
|
|
163
|
+
|
|
164
|
+
```typescript
|
|
165
|
+
// After milestone passes, claim investor tokens
|
|
166
|
+
await client.claimInvestorTokens({
|
|
167
|
+
projectId,
|
|
168
|
+
milestoneIndex: 0,
|
|
169
|
+
nftMint: myInvestmentNft,
|
|
170
|
+
investorTokenAccount: myProjectTokenAccount,
|
|
171
|
+
});
|
|
172
|
+
```
|
|
173
|
+
|
|
125
174
|
### Fetch Account Data
|
|
126
175
|
|
|
127
176
|
```typescript
|
|
128
177
|
// Fetch project
|
|
129
178
|
const project = await client.fetchProject(projectId);
|
|
130
179
|
console.log('Project state:', project?.state);
|
|
131
|
-
console.log('Amount raised:', project
|
|
180
|
+
console.log('Amount raised:', USDC.fromAmount(BigInt(project.amountRaised.toString())));
|
|
132
181
|
|
|
133
182
|
// Fetch all investments
|
|
134
183
|
const investments = await client.fetchAllInvestments(projectId);
|
|
135
184
|
console.log(`Total investors: ${investments.length}`);
|
|
136
185
|
|
|
137
|
-
// Fetch
|
|
138
|
-
const
|
|
186
|
+
// Fetch all milestones
|
|
187
|
+
const milestones = await client.fetchAllMilestones(projectId);
|
|
188
|
+
milestones.forEach((m, i) => {
|
|
189
|
+
console.log(`Milestone ${i}: ${m.account.description} (${m.account.percentage}%)`);
|
|
190
|
+
});
|
|
139
191
|
```
|
|
140
192
|
|
|
141
193
|
## Modular Imports
|
|
@@ -144,68 +196,90 @@ Import only what you need for smaller bundles:
|
|
|
144
196
|
|
|
145
197
|
```typescript
|
|
146
198
|
// PDAs only
|
|
147
|
-
import { getProjectPDA, getInvestmentPDA } from '@raise
|
|
199
|
+
import { getProjectPDA, getInvestmentPDA, getTokenomicsPDA } from '@zemyth/raise-sdk/pdas';
|
|
148
200
|
|
|
149
201
|
// Constants only
|
|
150
|
-
import { TIMING,
|
|
202
|
+
import { TIMING, GOVERNANCE, USDC, TIER_CONSTRAINTS } from '@zemyth/raise-sdk/constants';
|
|
151
203
|
|
|
152
204
|
// Account fetchers only
|
|
153
|
-
import { fetchProject, fetchAllInvestments } from '@raise
|
|
205
|
+
import { fetchProject, fetchAllInvestments } from '@zemyth/raise-sdk/accounts';
|
|
154
206
|
|
|
155
207
|
// Instructions only
|
|
156
|
-
import { invest, voteOnMilestone } from '@raise
|
|
208
|
+
import { invest, voteOnMilestone, claimInvestorTokens } from '@zemyth/raise-sdk/instructions';
|
|
157
209
|
|
|
158
210
|
// Error handling only
|
|
159
|
-
import { parseError, ERROR_CODES } from '@raise
|
|
211
|
+
import { parseError, ERROR_CODES, isRaiseError } from '@zemyth/raise-sdk/errors';
|
|
160
212
|
|
|
161
213
|
// Types only
|
|
162
|
-
import type { ProjectAccount, MilestoneAccount } from '@raise
|
|
214
|
+
import type { ProjectAccount, MilestoneAccount, TierConfig } from '@zemyth/raise-sdk/types';
|
|
163
215
|
```
|
|
164
216
|
|
|
165
217
|
## Constants Reference
|
|
166
218
|
|
|
167
|
-
###
|
|
219
|
+
### Tier Configuration (v2.0)
|
|
220
|
+
|
|
221
|
+
Projects now define custom tiers with flexible configuration:
|
|
168
222
|
|
|
169
223
|
```typescript
|
|
170
|
-
import {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
//
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
//
|
|
185
|
-
|
|
186
|
-
|
|
224
|
+
import { TIER_CONSTRAINTS, type TierConfig } from '@zemyth/raise-sdk';
|
|
225
|
+
|
|
226
|
+
// Tier constraints
|
|
227
|
+
console.log(TIER_CONSTRAINTS.MIN_TIERS); // 1
|
|
228
|
+
console.log(TIER_CONSTRAINTS.MAX_TIERS); // 10
|
|
229
|
+
console.log(TIER_CONSTRAINTS.MIN_TIER_AMOUNT); // 10_000_000n (10 USDC)
|
|
230
|
+
console.log(TIER_CONSTRAINTS.MIN_TIER_MAX_LOTS); // 1
|
|
231
|
+
console.log(TIER_CONSTRAINTS.MIN_TIER_VOTE_MULTIPLIER); // 100 (1.0x)
|
|
232
|
+
|
|
233
|
+
// Example tier configuration
|
|
234
|
+
const tiers: TierConfig[] = [
|
|
235
|
+
{
|
|
236
|
+
amount: new BN(100_000_000), // 100 USDC per lot
|
|
237
|
+
maxLots: 1000, // Max 1000 lots available
|
|
238
|
+
tokenRatio: new BN(100), // 100 tokens per $1
|
|
239
|
+
voteMultiplier: 100, // 1.0x vote weight
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
amount: new BN(1_000_000_000), // 1,000 USDC per lot
|
|
243
|
+
maxLots: 100,
|
|
244
|
+
tokenRatio: new BN(150), // 150 tokens per $1 (bonus)
|
|
245
|
+
voteMultiplier: 150, // 1.5x vote weight
|
|
246
|
+
},
|
|
247
|
+
];
|
|
187
248
|
```
|
|
188
249
|
|
|
189
250
|
### Timing Constants
|
|
190
251
|
|
|
191
252
|
```typescript
|
|
192
|
-
import { TIMING } from '@raise
|
|
193
|
-
|
|
194
|
-
console.log(TIMING.VOTING_PERIOD_SECONDS);
|
|
195
|
-
console.log(TIMING.HOLD_PERIOD_SECONDS);
|
|
196
|
-
console.log(TIMING.
|
|
197
|
-
console.log(TIMING.
|
|
253
|
+
import { TIMING } from '@zemyth/raise-sdk';
|
|
254
|
+
|
|
255
|
+
console.log(TIMING.VOTING_PERIOD_SECONDS); // 1,209,600 (14 days)
|
|
256
|
+
console.log(TIMING.HOLD_PERIOD_SECONDS); // 604,800 (7 days)
|
|
257
|
+
console.log(TIMING.ABANDONMENT_TIMEOUT_SECONDS); // 7,776,000 (90 days)
|
|
258
|
+
console.log(TIMING.PIVOT_WITHDRAWAL_WINDOW_SECONDS); // 604,800 (7 days)
|
|
259
|
+
console.log(TIMING.REFUND_WINDOW_SECONDS); // 1,209,600 (14 days)
|
|
260
|
+
console.log(TIMING.TGE_MIN_DAYS); // 1,296,000 (15 days)
|
|
261
|
+
console.log(TIMING.TGE_MAX_DAYS); // 7,776,000 (90 days)
|
|
198
262
|
```
|
|
199
263
|
|
|
200
264
|
### Governance Parameters
|
|
201
265
|
|
|
202
266
|
```typescript
|
|
203
|
-
import { GOVERNANCE } from '@raise
|
|
267
|
+
import { GOVERNANCE } from '@zemyth/raise-sdk';
|
|
204
268
|
|
|
205
269
|
console.log(GOVERNANCE.MILESTONE_APPROVAL_THRESHOLD_PERCENT); // 50 (>50%)
|
|
206
|
-
console.log(GOVERNANCE.
|
|
207
|
-
console.log(GOVERNANCE.
|
|
208
|
-
|
|
270
|
+
console.log(GOVERNANCE.SCAM_THRESHOLD_PERCENT); // 30 (30%)
|
|
271
|
+
console.log(GOVERNANCE.CONSECUTIVE_FAILURES_THRESHOLD); // 3
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### Validation Constants
|
|
275
|
+
|
|
276
|
+
```typescript
|
|
277
|
+
import { VALIDATION } from '@zemyth/raise-sdk';
|
|
278
|
+
|
|
279
|
+
console.log(VALIDATION.MIN_MILESTONES); // 2
|
|
280
|
+
console.log(VALIDATION.MAX_MILESTONES); // 10
|
|
281
|
+
console.log(VALIDATION.MILESTONE_PERCENTAGE_SUM); // 100
|
|
282
|
+
console.log(VALIDATION.MAX_METADATA_URI_LENGTH); // 200
|
|
209
283
|
```
|
|
210
284
|
|
|
211
285
|
## Error Handling
|
|
@@ -215,8 +289,9 @@ import {
|
|
|
215
289
|
parseError,
|
|
216
290
|
isRaiseError,
|
|
217
291
|
getErrorMessage,
|
|
218
|
-
ERROR_CODES
|
|
219
|
-
|
|
292
|
+
ERROR_CODES,
|
|
293
|
+
RaiseError
|
|
294
|
+
} from '@zemyth/raise-sdk';
|
|
220
295
|
|
|
221
296
|
try {
|
|
222
297
|
await client.invest({ ... });
|
|
@@ -227,12 +302,119 @@ try {
|
|
|
227
302
|
console.error('Investment too small for minimum tier');
|
|
228
303
|
} else if (isRaiseError(parsed, ERROR_CODES.FundingGoalExceeded)) {
|
|
229
304
|
console.error('Project is fully funded');
|
|
305
|
+
} else if (isRaiseError(parsed, ERROR_CODES.InvalidTier)) {
|
|
306
|
+
console.error('No matching tier for investment amount');
|
|
307
|
+
} else if (parsed instanceof RaiseError) {
|
|
308
|
+
console.error(`Program error ${parsed.code}: ${parsed.message}`);
|
|
230
309
|
} else {
|
|
231
310
|
console.error(getErrorMessage(parsed));
|
|
232
311
|
}
|
|
233
312
|
}
|
|
234
313
|
```
|
|
235
314
|
|
|
315
|
+
### Error Code Categories
|
|
316
|
+
|
|
317
|
+
| Range | Category |
|
|
318
|
+
|-------|----------|
|
|
319
|
+
| 6000-6099 | State Transition Errors |
|
|
320
|
+
| 6100-6199 | Authorization Errors |
|
|
321
|
+
| 6200-6299 | Investment Errors |
|
|
322
|
+
| 6300-6399 | Milestone Errors |
|
|
323
|
+
| 6400-6499 | TGE Errors |
|
|
324
|
+
| 6500-6599 | Pivot Errors |
|
|
325
|
+
| 6800-6899 | Refund Errors |
|
|
326
|
+
| 6900-6999 | Scam Report Errors |
|
|
327
|
+
|
|
328
|
+
## Event Parsing
|
|
329
|
+
|
|
330
|
+
```typescript
|
|
331
|
+
import {
|
|
332
|
+
EVENT_NAMES,
|
|
333
|
+
filterEventsByName,
|
|
334
|
+
findEvent,
|
|
335
|
+
type ProjectCreatedEvent,
|
|
336
|
+
type InvestmentMadeEvent
|
|
337
|
+
} from '@zemyth/raise-sdk';
|
|
338
|
+
|
|
339
|
+
// Parse events from transaction logs
|
|
340
|
+
const tx = await connection.getTransaction(signature, {
|
|
341
|
+
maxSupportedTransactionVersion: 0,
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
// Filter specific event type
|
|
345
|
+
const investmentEvents = filterEventsByName<InvestmentMadeEvent>(
|
|
346
|
+
parsedEvents,
|
|
347
|
+
EVENT_NAMES.InvestmentMade
|
|
348
|
+
);
|
|
349
|
+
|
|
350
|
+
// Find first matching event
|
|
351
|
+
const projectCreated = findEvent<ProjectCreatedEvent>(
|
|
352
|
+
parsedEvents,
|
|
353
|
+
EVENT_NAMES.ProjectCreated
|
|
354
|
+
);
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
## PDA Reference
|
|
358
|
+
|
|
359
|
+
### Core PDAs
|
|
360
|
+
|
|
361
|
+
```typescript
|
|
362
|
+
import {
|
|
363
|
+
getProjectPDA,
|
|
364
|
+
getEscrowPDA,
|
|
365
|
+
getMilestonePDA,
|
|
366
|
+
getInvestmentPDA,
|
|
367
|
+
getVotePDA,
|
|
368
|
+
getPivotProposalPDA,
|
|
369
|
+
getAdminConfigPDA,
|
|
370
|
+
getNftMintPDA,
|
|
371
|
+
getProjectPDAs,
|
|
372
|
+
} from '@zemyth/raise-sdk';
|
|
373
|
+
|
|
374
|
+
// Derive project and escrow PDAs together
|
|
375
|
+
const { project, escrow } = getProjectPDAs(projectId, programId);
|
|
376
|
+
|
|
377
|
+
// Derive milestone PDA
|
|
378
|
+
const milestonePda = getMilestonePDA(projectPda, 0, programId);
|
|
379
|
+
|
|
380
|
+
// Derive investment PDA
|
|
381
|
+
const investmentPda = getInvestmentPDA(projectPda, nftMint, programId);
|
|
382
|
+
|
|
383
|
+
// Derive vote PDA (includes voting round for rework support)
|
|
384
|
+
const votePda = getVotePDA(milestonePda, voterKey, votingRound, programId);
|
|
385
|
+
|
|
386
|
+
// Derive NFT mint PDA
|
|
387
|
+
const [nftMint, bump] = getNftMintPDA(projectId, investor, investmentCount, programId);
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
### ZTM v2.0 PDAs
|
|
391
|
+
|
|
392
|
+
```typescript
|
|
393
|
+
import {
|
|
394
|
+
getTokenomicsPDA,
|
|
395
|
+
getTokenMintPDA,
|
|
396
|
+
getVaultAuthorityPDA,
|
|
397
|
+
getInvestorVaultPDA,
|
|
398
|
+
getFounderVaultPDA,
|
|
399
|
+
getLpTokenVaultPDA,
|
|
400
|
+
getTreasuryVaultPDA,
|
|
401
|
+
getLpUsdcVaultPDA,
|
|
402
|
+
getFounderVestingPDA,
|
|
403
|
+
} from '@zemyth/raise-sdk';
|
|
404
|
+
|
|
405
|
+
// Token distribution vaults
|
|
406
|
+
const tokenomics = getTokenomicsPDA(projectPda, programId);
|
|
407
|
+
const tokenMint = getTokenMintPDA(projectPda, programId);
|
|
408
|
+
const investorVault = getInvestorVaultPDA(projectPda, programId);
|
|
409
|
+
const founderVault = getFounderVaultPDA(projectPda, programId);
|
|
410
|
+
const lpTokenVault = getLpTokenVaultPDA(projectPda, programId);
|
|
411
|
+
const treasuryVault = getTreasuryVaultPDA(projectPda, programId);
|
|
412
|
+
const lpUsdcVault = getLpUsdcVaultPDA(projectPda, programId);
|
|
413
|
+
|
|
414
|
+
// Founder vesting
|
|
415
|
+
const founderVesting = getFounderVestingPDA(projectPda, programId);
|
|
416
|
+
```
|
|
417
|
+
|
|
236
418
|
## Utility Functions
|
|
237
419
|
|
|
238
420
|
### Time Helpers
|
|
@@ -242,8 +424,9 @@ import {
|
|
|
242
424
|
timeRemaining,
|
|
243
425
|
formatDuration,
|
|
244
426
|
hasTimestampPassed,
|
|
245
|
-
timestampToDate
|
|
246
|
-
|
|
427
|
+
timestampToDate,
|
|
428
|
+
getCurrentTimestamp
|
|
429
|
+
} from '@zemyth/raise-sdk';
|
|
247
430
|
|
|
248
431
|
// Check voting deadline
|
|
249
432
|
const milestone = await client.fetchMilestone(projectId, 0);
|
|
@@ -255,34 +438,66 @@ if (milestone?.votingEndsAt) {
|
|
|
255
438
|
if (hasTimestampPassed(milestone.votingEndsAt)) {
|
|
256
439
|
console.log('Voting period ended');
|
|
257
440
|
}
|
|
441
|
+
|
|
442
|
+
const endDate = timestampToDate(milestone.votingEndsAt);
|
|
443
|
+
console.log(`Ends at: ${endDate.toISOString()}`);
|
|
258
444
|
}
|
|
259
445
|
```
|
|
260
446
|
|
|
261
447
|
### USDC Conversions
|
|
262
448
|
|
|
263
449
|
```typescript
|
|
264
|
-
import { USDC } from '@raise
|
|
450
|
+
import { USDC } from '@zemyth/raise-sdk';
|
|
265
451
|
|
|
266
|
-
// Convert USDC to lamports
|
|
452
|
+
// Convert USDC to lamports (6 decimals)
|
|
267
453
|
const lamports = USDC.toAmount(100); // 100_000_000n
|
|
268
454
|
|
|
269
455
|
// Convert lamports to USDC
|
|
270
456
|
const usdc = USDC.fromAmount(100_000_000n); // 100
|
|
271
457
|
```
|
|
272
458
|
|
|
459
|
+
### BN Conversions
|
|
460
|
+
|
|
461
|
+
```typescript
|
|
462
|
+
import { bnToNumber, bnToBigInt, bigIntToBN, BN } from '@zemyth/raise-sdk';
|
|
463
|
+
|
|
464
|
+
const bn = new BN('1000000000');
|
|
465
|
+
const bigint = bnToBigInt(bn); // 1000000000n
|
|
466
|
+
const num = bnToNumber(bn); // 1000000000 (throws if unsafe)
|
|
467
|
+
const back = bigIntToBN(bigint); // BN
|
|
468
|
+
```
|
|
469
|
+
|
|
273
470
|
### Validation
|
|
274
471
|
|
|
275
472
|
```typescript
|
|
276
473
|
import {
|
|
277
474
|
validateMilestonePercentages,
|
|
278
|
-
validateMetadataUri
|
|
279
|
-
|
|
475
|
+
validateMetadataUri,
|
|
476
|
+
isValidPublicKey,
|
|
477
|
+
shortenPublicKey
|
|
478
|
+
} from '@zemyth/raise-sdk';
|
|
280
479
|
|
|
281
480
|
// Validate milestone percentages sum to 100
|
|
282
|
-
|
|
481
|
+
validateMilestonePercentages([30, 40, 30]); // true
|
|
482
|
+
validateMilestonePercentages([30, 40, 20]); // false
|
|
283
483
|
|
|
284
484
|
// Validate metadata URI
|
|
285
|
-
|
|
485
|
+
validateMetadataUri('https://example.com/project.json'); // true
|
|
486
|
+
validateMetadataUri('not-a-url'); // false
|
|
487
|
+
|
|
488
|
+
// Public key utilities
|
|
489
|
+
isValidPublicKey('ABC123...'); // true/false
|
|
490
|
+
shortenPublicKey(pubkey, 4); // "ABC1...XYZ9"
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
### Percentage Utilities
|
|
494
|
+
|
|
495
|
+
```typescript
|
|
496
|
+
import { bpsToPercent, percentToBps, percentageOf } from '@zemyth/raise-sdk';
|
|
497
|
+
|
|
498
|
+
bpsToPercent(2000); // 0.2 (20%)
|
|
499
|
+
percentToBps(0.2); // 2000
|
|
500
|
+
percentageOf(1000n, 20); // 200n
|
|
286
501
|
```
|
|
287
502
|
|
|
288
503
|
## React Integration
|
|
@@ -291,10 +506,10 @@ const isValidUri = validateMetadataUri('https://example.com/project.json');
|
|
|
291
506
|
import { useMemo } from 'react';
|
|
292
507
|
import { useConnection, useWallet } from '@solana/wallet-adapter-react';
|
|
293
508
|
import { Program, AnchorProvider } from '@coral-xyz/anchor';
|
|
294
|
-
import { RaiseClient } from '@raise
|
|
509
|
+
import { RaiseClient } from '@zemyth/raise-sdk';
|
|
295
510
|
import idl from './idl/raise.json';
|
|
296
511
|
|
|
297
|
-
export function
|
|
512
|
+
export function useRaiseClient(): RaiseClient | null {
|
|
298
513
|
const { connection } = useConnection();
|
|
299
514
|
const wallet = useWallet();
|
|
300
515
|
|
|
@@ -315,25 +530,33 @@ export function useRaise(): RaiseClient | null {
|
|
|
315
530
|
}
|
|
316
531
|
|
|
317
532
|
// Usage in component
|
|
318
|
-
function InvestButton({ projectId }) {
|
|
319
|
-
const client =
|
|
533
|
+
function InvestButton({ projectId }: { projectId: string }) {
|
|
534
|
+
const client = useRaiseClient();
|
|
535
|
+
const [loading, setLoading] = useState(false);
|
|
320
536
|
|
|
321
537
|
const handleInvest = async () => {
|
|
322
538
|
if (!client) return;
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
539
|
+
setLoading(true);
|
|
540
|
+
|
|
541
|
+
try {
|
|
542
|
+
const tx = await client.invest({
|
|
543
|
+
projectId: new BN(projectId),
|
|
544
|
+
amount: new BN(100_000_000),
|
|
545
|
+
investorTokenAccount: myUsdcAta,
|
|
546
|
+
escrowTokenAccount: projectEscrow,
|
|
547
|
+
investmentCount: project.investorCount,
|
|
548
|
+
});
|
|
549
|
+
console.log('Investment tx:', tx);
|
|
550
|
+
} catch (error) {
|
|
551
|
+
console.error(parseError(error).message);
|
|
552
|
+
} finally {
|
|
553
|
+
setLoading(false);
|
|
554
|
+
}
|
|
332
555
|
};
|
|
333
556
|
|
|
334
557
|
return (
|
|
335
|
-
<button onClick={handleInvest} disabled={!client}>
|
|
336
|
-
Invest
|
|
558
|
+
<button onClick={handleInvest} disabled={!client || loading}>
|
|
559
|
+
{loading ? 'Investing...' : 'Invest'}
|
|
337
560
|
</button>
|
|
338
561
|
);
|
|
339
562
|
}
|
|
@@ -344,56 +567,164 @@ function InvestButton({ projectId }) {
|
|
|
344
567
|
### RaiseClient Methods
|
|
345
568
|
|
|
346
569
|
#### Admin Operations
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
570
|
+
| Method | Description |
|
|
571
|
+
|--------|-------------|
|
|
572
|
+
| `initializeAdmin(admin)` | Initialize admin config |
|
|
573
|
+
| `transferAdmin(newAdmin, adminKeypair)` | Propose admin transfer |
|
|
574
|
+
| `acceptAdmin()` | Accept admin transfer |
|
|
350
575
|
|
|
351
576
|
#### Project Operations
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
577
|
+
| Method | Description |
|
|
578
|
+
|--------|-------------|
|
|
579
|
+
| `initializeProject(args)` | Create new project with tiers and tokenomics |
|
|
580
|
+
| `submitForApproval(projectId)` | Submit for admin approval |
|
|
581
|
+
| `approveProject(args, adminKeypair)` | Approve project (admin) |
|
|
355
582
|
|
|
356
583
|
#### Milestone Operations
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
584
|
+
| Method | Description |
|
|
585
|
+
|--------|-------------|
|
|
586
|
+
| `createMilestone(args)` | Add milestone to project |
|
|
587
|
+
| `submitMilestone(projectId, index)` | Submit milestone for voting |
|
|
588
|
+
| `voteOnMilestone(args)` | Cast vote (Good/Bad) |
|
|
589
|
+
| `finalizeVoting(projectId, index)` | End voting period |
|
|
590
|
+
| `claimMilestoneFunds(args)` | Claim funds after passing |
|
|
591
|
+
| `resubmitMilestone(args)` | Resubmit failed milestone for rework |
|
|
592
|
+
| `setMilestoneDeadline(args)` | Set milestone deadline |
|
|
593
|
+
| `extendMilestoneDeadline(args)` | Extend deadline (max 3x) |
|
|
362
594
|
|
|
363
595
|
#### Investment Operations
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
596
|
+
| Method | Description |
|
|
597
|
+
|--------|-------------|
|
|
598
|
+
| `invest(args)` | Invest USDC, receive NFT |
|
|
599
|
+
| `cancelInvestment(args)` | Cancel within 24h cooling-off |
|
|
600
|
+
|
|
601
|
+
#### Token Distribution (ZTM v2.0)
|
|
602
|
+
| Method | Description |
|
|
603
|
+
|--------|-------------|
|
|
604
|
+
| `claimInvestorTokens(args)` | Claim tokens after milestone passes |
|
|
605
|
+
| `distributeTokens(args)` | Batch distribute (deprecated) |
|
|
606
|
+
| `completeDistribution(args)` | Mark distribution complete |
|
|
607
|
+
|
|
608
|
+
#### Founder Vesting (ZTM v2.0)
|
|
609
|
+
| Method | Description |
|
|
610
|
+
|--------|-------------|
|
|
611
|
+
| `initializeFounderVesting(args)` | Initialize vesting after MAE |
|
|
612
|
+
| `claimVestedTokens(args)` | Claim vested tokens |
|
|
613
|
+
|
|
614
|
+
#### Circuit Breaker (ZTM v2.0)
|
|
615
|
+
| Method | Description |
|
|
616
|
+
|--------|-------------|
|
|
617
|
+
| `forceCompleteDistribution(args, adminKeypair)` | Force-complete stuck distribution (admin) |
|
|
618
|
+
| `claimMissedUnlock(args)` | Claim tokens after force-complete |
|
|
378
619
|
|
|
379
620
|
#### Pivot Operations
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
621
|
+
| Method | Description |
|
|
622
|
+
|--------|-------------|
|
|
623
|
+
| `proposePivot(args)` | Propose project pivot |
|
|
624
|
+
| `approvePivot(projectId, adminKeypair)` | Approve pivot (admin) |
|
|
625
|
+
| `withdrawFromPivot(args)` | Withdraw during 7-day window |
|
|
626
|
+
| `finalizePivot(args)` | Finalize after window ends |
|
|
627
|
+
|
|
628
|
+
#### TGE Operations (Legacy)
|
|
629
|
+
| Method | Description |
|
|
630
|
+
|--------|-------------|
|
|
631
|
+
| `setTgeDate(args)` | Set token generation date |
|
|
632
|
+
| `depositTokens(args)` | Deposit tokens for distribution |
|
|
633
|
+
| `claimTokens(args)` | Claim allocated tokens |
|
|
634
|
+
| `reportScam(args)` | Report potential scam |
|
|
635
|
+
| `releaseHoldback(args)` | Release 10% founder holdback |
|
|
636
|
+
|
|
637
|
+
#### Abandonment & Refunds
|
|
638
|
+
| Method | Description |
|
|
639
|
+
|--------|-------------|
|
|
640
|
+
| `checkAbandonment(projectId, milestoneIndex)` | Check for abandonment |
|
|
641
|
+
| `claimRefund(args)` | Claim refund from abandoned project |
|
|
384
642
|
|
|
385
643
|
#### Account Fetchers
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
644
|
+
| Method | Description |
|
|
645
|
+
|--------|-------------|
|
|
646
|
+
| `fetchProject(projectId)` | Fetch project account |
|
|
647
|
+
| `fetchMilestone(projectId, index)` | Fetch milestone account |
|
|
648
|
+
| `fetchAllMilestones(projectId)` | Fetch all milestones |
|
|
649
|
+
| `fetchInvestment(projectId, nftMint)` | Fetch investment account |
|
|
650
|
+
| `fetchAllInvestments(projectId)` | Fetch all investments |
|
|
651
|
+
| `fetchVote(projectId, index, voter, round)` | Fetch vote account |
|
|
652
|
+
| `fetchAllVotes(projectId, index)` | Fetch all votes |
|
|
653
|
+
| `fetchPivotProposal(projectId)` | Fetch pivot proposal |
|
|
654
|
+
| `fetchTgeEscrow(projectId)` | Fetch TGE escrow |
|
|
655
|
+
| `fetchAdminConfig()` | Fetch admin config |
|
|
656
|
+
|
|
657
|
+
## TypeScript Types
|
|
658
|
+
|
|
659
|
+
```typescript
|
|
660
|
+
import type {
|
|
661
|
+
// Account types
|
|
662
|
+
ProjectAccount,
|
|
663
|
+
MilestoneAccount,
|
|
664
|
+
InvestmentAccount,
|
|
665
|
+
VoteAccount,
|
|
666
|
+
AdminConfigAccount,
|
|
667
|
+
PivotProposalAccount,
|
|
668
|
+
TgeEscrowAccount,
|
|
669
|
+
Tier,
|
|
670
|
+
TierConfig,
|
|
671
|
+
|
|
672
|
+
// Enums
|
|
673
|
+
ProjectState,
|
|
674
|
+
MilestoneState,
|
|
675
|
+
VoteChoice,
|
|
676
|
+
PivotState,
|
|
677
|
+
|
|
678
|
+
// Instruction args
|
|
679
|
+
InitializeProjectArgs,
|
|
680
|
+
CreateMilestoneArgs,
|
|
681
|
+
InvestArgs,
|
|
682
|
+
VoteOnMilestoneArgs,
|
|
683
|
+
ProposePivotArgs,
|
|
684
|
+
|
|
685
|
+
// Events
|
|
686
|
+
ProjectCreatedEvent,
|
|
687
|
+
InvestmentMadeEvent,
|
|
688
|
+
MilestoneVoteCastEvent,
|
|
689
|
+
MilestoneVoteFinalizedEvent,
|
|
690
|
+
|
|
691
|
+
// Utility types
|
|
692
|
+
InvestmentWithKey,
|
|
693
|
+
MilestoneWithKey,
|
|
694
|
+
VoteWithKey,
|
|
695
|
+
} from '@zemyth/raise-sdk';
|
|
696
|
+
```
|
|
697
|
+
|
|
698
|
+
### Project States
|
|
699
|
+
|
|
700
|
+
```typescript
|
|
701
|
+
enum ProjectState {
|
|
702
|
+
Draft = 'draft',
|
|
703
|
+
PendingApproval = 'pendingApproval',
|
|
704
|
+
Open = 'open',
|
|
705
|
+
Funded = 'funded',
|
|
706
|
+
InProgress = 'inProgress',
|
|
707
|
+
Completed = 'completed',
|
|
708
|
+
Abandoned = 'abandoned',
|
|
709
|
+
Failed = 'failed',
|
|
710
|
+
TGEFailed = 'tgeFailed',
|
|
711
|
+
Cancelled = 'cancelled',
|
|
712
|
+
}
|
|
713
|
+
```
|
|
714
|
+
|
|
715
|
+
### Milestone States
|
|
716
|
+
|
|
717
|
+
```typescript
|
|
718
|
+
enum MilestoneState {
|
|
719
|
+
Proposed = 'proposed',
|
|
720
|
+
Approved = 'approved',
|
|
721
|
+
InProgress = 'inProgress',
|
|
722
|
+
UnderReview = 'underReview',
|
|
723
|
+
Passed = 'passed',
|
|
724
|
+
Failed = 'failed',
|
|
725
|
+
Unlocked = 'unlocked',
|
|
726
|
+
}
|
|
727
|
+
```
|
|
397
728
|
|
|
398
729
|
## Development
|
|
399
730
|
|
|
@@ -409,8 +740,17 @@ npm run typecheck
|
|
|
409
740
|
|
|
410
741
|
# Watch mode
|
|
411
742
|
npm run dev
|
|
743
|
+
|
|
744
|
+
# Clean build artifacts
|
|
745
|
+
npm run clean
|
|
412
746
|
```
|
|
413
747
|
|
|
748
|
+
## Links
|
|
749
|
+
|
|
750
|
+
- [GitHub Repository](https://github.com/zemyth/raise)
|
|
751
|
+
- [Issue Tracker](https://github.com/zemyth/raise/issues)
|
|
752
|
+
- [npm Package](https://www.npmjs.com/package/@zemyth/raise-sdk)
|
|
753
|
+
|
|
414
754
|
## License
|
|
415
755
|
|
|
416
756
|
MIT
|