diff --git a/apps/circuit-compiler/src/app/actions/index.ts b/apps/circuit-compiler/src/app/actions/index.ts
index 30c7342b6d3..db39692597d 100644
--- a/apps/circuit-compiler/src/app/actions/index.ts
+++ b/apps/circuit-compiler/src/app/actions/index.ts
@@ -33,7 +33,7 @@ export const computeWitness = async (plugin: CircomPluginClient, appState: AppSt
const writePath = extractParentFromKey(appState.filePath) + `/.bin/${fileName.replace('.circom', '_js')}/${fileName.replace('.circom', '.wtn.json')}`
await plugin.call('fileManager', 'writeFile', writePath, JSON.stringify(wtnsJson, null, 2))
- trackMatomoEvent(plugin, { category: 'circuitCompiler', action: 'computeWitness', name: 'wtns.exportJson', value: writePath, isClick: true })
+ trackMatomoEvent(plugin, { category: 'circuit-compiler', action: 'compiler.generate_witness', name: 'wtns.exportJson', value: writePath, isClick: true })
}
} else {
console.log('Existing witness computation in progress')
@@ -62,38 +62,38 @@ export const runSetupAndExport = async (plugin: CircomPluginClient, appState: Ap
const zkey_final = { type: "mem" }
if (appState.provingScheme === 'groth16') {
- trackMatomoEvent(plugin, { category: 'circuitCompiler', action: 'runSetupAndExport', name: 'provingScheme', value: 'groth16', isClick: true })
+ trackMatomoEvent(plugin, { category: 'circuit-compiler', action: 'runSetupAndExport', name: 'provingScheme', value: 'groth16', isClick: true })
await snarkjs.zKey.newZKey(r1cs, ptau_final, zkey_final, zkLogger(plugin, dispatch, 'SET_SETUP_EXPORT_FEEDBACK'))
const vKey = await snarkjs.zKey.exportVerificationKey(zkey_final, zkLogger(plugin, dispatch, 'SET_SETUP_EXPORT_FEEDBACK'))
if (appState.exportVerificationKey) {
await plugin.call('fileManager', 'writeFile', `${extractParentFromKey(appState.filePath)}/groth16/zk/keys/verification_key.json`, JSON.stringify(vKey, null, 2))
- trackMatomoEvent(plugin, { category: 'circuitCompiler', action: 'runSetupAndExport', name: 'zKey.exportVerificationKey', value: `${extractParentFromKey(appState.filePath)}/groth16/zk/keys/verification_key.json`, isClick: true })
+ trackMatomoEvent(plugin, { category: 'circuit-compiler', action: 'runSetupAndExport', name: 'zKey.exportVerificationKey', value: `${extractParentFromKey(appState.filePath)}/groth16/zk/keys/verification_key.json`, isClick: true })
}
if (appState.exportVerificationContract) {
const templates = { groth16: GROTH16_VERIFIER }
const solidityContract = await snarkjs.zKey.exportSolidityVerifier(zkey_final, templates, zkLogger(plugin, dispatch, 'SET_SETUP_EXPORT_FEEDBACK'))
await plugin.call('fileManager', 'writeFile', `${extractParentFromKey(appState.filePath)}/groth16/zk/build/zk_verifier.sol`, solidityContract)
- trackMatomoEvent(plugin, { category: 'circuitCompiler', action: 'runSetupAndExport', name: 'zKey.exportSolidityVerifier', value: `${extractParentFromKey(appState.filePath)}/groth16/zk/build/zk_verifier.sol`, isClick: true })
+ trackMatomoEvent(plugin, { category: 'circuit-compiler', action: 'runSetupAndExport', name: 'zKey.exportSolidityVerifier', value: `${extractParentFromKey(appState.filePath)}/groth16/zk/build/zk_verifier.sol`, isClick: true })
}
dispatch({ type: 'SET_ZKEY', payload: zkey_final })
dispatch({ type: 'SET_VERIFICATION_KEY', payload: vKey })
} else if (appState.provingScheme === 'plonk') {
- trackMatomoEvent(plugin, { category: 'circuitCompiler', action: 'runSetupAndExport', name: 'provingScheme', value: 'plonk', isClick: true })
+ trackMatomoEvent(plugin, { category: 'circuit-compiler', action: 'runSetupAndExport', name: 'provingScheme', value: 'plonk', isClick: true })
await snarkjs.plonk.setup(r1cs, ptau_final, zkey_final, zkLogger(plugin, dispatch, 'SET_SETUP_EXPORT_FEEDBACK'))
const vKey = await snarkjs.zKey.exportVerificationKey(zkey_final, zkLogger(plugin, dispatch, 'SET_SETUP_EXPORT_FEEDBACK'))
if (appState.exportVerificationKey) {
await plugin.call('fileManager', 'writeFile', `${extractParentFromKey(appState.filePath)}/plonk/zk/keys/verification_key.json`, JSON.stringify(vKey, null, 2))
- trackMatomoEvent(plugin, { category: 'circuitCompiler', action: 'runSetupAndExport', name: 'zKey.exportVerificationKey', value: `${extractParentFromKey(appState.filePath)}/plonk/zk/keys/verification_key.json`, isClick: true })
+ trackMatomoEvent(plugin, { category: 'circuit-compiler', action: 'runSetupAndExport', name: 'zKey.exportVerificationKey', value: `${extractParentFromKey(appState.filePath)}/plonk/zk/keys/verification_key.json`, isClick: true })
}
if (appState.exportVerificationContract) {
const templates = { plonk: PLONK_VERIFIER }
const solidityContract = await snarkjs.zKey.exportSolidityVerifier(zkey_final, templates, zkLogger(plugin, dispatch, 'SET_SETUP_EXPORT_FEEDBACK'))
await plugin.call('fileManager', 'writeFile', `${extractParentFromKey(appState.filePath)}/plonk/zk/build/zk_verifier.sol`, solidityContract)
- trackMatomoEvent(plugin, { category: 'circuitCompiler', action: 'runSetupAndExport', name: 'zKey.exportSolidityVerifier', value: `${extractParentFromKey(appState.filePath)}/plonk/zk/build/zk_verifier.sol`, isClick: true })
+ trackMatomoEvent(plugin, { category: 'circuit-compiler', action: 'runSetupAndExport', name: 'zKey.exportSolidityVerifier', value: `${extractParentFromKey(appState.filePath)}/plonk/zk/build/zk_verifier.sol`, isClick: true })
}
dispatch({ type: 'SET_ZKEY', payload: zkey_final })
dispatch({ type: 'SET_VERIFICATION_KEY', payload: vKey })
@@ -101,7 +101,7 @@ export const runSetupAndExport = async (plugin: CircomPluginClient, appState: Ap
dispatch({ type: 'SET_COMPILER_STATUS', payload: 'idle' })
dispatch({ type: 'SET_SETUP_EXPORT_STATUS', payload: 'done' })
} catch (e) {
- trackMatomoEvent(plugin, { category: 'circuitCompiler', action: 'runSetupAndExport', name: 'error', value: e.message, isClick: true })
+ trackMatomoEvent(plugin, { category: 'circuit-compiler', action: 'runSetupAndExport', name: 'error', value: e.message, isClick: true })
dispatch({ type: 'SET_COMPILER_STATUS', payload: 'errored' })
console.error(e)
}
@@ -133,12 +133,12 @@ export const generateProof = async (plugin: CircomPluginClient, appState: AppSta
plugin.call('fileManager', 'writeFile', `${extractParentFromKey(appState.filePath)}/groth16/zk/build/proof.json`, JSON.stringify(proof, null, 2))
plugin.call('terminal', 'log', { type: 'log', value: 'zk proof validity ' + verified })
- trackMatomoEvent(plugin, { category: 'circuitCompiler', action: 'generateProof', name: 'groth16.prove', value: verified, isClick: true })
+ trackMatomoEvent(plugin, { category: 'circuit-compiler', action: 'generateProof', name: 'groth16.prove', value: verified, isClick: true })
if (appState.exportVerifierCalldata) {
const calldata = await snarkjs.groth16.exportSolidityCallData(proof, publicSignals)
plugin.call('fileManager', 'writeFile', `${extractParentFromKey(appState.filePath)}/groth16/zk/build/verifierCalldata.json`, calldata)
- trackMatomoEvent(plugin, { category: 'circuitCompiler', action: 'generateProof', name: 'groth16.exportSolidityCallData', value: `${extractParentFromKey(appState.filePath)}/groth16/zk/build/verifierCalldata.json`, isClick: true })
+ trackMatomoEvent(plugin, { category: 'circuit-compiler', action: 'generateProof', name: 'groth16.exportSolidityCallData', value: `${extractParentFromKey(appState.filePath)}/groth16/zk/build/verifierCalldata.json`, isClick: true })
}
} else if (appState.provingScheme === 'plonk') {
const { proof, publicSignals } = await snarkjs.plonk.prove(zkey_final, wtns, zkLogger(plugin, dispatch, 'SET_PROOF_FEEDBACK'))
@@ -146,12 +146,12 @@ export const generateProof = async (plugin: CircomPluginClient, appState: AppSta
plugin.call('fileManager', 'writeFile', `${extractParentFromKey(appState.filePath)}/plonk/zk/build/proof.json`, JSON.stringify(proof, null, 2))
plugin.call('terminal', 'log', { type: 'log', value: 'zk proof validity ' + verified })
- trackMatomoEvent(plugin, { category: 'circuitCompiler', action: 'generateProof', name: 'plonk.prove', value: verified, isClick: true })
+ trackMatomoEvent(plugin, { category: 'circuit-compiler', action: 'generateProof', name: 'plonk.prove', value: verified, isClick: true })
if (appState.exportVerifierCalldata) {
const calldata = await snarkjs.plonk.exportSolidityCallData(proof, publicSignals)
plugin.call('fileManager', 'writeFile', `${extractParentFromKey(appState.filePath)}/plonk/zk/build/verifierCalldata.json`, calldata)
- trackMatomoEvent(plugin, { category: 'circuitCompiler', action: 'generateProof', name: 'plonk.exportSolidityCallData', value: `${extractParentFromKey(appState.filePath)}/plonk/zk/build/verifierCalldata.json`, isClick: true })
+ trackMatomoEvent(plugin, { category: 'circuit-compiler', action: 'generateProof', name: 'plonk.exportSolidityCallData', value: `${extractParentFromKey(appState.filePath)}/plonk/zk/build/verifierCalldata.json`, isClick: true })
}
}
dispatch({ type: 'SET_COMPILER_STATUS', payload: 'idle' })
diff --git a/apps/circuit-compiler/src/app/services/circomPluginClient.ts b/apps/circuit-compiler/src/app/services/circomPluginClient.ts
index 256871f78c1..4aa95499709 100644
--- a/apps/circuit-compiler/src/app/services/circomPluginClient.ts
+++ b/apps/circuit-compiler/src/app/services/circomPluginClient.ts
@@ -171,7 +171,7 @@ export class CircomPluginClient extends PluginClient {
const circuitErrors = circuitApi.report()
this.logCompilerReport(circuitErrors)
- trackMatomoEvent(this, { category: 'circuitCompiler', action: 'compile', name: 'Compilation failed', isClick: true })
+ trackMatomoEvent(this, { category: 'circuit-compiler', action: 'compile', name: 'Compilation failed', isClick: true })
throw new Error(circuitErrors)
} else {
this.lastCompiledFile = path
@@ -200,7 +200,7 @@ export class CircomPluginClient extends PluginClient {
this.internalEvents.emit('circuit_parsing_done', parseErrors, filePathToId)
this.emit('statusChanged', { key: 'succeed', title: 'circuit compiled successfully', type: 'success' })
}
- trackMatomoEvent(this, { category: 'circuitCompiler', action: 'compile', name: 'Compilation successful', isClick: true })
+ trackMatomoEvent(this, { category: 'circuit-compiler', action: 'compile', name: 'Compilation successful', isClick: true })
circuitApi.log().map(log => {
log && this.call('terminal', 'log', { type: 'log', value: log })
})
@@ -282,7 +282,7 @@ export class CircomPluginClient extends PluginClient {
const r1csErrors = r1csApi.report()
this.logCompilerReport(r1csErrors)
- trackMatomoEvent(this, { category: 'circuitCompiler', action: 'generateR1cs', name: 'R1CS Generation failed', isClick: true })
+ trackMatomoEvent(this, { category: 'circuit-compiler', action: 'generateR1cs', name: 'R1CS Generation failed', isClick: true })
throw new Error(r1csErrors)
} else {
const fileName = extractNameFromKey(path)
@@ -290,7 +290,7 @@ export class CircomPluginClient extends PluginClient {
// @ts-ignore
await this.call('fileManager', 'writeFile', writePath, r1csProgram, true)
- trackMatomoEvent(this, { category: 'circuitCompiler', action: 'generateR1cs', name: 'R1CS Generation successful', isClick: true })
+ trackMatomoEvent(this, { category: 'circuit-compiler', action: 'generateR1cs', name: 'R1CS Generation successful', isClick: true })
r1csApi.log().map(log => {
log && this.call('terminal', 'log', { type: 'log', value: log })
})
@@ -338,7 +338,7 @@ export class CircomPluginClient extends PluginClient {
const witness = this.compiler ? await this.compiler.generate_witness(dataRead, input) : await generate_witness(dataRead, input)
// @ts-ignore
await this.call('fileManager', 'writeFile', wasmPath.replace('.wasm', '.wtn'), witness, { encoding: null })
- trackMatomoEvent(this, { category: 'circuitCompiler', action: 'computeWitness', name: wasmPath.replace('.wasm', '.wtn'), isClick: true })
+ trackMatomoEvent(this, { category: 'circuit-compiler', action: 'compiler.generate_witness', name: wasmPath.replace('.wasm', '.wtn'), isClick: true })
this.internalEvents.emit('circuit_computing_witness_done')
this.emit('statusChanged', { key: 'succeed', title: 'witness computed successfully', type: 'success' })
return witness
diff --git a/apps/learneth/src/redux/models/remixide.ts b/apps/learneth/src/redux/models/remixide.ts
index b538ff33435..4736996065e 100644
--- a/apps/learneth/src/redux/models/remixide.ts
+++ b/apps/learneth/src/redux/models/remixide.ts
@@ -69,7 +69,7 @@ const Model: ModelType = {
return
}
- trackMatomoEvent(remixClient, { category: 'learneth', action: 'displayFile', name: `${(step && step.name)}/${path}`, isClick: true })
+ trackMatomoEvent(remixClient, { category: 'learneth', action: 'display_file', name: `${(step && step.name)}/${path}`, isClick: true })
toast.info(`loading ${path} into IDE`)
yield put({
@@ -96,7 +96,7 @@ const Model: ModelType = {
})
toast.dismiss()
} catch (error) {
- trackMatomoEvent(remixClient, { category: 'learneth', action: 'displayFileError', name: error.message, isClick: false })
+ trackMatomoEvent(remixClient, { category: 'learneth', action: 'display_file_error', name: error.message, isClick: false })
toast.dismiss()
toast.error('File could not be loaded. Please try again.')
yield put({
@@ -146,7 +146,7 @@ const Model: ModelType = {
type: 'remixide/save',
payload: { errors: ['Compiler failed to test this file']},
});
- trackMatomoEvent(remixClient, { category: 'learneth', action: 'testStepError', name: 'Compiler failed to test this file', isClick: false })
+ trackMatomoEvent(remixClient, { category: 'learneth', action: 'test_step_error', name: 'Compiler failed to test this file', isClick: false })
} else {
const success = result.totalFailing === 0;
if (success) {
@@ -162,14 +162,14 @@ const Model: ModelType = {
},
})
}
- trackMatomoEvent(remixClient, { category: 'learneth', action: 'testStep', name: String(success), isClick: true })
+ trackMatomoEvent(remixClient, { category: 'learneth', action: 'test_step', name: String(success), isClick: true })
}
} catch (err) {
yield put({
type: 'remixide/save',
payload: { errors: [String(err)]},
});
- trackMatomoEvent(remixClient, { category: 'learneth', action: 'testStepError', name: String(err), isClick: false })
+ trackMatomoEvent(remixClient, { category: 'learneth', action: 'test_step_error', name: String(err), isClick: false })
}
yield put({
type: 'loading/save',
@@ -199,13 +199,13 @@ const Model: ModelType = {
yield remixClient.call('fileManager', 'setFile', path, content)
yield remixClient.call('fileManager', 'switchFile', `${path}`);
- trackMatomoEvent(remixClient, { category: 'learneth', action: 'showAnswer', name: path, isClick: true })
+ trackMatomoEvent(remixClient, { category: 'learneth', action: 'show_answer', name: path, isClick: true })
} catch (err) {
yield put({
type: 'remixide/save',
payload: { errors: [String(err)]},
});
- trackMatomoEvent(remixClient, { category: 'learneth', action: 'showAnswerError', name: err.message, isClick: false })
+ trackMatomoEvent(remixClient, { category: 'learneth', action: 'show_answer_error', name: err.message, isClick: false })
}
toast.dismiss()
@@ -219,7 +219,7 @@ const Model: ModelType = {
*testSolidityCompiler(_, { put, select }) {
try {
yield remixClient.call('solidity', 'getCompilationResult');
- trackMatomoEvent(remixClient, { category: 'learneth', action: 'testSolidityCompiler', isClick: true })
+ trackMatomoEvent(remixClient, { category: 'learneth', action: 'test_solidity_compiler', isClick: true })
} catch (err) {
const errors = yield select((state) => state.remixide.errors)
yield put({
@@ -228,7 +228,7 @@ const Model: ModelType = {
errors: [...errors, "The `Solidity Compiler` is not yet activated.
Please activate it using the `SOLIDITY` button in the `Featured Plugins` section of the homepage.
"],
},
});
- trackMatomoEvent(remixClient, { category: 'learneth', action: 'testSolidityCompilerError', name: err.message, isClick: false })
+ trackMatomoEvent(remixClient, { category: 'learneth', action: 'test_solidity_compiler_error', name: err.message, isClick: false })
}
}
},
diff --git a/apps/remix-ide/src/app.ts b/apps/remix-ide/src/app.ts
index 07505624656..d66f03aa334 100644
--- a/apps/remix-ide/src/app.ts
+++ b/apps/remix-ide/src/app.ts
@@ -685,7 +685,7 @@ class AppComponent {
if (callDetails.length > 1) {
this.appManager.call('notification', 'toast', `initiating ${callDetails[0]} and calling "${callDetails[1]}" ...`)
// @todo(remove the timeout when activatePlugin is on 0.3.0)
- this.track({ category: 'App', action: 'queryParamsCalls', name: this.params.call, isClick: false })
+ this.track({ category: 'App', action: 'queryParams-calls', name: this.params.call, isClick: false })
//@ts-ignore
await this.appManager.call(...callDetails).catch(console.error)
}
@@ -696,7 +696,7 @@ class AppComponent {
// call all functions in the list, one after the other
for (const call of calls) {
- this.track({ category: 'App', action: 'queryParamsCalls', name: call, isClick: false })
+ this.track({ category: 'App', action: 'queryParams-calls', name: call, isClick: false })
const callDetails = call.split('//')
if (callDetails.length > 1) {
this.appManager.call('notification', 'toast', `initiating ${callDetails[0]} and calling "${callDetails[1]}" ...`)
diff --git a/apps/remix-ide/src/app/components/preload.tsx b/apps/remix-ide/src/app/components/preload.tsx
index bd2db8cff8e..3b430413f86 100644
--- a/apps/remix-ide/src/app/components/preload.tsx
+++ b/apps/remix-ide/src/app/components/preload.tsx
@@ -69,7 +69,7 @@ export const Preload = (props: PreloadProps) => {
setShowDownloader(false)
const fsUtility = new fileSystemUtility()
const migrationResult = await fsUtility.migrate(localStorageFileSystem.current, remixIndexedDB.current)
- trackMatomoEvent?.({ category: 'migrate', action: 'result', name: migrationResult ? 'success' : 'fail', isClick: false })
+ trackMatomoEvent?.({ category: 'Migrate', action: 'result', name: migrationResult ? 'success' : 'fail', isClick: false })
await setFileSystems()
}
diff --git a/apps/remix-ide/src/app/files/filesystems/fileSystemUtility.ts b/apps/remix-ide/src/app/files/filesystems/fileSystemUtility.ts
index b3d8fd9e196..71186d7fb36 100644
--- a/apps/remix-ide/src/app/files/filesystems/fileSystemUtility.ts
+++ b/apps/remix-ide/src/app/files/filesystems/fileSystemUtility.ts
@@ -39,14 +39,14 @@ export class fileSystemUtility {
console.log('file migration successful')
return true
} else {
- track({ category: 'migrate', action: 'error', name: 'hash mismatch', isClick: false })
+ track({ category: 'Migrate', action: 'error', name: 'hash mismatch', isClick: false })
console.log('file migration failed falling back to ' + fsFrom.name)
fsTo.loaded = false
return false
}
} catch (err) {
console.log(err)
- track({ category: 'migrate', action: 'error', name: err && err.message, isClick: false })
+ track({ category: 'Migrate', action: 'error', name: err && err.message, isClick: false })
console.log('file migration failed falling back to ' + fsFrom.name)
fsTo.loaded = false
return false
diff --git a/apps/remix-ide/src/app/plugins/remix-ai-assistant.tsx b/apps/remix-ide/src/app/plugins/remix-ai-assistant.tsx
index 7f4d7bb11aa..23e57a8e4aa 100644
--- a/apps/remix-ide/src/app/plugins/remix-ai-assistant.tsx
+++ b/apps/remix-ide/src/app/plugins/remix-ai-assistant.tsx
@@ -102,8 +102,9 @@ export class RemixAIAssistant extends ViewPlugin {
}
async handleActivity(type: string, payload: any) {
- // Use the proper type-safe tracking helper with RemixAI events
- trackMatomoEvent(this, { category: 'ai', action: 'remixAI', name: `${type}-${payload}`, isClick: true })
+ // Never log user prompts - only track the activity type
+ const eventName = type === 'promptSend' ? 'remixai-assistant-promptSend' : `remixai-assistant-${type}-${payload}`;
+ trackMatomoEvent(this, { category: 'ai', action: 'remixAI', name: eventName as any, isClick: true })
}
updateComponent(state: {
diff --git a/apps/remix-ide/src/app/plugins/solidity-script.tsx b/apps/remix-ide/src/app/plugins/solidity-script.tsx
index 93fae6dbe92..d73bd925f62 100644
--- a/apps/remix-ide/src/app/plugins/solidity-script.tsx
+++ b/apps/remix-ide/src/app/plugins/solidity-script.tsx
@@ -18,7 +18,7 @@ export class SolidityScript extends Plugin {
}
async execute(path: string, functionName: string = 'run') {
- trackMatomoEvent(this, { category: 'solidityScript', action: 'execute', name: 'script', isClick: true })
+ trackMatomoEvent(this, { category: 'SolidityScript', action: 'execute', name: 'script', isClick: true })
this.call('terminal', 'log', `Running free function '${functionName}' from ${path}...`)
let content = await this.call('fileManager', 'readFile', path)
const params = await this.call('solidity', 'getCompilerQueryParameters')
diff --git a/apps/remix-ide/src/app/plugins/solidity-umlgen.tsx b/apps/remix-ide/src/app/plugins/solidity-umlgen.tsx
index 81d69676235..3bc11403a0a 100644
--- a/apps/remix-ide/src/app/plugins/solidity-umlgen.tsx
+++ b/apps/remix-ide/src/app/plugins/solidity-umlgen.tsx
@@ -88,7 +88,7 @@ export class SolidityUmlGen extends ViewPlugin implements ISolidityUmlGen {
})
const payload = vizRenderStringSync(umlDot)
this.updatedSvg = payload
- trackMatomoEvent(this, { category: 'solidityUMLGen', action: 'umlgenerated', isClick: false })
+ trackMatomoEvent(this, { category: 'solidityumlgen', action: 'umlgenerated', isClick: false })
this.renderComponent()
await this.call('tabs', 'focus', 'solidityumlgen')
} catch (error) {
@@ -125,7 +125,7 @@ export class SolidityUmlGen extends ViewPlugin implements ISolidityUmlGen {
generateCustomAction = async (action: customAction) => {
this.triggerGenerateUml = true
this.updatedSvg = this.updatedSvg.startsWith(' {
this.opts = {}
- trackMatomoEvent(this, { category: 'templateSelection', action: 'addToCurrentWorkspace', name: item.value, isClick: true })
+ trackMatomoEvent(this, { category: 'template-selection', action: 'addToCurrentWorkspace', name: item.value, isClick: true })
if (templateGroup.hasOptions) {
const modal: AppModal = {
id: 'TemplatesSelection',
diff --git a/apps/remix-ide/src/app/tabs/compile-and-run.ts b/apps/remix-ide/src/app/tabs/compile-and-run.ts
index 46256db8da9..35bb68a335b 100644
--- a/apps/remix-ide/src/app/tabs/compile-and-run.ts
+++ b/apps/remix-ide/src/app/tabs/compile-and-run.ts
@@ -29,11 +29,11 @@ export class CompileAndRun extends Plugin {
e.preventDefault()
this.targetFileName = file
await this.call('solidity', 'compile', file)
- trackMatomoEvent(this, { category: 'scriptExecutor', action: 'compileAndRun', name: 'compile_solidity', isClick: true })
+ trackMatomoEvent(this, { category: 'ScriptExecutor', action: 'CompileAndRun', name: 'compile_solidity', isClick: true })
} else if (file.endsWith('.js') || file.endsWith('.ts')) {
e.preventDefault()
this.runScript(file, false)
- trackMatomoEvent(this, { category: 'scriptExecutor', action: 'compileAndRun', name: 'run_script', isClick: true })
+ trackMatomoEvent(this, { category: 'ScriptExecutor', action: 'CompileAndRun', name: 'run_script', isClick: true })
}
}
}
@@ -42,7 +42,7 @@ export class CompileAndRun extends Plugin {
runScriptAfterCompilation (fileName: string) {
this.targetFileName = fileName
- trackMatomoEvent(this, { category: 'scriptExecutor', action: 'compileAndRun', name: 'request_run_script', isClick: true })
+ trackMatomoEvent(this, { category: 'ScriptExecutor', action: 'CompileAndRun', name: 'request_run_script', isClick: true })
}
async runScript (fileName, clearAllInstances) {
@@ -73,7 +73,7 @@ export class CompileAndRun extends Plugin {
const file = contract.object.devdoc['custom:dev-run-script']
if (file) {
this.runScript(file, true)
- trackMatomoEvent(this, { category: 'scriptExecutor', action: 'compileAndRun', name: 'run_script_after_compile', isClick: true })
+ trackMatomoEvent(this, { category: 'ScriptExecutor', action: 'CompileAndRun', name: 'run_script_after_compile', isClick: true })
} else {
this.call('notification', 'toast', 'You have not set a script to run. Set it with @custom:dev-run-script NatSpec tag.')
}
diff --git a/apps/remix-ide/src/assets/list.json b/apps/remix-ide/src/assets/list.json
index 1e99f780891..e136bac177b 100644
--- a/apps/remix-ide/src/assets/list.json
+++ b/apps/remix-ide/src/assets/list.json
@@ -1066,6 +1066,18 @@
"urls": [
"dweb:/ipfs/QmXFsguaaxZj2FZmf2pGLTPDDkDD8nHX4grC4jDVugnMxv"
]
+ },
+ {
+ "path": "soljson-v0.8.31-pre.1+commit.b59566f6.js",
+ "version": "0.8.31",
+ "prerelease": "pre.1",
+ "build": "commit.b59566f6",
+ "longVersion": "0.8.31-pre.1+commit.b59566f6",
+ "keccak256": "0x5cbab72123ec1f65e72592375e568788d88c96ffd90a1a3e9107fcd5a3b9cf87",
+ "sha256": "0xaf2b74e3c674c09ce89189edfaa81a0d01f1a0dce9100968e0d442de8a93b926",
+ "urls": [
+ "dweb:/ipfs/QmafWKo2uVeEPMi1GbY2DVPreWtbA6aqXjynnn4wViA6a4"
+ ]
}
],
"releases": {
diff --git a/libs/remix-api/src/lib/plugins/matomo/core/categories.ts b/libs/remix-api/src/lib/plugins/matomo/core/categories.ts
index f66573fd2b9..910556a7510 100644
--- a/libs/remix-api/src/lib/plugins/matomo/core/categories.ts
+++ b/libs/remix-api/src/lib/plugins/matomo/core/categories.ts
@@ -28,7 +28,8 @@ export const MatomoCategories = {
SOLIDITY_SCRIPT: 'SolidityScript' as const,
SCRIPT_EXECUTOR: 'ScriptExecutor' as const,
LOCALE_MODULE: 'localeModule' as const,
- THEME_MODULE: 'themeModule' as const
+ THEME_MODULE: 'themeModule' as const,
+ STATUS_BAR: 'statusBar' as const
}
// Common action constants used across multiple categories
diff --git a/libs/remix-api/src/lib/plugins/matomo/events/ai-events.ts b/libs/remix-api/src/lib/plugins/matomo/events/ai-events.ts
index 8606baaf034..110209a2bad 100644
--- a/libs/remix-api/src/lib/plugins/matomo/events/ai-events.ts
+++ b/libs/remix-api/src/lib/plugins/matomo/events/ai-events.ts
@@ -3,23 +3,47 @@
*
* This file contains all AI-related Matomo events including RemixAI interactions,
* Ollama local AI, and code completion features.
+ *
+ * STANDARDIZED PATTERN:
+ * - category: 'ai' (always)
+ * - action: 'remixAI' (always)
+ * - name: specific event identifier (type-safe)
*/
import { MatomoEventBase } from '../core/base-types';
export interface AIEvent extends MatomoEventBase {
category: 'ai';
- action:
- | 'remixAI'
- | 'error_explaining_SolidityError'
- | 'vulnerability_check_pasted_code'
- | 'generateDocumentation'
- | 'explainFunction'
+ action: 'remixAI';
+ name:
+ // Code completion & generation
| 'Copilot_Completion_Accepted'
| 'code_generation'
| 'code_insertion'
| 'code_completion'
+ | 'code_generation_did_show'
+ | 'code_insertion_did_show'
+ | 'code_completion_did_show'
+ | 'code_generation_partial_accept'
+ | 'code_insertion_partial_accept'
+ | 'code_completion_partial_accept'
+ | 'vulnerability_check_pasted_code'
+ | 'generateDocumentation'
+ | 'explainFunction'
+ | 'error_explaining_SolidityError'
+ // AI Context
| 'AddingAIContext'
+ // RemixAI workspace & chat
+ | 'GenerateNewAIWorkspace'
+ | 'WorkspaceAgentEdit'
+ | 'remixAI_chat'
+ | 'GenerateNewAIWorkspaceFromEditMode'
+ | 'GenerateNewAIWorkspaceFromModal'
+ // AI Provider selection
+ | 'SetAIProvider'
+ | 'SetOllamaModel'
+ | 'ModeSwitch'
+ // Ollama host discovery
| 'ollama_host_cache_hit'
| 'ollama_port_check'
| 'ollama_host_discovered_success'
@@ -27,47 +51,54 @@ export interface AIEvent extends MatomoEventBase {
| 'ollama_host_discovery_failed'
| 'ollama_availability_check'
| 'ollama_availability_result'
+ | 'ollama_reset_host'
+ // Ollama models
| 'ollama_list_models_start'
| 'ollama_list_models_failed'
- | 'ollama_reset_host'
| 'ollama_pull_model_start'
| 'ollama_pull_model_failed'
| 'ollama_pull_model_success'
| 'ollama_pull_model_error'
| 'ollama_get_best'
| 'ollama_get_best_model_error'
- | 'ollama_initialize_failed'
- | 'ollama_host_discovered'
| 'ollama_models_found'
| 'ollama_model_auto_selected'
+ | 'ollama_model_selected'
+ | 'ollama_model_set_backend_success'
+ | 'ollama_model_set_backend_failed'
+ | 'ollama_default_model_selected'
+ // Ollama initialization
+ | 'ollama_initialize_failed'
+ | 'ollama_host_discovered'
| 'ollama_initialize_success'
| 'ollama_model_selection_error'
+ // Ollama code operations
| 'ollama_fim_native'
| 'ollama_fim_token_based'
| 'ollama_completion_no_fim'
| 'ollama_suffix_overlap_removed'
| 'ollama_code_completion_complete'
| 'ollama_code_insertion'
+ | 'ollama_code_generation'
| 'ollama_generate_contract'
| 'ollama_generate_workspace'
| 'ollama_chat_answer'
| 'ollama_code_explaining'
| 'ollama_error_explaining'
| 'ollama_vulnerability_check'
+ // Ollama provider
| 'ollama_provider_selected'
| 'ollama_fallback_to_provider'
- | 'ollama_default_model_selected'
| 'ollama_unavailable'
| 'ollama_connection_error'
- | 'ollama_model_selected'
- | 'ollama_model_set_backend_success'
- | 'ollama_model_set_backend_failed';
+ // Assistant feedback (kebab-case to match original)
+ | 'like-response'
+ | 'dislike-response';
}
-
-
/**
- * RemixAI Events - Specific to RemixAI interactions
+ * @deprecated Use AIEvent with category: 'ai', action: 'remixAI' instead
+ * This interface is kept for backward compatibility during migration
*/
export interface RemixAIEvent extends MatomoEventBase {
category: 'remixAI';
@@ -79,15 +110,14 @@ export interface RemixAIEvent extends MatomoEventBase {
| 'GenerateNewAIWorkspaceFromModal';
}
-
-
/**
- * RemixAI Assistant Events - Specific to assistant interactions
+ * @deprecated Use AIEvent with name: 'like-response' | 'dislike-response' instead
+ * This interface is kept for backward compatibility during migration
*/
export interface RemixAIAssistantEvent extends MatomoEventBase {
- category: 'remixAIAssistant';
+ category: 'remixai-assistant';
action:
- | 'likeResponse'
- | 'dislikeResponse';
+ | 'like-response'
+ | 'dislike-response';
}
diff --git a/libs/remix-api/src/lib/plugins/matomo/events/file-events.ts b/libs/remix-api/src/lib/plugins/matomo/events/file-events.ts
index 2c8436240ae..0035c0fdaa1 100644
--- a/libs/remix-api/src/lib/plugins/matomo/events/file-events.ts
+++ b/libs/remix-api/src/lib/plugins/matomo/events/file-events.ts
@@ -21,7 +21,7 @@ export interface FileExplorerEvent extends MatomoEventBase {
}
export interface WorkspaceEvent extends MatomoEventBase {
- category: 'Workspace';
+ category: 'workspace';
action:
| 'switchWorkspace'
| 'template'
diff --git a/libs/remix-api/src/lib/plugins/matomo/events/plugin-events.ts b/libs/remix-api/src/lib/plugins/matomo/events/plugin-events.ts
index 4dcece9970a..00c47344a19 100644
--- a/libs/remix-api/src/lib/plugins/matomo/events/plugin-events.ts
+++ b/libs/remix-api/src/lib/plugins/matomo/events/plugin-events.ts
@@ -49,11 +49,11 @@ export interface AppEvent extends MatomoEventBase {
| 'loaded'
| 'error'
| 'PreloadError'
- | 'queryParamsCalls';
+ | 'queryParams-calls';
}
export interface MigrateEvent extends MatomoEventBase {
- category: 'migrate';
+ category: 'Migrate';
action:
| 'start'
| 'complete'
diff --git a/libs/remix-api/src/lib/plugins/matomo/events/tools-events.ts b/libs/remix-api/src/lib/plugins/matomo/events/tools-events.ts
index c884d70cee6..f5eea9bb9ee 100644
--- a/libs/remix-api/src/lib/plugins/matomo/events/tools-events.ts
+++ b/libs/remix-api/src/lib/plugins/matomo/events/tools-events.ts
@@ -70,7 +70,7 @@ export interface XTERMEvent extends MatomoEventBase {
}
export interface SolidityScriptEvent extends MatomoEventBase {
- category: 'solidityScript';
+ category: 'SolidityScript';
action:
| 'execute'
| 'deploy'
@@ -90,7 +90,7 @@ export interface RemixGuideEvent extends MatomoEventBase {
}
export interface TemplateSelectionEvent extends MatomoEventBase {
- category: 'templateSelection';
+ category: 'template-selection';
action:
| 'selectTemplate'
| 'createWorkspace'
@@ -99,13 +99,13 @@ export interface TemplateSelectionEvent extends MatomoEventBase {
}
export interface ScriptExecutorEvent extends MatomoEventBase {
- category: 'scriptExecutor';
+ category: 'ScriptExecutor';
action:
| 'execute'
| 'deploy'
| 'run'
| 'compile'
- | 'compileAndRun';
+ | 'CompileAndRun';
}
@@ -154,7 +154,7 @@ export interface ScriptExecutorEvent extends MatomoEventBase {
* Solidity UML Generation Events - Type-safe builders
*/
export interface SolidityUMLGenEvent extends MatomoEventBase {
- category: 'solidityUMLGen';
+ category: 'solidityumlgen';
action:
| 'umlpngdownload'
| 'umlpdfdownload'
@@ -171,17 +171,30 @@ export interface SolidityUMLGenEvent extends MatomoEventBase {
* Circuit Compiler Events - Type-safe builders
*/
export interface CircuitCompilerEvent extends MatomoEventBase {
- category: 'circuitCompiler';
+ category: 'circuit-compiler';
action:
| 'compile'
| 'generateProof'
| 'error'
| 'generateR1cs'
- | 'computeWitness'
+ | 'compiler.generate_witness'
+ | 'template'
| 'runSetupAndExport';
}
+/**
+ * Noir Compiler Events - Type-safe builders
+ */
+export interface NoirCompilerEvent extends MatomoEventBase {
+ category: 'noir-compiler';
+ action:
+ | 'compile'
+ | 'template'
+ | 'error';
+}
+
+
/**
* Contract Verification Events - Type-safe builders
*/
@@ -204,14 +217,14 @@ export interface LearnethEvent extends MatomoEventBase {
| 'lesson'
| 'tutorial'
| 'error'
- | 'displayFile'
- | 'displayFileError'
- | 'testStep'
- | 'testStepError'
- | 'showAnswer'
- | 'showAnswerError'
- | 'testSolidityCompiler'
- | 'testSolidityCompilerError'
+ | 'display_file'
+ | 'display_file_error'
+ | 'test_step'
+ | 'test_step_error'
+ | 'show_answer'
+ | 'show_answer_error'
+ | 'test_solidity_compiler'
+ | 'test_solidity_compiler_error'
| 'start_workshop'
| 'select_repo'
| 'import_repo'
diff --git a/libs/remix-api/src/lib/plugins/matomo/events/ui-events.ts b/libs/remix-api/src/lib/plugins/matomo/events/ui-events.ts
index 62997813cd6..17913944a7f 100644
--- a/libs/remix-api/src/lib/plugins/matomo/events/ui-events.ts
+++ b/libs/remix-api/src/lib/plugins/matomo/events/ui-events.ts
@@ -66,6 +66,27 @@ export interface LandingPageEvent extends MatomoEventBase {
| 'MatomoAIModal';
}
+export interface StatusBarEvent extends MatomoEventBase {
+ category: 'statusBar';
+ action:
+ | 'initNewRepo';
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/libs/remix-api/src/lib/plugins/matomo/index.ts b/libs/remix-api/src/lib/plugins/matomo/index.ts
index 31a790a2d08..c05afd48a51 100644
--- a/libs/remix-api/src/lib/plugins/matomo/index.ts
+++ b/libs/remix-api/src/lib/plugins/matomo/index.ts
@@ -30,11 +30,11 @@ export * from './events/tools-events';
import type { AIEvent, RemixAIEvent, RemixAIAssistantEvent } from './events/ai-events';
import type { CompilerEvent, SolidityCompilerEvent, CompilerContainerEvent } from './events/compiler-events';
import type { GitEvent } from './events/git-events';
-import type { HomeTabEvent, TopbarEvent, LayoutEvent, SettingsEvent, ThemeEvent, LocaleEvent, LandingPageEvent } from './events/ui-events';
+import type { HomeTabEvent, TopbarEvent, LayoutEvent, SettingsEvent, ThemeEvent, LocaleEvent, LandingPageEvent, StatusBarEvent } from './events/ui-events';
import type { FileExplorerEvent, WorkspaceEvent, StorageEvent, BackupEvent } from './events/file-events';
import type { BlockchainEvent, UdappEvent, RunEvent } from './events/blockchain-events';
import type { PluginEvent, ManagerEvent, PluginManagerEvent, AppEvent, MatomoManagerEvent, PluginPanelEvent, MigrateEvent } from './events/plugin-events';
-import type { DebuggerEvent, EditorEvent, SolidityUnitTestingEvent, SolidityStaticAnalyzerEvent, DesktopDownloadEvent, XTERMEvent, SolidityScriptEvent, RemixGuideEvent, TemplateSelectionEvent, ScriptExecutorEvent, GridViewEvent, SolidityUMLGenEvent, ScriptRunnerPluginEvent, CircuitCompilerEvent, ContractVerificationEvent, LearnethEvent } from './events/tools-events';
+import type { DebuggerEvent, EditorEvent, SolidityUnitTestingEvent, SolidityStaticAnalyzerEvent, DesktopDownloadEvent, XTERMEvent, SolidityScriptEvent, RemixGuideEvent, TemplateSelectionEvent, ScriptExecutorEvent, GridViewEvent, SolidityUMLGenEvent, ScriptRunnerPluginEvent, CircuitCompilerEvent, NoirCompilerEvent, ContractVerificationEvent, LearnethEvent } from './events/tools-events';
// Union type of all Matomo events - includes base properties for compatibility
export type MatomoEvent = (
@@ -59,6 +59,7 @@ export type MatomoEvent = (
| ThemeEvent
| LocaleEvent
| LandingPageEvent
+ | StatusBarEvent
// File Management events
| FileExplorerEvent
@@ -95,6 +96,7 @@ export type MatomoEvent = (
| SolidityUMLGenEvent
| ScriptRunnerPluginEvent
| CircuitCompilerEvent
+ | NoirCompilerEvent
| ContractVerificationEvent
| LearnethEvent
diff --git a/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts b/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts
index 87ecba34f35..927463a6768 100644
--- a/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts
+++ b/libs/remix-ui/editor/src/lib/providers/inlineCompletionProvider.ts
@@ -202,7 +202,7 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli
})
const data = await this.props.plugin.call('remixAI', 'code_insertion', word, word_after)
- this.trackMatomoEvent?.({ category: 'ai', action: 'code_generation', isClick: false })
+ this.trackMatomoEvent?.({ category: 'ai', action: 'remixAI', name: 'code_generation', isClick: false })
this.task = 'code_generation'
const parsedData = data.trimStart()
@@ -228,7 +228,7 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli
try {
CompletionParams.stop = ['\n\n', '```']
const output = await this.props.plugin.call('remixAI', 'code_insertion', word, word_after, CompletionParams)
- this.trackMatomoEvent?.({ category: 'ai', action: 'code_insertion', isClick: false })
+ this.trackMatomoEvent?.({ category: 'ai', action: 'remixAI', name: 'code_insertion', isClick: false })
const generatedText = output
this.task = 'code_insertion'
@@ -259,7 +259,7 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli
CompletionParams.stop = ['\n', '```']
this.task = 'code_completion'
const output = await this.props.plugin.call('remixAI', 'code_completion', word, word_after, CompletionParams)
- this.trackMatomoEvent?.({ category: 'ai', action: 'code_completion', isClick: false })
+ this.trackMatomoEvent?.({ category: 'ai', action: 'remixAI', name: 'code_completion', isClick: false })
const generatedText = output
let clean = generatedText
@@ -307,7 +307,7 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli
this.currentCompletion.task = this.task
this.rateLimiter.trackCompletionShown()
- this.trackMatomoEvent?.({ category: 'ai', action: 'remixAI', name: this.task + '_did_show', isClick: true })
+ this.trackMatomoEvent?.({ category: 'ai', action: 'remixAI', name: `${this.task}_did_show` as any, isClick: true })
}
handlePartialAccept?(
@@ -319,7 +319,7 @@ export class RemixInLineCompletionProvider implements monacoTypes.languages.Inli
this.currentCompletion.task = this.task
this.rateLimiter.trackCompletionAccepted()
- this.trackMatomoEvent?.({ category: 'ai', action: 'remixAI', name: this.task + '_partial_accept', isClick: true })
+ this.trackMatomoEvent?.({ category: 'ai', action: 'remixAI', name: `${this.task}_partial_accept` as any, isClick: true })
}
freeInlineCompletions(
diff --git a/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx b/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx
index 1751ee8cfb3..cd80fcab4aa 100644
--- a/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx
+++ b/libs/remix-ui/editor/src/lib/remix-ui-editor.tsx
@@ -794,7 +794,7 @@ export const EditorUI = (props: EditorUIProps) => {
setTimeout(async () => {
props.plugin.call('remixAI', 'chatPipe', 'vulnerability_check', pastedCodePrompt)
}, 500)
- trackMatomoEvent({ category: 'ai', action: 'vulnerability_check_pasted_code', isClick: true })
+ trackMatomoEvent({ category: 'ai', action: 'remixAI', name: 'vulnerability_check_pasted_code', isClick: true })
})();
}
};
@@ -862,7 +862,7 @@ export const EditorUI = (props: EditorUIProps) => {
if (changes.some(change => change.text === inlineCompletionProvider.currentCompletion.item.insertText)) {
inlineCompletionProvider.currentCompletion.onAccepted()
inlineCompletionProvider.currentCompletion.accepted = true
- trackMatomoEvent({ category: 'ai', action: 'Copilot_Completion_Accepted', isClick: true })
+ trackMatomoEvent({ category: 'ai', action: 'remixAI', name: 'Copilot_Completion_Accepted', isClick: true })
}
}
});
@@ -998,7 +998,7 @@ export const EditorUI = (props: EditorUIProps) => {
}, 150)
}
}
- trackMatomoEvent({ category: 'ai', action: 'generateDocumentation', isClick: true })
+ trackMatomoEvent({ category: 'ai', action: 'remixAI', name: 'generateDocumentation', isClick: true })
},
}
}
@@ -1017,7 +1017,7 @@ export const EditorUI = (props: EditorUIProps) => {
setTimeout(async () => {
await props.plugin.call('remixAI' as any, 'chatPipe', 'code_explaining', message, context)
}, 500)
- trackMatomoEvent({ category: 'ai', action: 'explainFunction', isClick: true })
+ trackMatomoEvent({ category: 'ai', action: 'remixAI', name: 'explainFunction', isClick: true })
},
}
@@ -1041,7 +1041,7 @@ export const EditorUI = (props: EditorUIProps) => {
setTimeout(async () => {
await props.plugin.call('remixAI' as any, 'chatPipe', 'code_explaining', selectedCode, content, pipeMessage)
}, 500)
- trackMatomoEvent({ category: 'ai', action: 'explainFunction', isClick: true })
+ trackMatomoEvent({ category: 'ai', action: 'remixAI', name: 'explainFunction', isClick: true })
},
}
diff --git a/libs/remix-ui/home-tab/src/lib/components/homeTabTitle.tsx b/libs/remix-ui/home-tab/src/lib/components/homeTabTitle.tsx
index bd41ebf5ef7..2c6770c858e 100644
--- a/libs/remix-ui/home-tab/src/lib/components/homeTabTitle.tsx
+++ b/libs/remix-ui/home-tab/src/lib/components/homeTabTitle.tsx
@@ -119,7 +119,7 @@ function HomeTabTitle() {
trackMatomoEvent({
category: 'hometab',
action: 'titleCard',
- name: button.matomoTrackingEntry[3],
+ name: button.matomoTrackingEntry[index],
isClick: true
})
}}
diff --git a/libs/remix-ui/remix-ai-assistant/src/components/prompt.tsx b/libs/remix-ui/remix-ai-assistant/src/components/prompt.tsx
index 608dbed0f48..53a640edc4a 100644
--- a/libs/remix-ui/remix-ai-assistant/src/components/prompt.tsx
+++ b/libs/remix-ui/remix-ai-assistant/src/components/prompt.tsx
@@ -129,7 +129,7 @@ export const PromptArea: React.FC = ({
className={`btn btn-sm ${aiMode === 'ask' ? 'btn-primary' : 'btn-outline-secondary'} px-2`}
onClick={() => {
setAiMode('ask')
- trackMatomoEvent({ category: 'remixAI', action: 'ModeSwitch', name: 'ask', isClick: true })
+ trackMatomoEvent({ category: 'ai', action: 'remixAI', name: 'ModeSwitch', value: 'ask', isClick: true })
}}
title="Ask mode - Chat with AI"
>
@@ -140,7 +140,7 @@ export const PromptArea: React.FC = ({
className={`btn btn-sm ${aiMode === 'edit' ? 'btn-primary' : 'btn-outline-secondary'} px-2`}
onClick={() => {
setAiMode('edit')
- trackMatomoEvent({ category: 'remixAI', action: 'ModeSwitch', name: 'edit', isClick: true })
+ trackMatomoEvent({ category: 'ai', action: 'remixAI', name: 'ModeSwitch', value: 'edit', isClick: true })
}}
title="Edit mode - Edit workspace code"
>
diff --git a/libs/remix-ui/remix-ai-assistant/src/components/remix-ui-remix-ai-assistant.tsx b/libs/remix-ui/remix-ai-assistant/src/components/remix-ui-remix-ai-assistant.tsx
index 71e37d7cc52..c90de548599 100644
--- a/libs/remix-ui/remix-ai-assistant/src/components/remix-ui-remix-ai-assistant.tsx
+++ b/libs/remix-ui/remix-ai-assistant/src/components/remix-ui-remix-ai-assistant.tsx
@@ -158,7 +158,7 @@ export const RemixUiRemixAiAssistant = React.forwardRef<
break
case 'current':
{
- trackMatomoEvent({ category: 'ai', action: 'AddingAIContext', name: choice, isClick: true })
+ trackMatomoEvent({ category: 'ai', action: 'remixAI', name: 'AddingAIContext', value: choice, isClick: true })
const f = await props.plugin.call('fileManager', 'getCurrentFile')
if (f) files = [f]
await props.plugin.call('remixAI', 'setContextFiles', { context: 'currentFile' })
@@ -166,7 +166,7 @@ export const RemixUiRemixAiAssistant = React.forwardRef<
break
case 'opened':
{
- trackMatomoEvent({ category: 'ai', action: 'AddingAIContext', name: choice, isClick: true })
+ trackMatomoEvent({ category: 'ai', action: 'remixAI', name: 'AddingAIContext', value: choice, isClick: true })
const res = await props.plugin.call('fileManager', 'getOpenedFiles')
if (Array.isArray(res)) {
files = res
@@ -178,7 +178,7 @@ export const RemixUiRemixAiAssistant = React.forwardRef<
break
case 'workspace':
{
- trackMatomoEvent({ category: 'ai', action: 'AddingAIContext', name: choice, isClick: true })
+ trackMatomoEvent({ category: 'ai', action: 'remixAI', name: 'AddingAIContext', value: choice, isClick: true })
await props.plugin.call('remixAI', 'setContextFiles', { context: 'workspace' })
files = ['@workspace']
}
@@ -251,9 +251,9 @@ export const RemixUiRemixAiAssistant = React.forwardRef<
prev.map(m => (m.id === msgId ? { ...m, sentiment: next } : m))
)
if (next === 'like') {
- trackMatomoEvent({ category: 'remixAIAssistant', action: 'likeResponse', isClick: true })
+ trackMatomoEvent({ category: 'ai', action: 'remixAI', name: 'like-response', isClick: true })
} else if (next === 'dislike') {
- trackMatomoEvent({ category: 'remixAIAssistant', action: 'dislikeResponse', isClick: true })
+ trackMatomoEvent({ category: 'ai', action: 'remixAI', name: 'dislike-response', isClick: true })
}
}
@@ -435,7 +435,7 @@ export const RemixUiRemixAiAssistant = React.forwardRef<
dispatchActivity('button', 'generateWorkspace')
if (prompt && prompt.trim()) {
await sendPrompt(`/workspace ${prompt.trim()}`)
- trackMatomoEvent({ category: 'remixAI', action: 'GenerateNewAIWorkspaceFromEditMode', name: prompt, isClick: true })
+ trackMatomoEvent({ category: 'ai', action: 'remixAI', name: 'GenerateNewAIWorkspaceFromEditMode', value: prompt, isClick: true })
}
}, [sendPrompt])
@@ -472,14 +472,14 @@ export const RemixUiRemixAiAssistant = React.forwardRef<
dispatchActivity('button', 'setAssistant')
setMessages([])
sendPrompt(`/setAssistant ${assistantChoice}`)
- trackMatomoEvent({ category: 'remixAI', action: 'SetAIProvider', name: assistantChoice, isClick: true })
+ trackMatomoEvent({ category: 'ai', action: 'remixAI', name: 'SetAIProvider', value: assistantChoice, isClick: true })
// Log specific Ollama selection
if (assistantChoice === 'ollama') {
- trackMatomoEvent({ category: 'ai', action: 'ollama_provider_selected', name: `from:${choiceSetting || 'unknown'}`, isClick: false })
+ trackMatomoEvent({ category: 'ai', action: 'remixAI', name: 'ollama_provider_selected', value: `from:${choiceSetting || 'unknown'}`, isClick: false })
}
} else {
// This is a fallback, just update the backend silently
- trackMatomoEvent({ category: 'ai', action: 'ollama_fallback_to_provider', name: `${assistantChoice}|from:${choiceSetting}`, isClick: false })
+ trackMatomoEvent({ category: 'ai', action: 'remixAI', name: 'ollama_fallback_to_provider', value: `${assistantChoice}|from:${choiceSetting}`, isClick: false })
await props.plugin.call('remixAI', 'setAssistantProvider', assistantChoice)
}
setAssistantChoice(assistantChoice || 'mistralai')
@@ -515,7 +515,7 @@ export const RemixUiRemixAiAssistant = React.forwardRef<
if (!selectedModel && models.length > 0) {
const defaultModel = models.find(m => m.includes('codestral')) || models[0]
setSelectedModel(defaultModel)
- trackMatomoEvent({ category: 'ai', action: 'ollama_default_model_selected', name: `${defaultModel}|codestral|total:${models.length}`, isClick: false })
+ trackMatomoEvent({ category: 'ai', action: 'remixAI', name: 'ollama_default_model_selected', value: `${defaultModel}|codestral|total:${models.length}`, isClick: false })
// Sync the default model with the backend
try {
await props.plugin.call('remixAI', 'setModel', defaultModel)
@@ -542,7 +542,7 @@ export const RemixUiRemixAiAssistant = React.forwardRef<
sentiment: 'none'
}])
// Log Ollama unavailable event
- trackMatomoEvent({ category: 'ai', action: 'ollama_unavailable', name: 'switching_to_mistralai', isClick: false })
+ trackMatomoEvent({ category: 'ai', action: 'remixAI', name: 'ollama_unavailable', value: 'switching_to_mistralai', isClick: false })
// Set failure flag before switching back to prevent success message
setIsOllamaFailureFallback(true)
// Automatically switch back to mistralai
@@ -559,7 +559,7 @@ export const RemixUiRemixAiAssistant = React.forwardRef<
sentiment: 'none'
}])
// Log Ollama connection error
- trackMatomoEvent({ category: 'ai', action: 'ollama_connection_error', name: `${error.message || 'unknown'}|switching_to_mistralai`, isClick: false })
+ trackMatomoEvent({ category: 'ai', action: 'remixAI', name: 'ollama_connection_error', value: `${error.message || 'unknown'}|switching_to_mistralai`, isClick: false })
// Set failure flag before switching back to prevent success message
setIsOllamaFailureFallback(true)
// Switch back to mistralai on error
@@ -582,16 +582,16 @@ export const RemixUiRemixAiAssistant = React.forwardRef<
const previousModel = selectedModel
setSelectedModel(modelName)
setShowModelOptions(false)
- trackMatomoEvent({ category: 'ai', action: 'ollama_model_selected', name: `${modelName}|from:${previousModel || 'none'}`, isClick: true })
+ trackMatomoEvent({ category: 'ai', action: 'remixAI', name: 'ollama_model_selected', value: `${modelName}|from:${previousModel || 'none'}`, isClick: true })
// Update the model in the backend
try {
await props.plugin.call('remixAI', 'setModel', modelName)
- trackMatomoEvent({ category: 'ai', action: 'ollama_model_set_backend_success', name: modelName, isClick: false })
+ trackMatomoEvent({ category: 'ai', action: 'remixAI', name: 'ollama_model_set_backend_success', value: modelName, isClick: false })
} catch (error) {
console.warn('Failed to set model:', error)
- trackMatomoEvent({ category: 'ai', action: 'ollama_model_set_backend_failed', name: `${modelName}|${error.message || 'unknown'}`, isClick: false })
+ trackMatomoEvent({ category: 'ai', action: 'remixAI', name: 'ollama_model_set_backend_failed', value: `${modelName}|${error.message || 'unknown'}`, isClick: false })
}
- trackMatomoEvent({ category: 'remixAI', action: 'SetOllamaModel', name: modelName, isClick: true })
+ trackMatomoEvent({ category: 'ai', action: 'remixAI', name: 'SetOllamaModel', value: modelName, isClick: true })
}, [props.plugin, selectedModel])
// refresh context whenever selection changes (even if selector is closed)
@@ -640,7 +640,7 @@ export const RemixUiRemixAiAssistant = React.forwardRef<
if (description && description.trim()) {
sendPrompt(`/generate ${description.trim()}`)
- trackMatomoEvent({ category: 'remixAI', action: 'GenerateNewAIWorkspaceFromModal', name: description, isClick: true })
+ trackMatomoEvent({ category: 'ai', action: 'remixAI', name: 'GenerateNewAIWorkspaceFromModal', value: description, isClick: true })
}
} catch {
/* user cancelled */
diff --git a/libs/remix-ui/renderer/src/lib/renderer.tsx b/libs/remix-ui/renderer/src/lib/renderer.tsx
index 23451de3749..5a5889064cf 100644
--- a/libs/remix-ui/renderer/src/lib/renderer.tsx
+++ b/libs/remix-ui/renderer/src/lib/renderer.tsx
@@ -102,7 +102,7 @@ export const Renderer = ({ message, opt, plugin, context }: RendererProps) => {
setTimeout(async () => {
await plugin.call('remixAI' as any, 'chatPipe', 'error_explaining', message)
}, 500)
- trackMatomoEvent?.({ category: 'ai', action: 'error_explaining_SolidityError' })
+ trackMatomoEvent?.({ category: 'ai', action: 'remixAI', name: 'error_explaining_SolidityError', isClick: true })
} catch (err) {
console.error('unable to ask RemixAI')
console.error(err)
diff --git a/libs/remix-ui/solidity-uml-gen/src/lib/components/UmlDownload.tsx b/libs/remix-ui/solidity-uml-gen/src/lib/components/UmlDownload.tsx
index d3c990b369a..a0d5cb5afd1 100644
--- a/libs/remix-ui/solidity-uml-gen/src/lib/components/UmlDownload.tsx
+++ b/libs/remix-ui/solidity-uml-gen/src/lib/components/UmlDownload.tsx
@@ -81,7 +81,7 @@ export default function UmlDownload(props: UmlDownloadProps) {
{
- trackMatomoEvent({ category: 'solidityUMLGen', action: 'umlpngdownload', name: 'downloadAsPng', isClick: true })
+ trackMatomoEvent({ category: 'solidityumlgen', action: 'umlpngdownload', name: 'downloadAsPng', isClick: true })
props.download('png')
}}
data-id="umlPngDownload"
@@ -103,7 +103,7 @@ export default function UmlDownload(props: UmlDownloadProps) {
{
- trackMatomoEvent({ category: 'solidityUMLGen', action: 'umlpdfdownload', name: 'downloadAsPdf', isClick: true })
+ trackMatomoEvent({ category: 'solidityumlgen', action: 'umlpdfdownload', name: 'downloadAsPdf', isClick: true })
props.download('pdf')
}}
data-id="umlPdfDownload"
diff --git a/libs/remix-ui/statusbar/src/lib/components/gitStatus.tsx b/libs/remix-ui/statusbar/src/lib/components/gitStatus.tsx
index c2282abb4b2..b61a790a5ea 100644
--- a/libs/remix-ui/statusbar/src/lib/components/gitStatus.tsx
+++ b/libs/remix-ui/statusbar/src/lib/components/gitStatus.tsx
@@ -21,7 +21,7 @@ export default function GitStatus({ plugin, gitBranchName, setGitBranchName }: G
const initializeNewGitRepo = async () => {
await plugin.call('dgit', 'init')
- trackMatomoEvent(plugin, { category: 'git', action: 'INIT', name: 'initNewRepo', isClick: false });
+ trackMatomoEvent(plugin, { category: 'statusBar', action: 'initNewRepo', isClick: true });
}
if (!appContext.appState.canUseGit) return null
diff --git a/libs/remix-ui/terminal/src/lib/components/RenderUnknownTransactions.tsx b/libs/remix-ui/terminal/src/lib/components/RenderUnknownTransactions.tsx
index 2f6b62806f9..94951d1c6b2 100644
--- a/libs/remix-ui/terminal/src/lib/components/RenderUnknownTransactions.tsx
+++ b/libs/remix-ui/terminal/src/lib/components/RenderUnknownTransactions.tsx
@@ -32,7 +32,7 @@ const RenderUnKnownTransactions = ({ tx, receipt, index, plugin, showTableHash,
let to = tx.to
if (tx.isUserOp) {
- trackMatomoEvent({ category: 'udapp', action: 'safeSmartAccount', name: 'txExecuted', value: 'successfully', isClick: false })
+ trackMatomoEvent({ category: 'udapp', action: 'safeSmartAccount', name: 'txExecutedSuccessfully', isClick: true })
// Track event with signature: ExecutionFromModuleSuccess (index_topic_1 address module)
// to get sender smart account address
const fromAddrLog = receipt.logs.find(e => e.topics[0] === "0x6895c13664aa4f67288b25d7a21d7aaa34916e355fb9b6fae0a139a9085becb8")
diff --git a/libs/remix-ui/top-bar/src/lib/remix-ui-topbar.tsx b/libs/remix-ui/top-bar/src/lib/remix-ui-topbar.tsx
index ed820421a81..14b2f1b95be 100644
--- a/libs/remix-ui/top-bar/src/lib/remix-ui-topbar.tsx
+++ b/libs/remix-ui/top-bar/src/lib/remix-ui-topbar.tsx
@@ -390,7 +390,7 @@ export function RemixUiTopbar() {
try {
await switchToWorkspace(name)
handleExpandPath([])
- trackMatomoEvent({ category: 'Workspace', action: 'switchWorkspace', name: name, isClick: true })
+ trackMatomoEvent({ category: 'workspace', action: 'switchWorkspace', name: name, isClick: true })
} catch (e) {
global.modal(
intl.formatMessage({ id: 'filePanel.workspace.switch' }),
diff --git a/libs/remix-ui/workspace/src/lib/actions/workspace.ts b/libs/remix-ui/workspace/src/lib/actions/workspace.ts
index 8e0a9d00a9a..ab02edb84dc 100644
--- a/libs/remix-ui/workspace/src/lib/actions/workspace.ts
+++ b/libs/remix-ui/workspace/src/lib/actions/workspace.ts
@@ -239,10 +239,12 @@ export const populateWorkspace = async (
if (workspaceTemplateName === 'semaphore' || workspaceTemplateName === 'hashchecker' || workspaceTemplateName === 'rln') {
const isCircomActive = await plugin.call('manager', 'isActive', 'circuit-compiler')
if (!isCircomActive) await plugin.call('manager', 'activatePlugin', 'circuit-compiler')
+ await trackMatomoEventAsync(plugin, { category: 'circuit-compiler', action: 'template', name: 'create', value: workspaceTemplateName, isClick: false })
}
if (workspaceTemplateName === 'multNr' || workspaceTemplateName === 'stealthDropNr') {
const isNoirActive = await plugin.call('manager', 'isActive', 'noir-compiler')
if (!isNoirActive) await plugin.call('manager', 'activatePlugin', 'noir-compiler')
+ await trackMatomoEventAsync(plugin, { category: 'noir-compiler', action: 'template', name: 'create', value: workspaceTemplateName, isClick: false })
}
}
@@ -299,7 +301,7 @@ export const loadWorkspacePreset = async (template: WorkspaceTemplate = 'remixDe
let content
if (params.code) {
- await trackMatomoEventAsync(plugin, { category: 'Workspace', action: 'template', name: 'code-template-code-param', isClick: false })
+ await trackMatomoEventAsync(plugin, { category: 'workspace', action: 'template', name: 'code-template-code-param', isClick: false })
const hashed = bytesToHex(hash.keccakFromString(params.code))
path = 'contract-' + hashed.replace('0x', '').substring(0, 10) + (params.language && params.language.toLowerCase() === 'yul' ? '.yul' : '.sol')
@@ -307,7 +309,7 @@ export const loadWorkspacePreset = async (template: WorkspaceTemplate = 'remixDe
await workspaceProvider.set(path, content)
}
if (params.shareCode) {
- await trackMatomoEventAsync(plugin, { category: 'Workspace', action: 'template', name: 'code-template-shareCode-param', isClick: false })
+ await trackMatomoEventAsync(plugin, { category: 'workspace', action: 'template', name: 'code-template-shareCode-param', isClick: false })
const host = '127.0.0.1'
const port = 5001
const protocol = 'http'
@@ -332,7 +334,7 @@ export const loadWorkspacePreset = async (template: WorkspaceTemplate = 'remixDe
await workspaceProvider.set(path, content)
}
if (params.url) {
- await trackMatomoEventAsync(plugin, { category: 'Workspace', action: 'template', name: 'code-template-url-param', isClick: false })
+ await trackMatomoEventAsync(plugin, { category: 'workspace', action: 'template', name: 'code-template-url-param', isClick: false })
const data = await plugin.call('contentImport', 'resolve', params.url)
path = data.cleanUrl
content = data.content
@@ -356,7 +358,7 @@ export const loadWorkspacePreset = async (template: WorkspaceTemplate = 'remixDe
}
if (params.ghfolder) {
try {
- await trackMatomoEventAsync(plugin, { category: 'Workspace', action: 'template', name: 'code-template-ghfolder-param', isClick: false })
+ await trackMatomoEventAsync(plugin, { category: 'workspace', action: 'template', name: 'code-template-ghfolder-param', isClick: false })
const files = await plugin.call('contentImport', 'resolveGithubFolder', params.ghfolder)
for (const [path, content] of Object.entries(files)) {
await workspaceProvider.set(path, content)
@@ -375,7 +377,7 @@ export const loadWorkspacePreset = async (template: WorkspaceTemplate = 'remixDe
case 'gist-template':
// creates a new workspace gist-sample and get the file from gist
try {
- await trackMatomoEventAsync(plugin, { category: 'Workspace', action: 'template', name: 'gist-template', isClick: false })
+ await trackMatomoEventAsync(plugin, { category: 'workspace', action: 'template', name: 'gist-template', isClick: false })
const gistId = params.gist
const response: AxiosResponse = await axios.get(`https://api.github.com/gists/${gistId}`)
const data = response.data as { files: any }
@@ -438,7 +440,7 @@ export const loadWorkspacePreset = async (template: WorkspaceTemplate = 'remixDe
const templateList = Object.keys(templateWithContent)
if (!templateList.includes(template)) break
- await trackMatomoEventAsync(plugin, { category: 'Workspace', action: 'template', name: template, isClick: false })
+ await trackMatomoEventAsync(plugin, { category: 'workspace', action: 'template', name: template, isClick: false })
// @ts-ignore
const files = await templateWithContent[template](opts, plugin)
for (const file in files) {
diff --git a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
index 8594e9460c6..f5140f6143a 100644
--- a/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
+++ b/libs/remix-ui/workspace/src/lib/remix-ui-workspace.tsx
@@ -525,7 +525,7 @@ export function Workspace() {
try {
await global.dispatchSwitchToWorkspace(name)
global.dispatchHandleExpandPath([])
- trackMatomoEvent({ category: 'Workspace', action: 'switchWorkspace', name: name, isClick: true })
+ trackMatomoEvent({ category: 'workspace', action: 'switchWorkspace', name: name, isClick: true })
} catch (e) {
global.modal(
intl.formatMessage({ id: 'filePanel.workspace.switch' }),
@@ -863,10 +863,10 @@ export function Workspace() {
try {
if (branch.remote) {
await global.dispatchCheckoutRemoteBranch(branch)
- trackMatomoEvent({ category: 'Workspace', action: 'GIT', name: 'checkout_remote_branch', isClick: true })
+ trackMatomoEvent({ category: 'workspace', action: 'GIT', name: 'checkout_remote_branch', isClick: true })
} else {
await global.dispatchSwitchToBranch(branch)
- trackMatomoEvent({ category: 'Workspace', action: 'GIT', name: 'switch_to_existing_branch', isClick: true })
+ trackMatomoEvent({ category: 'workspace', action: 'GIT', name: 'switch_to_existing_branch', isClick: true })
}
} catch (e) {
console.error(e)
@@ -883,7 +883,7 @@ export function Workspace() {
const switchToNewBranch = async () => {
try {
await global.dispatchCreateNewBranch(branchFilter)
- trackMatomoEvent({ category: 'Workspace', action: 'GIT', name: 'switch_to_new_branch', isClick: true })
+ trackMatomoEvent({ category: 'workspace', action: 'GIT', name: 'switch_to_new_branch', isClick: true })
} catch (e) {
global.modal(
intl.formatMessage({ id: 'filePanel.checkoutGitBranch' }),
@@ -927,7 +927,7 @@ export function Workspace() {
const logInGithub = async () => {
await global.plugin.call('menuicons', 'select', 'dgit');
await global.plugin.call('dgit', 'open', gitUIPanels.GITHUB)
- trackMatomoEvent({ category: 'Workspace', action: 'GIT', name: 'login', isClick: true })
+ trackMatomoEvent({ category: 'workspace', action: 'GIT', name: 'login', isClick: true })
}
const IsGitRepoDropDownMenuItem = (props: { isGitRepo: boolean, mName: string}) => {