This guide will help you get your first Beacon up and running in under 15 minutes.
# Clone the repository
git clone https://github.com/aura-labs/aura-framework.git
cd aura-framework
# Navigate to the simple beacon example
cd beacons/simple-beacon
# Install dependencies
npm install
A Beacon has five main responsibilities:
Create a .env file in the beacons/simple-beacon directory:
# Beacon identification
BEACON_ID=my-first-beacon
PORT=3000
# AURA Core connection
AURA_CORE_URL=ws://localhost:8080
AURA_API_KEY=your-api-key-here
# Merchant details
MERCHANT_NAME=My Demo Store
MERCHANT_CATEGORY=electronics
npm start
You should see:
✓ Loaded 3 items into inventory
Connecting to AURA Core at ws://localhost:8080...
✓ Connected to AURA Core
✓ Beacon registered with AURA Core
🚀 Simple Beacon started
Beacon ID: my-first-beacon
Merchant: My Demo Store
API Server: http://localhost:3000
✓ Beacon is ready to receive Scout inquiries
Open another terminal and test the health endpoint:
curl http://localhost:3000/health
You should get:
{
"status": "healthy",
"beaconId": "my-first-beacon",
"connected": true,
"inventory": 3,
"activeNegotiations": 0
}
Check your inventory:
curl http://localhost:3000/inventory
Let’s walk through what happens when a Scout discovers your Beacon:
A Scout sends an inquiry through AURA Core:
{
"type": "SCOUT_INQUIRY",
"payload": {
"scoutId": "sct_abc123",
"inquiryId": "inq_xyz789",
"intent": {
"category": "electronics",
"description": "wireless headphones",
"keywords": ["ANC", "over-ear"]
},
"preferences": {
"priceRange": { "min": 100, "max": 400 }
},
"behavioralData": {
"purchaseHistory": {
"totalPurchases": 5,
"averageOrderValue": 350
}
}
}
}
Note: The Scout’s identity is abstracted - you don’t know who the person is, only their shopping behavior.
Your Beacon’s handleScoutInquiry() method:
{
"type": "INQUIRY_RESPONSE",
"payload": {
"available": true,
"propositions": [
{
"propositionId": "prop_...",
"name": "Wireless Headphones Pro",
"priceRange": { "min": 240, "max": 300 },
"available": true
}
]
}
}
If the Scout is interested, they’ll request negotiation:
{
"type": "NEGOTIATION_REQUEST",
"payload": {
"propositionId": "prop_...",
"constraints": {
"maxPrice": 350
}
}
}
Your Beacon’s calculateDynamicPricing() method considers:
Then makes an offer:
{
"type": "NEGOTIATION_OFFER",
"payload": {
"price": 285.99,
"discount": 15,
"incentives": [
{
"type": "loyalty-discount",
"description": "15% off for loyal customers"
}
],
"validUntil": "2025-01-15T11:00:00Z"
}
}
If the Scout accepts, they send a transaction request:
{
"type": "TRANSACTION_REQUEST",
"payload": {
"negotiationId": "neg_...",
// NOW identity is revealed for fulfillment
"userIdentity": {
"name": "Jane Doe",
"email": "jane@example.com"
},
"shippingAddress": { /* ... */ },
"paymentMethod": { /* ... */ }
}
}
Your Beacon confirms the transaction and processes the order.
Edit simple-beacon.js and modify the loadInventory() method:
loadInventory() {
const myProducts = [
{
name: 'My Awesome Product',
category: 'my-category',
basePrice: 99.99,
stock: 100,
description: 'The best product ever',
features: ['feature1', 'feature2'],
},
// Add more products...
];
myProducts.forEach(product => {
const item = this.createInventoryItem(product);
this.inventory.set(item.id, item);
});
}
Modify the calculateDynamicPricing() method to implement your pricing logic:
calculateDynamicPricing(propositionId, behavioralData, constraints) {
const item = this.inventory.get(propositionId);
let discount = 5; // Base discount
// Your custom logic here
if (behavioralData.purchaseHistory.totalPurchases > 10) {
discount = 20; // VIP discount
}
if (item.stock < 5) {
discount = 0; // No discount for low stock
}
// ... more custom logic
return {
basePrice: item.basePrice,
offeredPrice: item.basePrice * (1 - discount / 100),
discountPercent: discount,
incentives: [],
};
}
The Beacon comes with basic monitoring. Access these endpoints:
# Check health
curl http://localhost:3000/health
# View inventory
curl http://localhost:3000/inventory
# View active negotiations
curl http://localhost:3000/negotiations
Set these in your production environment:
BEACON_ID=your-production-beacon-id
PORT=3000
AURA_CORE_URL=wss://api.aura-network.com
AURA_API_KEY=your-production-api-key
MERCHANT_NAME=Your Store Name
MERCHANT_CATEGORY=your-category
Replace the in-memory Map objects with a real database:
// Replace this:
this.inventory = new Map();
// With this:
this.inventory = {
get: (id) => database.query('SELECT * FROM inventory WHERE id = ?', [id]),
set: (id, item) => database.query('INSERT INTO inventory ...', [id, item]),
// ... other methods
};
Check:
Check:
loadInventory() is calledcreateInventoryItem() schemaCheck:
Solutions:
Stuck? We’re here to help:
Happy building! 🚀