@yuants/app-virtual-exchange 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/credential.js +58 -0
- package/dist/credential.js.map +1 -0
- package/dist/general.js +88 -0
- package/dist/general.js.map +1 -0
- package/dist/index.js +3 -146
- package/dist/index.js.map +1 -1
- package/dist/legacy-services.js +94 -0
- package/dist/legacy-services.js.map +1 -0
- package/lib/credential.d.ts +16 -0
- package/lib/credential.d.ts.map +1 -0
- package/lib/credential.js +63 -0
- package/lib/credential.js.map +1 -0
- package/lib/general.d.ts +2 -0
- package/lib/general.d.ts.map +1 -0
- package/lib/general.js +90 -0
- package/lib/general.js.map +1 -0
- package/lib/index.d.ts +3 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +3 -146
- package/lib/index.js.map +1 -1
- package/lib/legacy-services.d.ts +2 -0
- package/lib/legacy-services.d.ts.map +1 -0
- package/lib/legacy-services.js +96 -0
- package/lib/legacy-services.js.map +1 -0
- package/package.json +3 -1
- package/temp/package-deps.json +10 -5
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { getCredentialId } from '@yuants/exchange';
|
|
2
|
+
import { Terminal } from '@yuants/protocol';
|
|
3
|
+
import { readSecret, writeSecret } from '@yuants/secret';
|
|
4
|
+
import { escapeSQL, requestSQL } from '@yuants/sql';
|
|
5
|
+
import { defer, firstValueFrom, map, repeat, retry, shareReplay } from 'rxjs';
|
|
6
|
+
const terminal = Terminal.fromNodeEnv();
|
|
7
|
+
export const listAllCredentials = async () => {
|
|
8
|
+
const secrets = await requestSQL(terminal, `select * from secret where tags->>'type' = 'exchange_credential' and reader = ${escapeSQL(terminal.keyPair.public_key)}`);
|
|
9
|
+
const results = secrets.map((secret) => ({ secret }));
|
|
10
|
+
await Promise.all(results.map(async (result) => {
|
|
11
|
+
try {
|
|
12
|
+
const decrypted = await readSecret(terminal, result.secret);
|
|
13
|
+
const credential = JSON.parse(new TextDecoder().decode(decrypted));
|
|
14
|
+
result.credential = credential;
|
|
15
|
+
const res = await getCredentialId(terminal, credential);
|
|
16
|
+
const credentialId = res.data;
|
|
17
|
+
result.credentialId = credentialId;
|
|
18
|
+
}
|
|
19
|
+
catch (e) {
|
|
20
|
+
result.reason = `${e}`;
|
|
21
|
+
}
|
|
22
|
+
}));
|
|
23
|
+
return results;
|
|
24
|
+
};
|
|
25
|
+
terminal.server.provideService('VEX/RegisterExchangeCredential', {
|
|
26
|
+
type: 'object',
|
|
27
|
+
required: ['type', 'payload'],
|
|
28
|
+
properties: {
|
|
29
|
+
type: { type: 'string' },
|
|
30
|
+
payload: { type: 'object' },
|
|
31
|
+
},
|
|
32
|
+
}, async (msg) => {
|
|
33
|
+
const credential = msg.req;
|
|
34
|
+
const secretData = new TextEncoder().encode(JSON.stringify(credential));
|
|
35
|
+
await writeSecret(terminal, terminal.keyPair.public_key, { type: 'exchange_credential' }, secretData);
|
|
36
|
+
return { res: { code: 0, message: 'OK' } };
|
|
37
|
+
});
|
|
38
|
+
terminal.server.provideService('VEX/ListExchangeCredential', {}, async () => {
|
|
39
|
+
return { res: { code: 0, message: 'OK', data: await listAllCredentials() } };
|
|
40
|
+
});
|
|
41
|
+
terminal.server.provideService('VEX/ListCredentials', {}, async () => {
|
|
42
|
+
const credentials = await firstValueFrom(validCredentials$);
|
|
43
|
+
return { res: { code: 0, message: 'OK', data: [...credentials.keys()] } };
|
|
44
|
+
});
|
|
45
|
+
export const validCredentials$ = defer(() => listAllCredentials()).pipe(map((x) => {
|
|
46
|
+
const map = new Map();
|
|
47
|
+
for (const xx of x) {
|
|
48
|
+
if (xx.credentialId && xx.credential) {
|
|
49
|
+
map.set(xx.credentialId, xx.credential);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return map;
|
|
53
|
+
}), repeat({ delay: 10000 }), retry({ delay: 5000 }), shareReplay(1));
|
|
54
|
+
export const getCredentialById = async (credential_id) => {
|
|
55
|
+
const credentials = await firstValueFrom(validCredentials$);
|
|
56
|
+
return credentials.get(credential_id);
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=credential.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential.js","sourceRoot":"","sources":["../src/credential.ts"],"names":[],"mappings":"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","sourcesContent":["import { getCredentialId } from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { ISecret, readSecret, writeSecret } from '@yuants/secret';\nimport { escapeSQL, requestSQL } from '@yuants/sql';\nimport { defer, firstValueFrom, map, repeat, retry, shareReplay } from 'rxjs';\n\nexport interface IExchangeCredential {\n type: string;\n payload: any;\n}\n\nconst terminal = Terminal.fromNodeEnv();\n\ninterface ICredentialResolvedStatus {\n secret: ISecret;\n credential?: IExchangeCredential;\n credentialId?: string;\n reason?: string;\n}\n\nexport const listAllCredentials = async () => {\n const secrets = await requestSQL<ISecret[]>(\n terminal,\n `select * from secret where tags->>'type' = 'exchange_credential' and reader = ${escapeSQL(\n terminal.keyPair.public_key,\n )}`,\n );\n\n const results = secrets.map((secret): ICredentialResolvedStatus => ({ secret }));\n\n await Promise.all(\n results.map(async (result) => {\n try {\n const decrypted = await readSecret(terminal, result.secret);\n const credential = JSON.parse(new TextDecoder().decode(decrypted)) as IExchangeCredential;\n result.credential = credential;\n\n const res = await getCredentialId(terminal, credential);\n const credentialId = res.data;\n result.credentialId = credentialId;\n } catch (e) {\n result.reason = `${e}`;\n }\n }),\n );\n\n return results;\n};\n\nterminal.server.provideService<IExchangeCredential, void>(\n 'VEX/RegisterExchangeCredential',\n {\n type: 'object',\n required: ['type', 'payload'],\n properties: {\n type: { type: 'string' },\n payload: { type: 'object' },\n },\n },\n async (msg) => {\n const credential = msg.req;\n const secretData = new TextEncoder().encode(JSON.stringify(credential));\n await writeSecret(terminal, terminal.keyPair.public_key, { type: 'exchange_credential' }, secretData);\n return { res: { code: 0, message: 'OK' } };\n },\n);\n\nterminal.server.provideService<void, ICredentialResolvedStatus[]>(\n 'VEX/ListExchangeCredential',\n {},\n async () => {\n return { res: { code: 0, message: 'OK', data: await listAllCredentials() } };\n },\n);\n\nterminal.server.provideService<void, string[]>('VEX/ListCredentials', {}, async () => {\n const credentials = await firstValueFrom(validCredentials$);\n return { res: { code: 0, message: 'OK', data: [...credentials.keys()] } };\n});\n\nexport const validCredentials$ = defer(() => listAllCredentials()).pipe(\n map((x) => {\n const map = new Map<string, IExchangeCredential>();\n for (const xx of x) {\n if (xx.credentialId && xx.credential) {\n map.set(xx.credentialId, xx.credential);\n }\n }\n return map;\n }),\n repeat({ delay: 10000 }),\n retry({ delay: 5000 }),\n shareReplay(1),\n);\n\nexport const getCredentialById = async (credential_id: string) => {\n const credentials = await firstValueFrom(validCredentials$);\n return credentials.get(credential_id);\n};\n"]}
|
package/dist/general.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { cancelOrder, getOrders, getPositions, modifyOrder, submitOrder } from '@yuants/exchange';
|
|
2
|
+
import { Terminal } from '@yuants/protocol';
|
|
3
|
+
import { getCredentialById } from './credential';
|
|
4
|
+
const terminal = Terminal.fromNodeEnv();
|
|
5
|
+
terminal.server.provideService('VEX/GetPositions', {
|
|
6
|
+
type: 'object',
|
|
7
|
+
required: ['credential_id'],
|
|
8
|
+
properties: {
|
|
9
|
+
credential_id: { type: 'string' },
|
|
10
|
+
product_id: { type: 'string' },
|
|
11
|
+
},
|
|
12
|
+
}, async (msg) => {
|
|
13
|
+
const credential = await getCredentialById(msg.req.credential_id);
|
|
14
|
+
if (!credential) {
|
|
15
|
+
return { res: { code: 404, message: 'Credential not found' } };
|
|
16
|
+
}
|
|
17
|
+
const res = await getPositions(terminal, credential, msg.req.product_id);
|
|
18
|
+
return { res };
|
|
19
|
+
});
|
|
20
|
+
terminal.server.provideService('VEX/GetOrders', {
|
|
21
|
+
type: 'object',
|
|
22
|
+
required: ['credential_id'],
|
|
23
|
+
properties: {
|
|
24
|
+
credential_id: { type: 'string' },
|
|
25
|
+
product_id: { type: 'string' },
|
|
26
|
+
},
|
|
27
|
+
}, async (msg) => {
|
|
28
|
+
var _a;
|
|
29
|
+
const credential = await getCredentialById(msg.req.credential_id);
|
|
30
|
+
if (!credential) {
|
|
31
|
+
return { res: { code: 404, message: 'Credential not found' } };
|
|
32
|
+
}
|
|
33
|
+
const res = await getOrders(terminal, credential, msg.req.product_id);
|
|
34
|
+
(_a = res.data) === null || _a === void 0 ? void 0 : _a.forEach((order) => {
|
|
35
|
+
order.account_id = msg.req.credential_id;
|
|
36
|
+
});
|
|
37
|
+
return { res };
|
|
38
|
+
});
|
|
39
|
+
// 10. Proxy Orders
|
|
40
|
+
// SubmitOrder
|
|
41
|
+
terminal.server.provideService('VEX/SubmitOrder', {
|
|
42
|
+
type: 'object',
|
|
43
|
+
required: ['order', 'credential_id'],
|
|
44
|
+
properties: {
|
|
45
|
+
order: { type: 'object' },
|
|
46
|
+
credential_id: { type: 'string' },
|
|
47
|
+
},
|
|
48
|
+
}, async (msg) => {
|
|
49
|
+
const credential = await getCredentialById(msg.req.credential_id);
|
|
50
|
+
if (!credential) {
|
|
51
|
+
return { res: { code: 404, message: 'Credential not found' } };
|
|
52
|
+
}
|
|
53
|
+
const res = await submitOrder(terminal, credential, msg.req.order);
|
|
54
|
+
return { res };
|
|
55
|
+
});
|
|
56
|
+
// ModifyOrder
|
|
57
|
+
terminal.server.provideService('VEX/ModifyOrder', {
|
|
58
|
+
type: 'object',
|
|
59
|
+
required: ['order', 'credential_id'],
|
|
60
|
+
properties: {
|
|
61
|
+
order: { type: 'object' },
|
|
62
|
+
credential_id: { type: 'string' },
|
|
63
|
+
},
|
|
64
|
+
}, async (msg) => {
|
|
65
|
+
const credential = await getCredentialById(msg.req.credential_id);
|
|
66
|
+
if (!credential) {
|
|
67
|
+
return { res: { code: 404, message: 'Credential not found' } };
|
|
68
|
+
}
|
|
69
|
+
const res = await modifyOrder(terminal, credential, msg.req.order);
|
|
70
|
+
return { res };
|
|
71
|
+
});
|
|
72
|
+
// CancelOrder
|
|
73
|
+
terminal.server.provideService('VEX/CancelOrder', {
|
|
74
|
+
type: 'object',
|
|
75
|
+
required: ['order', 'credential_id'],
|
|
76
|
+
properties: {
|
|
77
|
+
order: { type: 'object' },
|
|
78
|
+
credential_id: { type: 'string' },
|
|
79
|
+
},
|
|
80
|
+
}, async (msg) => {
|
|
81
|
+
const credential = await getCredentialById(msg.req.credential_id);
|
|
82
|
+
if (!credential) {
|
|
83
|
+
return { res: { code: 404, message: 'Credential not found' } };
|
|
84
|
+
}
|
|
85
|
+
const res = await cancelOrder(terminal, credential, msg.req.order);
|
|
86
|
+
return { res };
|
|
87
|
+
});
|
|
88
|
+
//# sourceMappingURL=general.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"general.js","sourceRoot":"","sources":["../src/general.ts"],"names":[],"mappings":"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","sourcesContent":["import { IPosition } from '@yuants/data-account';\nimport { IOrder } from '@yuants/data-order';\nimport { cancelOrder, getOrders, getPositions, modifyOrder, submitOrder } from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { getCredentialById } from './credential';\n\nconst terminal = Terminal.fromNodeEnv();\n\nterminal.server.provideService<{ credential_id: string; product_id?: string }, IPosition[]>(\n 'VEX/GetPositions',\n {\n type: 'object',\n required: ['credential_id'],\n properties: {\n credential_id: { type: 'string' },\n product_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = await getCredentialById(msg.req.credential_id);\n if (!credential) {\n return { res: { code: 404, message: 'Credential not found' } };\n }\n const res = await getPositions(terminal, credential, msg.req.product_id);\n return { res };\n },\n);\n\nterminal.server.provideService<{ credential_id: string; product_id?: string }, IOrder[]>(\n 'VEX/GetOrders',\n {\n type: 'object',\n required: ['credential_id'],\n properties: {\n credential_id: { type: 'string' },\n product_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = await getCredentialById(msg.req.credential_id);\n if (!credential) {\n return { res: { code: 404, message: 'Credential not found' } };\n }\n const res = await getOrders(terminal, credential, msg.req.product_id);\n res.data?.forEach((order) => {\n order.account_id = msg.req.credential_id;\n });\n return { res };\n },\n);\n\n// 10. Proxy Orders\n// SubmitOrder\nterminal.server.provideService<{ order: IOrder; credential_id: string }, { order_id: string }>(\n 'VEX/SubmitOrder',\n {\n type: 'object',\n required: ['order', 'credential_id'],\n properties: {\n order: { type: 'object' },\n credential_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = await getCredentialById(msg.req.credential_id);\n if (!credential) {\n return { res: { code: 404, message: 'Credential not found' } };\n }\n const res = await submitOrder(terminal, credential, msg.req.order);\n return { res };\n },\n);\n\n// ModifyOrder\nterminal.server.provideService<{ order: IOrder; credential_id: string }, void>(\n 'VEX/ModifyOrder',\n {\n type: 'object',\n required: ['order', 'credential_id'],\n properties: {\n order: { type: 'object' },\n credential_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = await getCredentialById(msg.req.credential_id);\n if (!credential) {\n return { res: { code: 404, message: 'Credential not found' } };\n }\n const res = await modifyOrder(terminal, credential, msg.req.order);\n return { res };\n },\n);\n\n// CancelOrder\nterminal.server.provideService<{ order: IOrder; credential_id: string }, void>(\n 'VEX/CancelOrder',\n {\n type: 'object',\n required: ['order', 'credential_id'],\n properties: {\n order: { type: 'object' },\n credential_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = await getCredentialById(msg.req.credential_id);\n if (!credential) {\n return { res: { code: 404, message: 'Credential not found' } };\n }\n const res = await cancelOrder(terminal, credential, msg.req.order);\n return { res };\n },\n);\n"]}
|
package/dist/index.js
CHANGED
|
@@ -1,147 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import { defer, mergeMap, retry, timer } from 'rxjs';
|
|
5
|
-
const terminal = Terminal.fromNodeEnv();
|
|
6
|
-
const mapCredentialIdToCredential = new Map();
|
|
7
|
-
// 1. RegisterExchangeCredential
|
|
8
|
-
terminal.server.provideService('VirtualExchange/RegisterExchangeCredential', {
|
|
9
|
-
type: 'object',
|
|
10
|
-
required: ['type', 'payload'],
|
|
11
|
-
properties: {
|
|
12
|
-
type: { type: 'string' },
|
|
13
|
-
payload: { type: 'object' },
|
|
14
|
-
},
|
|
15
|
-
}, async (msg) => {
|
|
16
|
-
const credential = msg.req;
|
|
17
|
-
const secretData = new TextEncoder().encode(JSON.stringify(credential));
|
|
18
|
-
await writeSecret(terminal, terminal.keyPair.public_key, { type: 'exchange_credential' }, secretData);
|
|
19
|
-
return { res: { code: 0, message: 'OK' } };
|
|
20
|
-
});
|
|
21
|
-
// 2. ListExchangeCredential
|
|
22
|
-
terminal.server.provideService('VirtualExchange/ListExchangeCredential', {}, async () => {
|
|
23
|
-
const secrets = await requestSQL(terminal, `select * from secret where tags->>'type' = 'exchange_credential' and reader = ${escapeSQL(terminal.keyPair.public_key)}`);
|
|
24
|
-
const credentials = [];
|
|
25
|
-
for (const secret of secrets) {
|
|
26
|
-
try {
|
|
27
|
-
const decrypted = await readSecret(terminal, secret);
|
|
28
|
-
const credential = JSON.parse(new TextDecoder().decode(decrypted));
|
|
29
|
-
credentials.push(credential);
|
|
30
|
-
}
|
|
31
|
-
catch (e) {
|
|
32
|
-
console.error('Failed to decrypt secret', e);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
return { res: { code: 0, message: 'OK', data: credentials } };
|
|
36
|
-
});
|
|
37
|
-
terminal.server.provideService('VirtualExchange/ListCredentials', {}, async () => {
|
|
38
|
-
return { res: { code: 0, message: 'OK', data: [...mapCredentialIdToCredential.keys()] } };
|
|
39
|
-
});
|
|
40
|
-
// 9. Background listWatch
|
|
41
|
-
const updateIndex = async () => {
|
|
42
|
-
const secrets = await requestSQL(terminal, `select * from secret where tags->>'type' = 'exchange_credential' and reader = ${escapeSQL(terminal.keyPair.public_key)}`);
|
|
43
|
-
for (const secret of secrets) {
|
|
44
|
-
try {
|
|
45
|
-
const decrypted = await readSecret(terminal, secret);
|
|
46
|
-
const credential = JSON.parse(new TextDecoder().decode(decrypted));
|
|
47
|
-
// Call GetCredentialId to get credential id
|
|
48
|
-
const res = await terminal.client.requestForResponse('GetCredentialId', { credential });
|
|
49
|
-
if (res.code === 0 && res.data) {
|
|
50
|
-
const credentialId = res.data;
|
|
51
|
-
mapCredentialIdToCredential.set(credentialId, credential);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
catch (e) {
|
|
55
|
-
console.error('Failed to process secret', e);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
// Run updateIndex periodically
|
|
60
|
-
timer(0, 60000)
|
|
61
|
-
.pipe(mergeMap(() => defer(updateIndex).pipe(retry({ delay: 5000 }))))
|
|
62
|
-
.subscribe();
|
|
63
|
-
// 8. QueryAccountInfo
|
|
64
|
-
terminal.server.provideService('VirtualExchange/QueryPositions', {
|
|
65
|
-
type: 'object',
|
|
66
|
-
required: ['credential_id'],
|
|
67
|
-
properties: {
|
|
68
|
-
credential_id: { type: 'string' },
|
|
69
|
-
product_id: { type: 'string' },
|
|
70
|
-
},
|
|
71
|
-
}, async (msg) => {
|
|
72
|
-
const credential = mapCredentialIdToCredential.get(msg.req.credential_id);
|
|
73
|
-
if (!credential) {
|
|
74
|
-
return { res: { code: 404, message: 'Credential not found' } };
|
|
75
|
-
}
|
|
76
|
-
const res = await terminal.client.requestForResponse('QueryPositions', { credential, product_id: msg.req.product_id });
|
|
77
|
-
return { res };
|
|
78
|
-
});
|
|
79
|
-
terminal.server.provideService('VirtualExchange/QueryOrders', {
|
|
80
|
-
type: 'object',
|
|
81
|
-
required: ['credential_id'],
|
|
82
|
-
properties: {
|
|
83
|
-
credential_id: { type: 'string' },
|
|
84
|
-
product_id: { type: 'string' },
|
|
85
|
-
},
|
|
86
|
-
}, async (msg) => {
|
|
87
|
-
const credential = mapCredentialIdToCredential.get(msg.req.credential_id);
|
|
88
|
-
if (!credential) {
|
|
89
|
-
return { res: { code: 404, message: 'Credential not found' } };
|
|
90
|
-
}
|
|
91
|
-
const res = await terminal.client.requestForResponse('QueryOrders', {
|
|
92
|
-
credential,
|
|
93
|
-
product_id: msg.req.product_id,
|
|
94
|
-
});
|
|
95
|
-
return { res };
|
|
96
|
-
});
|
|
97
|
-
// 10. Proxy Orders
|
|
98
|
-
// SubmitOrder
|
|
99
|
-
terminal.server.provideService('VirtualExchange/SubmitOrder', {
|
|
100
|
-
type: 'object',
|
|
101
|
-
required: ['order', 'credential_id'],
|
|
102
|
-
properties: {
|
|
103
|
-
order: { type: 'object' },
|
|
104
|
-
credential_id: { type: 'string' },
|
|
105
|
-
},
|
|
106
|
-
}, async (msg) => {
|
|
107
|
-
const credential = mapCredentialIdToCredential.get(msg.req.credential_id);
|
|
108
|
-
if (!credential) {
|
|
109
|
-
return { res: { code: 404, message: 'Credential not found' } };
|
|
110
|
-
}
|
|
111
|
-
const res = await terminal.client.requestForResponse('SubmitOrder', { credential, order: msg.req.order });
|
|
112
|
-
return { res };
|
|
113
|
-
});
|
|
114
|
-
// ModifyOrder
|
|
115
|
-
terminal.server.provideService('VirtualExchange/ModifyOrder', {
|
|
116
|
-
type: 'object',
|
|
117
|
-
required: ['order', 'credential_id'],
|
|
118
|
-
properties: {
|
|
119
|
-
order: { type: 'object' },
|
|
120
|
-
credential_id: { type: 'string' },
|
|
121
|
-
},
|
|
122
|
-
}, async (msg) => {
|
|
123
|
-
const credential = mapCredentialIdToCredential.get(msg.req.credential_id);
|
|
124
|
-
if (!credential) {
|
|
125
|
-
return { res: { code: 404, message: 'Credential not found' } };
|
|
126
|
-
}
|
|
127
|
-
const res = await terminal.client.requestForResponse('ModifyOrder', { credential, order: msg.req.order });
|
|
128
|
-
return { res };
|
|
129
|
-
});
|
|
130
|
-
// CancelOrder
|
|
131
|
-
terminal.server.provideService('VirtualExchange/CancelOrder', {
|
|
132
|
-
type: 'object',
|
|
133
|
-
required: ['order', 'credential_id'],
|
|
134
|
-
properties: {
|
|
135
|
-
order: { type: 'object' },
|
|
136
|
-
credential_id: { type: 'string' },
|
|
137
|
-
},
|
|
138
|
-
}, async (msg) => {
|
|
139
|
-
const credential = mapCredentialIdToCredential.get(msg.req.credential_id);
|
|
140
|
-
if (!credential) {
|
|
141
|
-
return { res: { code: 404, message: 'Credential not found' } };
|
|
142
|
-
}
|
|
143
|
-
const res = await terminal.client.requestForResponse('CancelOrder', { credential, order: msg.req.order });
|
|
144
|
-
return { res };
|
|
145
|
-
});
|
|
146
|
-
// ListOrders
|
|
1
|
+
import './legacy-services';
|
|
2
|
+
import './credential';
|
|
3
|
+
import './general';
|
|
147
4
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { IAccountInfo } from '@yuants/data-account';\nimport { IOrder, ITypedCredential } from '@yuants/data-order';\nimport { Terminal } from '@yuants/protocol';\nimport { ISecret, readSecret, writeSecret } from '@yuants/secret';\nimport { escapeSQL, requestSQL } from '@yuants/sql';\nimport { defer, mergeMap, retry, timer } from 'rxjs';\n\nconst terminal = Terminal.fromNodeEnv();\n\ninterface IExchangeCredential {\n type: string;\n payload: any;\n}\n\nconst mapCredentialIdToCredential = new Map<string, IExchangeCredential>();\n\n// 1. RegisterExchangeCredential\nterminal.server.provideService<IExchangeCredential, void>(\n 'VirtualExchange/RegisterExchangeCredential',\n {\n type: 'object',\n required: ['type', 'payload'],\n properties: {\n type: { type: 'string' },\n payload: { type: 'object' },\n },\n },\n async (msg) => {\n const credential = msg.req;\n const secretData = new TextEncoder().encode(JSON.stringify(credential));\n await writeSecret(terminal, terminal.keyPair.public_key, { type: 'exchange_credential' }, secretData);\n return { res: { code: 0, message: 'OK' } };\n },\n);\n\n// 2. ListExchangeCredential\nterminal.server.provideService<void, IExchangeCredential[]>(\n 'VirtualExchange/ListExchangeCredential',\n {},\n async () => {\n const secrets = await requestSQL<ISecret[]>(\n terminal,\n `select * from secret where tags->>'type' = 'exchange_credential' and reader = ${escapeSQL(\n terminal.keyPair.public_key,\n )}`,\n );\n const credentials: IExchangeCredential[] = [];\n for (const secret of secrets) {\n try {\n const decrypted = await readSecret(terminal, secret);\n const credential = JSON.parse(new TextDecoder().decode(decrypted));\n credentials.push(credential);\n } catch (e) {\n console.error('Failed to decrypt secret', e);\n }\n }\n return { res: { code: 0, message: 'OK', data: credentials } };\n },\n);\n\nterminal.server.provideService<void, string[]>('VirtualExchange/ListCredentials', {}, async () => {\n return { res: { code: 0, message: 'OK', data: [...mapCredentialIdToCredential.keys()] } };\n});\n\n// 9. Background listWatch\nconst updateIndex = async () => {\n const secrets = await requestSQL<ISecret[]>(\n terminal,\n `select * from secret where tags->>'type' = 'exchange_credential' and reader = ${escapeSQL(\n terminal.keyPair.public_key,\n )}`,\n );\n for (const secret of secrets) {\n try {\n const decrypted = await readSecret(terminal, secret);\n const credential = JSON.parse(new TextDecoder().decode(decrypted)) as IExchangeCredential;\n\n // Call GetCredentialId to get credential id\n const res = await terminal.client.requestForResponse<{ credential: ITypedCredential<any> }, string>(\n 'GetCredentialId',\n { credential },\n );\n\n if (res.code === 0 && res.data) {\n const credentialId = res.data;\n mapCredentialIdToCredential.set(credentialId, credential);\n }\n } catch (e) {\n console.error('Failed to process secret', e);\n }\n }\n};\n\n// Run updateIndex periodically\ntimer(0, 60000)\n .pipe(mergeMap(() => defer(updateIndex).pipe(retry({ delay: 5000 }))))\n .subscribe();\n\n// 8. QueryAccountInfo\nterminal.server.provideService<{ credential_id: string; product_id?: string }, IAccountInfo>(\n 'VirtualExchange/QueryPositions',\n {\n type: 'object',\n required: ['credential_id'],\n properties: {\n credential_id: { type: 'string' },\n product_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = mapCredentialIdToCredential.get(msg.req.credential_id);\n if (!credential) {\n return { res: { code: 404, message: 'Credential not found' } };\n }\n const res = await terminal.client.requestForResponse<\n { credential: ITypedCredential<any>; product_id?: string },\n IAccountInfo\n >('QueryPositions', { credential, product_id: msg.req.product_id });\n return { res };\n },\n);\n\nterminal.server.provideService<{ credential_id: string; product_id?: string }, { orders: IOrder[] }>(\n 'VirtualExchange/QueryOrders',\n {\n type: 'object',\n required: ['credential_id'],\n properties: {\n credential_id: { type: 'string' },\n product_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = mapCredentialIdToCredential.get(msg.req.credential_id);\n if (!credential) {\n return { res: { code: 404, message: 'Credential not found' } };\n }\n const res = await terminal.client.requestForResponse<\n { credential: ITypedCredential<any>; product_id?: string },\n { orders: IOrder[] }\n >('QueryOrders', {\n credential,\n product_id: msg.req.product_id,\n });\n return { res };\n },\n);\n\n// 10. Proxy Orders\n// SubmitOrder\nterminal.server.provideService<{ order: IOrder; credential_id: string }, { order_id: string }>(\n 'VirtualExchange/SubmitOrder',\n {\n type: 'object',\n required: ['order', 'credential_id'],\n properties: {\n order: { type: 'object' },\n credential_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = mapCredentialIdToCredential.get(msg.req.credential_id);\n if (!credential) {\n return { res: { code: 404, message: 'Credential not found' } };\n }\n const res = await terminal.client.requestForResponse<\n { credential: ITypedCredential<any>; order: IOrder },\n { order_id: string }\n >('SubmitOrder', { credential, order: msg.req.order });\n return { res };\n },\n);\n\n// ModifyOrder\nterminal.server.provideService<{ order: IOrder; credential_id: string }, void>(\n 'VirtualExchange/ModifyOrder',\n {\n type: 'object',\n required: ['order', 'credential_id'],\n properties: {\n order: { type: 'object' },\n credential_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = mapCredentialIdToCredential.get(msg.req.credential_id);\n if (!credential) {\n return { res: { code: 404, message: 'Credential not found' } };\n }\n const res = await terminal.client.requestForResponse<\n { credential: ITypedCredential<any>; order: IOrder },\n void\n >('ModifyOrder', { credential, order: msg.req.order });\n return { res };\n },\n);\n\n// CancelOrder\nterminal.server.provideService<{ order: IOrder; credential_id: string }, void>(\n 'VirtualExchange/CancelOrder',\n {\n type: 'object',\n required: ['order', 'credential_id'],\n properties: {\n order: { type: 'object' },\n credential_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = mapCredentialIdToCredential.get(msg.req.credential_id);\n if (!credential) {\n return { res: { code: 404, message: 'Credential not found' } };\n }\n const res = await terminal.client.requestForResponse<\n { credential: ITypedCredential<any>; order: IOrder },\n void\n >('CancelOrder', { credential, order: msg.req.order });\n return { res };\n },\n);\n\n// ListOrders\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,mBAAmB,CAAC;AAC3B,OAAO,cAAc,CAAC;AACtB,OAAO,WAAW,CAAC","sourcesContent":["import './legacy-services';\nimport './credential';\nimport './general';\n"]}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { provideAccountInfoService } from '@yuants/data-account';
|
|
2
|
+
import { providePendingOrdersService } from '@yuants/data-order';
|
|
3
|
+
import { cancelOrder, getOrders, getPositions, modifyOrder, submitOrder } from '@yuants/exchange';
|
|
4
|
+
import { Terminal } from '@yuants/protocol';
|
|
5
|
+
import { listWatch, newError } from '@yuants/utils';
|
|
6
|
+
import { map, Observable } from 'rxjs';
|
|
7
|
+
import { validCredentials$ } from './credential';
|
|
8
|
+
const terminal = Terminal.fromNodeEnv();
|
|
9
|
+
validCredentials$
|
|
10
|
+
.pipe(map((x) => Array.from(x.entries())), listWatch(([id]) => id, ([credential_id, credential]) => new Observable((sub) => {
|
|
11
|
+
console.info(`Setting up VEX services for credential: ${credential_id}`);
|
|
12
|
+
// Setup AccountInfo Service
|
|
13
|
+
{
|
|
14
|
+
const service = provideAccountInfoService(terminal, credential_id, async () => {
|
|
15
|
+
const res = await getPositions(terminal, credential);
|
|
16
|
+
if (res.code === 0 && res.data) {
|
|
17
|
+
return res.data;
|
|
18
|
+
}
|
|
19
|
+
throw newError('FETCH_POSITIONS_FAILED', { credential_id, reason: res.message });
|
|
20
|
+
}, {
|
|
21
|
+
auto_refresh_interval: 1000,
|
|
22
|
+
});
|
|
23
|
+
sub.add(() => {
|
|
24
|
+
service.dispose$.next();
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
// Setup Pending Orders Service
|
|
28
|
+
{
|
|
29
|
+
const service = providePendingOrdersService(terminal, credential_id, async () => {
|
|
30
|
+
const res = await getOrders(terminal, credential);
|
|
31
|
+
if (!res.data)
|
|
32
|
+
throw newError('FETCH_ORDERS_FAILED', { credential_id, res });
|
|
33
|
+
res.data.forEach((order) => {
|
|
34
|
+
order.account_id = credential_id;
|
|
35
|
+
});
|
|
36
|
+
return res.data;
|
|
37
|
+
}, {
|
|
38
|
+
auto_refresh_interval: 1000,
|
|
39
|
+
});
|
|
40
|
+
sub.add(() => {
|
|
41
|
+
service.dispose$.next();
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
// Setup SubmitOrder Service
|
|
45
|
+
{
|
|
46
|
+
const service = terminal.server.provideService('SubmitOrder', {
|
|
47
|
+
type: 'object',
|
|
48
|
+
required: ['account_id'],
|
|
49
|
+
properties: {
|
|
50
|
+
account_id: { type: 'string', const: credential_id },
|
|
51
|
+
},
|
|
52
|
+
}, async (msg) => {
|
|
53
|
+
const res = await submitOrder(terminal, credential, msg.req);
|
|
54
|
+
return { res };
|
|
55
|
+
});
|
|
56
|
+
sub.add(() => {
|
|
57
|
+
service.dispose();
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
// Setup ModifyOrder Service
|
|
61
|
+
{
|
|
62
|
+
const service = terminal.server.provideService('ModifyOrder', {
|
|
63
|
+
type: 'object',
|
|
64
|
+
required: ['account_id'],
|
|
65
|
+
properties: {
|
|
66
|
+
account_id: { type: 'string', const: credential_id },
|
|
67
|
+
},
|
|
68
|
+
}, async (msg) => {
|
|
69
|
+
const res = await modifyOrder(terminal, credential, msg.req);
|
|
70
|
+
return { res };
|
|
71
|
+
});
|
|
72
|
+
sub.add(() => {
|
|
73
|
+
service.dispose();
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
// Setup CancelOrder Service
|
|
77
|
+
{
|
|
78
|
+
const service = terminal.server.provideService('CancelOrder', {
|
|
79
|
+
type: 'object',
|
|
80
|
+
required: ['account_id'],
|
|
81
|
+
properties: {
|
|
82
|
+
account_id: { type: 'string', const: credential_id },
|
|
83
|
+
},
|
|
84
|
+
}, async (msg) => {
|
|
85
|
+
const res = await cancelOrder(terminal, credential, msg.req);
|
|
86
|
+
return { res };
|
|
87
|
+
});
|
|
88
|
+
sub.add(() => {
|
|
89
|
+
service.dispose();
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
})))
|
|
93
|
+
.subscribe();
|
|
94
|
+
//# sourceMappingURL=legacy-services.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacy-services.js","sourceRoot":"","sources":["../src/legacy-services.ts"],"names":[],"mappings":"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","sourcesContent":["import { provideAccountInfoService } from '@yuants/data-account';\nimport { IOrder, providePendingOrdersService } from '@yuants/data-order';\nimport { cancelOrder, getOrders, getPositions, modifyOrder, submitOrder } from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { listWatch, newError } from '@yuants/utils';\nimport { map, Observable } from 'rxjs';\nimport { validCredentials$ } from './credential';\n\nconst terminal = Terminal.fromNodeEnv();\n\nvalidCredentials$\n .pipe(\n map((x) => Array.from(x.entries())),\n listWatch(\n ([id]) => id,\n ([credential_id, credential]) =>\n new Observable((sub) => {\n console.info(`Setting up VEX services for credential: ${credential_id}`);\n // Setup AccountInfo Service\n {\n const service = provideAccountInfoService(\n terminal,\n credential_id,\n async () => {\n const res = await getPositions(terminal, credential);\n if (res.code === 0 && res.data) {\n return res.data;\n }\n throw newError('FETCH_POSITIONS_FAILED', { credential_id, reason: res.message });\n },\n {\n auto_refresh_interval: 1000,\n },\n );\n sub.add(() => {\n service.dispose$.next();\n });\n }\n // Setup Pending Orders Service\n {\n const service = providePendingOrdersService(\n terminal,\n credential_id,\n async () => {\n const res = await getOrders(terminal, credential);\n if (!res.data) throw newError('FETCH_ORDERS_FAILED', { credential_id, res });\n\n res.data.forEach((order) => {\n order.account_id = credential_id;\n });\n\n return res.data;\n },\n {\n auto_refresh_interval: 1000,\n },\n );\n sub.add(() => {\n service.dispose$.next();\n });\n }\n // Setup SubmitOrder Service\n {\n const service = terminal.server.provideService<IOrder, { order_id: string }>(\n 'SubmitOrder',\n {\n type: 'object',\n required: ['account_id'],\n properties: {\n account_id: { type: 'string', const: credential_id },\n },\n },\n async (msg) => {\n const res = await submitOrder(terminal, credential, msg.req);\n return { res };\n },\n );\n sub.add(() => {\n service.dispose();\n });\n }\n\n // Setup ModifyOrder Service\n {\n const service = terminal.server.provideService<IOrder, void>(\n 'ModifyOrder',\n {\n type: 'object',\n required: ['account_id'],\n properties: {\n account_id: { type: 'string', const: credential_id },\n },\n },\n async (msg) => {\n const res = await modifyOrder(terminal, credential, msg.req);\n return { res };\n },\n );\n sub.add(() => {\n service.dispose();\n });\n }\n\n // Setup CancelOrder Service\n {\n const service = terminal.server.provideService<IOrder, void>(\n 'CancelOrder',\n {\n type: 'object',\n required: ['account_id'],\n properties: {\n account_id: { type: 'string', const: credential_id },\n },\n },\n async (msg) => {\n const res = await cancelOrder(terminal, credential, msg.req);\n return { res };\n },\n );\n sub.add(() => {\n service.dispose();\n });\n }\n }),\n ),\n )\n .subscribe();\n"]}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ISecret } from '@yuants/secret';
|
|
2
|
+
export interface IExchangeCredential {
|
|
3
|
+
type: string;
|
|
4
|
+
payload: any;
|
|
5
|
+
}
|
|
6
|
+
interface ICredentialResolvedStatus {
|
|
7
|
+
secret: ISecret;
|
|
8
|
+
credential?: IExchangeCredential;
|
|
9
|
+
credentialId?: string;
|
|
10
|
+
reason?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare const listAllCredentials: () => Promise<ICredentialResolvedStatus[]>;
|
|
13
|
+
export declare const validCredentials$: import("rxjs").Observable<Map<string, IExchangeCredential>>;
|
|
14
|
+
export declare const getCredentialById: (credential_id: string) => Promise<IExchangeCredential | undefined>;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=credential.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential.d.ts","sourceRoot":"","sources":["../src/credential.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAA2B,MAAM,gBAAgB,CAAC;AAIlE,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,GAAG,CAAC;CACd;AAID,UAAU,yBAAyB;IACjC,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,mBAAmB,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,kBAAkB,4CA2B9B,CAAC;AAiCF,eAAO,MAAM,iBAAiB,6DAa7B,CAAC;AAEF,eAAO,MAAM,iBAAiB,kBAAyB,MAAM,6CAG5D,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getCredentialById = exports.validCredentials$ = exports.listAllCredentials = void 0;
|
|
4
|
+
const exchange_1 = require("@yuants/exchange");
|
|
5
|
+
const protocol_1 = require("@yuants/protocol");
|
|
6
|
+
const secret_1 = require("@yuants/secret");
|
|
7
|
+
const sql_1 = require("@yuants/sql");
|
|
8
|
+
const rxjs_1 = require("rxjs");
|
|
9
|
+
const terminal = protocol_1.Terminal.fromNodeEnv();
|
|
10
|
+
const listAllCredentials = async () => {
|
|
11
|
+
const secrets = await (0, sql_1.requestSQL)(terminal, `select * from secret where tags->>'type' = 'exchange_credential' and reader = ${(0, sql_1.escapeSQL)(terminal.keyPair.public_key)}`);
|
|
12
|
+
const results = secrets.map((secret) => ({ secret }));
|
|
13
|
+
await Promise.all(results.map(async (result) => {
|
|
14
|
+
try {
|
|
15
|
+
const decrypted = await (0, secret_1.readSecret)(terminal, result.secret);
|
|
16
|
+
const credential = JSON.parse(new TextDecoder().decode(decrypted));
|
|
17
|
+
result.credential = credential;
|
|
18
|
+
const res = await (0, exchange_1.getCredentialId)(terminal, credential);
|
|
19
|
+
const credentialId = res.data;
|
|
20
|
+
result.credentialId = credentialId;
|
|
21
|
+
}
|
|
22
|
+
catch (e) {
|
|
23
|
+
result.reason = `${e}`;
|
|
24
|
+
}
|
|
25
|
+
}));
|
|
26
|
+
return results;
|
|
27
|
+
};
|
|
28
|
+
exports.listAllCredentials = listAllCredentials;
|
|
29
|
+
terminal.server.provideService('VEX/RegisterExchangeCredential', {
|
|
30
|
+
type: 'object',
|
|
31
|
+
required: ['type', 'payload'],
|
|
32
|
+
properties: {
|
|
33
|
+
type: { type: 'string' },
|
|
34
|
+
payload: { type: 'object' },
|
|
35
|
+
},
|
|
36
|
+
}, async (msg) => {
|
|
37
|
+
const credential = msg.req;
|
|
38
|
+
const secretData = new TextEncoder().encode(JSON.stringify(credential));
|
|
39
|
+
await (0, secret_1.writeSecret)(terminal, terminal.keyPair.public_key, { type: 'exchange_credential' }, secretData);
|
|
40
|
+
return { res: { code: 0, message: 'OK' } };
|
|
41
|
+
});
|
|
42
|
+
terminal.server.provideService('VEX/ListExchangeCredential', {}, async () => {
|
|
43
|
+
return { res: { code: 0, message: 'OK', data: await (0, exports.listAllCredentials)() } };
|
|
44
|
+
});
|
|
45
|
+
terminal.server.provideService('VEX/ListCredentials', {}, async () => {
|
|
46
|
+
const credentials = await (0, rxjs_1.firstValueFrom)(exports.validCredentials$);
|
|
47
|
+
return { res: { code: 0, message: 'OK', data: [...credentials.keys()] } };
|
|
48
|
+
});
|
|
49
|
+
exports.validCredentials$ = (0, rxjs_1.defer)(() => (0, exports.listAllCredentials)()).pipe((0, rxjs_1.map)((x) => {
|
|
50
|
+
const map = new Map();
|
|
51
|
+
for (const xx of x) {
|
|
52
|
+
if (xx.credentialId && xx.credential) {
|
|
53
|
+
map.set(xx.credentialId, xx.credential);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return map;
|
|
57
|
+
}), (0, rxjs_1.repeat)({ delay: 10000 }), (0, rxjs_1.retry)({ delay: 5000 }), (0, rxjs_1.shareReplay)(1));
|
|
58
|
+
const getCredentialById = async (credential_id) => {
|
|
59
|
+
const credentials = await (0, rxjs_1.firstValueFrom)(exports.validCredentials$);
|
|
60
|
+
return credentials.get(credential_id);
|
|
61
|
+
};
|
|
62
|
+
exports.getCredentialById = getCredentialById;
|
|
63
|
+
//# sourceMappingURL=credential.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential.js","sourceRoot":"","sources":["../src/credential.ts"],"names":[],"mappings":"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","sourcesContent":["import { getCredentialId } from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { ISecret, readSecret, writeSecret } from '@yuants/secret';\nimport { escapeSQL, requestSQL } from '@yuants/sql';\nimport { defer, firstValueFrom, map, repeat, retry, shareReplay } from 'rxjs';\n\nexport interface IExchangeCredential {\n type: string;\n payload: any;\n}\n\nconst terminal = Terminal.fromNodeEnv();\n\ninterface ICredentialResolvedStatus {\n secret: ISecret;\n credential?: IExchangeCredential;\n credentialId?: string;\n reason?: string;\n}\n\nexport const listAllCredentials = async () => {\n const secrets = await requestSQL<ISecret[]>(\n terminal,\n `select * from secret where tags->>'type' = 'exchange_credential' and reader = ${escapeSQL(\n terminal.keyPair.public_key,\n )}`,\n );\n\n const results = secrets.map((secret): ICredentialResolvedStatus => ({ secret }));\n\n await Promise.all(\n results.map(async (result) => {\n try {\n const decrypted = await readSecret(terminal, result.secret);\n const credential = JSON.parse(new TextDecoder().decode(decrypted)) as IExchangeCredential;\n result.credential = credential;\n\n const res = await getCredentialId(terminal, credential);\n const credentialId = res.data;\n result.credentialId = credentialId;\n } catch (e) {\n result.reason = `${e}`;\n }\n }),\n );\n\n return results;\n};\n\nterminal.server.provideService<IExchangeCredential, void>(\n 'VEX/RegisterExchangeCredential',\n {\n type: 'object',\n required: ['type', 'payload'],\n properties: {\n type: { type: 'string' },\n payload: { type: 'object' },\n },\n },\n async (msg) => {\n const credential = msg.req;\n const secretData = new TextEncoder().encode(JSON.stringify(credential));\n await writeSecret(terminal, terminal.keyPair.public_key, { type: 'exchange_credential' }, secretData);\n return { res: { code: 0, message: 'OK' } };\n },\n);\n\nterminal.server.provideService<void, ICredentialResolvedStatus[]>(\n 'VEX/ListExchangeCredential',\n {},\n async () => {\n return { res: { code: 0, message: 'OK', data: await listAllCredentials() } };\n },\n);\n\nterminal.server.provideService<void, string[]>('VEX/ListCredentials', {}, async () => {\n const credentials = await firstValueFrom(validCredentials$);\n return { res: { code: 0, message: 'OK', data: [...credentials.keys()] } };\n});\n\nexport const validCredentials$ = defer(() => listAllCredentials()).pipe(\n map((x) => {\n const map = new Map<string, IExchangeCredential>();\n for (const xx of x) {\n if (xx.credentialId && xx.credential) {\n map.set(xx.credentialId, xx.credential);\n }\n }\n return map;\n }),\n repeat({ delay: 10000 }),\n retry({ delay: 5000 }),\n shareReplay(1),\n);\n\nexport const getCredentialById = async (credential_id: string) => {\n const credentials = await firstValueFrom(validCredentials$);\n return credentials.get(credential_id);\n};\n"]}
|
package/lib/general.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"general.d.ts","sourceRoot":"","sources":["../src/general.ts"],"names":[],"mappings":""}
|
package/lib/general.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const exchange_1 = require("@yuants/exchange");
|
|
4
|
+
const protocol_1 = require("@yuants/protocol");
|
|
5
|
+
const credential_1 = require("./credential");
|
|
6
|
+
const terminal = protocol_1.Terminal.fromNodeEnv();
|
|
7
|
+
terminal.server.provideService('VEX/GetPositions', {
|
|
8
|
+
type: 'object',
|
|
9
|
+
required: ['credential_id'],
|
|
10
|
+
properties: {
|
|
11
|
+
credential_id: { type: 'string' },
|
|
12
|
+
product_id: { type: 'string' },
|
|
13
|
+
},
|
|
14
|
+
}, async (msg) => {
|
|
15
|
+
const credential = await (0, credential_1.getCredentialById)(msg.req.credential_id);
|
|
16
|
+
if (!credential) {
|
|
17
|
+
return { res: { code: 404, message: 'Credential not found' } };
|
|
18
|
+
}
|
|
19
|
+
const res = await (0, exchange_1.getPositions)(terminal, credential, msg.req.product_id);
|
|
20
|
+
return { res };
|
|
21
|
+
});
|
|
22
|
+
terminal.server.provideService('VEX/GetOrders', {
|
|
23
|
+
type: 'object',
|
|
24
|
+
required: ['credential_id'],
|
|
25
|
+
properties: {
|
|
26
|
+
credential_id: { type: 'string' },
|
|
27
|
+
product_id: { type: 'string' },
|
|
28
|
+
},
|
|
29
|
+
}, async (msg) => {
|
|
30
|
+
var _a;
|
|
31
|
+
const credential = await (0, credential_1.getCredentialById)(msg.req.credential_id);
|
|
32
|
+
if (!credential) {
|
|
33
|
+
return { res: { code: 404, message: 'Credential not found' } };
|
|
34
|
+
}
|
|
35
|
+
const res = await (0, exchange_1.getOrders)(terminal, credential, msg.req.product_id);
|
|
36
|
+
(_a = res.data) === null || _a === void 0 ? void 0 : _a.forEach((order) => {
|
|
37
|
+
order.account_id = msg.req.credential_id;
|
|
38
|
+
});
|
|
39
|
+
return { res };
|
|
40
|
+
});
|
|
41
|
+
// 10. Proxy Orders
|
|
42
|
+
// SubmitOrder
|
|
43
|
+
terminal.server.provideService('VEX/SubmitOrder', {
|
|
44
|
+
type: 'object',
|
|
45
|
+
required: ['order', 'credential_id'],
|
|
46
|
+
properties: {
|
|
47
|
+
order: { type: 'object' },
|
|
48
|
+
credential_id: { type: 'string' },
|
|
49
|
+
},
|
|
50
|
+
}, async (msg) => {
|
|
51
|
+
const credential = await (0, credential_1.getCredentialById)(msg.req.credential_id);
|
|
52
|
+
if (!credential) {
|
|
53
|
+
return { res: { code: 404, message: 'Credential not found' } };
|
|
54
|
+
}
|
|
55
|
+
const res = await (0, exchange_1.submitOrder)(terminal, credential, msg.req.order);
|
|
56
|
+
return { res };
|
|
57
|
+
});
|
|
58
|
+
// ModifyOrder
|
|
59
|
+
terminal.server.provideService('VEX/ModifyOrder', {
|
|
60
|
+
type: 'object',
|
|
61
|
+
required: ['order', 'credential_id'],
|
|
62
|
+
properties: {
|
|
63
|
+
order: { type: 'object' },
|
|
64
|
+
credential_id: { type: 'string' },
|
|
65
|
+
},
|
|
66
|
+
}, async (msg) => {
|
|
67
|
+
const credential = await (0, credential_1.getCredentialById)(msg.req.credential_id);
|
|
68
|
+
if (!credential) {
|
|
69
|
+
return { res: { code: 404, message: 'Credential not found' } };
|
|
70
|
+
}
|
|
71
|
+
const res = await (0, exchange_1.modifyOrder)(terminal, credential, msg.req.order);
|
|
72
|
+
return { res };
|
|
73
|
+
});
|
|
74
|
+
// CancelOrder
|
|
75
|
+
terminal.server.provideService('VEX/CancelOrder', {
|
|
76
|
+
type: 'object',
|
|
77
|
+
required: ['order', 'credential_id'],
|
|
78
|
+
properties: {
|
|
79
|
+
order: { type: 'object' },
|
|
80
|
+
credential_id: { type: 'string' },
|
|
81
|
+
},
|
|
82
|
+
}, async (msg) => {
|
|
83
|
+
const credential = await (0, credential_1.getCredentialById)(msg.req.credential_id);
|
|
84
|
+
if (!credential) {
|
|
85
|
+
return { res: { code: 404, message: 'Credential not found' } };
|
|
86
|
+
}
|
|
87
|
+
const res = await (0, exchange_1.cancelOrder)(terminal, credential, msg.req.order);
|
|
88
|
+
return { res };
|
|
89
|
+
});
|
|
90
|
+
//# sourceMappingURL=general.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"general.js","sourceRoot":"","sources":["../src/general.ts"],"names":[],"mappings":"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","sourcesContent":["import { IPosition } from '@yuants/data-account';\nimport { IOrder } from '@yuants/data-order';\nimport { cancelOrder, getOrders, getPositions, modifyOrder, submitOrder } from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { getCredentialById } from './credential';\n\nconst terminal = Terminal.fromNodeEnv();\n\nterminal.server.provideService<{ credential_id: string; product_id?: string }, IPosition[]>(\n 'VEX/GetPositions',\n {\n type: 'object',\n required: ['credential_id'],\n properties: {\n credential_id: { type: 'string' },\n product_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = await getCredentialById(msg.req.credential_id);\n if (!credential) {\n return { res: { code: 404, message: 'Credential not found' } };\n }\n const res = await getPositions(terminal, credential, msg.req.product_id);\n return { res };\n },\n);\n\nterminal.server.provideService<{ credential_id: string; product_id?: string }, IOrder[]>(\n 'VEX/GetOrders',\n {\n type: 'object',\n required: ['credential_id'],\n properties: {\n credential_id: { type: 'string' },\n product_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = await getCredentialById(msg.req.credential_id);\n if (!credential) {\n return { res: { code: 404, message: 'Credential not found' } };\n }\n const res = await getOrders(terminal, credential, msg.req.product_id);\n res.data?.forEach((order) => {\n order.account_id = msg.req.credential_id;\n });\n return { res };\n },\n);\n\n// 10. Proxy Orders\n// SubmitOrder\nterminal.server.provideService<{ order: IOrder; credential_id: string }, { order_id: string }>(\n 'VEX/SubmitOrder',\n {\n type: 'object',\n required: ['order', 'credential_id'],\n properties: {\n order: { type: 'object' },\n credential_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = await getCredentialById(msg.req.credential_id);\n if (!credential) {\n return { res: { code: 404, message: 'Credential not found' } };\n }\n const res = await submitOrder(terminal, credential, msg.req.order);\n return { res };\n },\n);\n\n// ModifyOrder\nterminal.server.provideService<{ order: IOrder; credential_id: string }, void>(\n 'VEX/ModifyOrder',\n {\n type: 'object',\n required: ['order', 'credential_id'],\n properties: {\n order: { type: 'object' },\n credential_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = await getCredentialById(msg.req.credential_id);\n if (!credential) {\n return { res: { code: 404, message: 'Credential not found' } };\n }\n const res = await modifyOrder(terminal, credential, msg.req.order);\n return { res };\n },\n);\n\n// CancelOrder\nterminal.server.provideService<{ order: IOrder; credential_id: string }, void>(\n 'VEX/CancelOrder',\n {\n type: 'object',\n required: ['order', 'credential_id'],\n properties: {\n order: { type: 'object' },\n credential_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = await getCredentialById(msg.req.credential_id);\n if (!credential) {\n return { res: { code: 404, message: 'Credential not found' } };\n }\n const res = await cancelOrder(terminal, credential, msg.req.order);\n return { res };\n },\n);\n"]}
|
package/lib/index.d.ts
CHANGED
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,mBAAmB,CAAC;AAC3B,OAAO,cAAc,CAAC;AACtB,OAAO,WAAW,CAAC"}
|
package/lib/index.js
CHANGED
|
@@ -1,149 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const rxjs_1 = require("rxjs");
|
|
7
|
-
const terminal = protocol_1.Terminal.fromNodeEnv();
|
|
8
|
-
const mapCredentialIdToCredential = new Map();
|
|
9
|
-
// 1. RegisterExchangeCredential
|
|
10
|
-
terminal.server.provideService('VirtualExchange/RegisterExchangeCredential', {
|
|
11
|
-
type: 'object',
|
|
12
|
-
required: ['type', 'payload'],
|
|
13
|
-
properties: {
|
|
14
|
-
type: { type: 'string' },
|
|
15
|
-
payload: { type: 'object' },
|
|
16
|
-
},
|
|
17
|
-
}, async (msg) => {
|
|
18
|
-
const credential = msg.req;
|
|
19
|
-
const secretData = new TextEncoder().encode(JSON.stringify(credential));
|
|
20
|
-
await (0, secret_1.writeSecret)(terminal, terminal.keyPair.public_key, { type: 'exchange_credential' }, secretData);
|
|
21
|
-
return { res: { code: 0, message: 'OK' } };
|
|
22
|
-
});
|
|
23
|
-
// 2. ListExchangeCredential
|
|
24
|
-
terminal.server.provideService('VirtualExchange/ListExchangeCredential', {}, async () => {
|
|
25
|
-
const secrets = await (0, sql_1.requestSQL)(terminal, `select * from secret where tags->>'type' = 'exchange_credential' and reader = ${(0, sql_1.escapeSQL)(terminal.keyPair.public_key)}`);
|
|
26
|
-
const credentials = [];
|
|
27
|
-
for (const secret of secrets) {
|
|
28
|
-
try {
|
|
29
|
-
const decrypted = await (0, secret_1.readSecret)(terminal, secret);
|
|
30
|
-
const credential = JSON.parse(new TextDecoder().decode(decrypted));
|
|
31
|
-
credentials.push(credential);
|
|
32
|
-
}
|
|
33
|
-
catch (e) {
|
|
34
|
-
console.error('Failed to decrypt secret', e);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
return { res: { code: 0, message: 'OK', data: credentials } };
|
|
38
|
-
});
|
|
39
|
-
terminal.server.provideService('VirtualExchange/ListCredentials', {}, async () => {
|
|
40
|
-
return { res: { code: 0, message: 'OK', data: [...mapCredentialIdToCredential.keys()] } };
|
|
41
|
-
});
|
|
42
|
-
// 9. Background listWatch
|
|
43
|
-
const updateIndex = async () => {
|
|
44
|
-
const secrets = await (0, sql_1.requestSQL)(terminal, `select * from secret where tags->>'type' = 'exchange_credential' and reader = ${(0, sql_1.escapeSQL)(terminal.keyPair.public_key)}`);
|
|
45
|
-
for (const secret of secrets) {
|
|
46
|
-
try {
|
|
47
|
-
const decrypted = await (0, secret_1.readSecret)(terminal, secret);
|
|
48
|
-
const credential = JSON.parse(new TextDecoder().decode(decrypted));
|
|
49
|
-
// Call GetCredentialId to get credential id
|
|
50
|
-
const res = await terminal.client.requestForResponse('GetCredentialId', { credential });
|
|
51
|
-
if (res.code === 0 && res.data) {
|
|
52
|
-
const credentialId = res.data;
|
|
53
|
-
mapCredentialIdToCredential.set(credentialId, credential);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
catch (e) {
|
|
57
|
-
console.error('Failed to process secret', e);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
};
|
|
61
|
-
// Run updateIndex periodically
|
|
62
|
-
(0, rxjs_1.timer)(0, 60000)
|
|
63
|
-
.pipe((0, rxjs_1.mergeMap)(() => (0, rxjs_1.defer)(updateIndex).pipe((0, rxjs_1.retry)({ delay: 5000 }))))
|
|
64
|
-
.subscribe();
|
|
65
|
-
// 8. QueryAccountInfo
|
|
66
|
-
terminal.server.provideService('VirtualExchange/QueryPositions', {
|
|
67
|
-
type: 'object',
|
|
68
|
-
required: ['credential_id'],
|
|
69
|
-
properties: {
|
|
70
|
-
credential_id: { type: 'string' },
|
|
71
|
-
product_id: { type: 'string' },
|
|
72
|
-
},
|
|
73
|
-
}, async (msg) => {
|
|
74
|
-
const credential = mapCredentialIdToCredential.get(msg.req.credential_id);
|
|
75
|
-
if (!credential) {
|
|
76
|
-
return { res: { code: 404, message: 'Credential not found' } };
|
|
77
|
-
}
|
|
78
|
-
const res = await terminal.client.requestForResponse('QueryPositions', { credential, product_id: msg.req.product_id });
|
|
79
|
-
return { res };
|
|
80
|
-
});
|
|
81
|
-
terminal.server.provideService('VirtualExchange/QueryOrders', {
|
|
82
|
-
type: 'object',
|
|
83
|
-
required: ['credential_id'],
|
|
84
|
-
properties: {
|
|
85
|
-
credential_id: { type: 'string' },
|
|
86
|
-
product_id: { type: 'string' },
|
|
87
|
-
},
|
|
88
|
-
}, async (msg) => {
|
|
89
|
-
const credential = mapCredentialIdToCredential.get(msg.req.credential_id);
|
|
90
|
-
if (!credential) {
|
|
91
|
-
return { res: { code: 404, message: 'Credential not found' } };
|
|
92
|
-
}
|
|
93
|
-
const res = await terminal.client.requestForResponse('QueryOrders', {
|
|
94
|
-
credential,
|
|
95
|
-
product_id: msg.req.product_id,
|
|
96
|
-
});
|
|
97
|
-
return { res };
|
|
98
|
-
});
|
|
99
|
-
// 10. Proxy Orders
|
|
100
|
-
// SubmitOrder
|
|
101
|
-
terminal.server.provideService('VirtualExchange/SubmitOrder', {
|
|
102
|
-
type: 'object',
|
|
103
|
-
required: ['order', 'credential_id'],
|
|
104
|
-
properties: {
|
|
105
|
-
order: { type: 'object' },
|
|
106
|
-
credential_id: { type: 'string' },
|
|
107
|
-
},
|
|
108
|
-
}, async (msg) => {
|
|
109
|
-
const credential = mapCredentialIdToCredential.get(msg.req.credential_id);
|
|
110
|
-
if (!credential) {
|
|
111
|
-
return { res: { code: 404, message: 'Credential not found' } };
|
|
112
|
-
}
|
|
113
|
-
const res = await terminal.client.requestForResponse('SubmitOrder', { credential, order: msg.req.order });
|
|
114
|
-
return { res };
|
|
115
|
-
});
|
|
116
|
-
// ModifyOrder
|
|
117
|
-
terminal.server.provideService('VirtualExchange/ModifyOrder', {
|
|
118
|
-
type: 'object',
|
|
119
|
-
required: ['order', 'credential_id'],
|
|
120
|
-
properties: {
|
|
121
|
-
order: { type: 'object' },
|
|
122
|
-
credential_id: { type: 'string' },
|
|
123
|
-
},
|
|
124
|
-
}, async (msg) => {
|
|
125
|
-
const credential = mapCredentialIdToCredential.get(msg.req.credential_id);
|
|
126
|
-
if (!credential) {
|
|
127
|
-
return { res: { code: 404, message: 'Credential not found' } };
|
|
128
|
-
}
|
|
129
|
-
const res = await terminal.client.requestForResponse('ModifyOrder', { credential, order: msg.req.order });
|
|
130
|
-
return { res };
|
|
131
|
-
});
|
|
132
|
-
// CancelOrder
|
|
133
|
-
terminal.server.provideService('VirtualExchange/CancelOrder', {
|
|
134
|
-
type: 'object',
|
|
135
|
-
required: ['order', 'credential_id'],
|
|
136
|
-
properties: {
|
|
137
|
-
order: { type: 'object' },
|
|
138
|
-
credential_id: { type: 'string' },
|
|
139
|
-
},
|
|
140
|
-
}, async (msg) => {
|
|
141
|
-
const credential = mapCredentialIdToCredential.get(msg.req.credential_id);
|
|
142
|
-
if (!credential) {
|
|
143
|
-
return { res: { code: 404, message: 'Credential not found' } };
|
|
144
|
-
}
|
|
145
|
-
const res = await terminal.client.requestForResponse('CancelOrder', { credential, order: msg.req.order });
|
|
146
|
-
return { res };
|
|
147
|
-
});
|
|
148
|
-
// ListOrders
|
|
3
|
+
require("./legacy-services");
|
|
4
|
+
require("./credential");
|
|
5
|
+
require("./general");
|
|
149
6
|
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { IAccountInfo } from '@yuants/data-account';\nimport { IOrder, ITypedCredential } from '@yuants/data-order';\nimport { Terminal } from '@yuants/protocol';\nimport { ISecret, readSecret, writeSecret } from '@yuants/secret';\nimport { escapeSQL, requestSQL } from '@yuants/sql';\nimport { defer, mergeMap, retry, timer } from 'rxjs';\n\nconst terminal = Terminal.fromNodeEnv();\n\ninterface IExchangeCredential {\n type: string;\n payload: any;\n}\n\nconst mapCredentialIdToCredential = new Map<string, IExchangeCredential>();\n\n// 1. RegisterExchangeCredential\nterminal.server.provideService<IExchangeCredential, void>(\n 'VirtualExchange/RegisterExchangeCredential',\n {\n type: 'object',\n required: ['type', 'payload'],\n properties: {\n type: { type: 'string' },\n payload: { type: 'object' },\n },\n },\n async (msg) => {\n const credential = msg.req;\n const secretData = new TextEncoder().encode(JSON.stringify(credential));\n await writeSecret(terminal, terminal.keyPair.public_key, { type: 'exchange_credential' }, secretData);\n return { res: { code: 0, message: 'OK' } };\n },\n);\n\n// 2. ListExchangeCredential\nterminal.server.provideService<void, IExchangeCredential[]>(\n 'VirtualExchange/ListExchangeCredential',\n {},\n async () => {\n const secrets = await requestSQL<ISecret[]>(\n terminal,\n `select * from secret where tags->>'type' = 'exchange_credential' and reader = ${escapeSQL(\n terminal.keyPair.public_key,\n )}`,\n );\n const credentials: IExchangeCredential[] = [];\n for (const secret of secrets) {\n try {\n const decrypted = await readSecret(terminal, secret);\n const credential = JSON.parse(new TextDecoder().decode(decrypted));\n credentials.push(credential);\n } catch (e) {\n console.error('Failed to decrypt secret', e);\n }\n }\n return { res: { code: 0, message: 'OK', data: credentials } };\n },\n);\n\nterminal.server.provideService<void, string[]>('VirtualExchange/ListCredentials', {}, async () => {\n return { res: { code: 0, message: 'OK', data: [...mapCredentialIdToCredential.keys()] } };\n});\n\n// 9. Background listWatch\nconst updateIndex = async () => {\n const secrets = await requestSQL<ISecret[]>(\n terminal,\n `select * from secret where tags->>'type' = 'exchange_credential' and reader = ${escapeSQL(\n terminal.keyPair.public_key,\n )}`,\n );\n for (const secret of secrets) {\n try {\n const decrypted = await readSecret(terminal, secret);\n const credential = JSON.parse(new TextDecoder().decode(decrypted)) as IExchangeCredential;\n\n // Call GetCredentialId to get credential id\n const res = await terminal.client.requestForResponse<{ credential: ITypedCredential<any> }, string>(\n 'GetCredentialId',\n { credential },\n );\n\n if (res.code === 0 && res.data) {\n const credentialId = res.data;\n mapCredentialIdToCredential.set(credentialId, credential);\n }\n } catch (e) {\n console.error('Failed to process secret', e);\n }\n }\n};\n\n// Run updateIndex periodically\ntimer(0, 60000)\n .pipe(mergeMap(() => defer(updateIndex).pipe(retry({ delay: 5000 }))))\n .subscribe();\n\n// 8. QueryAccountInfo\nterminal.server.provideService<{ credential_id: string; product_id?: string }, IAccountInfo>(\n 'VirtualExchange/QueryPositions',\n {\n type: 'object',\n required: ['credential_id'],\n properties: {\n credential_id: { type: 'string' },\n product_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = mapCredentialIdToCredential.get(msg.req.credential_id);\n if (!credential) {\n return { res: { code: 404, message: 'Credential not found' } };\n }\n const res = await terminal.client.requestForResponse<\n { credential: ITypedCredential<any>; product_id?: string },\n IAccountInfo\n >('QueryPositions', { credential, product_id: msg.req.product_id });\n return { res };\n },\n);\n\nterminal.server.provideService<{ credential_id: string; product_id?: string }, { orders: IOrder[] }>(\n 'VirtualExchange/QueryOrders',\n {\n type: 'object',\n required: ['credential_id'],\n properties: {\n credential_id: { type: 'string' },\n product_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = mapCredentialIdToCredential.get(msg.req.credential_id);\n if (!credential) {\n return { res: { code: 404, message: 'Credential not found' } };\n }\n const res = await terminal.client.requestForResponse<\n { credential: ITypedCredential<any>; product_id?: string },\n { orders: IOrder[] }\n >('QueryOrders', {\n credential,\n product_id: msg.req.product_id,\n });\n return { res };\n },\n);\n\n// 10. Proxy Orders\n// SubmitOrder\nterminal.server.provideService<{ order: IOrder; credential_id: string }, { order_id: string }>(\n 'VirtualExchange/SubmitOrder',\n {\n type: 'object',\n required: ['order', 'credential_id'],\n properties: {\n order: { type: 'object' },\n credential_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = mapCredentialIdToCredential.get(msg.req.credential_id);\n if (!credential) {\n return { res: { code: 404, message: 'Credential not found' } };\n }\n const res = await terminal.client.requestForResponse<\n { credential: ITypedCredential<any>; order: IOrder },\n { order_id: string }\n >('SubmitOrder', { credential, order: msg.req.order });\n return { res };\n },\n);\n\n// ModifyOrder\nterminal.server.provideService<{ order: IOrder; credential_id: string }, void>(\n 'VirtualExchange/ModifyOrder',\n {\n type: 'object',\n required: ['order', 'credential_id'],\n properties: {\n order: { type: 'object' },\n credential_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = mapCredentialIdToCredential.get(msg.req.credential_id);\n if (!credential) {\n return { res: { code: 404, message: 'Credential not found' } };\n }\n const res = await terminal.client.requestForResponse<\n { credential: ITypedCredential<any>; order: IOrder },\n void\n >('ModifyOrder', { credential, order: msg.req.order });\n return { res };\n },\n);\n\n// CancelOrder\nterminal.server.provideService<{ order: IOrder; credential_id: string }, void>(\n 'VirtualExchange/CancelOrder',\n {\n type: 'object',\n required: ['order', 'credential_id'],\n properties: {\n order: { type: 'object' },\n credential_id: { type: 'string' },\n },\n },\n async (msg) => {\n const credential = mapCredentialIdToCredential.get(msg.req.credential_id);\n if (!credential) {\n return { res: { code: 404, message: 'Credential not found' } };\n }\n const res = await terminal.client.requestForResponse<\n { credential: ITypedCredential<any>; order: IOrder },\n void\n >('CancelOrder', { credential, order: msg.req.order });\n return { res };\n },\n);\n\n// ListOrders\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,6BAA2B;AAC3B,wBAAsB;AACtB,qBAAmB","sourcesContent":["import './legacy-services';\nimport './credential';\nimport './general';\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacy-services.d.ts","sourceRoot":"","sources":["../src/legacy-services.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const data_account_1 = require("@yuants/data-account");
|
|
4
|
+
const data_order_1 = require("@yuants/data-order");
|
|
5
|
+
const exchange_1 = require("@yuants/exchange");
|
|
6
|
+
const protocol_1 = require("@yuants/protocol");
|
|
7
|
+
const utils_1 = require("@yuants/utils");
|
|
8
|
+
const rxjs_1 = require("rxjs");
|
|
9
|
+
const credential_1 = require("./credential");
|
|
10
|
+
const terminal = protocol_1.Terminal.fromNodeEnv();
|
|
11
|
+
credential_1.validCredentials$
|
|
12
|
+
.pipe((0, rxjs_1.map)((x) => Array.from(x.entries())), (0, utils_1.listWatch)(([id]) => id, ([credential_id, credential]) => new rxjs_1.Observable((sub) => {
|
|
13
|
+
console.info(`Setting up VEX services for credential: ${credential_id}`);
|
|
14
|
+
// Setup AccountInfo Service
|
|
15
|
+
{
|
|
16
|
+
const service = (0, data_account_1.provideAccountInfoService)(terminal, credential_id, async () => {
|
|
17
|
+
const res = await (0, exchange_1.getPositions)(terminal, credential);
|
|
18
|
+
if (res.code === 0 && res.data) {
|
|
19
|
+
return res.data;
|
|
20
|
+
}
|
|
21
|
+
throw (0, utils_1.newError)('FETCH_POSITIONS_FAILED', { credential_id, reason: res.message });
|
|
22
|
+
}, {
|
|
23
|
+
auto_refresh_interval: 1000,
|
|
24
|
+
});
|
|
25
|
+
sub.add(() => {
|
|
26
|
+
service.dispose$.next();
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
// Setup Pending Orders Service
|
|
30
|
+
{
|
|
31
|
+
const service = (0, data_order_1.providePendingOrdersService)(terminal, credential_id, async () => {
|
|
32
|
+
const res = await (0, exchange_1.getOrders)(terminal, credential);
|
|
33
|
+
if (!res.data)
|
|
34
|
+
throw (0, utils_1.newError)('FETCH_ORDERS_FAILED', { credential_id, res });
|
|
35
|
+
res.data.forEach((order) => {
|
|
36
|
+
order.account_id = credential_id;
|
|
37
|
+
});
|
|
38
|
+
return res.data;
|
|
39
|
+
}, {
|
|
40
|
+
auto_refresh_interval: 1000,
|
|
41
|
+
});
|
|
42
|
+
sub.add(() => {
|
|
43
|
+
service.dispose$.next();
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
// Setup SubmitOrder Service
|
|
47
|
+
{
|
|
48
|
+
const service = terminal.server.provideService('SubmitOrder', {
|
|
49
|
+
type: 'object',
|
|
50
|
+
required: ['account_id'],
|
|
51
|
+
properties: {
|
|
52
|
+
account_id: { type: 'string', const: credential_id },
|
|
53
|
+
},
|
|
54
|
+
}, async (msg) => {
|
|
55
|
+
const res = await (0, exchange_1.submitOrder)(terminal, credential, msg.req);
|
|
56
|
+
return { res };
|
|
57
|
+
});
|
|
58
|
+
sub.add(() => {
|
|
59
|
+
service.dispose();
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
// Setup ModifyOrder Service
|
|
63
|
+
{
|
|
64
|
+
const service = terminal.server.provideService('ModifyOrder', {
|
|
65
|
+
type: 'object',
|
|
66
|
+
required: ['account_id'],
|
|
67
|
+
properties: {
|
|
68
|
+
account_id: { type: 'string', const: credential_id },
|
|
69
|
+
},
|
|
70
|
+
}, async (msg) => {
|
|
71
|
+
const res = await (0, exchange_1.modifyOrder)(terminal, credential, msg.req);
|
|
72
|
+
return { res };
|
|
73
|
+
});
|
|
74
|
+
sub.add(() => {
|
|
75
|
+
service.dispose();
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
// Setup CancelOrder Service
|
|
79
|
+
{
|
|
80
|
+
const service = terminal.server.provideService('CancelOrder', {
|
|
81
|
+
type: 'object',
|
|
82
|
+
required: ['account_id'],
|
|
83
|
+
properties: {
|
|
84
|
+
account_id: { type: 'string', const: credential_id },
|
|
85
|
+
},
|
|
86
|
+
}, async (msg) => {
|
|
87
|
+
const res = await (0, exchange_1.cancelOrder)(terminal, credential, msg.req);
|
|
88
|
+
return { res };
|
|
89
|
+
});
|
|
90
|
+
sub.add(() => {
|
|
91
|
+
service.dispose();
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
})))
|
|
95
|
+
.subscribe();
|
|
96
|
+
//# sourceMappingURL=legacy-services.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacy-services.js","sourceRoot":"","sources":["../src/legacy-services.ts"],"names":[],"mappings":"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","sourcesContent":["import { provideAccountInfoService } from '@yuants/data-account';\nimport { IOrder, providePendingOrdersService } from '@yuants/data-order';\nimport { cancelOrder, getOrders, getPositions, modifyOrder, submitOrder } from '@yuants/exchange';\nimport { Terminal } from '@yuants/protocol';\nimport { listWatch, newError } from '@yuants/utils';\nimport { map, Observable } from 'rxjs';\nimport { validCredentials$ } from './credential';\n\nconst terminal = Terminal.fromNodeEnv();\n\nvalidCredentials$\n .pipe(\n map((x) => Array.from(x.entries())),\n listWatch(\n ([id]) => id,\n ([credential_id, credential]) =>\n new Observable((sub) => {\n console.info(`Setting up VEX services for credential: ${credential_id}`);\n // Setup AccountInfo Service\n {\n const service = provideAccountInfoService(\n terminal,\n credential_id,\n async () => {\n const res = await getPositions(terminal, credential);\n if (res.code === 0 && res.data) {\n return res.data;\n }\n throw newError('FETCH_POSITIONS_FAILED', { credential_id, reason: res.message });\n },\n {\n auto_refresh_interval: 1000,\n },\n );\n sub.add(() => {\n service.dispose$.next();\n });\n }\n // Setup Pending Orders Service\n {\n const service = providePendingOrdersService(\n terminal,\n credential_id,\n async () => {\n const res = await getOrders(terminal, credential);\n if (!res.data) throw newError('FETCH_ORDERS_FAILED', { credential_id, res });\n\n res.data.forEach((order) => {\n order.account_id = credential_id;\n });\n\n return res.data;\n },\n {\n auto_refresh_interval: 1000,\n },\n );\n sub.add(() => {\n service.dispose$.next();\n });\n }\n // Setup SubmitOrder Service\n {\n const service = terminal.server.provideService<IOrder, { order_id: string }>(\n 'SubmitOrder',\n {\n type: 'object',\n required: ['account_id'],\n properties: {\n account_id: { type: 'string', const: credential_id },\n },\n },\n async (msg) => {\n const res = await submitOrder(terminal, credential, msg.req);\n return { res };\n },\n );\n sub.add(() => {\n service.dispose();\n });\n }\n\n // Setup ModifyOrder Service\n {\n const service = terminal.server.provideService<IOrder, void>(\n 'ModifyOrder',\n {\n type: 'object',\n required: ['account_id'],\n properties: {\n account_id: { type: 'string', const: credential_id },\n },\n },\n async (msg) => {\n const res = await modifyOrder(terminal, credential, msg.req);\n return { res };\n },\n );\n sub.add(() => {\n service.dispose();\n });\n }\n\n // Setup CancelOrder Service\n {\n const service = terminal.server.provideService<IOrder, void>(\n 'CancelOrder',\n {\n type: 'object',\n required: ['account_id'],\n properties: {\n account_id: { type: 'string', const: credential_id },\n },\n },\n async (msg) => {\n const res = await cancelOrder(terminal, credential, msg.req);\n return { res };\n },\n );\n sub.add(() => {\n service.dispose();\n });\n }\n }),\n ),\n )\n .subscribe();\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yuants/app-virtual-exchange",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
"@yuants/data-order": "0.6.4",
|
|
15
15
|
"@yuants/secret": "0.3.11",
|
|
16
16
|
"@yuants/sql": "0.9.28",
|
|
17
|
+
"@yuants/exchange": "0.1.0",
|
|
18
|
+
"@yuants/cache": "0.3.2",
|
|
17
19
|
"rxjs": "~7.5.6",
|
|
18
20
|
"ajv": "~8.12.0"
|
|
19
21
|
},
|
package/temp/package-deps.json
CHANGED
|
@@ -1,20 +1,25 @@
|
|
|
1
1
|
{
|
|
2
|
-
"apps/virtual-exchange/CHANGELOG.json": "
|
|
3
|
-
"apps/virtual-exchange/CHANGELOG.md": "
|
|
2
|
+
"apps/virtual-exchange/CHANGELOG.json": "a77ccc0b1069eca16d04eb798af6e70cd3160840",
|
|
3
|
+
"apps/virtual-exchange/CHANGELOG.md": "59d5c45f94c134732f229d2e90556dd04a41ae0b",
|
|
4
4
|
"apps/virtual-exchange/api-extractor.json": "62f4fd324425b9a235f0c117975967aab09ced0c",
|
|
5
5
|
"apps/virtual-exchange/config/jest.config.json": "4bb17bde3ee911163a3edb36a6eb71491d80b1bd",
|
|
6
6
|
"apps/virtual-exchange/config/rig.json": "f6c7b5537dc77a3170ba9f008bae3b6c3ee11956",
|
|
7
7
|
"apps/virtual-exchange/config/typescript.json": "854907e8a821f2050f6533368db160c649c25348",
|
|
8
8
|
"apps/virtual-exchange/etc/app-virtual-exchange.api.md": "6cb40ec1fa2d40a31a7b0dd3f02b8b24a4d7c4de",
|
|
9
|
-
"apps/virtual-exchange/package.json": "
|
|
10
|
-
"apps/virtual-exchange/src/
|
|
9
|
+
"apps/virtual-exchange/package.json": "8775def1ac14bec9d9aa6df248127b03b540d71c",
|
|
10
|
+
"apps/virtual-exchange/src/credential.ts": "5277b4dbc4b634870203439ced554ae13b64b831",
|
|
11
|
+
"apps/virtual-exchange/src/general.ts": "068a19f33440cbaad103a5b2a68f9594dc692b81",
|
|
12
|
+
"apps/virtual-exchange/src/index.ts": "fab618a868a54508ffcd9c770485b3625d116c15",
|
|
13
|
+
"apps/virtual-exchange/src/legacy-services.ts": "08284bbb1d6526c6af15ef1530866f15295554d9",
|
|
11
14
|
"apps/virtual-exchange/tsconfig.json": "22f94ca28b507f8ddcc21b9053158eefd3f726a9",
|
|
12
|
-
"apps/virtual-exchange/.rush/temp/shrinkwrap-deps.json": "
|
|
15
|
+
"apps/virtual-exchange/.rush/temp/shrinkwrap-deps.json": "dd99597ee4f6af423ec6f59db9f4ec5b63ccebe8",
|
|
13
16
|
"libraries/protocol/temp/package-deps.json": "00d9a96a90bfc0e57ef3b9547151f2970a600402",
|
|
14
17
|
"libraries/utils/temp/package-deps.json": "4a683c07df7c75079b700111b9f6beb36c74ff7d",
|
|
15
18
|
"libraries/data-account/temp/package-deps.json": "bf8b41c4d878dab0f39ea684fffaf6bc3c74c988",
|
|
16
19
|
"libraries/data-order/temp/package-deps.json": "4a0272551da88c9eb52150775640b12c31786de8",
|
|
17
20
|
"libraries/secret/temp/package-deps.json": "8ebb302ac2e6fc0e98a3fc31f316796d9a0718e6",
|
|
18
21
|
"libraries/sql/temp/package-deps.json": "d227fb17cbb9f6e3b445a3b88e0d9978f5c1c823",
|
|
22
|
+
"libraries/exchange/temp/package-deps.json": "16a4864218e5ef6afb856b728aa0751bb89cc9e8",
|
|
23
|
+
"libraries/cache/temp/package-deps.json": "70044bb56d863988aa90d8dcea9e3919bf65d38f",
|
|
19
24
|
"tools/toolkit/temp/package-deps.json": "23e053490eb8feade23e4d45de4e54883e322711"
|
|
20
25
|
}
|