diff --git a/src/components/templates/TemplateDeployer.jsx b/src/components/templates/TemplateDeployer.jsx
index a83cecb..1d15bba 100644
--- a/src/components/templates/TemplateDeployer.jsx
+++ b/src/components/templates/TemplateDeployer.jsx
@@ -1,6 +1,7 @@
import React, { useState } from 'react'
import { buildDeploymentConfig, buildTemplateSource } from '../../lib/templateManager'
import { useStore } from '../../lib/store'
+import { downloadScaffold } from '../../lib/contractDevelopment'
import TemplateCustomizer from './TemplateCustomizer'
export default function TemplateDeployer({ template, onClose }) {
@@ -182,6 +183,50 @@ export default function TemplateDeployer({ template, onClose }) {
)}
+ {template && (
+
+
+ 📥 Quick Downloads
+
+
+
+
+ 📖 Stellar Docs
+
+
+
+)}
)
}
diff --git a/src/components/templates/TemplateLibrary.jsx b/src/components/templates/TemplateLibrary.jsx
index 210597f..832f66d 100644
--- a/src/components/templates/TemplateLibrary.jsx
+++ b/src/components/templates/TemplateLibrary.jsx
@@ -1,16 +1,33 @@
import React, { useState } from 'react'
import { getAllTemplates } from '../../lib/templateManager'
+import { getContractTemplates, downloadScaffold } from '../../lib/contractDevelopment'
import TemplateCard from './TemplateCard'
import TemplateDeployer from './TemplateDeployer'
-const CATEGORIES = ['all', 'token', 'escrow', 'governance', 'nft']
+const CATEGORIES = ['all', 'token', 'escrow', 'governance', 'nft', 'scaffold']
export default function TemplateLibrary() {
const templates = getAllTemplates()
+ const contractTemplates = getContractTemplates()
const [selected, setSelected] = useState(null)
const [filter, setFilter] = useState('all')
+ const [scaffoldDownloaded, setScaffoldDownloaded] = useState(null)
- const filtered = filter === 'all' ? templates : templates.filter((t) => t.category === filter)
+ const filtered = filter === 'all'
+ ? templates
+ : filter === 'scaffold'
+ ? [] // Scaffold section is separate
+ : templates.filter((t) => t.category === filter)
+
+ const handleScaffoldDownload = (templateId) => {
+ try {
+ const bundle = downloadScaffold(templateId)
+ setScaffoldDownloaded(templateId)
+ setTimeout(() => setScaffoldDownloaded(null), 2000)
+ } catch (err) {
+ console.error('Scaffold download failed:', err)
+ }
+ }
return (
@@ -38,20 +55,116 @@ export default function TemplateLibrary() {
{/* Template grid */}
-
- {filtered.map((template) => (
-
- ))}
-
+ {(filter !== 'scaffold') && (
+
+ {filtered.map((template) => (
+
+ ))}
+
+ )}
+
+ {/* Scaffold Section */}
+ {(filter === 'all' || filter === 'scaffold') && (
+
+
+ 📦 Contract Scaffolds
+
+
+ Download starter spec + README for token, escrow, and oracle patterns.
+ Real contracts require a full Rust build with Soroban SDK.
+
+
+ {contractTemplates.map((template) => (
+
+
+ {template.name}
+
+
+ {template.description}
+
+
+ {template.tags.map((tag) => (
+
+ {tag}
+
+ ))}
+
+
+
+ ))}
+
+
+
+ )}
{/* Deployer panel */}
{selected && (
@@ -62,4 +175,4 @@ export default function TemplateLibrary() {
)}
)
-}
+}
\ No newline at end of file
diff --git a/src/lib/contractDevelopment.js b/src/lib/contractDevelopment.js
index 2ad4bbd..c492388 100644
--- a/src/lib/contractDevelopment.js
+++ b/src/lib/contractDevelopment.js
@@ -199,3 +199,133 @@ export function generateDeploymentPlan(config = {}) {
],
}
}
+/**
+ * Generate a deterministic WASM hash placeholder for local dev.
+ * Real builds produce actual hashes; this stub allows UI testing.
+ */
+export function generateWasmHash(templateId) {
+ const base = `stellar-dev-${templateId}-wasm-${Date.now()}`
+ let hash = ''
+ for (let i = 0; i < 64; i++) {
+ hash += Math.floor(Math.random() * 16).toString(16)
+ }
+ return { hash, placeholder: true, generatedAt: new Date().toISOString() }
+}
+
+/**
+ * Export a starter contract specification (JSON) for a given template.
+ * Includes ABI-like method signatures and constructor args.
+ */
+export function exportContractSpec(templateId) {
+ const template = getContractTemplateById(templateId)
+ if (!template) throw new Error('Template not found')
+
+ const methods = template.source
+ .match(/pub fn \w+/g)
+ ?.map((m) => m.replace('pub fn ', '')) || []
+
+ return {
+ specVersion: '0.1.0',
+ contract: {
+ name: template.name,
+ id: templateId,
+ description: template.description,
+ entrypoint: template.entrypoint,
+ },
+ methods: methods.map((name) => ({
+ name,
+ kind: 'function',
+ inputs: [],
+ outputs: [],
+ })),
+ wasmHash: generateWasmHash(templateId),
+ docs: 'https://developers.stellar.org/docs/smart-contracts',
+ }
+}
+
+/**
+ * Build a downloadable README scaffold for a contract template.
+ */
+export function generateContractReadme(templateId) {
+ const template = getContractTemplateById(templateId)
+ if (!template) throw new Error('Template not found')
+
+ return `# ${template.name}
+
+> Generated by Stellar Dev Dashboard — Scaffold Template
+
+## Description
+${template.description}
+
+## Tags
+${template.tags.join(', ')}
+
+## Entrypoint
+\`${template.entrypoint}\`
+
+## Getting Started
+
+### Prerequisites
+- Rust 1.70+
+- Soroban CLI: \`cargo install soroban-cli\`
+- Target: \`rustup target add wasm32-unknown-unknown\`
+
+### Build
+\`\`\`bash
+cargo build --target wasm32-unknown-unknown --release
+\`\`\`
+
+### Deploy
+\`\`\`bash
+soroban contract deploy \\
+ --wasm target/wasm32-unknown-unknown/release/contract.wasm \\
+ --source-account \\
+ --network testnet
+\`\`\`
+
+### Test
+\`\`\`bash
+cargo test
+\`\`\`
+
+## Resources
+- [Stellar Smart Contracts Documentation](https://developers.stellar.org/docs/smart-contracts)
+- [Soroban SDK Reference](https://docs.rs/soroban-sdk)
+- [Stellar Testnet Faucet](https://laboratory.stellar.org/#faucet)
+`
+}
+
+/**
+ * Download a starter scaffold bundle (spec JSON + README + source) for a template.
+ * Triggers a browser download of a zip-like JSON bundle.
+ */
+export function downloadScaffold(templateId) {
+ const spec = exportContractSpec(templateId)
+ const readme = generateContractReadme(templateId)
+ const source = getContractTemplateById(templateId)?.source || ''
+
+ const bundle = {
+ scaffold: templateId,
+ generatedAt: new Date().toISOString(),
+ spec,
+ readme,
+ source,
+ links: {
+ stellarDocs: 'https://developers.stellar.org/docs/smart-contracts',
+ sorobanCli: 'https://docs.rs/soroban-sdk',
+ testnetFaucet: 'https://laboratory.stellar.org/#faucet',
+ },
+ }
+
+ const blob = new Blob([JSON.stringify(bundle, null, 2)], { type: 'application/json' })
+ const url = URL.createObjectURL(blob)
+ const a = document.createElement('a')
+ a.href = url
+ a.download = `${templateId}-scaffold.json`
+ document.body.appendChild(a)
+ a.click()
+ document.body.removeChild(a)
+ URL.revokeObjectURL(url)
+
+ return bundle
+}
\ No newline at end of file