diff --git a/src/app/api/registry/route.ts b/src/app/api/registry/route.ts index 1333354..9d0f821 100644 --- a/src/app/api/registry/route.ts +++ b/src/app/api/registry/route.ts @@ -95,8 +95,98 @@ export async function POST(request: NextRequest) { // Get current timestamp for the meta note const timestamp = new Date().toUTCString(); - // Prepare record data - const recordData = { + // Step 1: Create and publish ApplicationRecord first + console.log('Step 1: Publishing ApplicationRecord...'); + const applicationRecord = { + type: 'ApplicationRecord', + name: appName, + version: '0.0.1', + app_type: 'webapp', + repository: [url], + repository_ref: 'main', // Default reference or commit hash + app_version: '0.0.1' + }; + + // Create fee for transaction directly + const fee = { + amount: [{ denom: 'alnt', amount: '900000' }], + gas: '900000', + }; + + console.log('Application record data:', applicationRecord); + + // Publish the application record + let applicationRecordId; + try { + const appRecordResult = await registryTransactionWithRetry(() => + registry.setRecord( + { + privateKey: config.privateKey, + record: applicationRecord, + bondId: config.bondId, + }, + config.privateKey, + fee + ) + ) as { id?: string }; + + applicationRecordId = appRecordResult.id; + console.log('Application record published with ID:', applicationRecordId); + + if (!applicationRecordId) { + return NextResponse.json({ + status: 'error', + message: 'Failed to publish ApplicationRecord' + }, { status: 500 }); + } + } catch (err) { + console.error('Error publishing ApplicationRecord:', err); + return NextResponse.json({ + status: 'error', + message: err instanceof Error ? err.message : 'Unknown error publishing ApplicationRecord' + }, { status: 500 }); + } + + // Step 2: Set name mappings + console.log('Step 2: Setting name mappings...'); + try { + // Set the main LRN to point to the application record + await registryTransactionWithRetry(() => + registry.setName( + { + cid: applicationRecordId, + lrn + }, + config.privateKey, + fee + ) + ); + console.log(`Set name mapping: ${lrn} -> ${applicationRecordId}`); + + // Set the versioned LRN (with repository_ref) + await registryTransactionWithRetry(() => + registry.setName( + { + cid: applicationRecordId, + lrn: `${lrn}@main` // Using 'main' as default ref + }, + config.privateKey, + fee + ) + ); + console.log(`Set name mapping: ${lrn}@main -> ${applicationRecordId}`); + } catch (err) { + console.error('Error setting name mappings:', err); + return NextResponse.json({ + status: 'error', + message: err instanceof Error ? err.message : 'Unknown error setting name mappings' + }, { status: 500 }); + } + + // Step 3: Create ApplicationDeploymentRequest + console.log('Step 3: Creating ApplicationDeploymentRequest...'); + // Prepare record data for deployment request + const deploymentRequestData = { type: 'ApplicationDeploymentRequest', version: '1.0.0', name: appName, @@ -111,28 +201,16 @@ export async function POST(request: NextRequest) { payment: txHash, }; - // Create fee for transaction directly - const fee = { - amount: [{ denom: 'alnt', amount: '900000' }], - gas: '900000', - }; + console.log('Deployment request data:', deploymentRequestData); - console.log('Using fee:', fee); - - console.log('Publishing record to Laconic Registry...'); - console.log('Record data:', { - ...recordData, - payment: txHash, // Include the txHash in logs - }); - - // Publish the record using the SDK - let result; + // Publish the deployment request + let deploymentRequestId; try { - result = await registryTransactionWithRetry(() => + const deployRequestResult = await registryTransactionWithRetry(() => registry.setRecord( { privateKey: config.privateKey, - record: recordData, + record: deploymentRequestData, bondId: config.bondId, }, config.privateKey, @@ -140,26 +218,30 @@ export async function POST(request: NextRequest) { ) ) as { id?: string }; - console.log('Publishing result:', result); + deploymentRequestId = deployRequestResult.id; + console.log('Deployment request published with ID:', deploymentRequestId); + + if (!deploymentRequestId) { + return NextResponse.json({ + status: 'error', + message: 'Failed to publish ApplicationDeploymentRequest' + }, { status: 500 }); + } } catch (err) { - console.error('Error publishing record:', err); + console.error('Error publishing deployment request:', err); return NextResponse.json({ status: 'error', - message: err instanceof Error ? err.message : 'Unknown error publishing record' + message: err instanceof Error ? err.message : 'Unknown error publishing deployment request' }, { status: 500 }); } - if (result && result.id) { - return NextResponse.json({ - id: result.id, - status: 'success', - }); - } else { - return NextResponse.json({ - status: 'error', - message: 'Failed to create record in Laconic Registry' - }, { status: 500 }); - } + // Return combined results + return NextResponse.json({ + id: deploymentRequestId, + applicationRecordId: applicationRecordId, + status: 'success', + lrn: lrn + }); } catch (error) { console.error('Failed to create application deployment request:', error); return NextResponse.json({ diff --git a/src/app/page.tsx b/src/app/page.tsx index 5b0739d..f331cf3 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -17,6 +17,8 @@ export default function Home() { const [status, setStatus] = useState<'idle' | 'verifying' | 'creating' | 'success' | 'error'>('idle'); const [txHash, setTxHash] = useState(null); const [recordId, setRecordId] = useState(null); + const [appRecordId, setAppRecordId] = useState(null); + const [lrn, setLrn] = useState(null); const [error, setError] = useState(null); const handleConnect = (address: string) => { @@ -50,6 +52,12 @@ export default function Home() { if (result.status === 'success') { setRecordId(result.id); + if (result.applicationRecordId) { + setAppRecordId(result.applicationRecordId); + } + if (result.lrn) { + setLrn(result.lrn); + } setStatus('success'); } else { setStatus('error'); @@ -88,6 +96,8 @@ export default function Home() { status={status} txHash={txHash || undefined} recordId={recordId || undefined} + appRecordId={appRecordId || undefined} + lrn={lrn || undefined} error={error || undefined} /> diff --git a/src/components/StatusDisplay.tsx b/src/components/StatusDisplay.tsx index e65445e..e6e44e6 100644 --- a/src/components/StatusDisplay.tsx +++ b/src/components/StatusDisplay.tsx @@ -4,6 +4,8 @@ interface StatusDisplayProps { status: 'idle' | 'verifying' | 'creating' | 'success' | 'error'; txHash?: string; recordId?: string; + appRecordId?: string; + lrn?: string; error?: string; } @@ -11,6 +13,8 @@ export default function StatusDisplay({ status, txHash, recordId, + appRecordId, + lrn, error, }: StatusDisplayProps) { if (status === 'idle') return null; @@ -50,12 +54,26 @@ export default function StatusDisplay({ )} + {appRecordId && ( +
+

Application Record ID:

+

{appRecordId}

+
+ )} + {recordId && ( -
-

Laconic Registry Record ID:

+
+

Deployment Request Record ID:

{recordId}

)} + + {lrn && ( +
+

Laconic Resource Name (LRN):

+

{lrn}

+
+ )}
)} diff --git a/src/services/registry.ts b/src/services/registry.ts index e0398d8..10e44a1 100644 --- a/src/services/registry.ts +++ b/src/services/registry.ts @@ -23,6 +23,8 @@ export const createApplicationDeploymentRequest = async ( if (response.ok && result.status === 'success') { return { id: result.id, + applicationRecordId: result.applicationRecordId, + lrn: result.lrn, status: 'success', }; } else { diff --git a/src/types/index.ts b/src/types/index.ts index 671f74e..bcceb49 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -42,6 +42,8 @@ export interface LaconicRecordData { export interface CreateRecordResponse { id: string; + applicationRecordId?: string; + lrn?: string; status: 'success' | 'error'; message?: string; } \ No newline at end of file