VoiceShift AI (Voice AI Integration)
VoiceShift (ChangeVoice) is a stunning, high-fidelity AI video dubbing workspace built to showcase a complete real-world integration of the SettleSettle SDK. It manages idempotent user profile syncing, dynamic credits-based billing, multi-rail checkouts (Paystack + Solana), and rewarded ad fallbacks.
All billing rates, package sizes, and lookups are fetched dynamically from the SettleSettle cloud dashboard to ensure zero hardcoded values in the codebase.
**View the Repository on GitHub →**
Core Integration Blueprint
- Dynamic Cost Resolution: Costs are queried live from the active rules defined in your SettleSettle dashboard (e.g. charging 10 credits per minute of video processed).
- Debit-Before-Processing (The Gatekeeper): Enforces credit validation *before* executing expensive AI dubbing GPU/CPU tasks. If the wallet drops below the threshold, the SDK throws
InsufficientCreditsError(402). - Usage Tracking Telemetry: Emits a non-blocking asynchronous usage event after successful execution, allowing zero-latency performance.
- Flexible Refills: Supports traditional card payments via Paystack and next-gen Solana Web3 USDC peer-to-peer transfers.
Step-by-Step Integration Recipes
#### 1. Setup Singleton Client
Configure SettleSettle in a dedicated file (lib/settle.ts) to avoid duplicate connections in local Next.js HMR:
import { SettleSettle } from 'settlesettle'
// 1. Declare 'settle' in the global scope so it's typed everywhere
declare global {
var settle: SettleSettle;
}
// 2. Resolve singleton instance (preventing double instantiation in Next.js HMR development mode)
const settleInstance =
globalThis.settle ||
new SettleSettle({
apiKey: process.env.SETTLESETTLE_API_KEY!,
baseUrl: process.env.SETTLESETTLE_BASE_URL,
})
// 3. Assign to globalThis so it is globally accessible directly as 'settle'
globalThis.settle = settleInstance
// 4. Export it for standard import patterns as well
export const settle = settleInstance#### 2. Sync User Idempotently
Sync the logged-in user profile with SettleSettle's directory:
// app/api/settle/sync-user/route.ts
import { settle } from '@/lib/settle'
import { NextResponse } from 'next/server'
export async function POST() {
const user = await settle.users.sync({
externalUserId: 'voiceshift_demo_user',
email: 'demo@voiceshift.dev',
name: 'Demo Creator',
})
return NextResponse.json({ ok: true, data: user })
}#### 3. Debit-Before-Processing & Telemetry Metering
// app/api/settle/dub/route.ts
import { settle } from '@/lib/settle'
import { InsufficientCreditsError } from 'settlesettle'
import { NextResponse } from 'next/server'
export async function POST(req: Request) {
const userId = 'voiceshift_demo_user'
try {
const { videoUrl, language, durationMinutes } = await req.json()
const duration = Math.ceil(Number(durationMinutes))
// 1. Fetch live rules from bootstrap configuration
const bootstrapData = await settle.billing.bootstrap(userId)
const activeRules = bootstrapData.walletState?.activeRules || []
// Find the rule for event billing
const billingRule = activeRules.find(r => r.eventType === 'VIDEO_MINUTE_PROCESSED')
const costPerMinute = billingRule ? billingRule.cost : 10
const creditsRequired = duration * costPerMinute
// 2. Enforce pre-debit check
await settle.wallet.debit(userId, {
amount: creditsRequired,
description: `Dubbed ${duration} min video → ${language.toUpperCase()}`,
})
// 3. Process video dubbing (GPU/CPU action)
const result = await processAIDubbing(videoUrl, language, durationMinutes)
// 4. Emit non-blocking usage event
settle.events.track({
userId,
eventType: 'VIDEO_MINUTE_PROCESSED',
quantity: duration,
})
return NextResponse.json({ ok: true, data: result })
} catch (error) {
if (error instanceof InsufficientCreditsError) {
return NextResponse.json({
code: 'INSUFFICIENT_CREDITS',
currentBalance: error.currentBalance,
}, { status: 402 })
}
return NextResponse.json({ error: error.message }, { status: 500 })
}
}Clone & Run Locally
To spin up VoiceShift locally:
- Clone the repository and navigate inside:
git clone https://github.com/Ek0m/changevoice.git
cd changevoice- Install dependencies:
npm install- Configure your local environment in
.env.local:
SETTLESETTLE_API_KEY=ss_live_xxxxxxxxxxxxxxxxxxxxxxxx
SETTLESETTLE_BASE_URL=https://api.settlesettle.uno/v1- Run the Next.js development server:
npm run dev