Merge pull request #259 from blockfrost/master
releasing v0.1.49 to website
releasing v0.1.49 to website
name: open-api-CI
name: CIcko
on: [push]
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [14.x, 16.x, 18.x]
node-version: [16.x, 18.x]
steps:
- uses: actions/[email protected]
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/[email protected]
with:
node-version: ${{ matrix.node-version }}
- run: yarn
- run: yarn build
- run: yarn test
- run: yarn run build
\ No newline at end of file
- run: yarn coverage
yarnPath: .yarn/releases/yarn-3.3.0.cjs
nodeLinker: node-modules
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project will adhere to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) once it reaches maturity in v1.
## [0.1.XX] - 2022-XX-XX
## [0.1.49] - 2022-11-26
### Changed
- update deps and yarn version
### Added
- test coverage
- `getCIPstandard`, `getOnchainMetadataVersion`, `getOnchainMetadata` functions
## [0.1.48] - 2022-11-25
### Fixed
- descriptions
## [0.1.47] - 2022-11-24
### Added
- `getSchema` util function
- `validateSchema` util function
- `onchain_metadata_standard` to `/assets/{asset_id}` endpoint to report `onchain_metadata` validity
### Changed
- moved CIP-25 validation to a custom schema to avoid strict check on `onchain_metadata`
## [0.1.46] - 2022-11-22
### Added
- `/network/eras` endpoint
### Changed
- adjust CIP-25 and add v2 validation for onchain_metadata in `/assets/{asset_id}`
- refactored custom schemas
## [0.1.45] - 2022-11-20
### Fixed
- accidental npm release
## [0.1.44] - 2022-11-07
openapi: 3.0.0
info:
version: 0.1.44
version: 0.1.49
title: Blockfrost.io ~ API Documentation
x-logo:
url: https://staging.blockfrost.io/images/logo.svg
<tr><td>Crystal</td><td><a href="https://github.com/blockfrost/blockfrost-crystal">blockfrost-crystal</a></tr>
</table>
servers:
- url: https://cardano-mainnet.blockfrost.io/api/v0/
- url: https://cardano-mainnet.blockfrost.io/api/v0
description: Cardano Mainnet network
- url: https://cardano-testnet.blockfrost.io/api/v0/
- url: https://cardano-testnet.blockfrost.io/api/v0
description: Cardano Testnet network
- url: https://cardano-preprod.blockfrost.io/api/v0/
- url: https://cardano-preprod.blockfrost.io/api/v0
description: Cardano Preprod network
- url: https://cardano-preview.blockfrost.io/api/v0/
- url: https://cardano-preview.blockfrost.io/api/v0
description: Cardano Preview network
- url: https://localhost:3000
description: local
tags:
- Cardano » Accounts
summary: Account associated addresses
description: Obtain information about the addresses of a specific account.
description: >
Obtain information about the addresses of a specific account.
<b>Be careful</b>, as an account could be part of a mangled address and
does not necessarily mean the addresses are owned by user as the
account.
parameters:
- in: path
name: stake_address
$ref: '#/components/responses/429'
'500':
$ref: '#/components/responses/500'
/network/eras:
get:
tags:
- Cardano » Network
summary: Query summary of blockchain eras
description: |
Returns start and end of each era along with
parameters that can vary between hard forks.
responses:
'200':
description: Returns era summaries content.
content:
application/json:
schema:
$ref: '#/components/schemas/network-eras'
'400':
$ref: '#/components/responses/400'
'403':
$ref: '#/components/responses/403'
'404':
$ref: '#/components/responses/404'
'418':
$ref: '#/components/responses/418'
'425':
$ref: '#/components/responses/425'
'429':
$ref: '#/components/responses/429'
'500':
$ref: '#/components/responses/500'
/nutlink/{address}:
get:
tags:
'500':
$ref: '#/components/responses/500'
components:
responses:
'400':
description: Bad request
content:
application/json:
schema:
type: object
properties:
status_code:
type: integer
example: 400
error:
type: string
example: Bad Request
message:
type: string
example: Backend did not understand your request.
required:
- status_code
- error
- message
'403':
description: Authentication secret is missing or invalid
content:
application/json:
schema:
type: object
properties:
status_code:
type: integer
example: 403
error:
type: string
example: Forbidden
message:
type: string
example: Invalid project token.
required:
- status_code
- error
- message
'404':
description: Component not found
content:
application/json:
schema:
type: object
properties:
status_code:
type: integer
example: 404
error:
type: string
example: Not Found
message:
type: string
example: The requested component has not been found.
required:
- status_code
- error
- message
'418':
description: >-
IP has been auto-banned for extensive sending of requests after usage
limit has been reached
content:
application/json:
schema:
type: object
properties:
status_code:
type: integer
example: 418
error:
type: string
example: Requested Banned
message:
type: string
example: IP has been auto-banned for flooding.
required:
- status_code
- error
- message
'425':
description: Mempool is already full, not accepting new txs straight away
content:
application/json:
schema:
type: object
properties:
status_code:
type: integer
example: 425
error:
type: string
example: Mempool Full
message:
type: string
example: Mempool is full, please try resubmitting again later.
required:
- status_code
- error
- message
'429':
description: Usage limit reached
content:
application/json:
schema:
type: object
properties:
status_code:
type: integer
example: 429
error:
type: string
example: Project Over Limit
message:
type: string
example: Usage is over limit.
required:
{
"name": "@blockfrost/openapi",
"version": "0.1.44",
"version": "0.1.49",
"description": "OpenAPI specifications for blockfrost.io",
"repository": "[email protected]:blockfrost/openapi.git",
"author": "[email protected]",
"openapi.yaml"
],
"scripts": {
"prepublish": "yarn build",
"bundle": "openapi bundle -o ./openapi.yaml src/definitions.yaml",
"lint": "openapi lint src/definitions.yaml",
"generate-docs": "redoc-cli bundle -t ./src/template.hbs -o docs/index.html ./openapi.yaml",
"generate-docs": "redoc-cli build -t ./src/template.hbs -o docs/index.html ./openapi.yaml",
"generate-types": "openapi-typescript ./openapi.yaml --output ./src/generated-types.ts",
"build": "rimraf lib && yarn bundle && yarn generate-types && yarn generate-docs && yarn tsc",
"test": "vitest"
"test": "vitest",
"coverage": "vitest run --coverage"
},
"devDependencies": {
"ajv": "^6",
"@vitest/coverage-c8": "^0.25.3",
"ajv": "^8.11.2",
"core-js": "3.1.4",
"lodash.isequal": "^4.5.0",
"openapi-typescript": "^5.4.1",
"react-is": "16.8.2",
"redoc-cli": "^0.12.3",
"redoc-cli": "^0.13.2",
"rimraf": "^3.0.2",
"typescript": "^4.8.4",
"vite": "^3.2.4",
"vitest": "^0.24.3"
},
"dependencies": {
"@redocly/openapi-cli": "^1.0.0-beta.78",
"@redocly/openapi-cli": "^1.0.0-beta.95",
"yaml": "^2.1.3"
}
},
"packageManager": "[email protected]"
}
export PATH="$PATH:$(pwd)/node_modules/.bin"
yarn
echo "Rebuilding docs"
yarn run bundle && yarn run generate-docs
yarn run bundle && yarn run generate-docs && yarn run generate-types
echo -e "\nDON'T FORGET TO RUN THIS BEFORE OPENING PR:"
echo "yarn run bundle && yarn run generate-docs"
echo "yarn run bundle && yarn run generate-docs && yarn run generate-types"
'';
}
export default {
type: 'array',
items: {
type: 'object',
properties: {
tx_hash: {
type: 'string',
},
block_height: {
type: 'integer',
},
tx_index: {
type: 'integer',
},
payload: {
// possible bug FIXME https://github.com/fastify/fast-json-stringify/issues/246
// anyOf: [
// {
// type: 'string',
// },
// // {
// // type: 'object',
// // },
// {
// type: 'array',
// //items: {},
// additionalProperties: true,
// },
// {
// type: 'integer',
// },
// {
// type: 'number',
// },
// {
// type: 'boolean',
// },
// ],
//additionalProperties: true,
},
},
required: ['tx_hash', 'tx_index', 'block_height', 'payload'],
},
};
export default {
type: 'array',
items: {
type: 'object',
properties: {
address: {
type: 'string',
description: 'Address of a metadata oracle',
},
tx_hash: {
type: 'string',
description: 'Hash of the transaction',
},
block_height: {
type: 'integer',
description: 'Block height of the record',
},
tx_index: {
type: 'integer',
description: 'Transaction index within the block',
},
payload: {
// possible bug FIXME https://github.com/fastify/fast-json-stringify/issues/246
// anyOf: [
// {
// type: 'string',
// },
// // {
// // type: 'object',
// // },
// {
// type: 'array',
// //items: {},
// additionalProperties: true,
// },
// {
// type: 'integer',
// },
// {
// type: 'number',
// },
// {
// type: 'boolean',
// },
// ],
//additionalProperties: true,
},
},
required: ['address', 'tx_hash', 'block_height', 'tx_index', 'payload'],
},
};
export default {
type: 'object',
properties: {
json: {
nullable: true,
},
},
required: ['json'],
};
export default {
type: 'array',
items: {
type: 'object',
properties: {
label: {
type: 'string',
},
json_metadata: {
// possible bug FIXME https://github.com/fastify/fast-json-stringify/issues/246
// oneOf: [
// {
// type: 'string',
// },
// {
// type: 'object',
// },
// ],
},
},
required: ['label', 'json_metadata'],
},
};
openapi: 3.0.0
info:
version: "0.1.44"
version: "0.1.49"
title: Blockfrost.io ~ API Documentation
x-logo:
url: https://staging.blockfrost.io/images/logo.svg
</table>
servers:
- url: https://cardano-mainnet.blockfrost.io/api/v0/
- url: https://cardano-mainnet.blockfrost.io/api/v0
description: Cardano Mainnet network
- url: https://cardano-testnet.blockfrost.io/api/v0/
- url: https://cardano-testnet.blockfrost.io/api/v0
description: Cardano Testnet network
- url: https://cardano-preprod.blockfrost.io/api/v0/
- url: https://cardano-preprod.blockfrost.io/api/v0
description: Cardano Preprod network
- url: https://cardano-preview.blockfrost.io/api/v0/
- url: https://cardano-preview.blockfrost.io/api/v0
description: Cardano Preview network
- url: https://localhost:3000
description: local
/network:
$ref: ./paths/api/network/index.yaml
/network/eras:
$ref: ./paths/api/network/eras.yaml
/nutlink/{address}:
$ref: ./paths/api/nutlink/{address}/index.yaml
$ref: ./paths/api/nutlink/tickers/{ticker}/index.yaml
components:
schemas:
onchain_metadata_cip25:
$ref: ./schemas/assets/asset_onchain_metadata_cip25.yaml
responses:
overusage_limit:
$ref: ./responses/errors/429.yaml
import fs from 'fs';
import path from 'path';
import YAML from 'yaml';
const file = fs.readFileSync(
path.resolve(__dirname, '../../openapi.yaml'),
'utf8',
);
const spec = YAML.parse(file);
export default (endpointName: string) => {
if (!spec.paths[endpointName]) {
throw Error(
`Missing Blockfrost OpenAPI schema for endpoint "${endpointName}".`,
);
}
const responses: any = { response: {} };
for (const response of Object.keys(spec.paths[endpointName].get.responses)) {
// success 200
if (response === '200') {
const referenceOrValue =
spec.paths[endpointName].get.responses['200'].content[
'application/json'
].schema;
// is reference -> resolve references
if (referenceOrValue['$ref']) {
const schemaName = referenceOrValue['$ref'].replace(
'#/components/schemas/',
'',
);
const schemaReferenceOrValue = spec.components.schemas[schemaName];
// is nested reference
if (
schemaReferenceOrValue.items &&
schemaReferenceOrValue.items['$ref']
) {
const nestedSchemaName = schemaReferenceOrValue.items['$ref'].replace(
'#/components/schemas/',
'',
);
if (schemaReferenceOrValue.type) {
responses.response[200] = {
...schemaReferenceOrValue,
items: spec.components.schemas[nestedSchemaName],
};
} else {
responses.response[200] = spec.components.schemas[nestedSchemaName];
}
} else {
// is not nested reference
responses.response[200] = spec.components.schemas[schemaName];
}
} else {
// is not reference
responses.response[200] = referenceOrValue;
}
// anyOf case
if (referenceOrValue['anyOf']) {
const anyOfResult: any = { anyOf: [] };
for (const anyOfItem of referenceOrValue['anyOf']) {
const schemaName = anyOfItem['$ref'].replace(
'#/components/schemas/',
'',
);
anyOfResult['anyOf'].push(spec.components.schemas[schemaName]);
}
responses.response[200] = anyOfResult;
}
const parameters = spec.paths[endpointName].get.parameters;
if (parameters) {
const queryParams = parameters.filter((i: any) => i.in === 'query');
let queryProps: any = {};
if (queryParams && queryParams.length > 0) {
queryParams.forEach((param: any) => {
delete param.schema.format;
queryProps[param.name] = param.schema;
});
responses['querystring'] = {
type: 'object',
properties: queryProps,
};
}
const pathparams = parameters.filter((i: any) => i.in === 'path');
if (pathparams && pathparams.length > 0) {
let pathProps: any = {};
pathparams.forEach((param: any) => {
delete param.schema.format;
pathProps[param.name] = param.schema;
});
responses['params'] = {
type: 'object',
properties: pathProps,
};
}
// const query = parameters.filter((i: any) => i.in === 'param');
// let queryParams: any = {};
}
// 1 bug -> edge case
if (endpointName === '/txs/{hash}/metadata') {
responses.response[200] = {
type: 'array',
items: {
type: 'object',
properties: {
label: {
type: 'string',
},
json_metadata: {
// possible bug FIXME https://github.com/fastify/fast-json-stringify/issues/246
// oneOf: [
// {
// type: 'string',
// },
// {
// type: 'object',
// },
// ],
},
},
required: ['label', 'json_metadata'],
},
};
}
// 2 bug -> edge case
if (endpointName === '/nutlink/{address}/tickers/{ticker}') {
responses.response[200] = {
type: 'array',
items: {
type: 'object',
properties: {
tx_hash: {
type: 'string',
},
block_height: {
type: 'integer',
},
tx_index: {
type: 'integer',
},
payload: {
// possible bug FIXME https://github.com/fastify/fast-json-stringify/issues/246
// anyOf: [
// {
// type: 'string',
// },
// // {
// // type: 'object',
// // },
// {
// type: 'array',
// //items: {},
// additionalProperties: true,
// },
// {
// type: 'integer',
// },
// {
// type: 'number',
// },
// {
// type: 'boolean',
// },
// ],
//additionalProperties: true,
},
},
required: ['tx_hash', 'tx_index', 'block_height', 'payload'],
},
};
}
// 3 bug -> edge case
if (endpointName === '/nutlink/tickers/{ticker}') {
responses.response[200] = {
type: 'array',
items: {
type: 'object',
properties: {
address: {
type: 'string',
import { validateSchema } from '../index';
import { CIPTypes, GetOnchainMetadataResult, Asset } from '../types/metadata';
export const getCIPstandard = (version: number, isValid: boolean): CIPTypes => {
if (isValid) {
if (version === 1) {
return 'CIP25v1';
}
if (version === 2) {
return 'CIP25v2';
}
}
return null;
};
export const getOnchainMetadataVersion = (
onchainMetadata: Asset['onchain_metadata'],
): number => {
if (!onchainMetadata?.version) {
return 1;
}
return Number(onchainMetadata.version);
};
export const getOnchainMetadata = (
onchainMetadata: Asset['onchain_metadata'],
assetName: Asset['asset_name'],
policyId: Asset['policy_id'],
): GetOnchainMetadataResult => {
let internalOnchainMetada: any = onchainMetadata;
if (!internalOnchainMetada)
return { onchainMetadata: null, validCIPversion: null };
let isFound = false;
let onchainMetadataResult = null;
let validCIPversion: CIPTypes = null;
const version = getOnchainMetadataVersion(onchainMetadata);
const assetNameBase = assetName || '';
const assetNameVersion1 = Buffer.from(assetNameBase || '', 'hex').toString(
'utf8',
);
const assetNameVersion2 = assetNameBase;
if (version === 1) {
try {
onchainMetadataResult =
internalOnchainMetada[policyId][assetNameVersion1] || null;
isFound = true;
} catch (error) {
onchainMetadataResult = null;
}
}
if (version === 2) {
try {
const foundMetadata =
internalOnchainMetada[policyId][assetNameVersion2] || null;
if (foundMetadata) {
onchainMetadataResult = foundMetadata;
isFound = true;
} else {
// fallback
onchainMetadataResult =
internalOnchainMetada[policyId][assetNameVersion1] || null;
isFound = false;
}
} catch (error) {
onchainMetadataResult = null;
}
}
const { isValid } = validateSchema(
'asset_onchain_metadata_cip25',
onchainMetadataResult,
);
const CIPVersion = getCIPstandard(version, isFound && isValid);
validCIPversion = CIPVersion;
return {
onchainMetadata: onchainMetadataResult,
validCIPversion,
};
};
import fs from 'fs';
import path from 'path';
import YAML from 'yaml';
import Ajv from 'ajv';
import nutlinkAddressTickers from '../custom-schemas/nutlink-address-tickers';
import nutlinkTicker from '../custom-schemas/nutlink-ticker';
import scriptsJsonSchema from '../custom-schemas/scripts-json';
import txsMetadata from '../custom-schemas/txs-metadata';
const ajv = new Ajv({ strict: false });
const file = fs.readFileSync(
path.resolve(__dirname, '../../openapi.yaml'),
'utf8',
);
const spec = YAML.parse(file);
export const getSchemaForEndpoint = (endpointName: string) => {
if (!spec.paths[endpointName]) {
throw Error(
`Missing Blockfrost OpenAPI schema for endpoint "${endpointName}".`,
);
}
const responses: any = { response: {} };
for (const response of Object.keys(spec.paths[endpointName].get.responses)) {
// success 200
if (response === '200') {
const referenceOrValue =
spec.paths[endpointName].get.responses['200'].content[
'application/json'
].schema;
// is reference -> resolve references
if (referenceOrValue['$ref']) {
const schemaName = referenceOrValue['$ref'].replace(
'#/components/schemas/',
'',
);
const schemaReferenceOrValue = spec.components.schemas[schemaName];
// is nested reference
if (
schemaReferenceOrValue.items &&
schemaReferenceOrValue.items['$ref']
) {
const nestedSchemaName = schemaReferenceOrValue.items['$ref'].replace(
'#/components/schemas/',
'',
);
if (schemaReferenceOrValue.type) {
responses.response[200] = {
...schemaReferenceOrValue,
items: spec.components.schemas[nestedSchemaName],
};
} else {
responses.response[200] = spec.components.schemas[nestedSchemaName];
}
} else {
// is not nested reference
responses.response[200] = spec.components.schemas[schemaName];
}
} else {
// is not reference
responses.response[200] = referenceOrValue;
}
// anyOf case
if (referenceOrValue['anyOf']) {
const anyOfResult: any = { anyOf: [] };
for (const anyOfItem of referenceOrValue['anyOf']) {
const schemaName = anyOfItem['$ref'].replace(
'#/components/schemas/',
'',
);
anyOfResult['anyOf'].push(spec.components.schemas[schemaName]);
}
responses.response[200] = anyOfResult;
}
const parameters = spec.paths[endpointName].get.parameters;
if (parameters) {
const queryParams = parameters.filter((i: any) => i.in === 'query');
let queryProps: any = {};
if (queryParams && queryParams.length > 0) {
queryParams.forEach((param: any) => {
delete param.schema.format;
queryProps[param.name] = param.schema;
});
responses['querystring'] = {
type: 'object',
properties: queryProps,
};
}
const pathparams = parameters.filter((i: any) => i.in === 'path');
if (pathparams && pathparams.length > 0) {
let pathProps: any = {};
pathparams.forEach((param: any) => {
delete param.schema.format;
pathProps[param.name] = param.schema;
});
responses['params'] = {
type: 'object',
properties: pathProps,
};
}
// const query = parameters.filter((i: any) => i.in === 'param');
// let queryParams: any = {};
}
// custom schemas
if (endpointName === '/txs/{hash}/metadata') {
responses.response[200] = txsMetadata;
}
if (endpointName === '/nutlink/{address}/tickers/{ticker}') {
responses.response[200] = nutlinkAddressTickers;
}
if (endpointName === '/nutlink/tickers/{ticker}') {
responses.response[200] = nutlinkTicker;
}
if (endpointName === '/scripts/{script_hash}/json') {
responses.response[200] = scriptsJsonSchema;
}
}
// errors and others
else {
responses.response[response] =
spec.components.responses[response].content['application/json'].schema;
}
}
// debug
// if (endpointName === '/blocks/{hash_or_number}') {
// console.log(endpointName, JSON.stringify(responses));
// }
return responses;
};
export const getSchema = (schemaName: string) => {
if (!spec.components.schemas[schemaName]) {
throw Error(`Missing Blockfrost OpenAPI schema with name "${schemaName}".`);
}
return spec.components.schemas[schemaName];
};
export const validateSchema = (schemaName: string, input: unknown) => {
const schema = getSchema(schemaName);
const validate = ajv.compile(schema);
const isValid = validate(input);
return { isValid, errors: validate.errors };
};
};
};
"/accounts/{stake_address}/addresses": {
/** Obtain information about the addresses of a specific account. */
/**
* Obtain information about the addresses of a specific account.
* <b>Be careful</b>, as an account could be part of a mangled address and does not necessarily mean the addresses are owned by user as the account.
*/
get: {
parameters: {
path: {
};
};
};
"/network/eras": {
/**
* Returns start and end of each era along with
* parameters that can vary between hard forks.
*/
get: {
responses: {
/** Returns era summaries content. */
200: {
content: {
"application/json": components["schemas"]["network-eras"];
};
};
400: components["responses"]["400"];
403: components["responses"]["403"];
404: components["responses"]["404"];
418: components["responses"]["418"];
425: components["responses"]["425"];
429: components["responses"]["429"];
500: components["responses"]["500"];
};
};
};
"/nutlink/{address}": {
/** List metadata about specific address */
get: {
export interface components {
schemas: {
onchain_metadata_cip25: components["schemas"]["asset_onchain_metadata_cip25"];
block_content: {
/**
* @description Block creation time in UNIX time
quantity: string;
/** @description Number of decimal places of the asset unit */
decimals: number | null;
/** @description The latest minting transaction includes the NFT metadata according to CIP25 */
/** @description True if the latest minting transaction includes metadata (best-effort) */
has_nft_onchain_metadata: boolean;
}[];
/**
*/
mint_or_burn_count: number;
/**
* @description On-chain metadata stored in the minting transaction under label 721,
* community discussion around the standard ongoing at https://github.com/cardano-foundation/CIPs/pull/85
*/
onchain_metadata:
| ({
/**
* @description Name of the asset
* @example My NFT token
*/
name?: string;
/**
* @description URI(s) of the associated asset
* @example ipfs://ipfs/QmfKyJ4tuvHowwKQCbCHj4L5T3fSj8cjs7Aau8V7BWv226
*/
image?: string | string[];
} & { [key: string]: unknown })
| null;
* @description On-chain metadata which SHOULD adhere to the valid standards,
* based on which we perform the look up and display the asset
* (best effort)
*/
onchain_metadata: { [key: string]: unknown } | null;
/**
* @description If on-chain metadata passes validation, we display the standard
* under which it is valid
*
* @enum {string|null}
*/
onchain_metadata_standard?: ("CIP25v1" | "CIP25v2") | null;
/**
* @description Off-chain metadata fetched from GitHub based on network.
* Mainnet: https://github.com/cardano-foundation/cardano-token-registry/
active: string;
};
};
/**
* @example [
* {
* "start": {
* "time": 0,
* "slot": 0,
* "epoch": 0
* },
* "end": {
* "time": 89856000,
* "slot": 4492800,
* "epoch": 208
* },
* "parameters": {
* "epoch_length": 21600,
* "slot_length": 20,
* "safe_zone": 4320
* }
* },
* {
* "start": {
* "time": 89856000,
* "slot": 4492800,
* "epoch": 208
* },
* "end": {
* "time": 101952000,
* "slot": 16588800,
* "epoch": 236
* },
* "parameters": {
* "epoch_length": 432000,
* "slot_length": 1,
* "safe_zone": 129600
* }
* }
* ]
*/
"network-eras": {
/**
* @description Start of the blockchain era,
* relative to the start of the network
*/
start: {
/** @description Time in seconds relative to the start time of the network */
time: number;
/** @description Absolute slot number */
slot: number;
/** @description Epoch number */
epoch: number;
};
/**
* @description End of the blockchain era,
* relative to the start of the network
*/
end: {
/** @description Time in seconds relative to the start time of the network */
time: number;
/** @description Absolute slot number */
slot: number;
/** @description Epoch number */
epoch: number;
};
/** @description Era parameters */
parameters: {
/** @description Epoch length in number of slots */
epoch_length: number;
/** @description Slot length in seconds */
slot_length: number;
/** @description Zone in which it is guaranteed that no hard fork can take place */
safe_zone: number;
};
}[];
nutlink_address: {
/**
* @description Bech32 encoded address
Partial<number> &
Partial<boolean>) & { [key: string]: unknown };
}[];
/**
* @description On-chain metadata stored in the minting transaction under label 721,
* which adheres to https://cips.cardano.org/cips/cip25/
*/
asset_onchain_metadata_cip25: {
/**
* @description Name of the asset
* @example My NFT token
*/
name: string;
/**
* @description URI(s) of the associated asset
* @example ipfs://ipfs/QmfKyJ4tuvHowwKQCbCHj4L5T3fSj8cjs7Aau8V7BWv226
*/
image: string | string[];
/**
* @description Additional description
* @example My NFT token description
*/
description?: string | string[];
/**
import getSchemaForEndpoint from './functions/get-schema-for-endpoint';
import {
getSchemaForEndpoint,
getSchema,
validateSchema,
} from './functions/schema';
import {
getOnchainMetadata,
getOnchainMetadataVersion,
getCIPstandard,
} from './functions/metadata';
export {
getSchemaForEndpoint,
getSchema,
validateSchema,
getOnchainMetadata,
getCIPstandard,
getOnchainMetadataVersion,
};
export { getSchemaForEndpoint };
export type { paths, components } from './generated-types';
tags:
- Cardano » Accounts
summary: Account associated addresses
description: Obtain information about the addresses of a specific account.
description: |
Obtain information about the addresses of a specific account.
<b>Be careful</b>, as an account could be part of a mangled address and does not necessarily mean the addresses are owned by user as the account.
parameters:
- in: path
name: stake_address
get:
tags:
- Cardano » Network
summary: Query summary of blockchain eras
description: |
Returns start and end of each era along with
parameters that can vary between hard forks.
responses:
"200":
description: Returns era summaries content.
content:
application/json:
schema:
$ref: ../../../schemas/network-eras.yaml
"400":
$ref: ../../../responses/errors/400.yaml
"403":
$ref: ../../../responses/errors/403.yaml
"404":
$ref: ../../../responses/errors/404.yaml
"418":
$ref: ../../../responses/errors/418.yaml
"425":
$ref: ../../../responses/errors/425.yaml
"429":
$ref: ../../../responses/errors/429.yaml
"500":
$ref: ../../../responses/errors/500.yaml
description: Number of decimal places of the asset unit
has_nft_onchain_metadata:
type: boolean
description: The latest minting transaction includes the NFT metadata according to CIP25
description: True if the latest minting transaction includes metadata (best-effort)
required:
- unit
- quantity
- decimals
- has_nft_onchain_metadata
example:
- unit: "lovelace"
quantity: "42000000"
- unit: 'lovelace'
quantity: '42000000'
decimals: 6
has_nft_onchain_metadata: false
- unit: "b0d07d45fe9514f80213f4020e5a61241458be626841cde717cb38a76e7574636f696e"
quantity: "12"
- unit: 'b0d07d45fe9514f80213f4020e5a61241458be626841cde717cb38a76e7574636f696e'
quantity: '12'
decimals: null
has_nft_onchain_metadata: true
stake_address:
tracing the un-hashed bytes of the script integrity
SCP-4880 GetTransaction Query