- Introduced DexExample.swift demonstrating decentralized exchange operations including spot trading, perpetual futures, liquidity provision, order book management, and portfolio tracking. - Added IbcExample.swift showcasing inter-blockchain communication operations such as cross-chain transfers, channel management, packet handling, and relayer operations. - Created ZkExample.swift illustrating zero-knowledge proof operations including circuit compilation, proof generation and verification, and trusted setup ceremonies.
352 lines
12 KiB
Swift
352 lines
12 KiB
Swift
import Foundation
|
|
import SynorCompiler
|
|
|
|
/// Synor Compiler SDK Examples for Swift
|
|
///
|
|
/// Demonstrates smart contract compilation and analysis:
|
|
/// - WASM contract compilation and optimization
|
|
/// - ABI extraction and encoding
|
|
/// - Contract analysis and security scanning
|
|
/// - Validation and verification
|
|
|
|
@main
|
|
struct CompilerExample {
|
|
static func main() async throws {
|
|
// Initialize client
|
|
let config = CompilerConfig(
|
|
apiKey: ProcessInfo.processInfo.environment["SYNOR_API_KEY"] ?? "your-api-key",
|
|
endpoint: "https://compiler.synor.io/v1",
|
|
timeout: 60,
|
|
retries: 3,
|
|
debug: false,
|
|
defaultOptimizationLevel: .size,
|
|
maxContractSize: 256 * 1024,
|
|
useWasmOpt: true,
|
|
validate: true,
|
|
extractMetadata: true,
|
|
generateAbi: true
|
|
)
|
|
|
|
let compiler = SynorCompiler(config: config)
|
|
|
|
do {
|
|
// Check service health
|
|
let healthy = try await compiler.healthCheck()
|
|
print("Service healthy: \(healthy)\n")
|
|
|
|
// Run examples
|
|
try await compileContractExample(compiler: compiler)
|
|
try await compilationModesExample(compiler: compiler)
|
|
try await abiExample(compiler: compiler)
|
|
try await analysisExample(compiler: compiler)
|
|
try await validationExample(compiler: compiler)
|
|
try await securityExample(compiler: compiler)
|
|
} catch {
|
|
print("Error: \(error)")
|
|
}
|
|
|
|
await compiler.close()
|
|
}
|
|
|
|
/// Create a minimal valid WASM module for testing.
|
|
static func createMinimalWasm() -> Data {
|
|
return Data([
|
|
0x00, 0x61, 0x73, 0x6d, // Magic: \0asm
|
|
0x01, 0x00, 0x00, 0x00, // Version: 1
|
|
// Type section
|
|
0x01, 0x07, 0x01, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f,
|
|
// Function section
|
|
0x03, 0x02, 0x01, 0x00,
|
|
// Export section
|
|
0x07, 0x08, 0x01, 0x04, 0x61, 0x64, 0x64, 0x00, 0x00,
|
|
// Code section
|
|
0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, 0x00, 0x20, 0x01, 0x6a, 0x0b
|
|
])
|
|
}
|
|
|
|
static func compileContractExample(compiler: SynorCompiler) async throws {
|
|
print("=== Contract Compilation ===")
|
|
|
|
let wasm = createMinimalWasm()
|
|
|
|
let result = try await compiler.compile(
|
|
wasm: wasm,
|
|
options: CompileOptions(
|
|
optimizationLevel: .size,
|
|
useWasmOpt: true,
|
|
validate: true,
|
|
extractMetadata: true,
|
|
generateAbi: true,
|
|
stripOptions: StripOptions(
|
|
stripDebug: true,
|
|
stripProducers: true,
|
|
stripNames: true,
|
|
stripCustom: true,
|
|
stripUnused: true,
|
|
preserveSections: []
|
|
)
|
|
)
|
|
)
|
|
|
|
print("Compilation result:")
|
|
print(" Contract ID: \(result.contractId)")
|
|
print(" Code hash: \(result.codeHash)")
|
|
print(" Original size: \(result.originalSize) bytes")
|
|
print(" Optimized size: \(result.optimizedSize) bytes")
|
|
print(" Size reduction: \(String(format: "%.1f", result.sizeReduction))%")
|
|
print(" Estimated deploy gas: \(result.estimatedDeployGas)")
|
|
|
|
if let metadata = result.metadata {
|
|
print("\nMetadata:")
|
|
print(" Name: \(metadata.name)")
|
|
print(" Version: \(metadata.version)")
|
|
print(" SDK Version: \(metadata.sdkVersion)")
|
|
}
|
|
|
|
if let abi = result.abi {
|
|
print("\nABI:")
|
|
print(" Functions: \(abi.functions?.count ?? 0)")
|
|
print(" Events: \(abi.events?.count ?? 0)")
|
|
print(" Errors: \(abi.errors?.count ?? 0)")
|
|
}
|
|
|
|
print()
|
|
}
|
|
|
|
static func compilationModesExample(compiler: SynorCompiler) async throws {
|
|
print("=== Compilation Modes ===")
|
|
|
|
let wasm = createMinimalWasm()
|
|
|
|
// Development mode: fast compilation, debugging support
|
|
print("Development mode:")
|
|
let devResult = try await compiler.contracts.compileDev(wasm: wasm)
|
|
print(" Size: \(devResult.optimizedSize) bytes")
|
|
print(" Optimization: none")
|
|
|
|
// Production mode: maximum optimization
|
|
print("\nProduction mode:")
|
|
let prodResult = try await compiler.contracts.compileProduction(wasm: wasm)
|
|
print(" Size: \(prodResult.optimizedSize) bytes")
|
|
print(" Optimization: aggressive")
|
|
print(" Size savings: \(devResult.optimizedSize - prodResult.optimizedSize) bytes")
|
|
|
|
// Custom optimization levels
|
|
print("\nOptimization levels:")
|
|
let levels: [OptimizationLevel] = [.none, .basic, .size, .aggressive]
|
|
|
|
for level in levels {
|
|
let result = try await compiler.compile(
|
|
wasm: wasm,
|
|
options: CompileOptions(optimizationLevel: level)
|
|
)
|
|
print(" \(level): \(result.optimizedSize) bytes")
|
|
}
|
|
|
|
print()
|
|
}
|
|
|
|
static func abiExample(compiler: SynorCompiler) async throws {
|
|
print("=== ABI Operations ===")
|
|
|
|
let wasm = createMinimalWasm()
|
|
|
|
// Extract ABI from WASM
|
|
let abi = try await compiler.abi.extract(wasm: wasm)
|
|
print("Contract: \(abi.name)")
|
|
print("Version: \(abi.version)")
|
|
|
|
// List functions
|
|
if let functions = abi.functions, !functions.isEmpty {
|
|
print("\nFunctions:")
|
|
for function in functions {
|
|
let inputs = function.inputs?.map { "\($0.name): \($0.type.typeName)" }.joined(separator: ", ") ?? ""
|
|
let outputs = function.outputs?.map { $0.type.typeName }.joined(separator: ", ") ?? "void"
|
|
var modifiers: [String] = []
|
|
if function.view { modifiers.append("view") }
|
|
if function.payable { modifiers.append("payable") }
|
|
|
|
print(" \(function.name)(\(inputs)) -> \(outputs) \(modifiers.joined(separator: " "))")
|
|
print(" Selector: \(function.selector)")
|
|
}
|
|
}
|
|
|
|
// List events
|
|
if let events = abi.events, !events.isEmpty {
|
|
print("\nEvents:")
|
|
for event in events {
|
|
let params = event.params?.map { p in
|
|
"\(p.indexed ? "indexed " : "")\(p.name): \(p.type.typeName)"
|
|
}.joined(separator: ", ") ?? ""
|
|
print(" \(event.name)(\(params))")
|
|
print(" Topic: \(event.topic)")
|
|
}
|
|
}
|
|
|
|
// Encode a function call
|
|
if let function = abi.functions?.first {
|
|
let encoded = try await compiler.abi.encodeCall(function: function, args: ["arg1", "arg2"])
|
|
print("\nEncoded call to \(function.name): \(encoded)")
|
|
|
|
// Decode a result
|
|
let decoded = try await compiler.abi.decodeResult(function: function, data: encoded)
|
|
print("Decoded result: \(decoded)")
|
|
}
|
|
|
|
print()
|
|
}
|
|
|
|
static func analysisExample(compiler: SynorCompiler) async throws {
|
|
print("=== Contract Analysis ===")
|
|
|
|
let wasm = createMinimalWasm()
|
|
|
|
// Full analysis
|
|
let analysis = try await compiler.analysis.analyze(wasm: wasm)
|
|
|
|
// Size breakdown
|
|
if let size = analysis.sizeBreakdown {
|
|
print("Size breakdown:")
|
|
print(" Code: \(size.code) bytes")
|
|
print(" Data: \(size.data) bytes")
|
|
print(" Functions: \(size.functions) bytes")
|
|
print(" Memory: \(size.memory) bytes")
|
|
print(" Exports: \(size.exports) bytes")
|
|
print(" Imports: \(size.imports) bytes")
|
|
print(" Total: \(size.total) bytes")
|
|
}
|
|
|
|
// Function analysis
|
|
if let functions = analysis.functions, !functions.isEmpty {
|
|
print("\nFunction analysis:")
|
|
for function in functions.prefix(5) {
|
|
print(" \(function.name):")
|
|
print(" Size: \(function.size) bytes")
|
|
print(" Instructions: \(function.instructionCount)")
|
|
print(" Locals: \(function.localCount)")
|
|
print(" Exported: \(function.exported)")
|
|
print(" Estimated gas: \(function.estimatedGas)")
|
|
}
|
|
}
|
|
|
|
// Import analysis
|
|
if let imports = analysis.imports, !imports.isEmpty {
|
|
print("\nImports:")
|
|
for imp in imports {
|
|
print(" \(imp.module).\(imp.name) (\(imp.kind))")
|
|
}
|
|
}
|
|
|
|
// Gas analysis
|
|
if let gas = analysis.gasAnalysis {
|
|
print("\nGas analysis:")
|
|
print(" Deployment: \(gas.deploymentGas)")
|
|
print(" Memory init: \(gas.memoryInitGas)")
|
|
print(" Data section: \(gas.dataSectionGas)")
|
|
}
|
|
|
|
// Extract metadata
|
|
let metadata = try await compiler.analysis.extractMetadata(wasm: wasm)
|
|
print("\nContract metadata:")
|
|
print(" Name: \(metadata.name)")
|
|
print(" Version: \(metadata.version)")
|
|
print(" Build timestamp: \(metadata.buildTimestamp)")
|
|
|
|
// Estimate deployment gas
|
|
let gasEstimate = try await compiler.analysis.estimateDeployGas(wasm: wasm)
|
|
print("\nEstimated deployment gas: \(gasEstimate)")
|
|
|
|
print()
|
|
}
|
|
|
|
static func validationExample(compiler: SynorCompiler) async throws {
|
|
print("=== Contract Validation ===")
|
|
|
|
let wasm = createMinimalWasm()
|
|
|
|
// Full validation
|
|
let result = try await compiler.validation.validate(wasm: wasm)
|
|
print("Valid: \(result.valid)")
|
|
print("Exports: \(result.exportCount)")
|
|
print("Imports: \(result.importCount)")
|
|
print("Functions: \(result.functionCount)")
|
|
print("Memory pages: \(result.memoryPages)")
|
|
|
|
if let errors = result.errors, !errors.isEmpty {
|
|
print("\nValidation errors:")
|
|
for error in errors {
|
|
print(" [\(error.code)] \(error.message)")
|
|
if let location = error.location {
|
|
print(" at \(location)")
|
|
}
|
|
}
|
|
}
|
|
|
|
if let warnings = result.warnings, !warnings.isEmpty {
|
|
print("\nWarnings:")
|
|
for warning in warnings {
|
|
print(" \(warning)")
|
|
}
|
|
}
|
|
|
|
// Quick validation
|
|
let isValid = try await compiler.validation.isValid(wasm: wasm)
|
|
print("\nQuick validation: \(isValid)")
|
|
|
|
// Get validation errors only
|
|
let errors = try await compiler.validation.getErrors(wasm: wasm)
|
|
print("Error count: \(errors.count)")
|
|
|
|
// Validate required exports
|
|
let hasRequired = try await compiler.validation.validateExports(
|
|
wasm: wasm,
|
|
required: ["init", "execute", "query"]
|
|
)
|
|
print("Has required exports: \(hasRequired)")
|
|
|
|
// Validate memory constraints
|
|
let memoryValid = try await compiler.validation.validateMemory(wasm: wasm, maxPages: 16)
|
|
print("Memory within 16 pages: \(memoryValid)")
|
|
|
|
print()
|
|
}
|
|
|
|
static func securityExample(compiler: SynorCompiler) async throws {
|
|
print("=== Security Scanning ===")
|
|
|
|
let wasm = createMinimalWasm()
|
|
|
|
let security = try await compiler.analysis.securityScan(wasm: wasm)
|
|
|
|
print("Security score: \(security.score)/100")
|
|
|
|
if let issues = security.issues, !issues.isEmpty {
|
|
print("\nSecurity issues:")
|
|
let severityIcons: [String: String] = [
|
|
"critical": "[CRIT]",
|
|
"high": "[HIGH]",
|
|
"medium": "[MED]",
|
|
"low": "[LOW]"
|
|
]
|
|
for issue in issues {
|
|
let icon = severityIcons[issue.severity.lowercased()] ?? "[???]"
|
|
print("\(icon) [\(issue.severity.uppercased())] \(issue.type)")
|
|
print(" \(issue.description)")
|
|
if let location = issue.location {
|
|
print(" at \(location)")
|
|
}
|
|
}
|
|
} else {
|
|
print("No security issues found!")
|
|
}
|
|
|
|
if let recommendations = security.recommendations, !recommendations.isEmpty {
|
|
print("\nRecommendations:")
|
|
for rec in recommendations {
|
|
print(" • \(rec)")
|
|
}
|
|
}
|
|
|
|
print()
|
|
}
|
|
}
|