Skip to content

Commit 4fd77e5

Browse files
committed
Use remote endpoint for compilations
1 parent 4e5c4b2 commit 4fd77e5

File tree

4 files changed

+33
-73
lines changed

4 files changed

+33
-73
lines changed

.env.local

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@ account_passphrase=<passphrase>
33
account_password=<password>
44
NODE_OPTIONS=--max-old-space-size=2048
55
WALLET_CONNECT_PROJECT_ID=<project_id>
6+
NOIR_COMPILER_BASE_URL_DEV=<dev_base_endpoint>
7+
NOIR_COMPILER_BASE_URL_PROD=<prod_base_endpoint>
8+
NOIR_COMPILER_WS_URL_DEV=<dev_websocket_url>
9+
NOIR_COMPILER_WS_URL_PROD=<prod_websocket_url>

apps/noir-compiler/src/app/services/noirPluginClient.ts

Lines changed: 23 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,19 @@
11
import { PluginClient } from '@remixproject/plugin'
22
import { createClient } from '@remixproject/plugin-webview'
33
import EventManager from 'events'
4-
// @ts-ignore
5-
import { compile_program, createFileManager } from '@noir-lang/noir_wasm/default'
6-
import type { FileManager } from '@noir-lang/noir_wasm/dist/node/main'
7-
import pathModule from 'path'
84
import { DEFAULT_TOML_CONFIG } from '../actions/constants'
95
import NoirParser from './noirParser'
106
import { extractNameFromKey } from '@remix-ui/helper'
7+
import axios from 'axios'
118
export class NoirPluginClient extends PluginClient {
129
public internalEvents: EventManager
13-
public fm: FileManager
1410
public parser: NoirParser
1511

1612
constructor() {
1713
super()
1814
this.methods = ['init', 'parse', 'compile']
1915
createClient(this)
2016
this.internalEvents = new EventManager()
21-
this.fm = createFileManager('/')
2217
this.parser = new NoirParser()
2318
this.onload()
2419
}
@@ -37,14 +32,6 @@ export class NoirPluginClient extends PluginClient {
3732

3833
if (!nargoTomlExists) {
3934
await this.call('fileManager', 'writeFile', 'Nargo.toml', DEFAULT_TOML_CONFIG)
40-
const fileBytes = new TextEncoder().encode(DEFAULT_TOML_CONFIG)
41-
42-
await this.fm.writeFile('Nargo.toml', new Blob([fileBytes]).stream())
43-
} else {
44-
const nargoToml = await this.call('fileManager', 'readFile', 'Nargo.toml')
45-
const fileBytes = new TextEncoder().encode(nargoToml)
46-
47-
await this.fm.writeFile('Nargo.toml', new Blob([fileBytes]).stream())
4835
}
4936
}
5037

@@ -55,17 +42,30 @@ export class NoirPluginClient extends PluginClient {
5542
// @ts-ignore
5643
this.call('terminal', 'log', { type: 'log', value: 'Compiling ' + path })
5744
await this.setupNargoToml()
58-
const program = await compile_program(this.fm, null, this.logFn.bind(this), this.debugFn.bind(this))
59-
const filename = extractNameFromKey(path)
60-
const outputPath = `build/${filename.replace('.nr', '.json')}`
61-
62-
this.call('fileManager', 'writeFile', outputPath, JSON.stringify(program, null, 2))
63-
this.internalEvents.emit('noir_compiling_done')
64-
this.emit('statusChanged', { key: 'succeed', title: 'Noir circuit compiled successfully', type: 'success' })
6545
// @ts-ignore
66-
this.call('terminal', 'log', { type: 'log', value: 'Compiled successfully' })
46+
const zippedProject: Blob = await this.call('fileManager', 'download', '/', false)
47+
const formData = new FormData()
48+
49+
formData.append('file', zippedProject, `${extractNameFromKey(path)}.zip`)
6750
// @ts-ignore
68-
await this.call('editor', 'clearErrorMarkers', [path])
51+
const response = await axios.post(`${BASE_URL}/compile`, formData)
52+
53+
if (!response.data || !response.data.success) {
54+
this.internalEvents.emit('noir_compiling_errored', new Error('Compilation failed'))
55+
this.logFn('Compilation failed')
56+
return
57+
} else {
58+
const { compiledJson, proverToml } = response.data
59+
60+
this.call('fileManager', 'writeFile', 'build/program.json', compiledJson)
61+
this.call('fileManager', 'writeFile', 'build/prover.toml', proverToml)
62+
this.internalEvents.emit('noir_compiling_done')
63+
this.emit('statusChanged', { key: 'succeed', title: 'Noir circuit compiled successfully', type: 'success' })
64+
// @ts-ignore
65+
this.debugFn('Compiled successfully')
66+
// @ts-ignore
67+
await this.call('editor', 'clearErrorMarkers', [path])
68+
}
6969
} catch (e) {
7070
const regex = /^\s*(\/[^:]+):(\d+):/gm;
7171
const pathContent = await this.call('fileManager', 'readFile', path)
@@ -109,57 +109,11 @@ export class NoirPluginClient extends PluginClient {
109109
// @ts-ignore
110110
await this.call('editor', 'addErrorMarker', markers)
111111
} else {
112-
await this.resolveDependencies(path, content)
113-
const fileBytes = new TextEncoder().encode(content)
114-
115-
await this.fm.writeFile(`${path}`, new Blob([fileBytes]).stream())
116112
// @ts-ignore
117113
await this.call('editor', 'clearErrorMarkers', [path])
118114
}
119115
}
120116

121-
async resolveDependencies (filePath: string, fileContent: string, parentPath: string = '', visited: Record<string, string[]> = {}): Promise<void> {
122-
const imports = Array.from(fileContent.matchAll(/mod\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*(=\s*["'](.*?)["'])?\s*;/g), match => match[3] || match[1]);
123-
124-
for (let dep of imports) {
125-
if (!dep.endsWith('.nr')) dep += '.nr'
126-
if (visited[filePath] && visited[filePath].includes(parentPath)) return console.log('circular dependency detected')
127-
let dependencyContent = ''
128-
let path = dep.replace(/(\.\.\/)+/g, '')
129-
130-
// @ts-ignore
131-
const pathExists = await this.call('fileManager', 'exists', path)
132-
133-
if (pathExists) {
134-
dependencyContent = await this.call('fileManager', 'readFile', path)
135-
} else {
136-
let relativePath = pathModule.resolve(filePath.slice(0, filePath.lastIndexOf('/')), dep)
137-
138-
if (relativePath.indexOf('/') === 0) relativePath = relativePath.slice(1)
139-
// @ts-ignore
140-
const relativePathExists = await this.call('fileManager', 'exists', relativePath)
141-
142-
if (relativePathExists) {
143-
path = relativePath
144-
dependencyContent = await this.call('fileManager', 'readFile', relativePath)
145-
visited[filePath] = visited[filePath] ? [...visited[filePath], path] : [path]
146-
// extract all mod imports from the dependency content
147-
const depImports = Array.from(fileContent.matchAll(/mod\s+([a-zA-Z_][a-zA-Z0-9_]*)\s*(=\s*["'](.*?)["'])?\s*;/g), match => match[3] || match[1])
148-
149-
if (depImports.length > 0 && dependencyContent.length > 0) {
150-
const fileBytes = new TextEncoder().encode(dependencyContent)
151-
const writePath = parentPath ? `${filePath.replace('.nr', '')}/${dep}` : path
152-
153-
this.fm.writeFile(writePath, new Blob([fileBytes]).stream())
154-
await this.resolveDependencies(path, dependencyContent, filePath, visited)
155-
}
156-
} else {
157-
throw new Error(`Dependency ${dep} not found in Remix file system`)
158-
}
159-
}
160-
}
161-
}
162-
163117
logFn(log) {
164118
this.call('terminal', 'log', { type: 'error', value: log })
165119
}

apps/noir-compiler/webpack.config.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ module.exports = composePlugins(withNx(), (config) => {
5959
config.plugins.push(
6060
new webpack.DefinePlugin({
6161
WALLET_CONNECT_PROJECT_ID: JSON.stringify(process.env.WALLET_CONNECT_PROJECT_ID),
62+
BASE_URL: process.env.NODE_ENV === 'development' ? JSON.stringify(process.env.NOIR_COMPILER_BASE_URL_DEV) : JSON.stringify(process.env.NOIR_COMPILER_BASE_URL_PROD),
63+
WS_URL: process.env.NODE_ENV === 'development' ? JSON.stringify(process.env.NOIR_COMPILER_WS_URL_DEV) : JSON.stringify(process.env.NOIR_COMPILER_WS_URL_PROD)
6264
})
6365
)
6466

apps/remix-ide/src/app/files/fileManager.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const profile = {
2626
'readFile', 'copyFile', 'copyDir', 'rename', 'mkdir', 'readdir', 'dirList', 'fileList', 'remove', 'getCurrentFile', 'getFile',
2727
'getFolder', 'setFile', 'switchFile', 'refresh', 'getProviderOf', 'getProviderByName', 'getPathFromUrl', 'getUrlFromPath',
2828
'saveCurrentFile', 'setBatchFiles', 'isGitRepo', 'isFile', 'isDirectory', 'hasGitSubmodule', 'copyFolderToJson', 'diff',
29-
'hasGitSubmodules', 'getOpenedFiles'
29+
'hasGitSubmodules', 'getOpenedFiles', 'download'
3030
],
3131
kind: 'file-system'
3232
}
@@ -418,18 +418,18 @@ export default class FileManager extends Plugin {
418418
}
419419
}
420420

421-
async download(path) {
421+
async download(path, asZip = true) {
422422
try {
423423
const downloadFileName = helper.extractNameFromKey(path)
424424
if (await this.isDirectory(path)) {
425425
const zip = new JSZip()
426426
await this.zipDir(path, zip)
427427
const content = await zip.generateAsync({ type: 'blob' })
428-
saveAs(content, `${downloadFileName}.zip`)
428+
return asZip ? saveAs(content, `${downloadFileName}.zip`) : content
429429
} else {
430430
path = this.normalize(path)
431431
const content: any = await this.readFile(path)
432-
saveAs(new Blob([content]), downloadFileName)
432+
return asZip ? saveAs(new Blob([content]), downloadFileName) : new Blob([content])
433433
}
434434
} catch (e) {
435435
throw new Error(e)

0 commit comments

Comments
 (0)