Nexa Wallet SDK for TypeScript
A comprehensive TypeScript SDK for building applications on the Nexa blockchain. This SDK provides wallet functionality, transaction building, token operations, and more.
Features
- Wallet Management: Create wallets from seed phrases or private keys
- Account Types: Support for multiple account types (NEXA, Vault, DApp)
- Transaction Building: Fluent API for building and signing transactions
- Token Operations: Create, mint, melt, and transfer tokens and NFTs
- Watch-Only Wallets: Monitor addresses without storing private keys
- Network Support: Mainnet and testnet compatibility
- Multiple Formats: CommonJS, ES modules, and browser bundles
Installation
npm install nexa-wallet-sdk
Quick Start
Basic Wallet Setup
import { Wallet, rostrumProvider } from 'nexa-wallet-sdk'
// Connect to the default mainnet node
await rostrumProvider.connect()
// Connect to a specific network (mainnet or testnet)
await rostrumProvider.connect('testnet') // Uses predefined testnet node
await rostrumProvider.connect('mainnet') // Uses predefined mainnet node
// Connect to a custom node (ignores network parameter)
await rostrumProvider.connect({
host: 'your-custom-node.example.com',
port: 30004,
scheme: 'wss' // or 'ws' for unencrypted connection
})
// Create wallet from seed phrase
const wallet = new Wallet(
'your twelve word seed phrase goes here for wallet creation',
'testnet' // or 'mainnet'
)
// Initialize wallet to discover accounts
await wallet.initialize()
// Get the default account
const account = wallet.accountStore.getAccount('1.0')
Simple Transaction
// Send 100 NEXA
const tx = await wallet.newTransaction(account)
.onNetwork('testnet')
.sendTo('nexatest:nqtsq5g5jsdmqqywaqd82lhnnk3a8wqunjz6gtxdtavnnekc', '10000')
.populate()
.sign()
.build()
console.log('Transaction:', tx)
Core Concepts
Accounts
The SDK supports different account types:
- NEXA Account: Standard accounts for regular transactions
- Vault Account: Secure storage accounts
- DApp Account: Application-specific accounts
// Get a new receiving address (This only returns a different address for default accounts)
const address = account.getNewAddress()
// Check account balance
const balance = account.balance
console.log('Confirmed:', balance.confirmed)
console.log('Unconfirmed:', balance.unconfirmed)
// Get transaction history
const transactions = await account.getTransactions()
Transaction Building
All transactions follow the same pattern: create → configure → populate → sign → build
const tx = await wallet.newTransaction(account)
.onNetwork('testnet') // 1. Set network
.sendTo(address, amount) // 2. Configure outputs
.addOpReturn(data) // 3. Add optional data
.populate() // 4. Find inputs and calculate fees
.sign() // 5. Sign the transaction
.build() // 6. Get final transaction hex
Transaction Examples
Basic Send Transaction
// Send 500 Nexa
const tx = await wallet.newTransaction(account)
.onNetwork('testnet')
.sendTo('nexatest:nqtsq5g5jsdmqqywaqd82lhnnk3a8wqunjz6gtxdtavnnekc', '50000')
.populate()
.sign()
.build()
Multiple Outputs
const tx = await wallet.newTransaction(account)
.onNetwork('testnet')
.sendTo('nexatest:address1', '10000')
.sendTo('nexatest:address2', '20000')
.sendTo('nexatest:address3', '30000')
.addOpReturn('Multi-output transaction')
.populate()
.sign()
.build()
Fee From Amount
// Deduct transaction fee from the send amount
const tx = await wallet.newTransaction(account)
.sendTo(recipient, '50000')
.feeFromAmount() // Fee will be subtracted from the 50000
.populate()
.sign()
.build()
Consolidate UTXOs
// Consolidate all UTXOs to a single address
const tx = await wallet.newTransaction(account)
.consolidate('nexatest:nqtsq5g5jsdmqqywaqd82lhnnk3a8wqunjz6gtxdtavnnekc')
.populate()
.sign()
.build()
Token Operations
Create a Fungible Token
const tx = await wallet.newTransaction(account)
.onNetwork('testnet')
.token(
'MyToken', // Token name
'MTK', // Ticker symbol
8, // Decimal places
'https://mytoken.com/info', // Documentation URL
'sha256hash' // Documentation hash
)
.populate()
.sign()
.build()
Create an NFT Collection
const tx = await wallet.newTransaction(account)
.onNetwork('testnet')
.collection(
'My NFT Collection',
'MNC',
'https://mycollection.com/metadata',
'collectionhash'
)
.populate()
.sign()
.build()
Mint an NFT
const parentCollectionId = 'nexatest:tq8r37lcjlqazz7vuvug84q2ev50573hesrnxkv9y6hvhhl5k5qqqnmyf79mx'
const tx = await wallet.newTransaction(account)
.onNetwork('testnet')
.nft(
parentCollectionId,
'https://mynft.com/content.zip',
'contenthash123'
)
.populate()
.sign()
.build()
Token Transfers
const tokenId = 'nexatest:tqtsq5g5jsdmqqywaqd82lhnnk3a8wqunjz6gtxdtavnnekc'
const tx = await wallet.newTransaction(account)
.onNetwork('testnet')
.sendTo('nexatest:recipient', '1000') // Send NEXA
.sendToToken('nexatest:recipient', '500', tokenId) // Send tokens
.populate()
.sign()
.build()
Mint Additional Tokens
const tx = await wallet.newTransaction(account)
.onNetwork('testnet')
.mint(tokenId, '1000000') // Mint 1,000,000 token units
.populate()
.sign()
.build()
Burn (Melt) Tokens
const tx = await wallet.newTransaction(account)
.onNetwork('testnet')
.melt(tokenId, '500000') // Burn 500,000 token units
.populate()
.sign()
.build()
Authority Management
Renew Token Authorities
const tx = await wallet.newTransaction(account)
.onNetwork('testnet')
.renewAuthority(
tokenId,
['mint', 'melt'], // Permissions to renew
'nexatest:nqtsq5g5...' // Optional: new authority address
)
.populate()
.sign()
.build()
Delete Token Authority
const tx = await wallet.newTransaction(account)
.onNetwork('testnet')
.deleteAuthority(tokenId, 'abc123:0') // outpoint of authority to delete
.populate()
.sign()
.build()
Watch-Only Wallets
Watch-only wallets allow you to monitor addresses and create unsigned transactions without storing private keys.
Create Watch-Only Wallet
import { WatchOnlyWallet } from 'nexa-wallet-sdk'
const watchOnlyWallet = new WatchOnlyWallet([
{ address: 'nexatest:nqtsq5g5dsgh6mwjchqypn8hvdrjue0xpmz293fl7rm926xv' }
], 'testnet')
Create Unsigned Transaction
const unsignedTx = await watchOnlyWallet.newTransaction()
.sendTo('nexatest:nqtsq5g5jsdmqqywaqd82lhnnk3a8wqunjz6gtxdtavnnekc', '100000')
.addOpReturn("Watch-only transaction")
.populate()
.build()
Sign Watch-Only Transaction
// Pass the unsigned transaction to a wallet with private keys
const signedTx = await wallet.newTransaction(account, unsignedTx)
.sign()
.build()
Subscribe to Address Updates
await watchOnlyWallet.subscribeToAddressNotifications((notification) => {
console.log('Address activity:', notification)
})
Advanced Features
Parse Existing Transactions
// From hex string
const tx = await wallet.newTransaction(account)
.parseTxHex('0100000001...')
.sign()
.build()
// From buffer
const txBuffer = Buffer.from('0100000001...', 'hex')
const tx = await wallet.newTransaction(account)
.parseTxBuffer(txBuffer)
.sign()
.build()
Export Wallet Data
const walletData = wallet.export()
// Contains encrypted seed and account information for backup
Broadcasting Transactions
// Broadcast a signed transaction
const txId = await wallet.sendTransaction(signedTxHex)
console.log('Transaction ID:', txId)
// Or use watch-only wallet
const txId = await watchOnlyWallet.sendTransaction(signedTxHex)
Available Exports
The SDK exports the following components:
import {
// Core classes
Wallet,
WatchOnlyWallet,
// Account types
BaseAccount,
DefaultAccount,
DappAccount,
VaultAccount,
AccountStore,
// Transaction creators
WalletTransactionCreator,
WatchOnlyTransactionCreator,
// Network provider
rostrumProvider,
// Utility functions
ValidationUtils,
isValidNexaAddress,
// Enums
AccountType,
TxTokenType,
// Types
AccountKeys,
Balance,
TransactionEntity,
TokenAction
} from 'nexa-wallet-sdk'
Error Handling
try {
const tx = await wallet.newTransaction(account)
.sendTo('invalid-address', '1000')
.populate()
.sign()
.build()
} catch (error) {
if (error.message.includes('Invalid address')) {
console.error('Invalid Nexa address provided')
} else if (error.message.includes('Insufficient funds')) {
console.error('Not enough balance for transaction')
} else {
console.error('Transaction failed:', error.message)
}
}
Network Configuration
// Testnet (for development)
const wallet = new Wallet(seedPhrase, 'testnet')
// Mainnet (for production)
const wallet = new Wallet(seedPhrase, 'mainnet')
// Always specify network in transactions
const tx = await wallet.newTransaction(account)
.onNetwork('testnet') // Must match wallet network
.sendTo(address, amount)
.populate()
.sign()
.build()
Best Practices
- Always Connect First: Call
await rostrumProvider.connect()before wallet operations - Network Consistency: Ensure wallet and transaction networks match
- Amount Precision: Use strings for amounts to avoid floating-point precision issues
- Error Handling: Wrap wallet operations in try-catch blocks
- Private Key Security: Never log or expose private keys or seed phrases
- Address Validation: Validate addresses before sending transactions
- Fee Estimation: Use
populate()to estimate fees before signing
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
For issues and questions: - GitHub Issues: wallet-sdk-ts issues - Documentation: Nexa Documentation
⚠️ Security Notice: Never share your seed phrases or private keys. Always verify addresses before sending transactions. This SDK is for development purposes - use appropriate security measures in production applications.