@ocap/resolver 1.24.9 → 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 +71 -0
- package/lib/hooks.js +7 -1
- package/lib/index.js +21 -10
- package/package.json +17 -15
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:
|
|
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.
|
|
528
|
-
this.
|
|
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 =
|
|
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.
|
|
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.
|
|
18
|
-
"@ocap/statedb-memory": "1.
|
|
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
|
|
25
|
-
"@arcblock/did": "1.
|
|
26
|
-
"@arcblock/did-util": "1.
|
|
27
|
-
"@arcblock/validator": "1.
|
|
28
|
-
"@ocap/
|
|
29
|
-
"@ocap/
|
|
30
|
-
"@ocap/
|
|
31
|
-
"@ocap/
|
|
32
|
-
"@ocap/
|
|
33
|
-
"@ocap/
|
|
34
|
-
"@ocap/util": "1.
|
|
35
|
-
"@ocap/wallet": "1.
|
|
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",
|