@ocap/resolver 1.24.8 → 1.25.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.
package/lib/api.js ADDED
@@ -0,0 +1,71 @@
1
+ const { Router } = require('express');
2
+ const { getNftBGColorFromDid, getSvg } = require('@arcblock/nft-display');
3
+
4
+ function createAPIHandler({ resolver }) {
5
+ const router = Router();
6
+
7
+ router.get('/token/display', async (req, res) => {
8
+ const { address } = req.query;
9
+ if (!address) {
10
+ return res.status(400).json({ error: 'address is required' });
11
+ }
12
+
13
+ const token = await resolver.getTokenState({ address });
14
+
15
+ if (!token) {
16
+ return res.status(400).json({ error: 'token not found' });
17
+ }
18
+
19
+ let iconUri = '';
20
+
21
+ if (token.icon) {
22
+ let iconWidth = 40;
23
+ let iconHeight = 40;
24
+
25
+ // Extract viewBox dimensions to ensure the icon displays properly in nft-display
26
+ const viewBoxMatch = token.icon.match(/viewBox\s*=\s*["']([^"']+)["']/i);
27
+ if (viewBoxMatch) {
28
+ const viewBoxValues = viewBoxMatch[1].split(/\s+/);
29
+ if (viewBoxValues.length >= 4) {
30
+ iconWidth = +viewBoxValues[2] || iconWidth;
31
+ iconHeight = +viewBoxValues[3] || iconHeight;
32
+ }
33
+ }
34
+
35
+ const fixedSvg = token.icon.replace(/<svg([^>]*)>/, `<svg$1 width="${iconWidth}" height="${iconHeight}">`);
36
+
37
+ iconUri = `data:image/svg+xml;base64,${Buffer.from(fixedSvg).toString('base64')}`;
38
+ }
39
+
40
+ const svg = getSvg({
41
+ color: getNftBGColorFromDid(address),
42
+
43
+ did: address,
44
+ variant: 'app-passport',
45
+ verifiable: true,
46
+ chain: 'arcblock',
47
+
48
+ header: {
49
+ icon: iconUri,
50
+ name: token.symbol,
51
+ },
52
+
53
+ issuer: {
54
+ name: token.symbol,
55
+ icon: iconUri,
56
+ },
57
+
58
+ extra: {
59
+ key: 'Name',
60
+ value: token.name,
61
+ },
62
+ });
63
+
64
+ res.setHeader('Content-Type', 'image/svg+xml');
65
+ res.send(svg);
66
+ });
67
+
68
+ return router;
69
+ }
70
+
71
+ module.exports = { createAPIHandler };
package/lib/hooks.js CHANGED
@@ -295,6 +295,12 @@ const onAccountMigrate = async (tx, resolver) => {
295
295
  }
296
296
  };
297
297
 
298
+ const onUpdateToken = (tokenDoc, ctx, indexdb, resolver) => {
299
+ if (resolver.tokenCache) {
300
+ resolver.tokenCache.set(tokenDoc.address, tokenDoc);
301
+ }
302
+ };
303
+
298
304
  const onCreateTx = async (tx, ctx, resolver) => {
299
305
  // Always update distribution even if tx failed cause there might be had gas
300
306
  try {
@@ -331,4 +337,4 @@ const onCreateTx = async (tx, ctx, resolver) => {
331
337
  }
332
338
  };
333
339
 
334
- module.exports = { onCreateRollup, onCreateTx, onCreateRollupBlock };
340
+ module.exports = { onCreateRollup, onCreateTx, onCreateRollupBlock, onUpdateToken };
package/lib/index.js CHANGED
@@ -87,7 +87,7 @@ const maxGasOps = {
87
87
  'fg:t:transfer_v3': { create: 9, update: 16 },
88
88
  'fg:t:exchange_v2': { create: 1, update: 18 },
89
89
 
90
- 'fg:t:create_token_factory': { create: 2, update: 2 },
90
+ 'fg:t:create_token_factory': { create: 2, update: 3 },
91
91
  'fg:t:update_token_factory': { create: 0, update: 3 },
92
92
  'fg:t:mint_token': { create: 2, update: 13 },
93
93
  'fg:t:burn_token': { create: 2, update: 13 },
@@ -510,6 +510,9 @@ module.exports = class OCAPResolver {
510
510
  if (typeof state.decimal === 'undefined') {
511
511
  state.decimal = DEFAULT_TOKEN_DECIMAL;
512
512
  }
513
+ if (state.metadata) {
514
+ state.metadata = formatData(state.metadata);
515
+ }
513
516
  }
514
517
 
515
518
  return state;
@@ -524,11 +527,11 @@ module.exports = class OCAPResolver {
524
527
  onRead: async (state) => {
525
528
  if (state) {
526
529
  const [token, reserveToken] = await Promise.all([
527
- this.tokenCache.get(state.tokenAddress),
528
- this.tokenCache.get(state.reserveAddress),
530
+ this.getTokenState({ address: state.tokenAddress }),
531
+ this.getTokenState({ address: state.reserveAddress }),
529
532
  ]);
530
- state.token = token;
531
- state.reserveToken = reserveToken;
533
+ state.token = { ...token, metadata: formatData(token.metadata) };
534
+ state.reserveToken = { ...reserveToken, metadata: formatData(reserveToken.metadata) };
532
535
  }
533
536
 
534
537
  return state;
@@ -613,6 +616,10 @@ module.exports = class OCAPResolver {
613
616
  minStake: fromTokenToUnit(transaction.txGas.minStake, token.decimal).toString(10),
614
617
  maxStake: fromTokenToUnit(transaction.txGas.maxStake, token.decimal).toString(10),
615
618
  },
619
+ txStake: {
620
+ ...transaction.txStake,
621
+ createToken: fromTokenToUnit(transaction.txStake.createToken, token.decimal).toString(10),
622
+ },
616
623
  txFee: Object.keys(transaction.txFee)
617
624
  .filter((x) => x !== 'default')
618
625
  .map((x) => ({ typeUrl: x, fee: fromTokenToUnit(transaction.txFee[x], token.decimal).toString(10) })),
@@ -695,7 +702,7 @@ module.exports = class OCAPResolver {
695
702
  }
696
703
 
697
704
  listTokens(args, ctx) {
698
- return this._doPaginatedSearch('listTokens', args, 'tokens', 'data', ctx);
705
+ return this._doPaginatedSearch('listTokens', args, 'tokens', ['data', 'metadata'], ctx);
699
706
  }
700
707
 
701
708
  listTokenFactories(args, ctx) {
@@ -946,7 +953,7 @@ module.exports = class OCAPResolver {
946
953
  const mapping = {
947
954
  asset: [createIndexedAsset, 'address'],
948
955
  delegation: [createIndexedDelegation, 'address'],
949
- token: [createIndexedToken, 'address'],
956
+ token: [createIndexedToken, 'address', null, hooks.onUpdateToken],
950
957
  factory: [createIndexedFactory, 'address'],
951
958
  stake: [createIndexedStake, 'address'],
952
959
  rollup: [createIndexedRollup, 'address', hooks.onCreateRollup],
@@ -962,7 +969,7 @@ module.exports = class OCAPResolver {
962
969
  const doc = await fn(x, ctx, this.indexdb);
963
970
  await this.indexdb[table].insert(doc);
964
971
  if (typeof onCreate === 'function') {
965
- await onCreate(doc, ctx, this.indexdb);
972
+ await onCreate(doc, ctx, this.indexdb, this);
966
973
  }
967
974
  } catch (error) {
968
975
  this.logger.error(`create ${table} index failed`, { [table]: x, error });
@@ -975,7 +982,7 @@ module.exports = class OCAPResolver {
975
982
  const doc = await fn(x, ctx, this.indexdb);
976
983
  await this.indexdb[table].update(doc[key], doc);
977
984
  if (typeof onUpdate === 'function') {
978
- await onUpdate(doc, ctx, this.indexdb);
985
+ await onUpdate(doc, ctx, this.indexdb, this);
979
986
  }
980
987
  } catch (error) {
981
988
  this.logger.error(`update ${table} index failed`, { [table]: x, error });
@@ -1029,7 +1036,11 @@ module.exports = class OCAPResolver {
1029
1036
  if (dataKey) {
1030
1037
  data = await Promise.all(
1031
1038
  items.map(async (x) => {
1032
- let tx = set(x, dataKey, formatData(get(x, dataKey)));
1039
+ let tx = x;
1040
+ // dataKey can be an array or string
1041
+ [].concat(dataKey).forEach((key) => {
1042
+ tx = set(tx, key, formatData(get(tx, key)));
1043
+ });
1033
1044
  if (listKey === 'transactions') {
1034
1045
  tx = await this.formatTx(tx, ctx);
1035
1046
  }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.24.8",
6
+ "version": "1.25.0",
7
7
  "description": "GraphQL resolver built upon ocap statedb and GQL layer",
8
8
  "main": "lib/index.js",
9
9
  "files": [
@@ -14,25 +14,27 @@
14
14
  "license": "MIT",
15
15
  "devDependencies": {
16
16
  "jest": "^29.7.0",
17
- "@ocap/indexdb-memory": "1.24.8",
18
- "@ocap/statedb-memory": "1.24.8"
17
+ "@ocap/indexdb-memory": "1.25.0",
18
+ "@ocap/statedb-memory": "1.25.0"
19
19
  },
20
20
  "dependencies": {
21
+ "@arcblock/nft-display": "^3.1.41",
21
22
  "debug": "^4.3.6",
23
+ "express": "^4.19.2",
22
24
  "lodash": "^4.17.21",
23
25
  "queue": "^6",
24
- "@arcblock/did": "1.24.8",
25
- "@arcblock/did-ext": "1.24.8",
26
- "@arcblock/did-util": "1.24.8",
27
- "@arcblock/validator": "1.24.8",
28
- "@ocap/config": "1.24.8",
29
- "@ocap/indexdb": "1.24.8",
30
- "@ocap/mcrypto": "1.24.8",
31
- "@ocap/message": "1.24.8",
32
- "@ocap/state": "1.24.8",
33
- "@ocap/tx-protocols": "1.24.8",
34
- "@ocap/util": "1.24.8",
35
- "@ocap/wallet": "1.24.8"
26
+ "@arcblock/did": "1.25.0",
27
+ "@arcblock/did-ext": "1.25.0",
28
+ "@arcblock/did-util": "1.25.0",
29
+ "@arcblock/validator": "1.25.0",
30
+ "@ocap/config": "1.25.0",
31
+ "@ocap/indexdb": "1.25.0",
32
+ "@ocap/mcrypto": "1.25.0",
33
+ "@ocap/message": "1.25.0",
34
+ "@ocap/state": "1.25.0",
35
+ "@ocap/tx-protocols": "1.25.0",
36
+ "@ocap/util": "1.25.0",
37
+ "@ocap/wallet": "1.25.0"
36
38
  },
37
39
  "scripts": {
38
40
  "lint": "eslint tests lib",