@yuants/app-virtual-exchange 0.3.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.
@@ -2,9 +2,26 @@ import { getCredentialId } from '@yuants/exchange';
2
2
  import { Terminal } from '@yuants/protocol';
3
3
  import { readSecret, writeSecret } from '@yuants/secret';
4
4
  import { escapeSQL, requestSQL } from '@yuants/sql';
5
- import { formatTime, scopeError } from '@yuants/utils';
6
- import { defer, firstValueFrom, repeat, retry, shareReplay } from 'rxjs';
5
+ import { defer, firstValueFrom, map, repeat, retry, shareReplay } from 'rxjs';
7
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
+ };
8
25
  terminal.server.provideService('VEX/RegisterExchangeCredential', {
9
26
  type: 'object',
10
27
  required: ['type', 'payload'],
@@ -19,49 +36,21 @@ terminal.server.provideService('VEX/RegisterExchangeCredential', {
19
36
  return { res: { code: 0, message: 'OK' } };
20
37
  });
21
38
  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 } };
39
+ return { res: { code: 0, message: 'OK', data: await listAllCredentials() } };
35
40
  });
36
41
  terminal.server.provideService('VEX/ListCredentials', {}, async () => {
37
42
  const credentials = await firstValueFrom(validCredentials$);
38
43
  return { res: { code: 0, message: 'OK', data: [...credentials.keys()] } };
39
44
  });
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);
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);
60
50
  }
61
51
  }
62
- return credentials;
63
- };
64
- export const validCredentials$ = defer(() => listValidCredentials()).pipe(repeat({ delay: 60000 }), retry({ delay: 5000 }), shareReplay(1));
52
+ return map;
53
+ }), repeat({ delay: 10000 }), retry({ delay: 5000 }), shareReplay(1));
65
54
  export const getCredentialById = async (credential_id) => {
66
55
  const credentials = await firstValueFrom(validCredentials$);
67
56
  return credentials.get(credential_id);
@@ -1 +1 @@
1
- {"version":3,"file":"credential.js","sourceRoot":"","sources":["../src/credential.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAW,UAAU,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,MAAM,CAAC;AAOzE,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AAExC,QAAQ,CAAC,MAAM,CAAC,cAAc,CAC5B,gCAAgC,EAChC;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,WAAW,CAAC,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;AACF,QAAQ,CAAC,MAAM,CAAC,cAAc,CAA8B,4BAA4B,EAAE,EAAE,EAAE,KAAK,IAAI,EAAE;IACvG,MAAM,OAAO,GAAG,MAAM,UAAU,CAC9B,QAAQ,EACR,iFAAiF,SAAS,CACxF,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,UAAU,CAAC,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,CAAC,CAAC;AAEH,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAiB,qBAAqB,EAAE,EAAE,EAAE,KAAK,IAAI,EAAE;IACnF,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,iBAAiB,CAAC,CAAC;IAC5D,OAAO,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;AAC5E,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,IAAI,EAAE;IAC7C,MAAM,WAAW,GAAG,IAAI,GAAG,EAA+B,CAAC;IAC3D,MAAM,OAAO,GAAG,MAAM,UAAU,CAC9B,QAAQ,EACR,iFAAiF,SAAS,CACxF,QAAQ,CAAC,OAAO,CAAC,UAAU,CAC5B,EAAE,CACJ,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,SAAS,OAAO,CAAC,MAAM,8BAA8B,CAAC,CAAC;IAC5F,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE;QAC5B,IAAI;YACF,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,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,eAAe,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;YAExD,UAAU,CAAC,0BAA0B,EAAE,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE;gBACnD,MAAM,YAAY,GAAG,GAAG,CAAC,IAAI,CAAC;gBAC9B,IAAI,CAAC,YAAY;oBAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;gBAC7D,WAAW,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;gBAC1C,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,2BAA2B,YAAY,EAAE,CAAC,CAAC;YAClF,CAAC,CAAC,CAAC;SACJ;QAAC,OAAO,CAAC,EAAE;YACV,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,0BAA0B,EAAE,CAAC,CAAC,CAAC;SACrE;KACF;IACD,OAAO,WAAW,CAAC;AACrB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC,oBAAoB,EAAE,CAAC,CAAC,IAAI,CACvE,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EACxB,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EACtB,WAAW,CAAC,CAAC,CAAC,CACf,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,EAAE,aAAqB,EAAE,EAAE;IAC/D,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,iBAAiB,CAAC,CAAC;IAC5D,OAAO,WAAW,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;AACxC,CAAC,CAAC","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"]}
1
+ {"version":3,"file":"credential.js","sourceRoot":"","sources":["../src/credential.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAW,UAAU,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,MAAM,CAAC;AAO9E,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;AASxC,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,IAAI,EAAE;IAC3C,MAAM,OAAO,GAAG,MAAM,UAAU,CAC9B,QAAQ,EACR,iFAAiF,SAAS,CACxF,QAAQ,CAAC,OAAO,CAAC,UAAU,CAC5B,EAAE,CACJ,CAAC;IAEF,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAA6B,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;IAEjF,MAAM,OAAO,CAAC,GAAG,CACf,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;QAC3B,IAAI;YACF,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;YAC5D,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAwB,CAAC;YAC1F,MAAM,CAAC,UAAU,GAAG,UAAU,CAAC;YAE/B,MAAM,GAAG,GAAG,MAAM,eAAe,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;YACxD,MAAM,YAAY,GAAG,GAAG,CAAC,IAAI,CAAC;YAC9B,MAAM,CAAC,YAAY,GAAG,YAAY,CAAC;SACpC;QAAC,OAAO,CAAC,EAAE;YACV,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,EAAE,CAAC;SACxB;IACH,CAAC,CAAC,CACH,CAAC;IAEF,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF,QAAQ,CAAC,MAAM,CAAC,cAAc,CAC5B,gCAAgC,EAChC;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,WAAW,CAAC,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,QAAQ,CAAC,MAAM,CAAC,cAAc,CAC5B,4BAA4B,EAC5B,EAAE,EACF,KAAK,IAAI,EAAE;IACT,OAAO,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,kBAAkB,EAAE,EAAE,EAAE,CAAC;AAC/E,CAAC,CACF,CAAC;AAEF,QAAQ,CAAC,MAAM,CAAC,cAAc,CAAiB,qBAAqB,EAAE,EAAE,EAAE,KAAK,IAAI,EAAE;IACnF,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,iBAAiB,CAAC,CAAC;IAC5D,OAAO,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;AAC5E,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC,kBAAkB,EAAE,CAAC,CAAC,IAAI,CACrE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;IACR,MAAM,GAAG,GAAG,IAAI,GAAG,EAA+B,CAAC;IACnD,KAAK,MAAM,EAAE,IAAI,CAAC,EAAE;QAClB,IAAI,EAAE,CAAC,YAAY,IAAI,EAAE,CAAC,UAAU,EAAE;YACpC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,YAAY,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC;SACzC;KACF;IACD,OAAO,GAAG,CAAC;AACb,CAAC,CAAC,EACF,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,EACxB,KAAK,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EACtB,WAAW,CAAC,CAAC,CAAC,CACf,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,EAAE,aAAqB,EAAE,EAAE;IAC/D,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC,iBAAiB,CAAC,CAAC;IAC5D,OAAO,WAAW,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;AACxC,CAAC,CAAC","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"]}
@@ -1,8 +1,16 @@
1
+ import { ISecret } from '@yuants/secret';
1
2
  export interface IExchangeCredential {
2
3
  type: string;
3
4
  payload: any;
4
5
  }
5
- export declare const listValidCredentials: () => Promise<Map<string, IExchangeCredential>>;
6
+ interface ICredentialResolvedStatus {
7
+ secret: ISecret;
8
+ credential?: IExchangeCredential;
9
+ credentialId?: string;
10
+ reason?: string;
11
+ }
12
+ export declare const listAllCredentials: () => Promise<ICredentialResolvedStatus[]>;
6
13
  export declare const validCredentials$: import("rxjs").Observable<Map<string, IExchangeCredential>>;
7
14
  export declare const getCredentialById: (credential_id: string) => Promise<IExchangeCredential | undefined>;
15
+ export {};
8
16
  //# sourceMappingURL=credential.d.ts.map
@@ -1 +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"}
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"}
package/lib/credential.js CHANGED
@@ -1,13 +1,31 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getCredentialById = exports.validCredentials$ = exports.listValidCredentials = void 0;
3
+ exports.getCredentialById = exports.validCredentials$ = exports.listAllCredentials = void 0;
4
4
  const exchange_1 = require("@yuants/exchange");
5
5
  const protocol_1 = require("@yuants/protocol");
6
6
  const secret_1 = require("@yuants/secret");
7
7
  const sql_1 = require("@yuants/sql");
8
- const utils_1 = require("@yuants/utils");
9
8
  const rxjs_1 = require("rxjs");
10
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;
11
29
  terminal.server.provideService('VEX/RegisterExchangeCredential', {
12
30
  type: 'object',
13
31
  required: ['type', 'payload'],
@@ -22,50 +40,21 @@ terminal.server.provideService('VEX/RegisterExchangeCredential', {
22
40
  return { res: { code: 0, message: 'OK' } };
23
41
  });
24
42
  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 } };
43
+ return { res: { code: 0, message: 'OK', data: await (0, exports.listAllCredentials)() } };
38
44
  });
39
45
  terminal.server.provideService('VEX/ListCredentials', {}, async () => {
40
46
  const credentials = await (0, rxjs_1.firstValueFrom)(exports.validCredentials$);
41
47
  return { res: { code: 0, message: 'OK', data: [...credentials.keys()] } };
42
48
  });
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);
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);
63
54
  }
64
55
  }
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));
56
+ return map;
57
+ }), (0, rxjs_1.repeat)({ delay: 10000 }), (0, rxjs_1.retry)({ delay: 5000 }), (0, rxjs_1.shareReplay)(1));
69
58
  const getCredentialById = async (credential_id) => {
70
59
  const credentials = await (0, rxjs_1.firstValueFrom)(exports.validCredentials$);
71
60
  return credentials.get(credential_id);
@@ -1 +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"]}
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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yuants/app-virtual-exchange",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "main": "lib/index.js",
5
5
  "files": [
6
6
  "dist",
@@ -1,13 +1,13 @@
1
1
  {
2
- "apps/virtual-exchange/CHANGELOG.json": "1f8c0366866e86b43b8316593b7519fd6a6a5615",
3
- "apps/virtual-exchange/CHANGELOG.md": "ac3c743aa5d473fe06839d300b9ccebeffb820aa",
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": "6c1fdebe39f3aed28b428ff72a9aee50fc814b7f",
10
- "apps/virtual-exchange/src/credential.ts": "3ca95cbcf900e8f8ef32aee64931d778e35b596f",
9
+ "apps/virtual-exchange/package.json": "8775def1ac14bec9d9aa6df248127b03b540d71c",
10
+ "apps/virtual-exchange/src/credential.ts": "5277b4dbc4b634870203439ced554ae13b64b831",
11
11
  "apps/virtual-exchange/src/general.ts": "068a19f33440cbaad103a5b2a68f9594dc692b81",
12
12
  "apps/virtual-exchange/src/index.ts": "fab618a868a54508ffcd9c770485b3625d116c15",
13
13
  "apps/virtual-exchange/src/legacy-services.ts": "08284bbb1d6526c6af15ef1530866f15295554d9",