Documentation Index
Fetch the complete documentation index at: https://docs.scriptonia.xyz/llms.txt
Use this file to discover all available pages before exploring further.
Overview
| Integration | Purpose | Where used |
|---|
| Solana | SOL payments, Phantom/AppKit, transaction verification | lib/solana.ts, lib/solana-client.ts, PaymentForm, /api/payment, /api/execute |
| Dodo | Card/UPI checkout, webhooks, confirm-payment | /api/dodo/create-checkout, /api/dodo/webhook, /api/dodo/confirm-payment |
| GitHub | OAuth, create repo, push project files | /api/github/authorize, /api/github/callback, /api/github/upload |
| OpenRouter | AI (Idea, Intent, Platform, Execute) | lib/openai.ts |
Details: Integrations.
1. Solana Integration
Flow
- Client: Get agentAddress (Treasury) from
GET /api/payment/config
- Client: Call
POST /api/payment with sessionId, selectedPlatform, userWalletPubKey → server runs validatePayment; on success, client builds and signs the transaction
- Client: createPaymentTransaction(from, to, amount) from lib/solana-client (SPL or SOL fallback), sign via AppKit/Phantom,
connection.confirmTransaction(signature, 'confirmed')
- Client: Call
POST /api/execute with { sessionId, transactionSignature } → server runs verifyTransaction then executes
Client: build and send payment (React)
import { PublicKey } from '@solana/web3.js';
import { createPaymentTransaction } from '@/lib/solana-client';
async function handlePayment(publicKey, connection, walletProvider, amount, onSuccess, onError) {
const configRes = await fetch('/api/payment/config');
const { agentAddress } = await configRes.json();
const toPubkey = new PublicKey(agentAddress);
const tx = await createPaymentTransaction(publicKey, toPubkey, amount);
const { blockhash } = await connection.getLatestBlockhash();
tx.recentBlockhash = blockhash;
tx.feePayer = publicKey;
const solanaProvider = walletProvider;
const signature = typeof solanaProvider.signAndSendTransaction === 'function'
? await solanaProvider.signAndSendTransaction(tx)
: (await connection.sendRawTransaction(
(await solanaProvider.signTransaction(tx)).serialize()
));
await connection.confirmTransaction(signature, 'confirmed');
onSuccess(signature, publicKey.toString());
}
Server: validate and verify (lib/solana.ts)
// validatePayment: before user sends tx
const result = await validatePayment(userWalletPubKey, requiredAmount);
// { valid, balance, required, message? }
// verifyTransaction: after user pays
const ok = await verifyTransaction(transactionSignature);
// true if status.err === null && confirmationStatus present
createPaymentTransaction (SPL vs SOL)
- SPL: USE_SPL_TOKEN=true and mint set → createTransferInstruction from user ATA to treasury ATA
- SOL fallback: SystemProgram.transfer with lamports derived from amount
See Solana Integration.
2. Dodo Payments Integration
Flow
- Create checkout:
POST /api/dodo/create-checkout → get checkout_url
- Redirect: user pays on Dodo
- Webhook: Dodo POST to
/api/dodo/webhook; handler verifies signature and updates Workflow
- Optional: call
POST /api/dodo/confirm-payment if webhook is delayed
- Execute:
POST /api/execute with { sessionId }
Client: create checkout and redirect
const res = await fetch('/api/dodo/create-checkout', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ sessionId: '...', platform: 'Web Application' }),
});
const data = await res.json();
if (data.status === 'success' && data.checkout_url) {
window.location.href = data.checkout_url;
}
Server: create checkout
const payload = {
product_cart: [{ product_id: productId, quantity: 1 }],
return_url: `${process.env.NEXT_PUBLIC_APP_URL}/payment/success?sessionId=${sessionId}&platform=${platform}`,
metadata: { session_id: sessionId, platform },
customization: { redirect_immediately: true },
};
const response = await fetch('https://live.dodopayments.com/checkouts', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.DODO_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(payload),
});
const data = await response.json();
Webhook: signature verification
import crypto from 'crypto';
function verifyWebhookSignature(rawBody, signature, secret) {
if (!signature || Array.isArray(signature)) return false;
const expected = crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}
Confirm-payment (fallback)
POST /api/dodo/confirm-payment
- Updates Workflow: paymentMethod, paymentId, currentStage, selectedPlatform
See Dodo Payments.
3. GitHub Integration
Flow
- Authorize:
GET /api/github/authorize?sessionId=...
- Callback:
GET /api/github/callback?code=...&state=...
- Upload:
POST /api/github/upload → create repo and push files
OAuth: authorize
const state = Buffer.from(JSON.stringify({ sessionId })).toString('base64');
res.setHeader('Set-Cookie', `github_oauth_state=${state}; HttpOnly; SameSite=Lax; Path=/; Max-Age=600`);
const authUrl = `https://github.com/login/oauth/authorize?client_id=${clientId}&redirect_uri=${callbackUrl}&scope=repo&state=${state}`;
return res.redirect(authUrl);
OAuth: callback
- Verify state
- Exchange code for token
- Fetch user
- Set cookies
- Redirect to Execution
Upload: create repo and push files
const accessToken = req.cookies.github_access_token;
const createRes = await fetch('https://api.github.com/user/repos', {
method: 'POST',
headers: {
'Authorization': `Bearer ${accessToken}`,
'Accept': 'application/vnd.github.v3+json',
'Content-Type': 'application/json',
},
body: JSON.stringify({ name: projectName, description, private: isPrivate }),
});
Client: start OAuth
const statusRes = await fetch('/api/github/status');
const { connected } = await statusRes.json();
if (!connected) {
window.location.href = `/api/github/authorize?sessionId=${sessionId}`;
}
4. OpenRouter Integration
Where it’s used
- Idea: processIdea
- Intent: refineIntent
- Platform: selectPlatform
- Execute: executeX402Workflow
callOpenRouter
import { callOpenRouter } from '@/lib/openai';
const text = await callOpenRouter('Explain async/await in JavaScript.', 'GROK', {
temperature: 0.7,
systemPrompt: 'You are a concise teacher.',
});
createChatCompletion (internal)
const response = await fetch(process.env.OPENROUTER_BASE_URL, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${modelConfig.apiKey}`,
'HTTP-Referer': process.env.NEXT_PUBLIC_SITE_URL || 'http://localhost:3000',
'X-Title': 'Scriptonia Platform',
},
body: JSON.stringify({
model: modelConfig.model,
messages: [
{ role: 'system', content: '...' },
{ role: 'user', content: '...' },
],
temperature: 0.7,
response_format: { type: 'json_object' },
}),
});
Model and key mapping
| Model | Env key | Model ID (env override) |
|---|
| GROK | OPENROUTER_API_KEY_GROK4 | GROK4_MODEL |
| QWEN | OPENROUTER_API_KEY_QWEN3 | QWEN3_MODEL |
| GEMINI | OPENROUTER_API_KEY_GEMINI2_5 | GEMINI2_5_MODEL |
DEFAULT_MODEL is used by Idea, Intent, Platform; Execution often uses GROK explicitly.