Server Wallets Integration
This guide covers integrating AxonVault server wallets into your backend services for treasury management, automated trading, and payment processing.Overview
Server wallets are designed for:- Backend automation
- Treasury management
- Payment processing
- Programmatic trading
Setup
1. Create API Credentials
- Log in to AxonVault Dashboard
- Navigate to Settings > API Keys
- Create a new API key with appropriate permissions
- Store the Client Key and Secret Key securely
2. Configure Environment
Copy
# .env
AXONVAULT_CLIENT_KEY=ak_live_abc123
AXONVAULT_SECRET_KEY=sk_live_xyz789...
AXONVAULT_BASE_URL=https://api.axonvault.io
SDK Setup
Node.js
Copy
import crypto from 'crypto';
class AxonVaultClient {
constructor(clientKey, secretKey, baseUrl = 'https://api.axonvault.io') {
this.clientKey = clientKey;
this.secretKey = secretKey;
this.baseUrl = baseUrl;
}
sign(method, path, body = null) {
const timestamp = new Date().toISOString();
const bodyStr = body ? JSON.stringify(body) : '';
const payload = `${method}\n${path}\n${timestamp}\n${bodyStr}`;
const signature = crypto
.createHmac('sha256', this.secretKey)
.update(payload)
.digest('hex');
return {
'X-Access-Key': this.clientKey,
'X-Signature': signature,
'X-Timestamp': timestamp,
'Content-Type': 'application/json'
};
}
async request(method, path, body = null) {
const headers = this.sign(method, path, body);
const response = await fetch(`${this.baseUrl}${path}`, {
method,
headers,
body: body ? JSON.stringify(body) : undefined
});
if (!response.ok) {
const error = await response.json();
throw new Error(`${error.errorType}: ${error.errorMessage}`);
}
return response.json();
}
// Wallet methods
async createWallet(name) {
return this.request('POST', '/v1/server/wallets', { walletName: name });
}
async getWallet(walletId) {
return this.request('GET', `/v1/server/wallets/${walletId}`);
}
async listWallets(limit = 20, cursor = null) {
const params = new URLSearchParams({ limit: limit.toString() });
if (cursor) params.append('cursor', cursor);
return this.request('GET', `/v1/server/wallets?${params}`);
}
// Transaction methods
async buildTransaction(params) {
return this.request('POST', '/v1/transactions/build', params);
}
async signTransaction(params) {
return this.request('POST', '/v1/signature/sign', params);
}
async submitTransaction(txId, signedTxHex) {
return this.request('POST', '/v1/transactions/submit', { txId, signedTxHex });
}
}
// Usage
const client = new AxonVaultClient(
process.env.AXONVAULT_CLIENT_KEY,
process.env.AXONVAULT_SECRET_KEY
);
Python
Copy
import hmac
import hashlib
import json
import os
from datetime import datetime, timezone
import requests
class AxonVaultClient:
def __init__(self, client_key: str, secret_key: str, base_url: str = 'https://api.axonvault.io'):
self.client_key = client_key
self.secret_key = secret_key
self.base_url = base_url
def _sign(self, method: str, path: str, body: dict = None) -> dict:
timestamp = datetime.now(timezone.utc).strftime('%Y-%m-%dT%H:%M:%SZ')
body_str = json.dumps(body, separators=(',', ':')) if body else ''
payload = f"{method}\n{path}\n{timestamp}\n{body_str}"
signature = hmac.new(
self.secret_key.encode(),
payload.encode(),
hashlib.sha256
).hexdigest()
return {
'X-Access-Key': self.client_key,
'X-Signature': signature,
'X-Timestamp': timestamp,
'Content-Type': 'application/json'
}
def _request(self, method: str, path: str, body: dict = None):
headers = self._sign(method, path, body)
response = requests.request(
method,
f"{self.base_url}{path}",
headers=headers,
json=body
)
if not response.ok:
error = response.json()
raise Exception(f"{error['errorType']}: {error['errorMessage']}")
return response.json()
# Wallet methods
def create_wallet(self, name: str):
return self._request('POST', '/v1/server/wallets', {'walletName': name})
def get_wallet(self, wallet_id: str):
return self._request('GET', f'/v1/server/wallets/{wallet_id}')
# Transaction methods
def build_transaction(self, **params):
return self._request('POST', '/v1/transactions/build', params)
def sign_transaction(self, **params):
return self._request('POST', '/v1/signature/sign', params)
def submit_transaction(self, tx_id: str, signed_tx_hex: str):
return self._request('POST', '/v1/transactions/submit', {
'txId': tx_id,
'signedTxHex': signed_tx_hex
})
# Usage
client = AxonVaultClient(
os.environ['AXONVAULT_CLIENT_KEY'],
os.environ['AXONVAULT_SECRET_KEY']
)
Common Workflows
Create Treasury Wallet
Copy
async function setupTreasury() {
// Create wallet
const { wallet } = await client.createWallet('Treasury');
// Create account
const { account } = await client.request('POST',
`/v1/server/wallets/${wallet.walletId}/accounts`,
{ accountIndex: 0, accountName: 'Main' }
);
// Derive addresses for needed chains
const chains = ['eip155:1', 'eip155:8453', 'solana:mainnet'];
const addresses = [];
for (const chainId of chains) {
const { address } = await client.request('POST',
`/v1/wallets/${wallet.walletId}/accounts/${account.accountId}/addresses/derive`,
{ chainId }
);
addresses.push(address);
}
return { wallet, account, addresses };
}
Send Payment
Copy
async function sendPayment(from, to, amount, chainRef, keyId) {
// Build transaction
const { txId, unsignedTxHex } = await client.buildTransaction({
fromAddress: from,
toAddress: to,
amount: amount,
chainReference: chainRef
});
// Sign
const { signature } = await client.signTransaction({
chainReference: chainRef,
unsignedTxHex: unsignedTxHex,
keyId: keyId,
coinType: 60,
accountIndex: 0
});
// Construct signed
const { signedTxHex } = await client.request('POST',
'/v1/transactions/construct-signed',
{ txId, signature }
);
// Submit
const { txHash } = await client.submitTransaction(txId, signedTxHex);
return txHash;
}
Batch Payments
Copy
async function batchPayments(payments, keyId) {
const results = [];
for (const payment of payments) {
try {
const txHash = await sendPayment(
payment.from,
payment.to,
payment.amount,
payment.chainRef,
keyId
);
results.push({ success: true, txHash, payment });
} catch (error) {
results.push({ success: false, error: error.message, payment });
}
}
return results;
}
Webhook Integration
Set up webhooks to receive transaction notifications:Copy
// Create webhook
await client.request('POST', '/v1/tx-relay/webhooks', {
tenantId: 'ten_abc123',
projectId: 'proj_abc123',
url: 'https://yourapp.com/webhooks/axonvault',
events: ['transaction.confirmed', 'transaction.failed'],
secret: 'your_webhook_secret',
enabled: true
});
// Handle webhook (Express.js)
app.post('/webhooks/axonvault', (req, res) => {
const signature = req.headers['x-webhook-signature'];
// Verify signature
const expectedSig = crypto
.createHmac('sha256', webhookSecret)
.update(JSON.stringify(req.body))
.digest('hex');
if (signature !== expectedSig) {
return res.status(401).send('Invalid signature');
}
const { event, data } = req.body;
switch (event) {
case 'transaction.confirmed':
console.log(`Transaction ${data.txHash} confirmed`);
break;
case 'transaction.failed':
console.log(`Transaction ${data.txId} failed: ${data.error}`);
break;
}
res.status(200).send('OK');
});
Best Practices
Security
Security
- Store credentials in secret managers (AWS Secrets Manager, HashiCorp Vault)
- Rotate API keys regularly
- Use IP allowlisting
- Implement request logging
Reliability
Reliability
- Implement retry with exponential backoff
- Use idempotency keys for transactions
- Monitor webhook delivery
- Set up alerting for failures
Compliance
Compliance
- Configure policies before going live
- Enable audit logging
- Implement approval workflows for large transactions
- Regular security reviews