Skip to content
This repository was archived by the owner on Nov 10, 2021. It is now read-only.

Commit f4dbf1c

Browse files
authored
Merge pull request #13 from anonymoussprocket/master
Extra collection details
2 parents fd78f2d + 02d4e57 commit f4dbf1c

File tree

2 files changed

+124
-50
lines changed

2 files changed

+124
-50
lines changed

conseilUtil.js

Lines changed: 88 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const conseiljs = require('conseiljs')
22
const fetch = require('node-fetch')
33
const log = require('loglevel')
4+
const BigNumber = require('bignumber.js')
45

56
const logger = log.getLogger('conseiljs')
67
logger.setLevel('error', false)
@@ -35,7 +36,7 @@ const hDAOFeed = async () => {
3536
*/
3637
const getCollectionForAddress = async (address) => {
3738
let collectionQuery = conseiljs.ConseilQueryBuilder.blankQuery();
38-
collectionQuery = conseiljs.ConseilQueryBuilder.addFields(collectionQuery, 'key', 'value');
39+
collectionQuery = conseiljs.ConseilQueryBuilder.addFields(collectionQuery, 'key', 'value', 'operation_group_id');
3940
collectionQuery = conseiljs.ConseilQueryBuilder.addPredicate(collectionQuery, 'big_map_id', conseiljs.ConseilOperator.EQ, [mainnet.nftLedger])
4041
collectionQuery = conseiljs.ConseilQueryBuilder.addPredicate(collectionQuery, 'key', conseiljs.ConseilOperator.STARTSWITH, [
4142
`Pair 0x${conseiljs.TezosMessageUtils.writeAddress(address)}`,
@@ -45,10 +46,14 @@ const getCollectionForAddress = async (address) => {
4546

4647
const collectionResult = await conseiljs.TezosConseilClient.getTezosEntityData({ url: conseilServer, apiKey: conseilApiKey, network: 'mainnet' }, 'mainnet', 'big_map_contents', collectionQuery);
4748
let collection = collectionResult.map((i) => {
48-
return { piece: i.key.toString().replace(/.* ([0-9]{1,}$)/, '$1'), amount: Number(i.value) }
49+
return {
50+
piece: i['key'].toString().replace(/.* ([0-9]{1,}$)/, '$1'),
51+
amount: Number(i['value']),
52+
opId: i['operation_group_id']
53+
}
4954
})
5055

51-
const queryChunks = chunkArray(collection.map(i => i.piece), 20) // NOTE: consider increasing this number somewhat
56+
const queryChunks = chunkArray(collection.map(i => i.piece), 50) // NOTE: consider increasing this number somewhat
5257
const makeObjectQuery = (keys) => {
5358
let mintedObjectsQuery = conseiljs.ConseilQueryBuilder.blankQuery();
5459
mintedObjectsQuery = conseiljs.ConseilQueryBuilder.addFields(mintedObjectsQuery, 'key_hash', 'value');
@@ -70,17 +75,84 @@ const getCollectionForAddress = async (address) => {
7075
objectIpfsMap[objectId] = ipfsHash
7176
}))))
7277

73-
collection = collection.map(i => { return {
74-
ipfsHash: objectIpfsMap[i.piece.toString()],
75-
...i
78+
const operationGroupIds = collectionResult.map((r) => r.operation_group_id)
79+
const priceQueryChunks = chunkArray(operationGroupIds, 30)
80+
const makeLastPriceQuery = (opIds) => {
81+
let lastPriceQuery = conseiljs.ConseilQueryBuilder.blankQuery();
82+
lastPriceQuery = conseiljs.ConseilQueryBuilder.addFields(lastPriceQuery, 'timestamp', 'amount', 'operation_group_hash', 'parameters_entrypoints', 'parameters');
83+
lastPriceQuery = conseiljs.ConseilQueryBuilder.addPredicate(lastPriceQuery, 'kind', conseiljs.ConseilOperator.EQ, ['transaction']);
84+
lastPriceQuery = conseiljs.ConseilQueryBuilder.addPredicate(lastPriceQuery, 'status', conseiljs.ConseilOperator.EQ, ['applied']);
85+
lastPriceQuery = conseiljs.ConseilQueryBuilder.addPredicate(lastPriceQuery, 'internal', conseiljs.ConseilOperator.EQ, ['false']);
86+
lastPriceQuery = conseiljs.ConseilQueryBuilder.addPredicate(lastPriceQuery, 'operation_group_hash', opIds.length > 1 ? conseiljs.ConseilOperator.IN : conseiljs.ConseilOperator.EQ, opIds);
87+
lastPriceQuery = conseiljs.ConseilQueryBuilder.setLimit(lastPriceQuery, opIds.length);
88+
89+
return lastPriceQuery;
90+
}
91+
92+
const priceQueries = priceQueryChunks.map((c) => makeLastPriceQuery(c))
93+
const priceMap = {};
94+
await Promise.all(
95+
priceQueries.map(
96+
async (q) =>
97+
await conseiljs.TezosConseilClient.getTezosEntityData({ url: conseilServer, apiKey: conseilApiKey, network: 'mainnet' }, 'mainnet', 'operations', q).then((result) =>
98+
result.map((row) => {
99+
let amount = 0;
100+
const action = row.parameters_entrypoints;
101+
102+
if (action === 'collect') {
103+
amount = Number(row.parameters.toString().replace(/^Pair ([0-9]+) [0-9]+/, '$1'));
104+
} else if (action === 'transfer') {
105+
amount = Number(
106+
row.parameters
107+
.toString()
108+
.replace(
109+
/[{] Pair \"[1-9A-HJ-NP-Za-km-z]{36}\" [{] Pair \"[1-9A-HJ-NP-Za-km-z]{36}\" [(]Pair [0-9]+ [0-9]+[)] [}] [}]/,
110+
'$1'
111+
)
112+
);
113+
}
114+
115+
priceMap[row.operation_group_hash] = {
116+
price: new BigNumber(row.amount),
117+
amount,
118+
timestamp: row.timestamp,
119+
action,
120+
};
121+
})
122+
)
123+
)
124+
)
125+
126+
collection = collection.map(i => {
127+
let price = 0
128+
let receivedOn = new Date()
129+
let action = ''
130+
131+
try {
132+
const priceRecord = priceMap[i.opId]
133+
price = priceRecord.price.dividedToIntegerBy(priceRecord.amount).toNumber()
134+
receivedOn = new Date(priceRecord.timestamp)
135+
action = priceRecord.action === 'collect' ? 'Purchased' : 'Received'
136+
} catch {
137+
//
138+
}
139+
140+
delete i.opId
141+
142+
return {
143+
price: isNaN(price) ? 0 : price,
144+
receivedOn,
145+
action,
146+
ipfsHash: objectIpfsMap[i.piece.toString()],
147+
...i
76148
}})
77149

78-
return collection.sort((a, b) => parseInt(b.piece) - parseInt(a.piece)) // sort descending by id – most-recently minted art first
150+
return collection.sort((a, b) => b.receivedOn.getTime() - a.receivedOn.getTime()) // sort descending by date – most-recently acquired art first
79151
}
80152

81153
const gethDaoBalanceForAddress = async (address) => {
82-
let hDaoBalanceQuery = conseiljs.ConseilQueryBuilder.blankQuery();
83-
hDaoBalanceQuery = conseiljs.ConseilQueryBuilder.addFields(hDaoBalanceQuery, 'value');
154+
let hDaoBalanceQuery = conseiljs.ConseilQueryBuilder.blankQuery()
155+
hDaoBalanceQuery = conseiljs.ConseilQueryBuilder.addFields(hDaoBalanceQuery, 'value')
84156
hDaoBalanceQuery = conseiljs.ConseilQueryBuilder.addPredicate(hDaoBalanceQuery, 'big_map_id', conseiljs.ConseilOperator.EQ, [mainnet.daoLedger])
85157
hDaoBalanceQuery = conseiljs.ConseilQueryBuilder.addPredicate(hDaoBalanceQuery, 'key', conseiljs.ConseilOperator.EQ, [
86158
`Pair 0x${conseiljs.TezosMessageUtils.writeAddress(address)} 0`
@@ -91,7 +163,7 @@ const gethDaoBalanceForAddress = async (address) => {
91163
let balance = 0
92164

93165
try {
94-
const balanceResult = await conseiljs.TezosConseilClient.getTezosEntityData({ url: conseilServer, apiKey: conseilApiKey, network: 'mainnet' }, 'mainnet', 'big_map_contents', hDaoBalanceQuery);
166+
const balanceResult = await conseiljs.TezosConseilClient.getTezosEntityData({ url: conseilServer, apiKey: conseilApiKey, network: 'mainnet' }, 'mainnet', 'big_map_contents', hDaoBalanceQuery)
95167
balance = balanceResult[0]['value'] // TODO: consider bigNumber here, for the moment there is no reason for it
96168
} catch (error) {
97169
console.log(`gethDaoBalanceForAddress failed for ${JSON.stringify(hDaoBalanceQuery)} with ${error}`)
@@ -233,8 +305,8 @@ const getObjektMintingsLastWeek = async () => {
233305
* @returns
234306
*/
235307
const getArtisticOutputForAddress = async (address) => {
236-
let mintOperationQuery = conseiljs.ConseilQueryBuilder.blankQuery();
237-
mintOperationQuery = conseiljs.ConseilQueryBuilder.addFields(mintOperationQuery, 'operation_group_hash');
308+
let mintOperationQuery = conseiljs.ConseilQueryBuilder.blankQuery()
309+
mintOperationQuery = conseiljs.ConseilQueryBuilder.addFields(mintOperationQuery, 'operation_group_hash')
238310
mintOperationQuery = conseiljs.ConseilQueryBuilder.addPredicate(mintOperationQuery, 'kind', conseiljs.ConseilOperator.EQ, ['transaction'])
239311
mintOperationQuery = conseiljs.ConseilQueryBuilder.addPredicate(mintOperationQuery, 'timestamp', conseiljs.ConseilOperator.AFTER, [1612240919000]) // 2021 Feb 1
240312
mintOperationQuery = conseiljs.ConseilQueryBuilder.addPredicate(mintOperationQuery, 'status', conseiljs.ConseilOperator.EQ, ['applied'])
@@ -248,14 +320,14 @@ const getArtisticOutputForAddress = async (address) => {
248320
{ url: conseilServer, apiKey: conseilApiKey, network: 'mainnet' },
249321
'mainnet',
250322
'operations',
251-
mintOperationQuery);
323+
mintOperationQuery)
252324

253325
const operationGroupIds = mintOperationResult.map(r => r['operation_group_hash'])
254326
const queryChunks = chunkArray(operationGroupIds, 30)
255327

256328
const makeObjectQuery = (opIds) => {
257-
let mintedObjectsQuery = conseiljs.ConseilQueryBuilder.blankQuery();
258-
mintedObjectsQuery = conseiljs.ConseilQueryBuilder.addFields(mintedObjectsQuery, 'key_hash', 'value');
329+
let mintedObjectsQuery = conseiljs.ConseilQueryBuilder.blankQuery()
330+
mintedObjectsQuery = conseiljs.ConseilQueryBuilder.addFields(mintedObjectsQuery, 'key_hash', 'value')
259331
mintedObjectsQuery = conseiljs.ConseilQueryBuilder.addPredicate(mintedObjectsQuery, 'big_map_id', conseiljs.ConseilOperator.EQ, [mainnet.nftMetadataMap])
260332
mintedObjectsQuery = conseiljs.ConseilQueryBuilder.addPredicate(mintedObjectsQuery, 'operation_group_id', (opIds.length > 1 ? conseiljs.ConseilOperator.IN : conseiljs.ConseilOperator.EQ), opIds)
261333
mintedObjectsQuery = conseiljs.ConseilQueryBuilder.setLimit(mintedObjectsQuery, opIds.length)
@@ -306,7 +378,7 @@ const getArtisticUniverse = async (max_time) => {
306378
})
307379

308380
let swapsQuery = conseiljs.ConseilQueryBuilder.blankQuery();
309-
swapsQuery = conseiljs.ConseilQueryBuilder.addFields(swapsQuery, 'key', 'value');
381+
swapsQuery = conseiljs.ConseilQueryBuilder.addFields(swapsQuery, 'key', 'value')
310382
swapsQuery = conseiljs.ConseilQueryBuilder.addPredicate(swapsQuery, 'big_map_id', conseiljs.ConseilOperator.EQ, [mainnet.nftSwapMap])
311383
swapsQuery = conseiljs.ConseilQueryBuilder.setLimit(swapsQuery, 30_000) // NOTE, limited to 30_000
312384

@@ -410,7 +482,6 @@ const getRecommendedCurateDefault = async() => {
410482
* @param {number} objectId
411483
* @returns
412484
*/
413-
414485
const getObjectById = async (objectId) => {
415486
let objectQuery = conseiljs.ConseilQueryBuilder.blankQuery();
416487
objectQuery = conseiljs.ConseilQueryBuilder.addFields(objectQuery, 'value');

package.json

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,38 @@
11
{
2-
"name": "hicetnunc-apiv2",
3-
"version": "1.0.0",
4-
"description": "",
5-
"main": "index.js",
6-
"scripts": {
7-
"start": "node index.js"
8-
},
9-
"repository": {
10-
"type": "git",
11-
"url": "git+https://github.com/hicetnunc2000/hicetnunc.git"
12-
},
13-
"author": "@hicetnunc2000",
14-
"license": "MIT",
15-
"bugs": {
16-
"url": "https://github.com/hicetnunc2000/hicetnunc/issues"
17-
},
18-
"homepage": "https://github.com/hicetnunc2000/hicetnunc#readme",
19-
"dependencies": {
20-
"axios": "^0.21.1",
21-
"conseiljs": "5.0.7-2",
22-
"cors": "^2.8.5",
23-
"dotenv": "^8.2.0",
24-
"express": "^4.17.1",
25-
"lodash": "^4.17.21",
26-
"loglevel": "1.7.1",
27-
"node-fetch": "2.6.1",
28-
"serverless-dotenv-plugin": "^3.8.1",
29-
"serverless-http": "^2.7.0"
30-
},
31-
"engines": {
32-
"node": "12.20.1",
33-
"npm": "6.14.10"
34-
}
2+
"name": "hicetnunc-apiv2",
3+
"version": "1.0.0",
4+
"description": "",
5+
"main": "index.js",
6+
"scripts": {
7+
"start": "node index.js"
8+
},
9+
"repository": {
10+
"type": "git",
11+
"url": "git+https://github.com/hicetnunc2000/hicetnunc-api.git"
12+
},
13+
"author": "@hicetnunc2000",
14+
"license": "MIT",
15+
"bugs": {
16+
"url": "https://github.com/hicetnunc2000/hicetnunc-api/issues"
17+
},
18+
"homepage": "https://github.com/hicetnunc2000/hicetnunc-api#readme",
19+
"dependencies": {
20+
"axios": "^0.21.1",
21+
"bignumber.js": "9.0.1",
22+
"cloud-local-storage": "0.0.11",
23+
"conseiljs": "5.0.8-1",
24+
"cors": "^2.8.5",
25+
"dotenv": "^8.2.0",
26+
"express": "^4.17.1",
27+
"fetch": "^1.1.0",
28+
"lodash": "^4.17.21",
29+
"loglevel": "1.7.1",
30+
"node-fetch": "2.6.1",
31+
"serverless-dotenv-plugin": "^3.8.1",
32+
"serverless-http": "^2.7.0"
33+
},
34+
"engines": {
35+
"node": "12.20.1",
36+
"npm": "6.14.10"
37+
}
3538
}

0 commit comments

Comments
 (0)