JavaScript SDK
The official TAG IT JavaScript SDK for Node.js and browser environments.
Installation
Install the TAG IT SDK using your preferred package manager:
npm
npm install @tagit/sdk
yarn
yarn add @tagit/sdk
CDN (Browser)
For browser environments, you can include the SDK directly via CDN:
<!-- Production (minified) -->
<script src="https://cdn.tagit.network/sdk/v2/tagit.min.js"></script>
<!-- Development (with source maps) -->
<script src="https://cdn.tagit.network/sdk/v2/tagit.js"></script>
The SDK requires Node.js 16+ for server-side usage. For browsers, it supports all modern browsers (Chrome, Firefox, Safari, Edge).
Initialization
Initialize the SDK with your API credentials and configuration options:
import { TagIt } from '@tagit/sdk';
// Basic initialization
const tagit = new TagIt({
apiKey: process.env.TAGIT_API_KEY,
network: 'mainnet'
});
// Advanced configuration
const tagit = new TagIt({
apiKey: process.env.TAGIT_API_KEY,
apiSecret: process.env.TAGIT_API_SECRET,
network: 'mainnet', // 'mainnet' | 'testnet' | 'devnet'
timeout: 30000, // Request timeout in milliseconds
retries: 3, // Number of retry attempts
baseUrl: 'https://api.tagit.network/v2', // Custom API endpoint
debug: false, // Enable debug logging
onError: (error) => {
// Global error handler
console.error('TagIt Error:', error);
}
});
Browser Initialization
// When using CDN in browser
const tagit = new TagIt({
apiKey: 'your_public_api_key',
network: 'mainnet'
});
// Note: Never expose your API secret in browser code
// Use server-side proxying for sensitive operations
Products Module
The products module provides methods for registering, verifying, and managing product authenticity on the blockchain.
tagit.products.register()
Register a new product on the TAG IT Network blockchain:
// Register a new product
const product = await tagit.products.register({
tagId: 'NFC-TAG-001-XYZ',
metadata: {
productName: 'Luxury Handbag Model A',
brand: 'Premium Fashion',
serialNumber: 'SN-2024-789456',
manufactureDate: '2024-03-15',
origin: 'Italy',
materials: ['Genuine Leather', 'Gold Hardware'],
warranty: {
duration: '2 years',
coverage: 'Manufacturing defects'
}
},
initialOwner: '0x742d35Cc6634C0532925a3b844Bc9e7595f5c9E8',
privateMetadata: {
internalSku: 'INT-SKU-12345',
costPrice: '450.00'
}
});
console.log('Product registered:', product);
// Returns:
// {
// success: true,
// productId: 'prod_abc123xyz',
// tagId: 'NFC-TAG-001-XYZ',
// txHash: '0xabc123...',
// blockNumber: 12345678,
// tokenId: '98765'
// }
tagit.products.verify()
Verify the authenticity of a product using its NFC tag ID:
// Verify product authenticity
const verification = await tagit.products.verify('NFC-TAG-001-XYZ');
console.log('Verification result:', verification);
// Returns:
// {
// verified: true,
// authentic: true,
// tagId: 'NFC-TAG-001-XYZ',
// productId: 'prod_abc123xyz',
// metadata: {
// productName: 'Luxury Handbag Model A',
// brand: 'Premium Fashion',
// ...
// },
// currentOwner: '0x742d35Cc6634C0532925a3b844Bc9e7595f5c9E8',
// verificationTimestamp: '2024-03-20T14:30:00Z',
// blockchain: {
// network: 'polygon',
// contractAddress: '0x1234...',
// tokenId: '98765'
// }
// }
// Verify with additional options
const detailedVerification = await tagit.products.verify('NFC-TAG-001-XYZ', {
includeHistory: true, // Include transfer history
includeProvenanceProof: true, // Include cryptographic proof
checkRecalls: true // Check for product recalls
});
tagit.products.get()
Retrieve detailed information about a registered product:
// Get product by tag ID
const product = await tagit.products.get('NFC-TAG-001-XYZ');
// Get product by product ID
const product = await tagit.products.get({ productId: 'prod_abc123xyz' });
// Get product with specific fields
const product = await tagit.products.get('NFC-TAG-001-XYZ', {
fields: ['metadata', 'currentOwner', 'transferHistory'],
includePrivateMetadata: true // Requires authentication
});
console.log('Product details:', product);
// Returns:
// {
// productId: 'prod_abc123xyz',
// tagId: 'NFC-TAG-001-XYZ',
// status: 'active',
// metadata: { ... },
// currentOwner: '0x742d35...',
// transferHistory: [ ... ],
// createdAt: '2024-03-15T10:00:00Z',
// updatedAt: '2024-03-20T14:30:00Z'
// }
tagit.products.list()
List products with filtering and pagination:
// List all products for your account
const products = await tagit.products.list();
// List with pagination
const products = await tagit.products.list({
page: 1,
limit: 50,
sortBy: 'createdAt',
sortOrder: 'desc'
});
// List with filters
const products = await tagit.products.list({
brand: 'Premium Fashion',
status: 'active',
owner: '0x742d35Cc6634C0532925a3b844Bc9e7595f5c9E8',
createdAfter: '2024-01-01',
createdBefore: '2024-12-31'
});
console.log('Products:', products);
// Returns:
// {
// data: [ ... ],
// pagination: {
// page: 1,
// limit: 50,
// total: 234,
// totalPages: 5,
// hasMore: true
// }
// }
// Iterate through all products
for await (const product of tagit.products.listAll({ brand: 'Premium Fashion' })) {
console.log(product.tagId);
}
Transfers Module
The transfers module handles ownership transfers between parties.
tagit.transfers.initiate()
Initiate an ownership transfer for a product:
// Initiate a transfer
const transfer = await tagit.transfers.initiate({
tagId: 'NFC-TAG-001-XYZ',
toAddress: '0x8765432109abcdef...',
message: 'Sold via authorized retailer',
metadata: {
salePrice: '1299.00',
currency: 'USD',
retailer: 'Authorized Store #42',
invoiceNumber: 'INV-2024-001'
}
});
console.log('Transfer initiated:', transfer);
// Returns:
// {
// transferId: 'txf_abc123',
// status: 'pending_confirmation',
// tagId: 'NFC-TAG-001-XYZ',
// fromAddress: '0x742d35...',
// toAddress: '0x876543...',
// expiresAt: '2024-03-21T14:30:00Z',
// confirmationUrl: 'https://app.tagit.network/transfer/confirm/txf_abc123'
// }
// Initiate transfer with additional security
const secureTransfer = await tagit.transfers.initiate({
tagId: 'NFC-TAG-001-XYZ',
toAddress: '0x8765432109abcdef...',
requireSignature: true, // Require recipient signature
requireNfcScan: true, // Require NFC scan confirmation
expirationMinutes: 60, // Transfer expires in 60 minutes
notifyRecipient: true // Send notification to recipient
});
tagit.transfers.confirm()
Confirm a pending ownership transfer:
// Confirm transfer as recipient
const confirmation = await tagit.transfers.confirm({
transferId: 'txf_abc123',
signature: recipientSignature, // EIP-712 typed signature
nfcProof: nfcScanData // Optional NFC scan proof
});
console.log('Transfer confirmed:', confirmation);
// Returns:
// {
// success: true,
// transferId: 'txf_abc123',
// status: 'completed',
// txHash: '0xdef456...',
// blockNumber: 12345700,
// completedAt: '2024-03-20T15:00:00Z',
// newOwner: '0x876543...'
// }
// Cancel a pending transfer
const cancelled = await tagit.transfers.cancel('txf_abc123', {
reason: 'Buyer requested cancellation'
});
// Get transfer status
const status = await tagit.transfers.getStatus('txf_abc123');
// List transfer history for a product
const history = await tagit.transfers.history('NFC-TAG-001-XYZ', {
limit: 100,
includeDetails: true
});
Event Handling
Subscribe to real-time events and set up callbacks for various SDK operations.
// Subscribe to product events
tagit.events.on('product:verified', (event) => {
console.log('Product verified:', event.tagId);
console.log('Verification result:', event.data);
});
tagit.events.on('product:registered', (event) => {
console.log('New product registered:', event.productId);
});
tagit.events.on('transfer:initiated', (event) => {
console.log('Transfer started:', event.transferId);
});
tagit.events.on('transfer:completed', (event) => {
console.log('Transfer completed:', event.transferId);
console.log('New owner:', event.newOwner);
});
// Subscribe to specific product
const unsubscribe = tagit.events.subscribe('NFC-TAG-001-XYZ', {
onVerification: (data) => console.log('Scanned:', data),
onTransfer: (data) => console.log('Transferred:', data),
onStatusChange: (data) => console.log('Status changed:', data)
});
// Unsubscribe when done
unsubscribe();
// WebSocket connection for real-time updates
const ws = tagit.events.connectWebSocket({
onConnect: () => console.log('Connected'),
onDisconnect: () => console.log('Disconnected'),
onError: (error) => console.error('WebSocket error:', error),
autoReconnect: true,
reconnectInterval: 5000
});
// Batch event processing
tagit.events.onBatch(['product:verified', 'transfer:completed'], (events) => {
console.log('Batch received:', events.length, 'events');
events.forEach(processEvent);
});
TypeScript Support
The SDK includes comprehensive TypeScript definitions for type-safe development.
import {
TagIt,
TagItConfig,
Product,
ProductMetadata,
Verification,
Transfer,
TransferStatus,
TagItError,
NetworkType
} from '@tagit/sdk';
// Typed configuration
const config: TagItConfig = {
apiKey: process.env.TAGIT_API_KEY!,
network: 'mainnet' as NetworkType,
timeout: 30000,
retries: 3
};
const tagit = new TagIt(config);
// Typed product registration
interface CustomMetadata extends ProductMetadata {
customField: string;
warrantyYears: number;
}
const product: Product<CustomMetadata> = await tagit.products.register({
tagId: 'NFC-TAG-001-XYZ',
metadata: {
productName: 'Custom Product',
brand: 'My Brand',
serialNumber: 'SN-001',
customField: 'custom value',
warrantyYears: 2
}
});
// Typed verification result
const verification: Verification = await tagit.products.verify('NFC-TAG-001-XYZ');
if (verification.verified) {
const owner: string = verification.currentOwner;
const metadata: ProductMetadata = verification.metadata;
}
// Typed transfer
const transfer: Transfer = await tagit.transfers.initiate({
tagId: 'NFC-TAG-001-XYZ',
toAddress: '0x8765432109abcdef...'
});
const status: TransferStatus = transfer.status; // 'pending' | 'completed' | 'cancelled' | 'expired'
// Generic type support for custom responses
async function getCustomProduct<T extends ProductMetadata>(tagId: string): Promise<Product<T>> {
return tagit.products.get(tagId) as Promise<Product<T>>;
}
The SDK requires TypeScript 4.7+ for full type inference support. All types are exported from the main package entry point.
Error Handling
The SDK provides structured error handling with specific error types and retry strategies.
import {
TagIt,
TagItError,
AuthenticationError,
NotFoundError,
ValidationError,
RateLimitError,
NetworkError,
BlockchainError
} from '@tagit/sdk';
const tagit = new TagIt({ apiKey: 'your_api_key' });
try {
const product = await tagit.products.verify('NFC-TAG-001-XYZ');
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('Invalid API key or expired token');
// Refresh authentication
} else if (error instanceof NotFoundError) {
console.error('Product not found:', error.tagId);
// Handle missing product
} else if (error instanceof ValidationError) {
console.error('Invalid input:', error.validationErrors);
// Fix input parameters
error.validationErrors.forEach(err => {
console.log(`Field: ${err.field}, Message: ${err.message}`);
});
} else if (error instanceof RateLimitError) {
console.error('Rate limit exceeded');
console.log('Retry after:', error.retryAfter, 'seconds');
// Wait and retry
await sleep(error.retryAfter * 1000);
} else if (error instanceof NetworkError) {
console.error('Network error:', error.message);
// Retry with exponential backoff
} else if (error instanceof BlockchainError) {
console.error('Blockchain error:', error.message);
console.log('Transaction hash:', error.txHash);
// Handle blockchain-specific errors
} else if (error instanceof TagItError) {
console.error('TagIt error:', error.code, error.message);
} else {
throw error; // Re-throw unexpected errors
}
}
// Built-in retry with exponential backoff
const tagit = new TagIt({
apiKey: 'your_api_key',
retries: 3,
retryDelay: 1000, // Initial delay in ms
retryBackoff: 2, // Exponential backoff multiplier
retryOn: [500, 502, 503, 504], // HTTP status codes to retry
onRetry: (attempt, error) => {
console.log(`Retry attempt ${attempt}:`, error.message);
}
});
// Custom retry strategy
import { withRetry } from '@tagit/sdk';
const result = await withRetry(
() => tagit.products.verify('NFC-TAG-001-XYZ'),
{
maxAttempts: 5,
delay: 1000,
backoff: 'exponential',
shouldRetry: (error) => error instanceof NetworkError,
onRetry: (attempt, error, nextDelay) => {
console.log(`Attempt ${attempt} failed, retrying in ${nextDelay}ms`);
}
}
);
Always implement proper error handling in production. Use the specific error types to provide meaningful feedback to users and implement appropriate recovery strategies.
Join our Discord community for real-time support, or check out the API Reference for detailed endpoint documentation.