Skip to main content

Overview

This guide covers the complete process of integrating your business as a vendor in the boop network, from development to production deployment.

Architecture Overview

Phase 1: Development Setup

1.1 Environment Preparation

1

Install Dependencies

# Install required tools
brew install rust docker git

# Clone the boop repository
git clone https://github.com/boop-network/boop-network.git
cd boop-network
2

Configure Development Environment

Create .env file for your vendor service:
# .env
BOOP_API_URL=http://localhost:40401
VENDOR_PORT=8080
VENDOR_ID=your-vendor-id
VENDOR_SECRET=your-vendor-secret
LOG_LEVEL=debug
3

Start Local boop Services

cd docker/standalone
docker-compose up -d

1.2 Vendor Backend Implementation

Create your vendor backend that handles authentication requests:
import WebSocket from 'ws';
import express from 'express';

const app = express();
const BRIDGE_URL = 'ws://localhost:40403/vendor/connect';

class VendorService {
  private ws: WebSocket | null = null;
  private authCallbacks: Map<string, Function> = new Map();

  async connect() {
    this.ws = new WebSocket(BRIDGE_URL, {
      headers: {
        'X-Vendor-Id': process.env.VENDOR_ID,
        'X-Vendor-Secret': process.env.VENDOR_SECRET
      }
    });

    this.ws.on('message', (data) => {
      const message = JSON.parse(data.toString());
      this.handleMessage(message);
    });

    this.ws.on('open', () => {
      console.log('Connected to boop network');
      this.startHeartbeat();
    });
  }

  async createAuthContext(type: string, requirements: any) {
    const contextId = crypto.randomUUID();

    const message = {
      type: 'create_auth_context',
      context_id: contextId,
      auth_type: type,
      requirements: requirements,
      timestamp: new Date().toISOString()
    };

    this.ws?.send(JSON.stringify(message));

    return new Promise((resolve, reject) => {
      this.authCallbacks.set(contextId, resolve);

      // Timeout after 30 seconds
      setTimeout(() => {
        if (this.authCallbacks.has(contextId)) {
          this.authCallbacks.delete(contextId);
          reject(new Error('Authentication timeout'));
        }
      }, 30000);
    });
  }

  private handleMessage(message: any) {
    switch (message.type) {
      case 'auth_result':
        this.handleAuthResult(message);
        break;
      case 'error':
        console.error('Error from boop:', message.error);
        break;
    }
  }

  private handleAuthResult(message: any) {
    const callback = this.authCallbacks.get(message.context_id);
    if (callback) {
      callback(message);
      this.authCallbacks.delete(message.context_id);
    }
  }

  private startHeartbeat() {
    setInterval(() => {
      if (this.ws?.readyState === WebSocket.OPEN) {
        this.ws.send(JSON.stringify({ type: 'ping' }));
      }
    }, 30000);
  }
}

// API Endpoints
const vendor = new VendorService();

app.post('/auth/payment', async (req, res) => {
  try {
    const result = await vendor.createAuthContext('payment', {
      amount: req.body.amount,
      currency: 'USD',
      attributes: ['email']
    });

    res.json(result);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

app.post('/auth/entrance', async (req, res) => {
  try {
    const result = await vendor.createAuthContext('entrance', {
      venue_id: req.body.venue_id,
      require_age_verification: true,
      minimum_age: 21
    });

    res.json(result);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

// Start server
vendor.connect().then(() => {
  app.listen(8080, () => {
    console.log('Vendor server running on port 8080');
  });
});

Phase 2: Integration Testing

2.1 Test with Mock Services

Use the mock PVS web interface for comprehensive testing:
# Terminal 1: Start your vendor server
npm start  # or python server.py, or cargo run

# Terminal 2: Start mock PVS with web UI
cargo run --bin mock-pvs -- \
  --api-addr http://localhost:40401 \
  serve 0.0.0.0:8081
Access http://localhost:8081 to:
  • Register test users
  • Simulate authentication scenarios
  • Test error handling
  • Verify attribute retrieval

2.2 Automated Testing

Create integration tests for your vendor implementation:
test.js
describe('Vendor Authentication', () => {
  it('should handle payment authentication', async () => {
    const result = await vendor.createAuthContext('payment', {
      amount: 2500,
      currency: 'USD'
    });

    expect(result.success).toBe(true);
    expect(result.attributes).toHaveProperty('email');
  });

  it('should handle authentication timeout', async () => {
    // Disconnect PVS to simulate timeout
    await expect(
      vendor.createAuthContext('payment', {})
    ).rejects.toThrow('timeout');
  });

  it('should handle age verification', async () => {
    const result = await vendor.createAuthContext('entrance', {
      require_age_verification: true,
      minimum_age: 21
    });

    expect(result.attributes).toHaveProperty('age_verified');
  });
});

Phase 3: Security Implementation

3.1 Authentication & Authorization

Never expose vendor credentials in client-side code or logs. Always use environment variables and secure storage.
Implement proper authentication:
class SecureVendorService {
  private async authenticate() {
    // Use OAuth2 or API keys
    const token = await this.getAccessToken();

    this.ws = new WebSocket(BRIDGE_URL, {
      headers: {
        'Authorization': `Bearer ${token}`,
        'X-Vendor-Id': process.env.VENDOR_ID
      }
    });
  }

  private async getAccessToken() {
    // Implement OAuth2 flow or API key exchange
    const response = await fetch(`${BOOP_API}/oauth/token`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
      },
      body: new URLSearchParams({
        grant_type: 'client_credentials',
        client_id: process.env.VENDOR_ID,
        client_secret: process.env.VENDOR_SECRET,
      })
    });

    const data = await response.json();
    return data.access_token;
  }
}

3.2 Data Protection

Implement encryption for sensitive data:
import crypto from 'crypto';

class DataProtection {
  private encryptionKey: Buffer;

  constructor() {
    this.encryptionKey = Buffer.from(process.env.ENCRYPTION_KEY, 'hex');
  }

  encrypt(data: any): string {
    const iv = crypto.randomBytes(16);
    const cipher = crypto.createCipheriv(
      'aes-256-gcm',
      this.encryptionKey,
      iv
    );

    const encrypted = Buffer.concat([
      cipher.update(JSON.stringify(data), 'utf8'),
      cipher.final()
    ]);

    const tag = cipher.getAuthTag();

    return Buffer.concat([iv, tag, encrypted]).toString('base64');
  }

  decrypt(encryptedData: string): any {
    const buffer = Buffer.from(encryptedData, 'base64');
    const iv = buffer.slice(0, 16);
    const tag = buffer.slice(16, 32);
    const encrypted = buffer.slice(32);

    const decipher = crypto.createDecipheriv(
      'aes-256-gcm',
      this.encryptionKey,
      iv
    );

    decipher.setAuthTag(tag);

    const decrypted = Buffer.concat([
      decipher.update(encrypted),
      decipher.final()
    ]);

    return JSON.parse(decrypted.toString('utf8'));
  }
}

Phase 4: Production Deployment

4.1 Infrastructure Setup

# cloudformation.yaml
Resources:
  VendorService:
    Type: AWS::ECS::Service
    Properties:
      ServiceName: boop-vendor
      TaskDefinition: !Ref VendorTaskDefinition
      DesiredCount: 2
      LoadBalancers:
        - TargetGroupArn: !Ref TargetGroup
          ContainerName: vendor
          ContainerPort: 8080

  VendorTaskDefinition:
    Type: AWS::ECS::TaskDefinition
    Properties:
      ContainerDefinitions:
        - Name: vendor
          Image: !Sub ${AWS::AccountId}.dkr.ecr.${AWS::Region}.amazonaws.com/vendor:latest
          Environment:
            - Name: BOOP_API_URL
              Value: https://api.boop.network
            - Name: VENDOR_ID
              ValueFrom: !Ref VendorIdSecret
            - Name: VENDOR_SECRET
              ValueFrom: !Ref VendorSecretSecret

4.2 Monitoring & Observability

Implement comprehensive monitoring:
import * as prometheus from 'prom-client';

// Metrics
const authCounter = new prometheus.Counter({
  name: 'vendor_auth_total',
  help: 'Total authentication requests',
  labelNames: ['type', 'status']
});

const authDuration = new prometheus.Histogram({
  name: 'vendor_auth_duration_seconds',
  help: 'Authentication request duration',
  labelNames: ['type']
});

// Logging
import winston from 'winston';

const logger = winston.createLogger({
  level: process.env.LOG_LEVEL || 'info',
  format: winston.format.json(),
  transports: [
    new winston.transports.Console(),
    new winston.transports.File({ filename: 'error.log', level: 'error' }),
    new winston.transports.File({ filename: 'combined.log' })
  ]
});

// Health checks
app.get('/health', (req, res) => {
  const health = {
    status: 'UP',
    timestamp: new Date().toISOString(),
    services: {
      boop: vendor.isConnected() ? 'UP' : 'DOWN',
      database: db.isHealthy() ? 'UP' : 'DOWN'
    }
  };

  const httpStatus = health.services.boop === 'UP' ? 200 : 503;
  res.status(httpStatus).json(health);
});

app.get('/metrics', async (req, res) => {
  res.set('Content-Type', prometheus.register.contentType);
  res.end(await prometheus.register.metrics());
});

Phase 5: Going Live

5.1 Pre-Launch Checklist

  • All integration tests passing
  • Security audit completed
  • Load testing performed
  • Monitoring configured
  • Backup strategy implemented
  • Incident response plan documented
  • SSL certificates configured
  • Rate limiting implemented
  • Error handling comprehensive
  • Logging properly configured

5.2 Launch Process

1

Soft Launch

Start with a limited rollout:
  • Enable for 10% of locations/users
  • Monitor metrics closely
  • Gather feedback
  • Fix any issues
2

Gradual Rollout

Increase coverage:
  • 25% → 50% → 100%
  • Monitor at each stage
  • Ensure support team is ready
3

Full Production

Complete deployment:
  • All locations/users enabled
  • Marketing campaign launch
  • Continue monitoring

Support & Resources

Troubleshooting

For common issues and solutions, see our Troubleshooting Guide.