Methods
Collection
Get collection by Id new
Overview
The method returns collection info with parsed unique schema.
Brief example
import { CollectionIdArguments, CollectionInfoWithSchema } from '@unique-nft/substrate-client/types';
const getCollectionArgs: CollectionIdArguments = { collectionId: 123 };
const collection: CollectionInfoWithSchema = await sdk.collection.get(getCollectionArgs);
Arguments
collectionId: number
— collection id
Behaviour and errors
Returns null if the collection does not exist.
If collection properties can not be presented as unique schema, schema
property will be empty.
Returns
interface CollectionInfoWithSchema {
id: number;
owner: string;
mode: CollectionMode;
decimals?: number;
name: string;
description: string;
tokenPrefix: string;
sponsorship?: CollectionSponsorship;
limits?: CollectionLimits;
metaUpdatePermission?: MetaUpdatePermission;
readOnly?: boolean;
permissions?: CollectionPermissions;
schema?: UniqueCollectionSchemaDecoded;
properties: CollectionProperty[];
}
Examples
import { CollectionIdArguments, CollectionInfoWithSchema } from '@unique-nft/substrate-client/types';
const getCollectionArgs: CollectionIdArguments = { collectionId: 123 };
const collection: CollectionInfo = await sdk.collection.get(getCollectionArgs);
curl -X 'GET' \
'https://rest.unique.network/opal/v1/collection?collectionId=1' \
-H 'accept: application/json'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const collection = await sdk.collection.get({ collectionId: 1 });
Get collection properties
Overview
Gets the array of Collection properties. More details about Collection properties can be found in Set collection properties method.
Brief example
import {
CollectionPropertiesArguments,
CollectionPropertiesResult,
} from '@unique-nft/substrate-client';
const args: CollectionPropertiesArguments = {
collectionId: 1,
// propertyKeys: ['foo', 'bar'],
};
const result: CollectionPropertiesResult = await sdk.collection.properties(args);
Arguments
collectionId
- number
propertyKeys
- string[] - optional
Behaviour and errors
Returns array of collection properties
Returns
interface CollectionProperty {
key: string;
value: string;
}
interface CollectionPropertiesResult {
properties: CollectionProperty[];
};
Examples
import {
CollectionPropertiesArguments,
CollectionPropertiesResult,
} from '@unique-nft/substrate-client';
const args: CollectionPropertiesArguments = {
collectionId: 1,
// propertyKeys: ['foo', 'bar'],
};
const result: CollectionPropertiesResult = await sdk.collection.properties(args);
curl -X 'GET' \
'https://rest.unique.network/opal/v1/collections/properties?collectionId=1' \
-H 'accept: application/json'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const { properties } = await sdk.collection.properties({ collectionId: 1 });
Create collection with unique schema
Overview
The method creates a new collection with the Unique schema.
Brief example
Example without attributes
import {
COLLECTION_SCHEMA_NAME,
CreateCollectionNewArguments,
} from '@unique-nft/substrate-client/tokens';
import { UniqueCollectionSchemaToCreate } from '@unique-nft/api';
const collectionSchema: UniqueCollectionSchemaToCreate = {
schemaName: COLLECTION_SCHEMA_NAME.unique,
schemaVersion: '1.0.0',
image: { urlTemplate: 'some_url/{infix}.extension' },
coverPicture: {
ipfsCid: '<valid_ipfs_cid>',
},
};
const args: CreateCollectionNewArguments = {
address: '<your address>',
name: 'Foo',
description: 'Bar',
tokenPrefix: 'Baz',
schema: collectionSchema,
};
const result = await sdk.collection.create.submitWaitResult(args);
const {
parsed: { collectionId },
} = result;
console.log(`Created new collection with id ${collectionId}`);
Example with attributes
import {
AttributeType,
COLLECTION_SCHEMA_NAME,
CreateCollectionNewArguments,
} from '@unique-nft/substrate-client/tokens';
import { UniqueCollectionSchemaToCreate } from '@unique-nft/api';
const collectionSchema: UniqueCollectionSchemaToCreate = {
schemaName: COLLECTION_SCHEMA_NAME.unique,
schemaVersion: '1.0.0',
attributesSchemaVersion: '1.0.0',
image: { urlTemplate: 'https://ipfs.unique.network/ipfs/{infix}' },
attributesSchema: {
'0': {
name: {
_: 'Facial features',
},
type: AttributeType.string,
optional: true,
isArray: true,
enumValues: {
'0': {
_: 'Regular Head',
},
'1': {
_: 'Normal Eyes',
},
'2': {
_: 'Tired Eyes',
},
},
},
'1': {
name: {
_: 'Name',
},
type: AttributeType.string,
isArray: false,
optional: false,
},
},
audio: {
urlTemplate: 'https://ipfs.unique.network/ipfs/{infix}.ext',
format: 'string',
isLossless: true,
},
spatialObject: {
urlTemplate: 'https://ipfs.unique.network/ipfs/{infix}.ext',
format: 'string',
},
video: {
urlTemplate: 'https://ipfs.unique.network/ipfs/{infix}.ext',
},
coverPicture: {
ipfsCid: '<valid_ipfs_cid>',
},
};
const args: CreateCollectionNewArguments = {
address: '<your address>',
name: 'Foo',
description: 'Bar',
tokenPrefix: 'Baz',
schema: collectionSchema,
};
const result = await sdk.collection.create.submitWaitResult(args);
const {
parsed: { collectionId },
} = result;
console.log(`Created new collection with id ${collectionId}`);
Arguments
address
- The address of the collection owner
name
- Collection name (text, up to 64 characters)
description
- Collection description (text, up to 256 characters)
mode
- The collection type (Nft
, Fungible
, or ReFungible
)
tokenPrefix
- Token prefix (text, up to 4 characters)
sponsorship
- This field tells if sponsorship is enabled and what address is the current collection sponsor.
limits
- Collection limits
interface CollectionLimits {
accountTokenOwnershipLimit?: number | null;
sponsoredDataSize?: number | null;
sponsoredDataRateLimit?: number | null;
tokenLimit?: number | null;
sponsorTransferTimeout?: number | null;
sponsorApproveTimeout?: number | null;
ownerCanTransfer?: boolean | null;
ownerCanDestroy?: boolean | null;
transfersEnabled?: boolean | null;
}
metaUpdatePermission
- Permission for update meta (ItemOwner
, Admin
, None
)
permissions
- Collection permissions
export interface CollectionNestingPermissionsDto {
tokenOwner?: boolean;
collectionAdmin?: boolean;
restricted?: number[];
}
export interface CollectionPermissionsDto {
access?: 'Normal' | 'AllowList';
mintMode?: boolean;
nesting?: CollectionNestingPermissionsDto;
}
schema
- Collection schema
Behaviour and errors
Throws common errors on insufficient balance and so on.
Returns
The method returns a parsed
object that contains the CollectionIdArguments
.
interface CollectionIdArguments {
collectionId: number;
}
Examples
import { CreateCollectionNewArguments } from '@unique-nft/substrate-client/tokens';
const result = await sdk.collection.create.submitWaitResult({
address: '<your address>',
name: 'Foo',
description: 'Bar',
tokenPrefix: 'Baz',
schema: {
schemaName: COLLECTION_SCHEMA_NAME.unique,
schemaVersion: '1.0.0',
image: { urlTemplate: 'some_url/{infix}.extension' },
coverPicture: {
ipfsCid: '<valid_ipfs_cid>',
},
},
});
const {
parsed: { collectionId },
} = result;
console.log(`Created new collection with id ${collectionId}`);
curl -X 'POST' \
'https://rest.unique.network/opal/v1/collections' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"mode": "Nft",
"name": "Sample collection name",
"description": "sample collection description",
"tokenPrefix": "TEST",
"address": "yGCyN3eydMkze4EPtz59Tn7obwbUbYNZCz48dp8FRdemTaLwm",
"schema": {
schemaName: COLLECTION_SCHEMA_NAME.unique,
schemaVersion: '1.0.0',
image: { urlTemplate: 'some_url/{infix}.extension' },
coverPicture: {
ipfsCid: '<valid_ipfs_cid>',
},
}
}'
# then we sign, then we call
curl -X 'POST' \
'https://rest.unique.network/opal/v1/extrinsic/submit' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"signerPayloadJSON": { *from previous response* },
"signature": "0x_your_signature_in_hex"
}'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await sdk.collection.create.submitWaitResult({
address: '<your address>',
name: 'Foo',
description: 'Bar',
tokenPrefix: 'Baz',
schema: {
schemaName: COLLECTION_SCHEMA_NAME.unique,
schemaVersion: '1.0.0',
image: { urlTemplate: 'some_url/{infix}.extension' },
coverPicture: {
ipfsCid: '<valid_ipfs_cid>',
},
},
});
const {
parsed: { collectionId },
} = result;
console.log(`Created collection with id ${collectionId}`);
Delete collection properties
Overview
This method deletes collection properties.
Brief example
import { DeleteCollectionPropertiesArguments} from '@unique-nft/substrate-client/tokens';
const args: DeleteCollectionPropertiesArguments = {
address: '<your address>',
collectionId: 1,
propertyKeys: ['foo', 'bar'],
};
const result = await sdk.collection.deleteProperties.submitWaitResult(args);
const deletedKeys = result.parsed.properties.map((property) => property.propertyKey);
console.log(`Deleted ${deletedKeys.join()}`);
Arguments
address
- string
collectionId
- number
propertyKeys
- string[]
Behaviour and errors
Throws common errors on insufficient balance and so on.
Returns
interface CollectionPropertyDeletedEvent {
collectionId: number;
propertyKey: string;
}
interface DeleteCollectionPropertiesResult {
properties: CollectionPropertyDeletedEvent[];
}
Examples
import { DeleteCollectionPropertiesArguments} from '@unique-nft/substrate-client/tokens';
const args: DeleteCollectionPropertiesArguments = {
address: '<your address>',
collectionId: 1,
propertyKeys: ['foo', 'bar'],
};
const result = await sdk.collection.deleteProperties.submitWaitResult(args);
const deletedKeys = result.parsed.properties.map((property) => property.propertyKey);
console.log(`Deleted ${deletedKeys.join()}`);
curl -X 'DELETE' \
'https://rest.unique.network/opal/v1/collections/properties' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"address": "yGCyN3eydMkze4EPtz59Tn7obwbUbYNZCz48dp8FRdemTaLwm",
"collectionId": 1,
"propertyKeys": [
"foo", "bar"
]
}'
### then we sign, then we call
curl -X 'POST' \
'https://rest.unique.network/opal/v1/extrinsic/submit' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"signerPayloadJSON": { *from previous response* },
"signature": "0x_your_signature_in_hex"
}'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
await sdk.collection.deleteProperties.submitWaitResult({
address: '<your address>',
collectionId: 1,
propertyKeys: ['foo', 'bar'],
});
Destroy collection
Overview
The method destroys collection if no tokens within this collection.
Brief example
import { DestroyCollectionArguments } from '@unique-nft/substrate-client/tokens/types';
const destroyArgs: DestroyCollectionArguments = {
address: '<Account address>',
collectionId: '<ID of the collection>'
};
const result = await sdk.collection.destroy.submitWaitResult(destroyArgs);
const { success } = result.parsed;
Arguments
address
- string
collectionId
- number
Behaviour and errors
Throws common errors on insufficient balance and so on.
Returns
interface DestroyCollectionResult {
success: boolean;
}
Examples
import { DestroyCollectionArguments } from '@unique-nft/substrate-client/tokens/types';
const destroyArgs: DestroyCollectionArguments = {
address: '<Account address>',
collectionId: '<ID of the collection>'
};
const result = await sdk.collection.destroy.submitWaitResult(destroyArgs);
const { success } = result.parsed;
curl -X 'DELETE' \
'https://rest.unique.network/opal/v1/collections' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"address": "yGCyN3eydMkze4EPtz59Tn7obwbUbYNZCz48dp8FRdemTaLwm",
"collectionId": 1
}'
# then we sign, then we call
curl -X 'POST' \
'https://rest.unique.network/opal/v1/extrinsic/submit' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"signerPayloadJSON": { *from previous response* },
"signature": "0x_your_signature_in_hex"
}'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
client.collections.destroy.submitWaitResult({
address: '<your address>',
collectionId: 1,
});
Get effective limits by collection Id
Overview
The method gets collection effective limits.
Brief example
import { CollectionIdArguments, GetCollectionLimitsResult } from '@unique-nft/substrate-client/types';
const { collectionId, limits }: GetCollectionLimitsResult = await sdk.collection.getLimits({ collectionId: 123 });
console.log(`Collection ${collectionId} limits: ${JSON.stringify(limits)}`);
Arguments
collectionId
- number
Behaviour and errors
By default, the collection limit is not set (their value is null).
This limit value can be seen when requesting a collection using the Get collection by ID method.
If the limit is not set by the user, then the default limit is actually applied to the collection.
The values of the limits actually applied to the collection (default and user-set) can be obtained using Get effective limits
by collection ID.
Returns
interface CollectionLimits {
accountTokenOwnershipLimit: number | null;
sponsoredDataSize: number | null;
sponsoredDataRateLimit: number | null;
tokenLimit: number | null;
sponsorTransferTimeout: number | null;
sponsorApproveTimeout: number | null;
ownerCanTransfer: boolean | null;
ownerCanDestroy: boolean | null;
transfersEnabled: boolean | null;
}
interface GetCollectionLimitsResult {
collectionId: number;
limits: CollectionLimits;
}
Examples
import { CollectionIdArguments, GetCollectionLimitsResult } from '@unique-nft/substrate-client/types';
const { collectionId, limits }: GetCollectionLimitsResult = await sdk.collection.getLimits({ collectionId: 123 });
console.log(`Collection ${collectionId} limits: ${JSON.stringify(limits)}`);
curl -X 'GET' \
'https://rest.unique.network/opal/v1/collections/limits?collectionId=1' \
-H 'accept: application/json'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const { collectionId, limits } = await sdk.collection.getLimits({ collectionId: 1 });
console.log(`Collection ${collectionId} limits: ${JSON.stringify(limits)}`);
Property permissions
Overview
The method gets an array of collection property permissions (see Set token property permissions).
Brief example
import {
PropertyPermissionsArguments,
PropertyPermissionsResult,
} from '@unique-nft/substrate-client/tokens/types';
const args: PropertyPermissionsArguments = {
collectionId: 1,
// propertyKeys: ['foo', 'bar'],
};
const result: PropertyPermissionsResult =
await sdk.collection.propertyPermissions(args);
Arguments
collectionId: number
- Collection ID
propertyKeys?: string[]
- Array of property keys to get values for
at?: HexString;
- Allows specifying at which moment of the chain (block hash) you need to perform the check. If you leave it empty, the result will be for the last block of the chain.
Behaviour and errors
Throw errors:
- Collection not found
Returns
This method returns PropertyPermissionsResult
type PropertyPermissionsResult = {
propertyPermissions: Array<{
key: string;
permission: {
mutable: boolean;
collectionAdmin: boolean;
tokenOwner: boolean;
};
}>;
}
Examples
import {
PropertyPermissionsArguments,
PropertyPermissionsResult,
} from '@unique-nft/substrate-client/tokens/types';
const args: PropertyPermissionsArguments = {
collectionId: 1,
// propertyKeys: ['foo', 'bar'],
};
const result: PropertyPermissionsResult =
await sdk.collection.propertyPermissions(args);
curl -X 'GET' \
'http://rest.unique.network/opal/collection/property-permissions?collectionId=1' \
-H 'accept: application/json'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await sdk.collection.propertyPermissions({
collectionId: 1,
});
Set collection limits
Overview
The method sets some collection limits and starts enforcing them immediately.
You can get the current collection limits using the Get effective limits by collection Id method.
Only the Collection Owner has permission to call this method.
Brief example
import '@unique-nft/substrate-client/tokens';
import { SetCollectionLimitsArguments } from '@unique-nft/substrate-client/tokens/types';
const limitsArgs: SetCollectionLimitsArguments = {
address: '<your account address>',
collectionId: '<ID of the collection>',
limits: {
accountTokenOwnershipLimit: 1000,
sponsoredDataSize: 1024,
sponsoredDataRateLimit: 30,
tokenLimit: 1000000,
sponsorTransferTimeout: 6,
sponsorApproveTimeout: 6,
ownerCanTransfer: false,
ownerCanDestroy: false,
transfersEnabled: false,
}
};
const setResult = await sdk.collection.setLimits.submitWaitResult(limitsArgs);
const { parsed: { collectionId, limits } } = result;
Arguments
address: string
- Signer, the address of the Collection Owner
collectionId: number
- ID of the collection to set limits for
limits: CollectionLimits*
- The Effective Limits of the collection. The difference between the Effective Limits and the limits returned by Get collection by Id is explained in get effective limits.
* Interface CollectionLimits
accountTokenOwnershipLimit?: number | null
- Maximum number of tokens that one address can ownsponsoredDataSize?: number | null
- Maximum byte size of custom token data that can be sponsored when tokens are minted in sponsored modesponsoredDataRateLimit?: number | null
- Defines how many blocks need to pass between setVariableMetadata transactions in order for them to be sponsoredtokenLimit?: number | null
- Total amount of tokens that can be minted in this collection.sponsorTransferTimeout?: number | null
- Time interval in blocks that defines once per how long a non-privileged user transfer or the mint transaction can be sponsoredsponsorApproveTimeout?: number | null
- Time interval in blocks that defines once per how long a non-privileged user approve transaction can be sponsoredownerCanTransfer?: boolean | null
- A boolean value that tells if collection owner or admins can transfer or burn tokens owned by other non-privileged usersownerCanDestroy?: boolean | null
- A boolean value that tells if collection owner can destroy ittransfersEnabled?: boolean | null
- Flag that defines whether token transfers between users are currently enabled
Behaviour and errors
Attention! Total amount of tokens includes also the tokens that have been minted and burned after that. So if tokenLimit=3, 2 tokens were minted and 1 of them was burned, only 1 more token can be minted.
Throw errors:
- Collection not found
- Signer is not Collection Owner
Returns
This method returns SetCollectionLimitsResult
interface SetCollectionLimitsResult {
collectionId: number;
limits: CollectionLimits;
}
Examples
import '@unique-nft/substrate-client/tokens';
import { SetCollectionLimitsArguments } from '@unique-nft/substrate-client/tokens/types';
const limitsArgs: SetCollectionLimitsArguments = {
address: '<your account address>',
collectionId: '<ID of the collection>',
limits: {
accountTokenOwnershipLimit: 1000,
sponsoredDataSize: 1024,
sponsoredDataRateLimit: 30,
tokenLimit: 1000000,
sponsorTransferTimeout: 6,
sponsorApproveTimeout: 6,
ownerCanTransfer: false,
ownerCanDestroy: false,
transfersEnabled: false,
}
};
const setResult = await sdk.collection.setLimits.submitWaitResult(limitsArgs);
const { parsed: { collectionId, limits } } = result;
curl -X 'POST' \
'https://rest.unique.network/opal/v1/collections/set-limits?use=Build&withFee=false&verify=false' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"limits": {
"accountTokenOwnershipLimit": 1000,
"sponsoredDataSize": 1024,
"sponsoredDataRateLimit": 30,
"tokenLimit": 1000000,
"sponsorTransferTimeout": 6,
"sponsorApproveTimeout": 6,
"ownerCanTransfer": false,
"ownerCanDestroy": false,
"transfersEnabled": false
},
"address": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
"collectionId": 1
}'
# then we sign, then we call
curl -X 'POST' \
'https://rest.unique.network/opal/v1/extrinsic/submit' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"signerPayloadJSON": { *from previous response* },
"signature": "0x_your_signature_in_hex"
}'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await sdk.collection.setLimits.submitWaitResult({
"limits": {
"accountTokenOwnershipLimit": 1000,
"sponsoredDataSize": 1024,
"sponsoredDataRateLimit": 30,
"tokenLimit": 1000000,
"sponsorTransferTimeout": 6,
"sponsorApproveTimeout": 6,
"ownerCanTransfer": false,
"ownerCanDestroy": false,
"transfersEnabled": false
},
"address": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
"collectionId": 1
});
const { parsed: { collectionId, limits } } = result;
Set collection permissions
Overview
This method sets on-chain permissions for collection
Brief example
import {
SetCollectionPermissionsArguments,
CollectionAccess,
} from '@unique-nft/substrate-client/tokens';
const args: SetCollectionPermissionsArguments = {
address: account.address,
collectionId,
permissions: {
access: CollectionAccess.Normal,
mintMode: true,
nesting: {
collectionAdmin: true,
tokenOwner: true,
},
},
};
const result = await sdk.collection.setPermissions.submitWaitResult(args);
console.log(
`Collection #${result.parsed.collectionId} permissions successfully updated`,
);
Arguments
address: string
- Owner address
collectionId: number
- Collection id
permissions: CollectionPermissions
- Struct that contains the permissions for a collection
access?: CollectionAccess
- 'Normal' (for public access) or 'WhiteList' (for restricted access)mintMode?: boolean
- True, if anyone is allowed to mint. False otherwisenesting?:
tokenOwner?: boolean
collectionAdmin?: boolean
restricted?: number[]
Behaviour and errors
Throw errors:
- Collection not found
Returns
This method returns SetCollectionPermissionsResult
type SetCollectionPermissionsResult = {
collectionId: number;
}
Examples
import {
SetCollectionPermissionsArguments,
CollectionAccess,
} from '@unique-nft/substrate-client/tokens';
const args: SetCollectionPermissionsArguments = {
address: account.address,
collectionId,
permissions: {
access: CollectionAccess.Normal,
mintMode: true,
nesting: {
collectionAdmin: true,
tokenOwner: true,
},
},
};
const result = await sdk.collection.setPermissions.submitWaitResult(args);
console.log(
`Collection #${result.parsed.collectionId} permissions successfully updated`,
);
curl -X 'POST' \
'https://rest.unique.network/opal/v1/collections/permissions?use=Build&withFee=false&verify=false' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"collectionId": 1,
"address": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
"permissions": {
"access": "Normal",
"mintMode": true,
"nesting": {
"tokenOwner": true,
"collectionAdmin": true
}
}
}'
# then we sign, then we call
curl -X 'POST' \
'https://rest.unique.network/opal/v1/extrinsic/submit' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"signerPayloadJSON": { *from previous response* },
"signature": "0x_your_signature_in_hex"
}'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await sdk.collection.setPermissions.submitWaitResult({
"collectionId": 1,
"address": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
"permissions": {
"access": "Normal",
"mintMode": true,
"nesting": {
"tokenOwner": true,
"collectionAdmin": true
}
}
});
console.log(
`Collection #${result.parsed.collectionId} permissions successfully updated`,
);
Set collection properties
Overview
Collection properties are a unique set of keys and values. The maximum number of keys is 64. The maximum size of a parameter data block (keys and values) is 40kB.
Only the Collection Owner and Collection Admin can modify the Collection properties.
Property keys can only be added, they cannot be removed.
The naming of keys is restricted to a limited set of the following characters: Latin letter any case, numbers, dot, hyphen and underscore (regex: ^[0-9a-zA-Z.-_]).
Brief example
const args: SetCollectionPropertiesArguments = {
address: '5HNid8gyLiwocM9PyGVQetbWoBY76SrixnmjTRtewgaicKRX',
collectionId: 1,
properties: [
{
key: 'foo',
value: 'bar',
},
],
};
const result = await sdk.collection.setProperties.submitWaitResult(args);
console.log(result.parsed);
Arguments
address: Address
- Signer, the address of the Collection Owner or Collection Admin
collectionId: number
- Collection id
properties: Array<{ key: string; value: string; }>
- Array of properties
Behaviour and errors
Throw errors:
- Collection not found
- Signer is not Collection Owner or Collection Admin
Returns
This method returns SetCollectionPermissionsResult
type SetCollectionPermissionsResult = {
collectionId: number;
}
Examples
const args: SetCollectionPropertiesArguments = {
address: '5HNid8gyLiwocM9PyGVQetbWoBY76SrixnmjTRtewgaicKRX',
collectionId: 1,
properties: [
{
key: 'foo',
value: 'bar',
},
],
};
const result = await sdk.collection.setProperties.submitWaitResult(args);
console.log(result.parsed);
curl -X 'POST' \
'https://rest.unique.network/opal/v1/collections/properties?use=Build&withFee=false&verify=false' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"address": "5HNid8gyLiwocM9PyGVQetbWoBY76SrixnmjTRtewgaicKRX",
"collectionId": 1,
"properties": [
{
"key": "foo",
"value": "bar"
}
]
}'
# then we sign, then we call
curl -X 'POST' \
'https://rest.unique.network/opal/v1/extrinsic/submit' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"signerPayloadJSON": { *from previous response* },
"signature": "0x_your_signature_in_hex"
}'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await sdk.collection.setProperties.submitWaitResult({
"address": "5HNid8gyLiwocM9PyGVQetbWoBY76SrixnmjTRtewgaicKRX",
"collectionId": 1,
"properties": [
{
"key": "foo",
"value": "bar"
}
]
});
const { parsed: { properties } } = result;
console.log(`Properties ${properties.map(t => t.propertyKey).join()} are set for the collection`);
Set token property permissions
Overview
The method sets some tokenPropertyPermissions values. The current value of tokenPropertyPermissions can be found using Property permissions method.
The token cannot be attributed to an arbitrary key, only to a key from the tokenPropertyPermissions list.
Only the Collection Owner and Collection Admin can add and modify keys.
The permissions to create and modify properties of a collection are carried out using three keys - mutable, collectionAdmin and tokenOwner.
- mutable attribute sets the immutability attribute.
- collectionAdmin grants the designated collection administrator and the collection owner 'write/modify' access
- tokenOwner grants the token owner 'write/modify' access
Brief example
const args: SetTokenPropertyPermissionsArguments = {
address: '5HNid8gyLiwocM9PyGVQetbWoBY76SrixnmjTRtewgaicKRX',
collectionId: 1,
propertyPermissions: [
{
key: 'foo',
permission: {
mutable: true,
collectionAdmin: true,
tokenOwner: true,
},
},
],
};
const result =
await sdk.collection.setPropertyPermissions.submitWaitResult(args);
console.log(result.parsed);
Arguments
address: string
- Signer, the address of the Collection Owner or Collection Admin
collectionId: number
- Collection id
propertyPermissions: Array<{ key: string; permission: PropertyPermission*; }>
- Array of property permissions
* Type PropertyPermission
mutable: boolean
- attribute sets the immutability attribute
collectionAdmin: boolean
- grants the designated collection administrator and the collection owner 'write/modify' access
tokenOwner: boolean
- grants the token owner 'write/modify' access
Behaviour and errors
Throw errors:
- Collection not found
- Signer is not Collection Owner or Collection Admin
Returns
This method returns SetTokenPropertyPermissionsResult
type SetTokenPropertyPermissionsResult = {
propertyPermissions: Array<{
collectionId: number;
propertyKey: string;
}>;
};
Examples
const args: SetTokenPropertyPermissionsArguments = {
address: '5HNid8gyLiwocM9PyGVQetbWoBY76SrixnmjTRtewgaicKRX',
collectionId: 1,
propertyPermissions: [
{
key: 'foo',
permission: {
mutable: true,
collectionAdmin: true,
tokenOwner: true,
},
},
],
};
const result =
await sdk.collection.setPropertyPermissions.submitWaitResult(args);
console.log(result.parsed);
curl -X 'POST' \
'https://rest.unique.network/opal/v1/collections/property-permissions?use=Build&withFee=false&verify=false' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"address": "5HNid8gyLiwocM9PyGVQetbWoBY76SrixnmjTRtewgaicKRX",
"collectionId": 1,
"propertyPermissions": [
{
"key": "foo",
"permission": {
"mutable": true,
"collectionAdmin": true,
"tokenOwner": true
}
}
]
}'
# then we sign, then we call
curl -X 'POST' \
'https://rest.unique.network/opal/v1/extrinsic/submit' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"signerPayloadJSON": { *from previous response* },
"signature": "0x_your_signature_in_hex"
}'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await sdk.collection.setPropertyPermissions.submitWaitResult({
"address": "5HNid8gyLiwocM9PyGVQetbWoBY76SrixnmjTRtewgaicKRX",
"collectionId": 1,
"propertyPermissions": [
{
"key": "foo",
"permission": {
"mutable": true,
"collectionAdmin": true,
"tokenOwner": true
}
}
]
});
const { parsed: { propertyPermissions } } = result;
console.log(`the values of the keys ${propertyPermissions.map(t => t.propertyKey).join()} are set`);
Set transfers enabled flag
Overview
The method enables or disables transfers in a collection.
Only the Collection Owner can call this method.
The method sets transfersEnabled flag for particular collection. The current value of the transfersEnabled flag can be found using the method Get effective limits.
Brief example
import { SetTransfersEnabledArguments } from '@unique-nft/substrate-client/tokens/types';
const args: SetTransfersEnabledArguments = {
address: '5HNid8gyLiwocM9PyGVQetbWoBY76SrixnmjTRtewgaicKRX',
collectionId: 1,
isEnabled: true,
};
const result = await sdk.collection.setTransfersEnabled.submitWaitResult(args);
console.log(result.parsed.success);
Arguments
address: string
- Signer, the address of the Collection Owner
collectionId: number
- Collection id
isEnabled: boolean
- New flag value. If True, allows transfers, otherwise token transfers are frozen
Behaviour and errors
Throw errors:
- Collection not found
- Signer is not Collection Owner
Returns
This method returns SetTransfersEnabledResult
interface SetTransfersEnabledResult {
success: boolean;
}
Examples
import { SetTransfersEnabledArguments } from '@unique-nft/substrate-client/tokens/types';
const args: SetTransfersEnabledArguments = {
address: '5HNid8gyLiwocM9PyGVQetbWoBY76SrixnmjTRtewgaicKRX',
collectionId: 1,
isEnabled: true,
};
const result = await sdk.collection.setTransfersEnabled.submitWaitResult(args);
console.log(result.parsed.success);
curl -X 'POST' \
'https://rest.unique.network/opal/v1/collections/transfers-enabled?use=Build&withFee=false&verify=false' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"address": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
"collectionId": 1,
"isEnabled": true
}'
# then we sign, then we call
curl -X 'POST' \
'https://rest.unique.network/opal/v1/extrinsic/submit' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"signerPayloadJSON": { *from previous response* },
"signature": "0x_your_signature_in_hex"
}'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await sdk.collection.setTransfersEnabled.submitWaitResult({
"address": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
"collectionId": 1,
"isEnabled": true
});
console.log(result.parsed.success);
Change the owner of the collection
Overview
This method assigns a new collection owner. Only the Collection Owner can call this method.
Brief example
import { TransferCollectionArguments } from '@unique-nft/substrate-client/tokens/types';
const args: TransferCollectionArguments = {
collectionId: '<ID of the collection>',
from: '<collection owner>',
to: '<new collection owner>'
};
const result = await sdk.collection.transfer.submitWaitResult(args);
const { collectionId, newOnwer } = result.parsed;
Arguments
collectionId: number
- ID of the collection to change owner for
from: string
- The address of the Collection Owner
to: string
- New collection owner (Substrate address)
Behaviour and errors
Throw errors:
- Collection not found
- from address is not Collection Admin address
Returns
This method returns TransferCollectionResult
export interface TransferCollectionResult {
collectionId: number;
owner: string;
}
Examples
import { TransferCollectionArguments } from '@unique-nft/substrate-client/tokens/types';
const args: TransferCollectionArguments = {
collectionId: '<ID of the collection>',
from: '<collection owner>',
to: '<new collection owner>'
};
const result = await sdk.collection.transfer.submitWaitResult(args);
const { collectionId, newOnwer } = result.parsed;
curl -X 'PATCH' \
'https://rest.unique.network/opal/v1/collections/transfer?use=Build&withFee=false&verify=false' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"collectionId": 1,
"from": "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y",
"to": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty"
}'
# then we sign, then we call
curl -X 'POST' \
'https://rest.unique.network/opal/v1/extrinsic/submit' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"signerPayloadJSON": { *from previous response* },
"signature": "0x_your_signature_in_hex"
}'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await sdk.collection.transfer.submitWaitResult({
"collectionId": 1,
"from": "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y",
"to": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty"
});
const { parsed: { collectionId, owner } } = result;
console.log(`new owner of collection ${collectionId} has address ${owner}`);
Collections admin
Add collection admin
Overview
Adds an admin of the Collection.
Admin description is available in Get admin list method.
Only Collection Owner or Collection Admin has permission to call this method.
Brief example
import { AddCollectionAdminArguments } from '@unique-nft/substrate-client/tokens';
const args: AddCollectionAdminArguments = {
address: '<address>',
collectionId: 1,
newAdmin: '<address>',
};
const result = await sdk.collection.addAdmin.submitWaitResult(args);
console.log(result.parsed);
Arguments
address: string
- Signer, the address of the Collection Owner or Collection Admin
collectionId: number
- ID of the Collection to add admin for
newAdmin: string
- Address of new admin to add
Behaviour and errors
Throw errors:
- Collection not found
- Signer is not Collection Owner or Collection Admin
Returns
This method returns AddCollectionAdminResult
interface AddCollectionAdminResult {
collectionId: number;
newAdmin: string;
}
Examples
import { AddCollectionAdminArguments } from '@unique-nft/substrate-client/tokens';
const args: AddCollectionAdminArguments = {
address: '<address>',
collectionId: 1,
newAdmin: '<address>',
};
const result = await sdk.collection.addAdmin.submitWaitResult(args);
console.log(result.parsed);
curl -X 'POST' \
'https://rest.unique.network/opal/v1/collections/admins?use=Build&withFee=false&verify=false' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"address": "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y",
"collectionId": 1,
"newAdmin": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty"
}'
# then we sign, then we call
curl -X 'POST' \
'https://rest.unique.network/opal/v1/extrinsic/submit' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"signerPayloadJSON": { *from previous response* },
"signature": "0x_your_signature_in_hex"
}'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await sdk.collection.addAdmin.submitWaitResult({
"address": "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y",
"collectionId": 1,
"newAdmin": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty"
});
const { parsed: { collectionId, newAdmin } } = result;
console.log(`collection ${collectionId} has admin ${newAdmin}`);
Get admin list
Overview
Gets an array of Collection Admins.
NFT Collection can be controlled by multiple admin addresses (some of which can also be servers, for example).
Admins can issue and burn NFTs, as well as add and remove other admins, but cannot change NFT or Collection ownership.
The list of admins may be or become empty.
To add a Collection Admin, use the Add collection admin method.
Brief example
import {
AdminlistArguments,
AdminlistResult,
} from '@unique-nft/substrate-client/tokens/types';
const args: AdminlistArguments = {
collectionId: 1,
};
const result: AdminlistResult = await sdk.collection.admins(args);
Arguments
collectionId: number
- Collection id
at?: string;
- Allows to specify at which moment of the chain (block hash) you need to perform the check. If you leave it empty, the result will be for the last block of the chain.
Behaviour and errors
Throw errors:
- Collection not found
Returns
This method returns AdminlistResult
type AdminlistResult = {
admins: string[];
};
Examples
import {
AdminlistArguments,
AdminlistResult,
} from '@unique-nft/substrate-client/tokens/types';
const args: AdminlistArguments = {
collectionId: 1,
};
const result: AdminlistResult = await sdk.collection.admins(args);
curl -X 'GET' \
'https://rest.unique.network/opal/v1/collections/admins?collectionId=1' \
-H 'accept: application/json'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await sdk.collection.admins({
collectionId: 1,
});
const { admins } = result;
console.log(`${admins.join()} - collection admins`);
Remove collection admin
Overview
The method removes the admin address of the Collection. An admin address can remove itself.
The list of admins may be or become empty, in which case only Collection Owner will be able to add an Admin.
Admin description is available in Get admin list method.
Only the Collection Owner or Collection Admin has permission to call this method.
Brief example
import { RemoveCollectionAdminArguments } from '@unique-nft/substrate-client/tokens';
const args: RemoveCollectionAdminArguments = {
address: '<address>',
collectionId: 1,
accountId: '<address>',
};
const result = await sdk.collection.removeAdmin.submitWaitResult(args);
console.log(result.parsed);
Arguments
address: string
- Signer, the address of the Collection Owner or Collection Admin
collectionId: number
- ID of the Collection to remove admin for
admin: string
- Address of admin to remove
Behaviour and errors
Throw errors:
- Collection not found
- Signer is not Collection Owner or Collection Admin
Returns
This method returns RemoveCollectionAdminResult
interface RemoveCollectionAdminResult {
collectionId: number;
admin: string;
}
Examples
import { RemoveCollectionAdminArguments } from '@unique-nft/substrate-client/tokens';
const args: RemoveCollectionAdminArguments = {
address: '<address>',
collectionId: 1,
accountId: '<address>',
};
const result = await sdk.collection.removeAdmin.submitWaitResult(args);
console.log(result.parsed);
curl -X 'DELETE' \
'https://rest.unique.network/opal/v1/collections/admins?use=Build&withFee=false&verify=false' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"address": "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y",
"collectionId": 1,
"admin": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty"
}'
# then we sign, then we call
curl -X 'POST' \
'https://rest.unique.network/opal/v1/extrinsic/submit' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"signerPayloadJSON": { *from previous response* },
"signature": "0x_your_signature_in_hex"
}'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await sdk.collection.removeAdmin.submitWaitResult({
"address": "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y",
"collectionId": 1,
"admin": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty"
});
const { parsed: { collectionId, admin } } = result;
console.log(`admin ${admin} removed from collection ${collectionId}`);
Nesting
Get bundle
Overview
Returns full tree of a nested tokens. You can request it with any token from the bundle, the result will be the same for all.
Brief example
import { NestedToken } from '@unique-nft/substrate-client/types';
const result: NestedToken = await sdk.token.getBundle({
collectionId: 2,
tokenId: 5,
});
console.log(result);
/*
{
tokenId: 1,
collectionId: 1,
nestingChildTokens: [
{tokenId: 2, collectionId 1, childs: []},
...
{tokenId: 5, collectionId 1, childs: []}, <------- this is the requested token
]
}
*/
Arguments
collectionId: number
- collection id
tokenId: number
- token id
Behaviour and errors
Throw errors:
- If the topmost token of a bundle has no nested tokens
- Recursion depth exceeded
- Token not found during search for nested children
Returns
This method returns NestedToken
type NestedToken = Omit<TokenByIdResult, 'nestingChildTokens'> & {
nestingChildTokens: NestedToken[];
};
Examples
import { GetBundleArguments } from '@unique-nft/substrate-client/tokens';
const args: GetBundleArguments = {
collectionId: 2,
tokenId: 5,
};
const bundle = await sdk.token.getBundle(args);
console.log(bundle);
curl -X 'GET' \
'https://rest.unique.network/opal/v1/token/get-bundle?collectionId=2&tokenId=5' \
-H 'accept: application/json'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const bundle = await sdk.token.getBundle({
collectionId: 2,
tokenId: 5,
});
console.log(bundle);
Is Bundle
Overview
The method returns whether the token is in part of the bundle or not.
Brief example
const isBundle = await sdk.token.isBundle({
collectionId: 2,
tokenId: 1,
});
console.log(isBundle);
// false
Arguments
collectionId: number
- collection id
tokenId: number
- token id
Returns
This method returns IsBundleResult
type IsBundleResult = boolean;
Examples
import { IsBundleArguments } from '@unique-nft/substrate-client/tokens';
const args: IsBundleArguments = {
collectionId: 2,
tokenId: 1,
};
const bundle = await sdk.token.isBundle(args);
console.log(bundle);
curl -X 'GET' \
'https://rest.unique.network/opal/v1/token/is-bundle?collectionId=2&tokenId=1' \
-H 'accept: application/json'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await sdk.token.isBundle({
collectionId: 2,
tokenId: 1,
});
console.log(result.isBundle);
Nest token
Overview
Nesting is a process of forming a structural relationship between two NFTs that form a parent-child relationship in a tree structure. Such a relationship is formed by forwarding token A2 to the address of token A1 by which A2 becomes a child of token A1 (conversely, token A1 becomes the parent of A2).
Brief example
import { NestTokenArguments } from '@unique-nft/substrate-client/tokens/types';
const args: NestTokenArguments = {
address: '5HNid8gyLiwocM9PyGVQetbWoBY76SrixnmjTRtewgaicKRX',
parent: {
collectionId: 1,
tokenId: 1,
},
nested: {
collectionId: 1,
tokenId: 2,
},
};
const result = await sdk.token.nest.submitWaitResult(args);
const { tokenId, collectionId } = result.parsed;
console.log(
`Token ${tokenId} from collection ${collectionId} successfully nested`,
);
Arguments
address: string
- Token owner address
parent: { collectionId: number, tokenId: number }
- Parent token object
nested: { collectionId: number, tokenId: number }
- Nested token object
value: number
- optional (default: 1) - Amount of pieces (For Refungible token)
Behaviour and errors
Nesting can be applied only if the token collection has permission for nesting. If the collection has no permission for nesting - "UserIsNotAllowedToNest" Error will be thrown.
await sdk.collection.create.submitWaitResult({
// ...
permissions: {
nesting: {
tokenOwner: true,
collectionAdmin: true,
},
},
Returns
The method returns NestTokenResult
type NestTokenResult = {
/**
* id of the collection
*/
collectionId: number;
/**
* id of the token
*/
tokenId: number;
};
Examples
import { NestTokenArguments } from '@unique-nft/substrate-client/tokens/types';
const args: NestTokenArguments = {
address: '5HNid8gyLiwocM9PyGVQetbWoBY76SrixnmjTRtewgaicKRX',
parent: {
collectionId: 1,
tokenId: 1,
},
nested: {
collectionId: 1,
tokenId: 2,
},
};
const result = await sdk.token.nest.submitWaitResult(args);
const { tokenId, collectionId } = result.parsed;
console.log(
`Token ${tokenId} from collection ${collectionId} successfully nested`,
);
curl -X 'POST' \
'https://rest.unique.network/opal/v1/token/nest' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"address": "yGCyN3eydMkze4EPtz59Tn7obwbUbYNZCz48dp8FRdemTaLwm",
"parent": {
"collectionId": 1,
"tokenId": 1
},
"nested": {
"collectionId": 1,
"tokenId": 2
}
}'
# then we sign, then we call
curl -X 'POST' \
'https://rest.unique.network/opal/v1/extrinsic/submit' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"signerPayloadJSON": { *from previous response* },
"signature": "0x_your_signature_in_hex"
}'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await sdk.token.nest.submitWaitResult({
address: '5HNid8gyLiwocM9PyGVQetbWoBY76SrixnmjTRtewgaicKRX',
parent: {
collectionId: 1,
tokenId: 1,
},
nested: {
collectionId: 1,
tokenId: 2,
},
});
const {
parsed: { sponsor, collectionId },
} = result;
console.log(
`Token ${tokenId} from collection ${collectionId} successfully nested`,
);
Token children
Overview
Gets an array of nested tokens. If the token has no children returns an empty array.
Brief example
import {
TokenChildrenArguments,
TokenChildrenResult,
} from '@unique-nft/substrate-client/tokens/types';
const args: TokenChildrenArguments = {
collectionId: 1,
tokenId: 1,
};
const result: TokenChildrenResult = await sdk.token.children(args);
console.log(result);
/*
{
children: [
{
collectionId: 1,
token: 2
},
{
collection: 1,
token: 3
}
]
}
*/
Arguments
collectionId: number
- collection id
tokenId: number
- token id
Returns
This method returns TokenChildrenResult
type TokenChildrenArguments = {
collectionId: number;
tokenId: number;
};
type TokenChildrenResult = {
children: TokenChildrenArguments[];
};
Examples
import {
TokenChildrenArguments,
TokenChildrenResult,
} from '@unique-nft/substrate-client/tokens/types';
const args: TokenChildrenArguments = {
collectionId: 1,
tokenId: 1,
};
const result: TokenChildrenResult = await sdk.token.children(args);
console.log(result);
curl -X 'GET' \
'https://rest.unique.network/opal/v1/token/children?collectionId=1&tokenId=1' \
-H 'accept: application/json'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await sdk.token.children({
collectionId: 1,
tokenId: 1,
});
console.log(result.children);
Token parent
Overview
Returns info about the token parent. Call the tokenOwner
method. If the owner is not a nesting token returns null
.
Brief example
import {
TokenParentArguments,
TokenParentResult,
} from '@unique-nft/substrate-client/tokens/types';
const args: TokenParentArguments = {
collectionId: 1,
tokenId: 2,
};
const result: TokenParentResult = await sdk.token.parent(args);
console.log(result);
/*
{
collectionId: 1;
tokenId: 1;
address: "5HpZHYXjV23eEdVzhvYD2D3H6g1kM3aRGYwrmuGe9zaod6od";
}
*/
Arguments
collectionId: number
- collection id
tokenId: number
- token id
Returns
This method returns TokenParentResult
type TokenParentResult = {
collectionId: number;
tokenId: number;
address: Address;
};
Examples
import {
TokenParentArguments,
TokenParentResult,
} from '@unique-nft/substrate-client/tokens/types';
const args: TokenParentArguments = {
collectionId: 1,
tokenId: 2,
};
const result: TokenParentResult = await sdk.token.parent(args);
console.log(result);
curl -X 'GET' \
'https://rest.unique.network/opal/v1/token/parent?collectionId=1&tokenId=2' \
-H 'accept: application/json'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await sdk.token.parent({
collectionId: 1,
tokenId: 2,
});
console.log(result);
Topmost token owner
Overview
Returns substrate address of the topmost token owner.
Brief example
import {
TokenOwnerArguments,
TopmostTokenOwnerResult,
} from '@unique-nft/substrate-client/tokens/types';
const args: TokenOwnerArguments = {
collectionId: 1,
tokenId: 1,
// blockHashAt: '0xff19c2457fa4d7216cfad444615586c4365250e7310e2de7032ded4fcbd36873'
};
const result: TopmostTokenOwnerResult = await sdk.token.topmostOwner(args);
console.log(result);
/*
{
topmostOwner: "5HpZHYXjV23eEdVzhvYD2D3H6g1kM3aRGYwrmuGe9zaod6od"
}
*/
Arguments
collectionId: number
- collection id
tokenId: number
- token id
blockHashAt: string
- optional - hash of execution block
Returns
This method returns TopmostTokenOwnerResult
type TopmostTokenOwnerResult = { topmostOwner: Address };
Examples
import {
TokenOwnerArguments,
TopmostTokenOwnerResult,
} from '@unique-nft/substrate-client/tokens/types';
const args: TokenOwnerArguments = {
collectionId: 1,
tokenId: 1,
// blockHashAt: '0xff19c2457fa4d7216cfad444615586c4365250e7310e2de7032ded4fcbd36873'
};
const result: TopmostTokenOwnerResult = await sdk.token.topmostOwner(args);
console.log(result);
curl -X 'GET' \
'https://rest.unique.network/opal/v1/token/topmost-owner?collectionId=1&tokenId=2' \
-H 'accept: application/json'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await sdk.token.topmostOwner({
collectionId: 1,
tokenId: 2,
});
console.log(result.topmostOwner);
Unnest token
Overview
Nesting is a process of forming a structural relationship between two NFTs that form a parent-child relationship in a tree structure. Such a relationship is formed by forwarding token A2 to the address of token A1 by which A2 becomes a child of token A1 (conversely, token A1 becomes the parent of A2).
Brief example
import { UnnestTokenArguments } from '@unique-nft/substrate-client/tokens/types';
const args: UnnestTokenArguments = {
address: '5HNid8gyLiwocM9PyGVQetbWoBY76SrixnmjTRtewgaicKRX',
nested: {
collectionId: 1,
tokenId: 2,
},
};
const result = await sdk.token.unnest.submitWaitResult(args);
const { tokenId, collectionId } = result.parsed;
console.log(
`Token ${tokenId} from collection ${collectionId} successfully unnested`,
);
Arguments
address: string
- Token owner address
nested: { collectionId: number, tokenId: number }
- Nested token object
value: number
- optional (default: 1) - Amount of pieces (For Refungible token)
to: string
- optional - Address of new owner
Behaviour and errors
This method can only be executed if the token is nested.
Returns
The method returns UnnestTokenResult
type UnnestTokenResult = {
/**
* id of the collection
*/
collectionId: number;
/**
* id of the token
*/
tokenId: number;
};
Examples
import { UnnestTokenArguments } from '@unique-nft/substrate-client/tokens/types';
const args: UnnestTokenArguments = {
address: '5HNid8gyLiwocM9PyGVQetbWoBY76SrixnmjTRtewgaicKRX',
nested: {
collectionId: 1,
tokenId: 2,
},
};
const result = await sdk.token.unnest.submitWaitResult(args);
const { tokenId, collectionId } = result.parsed;
console.log(
`Token ${tokenId} from collection ${collectionId} successfully unnested`,
);
curl -X 'POST' \
'https://rest.unique.network/opal/v1/token/unnest' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"address": "yGCyN3eydMkze4EPtz59Tn7obwbUbYNZCz48dp8FRdemTaLwm",
"nested": {
"collectionId": 1,
"tokenId": 2
}
}'
# then we sign, then we call
curl -X 'POST' \
'https://rest.unique.network/opal/v1/extrinsic/submit' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"signerPayloadJSON": { *from previous response* },
"signature": "0x_your_signature_in_hex"
}'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await sdk.token.unnest.submitWaitResult({
address: '5HNid8gyLiwocM9PyGVQetbWoBY76SrixnmjTRtewgaicKRX',
nested: {
collectionId: 1,
tokenId: 2,
},
});
const {
parsed: { sponsor, collectionId },
} = result;
console.log(
`Token ${tokenId} from collection ${collectionId} successfully unnested`,
);
Sponsorship
Confirm sponsorship
Overview
Sponsors should use this method to confirm sponsorship after the collection owner called the set collection sponsor method.
Brief example
import { ConfirmSponsorshipArguments } from '@unique-nft/substrate-client/tokens';
const confirmSponsorshipArgs: ConfirmSponsorshipArguments = {
address: '5DZGhQtBRyZpRgKX3VffhyBCSQD1KwU2yY1eAs99Soh7Dpwp',
collectionId: 1,
};
await sdk.collection.confirmSponsorship.submitWaitResult(confirmSponsorshipArgs);
const { sponsorship } = await sdk.collection.get({ collectionId: 1 });
// `5DZGhQtBRyZpRgKX3VffhyBCSQD1KwU2yY1eAs99Soh7Dpwp - true`
console.log(`${sponsorship?.address} - ${sponsorship?.isConfirmed}`);
Arguments
address: string
— sponsor address
collectionId: number
— collection id
Behaviour and errors
This method takes collection id and confirms the signer to be a collection sponsor.
The collection owner should call the set collection sponsor with the sponsor address, otherwise, an error will be thrown.
Only an unconfirmed sponsor of the collection should call and sign this method.
Throws common errors on insufficient balance and so on.
Returns
This method returns ConfirmSponsorshipResult
interface ConfirmSponsorshipResult {
/**
* id of the collection
*/
collectionId: number;
/**
* address of the sponsor (Substrate)
*/
sponsor: Address;
}
Examples
import { ConfirmSponsorshipArguments } from '@unique-nft/substrate-client/tokens';
const confirmSponsorshipArgs: ConfirmSponsorshipArguments = {
address: '5DZGhQtBRyZpRgKX3VffhyBCSQD1KwU2yY1eAs99Soh7Dpwp',
collectionId: 1,
};
await sdk.collection.confirmSponsorship.submitWaitResult(confirmSponsorshipArgs);
const { sponsorship } = await sdk.collection.get({ collectionId: 1 });
// `5DZGhQtBRyZpRgKX3VffhyBCSQD1KwU2yY1eAs99Soh7Dpwp - true`
console.log(`${sponsorship?.address} - ${sponsorship?.isConfirmed}`);
curl -X 'POST' \
'https://rest.unique.network/opal/v1/collections/sponsorship/confirm' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"address": "5DZGhQtBRyZpRgKX3VffhyBCSQD1KwU2yY1eAs99Soh7Dpwp",
"collectionId": 1
}'
# then we sign, then we call
curl -X 'POST' \
'https://rest.unique.network/opal/v1/extrinsic/submit' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"signerPayloadJSON": { *from previous response* },
"signature": "0x_your_signature_in_hex"
}'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await sdk.collection.confirmSponsorship.submitWaitResult({
address: '5DZGhQtBRyZpRgKX3VffhyBCSQD1KwU2yY1eAs99Soh7Dpwp',
collectionId: 1,
});
const { parsed: { sponsor, collectionId } } = result;
console.log(`${sponsor} approved sponsorship of ${collectionId} collection`);
Next sponsored
Overview
This method returns the number of blocks when the sponsored transaction is available. Returns null if sponsorship hasn't been set.
Brief example
import {
NextSponsoredArguments,
NextSponsoredResult,
} from '@unique-nft/substrate-client/types';
const args: NextSponsoredArguments = {
collectionId: 1,
tokenId: 1,
address: '5G4M7RCt8PvtFPFm4XSwu85eK9Z8n9c6rygHZawHVALUvgcd',
// at: "0xa37d1c0155bda5877f4bc64c62cd37022c1b6db201c8225da7d169336d38b257"
};
const result: NextSponsoredResult = await sdk.collection.nextSponsored(args);
console.log(result);
/*
{
"blockNumber": 0
}
*/
Arguments
collectionId: number
- ID of collection
tokenId: number
- ID of token
address: string
- Address of transaction account
at: string
- optional - Hash of execution block
Returns
This method returns NextSponsoredResult
type NextSponsoredResult = {
blockNumber: number | null;
};
Examples
import {
NextSponsoredArguments,
NextSponsoredResult,
} from '@unique-nft/substrate-client/types';
const args: NextSponsoredArguments = {
collectionId: 1,
tokenId: 1,
address: '5G4M7RCt8PvtFPFm4XSwu85eK9Z8n9c6rygHZawHVALUvgcd',
// at: "0xa37d1c0155bda5877f4bc64c62cd37022c1b6db201c8225da7d169336d38b257"
};
const result: NextSponsoredResult = await sdk.collection.nextSponsored(args);
console.log(result);
curl -X 'GET' \
'https://rest.unique.network/opal/v1/collections/next-sponsored?collectionId=934&address=5GbRWxdwL8eHAgVaeXW3GUBffyLaKaLRhXXPwcnZbbzKDUU8&tokenId=1' \
-H 'accept: application/json'
Remove collection sponsor
Overview
The collection owner can use this method to remove sponsors added by the set collection sponsor method.
Brief example
import { RemoveSponsorshipArguments } from '@unique-nft/substrate-client/tokens';
const removeSponsorshipArgs: RemoveSponsorshipArguments = {
address: '5HgvUDiRm5yjRSrrG9B6q6km7KLzkXMxvFLHPZpA13pmwCJQ',
collectionId: 1,
};
await sdk.collection.removeSponsorship.submitWaitResult(removeSponsorshipArgs);
const { sponsorship } = await sdk.collection.get({ collectionId: 1 });
// `null`
console.log(sponsorship);
Arguments
address: string
— collection owner address
collectionId: number
— collection id
Behaviour and errors
This method takes the collection id and removes the collection sponsor.
Only collection owners are allowed to call this method.
Throws common errors on insufficient balance and so on.
Returns
This method returns RemoveSponsorshipResult
interface RemoveSponsorshipResult {
/**
* id of the collection
*/
collectionId: number;
}
Examples
import { RemoveSponsorshipArguments } from '@unique-nft/substrate-client/tokens';
const removeSponsorshipArgs: RemoveSponsorshipArguments = {
address: '5HgvUDiRm5yjRSrrG9B6q6km7KLzkXMxvFLHPZpA13pmwCJQ',
collectionId: 1,
};
await sdk.collection.removeSponsorship.submitWaitResult(removeSponsorshipArgs);
const { sponsorship } = await sdk.collection.get({ collectionId: 1 });
// `null`
console.log(sponsorship);
curl -X 'DELETE' \
'https://rest.unique.network/opal/v1/collections/sponsorship' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"address": "5HgvUDiRm5yjRSrrG9B6q6km7KLzkXMxvFLHPZpA13pmwCJQ",
"collectionId": 1
}'
# then we sign, then we call
curl -X 'POST' \
'https://rest.unique.network/opal/v1/extrinsic/submit' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"signerPayloadJSON": { *from previous response* },
"signature": "0x_your_signature_in_hex"
}'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await sdk.collection.removeSponsorship.submitWaitResult({
address: '5HgvUDiRm5yjRSrrG9B6q6km7KLzkXMxvFLHPZpA13pmwCJQ',
collectionId: 1,
});
const { parsed: { collectionId } } = result;
console.log(`${collectionId} now works without sponsoring`);
Set collection sponsor
Overview
The collection owner can use this method to set the sponsor of the collection.
After that sponsor should call confirm sponsorship method and the sponsoring mechanism will be enabled.
The collection owner can also call remove collection sponsor method.
Brief example
import { SetCollectionSponsorArguments } from '@unique-nft/substrate-client/tokens/types';
const setSponsorArgs: SetCollectionSponsorArguments = {
address: '5HgvUDiRm5yjRSrrG9B6q6km7KLzkXMxvFLHPZpA13pmwCJQ',
collectionId: 1,
newSponsor: '5DZGhQtBRyZpRgKX3VffhyBCSQD1KwU2yY1eAs99Soh7Dpwp',
};
await sdk.collection.setSponsorship.submitWaitResult(setSponsorArgs);
const { sponsorship } = await sdk.collection.get({ collectionId: 1 });
// `5DZGhQtBRyZpRgKX3VffhyBCSQD1KwU2yY1eAs99Soh7Dpwp - false`
console.log(`${sponsorship?.address} - ${sponsorship?.isConfirmed}`);
Arguments
address: string
— collection owner address
collectionId: number
— collection id
newSponsor: string
— address of new sponsor
Behaviour and errors
The method takes an address and sets it as a collection sponsor.
The signer must be an admin of the collection.
Be aware that if the address is already a sponsor of the given collection no exception will be thrown, but a fee will be charged.
Throws common errors on insufficient balance.
Returns
This method returns SetSponsorshipResult
interface SetSponsorshipResult {
/**
* id of the collection
*/
collectionId: number;
/**
* address of the sponsor (Substrate)
*/
sponsor: Address;
}
Examples
import { SetCollectionSponsorArguments } from '@unique-nft/substrate-client/tokens';
const setSponsorArgs: SetCollectionSponsorArguments = {
address: '5HgvUDiRm5yjRSrrG9B6q6km7KLzkXMxvFLHPZpA13pmwCJQ',
collectionId: 1,
newSponsor: '5DZGhQtBRyZpRgKX3VffhyBCSQD1KwU2yY1eAs99Soh7Dpwp',
};
await sdk.collection.setSponsorship.submitWaitResult(setSponsorArgs);
const { sponsorship } = await sdk.collection.get({ collectionId: 1 });
// `5DZGhQtBRyZpRgKX3VffhyBCSQD1KwU2yY1eAs99Soh7Dpwp - false`
console.log(`${sponsorship?.address} - ${sponsorship?.isConfirmed}`);
curl -X 'POST' \
'https://rest.unique.network/opal/v1/collections/sponsorship' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"address": "5HgvUDiRm5yjRSrrG9B6q6km7KLzkXMxvFLHPZpA13pmwCJQ",
"collectionId": 1,
"newSponsor": "5DZGhQtBRyZpRgKX3VffhyBCSQD1KwU2yY1eAs99Soh7Dpwp"
}'
# then we sign, then we call
curl -X 'POST' \
'https://rest.unique.network/opal/v1/extrinsic/submit' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"signerPayloadJSON": { *from previous response* },
"signature": "0x_your_signature_in_hex"
}'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await sdk.collection.setSponsorship.submitWaitResult({
address: '5HgvUDiRm5yjRSrrG9B6q6km7KLzkXMxvFLHPZpA13pmwCJQ',
collectionId: 1,
newSponsor: '5DZGhQtBRyZpRgKX3VffhyBCSQD1KwU2yY1eAs99Soh7Dpwp',
});
const { parsed: { sponsor, collectionId } } = result;
console.log(`${sponsor} should now approve sponsorship of ${collectionId} collection`);
Statistics
Get account tokens of the collection
Overview
Returns an array of tokens, owned by address.
Brief example
import { AccountTokensResult } from '@unique-nft/substrate-client/tokens';
const tokensResult: AccountTokensResult = await sdk.token.accountTokens({
collectionId: 1,
address: '<address>',
});
const token = tokensResult.tokens[0];
const { collectionId, tokenId } = token;
Arguments
collectionId: number
- ID of collection
address: string
- address of tokens owner
Behaviour and errors
Returns
This method returns AccountTokensResult
import { TokenIdArguments } from '@unique-nft/substrate-client/tokens';
interface AccountTokensResult {
tokens: TokenIdArguments[];
}
Examples
import { AccountTokensArguments, AccountTokensResult } from '@unique-nft/substrate-client/tokens';
const accountTokensArguments: AccountTokensArguments = {
address: '5DZGhQtBRyZpRgKX3VffhyBCSQD1KwU2yY1eAs99Soh7Dpwp',
collectionId: 1,
};
const tokensResult: AccountTokensResult = await sdk.token.accountTokens(accountTokensArguments);
const token = tokensResult.tokens[0];
const { collectionId, tokenId } = token;
console.log(`${collectionId} - ${tokenId}`);
curl -X 'GET' \
'https://rest.unique.network/opal/v1/token/account-tokens?address=5DZGhQtBRyZpRgKX3VffhyBCSQD1KwU2yY1eAs99Soh7Dpwp&collectionId=1'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const tokensResult = await sdk.token.accountTokens({
address: '5DZGhQtBRyZpRgKX3VffhyBCSQD1KwU2yY1eAs99Soh7Dpwp',
collectionId: 1,
});
const token = tokensResult.tokens[0];
const { collectionId, tokenId } = token;
console.log(`${collectionId} - ${tokenId}`);
Get account tokens amount
TBD
Overview
TBD
Brief example
TBD
Arguments
TBD
Examples
TBD
Get collection tokens
Overview
This method gets tokens contained within a collection.
Brief example
import { CollectionTokensResult } from '@unique-nft/substrate-client/tokens/types';
const result: CollectionTokensResult = await sdk.collection.tokens({
collectionId: 1,
});
Arguments
collectionId: number
- Collection ID
Behaviour and errors
Returns
This method returns CollectionTokensResult
- an array of token Ids contained within the passed collection.
interface CollectionTokensResult {
ids: number[];
}
Examples
import { CollectionTokensResult } from '@unique-nft/substrate-client/tokens';
const tokensResult: CollectionTokensResult = await sdk.collection.tokens({
collectionId: 1,
});
const { ids } = tokensResult;
console.log(`ids - ${ids}`);
curl -X 'GET' \
'https://rest.unique.network/opal/v1/collections/tokens?collectionId=1'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const tokensResult = await sdk.collection.tokens({
collectionId: 1,
});
const { ids } = tokensResult;
console.log(`ids - ${ids}`);
Get collection stats
Overview
Returns blockchain collection statistics:
- The number of total collections created
- The number of destroyed collections
- The number of collections that are still alive
Brief example
import { GetStatsResult } from '@unique-nft/substrate-client/types';
const stats: GetStatsResult = await sdk.collection.getStats();
console.log(`stats: ${stats.created}, ${stats.destroyed}, ${stats.alive}`);
Arguments
No arguments required.
Returns
This method returns GetStatsResult
interface GetStatsResult {
created: number;
destroyed: number;
alive: number;
}
Examples
import { CollectionTokensResult } from '@unique-nft/substrate-client/tokens';
const stats: GetStatsResult = await sdk.collection.getStats();
const { created, destroyed, alive } = stats;
console.log(`stats - ${created}, ${destroyed}, ${alive}`);
curl -X 'GET' \
'https://rest.unique.network/opal/v1/collections/stats'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const stats = await sdk.collection.stats();
const { created, destroyed, alive } = stats;
console.log(`stats - ${created}, ${destroyed}, ${alive}`);
Last token id
Overview
The method gets the last generated token id.
Brief example
import { LastTokenIdResult } from '@unique-nft/substrate-client/types';
const lastTokenIdResult: LastTokenIdResult = await sdk.collection.lastTokenId({
collectionId: 1,
});
const { tokenId } = lastTokenIdResult;
console.log(`tokenId - ${tokenId}`);
Arguments
collectionId: number
- ID of collection
Returns
This method returns LastTokenIdResult
interface LastTokenIdResult {
tokenId: number;
};
Examples
import { LastTokenIdResult } from '@unique-nft/substrate-client/types';
const lastTokenIdResult: LastTokenIdResult = await sdk.collection.lastTokenId({
collectionId: 1,
});
const { tokenId } = lastTokenIdResult;
console.log(`tokenId - ${tokenId}`);
curl -X 'GET' \
'https://rest.unique.network/opal/v1/collections/last-token-id?collectionId=1'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const lastTokenId = await sdk.collection.lastTokenId();
const { tokenId } = lastTokenId;
console.log(`lastTokenId - ${tokenId}`);
Total supply
Overview
Returns the number of tokens in the collection.
Brief example
import {
TotalSupplyResult,
} from '@unique-nft/substrate-client/tokens/types';
const result: TotalSupplyResult = await sdk.collection.totalSupply({
collectionId: 1
});
const { totalSupply } = result;
console.log(`totalSupply - ${totalSupply}`);
Arguments
collectionId: number
- ID of collection
blockHashAt?: number
- hash of execution block, is optional
Returns
This method returns LastTokenIdResult
interface TotalSupplyResult {
totalSupply: number;
}
Examples
import {
TotalSupplyResult,
} from '@unique-nft/substrate-client/tokens/types';
const result: TotalSupplyResult = await sdk.collection.totalSupply({
collectionId: 1
});
const { totalSupply } = result;
console.log(`totalSupply - ${totalSupply}`);
curl -X 'GET' \
'https://rest.unique.network/opal/v1/collections/total-supply?collectionId=1'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await sdk.collection.totalSupply();
const { totalSupply } = result;
console.log(`totalSupply - ${totalSupply}`);
Token
Get allowance
Overview
Get the amount of token pieces approved to transfer
Brief example
import { AllowanceArguments } from '@unique-nft/substrate-client/tokens/types';
const AllowanceArgs: AllowanceArguments = {
from: '<address>',
to: '<address>',
collectionId: 1,
tokenId: 1,
};
const { isAllowed } = await sdk.token.allowance(AllowanceArgs);
Arguments
from: string
- address from
to: string
- address to
collectionId: number
- ID of collection
tokenId: number
- ID of token
at?: string
— hash of execution block
Behaviour and errors
Throw errors:
- Collection or token not found
Returns
This method returns AllowanceResult
type AllowanceResult = {
isAllowed: boolean;
}
Examples
import { AllowanceArguments } from '@unique-nft/substrate-client/tokens/types';
const AllowanceArgs: AddToAllowListArguments = {
from: '<address>',
to: '<address>',
collectionId: 1,
tokenId: 1,
};
const { isAllowed } = await sdk.token.allowance(AllowanceArgs);
curl -X 'GET' \
'http://localhost:3000/token/allowance?collectionId=1&tokenId=1&from=<address>&to=<address>' \
-H 'accept: application/json'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const { isAllowed } = await sdk.token.allowance({
address: '<your account address>',
collectionId: '<ID of the collection>',
newAdminId: '<valid address>'
});
Burn token
Overview
This method destroys a concrete instance of NFT
If the from parameter is specified, then the token is destroyed on behalf of the owner of the item.
Only the Collection Owner, Collection Admin, or Current NFT owner has permission to call this method.
Brief example
import '@unique-nft/substrate-client/tokens';
import { BurnTokenArguments } from '@unique-nft/substrate-client/tokens/types';
const burnItemArgs: BurnTokenArguments = {
tokenId: 1,
collectionId: 1,
};
const setResult = await sdk.token.burn.submitWaitResult(burnItemArgs);
const { collectionId, tokenId, address } = setResult.parsed;
Arguments
address: string
- Signer address
collectionId: number
- ID of the collection
tokenId: number
- ID of NFT to burn
Optional Arguments
from?: string
- The owner of the item on whose behalf the token is destroyed
Behaviour and errors
Throw errors:
- Collection or token not found
- The Signer or from addresses do not have permission to call this method
- If the owner of the collection (but not the owner of the token) wants to burn the token and the ownerCanTransfer flag is set to false. Check the set limits using the method get effective collection limits.
- Insufficient balance
Returns
This method returns BurnTokenResult
interface BurnTokenResult {
collectionId: number;
tokenId: number;
address: Address;
}
Examples
import '@unique-nft/substrate-client/tokens';
import { BurnTokenArguments } from '@unique-nft/substrate-client/tokens/types';
const burnItemArgs: BurnTokenArguments = {
tokenId: 1,
collectionId: 1,
};
const setResult = await sdk.token.burn.submitWaitResult(burnItemArgs);
const { collectionId, tokenId, address } = setResult.parsed;
curl -X 'DELETE' \
'http://rest.unique.network/opal/token?use=Build&withFee=false&verify=false' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"collectionId": 183,
"tokenId": 5,
"address": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty"
}'
# then we sign, then we call
curl -X 'POST' \
'https://rest.unique.network/opal/v1/extrinsic/submit' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"signerPayloadJSON": { *from previous response* },
"signature": "0x_your_signature_in_hex"
}'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await sdk.token.burn.submitWaitResult({
"collectionId": 1,
"tokenId": 1,
"address": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty"
});
const { parsed: { collectionId, tokenId } } = result;
console.log(`burned token ${tokenId} collection ${collectionId}`);
Create multiple tokens
Overview
This method creates multiple items in a collection.
Only the Collection Owner, Collection Admin and addresses from the Allow List (if Allow List is enabled and MintPermission is enabled) can mint tokens.
Brief example
import { CreateMultipleTokensArguments } from '@unique-nft/substrate-client/tokens';
import {
UniqueCollectionSchemaToCreate,
COLLECTION_SCHEMA_NAME,
AttributeType,
} from '@unique-nft/substrate-client/tokens';
const args: CreateMultipleTokensArguments = {
address: '<your account address>',
collectionId: 123,
tokens: [
data: {
encodedAttributes: {
'0': 0,
'1': [0],
'2': 'foo_bar',
},
image: {
ipfsCid: '<valid_ipfs_cid>',
},
},
owner: '<new token owner address>',
properties: [{
key: "example",
value: "Hello world"
}]
],
};
const result = await sdk.token.createMultiple.submitWaitResult(args);
const [{ collectionId, tokenId }] = result.parsed;
const token = await sdk.token.get({ collectionId, tokenId });
Arguments
address: Address
- The address of the collection owner
collectionId: number
- Collection id
tokens: Array<CreateTokenPayload>
- The content of the tokens:
- Description UniqueTokenToCreate available in Create token method.
Behaviour and errors
Throw errors:
- Collection not found
- The signer must be Collection Owner or Collection Admin or in Allow List of the collection
- The collection is set TokenLimit and creating a new token will exceed the token limit
- Insufficient balance
Returns
This method returns TokenIdArguments[]
interface TokenIdArguments {
collectionId: number;
tokenId: number;
}
Examples
import { CreateMultipleTokensArguments } from '@unique-nft/substrate-client/tokens';
import {
UniqueCollectionSchemaToCreate,
COLLECTION_SCHEMA_NAME,
AttributeType,
} from '@unique-nft/substrate-client/tokens';
const args: CreateMultipleTokensArguments = {
address: '<your account address>',
collectionId: 123,
tokens: [
data: {
encodedAttributes: {
'0': 0,
'1': [0],
'2': 'foo_bar',
},
image: {
ipfsCid: '<valid_ipfs_cid>',
},
},
owner: '<new token owner address>',
properties: [{
key: "example",
value: "Hello world"
}]
],
};
const result = await sdk.token.createMultiple.submitWaitResult(args);
const [{ collectionId, tokenId }] = result.parsed;
const token = await sdk.token.get({ collectionId, tokenId });
curl -X 'POST' \
'http://rest.unique.network/opal/token/create-multiple?use=Build&withFee=false&verify=false' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"address": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
"collectionId": 183,
"tokens": [
{
"data": {
"image": {
"url": "https://ipfs.unique.network/ipfs/QmcAcH4F9HYQtpqKHxBFwGvkfKb8qckXj2YWUrcc8yd24G/image2.png"
}
}
},
{
"data": {
"image": {
"url": "https://ipfs.unique.network/ipfs/QmcAcH4F9HYQtpqKHxBFwGvkfKb8qckXj2YWUrcc8yd24G/image2.png"
}
}
}
]
}'
# then we sign, then we call
curl -X 'POST' \
'https://rest.unique.network/opal/v1/extrinsic/submit' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"signerPayloadJSON": { *from previous response* },
"signature": "0x_your_signature_in_hex"
}'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await sdk.token.createMultiple.submitWaitResult({
address: '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty',
collectionId: 183,
tokens: [
{
data: {
image: {
url: 'https://ipfs.unique.network/ipfs/QmcAcH4F9HYQtpqKHxBFwGvkfKb8qckXj2YWUrcc8yd24G/image1.png',
},
},
},
{
data: {
image: {
url: 'https://ipfs.unique.network/ipfs/QmcAcH4F9HYQtpqKHxBFwGvkfKb8qckXj2YWUrcc8yd24G/image1.png',
},
},
},
],
});
const { parsed } = result;
console.log(`minted ${parsed.length} tokens`);
Create token (mint)
Overview
This method creates a concrete token instance of NFT collection.
Collection can be created with create method in collection section.
Only the Collection Owner, Collection Admin and addresses from the Allow List (if Allow List is enabled and MintPermission is enabled) can mint token.
The owner of the token is specified in the owner field. If the owner field is not set, then the Signer becomes the owner of the token.
Brief example
import { CreateTokenNewArguments } from '@unique-nft/substrate-client/tokens/types';
import {
UniqueCollectionSchemaToCreate,
COLLECTION_SCHEMA_NAME,
AttributeType,
} from '@unique-nft/substrate-client/tokens';
const createTokenArgs: CreateTokenNewArguments = {
address: '<your account address>',
collectionId: 123,
data: {
encodedAttributes: {
'0': 0,
'1': [0],
'2': 'foo_bar',
},
image: {
ipfsCid: '<valid_ipfs_cid>',
},
},
};
const result = await sdk.token.create.submitWaitResult(createArgs);
const { collectionId, tokenId } = result.parsed;
const token = await sdk.token.get({ collectionId, tokenId });
Arguments
address: string
- The address of collection owner
collectionId: number
- Collection id
owner?: string
- The address of token owner (optional)
data: UniqueTokenToCreate
- The content of the token is stored in the fields of the object:
name?: LocalizedStringWithDefault*
description?: LocalizedStringWithDefault*
image: GenericInfixUrlOrCidWithHash**
- Token image (url
,urlInfix
oripfsCid
)imagePreview?: GenericInfixUrlOrCidWithHash**
video?: GenericInfixUrlOrCidWithHash**
audio?: GenericInfixUrlOrCidWithHash**
spatialObject?: GenericInfixUrlOrCidWithHash**
encodedAttributes?: EncodedTokenAttributes
- Token attributes
* Type LocalizedStringWithDefault
{
_: string;
[K: string]: string;
}
* Type GenericInfixUrlOrCidWithHash
{ urlInfix?: string; hash?: string | null }
| { url?: string; hash?: string | null }
| { ipfsCid?: string; hash?: string | null };
Behaviour and errors
Throw errors:
- Collection not found
- The signer must be Collection Owner or Collection Admin or in Allow List of the collection
- The collection is set TokenLimit and creating a new token will exceed the token limit (TokenLimit includes all the tokens that have been minted, even if some of them were burned after)
- Insufficient balance
Returns
This method returns TokenIdArguments
interface TokenIdArguments extends CollectionIdArguments {
tokenId: number;
}
Examples
import { CreateTokenNewArguments } from '@unique-nft/substrate-client/tokens/types';
import {
UniqueCollectionSchemaToCreate,
COLLECTION_SCHEMA_NAME,
AttributeType,
} from '@unique-nft/substrate-client/tokens';
const createTokenArgs: CreateTokenNewArguments = {
address: '<your account address>',
collectionId: 123,
data: {
encodedAttributes: {
'0': 0,
'1': [0],
'2': 'foo_bar',
},
image: {
ipfsCid: '<valid_ipfs_cid>',
},
},
};
const result = await sdk.token.create.submitWaitResult(createArgs);
const { collectionId, tokenId } = result.parsed;
const token = await sdk.token.get({ collectionId, tokenId });
curl -X 'POST' \
'http://rest.unique.network/opal/token?use=Build&withFee=false&verify=false' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"address": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
"collectionId": 183,
"data": {
"image": {
"url": "https://ipfs.unique.network/ipfs/QmcAcH4F9HYQtpqKHxBFwGvkfKb8qckXj2YWUrcc8yd24G/image1.png"
},
"name": {
"_": "Hello!"
},
"description": {
"_": "Hello!"
}
}
}'
# then we sign, then we call
curl -X 'POST' \
'https://rest.unique.network/opal/v1/extrinsic/submit' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"signerPayloadJSON": { *from previous response* },
"signature": "0x_your_signature_in_hex"
}'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await sdk.token.create.submitWaitResult({
"address": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
"collectionId": 183,
"data": {
"image": {
"url": "https://ipfs.unique.network/ipfs/QmcAcH4F9HYQtpqKHxBFwGvkfKb8qckXj2YWUrcc8yd24G/image1.png"
},
"name": {
"_": "Hello!"
},
"description": {
"_": "Hello!"
}
}
});
const { parsed: { collectionId, tokenId } } = result;
console.log(`created token ${tokenId} in collection ${collectionId}`);
Delete token properties
Overview
Deletes properties from a token.
Brief example
const args: DeleteTokenPropertiesArguments = {
address: '5HNid8gyLiwocM9PyGVQetbWoBY76SrixnmjTRtewgaicKRX',
collectionId: 1,
tokenId: 1,
propertyKeys: ['foo', 'bar'],
};
const result = await sdk.token.deleteProperties.submitWaitResult(args);
console.log(result.parsed);
Arguments
address: string
- Signer, the address of the Collection Owner, Collection Admin or Token Owner
collectionId: number
- Collection id
tokenId: number
- Token id
propertyKeys: string[]
- Array of properties keys
Behaviour and errors
Throw errors:
- Collection or token not found
- Signer is Collection Admin or Token Owner and does not have permission to call the method (see set token property permissions method for details).
- Keys not in tokenPropertyPermissions list
Returns
This method returns DeleteTokenPropertiesResult
type DeleteTokenPropertiesResult = {
properties: Array<{
collectionId: number;
tokenId: number;
propertyKey: string;
}>;
}
Examples
const args: DeleteTokenPropertiesArguments = {
address: '5HNid8gyLiwocM9PyGVQetbWoBY76SrixnmjTRtewgaicKRX',
collectionId: 1,
tokenId: 1,
propertyKeys: ['foo', 'bar'],
};
const result = await sdk.token.deleteProperties.submitWaitResult(args);
console.log(result.parsed);
curl -X 'DELETE' \
'http://rest.unique.network/opal/token/properties?use=Build&withFee=false&verify=false' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"address": "5HNid8gyLiwocM9PyGVQetbWoBY76SrixnmjTRtewgaicKRX",
"collectionId": 1,
"tokenId": 1,
"propertyKeys": ['\''foo'\'', '\''bar'\'']
}'
# then we sign, then we call
curl -X 'POST' \
'https://rest.unique.network/opal/v1/extrinsic/submit' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"signerPayloadJSON": { *from previous response* },
"signature": "0x_your_signature_in_hex"
}'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const { parsed: { properties } } = await sdk.token.deleteProperties.submitWaitResult({
"address": "5HNid8gyLiwocM9PyGVQetbWoBY76SrixnmjTRtewgaicKRX",
"collectionId": 1,
"tokenId": 1,
"propertyKeys": [
"foo",
"bar"
]
});
console.log(`removed properties ${properties.map(t => t.propertyKey).join()}`);
Set token properties
Overview
Sets (creates or overwrites) properties for token.
Brief example
const args: SetTokenPropertiesArguments = {
address: '5HNid8gyLiwocM9PyGVQetbWoBY76SrixnmjTRtewgaicKRX',
collectionId: 1,
tokenId: 1,
properties: [
{
key: 'foo',
value: 'bar',
},
],
};
const result = await sdk.token.setProperties.submitWaitResult(args);
console.log(result.parsed);
Arguments
address: string
- Signer, the address of the Collection Owner, Collection Admin or Token Owner
collectionId: number
- Collection id
tokenId: number
- Token id
properties: Array<{ key: string; value: string; }>
- Array of properties
Behaviour and errors
Throw errors:
- Collection or token not found
- Signer is Collection Admin or Token Owner and does not have permission to call the method (see set token property permissions method in the collection section for details).
- Keys not in tokenPropertyPermissions list
Returns
This method returns SetTokenPropertiesResult
type SetTokenPropertiesResult = {
properties: Array<{
collectionId: number;
tokenId: number;
propertyKey: string;
}>;
};
Examples
const args: SetTokenPropertiesArguments = {
address: '5HNid8gyLiwocM9PyGVQetbWoBY76SrixnmjTRtewgaicKRX',
collectionId: 1,
tokenId: 1,
properties: [
{
key: 'foo',
value: 'bar',
},
],
};
const result = await sdk.token.setProperties.submitWaitResult(args);
console.log(result.parsed);
curl -X 'POST' \
'https://rest.unique.network/opal/v1/token/properties?use=Build&withFee=false&verify=false' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"address": "5HNid8gyLiwocM9PyGVQetbWoBY76SrixnmjTRtewgaicKRX",
"collectionId": 1,
"tokenId": 1,
"properties": [
{
"key": "foo",
"value": "bar"
}
]
}'
# then we sign, then we call
curl -X 'POST' \
'https://rest.unique.network/opal/v1/extrinsic/submit' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"signerPayloadJSON": { *from previous response* },
"signature": "0x_your_signature_in_hex"
}'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const { parsed: { properties } } = await sdk.token.setProperties.submitWaitResult({
"address": "5HNid8gyLiwocM9PyGVQetbWoBY76SrixnmjTRtewgaicKRX",
"collectionId": 1,
"tokenId": 1,
"properties": [
{
"key": "foo",
"value": "bar"
}
]
});
console.log(`the values of the keys ${properties.map(t => t.propertyKey).join()} are set`);
Get token
Overview
Returns information about the NFT of a specific collection.
Brief example
const token = await sdk.token.get({
collectionId: 2,
tokenId: 1,
});
const {
collectionId,
tokenId,
owner,
image,
attributes,
} = token;
Arguments
collectionId: number
— collection id
tokenId: number
— token id
Behaviour and errors
Throw errors:
- Collection not found (not created or destroyed)
- Token not found (not created or burned)
- Check path chain (CHAIN_WS_URL)
Returns
This method returns TokenByIdResult
type TokenByIdResult = Omit<UniqueTokenDecoded, 'owner'> & {
owner: Address;
};
Examples
const token = await sdk.token.get({
collectionId: 2,
tokenId: 1,
});
const {
collectionId,
tokenId,
owner,
image,
attributes,
} = token;
curl -X 'GET' \
'https://rest.unique.network/opal/v1/token?collectionId=2&tokenId=1' \
-H 'accept: application/json'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await sdk.token.get({
collectionId: 2,
tokenId: 1,
});
const { tokenId, owner } = result;
console.log(`token ${tokenId} is owned by address ${owner}`);
Get token owner
Overview
This method allows you to get the current NFT owner.
The initial owner of the token is set to the address that signed the token creation extrinsic.
You can change the owner of the token using the token's transfer method.
Brief example
import {
TokenOwnerArguments,
TokenOwnerResult,
} from '@unique-nft/substrate-client/tokens/types';
const args: TokenOwnerArguments = {
collectionId: 1,
tokenId: 1,
// blockHashAt: '0xff19c2457fa4d7216cfad444615586c4365250e7310e2de7032ded4fcbd36873'
};
const result: TokenOwnerResult = await sdk.token.owner(
args,
);
Arguments
collectionId: number
— collection ID
tokenId: number
— token ID
blockHashAt?: string
— hash of execution block
Behaviour and errors
Throw errors:
- Collection not found (not created or destroyed)
- Token not found (not created or burned)
- Check path chain (CHAIN_WS_URL)
Returns
The method returns TokenOwnerResult
type TokenOwnerResult = { owner: Address }
Examples
import {
TokenOwnerArguments,
TokenOwnerResult,
} from '@unique-nft/substrate-client/tokens/types';
const args: TokenOwnerArguments = {
collectionId: 1,
tokenId: 1,
// blockHashAt: '0xff19c2457fa4d7216cfad444615586c4365250e7310e2de7032ded4fcbd36873'
};
const result: TokenOwnerResult = await sdk.token.owner(
args,
);
curl -X 'GET' \
'https://rest.unique.network/opal/v1/token/owner?collectionId=1&tokenId=1' \
-H 'accept: application/json'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const { owner } = await sdk.token.owner({
collectionId: 1,
tokenId: 1,
});
console.log(`token owner ${owner}`);
Token properties
Overview
Gets an array of token properties. Property keys must be in the tokenPropertyPermissions list.
Brief example
import {
TokenPropertiesArguments,
TokenPropertiesResult,
} from '@unique-nft/substrate-client/tokens/types';
const args: TokenPropertiesArguments = {
collectionId: 1,
tokenId: 1,
// propertyKeys: ['foo', 'bar'],
};
const result: TokenPropertiesResult = await sdk.token.properties(args);
Arguments
collectionId: number
- Collection ID
tokenId: number
- Token ID
Additional arguments
propertyKeys?: string[]
- Array of property keys
Behaviour and errors
Throw errors:
- Collection or token not found
Returns
This method returns TokenPropertiesResult
type TokenPropertiesResult = {
properties: Array<{
key: string;
value: string;
}>;
};
Examples
import {
TokenPropertiesArguments,
TokenPropertiesResult,
} from '@unique-nft/substrate-client/tokens/types';
const args: TokenPropertiesArguments = {
collectionId: 1,
tokenId: 1,
// propertyKeys: ['foo', 'bar'],
};
const result: TokenPropertiesResult = await sdk.token.properties(args);
curl -X 'GET' \
'https://rest.unique.network/opal/v1/token/properties?collectionId=1&tokenId=1' \
-H 'accept: application/json'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const { properties } = await sdk.token.properties({
collectionId: 1,
tokenId: 1,
});
Transfer token
Overview
This method changes the ownership of the token.
Only the Collection Owner, Collection Admin, or Current NFT owner has permission to call this method.
The Current NFT owner can be found using *get owner method of the token.
Brief example
import { TransferArguments } from '@unique-nft/substrate-client/tokens';
const args: TransferArguments = {
address: '<address>',
to: '<address>',
collectionId: 1,
tokenId: 1,
};
const result = await sdk.token.transfer.submitWaitResult(args);
console.log(result.parsed);
Arguments
address: string
- Signer address. Signer doesn't needs to be an owner of the token (in this case, the owner should set allowance for the Signer to transfer token)
to: string
- Address of token recipient
collectionId: number
- Collection id
tokenId: number
- Token id
Optional Arguments
from: string
- Address that owns token (default is signer address)
value: number
- Amount to transfer (default is 1):
- Non-Fungible Mode: Ignored
- Fungible Mode: Must specify transferred amount
- Re-Fungible Mode: Must specify transferred portion (between 0 and 1)
Behaviour and errors
Throw errors:
- Collection or token not found
- Signer is not a Collection Owner, Collection Admin, or Current NFT owner
- The restrictions set by the transfersEnabled or ownerCanTransfer flags apply. Check the set limits using collection get effective collection limits method.
- Insufficient balance
Returns
This method returns TransferResult
interface TransferResult {
collectionId: number;
tokenId: number;
from: Address;
to: Address;
value: number;
}
Examples
import { TransferArguments } from '@unique-nft/substrate-client/tokens';
const args: TransferArguments = {
address: '<address>',
to: '<address>',
collectionId: 1,
tokenId: 1,
};
const result = await sdk.token.transfer.submitWaitResult(args);
console.log(result.parsed);
curl -X 'PATCH' \
'http://rest.unique.network/opal/token/transfer?use=Build&withFee=false&verify=false' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"collectionId": 183,
"tokenId": 1,
"address": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
"to": "5HGjWAeFDfFCWPsjFQdVV2Msvz2XtMktvgocEZcCj68kUMaw"
}'
# then we sign, then we call
curl -X 'POST' \
'https://rest.unique.network/opal/v1/extrinsic/submit' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"signerPayloadJSON": { *from previous response* },
"signature": "0x_your_signature_in_hex"
}'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await sdk.token.transfer.submitWaitResult({
"collectionId": 183,
"tokenId": 1,
"address": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
"to": "5HGjWAeFDfFCWPsjFQdVV2Msvz2XtMktvgocEZcCj68kUMaw"
});
const { parsed: { collectionId, tokenId, to } } = result;
console.log(`${to} is the new owner of token ${tokenId} from collection ${collectionId}`);
Other
Approve
Overview
Set, change, or remove approved address to transfer the ownership of the token or burn the token.
Brief example
import { ApproveArguments } from '@unique-nft/substrate-client/tokens/types';
const approveArgs: ApproveArguments = {
address: '<Signer address>',
spender: '<Account address for whom token will be approved>',
collectionId: '<ID of the collection>',
tokenId: '<ID of the token>',
isApprove: true
};
const result = await sdk.token.approve.submitWaitResult(approveArgs);
const { collectionId, tokenId } = result.parsed;
Arguments
address: string
- Signer address
spender: string
- Address that is approved to transfer this token
collectionId: number
- Collection id
tokenId: number
- Token id
isApprove: boolean
- Must be true (for approval) or false (for disapproval)
Behaviour and errors
Throw errors:
- Collection ot token not found
- Signer is not Collection Owner, Collection Admin or Token Owner
Returns
This method returns ApproveResult
interface ApproveResult {
collectionId: number;
tokenId: number;
}
Examples
import { ApproveArguments } from '@unique-nft/substrate-client/tokens/types';
const approveArgs: ApproveArguments = {
address: '<Signer address>',
spender: '<Account address for whom token will be approved>',
collectionId: '<ID of the collection>',
tokenId: '<ID of the token>',
isApprove: true
};
const result = await sdk.token.approve.submitWaitResult(approveArgs);
const { collectionId, tokenId } = result.parsed;
curl -X 'POST' \
'http://localhost:3000/v1/tokens/approve?use=Build&withFee=false&verify=false' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"address": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
"spender": "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y",
"collectionId": 1,
"tokenId": 1,
"isApprove": true
}'
# then we sign, then we call
curl -X 'POST' \
'https://rest.unique.network/opal/v1/extrinsic/submit' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"signerPayloadJSON": { *from previous response* },
"signature": "0x_your_signature_in_hex"
}'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await sdk.token.approve.submitWaitResult({
address: '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty',
spender: '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty',
collectionId: 1,
tokenId: 1,
isApprove: true
});
const { collectionId, tokenId } = result.parsed;
Token exists
Overview
Checks if token exists in collection. Returns true or false.
Brief example
const { isExists } = await sdk.token.exists({ collectionId: 1, tokenId: 1 });
Arguments
collectionId: number
- ID of collection
tokenId: number
- ID of token
at: string
- optional - Hash of execution block
Behaviour and errors
Throw errors:
- Collection or token not found
Returns
This method returns TokenExistsResult
type TokenExistsResult = {
isExists: boolean;
}
Examples
const { isExists } = await sdk.token.exists({ collectionId: 1, tokenId: 1 });
curl -X 'GET' \
'https://rest.unique.network/opal/v1/tokens/exists?collectionId=1&tokenId=1' \
-H 'accept: application/json'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const { isExists } = await sdk.token.exists({
collectionId: 1,
tokenId: 1
});
Balance
Get all balances of the address
Overview
Returns information about account balances.
Brief example
const chainProperties = sdk.common.chainProperties();
const {
SS58Prefix,
token,
decimals,
wsUrl,
genesisHash,
} = chainProperties;
Arguments
- address - Wallet address
Behaviour and errors
Throw errors:
- Validation error - if invalid address provided
Returns
This method returns all balances of the address.
You can find more information about balances in the balances section.
- availableBalance - A truly free balance. Tokens that the user can transfer to another account or use in any other way.
- lockedBalance - The balance locked by the logic of some pallets.
- freeBalance - The balance of the user that they can use to perform operations on the network. Some operations (such as staking) may not decrease this balance, but may impose some restrictions on a part of it.
- totalBalance - All tokens owned by the user.
- reservedBalance - Reserved balance is a portion of the user's balance that is not available for any operations involving the user's funds.
- stakedBalance - Tokens staked by
appPromotion
pallet. - unstakedBalance - Tokens amount waiting for unstake.
- canstakeBalance - Amount of tokens that can be staked. It is equal to
freeBalance - (stakedBalance + unstakedBalance)
.
interface Balance {
raw: string;
unit: string;
decimals: number;
amount: string;
formatted: string;
}
interface AllBalances {
address: Address;
availableBalance: Balance;
lockedBalance: Balance;
freeBalance: Balance;
totalBalance: Balance;
reservedBalance: Balance;
stakedBalance?: Balance;
unstakedBalance?: Balance;
canstakeBalance?: Balance;
}
Examples
const balance = await sdk.balance.get({
address: 'yGCyN3eydMkze4EPtz59Tn7obwbUbYNZCz48dp8FRdemTaLwm',
});
const {
address,
availableBalance,
freeBalance,
lockedBalance,
} = balance;
curl -X 'GET' \
'https://rest.unique.network/opal/v1/balance?address=yGCyN3eydMkze4EPtz59Tn7obwbUbYNZCz48dp8FRdemTaLwm' \
-H 'accept: application/json'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const balance = await sdk.balance.get({ address: 'yGCyN3eydMkze4EPtz59Tn7obwbUbYNZCz48dp8FRdemTaLwm' });
const {
address,
availableBalance,
freeBalance,
lockedBalance,
} = balance;
Balance transfer
Overview
Balance transfers between accounts
Brief example
import { TransferBuildArguments } from '@unique-nft/substrate-client/types';
const transferArgs: TransferBuildArguments = {
address: '<from account address>',
destination: '<to account address>',
amount: 0.001,
};
const transferResult = await sdk.balance.transfer.submitWaitResult(transferArgs);
const { success } = transferResult.parsed;
Arguments
address: string
- Wallet address to withdraw from destination: string
- Wallet address for replenishment amount: number
- Number of coins transferred
Behaviour and errors
Returns
This method returns BalanceTransferResult
interface BalanceTransferResult {
success: boolean;
}
Examples
Fungible
Add fungible tokens
Arguments
- address - The address of collection owner
- collectionId - Collection Id
- amount - amount of tokens
- recipient - recipient of new tokens, address as default
Returns
- collectionId - Collection Id
- amount - amount of tokens
- recipient - recipient of new tokens
The method add new tokens of the collection to recipient
Examples
import { AddTokensArgs } from '@unique-nft/substrate-client/fungible';
const addTokens: AddTokensArgs = {
address: '<collection_owner_address>',
collectionId: 123,
amount: 777,
recipient: '<address_of_recipient>'
};
await sdk.fungible.addTokens.submitWaitResult(addTokens);
Get allowance
Overview
Get amount of fungible tokens approved to transfer
Brief example
import { AllowanceFungibleArguments } from '@unique-nft/substrate-client/fungible';
const AllowanceArgs: AllowanceFungibleArguments = {
from: '<address>',
to: '<address>',
collectionId: 1,
};
const { amount } = await sdk.fungible.allowance(AllowanceArgs);
Arguments
from: string
- Owner of tokens
to: string
- The address approved for the transfer of tokens on behalf of the owner
collectionId: number
- ID of collection
at?: string
— Hash of execution block (optional)
Behaviour and errors
Throw errors:
- Collection not found
Returns
The method returns a parsed
object that contains the Balance
.
interface Balance {
raw: string;
unit: string;
decimals: number;
amount: string;
formatted: string;
}
See the detailed description of the fields in getBalance.
Examples
import { AllowanceFungibleArguments } from '@unique-nft/substrate-client/fungible';
const AllowanceArgs: AllowanceFungibleArguments = {
from: '<address>',
to: '<address>',
collectionId: 1,
};
const { amount } = await sdk.fungible.allowance(AllowanceArgs);
curl -X 'GET' \
'https://rest.unique.network/opal/v1/fungible/tokens/allowance?collectionId=1&from=5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty&to=5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y' \
-H 'accept: application/json'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const { amount } = await client.fungible.allowanceTokens.submitWaitResult({
from: '<address>',
to: '<address>',
collectionId: 1,
});
Approve
Overview
Set, change, or remove approved address to transfer tokens.
Brief example
import { ApproveArguments } from '@unique-nft/substrate-client/refungible';
const approveArgs: ApproveArguments = {
address: '<Signer address>',
spender: '<Account address to be approved>',
collectionId: 1,
amount: '<amount of tokens to be approved>',
};
const result = await sdk.fungible.approve.submitWaitResult(approveArgs);
const { collectionId, amount } = result.parsed;
Arguments
address: string
- Signer address
spender: string
- Account address to be approved
collectionId: number
- Collection id
amount: number
- Amount of tokens to be approved
Behaviour and errors
Throw errors:
- Collection not found
- Signer is not Token Owner
- Insufficient balance
Returns
The method returns a parsed
object that contains the ApproveFungibleResult
.
{
collectionId: number;
amount: number;
}
Examples
import { ApproveArguments } from '@unique-nft/substrate-client/refungible';
const approveArgs: ApproveArguments = {
address: '<Signer address>',
spender: '<Account address to be approved>',
collectionId: 1,
amount: '<amount of tokens to be approved>',
};
const result = await sdk.fungible.approve.submitWaitResult(approveArgs);
const { collectionId, amount } = result.parsed;
curl -X 'POST' \
'https://rest.unique.network/opal/v1/fungible/tokens/approve?use=Result&withFee=false&verify=false' \
-H 'accept: application/json' \
-H 'Authorization: Seed //Bob' \
-H 'Content-Type: application/json' \
-d '{
"address": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
"spender": "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y",
"collectionId": 1,
"amount": 0.1
}'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await client.fungible.approveTokens.submitWaitResult({
address: '<Signer address>',
spender: '<Account address to be approved>',
collectionId: 1,
amount: '<amount of tokens to be approved>',
});
const { collectionId, amount } = result.parsed;
Burn token
Overview
This method destroys a amount of Fungible token.
If the from parameter is specified, then the token is destroyed on behalf of the owner of the item.
Only the Collection Owner, Collection Admin, or Current Fungible owner has permission to call this method.
Brief example
import '@unique-nft/substrate-client/tokens';
import { BurnFungibleArguments } from '@unique-nft/substrate-client/fungible';
const burnArgs: BurnFungibleArguments = {
address: '...'
collectionId: 1,
amount: 10
};
const result = await sdk.fungible.burn.submitWaitResult(burnArgs);
const { collectionId, address, amount } = result.parsed;
Arguments
address: string
- Signer address
collectionId: number
- ID of the collection
amount: number
- A amount of Fungible token
Optional Arguments
from?: string
- The owner of the item on whose behalf the token is destroyed
Behaviour and errors
Throw errors:
- Collection or token not found
- The Signer or from addresses do not have permission to call this method
- If the owner of the collection (but not the owner of the token) wants to burn the token and the ownerCanTransfer flag is set to false. Check the set limits using the method get effective limits of the collection.
- Insufficient balance
Returns
This method returns BurnFungibleResult
interface BurnFungibleResult {
collectionId: number;
address: Address;
amount: number;
}
Examples
import '@unique-nft/substrate-client/tokens';
import { BurnFungibleArguments } from '@unique-nft/substrate-client/fungible';
const burnArgs: BurnFungibleArguments = {
address: '...',
collectionId: 1,
amount: 10
};
const result = await sdk.fungible.burn.submitWaitResult(burnArgs);
const { collectionId, address, amount } = result.parsed;
curl -X 'DELETE' \
'http://rest.unique.network/opal/fungible?use=Build&withFee=false&verify=false' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"collectionId": 183,
"amount": 10,
"address": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty"
}'
# then we sign, then we call
curl -X 'POST' \
'https://rest.unique.network/opal/v1/extrinsic/submit' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"signerPayloadJSON": { *from previous response* },
"signature": "0x_your_signature_in_hex"
}'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await sdk.fungible.burn.submitWaitResult({
"collectionId": 1,
"amount": 10,
"address": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty"
});
const { parsed: { collectionId, amount } } = result;
console.log(`burned ${amount} tokens in collection ${collectionId}`);
Create collection
Arguments
- address - The address of collection owner
- name - Collection name (text, up to 64 characters)
- description - Collection description (text, up to 256 characters)
- mode - The collection type - Fungible
- decimals - decimal part for tokens in collection
- tokenPrefix - Token prefix (text, up to 4 characters)
- sponsorship - This field tells if sponsorship is enabled and what address is the current collection sponsor.
- limits - see set collection limits method
- metaUpdatePermission - Permission for update meta (ItemOwner, Admin, None)
- permissions - Collection permissions
Returns
The method returns a parsed
object that contains the collectionId: number
.
Examples
import { CreateFungibleCollectionArguments } from '@unique-nft/substrate-client/fungible';
const collectionCreateArgs: CreateFungibleCollectionArguments = {
address: '<valid_address>',
name: 'Test fungible collection',
description: 'just test',
tokenPrefix: 'TEST',
decimals: 10,
};
const createResult = await sdk.fungible.createCollection.submitWaitResult(collectionCreateArgs);
const { collectionId } = createResult.parsed;
const collection = await sdk.fungible.getCollection({ collectionId });
Get fungible tokens balance
Returns amount of fungible tokens owned by address.
Arguments
- collectionId - ID of the collection
- address - address
Returns
- raw - raw tokens amount
- decimals - decimal part in fungible collection
- amount - tokens amount (raw / decimal ** 10)
- unit - collection token prefix
- formatted - pretty formatted amount with SI
Examples
const accountBalance = await sdk.fungible.getBalance({ collectionId: 123, address: '<address>' });
const { formatted, unit } = accountBalance;
console.log(`Balance is ${formatted}${unit}`); // 'Balance is 100.0000 mTEST'
Get fungible collection by Id
Returns collection info in human format.
Arguments
- collectionId - ID of collection
Returns
- address - The address of collection owner
- name - Collection name (text, up to 64 characters)
- description - Collection description (text, up to 256 characters)
- mode - The collection type - Fungible
- decimals - decimal part for tokens in collection
- tokenPrefix - Token prefix (text, up to 4 characters)
- sponsorship - This field tells if sponsorship is enabled and what address is the current collection sponsor.
- limits - see set collection limits method
- metaUpdatePermission - Permission for update meta (
ItemOwner
,Admin
,None
) - permissions - Collection permissions
Examples
const {
name,
description,
decimals,
...rest
} = await sdk.fungible.getCollection({ collectionId: 123 });
Get total pieces
Overview
Returns amount of fungible tokens minted in collection.
Brief example
const { amount } = await sdk.fungible.getTotalPieces({ collectionId: 123 });
console.log(`Total pieces is ${amount}`);
Arguments
collectionId: number
— collection id
Behaviour and errors
Returns
This method returns GetTotalPiecesResult
interface GetTotalPiecesResult {
collectionId: number;
amount: number;
}
Examples
const { amount } = await sdk.fungible.getTotalPieces({ collectionId: 123 });
console.log(`Total pieces is ${amount}`);
curl -X 'GET' \
'https://rest.unique.network/opal/v1/fungible/total-pieces?collectionId=2' \
-H 'accept: application/json'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await sdk.fungible.getTotalPieces({
collectionId: 2,
});
const { amount } = result;
console.log(`Total pieces is ${amount}`);
Transfer fungible tokens
Arguments
- address - The address of tokens owner
- collectionId - ID of the collection
- recipient - The address of recipient
- amount - count of tokens
Returns
- sender - The address of tokens owner
- collectionId - ID of the collection
- recipient - The address of recipient
- amount - count of tokens
Examples
import { TransferTokensArgs } from '@unique-nft/substrate-client/fungible';
const transferArgs: TransferTokensArgs = {
address: '<your_address>',
collectionId: 123,
recipient: '<recipient_address>',
amount: 100.1,
};
await sdk.fungible.transferTokens.submitWaitResult(transferArgs);
Refungible
Get all account tokens of the collection
Overview
Returns an array of tokens, owned by address.
Brief example
import { AccountRefungibleTokensResult } from '@unique-nft/substrate-client/tokens';
const tokensResult: AccountRefungibleTokensResult = await sdk.refungible.getAccountTokens({
collectionId: 1,
address: '<address>',
});
const token = tokensResult.tokens[0];
const { collectionId, tokenId, amount } = token;
Arguments
collectionId: number
- ID of collection
address: string
- address of tokens owner
Behaviour and errors
Returns
This method returns AccountRefungibleTokensResult
interface AccountRefungibleTokenResult {
collectionId: number;
tokenId: number;
amount: number;
}
interface AccountRefungibleTokensResult {
tokens: AccountRefungibleTokenResult[];
}
Examples
import { AccountRefungibleTokenArguments, AccountRefungibleTokensResult } from '@unique-nft/substrate-client/tokens';
const accountTokensArguments: AccountRefungibleTokenArguments = {
address: '5DZGhQtBRyZpRgKX3VffhyBCSQD1KwU2yY1eAs99Soh7Dpwp',
collectionId: 1,
};
const tokensResult: AccountRefungibleTokensResult = await sdk.refungible.getAccountTokens(accountTokensArguments);
const token = tokensResult.tokens[0];
const { collectionId, tokenId, amount } = token;
console.log(`${collectionId} - ${tokenId} - ${amount}`);
curl -X 'GET' \
'https://rest.unique.network/opal/v1/refungible/tokens/account-tokens?address=5DZGhQtBRyZpRgKX3VffhyBCSQD1KwU2yY1eAs99Soh7Dpwp&collectionId=1'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const tokensResult = await sdk.refungible.accountTokens({
address: '5DZGhQtBRyZpRgKX3VffhyBCSQD1KwU2yY1eAs99Soh7Dpwp',
collectionId: 1,
});
const token = tokensResult.tokens[0];
const { collectionId, tokenId, amount } = token;
console.log(`${collectionId} - ${tokenId} - amount`);
Get allowance
Overview
Maximum number of RFT token pieces that one account is allowed to transfer from the balance of another account.
Brief example
import { AllowanceRefungibleArguments } from '@unique-nft/substrate-client/refungible/types';
const AllowanceArgs: AllowanceRefungibleArguments = {
from: '<address>',
to: '<address>',
collectionId: 1,
tokenId: 1,
};
const { amount } = await sdk.refungible.allowance(AllowanceArgs);
Arguments
from: string
- Owner of tokens
to: string
- The address approved for the transfer of tokens on behalf of the owner
collectionId: number
- ID of collection
tokenId: number
- ID of token
at?: string
— hash of execution block
Behaviour and errors
Throw errors:
- Collection or token not found
Returns
This method returns AllowanceRefungibleResult
type AllowanceRefungibleResult = {
amount: number;
};
- amount - number of pieces
Examples
import { AllowanceRefungibleArguments } from '@unique-nft/substrate-client/refungible/types';
const AllowanceArgs: AllowanceRefungibleArguments = {
from: '<address>',
to: '<address>',
collectionId: 1,
tokenId: 1,
};
const { amount } = await sdk.refungible.allowance(AllowanceArgs);
curl -X 'GET' \
'https://rest.unique.network/opal/v1/refungible/tokens/allowance?collectionId=1&tokenId=1&from=5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty&to=5HGjWAeFDfFCWPsjFQdVV2Msvz2XtMktvgocEZcCj68kUMaw' \
-H 'accept: application/json'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await client.fungible.allowanceToken.submitWaitResult({
from: '<address>',
to: '<address>',
collectionId: 1,
tokenId: 1,
});
const { amount } = result.parsed;
Approve
Overview
Set, change, or remove approved address to transfer the ownership of the RFT.
Brief example
import { ApproveArguments } from '@unique-nft/substrate-client/refungible';
const approveArgs: ApproveArguments = {
address: '<Signer address>',
spender: '<Account address for whom token will be approved>',
collectionId: 1,
tokenId: 1,
amount: '<number of pieces>',
};
const result = await sdk.refungible.approve.submitWaitResult(approveArgs);
const { collectionId, tokenId, amount } = result.parsed;
Arguments
address: string
- Signer address
spender: string
- Account address for whom token will be approved
collectionId: number
- Collection id
tokenId: number
- Token id
amount?: number
- Amount number of pieces to be approved (default value 1)
Behaviour and errors
Throw errors:
- Collection or token not found
- Signer is not Token Owner
- Insufficient balance
Returns
The method returns a parsed
object that contains the ApproveRefungibleResult
.
{
collectionId: number;
tokenId: number;
amount: number;
}
Examples
import { ApproveArguments } from '@unique-nft/substrate-client/refungible';
const approveArgs: ApproveArguments = {
address: '<Signer address>',
spender: '<Account address for whom token will be approved>',
collectionId: 1,
tokenId: 1,
amount: '<number of pieces>',
};
const result = await sdk.refungible.approve.submitWaitResult(approveArgs);
const { collectionId, tokenId, amount } = result.parsed;
curl -X 'POST' \
'https://rest.unique.network/opal/v1/refungible/tokens/approve?use=Result&withFee=false&verify=false' \
-H 'accept: application/json' \
-H 'Authorization: Seed //Bob' \
-H 'Content-Type: application/json' \
-d '{
"address": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
"spender": "5HGjWAeFDfFCWPsjFQdVV2Msvz2XtMktvgocEZcCj68kUMaw",
"collectionId": 1,
"tokenId": 1,
"amount": 3
}'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await client.refungible.approveToken.submitWaitResult({
address: '<Signer address>',
spender: '<Account address for whom token will be approved>',
collectionId: 1,
tokenId: 1,
amount: '<number of pieces>',
});
const { collectionId, tokenId, amount } = result.parsed;
Burn token
Overview
This method destroys a amount of Refungible token.
If the from parameter is specified, then the token is destroyed on behalf of the owner of the item.
Only the Collection Owner, Collection Admin, or Current Refungible owner has permission to call this method.
Brief example
import '@unique-nft/substrate-client/tokens';
import { BurnRefungibleArguments } from '@unique-nft/substrate-client/fungible';
const burnArgs: BurnRefungibleArguments = {
address: '...'
collectionId: 1,
topkenId: 1,
amount: 10
};
const result = await sdk.fungible.burn.submitWaitResult(burnArgs);
const { collectionId, tokenId, address, amount } = result.parsed;
Arguments
address: string
- Signer address
collectionId: number
- ID of the collection
tokenId: number
- ID of the token
amount: number
- A amount of Refungible token
Optional Arguments
from?: string
- The owner of the item on whose behalf the token is destroyed
Behaviour and errors
Throw errors:
- Collection or token not found
- The Signer or from addresses do not have permission to call this method
- If the owner of the collection (but not the owner of the token) wants to burn the token and the ownerCanTransfer flag is set to false. Check the set limits using the method get effective limits by collection id
- Insufficient balance
Returns
This method returns BurnRefungibleResult
interface BurnRefungibleResult {
collectionId: number;
tokenId: number;
address: Address;
amount: number;
}
Examples
import '@unique-nft/substrate-client/tokens';
import { BurnRefungibleArguments } from '@unique-nft/substrate-client/fungible';
const burnArgs: BurnRefungibleArguments = {
address: '...',
collectionId: 1,
tokenId: 1,
amount: 10
};
const result = await sdk.fungible.burn.submitWaitResult(burnArgs);
const { collectionId, tokenId, address, amount } = result.parsed;
curl -X 'DELETE' \
'http://rest.unique.network/opal/fungible?use=Build&withFee=false&verify=false' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"collectionId": 183,
"tokenId": 1,
"amount": 10,
"address": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty"
}'
# then we sign, then we call
curl -X 'POST' \
'https://rest.unique.network/opal/v1/extrinsic/submit' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"signerPayloadJSON": { *from previous response* },
"signature": "0x_your_signature_in_hex"
}'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await sdk.fungible.burn.submitWaitResult({
"collectionId": 1,
"tokenId": 1,
"amount": 10,
"address": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty"
});
const { parsed: { collectionId, tokenId, amount } } = result;
console.log(`burned ${amount} parts from token ${tokenId} in collection ${collectionId}`);
Create a refungible collection
Overview
The method creates a new RFT Collection.
RFT tokens can be created in a refungible collection.
Brief example
import { CreateFungibleCollectionArguments } from '@unique-nft/substrate-client/refungible';
const collectionCreateArgs: CreateFungibleCollectionArguments = {
address: '<valid_address>',
name: 'Test fungible collection',
description: 'just test',
tokenPrefix: 'TEST',
};
const createResult = await sdk.refungible.createCollection.submitWaitResult(collectionCreateArgs);
const { collectionId } = createResult.parsed;
const collection = await sdk.refungible.getCollection({ collectionId });
Arguments
The arguments are the same as for the create NFT token.
address
- The address of the collection owner
name
- Collection name (text, up to 64 characters)
description
- Collection description (text, up to 256 characters)
tokenPrefix
- Token prefix (text, up to 4 characters)
Optional Arguments
sponsorship
- This field tells if sponsorship is enabled and what address is the current collection sponsor.
limits
- see set collection limits method
metaUpdatePermission
- Permission for update meta (ItemOwner, Admin, None)
permissions
- Collection permissions
Behaviour and errors
Throws common errors on insufficient balance or incorrect parameters.
Returns
The method returns a parsed
object that contains the CollectionIdArguments
.
interface CollectionIdArguments {
collectionId: number;
}
Examples
import { CreateFungibleCollectionArguments } from '@unique-nft/substrate-client/refungible';
const collectionCreateArgs: CreateFungibleCollectionArguments = {
address: '<valid_address>',
name: 'Test refungible collection',
description: 'just test',
tokenPrefix: 'TEST',
};
const createResult = await sdk.refungible.createCollection.submitWaitResult(collectionCreateArgs);
const { collectionId } = createResult.parsed;
const collection = await sdk.refungible.getCollection({ collectionId });
curl -X 'POST' \
'https://rest.unique.network/opal/v1/refungible/collection?use=Result&withFee=false&verify=false' \
-H 'accept: application/json' \
-H 'Authorization: Seed //Bob' \
-H 'Content-Type: application/json' \
-d '{
"address": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
"name": "Test refungible collection",
"description": "just test",
"tokenPrefix": "TEST"
}'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await client.refungible.createCollection.submitWaitResult({
address: '<valid_address>',
name: 'Test refungible collection',
description: 'just test',
tokenPrefix: 'TEST',
});
const { collectionId, amount } = result.parsed;
Create RFT token
Overview
This method creates a concrete instance of RFT collection.
The RFT token is a non fungible token that was partitioned to pieces.
Collection can be created with create method in collection section.
Brief example
import { GetRefungibleCollectionArguments } from '@unique-nft/substrate-client/refungible/types';
const createTokenArgs: GetRefungibleCollectionArguments = {
address: '<your account address>',
collectionId: 123,
amount: 2,
};
const result = await sdk.refungible.createToken.submitWaitResult(createArgs);
const { collectionId, tokenId } = result.parsed;
const token = await sdk.token.get({ collectionId, tokenId });
Arguments
The arguments are the same as for the create NFT token.
And the amount property is added:
amount?: number;
- Number of pieces the RFT is split into
Behaviour and errors
Throw errors:
- Collection not found, the collection is not an RFT collection
- The number of pieces greater than 2^53 -1 (the maximum allowable number of pieces MAX_REFUNGIBLE_PIECES)
- Insufficient balance
Returns
The method returns a parsed
object that contains the CreateRefungibleTokenResult
.
{
collectionId: number;
tokenId: number;
owner: Address;
amount: number;
}
Examples
import { GetRefungibleCollectionArguments } from '@unique-nft/substrate-client/refungible/types';
const createTokenArgs: GetRefungibleCollectionArguments = {
address: '<your account address>',
collectionId: 123,
amount: 2,
};
const result = await sdk.refungible.createToken.submitWaitResult(createArgs);
const { collectionId, tokenId } = result.parsed;
const token = await sdk.token.get({ collectionId, tokenId });
curl -X 'POST' \
'https://rest.unique.network/opal/v1/refungible/tokens?use=Result&withFee=false&verify=false' \
-H 'accept: application/json' \
-H 'Authorization: Seed //Bob' \
-H 'Content-Type: application/json' \
-d ' {"address": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
"collectionId": 123,
"amount": 2}
'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await client.refungible.createToken.submitWaitResult({
address: '<your account address>',
collectionId: 123,
amount: 2,
});
const { collectionId, tokenId } = result.parsed;
Get balance
Overview
Get number of RFT token pieces owned by address.
Brief example
import { TokenBalanceRequest } from '@unique-nft/substrate-client/refungible';
const getBalanceArgs: TokenBalanceRequest = {
address: '<your account address>',
collectionId: 1,
tokenId: 1,
};
const { collectionId, tokenId, amount } = await sdk.refungible.getBalance(getBalanceArgs);
Arguments
address: Address;
- The address that owns the token pieces
collectionId: number;
- Collection id
tokenId: number;
- Token id
at?: At;
- Hash of execution block (optional)
Behaviour and errors
Throws common errors on incorrect parameters.
Returns
The method returns the TokenBalanceResult
.
export interface TokenBalanceResult {
collectionId: number;
tokenId: number;
amount: number;
}
Examples
import { TokenBalanceRequest } from '@unique-nft/substrate-client/refungible';
const getBalanceArgs: TokenBalanceRequest = {
address: '<your account address>',
collectionId: 1,
tokenId: 1,
};
const { collectionId, tokenId, amount } = await sdk.refungible.getBalance(getBalanceArgs);
curl -X 'GET' \
'https://rest.unique.network/opal/v1/refungible/tokens/balance?collectionId=1&tokenId=1&address=5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty' \
-H 'accept: application/json'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const { collectionId, tokenId, amount } = await client.fungible.getBalance({
address: '<your account address>',
collectionId: 1,
tokenId: 1,
});
Get refungible collection by Id
Overview
Returns RFT Collection info in human format.
Brief example
import { GetRefungibleCollectionArguments } from '@unique-nft/substrate-client/refungible';
const getCollectionArgs: GetRefungibleCollectionArguments = {
collectionId: 1,
};
const collection = await sdk.refungible.getCollection(getCollectionArgs);
Arguments
type GetRefungibleCollectionArguments = {
collectionId: number;
at?: string;
}
- collectionId - collection id
- at - hash of execution block
Behaviour and errors
Throws a SubstrateClientError if the requested collection is not an RFT collection
Returns
The method returns a parsed
object that contains the CollectionIdArguments
.
interface CollectionIdArguments {
collectionId: number;
}
Examples
import { GetRefungibleCollectionArguments } from '@unique-nft/substrate-client/refungible';
const getCollectionArgs: GetRefungibleCollectionArguments = {
collectionId: 1,
};
const collection = await sdk.refungible.getCollection(getCollectionArgs);
curl -X 'GET' \
'https://rest.unique.network/opal/v1/refungible/collection?collectionId=1' \
-H 'accept: application/json'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const collection = await client.refungible.getCollection.submitWaitResult({
collectionId: 1,
});
Repartition
Overview
Change number of RFT token pieces.
Signer must be the owner of all token pieces.
To combine all parts of the token into one, set the amount
parameter to 1.
Brief example
import { RepartitionTokenArguments } from '@unique-nft/substrate-client/refungible/types';
const repartitionArgs: RepartitionTokenArguments = {
address: '<your account address>',
collectionId: 123,
tokenId: 1,
amount: 5,
};
const result = await sdk.refungible.repartitionToken.submitWaitResult(repartitionArgs);
const { success } = result.parsed;
Arguments
address: string
- The address of token owner
collectionId: number
- Collection id
tokenId: number
- Token id
amount: number;
- Number of pieces the RFT is split into
Behaviour and errors
Throw errors:
- Collection not found, the collection is not an RFT collection
- Token not found
- The number of pieces greater than 2^53 -1 (the maximum allowable number of pieces MAX_REFUNGIBLE_PIECES)
- Insufficient balance
Returns
The method returns a parsed
object that contains the RepartitionTokenResult
.
interface RepartitionTokenResult {
success: boolean;
}
Examples
import { RepartitionTokenArguments } from '@unique-nft/substrate-client/refungible/types';
const repartitionArgs: RepartitionTokenArguments = {
address: '<your account address>',
collectionId: 123,
tokenId: 1,
amount: 5,
};
const result = await sdk.refungible.repartitionToken.submitWaitResult(repartitionArgs);
const { success } = result.parsed;
curl -X 'POST' \
'https://rest.unique.network/opal/v1/refungible/tokens/repartition?use=Result&withFee=false&verify=false' \
-H 'accept: application/json' \
-H 'Authorization: Seed //Bob' \
-H 'Content-Type: application/json' \
-d '{
"address": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
"collectionId": 123,
"tokenId": 1,
"amount": 5
}
'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await client.fungible.repartitionToken.submitWaitResult({
address: '<your account address>',
collectionId: 123,
tokenId: 1,
amount: 5,
});
const { success } = result.parsed;
Total pieces
Overview
Get total number of pieces
Brief example
import { TotalPiecesArguments } from '@unique-nft/substrate-client/fungible';
const AllowanceArgs: TotalPiecesArguments = {
collectionId: 1,
tokenId: 1,
};
const { amount } = await sdk.refungible.totalPieces(AllowanceArgs);
Arguments
collectionId: number
- ID of collection
tokenId: number
- ID of token
at?: string
— Hash of execution block (optional)
Behaviour and errors
Throw errors:
- Collection or token not found
Returns
This method returns TotalPiecesResult
type TotalPiecesResult = {
amount: number;
}
- amount - number of pieces
Examples
import { TotalPiecesArguments } from '@unique-nft/substrate-client/fungible';
const AllowanceArgs: TotalPiecesArguments = {
collectionId: 1,
tokenId: 1,
};
const { amount } = await sdk.refungible.totalPieces(AllowanceArgs);
curl -X 'GET' \
'https://rest.unique.network/opal/v1/refungible/tokens/total-pieces?collectionId=1&tokenId=1' \
-H 'accept: application/json'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await client.fungible.totalPieces.submitWaitResult({
collectionId: 1,
tokenId: 1,
});
const { amount } = result.parsed;
Transfer RFT tokens
Overview
This method changes the ownership of the RFT token pieces.
Brief example
import { TransferArguments } from '@unique-nft/substrate-client/tokens';
const args: TransferArguments = {
address: '<address>',
to: '<address>',
collectionId: 1,
tokenId: 1,
amount: 3,
};
const result = await sdk.refungible.transferToken.submitWaitResult(args);
console.log(result.parsed);
Arguments
The arguments are the same as for the transfer method in the tokens section.
And the amount property is added:
amount?: number
- Amount to transfer. The default value is 1 (optional)
Behaviour and errors
Throw errors:
address
is not the current owner or an authorized operator for this RFTfrom
is not the current ownerto
is the zero addresstokenId
is not a valid RFT- Transferable RFT pieces have multiple owners
- Insufficient balance
Returns
The method returns a parsed
object that contains the TransferRefungibleResult
.
interface TransferRefungibleResult {
collectionId: number;
tokenId: number;
from: Address;
to: Address;
amount: number;
}
Examples
import { TransferArguments } from '@unique-nft/substrate-client/tokens';
const args: TransferArguments = {
address: '<address>',
to: '<address>',
collectionId: 1,
tokenId: 1,
};
const result = await sdk.token.transfer.submitWaitResult(args);
console.log(result.parsed);
curl -X 'POST' \
'https://rest.unique.network/opal/v1/refungible/tokens/transfer?use=Result&withFee=false&verify=false' \
-H 'accept: application/json' \
-H 'Authorization: Seed //Bob' \
-H 'Content-Type: application/json' \
-d '{
"collectionId": 1,
"tokenId": 1,
"address": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
"to": "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y",
"amount": 3
}'
const sdk = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const result = await client.fungible.transferToken.submitWaitResult({
address: '<address>',
to: '<address>',
collectionId: 1,
tokenId: 1,
amount: 3,
});
console.log(result.parsed);
Evm
Call method
Overview
The method does not require a signature. With this method, you can only read information from the smart contract.
Brief example
const value = await sdk.evm.call({
abi,
contractAddress,
address: richAccount.address,
funcName: 'getTestValue',
args: [true],
});
console.log(value);
Arguments
address: string
- Signer address
contractAddress: string
- Ethereum address of the smart-contract
abi: Abi
- JSON Abi of your smart-contract
funcName: string
- Name of function smart-contract
args?: any[]
- An array of arguments you want to pass to the function call
nonce?: number | HexString
- The nonce for this transaction
at?: string
- Hash of execution block
Behaviour and errors
Returns
The method can return any data, depending on the result of the smart contract function.
Examples
const value = await sdk.evm.call({
abi,
contractAddress,
address: richAccount.address,
funcName: 'getTestValue',
args: [true],
});
console.log(value);
curl -X 'POST' \
'https://rest.unique.network/opal/v1/evm/call' \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-d '{
"address": "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",
"contractAddress": "0x60639DB997DAAeD16111998a45a4D6450809aB6A",
"abi": [{
"inputs": [],
"name": "myStrValue",
"outputs":
[
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
}],
"funcName": "myStrValue"
}'
const value = await sdk.evm.call({
abi,
contractAddress,
address: richAccount.address,
funcName: 'getTestValue',
args: [true],
});
console.log(value);
Check Smart contract exist method
Overview
The method will check if there is a smart contract in the network at the specified address
Brief example
const { exist } = await sdk.evm.contractExists({
contractAddress: '<ethereum address>'
});
console.log('exist', exist);
Arguments
contractAddress: string
- Ethereum address of the smart-contract
blockNumber?: number | string
- Number of execution block
Behaviour and errors
Returns
This method returns EvmContractExistResponse
interface EvmContractExistResponse {
exist: boolean;
};
Examples
const { exist } = await sdk.evm.contractExists({
contractAddress: '<ethereum address>'
});
console.log('exist', exist);
curl -X 'GET' \
'https://rest.unique.network/opal/v1/evm/contract-exists?contractAddress=0x60639DB997DAAeD16111998a45a4D6450809aB6A' \
-H 'accept: application/json'
const { exist } = await client.evm.contractExists({
contractAddress: '<ethereum address>'
});
console.log('exist', exist);
Send method
Overview
Method for calling functions that make changes to the network and require transactions to be signed.
Brief example
import { EvmSendArguments } from '@unique-nft/substrate-client/evm/methods/send';
const sendArgs: EvmSendArguments = {
abi,
contractAddress,
address: richAccount.address,
maxFeePerGas: gasPrice,
funcName: 'addValue',
args: [1],
};
const { parsed } = await sdk.evm.send.submitWaitResult(sendArgs);
console.log(parsed);
Arguments
address: string
- Signer address
contractAddress: string
- Ethereum address of the smart-contract
abi: Abi
- JSON Abi of your smart-contract
funcName: string
- Name of function smart-contract
args?: any[]
- An array of arguments you want to pass to the function call
nonce?: number | HexString
- The nonce for this transaction
value?: number | string
- The amount of money you want to transfer to the smart-contract
gasLimit?: number | string
- Function gas limit
maxFeePerGas?: number | string
maxPriorityFeePerGas?: number | string
Behaviour and errors
Returns
This method returns EvmSendResult
import { HexString } from '@polkadot/util/types';
import { Event } from 'abi-coder';
export interface UnknownEvent {
topics: string[];
data: string;
}
interface EvmSendResult {
isExecutedFailed: boolean;
parsedEvents: Event[];
unknownEvents: UnknownEvent[];
}
Examples
import { EvmSendArguments } from '@unique-nft/substrate-client/evm/methods/send';
const sendArgs: EvmSendArguments = {
abi,
contractAddress,
address: richAccount.address,
maxFeePerGas: gasPrice,
funcName: 'addValue',
args: [1],
};
const { parsed } = await sdk.evm.send.submitWaitResult(sendArgs);
console.log(parsed);
curl -X 'POST' \
'https://rest.unique.network/opal/v1/evm/send?use=SubmitWatch&withFee=false&verify=false' \
-H 'accept: application/json' \
-H 'Authorization: Seed <your seed>' \
-H 'Content-Type: application/json' \
-d '{
"address": "5HNUuEAYMWEo4cuBW7tuL9mLHR9zSA8H7SdNKsNnYRB9M5TX",
"contractAddress": "0x60639DB997DAAeD16111998a45a4D6450809aB6A",
"abi": [{
"inputs":
[
{
"internalType": "uint256",
"name": "delta",
"type": "uint256"
}
],
"name": "updateMyUint",
"outputs":
[],
"stateMutability": "nonpayable",
"type": "function"
}],
"funcName": "updateMyUint",
"args": [1]
}'
import { EvmSendArgumentsDto } from '@unique-nft/sdk/types';
const sendArgs: EvmSendArgumentsDto = {
abi,
contractAddress: <contract adress>,
address: <substrate address>,
funcName: 'addValue',
args: [1],
};
const { parsed } = await sdk.evm.send.submitWaitResult(sendArgs);
console.log(parsed);
Common
Ipfs
Upload file
Overview
Upload single file to IPFS
Brief example
const client = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const file = fs.readFileSync(`./your_picture.png`);
const { fullUrl, cid } = await client.ipfs.uploadFile({ file });
console.log(`Open by browser -> ${fullUrl}`);
console.log(`Or use CID if you need -> ${cid}`);
Arguments
file: Buffer | Blob
- File content
Behaviour and errors
Throws validation error if file mime type is not allowed
Returns
This method returns IpfsUploadResponse
export interface IpfsUploadResponse {
/** Entry CID_V0 */
cid: string;
/** Full url for entry on IPFS gateway */
fullUrl?: string;
}
Examples
curl -v -F file=@./1.jpg https://rest.unique.network/opal/v1/ipfs/upload-file
Upload multiple files
Overview
Upload multiple files to IPFS and group inside single directory
Brief example
const client = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const contentAsBuffer = fs.readFileSync(`./1.png`);
const contentAsStream = fs.createReadStream(`./2.png`);
const files = [
{ content: contentAsBuffer, name: `1.png` },
{ content: contentAsStream, name: `2.png` },
];
const { fullUrl, cid } = await client.ipfs.uploadFiles({ files })
console.log(`Open by browser -> ${fullUrl}`);
console.log(`Or use CID if you need -> ${cid}`);
Arguments
Method accepts IpfsUploadMultipleRequest
type FileLike = {
content: Buffer | ReadableStream;
name: string;
}
type IpfsUploadMultipleRequest = {
files: Array<FileLike | File>;
}
Behaviour and errors
Throws validation error if file mime type is not allowed
Returns
This method returns IpfsUploadResponse
export interface IpfsUploadResponse {
/** Entry CID_V0 */
cid: string;
/** Full url for entry on IPFS gateway */
fullUrl?: string;
}
Examples
const client = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const name = 'punk-1.png';
const contentAsBuffer = fs.readFileSync(`./1.png`);
const contentAsStream = fs.createReadStream(`./2.png`);
const files = [
{ content: contentAsBuffer, name: `1.png` },
{ content: contentAsStream, name: `2.png` },
];
const { fullUrl, cid } = await client.ipfs.uploadFiles({ files })
console.log(`Open by browser -> ${fullUrl}`);
console.log(`Or use CID if you need -> ${cid}`);
curl -v \
-F files=@1.jpg \
-F files=@2.jpg \
https://rest.unique.network/opal/v1/ipfs/upload-files
Add multiple files to existing folder
Overview
Upload multiple files to existing IPFS folder and get new URL and CID
Brief example
const client = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const contentAsBuffer = fs.readFileSync(`./1.png`);
const firstFilesArray = [{ content: contentAsBuffer, name: `1.png` }];
const contentAsStream = fs.createReadStream(`./2.png`);
const secondFilesArray = [{ content: contentAsStream, name: `2.png` }];
const { cid: firstCid } = await client.ipfs.uploadFiles({ files: firstFilesArray });
const { fullUrl, cid } = await client.ipfs.addFiles({ cid: firstCid, files: secondFilesArray });
console.log(`Open by browser -> ${fullUrl}`);
console.log(`Or use CID if you need -> ${cid}`);
Arguments
Method accepts IpfsAddMultipleRequest
type FileLike = {
content: Buffer | ReadableStream;
name: string;
}
type IpfsUploadMultipleRequest = {
cid: string;
files: Array<FileLike | File>;
}
Behaviour and errors
Throws validation error if file mime type is not allowed
Returns
This method returns IpfsUploadResponse
export interface IpfsUploadResponse {
/** Entry CID_V0 */
cid: string;
/** Full url for entry on IPFS gateway */
fullUrl?: string;
}
Examples
const client = new Sdk({ baseUrl: 'https://rest.unique.network/opal/v1' });
const contentAsBuffer = fs.readFileSync(`./1.png`);
const firstFilesArray = [{ content: contentAsBuffer, name: `1.png` }];
const contentAsStream = fs.createReadStream(`./2.png`);
const secondFilesArray = [{ content: contentAsStream, name: `2.png` }];
const { cid: firstCid } = await client.ipfs.uploadFiles({ files: firstFilesArray });
const { fullUrl, cid } = await client.ipfs.addFiles({ cid: firstCid, files: secondFilesArray });
console.log(`Open by browser -> ${fullUrl}`);
console.log(`Or use CID if you need -> ${cid}`);
curl -X PATCH -v \
-F files=@3.jpg \
-F cid=QmbZFugbeYQZj2jqH9qE1zPzUEJ4Zcj8RE5jqGGBpBYaRd \
https://rest.unique.network/opal/v1/ipfs/add-files