├── .eslintrc.js
├── .gitignore
├── README.md
├── babel.config.js
├── jsconfig.json
├── package-lock.json
├── package.json
├── public
├── favicon.ico
└── index.html
├── src
├── App.vue
├── components
│ ├── LogText.vue
│ └── TopMenu.vue
├── main.js
├── request
│ ├── okReq.js
│ └── request.js
├── router
│ └── router.js
├── utils
│ ├── DateUtils.js
│ └── NumberUtils.js
└── view
│ ├── Home.vue
│ ├── OKXContainer.vue
│ └── exchange
│ └── OKXWithdraw.vue
└── vue.config.js
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: [
3 | 'plugin:vue/vue3-recommended',
4 | 'airbnb-base',
5 | ],
6 | plugins: [
7 | 'vue',
8 | ],
9 | rules: {
10 | 'no-console': 'off', // 如果你不想限制console输出,可以把这个规则关闭
11 | 'vue/max-attributes-per-line': ['error', {
12 | singleline: 5, // 在单行上最多允许5个属性
13 | multiline: {
14 | max: 1, // 在多行上允许一个属性
15 | allowFirstLine: false // 不允许属性和开始标签放在同一行
16 | }
17 | }],
18 | // 在vue模板文件中强制使用4个空格缩进
19 | 'vue/html-indent': ['error', 2]
20 | },
21 | };
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /dist
4 |
5 |
6 | # local env files
7 | .env.local
8 | .env.*.local
9 |
10 | # Log files
11 | npm-debug.log*
12 | yarn-debug.log*
13 | yarn-error.log*
14 | pnpm-debug.log*
15 |
16 | # Editor directories and files
17 | .idea
18 | .vscode
19 | *.suo
20 | *.ntvs*
21 | *.njsproj
22 | *.sln
23 | *.sw?
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # fast-exchange
2 |
3 | 本项目为交易所账户与链上地址之间的交互提供了极大便利性。本项目为纯前端项目,直接连接区块链网络或者其他第三方网络进行交互。至于老生常谈的安全问题,有条件的可以`review代码`,无法review代码的小伙伴就跟着`感觉`走吧。
4 |
5 | Owner承诺github上的源码**不存在**恶意代码,其他基于此项目二次开发的代码,Owner无法保证其安全性,所以请尽量**从github下载发行版**。
6 |
7 | ## 开发者使用说明
8 |
9 | 欢迎有想法有时间的开发小伙伴提pr,review之后会尽快approve。
10 |
11 | 另外Owner更擅长后端,欢迎前端伙伴提一些界面优化类的PR。
12 |
13 | ### 技术栈
14 |
15 | VUE3 + axios + vue-router + element-plus + starkjs
16 |
17 | ### 安装依赖
18 |
19 | ```
20 | npm install
21 | ```
22 |
23 | ### 启动项目
24 |
25 | ```
26 | npm run serve
27 | ```
28 |
29 | ### 构建项目
30 | ```
31 | npm run build
32 | ```
33 |
34 | ## 普通用户使用说明
35 |
36 | 1. OKX配置白名单, 不会的可以搜一下
37 | 2. OKX生成API KEY, 生成之后请妥善保管, 避免丢失.
38 | 3. 点击**release**获取开箱即用的发行版软件,如下图。
39 |
40 | 
41 |
42 | 4.下载ZIP包
43 |
44 | 
45 |
46 | 5.解压,打开dist文件夹, 打开index.html即可使用,界面如下
47 |
48 | 
49 |
50 |
51 |
52 | ## 联系我们
53 |
54 | twitter:https://twitter.com/senokel
55 |
56 |
57 |
58 | ## 打赏/捐赠
59 |
60 | **新需求:**
61 |
62 | 有新需求的小伙伴,可以提起issue,会根据issue规划下一步功能开发。
63 |
64 | **捐赠:**
65 |
66 | 请向starknet地址捐赠 : 0x0219e47CD3Ab97C7602233c283811b731b75f7A5a2D26294de8ad0754e5fe7C4
67 |
68 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "esnext",
5 | "baseUrl": "./",
6 | "moduleResolution": "node",
7 | "paths": {
8 | "@/*": [
9 | "src/*"
10 | ]
11 | },
12 | "lib": [
13 | "esnext",
14 | "dom",
15 | "dom.iterable",
16 | "scripthost"
17 | ]
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fast-airdrop",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "serve": "vue-cli-service serve",
7 | "build": "vue-cli-service build",
8 | "lint": "vue-cli-service lint"
9 | },
10 | "dependencies": {
11 | "axios": "^1.5.0",
12 | "core-js": "^3.8.3",
13 | "crypto-js": "^4.1.1",
14 | "element-plus": "^2.3.12",
15 | "vue": "^3.2.13",
16 | "vue-router": "^4.2.4"
17 | },
18 | "devDependencies": {
19 | "@babel/core": "^7.12.16",
20 | "@babel/eslint-parser": "^7.12.16",
21 | "@vue/cli-plugin-babel": "~5.0.0",
22 | "@vue/cli-plugin-eslint": "~5.0.0",
23 | "@vue/cli-service": "~5.0.0",
24 | "eslint": "^7.32.0",
25 | "eslint-plugin-vue": "^8.0.3"
26 | },
27 | "eslintConfig": {
28 | "root": true,
29 | "env": {
30 | "node": true
31 | },
32 | "extends": [
33 | "plugin:vue/vue3-essential",
34 | "eslint:recommended"
35 | ],
36 | "parserOptions": {
37 | "parser": "@babel/eslint-parser"
38 | },
39 | "rules": {}
40 | },
41 | "browserslist": [
42 | "> 1%",
43 | "last 2 versions",
44 | "not dead",
45 | "not ie 11"
46 | ]
47 | }
48 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AceSen/fast-exchange/002ebb8a911c8cda70cd79873766d26b2f893e9a/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | <%= htmlWebpackPlugin.options.title %>
9 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
22 |
23 |
32 |
--------------------------------------------------------------------------------
/src/components/LogText.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
29 |
30 |
--------------------------------------------------------------------------------
/src/components/TopMenu.vue:
--------------------------------------------------------------------------------
1 |
2 |
15 |
16 |
17 |
37 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import { createApp } from 'vue'
2 | import App from './App.vue'
3 | import ElementPlus from 'element-plus'
4 | import 'element-plus/dist/index.css'
5 | import router from './router/router'
6 |
7 | createApp(App).use(ElementPlus).use(router).mount('#app')
8 |
--------------------------------------------------------------------------------
/src/request/okReq.js:
--------------------------------------------------------------------------------
1 | import { request } from './request';
2 | import CryptoJS from "crypto-js";
3 |
4 | const config = {
5 | baseURL: "https://www.okx.com"
6 | };
7 |
8 | /**
9 | * 签名
10 | * @param {*String} method 请求方式
11 | * @param {*String} url 路径
12 | */
13 | function getOkSign(method, url, timestamp, secret, body) {
14 | if (!method || !url || !timestamp || !secret) {
15 | return null;
16 | }
17 |
18 | return CryptoJS.enc.Base64.stringify(
19 | CryptoJS.HmacSHA256(timestamp + method.toUpperCase() + url + body, secret)
20 | );
21 | }
22 |
23 | /**
24 | *
25 | * @param {*} param
26 | * @param {*} headers
27 | * @param {*} secret
28 | * @returns
29 | */
30 | function getBalance(param, headers, secret) {
31 | config.method = 'get';
32 | config.url = '/api/v5/asset/balances';
33 | const timestamp = new Date().toISOString();
34 | const sign = getOkSign(config.method, config.url, timestamp, secret, '');
35 | config.headers = {
36 | "OK-ACCESS-SIGN": sign,
37 | "OK-ACCESS-TIMESTAMP": timestamp,
38 | ...headers,
39 | }
40 |
41 | return request(config);
42 | }
43 |
44 | function getCcyList(param, headers, secret) {
45 | config.method = 'get';
46 | config.url = '/api/v5/asset/currencies';
47 | const timestamp = new Date().toISOString();
48 | const sign = getOkSign(config.method, config.url, timestamp, secret, '');
49 | config.headers = {
50 | "OK-ACCESS-SIGN": sign,
51 | "OK-ACCESS-TIMESTAMP": timestamp,
52 | ...headers,
53 | }
54 |
55 | return request(config);
56 | }
57 |
58 | function withdrawal(param, headers, secret) {
59 | config.method = 'post';
60 | config.url = '/api/v5/asset/withdrawal';
61 | const timestamp = new Date().toISOString();
62 | const sign = getOkSign(config.method, config.url, timestamp, secret, JSON.stringify(param));
63 | console.log(JSON.stringify(param))
64 | config.headers = {
65 | "OK-ACCESS-SIGN": sign,
66 | "OK-ACCESS-TIMESTAMP": timestamp,
67 | ...headers,
68 | };
69 | config.data = param;
70 |
71 | return request(config);
72 | }
73 |
74 | /**
75 | * 查询充币历史记录
76 | * @param {*} param
77 | * @param {*} headers
78 | * @param {*} secret
79 | * @returns
80 | */
81 | function getDepositHis(param, headers, secret) {
82 | config.method = 'get';
83 | config.url = '/api/v5/asset/deposit-history';
84 | const timestamp = new Date().toISOString();
85 | const sign = getOkSign(config.method, config.url, timestamp, secret, '');
86 | config.headers = {
87 | "OK-ACCESS-SIGN": sign,
88 | "OK-ACCESS-TIMESTAMP": timestamp,
89 | ...headers,
90 | };
91 | return request(config)
92 | }
93 |
94 | /**
95 | * 获取充值地址
96 | * @param {*} param
97 | * @param {*} headers
98 | * @param {*} secret
99 | * @returns
100 | */
101 | function getDepositAddr(param, headers, secret) {
102 | config.method = 'get';
103 | config.url = '/api/v5/asset/deposit-address?ccy=' + param;
104 | const timestamp = new Date().toISOString();
105 | const sign = getOkSign(config.method, config.url, timestamp, secret, '');
106 | config.headers = {
107 | "OK-ACCESS-SIGN": sign,
108 | "OK-ACCESS-TIMESTAMP": timestamp,
109 | ...headers,
110 | };
111 | return request(config)
112 | }
113 |
114 |
115 | export default {
116 | getBalance,
117 | getCcyList,
118 | withdrawal,
119 | getDepositHis,
120 | getDepositAddr,
121 | }
122 |
123 |
--------------------------------------------------------------------------------
/src/request/request.js:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 |
3 | export function request(config) {
4 | const service = axios.create({
5 | timeout: 5000,
6 | })
7 |
8 | service.interceptors.request.use(config => {
9 | return config;
10 | },
11 | err => {
12 | console.log(err);
13 | return Promise.reject();
14 | })
15 |
16 | service.interceptors.response.use(res => {
17 | return res.data;
18 | },
19 | err => {
20 | console.log(err);
21 | return Promise.reject();
22 | })
23 |
24 | return service(config);
25 | }
--------------------------------------------------------------------------------
/src/router/router.js:
--------------------------------------------------------------------------------
1 | import { createRouter, createWebHashHistory } from "vue-router";
2 | import OKXContainer from "@/view/OKXContainer.vue";
3 | import Home from "@/view/Home.vue";
4 |
5 | const routes = [
6 | {
7 | path: "/",
8 | component: Home,
9 | name: "Home",
10 | children: [
11 | {
12 | path: "/exchange/okx",
13 | name: "OKXContainer",
14 | component: OKXContainer,
15 |
16 | },
17 | ]
18 | },
19 |
20 | ];
21 |
22 | const router = createRouter({
23 | history: createWebHashHistory(),
24 | routes,
25 | });
26 |
27 | export default router;
28 |
--------------------------------------------------------------------------------
/src/utils/DateUtils.js:
--------------------------------------------------------------------------------
1 | export default {
2 | /**
3 | * 暂停运行
4 | * @param {*number} ms
5 | * @returns
6 | */
7 | sleep(ms) {
8 | return new Promise(resolve => setTimeout(resolve, ms));
9 | },
10 |
11 | /**
12 | * 格式化时间
13 | * @param {*Date} dateTime
14 | * @returns
15 | */
16 | formatDateTime(dateTime) {
17 | let Y = dateTime.getFullYear();
18 | let M = (dateTime.getMonth() + 1 < 10 ? '0' + (dateTime.getMonth() + 1) : dateTime.getMonth() + 1);
19 | let D = (dateTime.getDate() < 10 ? '0' + dateTime.getDate() : dateTime.getDate());
20 | let h = (dateTime.getHours() < 10 ? '0' + dateTime.getHours() : dateTime.getHours());
21 | let m = (dateTime.getMinutes() < 10 ? '0' + dateTime.getMinutes() : dateTime.getMinutes());
22 | let s = (dateTime.getSeconds() < 10 ? '0' + dateTime.getSeconds() : dateTime.getSeconds());
23 | let ms = dateTime.getMilliseconds();
24 | let strDate = `${Y}/${M}/${D} ${h}:${m}:${s}:${ms}`;
25 | return strDate;
26 | },
27 | }
--------------------------------------------------------------------------------
/src/utils/NumberUtils.js:
--------------------------------------------------------------------------------
1 | export default {
2 | floatRate10: function() {
3 | return (1 + (Math.random() / 10)).toFixed(2);
4 | },
5 |
6 | floatRate: function(num) {
7 | return (1 + (Math.random() * num)).toFixed(2);
8 | },
9 |
10 | getRandomNum12: function() {
11 | const timestamp = Date.now().toString().slice(-8); // 获取后8位时间戳
12 | const randomPart = Math.floor(Math.random() * 10000).toString().padStart(4, '0'); // 生成4位随机数
13 |
14 | return timestamp + randomPart;
15 | },
16 | }
--------------------------------------------------------------------------------
/src/view/Home.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
34 |
35 |
--------------------------------------------------------------------------------
/src/view/OKXContainer.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
26 |
27 |
35 |
--------------------------------------------------------------------------------
/src/view/exchange/OKXWithdraw.vue:
--------------------------------------------------------------------------------
1 |
2 | 交易所配置
3 |
4 | API KEY
5 |
8 |
9 | secret
10 |
13 |
14 | password
15 |
18 |
19 | 间隔时常(秒) :
20 |
23 |
24 |
25 |
26 | 资金分发配置
27 |
28 |
29 | 资金分发
30 |
31 |
32 |
37 |
38 | 1.确认提币网络字段准确
39 |
40 | 2.确保余额充足
41 |
42 | 3.间隔时间上浮0~0.5倍
43 |
44 | 使用说明
45 |
46 |
47 |
48 |
49 |
50 |
56 |
57 |
58 | 资金发放日志
59 |
60 |
61 |
62 |
63 |
64 |
65 |
362 |
--------------------------------------------------------------------------------
/vue.config.js:
--------------------------------------------------------------------------------
1 | const { defineConfig } = require('@vue/cli-service')
2 | module.exports = defineConfig({
3 | transpileDependencies: true,
4 | publicPath: './',
5 | outputDir: 'dist',
6 | indexPath: 'index.html',
7 | lintOnSave: false,
8 | })
9 |
--------------------------------------------------------------------------------