@tangram-mover/sdk
v0.1.1
Published
TypeScript SDK for Tangram Mover - Transaction trace analyzer for Sui Move protocols
Downloads
18
Maintainers
Readme
Tangram Mover TypeScript SDK
TypeScript SDK for Tangram Mover - A comprehensive transaction trace analyzer for Sui Move protocols. Detect smart contract invariant violations, trace transactions, and execute transactions on the Sui network.
- Package:
@tangram-mover/sdk - Version: 0.1.0
- License: MIT
- Repository: tangram-mover
Features
✅ Transaction Tracing - Fetch and parse complete transaction traces including PTB commands, balance changes, object changes, and events
✅ Invariant Detection - Detect common security violations:
- Token inflation/deflation bugs
- Access control violations
- Ownership transfer anomalies
- Balance consistency issues
✅ Transaction Execution - Execute transactions using sui-kit:
- Transfer SUI and custom coins
- Call Move functions
- Transfer objects
- HD wallet multi-account support
✅ Batch Processing - Process multiple transactions efficiently with rate limiting
Installation
npm install @tangram-mover/sdkNote: This package includes @scallop-io/sui-kit as a dependency for Sui network interactions.
Quick Start
Initialize the SDK
import { TangramMover } from '@tangram-mover/sdk';
// Initialize with secret key
const mover = new TangramMover({
secretKey: 'your-secret-key',
networkType: 'testnet', // 'mainnet' | 'testnet' | 'devnet'
});
// Or initialize with mnemonics
const mover = new TangramMover({
mnemonics: 'word1 word2 ... word12',
networkType: 'testnet',
});
// Or create a new HD wallet
const mover = new TangramMover({
networkType: 'testnet',
});Trace a Transaction
// Fetch and parse transaction trace
const trace = await mover.traceTransaction('transaction-digest-here');
console.log('Transaction:', trace.digest);
console.log('Sender:', trace.sender);
console.log('Status:', trace.status);
console.log('Balance Changes:', trace.balance_changes);
console.log('PTB Commands:', trace.ptb_commands);Analyze for Invariant Violations
// Analyze a single transaction
const analysis = await mover.analyzeTransaction('transaction-digest-here');
console.log('Status:', analysis.status); // 'safe' | 'violations_detected'
console.log('Violations:', analysis.summary.violations);
console.log('Critical Violations:', analysis.summary.critical_violations);
// Check individual invariant results
analysis.invariants.forEach(inv => {
if (inv.violated) {
console.log(`⚠️ ${inv.name}: ${inv.message}`);
}
});Trace and Analyze in One Call
// Get both trace data and analysis
const result = await mover.traceAndAnalyze('transaction-digest-here');
console.log('Trace:', result.trace);
console.log('Analysis:', result.analysis);Execute Transactions
// Transfer SUI
const result = await mover.transferSui('0xrecipient-address', 1000000000); // 1 SUI
console.log('Transaction Digest:', result.digest);
// Transfer custom coin
const coinResult = await mover.transferCoin(
'0xrecipient-address',
1000000,
'0xpackage::module::CoinType'
);
// Call Move function
const moveResult = await mover.moveCall(
'0xpackage::module::function',
[arg1, arg2],
['TypeArg1']
);
// Transfer multiple objects
const objectResult = await mover.transferObjects(
['0xobject1', '0xobject2'],
'0xrecipient-address'
);
// Get balance
const balance = await mover.getBalance('0x2::sui::SUI');
console.log('SUI Balance:', balance.totalBalance);Batch Operations
// Trace multiple transactions
const traces = await mover.traceTransactions([
'digest1',
'digest2',
'digest3',
]);
// Analyze multiple transactions
const analyses = await mover.analyzeTransactions([
'digest1',
'digest2',
'digest3',
]);HD Wallet Multi-Accounts
// Get address for different account indices
const addr0 = mover.getAddress({ accountIndex: 0 });
const addr1 = mover.getAddress({ accountIndex: 1 });
// Execute transaction from specific account
await mover.transferSui('0xrecipient', 1000000, { accountIndex: 1 });
// Get balance for specific account
const balance = await mover.getBalance('0x2::sui::SUI', { accountIndex: 1 });API Reference
TangramMover
Main SDK class that provides all functionality.
Constructor Options
interface TangramMoverOptions {
secretKey?: string; // Base64, hex, or legacy format key
mnemonics?: string; // 12 or 24 word mnemonic phrase
networkType?: NetworkType; // 'mainnet' | 'testnet' | 'devnet' | 'localnet'
fullnodeUrls?: string[]; // Custom fullnode URLs
faucetUrl?: string; // Custom faucet URL
accountIndex?: number; // HD wallet account index (default: 0)
rateLimitMs?: number; // Rate limit between RPC calls (default: 1000)
}Methods
Transaction Tracing
traceTransaction(digest: string): Promise<TraceData>traceTransactions(digests: string[]): Promise<TraceData[]>
Invariant Analysis
analyzeTransaction(digest: string): Promise<AnalysisResult>analyzeTransactions(digests: string[]): Promise<AnalysisResult[]>traceAndAnalyze(digest: string): Promise<TraceAndAnalysisResult>
Transaction Execution
transferSui(recipient: string, amount: number, options?: { accountIndex?: number }): Promise<TransactionResult>transferSuiToMany(recipients: string[], amounts: number[], options?: { accountIndex?: number }): Promise<TransactionResult>transferCoin(recipient: string, amount: number, coinType: string, options?: { accountIndex?: number }): Promise<TransactionResult>transferCoinToMany(recipients: string[], amounts: number[], coinType: string, options?: { accountIndex?: number }): Promise<TransactionResult>moveCall(target: string, arguments: any[], typeArguments?: string[], options?: { accountIndex?: number }): Promise<TransactionResult>transferObjects(objectIds: string[], recipient: string, options?: { accountIndex?: number }): Promise<TransactionResult>
Utilities
getCurrentAddress(): stringgetAddress(options?: { accountIndex?: number }): stringgetBalance(coinType?: string, options?: { accountIndex?: number }): Promise<{ totalBalance: string }>
Utilities
getCurrentAddress(): stringgetAddress(options?: { accountIndex?: number }): stringgetBalance(coinType?: string, options?: { accountIndex?: number }): Promise<{ totalBalance: number }>
TraceData
Complete transaction trace information.
interface TraceData {
digest: string;
sender: string;
status: string;
gas_computation: number;
gas_storage: number;
gas_storage_rebate: number;
events: SuiEvent[];
balance_changes: BalanceChange[];
object_changes: ObjectChange[];
ptb_commands: PTBCommand[];
num_commands: number;
num_events: number;
num_balance_changes: number;
num_object_changes: number;
objects_created: number;
objects_mutated: number;
objects_deleted: number;
has_move_calls: boolean;
net_balance_change: number | string;
}AnalysisResult
Result of invariant analysis.
interface AnalysisResult {
digest: string;
timestamp: string;
status: 'safe' | 'violations_detected' | 'error';
invariants: InvariantResult[];
summary: {
total_checks: number;
violations: number;
critical_violations: number;
};
}Invariant Checks
The SDK includes several built-in invariant checks:
- Inflation Detection - Detects when tokens are created out of thin air (positive net balance change)
- Access Control - Basic validation of authorized operations (extendable for protocol-specific checks)
- Ownership Consistency - Validates object ownership transfers
- Balance Consistency - Ensures balance changes match object changes
Adding Custom Invariants
You can extend the analyzer with custom invariant checks:
import { Analyzer } from '@tangram-mover/sdk';
import type { TraceData } from '@tangram-mover/sdk';
const analyzer = new Analyzer();
// Add custom check
function checkCustomInvariant(traceData: TraceData): InvariantResult {
// Your custom logic here
return {
name: 'custom_check',
violated: false,
message: 'Custom check passed',
};
}
// Use in your analysis
const trace = await mover.traceTransaction('digest');
const customResult = checkCustomInvariant(trace);Examples
Monitor Protocol Transactions
import { TangramMover } from '@tangram-mover/sdk';
const mover = new TangramMover({ networkType: 'mainnet' });
async function monitorTransaction(digest: string) {
const result = await mover.traceAndAnalyze(digest);
if (result.analysis.status === 'violations_detected') {
console.error('🚨 INVARIANT VIOLATION DETECTED!');
console.error('Transaction:', digest);
result.analysis.invariants.forEach(inv => {
if (inv.violated) {
console.error(` - ${inv.name}: ${inv.message}`);
if (inv.severity === 'critical') {
// Send alert, pause protocol, etc.
}
}
});
} else {
console.log('✅ Transaction is safe');
}
}Batch Analysis
async function analyzeBatch(digests: string[]) {
const analyses = await mover.analyzeTransactions(digests);
const violations = analyses.filter(a => a.status === 'violations_detected');
const critical = violations.filter(a =>
a.summary.critical_violations > 0
);
console.log(`Analyzed ${digests.length} transactions`);
console.log(`Found ${violations.length} with violations`);
console.log(`Found ${critical.length} with critical violations`);
}Development
Build
npm run buildTest
npm testLint
npm run lintRelated Projects
- Tangram Mover Rust Crawler - High-performance Rust implementation for batch processing and CSV logging
- Tangram Mover Python Analyzer - Python-based invariant detection engine
- sui-kit - Sui network interaction toolkit (included as dependency)
License
MIT
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
