Author SHA1 Message Date
discountry 73d34434b0 fix size 2026-02-04 13:25:21 +08:00
discountry d0154e5721 fix den 2026-02-03 18:48:06 +08:00
discountry 52b6a8a076 Add invitation links for Nado registration in trading tutorial 2026-02-03 12:04:36 +08:00
discountry db6a9cfc68 Add Nado trading tutorial for ritmex-bot 2026-02-03 12:02:55 +08:00
DisneyandGitHub 03b8e53d30 Merge pull request #19 from discountry/feat/arb
Feat/arb
2026-02-01 11:15:42 +08:00
5 changed files with 648 additions and 41 deletions
+27 -29
View File
@@ -31,7 +31,7 @@
"packages": {
"@adraffy/ens-normalize": ["@adraffy/ens-normalize@1.11.1", "", {}, "sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ=="],
"@alcalzone/ansi-tokenize": ["@alcalzone/ansi-tokenize@0.2.0", "", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } }, "sha512-qI/5TaaaCZE4yeSZ83lu0+xi1r88JSxUjnH4OP/iZF7+KKZ75u3ee5isd0LxX+6N8U0npL61YrpbthILHB6BnA=="],
"@alcalzone/ansi-tokenize": ["@alcalzone/ansi-tokenize@0.2.4", "", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } }, "sha512-HTgrrTgZ9Jgeo6Z3oqbQ7lifOVvRR14vaDuBGPPUxk9Thm+vObaO4QfYYYWw4Zo5CWQDBEfsinFA6Gre+AqwNQ=="],
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.25.10", "", { "os": "aix", "cpu": "ppc64" }, "sha512-0NFWnA+7l41irNuaSVlLfgNT12caWJVLzp5eAVhZ0z1qpxbockccEt3s+149rE64VUI3Ml2zt8Nv5JVc4QXTsw=="],
@@ -85,19 +85,19 @@
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.10", "", { "os": "win32", "cpu": "x64" }, "sha512-9KpxSVFCu0iK1owoez6aC/s/EdUQLDN3adTxGCqxMVhrPDj6bt5dbrHDXUuq+Bs2vATFBBrQS5vdQ/Ed2P+nbw=="],
"@grvt/client": ["@grvt/client@1.6.4", "", { "dependencies": { "axios": "^1.12.2" } }, "sha512-yZfEvsC/BtkcdMjoB7Eh6gshBraz/9810qCllvNXDx6OmdxR+NfxPO+ucNlPbyjEt1HfSVzHBWB1yGnVl1usNA=="],
"@grvt/client": ["@grvt/client@1.6.25", "", { "dependencies": { "axios": "^1.13.2" } }, "sha512-LG3oZSJDq1Qz6mLiHDmg+v/Hp+Nd+yOp8GIvkBVyIdOcPVzuzC8UQD7IxvS+g5EfQQKLiKzXSjKLc39a11Uj1A=="],
"@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
"@nadohq/client": ["@nadohq/client@0.1.0-alpha.41", "", { "dependencies": { "@nadohq/engine-client": "^0.1.0-alpha.41", "@nadohq/indexer-client": "^0.1.0-alpha.41", "@nadohq/shared": "^0.1.0-alpha.41", "@nadohq/trigger-client": "^0.1.0-alpha.41", "ts-mixer": "*" }, "peerDependencies": { "viem": "*" } }, "sha512-BbJjG32AsaBJtFA9VPH+3/sfR/pUCXVJ0spgairReb+FaZY2rYsasWGPi07y7OROXL7ZS9/LewntC6iu2NVzQg=="],
"@nadohq/client": ["@nadohq/client@0.1.0-alpha.45", "", { "dependencies": { "@nadohq/engine-client": "^0.1.0-alpha.45", "@nadohq/indexer-client": "^0.1.0-alpha.45", "@nadohq/shared": "^0.1.0-alpha.45", "@nadohq/trigger-client": "^0.1.0-alpha.45", "ts-mixer": "*" }, "peerDependencies": { "viem": "*" } }, "sha512-63S7eT5xSk3hxEXRLGDI94mPeu/zd1Nu4oUOZrY8wzhaT7Gl7PVP2snb8JH/PduVQzgs7+qblr4aTBI/j6QvLQ=="],
"@nadohq/engine-client": ["@nadohq/engine-client@0.1.0-alpha.41", "", { "dependencies": { "@nadohq/shared": "^0.1.0-alpha.41", "axios": "*", "ts-mixer": "*" }, "peerDependencies": { "viem": "*" } }, "sha512-PR2/MaZ2rprd42572UL26B6zBzUFLUVbvAwPFGf6N733RysUxMRixEJmUfSrPVKgZkA4gxqqEhLB0iZA08DBjw=="],
"@nadohq/engine-client": ["@nadohq/engine-client@0.1.0-alpha.45", "", { "dependencies": { "@nadohq/shared": "^0.1.0-alpha.45", "axios": "*", "ts-mixer": "*" }, "peerDependencies": { "viem": "*" } }, "sha512-GqaRrsB0Z2EgNY6wu4nG5OTc5hF+buNRMc0+jPLlOQonlPJAC4OiMCgCigm4nJecYwsdiQD05W3Z4YUqggxbyw=="],
"@nadohq/indexer-client": ["@nadohq/indexer-client@0.1.0-alpha.41", "", { "dependencies": { "@nadohq/engine-client": "^0.1.0-alpha.41", "@nadohq/shared": "^0.1.0-alpha.41", "axios": "*", "ts-mixer": "*" }, "peerDependencies": { "viem": "*" } }, "sha512-5oXM+r3xQmbAHx00MlZmZj64VfcVNNWCtZgJu1Hx+A6F7zZtt0zBmDR6WnY1qWQBM/yZc/xa/Rr3ypXN5VSyQg=="],
"@nadohq/indexer-client": ["@nadohq/indexer-client@0.1.0-alpha.45", "", { "dependencies": { "@nadohq/engine-client": "^0.1.0-alpha.45", "@nadohq/shared": "^0.1.0-alpha.45", "axios": "*", "ts-mixer": "*" }, "peerDependencies": { "viem": "*" } }, "sha512-8PzG9taYh380lsKT8i4UvGfhZiPpt+zPisx+ErVqMifyhcJAhgMeYNcfijwMQFNJdgTaBvtI0R5JK98l4Y0YQw=="],
"@nadohq/shared": ["@nadohq/shared@0.1.0-alpha.41", "", { "peerDependencies": { "bignumber.js": "^9.3.0", "viem": "*" } }, "sha512-c6rRU/9RjIRV0RSHwmliNOE3i3xi65zKGqW9O0M4Oc8a0SQXB5SpskQeSFOaZ1b9BHGi0TYg1xaLBjtYzbysJQ=="],
"@nadohq/shared": ["@nadohq/shared@0.1.0-alpha.45", "", { "peerDependencies": { "bignumber.js": "^9.3.0", "viem": "*" } }, "sha512-4Ml8dO9mkwnIidflpunwVMLX2KJA79b53T9xTBkH1Yzy0iOnbEE27r25wvgJgyszU0aznbPBv2++FZ0d0B5Zhg=="],
"@nadohq/trigger-client": ["@nadohq/trigger-client@0.1.0-alpha.41", "", { "dependencies": { "@nadohq/engine-client": "^0.1.0-alpha.41", "@nadohq/shared": "^0.1.0-alpha.41", "axios": "*", "ts-mixer": "*" }, "peerDependencies": { "viem": "*" } }, "sha512-PxHeqi+aGUHs6S2jHRz2GC9OQD3Mb25sqqwgvDz3EoXWAfv+tYAaSDsLL8FmYEPsbTswjfXm0PoThPDyImyU9A=="],
"@nadohq/trigger-client": ["@nadohq/trigger-client@0.1.0-alpha.45", "", { "dependencies": { "@nadohq/engine-client": "^0.1.0-alpha.45", "@nadohq/shared": "^0.1.0-alpha.45", "axios": "*", "ts-mixer": "*" }, "peerDependencies": { "viem": "*" } }, "sha512-Xt8W9zxOZhMvoXSRnx9kUR26wWuHc3EgTVTBbUXt7SlI9v3IP9I3idS6SU3j2f08flcvNqRmC2EbXyYDC2XeyQ=="],
"@noble/ciphers": ["@noble/ciphers@1.3.0", "", {}, "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw=="],
@@ -157,7 +157,7 @@
"@scure/bip39": ["@scure/bip39@1.3.0", "", { "dependencies": { "@noble/hashes": "~1.4.0", "@scure/base": "~1.1.6" } }, "sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ=="],
"@types/bun": ["@types/bun@1.2.22", "", { "dependencies": { "bun-types": "1.2.22" } }, "sha512-5A/KrKos2ZcN0c6ljRSOa1fYIyCKhZfIVYeuyb4snnvomnpFqC0tTsEkdqNxbAgExV384OETQ//WAjl3XbYqQA=="],
"@types/bun": ["@types/bun@1.3.8", "", { "dependencies": { "bun-types": "1.3.8" } }, "sha512-3LvWJ2q5GerAXYxO2mffLTqOzEu5qnhEAlh48Vnu8WQfnmSwbgagjGZV6BoHKJztENYEDn6QmVd949W4uESRJA=="],
"@types/chai": ["@types/chai@5.2.2", "", { "dependencies": { "@types/deep-eql": "*" } }, "sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg=="],
@@ -171,8 +171,6 @@
"@types/node": ["@types/node@24.5.2", "", { "dependencies": { "undici-types": "~7.12.0" } }, "sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ=="],
"@types/react": ["@types/react@19.1.13", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-hHkbU/eoO3EG5/MZkuFSKmYqPbSVk5byPFa3e7y/8TybHiLMACgI8seVYlicwk7H5K/rI2px9xrQp/C+AUDTiQ=="],
"@vitest/expect": ["@vitest/expect@3.2.4", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/spy": "3.2.4", "@vitest/utils": "3.2.4", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" } }, "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig=="],
"@vitest/mocker": ["@vitest/mocker@3.2.4", "", { "dependencies": { "@vitest/spy": "3.2.4", "estree-walker": "^3.0.3", "magic-string": "^0.30.17" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "optionalPeers": ["msw", "vite"] }, "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ=="],
@@ -189,7 +187,7 @@
"abitype": ["abitype@1.2.3", "", { "peerDependencies": { "typescript": ">=5.0.4", "zod": "^3.22.0 || ^4.0.0" }, "optionalPeers": ["typescript", "zod"] }, "sha512-Ofer5QUnuUdTFsBRwARMoWKOH1ND5ehwYhJ3OJ/BQO+StkwQjHw0XyVh4vDttzHB7QOFhPHa/o413PJ82gU/Tg=="],
"ansi-escapes": ["ansi-escapes@7.1.0", "", { "dependencies": { "environment": "^1.0.0" } }, "sha512-YdhtCd19sKRKfAAUsrcC1wzm4JuzJoiX4pOJqIoW2qmKj5WzG/dL8uUJ0361zaXtHqK7gEhOwtAtz7t3Yq3X5g=="],
"ansi-escapes": ["ansi-escapes@7.2.0", "", { "dependencies": { "environment": "^1.0.0" } }, "sha512-g6LhBsl+GBPRWGWsBtutpzBYuIIdBkLEvad5C/va/74Db018+5TZiyA26cZJAr3Rft5lprVqOIPxf5Vid6tqAw=="],
"ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="],
@@ -201,17 +199,17 @@
"auto-bind": ["auto-bind@5.0.1", "", {}, "sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg=="],
"axios": ["axios@1.12.2", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw=="],
"axios": ["axios@1.13.4", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", "proxy-from-env": "^1.1.0" } }, "sha512-1wVkUaAO6WyaYtCkcYCOx12ZgpGf9Zif+qXa4n+oYzK558YryKqiL6UWwd5DqiH3VRW0GYhTZQ/vlgJrCoNQlg=="],
"bignumber.js": ["bignumber.js@9.3.1", "", {}, "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ=="],
"bun-types": ["bun-types@1.2.22", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-hwaAu8tct/Zn6Zft4U9BsZcXkYomzpHJX28ofvx7k0Zz2HNz54n1n+tDgxoWFGB4PcFvJXJQloPhaV2eP3Q6EA=="],
"bun-types": ["bun-types@1.3.8", "", { "dependencies": { "@types/node": "*" } }, "sha512-fL99nxdOWvV4LqjmC+8Q9kW3M4QTtTR1eePs94v5ctGqU8OeceWrSUaRw3JYb7tU3FkMIAjkueehrHPPPGKi5Q=="],
"cac": ["cac@6.7.14", "", {}, "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ=="],
"call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
"ccxt": ["ccxt@4.5.12", "", { "dependencies": { "ws": "^8.8.1" } }, "sha512-2lfL2TKjq4vBkQUQWJfDqFywhvYCZmk9r0SWC8GqA4AHZ6qozKVUJowxQTvdRsLX9jBwYSE0nc7JVurBrQ6SHg=="],
"ccxt": ["ccxt@4.5.35", "", { "dependencies": { "ws": "^8.8.1" } }, "sha512-aFn1jq/vR9wD3Vxu/2UFoS8snqlvfYn/iYrNhyZZfzB3N+kAHhP5+sAgO6ZwNHkHiUT9IPPahC1ZSFdPtjpIYA=="],
"chai": ["chai@5.3.3", "", { "dependencies": { "assertion-error": "^2.0.1", "check-error": "^2.1.1", "deep-eql": "^5.0.1", "loupe": "^3.1.0", "pathval": "^2.0.0" } }, "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw=="],
@@ -223,7 +221,7 @@
"cli-cursor": ["cli-cursor@4.0.0", "", { "dependencies": { "restore-cursor": "^4.0.0" } }, "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg=="],
"cli-truncate": ["cli-truncate@4.0.0", "", { "dependencies": { "slice-ansi": "^5.0.0", "string-width": "^7.0.0" } }, "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA=="],
"cli-truncate": ["cli-truncate@5.1.1", "", { "dependencies": { "slice-ansi": "^7.1.0", "string-width": "^8.0.0" } }, "sha512-SroPvNHxUnk+vIW/dOSfNqdy1sPEFkrTk6TUtqLCnBlo3N7TNYYkzzN7uSD6+jVjrdO4+p8nH7JzH6cIvUem6A=="],
"code-excerpt": ["code-excerpt@4.0.0", "", { "dependencies": { "convert-to-spaces": "^2.0.1" } }, "sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA=="],
@@ -231,15 +229,13 @@
"convert-to-spaces": ["convert-to-spaces@2.0.1", "", {}, "sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ=="],
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
"deep-eql": ["deep-eql@5.0.2", "", {}, "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q=="],
"delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="],
"dotenv": ["dotenv@17.2.2", "", {}, "sha512-Sf2LSQP+bOlhKWWyhFsn0UsfdK/kCWRv1iuA2gXAwt3dyNabr6QSj00I2V10pidqz69soatm9ZwZvpQMTIOd5Q=="],
"dotenv": ["dotenv@17.2.3", "", {}, "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w=="],
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
@@ -297,7 +293,7 @@
"indent-string": ["indent-string@5.0.0", "", {}, "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg=="],
"ink": ["ink@6.3.1", "", { "dependencies": { "@alcalzone/ansi-tokenize": "^0.2.0", "ansi-escapes": "^7.0.0", "ansi-styles": "^6.2.1", "auto-bind": "^5.0.1", "chalk": "^5.6.0", "cli-boxes": "^3.0.0", "cli-cursor": "^4.0.0", "cli-truncate": "^4.0.0", "code-excerpt": "^4.0.0", "es-toolkit": "^1.39.10", "indent-string": "^5.0.0", "is-in-ci": "^2.0.0", "patch-console": "^2.0.0", "react-reconciler": "^0.32.0", "signal-exit": "^3.0.7", "slice-ansi": "^7.1.0", "stack-utils": "^2.0.6", "string-width": "^7.2.0", "type-fest": "^4.27.0", "widest-line": "^5.0.0", "wrap-ansi": "^9.0.0", "ws": "^8.18.0", "yoga-layout": "~3.2.1" }, "peerDependencies": { "@types/react": ">=19.0.0", "react": ">=19.0.0", "react-devtools-core": "^6.1.2" }, "optionalPeers": ["@types/react", "react-devtools-core"] }, "sha512-3wGwITGrzL6rkWsi2gEKzgwdafGn4ZYd3u4oRp+sOPvfoxEHlnoB5Vnk9Uy5dMRUhDOqF3hqr4rLQ4lEzBc2sQ=="],
"ink": ["ink@6.6.0", "", { "dependencies": { "@alcalzone/ansi-tokenize": "^0.2.1", "ansi-escapes": "^7.2.0", "ansi-styles": "^6.2.1", "auto-bind": "^5.0.1", "chalk": "^5.6.0", "cli-boxes": "^3.0.0", "cli-cursor": "^4.0.0", "cli-truncate": "^5.1.1", "code-excerpt": "^4.0.0", "es-toolkit": "^1.39.10", "indent-string": "^5.0.0", "is-in-ci": "^2.0.0", "patch-console": "^2.0.0", "react-reconciler": "^0.33.0", "signal-exit": "^3.0.7", "slice-ansi": "^7.1.0", "stack-utils": "^2.0.6", "string-width": "^8.1.0", "type-fest": "^4.27.0", "widest-line": "^5.0.0", "wrap-ansi": "^9.0.0", "ws": "^8.18.0", "yoga-layout": "~3.2.1" }, "peerDependencies": { "@types/react": ">=19.0.0", "react": ">=19.0.0", "react-devtools-core": "^6.1.2" }, "optionalPeers": ["@types/react", "react-devtools-core"] }, "sha512-QDt6FgJxgmSxAelcOvOHUvFxbIUjVpCH5bx+Slvc5m7IEcpGt3dYwbz/L+oRnqEGeRvwy1tineKK4ect3nW1vQ=="],
"is-fullwidth-code-point": ["is-fullwidth-code-point@5.1.0", "", { "dependencies": { "get-east-asian-width": "^1.3.1" } }, "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ=="],
@@ -325,7 +321,7 @@
"onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="],
"ox": ["ox@0.10.5", "", { "dependencies": { "@adraffy/ens-normalize": "^1.11.0", "@noble/ciphers": "^1.3.0", "@noble/curves": "1.9.1", "@noble/hashes": "^1.8.0", "@scure/bip32": "^1.7.0", "@scure/bip39": "^1.6.0", "abitype": "^1.2.3", "eventemitter3": "5.0.1" }, "peerDependencies": { "typescript": ">=5.4.0" }, "optionalPeers": ["typescript"] }, "sha512-mXJRiZswmX46abrzNkJpTN9sPJ/Rhevsp5Dfg0z80D55aoLNmEV4oN+/+feSNW593c2CnHavMqSVBanpJ0lUkQ=="],
"ox": ["ox@0.11.3", "", { "dependencies": { "@adraffy/ens-normalize": "^1.11.0", "@noble/ciphers": "^1.3.0", "@noble/curves": "1.9.1", "@noble/hashes": "^1.8.0", "@scure/bip32": "^1.7.0", "@scure/bip39": "^1.6.0", "abitype": "^1.2.3", "eventemitter3": "5.0.1" }, "peerDependencies": { "typescript": ">=5.4.0" }, "optionalPeers": ["typescript"] }, "sha512-1bWYGk/xZel3xro3l8WGg6eq4YEKlaqvyMtVhfMFpbJzK2F6rj4EDRtqDCWVEJMkzcmEi9uW2QxsqELokOlarw=="],
"patch-console": ["patch-console@2.0.0", "", {}, "sha512-0YNdUceMdaQwoKce1gatDScmMo5pu/tfABfnzEqeG0gtTmd7mh/WcwgUjtAeOU7N8nFFlbQBnFK2gXW5fGvmMA=="],
@@ -341,15 +337,15 @@
"proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="],
"react": ["react@19.1.1", "", {}, "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ=="],
"react": ["react@19.2.4", "", {}, "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="],
"react-reconciler": ["react-reconciler@0.32.0", "", { "dependencies": { "scheduler": "^0.26.0" }, "peerDependencies": { "react": "^19.1.0" } }, "sha512-2NPMOzgTlG0ZWdIf3qG+dcbLSoAc/uLfOwckc3ofy5sSK0pLJqnQLpUFxvGcN2rlXSjnVtGeeFLNimCQEj5gOQ=="],
"react-reconciler": ["react-reconciler@0.33.0", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.0" } }, "sha512-KetWRytFv1epdpJc3J4G75I4WrplZE5jOL7Yq0p34+OVOKF4Se7WrdIdVC45XsSSmUTlht2FM/fM1FZb1mfQeA=="],
"restore-cursor": ["restore-cursor@4.0.0", "", { "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" } }, "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg=="],
"rollup": ["rollup@4.52.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.52.0", "@rollup/rollup-android-arm64": "4.52.0", "@rollup/rollup-darwin-arm64": "4.52.0", "@rollup/rollup-darwin-x64": "4.52.0", "@rollup/rollup-freebsd-arm64": "4.52.0", "@rollup/rollup-freebsd-x64": "4.52.0", "@rollup/rollup-linux-arm-gnueabihf": "4.52.0", "@rollup/rollup-linux-arm-musleabihf": "4.52.0", "@rollup/rollup-linux-arm64-gnu": "4.52.0", "@rollup/rollup-linux-arm64-musl": "4.52.0", "@rollup/rollup-linux-loong64-gnu": "4.52.0", "@rollup/rollup-linux-ppc64-gnu": "4.52.0", "@rollup/rollup-linux-riscv64-gnu": "4.52.0", "@rollup/rollup-linux-riscv64-musl": "4.52.0", "@rollup/rollup-linux-s390x-gnu": "4.52.0", "@rollup/rollup-linux-x64-gnu": "4.52.0", "@rollup/rollup-linux-x64-musl": "4.52.0", "@rollup/rollup-openharmony-arm64": "4.52.0", "@rollup/rollup-win32-arm64-msvc": "4.52.0", "@rollup/rollup-win32-ia32-msvc": "4.52.0", "@rollup/rollup-win32-x64-gnu": "4.52.0", "@rollup/rollup-win32-x64-msvc": "4.52.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-+IuescNkTJQgX7AkIDtITipZdIGcWF0pnVvZTWStiazUmcGA2ag8dfg0urest2XlXUi9kuhfQ+qmdc5Stc3z7g=="],
"scheduler": ["scheduler@0.26.0", "", {}, "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA=="],
"scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="],
"siginfo": ["siginfo@2.0.0", "", {}, "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g=="],
@@ -365,7 +361,7 @@
"std-env": ["std-env@3.9.0", "", {}, "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw=="],
"string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
"string-width": ["string-width@8.1.1", "", { "dependencies": { "get-east-asian-width": "^1.3.0", "strip-ansi": "^7.1.0" } }, "sha512-KpqHIdDL9KwYk22wEOg/VIqYbrnLeSApsKT/bSj6Ez7pn3CftUiLAv2Lccpq1ALcpLV9UX1Ppn92npZWu2w/aw=="],
"strip-ansi": ["strip-ansi@7.1.2", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="],
@@ -393,7 +389,7 @@
"undici-types": ["undici-types@7.12.0", "", {}, "sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ=="],
"viem": ["viem@2.43.1", "", { "dependencies": { "@noble/curves": "1.9.1", "@noble/hashes": "1.8.0", "@scure/bip32": "1.7.0", "@scure/bip39": "1.6.0", "abitype": "1.2.3", "isows": "1.0.7", "ox": "0.10.5", "ws": "8.18.3" }, "peerDependencies": { "typescript": ">=5.0.4" }, "optionalPeers": ["typescript"] }, "sha512-S33pBNlRvOlVv4+L94Z8ydCMDB1j0cuHFUvaC28i6OTxw3uY1P4M3h1YDFK8YC1H9/lIbeBTTvCRhi0FqU/2iw=="],
"viem": ["viem@2.45.1", "", { "dependencies": { "@noble/curves": "1.9.1", "@noble/hashes": "1.8.0", "@scure/bip32": "1.7.0", "@scure/bip39": "1.6.0", "abitype": "1.2.3", "isows": "1.0.7", "ox": "0.11.3", "ws": "8.18.3" }, "peerDependencies": { "typescript": ">=5.0.4" }, "optionalPeers": ["typescript"] }, "sha512-LN6Pp7vSfv50LgwhkfSbIXftAM5J89lP9x8TeDa8QM7o41IxlHrDh0F9X+FfnCWtsz11pEVV5sn+yBUoOHNqYA=="],
"vite": ["vite@7.1.7", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-VbA8ScMvAISJNJVbRDTJdCwqQoAareR/wutevKanhR2/1EkoXVZVkkORaYm/tNVCjP/UDTKtcw3bAkwOUdedmA=="],
@@ -407,12 +403,10 @@
"wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="],
"ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="],
"ws": ["ws@8.19.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg=="],
"yoga-layout": ["yoga-layout@3.2.1", "", {}, "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ=="],
"cli-truncate/slice-ansi": ["slice-ansi@5.0.0", "", { "dependencies": { "ansi-styles": "^6.0.0", "is-fullwidth-code-point": "^4.0.0" } }, "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ=="],
"ox/@noble/curves": ["@noble/curves@1.9.1", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA=="],
"ox/@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="],
@@ -429,7 +423,11 @@
"viem/@scure/bip39": ["@scure/bip39@1.6.0", "", { "dependencies": { "@noble/hashes": "~1.8.0", "@scure/base": "~1.2.5" } }, "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A=="],
"cli-truncate/slice-ansi/is-fullwidth-code-point": ["is-fullwidth-code-point@4.0.0", "", {}, "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ=="],
"viem/ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="],
"widest-line/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
"wrap-ansi/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
"ox/@scure/bip32/@scure/base": ["@scure/base@1.2.6", "", {}, "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg=="],
+550
View File
@@ -0,0 +1,550 @@
# Nado 交易机器人完全新手教程
> 本教程面向零基础用户,手把手教你如何在 Nado 交易所使用 ritmex-bot 进行自动化交易。
## 目录
1. [什么是 Nado 和 ritmex-bot](#什么是-nado-和-ritmex-bot)
2. [准备工作](#准备工作)
3. [安装 Bun 运行环境](#安装-bun-运行环境)
4. [下载并安装 ritmex-bot](#下载并安装-ritmex-bot)
5. [在 Nado 创建账户并入金](#在-nado-创建账户并入金)
6. [获取 Nado 鉴权信息(重要)](#获取-nado-鉴权信息重要)
7. [配置 .env 文件](#配置-env-文件)
8. [启动交易机器人](#启动交易机器人)
9. [策略说明与选择](#策略说明与选择)
10. [常见问题与排查](#常见问题与排查)
---
## 什么是 Nado 和 ritmex-bot
### Nado 交易所
Nado 是一个运行在 **Ink L2 网络**(基于 Optimism Superchain)的去中心化永续合约交易所。它支持 BTC、ETH 等主流加密货币的永续合约交易,具有以下特点:
- **去中心化**:资产由用户钱包控制,无需信任中心化机构
- **低延迟**:使用 L2 网络,交易确认快速
- **统一保证金**:支持多种资产作为抵押品
注册使用 Nado 目前需要邀请码:
* [https://app.nado.xyz?join=eGp9qPD](https://app.nado.xyz?join=eGp9qPD)
* [https://app.nado.xyz?join=LKbIUs5](https://app.nado.xyz?join=LKbIUs5)
### ritmex-bot 交易机器人
ritmex-bot 是一个多交易所量化交易终端,支持多种自动化交易策略:
- **趋势跟随策略**:基于 SMA30 均线的趋势交易
- **做市策略**:双边挂单赚取买卖价差
- **Guardian 防守策略**:自动监控仓位,补挂止损止盈
- **网格策略**:区间震荡行情的网格交易
---
## 准备工作
在开始之前,请确保你具备以下条件:
### 硬件要求
- 一台可以联网的电脑(macOS、Linux 或 Windows
- 稳定的网络连接
### 软件要求
- **终端/命令行工具**
- macOS:使用自带的"终端"应用
- Windows:推荐使用 WSLWindows Subsystem for Linux)或 PowerShell
- Linux:使用自带的终端
### 资金要求
- 至少 **50-100 USDT** 等值的资金用于交易
- 少量 **ETH**(约 0.01-0.05 ETH)用于支付 Gas 费用
### 钱包要求
- 一个支持 EVM 的钱包,推荐:
- **MetaMask**(浏览器插件)
- **Rabby Wallet**(更专业的交易钱包)
---
## 安装 Bun 运行环境
ritmex-bot 使用 **Bun** 作为运行环境。Bun 是一个快速的 JavaScript 运行时。
### macOS / Linux 安装
打开终端,输入以下命令:
```bash
curl -fsSL https://bun.sh/install | bash
```
安装完成后,**关闭并重新打开终端**,然后验证安装:
```bash
bun -v
```
如果显示版本号(如 `1.2.x`),说明安装成功。
### Windows 安装
**方法一:使用 PowerShell(推荐)**
以管理员身份打开 PowerShell,输入:
```powershell
powershell -c "irm bun.sh/install.ps1 | iex"
```
**方法二:使用 WSL(更稳定)**
1. 先安装 WSL:在 PowerShell 中运行 `wsl --install`
2. 重启电脑
3. 打开 WSL 终端,按照 Linux 方式安装 Bun
---
## 下载并安装 ritmex-bot
### 方法一:使用 Git(推荐)
```bash
# 克隆代码仓库
git clone https://github.com/discountry/ritmex-bot.git
# 进入项目目录
cd ritmex-bot
# 安装依赖
bun install
```
### 方法二:直接下载 ZIP
1. 访问 https://github.com/discountry/ritmex-bot
2. 点击绿色的 "Code" 按钮
3. 选择 "Download ZIP"
4. 解压下载的文件
5. 在终端中进入解压后的目录
6. 运行 `bun install`
---
## 在 Nado 创建账户并入金
### 步骤 1:连接钱包
1. 访问 Nado 官网:https://app.nado.xyz
2. 点击右上角的 **"Connect Wallet"**
3. 选择你的钱包(如 MetaMask)
4. 在钱包中确认连接
### 步骤 2:添加 Ink 网络到钱包
Nado 运行在 Ink L2 网络上,你需要先添加这个网络:
**自动添加方式:**
1. 访问 https://chainlist.org/
2. 搜索 "Ink"
3. 点击 "Add to MetaMask"
**手动添加方式:**
在钱包设置中添加自定义网络,填写以下信息:
| 参数 | 值 |
|------|-----|
| 网络名称 | INK |
| RPC URL | https://rpc-gel.inkonchain.com |
| Chain ID | 57073 |
| 货币符号 | ETH |
| 区块浏览器 | https://explorer.inkonchain.com |
### 步骤 3:获取 Gas 费用(ETH)
在 Ink 网络上进行任何操作都需要少量 ETH 作为 Gas 费用。
**获取方式:**
- **从 CEX 直接提现**:Kraken 支持零手续费提现到 Ink 网络
- **跨链桥接**:使用 [Superbridge](https://superbridge.app/)、[Bungee](https://bungee.exchange/) 或 [Relay](https://relay.link/) 从其他链桥接 ETH 到 Ink
> 建议至少准备 0.01-0.05 ETH 用于支付 Gas 费用
### 步骤 4:存入交易资金
1. 在 Nado 网站导航到 **Portfolio** 页面
2. 点击 **Deposit**
3. 选择要存入的资产(支持 USDT0、wETH、USDC、kBTC、wBTC
4. 输入金额并确认交易
---
## 获取 Nado 鉴权信息(重要)
这是配置机器人最关键的一步。Nado 使用基于 EVM 的签名认证方式,你需要获取以下两个关键信息:
- **NADO_SIGNER_PRIVATE_KEY**:签名私钥
- **NADO_SUBACCOUNT_OWNER**:子账户所有者地址
### 获取方式:从浏览器开发者工具提取
#### 步骤 1:登录 Nado 交易界面
1. 访问 https://app.nado.xyz
2. 连接你的钱包并完成登录
3. 确保你已经在 Nado 启用了一键交易功能并能正常下单
#### 步骤 2:打开浏览器开发者工具
- **Chrome / Edge**:按 `F12``Ctrl+Shift+I`Mac 上是 `Cmd+Option+I`
- **Firefox**:按 `F12``Ctrl+Shift+I`
- **Safari**:先在偏好设置中启用开发者菜单,然后按 `Cmd+Option+I`
#### 步骤 3:找到 Local Storage 中的私钥
1. 在开发者工具中,切换到 **Application** 标签(Chrome/Edge)或 **Storage** 标签(Firefox
2. 在左侧菜单找到 **Local Storage**
3. 点击展开,找到 `https://app.nado.xyz`
4. 在右侧列表中找到 **`nado.userSettings`** 这一项
5. 点击这一项,查看其 Value(值)
#### 步骤 4:提取私钥
`nado.userSettings` 的值是一个 JSON 对象,大致结构如下:
```json
"signingPreferenceBySubaccountKey": {
"inkMainnet_default": {
{
"privateKey": "0x1234567890abcdef...",
...
}
}
}
```
**你需要的是 `privateKey` 字段的值**,它是一个以 `0x` 开头的 64 位十六进制字符串。
将这个值复制下来,这就是你的 `NADO_SIGNER_PRIVATE_KEY`
#### 步骤 5:获取子账户所有者地址
`NADO_SUBACCOUNT_OWNER` 就是你连接到 Nado 的钱包地址。
获取方式:
1. 打开你的钱包(如 MetaMask)
2. 复制你的钱包地址(以 `0x` 开头的 42 位地址)
这就是你的 `NADO_SUBACCOUNT_OWNER`
### 关于 Linked Signer(进阶)
Nado 支持 "Linked Signer" 功能,允许你使用一个专门的签名密钥来代表你的主账户进行交易。这提供了额外的安全层:
- 主钱包私钥保持离线安全
- Linked Signer 只有交易权限,无法提取资金
- 可以随时撤销 Linked Signer
当你在 Nado 网站首次连接钱包时,系统会自动为你创建一个 Linked Signer,这个签名密钥就存储在浏览器的 Local Storage 中。
> **重要安全提示**
> - `NADO_SIGNER_PRIVATE_KEY` 是 Linked Signer 的私钥,不是你主钱包的私钥
> - 这个私钥只能用于在 Nado 上签署交易,无法直接转移你的链上资产
> - 但仍需妥善保管,不要分享给他人
---
## 配置 .env 文件
### 步骤 1:创建 .env 文件
在项目根目录下,复制示例配置文件:
```bash
cp .env.example .env
```
### 步骤 2:编辑 .env 文件
使用任意文本编辑器打开 `.env` 文件:
```bash
# macOS
open -e .env
# Linux
nano .env
# Windows
notepad .env
```
### 步骤 3:填写 Nado 配置
`.env` 文件中找到并修改以下配置项:
```bash
# ============================================
# 交易所选择
# ============================================
EXCHANGE=nado
# ============================================
# Nado 交易所配置(必填)
# ============================================
# 签名私钥 - 从浏览器 Local Storage 获取
# 格式:以 0x 开头的 64 位十六进制字符串
NADO_SIGNER_PRIVATE_KEY=0x你的私钥
# 子账户所有者地址 - 你的钱包地址
# 格式:以 0x 开头的 42 位地址
NADO_SUBACCOUNT_OWNER=0x你的钱包地址
# 子账户名称(可选,默认为 default)
NADO_SUBACCOUNT_NAME=default
# 网络环境(可选)
# inkMainnet = 主网(真实交易)
# inkTestnet = 测试网(模拟交易)
NADO_ENV=inkMainnet
# 交易品种(可选,默认 BTC-PERP)
NADO_SYMBOL=BTC-PERP
# ============================================
# 交易参数配置
# ============================================
# 单笔交易数量(以 BTC 计)
TRADE_AMOUNT=0.001
# 止损金额(USD)- 亏损超过此金额触发平仓
LOSS_LIMIT=10
# 移动止盈触发金额(USD
TRAILING_PROFIT=5
# 移动止盈回撤比例(0.2 = 20%)
TRAILING_CALLBACK_RATE=0.2
```
### 完整的 Nado 配置示例
```bash
# 交易所选择
EXCHANGE=nado
# Nado 凭证
NADO_SIGNER_PRIVATE_KEY=0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef
NADO_SUBACCOUNT_OWNER=0xAbCdEf1234567890AbCdEf1234567890AbCdEf12
NADO_SUBACCOUNT_NAME=default
NADO_ENV=inkMainnet
NADO_SYMBOL=BTC-PERP
# 交易参数
TRADE_AMOUNT=0.001
# 趋势策略
LOSS_LIMIT=10
TRAILING_PROFIT=5
TRAILING_CALLBACK_RATE=0.2
# 波段策略
SWING_DIRECTION=short
SWING_STOP_LOSS_PCT=0.05 # 价格反向运动 5% 止损
# 做市策略参数(如果使用做市策略)
LOSS_LIMIT=0.08
MAKER_LOSS_LIMIT=0.08
LIQUIDITY_MAKER_LOSS_LIMIT=0.08
LIQUIDITY_MAKER_CLOSE_TICK_OFFSET=5
MAKER_ENTRY_DEPTH_LEVEL=1
```
## 启动交易机器人
### 方法一:交互式启动(推荐新手)
```bash
bun run index.ts
```
启动后会显示一个交互式菜单,使用方向键选择策略,按回车确认。
### 方法二:命令行直接启动
```bash
# 启动趋势策略
bun run index.ts --strategy trend --silent
# 启动做市策略
bun run index.ts --strategy maker --silent
```
### 方法三:使用 PM2 后台运行(推荐生产环境)
```bash
# 安装 PM2
bun add -d pm2
# 后台启动趋势策略
bunx pm2 start bun --name ritmex-trend --cwd . --restart-delay 5000 -- run index.ts --strategy trend --silent
# 查看运行状态
bunx pm2 list
# 查看日志
bunx pm2 logs ritmex-trend
# 停止运行
bunx pm2 stop ritmex-trend
```
---
## 策略说明与选择
### 趋势策略(Trend
**适用场景**:单边行情,趋势明显的市场
**工作原理**
- 使用 SMA30(30 周期简单移动平均线)判断趋势
- 价格突破均线时开仓
- 内置止损和移动止盈
**配置参数**
```bash
TRADE_AMOUNT=0.001 # 单笔交易量
LOSS_LIMIT=10 # 止损金额(USD
TRAILING_PROFIT=5 # 移动止盈触发金额
TRAILING_CALLBACK_RATE=0.2 # 回撤比例
```
### 做市策略(Maker
**适用场景**:震荡行情,低波动市场
**工作原理**
- 在买卖盘口双边挂单
- 赚取买卖价差
- 根据持仓自动调整挂单方向
**配置参数**
```bash
MAKER_BID_OFFSET=0 # 买单价格偏移
MAKER_ASK_OFFSET=0 # 卖单价格偏移
MAKER_REFRESH_INTERVAL_MS=500 # 刷新间隔
```
## 常见问题与排查
### 问题 1:启动时提示 "Missing NADO_SIGNER_PRIVATE_KEY"
**原因**:未正确配置签名私钥
**解决方案**
1. 确认 `.env` 文件存在于项目根目录
2. 检查 `NADO_SIGNER_PRIVATE_KEY` 是否正确填写
3. 确保私钥以 `0x` 开头
### 问题 2:启动时提示 "Missing NADO_SUBACCOUNT_OWNER"
**原因**:未配置子账户所有者地址
**解决方案**
1.`.env` 中填写 `NADO_SUBACCOUNT_OWNER` 为你的钱包地址
2. 也可以使用 `NADO_EVM_ADDRESS` 作为替代
### 问题 3:连接失败,无法获取账户信息
**可能原因及解决方案**
1. **网络问题**:检查网络连接,确保能访问 Nado API
2. **私钥错误**:重新从浏览器 Local Storage 获取正确的私钥
3. **账户未激活**:确保在 Nado 网站上至少存入过资金
4. **Linked Signer 未启用**:账户需要至少有 5 USDT 价值的资产才能使用 Linked Signer
### 问题 4:下单失败,提示精度错误
**原因**:价格或数量精度不符合交易所要求
**解决方案**
```bash
# BTC-PERP 的标准精度
PRICE_TICK=0.1 # 价格精度 0.1 USD
QTY_STEP=0.001 # 数量精度 0.001 BTC
```
### 问题 5:时间同步错误
**原因**:本地时间与服务器时间相差太大
**解决方案**
- macOS/Linux`sudo ntpdate -u time.apple.com`
- Windows:设置 → 时间和语言 → 同步时间
### 问题 6Gas 费用不足
**原因**Ink 网络上的 ETH 余额不足
**解决方案**
1. 通过跨链桥向 Ink 网络转入少量 ETH0.01-0.05 ETH
2. 推荐使用 Superbridge 或 Relay 进行跨链
### 问题 7:找不到 Local Storage 中的私钥
**可能原因**
1. 尚未在 Nado 完成首次连接/操作
2. 浏览器清除了缓存
**解决方案**
1. 重新访问 https://app.nado.xyz
2. 连接钱包并进行一次操作(如查看账户)
3. 再次检查 Local Storage
---
## 安全提示
1. **永远不要分享你的私钥**`NADO_SIGNER_PRIVATE_KEY` 虽然不是主钱包私钥,但仍可用于在 Nado 上进行交易
2. **使用专用交易账户**:建议创建一个专门用于交易的新钱包,不要放置大量资产
3. **定期检查授权**:在钱包中定期检查并撤销不需要的 DApp 授权
4. **小额测试**:首次运行时使用小额资金测试,确认一切正常后再增加资金
5. **保护 .env 文件**
- 不要将 `.env` 文件提交到 Git
- 不要分享给他人
- 定期更换凭证
---
## 社区与支持
- **Telegram 交流群**https://t.me/+4fdo0quY87o4Mjhh
- **GitHub Issues**https://github.com/discountry/ritmex-bot/issues
- **Nado 官方文档**https://docs.nado.xyz
---
## 风险提示
量化交易具备风险。请注意:
- 市场波动可能导致亏损
- 技术故障可能导致订单执行异常
- 请勿投入无法承受损失的资金
- 建议先在测试网或小额账户中验证策略
祝交易顺利!
+11 -11
View File
@@ -21,21 +21,21 @@
"vitest": "^3.2.4"
},
"peerDependencies": {
"typescript": "^5"
"typescript": "^5.9.2"
},
"dependencies": {
"@grvt/client": "^1.6.4",
"@nadohq/client": "^0.1.0-alpha.41",
"@grvt/client": "^1.6.25",
"@nadohq/client": "^0.1.0-alpha.45",
"@noble/ed25519": "^3.0.0",
"axios": "^1.12.2",
"axios": "^1.13.4",
"bignumber.js": "^9.3.1",
"ccxt": "^4.5.12",
"dotenv": "^17.2.2",
"ethereum-cryptography": "^2.1.3",
"ink": "^6.3.1",
"react": "^19.1.1",
"ccxt": "^4.5.35",
"dotenv": "^17.2.3",
"ethereum-cryptography": "^2.2.1",
"ink": "^6.6.0",
"react": "^19.2.4",
"trading-signals": "^7.4.3",
"viem": "^2.43.1",
"ws": "^8.18.3"
"viem": "^2.45.1",
"ws": "^8.19.0"
}
}
+4 -1
View File
@@ -602,7 +602,10 @@ export class ParadexGateway {
// Only omit amount for MARKET close-position orders; STOP requires explicit size
const shouldOmitAmount = isClosePosition && type === "market";
const amountArg: any = shouldOmitAmount ? undefined : amount;
if (!shouldOmitAmount && amountArg != null && extraParams.size === undefined) {
// Paradex/ccxt may require `size` even when amount is omitted for closePosition MARKET orders.
if (shouldOmitAmount && amount != null && extraParams.size === undefined) {
extraParams.size = amount.toString();
} else if (!shouldOmitAmount && amountArg != null && extraParams.size === undefined) {
extraParams.size = amountArg.toString();
}
const order = (await this.exchange.createOrder(
+56
View File
@@ -0,0 +1,56 @@
import { describe, expect, it, vi } from "vitest";
import { ParadexGateway } from "../src/exchanges/paradex/gateway";
describe("ParadexGateway createOrder", () => {
it("sets `size` for closePosition MARKET orders even when amount is omitted", async () => {
const createOrder = vi.fn(async (symbol, type, side, amount, price, params) => ({
id: "1",
symbol,
type,
side,
status: "open",
price: price ?? 0,
amount: amount ?? Number(params?.size ?? 0),
filled: 0,
stopPrice: undefined,
timestamp: Date.now(),
lastUpdateTimestamp: Date.now(),
info: {
reduceOnly: params?.reduceOnly,
closePosition: params?.closePosition,
},
}));
const gateway = new ParadexGateway({
symbol: "BTC/USDC",
displaySymbol: "BTC/USDC",
privateKey: "test",
walletAddress: "test",
logger: () => {},
usePro: false,
}) as any;
gateway.exchange = { createOrder, markets: {}, symbols: [] };
gateway.initialized = true;
gateway.marketSymbol = "BTC/USDC";
await gateway.createOrder({
symbol: "BTC/USDC",
side: "SELL",
type: "MARKET",
quantity: 1.23,
reduceOnly: "true",
closePosition: "true",
});
expect(createOrder).toHaveBeenCalledTimes(1);
const [_symbol, _type, _side, amountArg, _price, extraParams] = createOrder.mock.calls[0]!;
expect(amountArg).toBeUndefined();
expect(extraParams).toMatchObject({
closePosition: true,
reduceOnly: true,
size: "1.23",
});
});
});