
Research
TeamPCP Compromises Telnyx Python SDK to Deliver Credential-Stealing Malware
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.
txflow-sdk
Advanced tools
TypeScript SDK for TxFlow perpetual DEX with EIP-712 signing and MCP (Model Context Protocol) server.
npm install txflow-sdk
TxFlow uses an agent wallet pattern: a user wallet authorizes a temporary agent wallet via EIP-712 signature, and all subsequent trading actions are signed by the agent wallet.
import { TxFlowClient } from "txflow-sdk";
import { ethers } from "ethers";
const userWallet = new ethers.Wallet("0xUSER_PRIVATE_KEY");
const agentWallet = new ethers.Wallet("0xAGENT_PRIVATE_KEY");
const client = new TxFlowClient({
privateKey: agentWallet.privateKey,
});
// Step 1: Authorize the agent wallet (one-time)
await client.approveAgent(userWallet);
// Step 2: Place orders using the agent wallet
const result = await client.placeOrder({
asset: 1, // Asset index (use getPerpMeta to look up)
isBuy: true,
price: "50000",
size: "0.01",
reduceOnly: false,
timeInForce: "gtc",
});
const client = new TxFlowClient({
privateKey: "0x...", // Agent wallet private key (required)
baseUrl: "https://testnet-api.txflow.net", // API base URL (optional)
isMainnet: true, // Source identifier for signing (optional, default: true)
vaultAddress: null, // Vault address if applicable (optional)
chainId: 1337, // L1 signing domain chain ID (optional)
});
When TxFlow launches mainnet, update the config:
import { TxFlowClient, MAINNET_API_URL } from "txflow-sdk";
const client = new TxFlowClient({
privateKey: "0x...",
baseUrl: MAINNET_API_URL, // or the actual mainnet URL
chainId: 1337, // update if mainnet uses a different chain ID
});
All signing logic, EIP-712 domains, and API calls adapt automatically based on the config.
placeOrder(params)await client.placeOrder({
asset: 1,
isBuy: true,
price: "50000",
size: "0.01",
reduceOnly: false,
timeInForce: "gtc", // "gtc" | "ioc" | "alo"
});
placeBatchOrders(params[])await client.placeBatchOrders([
{ asset: 1, isBuy: true, price: "50000", size: "0.01" },
{ asset: 1, isBuy: false, price: "60000", size: "0.01" },
]);
cancelOrder(params)await client.cancelOrder({ asset: 1, orderId: "123456" });
cancelOrders(params[])await client.cancelOrders([
{ asset: 1, orderId: "123456" },
{ asset: 1, orderId: "789012" },
]);
modifyOrder(params)await client.modifyOrder({
orderId: "123456",
asset: 1,
isBuy: true,
price: "51000",
size: "0.02",
});
updateLeverage(params)await client.updateLeverage({ asset: 1, leverage: 10 });
updateMarginMode(params)await client.updateMarginMode({ asset: 1, isCross: true });
These methods require the user wallet (not the agent wallet).
approveAgent(userWallet, params?)await client.approveAgent(userWallet, {
agentAddress: "0x...", // defaults to SDK agent address
agentName: "MyBot", // defaults to "TradeAgent"
});
withdraw(userWallet, params)await client.withdraw(userWallet, {
destination: "0x...",
amount: "100",
});
transferToken(userWallet, params)await client.transferToken(userWallet, {
amount: "100",
fromAccountType: "perp",
toAccountType: "spot",
});
sendToken(userWallet, params)await client.sendToken(userWallet, {
toAddress: "0x...",
amount: "50",
});
const meta = await client.getPerpMeta();
const state = await client.getUserState("0xUSER_ADDRESS");
const orders = await client.getOpenOrders("0xUSER_ADDRESS");
const book = await client.getL2Book(1);
const assetData = await client.getActiveAssetData("0xUSER_ADDRESS", "1");
const candles = await client.getCandleSnapshot({
coin: "BTC",
interval: "1h",
startTime: Date.now() - 86400000,
endTime: Date.now(),
});
const fees = await client.getUserFees("0xUSER_ADDRESS");
const funding = await client.getFundingHistory({
user: "0xUSER_ADDRESS",
startTime: Date.now() - 86400000,
});
await client.requestFund("0xUSER_ADDRESS");
Every trading method has a corresponding build* method that returns the signed request payload without sending it to the API. This is useful for custom submission logic, queuing, or inspecting the signed data.
import { TxFlowClient, SignedRequest } from "txflow-sdk";
const client = new TxFlowClient({ privateKey: "0x..." });
const signed: SignedRequest = await client.buildPlaceOrder({
asset: 1,
isBuy: true,
price: "50000",
size: "0.01",
});
// signed = { action, signature: { r, s, v }, nonce, vaultAddress? }
// You now have full control over when and how to submit it.
// Submit later when ready:
const result = await client.submitSignedRequest(signed);
Available build* methods:
| Method | Description |
|---|---|
buildPlaceOrder(params) | Sign a single order |
buildPlaceBatchOrders(params[]) | Sign a batch of orders |
buildCancelOrder(params) | Sign an order cancellation |
buildCancelOrders(params[]) | Sign multiple cancellations |
buildModifyOrder(params) | Sign an order modification |
buildUpdateLeverage(params) | Sign a leverage update |
buildUpdateMarginMode(params) | Sign a margin mode update |
All build* methods accept the same parameters as their corresponding action methods and return a SignedRequest object.
For custom integrations, the signing primitives are exported directly:
import {
actionHash,
signL1Action,
createSign,
signUserAction,
getL1ActionDomain,
L1_ACTION_TYPES,
USER_ACTION_DOMAIN,
APPROVE_AGENT_TYPES,
} from "txflow-sdk";
// Compute action hash (MessagePack + nonce + vault encoding + keccak256)
const hash = actionHash(action, vaultAddress, nonce);
// Sign an L1 action (order, cancel, modify, leverage, margin mode)
const sig = await signL1Action(wallet, action, vaultAddress, nonce, isMainnet, chainId);
// Sign a user action (approve, withdraw, transfer)
const sig = await signUserAction(wallet, domain, types, message);
p and s string fields recursively0x00 if null (9 extra bytes), or 0x01 + 20-byte address (29 extra bytes)The SDK includes an MCP server for AI agent integration (e.g., Claude Desktop, Cursor, OpenClaw).
Build the project first:
npm install && npm run build
Add to your MCP client config (e.g., claude_desktop_config.json):
{
"mcpServers": {
"txflow": {
"command": "node",
"args": ["/path/to/txflow-sdk/dist/mcp.js"],
"env": {
"TXFLOW_AGENT_PRIVATE_KEY": "0xAGENT_PRIVATE_KEY",
"TXFLOW_USER_PRIVATE_KEY": "0xUSER_PRIVATE_KEY",
"TXFLOW_BASE_URL": "https://testnet-api.txflow.net"
}
}
}
}
Or if installed globally via npm:
{
"mcpServers": {
"txflow": {
"command": "txflow-mcp",
"env": {
"TXFLOW_AGENT_PRIVATE_KEY": "0xAGENT_PRIVATE_KEY",
"TXFLOW_USER_PRIVATE_KEY": "0xUSER_PRIVATE_KEY"
}
}
}
}
| Variable | Required | Description |
|---|---|---|
TXFLOW_AGENT_PRIVATE_KEY | Yes | Agent wallet private key for signing trades |
TXFLOW_USER_PRIVATE_KEY | No | User wallet private key (only for approve_agent) |
TXFLOW_BASE_URL | No | API URL (default: https://testnet-api.txflow.net) |
| Tool | Description |
|---|---|
place_order | Place a perpetual futures order |
cancel_order | Cancel an open order |
cancel_orders | Cancel multiple orders |
modify_order | Modify an existing order |
update_leverage | Update leverage for an asset |
update_margin_mode | Switch cross/isolated margin |
approve_agent | Authorize agent wallet (requires user key) |
get_open_orders | List open orders for a user |
get_user_state | Get account state, positions, balances |
get_perp_meta | Get available assets and their indices |
get_l2_book | Get order book depth for a coin |
MIT
FAQs
TypeScript SDK for TxFlow perpetual DEX with EIP-712 signing and MCP server
The npm package txflow-sdk receives a total of 9 weekly downloads. As such, txflow-sdk popularity was classified as not popular.
We found that txflow-sdk demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.

Security News
TeamPCP is partnering with ransomware group Vect to turn open source supply chain attacks on tools like Trivy and LiteLLM into large-scale ransomware operations.

Security News
/Research
Widespread GitHub phishing campaign uses fake Visual Studio Code security alerts in Discussions to trick developers into visiting malicious website.