Skip to content

Commit b90c6ec

Browse files
committed
Updated version
1 parent dfbc2a1 commit b90c6ec

File tree

8 files changed

+371
-187
lines changed

8 files changed

+371
-187
lines changed

README.md

+11-2
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,26 @@
11
# StreamFlow Timelock
22

3-
Token Vesting and Streaming Payments for SPL tokens. Free and open-source.
3+
Token Vesting and Streaming Payments for SPL tokens. **Free and open-source.**
44

55
Backed by Serum and Solana.
66

77
## Important:
88

99
This software is under active development. It's provided as is, without any warranty.
1010

11-
**The code is not audited.**
11+
**The code is not yet audited.**
1212

1313
### System overview
1414

15+
System has 4 composable layers. There are (top to bottom):
16+
17+
- `streamflow-app` — React/TypeScript [web application that hosts user interface](https://app.streamflow.finance).
18+
- `@streamflow/timelock` — a [NPM package](https://www.npmjs.com/package/@streamflow/timelock) used by the web app.
19+
Interacts with provided `timelock` program deployed on Solana chain.
20+
- `timelock` — simple implementation of Solana/Anchor program that integrates `timelock-crate` (described below).
21+
- `timelock-crate` — a crate that provides `create`, `withdraw`, `cancel`, `transfer` stream/vesting contract
22+
functionalities out of the box. Can be used in other Solana/Anchor programs, as demonstrated here.
23+
1524
![Platform overview](/misc/platform.png)
1625

1726
### Legal

packages/timelock/idl.ts

+17-2
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,20 @@ export default {
9696
{
9797
name: "withdraw",
9898
accounts: [
99+
{
100+
name: "withdrawAuthority",
101+
isMut: false,
102+
isSigner: true,
103+
},
104+
{
105+
name: "sender",
106+
isMut: true,
107+
isSigner: false,
108+
},
99109
{
100110
name: "recipient",
101111
isMut: true,
102-
isSigner: true,
112+
isSigner: false,
103113
},
104114
{
105115
name: "recipientTokens",
@@ -137,10 +147,15 @@ export default {
137147
{
138148
name: "cancel",
139149
accounts: [
150+
{
151+
name: "cancelAuthority",
152+
isMut: false,
153+
isSigner: true,
154+
},
140155
{
141156
name: "sender",
142157
isMut: true,
143-
isSigner: true,
158+
isSigner: false,
144159
},
145160
{
146161
name: "senderTokens",

packages/timelock/layout.ts

+58-38
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,21 @@ import { PublicKey } from "@solana/web3.js";
33
import { BN } from "@project-serum/anchor";
44

55
const LE = "le"; //little endian
6-
const instructionsFields = [
6+
7+
const StreamInstructionLayout = BufferLayout.struct<StreamInstruction>([
78
BufferLayout.blob(8, "start_time"),
89
BufferLayout.blob(8, "end_time"),
910
BufferLayout.blob(8, "deposited_amount"),
1011
BufferLayout.blob(8, "total_amount"),
1112
BufferLayout.blob(8, "period"),
1213
BufferLayout.blob(8, "cliff"),
1314
BufferLayout.blob(8, "cliff_amount"),
14-
];
15-
16-
const StreamInstructionLayout =
17-
BufferLayout.struct<StreamInstruction>(instructionsFields);
15+
BufferLayout.blob(1, "is_cancelable_by_sender"),
16+
BufferLayout.blob(1, "is_cancelable_by_recipient"),
17+
BufferLayout.blob(1, "is_withdrawal_public"),
18+
BufferLayout.blob(1, "is_transferable"),
19+
BufferLayout.blob(4, "padding"),
20+
]);
1821

1922
function decode_stream_instruction(buf: Buffer) {
2023
let raw = StreamInstructionLayout.decode(buf);
@@ -29,69 +32,86 @@ function decode_stream_instruction(buf: Buffer) {
2932
};
3033
}
3134

32-
const TokenStreamDataLayout = BufferLayout.struct<Stream>([
35+
interface StreamInstruction {
36+
start_time: BN;
37+
end_time: BN;
38+
deposited_amount: BN;
39+
total_amount: BN;
40+
period: BN;
41+
cliff: BN;
42+
cliff_amount: BN;
43+
}
44+
45+
const TokenStreamDataLayout = BufferLayout.struct<TokenStreamData>([
3346
BufferLayout.blob(8, "magic"),
34-
...instructionsFields,
3547
BufferLayout.blob(8, "created_at"),
36-
BufferLayout.blob(8, "withdrawn"),
37-
BufferLayout.blob(8, "cancel_time"),
48+
BufferLayout.blob(8, "withdrawn_amount"),
49+
BufferLayout.blob(8, "canceled_at"),
50+
BufferLayout.blob(8, "cancellable_at"),
51+
BufferLayout.blob(8, "last_withdrawn_at"),
3852
BufferLayout.blob(32, "sender"),
3953
BufferLayout.blob(32, "sender_tokens"),
4054
BufferLayout.blob(32, "recipient"),
4155
BufferLayout.blob(32, "recipient_tokens"),
4256
BufferLayout.blob(32, "mint"),
4357
BufferLayout.blob(32, "escrow_tokens"),
58+
BufferLayout.blob(8, "start_time"),
59+
BufferLayout.blob(8, "end_time"),
60+
BufferLayout.blob(8, "deposited_amount"),
61+
BufferLayout.blob(8, "total_amount"),
62+
BufferLayout.blob(8, "period"),
63+
BufferLayout.blob(8, "cliff"),
64+
BufferLayout.blob(8, "cliff_amount"),
65+
BufferLayout.blob(1, "is_cancelable_by_sender"),
66+
BufferLayout.blob(1, "is_cancelable_by_recipient"),
67+
BufferLayout.blob(1, "is_withdrawal_public"),
68+
BufferLayout.blob(1, "is_transferable"),
69+
BufferLayout.blob(4, "padding"),
4470
]);
4571

4672
export function decode(buf: Buffer) {
4773
let raw = TokenStreamDataLayout.decode(buf);
4874
return {
4975
magic: new BN(raw.magic, LE),
50-
start_time: new BN(raw.start_time, LE),
51-
end_time: new BN(raw.end_time, LE),
52-
deposited_amount: new BN(raw.deposited_amount, LE),
53-
total_amount: new BN(raw.total_amount, LE),
54-
period: new BN(raw.period, LE),
55-
cliff: new BN(raw.cliff, LE),
56-
cliff_amount: new BN(raw.cliff_amount, LE),
5776
created_at: new BN(raw.created_at, LE),
58-
withdrawn: new BN(raw.withdrawn, LE),
59-
cancel_time: new BN(raw.cancel_time, LE),
77+
withdrawn_amount: new BN(raw.withdrawn_amount, LE),
78+
canceled_at: new BN(raw.canceled_at, LE),
79+
cancellable_at: new BN(raw.cancellable_at, LE),
80+
last_withdrawn_at: new BN(raw.last_withdrawn_at, LE),
6081
sender: new PublicKey(raw.sender),
6182
sender_tokens: new PublicKey(raw.sender_tokens),
6283
recipient: new PublicKey(raw.recipient),
6384
recipient_tokens: new PublicKey(raw.recipient_tokens),
6485
mint: new PublicKey(raw.mint),
6586
escrow_tokens: new PublicKey(raw.escrow_tokens),
87+
start_time: new BN(raw.start_time, LE),
88+
end_time: new BN(raw.end_time, LE),
89+
deposited_amount: new BN(raw.deposited_amount, LE),
90+
total_amount: new BN(raw.total_amount, LE),
91+
period: new BN(raw.period, LE),
92+
cliff: new BN(raw.cliff, LE),
93+
cliff_amount: new BN(raw.cliff_amount, LE),
6694
};
6795
}
6896

69-
export interface StreamInstruction {
70-
start_time: BN;
71-
end_time: BN;
72-
deposited_amount: BN;
73-
total_amount: BN;
74-
period: BN;
75-
cliff: BN;
76-
cliff_amount: BN;
77-
}
78-
79-
export interface Stream {
97+
export interface TokenStreamData {
8098
magic: BN;
81-
start_time: BN;
82-
end_time: BN;
83-
deposited_amount: BN;
84-
total_amount: BN;
85-
period: BN;
86-
cliff: BN;
87-
cliff_amount: BN;
8899
created_at: BN;
89-
withdrawn: BN;
90-
cancel_time: BN;
100+
withdrawn_amount: BN;
101+
canceled_at: BN;
102+
cancellable_at: BN;
103+
last_withdrawn_at: BN;
91104
sender: PublicKey;
92105
sender_tokens: PublicKey;
93106
recipient: PublicKey;
94107
recipient_tokens: PublicKey;
95108
mint: PublicKey;
96109
escrow_tokens: PublicKey;
110+
start_time: BN;
111+
end_time: BN;
112+
deposited_amount: BN;
113+
total_amount: BN;
114+
period: BN;
115+
cliff: BN;
116+
cliff_amount: BN;
97117
}

packages/timelock/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@streamflow/timelock",
3-
"version": "0.3.1",
3+
"version": "0.3.2",
44
"description": "SDK to interact with StreamFlow Finance's Timelock program on Solana.",
55
"main": "dist/timelock.js",
66
"types": "dist/timelock.d.ts",

0 commit comments

Comments
 (0)