Skip to content

Commit

Permalink
Updated version
Browse files Browse the repository at this point in the history
  • Loading branch information
imprfekt committed Oct 28, 2021
1 parent dfbc2a1 commit b90c6ec
Show file tree
Hide file tree
Showing 8 changed files with 371 additions and 187 deletions.
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
# StreamFlow Timelock

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

Backed by Serum and Solana.

## Important:

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

**The code is not audited.**
**The code is not yet audited.**

### System overview

System has 4 composable layers. There are (top to bottom):

- `streamflow-app` — React/TypeScript [web application that hosts user interface](https://app.streamflow.finance).
- `@streamflow/timelock` — a [NPM package](https://www.npmjs.com/package/@streamflow/timelock) used by the web app.
Interacts with provided `timelock` program deployed on Solana chain.
- `timelock` — simple implementation of Solana/Anchor program that integrates `timelock-crate` (described below).
- `timelock-crate` — a crate that provides `create`, `withdraw`, `cancel`, `transfer` stream/vesting contract
functionalities out of the box. Can be used in other Solana/Anchor programs, as demonstrated here.

![Platform overview](/misc/platform.png)

### Legal
Expand Down
19 changes: 17 additions & 2 deletions packages/timelock/idl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,20 @@ export default {
{
name: "withdraw",
accounts: [
{
name: "withdrawAuthority",
isMut: false,
isSigner: true,
},
{
name: "sender",
isMut: true,
isSigner: false,
},
{
name: "recipient",
isMut: true,
isSigner: true,
isSigner: false,
},
{
name: "recipientTokens",
Expand Down Expand Up @@ -137,10 +147,15 @@ export default {
{
name: "cancel",
accounts: [
{
name: "cancelAuthority",
isMut: false,
isSigner: true,
},
{
name: "sender",
isMut: true,
isSigner: true,
isSigner: false,
},
{
name: "senderTokens",
Expand Down
96 changes: 58 additions & 38 deletions packages/timelock/layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,21 @@ import { PublicKey } from "@solana/web3.js";
import { BN } from "@project-serum/anchor";

const LE = "le"; //little endian
const instructionsFields = [

const StreamInstructionLayout = BufferLayout.struct<StreamInstruction>([
BufferLayout.blob(8, "start_time"),
BufferLayout.blob(8, "end_time"),
BufferLayout.blob(8, "deposited_amount"),
BufferLayout.blob(8, "total_amount"),
BufferLayout.blob(8, "period"),
BufferLayout.blob(8, "cliff"),
BufferLayout.blob(8, "cliff_amount"),
];

const StreamInstructionLayout =
BufferLayout.struct<StreamInstruction>(instructionsFields);
BufferLayout.blob(1, "is_cancelable_by_sender"),
BufferLayout.blob(1, "is_cancelable_by_recipient"),
BufferLayout.blob(1, "is_withdrawal_public"),
BufferLayout.blob(1, "is_transferable"),
BufferLayout.blob(4, "padding"),
]);

function decode_stream_instruction(buf: Buffer) {
let raw = StreamInstructionLayout.decode(buf);
Expand All @@ -29,69 +32,86 @@ function decode_stream_instruction(buf: Buffer) {
};
}

const TokenStreamDataLayout = BufferLayout.struct<Stream>([
interface StreamInstruction {
start_time: BN;
end_time: BN;
deposited_amount: BN;
total_amount: BN;
period: BN;
cliff: BN;
cliff_amount: BN;
}

const TokenStreamDataLayout = BufferLayout.struct<TokenStreamData>([
BufferLayout.blob(8, "magic"),
...instructionsFields,
BufferLayout.blob(8, "created_at"),
BufferLayout.blob(8, "withdrawn"),
BufferLayout.blob(8, "cancel_time"),
BufferLayout.blob(8, "withdrawn_amount"),
BufferLayout.blob(8, "canceled_at"),
BufferLayout.blob(8, "cancellable_at"),
BufferLayout.blob(8, "last_withdrawn_at"),
BufferLayout.blob(32, "sender"),
BufferLayout.blob(32, "sender_tokens"),
BufferLayout.blob(32, "recipient"),
BufferLayout.blob(32, "recipient_tokens"),
BufferLayout.blob(32, "mint"),
BufferLayout.blob(32, "escrow_tokens"),
BufferLayout.blob(8, "start_time"),
BufferLayout.blob(8, "end_time"),
BufferLayout.blob(8, "deposited_amount"),
BufferLayout.blob(8, "total_amount"),
BufferLayout.blob(8, "period"),
BufferLayout.blob(8, "cliff"),
BufferLayout.blob(8, "cliff_amount"),
BufferLayout.blob(1, "is_cancelable_by_sender"),
BufferLayout.blob(1, "is_cancelable_by_recipient"),
BufferLayout.blob(1, "is_withdrawal_public"),
BufferLayout.blob(1, "is_transferable"),
BufferLayout.blob(4, "padding"),
]);

export function decode(buf: Buffer) {
let raw = TokenStreamDataLayout.decode(buf);
return {
magic: new BN(raw.magic, LE),
start_time: new BN(raw.start_time, LE),
end_time: new BN(raw.end_time, LE),
deposited_amount: new BN(raw.deposited_amount, LE),
total_amount: new BN(raw.total_amount, LE),
period: new BN(raw.period, LE),
cliff: new BN(raw.cliff, LE),
cliff_amount: new BN(raw.cliff_amount, LE),
created_at: new BN(raw.created_at, LE),
withdrawn: new BN(raw.withdrawn, LE),
cancel_time: new BN(raw.cancel_time, LE),
withdrawn_amount: new BN(raw.withdrawn_amount, LE),
canceled_at: new BN(raw.canceled_at, LE),
cancellable_at: new BN(raw.cancellable_at, LE),
last_withdrawn_at: new BN(raw.last_withdrawn_at, LE),
sender: new PublicKey(raw.sender),
sender_tokens: new PublicKey(raw.sender_tokens),
recipient: new PublicKey(raw.recipient),
recipient_tokens: new PublicKey(raw.recipient_tokens),
mint: new PublicKey(raw.mint),
escrow_tokens: new PublicKey(raw.escrow_tokens),
start_time: new BN(raw.start_time, LE),
end_time: new BN(raw.end_time, LE),
deposited_amount: new BN(raw.deposited_amount, LE),
total_amount: new BN(raw.total_amount, LE),
period: new BN(raw.period, LE),
cliff: new BN(raw.cliff, LE),
cliff_amount: new BN(raw.cliff_amount, LE),
};
}

export interface StreamInstruction {
start_time: BN;
end_time: BN;
deposited_amount: BN;
total_amount: BN;
period: BN;
cliff: BN;
cliff_amount: BN;
}

export interface Stream {
export interface TokenStreamData {
magic: BN;
start_time: BN;
end_time: BN;
deposited_amount: BN;
total_amount: BN;
period: BN;
cliff: BN;
cliff_amount: BN;
created_at: BN;
withdrawn: BN;
cancel_time: BN;
withdrawn_amount: BN;
canceled_at: BN;
cancellable_at: BN;
last_withdrawn_at: BN;
sender: PublicKey;
sender_tokens: PublicKey;
recipient: PublicKey;
recipient_tokens: PublicKey;
mint: PublicKey;
escrow_tokens: PublicKey;
start_time: BN;
end_time: BN;
deposited_amount: BN;
total_amount: BN;
period: BN;
cliff: BN;
cliff_amount: BN;
}
2 changes: 1 addition & 1 deletion packages/timelock/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@streamflow/timelock",
"version": "0.3.1",
"version": "0.3.2",
"description": "SDK to interact with StreamFlow Finance's Timelock program on Solana.",
"main": "dist/timelock.js",
"types": "dist/timelock.d.ts",
Expand Down
Loading

0 comments on commit b90c6ec

Please sign in to comment.