Internationalization (#85)

* Implement react i18n-next

* Add XHR i18n backend, include currencies_dict in APP

* Implement i18n 2/9. Add site description

* Implement i18n 3/9 TradeBox. Fix explicit pricing when amount range is enabled.

* Implement i18n 4/9 MakerPage.

* Implement i18n 5/9 OrderPage

* Implement i18n 6/9 Chat

* Implement i18n 9/9 Book, Bottom Bar, Profile, Misc, Info

* Add Contributing translation guidelines
This commit is contained in:
Reckless_Satoshi 2022-04-05 14:25:53 +00:00 committed by GitHub
parent 083c537700
commit 96c6358d4e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 2592 additions and 639 deletions

View File

@ -2657,9 +2657,9 @@
}
},
"ansi-regex": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg=="
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz",
"integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g=="
},
"ansi-styles": {
"version": "3.2.1",
@ -2966,9 +2966,9 @@
}
},
"bplist-parser": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.0.tgz",
"integrity": "sha512-zgmaRvT6AN1JpPPV+S0a1/FAtoxSreYDccZGIqEMSvZl9DMe70mJ7MFzpxa1X+gHVdkToE2haRUHHMiW1OdejA==",
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.3.1.tgz",
"integrity": "sha512-PyJxiNtA5T2PlLIeBot4lbp7rj4OadzjnMZD/G5zuBNt8ei/yCU7+wW0h2bag9vr8c+/WuRWmSxbqAl9hL1rBA==",
"requires": {
"big-integer": "1.6.x"
}
@ -3398,6 +3398,14 @@
"resolved": "https://registry.npmjs.org/country-flag-icons/-/country-flag-icons-1.4.25.tgz",
"integrity": "sha512-1sF/6cit7MYfmxrqNiVN0ijLGv10xtV8egAUwUgIW6Q/Y6d7SuuVw5TOBnG7qIFqrNjxaPNoIAZmx7yOEuZvDA=="
},
"cross-fetch": {
"version": "3.1.5",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz",
"integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==",
"requires": {
"node-fetch": "2.6.7"
}
},
"cross-spawn": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
@ -3415,14 +3423,15 @@
"integrity": "sha1-aiw3NEkoYYYxxUvTPO3TAdoYvqA="
},
"css-select": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz",
"integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==",
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz",
"integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==",
"requires": {
"boolbase": "^1.0.0",
"css-what": "^3.2.1",
"domutils": "^1.7.0",
"nth-check": "^1.0.2"
"css-what": "^6.0.1",
"domhandler": "^4.3.1",
"domutils": "^2.8.0",
"nth-check": "^2.0.1"
}
},
"css-tree": {
@ -3444,9 +3453,9 @@
}
},
"css-what": {
"version": "3.4.2",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-3.4.2.tgz",
"integrity": "sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ=="
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
"integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw=="
},
"csstype": {
"version": "2.6.19",
@ -3580,33 +3589,36 @@
}
},
"dom-serializer": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
"integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==",
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz",
"integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==",
"requires": {
"domelementtype": "^2.0.1",
"domhandler": "^4.2.0",
"entities": "^2.0.0"
},
"dependencies": {
"domelementtype": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz",
"integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A=="
}
}
},
"domelementtype": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
"integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w=="
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz",
"integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A=="
},
"domhandler": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz",
"integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==",
"requires": {
"domelementtype": "^2.2.0"
}
},
"domutils": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
"integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==",
"version": "2.8.0",
"resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz",
"integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==",
"requires": {
"dom-serializer": "0",
"domelementtype": "1"
"dom-serializer": "^1.0.1",
"domelementtype": "^2.2.0",
"domhandler": "^4.2.0"
}
},
"ee-first": {
@ -4273,6 +4285,19 @@
}
}
},
"html-escaper": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg=="
},
"html-parse-stringify": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz",
"integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==",
"requires": {
"void-elements": "3.1.0"
}
},
"http-errors": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz",
@ -4296,6 +4321,48 @@
"resolved": "https://registry.npmjs.org/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz",
"integrity": "sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ=="
},
"i18next": {
"version": "21.6.14",
"resolved": "https://registry.npmjs.org/i18next/-/i18next-21.6.14.tgz",
"integrity": "sha512-XL6WyD+xlwQwbieXRlXhKWoLb/rkch50/rA+vl6untHnJ+aYnkQ0YDZciTWE78PPhOpbi2gR0LTJCJpiAhA+uQ==",
"requires": {
"@babel/runtime": "^7.17.2"
},
"dependencies": {
"@babel/runtime": {
"version": "7.17.8",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.8.tgz",
"integrity": "sha512-dQpEpK0O9o6lj6oPu0gRDbbnk+4LeHlNcBpspf6Olzt3GIX4P1lWF1gS+pHLDFlaJvbR6q7jCfQ08zA4QJBnmA==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
}
}
},
"i18next-browser-languagedetector": {
"version": "6.1.4",
"resolved": "https://registry.npmjs.org/i18next-browser-languagedetector/-/i18next-browser-languagedetector-6.1.4.tgz",
"integrity": "sha512-wukWnFeU7rKIWT66VU5i8I+3Zc4wReGcuDK2+kuFhtoxBRGWGdvYI9UQmqNL/yQH1KogWwh+xGEaIPH8V/i2Zg==",
"requires": {
"@babel/runtime": "^7.14.6"
}
},
"i18next-http-backend": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/i18next-http-backend/-/i18next-http-backend-1.4.0.tgz",
"integrity": "sha512-wsvx7E/CT1pHmBM99Vu57YLJpsrHbVjxGxf25EIJ/6oTjsvCkZZ6c3SA4TejcK5jIHfv9oLxQX8l+DFKZHZ0Gg==",
"requires": {
"cross-fetch": "3.1.5"
}
},
"i18next-xhr-backend": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/i18next-xhr-backend/-/i18next-xhr-backend-3.2.2.tgz",
"integrity": "sha512-OtRf2Vo3IqAxsttQbpjYnmMML12IMB5e0fc5B7qKJFLScitYaXa1OhMX0n0X/3vrfFlpHL9Ro/H+ps4Ej2j7QQ==",
"requires": {
"@babel/runtime": "^7.5.5"
}
},
"image-size": {
"version": "0.6.3",
"resolved": "https://registry.npmjs.org/image-size/-/image-size-0.6.3.tgz",
@ -5751,9 +5818,9 @@
}
},
"minimist": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
"version": "1.2.6",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
},
"mixin-deep": {
"version": "1.3.2",
@ -5839,9 +5906,9 @@
}
},
"node-fetch": {
"version": "2.6.6",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.6.tgz",
"integrity": "sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==",
"version": "2.6.7",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz",
"integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==",
"requires": {
"whatwg-url": "^5.0.0"
}
@ -5881,11 +5948,11 @@
}
},
"nth-check": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
"integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==",
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz",
"integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==",
"requires": {
"boolbase": "~1.0.0"
"boolbase": "^1.0.0"
}
},
"nullthrows": {
@ -6143,9 +6210,9 @@
}
},
"plist": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/plist/-/plist-3.0.4.tgz",
"integrity": "sha512-ksrr8y9+nXOxQB2osVNqrgvX/XQPOXaU4BQMKjYq8PvaY1U18mo+fKgBSwzK+luSyinOuPae956lSVcBwxlAMg==",
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/plist/-/plist-3.0.5.tgz",
"integrity": "sha512-83vX4eYdQp3vP9SxuYgEM/G/pJQqLUz/V/xzPrzruLs7fz7jxGQ1msZ/mg1nwZxUSuOp4sb+/bEIbRrbzZRxDA==",
"requires": {
"base64-js": "^1.5.1",
"xmlbuilder": "^9.0.7"
@ -6355,6 +6422,16 @@
"scheduler": "^0.20.2"
}
},
"react-i18next": {
"version": "11.16.2",
"resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.16.2.tgz",
"integrity": "sha512-1iuZduvARUelL5ux663FvIoDZExwFO+9QtRAAt4uvs1/aun4cUZt8XBrVg7iiDgNls9cOSORAhE7Ri5KA9RMvg==",
"requires": {
"@babel/runtime": "^7.14.5",
"html-escaper": "^2.0.2",
"html-parse-stringify": "^3.0.1"
}
},
"react-is": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
@ -6601,11 +6678,11 @@
}
},
"react-native-svg": {
"version": "12.1.1",
"resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-12.1.1.tgz",
"integrity": "sha512-NIAJ8jCnXGCqGWXkkJ1GTzO4a3Md5at5sagYV8Vh4MXYnL4z5Rh428Wahjhh+LIjx40EE5xM5YtwyJBqOIba2Q==",
"version": "12.3.0",
"resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-12.3.0.tgz",
"integrity": "sha512-ESG1g1j7/WLD7X3XRFTQHVv0r6DpbHNNcdusngAODIxG88wpTWUZkhcM3A2HJTb+BbXTFDamHv7FwtRKWQ/ALg==",
"requires": {
"css-select": "^2.1.0",
"css-select": "^4.2.1",
"css-tree": "^1.0.0-alpha.39"
}
},
@ -7345,13 +7422,24 @@
"integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ=="
},
"simple-plist": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/simple-plist/-/simple-plist-1.3.0.tgz",
"integrity": "sha512-uYWpeGFtZtVt2NhG4AHgpwx323zxD85x42heMJBan1qAiqqozIlaGrwrEt6kRjXWRWIXsuV1VLCvVmZan2B5dg==",
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/simple-plist/-/simple-plist-1.3.1.tgz",
"integrity": "sha512-iMSw5i0XseMnrhtIzRb7XpQEXepa9xhWxGUojHBL43SIpQuDQkh3Wpy67ZbDzZVr6EKxvwVChnVpdl8hEVLDiw==",
"requires": {
"bplist-creator": "0.1.0",
"bplist-parser": "0.3.0",
"plist": "^3.0.4"
"bplist-parser": "0.3.1",
"plist": "^3.0.5"
},
"dependencies": {
"plist": {
"version": "3.0.5",
"resolved": "https://registry.npmjs.org/plist/-/plist-3.0.5.tgz",
"integrity": "sha512-83vX4eYdQp3vP9SxuYgEM/G/pJQqLUz/V/xzPrzruLs7fz7jxGQ1msZ/mg1nwZxUSuOp4sb+/bEIbRrbzZRxDA==",
"requires": {
"base64-js": "^1.5.1",
"xmlbuilder": "^9.0.7"
}
}
}
},
"sisteransi": {
@ -7993,6 +8081,11 @@
"resolved": "https://registry.npmjs.org/vlq/-/vlq-1.0.1.tgz",
"integrity": "sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w=="
},
"void-elements": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz",
"integrity": "sha1-YU9/v42AHwu18GYfWy9XhXUOTwk="
},
"walker": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz",

View File

@ -33,16 +33,22 @@
"@mui/x-data-grid": "^5.2.2",
"country-flag-icons": "^1.4.25",
"date-fns": "^2.28.0",
"i18next": "^21.6.14",
"i18next-browser-languagedetector": "^6.1.4",
"i18next-http-backend": "^1.4.0",
"i18next-xhr-backend": "^3.2.2",
"material-ui-image": "^3.3.2",
"react-countdown": "^2.3.2",
"react-i18next": "^11.16.2",
"react-native": "^0.66.4",
"react-native-svg": "^12.1.1",
"react-native-svg": "^12.3.0",
"react-qr-code": "^2.0.3",
"react-qr-reader": "^2.2.1",
"react-responsive": "^9.0.0-beta.6",
"react-router-dom": "^5.2.0",
"react-world-flags": "^1.4.0",
"reconnecting-websocket": "^4.4.0",
"simple-plist": "^1.3.1",
"websocket": "^1.0.34"
}
}

View File

@ -5,6 +5,9 @@ import { CssBaseline, IconButton} from "@mui/material";
import { ThemeProvider, createTheme } from '@mui/material/styles';
import UnsafeAlert from "./UnsafeAlert";
import { I18nextProvider } from "react-i18next";
import i18n from "./i18n";
import DarkModeIcon from '@mui/icons-material/DarkMode';
import LightModeIcon from '@mui/icons-material/LightMode';
@ -12,18 +15,11 @@ export default class App extends Component {
constructor(props) {
super(props);
this.state = {
nickname: null,
token: null,
dark: false,
}
}
setAppState=(newState)=>{
this.setState(newState)
}
lightTheme = createTheme({
});
lightTheme = createTheme({});
darkTheme = createTheme({
palette: {
@ -36,14 +32,16 @@ export default class App extends Component {
render() {
return (
<ThemeProvider theme={this.state.dark ? this.darkTheme : this.lightTheme}>
<CssBaseline/>
<IconButton sx={{position:'fixed',right:'0px'}} onClick={()=>this.setState({dark:!this.state.dark})}>
{this.state.dark ? <LightModeIcon/>:<DarkModeIcon/>}
</IconButton>
<UnsafeAlert className="unsafeAlert"/>
<HomePage setAppState={this.setAppState}/>
</ThemeProvider>
<I18nextProvider i18n={i18n}>
<ThemeProvider theme={this.state.dark ? this.darkTheme : this.lightTheme}>
<CssBaseline/>
<IconButton sx={{position:'fixed',right:'0px'}} onClick={()=>this.setState({dark:!this.state.dark})}>
{this.state.dark ? <LightModeIcon/>:<DarkModeIcon/>}
</IconButton>
<UnsafeAlert className="unsafeAlert"/>
<HomePage/>
</ThemeProvider>
</I18nextProvider>
);
}
}

View File

@ -1,22 +1,23 @@
import React, { Component , useState } from "react";
import React, { Component } from "react";
import { withTranslation, Trans} from "react-i18next";
import { Badge, Tooltip, Paper, Button, ListItemButton, Typography, Grid, Select, MenuItem, FormControl, FormHelperText, ListItemText, ListItemAvatar, IconButton} from "@mui/material";
import { Link } from 'react-router-dom'
import { DataGrid } from '@mui/x-data-grid';
import currencyDict from '../../static/assets/currencies.json';
import MediaQuery from 'react-responsive'
import Image from 'material-ui-image'
import getFlags from './getFlags'
import PaymentText from './PaymentText'
export default class BookPage extends Component {
class BookPage extends Component {
constructor(props) {
super(props);
this.state = {
orders: new Array({id:0,}),
currencies_dict: {"0":"ANY"},
loading: true,
pageSize: 6,
};
this.getCurrencyDict()
this.getOrderDetails(this.props.type, this.props.currency)
}
@ -50,21 +51,13 @@ export default class BookPage extends Component {
})
this.getOrderDetails(this.props.type, currency);
}
getCurrencyDict() {
fetch('/static/assets/currencies.json')
.then((response) => response.json())
.then((data) =>
this.setState({
currencies_dict: data
}));
}
getCurrencyCode(val){
const { t } = this.props;
if (val){
return val == 0 ? 'ANY' : this.state.currencies_dict[val.toString()]
return val == 0 ? t('ANY_currency') : currencyDict[val.toString()]
}else{
return 'ANY'
return t('ANY_currency')
}
}
@ -94,6 +87,7 @@ export default class BookPage extends Component {
}
bookListTableDesktop=()=>{
const { t } = this.props;
return (
<div style={{ height: 422, width: '100%' }}>
<DataGrid
@ -103,7 +97,7 @@ export default class BookPage extends Component {
avatar: window.location.origin +'/static/assets/avatars/' + order.maker_nick + '.png',
robot: order.maker_nick,
robot_status: order.maker_status,
type: order.type ? "Seller": "Buyer",
type: order.type ? t("Seller"): t("Buyer"),
amount: order.amount,
has_range: order.has_range,
min_amount: order.min_amount,
@ -117,11 +111,11 @@ export default class BookPage extends Component {
loading={this.state.loading}
columns={[
// { field: 'id', headerName: 'ID', width: 40 },
{ field: 'robot', headerName: 'Robot', width: 240,
{ field: 'robot', headerName: t("Robot"), width: 240,
renderCell: (params) => {return (
<ListItemButton style={{ cursor: "pointer" }}>
<ListItemAvatar>
<Tooltip placement="right" enterTouchDelay="0" title={params.row.robot_status}>
<Tooltip placement="right" enterTouchDelay="0" title={t(params.row.robot_status)}>
<Badge variant="dot" overlap="circular" badgeContent="" color={this.statusBadgeColor(params.row.robot_status)}>
<div style={{ width: 45, height: 45 }}>
<Image className='bookAvatar'
@ -139,24 +133,24 @@ export default class BookPage extends Component {
</ListItemButton>
);
} },
{ field: 'type', headerName: 'Is', width: 60 },
{ field: 'amount', headerName: 'Amount', type: 'number', width: 90,
{ field: 'type', headerName: t("Is"), width: 60 },
{ field: 'amount', headerName: t("Amount"), type: 'number', width: 90,
renderCell: (params) => {return (
<div style={{ cursor: "pointer" }}>{this.amountToString(params.row.amount,params.row.has_range, params.row.min_amount, params.row.max_amount)}</div>
)}},
{ field: 'currency', headerName: 'Currency', width: 100,
{ field: 'currency', headerName: t("Currency"), width: 100,
renderCell: (params) => {return (
<div style={{ cursor: "pointer", display:'flex',alignItems:'center', flexWrap:'wrap'}}>{params.row.currency+" "}{getFlags(params.row.currency)}</div>)
}},
{ field: 'payment_method', headerName: 'Payment Method', width: 180 ,
{ field: 'payment_method', headerName: t("Payment Method"), width: 180 ,
renderCell: (params) => {return (
<div style={{ cursor: "pointer" }}><PaymentText verbose={true} size={20} text={params.row.payment_method}/></div>
<div style={{ cursor: "pointer" }}><PaymentText othersText={t("Others")} verbose={true} size={20} text={params.row.payment_method}/></div>
)} },
{ field: 'price', headerName: 'Price', type: 'number', width: 140,
{ field: 'price', headerName: t("Price"), type: 'number', width: 140,
renderCell: (params) => {return (
<div style={{ cursor: "pointer" }}>{this.pn(params.row.price) + " " +params.row.currency+ "/BTC" }</div>
)} },
{ field: 'premium', headerName: 'Premium', type: 'number', width: 100,
{ field: 'premium', headerName: t("Premium"), type: 'number', width: 100,
renderCell: (params) => {return (
<div style={{ cursor: "pointer" }}>{parseFloat(parseFloat(params.row.premium).toFixed(4))+"%" }</div>
)} },
@ -172,7 +166,7 @@ export default class BookPage extends Component {
}
bookListTablePhone=()=>{
const { t } = this.props;
return (
<div style={{ height: 422, width: '100%' }}>
<DataGrid
@ -183,7 +177,7 @@ export default class BookPage extends Component {
avatar: window.location.origin +'/static/assets/avatars/' + order.maker_nick + '.png',
robot: order.maker_nick,
robot_status: order.maker_status,
type: order.type ? "Seller": "Buyer",
type: order.type ? t("Seller"): t("Buyer"),
amount: order.amount,
has_range: order.has_range,
min_amount: order.min_amount,
@ -197,9 +191,9 @@ export default class BookPage extends Component {
columns={[
// { field: 'id', headerName: 'ID', width: 40 },
{ field: 'robot', headerName: 'Robot', width: 64,
{ field: 'robot', headerName: t("Robot"), width: 64,
renderCell: (params) => {return (
<Tooltip placement="right" enterTouchDelay="0" title={params.row.robot+" ("+params.row.robot_status+")"}>
<Tooltip placement="right" enterTouchDelay="0" title={params.row.robot+" ("+t(params.row.robot_status)+")"}>
<Badge variant="dot" overlap="circular" badgeContent="" color={this.statusBadgeColor(params.row.robot_status)}>
<div style={{ width: 45, height: 45 }}>
<Image className='bookAvatar'
@ -214,29 +208,29 @@ export default class BookPage extends Component {
</Tooltip>
);
} },
{ field: 'type', headerName: 'Is', width: 60, hide:'true'},
{ field: 'amount', headerName: 'Amount', type: 'number', width: 84,
{ field: 'type', headerName: t("Is"), width: 60, hide:'true'},
{ field: 'amount', headerName: t("Amount"), type: 'number', width: 84,
renderCell: (params) => {return (
<Tooltip placement="right" enterTouchDelay="0" title={params.row.type}>
<Tooltip placement="right" enterTouchDelay="0" title={t(params.row.type)}>
<div style={{ cursor: "pointer" }}>{this.amountToString(params.row.amount,params.row.has_range, params.row.min_amount, params.row.max_amount)}</div>
</Tooltip>
)} },
{ field: 'currency', headerName: 'Currency', width: 85,
{ field: 'currency', headerName: t("Currency"), width: 85,
renderCell: (params) => {return (
// <Tooltip placement="left" enterTouchDelay="0" title={params.row.payment_method}>
<div style={{ cursor: "pointer", display:'flex',alignItems:'center', flexWrap:'wrap'}}>{params.row.currency+" "}{getFlags(params.row.currency)}</div>
// </Tooltip>
)} },
{ field: 'payment_method', headerName: 'Payment Method', width: 180, hide:'true'},
{ field: 'payment_icons', headerName: 'Pay', width: 75 ,
{ field: 'payment_method', headerName: t("Payment Method"), width: 180, hide:'true'},
{ field: 'payment_icons', headerName: t("Pay"), width: 75 ,
renderCell: (params) => {return (
<div style={{position:'relative', left:'-4px', cursor: "pointer", align:"center"}}><PaymentText size={16} text={params.row.payment_method}/></div>
<div style={{position:'relative', left:'-4px', cursor: "pointer", align:"center"}}><PaymentText othersText={t("Others")} size={16} text={params.row.payment_method}/></div>
)} },
{ field: 'price', headerName: 'Price', type: 'number', width: 140, hide:'true',
{ field: 'price', headerName: t("Price"), type: 'number', width: 140, hide:'true',
renderCell: (params) => {return (
<div style={{ cursor: "pointer" }}>{this.pn(params.row.price) + " " +params.row.currency+ "/BTC" }</div>
)} },
{ field: 'premium', headerName: 'Premium', type: 'number', width: 85,
{ field: 'premium', headerName: t("Premium"), type: 'number', width: 85,
renderCell: (params) => {return (
<Tooltip placement="left" enterTouchDelay="0" title={this.pn(params.row.price) + " " +params.row.currency+ "/BTC" }>
<div style={{ cursor: "pointer" }}>{parseFloat(parseFloat(params.row.premium).toFixed(4))+"%" }</div>
@ -255,6 +249,7 @@ export default class BookPage extends Component {
}
render() {
const { t } = this.props;
return (
<Grid className='orderBook' container spacing={1} sx={{minWidth:400}}>
{/* <Grid item xs={12} align="center">
@ -264,21 +259,21 @@ export default class BookPage extends Component {
<Grid item xs={6} align="right">
<FormControl align="center">
<FormHelperText align="center">
I want to
{t("I want to")}
</FormHelperText>
<Select
sx={{width:90}}
autoWidth={true}
label="Select Order Type"
label={t("Select Order Type")}
required="true"
value={this.props.type}
inputProps={{
style: {textAlign:"center"}
}}
onChange={this.handleTypeChange}
> <MenuItem value={2}>ANY</MenuItem>
<MenuItem value={1}>BUY</MenuItem>
<MenuItem value={0}>SELL</MenuItem>
> <MenuItem value={2}>{t("ANY_type")}</MenuItem>
<MenuItem value={1}>{t("BUY")}</MenuItem>
<MenuItem value={0}>{t("SELL")}</MenuItem>
</Select>
</FormControl>
</Grid>
@ -286,21 +281,21 @@ export default class BookPage extends Component {
<Grid item xs={6} align="left">
<FormControl align="center">
<FormHelperText align="center">
and {this.props.type == 0 ? ' receive' : (this.props.type == 1 ? ' pay with' : ' use' )}
{this.props.type == 0 ? t("and receive") : (this.props.type == 1 ? t("and pay with") : t("and use") )}
</FormHelperText>
<Select
//autoWidth={true}
sx={{width:110}}
label="Select Payment Currency"
label={t("Select Payment Currency")}
required="true"
value={this.props.currency}
inputProps={{
style: {textAlign:"center"}
}}
onChange={this.handleCurrencyChange}
> <MenuItem value={0}>🌍 ANY</MenuItem>
> <MenuItem value={0}>{"🌍 "+t("ANY_currency")}</MenuItem>
{
Object.entries(this.state.currencies_dict)
Object.entries(currencyDict)
.map( ([key, value]) => <MenuItem value={parseInt(key)}><div style={{display:'flex',alignItems:'center', flexWrap:'wrap'}}>{getFlags(value)}{" "+value}</div></MenuItem> )
}
</Select>
@ -309,7 +304,15 @@ export default class BookPage extends Component {
{ this.state.not_found ? "" :
<Grid item xs={12} align="center">
<Typography component="h5" variant="h5">
You are {this.props.type == 0 ? <b> selling </b> : (this.props.type == 1 ? <b> buying </b> :" looking at all ")} BTC for {this.props.currencyCode}
{this.props.type == 0 ?
t("You are SELLING BTC for {{currencyCode}}",{currencyCode:this.props.currencyCode})
:
(this.props.type == 1 ?
t("You are BUYING BTC for {{currencyCode}}",{currencyCode:this.props.currencyCode})
:
t("You are looking at all")
)
}
</Typography>
</Grid>
}
@ -318,15 +321,19 @@ export default class BookPage extends Component {
(<Grid item xs={12} align="center">
<Grid item xs={12} align="center">
<Typography component="h5" variant="h5">
No orders found to {this.props.type == 0 ? ' sell ' :' buy ' } BTC for {this.props.currencyCode}
{this.props.type == 0 ?
t("No orders found to sell BTC for {{currencyCode}}",{currencyCode:this.props.currencyCode})
:
t("No orders found to buy BTC for {{currencyCode}}",{currencyCode:this.props.currencyCode})
}
</Typography>
</Grid>
<br/>
<Grid item>
<Button size="large" variant="contained" color='primary' to='/make/' component={Link}>Make Order</Button>
<Button size="large" variant="contained" color='primary' to='/make/' component={Link}>{t("Make Order")}</Button>
</Grid>
<Typography color="primary" component="body1" variant="body1">
Be the first one to create an order
{t("Be the first one to create an order")}
<br/>
<br/>
</Typography>
@ -350,10 +357,12 @@ export default class BookPage extends Component {
}
<Grid item xs={12} align="center">
<Button color="secondary" variant="contained" to="/" component={Link}>
Back
{t("Back")}
</Button>
</Grid>
</Grid>
);
};
}
}
export default withTranslation()(BookPage);

View File

@ -1,7 +1,9 @@
import React, { Component } from 'react'
import { withTranslation, Trans} from "react-i18next";
import {FormControlLabel, Link, Switch, CircularProgress, Badge, Tooltip, TextField, ListItemAvatar, Button, Avatar,Paper, Grid, IconButton, Typography, Select, MenuItem, List, ListItemText, ListItem, ListItemIcon, ListItemButton, Divider, Dialog, DialogContent} from "@mui/material";
import MediaQuery from 'react-responsive'
import { Link as LinkRouter } from 'react-router-dom'
import Flags from 'country-flag-icons/react/3x2'
// Icons
import SettingsIcon from '@mui/icons-material/Settings';
@ -54,7 +56,7 @@ function getCookie(name) {
return cookieValue;
}
export default class BottomBar extends Component {
class BottomBar extends Component {
constructor(props) {
super(props);
this.state = {
@ -104,7 +106,7 @@ export default class BottomBar extends Component {
};
StatsDialog =() =>{
const { t } = this.props;
return(
<Dialog
open={this.state.openStatsForNerds}
@ -113,12 +115,12 @@ export default class BottomBar extends Component {
aria-describedby="stats-for-nerds-description"
>
<DialogContent>
<Typography component="h5" variant="h5">Stats For Nerds</Typography>
<Typography component="h5" variant="h5">{t("Stats For Nerds")}</Typography>
<List dense>
<Divider/>
<ListItem>
<ListItemIcon><BoltIcon/></ListItemIcon>
<ListItemText primary={this.state.lnd_version} secondary="LND version"/>
<ListItemText primary={this.state.lnd_version} secondary={t("LND version")}/>
</ListItem>
<Divider/>
@ -154,7 +156,7 @@ export default class BottomBar extends Component {
<Divider/>
<ListItem>
<ListItemIcon><GitHubIcon/></ListItemIcon>
<ListItemText secondary="Currently running commit hash">
<ListItemText secondary={t("Currently running commit hash")}>
<Link target="_blank" href={"https://github.com/Reckless-Satoshi/robosats/tree/"
+ this.state.robosats_running_commit_hash}>{this.state.robosats_running_commit_hash.slice(0, 12)+"..."}
</Link>
@ -164,13 +166,13 @@ export default class BottomBar extends Component {
<Divider/>
<ListItem>
<ListItemIcon><EqualizerIcon/></ListItemIcon>
<ListItemText primary={pn(this.state.last_day_volume)+" Sats"} secondary="24h contracted volume"/>
<ListItemText primary={pn(this.state.last_day_volume)+" Sats"} secondary={t("24h contracted volume")}/>
</ListItem>
<Divider/>
<ListItem>
<ListItemIcon><EqualizerIcon/></ListItemIcon>
<ListItemText primary={pn(this.state.lifetime_volume)+" BTC"} secondary="Lifetime contracted volume"/>
<ListItemText primary={pn(this.state.lifetime_volume)+" BTC"} secondary={t("Lifetime contracted volume")}/>
</ListItem>
<Divider/>
@ -178,12 +180,12 @@ export default class BottomBar extends Component {
<ListItemIcon><PublicIcon/></ListItemIcon>
<ListItemText primary={
<div style={{display:'flex', alignItems:'center', justifyContent:'left', flexWrap:'wrap'}}>
<span>Made with </span>
<span>{t("Made with")+" "}</span>
<FavoriteIcon sx={{ color: "#FF0000", height: '22px',width: '22px'}}/>
<span> and </span>
<span>{" "+t("and")+" "}</span>
<BoltIcon sx={{ color: "#fcba03", height: '23px',width: '23px'}}/>
</div>}
secondary="... somewhere on Earth!"/>
secondary={t("... somewhere on Earth!")}/>
</ListItem>
</List>
@ -200,6 +202,7 @@ export default class BottomBar extends Component {
};
CommunityDialog =() =>{
const { t } = this.props;
return(
<Dialog
@ -209,36 +212,43 @@ export default class BottomBar extends Component {
aria-describedby="community-description"
>
<DialogContent>
<Typography component="h5" variant="h5">Community</Typography>
<Typography component="h5" variant="h5">{t("Community")}</Typography>
<Typography component="body2" variant="body2">
<p> Support is only offered via public channels.
Join our Telegram community if you have
questions or want to hang out with other cool robots.
Please, use our Github Issues if you find a bug or want
to see new features!
</p>
<p>{t("Support is only offered via public channels. Join our Telegram community if you have questions or want to hang out with other cool robots. Please, use our Github Issues if you find a bug or want to see new features!")}</p>
</Typography>
<List>
<Divider/>
<ListItemButton component="a" target="_blank" href="https://t.me/robosats">
<ListItemIcon><SendIcon/></ListItemIcon>
<ListItemText primary="Join the RoboSats group"
secondary="Telegram (English / Main)"/>
<ListItemText primary={t("Join the RoboSats group")}
secondary={t("Telegram (English / Main)")}/>
</ListItemButton>
<Divider/>
<ListItemButton component="a" target="_blank" href="https://t.me/robosats_es">
<ListItem>
<ListItemIcon><SendIcon/></ListItemIcon>
<ListItemText primary="Unase al grupo RoboSats"
secondary="Telegram (Español)"/>
</ListItemButton>
<ListItemText secondary={t("RoboSats Telegram Communities")}>
<Tooltip title={t("Join RoboSats Spanish speaking community!")}>
<IconButton component="a" target="_blank" href="https://t.me/robosats_es"><Flags.ES width={30} height={30} style={{filter: 'drop-shadow(2px 2px 2px #444444)'}}/></IconButton>
</Tooltip>
<Tooltip title={t("Join RoboSats Russian speaking community!")}>
<IconButton component="a" target="_blank" href="https://t.me/robosats_ru"><Flags.RU width={30} height={30} style={{filter: 'drop-shadow(2px 2px 2px #444444)'}}/></IconButton>
</Tooltip>
<Tooltip title={t("Join RoboSats Chinese speaking community!")}>
<IconButton component="a" target="_blank" href="https://t.me/robosats_cn"><Flags.CN width={30} height={30} style={{filter: 'drop-shadow(2px 2px 2px #444444)'}}/></IconButton>
</Tooltip>
<Tooltip title={t("Join RoboSats English speaking community!")}>
<IconButton component="a" target="_blank" href="https://t.me/robosats"><Flags.US width={30} height={30} style={{filter: 'drop-shadow(2px 2px 2px #444444)'}}/></IconButton>
</Tooltip>
</ListItemText>
</ListItem>
<Divider/>
<ListItemButton component="a" target="_blank" href="https://github.com/Reckless-Satoshi/robosats/issues">
<ListItemIcon><GitHubIcon/></ListItemIcon>
<ListItemText primary="Tell us about a new feature or a bug"
secondary="Github Issues - The Robotic Satoshis Open Source Project"/>
<ListItemText primary={t("Tell us about a new feature or a bug")}
secondary={t("Github Issues - The Robotic Satoshis Open Source Project")}/>
</ListItemButton>
</List>
@ -285,6 +295,7 @@ export default class BottomBar extends Component {
}
dialogProfile =() =>{
const { t } = this.props;
return(
<Dialog
open={this.state.openProfile}
@ -293,11 +304,11 @@ export default class BottomBar extends Component {
aria-describedby="profile-description"
>
<DialogContent>
<Typography component="h5" variant="h5">Your Profile</Typography>
<Typography component="h5" variant="h5">{t("Your Profile")}</Typography>
<List>
<Divider/>
<ListItem className="profileNickname">
<ListItemText secondary="Your robot">
<ListItemText secondary={t("Your robot")}>
<Typography component="h6" variant="h6">
{this.props.nickname ?
<div style={{position:'relative',left:'-7px'}}>
@ -325,12 +336,12 @@ export default class BottomBar extends Component {
<NumbersIcon color="primary"/>
</Badge>
</ListItemIcon>
<ListItemText primary={'One active order #'+this.state.active_order_id} secondary="Your current order"/>
<ListItemText primary={t("One active order #{{orderID}}",{orderID: this.state.active_order_id})} secondary={t("Your current order")}/>
</ListItemButton>
:
<ListItem>
<ListItemIcon><NumbersIcon/></ListItemIcon>
<ListItemText primary="No active orders" secondary="Your current order"/>
<ListItemText primary={t("No active orders")} secondary={t("Your current order")}/>
</ListItem>
}
@ -338,17 +349,17 @@ export default class BottomBar extends Component {
<ListItemIcon>
<PasswordIcon/>
</ListItemIcon>
<ListItemText secondary="Your token (will not remain here)">
<ListItemText secondary={t("Your token (will not remain here)")}>
{this.props.token ?
<TextField
disabled
label='Back it up!'
label={t("Back it up!")}
value={this.props.token }
variant='filled'
size='small'
InputProps={{
endAdornment:
<Tooltip disableHoverListener enterTouchDelay="0" title="Copied!">
<Tooltip disableHoverListener enterTouchDelay="0" title={t("Copied!")}>
<IconButton onClick= {()=>navigator.clipboard.writeText(this.props.token)}>
<ContentCopy />
</IconButton>
@ -356,7 +367,7 @@ export default class BottomBar extends Component {
}}
/>
:
'Cannot remember'}
t("Cannot remember")}
</ListItemText>
</ListItem>
@ -367,7 +378,7 @@ export default class BottomBar extends Component {
<Switch
checked={this.state.showRewards}
onChange={()=> this.setState({showRewards: !this.state.showRewards})}/>}
label="Rewards and compensations"
label={t("Rewards and compensations")}
/>
</Grid>
@ -376,15 +387,14 @@ export default class BottomBar extends Component {
<ListItemIcon>
<PersonAddAltIcon/>
</ListItemIcon>
<ListItemText secondary="Share to earn 100 Sats per trade">
<ListItemText secondary={t("Share to earn 100 Sats per trade")}>
<TextField
label='Your referral link'
label={t("Your referral link")}
value={this.getHost()+'/ref/'+this.state.referral_code}
// variant='filled'
size='small'
InputProps={{
endAdornment:
<Tooltip disableHoverListener enterTouchDelay="0" title="Copied!">
<Tooltip disableHoverListener enterTouchDelay="0" title={t("Copied!")}>
<IconButton onClick= {()=>navigator.clipboard.writeText('http://'+this.getHost()+'/ref/'+this.state.referral_code)}>
<ContentCopy />
</IconButton>
@ -399,13 +409,13 @@ export default class BottomBar extends Component {
<EmojiEventsIcon/>
</ListItemIcon>
{!this.state.openClaimRewards ?
<ListItemText secondary="Your earned rewards">
<ListItemText secondary={t("Your earned rewards")}>
<Grid container xs={12}>
<Grid item xs={9}>
<Typography>{this.state.earned_rewards+" Sats"}</Typography>
</Grid>
<Grid item xs={3}>
<Button disabled={this.state.earned_rewards==0? true : false} onClick={() => this.setState({openClaimRewards:true})} variant="contained" size="small">Claim</Button>
<Button disabled={this.state.earned_rewards==0? true : false} onClick={() => this.setState({openClaimRewards:true})} variant="contained" size="small">{t("Claim")}</Button>
</Grid>
</Grid>
</ListItemText>
@ -416,8 +426,7 @@ export default class BottomBar extends Component {
<TextField
error={this.state.badInvoice}
helperText={this.state.badInvoice ? this.state.badInvoice : "" }
label={"Invoice for " + this.state.earned_rewards + " Sats"}
//variant="standard"
label={t("Invoice for {{amountSats}} Sats", {amountSats: this.state.earned_rewards})}
size="small"
value={this.state.rewardInvoice}
onChange={e => {
@ -426,7 +435,7 @@ export default class BottomBar extends Component {
/>
</Grid>
<Grid item alignItems="stretch" style={{ display: "flex" }}>
<Button sx={{maxHeight:38}} onClick={this.handleSubmitInvoiceClicked} variant="contained" color="primary" size="small" > Submit </Button>
<Button sx={{maxHeight:38}} onClick={this.handleSubmitInvoiceClicked} variant="contained" color="primary" size="small">{t("Submit")}</Button>
</Grid>
</Grid>
</form>
@ -441,7 +450,7 @@ export default class BottomBar extends Component {
{this.state.withdrawn?
<div style={{display: 'flex', justifyContent: 'center'}}>
<Typography color="primary" variant="body2"><b>There it goes, thank you!🥇</b></Typography>
<Typography color="primary" variant="body2"><b>{t("There it goes, thank you!🥇")}</b></Typography>
</div>
:""}
@ -454,6 +463,7 @@ export default class BottomBar extends Component {
}
bottomBarDesktop =()=>{
const { t } = this.props;
return(
<Paper elevation={6} style={{height:40}}>
<this.StatsDialog/>
@ -465,9 +475,9 @@ bottomBarDesktop =()=>{
<Grid item xs={1.9}>
<div style={{display: this.props.avatarLoaded ? '':'none'}}>
<ListItemButton onClick={this.handleClickOpenProfile} >
<Tooltip open={this.state.earned_rewards > 0 ? true: false} title="You can claim satoshis!">
<Tooltip open={this.state.earned_rewards > 0 ? true: false} title={t("You can claim satoshis!")}>
<Tooltip open={(this.state.active_order_id > 0 & !this.state.profileShown & this.props.avatarLoaded) ? true: false}
title="You have an active order">
title={t("You have an active order")}>
<ListItemAvatar sx={{ width: 30, height: 30 }} >
<Badge badgeContent={(this.state.active_order_id > 0 & !this.state.profileShown) ? "": null} color="primary">
<Avatar className='flippedSmallAvatar' sx={{margin: 0, top: -13}}
@ -495,7 +505,7 @@ bottomBarDesktop =()=>{
primaryTypographyProps={{fontSize: '14px'}}
secondaryTypographyProps={{fontSize: '12px'}}
primary={this.state.num_public_buy_orders}
secondary="Public Buy Orders" />
secondary={t("Public Buy Orders")} />
</ListItem>
</Grid>
@ -508,7 +518,7 @@ bottomBarDesktop =()=>{
primaryTypographyProps={{fontSize: '14px'}}
secondaryTypographyProps={{fontSize: '12px'}}
primary={this.state.num_public_sell_orders}
secondary="Public Sell Orders" />
secondary={t("Public Sell Orders")} />
</ListItem>
</Grid>
@ -521,7 +531,7 @@ bottomBarDesktop =()=>{
primaryTypographyProps={{fontSize: '14px'}}
secondaryTypographyProps={{fontSize: '12px'}}
primary={this.state.active_robots_today}
secondary="Today Active Robots" />
secondary={t("Today Active Robots")}/>
</ListItem>
</Grid>
@ -534,7 +544,7 @@ bottomBarDesktop =()=>{
primaryTypographyProps={{fontSize: '14px'}}
secondaryTypographyProps={{fontSize: '12px'}}
primary={this.state.last_day_nonkyc_btc_premium+"%"}
secondary="24h Avg Premium" />
secondary={t("24h Avg Premium")} />
</ListItem>
</Grid>
@ -547,23 +557,16 @@ bottomBarDesktop =()=>{
primaryTypographyProps={{fontSize: '14px'}}
secondaryTypographyProps={{fontSize: '12px'}}
primary={(this.state.maker_fee + this.state.taker_fee)*100}
secondary="Trade Fee" />
secondary={t("Trade Fee")} />
</ListItem>
</Grid>
<Grid container item xs={1}>
<Grid item xs={6}>
<Select
size = 'small'
defaultValue={1}
inputProps={{
style: {textAlign:"center"}
}}>
<MenuItem value={1}>EN</MenuItem>
</Select>
<this.LangSelect/>
</Grid>
<Grid item xs={3}>
<Tooltip enterTouchDelay="250" title="Show community and support links">
<Tooltip enterTouchDelay="250" title={t("Show community and support links")}>
<IconButton
color="primary"
aria-label="Community"
@ -573,7 +576,7 @@ bottomBarDesktop =()=>{
</Tooltip>
</Grid>
<Grid item xs={3}>
<Tooltip enterTouchDelay="250" title="Show stats for nerds">
<Tooltip enterTouchDelay="250" title={t("Show stats for nerds")}>
<IconButton color="primary"
aria-label="Stats for Nerds"
onClick={this.handleClickOpenStatsForNerds} >
@ -587,7 +590,30 @@ bottomBarDesktop =()=>{
</Paper>
)
}
handleChangeLang=(e)=>{
const { i18n} = this.props;
console.log(i18n)
i18n.changeLanguage(e.target.value)
}
LangSelect = () => {
const { i18n} = this.props;
return(
<Select
size = 'small'
value = {i18n.resolvedLanguage.substring(0,2)}
inputProps={{
style: {textAlign:"center"}
}}
onChange={this.handleChangeLang}>
<MenuItem value={'en'}>EN</MenuItem>
<MenuItem disabled={true} value={'es'}>ES</MenuItem>
<MenuItem disabled={true} value={'de'}>DE</MenuItem>
<MenuItem disabled={true} value={'ru'}>RU</MenuItem>
<MenuItem disabled={true} value={'zh'}>ZH</MenuItem>
</Select>
)
}
handleClickOpenExchangeSummary = () => {
this.getInfo();
this.setState({openExchangeSummary: true});
@ -597,6 +623,7 @@ bottomBarDesktop =()=>{
};
exchangeSummaryDialog =() =>{
const { t } = this.props;
return(
<Dialog
open={this.state.openExchangeSummary}
@ -605,7 +632,7 @@ bottomBarDesktop =()=>{
aria-describedby="exchange-summary-description"
>
<DialogContent>
<Typography component="h5" variant="h5">Exchange Summary</Typography>
<Typography component="h5" variant="h5">{t("Exchange Summary")}</Typography>
<List dense>
<ListItem >
<ListItemIcon size="small">
@ -615,7 +642,7 @@ bottomBarDesktop =()=>{
primaryTypographyProps={{fontSize: '14px'}}
secondaryTypographyProps={{fontSize: '12px'}}
primary={this.state.num_public_buy_orders}
secondary="Public buy orders" />
secondary={t("Public buy orders")} />
</ListItem>
<Divider/>
@ -627,7 +654,7 @@ bottomBarDesktop =()=>{
primaryTypographyProps={{fontSize: '14px'}}
secondaryTypographyProps={{fontSize: '12px'}}
primary={this.state.num_public_sell_orders}
secondary="Public sell orders" />
secondary={t("Public sell orders")} />
</ListItem>
<Divider/>
@ -639,7 +666,7 @@ bottomBarDesktop =()=>{
primaryTypographyProps={{fontSize: '14px'}}
secondaryTypographyProps={{fontSize: '12px'}}
primary={pn(this.state.book_liquidity)+" Sats"}
secondary="Book liquidity" />
secondary={t("Book liquidity")}/>
</ListItem>
<Divider/>
@ -651,7 +678,7 @@ bottomBarDesktop =()=>{
primaryTypographyProps={{fontSize: '14px'}}
secondaryTypographyProps={{fontSize: '12px'}}
primary={this.state.active_robots_today}
secondary="Today active robots" />
secondary={t("Today active robots")} />
</ListItem>
<Divider/>
@ -663,7 +690,7 @@ bottomBarDesktop =()=>{
primaryTypographyProps={{fontSize: '14px'}}
secondaryTypographyProps={{fontSize: '12px'}}
primary={this.state.last_day_nonkyc_btc_premium+"%"}
secondary="24h non-KYC average premium" />
secondary={t("24h non-KYC bitcoin premium")} />
</ListItem>
<Divider/>
@ -676,7 +703,7 @@ bottomBarDesktop =()=>{
<ListItemText
primaryTypographyProps={{fontSize: '14px'}}
secondaryTypographyProps={{fontSize: '12px'}}
secondary="Maker fee">
secondary={t("Maker fee")}>
{(this.state.maker_fee*100).toFixed(3)}%
</ListItemText>
</Grid>
@ -684,7 +711,7 @@ bottomBarDesktop =()=>{
<ListItemText
primaryTypographyProps={{fontSize: '14px'}}
secondaryTypographyProps={{fontSize: '12px'}}
secondary="Taker fee">
secondary={t("Taker fee")}>
{(this.state.taker_fee*100).toFixed(3)}%
</ListItemText>
</Grid>
@ -698,6 +725,7 @@ bottomBarDesktop =()=>{
}
bottomBarPhone =()=>{
const { t } = this.props;
return(
<Paper elevation={6} style={{height:40}}>
<this.StatsDialog/>
@ -708,9 +736,9 @@ bottomBarPhone =()=>{
<Grid item xs={1.6}>
<div style={{display: this.props.avatarLoaded ? '':'none'}}>
<Tooltip open={this.state.earned_rewards > 0 ? true: false} title="You can claim satoshis!">
<Tooltip open={this.state.earned_rewards > 0 ? true: false} title={t("You can claim satoshis!")}>
<Tooltip open={(this.state.active_order_id > 0 & !this.state.profileShown & this.props.avatarLoaded) ? true: false}
title="You have an active order">
title={t("You have an active order")}>
<IconButton onClick={this.handleClickOpenProfile} sx={{margin: 0, bottom: 17, right: 8}} >
<Badge badgeContent={(this.state.active_order_id >0 & !this.state.profileShown) ? "": null} color="primary">
<Avatar className='phoneFlippedSmallAvatar'
@ -729,7 +757,7 @@ bottomBarPhone =()=>{
</Grid>
<Grid item xs={1.6} align="center">
<Tooltip enterTouchDelay="300" title="Number of public BUY orders">
<Tooltip enterTouchDelay="300" title={t("Number of public BUY orders")}>
<IconButton onClick={this.handleClickOpenExchangeSummary} >
<Badge badgeContent={this.state.num_public_buy_orders} color="action">
<InventoryIcon />
@ -739,7 +767,7 @@ bottomBarPhone =()=>{
</Grid>
<Grid item xs={1.6} align="center">
<Tooltip enterTouchDelay="300" title="Number of public SELL orders">
<Tooltip enterTouchDelay="300" title={t("Number of public SELL orders")}>
<IconButton onClick={this.handleClickOpenExchangeSummary} >
<Badge badgeContent={this.state.num_public_sell_orders} color="action">
<SellIcon />
@ -749,7 +777,7 @@ bottomBarPhone =()=>{
</Grid>
<Grid item xs={1.6} align="center">
<Tooltip enterTouchDelay="300" title="Today active robots">
<Tooltip enterTouchDelay="300" title={t("Today active robots")}>
<IconButton onClick={this.handleClickOpenExchangeSummary} >
<Badge badgeContent={this.state.active_robots_today} color="action">
<SmartToyIcon />
@ -759,7 +787,7 @@ bottomBarPhone =()=>{
</Grid>
<Grid item xs={1.8} align="center">
<Tooltip enterTouchDelay="300" title="24h non-KYC bitcoin premium">
<Tooltip enterTouchDelay="300" title={t("24h non-KYC bitcoin premium")}>
<IconButton onClick={this.handleClickOpenExchangeSummary} >
<Badge badgeContent={this.state.last_day_nonkyc_btc_premium+"%"} color="action">
<PriceChangeIcon />
@ -770,17 +798,10 @@ bottomBarPhone =()=>{
<Grid container item xs={3.8}>
<Grid item xs={6}>
<Select
size = 'small'
defaultValue={1}
inputProps={{
style: {textAlign:"center"}
}}>
<MenuItem value={1}>EN</MenuItem>
</Select>
<this.LangSelect/>
</Grid>
<Grid item xs={3}>
<Tooltip enterTouchDelay="250" title="Show community and support links">
<Tooltip enterTouchDelay="250" title={t("Show community and support links")}>
<IconButton
color="primary"
aria-label="Community"
@ -790,7 +811,7 @@ bottomBarPhone =()=>{
</Tooltip>
</Grid>
<Grid item xs={3}>
<Tooltip enterTouchDelay="250" title="Show stats for nerds">
<Tooltip enterTouchDelay="250" title={t("Show stats for nerds")}>
<IconButton color="primary"
aria-label="Stats for Nerds"
onClick={this.handleClickOpenStatsForNerds} >
@ -819,3 +840,4 @@ bottomBarPhone =()=>{
)
}
}
export default withTranslation()(BottomBar);

View File

@ -1,8 +1,9 @@
import React, { Component } from 'react';
import { withTranslation, Trans} from "react-i18next";
import {Button, Link, Badge, TextField, Grid, Container, Card, CardHeader, Paper, Avatar, FormHelperText, Typography} from "@mui/material";
import ReconnectingWebSocket from 'reconnecting-websocket';
export default class Chat extends Component {
class Chat extends Component {
constructor(props) {
super(props);
}
@ -79,6 +80,7 @@ export default class Chat extends Component {
}
render() {
const { t } = this.props;
return (
<Container component="main" maxWidth="xs" >
<Grid container xs={12} spacing={0.5}>
@ -86,7 +88,7 @@ export default class Chat extends Component {
<Grid item xs={5.5}>
<Paper elevation={1} style={this.state.connected ? {backgroundColor: '#e8ffe6'}: {backgroundColor: '#FFF1C5'}}>
<Typography variant='caption' sx={{color: '#111111'}}>
You: {this.state.connected ? 'connected': 'disconnected'}
{t("You")+": "}{this.state.connected ? t("connected"): t("disconnected")}
</Typography>
</Paper>
</Grid>
@ -94,7 +96,7 @@ export default class Chat extends Component {
<Grid item xs={5.5}>
<Paper elevation={1} style={this.state.peer_connected ? {backgroundColor: '#e8ffe6'}: {backgroundColor: '#FFF1C5'}}>
<Typography variant='caption' sx={{color: '#111111'}}>
Peer: {this.state.peer_connected ? 'connected': 'disconnected'}
{t("Peer")+": "}{this.state.peer_connected ? t("connected"): t("disconnected")}
</Typography>
</Paper>
</Grid>
@ -142,10 +144,10 @@ export default class Chat extends Component {
<Grid containter alignItems="stretch" style={{ display: "flex" }}>
<Grid item alignItems="stretch" style={{ display: "flex"}}>
<TextField
label="Type a message"
label={t("Type a message")}
variant="standard"
size="small"
helperText={this.state.connected ? null : "Connecting..."}
helperText={this.state.connected ? null : t("Connecting...")}
value={this.state.value}
onChange={e => {
this.setState({ value: e.target.value });
@ -155,14 +157,16 @@ export default class Chat extends Component {
/>
</Grid>
<Grid item alignItems="stretch" style={{ display: "flex" }}>
<Button disabled={!this.state.connected} type="submit" variant="contained" color="primary" > Send </Button>
<Button disabled={!this.state.connected} type="submit" variant="contained" color="primary">{t("Send")} </Button>
</Grid>
</Grid>
</form>
<FormHelperText>
The chat has no memory: if you leave, messages are lost. <Link target="_blank" href="https://github.com/Reckless-Satoshi/robosats/blob/main/docs/sensitive-data-PGP-guide.md/"> Learn easy PGP encryption.</Link>
{t("The chat has no memory: if you leave, messages are lost.")} <Link target="_blank" href="https://github.com/Reckless-Satoshi/robosats/blob/main/docs/sensitive-data-PGP-guide.md/"> {t("Learn easy PGP encryption.")}</Link>
</FormHelperText>
</Container>
)
}
}
export default withTranslation()(Chat);

View File

@ -1,11 +1,12 @@
import {Typography, Link, DialogActions, DialogContent, Button, Grid} from "@mui/material"
import React, { Component } from 'react'
import { withTranslation, Trans} from "react-i18next";
import {Typography, Link, DialogActions, DialogContent, Button, Grid} from "@mui/material"
import Image from 'material-ui-image'
import MediaQuery from 'react-responsive'
export default class InfoDialog extends Component {
class InfoDialog extends Component {
render() {
const { t } = this.props;
return (
<div>
<DialogContent>
@ -13,13 +14,13 @@ export default class InfoDialog extends Component {
<MediaQuery minWidth={475}>
<Grid container xs={12}>
<Grid item xs={8}>
<Typography component="h4" variant="h4">What is <i>RoboSats</i>?</Typography>
<Typography component="h4" variant="h4">{t("What is RoboSats?")}</Typography>
<Typography component="body2" variant="body2">
<p>It is a BTC/FIAT peer-to-peer exchange over lightning. <br/> It simplifies
matchmaking and minimizes the need of trust. RoboSats focuses in privacy and speed.</p>
<p>{t("It is a BTC/FIAT peer-to-peer exchange over lightning.")} <br/>
{t("It simplifies matchmaking and minimizes the need of trust. RoboSats focuses in privacy and speed.")}</p>
<p>RoboSats is an open source project <Link
href='https://github.com/reckless-satoshi/robosats'>(GitHub).</Link>
<p>{t("RoboSats is an open source project ")} <Link
href='https://github.com/reckless-satoshi/robosats'>{t("(GitHub).")}</Link>
</p>
</Typography>
</Grid>
@ -35,130 +36,80 @@ export default class InfoDialog extends Component {
</MediaQuery>
<MediaQuery maxWidth={474}>
<Typography component="h4" variant="h4">What is <i>RoboSats</i>?</Typography>
<Typography component="h4" variant="h4">{t("What is RoboSats?")}</Typography>
<Typography component="body2" variant="body2">
<p>It is a BTC/FIAT peer-to-peer exchange over lightning. It simplifies
matchmaking and minimizes the need for trust. RoboSats focuses in privacy and speed.</p>
<p>{t("It is a BTC/FIAT peer-to-peer exchange over lightning.")+" "} {t("It simplifies matchmaking and minimizes the need of trust. RoboSats focuses in privacy and speed.")}</p>
<img
width='100%'
src={window.location.origin +'/static/assets/images/robosats_0.1.0_banner.png'}
/>
<p>RoboSats is an open source project <Link
href='https://github.com/reckless-satoshi/robosats'>(GitHub).</Link>
<p>{t("RoboSats is an open source project ")} <Link
href='https://github.com/reckless-satoshi/robosats'>{t("(GitHub).")}</Link>
</p>
</Typography>
</MediaQuery>
<Typography component="h5" variant="h5">How does it work?</Typography>
<Typography component="h5" variant="h5">{t("How does it work?")}</Typography>
<Typography component="body2" variant="body2">
<p> AnonymousAlice01 wants to sell bitcoin. She posts a sell order.
BafflingBob02 wants to buy bitcoin and he takes Alice's order.
Both have to post a small bond using lightning to prove they are real
robots. Then, Alice posts the trade collateral also using a lightning
hold invoice. <i>RoboSats</i> locks the invoice until Alice confirms she
received the fiat, then the satoshis are released to Bob. Enjoy your satoshis,
Bob!</p>
<p> {t("AnonymousAlice01 wants to sell bitcoin. She posts a sell order. BafflingBob02 wants to buy bitcoin and he takes Alice's order. Both have to post a small bond using lightning to prove they are real robots. Then, Alice posts the trade collateral also using a lightning hold invoice. RoboSats locks the invoice until Alice confirms she received the fiat, then the satoshis are released to Bob. Enjoy your satoshis, Bob!")}</p>
<p>At no point, AnonymousAlice01 and BafflingBob02 have to entrust the
bitcoin funds to each other. In case they have a conflict, <i>RoboSats</i> staff
will help resolving the dispute. You can find a step-by-step
description of the trade pipeline in <Link href='https://github.com/Reckless-Satoshi/robosats/blob/main/README.md#how-it-works'>How it works</Link>
You can also check the full guide in <Link href='https://github.com/Reckless-Satoshi/robosats/blob/main/docs/how-to-use.md'>How to use</Link></p>
<p>{t("At no point, AnonymousAlice01 and BafflingBob02 have to entrust the bitcoin funds to each other. In case they have a conflict, RoboSats staff will help resolving the dispute.")}
{t("You can find a step-by-step description of the trade pipeline in ")}
<Link href='https://github.com/Reckless-Satoshi/robosats/blob/main/README.md#how-it-works'>{t("How it works")}</Link>
{t("You can also check the full guide in ")}
<Link href='https://github.com/Reckless-Satoshi/robosats/blob/main/docs/how-to-use.md'>{t("How to use")}</Link></p>
</Typography>
<Typography component="h5" variant="h5">What payment methods are accepted?</Typography>
<Typography component="h5" variant="h5">{t("What payment methods are accepted?")}</Typography>
<Typography component="body2" variant="body2">
<p>Basically all of them as long as they are fast. You can write down your preferred payment
method(s). You will have to match with a peer who also accepts that method. The step to
exchange fiat has a expiry time of 24 hours before a dispute is automatically
open. We highly recommend using instant fiat payment rails. </p>
<p>{t("All of them as long as they are fast. You can write down your preferred payment method(s). You will have to match with a peer who also accepts that method. The step to exchange fiat has a expiry time of 24 hours before a dispute is automatically open. We highly recommend using instant fiat payment rails.")} </p>
</Typography>
<Typography component="h5" variant="h5">Are there trade limits?</Typography>
<Typography component="h5" variant="h5">{t("Are there trade limits?")}</Typography>
<Typography component="body2" variant="body2">
<p>Maximum single trade size is 800,000 Satoshis to minimize lightning
routing failure. There is no limits to the number of trades per day. A robot
can only have one order at a time. However, you can use multiple
robots simultaneously in different browsers (remember to back up your robot tokens!). </p>
<p>{t("Maximum single trade size is {{maxAmount}} Satoshis to minimize lightning routing failure. There is no limits to the number of trades per day. A robot can only have one order at a time. However, you can use multiple robots simultaneously in different browsers (remember to back up your robot tokens!).", {maxAmount: '800,000'})} </p>
</Typography>
<Typography component="h5" variant="h5">Is <i>RoboSats</i> private?</Typography>
<Typography component="h5" variant="h5">{t("Is RoboSats private?")}</Typography>
<Typography component="body2" variant="body2">
<p> RoboSats will never ask you for your name, country or ID. RoboSats does
not custody your funds, and doesn't care who you are. For best anonymity
use Tor Browser and access the .onion hidden service. </p>
<p>Your trading peer is the only one who can potentially guess
anything about you. Keep your chat short and concise. Avoid
providing non-essential information other than strictly necessary
for the fiat payment. </p>
<p> {t("RoboSats will never ask you for your name, country or ID. RoboSats does not custody your funds and does not care who you are. RoboSats does not collect or custody any personal data. For best anonymity use Tor Browser and access the .onion hidden service.")} </p>
<p>{t("Your trading peer is the only one who can potentially guess anything about you. Keep your chat short and concise. Avoid providing non-essential information other than strictly necessary for the fiat payment.")} </p>
</Typography>
<Typography component="h5" variant="h5">What are the risks?</Typography>
<Typography component="h5" variant="h5">{t("What are the risks?")}</Typography>
<Typography component="body2" variant="body2">
<p> This is an experimental application, things could go wrong.
Trade small amounts! </p>
<p>The seller faces the same charge-back risk as with any
other peer-to-peer service. Paypal or credit cards are
not recommended.</p>
<p> {t("This is an experimental application, things could go wrong. Trade small amounts!")}</p>
<p> {t("The seller faces the same charge-back risk as with any other peer-to-peer service. Paypal or credit cards are not recommended.")}</p>
</Typography>
<Typography component="h5" variant="h5">What is the trust model?</Typography>
<Typography component="h5" variant="h5">{t("What is the trust model?")}</Typography>
<Typography component="body2" variant="body2">
<p> The buyer and the seller never have to trust each other.
Some trust on <i>RoboSats</i> is needed since linking the
seller's hold invoice and buyer payment is not atomic (yet).
In addition, disputes are solved by the <i>RoboSats</i> staff.
</p>
<p> To be totally clear. Trust requirements are minimized. However, there is still
one way <i>RoboSats </i> could run away with your satoshis: by not releasing
the satoshis to the buyer. It could be argued that such move is not in <i>RoboSats' </i>
interest as it would damage the reputation for a small payout.
However, you should hesitate and only trade small quantities at a
time. For large amounts use an onchain escrow service such as <i>Bisq</i>
</p>
<p> You can build more trust on <i>RoboSats</i> by <Link href='https://github.com/reckless-satoshi/robosats'>
inspecting the source code. </Link> </p>
<p> {t("The buyer and the seller never have to trust each other. Some trust on RoboSats is needed since linking the seller's hold invoice and buyer payment is not atomic (yet). In addition, disputes are solved by the RoboSats staff.")}</p>
<p> {t("To be totally clear. Trust requirements are minimized. However, there is still one way RoboSats could run away with your satoshis: by not releasing the satoshis to the buyer. It could be argued that such move is not in RoboSats' interest as it would damage the reputation for a small payout. However, you should hesitate and only trade small quantities at a time. For large amounts use an onchain escrow service such as Bisq")}</p>
<p> {t("You can build more trust on RoboSats by inspecting the source code.")} <Link href='https://github.com/reckless-satoshi/robosats'> {t("Project source code")} </Link> </p>
</Typography>
<Typography component="h5" variant="h5">What happens if <i>RoboSats</i> suddenly disappears?</Typography>
<Typography component="h5" variant="h5">{t("What happens if RoboSats suddenly disappears?")}</Typography>
<Typography component="body2" variant="body2">
<p> Your sats will return to you. Any hold invoice that is not
settled would be automatically returned even if <i>RoboSats</i> goes down
forever. This is true for both, locked bonds and trading escrows. However,
there is a small window between the seller confirms FIAT RECEIVED and the moment
the buyer receives the satoshis when the funds could be permanently lost if
<i> RoboSats</i> disappears. This window is about 1 second long. Make sure to have enough
inbound liquidity to avoid routing failures. If you have any problem, reach out
trough the <i>RoboSats</i> public channels.
</p>
<p> {t("Your sats will return to you. Any hold invoice that is not settled would be automatically returned even if RoboSats goes down forever. This is true for both, locked bonds and trading escrows. However, there is a small window between the seller confirms FIAT RECEIVED and the moment the buyer receives the satoshis when the funds could be permanently lost if RoboSats disappears. This window is about 1 second long. Make sure to have enough inbound liquidity to avoid routing failures. If you have any problem, reach out trough the RoboSats public channels.")}</p>
</Typography>
<Typography component="h5" variant="h5">Is <i>RoboSats</i> legal in my country?</Typography>
<Typography component="h5" variant="h5">{t("Is RoboSats legal in my country?")}</Typography>
<Typography component="body2" variant="body2">
<p> In many countries using <i>RoboSats</i> is no different than using Ebay
or Craiglist. Your regulation may vary. It is your responsibility
to comply.
</p>
<p> {t("In many countries using RoboSats is no different than using Ebay or Craiglist. Your regulation may vary. It is your responsibility to comply.")}</p>
</Typography>
<Typography component="h5" variant="h5">Disclaimer</Typography>
<Typography component="h5" variant="h5">{t("Disclaimer")}</Typography>
<Typography component="body2" variant="body2">
<p> This lightning application is provided as is. It is in active
development: trade with the utmost caution. There is no private
support. Support is only offered via public channels <Link href='https://t.me/robosats'>
(Telegram)</Link>. <i>RoboSats</i> will never contact you. <i>
RoboSats</i> will definitely never ask for your robot token.
</p>
<p> {t("This lightning application is provided as is. It is in active development: trade with the utmost caution. There is no private support. Support is only offered via public channels ")}<Link href='https://t.me/robosats'>{t("(Telegram)")}</Link>{t(". RoboSats will never contact you. RoboSats will definitely never ask for your robot token.")}</p>
</Typography>
<DialogActions>
<Button onClick={this.props.handleCloseInfo}>Close</Button>
<Button onClick={this.props.handleCloseInfo}>{t("Close")}</Button>
</DialogActions>
</DialogContent>
</div>
)
}
}
}
export default withTranslation()(InfoDialog);

View File

@ -1,13 +1,18 @@
import React, { Component } from 'react';
import { withTranslation, Trans} from "react-i18next";
import { InputAdornment, LinearProgress, Link, Checkbox, Slider, Box, Tab, Tabs, SliderThumb, Tooltip, Paper, Button , Grid, Typography, TextField, Select, FormHelperText, MenuItem, FormControl, Radio, FormControlLabel, RadioGroup} from "@mui/material"
import { LocalizationProvider, TimePicker} from '@mui/lab';
import DateFnsUtils from "@date-io/date-fns";
import { Link as LinkRouter } from 'react-router-dom'
import { styled } from '@mui/material/styles';
import getFlags from './getFlags';
import AutocompletePayments from './autocompletePayments';
import LockIcon from '@mui/icons-material/Lock';
import HourglassTopIcon from '@mui/icons-material/HourglassTop';
import currencyDict from '../../static/assets/currencies.json';
function getCookie(name) {
let cookieValue = null;
@ -36,7 +41,7 @@ function pn(x) {
return parts.join(".");
}
export default class MakerPage extends Component {
class MakerPage extends Component {
defaultCurrency = 1;
defaultCurrencyCode = 'USD';
defaultPaymentMethod = "not specified";
@ -57,7 +62,6 @@ export default class MakerPage extends Component {
payment_method: this.defaultPaymentMethod,
premium: 0,
satoshis: null,
currencies_dict: {"1":"USD"},
showAdvanced: false,
allowBondless: false,
publicExpiryTime: new Date(0, 0, 0, 23, 59),
@ -69,7 +73,6 @@ export default class MakerPage extends Component {
maxAmount: null,
loadingLimits: false,
}
this.getCurrencyDict()
}
getLimits() {
@ -173,11 +176,14 @@ export default class MakerPage extends Component {
}
handlePremiumChange=(e)=>{
const { t } = this.props;
var max = 999;
var min = -100;
if(e.target.value > 999){
var bad_premium = "Must be less than 999%"
var bad_premium = t("Must be less than {{max}}%", {max:max})
}
if(e.target.value < -100){
var bad_premium = "Must be more than -100%"
if(e.target.value <= -100){
var bad_premium = t("Must be more than {{min}}%", {min:min})
}
this.setState({
@ -187,11 +193,12 @@ export default class MakerPage extends Component {
}
handleSatoshisChange=(e)=>{
const { t } = this.props;
if(e.target.value > this.maxTradeSats){
var bad_sats = "Must be less than " + pn(this.maxTradeSats)
var bad_sats = t("Must be less than {{maxSats}",{maxSats: pn(this.maxTradeSats)})
}
if(e.target.value < this.minTradeSats){
var bad_sats = "Must be more than "+pn(this.minTradeSats)
var bad_sats = t("Must be more than {{minSats}}",{minSats: pn(this.minTradeSats)})
}
this.setState({
@ -207,10 +214,12 @@ export default class MakerPage extends Component {
}
handleClickExplicit=(e)=>{
this.setState({
is_explicit: true,
});
this.handleSatoshisChange();
if(!this.state.enableAmountRange){
this.setState({
is_explicit: true,
});
this.handleSatoshisChange();
}
}
handleCreateOfferButtonPressed=()=>{
@ -240,18 +249,8 @@ export default class MakerPage extends Component {
& (data.id ? this.props.history.push('/order/' + data.id) :"")));
}
getCurrencyDict() {
fetch('/static/assets/currencies.json')
.then((response) => response.json())
.then((data) =>
this.setState({
currencies_dict: data
}));
}
getCurrencyCode(val){
return this.state.currencies_dict[val.toString()]
return currencyDict[val.toString()]
}
handleInputBondSizeChange = (event) => {
@ -259,25 +258,26 @@ export default class MakerPage extends Component {
};
StandardMakerOptions = () => {
const { t } = this.props;
return(
<Paper elevation={12} style={{ padding: 8, width:'260px', align:'center'}}>
<Grid item xs={12} align="center" spacing={1}>
<div style={{position:'relative', left:'5px'}}>
<FormControl component="fieldset">
<FormHelperText>
Buy or Sell Bitcoin?
{t("Buy or Sell Bitcoin?")}
</FormHelperText>
<RadioGroup row defaultValue="0" onChange={this.handleTypeChange}>
<FormControlLabel
value="0"
control={<Radio color="primary"/>}
label="Buy"
label={t("Buy")}
labelPlacement="Top"
/>
<FormControlLabel
value="1"
control={<Radio color="secondary"/>}
label="Sell"
label={t("Sell")}
labelPlacement="Top"
/>
</RadioGroup>
@ -287,13 +287,13 @@ export default class MakerPage extends Component {
<Grid containter xs={12} alignItems="stretch" style={{ display: "flex" }}>
<div style={{maxWidth:150}}>
<Tooltip placement="top" enterTouchDelay="500" enterDelay="700" enterNextDelay="2000" title="Amount of fiat to exchange for bitcoin">
<Tooltip placement="top" enterTouchDelay="500" enterDelay="700" enterNextDelay="2000" title={t("Amount of fiat to exchange for bitcoin")}>
<TextField
disabled = {this.state.enableAmountRange}
variant = {this.state.enableAmountRange ? 'filled' : 'outlined'}
error={this.state.amount <= 0 & this.state.amount != "" }
helperText={this.state.amount <= 0 & this.state.amount != "" ? 'Invalid' : null}
label="Amount"
helperText={this.state.amount <= 0 & this.state.amount != "" ? t("Invalid") : null}
label={t("Amount")}
type="number"
required="true"
value={this.state.amount}
@ -314,7 +314,7 @@ export default class MakerPage extends Component {
style: {textAlign:"center"}
}}
onChange={this.handleCurrencyChange}>
{Object.entries(this.state.currencies_dict)
{Object.entries(currencyDict)
.map( ([key, value]) => <MenuItem value={parseInt(key)}>
<div style={{display:'flex',alignItems:'center', flexWrap:'wrap'}}>{getFlags(value)}{" "+value}</div>
</MenuItem> )}
@ -323,13 +323,15 @@ export default class MakerPage extends Component {
</Grid>
<Grid item xs={12} align="center">
<Tooltip placement="top" enterTouchDelay="300" enterDelay="700" enterNextDelay="2000" title="Enter your preferred fiat payment methods. Fast methods are highly recommended.">
<Tooltip placement="top" enterTouchDelay="300" enterDelay="700" enterNextDelay="2000" title={t("Enter your preferred fiat payment methods. Fast methods are highly recommended.")}>
<AutocompletePayments
onAutocompleteChange={this.handlePaymentMethodChange}
optionsType={this.state.currency==1000 ? "swap":"fiat"}
error={this.state.badPaymentMethod}
helperText={this.state.badPaymentMethod ? "Must be shorter than 65 characters":""}
label={this.state.currency==1000 ? "Swap Destination(s)" : "Fiat Payment Method(s)"}
helperText={this.state.badPaymentMethod ? t("Must be shorter than 65 characters"):""}
label={this.state.currency==1000 ? t("Swap Destination(s)") : t("Fiat Payment Method(s)")}
listHeaderText={t("You can add any method")}
addNewButtonText={t("Add New")}
/>
</Tooltip>
</Grid>
@ -338,25 +340,25 @@ export default class MakerPage extends Component {
<FormControl component="fieldset">
<FormHelperText >
<div align='center'>
Choose a Pricing Method
{t("Choose a Pricing Method")}
</div>
</FormHelperText>
<RadioGroup row defaultValue="relative">
<Tooltip placement="top" enterTouchDelay="0" enterDelay="1000" enterNextDelay="2000" title="Let the price move with the market">
<Tooltip placement="top" enterTouchDelay="0" enterDelay="1000" enterNextDelay="2000" title={t("Let the price move with the market")}>
<FormControlLabel
value="relative"
control={<Radio color="primary"/>}
label="Relative"
label={t("Relative")}
labelPlacement="Top"
onClick={this.handleClickRelative}
/>
</Tooltip>
<Tooltip placement="top" enterTouchDelay="0" enterDelay="1000" enterNextDelay="2000" title="Set a fix amount of satoshis">
<Tooltip placement="top" enterTouchDelay="0" enterDelay="1000" enterNextDelay="2000" title={t("Set a fix amount of satoshis")}>
<FormControlLabel
disabled={this.state.enableAmountRange}
value="explicit"
control={<Radio color="secondary"/>}
label="Explicit"
label={t("Explicit")}
labelPlacement="Top"
onClick={this.handleClickExplicit}
/>
@ -369,20 +371,18 @@ export default class MakerPage extends Component {
<div style={{display: this.state.is_explicit ? '':'none'}}>
<TextField
sx={{width:240}}
label="Satoshis"
label={t("Satoshis")}
error={this.state.badSatoshis}
helperText={this.state.badSatoshis}
type="number"
required="true"
value={this.state.satoshis}
inputProps={{
// TODO read these from .env file
min:this.minTradeSats ,
max:this.maxTradeSats ,
style: {textAlign:"center"}
}}
onChange={this.handleSatoshisChange}
// defaultValue={this.defaultSatoshis}
/>
</div>
<div style={{display: this.state.is_explicit ? 'none':''}}>
@ -390,9 +390,8 @@ export default class MakerPage extends Component {
sx={{width:240}}
error={this.state.badPremium}
helperText={this.state.badPremium}
label="Premium over Market (%)"
label={t("Premium over Market (%)")}
type="number"
// defaultValue={this.defaultPremium}
inputProps={{
min: -100,
max: 999,
@ -492,10 +491,10 @@ export default class MakerPage extends Component {
}
rangeText =()=> {
const { t } = this.props;
return (
<div style={{display:'flex',alignItems:'center', flexWrap:'wrap'}}>
<span style={{width: 40}}>From</span>
<span style={{width: 40}}>{t("From")}</span>
<TextField
variant="standard"
type="number"
@ -505,7 +504,7 @@ export default class MakerPage extends Component {
error={this.minAmountError()}
sx={{width: this.state.minAmount.toString().length * 9, maxWidth: 40}}
/>
<span style={{width: 20}}>to</span>
<span style={{width: 20}}>{t("to")}</span>
<TextField
variant="standard"
size="small"
@ -522,6 +521,7 @@ export default class MakerPage extends Component {
}
AdvancedMakerOptions = () => {
const { t } = this.props;
return(
<Paper elevation={12} style={{ padding: 8, width:'280px', align:'center'}}>
@ -530,10 +530,10 @@ export default class MakerPage extends Component {
<Grid item xs={12} align="center" spacing={1}>
<FormControl align="center">
<FormHelperText>
<Tooltip enterTouchDelay="0" placement="top" align="center"title={"Let the taker chose an amount within the range"}>
<Tooltip enterTouchDelay="0" placement="top" align="center" title={t("Let the taker chose an amount within the range")}>
<div align="center" style={{display:'flex',alignItems:'center', flexWrap:'wrap'}}>
<Checkbox onChange={(e)=>this.setState({enableAmountRange:e.target.checked}) & (e.target.checked ? this.getLimits() : null)}/>
{this.state.enableAmountRange & this.state.minAmount != null? <this.rangeText/> : "Enable Amount Range"}
<Checkbox onChange={(e)=>this.setState({enableAmountRange:e.target.checked, is_explicit: false}) & (e.target.checked ? this.getLimits() : null)}/>
{this.state.enableAmountRange & this.state.minAmount != null? <this.rangeText/> : t("Enable Amount Range")}
</div>
</Tooltip>
</FormHelperText>
@ -583,7 +583,7 @@ export default class MakerPage extends Component {
</InputAdornment>)
}}
renderInput={(props) => <TextField {...props} />}
label="Public Duration (HH:mm)"
label={t("Public Duration (HH:mm)")}
value={this.state.publicExpiryTime}
onChange={this.handleChangePublicDuration}
minTime={new Date(0, 0, 0, 0, 10)}
@ -594,10 +594,10 @@ export default class MakerPage extends Component {
<Grid item xs={12} align="center" spacing={1}>
<FormControl align="center">
<Tooltip enterDelay="800" enterTouchDelay="0" placement="top" title={"Set the skin-in-the-game, increase for higher safety assurance"}>
<Tooltip enterDelay="800" enterTouchDelay="0" placement="top" title={t("Set the skin-in-the-game, increase for higher safety assurance")}>
<FormHelperText>
<div align="center" style={{display:'flex',flexWrap:'wrap', transform: 'translate(20%, 0)'}}>
Fidelity Bond Size <LockIcon sx={{height:20,width:20}}/>
{t("Fidelity Bond Size")} <LockIcon sx={{height:20,width:20}}/>
</div>
</FormHelperText>
</Tooltip>
@ -618,9 +618,9 @@ export default class MakerPage extends Component {
</Grid>
<Grid item xs={12} align="center" spacing={1}>
<Tooltip enterTouchDelay="0" title={"COMING SOON - High risk! Limited to "+ this.maxBondlessSats/1000 +"K Sats"}>
<Tooltip enterTouchDelay="0" title={t("COMING SOON - High risk! Limited to {{limitSats}}K Sats",{ limitSats: this.maxBondlessSats/1000})}>
<FormControlLabel
label={<a>Allow bondless taker (<Link href="https://git.robosats.com" target="_blank">info</Link>)</a>}
label={t("Allow bondless takers")}
control={
<Checkbox
disabled
@ -640,7 +640,7 @@ export default class MakerPage extends Component {
makeOrderBox=()=>{
const [value, setValue] = React.useState(this.state.showAdvanced);
const { t } = this.props;
const handleChange = (event, newValue) => {
this.setState({showAdvanced:newValue})
setValue(newValue);
@ -649,8 +649,8 @@ export default class MakerPage extends Component {
<Box sx={{width: this.state.showAdvanced? '270px':'252px'}}>
<Box sx={{ borderBottom: 1, borderColor: 'divider', position:'relative',left:'5px'}}>
<Tabs value={value? value:0} onChange={handleChange} variant="fullWidth" >
<Tab label="Order" {...this.a11yProps(0)} />
<Tab label="Customize" {...this.a11yProps(1)} />
<Tab label={t("Order")} {...this.a11yProps(0)} />
<Tab label={t("Customize")} {...this.a11yProps(1)} />
</Tabs>
</Box>
@ -666,6 +666,7 @@ export default class MakerPage extends Component {
)
}
render() {
const { t } = this.props;
return (
<Grid container xs={12} align="center" spacing={1} sx={{minWidth:380}}>
{/* <Grid item xs={12} align="center" sx={{minWidth:380}}>
@ -685,11 +686,11 @@ export default class MakerPage extends Component {
(this.state.is_explicit & (this.state.badSatoshis != null || this.state.satoshis == null)) ||
(!this.state.is_explicit & this.state.badPremium != null))
?
<Tooltip enterTouchDelay="0" title="You must fill the form correctly">
<div><Button disabled color="primary" variant="contained" onClick={this.handleCreateOfferButtonPressed} >Create Order</Button></div>
<Tooltip enterTouchDelay="0" title={t("You must fill the order correctly")}>
<div><Button disabled color="primary" variant="contained" onClick={this.handleCreateOfferButtonPressed}>{t("Create Order")}</Button></div>
</Tooltip>
:
<Button color="primary" variant="contained" onClick={this.handleCreateOfferButtonPressed} >Create Order</Button>
<Button color="primary" variant="contained" onClick={this.handleCreateOfferButtonPressed}>{t("Create Order")}</Button>
}
</Grid>
@ -701,22 +702,37 @@ export default class MakerPage extends Component {
: ""}
<Typography component="subtitle2" variant="subtitle2">
<div align='center'>
Create a BTC {this.state.type==0 ? "buy":"sell"} order for {this.state.enableAmountRange & this.state.minAmount != null?
" "+this.state.minAmount+"-"+this.state.maxAmount : pn(this.state.amount)} {this.state.currencyCode}
{this.state.is_explicit ? " of " + pn(this.state.satoshis) + " Satoshis" :
(this.state.premium == 0 ? " at market price" :
(this.state.premium > 0 ? " at a " + this.state.premium + "% premium":" at a " + -this.state.premium + "% discount")
{this.state.type==0 ?
t("Create a BTC buy order for ")
:
t("Create a BTC sell order for ")
}
{this.state.enableAmountRange & this.state.minAmount != null?
this.state.minAmount+"-"+this.state.maxAmount
:
pn(this.state.amount)}
{" " + this.state.currencyCode}
{this.state.is_explicit ?
t(" of {{satoshis}} Satoshis",{satoshis: pn(this.state.satoshis)})
:
(this.state.premium == 0 ? t(" at market price") :
(this.state.premium > 0 ?
t(" at a {{premium}}% premium", {premium: this.state.premium})
:
t(" at a {{discount}}% discount", {discount: -this.state.premium}))
)
}
</div>
</Typography>
<Grid item xs={12} align="center">
<Button color="secondary" variant="contained" to="/" component={LinkRouter}>
Back
{t("Back")}
</Button>
</Grid>
</Grid>
</Grid>
);
}
}
}
export default withTranslation()(MakerPage);

View File

@ -1,7 +1,9 @@
import React, { Component } from "react";
import { withTranslation, Trans} from "react-i18next";
import {TextField,Chip, Tooltip, Badge, Tab, Tabs, Alert, Paper, CircularProgress, Button , Grid, Typography, List, ListItem, ListItemIcon, ListItemText, ListItemAvatar, Avatar, Divider, Box, LinearProgress, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle} from "@mui/material"
import Countdown, { zeroPad, calcTimeDelta } from 'react-countdown';
import MediaQuery from 'react-responsive'
import currencyDict from '../../static/assets/currencies.json';
import PaymentText from './PaymentText'
import TradeBox from "./TradeBox";
@ -13,6 +15,7 @@ import NumbersIcon from '@mui/icons-material/Numbers';
import PriceChangeIcon from '@mui/icons-material/PriceChange';
import PaymentsIcon from '@mui/icons-material/Payments';
import ArticleIcon from '@mui/icons-material/Article';
import { t } from "i18next";
function getCookie(name) {
let cookieValue = null;
@ -38,13 +41,12 @@ function pn(x) {
return parts.join(".");
}
export default class OrderPage extends Component {
class OrderPage extends Component {
constructor(props) {
super(props);
this.state = {
is_explicit: false,
delay: 60000, // Refresh every 60 seconds by default
currencies_dict: {"1":"USD"},
total_secs_exp: 300,
loading: true,
openCancel: false,
@ -53,7 +55,6 @@ export default class OrderPage extends Component {
showContractBox: 1,
};
this.orderId = this.props.match.params.orderId;
this.getCurrencyDict();
this.getOrderDetails();
// Refresh delays according to Order status
@ -127,9 +128,10 @@ export default class OrderPage extends Component {
// Countdown Renderer callback with condition
countdownRenderer = ({ total, hours, minutes, seconds, completed }) => {
const { t } = this.props;
if (completed) {
// Render a completed state
return (<span> The order has expired</span>);
return (<span> {t("The order has expired")}</span>);
} else {
var col = 'inherit'
@ -148,13 +150,14 @@ export default class OrderPage extends Component {
// Countdown Renderer callback with condition
countdownPenaltyRenderer = ({ minutes, seconds, completed }) => {
const { t } = this.props;
if (completed) {
// Render a completed state
return (<span> Penalty lifted, good to go!</span>);
return (<span> {t("Penalty lifted, good to go!")}</span>);
} else {
return (
<span> You cannot take an order yet! Wait {zeroPad(minutes)}m {zeroPad(seconds)}s </span>
<span> {t("You cannot take an order yet! Wait {{timeMin}}m {{timeSec}}s",{timeMin: zeroPad(minutes), timeSec: zeroPad(seconds) })} </span>
);
}
};
@ -168,27 +171,29 @@ export default class OrderPage extends Component {
}
amountHelperText=()=>{
const { t } = this.props;
if(this.state.takeAmount < this.state.min_amount & this.state.takeAmount != ""){
return "Too low"
return t("Too low")
}else if (this.state.takeAmount > this.state.max_amount & this.state.takeAmount != ""){
return "Too high"
return t("Too high")
}else{
return null
}
}
takeOrderButton = () => {
const { t } = this.props;
if(this.state.has_range){
return(
<Grid containter xs={12} align="center" alignItems="stretch" justifyContent="center" style={{ display: "flex"}}>
<this.InactiveMakerDialog/>
<div style={{maxWidth:120}}>
<Tooltip placement="top" enterTouchDelay="500" enterDelay="700" enterNextDelay="2000" title="Enter amount of fiat to exchange for bitcoin">
<Tooltip placement="top" enterTouchDelay="500" enterDelay="700" enterNextDelay="2000" title={t("Enter amount of fiat to exchange for bitcoin")}>
<Paper elevation={5} sx={{maxHeight:40}}>
<TextField
error={(this.state.takeAmount < this.state.min_amount || this.state.takeAmount > this.state.max_amount) & this.state.takeAmount != "" }
helperText={this.amountHelperText()}
label={"Amount "+this.state.currencyCode}
label={t("Amount {{currencyCode}}", {currencyCode: this.state.currencyCode})}
size="small"
type="number"
required="true"
@ -204,11 +209,11 @@ export default class OrderPage extends Component {
</Tooltip>
</div>
<div style={{height:38, top:'1px', position:'relative', display: (this.state.takeAmount < this.state.min_amount || this.state.takeAmount > this.state.max_amount || this.state.takeAmount == "" || this.state.takeAmount == null) ? '':'none'}}>
<Tooltip placement="top" enterTouchDelay="0" enterDelay="500" enterNextDelay="1200" title="You must specify an amount first">
<Tooltip placement="top" enterTouchDelay="0" enterDelay="500" enterNextDelay="1200" title={t("You must specify an amount first")}>
<Paper elevation={4}>
<Button sx={{height:38}} variant='contained' color='primary'
disabled={true}>
Take Order
{t("Take Order")}
</Button>
</Paper>
</Tooltip>
@ -217,7 +222,7 @@ export default class OrderPage extends Component {
<Paper elevation={4}>
<Button sx={{height:38}} variant='contained' color='primary'
onClick={this.state.maker_status=='Inactive' ? this.handleClickOpenInactiveMakerDialog : this.takeOrder}>
Take Order
{t("Take Order")}
</Button>
</Paper>
</div>
@ -229,7 +234,7 @@ export default class OrderPage extends Component {
<this.InactiveMakerDialog/>
<Button variant='contained' color='primary'
onClick={this.state.maker_status=='Inactive' ? this.handleClickOpenInactiveMakerDialog : this.takeOrder}>
Take Order
{t("Take Order")}
</Button>
</>
)
@ -243,8 +248,8 @@ export default class OrderPage extends Component {
return ( <this.takeOrderButton/>);
} else{
return(
<Tooltip enterTouchDelay="0" title="Wait until you can take an order"><div>
<Button disabled={true} variant='contained' color='primary'>Take Order</Button>
<Tooltip enterTouchDelay="0" title={t("Wait until you can take an order")}><div>
<Button disabled={true} variant='contained' color='primary'>{t("Take Order")}</Button>
</div></Tooltip>)
}
};
@ -274,7 +279,6 @@ export default class OrderPage extends Component {
takeOrder=()=>{
this.setState({loading:true})
console.log(this.state.takeAmount)
const requestOptions = {
method: 'POST',
headers: {'Content-Type':'application/json', 'X-CSRFToken': getCookie('csrftoken'),},
@ -287,15 +291,6 @@ export default class OrderPage extends Component {
.then((response) => response.json())
.then((data) => this.completeSetState(data));
}
getCurrencyDict() {
fetch('/static/assets/currencies.json')
.then((response) => response.json())
.then((data) =>
this.setState({
currencies_dict: data
}));
}
// set delay to the one matching the order status. If null order status, delay goes to 9999999.
setDelay = (status)=>{
@ -303,7 +298,7 @@ export default class OrderPage extends Component {
}
getCurrencyCode(val){
let code = val ? this.state.currencies_dict[val.toString()] : ""
let code = val ? currencyDict[val.toString()] : ""
return code
}
@ -330,6 +325,7 @@ export default class OrderPage extends Component {
};
CancelDialog =() =>{
const { t } = this.props;
return(
<Dialog
open={this.state.openCancel}
@ -338,16 +334,16 @@ export default class OrderPage extends Component {
aria-describedby="cancel-dialog-description"
>
<DialogTitle id="cancel-dialog-title">
{"Cancel the order?"}
{t("Cancel the order?")}
</DialogTitle>
<DialogContent>
<DialogContentText id="cancel-dialog-description">
If the order is cancelled now you will lose your bond.
{t("If the order is cancelled now you will lose your bond.")}
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={this.handleClickCloseConfirmCancelDialog} autoFocus>Go back</Button>
<Button onClick={this.handleClickConfirmCancelButton}> Confirm Cancel </Button>
<Button onClick={this.handleClickCloseConfirmCancelDialog} autoFocus>{t("Go back")}</Button>
<Button onClick={this.handleClickConfirmCancelButton}>{t("Confirm Cancel")}</Button>
</DialogActions>
</Dialog>
)
@ -361,6 +357,7 @@ export default class OrderPage extends Component {
};
InactiveMakerDialog =() =>{
const { t } = this.props;
return(
<Dialog
open={this.state.openInactiveMaker}
@ -369,17 +366,16 @@ export default class OrderPage extends Component {
aria-describedby="inactive-maker-description"
>
<DialogTitle id="inactive-maker-dialog-title">
{"The maker is away"}
{t("The maker is away")}
</DialogTitle>
<DialogContent>
<DialogContentText id="cancel-dialog-description">
By taking this order you risk wasting your time.
If the maker does not proceed in time, you will be compensated in satoshis for 50% of the maker bond.
{t("By taking this order you risk wasting your time. If the maker does not proceed in time, you will be compensated in satoshis for 50% of the maker bond.")}
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={this.handleClickCloseInactiveMakerDialog} autoFocus>Go back</Button>
<Button onClick={this.takeOrder}> Take Order </Button>
<Button onClick={this.handleClickCloseInactiveMakerDialog} autoFocus>{t("Go back")}</Button>
<Button onClick={this.takeOrder}>{t("Take Order")}</Button>
</DialogActions>
</Dialog>
)
@ -406,6 +402,7 @@ export default class OrderPage extends Component {
};
CollaborativeCancelDialog =() =>{
const { t } = this.props;
return(
<Dialog
open={this.state.openCollaborativeCancel}
@ -414,41 +411,41 @@ export default class OrderPage extends Component {
aria-describedby="collaborative-cancel-dialog-description"
>
<DialogTitle id="cancel-dialog-title">
{"Collaborative cancel the order?"}
{t("Collaborative cancel the order?")}
</DialogTitle>
<DialogContent>
<DialogContentText id="cancel-dialog-description">
The trade escrow has been posted. The order can be cancelled only if both, maker and
taker, agree to cancel.
{t("The trade escrow has been posted. The order can be cancelled only if both, maker and taker, agree to cancel.")}
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={this.handleClickCloseCollaborativeCancelDialog} autoFocus>Go back</Button>
<Button onClick={this.handleClickConfirmCollaborativeCancelButton}> Ask for Cancel </Button>
<Button onClick={this.handleClickCloseCollaborativeCancelDialog} autoFocus>{t("Go back")}</Button>
<Button onClick={this.handleClickConfirmCollaborativeCancelButton}>{t("Ask for Cancel")}</Button>
</DialogActions>
</Dialog>
)
}
BackButton = () => {
const { t } = this.props;
// If order has expired, show back button.
if (this.state.status == 5){
return(
<Grid item xs={12} align="center">
<Button variant='contained' color='secondary' onClick={this.props.history.goBack}>Back</Button>
<Button variant='contained' color='secondary' onClick={this.props.history.goBack}>{t("Back")}</Button>
</Grid>
)}
return(null)
}
CancelButton = () => {
const { t } = this.props;
// If maker and Waiting for Bond. Or if taker and Waiting for bond.
// Simply allow to cancel without showing the cancel dialog.
if ((this.state.is_maker & [0,1].includes(this.state.status)) || this.state.is_taker & this.state.status == 3){
return(
<Grid item xs={12} align="center">
<Button variant='contained' color='secondary' onClick={this.handleClickConfirmCancelButton}>Cancel</Button>
<Button variant='contained' color='secondary' onClick={this.handleClickConfirmCancelButton}>{t("Cancel")}</Button>
</Grid>
)}
// If the order does not yet have an escrow deposited. Show dialog
@ -458,7 +455,7 @@ export default class OrderPage extends Component {
<div id="openDialogCancelButton">
<Grid item xs={12} align="center">
<this.CancelDialog/>
<Button variant='contained' color='secondary' onClick={this.handleClickOpenConfirmCancelDialog}>Cancel</Button>
<Button variant='contained' color='secondary' onClick={this.handleClickOpenConfirmCancelDialog}>{t("Cancel")}</Button>
</Grid>
</div>
)}
@ -469,7 +466,7 @@ export default class OrderPage extends Component {
return(
<Grid item xs={12} align="center">
<this.CollaborativeCancelDialog/>
<Button variant='contained' color='secondary' onClick={this.handleClickOpenCollaborativeCancelDialog}>Collaborative Cancel</Button>
<Button variant='contained' color='secondary' onClick={this.handleClickOpenCollaborativeCancelDialog}>{t("Collaborative Cancel")}</Button>
</Grid>
)}
@ -485,19 +482,20 @@ export default class OrderPage extends Component {
}
orderBox=()=>{
const { t } = this.props;
return(
<Grid container spacing={1} >
<Grid item xs={12} align="center">
<MediaQuery minWidth={920}>
<Typography component="h5" variant="h5">
Order Box
{t("Order Box")}
</Typography>
</MediaQuery>
<Paper elevation={12} style={{ padding: 8,}}>
<List dense="true">
<ListItem >
<ListItemAvatar sx={{ width: 56, height: 56 }}>
<Tooltip placement="top" enterTouchDelay="0" title={this.state.maker_status} >
<Tooltip placement="top" enterTouchDelay="0" title={t(this.state.maker_status)} >
<Badge variant="dot" overlap="circular" badgeContent="" color={this.statusBadgeColor(this.state.maker_status)}>
<Avatar className="flippedSmallAvatar"
alt={this.state.maker_nick}
@ -506,7 +504,7 @@ export default class OrderPage extends Component {
</Badge>
</Tooltip>
</ListItemAvatar>
<ListItemText primary={this.state.maker_nick + (this.state.type ? " (Seller)" : " (Buyer)")} secondary="Order maker" align="right"/>
<ListItemText primary={this.state.maker_nick + (this.state.type ? " "+t("(Seller)") : " "+t("(Buyer)") )} secondary={t("Order maker")} align="right"/>
</ListItem>
{this.state.is_participant ?
@ -515,9 +513,9 @@ export default class OrderPage extends Component {
<>
<Divider />
<ListItem align="left">
<ListItemText primary={this.state.taker_nick + (this.state.type ? " (Buyer)" : " (Seller)")} secondary="Order taker"/>
<ListItemText primary={this.state.taker_nick + (this.state.type ? " "+t("(Buyer)") : " "+t("(Seller)"))} secondary={t("Order taker")}/>
<ListItemAvatar >
<Tooltip enterTouchDelay="0" title={this.state.taker_status} >
<Tooltip enterTouchDelay="0" title={t(this.state.taker_status)} >
<Badge variant="dot" overlap="circular" badgeContent="" color={this.statusBadgeColor(this.state.taker_status)}>
<Avatar className="smallAvatar"
alt={this.state.taker_nick}
@ -530,16 +528,16 @@ export default class OrderPage extends Component {
</>:
""
}
<Divider><Chip label='Order Details'/></Divider>
<Divider><Chip label={t("Order Details")}/></Divider>
<ListItem>
<ListItemIcon>
<ArticleIcon/>
</ListItemIcon>
<ListItemText primary={this.state.status_message} secondary="Order status"/>
<ListItemText primary={t(this.state.status_message)} secondary={t("Order status")}/>
</ListItem>
<Divider/>
</>
:<Divider><Chip label='Order Details'/></Divider>
:<Divider><Chip label={t("Order Details")}/></Divider>
}
<ListItem>
@ -550,10 +548,10 @@ export default class OrderPage extends Component {
</ListItemIcon>
{this.state.has_range & this.state.amount == null ?
<ListItemText primary={parseFloat(Number(this.state.min_amount).toPrecision(2))
+"-" + parseFloat(Number(this.state.max_amount).toPrecision(2)) +" "+this.state.currencyCode} secondary="Amount range"/>
+"-" + parseFloat(Number(this.state.max_amount).toPrecision(2)) +" "+this.state.currencyCode} secondary={t("Amount range")}/>
:
<ListItemText primary={parseFloat(parseFloat(this.state.amount).toFixed(4))
+" "+this.state.currencyCode} secondary="Amount"/>
+" "+this.state.currencyCode} secondary={t("Amount")}/>
}
</ListItem>
@ -563,7 +561,7 @@ export default class OrderPage extends Component {
<ListItemIcon>
<PaymentsIcon/>
</ListItemIcon>
<ListItemText primary={<PaymentText size={20} verbose={true} text={this.state.payment_method}/>} secondary={this.state.currency==1000 ? "Swap destination":"Accepted payment methods"}/>
<ListItemText primary={<PaymentText size={20} othersText={t("Others")} verbose={true} text={this.state.payment_method}/>} secondary={this.state.currency==1000 ? t("Swap destination"):t("Accepted payment methods")}/>
</ListItem>
<Divider />
@ -573,12 +571,12 @@ export default class OrderPage extends Component {
<PriceChangeIcon/>
</ListItemIcon>
{this.state.price_now?
<ListItemText primary={pn(this.state.price_now)+" "+this.state.currencyCode+"/BTC - Premium: "+this.state.premium_now+"%"} secondary="Price and Premium"/>
<ListItemText primary={t("{{price}} {{currencyCode}}/BTC - Premium: {{premium}}%", {price: pn(this.state.price_now), currencyCode:this.state.currencyCode, premium: this.state.premium_now})} secondary={t("Price and Premium")}/>
:
(this.state.is_explicit ?
<ListItemText primary={pn(this.state.satoshis)} secondary="Amount of Satoshis"/>
<ListItemText primary={pn(this.state.satoshis)} secondary={t("Amount of Satoshis")}/>
:
<ListItemText primary={parseFloat(parseFloat(this.state.premium).toFixed(2))+"%"} secondary="Premium over market price"/>
<ListItemText primary={parseFloat(parseFloat(this.state.premium).toFixed(2))+"%"} secondary={t("Premium over market price")}/>
)
}
</ListItem>
@ -588,14 +586,14 @@ export default class OrderPage extends Component {
<ListItemIcon>
<NumbersIcon/>
</ListItemIcon>
<ListItemText primary={this.orderId} secondary="Order ID"/>
<ListItemText primary={this.orderId} secondary={t("Order ID")}/>
</ListItem>
<Divider />
<ListItem>
<ListItemIcon>
<AccessTimeIcon/>
</ListItemIcon>
<ListItemText secondary="Expires in">
<ListItemText secondary={t("Expires in")}>
<Countdown date={new Date(this.state.expires_at)} renderer={this.countdownRenderer} />
</ListItemText>
</ListItem>
@ -620,7 +618,7 @@ export default class OrderPage extends Component {
<Divider />
<Grid item xs={12} align="center">
<Alert severity="warning" sx={{maxWidth:360}}>
{this.state.is_maker ? this.state.taker_nick : this.state.maker_nick} is asking for a collaborative cancel
{t("{{nickname}} is asking for a collaborative cancel", {nickname: this.state.is_maker ? this.state.taker_nick : this.state.maker_nick})}
</Alert>
</Grid>
</>
@ -632,7 +630,7 @@ export default class OrderPage extends Component {
<Divider />
<Grid item xs={12} align="center">
<Alert severity="warning" sx={{maxWidth:360}}>
You asked for a collaborative cancellation
{t("You asked for a collaborative cancellation")}
</Alert>
</Grid>
</>
@ -654,7 +652,7 @@ export default class OrderPage extends Component {
<Countdown date={new Date(this.state.penalty)} renderer={this.countdownTakeOrderRenderer} />
</Grid>
<Grid item xs={12} align="center">
<Button variant='contained' color='secondary' onClick={this.props.history.goBack}>Back</Button>
<Button variant='contained' color='secondary' onClick={this.props.history.goBack}>{t("Back")}</Button>
</Grid>
</Grid>
}
@ -684,7 +682,7 @@ export default class OrderPage extends Component {
}
doubleOrderPagePhone=()=>{
const { t } = this.props;
const [value, setValue] = React.useState(this.state.showContractBox);
const handleChange = (event, newValue) => {
@ -696,8 +694,8 @@ export default class OrderPage extends Component {
<Box sx={{ width: '100%'}}>
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
<Tabs value={value} onChange={handleChange} variant="fullWidth" >
<Tab label="Order" {...this.a11yProps(0)} />
<Tab label="Contract" {...this.a11yProps(1)} />
<Tab label={t("Order")} {...this.a11yProps(0)} />
<Tab label={t("Contract")} {...this.a11yProps(1)} />
</Tabs>
</Box>
<Grid container spacing={2}>
@ -715,13 +713,15 @@ export default class OrderPage extends Component {
}
orderDetailsPage (){
const { t } = this.props;
return(
this.state.bad_request ?
<div align='center'>
<Typography component="subtitle2" variant="subtitle2" color="secondary" >
{this.state.bad_request}<br/>
{/* IMPLEMENT I18N for bad_request */}
{t(this.state.bad_request)}<br/>
</Typography>
<Button variant='contained' color='secondary' onClick={this.props.history.goBack}>Back</Button>
<Button variant='contained' color='secondary' onClick={this.props.history.goBack}>{t("Back")}</Button>
</div>
:
(this.state.is_participant ?
@ -750,3 +750,5 @@ export default class OrderPage extends Component {
);
}
}
export default withTranslation()(OrderPage);

View File

@ -1,4 +1,3 @@
import { TextField } from '@mui/material';
import React, { Component } from 'react';
import DashboardCustomizeIcon from '@mui/icons-material/DashboardCustomize';

View File

@ -1,7 +1,6 @@
import PaymentIcon from './PaymentIcons'
import React, { Component } from 'react'
import PaymentIcon from './PaymentIcons'
import {Tooltip} from "@mui/material"
import { intlFormat } from 'date-fns';
const someMethods = [
{name: "Revolut",icon:'revolut'},
@ -67,9 +66,9 @@ export default class PaymentText extends Component {
// Adds a Custom icon if there are words that do not match
var chars_left = custom_methods.replace(' ','')
chars_left = chars_left.replace(' ','')
if(chars_left.length > 0){rows.push(
<Tooltip placement="top" enterTouchDelay="0" title={this.props.verbose ? "Others": "Other: "+ custom_methods} >
<Tooltip placement="top" enterTouchDelay="0" title={this.props.verbose ? this.props.othersText: this.props.othersText+": "+ custom_methods} >
<div style={{position:'relative', display: 'inline-block',width: this.props.size+2, maxHeight: this.props.size, top:'-1px'}}>
<PaymentIcon width={this.props.size*1.1} height={this.props.size*1.1} icon={"custom"}/>
</div>

View File

@ -1,4 +1,5 @@
import React, { Component } from "react";
import { withTranslation, Trans} from "react-i18next";
import { IconButton, Box, Link, Paper, Rating, Button, Tooltip, CircularProgress, Grid, Typography, TextField, List, ListItem, ListItemText, Divider, ListItemIcon, Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle} from "@mui/material"
import QRCode from "react-qr-code";
import Countdown, { zeroPad} from 'react-countdown';
@ -40,7 +41,7 @@ function pn(x) {
return parts.join(".");
}
export default class TradeBox extends Component {
class TradeBox extends Component {
constructor(props) {
super(props);
this.state = {
@ -53,6 +54,8 @@ export default class TradeBox extends Component {
}
}
Sound = ({soundFileName}) => (
// Four filenames: "locked-invoice", "taker-found", "open-chat", "successful"
<audio autoPlay src={`/static/assets/sounds/${soundFileName}.mp3`} />
@ -129,6 +132,7 @@ export default class TradeBox extends Component {
}
ConfirmDisputeDialog =() =>{
const { t } = this.props;
return(
<Dialog
open={this.state.openConfirmDispute}
@ -137,19 +141,16 @@ export default class TradeBox extends Component {
aria-describedby="open-dispute-dialog-description"
>
<DialogTitle id="open-dispute-dialog-title">
{"Do you want to open a dispute?"}
{t("Do you want to open a dispute?")}
</DialogTitle>
<DialogContent>
<DialogContentText id="alert-dialog-description">
The RoboSats staff will examine the statements and evidence provided. You need to build
a complete case, as the staff cannot read the chat. It is best to provide a burner contact
method with your statement. The satoshis in the trade escrow will be sent to the dispute winner,
while the dispute loser will lose the bond.
{t("The RoboSats staff will examine the statements and evidence provided. You need to build a complete case, as the staff cannot read the chat. It is best to provide a burner contact method with your statement. The satoshis in the trade escrow will be sent to the dispute winner, while the dispute loser will lose the bond.")}
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={this.handleClickCloseConfirmDispute} autoFocus>Disagree</Button>
<Button onClick={this.handleClickAgreeDisputeButton}> Agree and open dispute </Button>
<Button onClick={this.handleClickCloseConfirmDispute} autoFocus>{t("Disagree")}</Button>
<Button onClick={this.handleClickAgreeDisputeButton}>{t("Agree and open dispute")}</Button>
</DialogActions>
</Dialog>
)
@ -168,6 +169,7 @@ export default class TradeBox extends Component {
};
ConfirmFiatReceivedDialog =() =>{
const { t } = this.props;
return(
<Dialog
open={this.state.openConfirmFiatReceived}
@ -176,40 +178,42 @@ export default class TradeBox extends Component {
aria-describedby="fiat-received-dialog-description"
>
<DialogTitle id="open-dispute-dialog-title">
{"Confirm you received " +this.props.data.currencyCode+ "?"}
{t("Confirm you received {{currencyCode}}?", {currencyCode: this.props.data.currencyCode})}
</DialogTitle>
<DialogContent>
<DialogContentText id="alert-dialog-description">
Confirming that you received the fiat will finalize the trade. The satoshis
in the escrow will be released to the buyer. Only confirm after the {this.props.data.currencyCode+ " "}
has arrived to your account. In addition, if you have received {this.props.data.currencyCode+ " "}
and do not confirm the receipt, you risk losing your bond.
{t("Confirming that you received the fiat will finalize the trade. The satoshis in the escrow will be released to the buyer. Only confirm after the {{currencyCode}} has arrived to your account. In addition, if you have received {{currencyCode}} and do not confirm the receipt, you risk losing your bond.",{currencyCode: this.props.data.currencyCode})}
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={this.handleClickCloseConfirmFiatReceived} autoFocus>Go back</Button>
<Button onClick={this.handleClickTotallyConfirmFiatReceived}> Confirm </Button>
<Button onClick={this.handleClickCloseConfirmFiatReceived} autoFocus>{t("Go back")}</Button>
<Button onClick={this.handleClickTotallyConfirmFiatReceived}>{t("Confirm")}</Button>
</DialogActions>
</Dialog>
)
}
showQRInvoice=()=>{
const { t } = this.props;
return (
<Grid container spacing={1}>
<Grid item xs={12} align="center">
<Typography component="body2" variant="body2">
Robots show commitment to their peers
{t("Robots show commitment to their peers")}
</Typography>
</Grid>
<Grid item xs={12} align="center">
{this.props.data.is_maker ?
<Typography color="primary" component="subtitle1" variant="subtitle1">
<b>Lock {pn(this.props.data.bond_satoshis)} Sats to PUBLISH order </b> {" " + this.stepXofY()}
<b>
{t("Lock {{amountSats}} Sats to PUBLISH order", {amountSats: pn(this.props.data.bond_satoshis)})}
</b> {" " + this.stepXofY()}
</Typography>
:
<Typography color="primary" component="subtitle1" variant="subtitle1">
<b>Lock {pn(this.props.data.bond_satoshis)} Sats to TAKE the order </b> {" " + this.stepXofY()}
<b>
{t("Lock {{amountSats}} Sats to TAKE order", {amountSats: pn(this.props.data.bond_satoshis)})}
</b> {" " + this.stepXofY()}
</Typography>
}
</Grid>
@ -217,8 +221,8 @@ export default class TradeBox extends Component {
<Box sx={{bgcolor:'#ffffff', width:'315px', position:'relative', left:'-5px'}} >
<QRCode value={this.props.data.bond_invoice} size={305} style={{position:'relative', top:'3px'}}/>
</Box>
<Tooltip disableHoverListener enterTouchDelay="0" title="Copied!">
<Button size="small" color="inherit" onClick={() => {navigator.clipboard.writeText(this.props.data.bond_invoice)}} align="center"> <ContentCopy/> Copy to clipboard</Button>
<Tooltip disableHoverListener enterTouchDelay="0" title={t("Copied!")}>
<Button size="small" color="inherit" onClick={() => {navigator.clipboard.writeText(this.props.data.bond_invoice)}} align="center"> <ContentCopy/>{t("Copy to clipboard")}</Button>
</Tooltip>
</Grid>
<Grid item xs={12} align="center">
@ -228,7 +232,7 @@ export default class TradeBox extends Component {
size="small"
defaultValue={this.props.data.bond_invoice}
disabled="true"
helperText="This is a hold invoice, it will freeze in your wallet. It will be charged only if you cancel or lose a dispute."
helperText={t("This is a hold invoice, it will freeze in your wallet. It will be charged only if you cancel or lose a dispute.")}
color = "secondary"
/>
</Grid>
@ -237,12 +241,13 @@ export default class TradeBox extends Component {
}
showBondIsLocked=()=>{
const {t} = this.props
return (
<Grid item xs={12} align="center">
<Typography color="primary" component="subtitle1" variant="subtitle1" align="center">
<div style={{display:'flex', alignItems:'center', justifyContent:'center', flexWrap:'wrap'}}>
<LockIcon/>
{" Your " + (this.props.data.is_maker ? 'maker' : 'taker')+" bond is locked"}
{this.props.data.is_maker ? t("Your maker bond is locked") : t("Your taker bond is locked")}
</div>
</Typography>
</Grid>
@ -250,12 +255,13 @@ export default class TradeBox extends Component {
}
showBondIsSettled=()=>{
const { t } = this.props;
return (
<Grid item xs={12} align="center">
<Typography color="error" component="subtitle1" variant="subtitle1" align="center">
<div style={{display:'flex',alignItems:'center', justifyContent:'center', flexWrap:'wrap', align:"center"}} align="center">
<BalanceIcon/>
{" Your " + (this.props.data.is_maker ? 'maker' : 'taker')+" bond was settled"}
{this.props.data.is_maker ? t("Your maker bond was settled") : t("Your taker bond was settled")}
</div>
</Typography>
</Grid>
@ -263,12 +269,13 @@ export default class TradeBox extends Component {
}
showBondIsReturned=()=>{
const { t } = this.props;
return (
<Grid item xs={12} align="center">
<Typography color="green" component="subtitle1" variant="subtitle1" align="center">
<div style={{display:'flex',alignItems:'center', justifyContent:'center', flexWrap:'wrap'}}>
<LockOpenIcon/>
{" Your " + (this.props.data.is_maker ? 'maker' : 'taker')+" bond was unlocked"}
{this.props.data.is_maker ? t("Your maker bond was unlock") : t("Your taker bond was unlocked")}
</div>
</Typography>
</Grid>
@ -276,20 +283,23 @@ export default class TradeBox extends Component {
}
showEscrowQRInvoice=()=>{
const { t } = this.props;
return (
<Grid container spacing={1}>
{/* Make confirmation sound for HTLC received. */}
<this.Sound soundFileName="locked-invoice"/>
<Grid item xs={12} align="center">
<Typography color="green" component="subtitle1" variant="subtitle1">
<b>Lock {pn(this.props.data.escrow_satoshis)} Sats as collateral </b> {" " + this.stepXofY()}
<b>
{t("Lock {{amountSats}} Sats as collateral", {amountSats:pn(this.props.data.escrow_satoshis)})}
</b>{" " + this.stepXofY()}
</Typography>
</Grid>
<Grid item xs={12} align="center">
<Box sx={{bgcolor:'#ffffff', width:'315px', position:'relative', left:'-5px'}} >
<QRCode value={this.props.data.escrow_invoice} size={305} style={{position:'relative', top:'3px'}}/>
</Box>
<Tooltip disableHoverListener enterTouchDelay="0" title="Copied!">
<Tooltip disableHoverListener enterTouchDelay="0" title={t("Copied!")}>
<Button size="small" color="inherit" onClick={() => {navigator.clipboard.writeText(this.props.data.escrow_invoice)}} align="center"> <ContentCopy/>Copy to clipboard</Button>
</Tooltip>
</Grid>
@ -300,7 +310,7 @@ export default class TradeBox extends Component {
size="small"
defaultValue={this.props.data.escrow_invoice}
disabled="true"
helperText={"This is a hold invoice, it will freeze in your wallet. It will be released to the buyer once you confirm to have received the "+this.props.data.currencyCode+"."}
helperText={t("This is a hold invoice, it will freeze in your wallet. It will be released to the buyer once you confirm to have received the {{currencyCode}}.",{currencyCode: this.props.data.currencyCode})}
color = "secondary"
/>
</Grid>
@ -310,21 +320,20 @@ export default class TradeBox extends Component {
}
showTakerFound=()=>{
const { t } = this.props;
return (
<Grid container spacing={1}>
{/* Make bell sound when taker is found */}
<this.Sound soundFileName="taker-found"/>
<Grid item xs={12} align="center">
<Typography component="subtitle1" variant="subtitle1">
<b>A taker has been found! </b> {" " + this.stepXofY()}
<b>{t("A taker has been found!")}</b> {" " + this.stepXofY()}
</Typography>
</Grid>
<Divider/>
<Grid item xs={12} align="center">
<Typography component="body2" variant="body2">
Please wait for the taker to lock a bond.
If the taker does not lock a bond in time, the order will be made
public again.
{t("Please wait for the taker to lock a bond. If the taker does not lock a bond in time, the order will be made public again.")}
</Typography>
</Grid>
{this.showBondIsLocked()}
@ -345,6 +354,7 @@ export default class TradeBox extends Component {
};
EnableTelegramDialog =() =>{
const { t } = this.props;
return(
<Dialog
open={this.state.openEnableTelegram}
@ -353,24 +363,23 @@ export default class TradeBox extends Component {
aria-describedby="enable-telegram-dialog-description"
>
<DialogTitle id="open-dispute-dialog-title">
Enable TG Notifications
{t("Enable TG Notifications")}
</DialogTitle>
<DialogContent>
<DialogContentText id="alert-dialog-description">
You will be taken to a conversation with RoboSats telegram bot.
Simply open the chat and press "Start". Note that by enabling
telegram notifications you might lower your level of anonymity.
{t("You will be taken to a conversation with RoboSats telegram bot. Simply open the chat and press Start. Note that by enabling telegram notifications you might lower your level of anonymity.")}
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={this.handleClickCloseEnableTelegramDialog}>Go back</Button>
<Button onClick={this.handleClickEnableTelegram} autoFocus> Enable </Button>
<Button onClick={this.handleClickCloseEnableTelegramDialog}> {t("Go back")} </Button>
<Button onClick={this.handleClickEnableTelegram} autoFocus> {t("Enable")} </Button>
</DialogActions>
</Dialog>
)
}
showMakerWait=()=>{
const { t } = this.props;
return (
<Grid container spacing={1}>
{/* Make confirmation sound for HTLC received. */}
@ -378,7 +387,7 @@ export default class TradeBox extends Component {
<this.EnableTelegramDialog/>
<Grid item xs={12} align="center">
<Typography component="subtitle1" variant="subtitle1">
<b> Your order is public </b> {" " + this.stepXofY()}
<b> {t("Your order is public")} </b> {" " + this.stepXofY()}
</Typography>
</Grid>
<Grid item xs={12} align="center">
@ -387,19 +396,16 @@ export default class TradeBox extends Component {
<Divider/>
<ListItem>
<Typography component="body2" variant="body2" align="left">
<p>Be patient while robots check the book.
It might take some time. This box will ring 🔊 once a robot takes your order. </p>
<p>Please note that if your premium is excessive or your currency or payment
methods are not popular, your order might expire untaken. Your bond will
return to you (no action needed).</p>
<p>{t("Be patient while robots check the book. It might take some time. This box will ring 🔊 once a robot takes your order.")} </p>
<p>{t("Please note that if your premium is excessive or your currency or payment methods are not popular, your order might expire untaken. Your bond will return to you (no action needed).")}</p>
</Typography>
</ListItem>
<Grid item xs={12} align="center">
{this.props.data.tg_enabled ?
<Typography color='primary' component="h6" variant="h6" align="center"> Telegram enabled</Typography>
<Typography color='primary' component="h6" variant="h6" align="center">{t("Telegram enabled")}</Typography>
:
<Button color="primary" onClick={this.handleClickOpenTelegramDialog}>
<SendIcon/>Enable Telegram Notifications
<SendIcon/>{t("Enable Telegram Notifications")}
</Button>
}
</Grid>
@ -408,7 +414,7 @@ export default class TradeBox extends Component {
<ListItemIcon>
<BookIcon/>
</ListItemIcon>
<ListItemText primary={this.props.data.num_similar_orders} secondary={"Public orders for " + this.props.data.currencyCode}/>
<ListItemText primary={this.props.data.num_similar_orders} secondary={t("Public orders for {{currencyCode}}",{currencyCode: this.props.data.currencyCode})}/>
</ListItem>
<Divider/>
@ -416,8 +422,8 @@ export default class TradeBox extends Component {
<ListItemIcon>
<PercentIcon/>
</ListItemIcon>
<ListItemText primary={"Premium rank " + this.props.data.premium_percentile*100+"%"}
secondary={"Among public " + this.props.data.currencyCode + " orders (higher is cheaper)"} />
<ListItemText primary={t("Premium rank") +" "+this.props.data.premium_percentile*100+"%"}
secondary={t("Among public {{currencyCode}} orders (higher is cheaper)",{ currencyCode: this.props.data.currencyCode })}/>
</ListItem>
<Divider/>
@ -492,6 +498,7 @@ export default class TradeBox extends Component {
}
showInputInvoice(){
const { t } = this.props;
return (
<Grid container spacing={1}>
@ -499,14 +506,18 @@ export default class TradeBox extends Component {
{/* Make confirmation sound for HTLC received. */}
<this.Sound soundFileName="locked-invoice"/>
<Typography color="primary" component="subtitle1" variant="subtitle1">
<b> Submit an invoice for {pn(this.props.data.invoice_amount)} Sats </b> {" " + this.stepXofY()}
<b> {t("Submit an invoice for {{amountSats}} Sats",{amountSats: pn(this.props.data.invoice_amount)})}
</b> {" " + this.stepXofY()}
</Typography>
</Grid>
<Grid item xs={12} align="left">
<Typography component="body2" variant="body2">
The taker is committed! Before letting you send {" "+ parseFloat(parseFloat(this.props.data.amount).toFixed(4))+
" "+ this.props.data.currencyCode}, we want to make sure you are able to receive the BTC. Please provide a
valid invoice for {pn(this.props.data.invoice_amount)} Satoshis.
{t("The taker is committed! Before letting you send {{amountFiat}} {{currencyCode}}, we want to make sure you are able to receive the BTC. Please provide a valid invoice for {{amountSats}} Satoshis.",
{amountFiat: parseFloat(parseFloat(this.props.data.amount).toFixed(4)),
currencyCode: this.props.data.currencyCode,
amountSats: pn(this.props.data.invoice_amount)}
)
}
</Typography>
</Grid>
@ -514,7 +525,7 @@ export default class TradeBox extends Component {
<TextField
error={this.state.badInvoice}
helperText={this.state.badInvoice ? this.state.badInvoice : "" }
label={"Payout Lightning Invoice"}
label={t("Payout Lightning Invoice")}
required
value={this.state.invoice}
inputProps={{
@ -549,23 +560,19 @@ export default class TradeBox extends Component {
// Asks the user for a dispute statement.
showInDisputeStatement=()=>{
const { t } = this.props;
if(this.props.data.statement_submitted){
return (
<Grid container spacing={1}>
<Grid item xs={12} align="center">
<Typography color="primary" component="subtitle1" variant="subtitle1">
<b> We have received your statement </b>
<b> {t("We have received your statement")} </b>
</Typography>
</Grid>
<Grid item xs={12} align="left">
<Typography component="body2" variant="body2">
<p>We are waiting for your trade counterpart statement. If you are hesitant about
the state of the dispute or want to add more information, contact robosats@protonmail.com.</p>
<p>Please, save the information needed to identify your order and your payments: order ID;
payment hashes of the bonds or escrow (check on your lightning wallet); exact amount of
satoshis; and robot nickname. You will have to identify yourself as the user involved
in this trade via email (or other contact methods).</p>
<p>{t("We are waiting for your trade counterpart statement. If you are hesitant about the state of the dispute or want to add more information, contact robosats@protonmail.com.")}</p>
<p>{t("Please, save the information needed to identify your order and your payments: order ID; payment hashes of the bonds or escrow (check on your lightning wallet); exact amount of satoshis; and robot nickname. You will have to identify yourself as the user involved in this trade via email (or other contact methods).")}</p>
</Typography>
</Grid>
{this.showBondIsSettled()}
@ -579,15 +586,12 @@ export default class TradeBox extends Component {
<Grid container spacing={1}>
<Grid item xs={12} align="center">
<Typography color="primary" component="subtitle1" variant="subtitle1">
<b> A dispute has been opened </b>
<b> {t("A dispute has been opened")} </b>
</Typography>
</Grid>
<Grid item xs={12} align="left">
<Typography component="body2" variant="body2">
Please, submit your statement. Be clear and specific about what happened and provide the necessary
evidence. You MUST provide a contact method: burner email, XMPP or telegram username to follow up with the staff.
Disputes are solved at the discretion of real robots <i>(aka humans)</i>, so be as helpful
as possible to ensure a fair outcome. Max 5000 chars.
{t("Please, submit your statement. Be clear and specific about what happened and provide the necessary evidence. You MUST provide a contact method: burner email, XMPP or telegram username to follow up with the staff. Disputes are solved at the discretion of real robots (aka humans), so be as helpful as possible to ensure a fair outcome. Max 5000 chars.")}
</Typography>
</Grid>
@ -595,7 +599,7 @@ export default class TradeBox extends Component {
<TextField
error={this.state.badStatement}
helperText={this.state.badStatement ? this.state.badStatement : "" }
label={"Submit dispute statement"}
label={t("Submit dispute statement")}
required
inputProps={{
style: {textAlign:"center"}
@ -614,24 +618,18 @@ export default class TradeBox extends Component {
}
showWaitForDisputeResolution=()=>{
const { t } = this.props;
return (
<Grid container spacing={1}>
<Grid item xs={12} align="center">
<Typography color="primary" component="subtitle1" variant="subtitle1">
<b> We have the statements </b>
<b> {t("We have the statements")} </b>
</Typography>
</Grid>
<Grid item xs={12} align="left">
<Typography component="body2" variant="body2">
<p>Both statements have been received, wait for the staff to resolve the dispute.
If you are hesitant about the state of the dispute or want to add more information,
contact robosats@protonmail.com. If you did not provide a contact method, or are unsure whether
you wrote it right, write us immediately. </p>
<p>Please, save the information needed to identify your order and your payments: order ID;
payment hashes of the bonds or escrow (check on your lightning wallet); exact amount of
satoshis; and robot nickname. You will have to identify yourself as the user involved
in this trade via email (or other contact methods).</p>
<p>{t("Both statements have been received, wait for the staff to resolve the dispute. If you are hesitant about the state of the dispute or want to add more information, contact robosats@protonmail.com. If you did not provide a contact method, or are unsure whether you wrote it right, write us immediately.")} </p>
<p>{t("Please, save the information needed to identify your order and your payments: order ID; payment hashes of the bonds or escrow (check on your lightning wallet); exact amount of satoshis; and robot nickname. You will have to identify yourself as the user involved in this trade via email (or other contact methods).")}</p>
</Typography>
</Grid>
{this.showBondIsSettled()}
@ -640,18 +638,17 @@ export default class TradeBox extends Component {
}
showDisputeWinner=()=>{
const { t } = this.props;
return (
<Grid container spacing={1}>
<Grid item xs={12} align="center">
<Typography color="primary" component="subtitle1" variant="subtitle1">
<b> You have won the dispute </b>
<b> {t("You have won the dispute")} </b>
</Typography>
</Grid>
<Grid item xs={12} align="left">
<Typography component="body2" variant="body2">
You can claim the dispute resolution amount (escrow and fidelity bond) from
your profile rewards. If there is anything the staff can help with, do not hesitate to contact to
robosats@protonmail.com (or via your provided burner contact method).
{t("You can claim the dispute resolution amount (escrow and fidelity bond) from your profile rewards. If there is anything the staff can help with, do not hesitate to contact to robosats@protonmail.com (or via your provided burner contact method).")}
</Typography>
</Grid>
{this.showBondIsSettled()}
@ -660,18 +657,17 @@ export default class TradeBox extends Component {
}
showDisputeLoser=()=>{
const { t } = this.props;
return (
<Grid container spacing={1}>
<Grid item xs={12} align="center">
<Typography color="error" component="subtitle1" variant="subtitle1">
<b> You have lost the dispute </b>
<b> {t("You have lost the dispute")} </b>
</Typography>
</Grid>
<Grid item xs={12} align="left">
<Typography component="body2" variant="body2">
Unfortunately you have lost the dispute. If you think this is a mistake
you can ask to re-open the case via email to robosats@protonmail.com. However,
chances of it being investigated again are low.
{t("Unfortunately you have lost the dispute. If you think this is a mistake you can ask to re-open the case via email to robosats@protonmail.com. However, chances of it being investigated again are low.")}
</Typography>
</Grid>
{this.showBondIsSettled()}
@ -680,19 +676,18 @@ export default class TradeBox extends Component {
}
showWaitingForEscrow(){
const { t } = this.props;
return(
<Grid container spacing={1}>
<Grid item xs={12} align="center">
<Typography component="subtitle1" variant="subtitle1">
<b>Your invoice looks good!🎉</b> {" " + this.stepXofY()}
<b>{t("Your invoice looks good!")}</b> {" " + this.stepXofY()}
</Typography>
</Grid>
<Grid item xs={12} align="center">
<Typography component="body2" variant="body2" align="left">
<p>We are waiting for the seller lock the trade amount. </p>
<p> Just hang on for a moment. If the seller does not deposit,
you will get your bond back automatically. In addition, you will
receive a compensation (check the rewards in your profile).</p>
<p>{t("We are waiting for the seller lock the trade amount.")}</p>
<p>{t("Just hang on for a moment. If the seller does not deposit, you will get your bond back automatically. In addition, you will receive a compensation (check the rewards in your profile).")}</p>
</Typography>
</Grid>
{this.showBondIsLocked()}
@ -701,23 +696,20 @@ export default class TradeBox extends Component {
}
showWaitingForBuyerInvoice(){
const { t } = this.props;
return(
<Grid container spacing={1}>
{/* Make confirmation sound for HTLC received. */}
<this.Sound soundFileName="locked-invoice"/>
<Grid item xs={12} align="center">
<Typography component="subtitle1" variant="subtitle1">
<b>The trade collateral is locked! 🎉 </b> {" " + this.stepXofY()}
<b>{t("The trade collateral is locked!")}</b> {" " + this.stepXofY()}
</Typography>
</Grid>
<Grid item xs={12} align="center">
<Typography component="body2" variant="body2" align="left">
<p> We are waiting for the buyer to post a lightning invoice. Once
he does, you will be able to directly communicate the fiat payment
details. </p>
<p> Just hang on for a moment. If the buyer does not cooperate,
you will get back the trade collateral and your bond automatically. In addition, you will
receive a compensation (check the rewards in your profile).</p>
<p>{t("We are waiting for the buyer to post a lightning invoice. Once he does, you will be able to directly communicate the fiat payment details.")} </p>
<p>{t("Just hang on for a moment. If the buyer does not cooperate, you will get back the trade collateral and your bond automatically. In addition, you will receive a compensation (check the rewards in your profile).")}</p>
</Typography>
</Grid>
{this.showBondIsLocked()}
@ -772,38 +764,41 @@ handleRatingRobosatsChange=(e)=>{
}
showFiatSentButton(){
const { t } = this.props;
return(
<Grid container spacing={1}>
<Grid item xs={12} align="center">
<Button defaultValue="confirm" variant='contained' color='secondary' onClick={this.handleClickConfirmButton}>Confirm {this.props.data.currencyCode} sent</Button>
<Button defaultValue="confirm" variant='contained' color='secondary' onClick={this.handleClickConfirmButton}>{t("Confirm {{currencyCode}} sent",{currencyCode: this.props.data.currencyCode})}</Button>
</Grid>
</Grid>
)
}
showFiatReceivedButton(){
const { t } = this.props;
return(
<Grid item xs={12} align="center">
<Button defaultValue="confirm" variant='contained' color='secondary' onClick={this.handleClickOpenConfirmFiatReceived}>Confirm {this.props.data.currencyCode} received</Button>
<Button defaultValue="confirm" variant='contained' color='secondary' onClick={this.handleClickOpenConfirmFiatReceived}>{t("Confirm {{currencyCode}} received",{currencyCode: this.props.data.currencyCode})}</Button>
</Grid>
)
}
showOpenDisputeButton(){
// TODO, show alert about how opening a dispute might involve giving away personal data and might mean losing the bond. Ask for double confirmation.
const { t } = this.props;
return(
<Grid item xs={12} align="center">
<Button color="inherit" onClick={this.handleClickOpenConfirmDispute}>Open Dispute</Button>
<Button color="inherit" onClick={this.handleClickOpenConfirmDispute}>{t("Open Dispute")}</Button>
</Grid>
)
}
showOrderExpired(){
const { t } = this.props;
return(
<Grid container spacing={1}>
<Grid item xs={12} align="center">
<Typography component="subtitle1" variant="subtitle1">
<b>The order has expired</b>
<b>{t("The order has expired")}</b>
</Typography>
</Grid>
</Grid>
@ -811,6 +806,7 @@ handleRatingRobosatsChange=(e)=>{
}
showChat=()=>{
const { t } = this.props;
//In Chatroom - No fiat sent - showChat(showSendButton, showReveiceButton, showDisputeButton)
if(this.props.data.is_buyer & this.props.data.status == 9){
var showSendButton=true;
@ -841,24 +837,24 @@ handleRatingRobosatsChange=(e)=>{
<this.Sound soundFileName="chat-open"/>
<Grid item xs={12} align="center">
<Typography component="subtitle1" variant="subtitle1">
<b>Chat with the {this.props.data.is_seller ? 'buyer': 'seller'}</b> {" " + this.stepXofY()}
<b> {this.props.data.is_seller ? t("Chat with the buyer"): t("Chat with the seller")}</b> {" " + this.stepXofY()}
</Typography>
</Grid>
<Grid item xs={12} align="center">
{this.props.data.is_seller ?
<Typography component="body2" variant="body2" align="center">
{this.props.data.status == 9?
"Say hi! Be helpful and concise. Let them know how to send you "+this.props.data.currencyCode+"."
t("Say hi! Be helpful and concise. Let them know how to send you {{currencyCode}}.",{currencyCode: this.props.data.currencyCode})
:
"The buyer has sent the fiat. Click 'Confirm Received' once you receive it."
t("The buyer has sent the fiat. Click 'Confirm Received' once you receive it.")
}
</Typography>
:
<Typography component="body2" variant="body2" align="center">
{this.props.data.status == 9?
"Say hi! Ask for payment details and click 'Confirm Sent' as soon as the payment is sent."
t("Say hi! Ask for payment details and click 'Confirm Sent' as soon as the payment is sent.")
:
"Wait for the seller to confirm he has received the payment."
t("Wait for the seller to confirm he has received the payment.")
}
</Typography>
}
@ -876,13 +872,14 @@ handleRatingRobosatsChange=(e)=>{
}
showRateSelect(){
const { t } = this.props;
return(
<Grid container spacing={1}>
{/* Make confirmation sound for Chat Open. */}
<this.Sound soundFileName="successful"/>
<Grid item xs={12} align="center">
<Typography component="h6" variant="h6">
🎉Trade finished!🥳
{t("🎉Trade finished!🥳")}
</Typography>
</Grid>
{/* <Grid item xs={12} align="center">
@ -895,7 +892,7 @@ handleRatingRobosatsChange=(e)=>{
</Grid> */}
<Grid item xs={12} align="center">
<Typography component="body2" variant="body2" align="center">
What do you think of 🤖<b>RoboSats</b>?
<Trans i18nKey="rate_robosats">What do you think of 🤖<b>RoboSats</b>?</Trans>
</Typography>
</Grid>
<Grid item xs={12} align="center">
@ -904,22 +901,21 @@ handleRatingRobosatsChange=(e)=>{
{this.state.rating_platform==5 ?
<Grid item xs={12} align="center">
<Typography component="body2" variant="body2" align="center">
<p><b>Thank you! RoboSats loves you too </b></p>
<p>RoboSats gets better with more liquidity and users. Tell a bitcoiner friend about Robosats!</p>
<p><b>{t("Thank you! RoboSats loves you too ❤️")}</b></p>
<p>{t("RoboSats gets better with more liquidity and users. Tell a bitcoiner friend about Robosats!")}</p>
</Typography>
</Grid>
: null}
{this.state.rating_platform!=5 & this.state.rating_platform!=null ?
<Grid item xs={12} align="center">
<Typography component="body2" variant="body2" align="center">
<p><b>Thank you for using Robosats!</b></p>
<p>Let us know how the platform could improve
(<Link href="https://t.me/robosats">Telegram</Link> / <Link href="https://github.com/Reckless-Satoshi/robosats/issues">Github</Link>)</p>
<p><b>{t("Thank you for using Robosats!")}</b></p>
<p><Trans i18nKey="let_us_know_hot_to_improve">Let us know how the platform could improve (<Link target='_blank' href="https://t.me/robosats">Telegram</Link> / <Link target='_blank' href="https://github.com/Reckless-Satoshi/robosats/issues">Github</Link>)</Trans></p>
</Typography>
</Grid>
: null}
<Grid item xs={12} align="center">
<Button color='primary' onClick={() => {this.props.push('/')}}>Start Again</Button>
<Button color='primary' onClick={() => {this.props.push('/')}}>{t("Start Again")}</Button>
</Grid>
{this.showBondIsReturned()}
</Grid>
@ -927,17 +923,17 @@ handleRatingRobosatsChange=(e)=>{
}
showSendingPayment(){
const { t } = this.props;
return(
<Grid container spacing={1}>
<Grid item xs={12} align="center">
<Typography component="h6" variant="h6">
Attempting Lightning Payment
{t("Attempting Lightning Payment")}
</Typography>
</Grid>
<Grid item xs={12} align="center">
<Typography component="body2" variant="body2" align="center">
RoboSats is trying to pay your lightning invoice. Remember that lightning nodes must
be online in order to receive payments.
{t("RoboSats is trying to pay your lightning invoice. Remember that lightning nodes must be online in order to receive payments.")}
</Typography>
<br/>
<Grid item xs={12} align="center">
@ -950,9 +946,10 @@ handleRatingRobosatsChange=(e)=>{
// Countdown Renderer callback with condition
countdownRenderer = ({ minutes, seconds, completed }) => {
const { t } = this.props;
if (completed) {
// Render a completed state
return (<div align="center"><span> Retrying! </span><br/><CircularProgress/></div> );
return (<div align="center"><span> {t("Retrying!")} </span><br/><CircularProgress/></div> );
} else {
return (
@ -962,32 +959,31 @@ handleRatingRobosatsChange=(e)=>{
};
showRoutingFailed=()=>{
// TODO If it has failed 3 times, ask for a new invoice.
const { t } = this.props;
if(this.props.data.invoice_expired){
return(
<Grid container spacing={1}>
<Grid item xs={12} align="center">
<Typography component="h6" variant="h6">
Lightning Routing Failed
{t("Lightning Routing Failed")}
</Typography>
</Grid>
<Grid item xs={12} align="center">
<Typography component="body2" variant="body2" align="center">
Your invoice has expired or more than 3 payment attempts have been made.
Muun wallet is not recommended, <Link href="https://github.com/Reckless-Satoshi/robosats/issues/44">check the list of
compatible wallets</Link>
{t("Your invoice has expired or more than 3 payment attempts have been made. Muun wallet is not recommended. ")}
<Link href="https://github.com/Reckless-Satoshi/robosats/issues/44"> {t("Check the list of compatible wallets")}</Link>
</Typography>
</Grid>
<Grid item xs={12} align="center">
<Typography color="primary" component="subtitle1" variant="subtitle1">
<b> Submit a LN invoice for {pn(this.props.data.invoice_amount)} Sats </b>
<b> {t("Submit an invoice for {{amountSats}} Sats",{amountSats: pn(this.props.data.invoice_amount)})}</b>
</Typography>
</Grid>
<Grid item xs={12} align="center">
<TextField
error={this.state.badInvoice}
helperText={this.state.badInvoice ? this.state.badInvoice : "" }
label={"Payout Lightning Invoice"}
label={t("Payout Lightning Invoice")}
required
inputProps={{
style: {textAlign:"center"}
@ -1009,18 +1005,16 @@ handleRatingRobosatsChange=(e)=>{
<Grid container spacing={1}>
<Grid item xs={12} align="center">
<Typography component="h6" variant="h6">
Lightning Routing Failed
{t("Lightning Routing Failed")}
</Typography>
</Grid>
<Grid item xs={12} align="center">
<Typography component="body2" variant="body2" align="center">
RoboSats will try to pay your invoice 3 times every 5 minutes. If it keeps failing, you
will be able to submit a new invoice. Check whether you have enough inbound liquidity.
Remember that lightning nodes must be online in order to receive payments.
{t("RoboSats will try to pay your invoice 3 times every 5 minutes. If it keeps failing, you will be able to submit a new invoice. Check whether you have enough inbound liquidity. Remember that lightning nodes must be online in order to receive payments.")}
</Typography>
<List>
<Divider/>
<ListItemText secondary="Next attempt in">
<ListItemText secondary={t("Next attempt in")}>
<Countdown date={new Date(this.props.data.next_retry_time)} renderer={this.countdownRenderer} />
</ListItemText>
</List>
@ -1031,6 +1025,7 @@ handleRatingRobosatsChange=(e)=>{
}
render() {
const { t } = this.props;
return (
<Grid container spacing={1} style={{ width:this.props.width}}>
<this.ConfirmDisputeDialog/>
@ -1038,7 +1033,7 @@ handleRatingRobosatsChange=(e)=>{
<Grid item xs={12} align="center">
<MediaQuery minWidth={920}>
<Typography component="h5" variant="h5">
Contract Box
{t("Contract Box")}
</Typography>
</MediaQuery>
<Paper elevation={12} style={{ padding: 8,}}>
@ -1087,4 +1082,6 @@ handleRatingRobosatsChange=(e)=>{
</Grid>
);
}
}
}
export default withTranslation()(TradeBox);

View File

@ -1,9 +1,9 @@
import {Paper, Alert, AlertTitle, Button, Link} from "@mui/material"
import React, { Component } from 'react'
import { withTranslation, Trans} from "react-i18next";
import {Paper, Alert, AlertTitle, Button, Link} from "@mui/material"
import MediaQuery from 'react-responsive'
export default class UnsafeAlert extends Component {
class UnsafeAlert extends Component {
constructor(props) {
super(props);
}
@ -23,31 +23,36 @@ export default class UnsafeAlert extends Component {
]
render() {
const { t, i18n} = this.props;
return (
(!this.safe_urls.includes(this.getHost()) & this.state.show) ?
<div>
<MediaQuery minWidth={800}>
<Paper elevation={6} className="alertUnsafe">
<Alert severity="warning" sx={{maxHeight:"100px"}}
action={<Button onClick={() => this.setState({show:false})}>Hide</Button>}
action={<Button onClick={() => this.setState({show:false})}>{t("Hide")}</Button>}
>
<AlertTitle>You are not using RoboSats privately</AlertTitle>
Some features are disabled for your protection (e.g. chat) and you will not be able to complete a
trade without them. To protect your privacy and fully enable RoboSats, use <Link href='https://www.torproject.org/download/' target="_blank">Tor Browser</Link> and visit the <Link chref='http://robosats6tkf3eva7x2voqso3a5wcorsnw34jveyxfqi2fu7oyheasid.onion' target="_blank">Onion</Link> site.
</Alert>
<AlertTitle>{t("You are not using RoboSats privately")}</AlertTitle>
<Trans i18nKey="desktop_unsafe_alert">
Some features are disabled for your protection (e.g. chat) and you will not be able to complete a
trade without them. To protect your privacy and fully enable RoboSats, use <Link href='https://www.torproject.org/download/' target="_blank">Tor Browser</Link> and visit the <Link href='http://robosats6tkf3eva7x2voqso3a5wcorsnw34jveyxfqi2fu7oyheasid.onion' target="_blank">Onion</Link> site.
</Trans>
</Alert>
</Paper>
</MediaQuery>
<MediaQuery maxWidth={799}>
<Paper elevation={6} className="alertUnsafe">
<Alert severity="warning" sx={{maxHeight:"120px"}}>
<AlertTitle>You are not using RoboSats privately</AlertTitle>
You will not be able to complete a
trade. Use <Link href='https://www.torproject.org/download/' target="_blank">Tor Browser</Link> and visit the <Link href='http://robosats6tkf3eva7x2voqso3a5wcorsnw34jveyxfqi2fu7oyheasid.onion' target="_blank">Onion</Link> site.
<AlertTitle>{t("You are not using RoboSats privately")}</AlertTitle>
<Trans i18nKey="phone_unsafe_alert">
You will not be able to complete a
trade. Use <Link href='https://www.torproject.org/download/' target="_blank">Tor Browser</Link> and visit the <Link href='http://robosats6tkf3eva7x2voqso3a5wcorsnw34jveyxfqi2fu7oyheasid.onion' target="_blank">Onion</Link> site.
</Trans>
<div style={{width: '100%'}}>
</div>
<div align="center">
<Button className="hideAlertButton" onClick={() => this.setState({show:false})}>Hide</Button>
<Button className="hideAlertButton" onClick={() => this.setState({show:false})}>{t("Hide")}</Button>
</div>
</Alert>
</Paper>
@ -57,4 +62,6 @@ export default class UnsafeAlert extends Component {
null
)
}
}
}
export default withTranslation()(UnsafeAlert);

View File

@ -1,13 +1,14 @@
import React, { Component } from "react";
import { withTranslation } from "react-i18next";
import { Button , Tooltip, Dialog, Grid, Typography, TextField, ButtonGroup, CircularProgress, IconButton} from "@mui/material"
import { Link } from 'react-router-dom'
import Image from 'material-ui-image'
import InfoDialog from './InfoDialog'
import SmartToyIcon from '@mui/icons-material/SmartToy';
import CasinoIcon from '@mui/icons-material/Casino';
import ContentCopy from "@mui/icons-material/ContentCopy";
import RoboSatsNoTextIcon from "./icons/RoboSatsNoTextIcon"
import BoltIcon from '@mui/icons-material/Bolt';
function getCookie(name) {
@ -27,7 +28,7 @@ function getCookie(name) {
}
const csrftoken = getCookie('csrftoken');
export default class UserGenPage extends Component {
class UserGenPage extends Component {
constructor(props) {
super(props);
this.state = {
@ -101,8 +102,7 @@ export default class UserGenPage extends Component {
headers: {'Content-Type':'application/json', 'X-CSRFToken': getCookie('csrftoken')},
};
fetch("/api/user", requestOptions)
.then((response) => response.json())
.then((data) => console.log(data));
.then((response) => response.json());
}
handleClickNewRandomToken=()=>{
@ -150,6 +150,7 @@ export default class UserGenPage extends Component {
}
render() {
const { t, i18n} = this.props;
return (
<Grid container spacing={1}>
<Grid item>
@ -168,7 +169,7 @@ export default class UserGenPage extends Component {
</Typography>
</Grid>
<Grid item xs={12} align="center">
<Tooltip enterTouchDelay="0" title="This is your trading avatar">
<Tooltip enterTouchDelay="0" title={t("This is your trading avatar")}>
<div style={{ maxWidth: 200, maxHeight: 200 }}>
<Image className='newAvatar'
disableError='true'
@ -186,7 +187,7 @@ export default class UserGenPage extends Component {
this.state.found ?
<Grid item xs={12} align="center">
<Typography component="subtitle2" variant="subtitle2" color='primary'>
{this.state.found}<br/>
{this.state.found ? t("A robot avatar was found, welcome back!"):null}<br/>
</Typography>
</Grid>
:
@ -195,18 +196,13 @@ export default class UserGenPage extends Component {
<Grid container align="center">
<Grid item xs={12} align="center">
<TextField sx={{maxWidth: 280}}
//sx={{ input: { color: 'purple' } }}
// InputLabelProps={{
// style: { color: 'green' },
// }}
error={this.state.bad_request}
label={"Store your token safely"}
label={t("Store your token safely")}
required='true'
value={this.state.token}
variant='standard'
helperText={this.state.bad_request}
size='small'
// multiline = {true}
onChange={this.handleChangeToken}
onKeyPress={(e) => {
if (e.key === 'Enter') {
@ -215,13 +211,13 @@ export default class UserGenPage extends Component {
}}
InputProps={{
startAdornment:
<Tooltip disableHoverListener open={this.state.copied} enterTouchDelay="0" title="Copied!">
<Tooltip disableHoverListener open={this.state.copied} enterTouchDelay="0" title={t("Copied!")}>
<IconButton onClick= {()=> (navigator.clipboard.writeText(this.state.token) & this.setState({copied:true}))}>
<ContentCopy color={this.props.avatarLoaded & !this.state.copied & !this.state.bad_request ? 'primary' : 'inherit' } sx={{width:18, height:18}}/>
</IconButton>
</Tooltip>,
endAdornment:
<Tooltip enterTouchDelay="250" title="Generate a new token">
<Tooltip enterTouchDelay="250" title={t("Generate a new token")}>
<IconButton onClick={this.handleClickNewRandomToken}><CasinoIcon/></IconButton>
</Tooltip>,
}}
@ -232,14 +228,14 @@ export default class UserGenPage extends Component {
{this.state.tokenHasChanged ?
<Button type="submit" size='small' onClick= {this.handleClickSubmitToken}>
<SmartToyIcon sx={{width:18, height:18}} />
<span> Generate Robot</span>
<span> {t("Generate Robot")}</span>
</Button>
:
<Tooltip enterTouchDelay="0" enterDelay="500" enterNextDelay="2000" title="You must enter a new token first">
<Tooltip enterTouchDelay="0" enterDelay="500" enterNextDelay="2000" title={t("You must enter a new token first")}>
<div>
<Button disabled={true} type="submit" size='small' >
<SmartToyIcon sx={{width:18, height:18}} />
<span> Generate Robot</span>
<span>{t("Generate Robot")}</span>
</Button>
</div>
</Tooltip>
@ -247,10 +243,10 @@ export default class UserGenPage extends Component {
</Grid>
<Grid item xs={12} align="center">
<ButtonGroup variant="contained" aria-label="outlined primary button group">
<Button disabled={this.state.loadingRobot} color='primary' to='/make/' component={Link}>Make Order</Button>
<Button color='inherit' onClick={this.handleClickOpenInfo}>Info</Button>
<Button disabled={this.state.loadingRobot} color='primary' to='/make/' component={Link}>{t("Make Order")}</Button>
<Button color='inherit' onClick={this.handleClickOpenInfo}>{t("Info")}</Button>
<this.InfoDialog/>
<Button disabled={this.state.loadingRobot} color='secondary' to='/book/' component={Link}>View Book</Button>
<Button disabled={this.state.loadingRobot} color='secondary' to='/book/' component={Link}>{t("View Book")}</Button>
</ButtonGroup>
</Grid>
@ -263,7 +259,7 @@ export default class UserGenPage extends Component {
<Grid item xs={0.8}/>
<Grid item xs={7.5} align="right">
<Typography component="h5" variant="h5">
Simple and Private LN P2P Exchange
{t("Simple and Private LN P2P Exchange")}
</Typography>
</Grid>
<Grid item xs={2.5} align="left">
@ -275,4 +271,6 @@ export default class UserGenPage extends Component {
</Grid>
);
}
}
}
export default withTranslation()(UserGenPage);

View File

@ -247,7 +247,7 @@ export default function AutocompletePayments(props) {
{groupedOptions.length > 0 ? (
<Listbox {...getListboxProps()}>
<div style={{position:'fixed', minHeight:'20px', marginLeft: '53px', marginTop: '-13px'}}>
<ListHeader><i>You can add any method </i></ListHeader>
<ListHeader><i>{props.listHeaderText}</i></ListHeader>
</div>
{groupedOptions.map((option, index) => (
<li {...getOptionProps({ option, index })}>
@ -262,7 +262,7 @@ export default function AutocompletePayments(props) {
))}
{val != null?
(val.length > 2 ?
<Button size="small" fullWidth={true} onClick={() => handleAddNew(getInputProps())}><DashboardCustomizeIcon sx={{width:18,height:18}}/>Add New</Button>
<Button size="small" fullWidth={true} onClick={() => handleAddNew(getInputProps())}><DashboardCustomizeIcon sx={{width:18,height:18}}/>{props.addNewButtonText}</Button>
:null)
:null}
</Listbox>
@ -270,7 +270,7 @@ export default function AutocompletePayments(props) {
//Here goes what happens if there is no groupedOptions
(getInputProps().value.length > 0 ?
<Listbox {...getListboxProps()}>
<Button fullWidth={true} onClick={() => handleAddNew(getInputProps())}><DashboardCustomizeIcon sx={{width:20,height:20}}/>Add New</Button>
<Button fullWidth={true} onClick={() => handleAddNew(getInputProps())}><DashboardCustomizeIcon sx={{width:20,height:20}}/>{props.addNewButtonText}</Button>
</Listbox>
:null)
}

View File

@ -0,0 +1,45 @@
import i18n from "i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import { initReactI18next } from "react-i18next";
import HttpApi from 'i18next-http-backend';
import translationEN from "../locales/en.json";
import translationES from "../locales/es.json";
import translationDE from "../locales/de.json";
import translationRU from "../locales/ru.json";
import translationZH from "../locales/zh.json";
i18n
.use(HttpApi)
.use(LanguageDetector)
.use(initReactI18next)
.init({
resources: {
en: {translations: translationEN},
es: {translations: translationES},
ru: {translations: translationRU},
de: {translations: translationDE},
zh: {translations: translationZH},
},
fallbackLng: "en",
debug: true,
// have a common namespace used around the full app
ns: ["translations"],
defaultNS: "translations",
keySeparator: false, // we use content as keys
interpolation: {
escapeValue: false,
formatSeparator: ","
},
react: {
wait: true,
useSuspense: false,
}
});
export default i18n;

View File

@ -0,0 +1,35 @@
# Contributing Translations to RoboSats
RoboSats is a way to exchange BTC for **any currency of the world**. As such, for many users this tool might only be useful if it is available in a language they can understand. Translating RoboSats into a new language is one of the most valuable contributions to the project, as it makes it available to new audience, increasing the reach of this cool freedom tool.
There isn't a lot of text in RoboSats, however it might be bst to split the work with another contributor. You can poll in the telegram community @RoboSats and find users willing to split the task.
## How to contribute a new translation.
Simply create a new translation file in `frontend/src/locales` (Same folder where you are reading these instructions). In `locales` there is a single file with a json dictionary for every language. In order to create a new translation, simply copy `en.json` (the master text) into a new file named after the language's [ISO 639 two character code](https://www.loc.gov/standards/iso639-2/php/English_list.php).
## Guidelines
Each language .json dictionary contains pairs of keys and values in the following format { "key1":"value1", "key2":"value2", ...}. Most keys are the literal English sentence. These simply have to be translated on the right side, for example, in order to translate the `Make Order` button to Spanish we should change the file to look like this `{... "Make Order":"Crear Orden",...}`.
1. **Not all keys are explicit sentences.** Some keys are variable names e.g. "phone_unsafe_alert". In these case you must take a look at the value originally in `en.json`.
2. **The language dictionary is split into 9 sections.** The first key of each section is a reference and does not need to be translated. For example, the second section starts with the key:value `"USER GENERATION PAGE - UserGenPage.js": "Landing Page and User Generation"` . It does not need to be translated, it is just information for the translator to understand what part of the app he will be working on.
3. **Try to keep a similar length to the original sentence.** In most cases it will be okay if the translation is shorter. However, translations that result in a higher character count might break the UI! Of course, it might not always be possible to stick to the length of the English sentence. In those cases the UI might have to be changed, contact the responsible person for such a change.
4. **Some sentences contain variables**, for example, {{currencyCode}}. It will insert the currency code where the variable is found. E.g., `"Pay 30 {{currencyCode}}"` will render into "Pay 30 USD".
5. **Some sentences contain HTML tags.** These tags are usually hyperlinks. For example in `{"phone_unsafe_alert": "Use <1>Tor Browser</1> and visit the <3>Onion</3> site."}` the children text of <1> (Tor Browser) will link to the Tor Download website, and the children of <3> will link to the RoboSats Onion site.
6. **Some text is high priority, some other text is low priority.** Some keys are likely to change soon or they might not be so relevant for the user of the app. The translation files are sorted from top to bottom by the priority of the translation. The keys by the end of the translation file are more likely to change. It is best to translate from top to bottom.
7. Use a spell checker ;)
8. **Understand the context of where the translation will be displayed.** Literal translations might not work well to some languages. While in English the wording is always similar, in some languages it might be very different if you are translating a button (the user is taking an action) or if you are simply translating a tooltip.
To understand the context it might be clever to translate the strings while looking at the app. However, many strings can only be found while trading. The testnet RoboSats site is great for this as you can explore the whole app simply interacting with it with testnet bitcoin. However, in case of doubt where a text is displayed, it might be faster to simply write a message on the community group @robosats in Telegram.
9. Congratulate yourself! Seriously, it's so awesome you are looking into building up freedom tools!!

View File

@ -0,0 +1,354 @@
{
"UNSAFE ALERT - UnsafeAlert.js": "Alert that shows on top when browsing from the unsafe clearnet sites",
"You are not using RoboSats privately": "You are not using RoboSats privately",
"desktop_unsafe_alert": "Some features are disabled for your protection (e.g. chat) and you will not be able to complete a trade without them. To protect your privacy and fully enable RoboSats, use <1>Tor Browser</1> and visit the <3>Onion</3> site.",
"phone_unsafe_alert": "You will not be able to complete a trade. Use <1>Tor Browser</1> and visit the <3>Onion</3> site.",
"Hide":"Hide",
"USER GENERATION PAGE - UserGenPage.js": "Landing Page and User Generation",
"Simple and Private LN P2P Exchange": "Simple and Private LN P2P Exchange",
"This is your trading avatar":"This is your trading avatar",
"Store your token safely":"Store your token safely",
"A robot avatar was found, welcome back!":"A robot avatar was found, welcome back!",
"Copied!":"Copied!",
"Generate a new token":"Generate a new token",
"Generate Robot":"Generate Robot",
"You must enter a new token first":"You must enter a new token first",
"Make Order":"Make Order",
"Info":"Info",
"View Book":"View Book",
"MAKER PAGE - MakerPage.js": "This is the page where users can create new orders",
"Order":"Order",
"Customize":"Customize",
"Buy or Sell Bitcoin?":"Buy or Sell Bitcoin?",
"Buy":"Buy",
"Sell":"Sell",
"Amount":"Amount",
"Amount of fiat to exchange for bitcoin":"Amount of fiat to exchange for bitcoin",
"Invalid":"Invalid",
"Enter your preferred fiat payment methods. Fast methods are highly recommended.":"Enter your preferred fiat payment methods. Fast methods are highly recommended.",
"Must be shorter than 65 characters":"Must be shorter than 65 characters",
"Swap Destination(s)":"Swap Destination(s)",
"Fiat Payment Method(s)":"Fiat Payment Method(s)",
"You can add any method":"You can add any method",
"Add New":"Add New",
"Choose a Pricing Method":"Choose a Pricing Method",
"Relative":"Relative",
"Let the price move with the market":"Let the price move with the market",
"Premium over Market (%)":"Premium over Market (%)",
"Explicit":"Explicit",
"Set a fix amount of satoshis":"Set a fix amount of satoshis",
"Satoshis":"Satoshis",
"Let the taker chose an amount within the range":"Let the taker chose an amount within the range",
"Enable Amount Range":"Enable Amount Range",
"From": "From",
"to":"to",
"Public Duration (HH:mm)":"Public Duration (HH:mm)",
"Set the skin-in-the-game, increase for higher safety assurance":"Set the skin-in-the-game, increase for higher safety assurance",
"Fidelity Bond Size":"Fidelity Bond Size",
"Allow bondless takers":"Allow bondless takers",
"COMING SOON - High risk! Limited to {{limitSats}}K Sats":"COMING SOON - High risk! Limited to {{limitSats}}K Sats",
"You must fill the order correctly":"You must fill the order correctly",
"Create Order":"Create Order",
"Back":"Back",
"Create a BTC buy order for ":"Create a BTC buy order for ",
"Create a BTC sell order for ":"Create a BTC sell order for ",
" of {{satoshis}} Satoshis":" of {{satoshis}} Satoshis",
" at market price":" at market price",
" at a {{premium}}% premium":" at a {{premium}}% premium",
" at a {{discount}}% discount":" at a {{discount}}% discount",
"Must be less than {{max}}%":"Must be less than {{max}}%",
"Must be more than {{min}}%":"Must be more than {{min}}%",
"Must be less than {{maxSats}": "Must be less than {{maxSats}}",
"Must be more than {{minSats}}": "Must be more than {{minSats}}",
"BOOK PAGE - BookPage.js":"The Book Order page",
"Seller":"Seller",
"Buyer":"Buyer",
"I want to":"I want to",
"Select Order Type":"Select Order Type",
"ANY_type":"ANY",
"ANY_currency":"ANY",
"BUY":"BUY",
"SELL":"SELL",
"and receive":"and receive",
"and pay with":"and pay with",
"and use":"and use",
"Select Payment Currency":"Select Payment Currency",
"Robot":"Robot",
"Is":"Is",
"Currency":"Currency",
"Payment Method":"Payment Method",
"Pay":"Pay",
"Price":"Price",
"Premium":"Premium",
"You are SELLING BTC for {{currencyCode}}":"You are SELLING BTC for {{currencyCode}}",
"You are BUYING BTC for {{currencyCode}}":"You are BUYING BTC for {{currencyCode}}",
"You are looking at all":"You are looking at all",
"No orders found to sell BTC for {{currencyCode}}":"No orders found to sell BTC for {{currencyCode}}",
"No orders found to buy BTC for {{currencyCode}}":"No orders found to buy BTC for {{currencyCode}}",
"Be the first one to create an order":"Be the first one to create an order",
"BOTTOM BAR AND MISC - BottomBar.js":"Bottom Bar user profile and miscellaneous dialogs",
"Stats For Nerds":"Stats For Nerds",
"LND version":"LND version",
"Currently running commit hash":"Currently running commit hash",
"24h contracted volume":"24h contracted volume",
"Lifetime contracted volume":"Lifetime contracted volume",
"Made with":"Made with",
"and":"and",
"... somewhere on Earth!":"... somewhere on Earth!",
"Community":"Community",
"Support is only offered via public channels. Join our Telegram community if you have questions or want to hang out with other cool robots. Please, use our Github Issues if you find a bug or want to see new features!":"Support is only offered via public channels. Join our Telegram community if you have questions or want to hang out with other cool robots. Please, use our Github Issues if you find a bug or want to see new features!",
"Join the RoboSats group":"Join the RoboSats group",
"Telegram (English / Main)":"Telegram (English / Main)",
"RoboSats Telegram Communities":"RoboSats Telegram Communities",
"Join RoboSats Spanish speaking community!":"Join RoboSats Spanish speaking community!",
"Join RoboSats Russian speaking community!":"Join RoboSats Russian speaking community!",
"Join RoboSats Chinese speaking community!":"Join RoboSats Chinese speaking community!",
"Join RoboSats English speaking community!":"Join RoboSats English speaking community!",
"Tell us about a new feature or a bug":"Tell us about a new feature or a bug",
"Github Issues - The Robotic Satoshis Open Source Project":"Github Issues - The Robotic Satoshis Open Source Project",
"Your Profile":"Your Profile",
"Your robot":"Your robot",
"One active order #{{orderID}}":"One active order #{{orderID}}",
"Your current order":"Your current order",
"No active orders":"No active orders",
"Your token (will not remain here)":"Your token (will not remain here)",
"Back it up!":"Back it up!",
"Cannot remember":"Cannot remember",
"Rewards and compensations":"Rewards and compensations",
"Share to earn 100 Sats per trade":"Share to earn 100 Sats per trade",
"Your referral link":"Your referral link",
"Your earned rewards":"Your earned rewards",
"Claim":"Claim",
"Invoice for {{amountSats}} Sats":"Invoice for {{amountSats}} Sats",
"Submit":"Submit",
"There it goes, thank you!🥇":"There it goes, thank you!🥇",
"You have an active order":"You have an active order",
"You can claim satoshis!":"You can claim satoshis!",
"Public Buy Orders":"Public Buy Orders",
"Public Sell Orders":"Public Sell Orders",
"Today Active Robots":"Today Active Robots",
"24h Avg Premium":"24h Avg Premium",
"Trade Fee":"Trade Fee",
"Show community and support links":"Show community and support links",
"Show stats for nerds":"Show stats for nerds",
"Exchange Summary":"Exchange Summary",
"Public buy orders":"Public buy orders",
"Public sell orders":"Public sell orders",
"Book liquidity":"Book liquidity",
"Today active robots":"Today active robots",
"24h non-KYC bitcoin premium":"24h non-KYC bitcoin premium",
"Maker fee":"Maker fee",
"Taker fee":"Taker fee",
"Number of public BUY orders":"Number of public BUY orders",
"Number of public SELL orders":"Number of public SELL orders",
"ORDER PAGE - OrderPage.js": "Order details page",
"Order Box":"Order Box",
"Contract":"Contract",
"Active":"Active",
"Seen recently":"Seen recently",
"Inactive":"Inactive",
"(Seller)":"(Seller)",
"(Buyer)":"(Buyer)",
"Order maker":"Order maker",
"Order taker":"Order taker",
"Order Details":"Order Details",
"Order status":"Order status",
"Waiting for maker bond":"Waiting for maker bond",
"Public":"Public",
"Waiting for taker bond":"Waiting for taker bond",
"Cancelled":"Cancelled",
"Expired":"Expired",
"Waiting for trade collateral and buyer invoice":"Waiting for trade collateral and buyer invoice",
"Waiting only for seller trade collateral":"Waiting only for seller trade collateral",
"Waiting only for buyer invoice":"Waiting only for buyer invoice",
"Sending fiat - In chatroom":"Sending fiat - In chatroom",
"Fiat sent - In chatroom":"Fiat sent - In chatroom",
"In dispute":"In dispute",
"Collaboratively cancelled":"Collaboratively cancelled",
"Sending satoshis to buyer":"Sending satoshis to buyer",
"Sucessful trade":"Successful trade",
"Failed lightning network routing":"Failed lightning network routing",
"Wait for dispute resolution":"Wait for dispute resolution",
"Maker lost dispute":"Maker lost dispute",
"Taker lost dispute":"Taker lost dispute",
"Amount range":"Amount range",
"Swap destination":"Swap destination",
"Accepted payment methods":"Accepted payment methods",
"Others":"Others",
"{{price}} {{currencyCode}}/BTC - Premium: {{premium}}%":"{{price}} {{currencyCode}}/BTC - Premium: {{premium}}%",
"Price and Premium":"Price and Premium",
"Amount of Satoshis":"Amount of Satoshis",
"Premium over market price":"Premium over market price",
"Order ID":"Order ID",
"Expires in":"Expires in",
"{{nickname}} is asking for a collaborative cancel":"{{nickname}} is asking for a collaborative cancel",
"You asked for a collaborative cancellation":"You asked for a collaborative cancellation",
"Invoice expired. You did not confirm publishing the order in time. Make a new order.":"Invoice expired. You did not confirm publishing the order in time. Make a new order.",
"This order has been cancelled by the maker":"This order has been cancelled by the maker",
"Penalty lifted, good to go!":"Penalty lifted, good to go!",
"You cannot take an order yet! Wait {{timeMin}}m {{timeSec}}s":"You cannot take an order yet! Wait {{timeMin}}m {{timeSec}}s",
"Too low":"Too low",
"Too high":"Too high",
"Enter amount of fiat to exchange for bitcoin":"Enter amount of fiat to exchange for bitcoin",
"Amount {{currencyCode}}":"Amount {{currencyCode}}",
"You must specify an amount first":"You must specify an amount first",
"Take Order":"Take Order",
"Wait until you can take an order":"Wait until you can take an order",
"Cancel the order?":"Cancel the order?",
"If the order is cancelled now you will lose your bond.":"If the order is cancelled now you will lose your bond.",
"Confirm Cancel":"Confirm Cancel",
"The maker is away":"The maker is away",
"By taking this order you risk wasting your time. If the maker does not proceed in time, you will be compensated in satoshis for 50% of the maker bond.":"By taking this order you risk wasting your time. If the maker does not proceed in time, you will be compensated in satoshis for 50% of the maker bond.",
"Collaborative cancel the order?":"Collaborative cancel the order?",
"The trade escrow has been posted. The order can be cancelled only if both, maker and taker, agree to cancel.":"The trade escrow has been posted. The order can be cancelled only if both, maker and taker, agree to cancel.",
"Ask for Cancel":"Ask for Cancel",
"Cancel":"Cancel",
"Collaborative Cancel":"Collaborative Cancel",
"Invalid Order Id":"Invalid Order Id",
"You must have a robot avatar to see the order details":"You must have a robot avatar to see the order details",
"This order has been cancelled collaborativelly":"This order has been cancelled collaborativelly",
"You are not allowed to see this order":"You are not allowed to see this order",
"The Robotic Satoshis working in the warehouse did not understand you. Please, fill a Bug Issue in Github https://github.com/reckless-satoshi/robosats/issues":"The Robotic Satoshis working in the warehouse did not understand you. Please, fill a Bug Issue in Github https://github.com/reckless-satoshi/robosats/issues",
"CHAT BOX - Chat.js":"Chat Box",
"You":"You",
"Peer":"Peer",
"connected":"connected",
"disconnected":"disconnected",
"Type a message":"Type a message",
"Connecting...":"Connecting...",
"Send":"Send",
"The chat has no memory: if you leave, messages are lost.":"The chat has no memory: if you leave, messages are lost.",
"Learn easy PGP encryption.":"Learn easy PGP encryption.",
"CONTRACT BOX - TradeBox.js": "The Contract Box that guides users trough the whole trade pipeline",
"Contract Box":"Contract Box",
"Robots show commitment to their peers": "Robots show commitment to their peers",
"Lock {{amountSats}} Sats to PUBLISH order": "Lock {{amountSats}} Sats to PUBLISH order",
"Lock {{amountSats}} Sats to TAKE order": "Lock {{amountSats}} Sats to TAKE order",
"Lock {{amountSats}} Sats as collateral": "Lock {{amountSats}} Sats as collateral",
"Copy to clipboard":"Copy to clipboard",
"This is a hold invoice, it will freeze in your wallet. It will be charged only if you cancel or lose a dispute.":"This is a hold invoice, it will freeze in your wallet. It will be charged only if you cancel or lose a dispute.",
"This is a hold invoice, it will freeze in your wallet. It will be released to the buyer once you confirm to have received the {{currencyCode}}.":"This is a hold invoice, it will freeze in your wallet. It will be released to the buyer once you confirm to have received the {{currencyCode}}.",
"Your maker bond is locked":"Your maker bond is locked",
"Your taker bond is locked":"Your taker bond is locked",
"Your maker bond was settled":"Your maker bond was settled",
"Your taker bond was settled":"Your taker bond was settled",
"Your maker bond was unlock":"Your maker bond was unlock",
"Your taker bond was unlocked":"Your taker bond was unlocked",
"Your order is public":"Your order is public",
"Be patient while robots check the book. It might take some time. This box will ring 🔊 once a robot takes your order.":"Be patient while robots check the book. It might take some time. This box will ring 🔊 once a robot takes your order.",
"Please note that if your premium is excessive or your currency or payment methods are not popular, your order might expire untaken. Your bond will return to you (no action needed).":"Please note that if your premium is excessive or your currency or payment methods are not popular, your order might expire untaken. Your bond will return to you (no action needed).",
"Enable Telegram Notifications":"Enable Telegram Notifications",
"Enable TG Notifications":"Enable TG Notifications",
"You will be taken to a conversation with RoboSats telegram bot. Simply open the chat and press Start. Note that by enabling telegram notifications you might lower your level of anonymity.":"You will be taken to a conversation with RoboSats telegram bot. Simply open the chat and press Start. Note that by enabling telegram notifications you might lower your level of anonymity.",
"Go back":"Go back",
"Enable":"Enable",
"Telegram enabled":"Telegram enabled",
"Public orders for {{currencyCode}}":"Public orders for {{currencyCode}}",
"Premium rank": "Premium rank",
"Among public {{currencyCode}} orders (higher is cheaper)": "Among public {{currencyCode}} orders (higher is cheaper)",
"A taker has been found!":"A taker has been found!",
"Please wait for the taker to lock a bond. If the taker does not lock a bond in time, the order will be made public again.":"Please wait for the taker to lock a bond. If the taker does not lock a bond in time, the order will be made public again.",
"Submit an invoice for {{amountSats}} Sats":"Submit an invoice for {{amountSats}} Sats",
"The taker is committed! Before letting you send {{amountFiat}} {{currencyCode}}, we want to make sure you are able to receive the BTC. Please provide a valid invoice for {{amountSats}} Satoshis.":"The taker is committed! Before letting you send {{amountFiat}} {{currencyCode}}, we want to make sure you are able to receive the BTC. Please provide a valid invoice for {{amountSats}} Satoshis.",
"Payout Lightning Invoice":"Payout Lightning Invoice",
"Your invoice looks good!":"Your invoice looks good!",
"We are waiting for the seller lock the trade amount.":"We are waiting for the seller lock the trade amount.",
"Just hang on for a moment. If the seller does not deposit, you will get your bond back automatically. In addition, you will receive a compensation (check the rewards in your profile).":"Just hang on for a moment. If the seller does not deposit, you will get your bond back automatically. In addition, you will receive a compensation (check the rewards in your profile).",
"The trade collateral is locked!":"The trade collateral is locked!",
"We are waiting for the buyer to post a lightning invoice. Once he does, you will be able to directly communicate the fiat payment details.":"We are waiting for the buyer to post a lightning invoice. Once he does, you will be able to directly communicate the fiat payment details.",
"Just hang on for a moment. If the buyer does not cooperate, you will get back the trade collateral and your bond automatically. In addition, you will receive a compensation (check the rewards in your profile).":"Just hang on for a moment. If the buyer does not cooperate, you will get back the trade collateral and your bond automatically. In addition, you will receive a compensation (check the rewards in your profile).",
"Confirm {{currencyCode}} sent":"Confirm {{currencyCode}} sent",
"Confirm {{currencyCode}} received":"Confirm {{currencyCode}} received",
"Open Dispute":"Open Dispute",
"The order has expired":"The order has expired",
"Chat with the buyer":"Chat with the buyer",
"Chat with the seller":"Chat with the seller",
"Say hi! Be helpful and concise. Let them know how to send you {{currencyCode}}.":"Say hi! Be helpful and concise. Let them know how to send you {{currencyCode}}.",
"The buyer has sent the fiat. Click 'Confirm Received' once you receive it.":"The buyer has sent the fiat. Click 'Confirm Received' once you receive it.",
"Say hi! Ask for payment details and click 'Confirm Sent' as soon as the payment is sent.":"Say hi! Ask for payment details and click 'Confirm Sent' as soon as the payment is sent.",
"Wait for the seller to confirm he has received the payment.":"Wait for the seller to confirm he has received the payment.",
"Confirm you received {{currencyCode}}?":"Confirm you received {{currencyCode}}?",
"Confirming that you received the fiat will finalize the trade. The satoshis in the escrow will be released to the buyer. Only confirm after the {{currencyCode}} has arrived to your account. In addition, if you have received {{currencyCode}} and do not confirm the receipt, you risk losing your bond.":"Confirming that you received the fiat will finalize the trade. The satoshis in the escrow will be released to the buyer. Only confirm after the {{currencyCode}} has arrived to your account. In addition, if you have received {{currencyCode}} and do not confirm the receipt, you risk losing your bond.",
"Confirm":"Confirm",
"🎉Trade finished!🥳":"🎉Trade finished!🥳",
"rate_robosats":"What do you think of 🤖<1>RoboSats</1>⚡?",
"Thank you! RoboSats loves you too ❤️":"Thank you! RoboSats loves you too ❤️",
"RoboSats gets better with more liquidity and users. Tell a bitcoiner friend about Robosats!":"RoboSats gets better with more liquidity and users. Tell a bitcoiner friend about Robosats!",
"Thank you for using Robosats!":"Thank you for using Robosats!",
"let_us_know_hot_to_improve":"Let us know how the platform could improve (<1>Telegram</1> / <3>Github</3>)",
"Start Again":"Start Again",
"Attempting Lightning Payment":"Attempting Lightning Payment",
"RoboSats is trying to pay your lightning invoice. Remember that lightning nodes must be online in order to receive payments.":"RoboSats is trying to pay your lightning invoice. Remember that lightning nodes must be online in order to receive payments.",
"Retrying!":"Retrying!",
"Lightning Routing Failed":"Lightning Routing Failed",
"Your invoice has expired or more than 3 payment attempts have been made. Muun wallet is not recommended. ":"Your invoice has expired or more than 3 payment attempts have been made. Muun wallet is not recommended. ",
"Check the list of compatible wallets":"Check the list of compatible wallets",
"RoboSats will try to pay your invoice 3 times every 5 minutes. If it keeps failing, you will be able to submit a new invoice. Check whether you have enough inbound liquidity. Remember that lightning nodes must be online in order to receive payments.":"RoboSats will try to pay your invoice 3 times every 5 minutes. If it keeps failing, you will be able to submit a new invoice. Check whether you have enough inbound liquidity. Remember that lightning nodes must be online in order to receive payments.",
"Next attempt in":"Next attempt in",
"Do you want to open a dispute?":"Do you want to open a dispute?",
"The RoboSats staff will examine the statements and evidence provided. You need to build a complete case, as the staff cannot read the chat. It is best to provide a burner contact method with your statement. The satoshis in the trade escrow will be sent to the dispute winner, while the dispute loser will lose the bond.":"The RoboSats staff will examine the statements and evidence provided. You need to build a complete case, as the staff cannot read the chat. It is best to provide a burner contact method with your statement. The satoshis in the trade escrow will be sent to the dispute winner, while the dispute loser will lose the bond.",
"Disagree":"Disagree",
"Agree and open dispute":"Agree and open dispute",
"A dispute has been opened":"A dispute has been opened",
"Please, submit your statement. Be clear and specific about what happened and provide the necessary evidence. You MUST provide a contact method: burner email, XMPP or telegram username to follow up with the staff. Disputes are solved at the discretion of real robots (aka humans), so be as helpful as possible to ensure a fair outcome. Max 5000 chars.":"Please, submit your statement. Be clear and specific about what happened and provide the necessary evidence. You MUST provide a contact method: burner email, XMPP or telegram username to follow up with the staff. Disputes are solved at the discretion of real robots (aka humans), so be as helpful as possible to ensure a fair outcome. Max 5000 chars.",
"Submit dispute statement":"Submit dispute statement",
"We have received your statement":"We have received your statement",
"We are waiting for your trade counterpart statement. If you are hesitant about the state of the dispute or want to add more information, contact robosats@protonmail.com.":"We are waiting for your trade counterpart statement. If you are hesitant about the state of the dispute or want to add more information, contact robosats@protonmail.com.",
"Please, save the information needed to identify your order and your payments: order ID; payment hashes of the bonds or escrow (check on your lightning wallet); exact amount of satoshis; and robot nickname. You will have to identify yourself as the user involved in this trade via email (or other contact methods).":"Please, save the information needed to identify your order and your payments: order ID; payment hashes of the bonds or escrow (check on your lightning wallet); exact amount of satoshis; and robot nickname. You will have to identify yourself as the user involved in this trade via email (or other contact methods).",
"We have the statements":"We have the statements",
"Both statements have been received, wait for the staff to resolve the dispute. If you are hesitant about the state of the dispute or want to add more information, contact robosats@protonmail.com. If you did not provide a contact method, or are unsure whether you wrote it right, write us immediately.":"Both statements have been received, wait for the staff to resolve the dispute. If you are hesitant about the state of the dispute or want to add more information, contact robosats@protonmail.com. If you did not provide a contact method, or are unsure whether you wrote it right, write us immediately.",
"You have won the dispute":"You have won the dispute",
"You can claim the dispute resolution amount (escrow and fidelity bond) from your profile rewards. If there is anything the staff can help with, do not hesitate to contact to robosats@protonmail.com (or via your provided burner contact method).":"You can claim the dispute resolution amount (escrow and fidelity bond) from your profile rewards. If there is anything the staff can help with, do not hesitate to contact to robosats@protonmail.com (or via your provided burner contact method).",
"You have lost the dispute":"You have lost the dispute",
"Unfortunately you have lost the dispute. If you think this is a mistake you can ask to re-open the case via email to robosats@protonmail.com. However, chances of it being investigated again are low.":"Unfortunately you have lost the dispute. If you think this is a mistake you can ask to re-open the case via email to robosats@protonmail.com. However, chances of it being investigated again are low.",
"INFO DIALOG - InfoDiagog.js":"App information and clarifications and terms of use",
"Close":"Close",
"What is RoboSats?":"What is RoboSats?",
"It is a BTC/FIAT peer-to-peer exchange over lightning.":"It is a BTC/FIAT peer-to-peer exchange over lightning.",
"RoboSats is an open source project ":"RoboSats is an open source project ",
"It simplifies matchmaking and minimizes the need of trust. RoboSats focuses in privacy and speed.":"It simplifies matchmaking and minimizes the need of trust. RoboSats focuses in privacy and speed.",
"(GitHub).":"(GitHub).",
"How does it work?":"How does it work?",
"AnonymousAlice01 wants to sell bitcoin. She posts a sell order. BafflingBob02 wants to buy bitcoin and he takes Alice's order. Both have to post a small bond using lightning to prove they are real robots. Then, Alice posts the trade collateral also using a lightning hold invoice. RoboSats locks the invoice until Alice confirms she received the fiat, then the satoshis are released to Bob. Enjoy your satoshis, Bob!":"AnonymousAlice01 wants to sell bitcoin. She posts a sell order. BafflingBob02 wants to buy bitcoin and he takes Alice's order. Both have to post a small bond using lightning to prove they are real robots. Then, Alice posts the trade collateral also using a lightning hold invoice. RoboSats locks the invoice until Alice confirms she received the fiat, then the satoshis are released to Bob. Enjoy your satoshis, Bob!",
"At no point, AnonymousAlice01 and BafflingBob02 have to entrust the bitcoin funds to each other. In case they have a conflict, RoboSats staff will help resolving the dispute.":"At no point, AnonymousAlice01 and BafflingBob02 have to entrust the bitcoin funds to each other. In case they have a conflict, RoboSats staff will help resolving the dispute.",
"You can find a step-by-step description of the trade pipeline in ":"You can find a step-by-step description of the trade pipeline in ",
"How it works":"How it works",
"You can also check the full guide in ":"You can also check the full guide in ",
"How to use":"How to use",
"What payment methods are accepted?":"What payment methods are accepted?",
"All of them as long as they are fast. You can write down your preferred payment method(s). You will have to match with a peer who also accepts that method. The step to exchange fiat has a expiry time of 24 hours before a dispute is automatically open. We highly recommend using instant fiat payment rails.":"All of them as long as they are fast. You can write down your preferred payment method(s). You will have to match with a peer who also accepts that method. The step to exchange fiat has a expiry time of 24 hours before a dispute is automatically open. We highly recommend using instant fiat payment rails.",
"Are there trade limits?":"Are there trade limits?",
"Maximum single trade size is {{maxAmount}} Satoshis to minimize lightning routing failure. There is no limits to the number of trades per day. A robot can only have one order at a time. However, you can use multiple robots simultaneously in different browsers (remember to back up your robot tokens!).":"Maximum single trade size is {{maxAmount}} Satoshis to minimize lightning routing failure. There is no limits to the number of trades per day. A robot can only have one order at a time. However, you can use multiple robots simultaneously in different browsers (remember to back up your robot tokens!).",
"Is RoboSats private?":"Is RoboSats private?",
"RoboSats will never ask you for your name, country or ID. RoboSats does not custody your funds and does not care who you are. RoboSats does not collect or custody any personal data. For best anonymity use Tor Browser and access the .onion hidden service.":"RoboSats will never ask you for your name, country or ID. RoboSats does not custody your funds and does not care who you are. RoboSats does not collect or custody any personal data. For best anonymity use Tor Browser and access the .onion hidden service.",
"Your trading peer is the only one who can potentially guess anything about you. Keep your chat short and concise. Avoid providing non-essential information other than strictly necessary for the fiat payment.":"Your trading peer is the only one who can potentially guess anything about you. Keep your chat short and concise. Avoid providing non-essential information other than strictly necessary for the fiat payment.",
"What are the risks?":"What are the risks?",
"This is an experimental application, things could go wrong. Trade small amounts!":"This is an experimental application, things could go wrong. Trade small amounts!",
"The seller faces the same charge-back risk as with any other peer-to-peer service. Paypal or credit cards are not recommended.":"The seller faces the same charge-back risk as with any other peer-to-peer service. Paypal or credit cards are not recommended.",
"What is the trust model?":"What is the trust model?",
"The buyer and the seller never have to trust each other. Some trust on RoboSats is needed since linking the seller's hold invoice and buyer payment is not atomic (yet). In addition, disputes are solved by the RoboSats staff.":"The buyer and the seller never have to trust each other. Some trust on RoboSats is needed since linking the seller's hold invoice and buyer payment is not atomic (yet). In addition, disputes are solved by the RoboSats staff.",
"To be totally clear. Trust requirements are minimized. However, there is still one way RoboSats could run away with your satoshis: by not releasing the satoshis to the buyer. It could be argued that such move is not in RoboSats' interest as it would damage the reputation for a small payout. However, you should hesitate and only trade small quantities at a time. For large amounts use an onchain escrow service such as Bisq":"To be totally clear. Trust requirements are minimized. However, there is still one way RoboSats could run away with your satoshis: by not releasing the satoshis to the buyer. It could be argued that such move is not in RoboSats' interest as it would damage the reputation for a small payout. However, you should hesitate and only trade small quantities at a time. For large amounts use an onchain escrow service such as Bisq",
"You can build more trust on RoboSats by inspecting the source code.":"You can build more trust on RoboSats by inspecting the source code.",
"Project source code":"Project source code",
"What happens if RoboSats suddenly disappears?":"What happens if RoboSats suddenly disappears?",
"Your sats will return to you. Any hold invoice that is not settled would be automatically returned even if RoboSats goes down forever. This is true for both, locked bonds and trading escrows. However, there is a small window between the seller confirms FIAT RECEIVED and the moment the buyer receives the satoshis when the funds could be permanently lost if RoboSats disappears. This window is about 1 second long. Make sure to have enough inbound liquidity to avoid routing failures. If you have any problem, reach out trough the RoboSats public channels.":"Your sats will return to you. Any hold invoice that is not settled would be automatically returned even if RoboSats goes down forever. This is true for both, locked bonds and trading escrows. However, there is a small window between the seller confirms FIAT RECEIVED and the moment the buyer receives the satoshis when the funds could be permanently lost if RoboSats disappears. This window is about 1 second long. Make sure to have enough inbound liquidity to avoid routing failures. If you have any problem, reach out trough the RoboSats public channels.",
"In many countries using RoboSats is no different than using Ebay or Craiglist. Your regulation may vary. It is your responsibility to comply.":"In many countries using RoboSats is no different than using Ebay or Craiglist. Your regulation may vary. It is your responsibility to comply.",
"Is RoboSats legal in my country?":"Is RoboSats legal in my country?",
"Disclaimer":"Disclaimer",
"This lightning application is provided as is. It is in active development: trade with the utmost caution. There is no private support. Support is only offered via public channels ":"This lightning application is provided as is. It is in active development: trade with the utmost caution. There is no private support. Support is only offered via public channels ",
"(Telegram)":"(Telegram)",
". RoboSats will never contact you. RoboSats will definitely never ask for your robot token.":". RoboSats will never contact you. RoboSats will definitely never ask for your robot token."
}

View File

@ -0,0 +1,354 @@
{
"UNSAFE ALERT - UnsafeAlert.js": "Alert that shows on top when browsing from the unsafe clearnet sites",
"You are not using RoboSats privately": "You are not using RoboSats privately",
"desktop_unsafe_alert": "Some features are disabled for your protection (e.g. chat) and you will not be able to complete a trade without them. To protect your privacy and fully enable RoboSats, use <1>Tor Browser</1> and visit the <3>Onion</3> site.",
"phone_unsafe_alert": "You will not be able to complete a trade. Use <1>Tor Browser</1> and visit the <3>Onion</3> site.",
"Hide":"Hide",
"USER GENERATION PAGE - UserGenPage.js": "Landing Page and User Generation",
"Simple and Private LN P2P Exchange": "Simple and Private LN P2P Exchange",
"This is your trading avatar":"This is your trading avatar",
"Store your token safely":"Store your token safely",
"A robot avatar was found, welcome back!":"A robot avatar was found, welcome back!",
"Copied!":"Copied!",
"Generate a new token":"Generate a new token",
"Generate Robot":"Generate Robot",
"You must enter a new token first":"You must enter a new token first",
"Make Order":"Make Order",
"Info":"Info",
"View Book":"View Book",
"MAKER PAGE - MakerPage.js": "This is the page where users can create new orders",
"Order":"Order",
"Customize":"Customize",
"Buy or Sell Bitcoin?":"Buy or Sell Bitcoin?",
"Buy":"Buy",
"Sell":"Sell",
"Amount":"Amount",
"Amount of fiat to exchange for bitcoin":"Amount of fiat to exchange for bitcoin",
"Invalid":"Invalid",
"Enter your preferred fiat payment methods. Fast methods are highly recommended.":"Enter your preferred fiat payment methods. Fast methods are highly recommended.",
"Must be shorter than 65 characters":"Must be shorter than 65 characters",
"Swap Destination(s)":"Swap Destination(s)",
"Fiat Payment Method(s)":"Fiat Payment Method(s)",
"You can add any method":"You can add any method",
"Add New":"Add New",
"Choose a Pricing Method":"Choose a Pricing Method",
"Relative":"Relative",
"Let the price move with the market":"Let the price move with the market",
"Premium over Market (%)":"Premium over Market (%)",
"Explicit":"Explicit",
"Set a fix amount of satoshis":"Set a fix amount of satoshis",
"Satoshis":"Satoshis",
"Let the taker chose an amount within the range":"Let the taker chose an amount within the range",
"Enable Amount Range":"Enable Amount Range",
"From": "From",
"to":"to",
"Public Duration (HH:mm)":"Public Duration (HH:mm)",
"Set the skin-in-the-game, increase for higher safety assurance":"Set the skin-in-the-game, increase for higher safety assurance",
"Fidelity Bond Size":"Fidelity Bond Size",
"Allow bondless takers":"Allow bondless takers",
"COMING SOON - High risk! Limited to {{limitSats}}K Sats":"COMING SOON - High risk! Limited to {{limitSats}}K Sats",
"You must fill the order correctly":"You must fill the order correctly",
"Create Order":"Create Order",
"Back":"Back",
"Create a BTC buy order for ":"Create a BTC buy order for ",
"Create a BTC sell order for ":"Create a BTC sell order for ",
" of {{satoshis}} Satoshis":" of {{satoshis}} Satoshis",
" at market price":" at market price",
" at a {{premium}}% premium":" at a {{premium}}% premium",
" at a {{discount}}% discount":" at a {{discount}}% discount",
"Must be less than {{max}}%":"Must be less than {{max}}%",
"Must be more than {{min}}%":"Must be more than {{min}}%",
"Must be less than {{maxSats}": "Must be less than {{maxSats}}",
"Must be more than {{minSats}}": "Must be more than {{minSats}}",
"BOOK PAGE - BookPage.js":"The Book Order page",
"Seller":"Seller",
"Buyer":"Buyer",
"I want to":"I want to",
"Select Order Type":"Select Order Type",
"ANY_type":"ANY",
"ANY_currency":"ANY",
"BUY":"BUY",
"SELL":"SELL",
"and receive":"and receive",
"and pay with":"and pay with",
"and use":"and use",
"Select Payment Currency":"Select Payment Currency",
"Robot":"Robot",
"Is":"Is",
"Currency":"Currency",
"Payment Method":"Payment Method",
"Pay":"Pay",
"Price":"Price",
"Premium":"Premium",
"You are SELLING BTC for {{currencyCode}}":"You are SELLING BTC for {{currencyCode}}",
"You are BUYING BTC for {{currencyCode}}":"You are BUYING BTC for {{currencyCode}}",
"You are looking at all":"You are looking at all",
"No orders found to sell BTC for {{currencyCode}}":"No orders found to sell BTC for {{currencyCode}}",
"No orders found to buy BTC for {{currencyCode}}":"No orders found to buy BTC for {{currencyCode}}",
"Be the first one to create an order":"Be the first one to create an order",
"BOTTOM BAR AND MISC - BottomBar.js":"Bottom Bar user profile and miscellaneous dialogs",
"Stats For Nerds":"Stats For Nerds",
"LND version":"LND version",
"Currently running commit hash":"Currently running commit hash",
"24h contracted volume":"24h contracted volume",
"Lifetime contracted volume":"Lifetime contracted volume",
"Made with":"Made with",
"and":"and",
"... somewhere on Earth!":"... somewhere on Earth!",
"Community":"Community",
"Support is only offered via public channels. Join our Telegram community if you have questions or want to hang out with other cool robots. Please, use our Github Issues if you find a bug or want to see new features!":"Support is only offered via public channels. Join our Telegram community if you have questions or want to hang out with other cool robots. Please, use our Github Issues if you find a bug or want to see new features!",
"Join the RoboSats group":"Join the RoboSats group",
"Telegram (English / Main)":"Telegram (English / Main)",
"RoboSats Telegram Communities":"RoboSats Telegram Communities",
"Join RoboSats Spanish speaking community!":"Join RoboSats Spanish speaking community!",
"Join RoboSats Russian speaking community!":"Join RoboSats Russian speaking community!",
"Join RoboSats Chinese speaking community!":"Join RoboSats Chinese speaking community!",
"Join RoboSats English speaking community!":"Join RoboSats English speaking community!",
"Tell us about a new feature or a bug":"Tell us about a new feature or a bug",
"Github Issues - The Robotic Satoshis Open Source Project":"Github Issues - The Robotic Satoshis Open Source Project",
"Your Profile":"Your Profile",
"Your robot":"Your robot",
"One active order #{{orderID}}":"One active order #{{orderID}}",
"Your current order":"Your current order",
"No active orders":"No active orders",
"Your token (will not remain here)":"Your token (will not remain here)",
"Back it up!":"Back it up!",
"Cannot remember":"Cannot remember",
"Rewards and compensations":"Rewards and compensations",
"Share to earn 100 Sats per trade":"Share to earn 100 Sats per trade",
"Your referral link":"Your referral link",
"Your earned rewards":"Your earned rewards",
"Claim":"Claim",
"Invoice for {{amountSats}} Sats":"Invoice for {{amountSats}} Sats",
"Submit":"Submit",
"There it goes, thank you!🥇":"There it goes, thank you!🥇",
"You have an active order":"You have an active order",
"You can claim satoshis!":"You can claim satoshis!",
"Public Buy Orders":"Public Buy Orders",
"Public Sell Orders":"Public Sell Orders",
"Today Active Robots":"Today Active Robots",
"24h Avg Premium":"24h Avg Premium",
"Trade Fee":"Trade Fee",
"Show community and support links":"Show community and support links",
"Show stats for nerds":"Show stats for nerds",
"Exchange Summary":"Exchange Summary",
"Public buy orders":"Public buy orders",
"Public sell orders":"Public sell orders",
"Book liquidity":"Book liquidity",
"Today active robots":"Today active robots",
"24h non-KYC bitcoin premium":"24h non-KYC bitcoin premium",
"Maker fee":"Maker fee",
"Taker fee":"Taker fee",
"Number of public BUY orders":"Number of public BUY orders",
"Number of public SELL orders":"Number of public SELL orders",
"ORDER PAGE - OrderPage.js": "Order details page",
"Order Box":"Order Box",
"Contract":"Contract",
"Active":"Active",
"Seen recently":"Seen recently",
"Inactive":"Inactive",
"(Seller)":"(Seller)",
"(Buyer)":"(Buyer)",
"Order maker":"Order maker",
"Order taker":"Order taker",
"Order Details":"Order Details",
"Order status":"Order status",
"Waiting for maker bond":"Waiting for maker bond",
"Public":"Public",
"Waiting for taker bond":"Waiting for taker bond",
"Cancelled":"Cancelled",
"Expired":"Expired",
"Waiting for trade collateral and buyer invoice":"Waiting for trade collateral and buyer invoice",
"Waiting only for seller trade collateral":"Waiting only for seller trade collateral",
"Waiting only for buyer invoice":"Waiting only for buyer invoice",
"Sending fiat - In chatroom":"Sending fiat - In chatroom",
"Fiat sent - In chatroom":"Fiat sent - In chatroom",
"In dispute":"In dispute",
"Collaboratively cancelled":"Collaboratively cancelled",
"Sending satoshis to buyer":"Sending satoshis to buyer",
"Sucessful trade":"Successful trade",
"Failed lightning network routing":"Failed lightning network routing",
"Wait for dispute resolution":"Wait for dispute resolution",
"Maker lost dispute":"Maker lost dispute",
"Taker lost dispute":"Taker lost dispute",
"Amount range":"Amount range",
"Swap destination":"Swap destination",
"Accepted payment methods":"Accepted payment methods",
"Others":"Others",
"{{price}} {{currencyCode}}/BTC - Premium: {{premium}}%":"{{price}} {{currencyCode}}/BTC - Premium: {{premium}}%",
"Price and Premium":"Price and Premium",
"Amount of Satoshis":"Amount of Satoshis",
"Premium over market price":"Premium over market price",
"Order ID":"Order ID",
"Expires in":"Expires in",
"{{nickname}} is asking for a collaborative cancel":"{{nickname}} is asking for a collaborative cancel",
"You asked for a collaborative cancellation":"You asked for a collaborative cancellation",
"Invoice expired. You did not confirm publishing the order in time. Make a new order.":"Invoice expired. You did not confirm publishing the order in time. Make a new order.",
"This order has been cancelled by the maker":"This order has been cancelled by the maker",
"Penalty lifted, good to go!":"Penalty lifted, good to go!",
"You cannot take an order yet! Wait {{timeMin}}m {{timeSec}}s":"You cannot take an order yet! Wait {{timeMin}}m {{timeSec}}s",
"Too low":"Too low",
"Too high":"Too high",
"Enter amount of fiat to exchange for bitcoin":"Enter amount of fiat to exchange for bitcoin",
"Amount {{currencyCode}}":"Amount {{currencyCode}}",
"You must specify an amount first":"You must specify an amount first",
"Take Order":"Take Order",
"Wait until you can take an order":"Wait until you can take an order",
"Cancel the order?":"Cancel the order?",
"If the order is cancelled now you will lose your bond.":"If the order is cancelled now you will lose your bond.",
"Confirm Cancel":"Confirm Cancel",
"The maker is away":"The maker is away",
"By taking this order you risk wasting your time. If the maker does not proceed in time, you will be compensated in satoshis for 50% of the maker bond.":"By taking this order you risk wasting your time. If the maker does not proceed in time, you will be compensated in satoshis for 50% of the maker bond.",
"Collaborative cancel the order?":"Collaborative cancel the order?",
"The trade escrow has been posted. The order can be cancelled only if both, maker and taker, agree to cancel.":"The trade escrow has been posted. The order can be cancelled only if both, maker and taker, agree to cancel.",
"Ask for Cancel":"Ask for Cancel",
"Cancel":"Cancel",
"Collaborative Cancel":"Collaborative Cancel",
"Invalid Order Id":"Invalid Order Id",
"You must have a robot avatar to see the order details":"You must have a robot avatar to see the order details",
"This order has been cancelled collaborativelly":"This order has been cancelled collaborativelly",
"You are not allowed to see this order":"You are not allowed to see this order",
"The Robotic Satoshis working in the warehouse did not understand you. Please, fill a Bug Issue in Github https://github.com/reckless-satoshi/robosats/issues":"The Robotic Satoshis working in the warehouse did not understand you. Please, fill a Bug Issue in Github https://github.com/reckless-satoshi/robosats/issues",
"CHAT BOX - Chat.js":"Chat Box",
"You":"You",
"Peer":"Peer",
"connected":"connected",
"disconnected":"disconnected",
"Type a message":"Type a message",
"Connecting...":"Connecting...",
"Send":"Send",
"The chat has no memory: if you leave, messages are lost.":"The chat has no memory: if you leave, messages are lost.",
"Learn easy PGP encryption.":"Learn easy PGP encryption.",
"CONTRACT BOX - TradeBox.js": "The Contract Box that guides users trough the whole trade pipeline",
"Contract Box":"Contract Box",
"Robots show commitment to their peers": "Robots show commitment to their peers",
"Lock {{amountSats}} Sats to PUBLISH order": "Lock {{amountSats}} Sats to PUBLISH order",
"Lock {{amountSats}} Sats to TAKE order": "Lock {{amountSats}} Sats to TAKE order",
"Lock {{amountSats}} Sats as collateral": "Lock {{amountSats}} Sats as collateral",
"Copy to clipboard":"Copy to clipboard",
"This is a hold invoice, it will freeze in your wallet. It will be charged only if you cancel or lose a dispute.":"This is a hold invoice, it will freeze in your wallet. It will be charged only if you cancel or lose a dispute.",
"This is a hold invoice, it will freeze in your wallet. It will be released to the buyer once you confirm to have received the {{currencyCode}}.":"This is a hold invoice, it will freeze in your wallet. It will be released to the buyer once you confirm to have received the {{currencyCode}}.",
"Your maker bond is locked":"Your maker bond is locked",
"Your taker bond is locked":"Your taker bond is locked",
"Your maker bond was settled":"Your maker bond was settled",
"Your taker bond was settled":"Your taker bond was settled",
"Your maker bond was unlock":"Your maker bond was unlock",
"Your taker bond was unlocked":"Your taker bond was unlocked",
"Your order is public":"Your order is public",
"Be patient while robots check the book. It might take some time. This box will ring 🔊 once a robot takes your order.":"Be patient while robots check the book. It might take some time. This box will ring 🔊 once a robot takes your order.",
"Please note that if your premium is excessive or your currency or payment methods are not popular, your order might expire untaken. Your bond will return to you (no action needed).":"Please note that if your premium is excessive or your currency or payment methods are not popular, your order might expire untaken. Your bond will return to you (no action needed).",
"Enable Telegram Notifications":"Enable Telegram Notifications",
"Enable TG Notifications":"Enable TG Notifications",
"You will be taken to a conversation with RoboSats telegram bot. Simply open the chat and press Start. Note that by enabling telegram notifications you might lower your level of anonymity.":"You will be taken to a conversation with RoboSats telegram bot. Simply open the chat and press Start. Note that by enabling telegram notifications you might lower your level of anonymity.",
"Go back":"Go back",
"Enable":"Enable",
"Telegram enabled":"Telegram enabled",
"Public orders for {{currencyCode}}":"Public orders for {{currencyCode}}",
"Premium rank": "Premium rank",
"Among public {{currencyCode}} orders (higher is cheaper)": "Among public {{currencyCode}} orders (higher is cheaper)",
"A taker has been found!":"A taker has been found!",
"Please wait for the taker to lock a bond. If the taker does not lock a bond in time, the order will be made public again.":"Please wait for the taker to lock a bond. If the taker does not lock a bond in time, the order will be made public again.",
"Submit an invoice for {{amountSats}} Sats":"Submit an invoice for {{amountSats}} Sats",
"The taker is committed! Before letting you send {{amountFiat}} {{currencyCode}}, we want to make sure you are able to receive the BTC. Please provide a valid invoice for {{amountSats}} Satoshis.":"The taker is committed! Before letting you send {{amountFiat}} {{currencyCode}}, we want to make sure you are able to receive the BTC. Please provide a valid invoice for {{amountSats}} Satoshis.",
"Payout Lightning Invoice":"Payout Lightning Invoice",
"Your invoice looks good!":"Your invoice looks good!",
"We are waiting for the seller lock the trade amount.":"We are waiting for the seller lock the trade amount.",
"Just hang on for a moment. If the seller does not deposit, you will get your bond back automatically. In addition, you will receive a compensation (check the rewards in your profile).":"Just hang on for a moment. If the seller does not deposit, you will get your bond back automatically. In addition, you will receive a compensation (check the rewards in your profile).",
"The trade collateral is locked!":"The trade collateral is locked!",
"We are waiting for the buyer to post a lightning invoice. Once he does, you will be able to directly communicate the fiat payment details.":"We are waiting for the buyer to post a lightning invoice. Once he does, you will be able to directly communicate the fiat payment details.",
"Just hang on for a moment. If the buyer does not cooperate, you will get back the trade collateral and your bond automatically. In addition, you will receive a compensation (check the rewards in your profile).":"Just hang on for a moment. If the buyer does not cooperate, you will get back the trade collateral and your bond automatically. In addition, you will receive a compensation (check the rewards in your profile).",
"Confirm {{currencyCode}} sent":"Confirm {{currencyCode}} sent",
"Confirm {{currencyCode}} received":"Confirm {{currencyCode}} received",
"Open Dispute":"Open Dispute",
"The order has expired":"The order has expired",
"Chat with the buyer":"Chat with the buyer",
"Chat with the seller":"Chat with the seller",
"Say hi! Be helpful and concise. Let them know how to send you {{currencyCode}}.":"Say hi! Be helpful and concise. Let them know how to send you {{currencyCode}}.",
"The buyer has sent the fiat. Click 'Confirm Received' once you receive it.":"The buyer has sent the fiat. Click 'Confirm Received' once you receive it.",
"Say hi! Ask for payment details and click 'Confirm Sent' as soon as the payment is sent.":"Say hi! Ask for payment details and click 'Confirm Sent' as soon as the payment is sent.",
"Wait for the seller to confirm he has received the payment.":"Wait for the seller to confirm he has received the payment.",
"Confirm you received {{currencyCode}}?":"Confirm you received {{currencyCode}}?",
"Confirming that you received the fiat will finalize the trade. The satoshis in the escrow will be released to the buyer. Only confirm after the {{currencyCode}} has arrived to your account. In addition, if you have received {{currencyCode}} and do not confirm the receipt, you risk losing your bond.":"Confirming that you received the fiat will finalize the trade. The satoshis in the escrow will be released to the buyer. Only confirm after the {{currencyCode}} has arrived to your account. In addition, if you have received {{currencyCode}} and do not confirm the receipt, you risk losing your bond.",
"Confirm":"Confirm",
"🎉Trade finished!🥳":"🎉Trade finished!🥳",
"rate_robosats":"What do you think of 🤖<1>RoboSats</1>⚡?",
"Thank you! RoboSats loves you too ❤️":"Thank you! RoboSats loves you too ❤️",
"RoboSats gets better with more liquidity and users. Tell a bitcoiner friend about Robosats!":"RoboSats gets better with more liquidity and users. Tell a bitcoiner friend about Robosats!",
"Thank you for using Robosats!":"Thank you for using Robosats!",
"let_us_know_hot_to_improve":"Let us know how the platform could improve (<1>Telegram</1> / <3>Github</3>)",
"Start Again":"Start Again",
"Attempting Lightning Payment":"Attempting Lightning Payment",
"RoboSats is trying to pay your lightning invoice. Remember that lightning nodes must be online in order to receive payments.":"RoboSats is trying to pay your lightning invoice. Remember that lightning nodes must be online in order to receive payments.",
"Retrying!":"Retrying!",
"Lightning Routing Failed":"Lightning Routing Failed",
"Your invoice has expired or more than 3 payment attempts have been made. Muun wallet is not recommended. ":"Your invoice has expired or more than 3 payment attempts have been made. Muun wallet is not recommended. ",
"Check the list of compatible wallets":"Check the list of compatible wallets",
"RoboSats will try to pay your invoice 3 times every 5 minutes. If it keeps failing, you will be able to submit a new invoice. Check whether you have enough inbound liquidity. Remember that lightning nodes must be online in order to receive payments.":"RoboSats will try to pay your invoice 3 times every 5 minutes. If it keeps failing, you will be able to submit a new invoice. Check whether you have enough inbound liquidity. Remember that lightning nodes must be online in order to receive payments.",
"Next attempt in":"Next attempt in",
"Do you want to open a dispute?":"Do you want to open a dispute?",
"The RoboSats staff will examine the statements and evidence provided. You need to build a complete case, as the staff cannot read the chat. It is best to provide a burner contact method with your statement. The satoshis in the trade escrow will be sent to the dispute winner, while the dispute loser will lose the bond.":"The RoboSats staff will examine the statements and evidence provided. You need to build a complete case, as the staff cannot read the chat. It is best to provide a burner contact method with your statement. The satoshis in the trade escrow will be sent to the dispute winner, while the dispute loser will lose the bond.",
"Disagree":"Disagree",
"Agree and open dispute":"Agree and open dispute",
"A dispute has been opened":"A dispute has been opened",
"Please, submit your statement. Be clear and specific about what happened and provide the necessary evidence. You MUST provide a contact method: burner email, XMPP or telegram username to follow up with the staff. Disputes are solved at the discretion of real robots (aka humans), so be as helpful as possible to ensure a fair outcome. Max 5000 chars.":"Please, submit your statement. Be clear and specific about what happened and provide the necessary evidence. You MUST provide a contact method: burner email, XMPP or telegram username to follow up with the staff. Disputes are solved at the discretion of real robots (aka humans), so be as helpful as possible to ensure a fair outcome. Max 5000 chars.",
"Submit dispute statement":"Submit dispute statement",
"We have received your statement":"We have received your statement",
"We are waiting for your trade counterpart statement. If you are hesitant about the state of the dispute or want to add more information, contact robosats@protonmail.com.":"We are waiting for your trade counterpart statement. If you are hesitant about the state of the dispute or want to add more information, contact robosats@protonmail.com.",
"Please, save the information needed to identify your order and your payments: order ID; payment hashes of the bonds or escrow (check on your lightning wallet); exact amount of satoshis; and robot nickname. You will have to identify yourself as the user involved in this trade via email (or other contact methods).":"Please, save the information needed to identify your order and your payments: order ID; payment hashes of the bonds or escrow (check on your lightning wallet); exact amount of satoshis; and robot nickname. You will have to identify yourself as the user involved in this trade via email (or other contact methods).",
"We have the statements":"We have the statements",
"Both statements have been received, wait for the staff to resolve the dispute. If you are hesitant about the state of the dispute or want to add more information, contact robosats@protonmail.com. If you did not provide a contact method, or are unsure whether you wrote it right, write us immediately.":"Both statements have been received, wait for the staff to resolve the dispute. If you are hesitant about the state of the dispute or want to add more information, contact robosats@protonmail.com. If you did not provide a contact method, or are unsure whether you wrote it right, write us immediately.",
"You have won the dispute":"You have won the dispute",
"You can claim the dispute resolution amount (escrow and fidelity bond) from your profile rewards. If there is anything the staff can help with, do not hesitate to contact to robosats@protonmail.com (or via your provided burner contact method).":"You can claim the dispute resolution amount (escrow and fidelity bond) from your profile rewards. If there is anything the staff can help with, do not hesitate to contact to robosats@protonmail.com (or via your provided burner contact method).",
"You have lost the dispute":"You have lost the dispute",
"Unfortunately you have lost the dispute. If you think this is a mistake you can ask to re-open the case via email to robosats@protonmail.com. However, chances of it being investigated again are low.":"Unfortunately you have lost the dispute. If you think this is a mistake you can ask to re-open the case via email to robosats@protonmail.com. However, chances of it being investigated again are low.",
"INFO DIALOG - InfoDiagog.js":"App information and clarifications and terms of use",
"Close":"Close",
"What is RoboSats?":"What is RoboSats?",
"It is a BTC/FIAT peer-to-peer exchange over lightning.":"It is a BTC/FIAT peer-to-peer exchange over lightning.",
"RoboSats is an open source project ":"RoboSats is an open source project ",
"It simplifies matchmaking and minimizes the need of trust. RoboSats focuses in privacy and speed.":"It simplifies matchmaking and minimizes the need of trust. RoboSats focuses in privacy and speed.",
"(GitHub).":"(GitHub).",
"How does it work?":"How does it work?",
"AnonymousAlice01 wants to sell bitcoin. She posts a sell order. BafflingBob02 wants to buy bitcoin and he takes Alice's order. Both have to post a small bond using lightning to prove they are real robots. Then, Alice posts the trade collateral also using a lightning hold invoice. RoboSats locks the invoice until Alice confirms she received the fiat, then the satoshis are released to Bob. Enjoy your satoshis, Bob!":"AnonymousAlice01 wants to sell bitcoin. She posts a sell order. BafflingBob02 wants to buy bitcoin and he takes Alice's order. Both have to post a small bond using lightning to prove they are real robots. Then, Alice posts the trade collateral also using a lightning hold invoice. RoboSats locks the invoice until Alice confirms she received the fiat, then the satoshis are released to Bob. Enjoy your satoshis, Bob!",
"At no point, AnonymousAlice01 and BafflingBob02 have to entrust the bitcoin funds to each other. In case they have a conflict, RoboSats staff will help resolving the dispute.":"At no point, AnonymousAlice01 and BafflingBob02 have to entrust the bitcoin funds to each other. In case they have a conflict, RoboSats staff will help resolving the dispute.",
"You can find a step-by-step description of the trade pipeline in ":"You can find a step-by-step description of the trade pipeline in ",
"How it works":"How it works",
"You can also check the full guide in ":"You can also check the full guide in ",
"How to use":"How to use",
"What payment methods are accepted?":"What payment methods are accepted?",
"All of them as long as they are fast. You can write down your preferred payment method(s). You will have to match with a peer who also accepts that method. The step to exchange fiat has a expiry time of 24 hours before a dispute is automatically open. We highly recommend using instant fiat payment rails.":"All of them as long as they are fast. You can write down your preferred payment method(s). You will have to match with a peer who also accepts that method. The step to exchange fiat has a expiry time of 24 hours before a dispute is automatically open. We highly recommend using instant fiat payment rails.",
"Are there trade limits?":"Are there trade limits?",
"Maximum single trade size is {{maxAmount}} Satoshis to minimize lightning routing failure. There is no limits to the number of trades per day. A robot can only have one order at a time. However, you can use multiple robots simultaneously in different browsers (remember to back up your robot tokens!).":"Maximum single trade size is {{maxAmount}} Satoshis to minimize lightning routing failure. There is no limits to the number of trades per day. A robot can only have one order at a time. However, you can use multiple robots simultaneously in different browsers (remember to back up your robot tokens!).",
"Is RoboSats private?":"Is RoboSats private?",
"RoboSats will never ask you for your name, country or ID. RoboSats does not custody your funds and does not care who you are. RoboSats does not collect or custody any personal data. For best anonymity use Tor Browser and access the .onion hidden service.":"RoboSats will never ask you for your name, country or ID. RoboSats does not custody your funds and does not care who you are. RoboSats does not collect or custody any personal data. For best anonymity use Tor Browser and access the .onion hidden service.",
"Your trading peer is the only one who can potentially guess anything about you. Keep your chat short and concise. Avoid providing non-essential information other than strictly necessary for the fiat payment.":"Your trading peer is the only one who can potentially guess anything about you. Keep your chat short and concise. Avoid providing non-essential information other than strictly necessary for the fiat payment.",
"What are the risks?":"What are the risks?",
"This is an experimental application, things could go wrong. Trade small amounts!":"This is an experimental application, things could go wrong. Trade small amounts!",
"The seller faces the same charge-back risk as with any other peer-to-peer service. Paypal or credit cards are not recommended.":"The seller faces the same charge-back risk as with any other peer-to-peer service. Paypal or credit cards are not recommended.",
"What is the trust model?":"What is the trust model?",
"The buyer and the seller never have to trust each other. Some trust on RoboSats is needed since linking the seller's hold invoice and buyer payment is not atomic (yet). In addition, disputes are solved by the RoboSats staff.":"The buyer and the seller never have to trust each other. Some trust on RoboSats is needed since linking the seller's hold invoice and buyer payment is not atomic (yet). In addition, disputes are solved by the RoboSats staff.",
"To be totally clear. Trust requirements are minimized. However, there is still one way RoboSats could run away with your satoshis: by not releasing the satoshis to the buyer. It could be argued that such move is not in RoboSats' interest as it would damage the reputation for a small payout. However, you should hesitate and only trade small quantities at a time. For large amounts use an onchain escrow service such as Bisq":"To be totally clear. Trust requirements are minimized. However, there is still one way RoboSats could run away with your satoshis: by not releasing the satoshis to the buyer. It could be argued that such move is not in RoboSats' interest as it would damage the reputation for a small payout. However, you should hesitate and only trade small quantities at a time. For large amounts use an onchain escrow service such as Bisq",
"You can build more trust on RoboSats by inspecting the source code.":"You can build more trust on RoboSats by inspecting the source code.",
"Project source code":"Project source code",
"What happens if RoboSats suddenly disappears?":"What happens if RoboSats suddenly disappears?",
"Your sats will return to you. Any hold invoice that is not settled would be automatically returned even if RoboSats goes down forever. This is true for both, locked bonds and trading escrows. However, there is a small window between the seller confirms FIAT RECEIVED and the moment the buyer receives the satoshis when the funds could be permanently lost if RoboSats disappears. This window is about 1 second long. Make sure to have enough inbound liquidity to avoid routing failures. If you have any problem, reach out trough the RoboSats public channels.":"Your sats will return to you. Any hold invoice that is not settled would be automatically returned even if RoboSats goes down forever. This is true for both, locked bonds and trading escrows. However, there is a small window between the seller confirms FIAT RECEIVED and the moment the buyer receives the satoshis when the funds could be permanently lost if RoboSats disappears. This window is about 1 second long. Make sure to have enough inbound liquidity to avoid routing failures. If you have any problem, reach out trough the RoboSats public channels.",
"In many countries using RoboSats is no different than using Ebay or Craiglist. Your regulation may vary. It is your responsibility to comply.":"In many countries using RoboSats is no different than using Ebay or Craiglist. Your regulation may vary. It is your responsibility to comply.",
"Is RoboSats legal in my country?":"Is RoboSats legal in my country?",
"Disclaimer":"Disclaimer",
"This lightning application is provided as is. It is in active development: trade with the utmost caution. There is no private support. Support is only offered via public channels ":"This lightning application is provided as is. It is in active development: trade with the utmost caution. There is no private support. Support is only offered via public channels ",
"(Telegram)":"(Telegram)",
". RoboSats will never contact you. RoboSats will definitely never ask for your robot token.":". RoboSats will never contact you. RoboSats will definitely never ask for your robot token."
}

View File

@ -0,0 +1,354 @@
{
"UNSAFE-ALERT": "Alert that shows on top when browsing from the unsafe clearnet sites",
"You are not using RoboSats privately": "No estás usando RoboSats de forma privada",
"desktop_unsafe_alert": "Some features are disabled for your protection (e.g. chat) and you will not be able to complete a trade without them. To protect your privacy and fully enable RoboSats, use <1>Tor Browser</1> and visit the <3>Onion</3> site.",
"phone_unsafe_alert": "You will not be able to complete a trade. Use <1>Tor Browser</1> and visit the <3>Onion</3> site.",
"Hide":"Hide",
"UserGenPage": "User Generation Page and Landing Page",
"Simple and Private LN P2P Exchange":"Intercambio LN P2P Fácil y Privado",
"This is your trading avatar":"Este es tu avatar de compraventa",
"Store your token safely":"Store your token safely",
"A robot avatar was found, welcome back!":"A robot avatar was found, welcome back!",
"Copied!":"Copied!",
"Generate a new token":"Generate a new token",
"Generate Robot":"Generate Robot",
"You must enter a new token first":"You must enter a new token first",
"Make Order":"Make Order",
"Info":"Info",
"View Book":"View Book",
"MAKER PAGE - MakerPage.js": "This is the page where users can create new orders",
"Order":"Order",
"Customize":"Customize",
"Buy or Sell Bitcoin?":"Buy or Sell Bitcoin?",
"Buy":"Buy",
"Sell":"Sell",
"Amount":"Amount",
"Amount of fiat to exchange for bitcoin":"Amount of fiat to exchange for bitcoin",
"Invalid":"Invalid",
"Enter your preferred fiat payment methods. Fast methods are highly recommended.":"Enter your preferred fiat payment methods. Fast methods are highly recommended.",
"Must be shorter than 65 characters":"Must be shorter than 65 characters",
"Swap Destination(s)":"Swap Destination(s)",
"Fiat Payment Method(s)":"Fiat Payment Method(s)",
"You can add any method":"You can add any method",
"Add New":"Add New",
"Choose a Pricing Method":"Choose a Pricing Method",
"Relative":"Relative",
"Let the price move with the market":"Let the price move with the market",
"Premium over Market (%)":"Premium over Market (%)",
"Explicit":"Explicit",
"Set a fix amount of satoshis":"Set a fix amount of satoshis",
"Satoshis":"Satoshis",
"Let the taker chose an amount within the range":"Let the taker chose an amount within the range",
"Enable Amount Range":"Enable Amount Range",
"From": "From",
"to":"to",
"Public Duration (HH:mm)":"Public Duration (HH:mm)",
"Set the skin-in-the-game, increase for higher safety assurance":"Set the skin-in-the-game, increase for higher safety assurance",
"Fidelity Bond Size":"Fidelity Bond Size",
"Allow bondless takers":"Allow bondless takers",
"COMING SOON - High risk! Limited to {{limitSats}}K Sats":"COMING SOON - High risk! Limited to {{limitSats}}K Sats",
"You must fill the order correctly":"You must fill the order correctly",
"Create Order":"Create Order",
"Back":"Back",
"Create a BTC buy order for ":"Create a BTC buy order for ",
"Create a BTC sell order for ":"Create a BTC sell order for ",
" of {{satoshis}} Satoshis":" of {{satoshis}} Satoshis",
" at market price":" at market price",
" at a {{premium}}% premium":" at a {{premium}}% premium",
" at a {{discount}}% discount":" at a {{discount}}% discount",
"Must be less than {{max}}%":"Must be less than {{max}}%",
"Must be more than {{min}}%":"Must be more than {{min}}%",
"Must be less than {{maxSats}": "Must be less than {{maxSats}}",
"Must be more than {{minSats}}": "Must be more than {{minSats}}",
"BOOK PAGE - BookPage.js":"The Book Order page",
"Seller":"Seller",
"Buyer":"Buyer",
"I want to":"I want to",
"Select Order Type":"Select Order Type",
"ANY_type":"ANY",
"ANY_currency":"ANY",
"BUY":"BUY",
"SELL":"SELL",
"and receive":"and receive",
"and pay with":"and pay with",
"and use":"and use",
"Select Payment Currency":"Select Payment Currency",
"Robot":"Robot",
"Is":"Is",
"Currency":"Currency",
"Payment Method":"Payment Method",
"Pay":"Pay",
"Price":"Price",
"Premium":"Premium",
"You are SELLING BTC for {{currencyCode}}":"You are SELLING BTC for {{currencyCode}}",
"You are BUYING BTC for {{currencyCode}}":"You are BUYING BTC for {{currencyCode}}",
"You are looking at all":"You are looking at all",
"No orders found to sell BTC for {{currencyCode}}":"No orders found to sell BTC for {{currencyCode}}",
"No orders found to buy BTC for {{currencyCode}}":"No orders found to buy BTC for {{currencyCode}}",
"Be the first one to create an order":"Be the first one to create an order",
"BOTTOM BAR AND MISC - BottomBar.js":"Bottom Bar user profile and miscellaneous dialogs",
"Stats For Nerds":"Stats For Nerds",
"LND version":"LND version",
"Currently running commit hash":"Currently running commit hash",
"24h contracted volume":"24h contracted volume",
"Lifetime contracted volume":"Lifetime contracted volume",
"Made with":"Made with",
"and":"and",
"... somewhere on Earth!":"... somewhere on Earth!",
"Community":"Community",
"Support is only offered via public channels. Join our Telegram community if you have questions or want to hang out with other cool robots. Please, use our Github Issues if you find a bug or want to see new features!":"Support is only offered via public channels. Join our Telegram community if you have questions or want to hang out with other cool robots. Please, use our Github Issues if you find a bug or want to see new features!",
"Join the RoboSats group":"Join the RoboSats group",
"Telegram (English / Main)":"Telegram (English / Main)",
"RoboSats Telegram Communities":"RoboSats Telegram Communities",
"Join RoboSats Spanish speaking community!":"Join RoboSats Spanish speaking community!",
"Join RoboSats Russian speaking community!":"Join RoboSats Russian speaking community!",
"Join RoboSats Chinese speaking community!":"Join RoboSats Chinese speaking community!",
"Join RoboSats English speaking community!":"Join RoboSats English speaking community!",
"Tell us about a new feature or a bug":"Tell us about a new feature or a bug",
"Github Issues - The Robotic Satoshis Open Source Project":"Github Issues - The Robotic Satoshis Open Source Project",
"Your Profile":"Your Profile",
"Your robot":"Your robot",
"One active order #{{orderID}}":"One active order #{{orderID}}",
"Your current order":"Your current order",
"No active orders":"No active orders",
"Your token (will not remain here)":"Your token (will not remain here)",
"Back it up!":"Back it up!",
"Cannot remember":"Cannot remember",
"Rewards and compensations":"Rewards and compensations",
"Share to earn 100 Sats per trade":"Share to earn 100 Sats per trade",
"Your referral link":"Your referral link",
"Your earned rewards":"Your earned rewards",
"Claim":"Claim",
"Invoice for {{amountSats}} Sats":"Invoice for {{amountSats}} Sats",
"Submit":"Submit",
"There it goes, thank you!🥇":"There it goes, thank you!🥇",
"You have an active order":"You have an active order",
"You can claim satoshis!":"You can claim satoshis!",
"Public Buy Orders":"Public Buy Orders",
"Public Sell Orders":"Public Sell Orders",
"Today Active Robots":"Today Active Robots",
"24h Avg Premium":"24h Avg Premium",
"Trade Fee":"Trade Fee",
"Show community and support links":"Show community and support links",
"Show stats for nerds":"Show stats for nerds",
"Exchange Summary":"Exchange Summary",
"Public buy orders":"Public buy orders",
"Public sell orders":"Public sell orders",
"Book liquidity":"Book liquidity",
"Today active robots":"Today active robots",
"24h non-KYC bitcoin premium":"24h non-KYC bitcoin premium",
"Maker fee":"Maker fee",
"Taker fee":"Taker fee",
"Number of public BUY orders":"Number of public BUY orders",
"Number of public SELL orders":"Number of public SELL orders",
"ORDER PAGE - OrderPage.js": "Order details page",
"Order Box":"Order Box",
"Contract":"Contract",
"Active":"Active",
"Seen recently":"Seen recently",
"Inactive":"Inactive",
"(Seller)":"(Seller)",
"(Buyer)":"(Buyer)",
"Order maker":"Order maker",
"Order taker":"Order taker",
"Order Details":"Order Details",
"Order status":"Order status",
"Waiting for maker bond":"Waiting for maker bond",
"Public":"Public",
"Waiting for taker bond":"Waiting for taker bond",
"Cancelled":"Cancelled",
"Expired":"Expired",
"Waiting for trade collateral and buyer invoice":"Waiting for trade collateral and buyer invoice",
"Waiting only for seller trade collateral":"Waiting only for seller trade collateral",
"Waiting only for buyer invoice":"Waiting only for buyer invoice",
"Sending fiat - In chatroom":"Sending fiat - In chatroom",
"Fiat sent - In chatroom":"Fiat sent - In chatroom",
"In dispute":"In dispute",
"Collaboratively cancelled":"Collaboratively cancelled",
"Sending satoshis to buyer":"Sending satoshis to buyer",
"Sucessful trade":"Successful trade",
"Failed lightning network routing":"Failed lightning network routing",
"Wait for dispute resolution":"Wait for dispute resolution",
"Maker lost dispute":"Maker lost dispute",
"Taker lost dispute":"Taker lost dispute",
"Amount range":"Amount range",
"Swap destination":"Swap destination",
"Accepted payment methods":"Accepted payment methods",
"Others":"Others",
"{{price}} {{currencyCode}}/BTC - Premium: {{premium}}%":"{{price}} {{currencyCode}}/BTC - Premium: {{premium}}%",
"Price and Premium":"Price and Premium",
"Amount of Satoshis":"Amount of Satoshis",
"Premium over market price":"Premium over market price",
"Order ID":"Order ID",
"Expires in":"Expires in",
"{{nickname}} is asking for a collaborative cancel":"{{nickname}} is asking for a collaborative cancel",
"You asked for a collaborative cancellation":"You asked for a collaborative cancellation",
"Invoice expired. You did not confirm publishing the order in time. Make a new order.":"Invoice expired. You did not confirm publishing the order in time. Make a new order.",
"This order has been cancelled by the maker":"This order has been cancelled by the maker",
"Penalty lifted, good to go!":"Penalty lifted, good to go!",
"You cannot take an order yet! Wait {{timeMin}}m {{timeSec}}s":"You cannot take an order yet! Wait {{timeMin}}m {{timeSec}}s",
"Too low":"Too low",
"Too high":"Too high",
"Enter amount of fiat to exchange for bitcoin":"Enter amount of fiat to exchange for bitcoin",
"Amount {{currencyCode}}":"Amount {{currencyCode}}",
"You must specify an amount first":"You must specify an amount first",
"Take Order":"Take Order",
"Wait until you can take an order":"Wait until you can take an order",
"Cancel the order?":"Cancel the order?",
"If the order is cancelled now you will lose your bond.":"If the order is cancelled now you will lose your bond.",
"Confirm Cancel":"Confirm Cancel",
"The maker is away":"The maker is away",
"By taking this order you risk wasting your time. If the maker does not proceed in time, you will be compensated in satoshis for 50% of the maker bond.":"By taking this order you risk wasting your time. If the maker does not proceed in time, you will be compensated in satoshis for 50% of the maker bond.",
"Collaborative cancel the order?":"Collaborative cancel the order?",
"The trade escrow has been posted. The order can be cancelled only if both, maker and taker, agree to cancel.":"The trade escrow has been posted. The order can be cancelled only if both, maker and taker, agree to cancel.",
"Ask for Cancel":"Ask for Cancel",
"Cancel":"Cancel",
"Collaborative Cancel":"Collaborative Cancel",
"Invalid Order Id":"Invalid Order Id",
"You must have a robot avatar to see the order details":"You must have a robot avatar to see the order details",
"This order has been cancelled collaborativelly":"This order has been cancelled collaborativelly",
"You are not allowed to see this order":"You are not allowed to see this order",
"The Robotic Satoshis working in the warehouse did not understand you. Please, fill a Bug Issue in Github https://github.com/reckless-satoshi/robosats/issues":"The Robotic Satoshis working in the warehouse did not understand you. Please, fill a Bug Issue in Github https://github.com/reckless-satoshi/robosats/issues",
"CHAT BOX - Chat.js":"Chat Box",
"You":"You",
"Peer":"Peer",
"connected":"connected",
"disconnected":"disconnected",
"Type a message":"Type a message",
"Connecting...":"Connecting...",
"Send":"Send",
"The chat has no memory: if you leave, messages are lost.":"The chat has no memory: if you leave, messages are lost.",
"Learn easy PGP encryption.":"Learn easy PGP encryption.",
"CONTRACT BOX - TradeBox.js": "The Contract Box that guides users trough the whole trade pipeline",
"Contract Box":"Contract Box",
"Robots show commitment to their peers": "Robots show commitment to their peers",
"Lock {{amountSats}} Sats to PUBLISH order": "Lock {{amountSats}} Sats to PUBLISH order",
"Lock {{amountSats}} Sats to TAKE order": "Lock {{amountSats}} Sats to TAKE order",
"Lock {{amountSats}} Sats as collateral": "Lock {{amountSats}} Sats as collateral",
"Copy to clipboard":"Copy to clipboard",
"This is a hold invoice, it will freeze in your wallet. It will be charged only if you cancel or lose a dispute.":"This is a hold invoice, it will freeze in your wallet. It will be charged only if you cancel or lose a dispute.",
"This is a hold invoice, it will freeze in your wallet. It will be released to the buyer once you confirm to have received the {{currencyCode}}.":"This is a hold invoice, it will freeze in your wallet. It will be released to the buyer once you confirm to have received the {{currencyCode}}.",
"Your maker bond is locked":"Your maker bond is locked",
"Your taker bond is locked":"Your taker bond is locked",
"Your maker bond was settled":"Your maker bond was settled",
"Your taker bond was settled":"Your taker bond was settled",
"Your maker bond was unlock":"Your maker bond was unlock",
"Your taker bond was unlocked":"Your taker bond was unlocked",
"Your order is public":"Your order is public",
"Be patient while robots check the book. It might take some time. This box will ring 🔊 once a robot takes your order.":"Be patient while robots check the book. It might take some time. This box will ring 🔊 once a robot takes your order.",
"Please note that if your premium is excessive or your currency or payment methods are not popular, your order might expire untaken. Your bond will return to you (no action needed).":"Please note that if your premium is excessive or your currency or payment methods are not popular, your order might expire untaken. Your bond will return to you (no action needed).",
"Enable Telegram Notifications":"Enable Telegram Notifications",
"Enable TG Notifications":"Enable TG Notifications",
"You will be taken to a conversation with RoboSats telegram bot. Simply open the chat and press Start. Note that by enabling telegram notifications you might lower your level of anonymity.":"You will be taken to a conversation with RoboSats telegram bot. Simply open the chat and press Start. Note that by enabling telegram notifications you might lower your level of anonymity.",
"Go back":"Go back",
"Enable":"Enable",
"Telegram enabled":"Telegram enabled",
"Public orders for {{currencyCode}}":"Public orders for {{currencyCode}}",
"Premium rank": "Premium rank",
"Among public {{currencyCode}} orders (higher is cheaper)": "Among public {{currencyCode}} orders (higher is cheaper)",
"A taker has been found!":"A taker has been found!",
"Please wait for the taker to lock a bond. If the taker does not lock a bond in time, the order will be made public again.":"Please wait for the taker to lock a bond. If the taker does not lock a bond in time, the order will be made public again.",
"Submit an invoice for {{amountSats}} Sats":"Submit an invoice for {{amountSats}} Sats",
"The taker is committed! Before letting you send {{amountFiat}} {{currencyCode}}, we want to make sure you are able to receive the BTC. Please provide a valid invoice for {{amountSats}} Satoshis.":"The taker is committed! Before letting you send {{amountFiat}} {{currencyCode}}, we want to make sure you are able to receive the BTC. Please provide a valid invoice for {{amountSats}} Satoshis.",
"Payout Lightning Invoice":"Payout Lightning Invoice",
"Your invoice looks good!":"Your invoice looks good!",
"We are waiting for the seller lock the trade amount.":"We are waiting for the seller lock the trade amount.",
"Just hang on for a moment. If the seller does not deposit, you will get your bond back automatically. In addition, you will receive a compensation (check the rewards in your profile).":"Just hang on for a moment. If the seller does not deposit, you will get your bond back automatically. In addition, you will receive a compensation (check the rewards in your profile).",
"The trade collateral is locked!":"The trade collateral is locked!",
"We are waiting for the buyer to post a lightning invoice. Once he does, you will be able to directly communicate the fiat payment details.":"We are waiting for the buyer to post a lightning invoice. Once he does, you will be able to directly communicate the fiat payment details.",
"Just hang on for a moment. If the buyer does not cooperate, you will get back the trade collateral and your bond automatically. In addition, you will receive a compensation (check the rewards in your profile).":"Just hang on for a moment. If the buyer does not cooperate, you will get back the trade collateral and your bond automatically. In addition, you will receive a compensation (check the rewards in your profile).",
"Confirm {{currencyCode}} sent":"Confirm {{currencyCode}} sent",
"Confirm {{currencyCode}} received":"Confirm {{currencyCode}} received",
"Open Dispute":"Open Dispute",
"The order has expired":"The order has expired",
"Chat with the buyer":"Chat with the buyer",
"Chat with the seller":"Chat with the seller",
"Say hi! Be helpful and concise. Let them know how to send you {{currencyCode}}.":"Say hi! Be helpful and concise. Let them know how to send you {{currencyCode}}.",
"The buyer has sent the fiat. Click 'Confirm Received' once you receive it.":"The buyer has sent the fiat. Click 'Confirm Received' once you receive it.",
"Say hi! Ask for payment details and click 'Confirm Sent' as soon as the payment is sent.":"Say hi! Ask for payment details and click 'Confirm Sent' as soon as the payment is sent.",
"Wait for the seller to confirm he has received the payment.":"Wait for the seller to confirm he has received the payment.",
"Confirm you received {{currencyCode}}?":"Confirm you received {{currencyCode}}?",
"Confirming that you received the fiat will finalize the trade. The satoshis in the escrow will be released to the buyer. Only confirm after the {{currencyCode}} has arrived to your account. In addition, if you have received {{currencyCode}} and do not confirm the receipt, you risk losing your bond.":"Confirming that you received the fiat will finalize the trade. The satoshis in the escrow will be released to the buyer. Only confirm after the {{currencyCode}} has arrived to your account. In addition, if you have received {{currencyCode}} and do not confirm the receipt, you risk losing your bond.",
"Confirm":"Confirm",
"🎉Trade finished!🥳":"🎉Trade finished!🥳",
"rate_robosats":"What do you think of 🤖<1>RoboSats</1>⚡?",
"Thank you! RoboSats loves you too ❤️":"Thank you! RoboSats loves you too ❤️",
"RoboSats gets better with more liquidity and users. Tell a bitcoiner friend about Robosats!":"RoboSats gets better with more liquidity and users. Tell a bitcoiner friend about Robosats!",
"Thank you for using Robosats!":"Thank you for using Robosats!",
"let_us_know_hot_to_improve":"Let us know how the platform could improve (<1>Telegram</1> / <3>Github</3>)",
"Start Again":"Start Again",
"Attempting Lightning Payment":"Attempting Lightning Payment",
"RoboSats is trying to pay your lightning invoice. Remember that lightning nodes must be online in order to receive payments.":"RoboSats is trying to pay your lightning invoice. Remember that lightning nodes must be online in order to receive payments.",
"Retrying!":"Retrying!",
"Lightning Routing Failed":"Lightning Routing Failed",
"Your invoice has expired or more than 3 payment attempts have been made. Muun wallet is not recommended. ":"Your invoice has expired or more than 3 payment attempts have been made. Muun wallet is not recommended. ",
"Check the list of compatible wallets":"Check the list of compatible wallets",
"RoboSats will try to pay your invoice 3 times every 5 minutes. If it keeps failing, you will be able to submit a new invoice. Check whether you have enough inbound liquidity. Remember that lightning nodes must be online in order to receive payments.":"RoboSats will try to pay your invoice 3 times every 5 minutes. If it keeps failing, you will be able to submit a new invoice. Check whether you have enough inbound liquidity. Remember that lightning nodes must be online in order to receive payments.",
"Next attempt in":"Next attempt in",
"Do you want to open a dispute?":"Do you want to open a dispute?",
"The RoboSats staff will examine the statements and evidence provided. You need to build a complete case, as the staff cannot read the chat. It is best to provide a burner contact method with your statement. The satoshis in the trade escrow will be sent to the dispute winner, while the dispute loser will lose the bond.":"The RoboSats staff will examine the statements and evidence provided. You need to build a complete case, as the staff cannot read the chat. It is best to provide a burner contact method with your statement. The satoshis in the trade escrow will be sent to the dispute winner, while the dispute loser will lose the bond.",
"Disagree":"Disagree",
"Agree and open dispute":"Agree and open dispute",
"A dispute has been opened":"A dispute has been opened",
"Please, submit your statement. Be clear and specific about what happened and provide the necessary evidence. You MUST provide a contact method: burner email, XMPP or telegram username to follow up with the staff. Disputes are solved at the discretion of real robots (aka humans), so be as helpful as possible to ensure a fair outcome. Max 5000 chars.":"Please, submit your statement. Be clear and specific about what happened and provide the necessary evidence. You MUST provide a contact method: burner email, XMPP or telegram username to follow up with the staff. Disputes are solved at the discretion of real robots (aka humans), so be as helpful as possible to ensure a fair outcome. Max 5000 chars.",
"Submit dispute statement":"Submit dispute statement",
"We have received your statement":"We have received your statement",
"We are waiting for your trade counterpart statement. If you are hesitant about the state of the dispute or want to add more information, contact robosats@protonmail.com.":"We are waiting for your trade counterpart statement. If you are hesitant about the state of the dispute or want to add more information, contact robosats@protonmail.com.",
"Please, save the information needed to identify your order and your payments: order ID; payment hashes of the bonds or escrow (check on your lightning wallet); exact amount of satoshis; and robot nickname. You will have to identify yourself as the user involved in this trade via email (or other contact methods).":"Please, save the information needed to identify your order and your payments: order ID; payment hashes of the bonds or escrow (check on your lightning wallet); exact amount of satoshis; and robot nickname. You will have to identify yourself as the user involved in this trade via email (or other contact methods).",
"We have the statements":"We have the statements",
"Both statements have been received, wait for the staff to resolve the dispute. If you are hesitant about the state of the dispute or want to add more information, contact robosats@protonmail.com. If you did not provide a contact method, or are unsure whether you wrote it right, write us immediately.":"Both statements have been received, wait for the staff to resolve the dispute. If you are hesitant about the state of the dispute or want to add more information, contact robosats@protonmail.com. If you did not provide a contact method, or are unsure whether you wrote it right, write us immediately.",
"You have won the dispute":"You have won the dispute",
"You can claim the dispute resolution amount (escrow and fidelity bond) from your profile rewards. If there is anything the staff can help with, do not hesitate to contact to robosats@protonmail.com (or via your provided burner contact method).":"You can claim the dispute resolution amount (escrow and fidelity bond) from your profile rewards. If there is anything the staff can help with, do not hesitate to contact to robosats@protonmail.com (or via your provided burner contact method).",
"You have lost the dispute":"You have lost the dispute",
"Unfortunately you have lost the dispute. If you think this is a mistake you can ask to re-open the case via email to robosats@protonmail.com. However, chances of it being investigated again are low.":"Unfortunately you have lost the dispute. If you think this is a mistake you can ask to re-open the case via email to robosats@protonmail.com. However, chances of it being investigated again are low.",
"INFO DIALOG - InfoDiagog.js":"App information and clarifications and terms of use",
"Close":"Close",
"What is RoboSats?":"What is RoboSats?",
"It is a BTC/FIAT peer-to-peer exchange over lightning.":"It is a BTC/FIAT peer-to-peer exchange over lightning.",
"RoboSats is an open source project ":"RoboSats is an open source project ",
"It simplifies matchmaking and minimizes the need of trust. RoboSats focuses in privacy and speed.":"It simplifies matchmaking and minimizes the need of trust. RoboSats focuses in privacy and speed.",
"(GitHub).":"(GitHub).",
"How does it work?":"How does it work?",
"AnonymousAlice01 wants to sell bitcoin. She posts a sell order. BafflingBob02 wants to buy bitcoin and he takes Alice's order. Both have to post a small bond using lightning to prove they are real robots. Then, Alice posts the trade collateral also using a lightning hold invoice. RoboSats locks the invoice until Alice confirms she received the fiat, then the satoshis are released to Bob. Enjoy your satoshis, Bob!":"AnonymousAlice01 wants to sell bitcoin. She posts a sell order. BafflingBob02 wants to buy bitcoin and he takes Alice's order. Both have to post a small bond using lightning to prove they are real robots. Then, Alice posts the trade collateral also using a lightning hold invoice. RoboSats locks the invoice until Alice confirms she received the fiat, then the satoshis are released to Bob. Enjoy your satoshis, Bob!",
"At no point, AnonymousAlice01 and BafflingBob02 have to entrust the bitcoin funds to each other. In case they have a conflict, RoboSats staff will help resolving the dispute.":"At no point, AnonymousAlice01 and BafflingBob02 have to entrust the bitcoin funds to each other. In case they have a conflict, RoboSats staff will help resolving the dispute.",
"You can find a step-by-step description of the trade pipeline in ":"You can find a step-by-step description of the trade pipeline in ",
"How it works":"How it works",
"You can also check the full guide in ":"You can also check the full guide in ",
"How to use":"How to use",
"What payment methods are accepted?":"What payment methods are accepted?",
"All of them as long as they are fast. You can write down your preferred payment method(s). You will have to match with a peer who also accepts that method. The step to exchange fiat has a expiry time of 24 hours before a dispute is automatically open. We highly recommend using instant fiat payment rails.":"All of them as long as they are fast. You can write down your preferred payment method(s). You will have to match with a peer who also accepts that method. The step to exchange fiat has a expiry time of 24 hours before a dispute is automatically open. We highly recommend using instant fiat payment rails.",
"Are there trade limits?":"Are there trade limits?",
"Maximum single trade size is {{maxAmount}} Satoshis to minimize lightning routing failure. There is no limits to the number of trades per day. A robot can only have one order at a time. However, you can use multiple robots simultaneously in different browsers (remember to back up your robot tokens!).":"Maximum single trade size is {{maxAmount}} Satoshis to minimize lightning routing failure. There is no limits to the number of trades per day. A robot can only have one order at a time. However, you can use multiple robots simultaneously in different browsers (remember to back up your robot tokens!).",
"Is RoboSats private?":"Is RoboSats private?",
"RoboSats will never ask you for your name, country or ID. RoboSats does not custody your funds and does not care who you are. RoboSats does not collect or custody any personal data. For best anonymity use Tor Browser and access the .onion hidden service.":"RoboSats will never ask you for your name, country or ID. RoboSats does not custody your funds and does not care who you are. RoboSats does not collect or custody any personal data. For best anonymity use Tor Browser and access the .onion hidden service.",
"Your trading peer is the only one who can potentially guess anything about you. Keep your chat short and concise. Avoid providing non-essential information other than strictly necessary for the fiat payment.":"Your trading peer is the only one who can potentially guess anything about you. Keep your chat short and concise. Avoid providing non-essential information other than strictly necessary for the fiat payment.",
"What are the risks?":"What are the risks?",
"This is an experimental application, things could go wrong. Trade small amounts!":"This is an experimental application, things could go wrong. Trade small amounts!",
"The seller faces the same charge-back risk as with any other peer-to-peer service. Paypal or credit cards are not recommended.":"The seller faces the same charge-back risk as with any other peer-to-peer service. Paypal or credit cards are not recommended.",
"What is the trust model?":"What is the trust model?",
"The buyer and the seller never have to trust each other. Some trust on RoboSats is needed since linking the seller's hold invoice and buyer payment is not atomic (yet). In addition, disputes are solved by the RoboSats staff.":"The buyer and the seller never have to trust each other. Some trust on RoboSats is needed since linking the seller's hold invoice and buyer payment is not atomic (yet). In addition, disputes are solved by the RoboSats staff.",
"To be totally clear. Trust requirements are minimized. However, there is still one way RoboSats could run away with your satoshis: by not releasing the satoshis to the buyer. It could be argued that such move is not in RoboSats' interest as it would damage the reputation for a small payout. However, you should hesitate and only trade small quantities at a time. For large amounts use an onchain escrow service such as Bisq":"To be totally clear. Trust requirements are minimized. However, there is still one way RoboSats could run away with your satoshis: by not releasing the satoshis to the buyer. It could be argued that such move is not in RoboSats' interest as it would damage the reputation for a small payout. However, you should hesitate and only trade small quantities at a time. For large amounts use an onchain escrow service such as Bisq",
"You can build more trust on RoboSats by inspecting the source code.":"You can build more trust on RoboSats by inspecting the source code.",
"Project source code":"Project source code",
"What happens if RoboSats suddenly disappears?":"What happens if RoboSats suddenly disappears?",
"Your sats will return to you. Any hold invoice that is not settled would be automatically returned even if RoboSats goes down forever. This is true for both, locked bonds and trading escrows. However, there is a small window between the seller confirms FIAT RECEIVED and the moment the buyer receives the satoshis when the funds could be permanently lost if RoboSats disappears. This window is about 1 second long. Make sure to have enough inbound liquidity to avoid routing failures. If you have any problem, reach out trough the RoboSats public channels.":"Your sats will return to you. Any hold invoice that is not settled would be automatically returned even if RoboSats goes down forever. This is true for both, locked bonds and trading escrows. However, there is a small window between the seller confirms FIAT RECEIVED and the moment the buyer receives the satoshis when the funds could be permanently lost if RoboSats disappears. This window is about 1 second long. Make sure to have enough inbound liquidity to avoid routing failures. If you have any problem, reach out trough the RoboSats public channels.",
"In many countries using RoboSats is no different than using Ebay or Craiglist. Your regulation may vary. It is your responsibility to comply.":"In many countries using RoboSats is no different than using Ebay or Craiglist. Your regulation may vary. It is your responsibility to comply.",
"Is RoboSats legal in my country?":"Is RoboSats legal in my country?",
"Disclaimer":"Disclaimer",
"This lightning application is provided as is. It is in active development: trade with the utmost caution. There is no private support. Support is only offered via public channels ":"This lightning application is provided as is. It is in active development: trade with the utmost caution. There is no private support. Support is only offered via public channels ",
"(Telegram)":"(Telegram)",
". RoboSats will never contact you. RoboSats will definitely never ask for your robot token.":". RoboSats will never contact you. RoboSats will definitely never ask for your robot token."
}

View File

@ -0,0 +1,354 @@
{
"UNSAFE ALERT - UnsafeAlert.js": "Alert that shows on top when browsing from the unsafe clearnet sites",
"You are not using RoboSats privately": "You are not using RoboSats privately",
"desktop_unsafe_alert": "Some features are disabled for your protection (e.g. chat) and you will not be able to complete a trade without them. To protect your privacy and fully enable RoboSats, use <1>Tor Browser</1> and visit the <3>Onion</3> site.",
"phone_unsafe_alert": "You will not be able to complete a trade. Use <1>Tor Browser</1> and visit the <3>Onion</3> site.",
"Hide":"Hide",
"USER GENERATION PAGE - UserGenPage.js": "Landing Page and User Generation",
"Simple and Private LN P2P Exchange": "Simple and Private LN P2P Exchange",
"This is your trading avatar":"This is your trading avatar",
"Store your token safely":"Store your token safely",
"A robot avatar was found, welcome back!":"A robot avatar was found, welcome back!",
"Copied!":"Copied!",
"Generate a new token":"Generate a new token",
"Generate Robot":"Generate Robot",
"You must enter a new token first":"You must enter a new token first",
"Make Order":"Make Order",
"Info":"Info",
"View Book":"View Book",
"MAKER PAGE - MakerPage.js": "This is the page where users can create new orders",
"Order":"Order",
"Customize":"Customize",
"Buy or Sell Bitcoin?":"Buy or Sell Bitcoin?",
"Buy":"Buy",
"Sell":"Sell",
"Amount":"Amount",
"Amount of fiat to exchange for bitcoin":"Amount of fiat to exchange for bitcoin",
"Invalid":"Invalid",
"Enter your preferred fiat payment methods. Fast methods are highly recommended.":"Enter your preferred fiat payment methods. Fast methods are highly recommended.",
"Must be shorter than 65 characters":"Must be shorter than 65 characters",
"Swap Destination(s)":"Swap Destination(s)",
"Fiat Payment Method(s)":"Fiat Payment Method(s)",
"You can add any method":"You can add any method",
"Add New":"Add New",
"Choose a Pricing Method":"Choose a Pricing Method",
"Relative":"Relative",
"Let the price move with the market":"Let the price move with the market",
"Premium over Market (%)":"Premium over Market (%)",
"Explicit":"Explicit",
"Set a fix amount of satoshis":"Set a fix amount of satoshis",
"Satoshis":"Satoshis",
"Let the taker chose an amount within the range":"Let the taker chose an amount within the range",
"Enable Amount Range":"Enable Amount Range",
"From": "From",
"to":"to",
"Public Duration (HH:mm)":"Public Duration (HH:mm)",
"Set the skin-in-the-game, increase for higher safety assurance":"Set the skin-in-the-game, increase for higher safety assurance",
"Fidelity Bond Size":"Fidelity Bond Size",
"Allow bondless takers":"Allow bondless takers",
"COMING SOON - High risk! Limited to {{limitSats}}K Sats":"COMING SOON - High risk! Limited to {{limitSats}}K Sats",
"You must fill the order correctly":"You must fill the order correctly",
"Create Order":"Create Order",
"Back":"Back",
"Create a BTC buy order for ":"Create a BTC buy order for ",
"Create a BTC sell order for ":"Create a BTC sell order for ",
" of {{satoshis}} Satoshis":" of {{satoshis}} Satoshis",
" at market price":" at market price",
" at a {{premium}}% premium":" at a {{premium}}% premium",
" at a {{discount}}% discount":" at a {{discount}}% discount",
"Must be less than {{max}}%":"Must be less than {{max}}%",
"Must be more than {{min}}%":"Must be more than {{min}}%",
"Must be less than {{maxSats}": "Must be less than {{maxSats}}",
"Must be more than {{minSats}}": "Must be more than {{minSats}}",
"BOOK PAGE - BookPage.js":"The Book Order page",
"Seller":"Seller",
"Buyer":"Buyer",
"I want to":"I want to",
"Select Order Type":"Select Order Type",
"ANY_type":"ANY",
"ANY_currency":"ANY",
"BUY":"BUY",
"SELL":"SELL",
"and receive":"and receive",
"and pay with":"and pay with",
"and use":"and use",
"Select Payment Currency":"Select Payment Currency",
"Robot":"Robot",
"Is":"Is",
"Currency":"Currency",
"Payment Method":"Payment Method",
"Pay":"Pay",
"Price":"Price",
"Premium":"Premium",
"You are SELLING BTC for {{currencyCode}}":"You are SELLING BTC for {{currencyCode}}",
"You are BUYING BTC for {{currencyCode}}":"You are BUYING BTC for {{currencyCode}}",
"You are looking at all":"You are looking at all",
"No orders found to sell BTC for {{currencyCode}}":"No orders found to sell BTC for {{currencyCode}}",
"No orders found to buy BTC for {{currencyCode}}":"No orders found to buy BTC for {{currencyCode}}",
"Be the first one to create an order":"Be the first one to create an order",
"BOTTOM BAR AND MISC - BottomBar.js":"Bottom Bar user profile and miscellaneous dialogs",
"Stats For Nerds":"Stats For Nerds",
"LND version":"LND version",
"Currently running commit hash":"Currently running commit hash",
"24h contracted volume":"24h contracted volume",
"Lifetime contracted volume":"Lifetime contracted volume",
"Made with":"Made with",
"and":"and",
"... somewhere on Earth!":"... somewhere on Earth!",
"Community":"Community",
"Support is only offered via public channels. Join our Telegram community if you have questions or want to hang out with other cool robots. Please, use our Github Issues if you find a bug or want to see new features!":"Support is only offered via public channels. Join our Telegram community if you have questions or want to hang out with other cool robots. Please, use our Github Issues if you find a bug or want to see new features!",
"Join the RoboSats group":"Join the RoboSats group",
"Telegram (English / Main)":"Telegram (English / Main)",
"RoboSats Telegram Communities":"RoboSats Telegram Communities",
"Join RoboSats Spanish speaking community!":"Join RoboSats Spanish speaking community!",
"Join RoboSats Russian speaking community!":"Join RoboSats Russian speaking community!",
"Join RoboSats Chinese speaking community!":"Join RoboSats Chinese speaking community!",
"Join RoboSats English speaking community!":"Join RoboSats English speaking community!",
"Tell us about a new feature or a bug":"Tell us about a new feature or a bug",
"Github Issues - The Robotic Satoshis Open Source Project":"Github Issues - The Robotic Satoshis Open Source Project",
"Your Profile":"Your Profile",
"Your robot":"Your robot",
"One active order #{{orderID}}":"One active order #{{orderID}}",
"Your current order":"Your current order",
"No active orders":"No active orders",
"Your token (will not remain here)":"Your token (will not remain here)",
"Back it up!":"Back it up!",
"Cannot remember":"Cannot remember",
"Rewards and compensations":"Rewards and compensations",
"Share to earn 100 Sats per trade":"Share to earn 100 Sats per trade",
"Your referral link":"Your referral link",
"Your earned rewards":"Your earned rewards",
"Claim":"Claim",
"Invoice for {{amountSats}} Sats":"Invoice for {{amountSats}} Sats",
"Submit":"Submit",
"There it goes, thank you!🥇":"There it goes, thank you!🥇",
"You have an active order":"You have an active order",
"You can claim satoshis!":"You can claim satoshis!",
"Public Buy Orders":"Public Buy Orders",
"Public Sell Orders":"Public Sell Orders",
"Today Active Robots":"Today Active Robots",
"24h Avg Premium":"24h Avg Premium",
"Trade Fee":"Trade Fee",
"Show community and support links":"Show community and support links",
"Show stats for nerds":"Show stats for nerds",
"Exchange Summary":"Exchange Summary",
"Public buy orders":"Public buy orders",
"Public sell orders":"Public sell orders",
"Book liquidity":"Book liquidity",
"Today active robots":"Today active robots",
"24h non-KYC bitcoin premium":"24h non-KYC bitcoin premium",
"Maker fee":"Maker fee",
"Taker fee":"Taker fee",
"Number of public BUY orders":"Number of public BUY orders",
"Number of public SELL orders":"Number of public SELL orders",
"ORDER PAGE - OrderPage.js": "Order details page",
"Order Box":"Order Box",
"Contract":"Contract",
"Active":"Active",
"Seen recently":"Seen recently",
"Inactive":"Inactive",
"(Seller)":"(Seller)",
"(Buyer)":"(Buyer)",
"Order maker":"Order maker",
"Order taker":"Order taker",
"Order Details":"Order Details",
"Order status":"Order status",
"Waiting for maker bond":"Waiting for maker bond",
"Public":"Public",
"Waiting for taker bond":"Waiting for taker bond",
"Cancelled":"Cancelled",
"Expired":"Expired",
"Waiting for trade collateral and buyer invoice":"Waiting for trade collateral and buyer invoice",
"Waiting only for seller trade collateral":"Waiting only for seller trade collateral",
"Waiting only for buyer invoice":"Waiting only for buyer invoice",
"Sending fiat - In chatroom":"Sending fiat - In chatroom",
"Fiat sent - In chatroom":"Fiat sent - In chatroom",
"In dispute":"In dispute",
"Collaboratively cancelled":"Collaboratively cancelled",
"Sending satoshis to buyer":"Sending satoshis to buyer",
"Sucessful trade":"Successful trade",
"Failed lightning network routing":"Failed lightning network routing",
"Wait for dispute resolution":"Wait for dispute resolution",
"Maker lost dispute":"Maker lost dispute",
"Taker lost dispute":"Taker lost dispute",
"Amount range":"Amount range",
"Swap destination":"Swap destination",
"Accepted payment methods":"Accepted payment methods",
"Others":"Others",
"{{price}} {{currencyCode}}/BTC - Premium: {{premium}}%":"{{price}} {{currencyCode}}/BTC - Premium: {{premium}}%",
"Price and Premium":"Price and Premium",
"Amount of Satoshis":"Amount of Satoshis",
"Premium over market price":"Premium over market price",
"Order ID":"Order ID",
"Expires in":"Expires in",
"{{nickname}} is asking for a collaborative cancel":"{{nickname}} is asking for a collaborative cancel",
"You asked for a collaborative cancellation":"You asked for a collaborative cancellation",
"Invoice expired. You did not confirm publishing the order in time. Make a new order.":"Invoice expired. You did not confirm publishing the order in time. Make a new order.",
"This order has been cancelled by the maker":"This order has been cancelled by the maker",
"Penalty lifted, good to go!":"Penalty lifted, good to go!",
"You cannot take an order yet! Wait {{timeMin}}m {{timeSec}}s":"You cannot take an order yet! Wait {{timeMin}}m {{timeSec}}s",
"Too low":"Too low",
"Too high":"Too high",
"Enter amount of fiat to exchange for bitcoin":"Enter amount of fiat to exchange for bitcoin",
"Amount {{currencyCode}}":"Amount {{currencyCode}}",
"You must specify an amount first":"You must specify an amount first",
"Take Order":"Take Order",
"Wait until you can take an order":"Wait until you can take an order",
"Cancel the order?":"Cancel the order?",
"If the order is cancelled now you will lose your bond.":"If the order is cancelled now you will lose your bond.",
"Confirm Cancel":"Confirm Cancel",
"The maker is away":"The maker is away",
"By taking this order you risk wasting your time. If the maker does not proceed in time, you will be compensated in satoshis for 50% of the maker bond.":"By taking this order you risk wasting your time. If the maker does not proceed in time, you will be compensated in satoshis for 50% of the maker bond.",
"Collaborative cancel the order?":"Collaborative cancel the order?",
"The trade escrow has been posted. The order can be cancelled only if both, maker and taker, agree to cancel.":"The trade escrow has been posted. The order can be cancelled only if both, maker and taker, agree to cancel.",
"Ask for Cancel":"Ask for Cancel",
"Cancel":"Cancel",
"Collaborative Cancel":"Collaborative Cancel",
"Invalid Order Id":"Invalid Order Id",
"You must have a robot avatar to see the order details":"You must have a robot avatar to see the order details",
"This order has been cancelled collaborativelly":"This order has been cancelled collaborativelly",
"You are not allowed to see this order":"You are not allowed to see this order",
"The Robotic Satoshis working in the warehouse did not understand you. Please, fill a Bug Issue in Github https://github.com/reckless-satoshi/robosats/issues":"The Robotic Satoshis working in the warehouse did not understand you. Please, fill a Bug Issue in Github https://github.com/reckless-satoshi/robosats/issues",
"CHAT BOX - Chat.js":"Chat Box",
"You":"You",
"Peer":"Peer",
"connected":"connected",
"disconnected":"disconnected",
"Type a message":"Type a message",
"Connecting...":"Connecting...",
"Send":"Send",
"The chat has no memory: if you leave, messages are lost.":"The chat has no memory: if you leave, messages are lost.",
"Learn easy PGP encryption.":"Learn easy PGP encryption.",
"CONTRACT BOX - TradeBox.js": "The Contract Box that guides users trough the whole trade pipeline",
"Contract Box":"Contract Box",
"Robots show commitment to their peers": "Robots show commitment to their peers",
"Lock {{amountSats}} Sats to PUBLISH order": "Lock {{amountSats}} Sats to PUBLISH order",
"Lock {{amountSats}} Sats to TAKE order": "Lock {{amountSats}} Sats to TAKE order",
"Lock {{amountSats}} Sats as collateral": "Lock {{amountSats}} Sats as collateral",
"Copy to clipboard":"Copy to clipboard",
"This is a hold invoice, it will freeze in your wallet. It will be charged only if you cancel or lose a dispute.":"This is a hold invoice, it will freeze in your wallet. It will be charged only if you cancel or lose a dispute.",
"This is a hold invoice, it will freeze in your wallet. It will be released to the buyer once you confirm to have received the {{currencyCode}}.":"This is a hold invoice, it will freeze in your wallet. It will be released to the buyer once you confirm to have received the {{currencyCode}}.",
"Your maker bond is locked":"Your maker bond is locked",
"Your taker bond is locked":"Your taker bond is locked",
"Your maker bond was settled":"Your maker bond was settled",
"Your taker bond was settled":"Your taker bond was settled",
"Your maker bond was unlock":"Your maker bond was unlock",
"Your taker bond was unlocked":"Your taker bond was unlocked",
"Your order is public":"Your order is public",
"Be patient while robots check the book. It might take some time. This box will ring 🔊 once a robot takes your order.":"Be patient while robots check the book. It might take some time. This box will ring 🔊 once a robot takes your order.",
"Please note that if your premium is excessive or your currency or payment methods are not popular, your order might expire untaken. Your bond will return to you (no action needed).":"Please note that if your premium is excessive or your currency or payment methods are not popular, your order might expire untaken. Your bond will return to you (no action needed).",
"Enable Telegram Notifications":"Enable Telegram Notifications",
"Enable TG Notifications":"Enable TG Notifications",
"You will be taken to a conversation with RoboSats telegram bot. Simply open the chat and press Start. Note that by enabling telegram notifications you might lower your level of anonymity.":"You will be taken to a conversation with RoboSats telegram bot. Simply open the chat and press Start. Note that by enabling telegram notifications you might lower your level of anonymity.",
"Go back":"Go back",
"Enable":"Enable",
"Telegram enabled":"Telegram enabled",
"Public orders for {{currencyCode}}":"Public orders for {{currencyCode}}",
"Premium rank": "Premium rank",
"Among public {{currencyCode}} orders (higher is cheaper)": "Among public {{currencyCode}} orders (higher is cheaper)",
"A taker has been found!":"A taker has been found!",
"Please wait for the taker to lock a bond. If the taker does not lock a bond in time, the order will be made public again.":"Please wait for the taker to lock a bond. If the taker does not lock a bond in time, the order will be made public again.",
"Submit an invoice for {{amountSats}} Sats":"Submit an invoice for {{amountSats}} Sats",
"The taker is committed! Before letting you send {{amountFiat}} {{currencyCode}}, we want to make sure you are able to receive the BTC. Please provide a valid invoice for {{amountSats}} Satoshis.":"The taker is committed! Before letting you send {{amountFiat}} {{currencyCode}}, we want to make sure you are able to receive the BTC. Please provide a valid invoice for {{amountSats}} Satoshis.",
"Payout Lightning Invoice":"Payout Lightning Invoice",
"Your invoice looks good!":"Your invoice looks good!",
"We are waiting for the seller lock the trade amount.":"We are waiting for the seller lock the trade amount.",
"Just hang on for a moment. If the seller does not deposit, you will get your bond back automatically. In addition, you will receive a compensation (check the rewards in your profile).":"Just hang on for a moment. If the seller does not deposit, you will get your bond back automatically. In addition, you will receive a compensation (check the rewards in your profile).",
"The trade collateral is locked!":"The trade collateral is locked!",
"We are waiting for the buyer to post a lightning invoice. Once he does, you will be able to directly communicate the fiat payment details.":"We are waiting for the buyer to post a lightning invoice. Once he does, you will be able to directly communicate the fiat payment details.",
"Just hang on for a moment. If the buyer does not cooperate, you will get back the trade collateral and your bond automatically. In addition, you will receive a compensation (check the rewards in your profile).":"Just hang on for a moment. If the buyer does not cooperate, you will get back the trade collateral and your bond automatically. In addition, you will receive a compensation (check the rewards in your profile).",
"Confirm {{currencyCode}} sent":"Confirm {{currencyCode}} sent",
"Confirm {{currencyCode}} received":"Confirm {{currencyCode}} received",
"Open Dispute":"Open Dispute",
"The order has expired":"The order has expired",
"Chat with the buyer":"Chat with the buyer",
"Chat with the seller":"Chat with the seller",
"Say hi! Be helpful and concise. Let them know how to send you {{currencyCode}}.":"Say hi! Be helpful and concise. Let them know how to send you {{currencyCode}}.",
"The buyer has sent the fiat. Click 'Confirm Received' once you receive it.":"The buyer has sent the fiat. Click 'Confirm Received' once you receive it.",
"Say hi! Ask for payment details and click 'Confirm Sent' as soon as the payment is sent.":"Say hi! Ask for payment details and click 'Confirm Sent' as soon as the payment is sent.",
"Wait for the seller to confirm he has received the payment.":"Wait for the seller to confirm he has received the payment.",
"Confirm you received {{currencyCode}}?":"Confirm you received {{currencyCode}}?",
"Confirming that you received the fiat will finalize the trade. The satoshis in the escrow will be released to the buyer. Only confirm after the {{currencyCode}} has arrived to your account. In addition, if you have received {{currencyCode}} and do not confirm the receipt, you risk losing your bond.":"Confirming that you received the fiat will finalize the trade. The satoshis in the escrow will be released to the buyer. Only confirm after the {{currencyCode}} has arrived to your account. In addition, if you have received {{currencyCode}} and do not confirm the receipt, you risk losing your bond.",
"Confirm":"Confirm",
"🎉Trade finished!🥳":"🎉Trade finished!🥳",
"rate_robosats":"What do you think of 🤖<1>RoboSats</1>⚡?",
"Thank you! RoboSats loves you too ❤️":"Thank you! RoboSats loves you too ❤️",
"RoboSats gets better with more liquidity and users. Tell a bitcoiner friend about Robosats!":"RoboSats gets better with more liquidity and users. Tell a bitcoiner friend about Robosats!",
"Thank you for using Robosats!":"Thank you for using Robosats!",
"let_us_know_hot_to_improve":"Let us know how the platform could improve (<1>Telegram</1> / <3>Github</3>)",
"Start Again":"Start Again",
"Attempting Lightning Payment":"Attempting Lightning Payment",
"RoboSats is trying to pay your lightning invoice. Remember that lightning nodes must be online in order to receive payments.":"RoboSats is trying to pay your lightning invoice. Remember that lightning nodes must be online in order to receive payments.",
"Retrying!":"Retrying!",
"Lightning Routing Failed":"Lightning Routing Failed",
"Your invoice has expired or more than 3 payment attempts have been made. Muun wallet is not recommended. ":"Your invoice has expired or more than 3 payment attempts have been made. Muun wallet is not recommended. ",
"Check the list of compatible wallets":"Check the list of compatible wallets",
"RoboSats will try to pay your invoice 3 times every 5 minutes. If it keeps failing, you will be able to submit a new invoice. Check whether you have enough inbound liquidity. Remember that lightning nodes must be online in order to receive payments.":"RoboSats will try to pay your invoice 3 times every 5 minutes. If it keeps failing, you will be able to submit a new invoice. Check whether you have enough inbound liquidity. Remember that lightning nodes must be online in order to receive payments.",
"Next attempt in":"Next attempt in",
"Do you want to open a dispute?":"Do you want to open a dispute?",
"The RoboSats staff will examine the statements and evidence provided. You need to build a complete case, as the staff cannot read the chat. It is best to provide a burner contact method with your statement. The satoshis in the trade escrow will be sent to the dispute winner, while the dispute loser will lose the bond.":"The RoboSats staff will examine the statements and evidence provided. You need to build a complete case, as the staff cannot read the chat. It is best to provide a burner contact method with your statement. The satoshis in the trade escrow will be sent to the dispute winner, while the dispute loser will lose the bond.",
"Disagree":"Disagree",
"Agree and open dispute":"Agree and open dispute",
"A dispute has been opened":"A dispute has been opened",
"Please, submit your statement. Be clear and specific about what happened and provide the necessary evidence. You MUST provide a contact method: burner email, XMPP or telegram username to follow up with the staff. Disputes are solved at the discretion of real robots (aka humans), so be as helpful as possible to ensure a fair outcome. Max 5000 chars.":"Please, submit your statement. Be clear and specific about what happened and provide the necessary evidence. You MUST provide a contact method: burner email, XMPP or telegram username to follow up with the staff. Disputes are solved at the discretion of real robots (aka humans), so be as helpful as possible to ensure a fair outcome. Max 5000 chars.",
"Submit dispute statement":"Submit dispute statement",
"We have received your statement":"We have received your statement",
"We are waiting for your trade counterpart statement. If you are hesitant about the state of the dispute or want to add more information, contact robosats@protonmail.com.":"We are waiting for your trade counterpart statement. If you are hesitant about the state of the dispute or want to add more information, contact robosats@protonmail.com.",
"Please, save the information needed to identify your order and your payments: order ID; payment hashes of the bonds or escrow (check on your lightning wallet); exact amount of satoshis; and robot nickname. You will have to identify yourself as the user involved in this trade via email (or other contact methods).":"Please, save the information needed to identify your order and your payments: order ID; payment hashes of the bonds or escrow (check on your lightning wallet); exact amount of satoshis; and robot nickname. You will have to identify yourself as the user involved in this trade via email (or other contact methods).",
"We have the statements":"We have the statements",
"Both statements have been received, wait for the staff to resolve the dispute. If you are hesitant about the state of the dispute or want to add more information, contact robosats@protonmail.com. If you did not provide a contact method, or are unsure whether you wrote it right, write us immediately.":"Both statements have been received, wait for the staff to resolve the dispute. If you are hesitant about the state of the dispute or want to add more information, contact robosats@protonmail.com. If you did not provide a contact method, or are unsure whether you wrote it right, write us immediately.",
"You have won the dispute":"You have won the dispute",
"You can claim the dispute resolution amount (escrow and fidelity bond) from your profile rewards. If there is anything the staff can help with, do not hesitate to contact to robosats@protonmail.com (or via your provided burner contact method).":"You can claim the dispute resolution amount (escrow and fidelity bond) from your profile rewards. If there is anything the staff can help with, do not hesitate to contact to robosats@protonmail.com (or via your provided burner contact method).",
"You have lost the dispute":"You have lost the dispute",
"Unfortunately you have lost the dispute. If you think this is a mistake you can ask to re-open the case via email to robosats@protonmail.com. However, chances of it being investigated again are low.":"Unfortunately you have lost the dispute. If you think this is a mistake you can ask to re-open the case via email to robosats@protonmail.com. However, chances of it being investigated again are low.",
"INFO DIALOG - InfoDiagog.js":"App information and clarifications and terms of use",
"Close":"Close",
"What is RoboSats?":"What is RoboSats?",
"It is a BTC/FIAT peer-to-peer exchange over lightning.":"It is a BTC/FIAT peer-to-peer exchange over lightning.",
"RoboSats is an open source project ":"RoboSats is an open source project ",
"It simplifies matchmaking and minimizes the need of trust. RoboSats focuses in privacy and speed.":"It simplifies matchmaking and minimizes the need of trust. RoboSats focuses in privacy and speed.",
"(GitHub).":"(GitHub).",
"How does it work?":"How does it work?",
"AnonymousAlice01 wants to sell bitcoin. She posts a sell order. BafflingBob02 wants to buy bitcoin and he takes Alice's order. Both have to post a small bond using lightning to prove they are real robots. Then, Alice posts the trade collateral also using a lightning hold invoice. RoboSats locks the invoice until Alice confirms she received the fiat, then the satoshis are released to Bob. Enjoy your satoshis, Bob!":"AnonymousAlice01 wants to sell bitcoin. She posts a sell order. BafflingBob02 wants to buy bitcoin and he takes Alice's order. Both have to post a small bond using lightning to prove they are real robots. Then, Alice posts the trade collateral also using a lightning hold invoice. RoboSats locks the invoice until Alice confirms she received the fiat, then the satoshis are released to Bob. Enjoy your satoshis, Bob!",
"At no point, AnonymousAlice01 and BafflingBob02 have to entrust the bitcoin funds to each other. In case they have a conflict, RoboSats staff will help resolving the dispute.":"At no point, AnonymousAlice01 and BafflingBob02 have to entrust the bitcoin funds to each other. In case they have a conflict, RoboSats staff will help resolving the dispute.",
"You can find a step-by-step description of the trade pipeline in ":"You can find a step-by-step description of the trade pipeline in ",
"How it works":"How it works",
"You can also check the full guide in ":"You can also check the full guide in ",
"How to use":"How to use",
"What payment methods are accepted?":"What payment methods are accepted?",
"All of them as long as they are fast. You can write down your preferred payment method(s). You will have to match with a peer who also accepts that method. The step to exchange fiat has a expiry time of 24 hours before a dispute is automatically open. We highly recommend using instant fiat payment rails.":"All of them as long as they are fast. You can write down your preferred payment method(s). You will have to match with a peer who also accepts that method. The step to exchange fiat has a expiry time of 24 hours before a dispute is automatically open. We highly recommend using instant fiat payment rails.",
"Are there trade limits?":"Are there trade limits?",
"Maximum single trade size is {{maxAmount}} Satoshis to minimize lightning routing failure. There is no limits to the number of trades per day. A robot can only have one order at a time. However, you can use multiple robots simultaneously in different browsers (remember to back up your robot tokens!).":"Maximum single trade size is {{maxAmount}} Satoshis to minimize lightning routing failure. There is no limits to the number of trades per day. A robot can only have one order at a time. However, you can use multiple robots simultaneously in different browsers (remember to back up your robot tokens!).",
"Is RoboSats private?":"Is RoboSats private?",
"RoboSats will never ask you for your name, country or ID. RoboSats does not custody your funds and does not care who you are. RoboSats does not collect or custody any personal data. For best anonymity use Tor Browser and access the .onion hidden service.":"RoboSats will never ask you for your name, country or ID. RoboSats does not custody your funds and does not care who you are. RoboSats does not collect or custody any personal data. For best anonymity use Tor Browser and access the .onion hidden service.",
"Your trading peer is the only one who can potentially guess anything about you. Keep your chat short and concise. Avoid providing non-essential information other than strictly necessary for the fiat payment.":"Your trading peer is the only one who can potentially guess anything about you. Keep your chat short and concise. Avoid providing non-essential information other than strictly necessary for the fiat payment.",
"What are the risks?":"What are the risks?",
"This is an experimental application, things could go wrong. Trade small amounts!":"This is an experimental application, things could go wrong. Trade small amounts!",
"The seller faces the same charge-back risk as with any other peer-to-peer service. Paypal or credit cards are not recommended.":"The seller faces the same charge-back risk as with any other peer-to-peer service. Paypal or credit cards are not recommended.",
"What is the trust model?":"What is the trust model?",
"The buyer and the seller never have to trust each other. Some trust on RoboSats is needed since linking the seller's hold invoice and buyer payment is not atomic (yet). In addition, disputes are solved by the RoboSats staff.":"The buyer and the seller never have to trust each other. Some trust on RoboSats is needed since linking the seller's hold invoice and buyer payment is not atomic (yet). In addition, disputes are solved by the RoboSats staff.",
"To be totally clear. Trust requirements are minimized. However, there is still one way RoboSats could run away with your satoshis: by not releasing the satoshis to the buyer. It could be argued that such move is not in RoboSats' interest as it would damage the reputation for a small payout. However, you should hesitate and only trade small quantities at a time. For large amounts use an onchain escrow service such as Bisq":"To be totally clear. Trust requirements are minimized. However, there is still one way RoboSats could run away with your satoshis: by not releasing the satoshis to the buyer. It could be argued that such move is not in RoboSats' interest as it would damage the reputation for a small payout. However, you should hesitate and only trade small quantities at a time. For large amounts use an onchain escrow service such as Bisq",
"You can build more trust on RoboSats by inspecting the source code.":"You can build more trust on RoboSats by inspecting the source code.",
"Project source code":"Project source code",
"What happens if RoboSats suddenly disappears?":"What happens if RoboSats suddenly disappears?",
"Your sats will return to you. Any hold invoice that is not settled would be automatically returned even if RoboSats goes down forever. This is true for both, locked bonds and trading escrows. However, there is a small window between the seller confirms FIAT RECEIVED and the moment the buyer receives the satoshis when the funds could be permanently lost if RoboSats disappears. This window is about 1 second long. Make sure to have enough inbound liquidity to avoid routing failures. If you have any problem, reach out trough the RoboSats public channels.":"Your sats will return to you. Any hold invoice that is not settled would be automatically returned even if RoboSats goes down forever. This is true for both, locked bonds and trading escrows. However, there is a small window between the seller confirms FIAT RECEIVED and the moment the buyer receives the satoshis when the funds could be permanently lost if RoboSats disappears. This window is about 1 second long. Make sure to have enough inbound liquidity to avoid routing failures. If you have any problem, reach out trough the RoboSats public channels.",
"In many countries using RoboSats is no different than using Ebay or Craiglist. Your regulation may vary. It is your responsibility to comply.":"In many countries using RoboSats is no different than using Ebay or Craiglist. Your regulation may vary. It is your responsibility to comply.",
"Is RoboSats legal in my country?":"Is RoboSats legal in my country?",
"Disclaimer":"Disclaimer",
"This lightning application is provided as is. It is in active development: trade with the utmost caution. There is no private support. Support is only offered via public channels ":"This lightning application is provided as is. It is in active development: trade with the utmost caution. There is no private support. Support is only offered via public channels ",
"(Telegram)":"(Telegram)",
". RoboSats will never contact you. RoboSats will definitely never ask for your robot token.":". RoboSats will never contact you. RoboSats will definitely never ask for your robot token."
}

View File

@ -0,0 +1,354 @@
{
"UNSAFE ALERT - UnsafeAlert.js": "Alert that shows on top when browsing from the unsafe clearnet sites",
"You are not using RoboSats privately": "You are not using RoboSats privately",
"desktop_unsafe_alert": "Some features are disabled for your protection (e.g. chat) and you will not be able to complete a trade without them. To protect your privacy and fully enable RoboSats, use <1>Tor Browser</1> and visit the <3>Onion</3> site.",
"phone_unsafe_alert": "You will not be able to complete a trade. Use <1>Tor Browser</1> and visit the <3>Onion</3> site.",
"Hide":"Hide",
"USER GENERATION PAGE - UserGenPage.js": "Landing Page and User Generation",
"Simple and Private LN P2P Exchange": "Simple and Private LN P2P Exchange",
"This is your trading avatar":"This is your trading avatar",
"Store your token safely":"Store your token safely",
"A robot avatar was found, welcome back!":"A robot avatar was found, welcome back!",
"Copied!":"Copied!",
"Generate a new token":"Generate a new token",
"Generate Robot":"Generate Robot",
"You must enter a new token first":"You must enter a new token first",
"Make Order":"Make Order",
"Info":"Info",
"View Book":"View Book",
"MAKER PAGE - MakerPage.js": "This is the page where users can create new orders",
"Order":"Order",
"Customize":"Customize",
"Buy or Sell Bitcoin?":"Buy or Sell Bitcoin?",
"Buy":"Buy",
"Sell":"Sell",
"Amount":"Amount",
"Amount of fiat to exchange for bitcoin":"Amount of fiat to exchange for bitcoin",
"Invalid":"Invalid",
"Enter your preferred fiat payment methods. Fast methods are highly recommended.":"Enter your preferred fiat payment methods. Fast methods are highly recommended.",
"Must be shorter than 65 characters":"Must be shorter than 65 characters",
"Swap Destination(s)":"Swap Destination(s)",
"Fiat Payment Method(s)":"Fiat Payment Method(s)",
"You can add any method":"You can add any method",
"Add New":"Add New",
"Choose a Pricing Method":"Choose a Pricing Method",
"Relative":"Relative",
"Let the price move with the market":"Let the price move with the market",
"Premium over Market (%)":"Premium over Market (%)",
"Explicit":"Explicit",
"Set a fix amount of satoshis":"Set a fix amount of satoshis",
"Satoshis":"Satoshis",
"Let the taker chose an amount within the range":"Let the taker chose an amount within the range",
"Enable Amount Range":"Enable Amount Range",
"From": "From",
"to":"to",
"Public Duration (HH:mm)":"Public Duration (HH:mm)",
"Set the skin-in-the-game, increase for higher safety assurance":"Set the skin-in-the-game, increase for higher safety assurance",
"Fidelity Bond Size":"Fidelity Bond Size",
"Allow bondless takers":"Allow bondless takers",
"COMING SOON - High risk! Limited to {{limitSats}}K Sats":"COMING SOON - High risk! Limited to {{limitSats}}K Sats",
"You must fill the order correctly":"You must fill the order correctly",
"Create Order":"Create Order",
"Back":"Back",
"Create a BTC buy order for ":"Create a BTC buy order for ",
"Create a BTC sell order for ":"Create a BTC sell order for ",
" of {{satoshis}} Satoshis":" of {{satoshis}} Satoshis",
" at market price":" at market price",
" at a {{premium}}% premium":" at a {{premium}}% premium",
" at a {{discount}}% discount":" at a {{discount}}% discount",
"Must be less than {{max}}%":"Must be less than {{max}}%",
"Must be more than {{min}}%":"Must be more than {{min}}%",
"Must be less than {{maxSats}": "Must be less than {{maxSats}}",
"Must be more than {{minSats}}": "Must be more than {{minSats}}",
"BOOK PAGE - BookPage.js":"The Book Order page",
"Seller":"Seller",
"Buyer":"Buyer",
"I want to":"I want to",
"Select Order Type":"Select Order Type",
"ANY_type":"ANY",
"ANY_currency":"ANY",
"BUY":"BUY",
"SELL":"SELL",
"and receive":"and receive",
"and pay with":"and pay with",
"and use":"and use",
"Select Payment Currency":"Select Payment Currency",
"Robot":"Robot",
"Is":"Is",
"Currency":"Currency",
"Payment Method":"Payment Method",
"Pay":"Pay",
"Price":"Price",
"Premium":"Premium",
"You are SELLING BTC for {{currencyCode}}":"You are SELLING BTC for {{currencyCode}}",
"You are BUYING BTC for {{currencyCode}}":"You are BUYING BTC for {{currencyCode}}",
"You are looking at all":"You are looking at all",
"No orders found to sell BTC for {{currencyCode}}":"No orders found to sell BTC for {{currencyCode}}",
"No orders found to buy BTC for {{currencyCode}}":"No orders found to buy BTC for {{currencyCode}}",
"Be the first one to create an order":"Be the first one to create an order",
"BOTTOM BAR AND MISC - BottomBar.js":"Bottom Bar user profile and miscellaneous dialogs",
"Stats For Nerds":"Stats For Nerds",
"LND version":"LND version",
"Currently running commit hash":"Currently running commit hash",
"24h contracted volume":"24h contracted volume",
"Lifetime contracted volume":"Lifetime contracted volume",
"Made with":"Made with",
"and":"and",
"... somewhere on Earth!":"... somewhere on Earth!",
"Community":"Community",
"Support is only offered via public channels. Join our Telegram community if you have questions or want to hang out with other cool robots. Please, use our Github Issues if you find a bug or want to see new features!":"Support is only offered via public channels. Join our Telegram community if you have questions or want to hang out with other cool robots. Please, use our Github Issues if you find a bug or want to see new features!",
"Join the RoboSats group":"Join the RoboSats group",
"Telegram (English / Main)":"Telegram (English / Main)",
"RoboSats Telegram Communities":"RoboSats Telegram Communities",
"Join RoboSats Spanish speaking community!":"Join RoboSats Spanish speaking community!",
"Join RoboSats Russian speaking community!":"Join RoboSats Russian speaking community!",
"Join RoboSats Chinese speaking community!":"Join RoboSats Chinese speaking community!",
"Join RoboSats English speaking community!":"Join RoboSats English speaking community!",
"Tell us about a new feature or a bug":"Tell us about a new feature or a bug",
"Github Issues - The Robotic Satoshis Open Source Project":"Github Issues - The Robotic Satoshis Open Source Project",
"Your Profile":"Your Profile",
"Your robot":"Your robot",
"One active order #{{orderID}}":"One active order #{{orderID}}",
"Your current order":"Your current order",
"No active orders":"No active orders",
"Your token (will not remain here)":"Your token (will not remain here)",
"Back it up!":"Back it up!",
"Cannot remember":"Cannot remember",
"Rewards and compensations":"Rewards and compensations",
"Share to earn 100 Sats per trade":"Share to earn 100 Sats per trade",
"Your referral link":"Your referral link",
"Your earned rewards":"Your earned rewards",
"Claim":"Claim",
"Invoice for {{amountSats}} Sats":"Invoice for {{amountSats}} Sats",
"Submit":"Submit",
"There it goes, thank you!🥇":"There it goes, thank you!🥇",
"You have an active order":"You have an active order",
"You can claim satoshis!":"You can claim satoshis!",
"Public Buy Orders":"Public Buy Orders",
"Public Sell Orders":"Public Sell Orders",
"Today Active Robots":"Today Active Robots",
"24h Avg Premium":"24h Avg Premium",
"Trade Fee":"Trade Fee",
"Show community and support links":"Show community and support links",
"Show stats for nerds":"Show stats for nerds",
"Exchange Summary":"Exchange Summary",
"Public buy orders":"Public buy orders",
"Public sell orders":"Public sell orders",
"Book liquidity":"Book liquidity",
"Today active robots":"Today active robots",
"24h non-KYC bitcoin premium":"24h non-KYC bitcoin premium",
"Maker fee":"Maker fee",
"Taker fee":"Taker fee",
"Number of public BUY orders":"Number of public BUY orders",
"Number of public SELL orders":"Number of public SELL orders",
"ORDER PAGE - OrderPage.js": "Order details page",
"Order Box":"Order Box",
"Contract":"Contract",
"Active":"Active",
"Seen recently":"Seen recently",
"Inactive":"Inactive",
"(Seller)":"(Seller)",
"(Buyer)":"(Buyer)",
"Order maker":"Order maker",
"Order taker":"Order taker",
"Order Details":"Order Details",
"Order status":"Order status",
"Waiting for maker bond":"Waiting for maker bond",
"Public":"Public",
"Waiting for taker bond":"Waiting for taker bond",
"Cancelled":"Cancelled",
"Expired":"Expired",
"Waiting for trade collateral and buyer invoice":"Waiting for trade collateral and buyer invoice",
"Waiting only for seller trade collateral":"Waiting only for seller trade collateral",
"Waiting only for buyer invoice":"Waiting only for buyer invoice",
"Sending fiat - In chatroom":"Sending fiat - In chatroom",
"Fiat sent - In chatroom":"Fiat sent - In chatroom",
"In dispute":"In dispute",
"Collaboratively cancelled":"Collaboratively cancelled",
"Sending satoshis to buyer":"Sending satoshis to buyer",
"Sucessful trade":"Successful trade",
"Failed lightning network routing":"Failed lightning network routing",
"Wait for dispute resolution":"Wait for dispute resolution",
"Maker lost dispute":"Maker lost dispute",
"Taker lost dispute":"Taker lost dispute",
"Amount range":"Amount range",
"Swap destination":"Swap destination",
"Accepted payment methods":"Accepted payment methods",
"Others":"Others",
"{{price}} {{currencyCode}}/BTC - Premium: {{premium}}%":"{{price}} {{currencyCode}}/BTC - Premium: {{premium}}%",
"Price and Premium":"Price and Premium",
"Amount of Satoshis":"Amount of Satoshis",
"Premium over market price":"Premium over market price",
"Order ID":"Order ID",
"Expires in":"Expires in",
"{{nickname}} is asking for a collaborative cancel":"{{nickname}} is asking for a collaborative cancel",
"You asked for a collaborative cancellation":"You asked for a collaborative cancellation",
"Invoice expired. You did not confirm publishing the order in time. Make a new order.":"Invoice expired. You did not confirm publishing the order in time. Make a new order.",
"This order has been cancelled by the maker":"This order has been cancelled by the maker",
"Penalty lifted, good to go!":"Penalty lifted, good to go!",
"You cannot take an order yet! Wait {{timeMin}}m {{timeSec}}s":"You cannot take an order yet! Wait {{timeMin}}m {{timeSec}}s",
"Too low":"Too low",
"Too high":"Too high",
"Enter amount of fiat to exchange for bitcoin":"Enter amount of fiat to exchange for bitcoin",
"Amount {{currencyCode}}":"Amount {{currencyCode}}",
"You must specify an amount first":"You must specify an amount first",
"Take Order":"Take Order",
"Wait until you can take an order":"Wait until you can take an order",
"Cancel the order?":"Cancel the order?",
"If the order is cancelled now you will lose your bond.":"If the order is cancelled now you will lose your bond.",
"Confirm Cancel":"Confirm Cancel",
"The maker is away":"The maker is away",
"By taking this order you risk wasting your time. If the maker does not proceed in time, you will be compensated in satoshis for 50% of the maker bond.":"By taking this order you risk wasting your time. If the maker does not proceed in time, you will be compensated in satoshis for 50% of the maker bond.",
"Collaborative cancel the order?":"Collaborative cancel the order?",
"The trade escrow has been posted. The order can be cancelled only if both, maker and taker, agree to cancel.":"The trade escrow has been posted. The order can be cancelled only if both, maker and taker, agree to cancel.",
"Ask for Cancel":"Ask for Cancel",
"Cancel":"Cancel",
"Collaborative Cancel":"Collaborative Cancel",
"Invalid Order Id":"Invalid Order Id",
"You must have a robot avatar to see the order details":"You must have a robot avatar to see the order details",
"This order has been cancelled collaborativelly":"This order has been cancelled collaborativelly",
"You are not allowed to see this order":"You are not allowed to see this order",
"The Robotic Satoshis working in the warehouse did not understand you. Please, fill a Bug Issue in Github https://github.com/reckless-satoshi/robosats/issues":"The Robotic Satoshis working in the warehouse did not understand you. Please, fill a Bug Issue in Github https://github.com/reckless-satoshi/robosats/issues",
"CHAT BOX - Chat.js":"Chat Box",
"You":"You",
"Peer":"Peer",
"connected":"connected",
"disconnected":"disconnected",
"Type a message":"Type a message",
"Connecting...":"Connecting...",
"Send":"Send",
"The chat has no memory: if you leave, messages are lost.":"The chat has no memory: if you leave, messages are lost.",
"Learn easy PGP encryption.":"Learn easy PGP encryption.",
"CONTRACT BOX - TradeBox.js": "The Contract Box that guides users trough the whole trade pipeline",
"Contract Box":"Contract Box",
"Robots show commitment to their peers": "Robots show commitment to their peers",
"Lock {{amountSats}} Sats to PUBLISH order": "Lock {{amountSats}} Sats to PUBLISH order",
"Lock {{amountSats}} Sats to TAKE order": "Lock {{amountSats}} Sats to TAKE order",
"Lock {{amountSats}} Sats as collateral": "Lock {{amountSats}} Sats as collateral",
"Copy to clipboard":"Copy to clipboard",
"This is a hold invoice, it will freeze in your wallet. It will be charged only if you cancel or lose a dispute.":"This is a hold invoice, it will freeze in your wallet. It will be charged only if you cancel or lose a dispute.",
"This is a hold invoice, it will freeze in your wallet. It will be released to the buyer once you confirm to have received the {{currencyCode}}.":"This is a hold invoice, it will freeze in your wallet. It will be released to the buyer once you confirm to have received the {{currencyCode}}.",
"Your maker bond is locked":"Your maker bond is locked",
"Your taker bond is locked":"Your taker bond is locked",
"Your maker bond was settled":"Your maker bond was settled",
"Your taker bond was settled":"Your taker bond was settled",
"Your maker bond was unlock":"Your maker bond was unlock",
"Your taker bond was unlocked":"Your taker bond was unlocked",
"Your order is public":"Your order is public",
"Be patient while robots check the book. It might take some time. This box will ring 🔊 once a robot takes your order.":"Be patient while robots check the book. It might take some time. This box will ring 🔊 once a robot takes your order.",
"Please note that if your premium is excessive or your currency or payment methods are not popular, your order might expire untaken. Your bond will return to you (no action needed).":"Please note that if your premium is excessive or your currency or payment methods are not popular, your order might expire untaken. Your bond will return to you (no action needed).",
"Enable Telegram Notifications":"Enable Telegram Notifications",
"Enable TG Notifications":"Enable TG Notifications",
"You will be taken to a conversation with RoboSats telegram bot. Simply open the chat and press Start. Note that by enabling telegram notifications you might lower your level of anonymity.":"You will be taken to a conversation with RoboSats telegram bot. Simply open the chat and press Start. Note that by enabling telegram notifications you might lower your level of anonymity.",
"Go back":"Go back",
"Enable":"Enable",
"Telegram enabled":"Telegram enabled",
"Public orders for {{currencyCode}}":"Public orders for {{currencyCode}}",
"Premium rank": "Premium rank",
"Among public {{currencyCode}} orders (higher is cheaper)": "Among public {{currencyCode}} orders (higher is cheaper)",
"A taker has been found!":"A taker has been found!",
"Please wait for the taker to lock a bond. If the taker does not lock a bond in time, the order will be made public again.":"Please wait for the taker to lock a bond. If the taker does not lock a bond in time, the order will be made public again.",
"Submit an invoice for {{amountSats}} Sats":"Submit an invoice for {{amountSats}} Sats",
"The taker is committed! Before letting you send {{amountFiat}} {{currencyCode}}, we want to make sure you are able to receive the BTC. Please provide a valid invoice for {{amountSats}} Satoshis.":"The taker is committed! Before letting you send {{amountFiat}} {{currencyCode}}, we want to make sure you are able to receive the BTC. Please provide a valid invoice for {{amountSats}} Satoshis.",
"Payout Lightning Invoice":"Payout Lightning Invoice",
"Your invoice looks good!":"Your invoice looks good!",
"We are waiting for the seller lock the trade amount.":"We are waiting for the seller lock the trade amount.",
"Just hang on for a moment. If the seller does not deposit, you will get your bond back automatically. In addition, you will receive a compensation (check the rewards in your profile).":"Just hang on for a moment. If the seller does not deposit, you will get your bond back automatically. In addition, you will receive a compensation (check the rewards in your profile).",
"The trade collateral is locked!":"The trade collateral is locked!",
"We are waiting for the buyer to post a lightning invoice. Once he does, you will be able to directly communicate the fiat payment details.":"We are waiting for the buyer to post a lightning invoice. Once he does, you will be able to directly communicate the fiat payment details.",
"Just hang on for a moment. If the buyer does not cooperate, you will get back the trade collateral and your bond automatically. In addition, you will receive a compensation (check the rewards in your profile).":"Just hang on for a moment. If the buyer does not cooperate, you will get back the trade collateral and your bond automatically. In addition, you will receive a compensation (check the rewards in your profile).",
"Confirm {{currencyCode}} sent":"Confirm {{currencyCode}} sent",
"Confirm {{currencyCode}} received":"Confirm {{currencyCode}} received",
"Open Dispute":"Open Dispute",
"The order has expired":"The order has expired",
"Chat with the buyer":"Chat with the buyer",
"Chat with the seller":"Chat with the seller",
"Say hi! Be helpful and concise. Let them know how to send you {{currencyCode}}.":"Say hi! Be helpful and concise. Let them know how to send you {{currencyCode}}.",
"The buyer has sent the fiat. Click 'Confirm Received' once you receive it.":"The buyer has sent the fiat. Click 'Confirm Received' once you receive it.",
"Say hi! Ask for payment details and click 'Confirm Sent' as soon as the payment is sent.":"Say hi! Ask for payment details and click 'Confirm Sent' as soon as the payment is sent.",
"Wait for the seller to confirm he has received the payment.":"Wait for the seller to confirm he has received the payment.",
"Confirm you received {{currencyCode}}?":"Confirm you received {{currencyCode}}?",
"Confirming that you received the fiat will finalize the trade. The satoshis in the escrow will be released to the buyer. Only confirm after the {{currencyCode}} has arrived to your account. In addition, if you have received {{currencyCode}} and do not confirm the receipt, you risk losing your bond.":"Confirming that you received the fiat will finalize the trade. The satoshis in the escrow will be released to the buyer. Only confirm after the {{currencyCode}} has arrived to your account. In addition, if you have received {{currencyCode}} and do not confirm the receipt, you risk losing your bond.",
"Confirm":"Confirm",
"🎉Trade finished!🥳":"🎉Trade finished!🥳",
"rate_robosats":"What do you think of 🤖<1>RoboSats</1>⚡?",
"Thank you! RoboSats loves you too ❤️":"Thank you! RoboSats loves you too ❤️",
"RoboSats gets better with more liquidity and users. Tell a bitcoiner friend about Robosats!":"RoboSats gets better with more liquidity and users. Tell a bitcoiner friend about Robosats!",
"Thank you for using Robosats!":"Thank you for using Robosats!",
"let_us_know_hot_to_improve":"Let us know how the platform could improve (<1>Telegram</1> / <3>Github</3>)",
"Start Again":"Start Again",
"Attempting Lightning Payment":"Attempting Lightning Payment",
"RoboSats is trying to pay your lightning invoice. Remember that lightning nodes must be online in order to receive payments.":"RoboSats is trying to pay your lightning invoice. Remember that lightning nodes must be online in order to receive payments.",
"Retrying!":"Retrying!",
"Lightning Routing Failed":"Lightning Routing Failed",
"Your invoice has expired or more than 3 payment attempts have been made. Muun wallet is not recommended. ":"Your invoice has expired or more than 3 payment attempts have been made. Muun wallet is not recommended. ",
"Check the list of compatible wallets":"Check the list of compatible wallets",
"RoboSats will try to pay your invoice 3 times every 5 minutes. If it keeps failing, you will be able to submit a new invoice. Check whether you have enough inbound liquidity. Remember that lightning nodes must be online in order to receive payments.":"RoboSats will try to pay your invoice 3 times every 5 minutes. If it keeps failing, you will be able to submit a new invoice. Check whether you have enough inbound liquidity. Remember that lightning nodes must be online in order to receive payments.",
"Next attempt in":"Next attempt in",
"Do you want to open a dispute?":"Do you want to open a dispute?",
"The RoboSats staff will examine the statements and evidence provided. You need to build a complete case, as the staff cannot read the chat. It is best to provide a burner contact method with your statement. The satoshis in the trade escrow will be sent to the dispute winner, while the dispute loser will lose the bond.":"The RoboSats staff will examine the statements and evidence provided. You need to build a complete case, as the staff cannot read the chat. It is best to provide a burner contact method with your statement. The satoshis in the trade escrow will be sent to the dispute winner, while the dispute loser will lose the bond.",
"Disagree":"Disagree",
"Agree and open dispute":"Agree and open dispute",
"A dispute has been opened":"A dispute has been opened",
"Please, submit your statement. Be clear and specific about what happened and provide the necessary evidence. You MUST provide a contact method: burner email, XMPP or telegram username to follow up with the staff. Disputes are solved at the discretion of real robots (aka humans), so be as helpful as possible to ensure a fair outcome. Max 5000 chars.":"Please, submit your statement. Be clear and specific about what happened and provide the necessary evidence. You MUST provide a contact method: burner email, XMPP or telegram username to follow up with the staff. Disputes are solved at the discretion of real robots (aka humans), so be as helpful as possible to ensure a fair outcome. Max 5000 chars.",
"Submit dispute statement":"Submit dispute statement",
"We have received your statement":"We have received your statement",
"We are waiting for your trade counterpart statement. If you are hesitant about the state of the dispute or want to add more information, contact robosats@protonmail.com.":"We are waiting for your trade counterpart statement. If you are hesitant about the state of the dispute or want to add more information, contact robosats@protonmail.com.",
"Please, save the information needed to identify your order and your payments: order ID; payment hashes of the bonds or escrow (check on your lightning wallet); exact amount of satoshis; and robot nickname. You will have to identify yourself as the user involved in this trade via email (or other contact methods).":"Please, save the information needed to identify your order and your payments: order ID; payment hashes of the bonds or escrow (check on your lightning wallet); exact amount of satoshis; and robot nickname. You will have to identify yourself as the user involved in this trade via email (or other contact methods).",
"We have the statements":"We have the statements",
"Both statements have been received, wait for the staff to resolve the dispute. If you are hesitant about the state of the dispute or want to add more information, contact robosats@protonmail.com. If you did not provide a contact method, or are unsure whether you wrote it right, write us immediately.":"Both statements have been received, wait for the staff to resolve the dispute. If you are hesitant about the state of the dispute or want to add more information, contact robosats@protonmail.com. If you did not provide a contact method, or are unsure whether you wrote it right, write us immediately.",
"You have won the dispute":"You have won the dispute",
"You can claim the dispute resolution amount (escrow and fidelity bond) from your profile rewards. If there is anything the staff can help with, do not hesitate to contact to robosats@protonmail.com (or via your provided burner contact method).":"You can claim the dispute resolution amount (escrow and fidelity bond) from your profile rewards. If there is anything the staff can help with, do not hesitate to contact to robosats@protonmail.com (or via your provided burner contact method).",
"You have lost the dispute":"You have lost the dispute",
"Unfortunately you have lost the dispute. If you think this is a mistake you can ask to re-open the case via email to robosats@protonmail.com. However, chances of it being investigated again are low.":"Unfortunately you have lost the dispute. If you think this is a mistake you can ask to re-open the case via email to robosats@protonmail.com. However, chances of it being investigated again are low.",
"INFO DIALOG - InfoDiagog.js":"App information and clarifications and terms of use",
"Close":"Close",
"What is RoboSats?":"What is RoboSats?",
"It is a BTC/FIAT peer-to-peer exchange over lightning.":"It is a BTC/FIAT peer-to-peer exchange over lightning.",
"RoboSats is an open source project ":"RoboSats is an open source project ",
"It simplifies matchmaking and minimizes the need of trust. RoboSats focuses in privacy and speed.":"It simplifies matchmaking and minimizes the need of trust. RoboSats focuses in privacy and speed.",
"(GitHub).":"(GitHub).",
"How does it work?":"How does it work?",
"AnonymousAlice01 wants to sell bitcoin. She posts a sell order. BafflingBob02 wants to buy bitcoin and he takes Alice's order. Both have to post a small bond using lightning to prove they are real robots. Then, Alice posts the trade collateral also using a lightning hold invoice. RoboSats locks the invoice until Alice confirms she received the fiat, then the satoshis are released to Bob. Enjoy your satoshis, Bob!":"AnonymousAlice01 wants to sell bitcoin. She posts a sell order. BafflingBob02 wants to buy bitcoin and he takes Alice's order. Both have to post a small bond using lightning to prove they are real robots. Then, Alice posts the trade collateral also using a lightning hold invoice. RoboSats locks the invoice until Alice confirms she received the fiat, then the satoshis are released to Bob. Enjoy your satoshis, Bob!",
"At no point, AnonymousAlice01 and BafflingBob02 have to entrust the bitcoin funds to each other. In case they have a conflict, RoboSats staff will help resolving the dispute.":"At no point, AnonymousAlice01 and BafflingBob02 have to entrust the bitcoin funds to each other. In case they have a conflict, RoboSats staff will help resolving the dispute.",
"You can find a step-by-step description of the trade pipeline in ":"You can find a step-by-step description of the trade pipeline in ",
"How it works":"How it works",
"You can also check the full guide in ":"You can also check the full guide in ",
"How to use":"How to use",
"What payment methods are accepted?":"What payment methods are accepted?",
"All of them as long as they are fast. You can write down your preferred payment method(s). You will have to match with a peer who also accepts that method. The step to exchange fiat has a expiry time of 24 hours before a dispute is automatically open. We highly recommend using instant fiat payment rails.":"All of them as long as they are fast. You can write down your preferred payment method(s). You will have to match with a peer who also accepts that method. The step to exchange fiat has a expiry time of 24 hours before a dispute is automatically open. We highly recommend using instant fiat payment rails.",
"Are there trade limits?":"Are there trade limits?",
"Maximum single trade size is {{maxAmount}} Satoshis to minimize lightning routing failure. There is no limits to the number of trades per day. A robot can only have one order at a time. However, you can use multiple robots simultaneously in different browsers (remember to back up your robot tokens!).":"Maximum single trade size is {{maxAmount}} Satoshis to minimize lightning routing failure. There is no limits to the number of trades per day. A robot can only have one order at a time. However, you can use multiple robots simultaneously in different browsers (remember to back up your robot tokens!).",
"Is RoboSats private?":"Is RoboSats private?",
"RoboSats will never ask you for your name, country or ID. RoboSats does not custody your funds and does not care who you are. RoboSats does not collect or custody any personal data. For best anonymity use Tor Browser and access the .onion hidden service.":"RoboSats will never ask you for your name, country or ID. RoboSats does not custody your funds and does not care who you are. RoboSats does not collect or custody any personal data. For best anonymity use Tor Browser and access the .onion hidden service.",
"Your trading peer is the only one who can potentially guess anything about you. Keep your chat short and concise. Avoid providing non-essential information other than strictly necessary for the fiat payment.":"Your trading peer is the only one who can potentially guess anything about you. Keep your chat short and concise. Avoid providing non-essential information other than strictly necessary for the fiat payment.",
"What are the risks?":"What are the risks?",
"This is an experimental application, things could go wrong. Trade small amounts!":"This is an experimental application, things could go wrong. Trade small amounts!",
"The seller faces the same charge-back risk as with any other peer-to-peer service. Paypal or credit cards are not recommended.":"The seller faces the same charge-back risk as with any other peer-to-peer service. Paypal or credit cards are not recommended.",
"What is the trust model?":"What is the trust model?",
"The buyer and the seller never have to trust each other. Some trust on RoboSats is needed since linking the seller's hold invoice and buyer payment is not atomic (yet). In addition, disputes are solved by the RoboSats staff.":"The buyer and the seller never have to trust each other. Some trust on RoboSats is needed since linking the seller's hold invoice and buyer payment is not atomic (yet). In addition, disputes are solved by the RoboSats staff.",
"To be totally clear. Trust requirements are minimized. However, there is still one way RoboSats could run away with your satoshis: by not releasing the satoshis to the buyer. It could be argued that such move is not in RoboSats' interest as it would damage the reputation for a small payout. However, you should hesitate and only trade small quantities at a time. For large amounts use an onchain escrow service such as Bisq":"To be totally clear. Trust requirements are minimized. However, there is still one way RoboSats could run away with your satoshis: by not releasing the satoshis to the buyer. It could be argued that such move is not in RoboSats' interest as it would damage the reputation for a small payout. However, you should hesitate and only trade small quantities at a time. For large amounts use an onchain escrow service such as Bisq",
"You can build more trust on RoboSats by inspecting the source code.":"You can build more trust on RoboSats by inspecting the source code.",
"Project source code":"Project source code",
"What happens if RoboSats suddenly disappears?":"What happens if RoboSats suddenly disappears?",
"Your sats will return to you. Any hold invoice that is not settled would be automatically returned even if RoboSats goes down forever. This is true for both, locked bonds and trading escrows. However, there is a small window between the seller confirms FIAT RECEIVED and the moment the buyer receives the satoshis when the funds could be permanently lost if RoboSats disappears. This window is about 1 second long. Make sure to have enough inbound liquidity to avoid routing failures. If you have any problem, reach out trough the RoboSats public channels.":"Your sats will return to you. Any hold invoice that is not settled would be automatically returned even if RoboSats goes down forever. This is true for both, locked bonds and trading escrows. However, there is a small window between the seller confirms FIAT RECEIVED and the moment the buyer receives the satoshis when the funds could be permanently lost if RoboSats disappears. This window is about 1 second long. Make sure to have enough inbound liquidity to avoid routing failures. If you have any problem, reach out trough the RoboSats public channels.",
"In many countries using RoboSats is no different than using Ebay or Craiglist. Your regulation may vary. It is your responsibility to comply.":"In many countries using RoboSats is no different than using Ebay or Craiglist. Your regulation may vary. It is your responsibility to comply.",
"Is RoboSats legal in my country?":"Is RoboSats legal in my country?",
"Disclaimer":"Disclaimer",
"This lightning application is provided as is. It is in active development: trade with the utmost caution. There is no private support. Support is only offered via public channels ":"This lightning application is provided as is. It is in active development: trade with the utmost caution. There is no private support. Support is only offered via public channels ",
"(Telegram)":"(Telegram)",
". RoboSats will never contact you. RoboSats will definitely never ask for your robot token.":". RoboSats will never contact you. RoboSats will definitely never ask for your robot token."
}

File diff suppressed because one or more lines are too long

View File

@ -9,6 +9,8 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="A simple and private way to exchange bitcoin for national currencies. Robosats simplifies the peer-to-peer user experience and uses lightning hold invoices to minimize custody and trust requirements. No user registration required.">
<title>RoboSats - Simple and Private Bitcoin Exchange</title>
{% load static %}
<link rel="stylesheet" href="{% static "css/fonts.css" %}"/>