@unifiedflow/unified-flow-sdk 1.0.3 → 1.0.5

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 CHANGED
@@ -1,227 +1,275 @@
1
1
  # @unifiedflow/unified-flow-sdk
2
2
 
3
- TypeScript SDK for interacting with the **Unified Flow** on-chain token vesting and streaming program on Solana.
3
+ TypeScript SDK for interacting with the **Unified Flow** on-chain token vesting and streaming protocol on Solana.
4
4
 
5
5
  ---
6
6
 
7
- ## Installation
7
+ # Installation
8
8
 
9
9
  ```bash
10
10
  npm install @unifiedflow/unified-flow-sdk
11
- # or
12
- yarn add @unifiedflow/unified-flow-sdk
13
11
  ```
14
12
 
15
- ### Peer Dependencies
13
+ or
16
14
 
17
15
  ```bash
18
- npm install @coral-xyz/anchor @solana/web3.js @solana/spl-token
16
+ yarn add @unifiedflow/unified-flow-sdk
19
17
  ```
20
18
 
21
- > **Version note:** Make sure your project uses the same `@coral-xyz/anchor` version as the SDK to avoid type conflicts. Add to `package.json` if needed:
22
- > ```json
23
- > { "overrides": { "@coral-xyz/anchor": "<sdk-anchor-version>" } }
24
- > ```
19
+ ## Peer Dependencies
20
+
21
+ ```bash
22
+ npm install \
23
+ @coral-xyz/anchor \
24
+ @solana/web3.js \
25
+ @solana/spl-token
26
+ ```
25
27
 
26
28
  ---
27
29
 
28
- ## Quick Start
30
+ # Quick Start
29
31
 
30
- ### 1. Initialize the Client
32
+ ## Initialize Client
31
33
 
32
- ```typescript
33
- import { useAnchorWallet, useConnection } from "@solana/wallet-adapter-react";
34
- import { AnchorProvider, Program } from "@coral-xyz/anchor";
35
- import { IDL, UnifiedFlow, UnifiedFlowClient } from "@unifiedflow/unified-flow-sdk";
34
+ ```ts
36
35
  import { useMemo } from "react";
36
+ import { Program, AnchorProvider } from "@coral-xyz/anchor";
37
+ import { useConnection } from "@solana/wallet-adapter-react";
38
+
39
+ import {
40
+ IDL,
41
+ UnifiedFlowClient,
42
+ type UnifiedFlow,
43
+ } from "@unifiedflow/unified-flow-sdk";
44
+
45
+ import { useWalletSession } from "@wallet-standard/react";
37
46
 
38
47
  export function useUnifiedFlowClient() {
39
48
  const { connection } = useConnection();
40
- const wallet = useAnchorWallet();
49
+ const wallet = useWalletSession();
41
50
 
42
51
  return useMemo(() => {
43
52
  if (!wallet) return null;
44
53
 
45
- const provider = new AnchorProvider(connection, wallet, {
46
- commitment: "confirmed",
47
- });
48
-
49
- const program = new Program(IDL, provider) as any;
50
- return new UnifiedFlowClient(program);
54
+ const provider = new AnchorProvider(
55
+ connection,
56
+ {} as any,
57
+ { commitment: "confirmed" }
58
+ );
59
+
60
+ const program = new Program(
61
+ IDL,
62
+ provider
63
+ ) as Program<UnifiedFlow>;
64
+
65
+ return new UnifiedFlowClient(
66
+ program,
67
+ wallet,
68
+ connection,
69
+ "confirmed"
70
+ );
51
71
  }, [wallet, connection]);
52
72
  }
53
73
  ```
54
74
 
55
- ### 2. Use in a Component
75
+ ---
76
+
77
+ # Transaction Status Tracking
78
+
79
+ All transaction methods support an optional status callback.
80
+
81
+ ```ts
82
+ await client.withdraw(streamPDA, (status) => {
83
+ switch (status) {
84
+ case "wallet_approval":
85
+ console.log("Waiting for wallet approval");
86
+ break;
87
+
88
+ case "sending":
89
+ console.log("Sending transaction");
90
+ break;
91
+
92
+ case "confirming":
93
+ console.log("Confirming transaction");
94
+ break;
95
+ }
96
+ });
97
+ ```
56
98
 
57
- ```typescript
58
- const client = useUnifiedFlowClient();
99
+ Available phases:
59
100
 
60
- if (!client) return <p>Connect your wallet</p>;
101
+ ```ts
102
+ type TxProgressPhase =
103
+ | "wallet_approval"
104
+ | "sending"
105
+ | "confirming";
61
106
  ```
62
107
 
63
108
  ---
64
109
 
65
- ## Vesting Types
110
+ # Vesting Types
66
111
 
67
- | Value | Type | Description |
68
- |-------|-------------|--------------------------------------------------|
69
- | `0` | `LINEAR` | Tokens vest continuously over time |
70
- | `1` | `CLIFF` | All tokens unlock at a single cliff timestamp |
71
- | `2` | `MILESTONE` | Tokens unlock per milestone, approved by creator |
112
+ | Value | Type | Description |
113
+ | ----- | --------- | ---------------------------------- |
114
+ | 0 | LINEAR | Continuous linear vesting |
115
+ | 1 | CLIFF | Entire allocation unlocks at cliff |
116
+ | 2 | MILESTONE | Unlocks milestone-by-milestone |
72
117
 
73
118
  ---
74
119
 
75
- ## API Reference
120
+ # API Reference
76
121
 
77
- ### `createStream`
122
+ ## createStream
78
123
 
79
- Create a new vesting stream.
124
+ Creates a new stream.
80
125
 
81
- ```typescript
82
- const builder = await client.createStream(
83
- creator, // PublicKey — stream creator / funder
84
- recipient, // PublicKey — token recipient
85
- mint, // PublicKey — SPL token mint
86
- new BN(1_000_000),// amount — total tokens (in smallest unit)
87
- new BN(startTs), // start timestamp (Unix seconds)
88
- new BN(cliffTs), // cliff timestamp (set equal to startTs if no cliff)
89
- new BN(endTs), // end timestamp
90
- 0, // vestingType: 0 = linear, 1 = cliff, 2 = milestone
91
- [], // milestones: MilestoneInput[] (empty for non-milestone)
92
- new BN(nonce) // unique nonce per creator+recipient pair
126
+ ```ts
127
+ const result = await client.createStream(
128
+ recipient,
129
+ mint,
130
+ new BN(1_000_000),
131
+ new BN(startTs),
132
+ new BN(cliffTs),
133
+ new BN(endTs),
134
+ 0,
135
+ [],
136
+ new BN(nonce)
93
137
  );
94
138
 
95
- const txSig = await builder.rpc();
139
+ console.log(result.signature);
96
140
  ```
97
141
 
98
- **Milestone stream example:**
142
+ ### Milestone Example
99
143
 
100
- ```typescript
101
- const milestones: MilestoneInput[] = [
144
+ ```ts
145
+ const milestones = [
102
146
  { amount: new BN(250_000) },
103
147
  { amount: new BN(250_000) },
104
148
  { amount: new BN(500_000) },
105
149
  ];
106
150
 
107
- const builder = await client.createStream(
108
- creator, recipient, mint,
151
+ await client.createStream(
152
+ recipient,
153
+ mint,
109
154
  new BN(1_000_000),
110
- new BN(startTs), new BN(startTs), new BN(endTs),
111
- 2, // MILESTONE
155
+ new BN(startTs),
156
+ new BN(startTs),
157
+ new BN(endTs),
158
+ 2,
112
159
  milestones,
113
160
  new BN(nonce)
114
161
  );
115
162
  ```
116
163
 
164
+ Returns:
165
+
166
+ ```ts
167
+ {
168
+ signature: string;
169
+ }
170
+ ```
171
+
117
172
  ---
118
173
 
119
- ### `withdraw`
174
+ ## withdraw
120
175
 
121
- Withdraw vested/unlocked tokens from a stream. Callable by the recipient.
176
+ Withdraw vested tokens.
122
177
 
123
- ```typescript
124
- const builder = await client.withdraw(
125
- streamPDA, // PublicKey — stream account address
126
- recipient, // PublicKey
127
- mint // PublicKey
178
+ ```ts
179
+ const result = await client.withdraw(
180
+ streamPDA
128
181
  );
129
182
 
130
- const txSig = await builder.rpc();
183
+ console.log(result.signature);
131
184
  ```
132
185
 
186
+ The recipient must be the connected wallet.
187
+
133
188
  ---
134
189
 
135
- ### `cancel`
190
+ ## cancel
136
191
 
137
- Cancel an active stream. Returns unvested tokens to the creator. Callable by the creator.
192
+ Cancel a stream.
138
193
 
139
- ```typescript
140
- const builder = await client.cancel(
141
- streamPDA, // PublicKey — stream account address
142
- creator, // PublicKey
143
- recipient, // PublicKey
144
- mint // PublicKey
194
+ ```ts
195
+ const result = await client.cancel(
196
+ streamPDA
145
197
  );
146
198
 
147
- const txSig = await builder.rpc();
199
+ console.log(result.signature);
148
200
  ```
149
201
 
202
+ The creator must be the connected wallet.
203
+
150
204
  ---
151
205
 
152
- ### `unlockMilestone`
206
+ ## unlockMilestone
153
207
 
154
- Unlock the next milestone in a milestone vesting stream. Callable by the creator.
208
+ Unlock a milestone.
155
209
 
156
- ```typescript
157
- const builder = await client.unlockMilestone(
158
- streamPDA, // PublicKey
159
- creator, // PublicKey
160
- milestoneIndex // number — 0-indexed
210
+ ```ts
211
+ const result = await client.unlockMilestone(
212
+ streamPDA,
213
+ 0
161
214
  );
162
215
 
163
- const txSig = await builder.rpc();
216
+ console.log(result.signature);
164
217
  ```
165
218
 
166
219
  ---
167
220
 
168
- ### `editMilestone`
221
+ ## editMilestone
169
222
 
170
- Change the token amount for a specific milestone (before it is unlocked).
223
+ Update a milestone allocation.
171
224
 
172
- ```typescript
173
- const builder = await client.editMilestone(
225
+ ```ts
226
+ const result = await client.editMilestone(
174
227
  streamPDA,
175
- creator,
176
228
  mint,
177
- milestoneIndex, // number
178
- new BN(newAmount) // BN
229
+ milestoneIndex,
230
+ new BN(newAmount)
179
231
  );
180
232
 
181
- const txSig = await builder.rpc();
233
+ console.log(result.signature);
182
234
  ```
183
235
 
184
236
  ---
185
237
 
186
- ### `editCliff`
238
+ ## editCliff
187
239
 
188
- Update the cliff timestamp on a cliff vesting stream.
240
+ Update the cliff timestamp.
189
241
 
190
- ```typescript
191
- const builder = await client.editCliff(
242
+ ```ts
243
+ const result = await client.editCliff(
192
244
  streamPDA,
193
- creator,
194
245
  new BN(newCliffTs)
195
246
  );
196
247
 
197
- const txSig = await builder.rpc();
248
+ console.log(result.signature);
198
249
  ```
199
250
 
200
251
  ---
201
252
 
202
- ### `editLinear`
253
+ ## editLinear
203
254
 
204
- Extend the end timestamp and/or top up tokens on a linear vesting stream. Both operations happen in a single transaction.
255
+ Extend a linear stream and/or deposit additional tokens.
205
256
 
206
- ```typescript
207
- const builder = await client.editLinear(
257
+ ```ts
258
+ const result = await client.editLinear(
208
259
  streamPDA,
209
- creator,
210
260
  mint,
211
- new BN(newEndTs), // new end timestamp
212
- new BN(topupAmount) // additional tokens to deposit (0 if no top-up)
261
+ new BN(newEndTs),
262
+ new BN(topupAmount)
213
263
  );
214
264
 
215
- const txSig = await builder.rpc();
265
+ console.log(result.signature);
216
266
  ```
217
267
 
218
268
  ---
219
269
 
220
- ## PDA Helpers
270
+ # PDA Helpers
221
271
 
222
- The SDK exports PDA derivation utilities if you need raw account addresses:
223
-
224
- ```typescript
272
+ ```ts
225
273
  import {
226
274
  getConfigPDA,
227
275
  getStreamPDA,
@@ -229,64 +277,68 @@ import {
229
277
  getFeeVaultPDA,
230
278
  getVaultATA,
231
279
  } from "@unifiedflow/unified-flow-sdk";
232
-
233
- const [streamPDA] = getStreamPDA(creator, recipient, nonce, programId);
234
- const [milestonePDA] = getMilestonePDA(streamPDA, milestoneIndex, programId);
235
280
  ```
236
281
 
237
- ---
282
+ ### Stream PDA
238
283
 
239
- ## Chainlink Oracle
284
+ ```ts
285
+ const [streamPDA] = getStreamPDA(
286
+ creator,
287
+ recipient,
288
+ nonce,
289
+ programId
290
+ );
291
+ ```
240
292
 
241
- Withdrawal fees are denominated in USD and calculated on-chain via the Chainlink SOL/USD price feed. The SDK wires this up automatically — no extra configuration needed.
293
+ ### Milestone PDA
242
294
 
243
- | Constant | Value |
244
- |-----------------------|----------------------------------------------|
245
- | `CHAINLINK_PROGRAM_ID`| `HEvSKofvBgfaexv23kMabbYqxasxU3mQ4ibBMEmJWHny` |
246
- | `SOL_USD_FEED` | `99B2bTijsU6f1GCT73HmdR7HCFFjGMBcPZY6jZ96ynrR` |
295
+ ```ts
296
+ const [milestonePDA] = getMilestonePDA(
297
+ streamPDA,
298
+ milestoneIndex,
299
+ programId
300
+ );
301
+ ```
247
302
 
248
303
  ---
249
304
 
250
- ## Builder Pattern
251
-
252
- All client methods return an **Anchor instruction builder**. You have three options:
305
+ # Chainlink Integration
253
306
 
254
- ```typescript
255
- const builder = await client.withdraw(streamPDA, recipient, mint);
307
+ Withdrawal fees are priced in USD and converted on-chain using Chainlink SOL/USD.
256
308
 
257
- // Execute and return transaction signature
258
- const txSig = await builder.rpc();
309
+ ```ts
310
+ CHAINLINK_PROGRAM_ID
311
+ = HEvSKofvBgfaexv23kMabbYqxasxU3mQ4ibBMEmJWHny
259
312
 
260
- // Build a Transaction object (e.g. for simulation or custom signing)
261
- const tx = await builder.transaction();
262
-
263
- // Simulate without sending
264
- const result = await builder.simulate();
313
+ SOL_USD_FEED
314
+ = 99B2bTijsU6f1GCT73HmdR7HCFFjGMBcPZY6jZ96ynrR
265
315
  ```
266
316
 
317
+ The SDK automatically includes these accounts during withdrawals.
318
+
267
319
  ---
268
320
 
269
- ## Error Reference
321
+ # Error Reference
270
322
 
271
- | Error | Likely Cause |
272
- |-------------------------------|-----------------------------------------------------------|
273
- | `AccountDiscriminatorMismatch`| Wrong cluster (e.g. calling devnet PDA on mainnet RPC) |
274
- | `AccountNotInitialized` | Stream or milestone PDA does not exist yet |
275
- | `InvalidMilestoneIndex` | `milestoneIndex` out of range |
276
- | `StreamNotActive` | Stream already cancelled or fully vested |
323
+ | Error | Description |
324
+ | ---------------------------- | ------------------------------------- |
325
+ | AccountDiscriminatorMismatch | Wrong cluster or incorrect account |
326
+ | AccountNotInitialized | PDA account does not exist |
327
+ | InvalidMilestoneIndex | Milestone index out of range |
328
+ | StreamNotActive | Stream already completed or cancelled |
277
329
 
278
330
  ---
279
331
 
280
- ## Network Support
332
+ # Network Support
281
333
 
282
- | Network | Status |
283
- |---------|--------|
284
- | Devnet | ✅ Supported |
285
- | Mainnet | ✅ Supported |
286
- | Localnet| ✅ Supported (bankrun / solana-test-validator) |
334
+ | Network | Status |
335
+ | -------- | ------ |
336
+ | Devnet | ✅ |
337
+ | Mainnet | ✅ |
338
+ | Localnet | ✅ |
287
339
 
288
340
  ---
289
341
 
290
- ## License
342
+ # License
291
343
 
292
- MIT
344
+ MIT
package/dist/client.d.ts CHANGED
@@ -8,6 +8,11 @@ export interface MilestoneInput {
8
8
  amount: anchor.BN;
9
9
  }
10
10
  export type TxProgressPhase = "wallet_approval" | "sending" | "confirming";
11
+ export declare function getAnchorWallet(session: WalletSession): {
12
+ publicKey: anchor.web3.PublicKey;
13
+ signTransaction: <T extends anchor.web3.Transaction | anchor.web3.VersionedTransaction>(transaction: T) => Promise<T>;
14
+ signAllTransactions: <T extends anchor.web3.Transaction | anchor.web3.VersionedTransaction>(transactions: T[]) => Promise<T[]>;
15
+ };
11
16
  export declare class UnifiedFlowClient {
12
17
  private readonly program;
13
18
  private readonly wallet;
package/dist/client.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.UnifiedFlowClient = exports.SOL_USD_FEED = exports.CHAINLINK_PROGRAM_ID = void 0;
4
+ exports.getAnchorWallet = getAnchorWallet;
4
5
  const web3_js_1 = require("@solana/web3.js");
5
6
  const spl_token_1 = require("@solana/spl-token");
6
7
  const kit_1 = require("@solana/kit");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unifiedflow/unified-flow-sdk",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "SDK for the Unified Flow program",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",