Skip to content

Commit 353fb7b

Browse files
authored
Merge pull request #263 from hirosystems/master
merge master to develop
2 parents b1b8f4b + 0a04aab commit 353fb7b

File tree

10 files changed

+77
-55
lines changed

10 files changed

+77
-55
lines changed

CHANGELOG.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,30 @@
1+
## [1.1.2](https://github.com/hirosystems/token-metadata-api/compare/v1.1.1...v1.1.2) (2024-08-30)
2+
3+
4+
### Bug Fixes
5+
6+
* handle updated chain tip on rollbacks correctly ([#261](https://github.com/hirosystems/token-metadata-api/issues/261)) ([b85b1d3](https://github.com/hirosystems/token-metadata-api/commit/b85b1d3903a336d5691e05387140fcc1e8a41f16))
7+
8+
## [1.1.1](https://github.com/hirosystems/token-metadata-api/compare/v1.1.0...v1.1.1) (2024-08-30)
9+
10+
11+
### Bug Fixes
12+
13+
* allow boolean metadata properties ([#260](https://github.com/hirosystems/token-metadata-api/issues/260)) ([d52861a](https://github.com/hirosystems/token-metadata-api/commit/d52861a1434d51ffd340063ca2cc5ccc4bb03676))
14+
15+
## [1.1.0](https://github.com/hirosystems/token-metadata-api/compare/v1.0.3...v1.1.0) (2024-08-30)
16+
17+
18+
### Features
19+
20+
* add configurable delay for retrying jobs ([#257](https://github.com/hirosystems/token-metadata-api/issues/257)) ([20d753a](https://github.com/hirosystems/token-metadata-api/commit/20d753a82a4e7f214cf9dc8cb2fee333ac5a4f4c))
21+
22+
23+
### Bug Fixes
24+
25+
* add chain tip etag generator ([#255](https://github.com/hirosystems/token-metadata-api/issues/255)) ([2b993cd](https://github.com/hirosystems/token-metadata-api/commit/2b993cd34484e156db9e24be8571c0e0e5b4bde0))
26+
* retry when a contract is not yet found ([#256](https://github.com/hirosystems/token-metadata-api/issues/256)) ([46d8fc8](https://github.com/hirosystems/token-metadata-api/commit/46d8fc892790d64e2a2646efbc64d97be4a109e3))
27+
128
## [1.0.3](https://github.com/hirosystems/token-metadata-api/compare/v1.0.2...v1.0.3) (2024-08-27)
229

330

src/api/util/helpers.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,7 @@ export function parseMetadataLocaleBundle(
3232
if (locale.properties.length > 0) {
3333
const mergedProperties: MetadataPropertiesType = {};
3434
for (const property of locale.properties) {
35-
if (property.value) {
36-
mergedProperties[property.name] = property.value as MetadataValueType;
37-
}
35+
mergedProperties[property.name] = property.value as MetadataValueType;
3836
}
3937
response.properties = mergedProperties;
4038
}

src/pg/chainhook/chainhook-pg-store.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ export class ChainhookPgStore extends BasePgStoreModule {
3939
} finished in ${time.getElapsedSeconds()}s`
4040
);
4141
}
42+
if (payload.rollback.length) {
43+
const earliestRolledBack = Math.min(...payload.rollback.map(r => r.block_identifier.index));
44+
await this.updateChainTipBlockHeight(earliestRolledBack - 1);
45+
}
4246
for (const block of payload.apply) {
4347
if (block.block_identifier.index <= (await this.getLastIngestedBlockHeight())) {
4448
logger.info(
@@ -114,7 +118,7 @@ export class ChainhookPgStore extends BasePgStoreModule {
114118
}
115119

116120
async updateChainTipBlockHeight(blockHeight: number): Promise<void> {
117-
await this.sql`UPDATE chain_tip SET block_height = GREATEST(${blockHeight}, block_height)`;
121+
await this.sql`UPDATE chain_tip SET block_height = ${blockHeight}`;
118122
}
119123

120124
private async getLastIngestedBlockHeight(): Promise<number> {

src/pg/pg-store.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,11 @@ export class PgStore extends BasePgStore {
189189
}
190190
if (locale.properties && locale.properties.length > 0) {
191191
const values = locale.properties.map(property => ({
192-
...property,
192+
name: property.name,
193+
value:
194+
typeof property.value == 'boolean'
195+
? sql`TO_JSONB(${property.value})`
196+
: property.value,
193197
metadata_id: metadataId,
194198
}));
195199
await sql`INSERT INTO metadata_properties ${sql(values)}`;

src/token-processor/util/metadata-helpers.ts

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -211,16 +211,14 @@ async function parseMetadataForInsertion(
211211
const properties: DbMetadataPropertyInsert[] = defaultInsert?.properties ?? [];
212212
if (RawMetadataPropertiesCType.Check(metadata.properties)) {
213213
for (const [key, value] of Object.entries(metadata.properties)) {
214-
if (key && value) {
215-
const defaultProp = properties.find(p => p.name === key);
216-
if (defaultProp) {
217-
defaultProp.value = value;
218-
} else {
219-
properties.push({
220-
name: key,
221-
value: value,
222-
});
223-
}
214+
const defaultProp = properties.find(p => p.name === key);
215+
if (defaultProp) {
216+
defaultProp.value = value;
217+
} else {
218+
properties.push({
219+
name: key,
220+
value: value,
221+
});
224222
}
225223
}
226224
}

tests/api/nft.test.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,14 @@ describe('NFT routes', () => {
217217
name: 'prop2',
218218
value: 1,
219219
},
220+
{
221+
name: 'prop3',
222+
value: true,
223+
},
224+
{
225+
name: 'prop4',
226+
value: false,
227+
},
220228
],
221229
},
222230
],
@@ -251,6 +259,8 @@ describe('NFT routes', () => {
251259
properties: {
252260
prop1: 'ABC',
253261
prop2: 1,
262+
prop3: true,
263+
prop4: false,
254264
},
255265
},
256266
});

tests/api/status.test.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,13 @@ describe('Status routes', () => {
4444
db,
4545
'SP2SYHR84SDJJDK8M09HFS4KBFXPPCX9H7RZ9YVTS.hello-world',
4646
DbSipNumber.sip009,
47-
1n
47+
4n
4848
);
4949
await db.chainhook.updateChainTipBlockHeight(100);
50+
await db.sql`UPDATE jobs SET status = 'failed' WHERE id = 2`;
51+
await db.sql`UPDATE jobs SET status = 'invalid' WHERE id = 3`;
52+
await db.sql`UPDATE jobs SET status = 'queued' WHERE id = 4`;
53+
await db.sql`UPDATE jobs SET status = 'done' WHERE id = 5`;
5054

5155
const response = await fastify.inject({ method: 'GET', url: '/metadata/v1/' });
5256
const json = response.json();
@@ -57,13 +61,17 @@ describe('Status routes', () => {
5761
block_height: 100,
5862
},
5963
job_queue: {
60-
pending: 2,
64+
pending: 1,
65+
failed: 1,
66+
invalid: 1,
67+
queued: 1,
68+
done: 1,
6169
},
6270
token_contracts: {
6371
'sip-009': 1,
6472
},
6573
tokens: {
66-
nft: 1,
74+
nft: 4,
6775
},
6876
});
6977
});

tests/chainhook/chainhook-observer.test.ts

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -59,42 +59,6 @@ describe('Chainhook observer', () => {
5959
await expect(db.getChainTipBlockHeight()).resolves.toBe(101);
6060
});
6161

62-
test('keeps only the highest chain tip value', async () => {
63-
await db.chainhook.processPayload(
64-
new TestChainhookPayloadBuilder()
65-
.apply()
66-
.block({ height: 100 })
67-
.transaction({ hash: '0x01', sender: 'SP1K1A1PMGW2ZJCNF46NWZWHG8TS1D23EGH1KNK60' })
68-
.contractDeploy('SP1K1A1PMGW2ZJCNF46NWZWHG8TS1D23EGH1KNK60.friedger-pool-nft', {
69-
maps: [],
70-
functions: [],
71-
variables: [],
72-
fungible_tokens: [],
73-
non_fungible_tokens: [],
74-
})
75-
.build()
76-
);
77-
await expect(db.getChainTipBlockHeight()).resolves.toBe(100);
78-
79-
await db.chainhook.processPayload(
80-
new TestChainhookPayloadBuilder()
81-
.apply()
82-
.block({ height: 65 })
83-
.transaction({ hash: '0x01', sender: 'SP1K1A1PMGW2ZJCNF46NWZWHG8TS1D23EGH1KNK60' })
84-
.event({
85-
type: 'SmartContractEvent',
86-
position: { index: 0 },
87-
data: {
88-
contract_identifier: 'SP1K1A1PMGW2ZJCNF46NWZWHG8TS1D23EGH1KNK60.friedger-pool-nft',
89-
topic: 'print',
90-
raw_value: cvToHex(stringUtf8CV('test')),
91-
},
92-
})
93-
.build()
94-
);
95-
await expect(db.getChainTipBlockHeight()).resolves.toBe(100);
96-
});
97-
9862
test('enqueues dynamic tokens for refresh with standard interval', async () => {
9963
const address = 'SP1K1A1PMGW2ZJCNF46NWZWHG8TS1D23EGH1KNK60';
10064
const contractId = `${address}.friedger-pool-nft`;

tests/token-queue/metadata-helpers.test.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ describe('Metadata Helpers', () => {
6060
await expect(fetchMetadata(url, 'ABCD.test', 1n)).rejects.toThrow(MetadataHttpError);
6161
});
6262

63-
test('does not throw on raw metadata with null or stringable values', async () => {
63+
test('does not throw on raw metadata with null, stringable, or boolean values', async () => {
6464
const crashPunks1 = {
6565
version: '1',
6666
name: 'Crash Punk 294',
@@ -74,6 +74,9 @@ describe('Metadata Helpers', () => {
7474
external_url:
7575
'https://thisisnumberone.com/nfts/SP3QSAJQ4EA8WXEDSRRKMZZ29NH91VZ6C5X88FGZQ.crashpunks-v2/294',
7676
animation_url: null,
77+
allow_multiple_claims: true,
78+
whitelisted: false,
79+
minted: 160,
7780
},
7881
localization: {
7982
uri: null,

tests/token-queue/process-token-job.test.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,8 @@ describe('ProcessTokenJob', () => {
382382
collection_size: 5000,
383383
artist: 'Bitcoin Monkeys',
384384
prop: { a: 1, b: 2 },
385+
allow_multiple_claims: true,
386+
whitelisted: false,
385387
},
386388
};
387389
const agent = new MockAgent();
@@ -441,6 +443,10 @@ describe('ProcessTokenJob', () => {
441443
expect(properties[4].value).toBe(5000);
442444
expect(properties[6].name).toBe('prop');
443445
expect(properties[6].value).toStrictEqual({ a: 1, b: 2 });
446+
expect(properties[7].name).toBe('allow_multiple_claims');
447+
expect(properties[7].value).toStrictEqual(true);
448+
expect(properties[8].name).toBe('whitelisted');
449+
expect(properties[8].value).toStrictEqual(false);
444450
});
445451

446452
test('parses metadata with localizations', async () => {

0 commit comments

Comments
 (0)