@noves/noves-sdk
Version:
Noves Developer Kit
398 lines (347 loc) • 13 kB
Markdown
The TVM Translate API provides functionality to interact with Tron Virtual Machine (TVM) based blockchains.
## Table of Contents
- [Getting Started](#getting-started)
- [API Reference](#api-reference)
- [Examples](#examples)
- [Error Handling](#error-handling)
## Getting Started
```typescript
import { Translate } from "@noves/noves-sdk";
// Initialize the TVM translator
const tvmTranslate = Translate.tvm("YOUR_API_KEY");
```
Returns a list of supported TVM chains.
```typescript
const chains = await tvmTranslate.getChains();
// Returns: [{ name: "tron", ecosystem: "tvm", nativeCoin: { ... } }]
```
Response format:
```typescript
interface TVMTranslateChain {
name: string; // Chain identifier (e.g., "tron")
ecosystem: string; // Always "tvm"
nativeCoin: {
name: string; // Native coin name (e.g., "TRX")
symbol: string; // Native coin symbol
address: string; // Native coin address
decimals: number; // Number of decimals for the native coin
};
tier: number; // Chain tier level
}
```
Get detailed information about a specific transaction. The format parameter determines the response structure.
```typescript
// Get transaction in v5 format (default)
const txInfoV5 = await tvmTranslate.getTransaction(
"tron",
"3c74d7fedca0cc50f80d472233d990449d10190de1e80c9098168d721f6aa2b8"
);
// Get transaction in v2 format (legacy)
const txInfoV2 = await tvmTranslate.getTransaction(
"tron",
"3c74d7fedca0cc50f80d472233d990449d10190de1e80c9098168d721f6aa2b8",
"v2"
);
```
```typescript
interface TVMTranslateTransactionV5 {
txTypeVersion: number; // Always 5 for v5 format
chain: string; // Chain name (e.g., "tron")
accountAddress: string; // Account address
timestamp: number; // Transaction timestamp (top-level)
classificationData: {
type: string; // Transaction type (e.g., "sendToken")
source: {
type: string; // Source type (e.g., "human")
};
description: string; // Human-readable description
protocol: {
name: string | null; // Protocol name or null
};
};
transfers: Array<{ // Array of transfers
action: string; // Action type (e.g., "sent", "received", "paidGas")
from: {
name: string | null; // From address name or null
address: string | null; // From address or null
};
to: {
name: string | null; // To address name or null
address: string | null; // To address or null
};
amount: string; // Transfer amount
token: {
symbol: string; // Token symbol
name: string; // Token name
decimals: number; // Token decimals
address: string; // Token address
};
}>;
values: any[]; // Array of values (structure may vary)
rawTransactionData: {
transactionHash: string;
fromAddress: string;
toAddress: string;
blockNumber: number;
gas: number;
gasUsed: number;
gasPrice: number;
transactionFee: {
amount: string;
token: {
symbol: string;
name: string;
decimals: number;
address: string;
};
};
timestamp: number; // Also included in rawTransactionData
};
}
```
```typescript
interface TVMTranslateTransactionV2 {
txTypeVersion: number; // Always 2 for v2 format
chain: string; // Chain name (e.g., "tron")
accountAddress: string; // Account address
classificationData: {
type: string; // Transaction type
source: {
type: string; // Source type
};
description: string; // Human-readable description
protocol: {
name: string | null; // Protocol name or null
};
sent: Array<{ // Sent transfers
action: string;
from: { name: string | null; address: string | null; };
to: { name: string | null; address: string | null; };
amount: string;
token: { symbol: string; name: string; decimals: number; address: string; };
}>;
received: Array<{ // Received transfers
action: string;
from: { name: string | null; address: string | null; };
to: { name: string | null; address: string | null; };
amount: string;
token: { symbol: string; name: string; decimals: number; address: string; };
}>;
};
rawTransactionData: {
transactionHash: string;
fromAddress: string;
toAddress: string;
blockNumber: number;
gas: number;
gasUsed: number;
gasPrice: number;
transactionFee: {
amount: string;
token: { symbol: string; name: string; decimals: number; address: string; };
};
timestamp: number; // Timestamp is only in rawTransactionData for v2
};
}
```
**Key Differences Between Formats:**
- **V5 Format**: Has `timestamp` at top level, uses `transfers` array, includes `values` array
- **V2 Format**: Has `timestamp` only in `rawTransactionData`, uses separate `sent`/`received` arrays
Get a pagination object to iterate over transactions pages.
```typescript
const transactionsPage = await tvmTranslate.getTransactions('tron', address, {
pageSize: 10,
sort: 'desc',
pageNumber: 1,
liveData: false,
viewAsTransactionSender: false
});
// Get current page of transactions
const transactions = transactionsPage.getTransactions();
console.log("Transactions:", transactions);
console.log("Has next page:", !!transactionsPage.getNextPageKeys());
// Navigate through pages
if (transactionsPage.getNextPageKeys()) {
await transactionsPage.next();
console.log("Next page:", transactionsPage.getTransactions());
}
// Go back to previous page
if (transactionsPage.hasPrevious()) {
await transactionsPage.previous();
console.log("Previous page:", transactionsPage.getTransactions());
}
// Iterate through all transactions using async iterator
for await (const tx of transactionsPage) {
console.log("Transaction:", tx);
}
```
The `pageOptions` parameter supports the following options:
- `pageSize`: Number of transactions per page (default: 10)
- `sort`: Sort order ('asc' or 'desc', default: 'desc')
- `pageNumber`: Page number to fetch (default: 1)
- `liveData`: Whether to include live data (default: false)
- `viewAsTransactionSender`: Whether to view transactions as sender (default: false)
- `maxNavigationHistory`: Maximum number of pages to keep in navigation history for backward navigation (default: 10)
The method returns a `TransactionsPage` object with the following methods:
#### Simple Pagination Methods
- `getTransactions()`: Get current page of transactions
- `getNextPageKeys()`: Get next page keys if available
- `next()`: Fetch next page of transactions
- `previous()`: Go back to previous page of transactions
- `hasPrevious()`: Check if there's a previous page available
- `[Symbol.asyncIterator]()`: Async iterator for all transactions
#### Cursor-Based Pagination Methods
- `getCursorInfo()`: Get cursor information for external pagination systems
- `getNextCursor()`: Get next page cursor as Base64 encoded string
- `getPreviousCursor()`: Get previous page cursor as Base64 encoded string
- `TransactionsPage.fromCursor()`: Static method to create a page from cursor string
- `TransactionsPage.decodeCursor()`: Static method to decode cursor to page options
### startBalancesJob(chain: string, tokenAddress: string, accountAddress: string, blockNumber: number)
Starts a job to fetch the token balance for a given account and token address as of a specific block.
```typescript
const jobResponse = await tvmTranslate.startBalancesJob(
'tron',
'TXL6rJbvmjD46zeN1JssfgxvSo99qC8MRT', // Token address
'TH2uNFtnwr5NsiAW2Py6Fmv8zDhfYXyDd9', // Account address
73196764 // Block number
);
console.log('Job ID:', jobResponse.jobId);
console.log('Result URL:', jobResponse.resultUrl);
```
Response format:
```typescript
interface TVMTranslateStartBalanceJobResponse {
jobId: string; // Unique identifier for the balance job
resultUrl: string; // URL to poll for job results
}
```
Gets the result of a balance job by job ID. This method may return a 425 status if the job is still processing.
```typescript
try {
const balanceResult = await tvmTranslate.getBalancesJobResults(
'tron',
'0xc8259410336d786984a8194db6f9a732381a4c68'
);
console.log('Balance:', balanceResult.amount);
console.log('Token:', balanceResult.token);
} catch (error) {
if (error.status === 425) {
console.log('Job still processing, try again later');
}
}
```
Response format:
```typescript
interface TVMTranslateBalanceJobResult {
chain: string; // Chain name (e.g., "tron")
accountAddress: string; // Account address that was queried
token: {
symbol: string; // Token symbol (e.g., "SUNDOG")
name: string; // Token name (e.g., "Sundog")
decimals: number; // Token decimals (e.g., 18)
address: string; // Token contract address
};
amount: string; // Token balance as a string (e.g., "19.52212")
blockNumber: number; // Block number at which balance was calculated
}
```
**Important Notes:**
- Processing time depends on how far the requested block is from chain genesis
- Processing time also depends on the transaction volume of the requested account
- If you receive a 425 status code, retry the request after some time
- Continue polling until you get the final balance result
**⚠️ Deprecated:** Use `getTransactions()` instead. This method will be removed in a future version.
Get paginated transactions for an account. This method is maintained for backward compatibility.
```typescript
// Get all supported chains
const chains = await tvmTranslate.getChains();
console.log(chains);
// Output: [{ name: "tron", ecosystem: "tvm", nativeCoin: { ... } }]
```
```typescript
// Get transaction details
const txInfo = await tvmTranslate.getTransaction(
"tron",
"c709a6400fc11a24460ac3a2871ad5877bc47383b51fc702c00d4f447091c462"
);
console.log(txInfo);
// Output: { hash: "...", accountAddress: "...", rawTransactionData: { ... }, classificationData: { ... } }
```
```typescript
// Get paginated transactions
const transactionsPage = await tvmTranslate.getTransactions('tron', 'TMA6mAoXs24NZRy3sWmc3i5FPA6KE1JQRR', {
pageSize: 10,
sort: 'desc'
});
// Process current page
console.log("Current transactions:", transactionsPage.getTransactions());
// Navigate through pages
if (transactionsPage.getNextPageKeys()) {
await transactionsPage.next();
console.log("Next page:", transactionsPage.getTransactions());
}
// Go back to previous page
if (transactionsPage.hasPrevious()) {
await transactionsPage.previous();
console.log("Previous page:", transactionsPage.getTransactions());
}
```
```typescript
// Start a balance job
const jobResponse = await tvmTranslate.startBalancesJob(
'tron',
'TXL6rJbvmjD46zeN1JssfgxvSo99qC8MRT', // SUNDOG token
'TH2uNFtnwr5NsiAW2Py6Fmv8zDhfYXyDd9', // Account address
73196764 // Block number
);
console.log('Job started:', jobResponse.jobId);
// Poll for results (with retry logic for 425 status)
async function pollForBalance(chain: string, jobId: string, maxRetries = 10, delayMs = 2000) {
for (let i = 0; i < maxRetries; i++) {
try {
const result = await tvmTranslate.getBalancesJobResults(chain, jobId);
console.log('Balance result:', result);
return result;
} catch (error) {
if (error.status === 425 && i < maxRetries - 1) {
console.log(`Job still processing, retrying in ${delayMs}ms...`);
await new Promise(resolve => setTimeout(resolve, delayMs));
} else {
throw error;
}
}
}
throw new Error('Max retries exceeded');
}
// Get the balance result
const balanceResult = await pollForBalance('tron', jobResponse.jobId);
console.log(`Balance: ${balanceResult.amount} ${balanceResult.token.symbol}`);
```
The TVM Translate API uses the following error types:
- `TransactionError`: Thrown for transaction-related errors
- `ValidationError`: Thrown for validation errors in request parameters
Example error handling:
```typescript
try {
const txInfo = await tvmTranslate.getTransaction("tron", "invalid-hash");
} catch (error) {
if (error instanceof TransactionError) {
console.error("Transaction error:", error.message);
}
}
```