Official TypeScript/JavaScript SDK for Amadeus Protocol - Core utilities for serialization, cryptography, transaction building, and API client.
npm install @amadeus-protocol/sdk
# or
yarn add @amadeus-protocol/sdk
# or
pnpm add @amadeus-protocol/sdk
# or
bun add @amadeus-protocol/sdk- Canonical Serialization (VecPack): Deterministic encoding/decoding for cryptographic operations
- Cryptographic Operations: BLS12-381 key generation, signing, and verification
- Password-Based Encryption: Secure AES-GCM encryption with PBKDF2 key derivation for wallet data
- Transaction Building: Create and sign Amadeus protocol transactions
- Token Conversions: Convert between atomic units and human-readable amounts
- Encoding Utilities: Base58 and Base64 encoding/decoding for addresses, keys, and binary data
- API Client: Full-featured HTTP client for interacting with Amadeus nodes
- Type Safety: Complete TypeScript definitions for all APIs
- Zero Dependencies: Uses native fetch (no axios or other HTTP libraries)
import { AmadeusSDK } from '@amadeus-protocol/sdk'
// Initialize SDK (uses default node URL if not specified)
const sdk = new AmadeusSDK({
baseUrl: 'https://nodes.amadeus.bot/api'
})
// Query chain
const tip = await sdk.chain.getTip()
console.log('Current height:', tip.entry.height)
// Query wallet balance
const balance = await sdk.wallet.getBalance('5Kd3N...', 'AMA')
console.log('Balance:', balance.balance.float)
// Submit transaction
const result = await sdk.transaction.submit(txPacked)import { AmadeusSDK } from '@amadeus-protocol/sdk'
const sdk = new AmadeusSDK({
baseUrl: 'https://nodes.amadeus.bot/api',
timeout: 30000 // Optional: custom timeout
})
// Chain API
const stats = await sdk.chain.getStats()
const tip = await sdk.chain.getTip()
const entry = await sdk.chain.getByHash('5Kd3N...')
// Wallet API
const balance = await sdk.wallet.getBalance('5Kd3N...', 'AMA')
const allBalances = await sdk.wallet.getAllBalances('5Kd3N...')
// Transaction API
const result = await sdk.transaction.submit(txPacked)
const resultWithWait = await sdk.transaction.submitAndWait(txPacked)
const tx = await sdk.transaction.get('5Kd3N...')
// Contract API
const contractData = await sdk.contract.get(key)
const richlist = await sdk.contract.getRichlist()
// Epoch API
const scores = await sdk.epoch.getScore()
const emission = await sdk.epoch.getEmissionAddress('5Kd3N...')
// Peer API
const nodes = await sdk.peer.getNodes()
const trainers = await sdk.peer.getTrainers()import { generateKeypair, derivePublicKeyFromSeedBase58 } from '@amadeus-protocol/sdk'
// Generate a new keypair
const keypair = generateKeypair()
console.log(keypair.publicKey) // Base58 public key
console.log(keypair.privateKey) // Base58 private key (seed)
// Derive public key from existing seed
const publicKey = derivePublicKeyFromSeedBase58(keypair.privateKey)import { TransactionBuilder, fromBase58, toAtomicAma } from '@amadeus-protocol/sdk'
// Instance-based usage (convenient for multiple transactions)
const builder = new TransactionBuilder('5Kd3N...') // Base58 encoded seed
// Option 1: Build and sign in one step (convenience)
const { txHash, txPacked } = builder.transfer({
recipient: '5Kd3N...', // Base58 encoded recipient address
amount: 10.5, // Amount in human-readable format
symbol: 'AMA' // Token symbol
})
// Option 2: Build unsigned, then sign (more control)
const unsignedTx = builder.buildTransfer({
recipient: '5Kd3N...',
amount: 10.5,
symbol: 'AMA'
})
// Can inspect or modify unsignedTx before signing
const { txHash, txPacked } = builder.sign(unsignedTx)
// Option 3: Build custom transaction and sign
const unsignedTx = builder.build('Coin', 'transfer', [
fromBase58('5Kd3N...'), // Recipient bytes
toAtomicAma(10.5).toString(), // Amount in atomic units
'AMA'
])
const { txHash, txPacked } = builder.sign(unsignedTx)
// Option 4: Build and sign custom transaction (convenience)
const { txHash, txPacked } = builder.buildAndSign('Coin', 'transfer', [
fromBase58('5Kd3N...'),
toAtomicAma(10.5).toString(),
'AMA'
])import {
TransactionBuilder,
fromBase58,
toAtomicAma,
getPublicKey,
deriveSkAndSeed64FromBase58Seed
} from '@amadeus-protocol/sdk'
// Option 1: Build and sign transfer in one step (convenience)
const { txHash, txPacked } = TransactionBuilder.buildSignedTransfer({
senderPrivkey: '5Kd3N...', // Base58 encoded seed
recipient: '5Kd3N...', // Base58 encoded recipient address
amount: 10.5, // Amount in human-readable format
symbol: 'AMA' // Token symbol
})
// Option 2: Build unsigned transfer, then sign
const { seed64 } = deriveSkAndSeed64FromBase58Seed('5Kd3N...')
const signerPubKey = getPublicKey(seed64)
const unsignedTx = TransactionBuilder.buildTransfer(
{ recipient: '5Kd3N...', amount: 10.5, symbol: 'AMA' },
signerPubKey
)
const { txHash, txPacked } = TransactionBuilder.sign(unsignedTx, '5Kd3N...')
// Option 3: Build custom unsigned transaction, then sign
const unsignedTx = TransactionBuilder.build(
signerPubKey,
'Coin', // Contract name
'transfer', // Method name
[fromBase58('5Kd3N...'), toAtomicAma(10.5).toString(), 'AMA']
)
const { txHash, txPacked } = TransactionBuilder.sign(unsignedTx, '5Kd3N...')
// Option 4: Build and sign custom transaction (convenience)
const { seed64, sk } = deriveSkAndSeed64FromBase58Seed('5Kd3N...')
const signerPubKey = getPublicKey(seed64)
const { txHash, txPacked } = TransactionBuilder.buildAndSign(signerPubKey, sk, 'Coin', 'transfer', [
fromBase58('5Kd3N...'),
toAtomicAma(10.5).toString(),
'AMA'
])import { encode, decode } from '@amadeus-protocol/sdk'
// Encode data to canonical format
const data = {
foo: 'bar',
count: 42,
items: [1, 2, 3]
}
const encoded = encode(data)
// Decode data from canonical format
const decoded = decode(encoded)import { toAtomicAma, fromAtomicAma } from '@amadeus-protocol/sdk'
// Convert to atomic units
const atomic = toAtomicAma(1.5) // Returns 1500000000
// Convert from atomic units
const ama = fromAtomicAma(1500000000) // Returns 1.5import { TransactionBuilder } from '@amadeus-protocol/sdk'
// Using TransactionBuilder instance
const builder = new TransactionBuilder('5Kd3N...')
// Build unsigned transaction
const unsignedTx = builder.build('Coin', 'transfer', args)
// Sign the transaction
const { txHash, txPacked } = builder.sign(unsignedTx)
// Or build and sign in one step
const { txHash, txPacked } = builder.buildAndSign('Coin', 'transfer', args)import { toBase58, fromBase58, uint8ArrayToBase64, base64ToUint8Array } from '@amadeus-protocol/sdk'
// Base58 encoding
const encoded = toBase58(new Uint8Array([1, 2, 3]))
const decoded = fromBase58('5Kd3N...')
// Base64 encoding
const base64 = uint8ArrayToBase64(new Uint8Array([1, 2, 3]))
const bytes = base64ToUint8Array(base64)import { encryptWithPassword, decryptWithPassword } from '@amadeus-protocol/sdk'
// Encrypt sensitive data (e.g., private keys)
const encrypted = await encryptWithPassword('sensitive wallet data', 'my-password')
// Returns: { encryptedData, iv, salt } (all Base64 encoded)
// Decrypt the data
const decrypted = await decryptWithPassword(encrypted, 'my-password')
// Returns: 'sensitive wallet data'AMADEUS_PUBLIC_KEY_BYTE_LENGTH: Byte length of public key (48)AMADEUS_SEED_BYTE_LENGTH: Byte length of seed (64)AMA_TOKEN_DECIMALS: Number of decimal places (9)AMA_TOKEN_DECIMALS_MULTIPLIER: Multiplier for conversions (10^9)AMA_TRANSFER_FEE: Network transfer fee (0.02)EXPLORER_URL: Default explorer URLNODE_API_URL: Default node API URL
encode(term: SerializableValue): Uint8Array- Encode value to canonical formatdecode(bytes: Uint8Array | number[]): DecodedValue- Decode from canonical format
generateKeypair(): KeyPair- Generate a new keypairgeneratePrivateKey(): Uint8Array- Generate a random 64-byte seedgetPublicKey(seed64: Uint8Array): Uint8Array- Derive public key from seedderivePublicKeyFromSeedBase58(base58Seed: string): string- Derive public key from Base58 seedderiveSkAndSeed64FromBase58Seed(base58Seed64: string)- Derive secret key and seed
toBase58(buf: Uint8Array): string- Encode bytes to Base58fromBase58(str: string): Uint8Array- Decode Base58 to bytesuint8ArrayToBase64(bytes: Uint8Array): string- Convert bytes to Base64base64ToUint8Array(base64: string): Uint8Array- Convert Base64 to bytesarrayBufferToBase64(buffer: ArrayBuffer): string- Convert ArrayBuffer to Base64base64ToArrayBuffer(base64: string): ArrayBuffer- Convert Base64 to ArrayBufferuint8ArrayToArrayBuffer(bytes: Uint8Array): ArrayBuffer- Convert Uint8Array to ArrayBufferarrayBufferToUint8Array(buffer: ArrayBuffer): Uint8Array- Convert ArrayBuffer to Uint8Array
signTx(hash: Uint8Array, sk: PrivKey): Uint8Array- Sign a transaction hashsignOOB(sk: string, msg: Uint8Array): Uint8Array- Sign an out-of-band message
toAtomicAma(ama: number): number- Convert AMA to atomic unitsfromAtomicAma(atomicAma: number | string): number- Convert atomic units to AMA
encryptWithPassword(plaintext: string, password: string): Promise<EncryptedPayload>- Encrypt data with password (AES-GCM + PBKDF2)decryptWithPassword(payload: EncryptedPayload, password: string): Promise<string>- Decrypt data with passwordgenerateSalt(): Uint8Array- Generate random salt (16 bytes)generateIV(): Uint8Array- Generate random IV (12 bytes)deriveKey(password: string, salt: Uint8Array | ArrayBuffer): Promise<CryptoKey>- Derive AES-GCM key from password
TransactionBuilder- Class for building and signing transactions- Constructor:
new TransactionBuilder(privateKey?: string)- Create a new builder instance - Instance Methods:
build(contract, method, args, signerPk?): UnsignedTransactionWithHash- Build an unsigned transactionsign(unsignedTx, signerSk?): BuildTxResult- Sign an unsigned transactionbuildAndSign(contract, method, args, signerPk?, signerSk?): BuildTxResult- Build and sign in one stepbuildTransfer(input, signerPk?): UnsignedTransactionWithHash- Build an unsigned transfertransfer(input): BuildTxResult- Build and sign a transfer (convenience)
- Static Methods:
build(signerPk, contract, method, args): UnsignedTransactionWithHash- Build unsigned transactionsign(unsignedTx, signerSk): BuildTxResult- Sign an unsigned transactionbuildAndSign(signerPk, signerSk, contract, method, args): BuildTxResult- Build and sign in one stepbuildTransfer(input, signerPk): UnsignedTransactionWithHash- Build unsigned transferbuildSignedTransfer(input): BuildTxResult- Build and sign transfer (convenience)
- Constructor:
See the examples/ directory for comprehensive usage examples:
- Basic Usage - SDK initialization, key generation, queries
- Transaction Flow - Complete transaction building and submission flow
- API Usage - All API endpoints demonstrated
# Run examples
npm run example:basic
npm run example:tx
npm run example:apiThe SDK includes comprehensive test coverage:
# Run tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm run test:coverageThis package is written in TypeScript and includes full type definitions. All exports are typed and documented.
All errors are thrown as AmadeusSDKError instances with descriptive messages:
import { AmadeusSDK, AmadeusSDKError } from '@amadeus-protocol/sdk'
try {
const balance = await sdk.wallet.getBalance('invalid')
} catch (error) {
if (error instanceof AmadeusSDKError) {
console.error('SDK Error:', error.message)
console.error('Status:', error.status)
console.error('Response:', error.response)
}
}MIT
Contributions are welcome! Please ensure all code follows the existing style and includes appropriate tests.