@zebec-network/proxy-stream-sdk
v1.3.0
Published
A TypeScript SDK for interacting with the Zebec Proxy Stream Program on Solana. This SDK enables cross-chain token streaming capabilities, allowing users to create, manage, and interact with token streams through a proxy layer.
Readme
Proxy Stream SDK
A TypeScript SDK for interacting with the Zebec Proxy Stream Program on Solana. This SDK enables cross-chain token streaming capabilities, allowing users to create, manage, and interact with token streams through a proxy layer.
Features
- Cross-Chain Token Streaming - Create and manage token streams with L1 wallet hash integration
- Token Management - Mint and burn Z-tokens (wrapped tokens for cross-chain compatibility)
- Stream Operations - Create, pause/resume, withdraw, and cancel token streams
- User PDA Management - Create and manage user PDAs for cross-chain wallet mapping
- Full TypeScript Support - Complete type definitions for all operations
Installation
Using npm
npm install @zebec-network/proxy-stream-sdkUsing yarn
yarn add @zebec-network/proxy-stream-sdkRequirements
- Node.js >= 16
- TypeScript >= 5.0 (for development)
- Solana Web3.js ^1.98.2
- Anchor ^0.31.1
Quick Setup
1. Import and Initialize the Service
import { Connection, Keypair } from "@solana/web3.js";
import {
createAnchorProvider,
ProxyStreamService,
AnchorWallet,
} from "@zebec-network/proxy-stream-sdk";
// Create a connection to the Solana network
const connection = new Connection("https://api.devnet.solana.com", "confirmed");
// Create a wallet (use your own wallet implementation)
const wallet: AnchorWallet = {
publicKey: keypair.publicKey,
signTransaction: async (tx) => {
tx.sign(keypair);
return tx;
},
signAllTransactions: async (txs) => {
txs.forEach((tx) => tx.sign(keypair));
return txs;
},
};
// Create the provider
const provider = createAnchorProvider(connection, wallet);
// Initialize the ProxyStreamService
const network = "devnet"; // or "mainnet-beta"
const service = ProxyStreamService.create(provider, network);Usage
Initialize Proxy Configuration
Initialize the proxy configuration for a specific chain. This is typically done once by the admin.
const txPayload = await service.initProxyConfig({
admin: wallet.publicKey,
feeVault: "FEE_VAULT_PUBLIC_KEY",
chainId: "DASH", // Unique identifier for the chain
fee: 0.5, // Fee percentage (0.5%)
minAmount: 1000, // Minimum amount for transactions
});
const signature = await txPayload.execute({ commitment: "confirmed" });
console.log("Transaction signature:", signature);Create a Token
Create a new Z-token (wrapped token) for cross-chain operations.
import { Keypair } from "@solana/web3.js";
const mintKeypair = Keypair.generate();
const txPayload = await service.createToken({
admin: wallet.publicKey,
chainId: "DASH",
tokenInfo: {
tokenName: "Z Dash",
symbol: "ZDASH",
metadataUri: "https://example.com/token-metadata.json",
decimals: 9,
mintKeypair, // Optional: will generate a new one if not provided
},
});
const signature = await txPayload.execute({ commitment: "confirmed" });
console.log("Token created:", mintKeypair.publicKey.toString());Create User PDA
Create a user PDA that maps an L1 wallet to a Solana account.
import { hashSHA256ToBuffer } from "@zebec-network/core-utils";
// Hash the L1 wallet address (32 bytes)
const l1WalletHash = await hashSHA256ToBuffer("L1_WALLET_ADDRESS");
const txPayload = await service.createUserPda({
admin: wallet.publicKey,
chainId: "DASH",
l1WalletHash,
});
const signature = await txPayload.execute({ commitment: "confirmed" });Mint Z-Tokens
Mint Z-tokens to a user's account.
const txPayload = await service.mintZToken({
admin: wallet.publicKey,
chainId: "DASH",
destination: "DESTINATION_TOKEN_ACCOUNT",
mint: "TOKEN_MINT_ADDRESS",
amount: 1000, // Amount to mint
signatureHash: signatureHashBuffer, // 32-byte unique hash to prevent duplicate mints
});
const signature = await txPayload.execute({ commitment: "confirmed" });Create a Stream
Create a new token stream between two users.
const senderL1WalletHash = await hashSHA256ToBuffer("SENDER_L1_WALLET");
const receiverL1WalletHash = await hashSHA256ToBuffer("RECEIVER_L1_WALLET");
const txPayload = await service.createStream({
proxyAdmin: wallet.publicKey,
chainId: "DASH",
senderL1WalletHash,
receiverL1WalletHash,
streamToken: "TOKEN_MINT_ADDRESS",
amount: 1000, // Total stream amount
duration: 3600, // Stream duration in seconds (1 hour)
startNow: true,
startTime: 0, // Ignored if startNow is true
streamName: "My Token Stream",
// Stream options
automaticWithdrawal: false,
autoWithdrawFrequency: 0, // Required if automaticWithdrawal is true
cancelableByRecipient: true,
cancelableBySender: true,
isPausable: true,
transferableByRecipient: false,
transferableBySender: false,
canTopup: false,
rateUpdatable: false,
cliffPercentage: 0, // Percentage unlocked immediately (in %)
});
const signature = await txPayload.execute({ commitment: "confirmed" });Withdraw from Stream
Withdraw available tokens from an active stream.
const txPayload = await service.withdrawStream({
proxyAdmin: wallet.publicKey,
chainId: "DASH",
receiverL1WalletHash,
streamMetadata: "STREAM_METADATA_PUBLIC_KEY",
});
const signature = await txPayload.execute({ commitment: "confirmed" });Pause/Resume Stream
Toggle the pause state of a stream.
const txPayload = await service.pauseResumeStream({
proxyAdmin: wallet.publicKey,
chainId: "DASH",
senderL1WalletHash,
streamMetadata: "STREAM_METADATA_PUBLIC_KEY",
});
const signature = await txPayload.execute({ commitment: "confirmed" });Cancel Stream
Cancel an active stream and return remaining funds.
const txPayload = await service.cancelStream({
proxyAdmin: wallet.publicKey,
chainId: "DASH",
senderL1WalletHash,
receiverL1WalletHash,
streamMetadata: "STREAM_METADATA_PUBLIC_KEY",
});
const signature = await txPayload.execute({ commitment: "confirmed" });Burn Z-Tokens
Burn Z-tokens to initiate a cross-chain transfer back to L1.
const txPayload = await service.burnZToken({
proxyAdmin: wallet.publicKey,
chainId: "DASH",
mint: "TOKEN_MINT_ADDRESS",
receiverL1WalletHash,
amount: 500, // Amount to burn
});
const signature = await txPayload.execute({ commitment: "confirmed" });Emergency Pause
Pause all operations (admin only).
const txPayload = await service.emergencyPause({
admin: wallet.publicKey,
});
const signature = await txPayload.execute({ commitment: "confirmed" });PDA Derivation Utilities
The SDK provides utility functions for deriving Program Derived Addresses:
import {
deriveProxyConfigPda,
deriveMintAuthorityPda,
deriveUserPda,
deriveUserVaultPda,
deriveCheckAccountPda,
} from "@zebec-network/proxy-stream-sdk";
// Derive proxy config PDA
const [proxyConfig] = deriveProxyConfigPda(chainId, programId);
// Derive mint authority PDA
const [mintAuthority] = deriveMintAuthorityPda(programId);
// Derive user PDA from chain ID and wallet hash
const [userPda] = deriveUserPda(chainId, walletHash, programId);
// Derive user vault PDA
const [userVault] = deriveUserVaultPda(userPda, programId);Networks
The SDK supports the following networks:
| Network | Program ID |
| ------------- | -------------------------------------------- |
| Devnet | 5SaauzPGka7m7pTis7BXGwTh1zFYpGnU3wSQrehZDgJH |
| Mainnet-Beta | Coming soon |
Development
Build
npm run buildRun Tests
# Run all tests
npm test
# Run a single test file
npm run test:single test/e2e/createStream.test.tsFormat Code
npm run formatEnvironment Variables
For running tests, create a .env file with:
DEVNET_RPC_URL=https://api.devnet.solana.com
RPC_URL=https://api.mainnet-beta.solana.com
DEVNET_SECRET_KEYS=["base58_encoded_private_key"]
MAINNET_SECRET_KEYS=["base58_encoded_private_key"]Dependencies
- @coral-xyz/anchor - Solana development framework
- @solana/web3.js - Solana JavaScript API
- @solana/spl-token - SPL Token utilities
- @metaplex-foundation/mpl-token-metadata - Token metadata program
- @zebec-network/zebec-stream-sdk - Core Zebec streaming SDK
- @zebec-network/core-utils - Zebec utility functions
License
MIT License - see LICENSE for details.
Author
Zebec Network | Ashish Sapkota
