nexa-wallet-sdk
v0.8.0
Published
Wallet SDK for the Nexa blockchain
Maintainers
Readme
Nexa Wallet SDK
Production-ready TypeScript SDK for building Nexa blockchain wallets and dApps.
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-sdkQuick 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 hexTransaction 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
const myCallback = (notification) => {
console.log('Address activity:', notification)
}
await watchOnlyWallet.subscribeToAddressNotifications(myCallback)
// Later, to prevent memory leaks:
await watchOnlyWallet.unsubscribeFromAddressNotifications(myCallback)Advanced Features
Address Notifications
// Define your callback function
const myCallback = (notification) => {
console.log('Address notification:', notification)
}
// Subscribe to a single address
await wallet.subscribeToAddressNotifications(
'nexa:nqtsq5g5jsdmqqywaqd82lhnnk3a8wqunjz6gtxdtavnnekc',
myCallback
)
// Subscribe to addresses as an array
const addresses = [
'nexa:nqtsq5g5jsdmqqywaqd82lhnnk3a8wqunjz6gtxdtavnnekc'
]
await wallet.subscribeToAddressNotifications(addresses, myCallback)
// Subscribe to all wallet addresses
const accounts = wallet.accountStore.listAccounts()
const allAddresses = accounts.flatMap(account =>
account.getAddresses().map(addr => addr.address)
)
await wallet.subscribeToAddressNotifications(allAddresses, myCallback)
// Always unsubscribe when done to prevent memory leaks
await wallet.unsubscribeFromAddressNotifications(allAddresses, myCallback)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 backupBroadcasting 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,
// Utility classes
AccountKeysUtils,
// Enums
AccountType,
TxTokenType,
// Types
AccountKeys,
AccountIndexes,
AddressKey,
Balance,
WatchOnlyAddress,
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 testnetWallet = new Wallet(seedPhrase, 'testnet')
// Mainnet (for production)
const mainnetWallet = 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 - Memory Management: Always unsubscribe from address notifications when done to prevent memory leaks
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.
