Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
127 commits
Select commit Hold shift + click to select a range
fba4770
tracking fixes
Sep 26, 2025
ffa72e4
disableCookies
Sep 26, 2025
c00166a
rm file
Sep 27, 2025
3173141
desktop fix
Sep 29, 2025
f87398e
matomo tests
Sep 29, 2025
ed9ed08
redorder consent
Sep 29, 2025
f025473
debug plugin
Sep 30, 2025
a8a0be6
rm init
Sep 30, 2025
2539b67
rm unneeded code
Sep 30, 2025
2f40555
rm stuff
Sep 30, 2025
b9aa3a9
rm stuff
Sep 30, 2025
d46caa2
cleanup
Sep 30, 2025
7f20dfb
fix perms
Sep 30, 2025
ed92af8
correct sequence on blank load
Sep 30, 2025
b8cbc16
added matomo ts
Oct 1, 2025
509a79e
replace plugin matomo calls
Oct 1, 2025
185dd43
replace calls with context
Oct 1, 2025
ae131da
flush properly
Oct 1, 2025
566de94
fix calls
Oct 1, 2025
09c60d5
replace _paq
Oct 1, 2025
14d85c6
replace paq
Oct 1, 2025
b7f848e
replace paq
Oct 1, 2025
d665166
replace paq
Oct 1, 2025
7c67e23
paq replace
Oct 1, 2025
5c5cade
paq replace
Oct 1, 2025
d8e7ce5
paq replace
Oct 1, 2025
2dccc0f
replace paq
Oct 1, 2025
02a54ee
Merge branch 'master' of https://github.com/remix-project-org/remix-p…
Oct 1, 2025
8e9482f
replace paq
Oct 1, 2025
c90ea9b
update preload
Oct 1, 2025
9381458
replace paq
Oct 1, 2025
82509a8
uml
Oct 1, 2025
6013785
ai core
Oct 1, 2025
4e6dfcc
fs utility
Oct 1, 2025
6f4a4fc
fs util
Oct 1, 2025
8183d15
settings call
Oct 1, 2025
b2053cd
use trackcontext
Oct 1, 2025
fa03359
use tracking context
Oct 1, 2025
7e16423
tracking context
Oct 1, 2025
7f8e84c
update calls
Oct 1, 2025
80cfc9d
fix site ids
Oct 1, 2025
3df9e27
Refactor Matomo tracking system: fix parameter issues and clean archi…
Oct 1, 2025
2373525
eslint
Oct 2, 2025
1f72e05
debug plugin
Oct 2, 2025
27fd48f
fix test
Oct 2, 2025
b10b352
fix test
Oct 2, 2025
acbc668
test done
Oct 2, 2025
0d907c6
rename test file
Oct 2, 2025
cd3b227
rm stuff
Oct 2, 2025
4fa9b8b
mark pr test
Oct 2, 2025
64e6d42
matomo types
Oct 3, 2025
67d27df
events update
Oct 3, 2025
40b04d3
matomo test
Oct 3, 2025
51fb886
tracking event builder
Oct 3, 2025
a2b2782
type builders
Oct 3, 2025
afa6ce9
fix events
Oct 3, 2025
68ec7e8
update calls
Oct 3, 2025
1bbdc75
more events
Oct 3, 2025
cc7a25a
fix events
Oct 3, 2025
dc4504a
replace calls
Oct 3, 2025
fd5dcb4
replace calls
Oct 3, 2025
8a1f47e
trackng fix
Oct 3, 2025
5b0e7e8
legacy adding
Oct 3, 2025
7b531be
plugins
Oct 3, 2025
5fda2d9
ai
Oct 3, 2025
2be8baf
more calls
Oct 3, 2025
5ff0eea
fix ci scriprt
Oct 3, 2025
226da6a
more test
Oct 3, 2025
d096e15
test
Oct 3, 2025
1aa55d5
test dimensions
Oct 3, 2025
da9ee63
rm md
Oct 3, 2025
6b730e9
rm old test
Oct 3, 2025
80b783b
fix ci
Oct 3, 2025
c543cd3
refactor split
Oct 3, 2025
134ea98
udapp events
Oct 3, 2025
c1603ad
fix events
Oct 3, 2025
9c33916
ifx test
Oct 3, 2025
6c62078
screenshot
Oct 3, 2025
dabceba
Fix matomo modal click interception with stabilization pauses
Oct 3, 2025
29da1c5
ts things
Oct 3, 2025
0fea71c
Fix Monaco Editor theme initialization race condition
Oct 3, 2025
44dff87
more click events
Oct 4, 2025
3183615
ENABLE_MATOMO_LOCALHOST
Oct 4, 2025
cd66fef
linting
Oct 4, 2025
86e4e5e
linting task
Oct 4, 2025
a671109
lint only
Oct 4, 2025
4e76c7e
no libs building
Oct 4, 2025
08d0ae2
lint
Oct 4, 2025
6286455
feat: fix module boundaries and linting issues with TrackingContext
Oct 4, 2025
b8719b6
fix ts
Oct 4, 2025
9f8361d
build only
Oct 4, 2025
11abfac
fix etherscan
Oct 4, 2025
8121670
Merge branch 'fix/etherscan-v2-api' into trackerfix
Oct 4, 2025
63aa958
chore: fix comment syntax in etherscan fetch helper
Oct 4, 2025
cbb4686
refactor(etherscan): use central V2 API host with chainId and V1 fall…
Oct 4, 2025
9215859
docs(etherscan): clarify comment about central V2 API support scope
Oct 4, 2025
f65473c
feat(etherscan): add per-network V2 fallback and normalize endpoint n…
Oct 4, 2025
5c3df14
Merge branch 'fix/etherscan-v2-api' into trackerfix
Oct 5, 2025
27fef5d
fix number conversion
Oct 5, 2025
515f466
rm loader
Oct 5, 2025
4b6b3e2
localhost
Oct 5, 2025
4483fca
Merge branch 'master' into trackerfix
bunsenstraat Oct 5, 2025
29570a2
linter
Oct 5, 2025
8d07d8f
Merge branch 'trackerfix' of https://github.com/remix-project-org/rem…
Oct 5, 2025
0094c0b
click dimension
Oct 5, 2025
33c6037
rename method
Oct 5, 2025
1934c73
clean up events
Oct 5, 2025
767ad4d
fix rename
Oct 5, 2025
3a69135
fix rename
Oct 5, 2025
855eb3f
Rename modalStruct to modal in runSolidityScan
bunsenstraat Oct 5, 2025
cc55b21
revert desktop
Oct 5, 2025
173899d
Merge branch 'trackerfix' of https://github.com/remix-project-org/rem…
Oct 5, 2025
cb6b3aa
clean up
Oct 5, 2025
e638315
clean up
Oct 5, 2025
a4d7d5d
bot detect
Oct 6, 2025
8c7d562
update test
Oct 6, 2025
1ff1af4
bot detection domains
Oct 6, 2025
4b1b6b3
types
Oct 6, 2025
715c8ed
fixes
Oct 6, 2025
a859c49
tests
Oct 6, 2025
691e4ae
test
Oct 6, 2025
68399ff
test: Replace pause() with E2E state markers for reliable Matomo tests
Oct 7, 2025
21b0716
fix event state
Oct 7, 2025
db39992
bot config
Oct 7, 2025
145caea
bot side ids
Oct 7, 2025
eae4d7b
del docs
Oct 7, 2025
df1869b
flags
Oct 7, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ parameters:
run_flaky_tests:
type: boolean
default: false
run_lint_only:
type: boolean
default: false
run_build_only:
type: boolean
default: false
resource_class:
type: enum
enum: ["small", "medium", "medium+", "large", "xlarge", "2xlarge"]
Expand Down Expand Up @@ -367,7 +373,7 @@ workflows:
job: ["nogroup"]
jobsize: ["1"]
parallelism: [1]
scriptparameter: ["\\.pr"]
scriptparameter: ["\\.pr\\.js$"]

run_flaky_tests:
when: << pipeline.parameters.run_flaky_tests >>
Expand Down Expand Up @@ -508,4 +514,14 @@ workflows:
branches:
only: remix_beta

lint_only:
when: << pipeline.parameters.run_lint_only >>
jobs:
- lint

build_only:
when: << pipeline.parameters.run_build_only >>
jobs:
- build

# VS Code Extension Version: 1.5.1
19 changes: 18 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,24 @@
"object-curly-spacing": ["error", "always", { "arraysInObjects": false }],
"no-trailing-spaces": "error",
"no-multi-spaces": "error",
"no-multiple-empty-lines": ["error" , { "max": 1}]
"no-multiple-empty-lines": ["error" , { "max": 1}],
"no-restricted-syntax": [
"error",
{
"selector": "MemberExpression[object.type='Identifier'][object.name='window'][property.type='Identifier'][property.name='_paq']",
"message": "Direct usage of window._paq is not allowed. Use one of these alternatives instead:\n 1. TrackingContext: track(eventBuilder)\n 2. MatomoManager: matomoManager.trackEvent(...)\n 3. Matomo Plugin: plugin.call('matomo', 'track', ...)\n 4. Helper: trackMatomoEvent(plugin, eventBuilder)"
},
{
"selector": "MemberExpression[object.type='MemberExpression'][object.object.type='Identifier'][object.object.name='window'][object.property.type='Identifier'][object.property.name='_paq']",
"message": "Direct usage of window._paq methods is not allowed. Use one of these alternatives instead:\n 1. TrackingContext: track(eventBuilder)\n 2. MatomoManager: matomoManager.trackEvent(...)\n 3. Matomo Plugin: plugin.call('matomo', 'track', ...)\n 4. Helper: trackMatomoEvent(plugin, eventBuilder)"
}
]
}
},
{
"files": ["**/src/app/matomo/*.ts", "**/src/assets/js/**/*.js"],
"rules": {
"no-restricted-syntax": "off"
}
},
{
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,4 @@ apps/remix-ide-e2e/tmp/

# IDE - Cursor
.cursor/
PR_MESSAGE.md
27 changes: 20 additions & 7 deletions apps/circuit-compiler/src/app/services/circomPluginClient.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { PluginClient } from '@remixproject/plugin'
import { createClient } from '@remixproject/plugin-webview'
import { trackMatomoEvent, CircuitCompilerEvents } from '@remix-api'
import EventManager from 'events'
import pathModule from 'path'
import { compiler_list, parse, compile, generate_r1cs, generate_witness } from 'circom_wasm'
Expand All @@ -22,11 +23,23 @@ export class CircomPluginClient extends PluginClient {
private lastCompiledFile: string = ''
private compiler: typeof compilerV215 & typeof compilerV216 & typeof compilerV217 & typeof compilerV218
public _paq = {
push: (args) => {
this.call('matomo' as any, 'track', args)
push: (args: any[]) => {
if (args[0] === 'trackEvent' && args.length >= 3) {
// Convert legacy _paq.push(['trackEvent', 'category', 'action', 'name'])
// to matomo plugin call with legacy string signature
const [, category, action, name, value] = args;
this.call('matomo' as any, 'trackEvent', category, action, name, value);
} else {
// For other _paq commands, pass through as-is
console.warn('CircuitCompiler: Unsupported _paq command:', args);
}
}
}

private trackCircuitEvent = (event: ReturnType<typeof CircuitCompilerEvents[keyof typeof CircuitCompilerEvents]>) => {
trackMatomoEvent(this, event);
}

constructor() {
super()
this.methods = ['init', 'parse', 'compile', 'generateR1cs', 'resolveDependencies']
Expand Down Expand Up @@ -175,7 +188,7 @@ export class CircomPluginClient extends PluginClient {
const circuitErrors = circuitApi.report()

this.logCompilerReport(circuitErrors)
this._paq.push(['trackEvent', 'circuit-compiler', 'compile', 'Compilation failed'])
this.trackCircuitEvent(CircuitCompilerEvents.compile('Compilation failed'))
throw new Error(circuitErrors)
} else {
this.lastCompiledFile = path
Expand Down Expand Up @@ -204,7 +217,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' })
}
this._paq.push(['trackEvent', 'circuit-compiler', 'compile', 'Compilation successful'])
this.trackCircuitEvent(CircuitCompilerEvents.compile('Compilation successful'))
circuitApi.log().map(log => {
log && this.call('terminal', 'log', { type: 'log', value: log })
})
Expand Down Expand Up @@ -286,15 +299,15 @@ export class CircomPluginClient extends PluginClient {
const r1csErrors = r1csApi.report()

this.logCompilerReport(r1csErrors)
this._paq.push(['trackEvent', 'circuit-compiler', 'generateR1cs', 'R1CS Generation failed'])
this.trackCircuitEvent(CircuitCompilerEvents.generateR1cs('R1CS Generation failed'))
throw new Error(r1csErrors)
} else {
const fileName = extractNameFromKey(path)
const writePath = extractParentFromKey(path) + "/.bin/" + fileName.replace('.circom', '.r1cs')

// @ts-ignore
await this.call('fileManager', 'writeFile', writePath, r1csProgram, true)
this._paq.push(['trackEvent', 'circuit-compiler', 'generateR1cs', 'R1CS Generation successful'])
this.trackCircuitEvent(CircuitCompilerEvents.generateR1cs('R1CS Generation successful'))
r1csApi.log().map(log => {
log && this.call('terminal', 'log', { type: 'log', value: log })
})
Expand Down Expand Up @@ -342,7 +355,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 })
this._paq.push(['trackEvent', 'circuit-compiler', 'computeWitness', 'compiler.generate_witness', wasmPath.replace('.wasm', '.wtn')])
this.trackCircuitEvent(CircuitCompilerEvents.computeWitness(wasmPath.replace('.wasm', '.wtn')))
this.internalEvents.emit('circuit_computing_witness_done')
this.emit('statusChanged', { key: 'succeed', title: 'witness computed successfully', type: 'success' })
return witness
Expand Down
7 changes: 4 additions & 3 deletions apps/contract-verification/src/app/views/LookupView.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useContext, useEffect, useMemo, useState } from 'react'
import { trackMatomoEvent, ContractVerificationEvents } from '@remix-api'
import { SearchableChainDropdown, ContractAddressInput } from '../components'
import { mergeChainSettingsWithDefaults, validConfiguration } from '../utils'
import type { LookupResponse, VerifierIdentifier } from '../types'
Expand Down Expand Up @@ -59,14 +60,14 @@ export const LookupView = () => {
}
}

const sendToMatomo = async (eventAction: string, eventName: string) => {
await clientInstance.call('matomo' as any, 'track', ['trackEvent', 'ContractVerification', eventAction, eventName])
const sendToMatomo = async (eventName: string) => {
await trackMatomoEvent(clientInstance, ContractVerificationEvents.lookup(eventName));
}

const handleOpenInRemix = async (lookupResponse: LookupResponse) => {
try {
await clientInstance.saveToRemix(lookupResponse)
await sendToMatomo('lookup', 'openInRemix On: ' + selectedChain)
await sendToMatomo('openInRemix On: ' + selectedChain)
} catch (err) {
console.error(`Error while trying to open in Remix: ${err.message}`)
}
Expand Down
7 changes: 4 additions & 3 deletions apps/contract-verification/src/app/views/VerifyView.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useContext, useEffect, useMemo, useState } from 'react'
import { trackMatomoEvent, ContractVerificationEvents } from '@remix-api'

import { AppContext } from '../AppContext'
import { SearchableChainDropdown, ContractDropdown, ContractAddressInput } from '../components'
Expand Down Expand Up @@ -42,8 +43,8 @@ export const VerifyView = () => {
setEnabledVerifiers({ ...enabledVerifiers, [verifierId]: checked })
}

const sendToMatomo = async (eventAction: string, eventName: string) => {
await clientInstance.call("matomo" as any, 'track', ['trackEvent', 'ContractVerification', eventAction, eventName]);
const sendToMatomo = async (eventName: string) => {
await trackMatomoEvent(clientInstance, ContractVerificationEvents.verify(eventName));
}

const handleVerify = async (e) => {
Expand All @@ -68,7 +69,7 @@ export const VerifyView = () => {
name: verifierId as VerifierIdentifier,
}
receipts.push({ verifierInfo, status: 'pending', contractId, isProxyReceipt: false, failedChecks: 0 })
await sendToMatomo('verify', `verifyWith${verifierId} On: ${selectedChain?.chainId} IsProxy: ${!!(hasProxy && proxyAddress)}`)
await sendToMatomo(`verifyWith${verifierId} On: ${selectedChain?.chainId} IsProxy: ${!!(hasProxy && proxyAddress)}`)
}

const newSubmittedContract: SubmittedContract = {
Expand Down
42 changes: 30 additions & 12 deletions apps/learneth/src/redux/models/remixide.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { toast } from 'react-toastify'
import { type ModelType } from '../store'
import remixClient from '../../remix-client'
import { router } from '../../App'
import { trackMatomoEvent, LearnethEvents } from '@remix-api'

function getFilePath(file: string): string {
const name = file.split('/')
Expand Down Expand Up @@ -46,11 +47,28 @@ const Model: ModelType = {
},
});

// Type-safe Matomo tracking helper
const trackLearnethEvent = (event: ReturnType<typeof LearnethEvents[keyof typeof LearnethEvents]>) => {
trackMatomoEvent(remixClient, event);
};

// Legacy _paq compatibility layer for existing learneth tracking calls
(window as any)._paq = {
push: (args) => {
remixClient.call('matomo' as any, 'track', args)
push: (args: any[]) => {
if (args[0] === 'trackEvent' && args.length >= 3) {
// Convert legacy _paq.push(['trackEvent', 'category', 'action', 'name'])
// to matomo plugin call with legacy string signature
const [, category, action, name, value] = args;
remixClient.call('matomo' as any, 'trackEvent', category, action, name, value);
} else {
// For other _paq commands, pass through as-is
console.warn('Learneth: Unsupported _paq command:', args);
}
}
}
};

// Make trackLearnethEvent available globally for the effects
(window as any).trackLearnethEvent = trackLearnethEvent;

yield router.navigate('/home')
},
Expand All @@ -74,7 +92,7 @@ const Model: ModelType = {
return
}

(<any>window)._paq.push(['trackEvent', 'learneth', 'display_file', `${(step && step.name)}/${path}`])
(<any>window).trackLearnethEvent(LearnethEvents.displayFile(`${(step && step.name)}/${path}`))

toast.info(`loading ${path} into IDE`)
yield put({
Expand All @@ -101,7 +119,7 @@ const Model: ModelType = {
})
toast.dismiss()
} catch (error) {
(<any>window)._paq.push(['trackEvent', 'learneth', 'display_file_error', error.message])
(<any>window).trackLearnethEvent(LearnethEvents.displayFileError(error.message))
toast.dismiss()
toast.error('File could not be loaded. Please try again.')
yield put({
Expand Down Expand Up @@ -151,7 +169,7 @@ const Model: ModelType = {
type: 'remixide/save',
payload: { errors: ['Compiler failed to test this file']},
});
(<any>window)._paq.push(['trackEvent', 'learneth', 'test_step_error', 'Compiler failed to test this file'])
(<any>window).trackLearnethEvent(LearnethEvents.testStepError('Compiler failed to test this file'))
} else {
const success = result.totalFailing === 0;
if (success) {
Expand All @@ -167,14 +185,14 @@ const Model: ModelType = {
},
})
}
(<any>window)._paq.push(['trackEvent', 'learneth', 'test_step', success])
(<any>window).trackLearnethEvent(LearnethEvents.testStep(String(success)))
}
} catch (err) {
yield put({
type: 'remixide/save',
payload: { errors: [String(err)]},
});
(<any>window)._paq.push(['trackEvent', 'learneth', 'test_step_error', err])
(<any>window).trackLearnethEvent(LearnethEvents.testStepError(String(err)))
}
yield put({
type: 'loading/save',
Expand Down Expand Up @@ -204,13 +222,13 @@ const Model: ModelType = {
yield remixClient.call('fileManager', 'setFile', path, content)
yield remixClient.call('fileManager', 'switchFile', `${path}`);

(<any>window)._paq.push(['trackEvent', 'learneth', 'show_answer', path])
(<any>window).trackLearnethEvent(LearnethEvents.showAnswer(path))
} catch (err) {
yield put({
type: 'remixide/save',
payload: { errors: [String(err)]},
});
(<any>window)._paq.push(['trackEvent', 'learneth', 'show_answer_error', err.message])
(<any>window).trackLearnethEvent(LearnethEvents.showAnswerError(err.message))
}

toast.dismiss()
Expand All @@ -224,7 +242,7 @@ const Model: ModelType = {
*testSolidityCompiler(_, { put, select }) {
try {
yield remixClient.call('solidity', 'getCompilationResult');
(<any>window)._paq.push(['trackEvent', 'learneth', 'test_solidity_compiler'])
(<any>window).trackLearnethEvent(LearnethEvents.testSolidityCompiler())
} catch (err) {
const errors = yield select((state) => state.remixide.errors)
yield put({
Expand All @@ -233,7 +251,7 @@ const Model: ModelType = {
errors: [...errors, "The `Solidity Compiler` is not yet activated.<br>Please activate it using the `SOLIDITY` button in the `Featured Plugins` section of the homepage.<img class='img-thumbnail mt-3' src='assets/activatesolidity.png'>"],
},
});
(<any>window)._paq.push(['trackEvent', 'learneth', 'test_solidity_compiler_error', err.message])
(<any>window).trackLearnethEvent(LearnethEvents.testSolidityCompilerError(err.message))
}
}
},
Expand Down
Loading