diff --git a/build/13-infrastructure-api.md b/build/13-infrastructure-api.md new file mode 100644 index 00000000..832cb5b5 --- /dev/null +++ b/build/13-infrastructure-api.md @@ -0,0 +1,311 @@ +# Infrastructure API + +The Infrastructure API provides an interface for managing essential infrastructure services required to build modern Web3 applications. + +
+ +## RPC Service + +### Create a RPC API Key + +> Create a new RPC API key for a project. + + POST /rpc/api-key + +
+
+ +#### Body Fields + +| Field | Type | Description | Required | +|--------------|----------|-----------------------------------------|----------| +| name | `string` | Name of the API key | Yes | +| description | `string` | Description of the API key | No | + +#### Possible Errors + +| Code | Description | +|----------|------------------------------------------| +| 40300000 | Forbidden | +| 40020001 | Max RPC API keys limit reached | +| 40405001 | Project owner not found | +| 50000001 | Internal server error | +| 422001101| RPC API key name is missing | + +
+
+
+ + + +```sh +curl --location --request POST "https://api.apillon.io/rpc/api-key" \ +--header "Authorization: Bearer :credentials" \ +--header "Content-Type: application/json" \ +--data-raw "{ + \"name\": \"RPC API Key\", + \"description\": \"Description of the API key\" +}" +``` + + + + + + +```json +{ + "status": 201, + "data": { + "id": 4, + "projectUuid": "d0c34b5e-1fd6-473e-81f8-e89ee479f7aa", + "name": "RPC API Key", + "description": "Description of the API key", + "uuid": "60020364-7edc-495a-a0a2-df695bb1cc3f" + } +} +``` + + + +
+
+ +### List RPC API Keys + +> Retrieve a list of RPC API keys associated with a project. + + GET /rpc/api-key + +
+
+ +#### Query Parameters + +All query parameters from [listing request](1-apillon-api.md#listing-requests) + +#### Response Fields + +| Field | Type | Description | +|----------------|------------|----------------------------------------------------------| +| id | `number` | Unique identifier of the RPC API key | +| projectUuid | `string` | UUID of the project the RPC API key belongs to | +| name | `string` | Name of the RPC API key | +| uuid | `string` | Unique identifier of the RPC API key returned by Dwellir | +| description | `string` | Description of the RPC API key | +| createTime | `DateTime` | Creation timestamp | +| updateTime | `DateTime` | Last updated timestamp | + +
+
+
+ + + +```sh +curl --location --request GET "https://api.apillon.io/rpc/api-key" \ +--header "Authorization: Bearer :credentials" +``` + + + + + + +```json +{ + "status": 200, + "data": { + "items": [ + { + "id": 4, + "createTime": "2024-09-09T11:15:26.000Z", + "updateTime": "2024-09-10T13:18:31.000Z", + "projectUuid": "cfd85992-8f79-4486-97cf-2406bd722d90", + "name": "RPC API Key", + "description": "Description of the API key", + "uuid": "60020364-7edc-495a-a0a2-df695bb1cc3f" + } + ], + "total": 1, + "page": 1, + "limit": 20 + } +} +``` + + + +
+
+ +### Get a RPC API Key + +> Retrieve the details of a specific RPC API key by its ID along with the list of RPC endpoints marked as favorite for this API key. + + GET /rpc/api-key/:id + +
+
+ +#### URL Parameters + +| Field | Type | Description | Required | +|-------|----------|------------------------------------------|----------| +| id | `number` | Unique identifier of the RPC API key | Yes | + +#### Response Fields + +| Field | Type | Description | +|----------------|------------|-------------------------------------------------------------| +| id | `number` | Unique identifier of the RPC API key | +| name | `string` | Name of the RPC API key | +| description | `string` | Description of the RPC API key | +| projectUuid | `string` | Unique identifier of the project | +| uuid | `string` | Unique identifier of the RPC API key | +| createTime | `DateTime` | Creation timestamp | +| updateTime | `DateTime` | Last updated timestamp | +| urls | `array` | Array of favorite URLs for the RPC API key | + +###### URL Fields +| Field | Type | Description | +|----------------|------------|--------------------------------------------------------------| +| id | `number` | Unique identifier of the RPC Endpoint | +| apiKeyId | `number` | Unique identifier of the RPC API key | +| chainName | `string` | Name of the chain the RPC Endpoint belongs to | +| network | `string` | Network of the RPC Endpoint (Usually mainnet, testnet, etc.) | +| httpsUrl | `string` | HTTPS URL of the RPC Endpoint | +| wssUrl | `string` | WSS URL of the RPC Endpoint | +| createTime | `DateTime` | Creation timestamp | +| updateTime | `DateTime` | Last updated timestamp | + +#### Possible Errors + +| Code | Description | +|----------|---------------------------| +| 40300000 | Forbidden | +| 40420001 | RPC API key not found | + +
+
+
+ + + +```sh +curl --location --request GET "https://api.apillon.io/rpc/api-key/:id" \ +--header "Authorization: Bearer :credentials" +``` + + + + + + +```json +{ + "id": "60020364-7edc-495a-a0a2-df695bb1cc3f", + "status": 200, + "data": { + "createTime": "2024-09-09T11:15:26.000Z", + "updateTime": "2024-09-10T13:18:31.000Z", + "name": "RPC API Key", + "description": null, + "project_uuid": "d0c34b5e-1fd6-473e-81f8-e89ee479f7aa", + "uuid": "60020364-7edc-495a-a0a2-df695bb1cc3f", + "urls": [ + { + "id": 77, + "chainName": "Ethereum", + "network": "mainnet", + "httpsUrl": "https://mainnet.apillon.io/60020364-7edc-495a-a0a2-df695bb1cc3f", + "wssUrl": "wss://mainnet.apillon.io/60020364-7edc-495a-a0a2-df695bb1cc3f", + "createTime": "2024-09-10T12:55:44.000Z", + "updateTime": "2024-09-12T13:57:26.000Z", + } + ] + } +} +``` + + + +
+
+ +### List RPC Endpoints + +> Retrieve a list of available RPC endpoints by Dwellir. + + GET /rpc/endpoints + +
+
+ +#### Response Fields + +| Field | Type | Description | +|----------------|------------|--------------------------------------------------------------| +| id | `number` | Unique identifier of the RPC Endpoint | +| image_url | `string` | URL of the RPC Endpoint chain image | +| name | `string` | Name of the RPC Endpoint chain | +| networkId | `number` | Network ID of the RPC Endpoint | +| networkName | `string` | Network of the RPC Endpoint (Usually Mainnet, Testnet, etc.) | +| nodes | `array` | Array of nodes for the RPC Endpoint | +| type | `string` | Type of the Entity (will be 'network') | +| version | `string ` | Version of the RPC Endpoint | + +##### Node Fields + +| Field | Type | Description | +|----------------|------------|--------------------------------------------------------------| +| id | `number` | Unique identifier of the RPC Endpoint Node | +| https | `string` | HTTPS URL of the RPC Endpoint Node | +| wss | `string` | WSS URL of the RPC Endpoint Node | +| type | `string` | Type of the Entity (will be 'node') | +| node_type | `string` | Type of the RPC Endpoint Node | +| version | `string ` | Version of the RPC Endpoint Node | + +
+
+
+ + + +```sh +curl --location --request GET "https://api.apillon.io/rpc/endpoints" \ +--header "Authorization: Bearer :credentials" +``` + + + + + + +```json +{ + "status": 200, + "data": [{ + "id": 1, + "image_url": "https://apillon.io/images/chains/ethereum.svg", + "name": "Ethereum", + "networkId": 31, + "networkName": "Mainnet", + "nodes": [{ + "id": 1, + "https": "https://mainnet.apillon.io/", + "wss": "wss://mainnet.apillon.io/", + "type": "node", + "node_type": "Archive", + "version": "1.0" + }], + "type": "network", + "version": "1.0" + }] +} +``` + + + +
+
\ No newline at end of file diff --git a/build/4-nfts-api.md b/build/4-nfts-api.md index 72452d3b..0f7ca510 100644 --- a/build/4-nfts-api.md +++ b/build/4-nfts-api.md @@ -315,8 +315,8 @@ An NFT Collection can be created with a few features/functionalities: 2 types of collections are supported: -1. Generic collection, which represents an extension of the ERC-721 standard for EVM collections and the PSP-34 standard for substrate collections. You can read more about these standards [here](/web3-services/4-nfts.html#nft-files) -2. Nestable collection which allows nesting NFTs under each other (based on [RMRKs ERC-7401](https://evm.rmrk.app/nestable) NFT standard - EVM only) +1. Generic collection, which represents an extension of the ERC-721 standard for EVM collections and the PSP-34 standard / Native NFTs for substrate collections. You can read more about these standards [here](/web3-services/4-nfts.html#nft-files) +2. Nestable collection which allows nesting NFTs under each other (based on [RMRKs ERC-7401](https://evm.rmrk.app/nestable) NFT standard and [Unique Native NFTs](https://docs.unique.network/reference/blockchain/nesting.html)) Additionally, 2 chain types/environments are supported: EVM and Substrate. @@ -519,8 +519,6 @@ curl --location 'https://api.apillon.io/nfts/collections/evm' \ "bucketUuid": "a9425ff7-4802-4a38-b771-84a790112c30", "baseUri": "https://ipfs.apillon.io/metadata/", "baseExtension": ".json", - "isSoulbound": false, - "isRevokable": false, "royaltiesFees": 0.1, "royaltiesAddress": "0x4156edbafc5091507de2dd2a53ded551a346f83b", "collectionStatus": 0, @@ -542,6 +540,178 @@ curl --location 'https://api.apillon.io/nfts/collections/evm' \ + +#### Create Unique NFT Collection +
+POST /nfts/collections/unique + +
+
+ +#### Body fields + +| Name | Type | Description | Required | +|----------------|-----------|--------------------------------------------------------------------------------------------|----------| +| collectionType | `number` | Type of smart contract to use when deploying collection (1 for generic, 2 for nestable). | true | +| symbol | `string` | NFT collection symbol (usually 3-4 characters long). | true | +| name | `string` | NFT collection name. | true | +| description | `string` | NFT collection description. | false | +| maxSupply | `number` | Maximal number of NFTs ever in existence (0 stands for unlimited). | true | +| isRevokable | `boolean` | For revocable collection owner can destroy NFTs at any time. (default: false) | true | +| isSoulbound | `boolean` | Soul bound tokens are NFTs that are bound to wallet and not transferable. (default: false) | true | +| metadata | `object` | Object containing metadata for different token ids (more details bellow). | true | + +#### Metadata field +Metadata field is an object with token ids as keys and token metadata as values. Here are the fields for each token metadata: + +| Name | Type | Description | Required | +|-------------------|----------|-----------------------------------------------------------------------------------------|------------| +| name | `string` | NFT name. | true | +| description | `string` | NFT description. | false | +| image | `string` | NFT image URL. | true | +| image_details | `object` | Additional details about the image from the image field (see table bellow). | false | +| attributes | `array` | Array of NFT attributes (see table bellow). | true | +| animation_url | `string` | NFT animation URL. | false | +| animation_details | `object` | Additional details about the animation from the animation_url field (see table bellow). | false | +| youtube_url | `string` | URL to a YouTube video associated with the NFT. | false | +| created_by | `string` | Address of the creator of the NFT. | false | +| external_url | `string` | URL to an external resource providing more information about the NFT. | false | +| background_color | `string` | Background color of the NFT. | false | +| locale | `string` | Locale of the NFT. | false | + +##### Metadata field attributes +Attributes field of metadata field is an array of NFT traits described bellow: + +| Name | Type | Description | Required | +|---------------|-----------|---------------------------------------------------|----------| +| value | `string` | Trait value. | true | +| trait_type | `string` | Name of the trait. | true | +| display_type | `string` | Type for displaying trait (`number`, `date`,...). | false | + +##### Metadata field image_details and animation_details +| Name | Type | Description | Required | +|--------|----------|------------------------------------------------------------------------------------------|----------| +| name | `string` | Name of the image (for captions, etc.). | false | +| type | `enum` | Type of content (`image`,`animation`,`video`,`audio`,`spatial`,`pdf`,`document`,`other`) | false | +| bytes | `number` | Size of the image file in bytes. | false | +| format | `string` | Format of the image file (e.g., PNG, JPEG). | false | +| sha256 | `string` | SHA-256 hash of the image file. | false | +| width | `number` | Width of the image in pixels. | false | +| height | `number` | Height of the image in pixels. | false | +| order | `number` | Order of the image. | false | + +You can find more information about metadata in [Unique docs](https://docs.unique.network/reference/schemas/#nft-token-schema-v2-detailed-description). + + +#### Possible errors + +Beside validation errors (with 422 http status code) these are the error codes may be returned: + +| Code | Description | +|----------|-----------------------------------------------| +| 40012002 | Collection quota reached | +| 50012003 | Failed deploying NFT contract on chain. | + +#### Response + +Response payload is described [under Response Fields above](#get-nft-collection). + +
+
+ + + + +```sh +curl --location 'https://api.apillon.io/nfts/collections/unique' \ +--header 'Content-Type: application/json' \ +--header 'Authorization: Basic :credentials' \ +--data '{ + "collectionType": 1, + "symbol": "NFT", + "name": "NFT Collection", + "description": "NFT Collection description", + "maxSupply": 1000, + "isRevokable": true, + "isSoulbound": true, + "metadata": { + "1": { + "name": "name", + "description": "description", + "image": "image", + "attributes": [ + { + "value": "value", + "trait_type": "trait_type", + "display_type": "display_type" + } + ] + }, + "2": { + "name": "name", + "description": "description", + "image": "image", + "attributes": [ + { + "value": "value", + "trait_type": "trait_type", + "display_type": "display_type" + }, + { + "value": "value", + "trait_type": "trait_type", + "display_type": "display_type" + } + ] + }, + } +}' +``` + + + + + + +```json +{ + "id": "b5935c73-204d-4365-9f9a-6a1792adab5b", + "status": 200, + "data": { + "createTime": "2023-06-13T10:15:58.000Z", + "updateTime": "2023-06-13T10:15:58.000Z", + "chain": 11, + "collectionType": 1, + "collectionUuid": "d6355fd3-640d-4803-a4d9-79d875abcb5a", + "symbol": "NFT", + "name": "NFT Collection", + "description": "NFT Collection Description", + "maxSupply": 1000, + "bucketUuid": null, + "baseUri": null, + "baseExtension": "", + "royaltiesFees": 0, + "royaltiesAddress": null, + "collectionStatus": 0, + "contractAddress": "XjuXMnFxcJoAgMCdUQKvvt2Daykq4H9rsCfYEVpF6noFP5u", + "transactionHash": "0xb59d8497feb121b0ca0b8480df72a456333edddc68ad65f23b6b8b9028e3a6b3", + "deployerAddress": "WmMcyrPY4fivB5FUPN85QPhCMKtnrjmUyAgtXC2oW2XbcnY", + "drop": false, + "dropStart": 0, + "dropPrice": 0, + "dropReserve": 0, + "isRevokable": true, + "isSoulbound": true, + "isAutoIncrement": true + } +} +``` + + + +
+
+ ### Transfer Collection > Transfer collection ownership from a wallet owned by caller to a new wallet address. diff --git a/build/6-apillon-cli.md b/build/6-apillon-cli.md index 4a27aea4..185f8ce5 100644 --- a/build/6-apillon-cli.md +++ b/build/6-apillon-cli.md @@ -858,6 +858,25 @@ Deletes a job from a cloud function. apillon cloud-functions delete-job --job-uuid "987e6543-e21c-32f1-b123-426655441111" ``` +## Indexing Commands + +#### `indexing deploy` + +Deploy a local squid indexer repository to an Apillon indexer with a specific UUID. +The CLI zips files that were added to tar.gz archive, which is created in the builds/ directory. +The compressed file is uploaded to S3, and the deployment is started. The deployment can take some time, and progress can be monitored on the [Apillon developer console](https://app.apillon.io/dashboard/service/indexing). + +**Options** + +- ``: Path to local squid repository (indexer source code). +- `-i `: UUID of the indexer to be deployed. + +**Example** + +```sh +apillon indexing deploy ./local-path -i "7af5bea4-7989-41fe-958a-dfe7fa8ff72d" +``` + ## Using in CI/CD tools CLI is particularly useful for CI/CD builds and pipelines. diff --git a/web3-services/10-web3-infrastructure.md b/web3-services/10-web3-infrastructure.md new file mode 100644 index 00000000..14b1112c --- /dev/null +++ b/web3-services/10-web3-infrastructure.md @@ -0,0 +1,108 @@ +# Web3 infrastructure + +## Introduction + +**Apillon's Infrastructure Service** provides developers with the essential infrastructure required to build modern Web3 applications. Our infrastructure services currently include: + +- **RPC Service**: Reliable and high-performance access to blockchain networks +- **Indexing Service**: Efficient data indexing and querying capabilities + +These services are designed to simplify Web3 development while ensuring scalability and reliability for your decentralized applications. + +## RPC Service + +The RPC (Remote Procedure Call) service in Apillon's infrastructure provides seamless connectivity to blockchain networks, allowing developers to interact with blockchain data and execute smart contracts. +By utilizing [Dwellir](https://www.dwellir.com/) as the RPC provider, Apillon ensures reliable and efficient access to blockchain nodes. The service is designed for flexibility, enabling developers to create, manage, and optimize their own RPC endpoints through a user-friendly interface. + +### Dwellir + +**Dwellir** is a highly reliable and scalable RPC (Remote Procedure Call) provider that powers the Apillon infrastructure, enabling developers to interact with various blockchain networks. +Dwellir ensures secure, low-latency connections and high availability, allowing developers to execute smart contract functions, query blockchain data, and perform transactions seamlessly. + +Core Services: +- **Multi-Blockchain Support**: Dwellir supports a wide range of blockchain networks, including popular ecosystems like EVM (Ethereum Virtual Machine), Substrate-based chains, and others, providing extensive coverage and flexibility. +- **High Availability and Redundancy**: Dwellir's infrastructure is designed with built-in redundancy and geo-distributed nodes, ensuring minimal downtime and reliable access to blockchain networks. +- **Secure Connections**: Supports both HTTPS and WSS (WebSocket Secure) protocols for encrypted communication, ensuring data privacy and integrity during transmission. +- **API Key Management**: Allows project owners to create, manage, and revoke API keys, offering fine-grained control over who can access RPC endpoints. + +### How it works + +1. **Activate RPC Service for a Project**: Project owner activates RPC service for their project in the Apillon dashboard. +2. **Create an RPC API Key**: Developers can generate an API key from the Apillon dashboard, which is used to authenticate requests to the RPC service. +3. **Set Favorite Endpoints**: Developers can mark the preferred RPC endpoints as "favorites" for selected API key to make them easily accessible through the Apillon dashboard. +4. **Manage API Keys**: Project owners can manage API keys in the Apillon dashboard, allowing for flexible management of access to RPC endpoints. +5. **Monitor Usage**: Developers can monitor the usage of their RPC keys in the Apillon dashboard, allowing for better control over their infrastructure costs. + +### Pricing + +The RPC service is available with two main plants: + +**Free Plan** (default): +- **RPC Calls**: Up to 5 million RPC calls per month +- **API Keys**: Allows a single API key per user +- **Cost**: Free of charge + +**Developer Plan**: +- **RPC Calls**: Increases the limit to 25 million RPC calls per month +- **API Keys**: Allows up to 5 API keys per user +- **Cost**: 49.99€ per month + + +## Indexing service + +The Indexing Service is a crucial component of Apillon's infrastructure, designed to efficiently index and query blockchain data. It plays a vital role in powering our Web3 services and enhancing the overall user experience. +In the background, Apillon uses the [Subsquid](https://subsquid.io/) indexing framework and Subsquid Cloud to run indexing nodes. +Developers can create their own indexers or use one of the available templates, and can query more than 150 blockchain networks. + +### SQD (Subsquid) Web3 Data Infrastructure + +**SQD** is a powerful Web3 data infrastructure platform that offers: + +- **High-Performance Data Indexing**: Processes blockchain data up to 100x faster than traditional providers +- **Comprehensive Network Coverage**: Supports 150+ blockchain networks including EVM, SVM, Substrate, and more +- **Cost-Efficient Infrastructure**: Eliminates egress fees, users only pay for compute resources +- **Core Services**: + - SQD Network: A decentralized data lake for Web3 + - Squid SDK: Advanced blockchain indexing toolkit + - SQD Cloud: Enterprise-grade hosted indexing service + +Used by major projects like PancakeSwap, Railgun, and Chainsafe, SQD processes hundreds of thousands of terabytes of blockchain data while significantly reducing infrastructure costs. + +### Workflow + +1. **Create an indexer**: Developers create an indexer in the Apillon Indexer Dashboard. +2. **Adjust indexer source code**: Use one of the available templates for squid indexer or write your own. +3. **Deploy indexer**: Deploy your indexer through the Apillon CLI. +4. **Use indexer**: Use the indexer in your application. + +### How it works + +The indexing process follows a standardized workflow while allowing for flexible implementation approaches. Developers can leverage existing templates as a starting point and customize them according to their specific requirements. Before deployment, indexers can be thoroughly tested in a local environment to ensure proper functionality. + +An indexer implementation consists of three core components: + +- **Indexer Processor**: Handles data fetching and processing from the blockchain +- **Indexer Database**: Stores the processed blockchain data +- **Indexer API**: Provides GraphQL endpoint for querying the indexed data + +To configure an indexer, developers need to specify: + +- **RPC Node Endpoint**: Connection point to the blockchain network +- **Starting Block**: Initial block number from which to begin indexing +- **Target Events and Fields**: Specific blockchain events and data fields to monitor and process + +The indexer processor continuously fetches new blocks from the specified starting point up to the latest block, processing the relevant data according to the configured rules and storing it in the indexer database. + +The processed data becomes accessible through a GraphQL API, providing a flexible and efficient way to query the indexed blockchain data. This API supports complex queries, filtering, and data relationships, enabling developers to retrieve exactly the information they need for their applications. + +### Pricing + +Indexers are billed based on the amount of processed and stored data and the number of queries made to the indexer API. +Project need to have sufficient credit balance to deploy an indexer. The deployment itself is free of charge, Apillon charges for the working indexer only. +Indexers are billed daily - each day Apillon calculates price for the indexer and uses project's credit balance to pay for it. + +If project's credit balance is insufficient, indexer will be hibernated and later deleted after few days if no action is taken. + +## Conclusion + +Apillon's Web3 Infrastructure services provide developers with powerful tools to build and scale decentralized applications. Through SQD integration, developers can efficiently index and query blockchain data across multiple networks, while maintaining cost-effectiveness and high performance. The platform's user-friendly approach, combined with its robust technical capabilities, makes it an ideal choice for projects of any size looking to leverage blockchain data effectively. diff --git a/web3-services/4-nfts.md b/web3-services/4-nfts.md index c438cc77..a35dc493 100644 --- a/web3-services/4-nfts.md +++ b/web3-services/4-nfts.md @@ -2,17 +2,22 @@ Apillon NFT service supports drag-and-drop compilation, deployment, and minting of non-fungible assets. -The service is currently supported by the [Moonbeam Network](https://blog.apillon.io/guide-nft-service-pt-2-create-and-deploy-nft-collection-on-moonbeam-2d7eedf79756) and [Astar Network](https://blog.apillon.io/guide-nft-service-create-and-deploy-nft-collection-on-astar-3d6674994b0f) for EVM and Astar network for substrate based NFTs. +Service currently supports creating NFT collections on multiple EVM and substrate chains: + - [Moonbeam Network](https://blog.apillon.io/guide-nft-service-pt-2-create-and-deploy-nft-collection-on-moonbeam-2d7eedf79756) (EVM and Substrate based NFTs) + - [Astar Network](https://blog.apillon.io/guide-nft-service-create-and-deploy-nft-collection-on-astar-3d6674994b0f) (Substrate based NFTs) + - [Unique Network](https://blog.apillon.io/guide-nft-service-create-and-deploy-nft-collection-on-astar-3d6674994b0f) (Substrate based NFTs) -## NFT files +## NFT media -NFT files are at the front and center of an NFT collection. +NFT media are at the front and center of an NFT collection. -Apillon NFT Service currently runs on the Moonbeam and Astar parachains, and supports -[ERC-721](https://eips.ethereum.org/EIPS/eip-721) and [ERC-6059](https://eips.ethereum.org/EIPS/eip-6059) standards for NFTs on EVM and [PSP-34](https://github.com/w3f/PSPs/blob/master/PSPs/psp-34.md) standard for substrate. +Apillon NFT Service currently runs on the Moonbeam, Astar and Unique parachains, and supports +[ERC-721](https://eips.ethereum.org/EIPS/eip-721) and [ERC-6059](https://eips.ethereum.org/EIPS/eip-6059) standards for NFTs on EVM and [PSP-34](https://github.com/w3f/PSPs/blob/master/PSPs/psp-34.md) standard and [Unique Native NFTs](https://docs.unique.network/about/nft-features/native.html) for substrate. The ERC-721 standard packs any file format into permanently stored content on the blockchain. Thanks to Moonbeam’s and Astar’s EVM compatibility, it can be deployed quickly and efficiently with Apillon. +Native NFTs on Unique Network are streamlined, blockchain-integrated tokens that offer simplicity, speed, cost-efficiency, and enhanced security, eliminating the complexities of traditional smart contract-based NFTs. + [Learn more >](https://blog.apillon.io/guide-nft-service-pt-1-generate-nft-art-with-ai-and-get-files-ready-200168b6b303#eb24) ## NFT metadata @@ -21,7 +26,7 @@ NFT metadata is the backbone of an NFT collection and communicates the essential It can also include certain attributes that make an NFT one of a kind. -As an essential component of NFT collections, metadata should be managed and stored carefully. To ensure its permanent access free of third-party intervention, Apillon stores it on a decentralized network with [Apillon Web3 Storage bucket](/web3-services/1-good-to-know.html#web3-storage), [Crust Network](https://crust.network/), and [IPFS](https://ipfs.tech/). +As an essential component of NFT collections, metadata should be managed and stored carefully. To ensure its permanent access free of third-party intervention, Apillon stores it either on-chain via [Unique metadata schema](https://docs.unique.network/reference/schemas/#unique-metadata-schema-v2) or on a decentralized network with [Apillon Web3 Storage bucket](/web3-services/1-good-to-know.html#web3-storage), [Crust Network](https://crust.network/), and [IPFS](https://ipfs.tech/). Apillon supports metadata that is structured according to the [official OpenSea metadata standard](https://docs.opensea.io/docs/metadata-standards).