API: Phoenix railing proxy, API key auth for /api/v1/*, schema export, docs, migrations, tests
- Phoenix API Railing: proxy to PHOENIX_RAILING_URL, tenant me routes - Tenant-auth: X-API-Key support for /api/v1/* (api_keys table) - Migration 026: api_keys table; 025 sovereign stack marketplace - GET /graphql/schema, GET /graphql-playground, api/docs OpenAPI - Integration tests: phoenix-railing.test.ts - docs/api/API_VERSIONING: /api/v1/ railing alignment - docs/phoenix/PORTAL_RAILING_WIRING Made-with: Cursor
This commit is contained in:
112
api/src/services/sovereign-stack/wallet-registry-service.ts
Normal file
112
api/src/services/sovereign-stack/wallet-registry-service.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
* Phoenix Wallet Registry Service
|
||||
* Wallet mapping, chain support, policy engine, and recovery
|
||||
*/
|
||||
|
||||
import { getDb } from '../../db/index.js'
|
||||
import { logger } from '../../lib/logger.js'
|
||||
|
||||
export interface Wallet {
|
||||
walletId: string
|
||||
userId: string
|
||||
orgId: string | null
|
||||
address: string
|
||||
chainId: number
|
||||
custodyType: 'USER' | 'SHARED' | 'PLATFORM'
|
||||
status: 'ACTIVE' | 'SUSPENDED' | 'RECOVERED'
|
||||
}
|
||||
|
||||
export interface TransactionRequest {
|
||||
from: string
|
||||
to: string
|
||||
value: string
|
||||
data?: string
|
||||
chainId: number
|
||||
}
|
||||
|
||||
export interface TransactionSimulation {
|
||||
success: boolean
|
||||
gasEstimate: string
|
||||
error?: string
|
||||
warnings?: string[]
|
||||
}
|
||||
|
||||
class WalletRegistryService {
|
||||
/**
|
||||
* Register a wallet
|
||||
*/
|
||||
async registerWallet(
|
||||
userId: string,
|
||||
address: string,
|
||||
chainId: number,
|
||||
custodyType: 'USER' | 'SHARED' | 'PLATFORM',
|
||||
orgId?: string
|
||||
): Promise<Wallet> {
|
||||
const db = getDb()
|
||||
|
||||
const result = await db.query(
|
||||
`INSERT INTO wallets (user_id, org_id, address, chain_id, custody_type, status)
|
||||
VALUES ($1, $2, $3, $4, $5, 'ACTIVE')
|
||||
RETURNING *`,
|
||||
[userId, orgId || null, address, chainId, custodyType]
|
||||
)
|
||||
|
||||
logger.info('Wallet registered', { walletId: result.rows[0].id, address })
|
||||
return this.mapWallet(result.rows[0])
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a transaction
|
||||
*/
|
||||
async buildTransaction(request: TransactionRequest): Promise<string> {
|
||||
// This would use a transaction builder service with deterministic encoding
|
||||
logger.info('Building transaction', { request })
|
||||
|
||||
// Placeholder - would integrate with actual transaction builder
|
||||
return '0x' // Serialized transaction
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate a transaction
|
||||
*/
|
||||
async simulateTransaction(request: TransactionRequest): Promise<TransactionSimulation> {
|
||||
logger.info('Simulating transaction', { request })
|
||||
|
||||
// Placeholder - would call chain RPC for simulation
|
||||
return {
|
||||
success: true,
|
||||
gasEstimate: '21000',
|
||||
warnings: []
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get wallets for user
|
||||
*/
|
||||
async getWalletsForUser(userId: string, chainId?: number): Promise<Wallet[]> {
|
||||
const db = getDb()
|
||||
|
||||
const query = chainId
|
||||
? `SELECT * FROM wallets WHERE user_id = $1 AND chain_id = $2`
|
||||
: `SELECT * FROM wallets WHERE user_id = $1`
|
||||
|
||||
const params = chainId ? [userId, chainId] : [userId]
|
||||
const result = await db.query(query, params)
|
||||
|
||||
return result.rows.map(this.mapWallet)
|
||||
}
|
||||
|
||||
private mapWallet(row: any): Wallet {
|
||||
return {
|
||||
walletId: row.id,
|
||||
userId: row.user_id,
|
||||
orgId: row.org_id,
|
||||
address: row.address,
|
||||
chainId: row.chain_id,
|
||||
custodyType: row.custody_type,
|
||||
status: row.status
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const walletRegistryService = new WalletRegistryService()
|
||||
Reference in New Issue
Block a user