diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..42ad5d6 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +only-built-dependencies=bufferutil,esbuild,keccak,utf-8-validate diff --git a/package.json b/package.json index 529d82c..5baa687 100644 --- a/package.json +++ b/package.json @@ -38,9 +38,12 @@ "@wraith-protocol/sdk": "^1.4.5", "bs58": "^6.0.0", "buffer": "^6.0.3", + "i18next": "^24.2.3", + "i18next-browser-languagedetector": "^8.0.5", "qrcode.react": "^4.2.0", "react": "^19.0.0", "react-dom": "^19.0.0", + "react-i18next": "^15.5.1", "react-qr-reader": "3.0.0-beta-1", "react-router-dom": "^7.6.0", "viem": "^2.23.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 10d68db..df4b02a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -65,6 +65,12 @@ importers: buffer: specifier: ^6.0.3 version: 6.0.3 + i18next: + specifier: ^24.2.3 + version: 24.2.3(typescript@5.9.3) + i18next-browser-languagedetector: + specifier: ^8.0.5 + version: 8.2.1 qrcode.react: specifier: ^4.2.0 version: 4.2.0(react@19.2.5) @@ -74,6 +80,9 @@ importers: react-dom: specifier: ^19.0.0 version: 19.2.5(react@19.2.5) + react-i18next: + specifier: ^15.5.1 + version: 15.7.4(i18next@24.2.3(typescript@5.9.3))(react-dom@19.2.5(react@19.2.5))(react-native@0.85.1(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.5)(utf-8-validate@6.0.6))(react@19.2.5)(typescript@5.9.3) react-qr-reader: specifier: 3.0.0-beta-1 version: 3.0.0-beta-1(react-dom@19.2.5(react@19.2.5))(react@19.2.5) @@ -3968,6 +3977,8 @@ packages: resolution: {integrity: sha512-p1JfQMKaceuCbpJKAPKVqyqviZdS0eUxH9v82oWo1kb9xjQ5wA6iP3FNVAPDFlz5/p7d45lO+BpSk1tuSZMF4Q==} engines: {node: '>=16.9.0'} + html-parse-stringify@3.0.1: + resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==} html-encoding-sniffer@3.0.0: resolution: {integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==} engines: {node: '>=12'} @@ -4011,6 +4022,16 @@ packages: engines: {node: '>=18'} hasBin: true + i18next-browser-languagedetector@8.2.1: + resolution: {integrity: sha512-bZg8+4bdmaOiApD7N7BPT9W8MLZG+nPTOFlLiJiT8uzKXFjhxw4v2ierCXOwB5sFDMtuA5G4kgYZ0AznZxQ/cw==} + + i18next@24.2.3: + resolution: {integrity: sha512-lfbf80OzkocvX7nmZtu7nSTNbrTYR52sLWxPtlXX1zAhVw8WEnFk4puUkCR4B1dNQwbSpEHHHemcZu//7EcB7A==} + peerDependencies: + typescript: ^5 + peerDependenciesMeta: + typescript: + optional: true iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} @@ -5408,6 +5429,21 @@ packages: peerDependencies: react: ^19.2.5 + react-i18next@15.7.4: + resolution: {integrity: sha512-nyU8iKNrI5uDJch0z9+Y5XEr34b0wkyYj3Rp+tfbahxtlswxSCjcUL9H0nqXo9IR3/t5Y5PKIA3fx3MfUyR9Xw==} + peerDependencies: + i18next: '>= 23.4.0' + react: '>= 16.8.0' + react-dom: '*' + react-native: '*' + typescript: ^5 + peerDependenciesMeta: + react-dom: + optional: true + react-native: + optional: true + typescript: + optional: true react-is@17.0.2: resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} @@ -6346,6 +6382,10 @@ packages: vlq@1.0.1: resolution: {integrity: sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w==} + void-elements@3.1.0: + resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} + engines: {node: '>=0.10.0'} + wagmi@2.19.5: resolution: {integrity: sha512-RQUfKMv6U+EcSNNGiPbdkDtJwtuFxZWLmvDiQmjjBgkuPulUwDJsKhi7gjynzJdsx2yDqhHCXkKsbbfbIsHfcQ==} peerDependencies: @@ -6840,6 +6880,7 @@ snapshots: - utf-8-validate - zod + '@ckb-ccc/ccc@1.1.25(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6)(zod@3.25.76)': '@bcoe/v8-coverage@0.2.3': {} '@ckb-ccc/ccc@1.1.25(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6)(zod@3.25.76)': @@ -7336,6 +7377,24 @@ snapshots: dependencies: '@hapi/hoek': 11.0.7 + '@joyid/ckb@1.1.4(typescript@5.9.3)(zod@3.25.76)': + dependencies: + '@joyid/common': 0.2.2(typescript@5.9.3)(zod@3.25.76) + '@nervosnetwork/ckb-sdk-utils': 0.109.5 + cross-fetch: 4.0.0 + uncrypto: 0.1.3 + transitivePeerDependencies: + - encoding + - typescript + - zod + + '@joyid/common@0.2.2(typescript@5.9.3)(zod@3.25.76)': + dependencies: + abitype: 0.8.7(typescript@5.9.3)(zod@3.25.76) + type-fest: 4.6.0 + transitivePeerDependencies: + - typescript + - zod '@inquirer/ansi@2.0.6': {} '@inquirer/confirm@6.1.0(@types/node@25.9.4)': @@ -7916,6 +7975,7 @@ snapshots: '@paulmillr/qr@0.2.1': {} + '@rainbow-me/rainbowkit@2.2.10(@tanstack/react-query@5.99.0(react@19.2.5))(@types/react@19.2.14)(react-dom@19.2.5(react@19.2.5))(react@19.2.5)(typescript@5.9.3)(viem@2.47.17(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6)(zod@4.3.6))(wagmi@2.19.5(@react-native-async-storage/async-storage@1.24.0(react-native@0.85.1(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.5)(utf-8-validate@6.0.6)))(@tanstack/query-core@5.99.0)(@tanstack/react-query@5.99.0(react@19.2.5))(@types/react@19.2.14)(bufferutil@4.1.0)(react-native@0.85.1(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.5)(utf-8-validate@6.0.6))(react@19.2.5)(typescript@5.9.3)(utf-8-validate@6.0.6)(viem@2.47.17(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6)(zod@4.3.6))(zod@3.25.76))': '@playwright/test@1.61.0': dependencies: playwright: 1.61.0 @@ -9728,6 +9788,7 @@ snapshots: transitivePeerDependencies: - supports-color + '@wagmi/connectors@6.2.0(d32fac3895882b0645754e2e858c70dd)': '@vitest/expect@2.0.5': dependencies: '@vitest/spy': 2.0.5 @@ -9772,6 +9833,7 @@ snapshots: '@walletconnect/ethereum-provider': 2.21.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.85.1(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.5)(utf-8-validate@6.0.6)))(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.5)(typescript@5.9.3)(utf-8-validate@6.0.6)(zod@3.25.76) cbw-sdk: '@coinbase/wallet-sdk@3.9.3' porto: 0.2.35(de3b9b5ab3c2ce8d2e8c6952073a517f) + porto: 0.2.35(guqvgfizw6uggvf5t4dm2gogwe) viem: 2.47.17(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6)(zod@4.3.6) optionalDependencies: typescript: 5.9.3 @@ -11933,6 +11995,9 @@ snapshots: hono@4.12.12: {} + html-parse-stringify@3.0.1: + dependencies: + void-elements: 3.1.0 html-encoding-sniffer@3.0.0: dependencies: whatwg-encoding: 2.0.0 @@ -12005,6 +12070,15 @@ snapshots: husky@9.1.7: {} + i18next-browser-languagedetector@8.2.1: + dependencies: + '@babel/runtime': 7.29.2 + + i18next@24.2.3(typescript@5.9.3): + dependencies: + '@babel/runtime': 7.29.2 + optionalDependencies: + typescript: 5.9.3 iconv-lite@0.6.3: dependencies: safer-buffer: 2.1.2 @@ -13597,6 +13671,7 @@ snapshots: pony-cause@2.1.11: {} + porto@0.2.35(de3b9b5ab3c2ce8d2e8c6952073a517f): portfinder@1.0.38: dependencies: async: 3.2.6 @@ -13802,6 +13877,16 @@ snapshots: react: 19.2.5 scheduler: 0.27.0 + react-i18next@15.7.4(i18next@24.2.3(typescript@5.9.3))(react-dom@19.2.5(react@19.2.5))(react-native@0.85.1(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.5)(utf-8-validate@6.0.6))(react@19.2.5)(typescript@5.9.3): + dependencies: + '@babel/runtime': 7.29.2 + html-parse-stringify: 3.0.1 + i18next: 24.2.3(typescript@5.9.3) + react: 19.2.5 + optionalDependencies: + react-dom: 19.2.5(react@19.2.5) + react-native: 0.85.1(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.5)(utf-8-validate@6.0.6) + typescript: 5.9.3 react-is@17.0.2: {} react-is@18.3.1: {} @@ -14747,10 +14832,13 @@ snapshots: vlq@1.0.1: {} + void-elements@3.1.0: {} + wagmi@2.19.5(@react-native-async-storage/async-storage@1.24.0(react-native@0.85.1(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.5)(utf-8-validate@6.0.6)))(@tanstack/query-core@5.99.0)(@tanstack/react-query@5.99.0(react@19.2.5))(@types/react@19.2.14)(bufferutil@4.1.0)(react-native@0.85.1(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.5)(utf-8-validate@6.0.6))(react@19.2.5)(typescript@5.9.3)(utf-8-validate@6.0.6)(viem@2.47.17(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6)(zod@4.3.6))(zod@3.25.76): dependencies: '@tanstack/react-query': 5.99.0(react@19.2.5) '@wagmi/connectors': 6.2.0(d32fac3895882b0645754e2e858c70dd) + '@wagmi/connectors': 6.2.0(pomzlx72jhm3uc2rzocjy5pjja) '@wagmi/core': 2.22.1(@tanstack/query-core@5.99.0)(@types/react@19.2.14)(react@19.2.5)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.5))(viem@2.47.17(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6)(zod@4.3.6)) react: 19.2.5 use-sync-external-store: 1.4.0(react@19.2.5) diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index a11079a..05afb45 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,3 +1,11 @@ +onlyBuiltDependencies: + - bufferutil + - esbuild + - keccak + - utf-8-validate + - utf-8-validate@5.0.10 + - utf-8-validate@6.0.6 + allowBuilds: '@swc/core': set this to true or false bufferutil: true @@ -5,3 +13,5 @@ allowBuilds: keccak: true msw: set this to true or false utf-8-validate: true + +dangerouslyAllowAllBuilds: true diff --git a/src/components/CkbReceive.tsx b/src/components/CkbReceive.tsx index 183571e..3ff067f 100644 --- a/src/components/CkbReceive.tsx +++ b/src/components/CkbReceive.tsx @@ -9,10 +9,12 @@ import { type MatchedStealthCell, type HexString, } from '@wraith-protocol/sdk/chains/ckb'; +import { useTranslation } from 'react-i18next'; import { useStealthKeys } from '@/context/StealthKeysContext'; import { CopyButton } from '@/components/CopyButton'; function CkbStealthRow({ match }: { match: MatchedStealthCell }) { + const { t } = useTranslation(); const [showKey, setShowKey] = useState(false); const keyHex = match.stealthPrivateKey.slice(2); const capacityCkb = (Number(match.capacity) / 1e8).toFixed(4); @@ -22,7 +24,7 @@ function CkbStealthRow({ match }: { match: MatchedStealthCell }) {
{match.stealthPubKeyHash}
@@ -36,7 +38,9 @@ function CkbStealthRow({ match }: { match: MatchedStealthCell }) {{match.txHash}:{match.index}
@@ -44,10 +48,10 @@ function CkbStealthRow({ match }: { match: MatchedStealthCell }) {- Withdraw + {t('ckb.withdraw')}
- Use the private key below to sign a CKB transaction consuming this Cell. + {t('ckb.withdrawInstruction')}
- Connect your CKB wallet to scan for stealth payments. + {t('ckb.receiveConnectPrompt')}
- Derive your stealth keys, then scan for stealth Cells on CKB Testnet. + {t('ckb.receiveDescription')}
{error}
}- No cells found + {t('ckb.noCellsFound')}
- No stealth Cells matched your keys. + {t('ckb.noCellsMatchedKeys')}
- Connect your CKB wallet to send stealth payments. + {t('ckb.sendConnectPrompt')}
- Send CKB privately using stealth addresses. The recipient gets funds at a fresh Cell only - they can unlock. + {t('ckb.sendDescription')}
@@ -221,7 +224,7 @@ export function CkbSend() {