@zebec-network/zebec-stream-sdk 3.1.1 → 3.1.2
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 +531 -208
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,344 +4,667 @@ A TypeScript SDK for interacting with the Zebec Stream protocol on Solana. This
|
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- **Stream Management**: Create, cancel, pause, and
|
|
8
|
-
- **Token Streaming**:
|
|
9
|
-
- **
|
|
10
|
-
- **
|
|
7
|
+
- **Stream Management**: Create, cancel, pause, resume, and withdraw from payment streams
|
|
8
|
+
- **Token Streaming**: SPL token streaming with configurable cliff, frequency, and duration
|
|
9
|
+
- **Tiered Fee System**: Dynamic fee calculation based on stream amount via on-chain fee tiers
|
|
10
|
+
- **Token Whitelisting**: Admin-controlled token whitelist with full metadata resolution via Metaplex
|
|
11
|
+
- **Admin Operations**: Initialize and update global stream configuration, fee tiers, and fee vaults
|
|
12
|
+
- **Flexible Permissions**: Granular per-stream control — cancellation, transfer, topup, pause, and rate update permissions
|
|
13
|
+
- **PDA Utilities**: Helpers for deriving stream config and stream vault program-derived addresses
|
|
14
|
+
- **Provider Abstractions**: Separate read-only and read-write provider helpers
|
|
11
15
|
- **Type Safety**: Full TypeScript support with comprehensive type definitions
|
|
12
16
|
|
|
13
17
|
## Installation
|
|
14
18
|
|
|
15
19
|
```bash
|
|
16
|
-
npm install @zebec-network/stream-sdk
|
|
20
|
+
npm install @zebec-network/zebec-stream-sdk
|
|
17
21
|
```
|
|
18
22
|
|
|
19
23
|
```bash
|
|
20
|
-
yarn add @zebec-network/stream-sdk
|
|
24
|
+
yarn add @zebec-network/zebec-stream-sdk
|
|
21
25
|
```
|
|
22
26
|
|
|
23
27
|
## Quick Start
|
|
24
28
|
|
|
25
|
-
### Setting
|
|
29
|
+
### Setting Up the Service
|
|
26
30
|
|
|
27
31
|
```typescript
|
|
28
|
-
import { Connection
|
|
29
|
-
import { ZebecStreamService, createAnchorProvider } from "@zebec-network/stream-sdk";
|
|
32
|
+
import { Connection } from "@solana/web3.js";
|
|
33
|
+
import { ZebecStreamService, createAnchorProvider } from "@zebec-network/zebec-stream-sdk";
|
|
30
34
|
|
|
31
|
-
// Create connection
|
|
35
|
+
// Create a connection to devnet or mainnet-beta
|
|
32
36
|
const connection = new Connection("https://api.devnet.solana.com");
|
|
33
37
|
|
|
34
|
-
// Create
|
|
38
|
+
// Create an AnchorProvider using your wallet
|
|
35
39
|
const provider = createAnchorProvider(connection, wallet);
|
|
36
40
|
|
|
37
|
-
// Initialize the service
|
|
38
|
-
const streamService = ZebecStreamService.create(provider, "devnet");
|
|
41
|
+
// Initialize the service with a config name and network
|
|
42
|
+
const streamService = ZebecStreamService.create("my-app-config", provider, "devnet");
|
|
39
43
|
```
|
|
40
44
|
|
|
41
45
|
### Creating a Stream
|
|
42
46
|
|
|
43
47
|
```typescript
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
};
|
|
48
|
+
const tx = await streamService.createStream({
|
|
49
|
+
sender: "SenderPublicKeyHere",
|
|
50
|
+
receiver: "ReceiverPublicKeyHere",
|
|
51
|
+
streamToken: "TokenMintAddressHere",
|
|
52
|
+
amount: "1000", // Amount in human-readable token units
|
|
53
|
+
duration: 86400, // Total stream duration in seconds (1 day)
|
|
54
|
+
autoWithdrawFrequency: 3600, // Auto-withdrawal interval in seconds (1 hour)
|
|
55
|
+
streamName: "Monthly Salary",
|
|
56
|
+
startNow: true,
|
|
57
|
+
startTime: Math.floor(Date.now() / 1000),
|
|
58
|
+
cliffPercentage: 0,
|
|
59
|
+
automaticWithdrawal: true,
|
|
60
|
+
cancelableByRecipient: true,
|
|
61
|
+
cancelableBySender: true,
|
|
62
|
+
isPausable: true,
|
|
63
|
+
transferableByRecipient: false,
|
|
64
|
+
transferableBySender: false,
|
|
65
|
+
canTopup: true,
|
|
66
|
+
rateUpdatable: false,
|
|
67
|
+
});
|
|
64
68
|
|
|
65
|
-
const
|
|
66
|
-
|
|
69
|
+
const signature = await tx.execute();
|
|
70
|
+
console.log("Stream created:", signature);
|
|
67
71
|
```
|
|
68
72
|
|
|
69
73
|
## API Reference
|
|
70
74
|
|
|
71
|
-
### ZebecStreamService
|
|
75
|
+
### `ZebecStreamService`
|
|
72
76
|
|
|
73
77
|
The main service class for interacting with Zebec streams.
|
|
74
78
|
|
|
75
|
-
####
|
|
79
|
+
#### `ZebecStreamService.create(streamConfigName, provider, network)`
|
|
80
|
+
|
|
81
|
+
Creates a new service instance. Validates that the provider connection network matches the specified `network`.
|
|
76
82
|
|
|
77
83
|
```typescript
|
|
78
|
-
static create(
|
|
84
|
+
static create(
|
|
85
|
+
streamConfigName: string,
|
|
86
|
+
provider: Provider,
|
|
87
|
+
network: "mainnet-beta" | "devnet"
|
|
88
|
+
): ZebecStreamService
|
|
79
89
|
```
|
|
80
90
|
|
|
91
|
+
| Parameter | Type | Description |
|
|
92
|
+
| --- | --- | --- |
|
|
93
|
+
| `streamConfigName` | `string` | Unique name identifying the stream config PDA |
|
|
94
|
+
| `provider` | `Provider` | Anchor or readonly provider |
|
|
95
|
+
| `network` | `RpcNetwork` | `"mainnet-beta"` or `"devnet"` |
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
81
99
|
### Stream Operations
|
|
82
100
|
|
|
83
|
-
#### createStream(params
|
|
101
|
+
#### `createStream(params)`
|
|
84
102
|
|
|
85
|
-
Creates a new payment stream.
|
|
103
|
+
Creates a new payment stream. Automatically fetches the fee quote from the Zebec backend and includes the fee transfer instruction in the transaction.
|
|
86
104
|
|
|
87
|
-
**Parameters
|
|
105
|
+
**Parameters** (`CreateStreamParams`):
|
|
88
106
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
Cancels an existing stream.
|
|
107
|
+
| Field | Type | Description |
|
|
108
|
+
| --- | --- | --- |
|
|
109
|
+
| `sender` | `Address` | Sender's public key |
|
|
110
|
+
| `receiver` | `Address` | Recipient's public key |
|
|
111
|
+
| `streamToken` | `Address` | SPL token mint address |
|
|
112
|
+
| `amount` | `Numeric` | Amount to stream in human-readable token units |
|
|
113
|
+
| `duration` | `number` | Stream duration in seconds |
|
|
114
|
+
| `autoWithdrawFrequency` | `number` | Auto-withdrawal interval in seconds (must be in config's allowed frequencies when `automaticWithdrawal` is true) |
|
|
115
|
+
| `streamName` | `string` | Human-readable stream name (max 128 bytes) |
|
|
116
|
+
| `startNow` | `boolean` | Whether to start immediately |
|
|
117
|
+
| `startTime` | `number` | Unix timestamp for scheduled start |
|
|
118
|
+
| `cliffPercentage` | `Numeric` | Percentage of amount locked until cliff expires |
|
|
119
|
+
| `automaticWithdrawal` | `boolean` | Enable automatic withdrawals |
|
|
120
|
+
| `cancelableByRecipient` | `boolean` | Allow recipient to cancel |
|
|
121
|
+
| `cancelableBySender` | `boolean` | Allow sender to cancel |
|
|
122
|
+
| `isPausable` | `boolean` | Allow stream to be paused |
|
|
123
|
+
| `transferableByRecipient` | `boolean` | Allow recipient to transfer |
|
|
124
|
+
| `transferableBySender` | `boolean` | Allow sender to transfer |
|
|
125
|
+
| `canTopup` | `boolean` | Allow adding funds to stream |
|
|
126
|
+
| `rateUpdatable` | `boolean` | Allow rate modifications |
|
|
127
|
+
| `feePayer?` | `Address` | Optional custom fee payer (defaults to sender) |
|
|
128
|
+
| `streamMetadataKeypair?` | `Keypair` | Optional custom metadata keypair |
|
|
113
129
|
|
|
114
|
-
**
|
|
130
|
+
**Returns:** `Promise<TransactionPayload>`
|
|
115
131
|
|
|
116
|
-
|
|
117
|
-
- `user`: Address - The user canceling the stream (sender or receiver)
|
|
118
|
-
- `feePayer?`: Address - Optional custom fee payer
|
|
132
|
+
---
|
|
119
133
|
|
|
120
|
-
####
|
|
134
|
+
#### `cancelStream(params)`
|
|
121
135
|
|
|
122
|
-
|
|
136
|
+
Cancels an existing stream. Either sender or receiver can cancel (if allowed by stream permissions).
|
|
123
137
|
|
|
124
|
-
**Parameters
|
|
138
|
+
**Parameters** (`CancelStreamParams`):
|
|
139
|
+
|
|
140
|
+
| Field | Type | Description |
|
|
141
|
+
| --- | --- | --- |
|
|
142
|
+
| `streamMetadata` | `Address` | Stream metadata account address |
|
|
143
|
+
| `user` | `Address` | User canceling the stream (must be sender or receiver) |
|
|
144
|
+
| `feePayer?` | `Address` | Optional custom fee payer |
|
|
145
|
+
|
|
146
|
+
**Returns:** `Promise<TransactionPayload>`
|
|
125
147
|
|
|
126
|
-
|
|
148
|
+
---
|
|
127
149
|
|
|
128
|
-
####
|
|
150
|
+
#### `pauseResumeStream(params)`
|
|
129
151
|
|
|
130
|
-
|
|
152
|
+
Toggles a stream between paused and active states. Only the sender can call this.
|
|
131
153
|
|
|
132
154
|
**Parameters:**
|
|
133
155
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
156
|
+
| Field | Type | Description |
|
|
157
|
+
| --- | --- | --- |
|
|
158
|
+
| `streamMetadata` | `Address` | Stream metadata account address |
|
|
137
159
|
|
|
138
|
-
|
|
160
|
+
**Returns:** `Promise<TransactionPayload>`
|
|
139
161
|
|
|
140
|
-
|
|
162
|
+
---
|
|
141
163
|
|
|
142
|
-
|
|
164
|
+
#### `withdrawStream(params)`
|
|
165
|
+
|
|
166
|
+
Withdraws vested tokens from a stream to the receiver.
|
|
167
|
+
|
|
168
|
+
**Parameters** (`WithdrawStreamParams`):
|
|
169
|
+
|
|
170
|
+
| Field | Type | Description |
|
|
171
|
+
| --- | --- | --- |
|
|
172
|
+
| `streamMetadata` | `Address` | Stream metadata account address |
|
|
173
|
+
| `receiver` | `Address` | Recipient's public key |
|
|
174
|
+
| `withdrawer?` | `Address` | Optional custom withdrawer (defaults to receiver) |
|
|
175
|
+
| `feePayer?` | `Address` | Optional custom fee payer |
|
|
176
|
+
|
|
177
|
+
**Returns:** `Promise<TransactionPayload>`
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
#### `changeStreamReceiver(params)`
|
|
182
|
+
|
|
183
|
+
Transfers stream ownership to a new recipient.
|
|
184
|
+
|
|
185
|
+
**Parameters** (`ChangeStreamReceiverParams`):
|
|
186
|
+
|
|
187
|
+
| Field | Type | Description |
|
|
188
|
+
| --- | --- | --- |
|
|
189
|
+
| `streamMetadata` | `Address` | Stream metadata account address |
|
|
190
|
+
| `newRecipient` | `Address` | New recipient's public key |
|
|
191
|
+
| `signer` | `Address` | Currently authorized signer |
|
|
143
192
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
193
|
+
**Returns:** `Promise<TransactionPayload>`
|
|
194
|
+
|
|
195
|
+
---
|
|
147
196
|
|
|
148
197
|
### Information Retrieval
|
|
149
198
|
|
|
150
|
-
#### getStreamMetadataInfo(streamMetadata
|
|
199
|
+
#### `getStreamMetadataInfo(streamMetadata, commitment?)`
|
|
151
200
|
|
|
152
201
|
Retrieves detailed information about a stream.
|
|
153
202
|
|
|
154
|
-
**Returns:** `StreamMetadataInfo
|
|
203
|
+
**Returns:** `Promise<StreamMetadataInfo>`
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
const info = await streamService.getStreamMetadataInfo("StreamMetadataAddressHere");
|
|
207
|
+
console.log(info.parties.sender.toBase58());
|
|
208
|
+
console.log(info.financials.depositedAmount); // human-readable
|
|
209
|
+
console.log(info.schedule.startTime);
|
|
210
|
+
console.log(info.permissions.isPausable);
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
---
|
|
155
214
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
215
|
+
#### `getStreamConfigInfo(configName, commitment?)`
|
|
216
|
+
|
|
217
|
+
Retrieves the global stream configuration for a given config name.
|
|
218
|
+
|
|
219
|
+
**Returns:** `Promise<StreamConfigInfo>`
|
|
220
|
+
|
|
221
|
+
```typescript
|
|
222
|
+
const config = await streamService.getStreamConfigInfo("my-app-config");
|
|
223
|
+
console.log(config.frequencies); // allowed auto-withdraw intervals
|
|
224
|
+
console.log(config.feeTiers); // tiered fee schedule
|
|
225
|
+
console.log(config.feeVault.toBase58());
|
|
226
|
+
```
|
|
161
227
|
|
|
162
|
-
|
|
228
|
+
---
|
|
163
229
|
|
|
164
|
-
|
|
230
|
+
#### `getWhitelistedTokens(configName, commitment?)`
|
|
165
231
|
|
|
166
|
-
|
|
232
|
+
Fetches the list of whitelisted tokens with full on-chain mint info and Metaplex metadata.
|
|
167
233
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
234
|
+
**Returns:** `Promise<TokenMetadata[]>`
|
|
235
|
+
|
|
236
|
+
```typescript
|
|
237
|
+
const tokens = await streamService.getWhitelistedTokens("my-app-config");
|
|
238
|
+
tokens.forEach(t => {
|
|
239
|
+
console.log(t.metadata?.symbol, t.mint.toBase58());
|
|
240
|
+
});
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
---
|
|
174
244
|
|
|
175
245
|
### Admin Operations
|
|
176
246
|
|
|
177
|
-
####
|
|
247
|
+
#### `initializeStreamConfig(params)`
|
|
178
248
|
|
|
179
|
-
Initializes the global stream configuration (admin only).
|
|
249
|
+
Initializes the global stream configuration (admin only, one-time setup).
|
|
180
250
|
|
|
181
|
-
**Parameters
|
|
251
|
+
**Parameters** (`InitializeStreamConfigParams`):
|
|
182
252
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
253
|
+
```typescript
|
|
254
|
+
await streamService.initializeStreamConfig({
|
|
255
|
+
admin: adminAddress, // optional, defaults to provider wallet
|
|
256
|
+
config: {
|
|
257
|
+
baseFeePercent: "0.1",
|
|
258
|
+
platformFeePercent: "0.05",
|
|
259
|
+
frequencies: [3600, 86400, 604800], // hourly, daily, weekly
|
|
260
|
+
withdrawAccount: "WithdrawAccountAddressHere",
|
|
261
|
+
feeVault: "FeeVaultAddressHere",
|
|
262
|
+
feeTiers: [
|
|
263
|
+
{ minThreshold: "0", maxThreshold: "1000", feeRateInPercent: "1.0" },
|
|
264
|
+
{ minThreshold: "1000", maxThreshold: "10000", feeRateInPercent: "0.75" },
|
|
265
|
+
{ minThreshold: "10000", maxThreshold: "99999999", feeRateInPercent: "0.5" },
|
|
266
|
+
],
|
|
267
|
+
},
|
|
268
|
+
});
|
|
269
|
+
```
|
|
188
270
|
|
|
189
|
-
|
|
271
|
+
---
|
|
190
272
|
|
|
191
|
-
|
|
273
|
+
#### `updateStreamConfig(params)`
|
|
192
274
|
|
|
193
|
-
|
|
275
|
+
Updates an existing stream configuration (admin only).
|
|
276
|
+
|
|
277
|
+
**Parameters** (`UpdateStreamConfigParams`): Same shape as `InitializeStreamConfigParams`.
|
|
278
|
+
|
|
279
|
+
**Returns:** `Promise<TransactionPayload>`
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
#### `whiteListTokens(params)`
|
|
284
|
+
|
|
285
|
+
Adds token mint addresses to the whitelist (admin only).
|
|
286
|
+
|
|
287
|
+
**Parameters** (`WhiteListTokensParams`):
|
|
288
|
+
|
|
289
|
+
| Field | Type | Description |
|
|
290
|
+
| --- | --- | --- |
|
|
291
|
+
| `admin` | `Address` | Admin public key |
|
|
292
|
+
| `tokens` | `Address[]` | Array of token mint addresses to whitelist |
|
|
293
|
+
|
|
294
|
+
**Returns:** `Promise<TransactionPayload>`
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
### Low-Level Instruction Builders
|
|
299
|
+
|
|
300
|
+
Each high-level method has a corresponding instruction builder for composing custom transactions:
|
|
301
|
+
|
|
302
|
+
| Method | Returns |
|
|
303
|
+
| --- | --- |
|
|
304
|
+
| `getCreateStreamInstruction(...)` | `Promise<TransactionInstruction>` |
|
|
305
|
+
| `getCancelStreamInstruction(...)` | `Promise<TransactionInstruction>` |
|
|
306
|
+
| `getPauseResumeStreamInstruction(...)` | `Promise<TransactionInstruction>` |
|
|
307
|
+
| `getWithdrawStreamInstruction(...)` | `Promise<TransactionInstruction>` |
|
|
308
|
+
| `getChangeStreamReceiverInstruction(...)` | `Promise<TransactionInstruction>` |
|
|
309
|
+
| `getWhitelistTokensInstruction(...)` | `Promise<TransactionInstruction>` |
|
|
310
|
+
| `getInitializeStreamConfigInstruction(...)` | `Promise<TransactionInstruction>` |
|
|
311
|
+
| `getUpdateStreamConfigInstruction(...)` | `Promise<TransactionInstruction>` |
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
## Provider Setup
|
|
316
|
+
|
|
317
|
+
### AnchorProvider (Read/Write)
|
|
318
|
+
|
|
319
|
+
Use for operations that sign transactions:
|
|
320
|
+
|
|
321
|
+
```typescript
|
|
322
|
+
import { createAnchorProvider } from "@zebec-network/zebec-stream-sdk";
|
|
323
|
+
|
|
324
|
+
const provider = createAnchorProvider(connection, wallet, {
|
|
325
|
+
commitment: "confirmed",
|
|
326
|
+
preflightCommitment: "confirmed",
|
|
327
|
+
});
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### ReadonlyProvider (Read-Only)
|
|
331
|
+
|
|
332
|
+
Use for read-only queries without a wallet:
|
|
333
|
+
|
|
334
|
+
```typescript
|
|
335
|
+
import { createReadonlyProvider } from "@zebec-network/zebec-stream-sdk";
|
|
336
|
+
|
|
337
|
+
const provider = createReadonlyProvider(connection, optionalWalletAddress);
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
---
|
|
341
|
+
|
|
342
|
+
## PDA Utilities
|
|
343
|
+
|
|
344
|
+
```typescript
|
|
345
|
+
import { deriveStreamConfigPda, deriveStreamVaultPda } from "@zebec-network/zebec-stream-sdk";
|
|
346
|
+
|
|
347
|
+
// Derive the stream config PDA
|
|
348
|
+
const [configPda] = deriveStreamConfigPda("my-app-config", programId);
|
|
349
|
+
|
|
350
|
+
// Derive the stream vault PDA for a given stream metadata address
|
|
351
|
+
const [vaultPda] = deriveStreamVaultPda(streamMetadataAddress, programId);
|
|
352
|
+
```
|
|
194
353
|
|
|
195
|
-
|
|
196
|
-
- `tokens`: Address[] - Array of token mint addresses to whitelist
|
|
354
|
+
---
|
|
197
355
|
|
|
198
356
|
## Types
|
|
199
357
|
|
|
200
|
-
### StreamMetadataInfo
|
|
358
|
+
### `StreamMetadataInfo`
|
|
201
359
|
|
|
202
360
|
```typescript
|
|
203
361
|
type StreamMetadataInfo = {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
362
|
+
address: PublicKey;
|
|
363
|
+
parties: {
|
|
364
|
+
sender: PublicKey;
|
|
365
|
+
receiver: PublicKey;
|
|
366
|
+
};
|
|
367
|
+
financials: {
|
|
368
|
+
streamToken: PublicKey;
|
|
369
|
+
cliffPercentage: number;
|
|
370
|
+
depositedAmount: string; // human-readable
|
|
371
|
+
withdrawnAmount: string; // human-readable
|
|
372
|
+
};
|
|
373
|
+
schedule: {
|
|
374
|
+
startTime: number;
|
|
375
|
+
endTime: number;
|
|
376
|
+
lastWithdrawTime: number;
|
|
377
|
+
frequency: number;
|
|
378
|
+
duration: number;
|
|
379
|
+
pausedTimestamp: number;
|
|
380
|
+
pausedInterval: number;
|
|
381
|
+
canceledTimestamp: number;
|
|
382
|
+
};
|
|
383
|
+
permissions: {
|
|
384
|
+
cancelableBySender: boolean;
|
|
385
|
+
cancelableByRecipient: boolean;
|
|
386
|
+
automaticWithdrawal: boolean;
|
|
387
|
+
transferableBySender: boolean;
|
|
388
|
+
transferableByRecipient: boolean;
|
|
389
|
+
canTopup: boolean;
|
|
390
|
+
isPausable: boolean;
|
|
391
|
+
rateUpdatable: boolean;
|
|
392
|
+
};
|
|
393
|
+
streamName: string;
|
|
235
394
|
};
|
|
236
395
|
```
|
|
237
396
|
|
|
238
|
-
### StreamConfigInfo
|
|
397
|
+
### `StreamConfigInfo`
|
|
239
398
|
|
|
240
399
|
```typescript
|
|
241
400
|
type StreamConfigInfo = {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
401
|
+
address: PublicKey;
|
|
402
|
+
admin: PublicKey;
|
|
403
|
+
withdrawerAccount: PublicKey;
|
|
404
|
+
whitelistedTokens: PublicKey[];
|
|
405
|
+
platformFee: number;
|
|
406
|
+
baseFee: number;
|
|
407
|
+
frequencies: number[];
|
|
408
|
+
feeTiers: FeeTier[];
|
|
409
|
+
feeVault: PublicKey;
|
|
248
410
|
};
|
|
249
411
|
```
|
|
250
412
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
### AnchorProvider (Read/Write Operations)
|
|
254
|
-
|
|
255
|
-
For operations that require signing transactions:
|
|
413
|
+
### `FeeTier`
|
|
256
414
|
|
|
257
415
|
```typescript
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
});
|
|
416
|
+
type FeeTier = {
|
|
417
|
+
minThreshold: Numeric; // minimum USD amount for this tier
|
|
418
|
+
maxThreshold: Numeric; // maximum USD amount for this tier
|
|
419
|
+
feeRateInPercent: Numeric;
|
|
420
|
+
};
|
|
264
421
|
```
|
|
265
422
|
|
|
266
|
-
###
|
|
423
|
+
### `StreamFeeInfo`
|
|
267
424
|
|
|
268
|
-
|
|
425
|
+
Returned by the Zebec backend fee quote API and used internally during stream creation:
|
|
269
426
|
|
|
270
427
|
```typescript
|
|
271
|
-
|
|
428
|
+
type StreamFeeInfo = {
|
|
429
|
+
tokenSymbol: string;
|
|
430
|
+
mintAddress: string;
|
|
431
|
+
chain: string;
|
|
432
|
+
streamAmount: string;
|
|
433
|
+
streamAmountUi: string;
|
|
434
|
+
tokenPriceUsd: number;
|
|
435
|
+
streamAmountUsd: number;
|
|
436
|
+
feeTier: { tier: number; range: string; feeRatePercent: number };
|
|
437
|
+
feeRatePercent: number;
|
|
438
|
+
feeAmountUsd: number;
|
|
439
|
+
feeToken: { symbol: string; decimals: number; priceUsd: number; mintAddress: string };
|
|
440
|
+
feeAmount: number;
|
|
441
|
+
feeAmountRaw: string;
|
|
442
|
+
};
|
|
443
|
+
```
|
|
272
444
|
|
|
273
|
-
|
|
445
|
+
### `TokenMetadata`
|
|
446
|
+
|
|
447
|
+
```typescript
|
|
448
|
+
type TokenMetadata = {
|
|
449
|
+
mint: PublicKey;
|
|
450
|
+
decimals: number;
|
|
451
|
+
freezeAuthority: PublicKey | null;
|
|
452
|
+
supply: string;
|
|
453
|
+
isInitialized: boolean;
|
|
454
|
+
mintAuthority: PublicKey | null;
|
|
455
|
+
metadata: {
|
|
456
|
+
address: PublicKey;
|
|
457
|
+
updateAuthority: PublicKey;
|
|
458
|
+
name: string;
|
|
459
|
+
symbol: string;
|
|
460
|
+
uri: string;
|
|
461
|
+
} | null;
|
|
462
|
+
};
|
|
274
463
|
```
|
|
275
464
|
|
|
276
|
-
|
|
465
|
+
---
|
|
466
|
+
|
|
467
|
+
## Usage Examples
|
|
277
468
|
|
|
278
469
|
### Complete Stream Lifecycle
|
|
279
470
|
|
|
280
471
|
```typescript
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
duration: 86400, // 1 day
|
|
288
|
-
streamFrequency: 3600, // 1 hour
|
|
289
|
-
streamName: "Test Stream",
|
|
290
|
-
startNow: true,
|
|
291
|
-
// ... other parameters
|
|
292
|
-
};
|
|
472
|
+
import { Connection } from "@solana/web3.js";
|
|
473
|
+
import { ZebecStreamService, createAnchorProvider } from "@zebec-network/zebec-stream-sdk";
|
|
474
|
+
|
|
475
|
+
const connection = new Connection("https://api.devnet.solana.com");
|
|
476
|
+
const provider = createAnchorProvider(connection, wallet);
|
|
477
|
+
const streamService = ZebecStreamService.create("my-app-config", provider, "devnet");
|
|
293
478
|
|
|
294
|
-
|
|
295
|
-
await
|
|
479
|
+
// 1. Create a stream
|
|
480
|
+
const createTx = await streamService.createStream({
|
|
481
|
+
sender: senderAddress,
|
|
482
|
+
receiver: receiverAddress,
|
|
483
|
+
streamToken: tokenMintAddress,
|
|
484
|
+
amount: "1000",
|
|
485
|
+
duration: 86400,
|
|
486
|
+
autoWithdrawFrequency: 3600,
|
|
487
|
+
streamName: "Test Stream",
|
|
488
|
+
startNow: true,
|
|
489
|
+
startTime: Math.floor(Date.now() / 1000),
|
|
490
|
+
cliffPercentage: 0,
|
|
491
|
+
automaticWithdrawal: true,
|
|
492
|
+
cancelableByRecipient: false,
|
|
493
|
+
cancelableBySender: true,
|
|
494
|
+
isPausable: true,
|
|
495
|
+
transferableByRecipient: false,
|
|
496
|
+
transferableBySender: false,
|
|
497
|
+
canTopup: false,
|
|
498
|
+
rateUpdatable: false,
|
|
499
|
+
});
|
|
500
|
+
const streamSignature = await createTx.execute();
|
|
501
|
+
console.log("Stream created:", streamSignature);
|
|
296
502
|
|
|
297
|
-
// 2.
|
|
298
|
-
const streamInfo = await streamService.getStreamMetadataInfo(
|
|
299
|
-
console.log("
|
|
503
|
+
// 2. Fetch stream info
|
|
504
|
+
const streamInfo = await streamService.getStreamMetadataInfo(streamMetadataAddress);
|
|
505
|
+
console.log("Deposited:", streamInfo.financials.depositedAmount);
|
|
300
506
|
|
|
301
|
-
// 3. Withdraw
|
|
507
|
+
// 3. Withdraw vested tokens
|
|
302
508
|
const withdrawTx = await streamService.withdrawStream({
|
|
303
|
-
|
|
304
|
-
|
|
509
|
+
streamMetadata: streamMetadataAddress,
|
|
510
|
+
receiver: receiverAddress,
|
|
305
511
|
});
|
|
306
512
|
await withdrawTx.execute();
|
|
307
513
|
|
|
308
|
-
// 4. Cancel stream
|
|
514
|
+
// 4. Cancel the stream
|
|
309
515
|
const cancelTx = await streamService.cancelStream({
|
|
310
|
-
|
|
311
|
-
|
|
516
|
+
streamMetadata: streamMetadataAddress,
|
|
517
|
+
user: senderAddress,
|
|
312
518
|
});
|
|
313
519
|
await cancelTx.execute();
|
|
314
520
|
```
|
|
315
521
|
|
|
522
|
+
### Pause and Resume a Stream
|
|
523
|
+
|
|
524
|
+
```typescript
|
|
525
|
+
const pauseTx = await streamService.pauseResumeStream({
|
|
526
|
+
streamMetadata: streamMetadataAddress,
|
|
527
|
+
});
|
|
528
|
+
await pauseTx.execute(); // toggles between paused and active
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
### Change Stream Receiver
|
|
532
|
+
|
|
533
|
+
```typescript
|
|
534
|
+
const changeTx = await streamService.changeStreamReceiver({
|
|
535
|
+
streamMetadata: streamMetadataAddress,
|
|
536
|
+
newRecipient: newRecipientAddress,
|
|
537
|
+
signer: currentRecipientAddress,
|
|
538
|
+
});
|
|
539
|
+
await changeTx.execute();
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
### Fetch Whitelisted Tokens
|
|
543
|
+
|
|
544
|
+
```typescript
|
|
545
|
+
const tokens = await streamService.getWhitelistedTokens("my-app-config");
|
|
546
|
+
tokens.forEach((token) => {
|
|
547
|
+
console.log(token.metadata?.name, token.metadata?.symbol);
|
|
548
|
+
console.log("Mint:", token.mint.toBase58());
|
|
549
|
+
console.log("Decimals:", token.decimals);
|
|
550
|
+
});
|
|
551
|
+
```
|
|
552
|
+
|
|
316
553
|
### Error Handling
|
|
317
554
|
|
|
318
555
|
```typescript
|
|
319
556
|
try {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
557
|
+
const tx = await streamService.createStream(params);
|
|
558
|
+
const signature = await tx.execute();
|
|
559
|
+
console.log("Success:", signature);
|
|
323
560
|
} catch (error) {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
561
|
+
if (error.message.includes("Invalid stream frequency")) {
|
|
562
|
+
console.error("autoWithdrawFrequency must be one of the config's allowed frequencies");
|
|
563
|
+
} else {
|
|
564
|
+
console.error("Stream creation failed:", error);
|
|
565
|
+
}
|
|
329
566
|
}
|
|
330
567
|
```
|
|
331
568
|
|
|
569
|
+
---
|
|
570
|
+
|
|
571
|
+
## Constants
|
|
572
|
+
|
|
573
|
+
| Constant | Description |
|
|
574
|
+
| --- | --- |
|
|
575
|
+
| `STREAM_PROGRAM_ID` | Program ID per network (`zSTRMmYcFF8SPdHmsAmAUjBnx4zDHvnqqGz2mPcc5QC`) |
|
|
576
|
+
| `STREAM_PROGRAM_LOOKUP_TABLE_ADDRESS` | Address lookup table per network |
|
|
577
|
+
| `SUPERAPP_BACKEND_URL` | Zebec backend URL per network (used for fee quotes) |
|
|
578
|
+
| `STREAM_NAME_BUFFER_SIZE` | Fixed buffer size for stream names (128 bytes) |
|
|
579
|
+
|
|
580
|
+
---
|
|
581
|
+
|
|
332
582
|
## Network Support
|
|
333
583
|
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
584
|
+
| Network | Status |
|
|
585
|
+
| --- | --- |
|
|
586
|
+
| Mainnet Beta | Supported |
|
|
587
|
+
| Devnet | Supported |
|
|
588
|
+
| Testnet | Not supported |
|
|
589
|
+
|
|
590
|
+
---
|
|
337
591
|
|
|
338
592
|
## Dependencies
|
|
339
593
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
-
|
|
594
|
+
| Package | Purpose |
|
|
595
|
+
| --- | --- |
|
|
596
|
+
| `@coral-xyz/anchor` | Anchor framework for Solana program interaction |
|
|
597
|
+
| `@solana/web3.js` | Solana Web3 JavaScript API |
|
|
598
|
+
| `@solana/spl-token` | SPL token utilities |
|
|
599
|
+
| `@metaplex-foundation/mpl-token-metadata` | On-chain token metadata resolution |
|
|
600
|
+
| `@metaplex-foundation/umi` | Metaplex UMI framework |
|
|
601
|
+
| `@metaplex-foundation/umi-bundle-defaults` | UMI default bundle |
|
|
602
|
+
| `@metaplex-foundation/umi-web3js-adapters` | UMI ↔ web3.js adapters |
|
|
603
|
+
| `@zebec-network/core-utils` | Zebec core utility functions (BPS conversions, etc.) |
|
|
604
|
+
| `@zebec-network/solana-common` | Common Solana helpers (ATAs, transaction payload, etc.) |
|
|
605
|
+
| `bignumber.js` | Arbitrary-precision arithmetic for token amounts |
|
|
606
|
+
|
|
607
|
+
---
|
|
608
|
+
|
|
609
|
+
## Development
|
|
610
|
+
|
|
611
|
+
### Install Dependencies
|
|
612
|
+
|
|
613
|
+
```bash
|
|
614
|
+
npm install
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
### Build
|
|
618
|
+
|
|
619
|
+
```bash
|
|
620
|
+
npm run build
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
### Clean Build Artifacts
|
|
624
|
+
|
|
625
|
+
```bash
|
|
626
|
+
npm run clean
|
|
627
|
+
```
|
|
628
|
+
|
|
629
|
+
### Run Tests
|
|
630
|
+
|
|
631
|
+
```bash
|
|
632
|
+
npm test
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
### Run a Single Test File
|
|
636
|
+
|
|
637
|
+
```bash
|
|
638
|
+
npm run test:single -- test/e2e/stream/createStream.test.ts
|
|
639
|
+
```
|
|
640
|
+
|
|
641
|
+
### Format Code
|
|
642
|
+
|
|
643
|
+
```bash
|
|
644
|
+
npm run format
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
---
|
|
648
|
+
|
|
649
|
+
## Publishing
|
|
650
|
+
|
|
651
|
+
1. Bump the version in [package.json](package.json).
|
|
652
|
+
|
|
653
|
+
2. Build the package:
|
|
654
|
+
|
|
655
|
+
```bash
|
|
656
|
+
npm run build
|
|
657
|
+
```
|
|
658
|
+
|
|
659
|
+
3. Publish to npm:
|
|
660
|
+
|
|
661
|
+
```bash
|
|
662
|
+
npm publish --access public
|
|
663
|
+
```
|
|
664
|
+
|
|
665
|
+
Only the `dist/` directory is included in the published package (as specified by the `files` field in [package.json](package.json)).
|
|
666
|
+
|
|
667
|
+
---
|
|
345
668
|
|
|
346
669
|
## License
|
|
347
670
|
|
|
@@ -351,4 +674,4 @@ This project is licensed under the MIT License.
|
|
|
351
674
|
|
|
352
675
|
For issues and questions:
|
|
353
676
|
|
|
354
|
-
- GitHub Issues: [Repository Issues](https://github.com/zebec-network/stream-sdk/issues)
|
|
677
|
+
- GitHub Issues: [Repository Issues](https://github.com/zebec-network/zebec-stream-sdk/issues)
|
package/package.json
CHANGED