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

Commit 67888ab

Browse files
- matching collection functionality to Gallon 1.1.16
- show last price - show last acquisition date - show acquisition action
1 parent 3053fab commit 67888ab

File tree

2 files changed

+87
-15
lines changed

2 files changed

+87
-15
lines changed

conseilUtil.js

Lines changed: 86 additions & 15 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)
@@ -20,7 +21,7 @@ const mainnet = require('./config').networkConfig
2021
*/
2122
const getCollectionForAddress = async (address) => {
2223
let collectionQuery = conseiljs.ConseilQueryBuilder.blankQuery();
23-
collectionQuery = conseiljs.ConseilQueryBuilder.addFields(collectionQuery, 'key', 'value');
24+
collectionQuery = conseiljs.ConseilQueryBuilder.addFields(collectionQuery, 'key', 'value', 'operation_group_id');
2425
collectionQuery = conseiljs.ConseilQueryBuilder.addPredicate(collectionQuery, 'big_map_id', conseiljs.ConseilOperator.EQ, [mainnet.nftLedger])
2526
collectionQuery = conseiljs.ConseilQueryBuilder.addPredicate(collectionQuery, 'key', conseiljs.ConseilOperator.STARTSWITH, [
2627
`Pair 0x${conseiljs.TezosMessageUtils.writeAddress(address)}`,
@@ -30,10 +31,14 @@ const getCollectionForAddress = async (address) => {
3031

3132
const collectionResult = await conseiljs.TezosConseilClient.getTezosEntityData({ url: conseilServer, apiKey: conseilApiKey, network: 'mainnet' }, 'mainnet', 'big_map_contents', collectionQuery);
3233
let collection = collectionResult.map((i) => {
33-
return { piece: i.key.toString().replace(/.* ([0-9]{1,}$)/, '$1'), amount: Number(i.value) }
34+
return {
35+
piece: i['key'].toString().replace(/.* ([0-9]{1,}$)/, '$1'),
36+
amount: Number(i['value']),
37+
opId: i['operation_group_id']
38+
}
3439
})
3540

36-
const queryChunks = chunkArray(collection.map(i => i.piece), 20) // NOTE: consider increasing this number somewhat
41+
const queryChunks = chunkArray(collection.map(i => i.piece), 50) // NOTE: consider increasing this number somewhat
3742
const makeObjectQuery = (keys) => {
3843
let mintedObjectsQuery = conseiljs.ConseilQueryBuilder.blankQuery();
3944
mintedObjectsQuery = conseiljs.ConseilQueryBuilder.addFields(mintedObjectsQuery, 'key_hash', 'value');
@@ -55,17 +60,84 @@ const getCollectionForAddress = async (address) => {
5560
objectIpfsMap[objectId] = ipfsHash
5661
}))))
5762

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

63135
return collection.sort((a, b) => parseInt(b.piece) - parseInt(a.piece)) // sort descending by id – most-recently minted art first
64136
}
65137

66138
const gethDaoBalanceForAddress = async (address) => {
67-
let hDaoBalanceQuery = conseiljs.ConseilQueryBuilder.blankQuery();
68-
hDaoBalanceQuery = conseiljs.ConseilQueryBuilder.addFields(hDaoBalanceQuery, 'value');
139+
let hDaoBalanceQuery = conseiljs.ConseilQueryBuilder.blankQuery()
140+
hDaoBalanceQuery = conseiljs.ConseilQueryBuilder.addFields(hDaoBalanceQuery, 'value')
69141
hDaoBalanceQuery = conseiljs.ConseilQueryBuilder.addPredicate(hDaoBalanceQuery, 'big_map_id', conseiljs.ConseilOperator.EQ, [mainnet.daoLedger])
70142
hDaoBalanceQuery = conseiljs.ConseilQueryBuilder.addPredicate(hDaoBalanceQuery, 'key', conseiljs.ConseilOperator.EQ, [
71143
`Pair 0x${conseiljs.TezosMessageUtils.writeAddress(address)} 0`
@@ -76,7 +148,7 @@ const gethDaoBalanceForAddress = async (address) => {
76148
let balance = 0
77149

78150
try {
79-
const balanceResult = await conseiljs.TezosConseilClient.getTezosEntityData({ url: conseilServer, apiKey: conseilApiKey, network: 'mainnet' }, 'mainnet', 'big_map_contents', hDaoBalanceQuery);
151+
const balanceResult = await conseiljs.TezosConseilClient.getTezosEntityData({ url: conseilServer, apiKey: conseilApiKey, network: 'mainnet' }, 'mainnet', 'big_map_contents', hDaoBalanceQuery)
80152
balance = balanceResult[0]['value'] // TODO: consider bigNumber here, for the moment there is no reason for it
81153
} catch (error) {
82154
console.log(`gethDaoBalanceForAddress failed for ${JSON.stringify(hDaoBalanceQuery)} with ${error}`)
@@ -92,8 +164,8 @@ const gethDaoBalanceForAddress = async (address) => {
92164
* @returns
93165
*/
94166
const getArtisticOutputForAddress = async (address) => {
95-
let mintOperationQuery = conseiljs.ConseilQueryBuilder.blankQuery();
96-
mintOperationQuery = conseiljs.ConseilQueryBuilder.addFields(mintOperationQuery, 'operation_group_hash');
167+
let mintOperationQuery = conseiljs.ConseilQueryBuilder.blankQuery()
168+
mintOperationQuery = conseiljs.ConseilQueryBuilder.addFields(mintOperationQuery, 'operation_group_hash')
97169
mintOperationQuery = conseiljs.ConseilQueryBuilder.addPredicate(mintOperationQuery, 'kind', conseiljs.ConseilOperator.EQ, ['transaction'])
98170
mintOperationQuery = conseiljs.ConseilQueryBuilder.addPredicate(mintOperationQuery, 'timestamp', conseiljs.ConseilOperator.AFTER, [1612240919000]) // 2021 Feb 1
99171
mintOperationQuery = conseiljs.ConseilQueryBuilder.addPredicate(mintOperationQuery, 'status', conseiljs.ConseilOperator.EQ, ['applied'])
@@ -107,14 +179,14 @@ const getArtisticOutputForAddress = async (address) => {
107179
{ url: conseilServer, apiKey: conseilApiKey, network: 'mainnet' },
108180
'mainnet',
109181
'operations',
110-
mintOperationQuery);
182+
mintOperationQuery)
111183

112184
const operationGroupIds = mintOperationResult.map(r => r['operation_group_hash'])
113185
const queryChunks = chunkArray(operationGroupIds, 30)
114186

115187
const makeObjectQuery = (opIds) => {
116-
let mintedObjectsQuery = conseiljs.ConseilQueryBuilder.blankQuery();
117-
mintedObjectsQuery = conseiljs.ConseilQueryBuilder.addFields(mintedObjectsQuery, 'key_hash', 'value');
188+
let mintedObjectsQuery = conseiljs.ConseilQueryBuilder.blankQuery()
189+
mintedObjectsQuery = conseiljs.ConseilQueryBuilder.addFields(mintedObjectsQuery, 'key_hash', 'value')
118190
mintedObjectsQuery = conseiljs.ConseilQueryBuilder.addPredicate(mintedObjectsQuery, 'big_map_id', conseiljs.ConseilOperator.EQ, [mainnet.nftMetadataMap])
119191
mintedObjectsQuery = conseiljs.ConseilQueryBuilder.addPredicate(mintedObjectsQuery, 'operation_group_id', (opIds.length > 1 ? conseiljs.ConseilOperator.IN : conseiljs.ConseilOperator.EQ), opIds)
120192
mintedObjectsQuery = conseiljs.ConseilQueryBuilder.setLimit(mintedObjectsQuery, opIds.length)
@@ -222,7 +294,6 @@ const getArtisticUniverse = async (offset) => {
222294
* @param {number} objectId
223295
* @returns
224296
*/
225-
226297
const getObjectById = async (objectId) => {
227298
let objectQuery = conseiljs.ConseilQueryBuilder.blankQuery();
228299
objectQuery = conseiljs.ConseilQueryBuilder.addFields(objectQuery, 'value');

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"homepage": "https://github.com/hicetnunc2000/hicetnunc#readme",
1919
"dependencies": {
2020
"axios": "^0.21.1",
21+
"bignumber.js": "9.0.1",
2122
"conseiljs": "5.0.7-2",
2223
"cors": "^2.8.5",
2324
"express": "^4.17.1",

0 commit comments

Comments
 (0)