@yuants/app-virtual-exchange 0.2.0 → 0.3.0

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.
@@ -0,0 +1,69 @@
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 { formatTime, scopeError } from '@yuants/utils';
6
+ import { defer, firstValueFrom, repeat, retry, shareReplay } from 'rxjs';
7
+ const terminal = Terminal.fromNodeEnv();
8
+ terminal.server.provideService('VEX/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
+ terminal.server.provideService('VEX/ListExchangeCredential', {}, async () => {
22
+ const secrets = await requestSQL(terminal, `select * from secret where tags->>'type' = 'exchange_credential' and reader = ${escapeSQL(terminal.keyPair.public_key)}`);
23
+ const credentials = [];
24
+ for (const secret of secrets) {
25
+ try {
26
+ const decrypted = await readSecret(terminal, secret);
27
+ const credential = JSON.parse(new TextDecoder().decode(decrypted));
28
+ credentials.push(credential);
29
+ }
30
+ catch (e) {
31
+ console.error('Failed to decrypt secret', e);
32
+ }
33
+ }
34
+ return { res: { code: 0, message: 'OK', data: credentials } };
35
+ });
36
+ terminal.server.provideService('VEX/ListCredentials', {}, async () => {
37
+ const credentials = await firstValueFrom(validCredentials$);
38
+ return { res: { code: 0, message: 'OK', data: [...credentials.keys()] } };
39
+ });
40
+ export const listValidCredentials = async () => {
41
+ const credentials = new Map();
42
+ const secrets = await requestSQL(terminal, `select * from secret where tags->>'type' = 'exchange_credential' and reader = ${escapeSQL(terminal.keyPair.public_key)}`);
43
+ console.info(formatTime(Date.now()), `Found ${secrets.length} exchange credential secrets`);
44
+ for (const secret of secrets) {
45
+ try {
46
+ const decrypted = await readSecret(terminal, secret);
47
+ const credential = JSON.parse(new TextDecoder().decode(decrypted));
48
+ // Call GetCredentialId to get credential id
49
+ const res = await getCredentialId(terminal, credential);
50
+ scopeError('GET_CREDENTIAL_ID_FAILED', { res }, () => {
51
+ const credentialId = res.data;
52
+ if (!credentialId)
53
+ throw new Error('Credential ID is empty');
54
+ credentials.set(credentialId, credential);
55
+ console.info(formatTime(Date.now()), `Valid credential found: ${credentialId}`);
56
+ });
57
+ }
58
+ catch (e) {
59
+ console.info(formatTime(Date.now()), 'Failed to process secret', e);
60
+ }
61
+ }
62
+ return credentials;
63
+ };
64
+ export const validCredentials$ = defer(() => listValidCredentials()).pipe(repeat({ delay: 60000 }), retry({ delay: 5000 }), shareReplay(1));
65
+ export const getCredentialById = async (credential_id) => {
66
+ const credentials = await firstValueFrom(validCredentials$);
67
+ return credentials.get(credential_id);
68
+ };
69
+ //# 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 { formatTime, scopeError } from '@yuants/utils';\nimport { defer, firstValueFrom, repeat, retry, shareReplay } from 'rxjs';\n\nexport interface IExchangeCredential {\n type: string;\n payload: any;\n}\n\nconst terminal = Terminal.fromNodeEnv();\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);\nterminal.server.provideService<void, IExchangeCredential[]>('VEX/ListExchangeCredential', {}, 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\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 listValidCredentials = async () => {\n const credentials = new Map<string, IExchangeCredential>();\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 console.info(formatTime(Date.now()), `Found ${secrets.length} exchange credential secrets`);\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 getCredentialId(terminal, credential);\n\n scopeError('GET_CREDENTIAL_ID_FAILED', { res }, () => {\n const credentialId = res.data;\n if (!credentialId) throw new Error('Credential ID is empty');\n credentials.set(credentialId, credential);\n console.info(formatTime(Date.now()), `Valid credential found: ${credentialId}`);\n });\n } catch (e) {\n console.info(formatTime(Date.now()), 'Failed to process secret', e);\n }\n }\n return credentials;\n};\n\nexport const validCredentials$ = defer(() => listValidCredentials()).pipe(\n repeat({ delay: 60000 }),\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"]}
@@ -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 { Terminal } from '@yuants/protocol';
2
- import { readSecret, writeSecret } from '@yuants/secret';
3
- import { escapeSQL, requestSQL } from '@yuants/sql';
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,8 @@
1
+ export interface IExchangeCredential {
2
+ type: string;
3
+ payload: any;
4
+ }
5
+ export declare const listValidCredentials: () => Promise<Map<string, IExchangeCredential>>;
6
+ export declare const validCredentials$: import("rxjs").Observable<Map<string, IExchangeCredential>>;
7
+ export declare const getCredentialById: (credential_id: string) => Promise<IExchangeCredential | undefined>;
8
+ //# sourceMappingURL=credential.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credential.d.ts","sourceRoot":"","sources":["../src/credential.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,GAAG,CAAC;CACd;AA8CD,eAAO,MAAM,oBAAoB,iDA4BhC,CAAC;AAEF,eAAO,MAAM,iBAAiB,6DAI7B,CAAC;AAEF,eAAO,MAAM,iBAAiB,kBAAyB,MAAM,6CAG5D,CAAC"}
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCredentialById = exports.validCredentials$ = exports.listValidCredentials = 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 utils_1 = require("@yuants/utils");
9
+ const rxjs_1 = require("rxjs");
10
+ const terminal = protocol_1.Terminal.fromNodeEnv();
11
+ terminal.server.provideService('VEX/RegisterExchangeCredential', {
12
+ type: 'object',
13
+ required: ['type', 'payload'],
14
+ properties: {
15
+ type: { type: 'string' },
16
+ payload: { type: 'object' },
17
+ },
18
+ }, async (msg) => {
19
+ const credential = msg.req;
20
+ const secretData = new TextEncoder().encode(JSON.stringify(credential));
21
+ await (0, secret_1.writeSecret)(terminal, terminal.keyPair.public_key, { type: 'exchange_credential' }, secretData);
22
+ return { res: { code: 0, message: 'OK' } };
23
+ });
24
+ terminal.server.provideService('VEX/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('VEX/ListCredentials', {}, async () => {
40
+ const credentials = await (0, rxjs_1.firstValueFrom)(exports.validCredentials$);
41
+ return { res: { code: 0, message: 'OK', data: [...credentials.keys()] } };
42
+ });
43
+ const listValidCredentials = async () => {
44
+ const credentials = new Map();
45
+ 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)}`);
46
+ console.info((0, utils_1.formatTime)(Date.now()), `Found ${secrets.length} exchange credential secrets`);
47
+ for (const secret of secrets) {
48
+ try {
49
+ const decrypted = await (0, secret_1.readSecret)(terminal, secret);
50
+ const credential = JSON.parse(new TextDecoder().decode(decrypted));
51
+ // Call GetCredentialId to get credential id
52
+ const res = await (0, exchange_1.getCredentialId)(terminal, credential);
53
+ (0, utils_1.scopeError)('GET_CREDENTIAL_ID_FAILED', { res }, () => {
54
+ const credentialId = res.data;
55
+ if (!credentialId)
56
+ throw new Error('Credential ID is empty');
57
+ credentials.set(credentialId, credential);
58
+ console.info((0, utils_1.formatTime)(Date.now()), `Valid credential found: ${credentialId}`);
59
+ });
60
+ }
61
+ catch (e) {
62
+ console.info((0, utils_1.formatTime)(Date.now()), 'Failed to process secret', e);
63
+ }
64
+ }
65
+ return credentials;
66
+ };
67
+ exports.listValidCredentials = listValidCredentials;
68
+ exports.validCredentials$ = (0, rxjs_1.defer)(() => (0, exports.listValidCredentials)()).pipe((0, rxjs_1.repeat)({ delay: 60000 }), (0, rxjs_1.retry)({ delay: 5000 }), (0, rxjs_1.shareReplay)(1));
69
+ const getCredentialById = async (credential_id) => {
70
+ const credentials = await (0, rxjs_1.firstValueFrom)(exports.validCredentials$);
71
+ return credentials.get(credential_id);
72
+ };
73
+ exports.getCredentialById = getCredentialById;
74
+ //# 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 { formatTime, scopeError } from '@yuants/utils';\nimport { defer, firstValueFrom, repeat, retry, shareReplay } from 'rxjs';\n\nexport interface IExchangeCredential {\n type: string;\n payload: any;\n}\n\nconst terminal = Terminal.fromNodeEnv();\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);\nterminal.server.provideService<void, IExchangeCredential[]>('VEX/ListExchangeCredential', {}, 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\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 listValidCredentials = async () => {\n const credentials = new Map<string, IExchangeCredential>();\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 console.info(formatTime(Date.now()), `Found ${secrets.length} exchange credential secrets`);\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 getCredentialId(terminal, credential);\n\n scopeError('GET_CREDENTIAL_ID_FAILED', { res }, () => {\n const credentialId = res.data;\n if (!credentialId) throw new Error('Credential ID is empty');\n credentials.set(credentialId, credential);\n console.info(formatTime(Date.now()), `Valid credential found: ${credentialId}`);\n });\n } catch (e) {\n console.info(formatTime(Date.now()), 'Failed to process secret', e);\n }\n }\n return credentials;\n};\n\nexport const validCredentials$ = defer(() => listValidCredentials()).pipe(\n repeat({ delay: 60000 }),\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"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=general.d.ts.map
@@ -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
@@ -1,2 +1,4 @@
1
- export {};
1
+ import './legacy-services';
2
+ import './credential';
3
+ import './general';
2
4
  //# sourceMappingURL=index.d.ts.map
@@ -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
- const protocol_1 = require("@yuants/protocol");
4
- const secret_1 = require("@yuants/secret");
5
- const sql_1 = require("@yuants/sql");
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":";;AAEA,+CAA4C;AAC5C,2CAAkE;AAClE,qCAAoD;AACpD,+BAAqD;AAErD,MAAM,QAAQ,GAAG,mBAAQ,CAAC,WAAW,EAAE,CAAC;AAOxC,MAAM,2BAA2B,GAAG,IAAI,GAAG,EAA+B,CAAC;AAE3E,gCAAgC;AAChC,QAAQ,CAAC,MAAM,CAAC,cAAc,CAC5B,4CAA4C,EAC5C;IACE,IAAI,EAAE,QAAQ;IACd,QAAQ,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC;IAC7B,UAAU,EAAE;QACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACxB,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;KAC5B;CACF,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;IACZ,MAAM,UAAU,GAAG,GAAG,CAAC,GAAG,CAAC;IAC3B,MAAM,UAAU,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC;IACxE,MAAM,IAAA,oBAAW,EAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE,EAAE,UAAU,CAAC,CAAC;IACtG,OAAO,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC;AAC7C,CAAC,CACF,CAAC;AAEF,4BAA4B;AAC5B,QAAQ,CAAC,MAAM,CAAC,cAAc,CAC5B,wCAAwC,EACxC,EAAE,EACF,KAAK,IAAI,EAAE;IACT,MAAM,OAAO,GAAG,MAAM,IAAA,gBAAU,EAC9B,QAAQ,EACR,iFAAiF,IAAA,eAAS,EACxF,QAAQ,CAAC,OAAO,CAAC,UAAU,CAC5B,EAAE,CACJ,CAAC;IACF,MAAM,WAAW,GAA0B,EAAE,CAAC;IAC9C,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;QAC5B,IAAI;YACF,MAAM,SAAS,GAAG,MAAM,IAAA,mBAAU,EAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YACrD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;YACnE,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;SAC9B;QAAC,OAAO,CAAC,EAAE;YACV,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,CAAC,CAAC,CAAC;SAC9C;KACF;IACD,OAAO,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,CAAC;AAChE,CAAC,CACF,CAAC;AAEF,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAiB,iCAAiC,EAAE,EAAE,EAAE,KAAK,IAAI,EAAE;IAC/F,OAAO,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,2BAA2B,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;AAC5F,CAAC,CAAC,CAAC;AAEH,0BAA0B;AAC1B,MAAM,WAAW,GAAG,KAAK,IAAI,EAAE;IAC7B,MAAM,OAAO,GAAG,MAAM,IAAA,gBAAU,EAC9B,QAAQ,EACR,iFAAiF,IAAA,eAAS,EACxF,QAAQ,CAAC,OAAO,CAAC,UAAU,CAC5B,EAAE,CACJ,CAAC;IACF,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;QAC5B,IAAI;YACF,MAAM,SAAS,GAAG,MAAM,IAAA,mBAAU,EAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YACrD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAwB,CAAC;YAE1F,4CAA4C;YAC5C,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,kBAAkB,CAClD,iBAAiB,EACjB,EAAE,UAAU,EAAE,CACf,CAAC;YAEF,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC,IAAI,GAAG,CAAC,IAAI,EAAE;gBAC9B,MAAM,YAAY,GAAG,GAAG,CAAC,IAAI,CAAC;gBAC9B,2BAA2B,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;aAC3D;SACF;QAAC,OAAO,CAAC,EAAE;YACV,OAAO,CAAC,KAAK,CAAC,0BAA0B,EAAE,CAAC,CAAC,CAAC;SAC9C;KACF;AACH,CAAC,CAAC;AAEF,+BAA+B;AAC/B,IAAA,YAAK,EAAC,CAAC,EAAE,KAAK,CAAC;KACZ,IAAI,CAAC,IAAA,eAAQ,EAAC,GAAG,EAAE,CAAC,IAAA,YAAK,EAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAA,YAAK,EAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;KACrE,SAAS,EAAE,CAAC;AAEf,sBAAsB;AACtB,QAAQ,CAAC,MAAM,CAAC,cAAc,CAC5B,gCAAgC,EAChC;IACE,IAAI,EAAE,QAAQ;IACd,QAAQ,EAAE,CAAC,eAAe,CAAC;IAC3B,UAAU,EAAE;QACV,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACjC,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;KAC/B;CACF,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;IACZ,MAAM,UAAU,GAAG,2BAA2B,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAC1E,IAAI,CAAC,UAAU,EAAE;QACf,OAAO,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,sBAAsB,EAAE,EAAE,CAAC;KAChE;IACD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,kBAAkB,CAGlD,gBAAgB,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,GAAG,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC;IACpE,OAAO,EAAE,GAAG,EAAE,CAAC;AACjB,CAAC,CACF,CAAC;AAEF,QAAQ,CAAC,MAAM,CAAC,cAAc,CAC5B,6BAA6B,EAC7B;IACE,IAAI,EAAE,QAAQ;IACd,QAAQ,EAAE,CAAC,eAAe,CAAC;IAC3B,UAAU,EAAE;QACV,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACjC,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;KAC/B;CACF,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;IACZ,MAAM,UAAU,GAAG,2BAA2B,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAC1E,IAAI,CAAC,UAAU,EAAE;QACf,OAAO,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,sBAAsB,EAAE,EAAE,CAAC;KAChE;IACD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,kBAAkB,CAGlD,aAAa,EAAE;QACf,UAAU;QACV,UAAU,EAAE,GAAG,CAAC,GAAG,CAAC,UAAU;KAC/B,CAAC,CAAC;IACH,OAAO,EAAE,GAAG,EAAE,CAAC;AACjB,CAAC,CACF,CAAC;AAEF,mBAAmB;AACnB,cAAc;AACd,QAAQ,CAAC,MAAM,CAAC,cAAc,CAC5B,6BAA6B,EAC7B;IACE,IAAI,EAAE,QAAQ;IACd,QAAQ,EAAE,CAAC,OAAO,EAAE,eAAe,CAAC;IACpC,UAAU,EAAE;QACV,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACzB,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;KAClC;CACF,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;IACZ,MAAM,UAAU,GAAG,2BAA2B,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAC1E,IAAI,CAAC,UAAU,EAAE;QACf,OAAO,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,sBAAsB,EAAE,EAAE,CAAC;KAChE;IACD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,kBAAkB,CAGlD,aAAa,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;IACvD,OAAO,EAAE,GAAG,EAAE,CAAC;AACjB,CAAC,CACF,CAAC;AAEF,cAAc;AACd,QAAQ,CAAC,MAAM,CAAC,cAAc,CAC5B,6BAA6B,EAC7B;IACE,IAAI,EAAE,QAAQ;IACd,QAAQ,EAAE,CAAC,OAAO,EAAE,eAAe,CAAC;IACpC,UAAU,EAAE;QACV,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACzB,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;KAClC;CACF,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;IACZ,MAAM,UAAU,GAAG,2BAA2B,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAC1E,IAAI,CAAC,UAAU,EAAE;QACf,OAAO,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,sBAAsB,EAAE,EAAE,CAAC;KAChE;IACD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,kBAAkB,CAGlD,aAAa,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;IACvD,OAAO,EAAE,GAAG,EAAE,CAAC;AACjB,CAAC,CACF,CAAC;AAEF,cAAc;AACd,QAAQ,CAAC,MAAM,CAAC,cAAc,CAC5B,6BAA6B,EAC7B;IACE,IAAI,EAAE,QAAQ;IACd,QAAQ,EAAE,CAAC,OAAO,EAAE,eAAe,CAAC;IACpC,UAAU,EAAE;QACV,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACzB,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;KAClC;CACF,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;IACZ,MAAM,UAAU,GAAG,2BAA2B,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAC1E,IAAI,CAAC,UAAU,EAAE;QACf,OAAO,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,sBAAsB,EAAE,EAAE,CAAC;KAChE;IACD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,kBAAkB,CAGlD,aAAa,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;IACvD,OAAO,EAAE,GAAG,EAAE,CAAC;AACjB,CAAC,CACF,CAAC;AAEF,aAAa","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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=legacy-services.d.ts.map
@@ -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.2.0",
3
+ "version": "0.3.0",
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
  },
@@ -1,20 +1,25 @@
1
1
  {
2
- "apps/virtual-exchange/CHANGELOG.json": "2cd374d6d4056bd811d5d5203b1d42bb384ca5c3",
3
- "apps/virtual-exchange/CHANGELOG.md": "b6255a27348857b64bff46895baada2240aefc99",
2
+ "apps/virtual-exchange/CHANGELOG.json": "1f8c0366866e86b43b8316593b7519fd6a6a5615",
3
+ "apps/virtual-exchange/CHANGELOG.md": "ac3c743aa5d473fe06839d300b9ccebeffb820aa",
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": "b88aa74b5095fe55485fe08ccd30ecc511c283ba",
10
- "apps/virtual-exchange/src/index.ts": "8bc86fc3fdf97602be9772127fcec48f5edb5c6c",
9
+ "apps/virtual-exchange/package.json": "6c1fdebe39f3aed28b428ff72a9aee50fc814b7f",
10
+ "apps/virtual-exchange/src/credential.ts": "3ca95cbcf900e8f8ef32aee64931d778e35b596f",
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": "8c5c8eb58b6b8757344017c67c08f71d4e6dd4d7",
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
  }