Compare commits
1 Commits
master
...
unwanted-u
Author | SHA1 | Date | |
---|---|---|---|
![]() |
fe64495581 |
1
.npmrc
1
.npmrc
@ -1 +0,0 @@
|
||||
@tornado:registry=https://git.tornado.ws/api/packages/tornado-packages/npm/
|
31
README.md
31
README.md
@ -1,6 +1,6 @@
|
||||
# Tornado Cash Classic UI
|
||||
|
||||
> Self-hostable Tornado Cash UI software for interacting with the protocol
|
||||
> UI for non-custodial Ethereum Privacy solution
|
||||
|
||||
## Building locally
|
||||
|
||||
@ -31,42 +31,29 @@ For detailed explanation on how things work, checkout [Nuxt.js docs](https://nux
|
||||
|
||||
## Update cached files
|
||||
|
||||
- To update deposit and withdrawal events use `yarn update:events {chainId} {optional: tokenOrEvent} {optional: tokenOrEvent}`
|
||||
- To update encrypted notes use `yarn update:encrypted {chainId}`
|
||||
- To update merkle tree use `yarn update:tree {chainId}`
|
||||
- For update deposits and withdrawals events use `yarn update:events {chainId}`
|
||||
- For update encrypted notes use `yarn update:encrypted {chainId}`
|
||||
- For update merkle tree use `yarn update:tree {chainId}`
|
||||
|
||||
#### NOTE!
|
||||
|
||||
After updating cached files do not forget to use `yarn update:zip`.
|
||||
After update cached files do not forget to use `yarn update:zip`
|
||||
|
||||
### Example for Ethereum Mainnet:
|
||||
|
||||
You may set in [`networkConfig.js`](./networkConfig.js) the `blockSyncInterval` (def: 10_000) to the maximum value allowed by your RPC provider. Command usage follows below.
|
||||
|
||||
```bash
|
||||
# Updating events with just the required chain id parameter
|
||||
```
|
||||
yarn update:events 1
|
||||
# Updating events for only one token across all instances on that network
|
||||
yarn update:events 1 dai
|
||||
# Updating events for only one event on only some network
|
||||
yarn update:events 1 deposit
|
||||
# Both
|
||||
yarn update:events 1 dai deposit
|
||||
# Updating encrypted notes for some chain id
|
||||
yarn update:encrypted 1
|
||||
# Updating trees for some chain id
|
||||
yarn update:tree 1
|
||||
# Finally zips must be updated
|
||||
|
||||
yarn update:zip
|
||||
```
|
||||
|
||||
### Example for Binance Smart Chain:
|
||||
|
||||
```bash
|
||||
```
|
||||
yarn update:events 56
|
||||
yarn update:events 56 bnb
|
||||
yarn update:events 56 bnb deposit
|
||||
yarn update:encrypted 56
|
||||
yarn update:tree 56
|
||||
|
||||
yarn update:zip
|
||||
```
|
||||
|
@ -37,7 +37,7 @@
|
||||
<b-button
|
||||
tag="a"
|
||||
type="is-icon"
|
||||
href="https://git.tornado.ws/tornadocash/classic-ui"
|
||||
href="https://development.tornadocash.community/tornadocash/classic-ui"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
icon-right="git"
|
||||
|
@ -20,7 +20,7 @@
|
||||
{{ $t('compliance') }}
|
||||
</b-navbar-item>
|
||||
<b-navbar-item
|
||||
href="https://docs.tornado.ws"
|
||||
href="https://docs.tornado.cash"
|
||||
target="_blank"
|
||||
data-test="docs_link"
|
||||
rel="noopener noreferrer"
|
||||
|
@ -18,7 +18,12 @@
|
||||
</template>
|
||||
<template v-slot:description>{{ notice.description }}</template>
|
||||
</i18n>
|
||||
<a v-if="notice.nova" href="https://nova.tornado.ws/" target="_blank" rel="noopener noreferrer">
|
||||
<a
|
||||
v-if="notice.nova"
|
||||
href="https://nova.tornadocash.eth.link"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Tornado Cash Nova
|
||||
</a>
|
||||
<a
|
||||
|
@ -151,7 +151,7 @@
|
||||
"nullifierHash": "Nullifier Hash",
|
||||
"verified": "Verified",
|
||||
"generatePdfReport": "Generate PDF report",
|
||||
"compliancePrintWarning": "This Compliance Report is for informational purposes only. You should confirm the validity of this report by using Tornado’s Compliance Tool (https://tornado.ws/compliance) or via any other cryptographic software that can compute and verify the information contained herein(the \"Tornado Compliance Tool\"). Any discrepancies between information found in this report and provided by the above tool indicate that the information in this report may be inaccurate and/or fraudulent.{newline}THE COMPLIANCE REPORT IS PROVIDED \"AS IS,\" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OF THE TORNADO.CASH COMPLIANCE TOOL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THIS COMPLIANCE REPORT.",
|
||||
"compliancePrintWarning": "This Compliance Report is for informational purposes only. You should confirm the validity of this report by using Tornado’s Compliance Tool (https://tornadocash.eth.link/compliance) or via any other cryptographic software that can compute and verify the information contained herein(the \"Tornado Compliance Tool\"). Any discrepancies between information found in this report and provided by the above tool indicate that the information in this report may be inaccurate and/or fraudulent.{newline}THE COMPLIANCE REPORT IS PROVIDED \"AS IS,\" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OF THE TORNADO.CASH COMPLIANCE TOOL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THIS COMPLIANCE REPORT.",
|
||||
"relayRequestFailed": "Relayer {relayerName} is down. Please choose a different relayer.",
|
||||
"selectProvider": "Select provider",
|
||||
"walletDoesNotSupported": "The wallet is not supported",
|
||||
|
@ -151,7 +151,7 @@
|
||||
"nullifierHash": "Hash del Nullifier",
|
||||
"verified": "Verificador",
|
||||
"generatePdfReport": "Genere informe PDF",
|
||||
"compliancePrintWarning": "Este Informe de Compromiso es para propósito informativo unicamente. Debería confirmar la validez de este informe utilizando la Herramienta de Cumplimiento de Tornado (https://tornado.ws/compliance) o cualquier otro software criptográfico que pueda procesar y verificar la información contenida aquí(la \"Tornado Compliance Tool\"). Cualquier discrepancia entre la información recogida en este informe y entregado por la herramienta anterior indica que este informe no es riguroso y/o fraudulento.{newline}EL INFORME DE CUMPLIMIENTO SE PRESENTA \"COMO TAL,\" SIN GARANTÍA DE NINGÚN TIPO, EXPRESA O IMPLÍCITAMENTE, INCLUYENDO PERO NO LIMITADA A LAS GARANTÍAS MERCANTILES, ADECUADAS PARA UN PROPÓSITO PARTICULAR Y LA NO INFRACCIÓN. EN NINGÚN CASO DEBERÍAN LOS AUTORES DE LA HERRAMIENTA DE CUMPLIMIENTO DE TORNADO.CASH SER RESPONSABLES U OBJETO DE CUALQUIER RECLAMO, DAÑO U OTRA RESPONSABILIDAD, YA SEA EN ACCIÓN CONTRACTUAL, AGRAVIADO O DE CUALQUIER OTRO MODO, DERIVADO DE, PRODUCTO DE O EN CONEXIÓN CON EL MENCIONADO INFORME DE CUMPLIMIENTO.",
|
||||
"compliancePrintWarning": "Este Informe de Compromiso es para propósito informativo unicamente. Debería confirmar la validez de este informe utilizando la Herramienta de Cumplimiento de Tornado (https://tornadocash.eth.link/compliance) o cualquier otro software criptográfico que pueda procesar y verificar la información contenida aquí(la \"Tornado Compliance Tool\"). Cualquier discrepancia entre la información recogida en este informe y entregado por la herramienta anterior indica que este informe no es riguroso y/o fraudulento.{newline}EL INFORME DE CUMPLIMIENTO SE PRESENTA \"COMO TAL,\" SIN GARANTÍA DE NINGÚN TIPO, EXPRESA O IMPLÍCITAMENTE, INCLUYENDO PERO NO LIMITADA A LAS GARANTÍAS MERCANTILES, ADECUADAS PARA UN PROPÓSITO PARTICULAR Y LA NO INFRACCIÓN. EN NINGÚN CASO DEBERÍAN LOS AUTORES DE LA HERRAMIENTA DE CUMPLIMIENTO DE TORNADO.CASH SER RESPONSABLES U OBJETO DE CUALQUIER RECLAMO, DAÑO U OTRA RESPONSABILIDAD, YA SEA EN ACCIÓN CONTRACTUAL, AGRAVIADO O DE CUALQUIER OTRO MODO, DERIVADO DE, PRODUCTO DE O EN CONEXIÓN CON EL MENCIONADO INFORME DE CUMPLIMIENTO.",
|
||||
"relayRequestFailed": "El retransmisor {relayerName} no responde. Por favor escoja uno diferente.",
|
||||
"selectProvider": "Seleccione proveedor",
|
||||
"walletDoesNotSupported": "El monedero no es compatible",
|
||||
|
@ -151,7 +151,7 @@
|
||||
"nullifierHash": "Hash Nullifié",
|
||||
"verified": "Verifié",
|
||||
"generatePdfReport": "Générer un rapport PDF",
|
||||
"compliancePrintWarning": "Ce rapport de conformité est uniquement destiné à des fins d'information. Vous devez confirmer la validité de ce rapport en utilisant l'outil de conformité de Tornado (https://tornado.ws/compliance) ou tout autre logiciel cryptographique capable de calculer et de vérifier les informations contenues dans ce document (l' \"Outil de Conformité Tornado\"). Toute divergence entre les informations trouvées dans ce rapport et celles fournies par l'outil susmentionné indique que les informations contenues dans ce rapport sont inexactes et/ou frauduleuses.{newline}LE RAPPORT DE CONFORMITÉ EST FOURNI \"EN L'ÉTAT\", SANS GARANTIE D'AUCUNE SORTE, EXPRESSE OU IMPLICITE, Y COMPRIS, MAIS SANS S'Y LIMITER, LES GARANTIES DE QUALITÉ MARCHANDE, D'ADÉQUATION À UN USAGE PARTICULIER ET D'ABSENCE DE CONTREFAÇON. EN AUCUN CAS, LES AUTEURS DE L'OUTIL DE CONFORMITÉ TORNADO.CASH NE POURRONT ÊTRE TENUS RESPONSABLES DE TOUTE RÉCLAMATION, DE TOUT DOMMAGE OU DE TOUTE AUTRE RESPONSABILITÉ, QUE CE SOIT DANS LE CADRE D'UNE ACTION CONTRACTUELLE, DÉLICTUELLE OU AUTRE, DÉCOULANT DE, EN DEHORS DE OU EN RELATION AVEC CE RAPPORT DE CONFORMITÉ.",
|
||||
"compliancePrintWarning": "Ce rapport de conformité est uniquement destiné à des fins d'information. Vous devez confirmer la validité de ce rapport en utilisant l'outil de conformité de Tornado (https://tornadocash.eth.link/compliance) ou tout autre logiciel cryptographique capable de calculer et de vérifier les informations contenues dans ce document (l' \"Outil de Conformité Tornado\"). Toute divergence entre les informations trouvées dans ce rapport et celles fournies par l'outil susmentionné indique que les informations contenues dans ce rapport sont inexactes et/ou frauduleuses.{newline}LE RAPPORT DE CONFORMITÉ EST FOURNI \"EN L'ÉTAT\", SANS GARANTIE D'AUCUNE SORTE, EXPRESSE OU IMPLICITE, Y COMPRIS, MAIS SANS S'Y LIMITER, LES GARANTIES DE QUALITÉ MARCHANDE, D'ADÉQUATION À UN USAGE PARTICULIER ET D'ABSENCE DE CONTREFAÇON. EN AUCUN CAS, LES AUTEURS DE L'OUTIL DE CONFORMITÉ TORNADO.CASH NE POURRONT ÊTRE TENUS RESPONSABLES DE TOUTE RÉCLAMATION, DE TOUT DOMMAGE OU DE TOUTE AUTRE RESPONSABILITÉ, QUE CE SOIT DANS LE CADRE D'UNE ACTION CONTRACTUELLE, DÉLICTUELLE OU AUTRE, DÉCOULANT DE, EN DEHORS DE OU EN RELATION AVEC CE RAPPORT DE CONFORMITÉ.",
|
||||
"relayRequestFailed": "Le relais {relayerName} est en panne. Veuillez choisir un autre relais.",
|
||||
"selectProvider": "Sélectionner le fournisseur",
|
||||
"walletDoesNotSupported": "Le portefeuille n'est pas supporté",
|
||||
|
@ -151,7 +151,7 @@
|
||||
"nullifierHash": "Nullifier Hash",
|
||||
"verified": "Подтверждено",
|
||||
"generatePdfReport": "Сгенерировать PDF отчёт",
|
||||
"compliancePrintWarning": "Настоящий отчет о соответствии носит исключительно информационный характер. Вы должны подтвердить действительность этого отчета с помощью средства проверки соответствия Tornado (https://tornado.ws/compliance) или с помощью любого другого криптографического программного обеспечения, которое может обработать и проверить информацию, содержащуюся в этом отчете(\"Tornado Compliance Tool\"). Любые расхождения между информацией, приведенной в данном отчете и предоставленной вышеуказанным инструментом, указывают на то, что информация, содержащаяся в этом отчете, является неточной и/или мошеннической.{newline}ОТЧЕТ О СООТВЕТСТВИИ ПРЕДОСТАВЛЯЕТСЯ \"КАК ЕСТЬ,\" БЕЗ ГАРАНТИЙ ЛЮБОГО РОДА, ЯВНЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ГАРАНТИЯМИ ТОВАРНОГО КАЧЕСТВА, ПРИГОДНОСТЬЮ К КОНКРЕТНОЙ ЦЕЛИ. НИ ПРИ КАКИХ ОБСТОЯТЕЛЬСТВАХ АВТОРЫ ИНСТРУМЕНТА СООТВЕТСТВИЯ TORNADO.CASH НЕ НЕСУТ ОТВЕТСТВЕННОСТИ ЗА ЛЮБЫЕ ПРЕТЕНЗИИ, УЩЕРБ ИЛИ ДРУГУЮ ОТВЕТСТВЕННОСТЬ, ОТНОСЯЩУЮСЯ К ДЕЙСТВИЮ ДОГОВОРОВ, ГРАЖДАНСКИМ ПРАВОНАРУШЕНИЯМ, А ТАКЖЕ ВЫТЕКАЮЩУЮ ИЗ НАСТОЯЩЕГО ОТЧЕТА О СООТВЕТСТВИИ ИЛИ СВЯЗАННУЮ С НИМ.",
|
||||
"compliancePrintWarning": "Настоящий отчет о соответствии носит исключительно информационный характер. Вы должны подтвердить действительность этого отчета с помощью средства проверки соответствия Tornado (https://tornadocash.eth.link/compliance) или с помощью любого другого криптографического программного обеспечения, которое может обработать и проверить информацию, содержащуюся в этом отчете(\"Tornado Compliance Tool\"). Любые расхождения между информацией, приведенной в данном отчете и предоставленной вышеуказанным инструментом, указывают на то, что информация, содержащаяся в этом отчете, является неточной и/или мошеннической.{newline}ОТЧЕТ О СООТВЕТСТВИИ ПРЕДОСТАВЛЯЕТСЯ \"КАК ЕСТЬ,\" БЕЗ ГАРАНТИЙ ЛЮБОГО РОДА, ЯВНЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ГАРАНТИЯМИ ТОВАРНОГО КАЧЕСТВА, ПРИГОДНОСТЬЮ К КОНКРЕТНОЙ ЦЕЛИ. НИ ПРИ КАКИХ ОБСТОЯТЕЛЬСТВАХ АВТОРЫ ИНСТРУМЕНТА СООТВЕТСТВИЯ TORNADO.CASH НЕ НЕСУТ ОТВЕТСТВЕННОСТИ ЗА ЛЮБЫЕ ПРЕТЕНЗИИ, УЩЕРБ ИЛИ ДРУГУЮ ОТВЕТСТВЕННОСТЬ, ОТНОСЯЩУЮСЯ К ДЕЙСТВИЮ ДОГОВОРОВ, ГРАЖДАНСКИМ ПРАВОНАРУШЕНИЯМ, А ТАКЖЕ ВЫТЕКАЮЩУЮ ИЗ НАСТОЯЩЕГО ОТЧЕТА О СООТВЕТСТВИИ ИЛИ СВЯЗАННУЮ С НИМ.",
|
||||
"relayRequestFailed": "Relayer {relayerName} не отвечает. Попробуйте сменить Relayer.",
|
||||
"selectProvider": "Выберите кошелёк",
|
||||
"walletDoesNotSupported": "Выбранный кошелёк не поддерживается",
|
||||
|
@ -151,7 +151,7 @@
|
||||
"nullifierHash": "Nullifier Hash",
|
||||
"verified": "Onaylanmış",
|
||||
"generatePdfReport": "PDF rapora dönüştür.",
|
||||
"compliancePrintWarning": "Bu Uyumluluk Raporu yalnızca bilgilendirme amaçlıdır. Bu raporun geçerliliğini Tornado’nun Uyumluluk Aracını (https://tornado.ws/compliance) veya burada yer alan bilgileri hesaplayabilen ve doğrulayabilen diğer herhangi bir şifreleme yazılımıyla (\"Tornado Uyumluluk Aracı\") kullanarak onaylamalısınız.) Bu raporda bulunan ve yukarıdaki araç tarafından sağlanan bilgiler arasındaki herhangi bir tutarsızlık, rapordaki bilgilerin yanlış ve/veya sahte olduğunu gösterir.{newline} UYGUNLUK RAPORU, HERHANGİ BİR GARANTİ OLMADAN tamamen\"OLDUĞU GİBİ\" SUNULMAKTADIR. BELİRLİ BİR AMACA UYGUNLUK VE İHLAL ETMEME GARANTİLERİ DAHİLDİR ANCAK BUNLARLA SINIRLI OLMAMAK ÜZERE ZIMNİ VEYA ZIMNİ OLARAK GEÇERLİDİR. TORNADO.CASH UYUM ARACININ YAZARLARI RAPORDAN KAYNAKLANAN, UYUMLULUKTAN KAYNAKLANAN VEYA BAĞLANTILI OLARAK SÖZLEŞME, HAKSIZ YA DA BAŞKA BİR DURUMDA OLAN HERHANGİ BİR İDDİADAN, ZARAR VEYA BAŞKA SORUMLULUKTAN SORUMLU TUTULAMAZ.",
|
||||
"compliancePrintWarning": "Bu Uyumluluk Raporu yalnızca bilgilendirme amaçlıdır. Bu raporun geçerliliğini Tornado’nun Uyumluluk Aracını (https://tornadocash.eth.link/compliance) veya burada yer alan bilgileri hesaplayabilen ve doğrulayabilen diğer herhangi bir şifreleme yazılımıyla (\"Tornado Uyumluluk Aracı\") kullanarak onaylamalısınız.) Bu raporda bulunan ve yukarıdaki araç tarafından sağlanan bilgiler arasındaki herhangi bir tutarsızlık, rapordaki bilgilerin yanlış ve/veya sahte olduğunu gösterir.{newline} UYGUNLUK RAPORU, HERHANGİ BİR GARANTİ OLMADAN tamamen\"OLDUĞU GİBİ\" SUNULMAKTADIR. BELİRLİ BİR AMACA UYGUNLUK VE İHLAL ETMEME GARANTİLERİ DAHİLDİR ANCAK BUNLARLA SINIRLI OLMAMAK ÜZERE ZIMNİ VEYA ZIMNİ OLARAK GEÇERLİDİR. TORNADO.CASH UYUM ARACININ YAZARLARI RAPORDAN KAYNAKLANAN, UYUMLULUKTAN KAYNAKLANAN VEYA BAĞLANTILI OLARAK SÖZLEŞME, HAKSIZ YA DA BAŞKA BİR DURUMDA OLAN HERHANGİ BİR İDDİADAN, ZARAR VEYA BAŞKA SORUMLULUKTAN SORUMLU TUTULAMAZ.",
|
||||
"relayRequestFailed": "Relayer {relayerName} çöktü. lütfen başka bir relayer seçin.",
|
||||
"selectProvider": "Sağlayıcı seçin",
|
||||
"walletDoesNotSupported": "Bu cüzdan desteklenmiyor",
|
||||
|
@ -151,7 +151,7 @@
|
||||
"nullifierHash": "无效符",
|
||||
"verified": "已验证",
|
||||
"generatePdfReport": "生成 PDF 报告",
|
||||
"compliancePrintWarning": "这本来源证明报告仅供参考的。 你应该使用Tornado的来源证明工具来确认报告 (https://tornado.ws/compliance) 的有效性,或者与可以算出和验证此处包含信息的任何其他密码学软件 (\"Tornado来源证明工具\") 一起使用。 报告中发现的信息与上述工具提供的信息之间存在任何差异,表明报告中的信息是不正确的{newline} 来源证明报告按 \"原样,\" 提供,不提供任何明示或暗示担保,包括但不限于对适销性,用途的适用性和非侵权专利的担保。 无论是出于合同要求、侵权或其他原因,由本来源证明报告引起与相关的任何索赔,损害或其他责任,Tornado.cash的作者概不负责。",
|
||||
"compliancePrintWarning": "这本来源证明报告仅供参考的。 你应该使用Tornado的来源证明工具来确认报告 (https://tornadocash.eth.link/compliance) 的有效性,或者与可以算出和验证此处包含信息的任何其他密码学软件 (\"Tornado来源证明工具\") 一起使用。 报告中发现的信息与上述工具提供的信息之间存在任何差异,表明报告中的信息是不正确的{newline} 来源证明报告按 \"原样,\" 提供,不提供任何明示或暗示担保,包括但不限于对适销性,用途的适用性和非侵权专利的担保。 无论是出于合同要求、侵权或其他原因,由本来源证明报告引起与相关的任何索赔,损害或其他责任,Tornado.cash的作者概不负责。",
|
||||
"relayRequestFailed": "中继者 {relayerName} 无法使用,请选择其他中继者。",
|
||||
"selectProvider": "请选择钱包",
|
||||
"walletDoesNotSupported": "此钱包不受支持",
|
||||
|
@ -25,7 +25,7 @@ export async function _encryptFormatTx({ dispatch, getters, rootGetters }, { eve
|
||||
if (!instance) {
|
||||
return acc
|
||||
}
|
||||
const name = `${netId}${instance.amount}${instance.currency}`
|
||||
const name = `${instance.amount}${instance.currency}`
|
||||
if (!acc[name]) {
|
||||
const service = eventsInterface.getService({ netId, ...instance })
|
||||
acc[name] = { ...instance, service }
|
||||
@ -49,7 +49,7 @@ export async function _encryptFormatTx({ dispatch, getters, rootGetters }, { eve
|
||||
if (!instance) {
|
||||
return
|
||||
}
|
||||
const { service } = instances[`${netId}${instance.amount}${instance.currency}`]
|
||||
const { service } = instances[`${instance.amount}${instance.currency}`]
|
||||
return getDeposit({ event, netId, service, instance })
|
||||
})
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
export const blockSyncInterval = 10000
|
||||
export const enabledChains = ['1', '10', '56', '100', '137', '43114', '42161']
|
||||
export const enabledChains = ['1', '10', '56', '100', '137', '42161']
|
||||
export const chainsWithEncryptedNotes = ['1', '5', '56', '100', '137']
|
||||
export default {
|
||||
netId1: {
|
||||
@ -22,13 +21,9 @@ export default {
|
||||
networkName: 'Ethereum Mainnet',
|
||||
deployedBlock: 9116966,
|
||||
rpcUrls: {
|
||||
chainnodes: {
|
||||
name: 'Tornado RPC',
|
||||
url: 'https://mainnet.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607'
|
||||
},
|
||||
mevblockerRPC: {
|
||||
name: 'MevblockerRPC',
|
||||
url: 'https://rpc.mevblocker.io'
|
||||
secureRPC: {
|
||||
name: 'SecureRPC',
|
||||
url: 'https://api.securerpc.com/v1'
|
||||
},
|
||||
llamaRPC: {
|
||||
name: 'llamarpc',
|
||||
@ -123,7 +118,7 @@ export default {
|
||||
'torn.contract.tornadocash.eth': '0x77777FeDdddFfC19Ff86DB637967013e6C6A116C',
|
||||
'governance.contract.tornadocash.eth': '0x5efda50f22d34F262c29268506C5Fa42cB56A1Ce',
|
||||
'tornado-router.contract.tornadocash.eth': '0xd90e2f925DA726b50C4Ed8D0Fb90Ad053324F31b',
|
||||
'staking-rewards.contract.tornadocash.eth': '0x5B3f656C80E8ddb9ec01Dd9018815576E9238c29'
|
||||
'staking-rewards.contract.tornadocash.eth': '0x2FC93484614a34f26F7970CBB94615bA109BB4bf'
|
||||
},
|
||||
netId56: {
|
||||
rpcCallRetryAttempt: 15,
|
||||
@ -147,13 +142,17 @@ export default {
|
||||
multicall: '0x41263cba59eb80dc200f3e2544eda4ed6a90e76c',
|
||||
echoContractAccount: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
|
||||
rpcUrls: {
|
||||
chainnodes: {
|
||||
name: 'Tornado RPC',
|
||||
url: 'https://bsc-mainnet.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607'
|
||||
},
|
||||
oneRPC: {
|
||||
name: '1RPC',
|
||||
url: 'https://1rpc.io/bnb'
|
||||
},
|
||||
blockPi: {
|
||||
name: 'BlockPi',
|
||||
url: 'https://bsc.blockpi.network/v1/rpc/public'
|
||||
},
|
||||
nodeReal: {
|
||||
name: 'NodeReal',
|
||||
url: 'https://bsc-mainnet.nodereal.io/v1/64a9df0874fb4a93b9d0a3849de012d3'
|
||||
}
|
||||
},
|
||||
tokens: {
|
||||
@ -198,9 +197,9 @@ export default {
|
||||
multicall: '0x11ce4B23bD875D7F5C6a31084f55fDe1e9A87507',
|
||||
echoContractAccount: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
|
||||
rpcUrls: {
|
||||
chainnodes: {
|
||||
name: 'Tornado RPC',
|
||||
url: 'https://polygon-mainnet.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607'
|
||||
polygonRpc: {
|
||||
name: 'Polygon RPC',
|
||||
url: 'https://polygon-rpc.com'
|
||||
},
|
||||
oneRpc: {
|
||||
name: '1RPC',
|
||||
@ -250,13 +249,17 @@ export default {
|
||||
echoContractAccount: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
|
||||
ovmGasPriceOracleContract: '0x420000000000000000000000000000000000000F',
|
||||
rpcUrls: {
|
||||
chainnodes: {
|
||||
name: 'Tornado RPC',
|
||||
url: 'https://optimism-mainnet.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607'
|
||||
blockPi: {
|
||||
name: 'BlockPi',
|
||||
url: 'https://optimism.blockpi.network/v1/rpc/public'
|
||||
},
|
||||
oneRpc: {
|
||||
name: '1RPC',
|
||||
url: 'https://1rpc.io/op'
|
||||
},
|
||||
Optimism: {
|
||||
name: 'Optimism',
|
||||
url: 'https://mainnet.optimism.io'
|
||||
}
|
||||
},
|
||||
tokens: {
|
||||
@ -301,14 +304,14 @@ export default {
|
||||
multicall: '0x842eC2c7D803033Edf55E478F461FC547Bc54EB2',
|
||||
echoContractAccount: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
|
||||
rpcUrls: {
|
||||
chainnodes: {
|
||||
name: 'Tornado RPC',
|
||||
url: 'https://arbitrum-one.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607'
|
||||
},
|
||||
oneRpc: {
|
||||
name: '1rpc',
|
||||
url: 'https://1rpc.io/arb'
|
||||
},
|
||||
blockPi: {
|
||||
name: 'BlockPi',
|
||||
url: 'https://arbitrum.blockpi.network/v1/rpc/public'
|
||||
},
|
||||
Arbitrum: {
|
||||
name: 'Arbitrum RPC',
|
||||
url: 'https://arb1.arbitrum.io/rpc'
|
||||
@ -356,9 +359,9 @@ export default {
|
||||
multicall: '0xb5b692a88bdfc81ca69dcb1d924f59f0413a602a',
|
||||
echoContractAccount: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
|
||||
rpcUrls: {
|
||||
chainnodes: {
|
||||
name: 'Tornado RPC',
|
||||
url: 'https://gnosis-mainnet.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607'
|
||||
communityResolver: {
|
||||
name: 'Community RPC Resolver',
|
||||
url: 'https://development.tornadocash.community/rpc/v1'
|
||||
},
|
||||
blockPi: {
|
||||
name: 'BlockPi',
|
||||
@ -407,14 +410,18 @@ export default {
|
||||
multicall: '0xe86e3989c74293Acc962156cd3F525c07b6a1B6e',
|
||||
echoContractAccount: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4',
|
||||
rpcUrls: {
|
||||
communityRPC: {
|
||||
name: 'Tornado RPC',
|
||||
url: 'https://avalanche-rpc.tornado.ws/ext/bc/C/rpc'
|
||||
},
|
||||
publicRpc1: {
|
||||
name: 'Avalanche RPC',
|
||||
url: 'https://api.avax.network/ext/bc/C/rpc'
|
||||
},
|
||||
blockPi: {
|
||||
name: 'BlockPi',
|
||||
url: 'https://avalanche.blockpi.network/v1/rpc/public'
|
||||
},
|
||||
publicRpc2: {
|
||||
name: 'Avalanche Public PRC',
|
||||
url: 'https://avalanche-evm.publicnode.com'
|
||||
},
|
||||
oneRpc: {
|
||||
name: '1RPC',
|
||||
ulr: 'https://1rpc.io/avax/'
|
||||
@ -462,9 +469,9 @@ export default {
|
||||
echoContractAccount: '0x37e6859804b6499d1e4a86d70a5fdd5de6a0ac65',
|
||||
aggregatorContract: '0x8cb1436F64a3c33aD17bb42F94e255c4c0E871b2',
|
||||
rpcUrls: {
|
||||
chainnodes: {
|
||||
name: 'Tornado RPC',
|
||||
url: 'https://goerli.chainnodes.org/d692ae63-0a7e-43e0-9da9-fe4f4cc6c607'
|
||||
Infura: {
|
||||
name: 'Infura',
|
||||
url: 'https://goerli.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161'
|
||||
}
|
||||
},
|
||||
tokens: {
|
||||
|
@ -79,7 +79,7 @@ export default {
|
||||
{
|
||||
hid: 'og:url',
|
||||
property: 'og:url',
|
||||
content: 'https://tornado.ws'
|
||||
content: 'https://tornado.cash'
|
||||
},
|
||||
{
|
||||
hid: 'og:type',
|
||||
@ -89,7 +89,7 @@ export default {
|
||||
{
|
||||
hid: 'og:image',
|
||||
property: 'og:image',
|
||||
content: 'https://tornado.ws/tw.png'
|
||||
content: 'https://tornado.cash/tw.png'
|
||||
},
|
||||
{
|
||||
hid: 'description',
|
||||
|
10
package.json
10
package.json
@ -7,14 +7,15 @@
|
||||
"lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
|
||||
"precommit": "yarn lint",
|
||||
"test": "jest",
|
||||
"dev": "cross-env NODE_OPTIONS='--max-old-space-size=8192' nuxt",
|
||||
"dev": "NODE_OPTIONS='--max-old-space-size=8192' nuxt",
|
||||
"build": "nuxt build",
|
||||
"start": "nuxt start",
|
||||
"update:zip": "node -r esm scripts/updateZip.js",
|
||||
"update:events": "node -r esm scripts/updateEvents.js --network",
|
||||
"update:unwanted": "node -r esm scripts/updateUnwanted.js --network",
|
||||
"update:encrypted": "node -r esm scripts/updateEncryptedEvents.js --network",
|
||||
"update:tree": "node -r esm scripts/updateTree.js --network",
|
||||
"generate": "cross-env NODE_OPTIONS='--max-old-space-size=8192' nuxt generate && cp dist/404.html dist/ipfs-404.html",
|
||||
"generate": "NODE_OPTIONS='--max-old-space-size=8192' nuxt generate && cp dist/404.html dist/ipfs-404.html",
|
||||
"check:sync": "node -r esm scripts/checkEventsSync.js",
|
||||
"ipfsUpload": "node scripts/ipfsUpload.js",
|
||||
"deploy:ipfs": "yarn generate && yarn ipfsUpload"
|
||||
@ -49,14 +50,13 @@
|
||||
"nuxt-web3-provider": "0.1.4",
|
||||
"push-dir": "^0.4.1",
|
||||
"recursive-fs": "^2.1.0",
|
||||
"snarkjs": "git+https://development.tornadocash.community/tornadocash/snarkjs.git#869181cfaf7526fe8972073d31655493a04326d5",
|
||||
"v-idle": "^0.2.0",
|
||||
"vue-clipboard2": "^0.3.1",
|
||||
"vue-i18n": "^8.15.4",
|
||||
"vuex-persistedstate": "^2.7.0",
|
||||
"web3": "1.5.2",
|
||||
"cross-env": "7.0.3",
|
||||
"@tornado/snarkjs": "0.1.20-p2",
|
||||
"@tornado/websnark": "0.0.4-p1"
|
||||
"websnark": "git+https://development.tornadocash.community/tornadocash/websnark.git#671762fab73f01771d0e7ebcf6b6a3123e193fb4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nuxtjs/eslint-config": "^1.1.2",
|
||||
|
@ -24,7 +24,7 @@
|
||||
>
|
||||
<i18n path="trustBanner.trustLess">
|
||||
<template v-slot:link>
|
||||
<a href="https://tornado.ws/">{{ $t('trustBanner.link') }}</a>
|
||||
<a href="https://tornado.cash/">{{ $t('trustBanner.link') }}</a>
|
||||
</template>
|
||||
</i18n>
|
||||
</b-notification>
|
||||
@ -73,7 +73,7 @@
|
||||
</template>
|
||||
<template v-slot:linkThree>
|
||||
<a
|
||||
href="https://docs.tornado.ws/general/guides/post-censorship#RPC"
|
||||
href="https://hackmd.io/@gozzy/tornado-cash-post-censorship#RPC"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
|
@ -4,8 +4,12 @@ export default ({ store, isHMR, app }, inject) => {
|
||||
}
|
||||
function main() {
|
||||
const whiteListedDomains = [
|
||||
'tornadocash.3th.li',
|
||||
'tornadocash.3th.ws',
|
||||
'tornadocash.eth.link',
|
||||
'tornadocash.eth.limo',
|
||||
'tornadocashcommunity.3th.li',
|
||||
'tornadocashcommunity.3th.ws',
|
||||
'tornadocashcommunity.eth.link',
|
||||
'tornadocashcommunity.eth.limo'
|
||||
]
|
||||
|
@ -264,24 +264,24 @@ export default async (ctx, inject) => {
|
||||
Object.keys(tokens[token].instanceAddress).forEach((amount) => {
|
||||
if (nativeCurrency === token && netId === 1) {
|
||||
stores.push({
|
||||
name: `stringify_bloom_${netId}_${token}_${amount}`,
|
||||
name: `stringify_bloom_${token}_${amount}`,
|
||||
keyPath: 'hashBloom'
|
||||
})
|
||||
}
|
||||
|
||||
stores.push(
|
||||
{
|
||||
name: `deposits_${netId}_${token}_${amount}`,
|
||||
name: `deposits_${token}_${amount}`,
|
||||
keyPath: 'leafIndex', // the key by which it refers to the object must be in all instances of the storage
|
||||
indexes: DEPOSIT_INDEXES
|
||||
},
|
||||
{
|
||||
name: `withdrawals_${netId}_${token}_${amount}`,
|
||||
name: `withdrawals_${token}_${amount}`,
|
||||
keyPath: 'blockNumber',
|
||||
indexes: WITHDRAWAL_INDEXES
|
||||
},
|
||||
{
|
||||
name: `stringify_tree_${netId}_${token}_${amount}`,
|
||||
name: `stringify_tree_${token}_${amount}`,
|
||||
keyPath: 'hashTree'
|
||||
}
|
||||
)
|
||||
|
@ -23,9 +23,9 @@ function main(store) {
|
||||
window.multipleTabsDetected = true
|
||||
window.onbeforeunload = null
|
||||
window.alert(
|
||||
'Multiple tabs opened. Your page will be closed. Please only use single instance of https://tornado.ws'
|
||||
'Multiple tabs opened. Your page will be closed. Please only use single instance of https://tornado.cash'
|
||||
)
|
||||
window.location = 'https://t.me/TornadoOfficial'
|
||||
window.location = 'https://twitter.com/tornadocash'
|
||||
}
|
||||
}
|
||||
|
||||
|
3
scripts/helpers/args.js
Normal file
3
scripts/helpers/args.js
Normal file
@ -0,0 +1,3 @@
|
||||
export function needsArg(argname) {
|
||||
throw Error('classic-ui: this function requires the argument: ' + argname)
|
||||
}
|
@ -2,12 +2,12 @@ import fs from 'fs'
|
||||
import zlib from 'zlib'
|
||||
import Web3 from 'web3'
|
||||
|
||||
import networkConfig, { blockSyncInterval } from '../../networkConfig'
|
||||
import networkConfig from '../../networkConfig'
|
||||
|
||||
export function download({ name, directory }) {
|
||||
const path = `${directory}${name}.gz`.toLowerCase()
|
||||
|
||||
const data = fs.readFileSync(path, { flag: 'as+' })
|
||||
const data = fs.readFileSync(path)
|
||||
const content = zlib.inflateSync(data)
|
||||
|
||||
return content
|
||||
@ -53,7 +53,7 @@ export async function getPastEvents({ type, fromBlock, netId, events, contractAt
|
||||
const blockDifference = Math.ceil(blockNumberBuffer - fromBlock)
|
||||
|
||||
// eth_logs and eth_filter are restricted > 10,000 block queries
|
||||
const blockRange = blockSyncInterval ? blockSyncInterval : 10_000
|
||||
const blockRange = 10000
|
||||
|
||||
let chunksCount = blockDifference === 0 ? 1 : Math.ceil(blockDifference / blockRange)
|
||||
const chunkSize = Math.ceil(blockDifference / chunksCount)
|
||||
|
@ -1,2 +1,3 @@
|
||||
export { needsArg } from "./args"
|
||||
export { download, loadCachedEvents, getPastEvents } from './download'
|
||||
export { save } from './save'
|
||||
|
@ -23,7 +23,7 @@ async function saveEncryptedNote(netId) {
|
||||
let encryptedEvents = []
|
||||
const name = `encrypted_notes_${netId}.json`
|
||||
|
||||
const cachedEvents = loadCachedEvents({
|
||||
const cachedEvents = await loadCachedEvents({
|
||||
name,
|
||||
directory: EVENTS_PATH,
|
||||
deployedBlock: constants.ENCRYPTED_NOTES_BLOCK
|
||||
@ -61,14 +61,17 @@ async function saveEncryptedNote(netId) {
|
||||
fs.writeFileSync(`${EVENTS_PATH}${name}`, eventsJson)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param netId The netId of the chain to synchronize encrypted note events for.
|
||||
*/
|
||||
async function main() {
|
||||
const [, , , chain] = process.argv
|
||||
const [, , , netId] = process.argv
|
||||
|
||||
if (!enabledChains.includes(chain)) {
|
||||
if (!enabledChains.includes(netId)) {
|
||||
throw new Error(`Supported chain ids ${enabledChains.join(', ')}`)
|
||||
}
|
||||
|
||||
await saveEncryptedNote(chain)
|
||||
await saveEncryptedNote(netId)
|
||||
}
|
||||
|
||||
main()
|
||||
|
@ -6,117 +6,94 @@ import { uniqBy } from 'lodash'
|
||||
import networkConfig, { enabledChains } from '../networkConfig'
|
||||
import ABI from '../abis/Instance.abi.json'
|
||||
|
||||
import { loadCachedEvents, getPastEvents } from './helpers'
|
||||
import { loadCachedEvents, getPastEvents, needsArg } from './helpers'
|
||||
|
||||
const EVENTS_PATH = './static/events/'
|
||||
const EVENTS = ['Deposit', 'Withdrawal']
|
||||
|
||||
function parseArg(netId, tokenOrEvent) {
|
||||
const { tokens } = networkConfig[`netId${netId}`]
|
||||
const keys = Object.keys(tokens)
|
||||
if (tokenOrEvent !== undefined) {
|
||||
const lower = tokenOrEvent.toLowerCase()
|
||||
return keys.includes(lower)
|
||||
? { token: lower }
|
||||
: { event: lower[0].toUpperCase() + lower.slice(1).toLowerCase() }
|
||||
} else return undefined
|
||||
}
|
||||
async function main(type, netId, chosenToken) {
|
||||
const { tokens, nativeCurrency, deployedBlock } = networkConfig[`netId${netId}`]
|
||||
const token = chosenToken !== undefined ? chosenToken : nativeCurrency
|
||||
|
||||
function parseDepositEvent({ blockNumber, transactionHash, returnValues }) {
|
||||
const { commitment, leafIndex, timestamp } = returnValues
|
||||
return {
|
||||
timestamp,
|
||||
commitment,
|
||||
blockNumber,
|
||||
transactionHash,
|
||||
leafIndex: Number(leafIndex)
|
||||
}
|
||||
}
|
||||
const CONTRACTS = tokens[token].instanceAddress
|
||||
|
||||
function parseWithdrawalEvent({ blockNumber, transactionHash, returnValues }) {
|
||||
const { nullifierHash, to, fee } = returnValues
|
||||
return {
|
||||
to,
|
||||
fee,
|
||||
blockNumber,
|
||||
nullifierHash,
|
||||
transactionHash
|
||||
}
|
||||
}
|
||||
for (const [instance, _contract] of Object.entries(CONTRACTS)) {
|
||||
const cachedEvents = loadCachedEvents({
|
||||
name: `${type.toLowerCase()}s_${netId}_${token}_${instance}.json`,
|
||||
directory: EVENTS_PATH,
|
||||
deployedBlock
|
||||
})
|
||||
|
||||
function filterWithdrawalEvents(events) {
|
||||
return uniqBy(events, 'nullifierHash').sort((a, b) => a.blockNumber - b.blockNumber)
|
||||
}
|
||||
console.log('Update events for', instance, token.toUpperCase(), `${type.toLowerCase()}s`)
|
||||
console.log('cachedEvents count - ', cachedEvents.events.length)
|
||||
console.log('lastBlock - ', cachedEvents.lastBlock)
|
||||
|
||||
function filterDepositEvents(events) {
|
||||
return events.filter((e, index) => Number(e.leafIndex) === index)
|
||||
}
|
||||
let events = []
|
||||
|
||||
async function main(netId, chosenToken, chosenEvent) {
|
||||
const { tokens, deployedBlock } = networkConfig[`netId${netId}`]
|
||||
events = await getPastEvents({
|
||||
type,
|
||||
netId,
|
||||
events,
|
||||
contractAttrs: [ABI, _contract],
|
||||
fromBlock: cachedEvents.lastBlock + 1
|
||||
})
|
||||
|
||||
const tokenSymbols = chosenToken !== undefined ? [chosenToken] : Object.keys(tokens)
|
||||
const eventNames = chosenEvent !== undefined ? [chosenEvent] : ['Deposit', 'Withdrawal']
|
||||
|
||||
for (const eventName of eventNames) {
|
||||
// Get the parser that we need
|
||||
const parser = eventName === 'Deposit' ? parseDepositEvent : parseWithdrawalEvent
|
||||
// Get the parser that we need
|
||||
const filter = eventName === 'Deposit' ? filterDepositEvents : filterWithdrawalEvents
|
||||
|
||||
for (const tokenSymbol of tokenSymbols) {
|
||||
// Now load the denominations and address
|
||||
const instanceData = Object.entries(tokens[tokenSymbol].instanceAddress)
|
||||
|
||||
// And now sync
|
||||
for (const data of instanceData) {
|
||||
const denom = data[0]
|
||||
const address = data[1]
|
||||
|
||||
// Now load cached events
|
||||
const cachedEvents = loadCachedEvents({
|
||||
name: `${eventName.toLowerCase()}s_${netId}_${tokenSymbol}_${denom}.json`,
|
||||
directory: EVENTS_PATH,
|
||||
deployedBlock
|
||||
})
|
||||
|
||||
console.log('Update events for', denom, tokenSymbol.toUpperCase(), `${eventName.toLowerCase()}s`)
|
||||
console.log('cachedEvents count - ', cachedEvents.events.length)
|
||||
console.log('lastBlock - ', cachedEvents.lastBlock)
|
||||
|
||||
let events = await getPastEvents({
|
||||
type: eventName,
|
||||
fromBlock: cachedEvents.lastBlock + 1,
|
||||
netId: netId,
|
||||
events: [],
|
||||
contractAttrs: [ABI, address]
|
||||
})
|
||||
|
||||
events = filter(cachedEvents.events.concat(events.map(parser)))
|
||||
|
||||
fs.writeFileSync(
|
||||
`${EVENTS_PATH}${eventName.toLowerCase()}s_${netId}_${tokenSymbol}_${denom}.json`,
|
||||
JSON.stringify(events, null, 2) + '\n'
|
||||
)
|
||||
}
|
||||
if (type === 'Deposit') {
|
||||
events = events.map(({ blockNumber, transactionHash, returnValues }) => {
|
||||
const { commitment, leafIndex, timestamp } = returnValues
|
||||
return {
|
||||
timestamp,
|
||||
commitment,
|
||||
blockNumber,
|
||||
transactionHash,
|
||||
leafIndex: Number(leafIndex)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (type === 'Withdrawal') {
|
||||
events = events.map(({ blockNumber, transactionHash, returnValues }) => {
|
||||
const { nullifierHash, to, fee } = returnValues
|
||||
return {
|
||||
to,
|
||||
fee,
|
||||
blockNumber,
|
||||
nullifierHash,
|
||||
transactionHash
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
let freshEvents = cachedEvents.events.concat(events)
|
||||
|
||||
if (type === 'Withdrawal') {
|
||||
freshEvents = uniqBy(freshEvents, 'nullifierHash').sort((a, b) => a.blockNumber - b.blockNumber)
|
||||
} else {
|
||||
freshEvents = freshEvents.filter((e, index) => Number(e.leafIndex) === index)
|
||||
}
|
||||
|
||||
const eventsJson = JSON.stringify(freshEvents, null, 2) + '\n'
|
||||
|
||||
fs.writeFileSync(`${EVENTS_PATH}${type.toLowerCase()}s_${netId}_${token}_${instance}.json`, eventsJson)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param netId ID of the network for which event(s) should be synced.
|
||||
* @param tokenOrEvent Optional token or event.
|
||||
* @param eventOrToken Optional token or event. Overwrites the former option.
|
||||
* @param netId The netId of the chain to synchronize deposits and withdrawal events for.
|
||||
* @param chosenToken Optional. Default is native. The token for which to synchronize the events.
|
||||
*/
|
||||
async function start() {
|
||||
const [, , , netId, tokenOrEvent, eventOrToken] = process.argv
|
||||
|
||||
const args = { ...parseArg(netId, tokenOrEvent), ...parseArg(netId, eventOrToken) }
|
||||
const [, , , netId, chosenToken] = process.argv
|
||||
|
||||
if (!enabledChains.includes(netId)) {
|
||||
throw new Error(`Supported chain ids ${enabledChains.join(', ')}`)
|
||||
}
|
||||
|
||||
await main(netId, args.token, args.event)
|
||||
if (!netId) needsArg('netId')
|
||||
|
||||
for (const event of EVENTS) {
|
||||
await main(event, netId, chosenToken)
|
||||
}
|
||||
}
|
||||
|
||||
start()
|
||||
|
@ -78,7 +78,7 @@ async function createTree(netId) {
|
||||
|
||||
console.log('createTree', { type, instance })
|
||||
|
||||
const { events } = loadCachedEvents({
|
||||
const { events } = await loadCachedEvents({
|
||||
name: `${type}s_${netId}_${nativeCurrency}_${instance}.json`,
|
||||
directory: EVENTS_PATH,
|
||||
deployedBlock
|
||||
@ -142,17 +142,17 @@ async function initMimc() {
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const [, , , chain] = process.argv
|
||||
const [, , , netId] = process.argv
|
||||
|
||||
if (!enabledChains.includes(chain)) {
|
||||
if (!enabledChains.includes(netId)) {
|
||||
throw new Error(`Supported chain ids ${enabledChains.join(', ')}`)
|
||||
}
|
||||
|
||||
await initMimc()
|
||||
|
||||
await createTree(chain)
|
||||
await createTree(netId)
|
||||
|
||||
createTreeZip(chain)
|
||||
createTreeZip(netId)
|
||||
}
|
||||
|
||||
main()
|
||||
|
162
scripts/updateUnwanted.js
Normal file
162
scripts/updateUnwanted.js
Normal file
@ -0,0 +1,162 @@
|
||||
import fs from 'fs'
|
||||
|
||||
import Web3 from 'web3'
|
||||
|
||||
import { uniq } from 'lodash'
|
||||
|
||||
import { loadCachedEvents, needsArg, save } from './helpers'
|
||||
|
||||
import networkConfig, { enabledChains } from '../networkConfig'
|
||||
|
||||
import RELAYER_REGISTRY_ABI from '../abis/RelayerRegistry.abi.json'
|
||||
import AGGREGATOR_REGISTRY_ABI from '../abis/Aggregator.abi.json'
|
||||
|
||||
const RELAYERS_DIR_PATH = './static/relayers/'
|
||||
|
||||
const zeroAddress = '0x0000000000000000000000000000000000000000'
|
||||
|
||||
const subdomains = Object.values(networkConfig).map(({ ensSubdomainKey }) => ensSubdomainKey)
|
||||
|
||||
async function update(netId, untilBlock, rpcIndex) {
|
||||
// Get all of the network data we need
|
||||
// "Contract" in fact means address
|
||||
const { rpcUrls, tokens, registryContract, aggregatorContract, routerContract } = networkConfig[
|
||||
`netId${netId}`
|
||||
]
|
||||
|
||||
// Get the rpcUrl we have chosen
|
||||
const rpcUrl = Object.values(rpcUrls)[rpcIndex].url
|
||||
|
||||
// Prepare the provider
|
||||
const provider = new Web3(new Web3.providers.HttpProvider(rpcUrl))
|
||||
|
||||
// Get the contracts
|
||||
const aggregator = new provider.eth.Contract(AGGREGATOR_REGISTRY_ABI, aggregatorContract)
|
||||
const registry = new provider.eth.Contract(RELAYER_REGISTRY_ABI, registryContract)
|
||||
|
||||
// Get all tokens for the network
|
||||
const tokenSymbols = Object.keys(tokens)
|
||||
|
||||
// All avoiding txs
|
||||
const avoids = []
|
||||
|
||||
// Start discovering unwanted relayers
|
||||
for (const tokenSymbol of tokenSymbols) {
|
||||
// Load denominations
|
||||
const denoms = Object.entries(tokens[tokenSymbol].instanceAddress)
|
||||
|
||||
// Go through all denominations
|
||||
for (const denom of denoms) {
|
||||
// Load the cache, we need it in reverse
|
||||
const withdrawals = loadCachedEvents({
|
||||
name: `withdrawals_${netId}_${tokenSymbol}_${denom[0]}.json`,
|
||||
directory: `./static/events/`,
|
||||
deployedBlock: undefined
|
||||
}).events.reverse()
|
||||
|
||||
// Start searching
|
||||
for (const withdrawal of withdrawals) {
|
||||
// If we are at the until block then stop scanning
|
||||
if (withdrawal.blockNumber < untilBlock) {
|
||||
break
|
||||
}
|
||||
|
||||
// Get the tx, we need proper "to" data
|
||||
const tx = await provider.eth.getTransaction(withdrawal.transactionHash)
|
||||
|
||||
// Found a sus tx
|
||||
if (tx.to !== routerContract) {
|
||||
// Look for the owner
|
||||
const owner = await registry.methods.workers(tx.from).call()
|
||||
|
||||
// If not zeroAddress, it's an owner and he's misbehaving!
|
||||
if (owner != zeroAddress) {
|
||||
// Get his ens hash
|
||||
const node = await registry.methods.getRelayerEnsHash(owner).call()
|
||||
|
||||
// Get his records
|
||||
const data = (await aggregator.methods.relayersData([node], subdomains).call())[0]
|
||||
|
||||
// Since we are doing this in reverse, the last element is going to have the lowest block number
|
||||
// We are storing this much data because relayers doing unwanted stuff should be quite rare
|
||||
// And when this rolls out, it should become even moreso rare
|
||||
avoids.push({
|
||||
address: owner,
|
||||
node: node,
|
||||
net: netId,
|
||||
token: tokenSymbol,
|
||||
denomination: denom[0],
|
||||
caughtAtTxHash: tx.hash,
|
||||
blockNumber: tx.blockNumber,
|
||||
records: data.records.filter((record) => record !== '')
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// This is a set of the avoiding data meaning unwanted relayer + transaction proof
|
||||
// Block numbers are descending
|
||||
const cachedAvoids = loadCachedEvents({
|
||||
name: 'avoids.json',
|
||||
directory: RELAYERS_DIR_PATH,
|
||||
deployedBlock: 99999999999999 // Has to be the future formally
|
||||
}).events
|
||||
|
||||
// This on the other hand is a set of the unwanted relayers
|
||||
const cachedUnwanted = loadCachedEvents({
|
||||
name: 'unwanted.json',
|
||||
directory: RELAYERS_DIR_PATH,
|
||||
deployedBlock: undefined // No such concept
|
||||
}).events
|
||||
|
||||
// Now prepare for latter data, kill duplicates to make it a set (hopefully)
|
||||
const unwanted = uniq(
|
||||
avoids.map((avoidingTx) => {
|
||||
return {
|
||||
address: avoidingTx.address,
|
||||
node: avoidingTx.node,
|
||||
records: avoidingTx.records
|
||||
}
|
||||
})
|
||||
)
|
||||
|
||||
// Requires path
|
||||
if (!fs.existsSync(RELAYERS_DIR_PATH)) fs.mkdirSync(RELAYERS_DIR_PATH)
|
||||
|
||||
// Write down avoids
|
||||
fs.writeFileSync(
|
||||
`${RELAYERS_DIR_PATH}avoids.json`,
|
||||
JSON.stringify(cachedAvoids.concat(avoids), null, 2) + '\n'
|
||||
)
|
||||
|
||||
// Write down unwanted relayers
|
||||
fs.writeFileSync(
|
||||
`${RELAYERS_DIR_PATH}unwanted.json`,
|
||||
JSON.stringify(cachedUnwanted.concat(unwanted), null, 2) + '\n'
|
||||
)
|
||||
|
||||
// Finally, save both
|
||||
save(`${RELAYERS_DIR_PATH}avoids.json`)
|
||||
save(`${RELAYERS_DIR_PATH}unwanted.json`)
|
||||
}
|
||||
|
||||
/**
|
||||
* @param netId The netId of the chain to synchronize deposits and withdrawal events for.
|
||||
* @param untilBlock The LOWER block limit to which we will search for misbehaving relayers in all withdrawal event caches.
|
||||
* @param rpcIndex Optional. The RPC to use according to networkConfig.
|
||||
*/
|
||||
async function main() {
|
||||
const [, , , netId, untilBlock, rpcIndex] = process.argv
|
||||
|
||||
if (!enabledChains.includes(netId)) {
|
||||
throw new Error(`Supported chain ids ${enabledChains.join(', ')}`)
|
||||
}
|
||||
|
||||
if (!untilBlock) needsArg('untilBlock')
|
||||
|
||||
await update(netId, untilBlock, rpcIndex !== undefined ? rpcIndex : 0)
|
||||
}
|
||||
|
||||
main()
|
@ -464,7 +464,7 @@ class EventsFactory {
|
||||
}
|
||||
|
||||
getService = (payload) => {
|
||||
const instanceName = `${payload.netId}_${payload.currency}_${payload.amount}`
|
||||
const instanceName = `${payload.currency}_${payload.amount}`
|
||||
|
||||
if (this.instances.has(instanceName)) {
|
||||
return this.instances.get(instanceName)
|
||||
|
@ -186,7 +186,7 @@ class TreesFactory {
|
||||
instances = new Map()
|
||||
|
||||
getService = (payload) => {
|
||||
const instanceName = `${payload.netId}_${payload.currency}_${payload.amount}`
|
||||
const instanceName = `${payload.currency}_${payload.amount}`
|
||||
if (this.instances.has(instanceName)) {
|
||||
return this.instances.get(instanceName)
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ import { buildGroth16, download, getTornadoKeys } from './snark'
|
||||
|
||||
let groth16
|
||||
|
||||
const websnarkUtils = require('@tornado/websnark/src/utils')
|
||||
const websnarkUtils = require('websnark/src/utils')
|
||||
const { toWei, numberToHex, toBN, isAddress } = require('web3-utils')
|
||||
|
||||
const getStatisticStore = (acc, { tokens }) => {
|
||||
@ -324,7 +324,7 @@ const actions = {
|
||||
lastBlock = await this.$indexedDB(netId).getFromIndex({
|
||||
indexName: 'name',
|
||||
storeName: 'lastEvents',
|
||||
key: `${type}s_${netId}_${currency}_${amount}`
|
||||
key: `${type}s_${currency}_${amount}`
|
||||
})
|
||||
}
|
||||
|
||||
@ -661,7 +661,7 @@ const actions = {
|
||||
}
|
||||
},
|
||||
async buildTree({ dispatch }, { currency, amount, netId, commitmentHex }) {
|
||||
const treeInstanceName = `${netId}_${currency}_${amount}`
|
||||
const treeInstanceName = `${currency}_${amount}`
|
||||
const params = { netId, amount, currency }
|
||||
|
||||
const treeService = treesInterface.getService({
|
||||
|
@ -705,24 +705,16 @@ const actions = {
|
||||
break
|
||||
case 13:
|
||||
text = text.replace(/\\\\n\\\\n(\s)?(\\n)?/g, '\\n')
|
||||
break
|
||||
// Fix invalid JSON in proposal 15: replace single quotes with double and add comma before description
|
||||
case 15:
|
||||
text = text.replaceAll(`'`, `"`)
|
||||
text = text.replace('"description"', ',"description"')
|
||||
break
|
||||
case 16:
|
||||
text = text.replace('#16: ', '')
|
||||
break
|
||||
// Add title to empty (without title and description) hacker proposal 21
|
||||
case 21:
|
||||
return {
|
||||
title: 'Proposal #21: Restore Governance',
|
||||
description: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (text.includes(`'`)) {
|
||||
text = text.replaceAll(`'`, `"`)
|
||||
}
|
||||
if (text.includes(`" "`)) {
|
||||
text = text.replace(`" "`, `", "`)
|
||||
}
|
||||
|
||||
let title, description, rest
|
||||
try {
|
||||
;({ title, description } = JSON.parse(text))
|
||||
|
@ -8,7 +8,7 @@ import networkConfig from '@/networkConfig'
|
||||
|
||||
const { APP_ENS_NAME } = process.env
|
||||
|
||||
const groth16 = require('@tornado/websnark/src/groth16')
|
||||
const groth16 = require('websnark/src/groth16')
|
||||
|
||||
function buildGroth16() {
|
||||
const isMobile = detectMob()
|
||||
|
@ -129,7 +129,7 @@ export const actions = {
|
||||
const instances = txs.reduce((acc, curr) => {
|
||||
const [, currency, amount, netId] = curr.prefix.split('-')
|
||||
|
||||
const name = `${netId}${amount}${currency}`
|
||||
const name = `${amount}${currency}`
|
||||
if (!acc[name]) {
|
||||
const service = eventsInterface.getService({ netId, amount, currency })
|
||||
acc[name] = { currency, amount, netId, service }
|
||||
@ -161,7 +161,7 @@ export const actions = {
|
||||
txHash: tx.txHash,
|
||||
type: eventsType.DEPOSIT,
|
||||
commitment: tx.commitmentHex,
|
||||
service: instances[`${netId}${amount}${currency}`]
|
||||
service: instances[`${amount}${currency}`]
|
||||
})
|
||||
}
|
||||
},
|
||||
@ -213,7 +213,7 @@ export const actions = {
|
||||
if (!tx.isSpent) {
|
||||
const { currency, amount, netId, nullifierHex } = parseNote(`${tx.prefix}-${tx.note}`)
|
||||
|
||||
const isSpent = await instances[`${netId}${amount}${currency}`].service.findEvent({
|
||||
const isSpent = await instances[`${amount}${currency}`].service.findEvent({
|
||||
eventName: 'nullifierHash',
|
||||
eventToFind: nullifierHex,
|
||||
type: eventsType.WITHDRAWAL
|
||||
@ -364,7 +364,7 @@ export const actions = {
|
||||
if (tx && !tx.isSpent) {
|
||||
const { currency, amount, netId, nullifierHex } = parseNote(`${tx.prefix}-${tx.note}`)
|
||||
|
||||
const isSpent = await instances[`${netId}${amount}${currency}`].service.findEvent({
|
||||
const isSpent = await instances[`${amount}${currency}`].service.findEvent({
|
||||
eventName: 'nullifierHash',
|
||||
eventToFind: nullifierHex,
|
||||
type: eventsType.WITHDRAWAL
|
||||
|
61
yarn.lock
61
yarn.lock
@ -2109,27 +2109,6 @@
|
||||
dependencies:
|
||||
defer-to-connect "^1.0.1"
|
||||
|
||||
"@tornado/snarkjs@0.1.20-p2":
|
||||
version "0.1.20-p2"
|
||||
resolved "https://git.tornado.ws/api/packages/tornado-packages/npm/%40tornado%2Fsnarkjs/-/0.1.20-p2/snarkjs-0.1.20-p2.tgz#e25a1d4ca8305887202d02cb38077795108f1ec3"
|
||||
integrity sha512-3E+tmJXtYj7GE8DZ13IBTgqkgplembU/qxYczIOxyxxEYBRAubccr9hFMrAjCaYBh/Rq94lDd5G4SE/l08IrNA==
|
||||
dependencies:
|
||||
big-integer "^1.6.43"
|
||||
chai "^4.2.0"
|
||||
escape-string-regexp "^1.0.5"
|
||||
eslint "^5.16.0"
|
||||
keccak "^2.0.0"
|
||||
yargs "^12.0.5"
|
||||
|
||||
"@tornado/websnark@0.0.4-p1":
|
||||
version "0.0.4-p1"
|
||||
resolved "https://git.tornado.ws/api/packages/tornado-packages/npm/%40tornado%2Fwebsnark/-/0.0.4-p1/websnark-0.0.4-p1.tgz#9a44a06a53d6931f85c8454cf31b7239c150ff46"
|
||||
integrity sha512-sWQESVWarJsjjc0/t4G2eAy/Z1eZfzDG2V51jDzJBg0tQQkAjhBXsGIn+xdCIvPwn7bMvmDGxpicCzNQhieOJg==
|
||||
dependencies:
|
||||
"@tornado/snarkjs" "0.1.20-p2"
|
||||
big-integer "1.6.42"
|
||||
wasmbuilder "0.0.3"
|
||||
|
||||
"@types/anymatch@*":
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a"
|
||||
@ -5378,13 +5357,6 @@ create-require@^1.0.2, create-require@^1.1.0:
|
||||
resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333"
|
||||
integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==
|
||||
|
||||
cross-env@7.0.3:
|
||||
version "7.0.3"
|
||||
resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf"
|
||||
integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==
|
||||
dependencies:
|
||||
cross-spawn "^7.0.1"
|
||||
|
||||
cross-fetch@^2.1.0:
|
||||
version "2.2.5"
|
||||
resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-2.2.5.tgz#afaf5729f3b6c78d89c9296115c9f142541a5705"
|
||||
@ -5422,15 +5394,6 @@ cross-spawn@^7.0.0:
|
||||
shebang-command "^2.0.0"
|
||||
which "^2.0.1"
|
||||
|
||||
cross-spawn@^7.0.1:
|
||||
version "7.0.3"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
|
||||
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
|
||||
dependencies:
|
||||
path-key "^3.1.0"
|
||||
shebang-command "^2.0.0"
|
||||
which "^2.0.1"
|
||||
|
||||
crypto-browserify@3.12.0, crypto-browserify@^3.11.0:
|
||||
version "3.12.0"
|
||||
resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec"
|
||||
@ -14172,6 +14135,17 @@ snapdragon@^0.8.1:
|
||||
source-map-resolve "^0.5.0"
|
||||
use "^3.1.0"
|
||||
|
||||
"snarkjs@git+https://development.tornadocash.community/tornadocash/snarkjs.git#869181cfaf7526fe8972073d31655493a04326d5":
|
||||
version "0.1.20"
|
||||
resolved "git+https://development.tornadocash.community/tornadocash/snarkjs.git#869181cfaf7526fe8972073d31655493a04326d5"
|
||||
dependencies:
|
||||
big-integer "^1.6.43"
|
||||
chai "^4.2.0"
|
||||
escape-string-regexp "^1.0.5"
|
||||
eslint "^5.16.0"
|
||||
keccak "^2.0.0"
|
||||
yargs "^12.0.5"
|
||||
|
||||
sort-keys@^1.0.0:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad"
|
||||
@ -15608,13 +15582,6 @@ walker@^1.0.7, walker@~1.0.5:
|
||||
dependencies:
|
||||
makeerror "1.0.x"
|
||||
|
||||
wasmbuilder@0.0.3:
|
||||
version "0.0.3"
|
||||
resolved "https://registry.yarnpkg.com/wasmbuilder/-/wasmbuilder-0.0.3.tgz#761766a87ef1f65d07d920dc671e691e2d98ff65"
|
||||
integrity sha512-6+lhe2ong4zTG+XkqMduzXzNT1Lxiz9UpwgU4FJ+Ttx8zGeH3nOXROiyVqTRQr/l+NYw7KN5T009uAKaSOmMAQ==
|
||||
dependencies:
|
||||
big-integer "^1.6.43"
|
||||
|
||||
wasmbuilder@^0.0.12:
|
||||
version "0.0.12"
|
||||
resolved "https://registry.yarnpkg.com/wasmbuilder/-/wasmbuilder-0.0.12.tgz#a60cb25d6d11f314fe5ab3f4ee041ccb493cb78a"
|
||||
@ -16252,6 +16219,12 @@ webpackbar@^4.0.0:
|
||||
text-table "^0.2.0"
|
||||
wrap-ansi "^6.0.0"
|
||||
|
||||
"websnark@git+https://development.tornadocash.community/tornadocash/websnark.git#671762fab73f01771d0e7ebcf6b6a3123e193fb4":
|
||||
version "0.0.4"
|
||||
resolved "git+https://development.tornadocash.community/tornadocash/websnark.git#671762fab73f01771d0e7ebcf6b6a3123e193fb4"
|
||||
dependencies:
|
||||
big-integer "1.6.42"
|
||||
|
||||
websocket@^1.0.32:
|
||||
version "1.0.34"
|
||||
resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.34.tgz#2bdc2602c08bf2c82253b730655c0ef7dcab3111"
|
||||
|
Loading…
x
Reference in New Issue
Block a user