Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CIP68: allow array of bytes for bytestring fields #61

Merged
merged 5 commits into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,86 +7,127 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

### Changed

- CIP68: allow byte string fields to be encoded as an array of bytes

## 2.8.0 - 2023-08-23

### Added

- `sanchonet` network support

## 2.7.1 - 2023-08-17

### Changed

- `getAdditionalParametersFromRequest` returns `outOfRangeOrMalformedErr` if a string parameter contains non-numeric characters (eg. `123a`)
- `getAdditionalParametersFromRequest` returns `outOfRangeOrMalformedErr` if a from parameter > to parameter

## 2.7.0 - 2023-08-08

### Added

- `getAdditionalParametersFromRequest` from blockfrost-backend-ryo

## 2.6.2 - 2023-07-09

### Fixed

- parsing CIP68 datum with missing version returns `null` instead of throwing an error

## 2.6.1 - 2023-06-12

## 2.6.0 - 2023-06-12

### Added

- `convertStreamToString` function
- pm2 metrics

## 2.5.0 - 2023-05-17

### Added

- CIP68 RFT 444 support

## 2.4.0 - 2023-03-15

### Removed

- `addr_vk` support in `paymentCredToBech32Address`

## 2.3.2 - 2023-03-07

### Added

- Support for ScriptHash payment credential using `script` addresses.

### Changed

- do not leak framework in errors

## 2.3.1 - 2023-02-06

### Removed

- `addr_vk` is no longer valid address type as returned by `detectAndValidateAddressType`

### Fixed

- CIP68 `getMetadataFromOutputDatum` parsing of `files` and custom fields

## 2.3.0 - 2023-02-02

### Added

- support for `addr_vk` addresses in `paymentCredFromBech32Address`
- `getPaymentPartBech32` for generating partial bech32 address consisting of bech32 prefix, addr header and payment part

### Changed

- fastify dependencies

## 2.2.0 - 2022-12-30

### Added

- Missing custom 400s

## 2.1.1 - 2022-12-30

### Changed

- js implementation of utf-8-validate, no longer requiring node-gyp

## 2.1.0 - 2022-12-28

### Added

- CIP68 utils

## 2.0.0 - 2022-11-27

### Removed

- BREAKING CHANGE: `getSchemaForEndpoint` is now part of the `@blockfrost/openapi` package
- `@blockfrost/openapi` dependency

## 1.1.0 - 2022-11-02

### Added

- `validatePolicy` and `validateAsset` to validation functions
- invalid asset and invalid policy 400 handlers

## 1.0.1 - 2022-10-24

### Changed

- `getAddressTypeAndPaymentCred` to return undefined instead of `''` when there is not valid `paymentCred`

## 1.0.0 - 2022-09-23

### Added

- Initial release
43 changes: 12 additions & 31 deletions src/cip68.ts
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,10 @@ const convertDatumValue = (
return decodedValue;
} else if (schema.type === 'bytestring' && Buffer.isBuffer(decodedValue)) {
return toUTF8OrHex(decodedValue);
} else if (schema.type === 'bytestring' && Array.isArray(decodedValue)) {
// bytestring, but encoded as array of bytes
// concat chunks and convert to utf-8 or return bytes as hex
return toUTF8OrHex(Buffer.concat(decodedValue));
} else if (Array.isArray(decodedValue)) {
const convertedArray = [];
for (const arrayItem of decodedValue) {
Expand Down Expand Up @@ -436,37 +440,14 @@ export const getMetadataFromOutputDatum = (
// Return unparsed CBOR data
metadataMap[convertedKey] = value?.to_hex();
} else {
if (
metadataFormat[convertedKey].type === 'array' &&
Array.isArray(decodedValue)
) {
// array
// 'files' field contains array of maps
const filesValue = convertDatumValue(
decodedValue,
metadataFormat[convertedKey],
);
// If convertDatumValue returns null then the decodedValue has unsupported format,
// return CBOR hex instead
metadataMap[convertedKey] = filesValue ?? value.to_hex();
} else if (
metadataFormat[convertedKey].type === 'number' &&
typeof decodedValue === 'number'
) {
// number
metadataMap[convertedKey] = decodedValue;
} else if (
metadataFormat[convertedKey].type === 'bytestring' &&
Buffer.isBuffer(decodedValue)
) {
// bytestring buffer
// convert to utf-8 or return bytes as hex
metadataMap[convertedKey] = toUTF8OrHex(decodedValue);
} else {
// other
// leave it as cbor
metadataMap[convertedKey] = value.to_hex();
}
const convertedValue = convertDatumValue(
decodedValue,
metadataFormat[convertedKey],
);

// use converted value if available, otherwise leave it as cbor
metadataMap[convertedKey] =
convertedValue !== null ? convertedValue : value.to_hex();
}
}

Expand Down
67 changes: 66 additions & 1 deletion test/fixtures/cip68.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,10 +238,75 @@ export const getMetadataFromOutputDatum = [
},
},
{
description: 'Missing version field (datum = #6.121([metadata, version, extra]))',
description:
'Missing version field (datum = #6.121([metadata, version, extra]))',
payload:
'd8799fa6446e616d654847656e69757320584b6465736372697074696f6e582547656e6975732058207574696c69747920616e6420676f7665726e616e636520746f6b656e467469636b65724547454e53584375726c581868747470733a2f2f7777772e67656e6975732d782e636f2f446c6f676f5835697066733a2f2f516d635667683678677643364b4575797a72514d4d55753952656162377958786f5a58384352614a6d755937573148646563696d616c7306ff',
options: { standard: 'nft' } as const,
result: null,
},
{
description: 'bytes(*) 5F in image field',
payload:
'd8799fa3446e616d65581f426c6f636b66726f7374204e46542076322074657374696e6720746f6b656e4b6465736372697074696f6e581f426c6f636b66726f7374204e46542076322074657374696e6720746f6b656e45696d6167655f5840697066733a2f2f516d5543584d546376754a7077484633674142527236396365515232754547324673696b3943795768384d556f51766572796c6f6e677572695819646566696e6974656c796d6f72657468616e36346279746573ff01ac44666f6e74582754696c7420507269736d2c68747470733a2f2f74696e7975726c2e636f6d2f32616e357062356145707269636518324a666f6e745f636f6c6f7243ff61304671725f646f744f726f756e6465642c236666363133304c71725f696e6e65725f6579654e7371756172652c236632663238354c71725f6f757465725f6579654f726f756e6465642c236632663238354d626f726465725f636f6c6f72739f441254629443797986ff517066705f626f726465725f636f6c6f72739f4412546294ff52666f6e745f736861646f775f636f6c6f72739f430a1fd34322d1af4331bc23ff52746578745f726962626f6e5f636f6c6f72739f430000004412546294ff4b71725f62675f636f6c6f72440000000054746578745f726962626f6e5f6772616469656e744672616469616cff',
options: { standard: 'nft' } as const,
result: {
version: 1,
metadata: {
description: 'Blockfrost NFT v2 testing token',
image:
'ipfs://QmUCXMTcvuJpwHF3gABRr69ceQR2uEG2Fsik9CyWh8MUoQverylonguridefinitelymorethan64bytes',
name: 'Blockfrost NFT v2 testing token',
},
extra:
'ac44666f6e74582754696c7420507269736d2c68747470733a2f2f74696e7975726c2e636f6d2f32616e357062356145707269636518324a666f6e745f636f6c6f7243ff61304671725f646f744f726f756e6465642c236666363133304c71725f696e6e65725f6579654e7371756172652c236632663238354c71725f6f757465725f6579654f726f756e6465642c236632663238354d626f726465725f636f6c6f72739f441254629443797986ff517066705f626f726465725f636f6c6f72739f4412546294ff52666f6e745f736861646f775f636f6c6f72739f430a1fd34322d1af4331bc23ff52746578745f726962626f6e5f636f6c6f72739f430000004412546294ff4b71725f62675f636f6c6f72440000000054746578745f726962626f6e5f6772616469656e744672616469616c',
},
},
{
description: 'array(*) 9F in image field',
payload:
'd8799fae436167654b41707220362c2032303233437066709f584068747470733a2f2f6173736574317870743436647a336e39377979336c3937633035666a6c73727976357267677274306e6361372e6170652e6e667463646e2e5840696f2f696d6167653f73697a653d32353626746b3d506e307935746651766165654c6a4277764c646a506158684a322d445f735352664e4a6856386854336c6fff446e616d654d436974697a656e202330313333446f70656e44747275654566696c65739fa3437372639f5840697066733a2f2f626166796265696162736d326d67376d756e6d6f646b33376e653768776f6b683467786c76683237353274667763716b3279356b7974377070423379ff446e616d654d436974697a656e202330313333496d65646961547970654a696d6167652f6a706567a3437372635835697066733a2f2f516d563936567065514b41374d4e635a6d766a4653587277544365563364633431434b4c37747154574670505376446e616d654f476f6c64656e2050617373706f7274496d656469615479706549696d6167652f676966a3437372635835697066733a2f2f516d517a4253667531645a5664356575634445433843645478386939536271764441506643666851686f6f4c6d48446e616d654f476f6c64656e2050617373706f7274496d656469615479706549766964656f2f6d7034ff45696d6167659f5840697066733a2f2f626166796265696162736d326d67376d756e6d6f646b33376e653768776f6b683467786c76683237353274667763716b3279356b7974377070423379ff46476f6c64656e4474727565466f726967696e4f5468652041706520536f6369657479467374616d7073a2456c65767679a2447261746519029b456c6576656c0046706c756e676503496d65646961547970654a696d6167652f6a70656749747769747465724964533134333835393437323131333634303234333649757064617465644279583b7374616b653175387076346165726335616e77326b30356d337a653673327375753236723075683938777866786178756a686c78716664383873704b63617264616e6f5f70686b581c426bdec41c47cae88d63a0d742f72c801e68c628a33334fe4262ff3b4b74776974746572557365724a437279705f546f6b796f01d8799f019f581ce36f43a40751c35295b19a218301cc7be019d016e8927c0321fd28c7ffd87a9fff581cfca746f58adf9f3da13b7227e5e2c6052f376447473f4d49f8004195d87a9fffd87a9fffffff',
options: { standard: 'nft' } as const,
result: {
version: 1,
extra:
'd8799f019f581ce36f43a40751c35295b19a218301cc7be019d016e8927c0321fd28c7ffd87a9fff581cfca746f58adf9f3da13b7227e5e2c6052f376447473f4d49f8004195d87a9fffd87a9fffff',
metadata: {
Golden: '4474727565',
age: '4b41707220362c2032303233',
cardano_phk:
'581c426bdec41c47cae88d63a0d742f72c801e68c628a33334fe4262ff3b',
files: [
{
mediaType: 'image/jpeg',
name: 'Citizen #0133',
src: 'ipfs://bafybeiabsm2mg7munmodk37ne7hwokh4gxlvh2752tfwcqk2y5kyt7pp3y',
},
{
mediaType: 'image/gif',
name: 'Golden Passport',
src: 'ipfs://QmV96VpeQKA7MNcZmvjFSXrwTCeV3dc41CKL7tqTWFpPSv',
},
{
mediaType: 'video/mp4',
name: 'Golden Passport',
src: 'ipfs://QmQzBSfu1dZVd5eucDEC8CdTx8i9SbqvDAPfCfhQhooLmH',
},
],
image:
'ipfs://bafybeiabsm2mg7munmodk37ne7hwokh4gxlvh2752tfwcqk2y5kyt7pp3y',
mediaType: 'image/jpeg',
name: 'Citizen #0133',
open: '4474727565',
origin: '4f5468652041706520536f6369657479',
pfp: '9f584068747470733a2f2f6173736574317870743436647a336e39377979336c3937633035666a6c73727976357267677274306e6361372e6170652e6e667463646e2e5840696f2f696d6167653f73697a653d32353626746b3d506e307935746651766165654c6a4277764c646a506158684a322d445f735352664e4a6856386854336c6fff',
stamps:
'a2456c65767679a2447261746519029b456c6576656c0046706c756e676503',
twitterId: '5331343338353934373231313336343032343336',
twitterUser: '4a437279705f546f6b796f',
updatedBy:
'583b7374616b653175387076346165726335616e77326b30356d337a653673327375753236723075683938777866786178756a686c7871666438387370',
},
},
},
];
Loading